Asterisk - The Open Source Telephony Project GIT-master-8ef3e4f
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  event_filter_entry
 
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  originate_permissions_entry
 
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 = 0 , FILTER_ALLOC_FAILED , FILTER_COMPILE_FAIL , FILTER_FORMAT_ERROR }
 
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  event_filter_match_type {
  FILTER_MATCH_REGEX = 0 , FILTER_MATCH_EXACT , FILTER_MATCH_STARTS_WITH , FILTER_MATCH_ENDS_WITH ,
  FILTER_MATCH_CONTAINS , FILTER_MATCH_NONE
}
 
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 int app_match (const char *app, const char *data, const char *search)
 
static int appdata_match (const char *app, const char *data, const char *search)
 
static void append_channel_vars (struct ast_str **pbuf, struct ast_channel *chan)
 
static int append_event (const char *str, int event_name_hash, 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 async_goto_with_discard_bridge_after (struct ast_channel *chan, const char *context, const char *exten, int priority)
 
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 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 file_in_modules_dir (const char *filename)
 Check if the given file path is in the modules dir or not. More...
 
static int filter_cmp_fn (void *obj, void *arg, void *data, int flags)
 
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 int is_originate_app_permitted (const char *app, const char *data, int permission)
 
static int is_restricted_file (const char *filename)
 Check if a file is restricted or not. 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 *criteria, const char *filter_pattern, struct ao2_container *includefilters, struct ao2_container *excludefilters)
 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_eventdata (struct event_filter_entry *entry, const char *eventdata)
 Test eventdata against a filter entry. More...
 
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_match (const char *app, const char *data, const char *search)
 
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 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 should_send_event (struct ao2_container *includefilters, struct ao2_container *excludefilters, struct eventqent *eqe)
 
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...
 

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 char * match_type_names []
 
static struct originate_permissions_entry originate_app_permissions []
 
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 565 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 1889 of file manager.c.

◆ DEFAULT_REALM

#define DEFAULT_REALM   "asterisk"

Definition at line 175 of file manager.c.

◆ EVENT_FLAG_SHUTDOWN

#define EVENT_FLAG_SHUTDOWN   -1

Fake event class used to end sessions at shutdown.

Definition at line 208 of file manager.c.

◆ GET_HEADER_FIRST_MATCH

#define GET_HEADER_FIRST_MATCH   0

Definition at line 1589 of file manager.c.

◆ GET_HEADER_LAST_MATCH

#define GET_HEADER_LAST_MATCH   1

Definition at line 1590 of file manager.c.

◆ GET_HEADER_SKIP_EMPTY

#define GET_HEADER_SKIP_EMPTY   2

Definition at line 1591 of file manager.c.

◆ MANAGER_EVENT_BUF_INITSIZE

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 7536 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 562 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 774 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 220 of file manager.c.

◆ MAX_VARS

#define MAX_VARS   128

Definition at line 205 of file manager.c.

◆ MGR_SHOW_TERMINAL_WIDTH

#define MGR_SHOW_TERMINAL_WIDTH   80

Definition at line 203 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 1937 of file manager.c.

Enumeration Type Documentation

◆ add_filter_result

Enumerator
FILTER_SUCCESS 
FILTER_ALLOC_FAILED 
FILTER_COMPILE_FAIL 
FILTER_FORMAT_ERROR 

Definition at line 123 of file manager.c.

123 {
124 FILTER_SUCCESS = 0,
128};
@ FILTER_SUCCESS
Definition: manager.c:124
@ FILTER_FORMAT_ERROR
Definition: manager.c:127
@ FILTER_COMPILE_FAIL
Definition: manager.c:126
@ FILTER_ALLOC_FAILED
Definition: manager.c:125

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

108 {
109 UNKNOWN_ACTION = 1,
121};
@ FAILURE_EMPTYCAT
Definition: manager.c:116
@ FAILURE_UPDATE
Definition: manager.c:117
@ FAILURE_NEWCAT
Definition: manager.c:114
@ FAILURE_DELETE
Definition: manager.c:118
@ FAILURE_APPEND
Definition: manager.c:119
@ UNKNOWN_CATEGORY
Definition: manager.c:110
@ FAILURE_DELCAT
Definition: manager.c:115
@ FAILURE_ALLOCATION
Definition: manager.c:113
@ FAILURE_TEMPLATE
Definition: manager.c:120
@ UNSPECIFIED_CATEGORY
Definition: manager.c:111
@ UNSPECIFIED_ARGUMENT
Definition: manager.c:112
@ UNKNOWN_ACTION
Definition: manager.c:109

◆ event_filter_match_type

Enumerator
FILTER_MATCH_REGEX 
FILTER_MATCH_EXACT 
FILTER_MATCH_STARTS_WITH 
FILTER_MATCH_ENDS_WITH 
FILTER_MATCH_CONTAINS 
FILTER_MATCH_NONE 

Definition at line 385 of file manager.c.

385 {
392};
@ FILTER_MATCH_ENDS_WITH
Definition: manager.c:389
@ FILTER_MATCH_CONTAINS
Definition: manager.c:390
@ FILTER_MATCH_STARTS_WITH
Definition: manager.c:388
@ FILTER_MATCH_REGEX
Definition: manager.c:386
@ FILTER_MATCH_NONE
Definition: manager.c:391
@ FILTER_MATCH_EXACT
Definition: manager.c:387

◆ mansession_message_parsing

Enumerator
MESSAGE_OKAY 
MESSAGE_LINE_TOO_LONG 

Definition at line 313 of file manager.c.

313 {
316};
@ MESSAGE_OKAY
Definition: manager.c:314
@ MESSAGE_LINE_TOO_LONG
Definition: manager.c:315

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

7673{
7674 struct ao2_container *sessions = ao2_global_obj_ref(mgr_sessions);
7675 va_list ap;
7676 int res;
7677
7679 /* Nobody is listening */
7681 return 0;
7682 }
7683
7684 va_start(ap, fmt);
7686 file, line, func, fmt, ap);
7687 va_end(ap);
7689 return res;
7690}
#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:95
#define any_manager_listeners(sessions)
Definition: manager.c:565
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:7538
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 1606 of file manager.c.

1607{
1608 int x, l = strlen(var);
1609 const char *result = "";
1610
1611 if (!m) {
1612 return result;
1613 }
1614
1615 for (x = 0; x < m->hdrcount; x++) {
1616 const char *h = m->headers[x];
1617 if (!strncasecmp(var, h, l) && h[l] == ':') {
1618 const char *value = h + l + 1;
1619 value = ast_skip_blanks(value); /* ignore leading spaces in the value */
1620 /* found a potential candidate */
1621 if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) {
1622 continue; /* not interesting */
1623 }
1624 if (mode & GET_HEADER_LAST_MATCH) {
1625 result = value; /* record the last match so far */
1626 } else {
1627 return value;
1628 }
1629 }
1630 }
1631
1632 return result;
1633}
#define var
Definition: ast_expr2f.c:605
static PGresult * result
Definition: cel_pgsql.c:84
#define GET_HEADER_LAST_MATCH
Definition: manager.c:1590
#define GET_HEADER_SKIP_EMPTY
Definition: manager.c:1591
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 1884 of file manager.c.

1892{

◆ __init_manager_event_buf()

static void __init_manager_event_buf ( void  )
static

Definition at line 7535 of file manager.c.

7549{

◆ __init_userevent_buf()

static void __init_userevent_buf ( void  )
static

Definition at line 1886 of file manager.c.

1892{

◆ __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 7648 of file manager.c.

7659{
7660 va_list ap;
7661 int res;
7662
7663 va_start(ap, fmt);
7665 chancount, chans, file, line, func, fmt, ap);
7666 va_end(ap);
7667 return res;
7668}

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

7549{
7551 const char *cat_str;
7552 struct timeval now;
7553 struct ast_str *buf;
7554 int i;
7555 int event_name_hash;
7556
7559 ast_debug(3, "AMI Event '%s' is globally disabled, skipping\n", event);
7560 /* Event is globally disabled */
7561 return -1;
7562 }
7563 }
7564
7566 if (!buf) {
7567 return -1;
7568 }
7569
7570 cat_str = authority_to_str(category, &auth);
7571 ast_str_set(&buf, 0,
7572 "Event: %s\r\n"
7573 "Privilege: %s\r\n",
7574 event, cat_str);
7575
7576 if (timestampevents) {
7577 now = ast_tvnow();
7578 ast_str_append(&buf, 0,
7579 "Timestamp: %ld.%06lu\r\n",
7580 (long)now.tv_sec, (unsigned long) now.tv_usec);
7581 }
7582 if (manager_debug) {
7583 static int seq;
7584
7585 ast_str_append(&buf, 0,
7586 "SequenceNumber: %d\r\n",
7588 ast_str_append(&buf, 0,
7589 "File: %s\r\n"
7590 "Line: %d\r\n"
7591 "Func: %s\r\n",
7592 file, line, func);
7593 }
7595 ast_str_append(&buf, 0,
7596 "SystemName: %s\r\n",
7598 }
7599
7600 ast_str_append_va(&buf, 0, fmt, ap);
7601 for (i = 0; i < chancount; i++) {
7603 }
7604
7605 ast_str_append(&buf, 0, "\r\n");
7606
7607 event_name_hash = ast_str_hash(event);
7608
7609 append_event(ast_str_buffer(buf), event_name_hash, category);
7610
7611 /* Wake up any sleeping sessions */
7612 if (sessions) {
7613 struct ao2_iterator iter;
7615
7616 iter = ao2_iterator_init(sessions, 0);
7617 while ((session = ao2_iterator_next(&iter))) {
7618 ast_mutex_lock(&session->notify_lock);
7619 if (session->waiting_thread != AST_PTHREADT_NULL) {
7620 pthread_kill(session->waiting_thread, SIGURG);
7621 } else {
7622 /* We have an event to process, but the mansession is
7623 * not waiting for it. We still need to indicate that there
7624 * is an event waiting so that get_input processes the pending
7625 * event instead of polling.
7626 */
7627 session->pending_event = 1;
7628 }
7629 ast_mutex_unlock(&session->notify_lock);
7631 }
7632 ao2_iterator_destroy(&iter);
7633 }
7634
7635 if (category != EVENT_FLAG_SHUTDOWN && !AST_RWLIST_EMPTY(&manager_hooks)) {
7636 struct manager_custom_hook *hook;
7637
7639 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
7640 hook->helper(category, event, ast_str_buffer(buf));
7641 }
7643 }
7644
7645 return 0;
7646}
static volatile unsigned int seq
Definition: app_sms.c:126
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 int append_event(const char *str, int event_name_hash, int category)
events are appended to a queue from where they can be dispatched to clients.
Definition: manager.c:7493
static struct ast_threadstorage manager_event_buf
Definition: manager.c:7535
static int manager_debug
Definition: manager.c:169
static void append_channel_vars(struct ast_str **pbuf, struct ast_channel *chan)
Definition: manager.c:7518
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:914
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:815
#define MAX_AUTH_PERM_STRING
Definition: manager.c:774
static int timestampevents
Definition: manager.c:163
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition: manager.c:208
#define MANAGER_EVENT_BUF_INITSIZE
Definition: manager.c:7536
static char * manager_disabledevents
Definition: manager.c:173
#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:73
#define ast_mutex_unlock(a)
Definition: lock.h:197
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:764
#define ast_mutex_lock(a)
Definition: lock.h:196
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:171
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
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259
#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:466
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:366
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_hash(), 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 10045 of file manager.c.

10047{
10049 return;
10050 }
10051
10052 /* For now, this is going to be performed simply and just execute a forced reload. */
10053 ast_log(LOG_NOTICE, "Reloading manager in response to ACL change event.\n");
10054 __init_manager(1, 1);
10055}
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:9642
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 231 of file manager.c.

232{
233 if (!acl_change_sub) {
238 }
239}
static struct stasis_subscription * acl_change_sub
Definition: manager.c:179
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:10045
#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:1050
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:1104
#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 241 of file manager.c.

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

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

4497{
4498 const char *msgtype = astman_get_header(m, "MsgType");
4499 const char *chargetype = astman_get_header(m, "ChargeType");
4500 const char *currencyname = astman_get_header(m, "CurrencyName");
4501 const char *currencyamount = astman_get_header(m, "CurrencyAmount");
4502 const char *mult = astman_get_header(m, "CurrencyMultiplier");
4503 const char *totaltype = astman_get_header(m, "TotalType");
4504 const char *aocbillingid = astman_get_header(m, "AOCBillingId");
4505 const char *association_id= astman_get_header(m, "ChargingAssociationId");
4506 const char *association_num = astman_get_header(m, "ChargingAssociationNumber");
4507 const char *association_plan = astman_get_header(m, "ChargingAssociationPlan");
4508
4509 enum ast_aoc_type _msgtype;
4510 enum ast_aoc_charge_type _chargetype;
4512 enum ast_aoc_total_type _totaltype = AST_AOC_TOTAL;
4513 enum ast_aoc_billing_id _billingid = AST_AOC_BILLING_NA;
4514 unsigned int _currencyamount = 0;
4515 int _association_id = 0;
4516 unsigned int _association_plan = 0;
4517
4518 struct ast_aoc_decoded *decoded = NULL;
4519
4520 if (ast_strlen_zero(chargetype)) {
4521 astman_send_error(s, m, "ChargeType not specified");
4522 goto aocmessage_cleanup;
4523 }
4524
4525 _msgtype = strcasecmp(msgtype, "d") ? AST_AOC_E : AST_AOC_D;
4526
4527 if (!strcasecmp(chargetype, "NA")) {
4528 _chargetype = AST_AOC_CHARGE_NA;
4529 } else if (!strcasecmp(chargetype, "Free")) {
4530 _chargetype = AST_AOC_CHARGE_FREE;
4531 } else if (!strcasecmp(chargetype, "Currency")) {
4532 _chargetype = AST_AOC_CHARGE_CURRENCY;
4533 } else if (!strcasecmp(chargetype, "Unit")) {
4534 _chargetype = AST_AOC_CHARGE_UNIT;
4535 } else {
4536 astman_send_error(s, m, "Invalid ChargeType");
4537 goto aocmessage_cleanup;
4538 }
4539
4540 if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
4541
4542 if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u", &_currencyamount) != 1)) {
4543 astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when ChargeType is Currency");
4544 goto aocmessage_cleanup;
4545 }
4546
4547 if (ast_strlen_zero(mult)) {
4548 astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
4549 goto aocmessage_cleanup;
4550 } else if (!strcasecmp(mult, "onethousandth")) {
4552 } else if (!strcasecmp(mult, "onehundredth")) {
4554 } else if (!strcasecmp(mult, "onetenth")) {
4555 _mult = AST_AOC_MULT_ONETENTH;
4556 } else if (!strcasecmp(mult, "one")) {
4557 _mult = AST_AOC_MULT_ONE;
4558 } else if (!strcasecmp(mult, "ten")) {
4559 _mult = AST_AOC_MULT_TEN;
4560 } else if (!strcasecmp(mult, "hundred")) {
4561 _mult = AST_AOC_MULT_HUNDRED;
4562 } else if (!strcasecmp(mult, "thousand")) {
4563 _mult = AST_AOC_MULT_THOUSAND;
4564 } else {
4565 astman_send_error(s, m, "Invalid ChargeMultiplier");
4566 goto aocmessage_cleanup;
4567 }
4568 }
4569
4570 /* create decoded object and start setting values */
4571 if (!(decoded = ast_aoc_create(_msgtype, _chargetype, 0))) {
4572 astman_send_error(s, m, "Message Creation Failed");
4573 goto aocmessage_cleanup;
4574 }
4575
4576 if (_msgtype == AST_AOC_D) {
4577 if (!ast_strlen_zero(totaltype) && !strcasecmp(totaltype, "subtotal")) {
4578 _totaltype = AST_AOC_SUBTOTAL;
4579 }
4580
4581 if (ast_strlen_zero(aocbillingid)) {
4582 /* ignore this is optional */
4583 } else if (!strcasecmp(aocbillingid, "Normal")) {
4584 _billingid = AST_AOC_BILLING_NORMAL;
4585 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
4586 _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
4587 } else if (!strcasecmp(aocbillingid, "CreditCard")) {
4588 _billingid = AST_AOC_BILLING_CREDIT_CARD;
4589 } else {
4590 astman_send_error(s, m, "Invalid AOC-D AOCBillingId");
4591 goto aocmessage_cleanup;
4592 }
4593 } else {
4594 if (ast_strlen_zero(aocbillingid)) {
4595 /* ignore this is optional */
4596 } else if (!strcasecmp(aocbillingid, "Normal")) {
4597 _billingid = AST_AOC_BILLING_NORMAL;
4598 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
4599 _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
4600 } else if (!strcasecmp(aocbillingid, "CreditCard")) {
4601 _billingid = AST_AOC_BILLING_CREDIT_CARD;
4602 } else if (!strcasecmp(aocbillingid, "CallFwdUnconditional")) {
4604 } else if (!strcasecmp(aocbillingid, "CallFwdBusy")) {
4605 _billingid = AST_AOC_BILLING_CALL_FWD_BUSY;
4606 } else if (!strcasecmp(aocbillingid, "CallFwdNoReply")) {
4608 } else if (!strcasecmp(aocbillingid, "CallDeflection")) {
4610 } else if (!strcasecmp(aocbillingid, "CallTransfer")) {
4611 _billingid = AST_AOC_BILLING_CALL_TRANSFER;
4612 } else {
4613 astman_send_error(s, m, "Invalid AOC-E AOCBillingId");
4614 goto aocmessage_cleanup;
4615 }
4616
4617 if (!ast_strlen_zero(association_id) && (sscanf(association_id, "%30d", &_association_id) != 1)) {
4618 astman_send_error(s, m, "Invalid ChargingAssociationId");
4619 goto aocmessage_cleanup;
4620 }
4621 if (!ast_strlen_zero(association_plan) && (sscanf(association_plan, "%30u", &_association_plan) != 1)) {
4622 astman_send_error(s, m, "Invalid ChargingAssociationPlan");
4623 goto aocmessage_cleanup;
4624 }
4625
4626 if (_association_id) {
4627 ast_aoc_set_association_id(decoded, _association_id);
4628 } else if (!ast_strlen_zero(association_num)) {
4629 ast_aoc_set_association_number(decoded, association_num, _association_plan);
4630 }
4631 }
4632
4633 if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
4634 ast_aoc_set_currency_info(decoded, _currencyamount, _mult, ast_strlen_zero(currencyname) ? NULL : currencyname);
4635 } else if (_chargetype == AST_AOC_CHARGE_UNIT) {
4636 struct ast_aoc_unit_entry entry;
4637 int i;
4638
4639 /* multiple unit entries are possible, lets get them all */
4640 for (i = 0; i < 32; i++) {
4641 if (aocmessage_get_unit_entry(m, &entry, i)) {
4642 break; /* that's the end then */
4643 }
4644
4645 ast_aoc_add_unit_entry(decoded, entry.valid_amount, entry.amount, entry.valid_type, entry.type);
4646 }
4647
4648 /* at least one unit entry is required */
4649 if (!i) {
4650 astman_send_error(s, m, "Invalid UnitAmount(0), At least one valid unit entry is required when ChargeType is set to Unit");
4651 goto aocmessage_cleanup;
4652 }
4653
4654 }
4655
4656 ast_aoc_set_billing_id(decoded, _billingid);
4657 ast_aoc_set_total_type(decoded, _totaltype);
4658
4659 return decoded;
4660
4661aocmessage_cleanup:
4662
4663 ast_aoc_destroy_decoded(decoded);
4664 return NULL;
4665}
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:285
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:316
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:1065
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:986
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:1033
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:928
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:1049
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:916
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:1982
const char * astman_get_header(const struct message *m, char *var)
Return the first matching variable from an array.
Definition: manager.c:1643
static int aocmessage_get_unit_entry(const struct message *m, struct ast_aoc_unit_entry *entry, unsigned int entry_num)
Definition: manager.c:4471
Definition: aoc.h:178

References ast_aoc_unit_entry::amount, aocmessage_get_unit_entry(), ast_aoc_add_unit_entry(), AST_AOC_BILLING_CALL_DEFLECTION, AST_AOC_BILLING_CALL_FWD_BUSY, AST_AOC_BILLING_CALL_FWD_NO_REPLY, AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL, AST_AOC_BILLING_CALL_TRANSFER, AST_AOC_BILLING_CREDIT_CARD, AST_AOC_BILLING_NA, AST_AOC_BILLING_NORMAL, AST_AOC_BILLING_REVERSE_CHARGE, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_NA, AST_AOC_CHARGE_UNIT, ast_aoc_create(), AST_AOC_D, ast_aoc_destroy_decoded(), AST_AOC_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(), NULL, ast_aoc_unit_entry::type, ast_aoc_unit_entry::valid_amount, and ast_aoc_unit_entry::valid_type.

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

4893{
4894 struct ast_aoc_decoded *decoded = NULL;
4895 int hdrlen;
4896 int x;
4897 static const char hdr[] = "ChargedItem:";
4898 struct message sm = { 0 };
4899 int rates = 0;
4900
4901 if (!(decoded = ast_aoc_create(AST_AOC_S, 0, 0))) {
4902 astman_send_error(s, m, "Message Creation Failed");
4903 goto aocmessage_cleanup;
4904 }
4905
4906 hdrlen = strlen(hdr);
4907 for (x = 0; x < m->hdrcount; x++) {
4908 if (strncasecmp(hdr, m->headers[x], hdrlen) == 0) {
4909 if (rates > ast_aoc_s_get_count(decoded)) {
4910 if (action_aoc_s_submessage(s, &sm, decoded) == -1) {
4911 goto aocmessage_cleanup;
4912 }
4913 }
4914 ++rates;
4915 }
4916
4917 sm.headers[sm.hdrcount] = m->headers[x];
4918 ++sm.hdrcount;
4919 }
4920 if (rates > ast_aoc_s_get_count(decoded)) {
4921 if (action_aoc_s_submessage(s, &sm, decoded) == -1) {
4922 goto aocmessage_cleanup;
4923 }
4924 }
4925
4926 return decoded;
4927
4928aocmessage_cleanup:
4929
4930 ast_aoc_destroy_decoded(decoded);
4931 return NULL;
4932}
@ 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:765
static int action_aoc_s_submessage(struct mansession *s, const struct message *m, struct ast_aoc_decoded *decoded)
Definition: manager.c:4667

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

4669{
4670 const char *chargeditem = __astman_get_header(m, "ChargedItem", GET_HEADER_LAST_MATCH);
4671 const char *ratetype = __astman_get_header(m, "RateType", GET_HEADER_LAST_MATCH);
4672 const char *currencyname = __astman_get_header(m, "CurrencyName", GET_HEADER_LAST_MATCH);
4673 const char *currencyamount = __astman_get_header(m, "CurrencyAmount", GET_HEADER_LAST_MATCH);
4674 const char *mult = __astman_get_header(m, "CurrencyMultiplier", GET_HEADER_LAST_MATCH);
4675 const char *time = __astman_get_header(m, "Time", GET_HEADER_LAST_MATCH);
4676 const char *timescale = __astman_get_header(m, "TimeScale", GET_HEADER_LAST_MATCH);
4677 const char *granularity = __astman_get_header(m, "Granularity", GET_HEADER_LAST_MATCH);
4678 const char *granularitytimescale = __astman_get_header(m, "GranularityTimeScale", GET_HEADER_LAST_MATCH);
4679 const char *chargingtype = __astman_get_header(m, "ChargingType", GET_HEADER_LAST_MATCH);
4680 const char *volumeunit = __astman_get_header(m, "VolumeUnit", GET_HEADER_LAST_MATCH);
4681 const char *code = __astman_get_header(m, "Code", GET_HEADER_LAST_MATCH);
4682
4683 enum ast_aoc_s_charged_item _chargeditem;
4684 enum ast_aoc_s_rate_type _ratetype;
4686 unsigned int _currencyamount = 0;
4687 unsigned int _code;
4688 unsigned int _time = 0;
4689 enum ast_aoc_time_scale _scale = 0;
4690 unsigned int _granularity = 0;
4691 enum ast_aoc_time_scale _granularity_time_scale = AST_AOC_TIME_SCALE_MINUTE;
4692 int _step = 0;
4693 enum ast_aoc_volume_unit _volumeunit = 0;
4694
4695 if (ast_strlen_zero(chargeditem)) {
4696 astman_send_error(s, m, "ChargedItem not specified");
4697 goto aocmessage_cleanup;
4698 }
4699
4700 if (ast_strlen_zero(ratetype)) {
4701 astman_send_error(s, m, "RateType not specified");
4702 goto aocmessage_cleanup;
4703 }
4704
4705 if (!strcasecmp(chargeditem, "NA")) {
4706 _chargeditem = AST_AOC_CHARGED_ITEM_NA;
4707 } else if (!strcasecmp(chargeditem, "SpecialArrangement")) {
4709 } else if (!strcasecmp(chargeditem, "BasicCommunication")) {
4711 } else if (!strcasecmp(chargeditem, "CallAttempt")) {
4712 _chargeditem = AST_AOC_CHARGED_ITEM_CALL_ATTEMPT;
4713 } else if (!strcasecmp(chargeditem, "CallSetup")) {
4714 _chargeditem = AST_AOC_CHARGED_ITEM_CALL_SETUP;
4715 } else if (!strcasecmp(chargeditem, "UserUserInfo")) {
4717 } else if (!strcasecmp(chargeditem, "SupplementaryService")) {
4719 } else {
4720 astman_send_error(s, m, "Invalid ChargedItem");
4721 goto aocmessage_cleanup;
4722 }
4723
4724 if (!strcasecmp(ratetype, "NA")) {
4725 _ratetype = AST_AOC_RATE_TYPE_NA;
4726 } else if (!strcasecmp(ratetype, "Free")) {
4727 _ratetype = AST_AOC_RATE_TYPE_FREE;
4728 } else if (!strcasecmp(ratetype, "FreeFromBeginning")) {
4730 } else if (!strcasecmp(ratetype, "Duration")) {
4731 _ratetype = AST_AOC_RATE_TYPE_DURATION;
4732 } else if (!strcasecmp(ratetype, "Flat")) {
4733 _ratetype = AST_AOC_RATE_TYPE_FLAT;
4734 } else if (!strcasecmp(ratetype, "Volume")) {
4735 _ratetype = AST_AOC_RATE_TYPE_VOLUME;
4736 } else if (!strcasecmp(ratetype, "SpecialCode")) {
4738 } else {
4739 astman_send_error(s, m, "Invalid RateType");
4740 goto aocmessage_cleanup;
4741 }
4742
4743 if (_ratetype > AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING) {
4744 if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u",
4745 &_currencyamount) != 1)) {
4746 astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when RateType is non-free");
4747 goto aocmessage_cleanup;
4748 }
4749
4750 if (ast_strlen_zero(mult)) {
4751 astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
4752 goto aocmessage_cleanup;
4753 } else if (!strcasecmp(mult, "onethousandth")) {
4755 } else if (!strcasecmp(mult, "onehundredth")) {
4757 } else if (!strcasecmp(mult, "onetenth")) {
4758 _mult = AST_AOC_MULT_ONETENTH;
4759 } else if (!strcasecmp(mult, "one")) {
4760 _mult = AST_AOC_MULT_ONE;
4761 } else if (!strcasecmp(mult, "ten")) {
4762 _mult = AST_AOC_MULT_TEN;
4763 } else if (!strcasecmp(mult, "hundred")) {
4764 _mult = AST_AOC_MULT_HUNDRED;
4765 } else if (!strcasecmp(mult, "thousand")) {
4766 _mult = AST_AOC_MULT_THOUSAND;
4767 } else {
4768 astman_send_error(s, m, "Invalid ChargeMultiplier");
4769 goto aocmessage_cleanup;
4770 }
4771 }
4772
4773 if (_ratetype == AST_AOC_RATE_TYPE_DURATION) {
4774 if (ast_strlen_zero(timescale)) {
4775 astman_send_error(s, m, "TimeScale unspecified, TimeScale is required when RateType is Duration.");
4776 goto aocmessage_cleanup;
4777 } else if (!strcasecmp(timescale, "onehundredthsecond")) {
4779 } else if (!strcasecmp(timescale, "onetenthsecond")) {
4781 } else if (!strcasecmp(timescale, "second")) {
4783 } else if (!strcasecmp(timescale, "tenseconds")) {
4785 } else if (!strcasecmp(timescale, "minute")) {
4787 } else if (!strcasecmp(timescale, "hour")) {
4788 _scale = AST_AOC_TIME_SCALE_HOUR;
4789 } else if (!strcasecmp(timescale, "day")) {
4790 _scale = AST_AOC_TIME_SCALE_DAY;
4791 } else {
4792 astman_send_error(s, m, "Invalid TimeScale");
4793 goto aocmessage_cleanup;
4794 }
4795
4796 if (ast_strlen_zero(time) || (sscanf(time, "%30u", &_time) != 1)) {
4797 astman_send_error(s, m, "Invalid Time, Time is a required when RateType is Duration");
4798 goto aocmessage_cleanup;
4799 }
4800
4801 if (!ast_strlen_zero(granularity)) {
4802 if ((sscanf(time, "%30u", &_granularity) != 1)) {
4803 astman_send_error(s, m, "Invalid Granularity");
4804 goto aocmessage_cleanup;
4805 }
4806
4807 if (ast_strlen_zero(granularitytimescale)) {
4808 astman_send_error(s, m, "Invalid GranularityTimeScale, GranularityTimeScale is a required when Granularity is specified");
4809 } else if (!strcasecmp(granularitytimescale, "onehundredthsecond")) {
4810 _granularity_time_scale = AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
4811 } else if (!strcasecmp(granularitytimescale, "onetenthsecond")) {
4812 _granularity_time_scale = AST_AOC_TIME_SCALE_TENTH_SECOND;
4813 } else if (!strcasecmp(granularitytimescale, "second")) {
4814 _granularity_time_scale = AST_AOC_TIME_SCALE_SECOND;
4815 } else if (!strcasecmp(granularitytimescale, "tenseconds")) {
4816 _granularity_time_scale = AST_AOC_TIME_SCALE_TEN_SECOND;
4817 } else if (!strcasecmp(granularitytimescale, "minute")) {
4818 _granularity_time_scale = AST_AOC_TIME_SCALE_MINUTE;
4819 } else if (!strcasecmp(granularitytimescale, "hour")) {
4820 _granularity_time_scale = AST_AOC_TIME_SCALE_HOUR;
4821 } else if (!strcasecmp(granularitytimescale, "day")) {
4822 _granularity_time_scale = AST_AOC_TIME_SCALE_DAY;
4823 } else {
4824 astman_send_error(s, m, "Invalid GranularityTimeScale");
4825 goto aocmessage_cleanup;
4826 }
4827 }
4828
4829 if (ast_strlen_zero(chargingtype) || strcasecmp(chargingtype, "continuouscharging") == 0) {
4830 _step = 0;
4831 } else if (strcasecmp(chargingtype, "stepfunction") == 0 ) {
4832 _step = 1;
4833 } else {
4834 astman_send_error(s, m, "Invalid ChargingType");
4835 goto aocmessage_cleanup;
4836 }
4837 }
4838
4839 if (_ratetype == AST_AOC_RATE_TYPE_VOLUME) {
4840 if (ast_strlen_zero(volumeunit)) {
4841 astman_send_error(s, m, "VolumeUnit unspecified, VolumeUnit is required when RateType is Volume.");
4842 goto aocmessage_cleanup;
4843 } else if (!strcasecmp(timescale, "octet")) {
4844 _volumeunit = AST_AOC_VOLUME_UNIT_OCTET;
4845 } else if (!strcasecmp(timescale, "segment")) {
4846 _volumeunit = AST_AOC_VOLUME_UNIT_SEGMENT;
4847 } else if (!strcasecmp(timescale, "message")) {
4848 _volumeunit = AST_AOC_VOLUME_UNIT_MESSAGE;
4849 }else {
4850 astman_send_error(s, m, "Invalid VolumeUnit");
4851 goto aocmessage_cleanup;
4852 }
4853 }
4854
4856 || _ratetype == AST_AOC_RATE_TYPE_SPECIAL_CODE) {
4857 if (ast_strlen_zero(code) || (sscanf(code, "%30u", &_code) != 1)) {
4858 astman_send_error(s, m, "Invalid Code, Code is a required when ChargedItem is SpecialArrangement and when RateType is SpecialCode");
4859 goto aocmessage_cleanup;
4860 }
4861 }
4862
4863 if (_chargeditem == AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT) {
4864 ast_aoc_s_add_special_arrangement(decoded, _code);
4865 } else if (_ratetype == AST_AOC_RATE_TYPE_DURATION) {
4866 ast_aoc_s_add_rate_duration(decoded, _chargeditem, _currencyamount, _mult,
4867 currencyname, _time, _scale, _granularity, _granularity_time_scale, _step);
4868 } else if (_ratetype == AST_AOC_RATE_TYPE_FLAT) {
4869 ast_aoc_s_add_rate_flat(decoded, _chargeditem, _currencyamount, _mult,
4870 currencyname);
4871 } else if (_ratetype == AST_AOC_RATE_TYPE_VOLUME) {
4872 ast_aoc_s_add_rate_volume(decoded, _chargeditem, _volumeunit, _currencyamount,
4873 _mult, currencyname);
4874 } else if (_ratetype == AST_AOC_RATE_TYPE_SPECIAL_CODE) {
4875 ast_aoc_s_add_rate_special_charge_code(decoded, _chargeditem, _code);
4876 } else if (_ratetype == AST_AOC_RATE_TYPE_FREE) {
4877 ast_aoc_s_add_rate_free(decoded, _chargeditem, 0);
4878 } else if (_ratetype == AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING) {
4879 ast_aoc_s_add_rate_free(decoded, _chargeditem, 1);
4880 } else if (_ratetype == AST_AOC_RATE_TYPE_NA) {
4881 ast_aoc_s_add_rate_na(decoded, _chargeditem);
4882 }
4883
4884 return 0;
4885
4886aocmessage_cleanup:
4887
4888 return -1;
4889}
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:779
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:853
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:866
int ast_aoc_s_add_special_arrangement(struct ast_aoc_decoded *decoded, unsigned int code)
Add AOC-S special arrangement entry.
Definition: aoc.c:889
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:810
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:831
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:878
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:1606

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

4935{
4936 const char *msgtype = astman_get_header(m, "MsgType");
4937 const char *channel = astman_get_header(m, "Channel");
4938 const char *pchannel = astman_get_header(m, "ChannelPrefix");
4939
4940 struct ast_channel *chan = NULL;
4941
4942 struct ast_aoc_decoded *decoded = NULL;
4943 struct ast_aoc_encoded *encoded = NULL;
4944 size_t encoded_size = 0;
4945
4946 if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) {
4947 astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these.");
4948 goto aocmessage_cleanup;
4949 }
4950
4951 if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) {
4952 chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel));
4953 }
4954
4955 if (!chan) {
4956 astman_send_error(s, m, "No such channel");
4957 goto aocmessage_cleanup;
4958 }
4959
4960 if (strcasecmp(msgtype, "d") == 0 || strcasecmp(msgtype, "e") == 0) {
4961 decoded = action_aoc_de_message(s, m);
4962 }
4963 else if (strcasecmp(msgtype, "s") == 0) {
4964 decoded = action_aoc_s_message(s, m);
4965 }
4966 else {
4967 astman_send_error(s, m, "Invalid MsgType");
4968 goto aocmessage_cleanup;
4969 }
4970
4971 if (!decoded) {
4972 goto aocmessage_cleanup;
4973 }
4974
4975 if ((encoded = ast_aoc_encode(decoded, &encoded_size, chan))
4976 && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) {
4977 astman_send_ack(s, m, "AOC Message successfully queued on channel");
4978 } else {
4979 astman_send_error(s, m, "Error encoding AOC message, could not queue onto channel");
4980 }
4981
4982aocmessage_cleanup:
4983
4984 ast_aoc_destroy_decoded(decoded);
4985 ast_aoc_destroy_encoded(encoded);
4986
4987 if (chan) {
4988 chan = ast_channel_unref(chan);
4989 }
4990 return 0;
4991}
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:322
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:659
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:1380
struct ast_channel * ast_channel_get_by_name(const char *search)
Find a channel by name or uniqueid.
Definition: channel.c:1397
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:4608
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3008
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2014
static struct ast_aoc_decoded * action_aoc_s_message(struct mansession *s, const struct message *m)
Definition: manager.c:4891
static struct ast_aoc_decoded * action_aoc_de_message(struct mansession *s, const struct message *m)
Definition: manager.c:4496
@ 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 4144 of file manager.c.

4145{
4146 const char *name = astman_get_header(m, "Channel");
4147 const char *exten = astman_get_header(m, "Exten");
4148 const char *context = astman_get_header(m, "Context");
4149 struct ast_channel *chan = NULL;
4150 char feature_code[AST_FEATURE_MAX_LEN];
4151 const char *digit;
4152
4153 if (ast_strlen_zero(name)) {
4154 astman_send_error(s, m, "No channel specified");
4155 return 0;
4156 }
4157 if (ast_strlen_zero(exten)) {
4158 astman_send_error(s, m, "No extension specified");
4159 return 0;
4160 }
4161
4162 if (!(chan = ast_channel_get_by_name(name))) {
4163 astman_send_error(s, m, "Channel specified does not exist");
4164 return 0;
4165 }
4166
4167 ast_channel_lock(chan);
4168 if (ast_get_builtin_feature(chan, "atxfer", feature_code, sizeof(feature_code)) ||
4169 ast_strlen_zero(feature_code)) {
4170 ast_channel_unlock(chan);
4171 astman_send_error(s, m, "No attended transfer feature code found");
4172 ast_channel_unref(chan);
4173 return 0;
4174 }
4175 ast_channel_unlock(chan);
4176
4177 if (!ast_strlen_zero(context)) {
4178 pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context);
4179 }
4180
4181 for (digit = feature_code; *digit; ++digit) {
4182 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
4183 ast_queue_frame(chan, &f);
4184 }
4185
4186 for (digit = exten; *digit; ++digit) {
4187 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
4188 ast_queue_frame(chan, &f);
4189 }
4190
4191 chan = ast_channel_unref(chan);
4192
4193 astman_send_ack(s, m, "Atxfer successfully queued");
4194
4195 return 0;
4196}
char digit
#define ast_channel_lock(chan)
Definition: channel.h:2972
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:1169
#define ast_channel_unlock(chan)
Definition: channel.h:2973
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 4098 of file manager.c.

4099{
4100 const char *name = astman_get_header(m, "Channel");
4101 const char *exten = astman_get_header(m, "Exten");
4102 const char *context = astman_get_header(m, "Context");
4103 struct ast_channel *chan;
4104
4105 if (ast_strlen_zero(name)) {
4106 astman_send_error(s, m, "No channel specified");
4107 return 0;
4108 }
4109
4110 if (ast_strlen_zero(exten)) {
4111 astman_send_error(s, m, "No extension specified");
4112 return 0;
4113 }
4114
4116 if (!chan) {
4117 astman_send_error(s, m, "Channel specified does not exist");
4118 return 0;
4119 }
4120
4121 if (ast_strlen_zero(context)) {
4123 }
4124
4125 switch (ast_bridge_transfer_blind(1, chan, exten, context, NULL, NULL)) {
4127 astman_send_error(s, m, "Transfer not permitted");
4128 break;
4130 astman_send_error(s, m, "Transfer invalid");
4131 break;
4133 astman_send_error(s, m, "Transfer failed");
4134 break;
4136 astman_send_ack(s, m, "Transfer succeeded");
4137 break;
4138 }
4139
4140 ast_channel_unref(chan);
4141 return 0;
4142}
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:4494
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
Definition: bridge.h:1106
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1104
@ AST_BRIDGE_TRANSFER_INVALID
Definition: bridge.h:1108
@ AST_BRIDGE_TRANSFER_FAIL
Definition: bridge.h:1110
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 4198 of file manager.c.

4199{
4200 const char *name = astman_get_header(m, "Channel");
4201 struct ast_channel *chan = NULL;
4202 char *feature_code;
4203 const char *digit;
4204
4205 if (ast_strlen_zero(name)) {
4206 astman_send_error(s, m, "No channel specified");
4207 return 0;
4208 }
4209
4210 if (!(chan = ast_channel_get_by_name(name))) {
4211 astman_send_error(s, m, "Channel specified does not exist");
4212 return 0;
4213 }
4214
4215 ast_channel_lock(chan);
4216 feature_code = ast_get_chan_features_atxferabort(chan);
4217 ast_channel_unlock(chan);
4218
4219 if (!feature_code) {
4220 astman_send_error(s, m, "No disconnect feature code found");
4221 ast_channel_unref(chan);
4222 return 0;
4223 }
4224
4225 for (digit = feature_code; *digit; ++digit) {
4226 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
4227 ast_queue_frame(chan, &f);
4228 }
4229 ast_free(feature_code);
4230
4231 chan = ast_channel_unref(chan);
4232
4233 astman_send_ack(s, m, "CancelAtxfer successfully queued");
4234
4235 return 0;
4236}
#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 3403 of file manager.c.

3404{
3405 const char *authtype = astman_get_header(m, "AuthType");
3406
3407 if (!strcasecmp(authtype, "MD5")) {
3409 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
3410 }
3411 mansession_lock(s);
3412 astman_start_ack(s, m);
3413 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
3415 } else {
3416 astman_send_error(s, m, "Must specify AuthType");
3417 }
3418 return 0;
3419}
static void mansession_unlock(struct mansession *s)
Unlock the 'mansession' structure.
Definition: manager.c:2080
static void mansession_lock(struct mansession *s)
Lock the 'mansession' structure.
Definition: manager.c:2074
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2019
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1903
char challenge[10]
Definition: manager.c:290
struct mansession_session * session
Definition: manager.c:324
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 4275 of file manager.c.

4276{
4277 const char *cmd = astman_get_header(m, "Command");
4278 char *buf = NULL, *final_buf = NULL, *delim, *output;
4279 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */
4280 int fd, ret;
4281 off_t len;
4282
4283 if (ast_strlen_zero(cmd)) {
4284 astman_send_error(s, m, "No command provided");
4285 return 0;
4286 }
4287
4288 if (check_blacklist(cmd)) {
4289 astman_send_error(s, m, "Command blacklisted");
4290 return 0;
4291 }
4292
4293 if ((fd = mkstemp(template)) < 0) {
4294 astman_send_error_va(s, m, "Failed to create temporary file: %s", strerror(errno));
4295 return 0;
4296 }
4297
4298 ret = ast_cli_command(fd, cmd);
4299 astman_send_response_full(s, m, ret == RESULT_SUCCESS ? "Success" : "Error", MSG_MOREDATA, NULL);
4300
4301 /* Determine number of characters available */
4302 if ((len = lseek(fd, 0, SEEK_END)) < 0) {
4303 astman_append(s, "Message: Failed to determine number of characters: %s\r\n", strerror(errno));
4304 goto action_command_cleanup;
4305 }
4306
4307 /* This has a potential to overflow the stack. Hence, use the heap. */
4308 buf = ast_malloc(len + 1);
4309 final_buf = ast_malloc(len + 1);
4310
4311 if (!buf || !final_buf) {
4312 astman_append(s, "Message: Memory allocation failure\r\n");
4313 goto action_command_cleanup;
4314 }
4315
4316 if (lseek(fd, 0, SEEK_SET) < 0) {
4317 astman_append(s, "Message: Failed to set position on temporary file: %s\r\n", strerror(errno));
4318 goto action_command_cleanup;
4319 }
4320
4321 if (read(fd, buf, len) < 0) {
4322 astman_append(s, "Message: Failed to read from temporary file: %s\r\n", strerror(errno));
4323 goto action_command_cleanup;
4324 }
4325
4326 buf[len] = '\0';
4327 term_strip(final_buf, buf, len);
4328 final_buf[len] = '\0';
4329
4330 /* Trim trailing newline */
4331 if (len && final_buf[len - 1] == '\n') {
4332 final_buf[len - 1] = '\0';
4333 }
4334
4335 astman_append(s, "Message: Command output follows\r\n");
4336
4337 delim = final_buf;
4338 while ((output = strsep(&delim, "\n"))) {
4339 astman_append(s, "Output: %s\r\n", output);
4340 }
4341
4342action_command_cleanup:
4343 astman_append(s, "\r\n");
4344
4345 close(fd);
4346 unlink(template);
4347
4348 ast_free(buf);
4349 ast_free(final_buf);
4350
4351 return 0;
4352}
char * strsep(char **str, const char *delims)
#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:1987
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:1946
static int check_blacklist(const char *cmd)
Definition: manager.c:4239
#define MSG_MOREDATA
Definition: manager.c:1937
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 6459 of file manager.c.

6460{
6461 const char *actionid = astman_get_header(m, "ActionID");
6462 char idText[150];
6463
6464 if (!ast_strlen_zero(actionid)) {
6465 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6466 } else {
6467 idText[0] = '\0';
6468 }
6469
6470 astman_append(s, "Response: Success\r\n"
6471 "%s"
6472 "AMIversion: %s\r\n"
6473 "AsteriskVersion: %s\r\n"
6474 "SystemName: %s\r\n"
6475 "CoreMaxCalls: %d\r\n"
6476 "CoreMaxLoadAvg: %f\r\n"
6477 "CoreRunUser: %s\r\n"
6478 "CoreRunGroup: %s\r\n"
6479 "CoreMaxFilehandles: %d\r\n"
6480 "CoreRealTimeEnabled: %s\r\n"
6481 "CoreCDRenabled: %s\r\n"
6482 "CoreHTTPenabled: %s\r\n"
6483 "SoundsSearchCustomDir: %s\r\n"
6484 "\r\n",
6485 idText,
6498 );
6499 return 0;
6500}
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:2981
#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:685
int ast_option_maxfiles
Definition: options.c:82
int ast_option_maxcalls
Definition: options.c:80
double ast_option_maxload
Definition: options.c:78
int ast_realtime_enabled(void)
Check if there's any realtime engines loaded.
Definition: main/config.c:3764
#define AMI_VERSION
Definition: manager.h:57
#define ast_opt_sounds_search_custom
Definition: options.h:139
const char * ast_config_AST_RUN_GROUP
Definition: options.c:170
const char * ast_config_AST_RUN_USER
Definition: options.c:169

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

6746{
6747 const char *actionid = astman_get_header(m, "ActionID");
6748 const char *channel_name = astman_get_header(m, "Channel");
6749 char *current_channel_name;
6750 char id_text[256];
6751 int total = 0;
6752 struct ao2_container *channel_map;
6753 struct ao2_iterator i;
6754 RAII_VAR(struct ast_bridge_snapshot *, bridge_snapshot, NULL, ao2_cleanup);
6755 RAII_VAR(struct ast_channel_snapshot *, channel_snapshot, NULL, ao2_cleanup);
6756
6757 if (!ast_strlen_zero(actionid)) {
6758 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
6759 } else {
6760 id_text[0] = '\0';
6761 }
6762
6763 if (ast_strlen_zero(channel_name)) {
6764 astman_send_error(s, m, "CoreShowChannelMap requires a channel.\n");
6765 return 0;
6766 }
6767
6768 channel_snapshot = ast_channel_snapshot_get_latest_by_name(channel_name);
6769 if (!channel_snapshot) {
6770 astman_send_error(s, m, "Could not get channel snapshot\n");
6771 return 0;
6772 }
6773
6774 if (ast_strlen_zero(channel_snapshot->bridge->id)) {
6775 astman_send_listack(s, m, "Channel map will follow", "start");
6776 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", 0);
6778 return 0;
6779 }
6780
6781 bridge_snapshot = ast_bridge_get_snapshot_by_uniqueid(channel_snapshot->bridge->id);
6782 if (!bridge_snapshot) {
6783 astman_send_listack(s, m, "Channel map will follow", "start");
6784 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", 0);
6786 return 0;
6787 }
6788
6790 if (!channel_map) {
6791 astman_send_error(s, m, "Could not create channel map\n");
6792 return 0;
6793 }
6794
6795 astman_send_listack(s, m, "Channel map will follow", "start");
6796
6797 if (coreshowchannelmap_add_connected_channels(channel_map, channel_snapshot, bridge_snapshot)) {
6798 astman_send_error(s, m, "Could not complete channel map\n");
6799 ao2_ref(channel_map, -1);
6800 return 0;
6801 }
6802
6803 i = ao2_iterator_init(channel_map, 0);
6804 while ((current_channel_name = ao2_iterator_next(&i))) {
6805 astman_append(s,
6806 "Event: CoreShowChannelMap\r\n"
6807 "%s"
6808 "Channel: %s\r\n"
6809 "ConnectedChannel: %s\r\n\r\n",
6810 id_text,
6811 channel_name,
6812 current_channel_name);
6813 total++;
6814 }
6816
6817 ao2_ref(channel_map, -1);
6818 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", total);
6820
6821 return 0;
6822}
@ 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:2024
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:2060
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:6661
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2068
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:318
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:947

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

6578{
6579 const char *actionid = astman_get_header(m, "ActionID");
6580 char idText[256];
6581 int numchans = 0;
6582 struct ao2_container *channels;
6583 struct ao2_iterator it_chans;
6584 struct ast_channel_snapshot *cs;
6585
6586 if (!ast_strlen_zero(actionid)) {
6587 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6588 } else {
6589 idText[0] = '\0';
6590 }
6591
6593
6594 astman_send_listack(s, m, "Channels will follow", "start");
6595
6596 it_chans = ao2_iterator_init(channels, 0);
6597 for (; (cs = ao2_iterator_next(&it_chans)); ao2_ref(cs, -1)) {
6599 char durbuf[16] = "";
6600
6601 if (!built) {
6602 continue;
6603 }
6604
6605 if (!ast_tvzero(cs->base->creationtime)) {
6606 int duration, durh, durm, durs;
6607
6608 duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->base->creationtime) / 1000);
6609 durh = duration / 3600;
6610 durm = (duration % 3600) / 60;
6611 durs = duration % 60;
6612 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
6613 }
6614
6615 astman_append(s,
6616 "Event: CoreShowChannel\r\n"
6617 "%s"
6618 "%s"
6619 "Application: %s\r\n"
6620 "ApplicationData: %s\r\n"
6621 "Duration: %s\r\n"
6622 "BridgeId: %s\r\n"
6623 "\r\n",
6624 idText,
6625 ast_str_buffer(built),
6626 cs->dialplan->appl,
6627 cs->dialplan->data,
6628 durbuf,
6629 cs->bridge->id);
6630
6631 numchans++;
6632
6633 ast_free(built);
6634 }
6635 ao2_iterator_destroy(&it_chans);
6636
6637 astman_send_list_complete(s, m, "CoreShowChannelsComplete", numchans);
6638
6639 ao2_ref(channels, -1);
6640 return 0;
6641}
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:2051
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 6503 of file manager.c.

6504{
6505 const char *actionid = astman_get_header(m, "ActionID");
6506 char idText[150];
6507 char startuptime[150], startupdate[150];
6508 char reloadtime[150], reloaddate[150];
6509 struct ast_tm tm;
6510
6511 if (!ast_strlen_zero(actionid)) {
6512 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6513 } else {
6514 idText[0] = '\0';
6515 }
6516
6518 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
6519 ast_strftime(startupdate, sizeof(startupdate), "%Y-%m-%d", &tm);
6521 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
6522 ast_strftime(reloaddate, sizeof(reloaddate), "%Y-%m-%d", &tm);
6523
6524 astman_append(s, "Response: Success\r\n"
6525 "%s"
6526 "CoreStartupDate: %s\r\n"
6527 "CoreStartupTime: %s\r\n"
6528 "CoreReloadDate: %s\r\n"
6529 "CoreReloadTime: %s\r\n"
6530 "CoreCurrentCalls: %d\r\n"
6531 "CoreProcessedCalls: %d\r\n"
6532 "\r\n",
6533 idText,
6534 startupdate,
6535 startuptime,
6536 reloaddate,
6537 reloadtime,
6540 );
6541 return 0;
6542}
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:498
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:344
struct timeval ast_startuptime
Definition: asterisk.c:343
int ast_processed_calls(void)
Retrieve the total number of calls processed through the PBX since last restart.
Definition: pbx.c:4780

References ast_active_channels(), ast_lastreloadtime, ast_localtime(), ast_processed_calls(), 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 3093 of file manager.c.

3094{
3095 int fd;
3096 const char *fn = astman_get_header(m, "Filename");
3097 char *stripped_filename;
3098 RAII_VAR(char *, filepath, NULL, ast_free);
3099 RAII_VAR(char *, real_dir, NULL, ast_std_free);
3100 RAII_VAR(char *, real_path, NULL, ast_free);
3101 char *filename;
3102
3103 if (ast_strlen_zero(fn)) {
3104 astman_send_error(s, m, "Filename not specified");
3105 return 0;
3106 }
3107
3108 stripped_filename = ast_strip(ast_strdupa(fn));
3109
3110 /* If the file name is relative, prepend ast_config_AST_CONFIG_DIR */
3111 if (stripped_filename[0] != '/') {
3112 if (ast_asprintf(&filepath, "%s/%s", ast_config_AST_CONFIG_DIR, stripped_filename) == -1) {
3113 return -1;
3114 }
3115 } else {
3116 filepath = ast_strdup(stripped_filename);
3117 }
3118
3119 /*
3120 * We can't call is_restricted_file() here because it uses realpath() and...
3121 *
3122 * realpath() and other functions that canonicalize paths won't work with
3123 * a filename that doesn't exist, so we need to separate the directory
3124 * from the filename and canonicalize the directory first. We have to do
3125 * the separation manually because dirname() and basename() aren't all
3126 * that friendly to multi-threaded programs and there are different
3127 * versions of basename for glibc and POSIX.
3128 */
3129
3130 filename = strrchr(filepath, '/');
3131 if (!filename) {
3132 astman_send_error(s, m, "Filename is invalid");
3133 return 0;
3134 }
3135 *filename = '\0';
3136 filename++;
3137
3138 /* filepath just has the directory now so canonicalize it. */
3139 real_dir = realpath(filepath, NULL);
3140 if (ast_strlen_zero(real_dir)) {
3141 astman_send_error(s, m, strerror(errno));
3142 return 0;
3143 }
3144
3145 /* Check if the directory is restricted. */
3147 astman_send_error(s, m, "File requires escalated privileges");
3148 return 0;
3149 }
3150
3151 /* Create the final file path. */
3152 if (ast_asprintf(&real_path, "%s/%s", real_dir, filename) == -1) {
3153 astman_send_error(s, m, strerror(errno));
3154 return -1;
3155 }
3156
3157 if ((fd = open(real_path, O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
3158 close(fd);
3159 astman_send_ack(s, m, "New configuration file created successfully");
3160 } else {
3161 astman_send_error(s, m, strerror(errno));
3162 }
3163
3164 return 0;
3165}
#define AST_FILE_MODE
Definition: asterisk.h:32
void ast_std_free(void *ptr)
Definition: astmm.c:1734
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
static int live_dangerously
Set to true (non-zero) to globally allow all dangerous AMI actions to run.
Definition: manager.c:196
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:152
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
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223

References ast_asprintf, ast_begins_with(), ast_config_AST_CONFIG_DIR, AST_FILE_MODE, ast_free, ast_std_free(), ast_strdup, ast_strdupa, ast_strip(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), errno, live_dangerously, NULL, and RAII_VAR.

Referenced by __init_manager().

◆ action_destroy()

static void action_destroy ( void *  obj)
static

Definition at line 7807 of file manager.c.

7808{
7809 struct manager_action *doomed = obj;
7810
7811 if (doomed->synopsis) {
7812 /* The string fields were initialized. */
7814 }
7815 ao2_cleanup(doomed->final_response);
7816 ao2_cleanup(doomed->list_responses);
7817}
#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 3304 of file manager.c.

3305{
3306 const char *mask = astman_get_header(m, "EventMask");
3307 int res, x;
3308 const char *id = astman_get_header(m, "ActionID");
3309 char id_text[256];
3310
3311 if (!ast_strlen_zero(id)) {
3312 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
3313 } else {
3314 id_text[0] = '\0';
3315 }
3316
3317 res = set_eventmask(s, mask);
3319 /* if this option is set we should not return a response on
3320 * error, or when all events are set */
3321
3322 if (res > 0) {
3323 for (x = 0; x < ARRAY_LEN(perms); x++) {
3324 if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) {
3325 return 0;
3326 }
3327 }
3328 astman_append(s, "Response: Success\r\n%s"
3329 "Events: On\r\n\r\n", id_text);
3330 } else if (res == 0)
3331 astman_append(s, "Response: Success\r\n%s"
3332 "Events: Off\r\n\r\n", id_text);
3333 return 0;
3334 }
3335
3336 if (res > 0)
3337 astman_append(s, "Response: Success\r\n%s"
3338 "Events: On\r\n\r\n", id_text);
3339 else if (res == 0)
3340 astman_append(s, "Response: Success\r\n%s"
3341 "Events: Off\r\n\r\n", id_text);
3342 else
3343 astman_send_error(s, m, "Invalid event mask");
3344
3345 return 0;
3346}
static int broken_events_action
Definition: manager.c:165
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:2089
static const struct permalias perms[]
int num
Definition: manager.c:747
#define ARRAY_LEN(a)
Definition: utils.h:672

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

5461{
5462 const char *exten = astman_get_header(m, "Exten");
5463 const char *context = astman_get_header(m, "Context");
5464 char hint[256];
5465 int status;
5466
5467 if (ast_strlen_zero(exten)) {
5468 astman_send_error(s, m, "Extension not specified");
5469 return 0;
5470 }
5471 if (ast_strlen_zero(context)) {
5472 context = "default";
5473 }
5475 hint[0] = '\0';
5476 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
5477 astman_start_ack(s, m);
5478 astman_append(s, "Message: Extension Status\r\n"
5479 "Exten: %s\r\n"
5480 "Context: %s\r\n"
5481 "Hint: %s\r\n"
5482 "Status: %d\r\n"
5483 "StatusText: %s\r\n"
5484 "\r\n",
5485 exten, context, hint, status,
5487 return 0;
5488}
jack_status_t status
Definition: app_jack.c:149
const char * ast_extension_state2str(int extension_state)
Return string representation of the state of an extension.
Definition: pbx.c:3141
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:4152
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:3185

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

5683{
5684 const char *match_criteria = astman_get_header(m, "MatchCriteria");
5685 const char *filter = astman_get_header(m, "Filter");
5686 const char *operation = astman_get_header(m, "Operation");
5687 int res;
5688
5689 if (!strcasecmp(operation, "Add")) {
5690 char *criteria;
5691 int have_match = !ast_strlen_zero(match_criteria);
5692
5693 /* Create an eventfilter expression.
5694 * eventfilter[(match_criteria)]
5695 */
5696 res = ast_asprintf(&criteria, "eventfilter%s%s%s",
5697 S_COR(have_match, "(", ""), S_OR(match_criteria, ""),
5698 S_COR(have_match, ")", ""));
5699 if (res <= 0) {
5700 astman_send_error(s, m, "Internal Error. Failed to allocate storage for filter type");
5701 return 0;
5702 }
5703
5705 ast_std_free(criteria);
5706 if (res != FILTER_SUCCESS) {
5707 if (res == FILTER_ALLOC_FAILED) {
5708 astman_send_error(s, m, "Internal Error. Failed to allocate regex for filter");
5709 return 0;
5710 } else if (res == FILTER_COMPILE_FAIL) {
5711 astman_send_error(s, m,
5712 "Filter did not compile. Check the syntax of the filter given.");
5713 return 0;
5714 } else if (res == FILTER_FORMAT_ERROR) {
5715 astman_send_error(s, m,
5716 "Filter was formatted incorrectly. Check the syntax of the filter given.");
5717 return 0;
5718 } else {
5719 astman_send_error(s, m, "Internal Error. Failed adding filter.");
5720 return 0;
5721 }
5722 }
5723
5724 astman_send_ack(s, m, "Success");
5725 return 0;
5726 }
5727
5728 astman_send_error(s, m, "Unknown operation");
5729 return 0;
5730}
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:899
static enum add_filter_result manager_add_filter(const char *criteria, const char *filter_pattern, struct ao2_container *includefilters, struct ao2_container *excludefilters)
Add an event filter to a manager session.
Definition: manager.c:5749
#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
#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
struct ao2_container * excludefilters
Definition: manager.c:297
struct ao2_container * includefilters
Definition: manager.c:296

References ast_asprintf, ast_std_free(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), mansession_session::excludefilters, filter(), FILTER_ALLOC_FAILED, FILTER_COMPILE_FAIL, FILTER_FORMAT_ERROR, FILTER_SUCCESS, mansession_session::includefilters, manager_add_filter(), S_COR, S_OR, and mansession::session.

Referenced by __init_manager().

◆ action_find()

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

Definition at line 434 of file manager.c.

435{
436 struct manager_action *act;
437
439 AST_RWLIST_TRAVERSE(&actions, act, list) {
440 if (!strcasecmp(name, act->action)) {
441 ao2_t_ref(act, +1, "found action object");
442 break;
443 }
444 }
446
447 return act;
448}
#define ao2_t_ref(o, delta, tag)
Definition: astobj2.h:460
list of actions registered
Definition: manager.c:363
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 2497 of file manager.c.

2498{
2499 struct ast_config *cfg;
2500 const char *fn = astman_get_header(m, "Filename");
2501 const char *category = astman_get_header(m, "Category");
2502 const char *filter = astman_get_header(m, "Filter");
2503 const char *category_name;
2504 int catcount = 0;
2505 int lineno = 0;
2506 int ret = 0;
2507 struct ast_category *cur_category = NULL;
2508 struct ast_variable *v;
2509 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2510
2511 if (ast_strlen_zero(fn)) {
2512 astman_send_error(s, m, "Filename not specified");
2513 return 0;
2514 }
2515
2516 ret = is_restricted_file(fn);
2517 if (ret == 1) {
2518 astman_send_error(s, m, "File requires escalated privileges");
2519 return 0;
2520 } else if (ret == -1) {
2521 astman_send_error(s, m, "Config file not found");
2522 return 0;
2523 }
2524
2525 cfg = ast_config_load2(fn, "manager", config_flags);
2526 if (cfg == CONFIG_STATUS_FILEMISSING) {
2527 astman_send_error(s, m, "Config file not found");
2528 return 0;
2529 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2530 astman_send_error(s, m, "Config file has invalid format");
2531 return 0;
2532 }
2533
2534 astman_start_ack(s, m);
2535 while ((cur_category = ast_category_browse_filtered(cfg, category, cur_category, filter))) {
2536 struct ast_str *templates;
2537
2538 category_name = ast_category_get_name(cur_category);
2539 lineno = 0;
2540 astman_append(s, "Category-%06d: %s\r\n", catcount, category_name);
2541
2542 if (ast_category_is_template(cur_category)) {
2543 astman_append(s, "IsTemplate-%06d: %d\r\n", catcount, 1);
2544 }
2545
2546 if ((templates = ast_category_get_templates(cur_category))
2547 && ast_str_strlen(templates) > 0) {
2548 astman_append(s, "Templates-%06d: %s\r\n", catcount, ast_str_buffer(templates));
2550 }
2551
2552 for (v = ast_category_first(cur_category); v; v = v->next) {
2553 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
2554 }
2555
2556 catcount++;
2557 }
2558
2559 if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
2560 astman_append(s, "No categories found\r\n");
2561 }
2562
2563 ast_config_destroy(cfg);
2564 astman_append(s, "\r\n");
2565
2566 return 0;
2567}
static int is_restricted_file(const char *filename)
Check if a file is restricted or not.
Definition: manager.c:2464
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1211
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:3541
#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:1221
#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:1216
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1358
@ 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:1536
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(), is_restricted_file(), ast_variable::name, ast_variable::next, NULL, 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 2645 of file manager.c.

2646{
2647 struct ast_config *cfg;
2648 const char *fn = astman_get_header(m, "Filename");
2649 const char *filter = astman_get_header(m, "Filter");
2650 const char *category = astman_get_header(m, "Category");
2651 struct ast_category *cur_category = NULL;
2652 const char *category_name;
2653 struct ast_variable *v;
2654 int comma1 = 0;
2655 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2656
2657 if (ast_strlen_zero(fn)) {
2658 astman_send_error(s, m, "Filename not specified");
2659 return 0;
2660 }
2661
2662 if (is_restricted_file(fn)) {
2663 astman_send_error(s, m, "File requires escalated privileges");
2664 return 0;
2665 }
2666
2667 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
2668 astman_send_error(s, m, "Config file not found");
2669 return 0;
2670 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2671 astman_send_error(s, m, "Config file has invalid format");
2672 return 0;
2673 }
2674
2675 astman_start_ack(s, m);
2676 astman_append(s, "JSON: {");
2677 while ((cur_category = ast_category_browse_filtered(cfg, category, cur_category, filter))) {
2678 int comma2 = 0;
2679 struct ast_str *templates;
2680
2681 category_name = ast_category_get_name(cur_category);
2682 astman_append(s, "%s\"", comma1 ? "," : "");
2683 astman_append_json(s, category_name);
2684 astman_append(s, "\":{");
2685 comma1 = 1;
2686
2687 if (ast_category_is_template(cur_category)) {
2688 astman_append(s, "\"istemplate\":1");
2689 comma2 = 1;
2690 }
2691
2692 if ((templates = ast_category_get_templates(cur_category))
2693 && ast_str_strlen(templates) > 0) {
2694 astman_append(s, "%s", comma2 ? "," : "");
2695 astman_append(s, "\"templates\":\"%s\"", ast_str_buffer(templates));
2697 comma2 = 1;
2698 }
2699
2700 for (v = ast_category_first(cur_category); v; v = v->next) {
2701 astman_append(s, "%s\"", comma2 ? "," : "");
2702 astman_append_json(s, v->name);
2703 astman_append(s, "\":\"");
2705 astman_append(s, "\"");
2706 comma2 = 1;
2707 }
2708
2709 astman_append(s, "}");
2710 }
2711 astman_append(s, "}\r\n\r\n");
2712
2713 ast_config_destroy(cfg);
2714
2715 return 0;
2716}
static void astman_append_json(struct mansession *s, const char *str)
Definition: manager.c:2636

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(), is_restricted_file(), ast_variable::name, ast_variable::next, NULL, 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 3581 of file manager.c.

3582{
3583 struct ast_channel *c = NULL;
3584 const char *name = astman_get_header(m, "Channel");
3585 const char *varname = astman_get_header(m, "Variable");
3586 char *varval;
3587 char workspace[1024];
3588
3589 if (ast_strlen_zero(varname)) {
3590 astman_send_error(s, m, "No variable specified");
3591 return 0;
3592 }
3593
3594 /* We don't want users with insufficient permissions using certain functions. */
3596 astman_send_error(s, m, "GetVar Access Forbidden: Variable");
3597 return 0;
3598 }
3599
3600 if (!ast_strlen_zero(name)) {
3601 if (!(c = ast_channel_get_by_name(name))) {
3602 astman_send_error(s, m, "No such channel");
3603 return 0;
3604 }
3605 }
3606
3607 workspace[0] = '\0';
3608 if (varname[strlen(varname) - 1] == ')') {
3609 if (!c) {
3611 if (c) {
3612 ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
3613 } else
3614 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n");
3615 } else {
3616 ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
3617 }
3618 varval = workspace;
3619 } else {
3620 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
3621 }
3622
3623 if (c) {
3625 }
3626
3627 astman_start_ack(s, m);
3628 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, S_OR(varval, ""));
3629
3630 return 0;
3631}
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1328
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:777
#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.
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 3542 of file manager.c.

3543{
3544 return ast_manager_hangup_helper(s, m,
3546}
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:467
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:3421

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

2570{
2571 struct ast_config *cfg;
2572 const char *fn = astman_get_header(m, "Filename");
2573 const char *match = astman_get_header(m, "Match");
2574 struct ast_category *category = NULL;
2575 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2576 int catcount = 0;
2577 int ret = 0;
2578
2579 if (ast_strlen_zero(fn)) {
2580 astman_send_error(s, m, "Filename not specified");
2581 return 0;
2582 }
2583
2584 ret = is_restricted_file(fn);
2585 if (ret == 1) {
2586 astman_send_error(s, m, "File requires escalated privileges");
2587 return 0;
2588 } else if (ret == -1) {
2589 astman_send_error(s, m, "Config file not found");
2590 return 0;
2591 }
2592
2593 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
2594 astman_send_error(s, m, "Config file not found");
2595 return 0;
2596 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2597 astman_send_error(s, m, "Config file has invalid format");
2598 return 0;
2599 }
2600
2601 astman_start_ack(s, m);
2602 while ((category = ast_category_browse_filtered(cfg, NULL, category, match))) {
2603 astman_append(s, "Category-%06d: %s\r\n", catcount, ast_category_get_name(category));
2604 catcount++;
2605 }
2606
2607 if (catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
2608 astman_append(s, "Error: no categories found\r\n");
2609 }
2610
2611 ast_config_destroy(cfg);
2612 astman_append(s, "\r\n");
2613
2614 return 0;
2615}
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:2388

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, is_restricted_file(), match(), and NULL.

Referenced by __init_manager().

◆ action_listcommands()

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

Definition at line 3285 of file manager.c.

3286{
3287 struct manager_action *cur;
3289
3290 astman_start_ack(s, m);
3292 AST_RWLIST_TRAVERSE(&actions, cur, list) {
3293 if ((s->session->writeperm & cur->authority) || cur->authority == 0) {
3294 astman_append(s, "%s: %s (Priv: %s)\r\n",
3295 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
3296 }
3297 }
3299 astman_append(s, "\r\n");
3300
3301 return 0;
3302}

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

6827{
6828 if (ast_logger_rotate()) {
6829 astman_send_error(s, m, "Failed to reload the logger and rotate log files");
6830 return 0;
6831 }
6832
6833 astman_send_ack(s, m, "Reloaded the logger and rotated log files");
6834 return 0;
6835}
int ast_logger_rotate(void)
Reload logger while rotating log files.
Definition: logger.c:1312

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

3355{
3356
3357 /* still authenticated - don't process again */
3358 if (s->session->authenticated) {
3359 astman_send_ack(s, m, "Already authenticated");
3360 return 0;
3361 }
3362
3363 if (authenticate(s, m)) {
3364 sleep(1);
3365 astman_send_error(s, m, "Authentication failed");
3366 return -1;
3367 }
3368 s->session->authenticated = 1;
3371 ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_sockaddr_stringify_addr(&s->session->addr));
3372 }
3373 astman_send_ack(s, m, "Authentication accepted");
3378 const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
3379 long uptime = 0;
3380 long lastreloaded = 0;
3381 struct timeval tmp;
3382 struct timeval curtime = ast_tvnow();
3383
3384 if (ast_startuptime.tv_sec) {
3385 tmp = ast_tvsub(curtime, ast_startuptime);
3386 uptime = tmp.tv_sec;
3387 }
3388
3389 if (ast_lastreloadtime.tv_sec) {
3390 tmp = ast_tvsub(curtime, ast_lastreloadtime);
3391 lastreloaded = tmp.tv_sec;
3392 }
3393
3394 astman_append(s, "Event: FullyBooted\r\n"
3395 "Privilege: %s\r\n"
3396 "Uptime: %ld\r\n"
3397 "LastReload: %ld\r\n"
3398 "Status: Fully Booted\r\n\r\n", cat_str, uptime, lastreloaded);
3399 }
3400 return 0;
3401}
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:1059
static int unauth_sessions
Definition: manager.c:178
static int authenticate(struct mansession *s, const struct message *m)
Definition: manager.c:2328
struct ast_flags ast_options
Definition: options.c:62
@ AST_OPT_FLAG_FULLY_BOOTED
Definition: options.h:59
#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:280
uint32_t managerid
Definition: manager.c:285
char username[80]
Definition: manager.c:289
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, 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 3348 of file manager.c.

3349{
3350 astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
3351 return -1;
3352}
void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg)
Send response in manager transaction.
Definition: manager.c:1977

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

5440{
5441 const char *mailbox = astman_get_header(m, "Mailbox");
5442 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;;
5443
5444 if (ast_strlen_zero(mailbox)) {
5445 astman_send_error(s, m, "Mailbox not specified");
5446 return 0;
5447 }
5448 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs);
5449 astman_start_ack(s, m);
5450 astman_append(s, "Message: Mailbox Message Count\r\n"
5451 "Mailbox: %s\r\n"
5452 "UrgMessages: %d\r\n"
5453 "NewMessages: %d\r\n"
5454 "OldMessages: %d\r\n"
5455 "\r\n",
5456 mailbox, urgentmsgs, newmsgs, oldmsgs);
5457 return 0;
5458}
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 5422 of file manager.c.

5423{
5424 const char *mailbox = astman_get_header(m, "Mailbox");
5425 int ret;
5426
5427 if (ast_strlen_zero(mailbox)) {
5428 astman_send_error(s, m, "Mailbox not specified");
5429 return 0;
5430 }
5432 astman_start_ack(s, m);
5433 astman_append(s, "Message: Mailbox Status\r\n"
5434 "Mailbox: %s\r\n"
5435 "Waiting: %d\r\n\r\n", mailbox, ret);
5436 return 0;
5437}
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 5227 of file manager.c.

5228{
5229 const char *name = astman_get_header(m, "Channel");
5230 const char *exten = astman_get_header(m, "Exten");
5231 const char *context = astman_get_header(m, "Context");
5232 const char *priority = astman_get_header(m, "Priority");
5233 const char *timeout = astman_get_header(m, "Timeout");
5234 const char *callerid = astman_get_header(m, "CallerID");
5235 const char *account = astman_get_header(m, "Account");
5236 const char *app = astman_get_header(m, "Application");
5237 const char *appdata = astman_get_header(m, "Data");
5238 const char *async = astman_get_header(m, "Async");
5239 const char *id = astman_get_header(m, "ActionID");
5240 const char *codecs = astman_get_header(m, "Codecs");
5241 const char *early_media = astman_get_header(m, "Earlymedia");
5242 struct ast_assigned_ids assignedids = {
5243 .uniqueid = astman_get_header(m, "ChannelId"),
5244 .uniqueid2 = astman_get_header(m, "OtherChannelId"),
5245 };
5246 const char *gosub = astman_get_header(m, "PreDialGoSub");
5247
5248 struct ast_variable *vars = NULL;
5249 char *tech, *data;
5250 char *l = NULL, *n = NULL;
5251 int pi = 0;
5252 int res;
5253 int to = 30000;
5254 int reason = 0;
5255 char tmp[256];
5256 char tmp2[256];
5258 pthread_t th;
5259 int bridge_early = 0;
5260
5261 if (!cap) {
5262 astman_send_error(s, m, "Internal Error. Memory allocation failure.");
5263 return 0;
5264 }
5266
5267 if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid))
5268 || (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) {
5269 astman_send_error_va(s, m, "Uniqueid length exceeds maximum of %d\n",
5271 res = 0;
5272 goto fast_orig_cleanup;
5273 }
5274
5275 if (ast_strlen_zero(name)) {
5276 astman_send_error(s, m, "Channel not specified");
5277 res = 0;
5278 goto fast_orig_cleanup;
5279 }
5280 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
5281 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
5282 astman_send_error(s, m, "Invalid priority");
5283 res = 0;
5284 goto fast_orig_cleanup;
5285 }
5286 }
5287 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
5288 astman_send_error(s, m, "Invalid timeout");
5289 res = 0;
5290 goto fast_orig_cleanup;
5291 }
5292 ast_copy_string(tmp, name, sizeof(tmp));
5293 tech = tmp;
5294 data = strchr(tmp, '/');
5295 if (!data) {
5296 astman_send_error(s, m, "Invalid channel");
5297 res = 0;
5298 goto fast_orig_cleanup;
5299 }
5300 *data++ = '\0';
5301 ast_copy_string(tmp2, callerid, sizeof(tmp2));
5302 ast_callerid_parse(tmp2, &n, &l);
5303 if (n) {
5304 if (ast_strlen_zero(n)) {
5305 n = NULL;
5306 }
5307 }
5308 if (l) {
5310 if (ast_strlen_zero(l)) {
5311 l = NULL;
5312 }
5313 }
5314 if (!ast_strlen_zero(codecs)) {
5317 }
5318
5319 if (!ast_strlen_zero(app) && s->session) {
5320 if (!is_originate_app_permitted(app, appdata, s->session->writeperm)) {
5321 astman_send_error(s, m, "Originate Access Forbidden: app or data blacklisted");
5322 res = 0;
5323 goto fast_orig_cleanup;
5324 }
5325 }
5326
5327 /* Check early if the extension exists. If not, we need to bail out here. */
5328 if (exten && context && pi) {
5329 if (! ast_exists_extension(NULL, context, exten, pi, l)) {
5330 /* The extension does not exist. */
5331 astman_send_error(s, m, "Extension does not exist.");
5332 res = 0;
5333 goto fast_orig_cleanup;
5334 }
5335 }
5336
5337 /* Allocate requested channel variables */
5338 vars = astman_get_variables(m);
5339 if (s->session && s->session->chanvars) {
5340 struct ast_variable *v, *old;
5341 old = vars;
5342 vars = NULL;
5343
5344 /* The variables in the AMI originate action are appended at the end of the list, to override any user variables that apply */
5345
5347 if (old) {
5348 for (v = vars; v->next; v = v->next );
5349 v->next = old; /* Append originate variables at end of list */
5350 }
5351 }
5352
5353 /* For originate async - we can bridge in early media stage */
5354 bridge_early = ast_true(early_media);
5355
5356 if (ast_true(async)) {
5357 struct fast_originate_helper *fast;
5358
5359 fast = ast_calloc(1, sizeof(*fast));
5360 if (!fast || ast_string_field_init(fast, 252)) {
5361 ast_free(fast);
5363 res = -1;
5364 } else {
5365 if (!ast_strlen_zero(id)) {
5366 ast_string_field_build(fast, idtext, "ActionID: %s\r\n", id);
5367 }
5372 ast_string_field_set(fast, cid_num, l);
5377 ast_string_field_set(fast, channelid, assignedids.uniqueid);
5378 ast_string_field_set(fast, otherchannelid, assignedids.uniqueid2);
5379 fast->vars = vars;
5380 fast->cap = cap;
5381 cap = NULL; /* transferred originate helper the capabilities structure. It is now responsible for freeing it. */
5382 fast->timeout = to;
5383 fast->early_media = bridge_early;
5384 fast->priority = pi;
5387 res = -1;
5388 } else {
5389 res = 0;
5390 }
5391 }
5392 } else if (!ast_strlen_zero(app)) {
5393 res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason,
5395 assignedids.uniqueid ? &assignedids : NULL);
5397 } else {
5398 if (exten && context && pi) {
5400 context, exten, pi, &reason, AST_OUTGOING_WAIT,
5401 l, n, vars, account, NULL, bridge_early,
5402 assignedids.uniqueid ? &assignedids : NULL , gosub);
5404 } else {
5405 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
5407 res = 0;
5408 goto fast_orig_cleanup;
5409 }
5410 }
5411 if (!res) {
5412 astman_send_ack(s, m, "Originate successfully queued");
5413 } else {
5414 astman_send_error(s, m, "Originate failed");
5415 }
5416
5417fast_orig_cleanup:
5419 return 0;
5420}
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 int is_originate_app_permitted(const char *app, const char *data, int permission)
Definition: manager.c:5121
static void destroy_fast_originate_helper(struct fast_originate_helper *doomed)
Definition: manager.c:4383
struct ast_variable * astman_get_variables(const struct message *m)
Get a linked list of the Variable: headers.
Definition: manager.c:1729
static void * fast_originate(void *data)
Definition: manager.c:4391
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:629
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:4195
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:7945
@ AST_OUTGOING_WAIT
Definition: pbx.h:1144
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:7999
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:4190
#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:606
const char * uniqueid2
Definition: channel.h:608
const char * uniqueid
Definition: channel.h:607
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
helper function for originate
Definition: manager.c:4355
const ast_string_field appdata
Definition: manager.c:4373
struct ast_variable * vars
Definition: manager.c:4375
const ast_string_field cid_num
Definition: manager.c:4373
const ast_string_field account
Definition: manager.c:4373
const ast_string_field tech
Definition: manager.c:4373
const ast_string_field data
Definition: manager.c:4373
const ast_string_field channelid
Definition: manager.c:4373
const ast_string_field otherchannelid
Definition: manager.c:4373
struct ast_format_cap * cap
Definition: manager.c:4357
const ast_string_field exten
Definition: manager.c:4373
const ast_string_field idtext
Definition: manager.c:4373
const ast_string_field cid_name
Definition: manager.c:4373
struct ast_variable * chanvars
Definition: manager.c:298
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:594

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, fast_originate(), is_originate_app_permitted(), name, ast_variable::next, NULL, priority, fast_originate_helper::priority, mansession::session, fast_originate_helper::timeout, 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 2425 of file manager.c.

2426{
2427 const char *actionid = astman_get_header(m, "ActionID");
2428 struct timeval now = ast_tvnow();
2429
2430 astman_append(s, "Response: Success\r\n");
2431 if (!ast_strlen_zero(actionid)){
2432 astman_append(s, "ActionID: %s\r\n", actionid);
2433 }
2435 s,
2436 "Ping: Pong\r\n"
2437 "Timestamp: %ld.%06lu\r\n"
2438 "\r\n",
2439 (long) now.tv_sec, (unsigned long) now.tv_usec);
2440 return 0;
2441}

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

5491{
5492 const char *provider = astman_get_header(m, "Provider");
5494 char *subtype;
5495 char *message;
5496
5498 astman_send_error(s, m, "No provider specified");
5499 return 0;
5500 }
5501
5503 if (state == AST_PRESENCE_INVALID) {
5504 astman_send_error_va(s, m, "Invalid provider %s or provider in invalid state", provider);
5505 return 0;
5506 }
5507
5508 astman_start_ack(s, m);
5509 astman_append(s, "Message: Presence State\r\n"
5510 "State: %s\r\n", ast_presence_state2str(state));
5511
5512 if (!ast_strlen_zero(subtype)) {
5513 astman_append(s, "Subtype: %s\r\n", subtype);
5514 }
5515
5516 if (!ast_strlen_zero(message)) {
5517 /* XXX The Message header here is deprecated as it
5518 * duplicates the action response header 'Message'.
5519 * Remove it in the next major revision of AMI.
5520 */
5521 astman_append(s, "Message: %s\r\n"
5522 "PresenceMessage: %s\r\n",
5523 message, message);
5524 }
5525 astman_append(s, "\r\n");
5526
5527 return 0;
5528}
static struct prometheus_metrics_provider provider
Definition: bridges.c:201
enum cc_state state
Definition: ccss.c:399
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 3953 of file manager.c.

3954{
3955 char buf[256];
3956 const char *name = astman_get_header(m, "Channel");
3957 const char *name2 = astman_get_header(m, "ExtraChannel");
3958 const char *exten = astman_get_header(m, "Exten");
3959 const char *exten2 = astman_get_header(m, "ExtraExten");
3960 const char *context = astman_get_header(m, "Context");
3961 const char *context2 = astman_get_header(m, "ExtraContext");
3962 const char *priority = astman_get_header(m, "Priority");
3963 const char *priority2 = astman_get_header(m, "ExtraPriority");
3964 struct ast_channel *chan;
3965 struct ast_channel *chan2;
3966 int pi = 0;
3967 int pi2 = 0;
3968 int res;
3969 int chan1_wait = 0;
3970 int chan2_wait = 0;
3971
3972 if (ast_strlen_zero(name)) {
3973 astman_send_error(s, m, "Channel not specified");
3974 return 0;
3975 }
3976
3977 if (ast_strlen_zero(context)) {
3978 astman_send_error(s, m, "Context not specified");
3979 return 0;
3980 }
3981 if (ast_strlen_zero(exten)) {
3982 astman_send_error(s, m, "Exten not specified");
3983 return 0;
3984 }
3986 astman_send_error(s, m, "Priority not specified");
3987 return 0;
3988 }
3989 if (sscanf(priority, "%30d", &pi) != 1) {
3991 }
3992 if (pi < 1) {
3993 astman_send_error(s, m, "Priority is invalid");
3994 return 0;
3995 }
3996
3997 if (!ast_strlen_zero(name2) && !ast_strlen_zero(context2)) {
3998 /* We have an ExtraChannel and an ExtraContext */
3999 if (ast_strlen_zero(exten2)) {
4000 astman_send_error(s, m, "ExtraExten not specified");
4001 return 0;
4002 }
4003 if (ast_strlen_zero(priority2)) {
4004 astman_send_error(s, m, "ExtraPriority not specified");
4005 return 0;
4006 }
4007 if (sscanf(priority2, "%30d", &pi2) != 1) {
4008 pi2 = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL);
4009 }
4010 if (pi2 < 1) {
4011 astman_send_error(s, m, "ExtraPriority is invalid");
4012 return 0;
4013 }
4014 }
4015
4017 if (!chan) {
4018 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
4019 astman_send_error(s, m, buf);
4020 return 0;
4021 }
4022 if (ast_check_hangup_locked(chan)) {
4023 astman_send_error(s, m, "Redirect failed, channel not up.");
4024 chan = ast_channel_unref(chan);
4025 return 0;
4026 }
4027
4028 if (ast_strlen_zero(name2)) {
4029 /* Single channel redirect in progress. */
4031 if (!res) {
4032 astman_send_ack(s, m, "Redirect successful");
4033 } else {
4034 astman_send_error(s, m, "Redirect failed");
4035 }
4036 chan = ast_channel_unref(chan);
4037 return 0;
4038 }
4039
4040 chan2 = ast_channel_get_by_name(name2);
4041 if (!chan2) {
4042 snprintf(buf, sizeof(buf), "ExtraChannel does not exist: %s", name2);
4043 astman_send_error(s, m, buf);
4044 chan = ast_channel_unref(chan);
4045 return 0;
4046 }
4047 if (ast_check_hangup_locked(chan2)) {
4048 astman_send_error(s, m, "Redirect failed, extra channel not up.");
4049 chan2 = ast_channel_unref(chan2);
4050 chan = ast_channel_unref(chan);
4051 return 0;
4052 }
4053
4054 /* Dual channel redirect in progress. */
4055 ast_channel_lock(chan);
4056 if (ast_channel_is_bridged(chan)) {
4058 chan1_wait = 1;
4059 }
4060 ast_channel_unlock(chan);
4061
4062 ast_channel_lock(chan2);
4063 if (ast_channel_is_bridged(chan2)) {
4065 chan2_wait = 1;
4066 }
4067 ast_channel_unlock(chan2);
4068
4070 if (!res) {
4071 if (!ast_strlen_zero(context2)) {
4072 res = async_goto_with_discard_bridge_after(chan2, context2, exten2, pi2);
4073 } else {
4075 }
4076 if (!res) {
4077 astman_send_ack(s, m, "Dual Redirect successful");
4078 } else {
4079 astman_send_error(s, m, "Secondary redirect failed");
4080 }
4081 } else {
4082 astman_send_error(s, m, "Redirect failed");
4083 }
4084
4085 /* Release the bridge wait. */
4086 if (chan1_wait) {
4088 }
4089 if (chan2_wait) {
4091 }
4092
4093 chan2 = ast_channel_unref(chan2);
4094 chan = ast_channel_unref(chan);
4095 return 0;
4096}
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11035
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
@ AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT
Definition: channel.h:1055
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:458
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10546
static int async_goto_with_discard_bridge_after(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: manager.c:3946
#define ast_set_flag(p, flag)
Definition: utils.h:70

References 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(), async_goto_with_discard_bridge_after(), 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 6545 of file manager.c.

6546{
6547 const char *module = astman_get_header(m, "Module");
6549
6550 switch (res) {
6552 astman_send_error(s, m, "No such module");
6553 break;
6555 astman_send_error(s, m, "Module does not support reload");
6556 break;
6558 astman_send_error(s, m, "An unknown error occurred");
6559 break;
6561 astman_send_error(s, m, "A reload is in progress");
6562 break;
6564 astman_send_error(s, m, "Module not initialized");
6565 break;
6568 /* Treat a queued request as success */
6569 astman_send_ack(s, m, "Module Reloaded");
6570 break;
6571 }
6572 return 0;
6573}
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:1730

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

3905{
3906 struct ast_channel *c;
3907 const char *name = astman_get_header(m, "Channel");
3908 const char *textmsg = astman_get_header(m, "Message");
3909 const char *content_type = astman_get_header(m, "Content-Type");
3910 int res;
3911
3912 if (ast_strlen_zero(name)) {
3913 astman_send_error(s, m, "No channel specified");
3914 return 0;
3915 }
3916
3917 if (ast_strlen_zero(textmsg)) {
3918 astman_send_error(s, m, "No Message specified");
3919 return 0;
3920 }
3921
3923 if (!c) {
3924 astman_send_error(s, m, "No such channel");
3925 return 0;
3926 }
3927
3928 /*
3929 * If the "extra" data is not available, then send using "string" only.
3930 * Doing such maintains backward compatibilities.
3931 */
3932 res = ast_strlen_zero(content_type) ? queue_sendtext(c, textmsg) :
3933 queue_sendtext_data(c, textmsg, content_type);
3934
3936
3937 if (res >= 0) {
3938 astman_send_ack(s, m, "Success");
3939 } else {
3940 astman_send_error(s, m, "Failure");
3941 }
3942
3943 return 0;
3944}
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:3885
static int queue_sendtext(struct ast_channel *chan, const char *body)
Queue a read action to send a text message.
Definition: manager.c:3869

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

3549{
3550 struct ast_channel *c = NULL;
3551 const char *name = astman_get_header(m, "Channel");
3552 const char *varname = astman_get_header(m, "Variable");
3553 const char *varval = astman_get_header(m, "Value");
3554 int res = 0;
3555
3556 if (ast_strlen_zero(varname)) {
3557 astman_send_error(s, m, "No variable specified");
3558 return 0;
3559 }
3560
3561 if (!ast_strlen_zero(name)) {
3562 if (!(c = ast_channel_get_by_name(name))) {
3563 astman_send_error(s, m, "No such channel");
3564 return 0;
3565 }
3566 }
3567
3568 res = pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
3569
3570 if (c) {
3572 }
3573 if (res == 0) {
3574 astman_send_ack(s, m, "Variable Set");
3575 } else {
3576 astman_send_error(s, m, "Variable not set");
3577 }
3578 return 0;
3579}

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

3749{
3750 const char *name = astman_get_header(m, "Channel");
3751 const char *chan_variables = astman_get_header(m, "Variables");
3752 const char *all_chan_variables = astman_get_header(m, "AllVariables");
3753 int all_variables = 0;
3754 const char *id = astman_get_header(m, "ActionID");
3755 char *variables = ast_strdupa(S_OR(chan_variables, ""));
3756 struct ast_channel *chan;
3757 int channels = 0;
3758 int all = ast_strlen_zero(name); /* set if we want all channels */
3759 char id_text[256];
3760 struct ast_channel_iterator *it_chans = NULL;
3762 AST_APP_ARG(name)[100];
3763 );
3764
3765 if (!ast_strlen_zero(all_chan_variables)) {
3766 all_variables = ast_true(all_chan_variables);
3767 }
3768
3770 astman_send_error(s, m, "Status Access Forbidden: Variables");
3771 return 0;
3772 }
3773
3774 if (all) {
3775 if (!(it_chans = ast_channel_iterator_all_new())) {
3776 astman_send_error(s, m, "Memory Allocation Failure");
3777 return 1;
3778 }
3779 chan = ast_channel_iterator_next(it_chans);
3780 } else {
3782 if (!chan) {
3783 astman_send_error(s, m, "No such channel");
3784 return 0;
3785 }
3786 }
3787
3788 astman_send_listack(s, m, "Channel status will follow", "start");
3789
3790 if (!ast_strlen_zero(id)) {
3791 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
3792 } else {
3793 id_text[0] = '\0';
3794 }
3795
3796 if (!ast_strlen_zero(chan_variables)) {
3797 AST_STANDARD_APP_ARGS(vars, variables);
3798 }
3799
3800 /* if we look by name, we break after the first iteration */
3801 for (; chan; all ? chan = ast_channel_iterator_next(it_chans) : 0) {
3802 ast_channel_lock(chan);
3803
3804 generate_status(s, chan, vars.name, vars.argc, all_variables, id_text, &channels);
3805
3806 ast_channel_unlock(chan);
3807 chan = ast_channel_unref(chan);
3808 }
3809
3810 if (it_chans) {
3812 }
3813
3814 astman_send_list_complete_start(s, m, "StatusComplete", channels);
3815 astman_append(s, "Items: %d\r\n", channels);
3817
3818 return 0;
3819}
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1329
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1368
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1360
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:3633
#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, 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 5530 of file manager.c.

5531{
5532 struct ast_channel *c;
5533 const char *name = astman_get_header(m, "Channel");
5534 double timeout = atof(astman_get_header(m, "Timeout"));
5535 struct timeval when = { timeout, 0 };
5536
5537 if (ast_strlen_zero(name)) {
5538 astman_send_error(s, m, "No channel specified");
5539 return 0;
5540 }
5541
5542 if (!timeout || timeout < 0) {
5543 astman_send_error(s, m, "No timeout specified");
5544 return 0;
5545 }
5546
5547 if (!(c = ast_channel_get_by_name(name))) {
5548 astman_send_error(s, m, "No such channel");
5549 return 0;
5550 }
5551
5552 when.tv_usec = (timeout - when.tv_sec) * 1000000.0;
5553
5558
5559 astman_send_ack(s, m, "Timeout Set");
5560
5561 return 0;
5562}
void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
Set when to hang a channel up.
Definition: channel.c:509

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

3003{
3004 struct ast_config *cfg;
3005 const char *sfn = astman_get_header(m, "SrcFilename");
3006 const char *dfn = astman_get_header(m, "DstFilename");
3007 int res;
3008 const char *rld = astman_get_header(m, "Reload");
3009 int preserve_effective_context = CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT;
3010 const char *preserve_effective_context_string = astman_get_header(m, "PreserveEffectiveContext");
3011 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
3012 enum error_type result;
3013
3014 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
3015 astman_send_error(s, m, "Filename not specified");
3016 return 0;
3017 }
3018 if (is_restricted_file(sfn) || is_restricted_file(dfn)) {
3019 astman_send_error(s, m, "File requires escalated privileges");
3020 return 0;
3021 }
3022 if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) {
3023 astman_send_error(s, m, "Config file not found");
3024 return 0;
3025 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
3026 astman_send_error(s, m, "Config file has invalid format");
3027 return 0;
3028 }
3029 result = handle_updates(s, m, cfg, dfn);
3030 if (!result) {
3031 ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
3032 if (!ast_strlen_zero(preserve_effective_context_string) && !ast_true(preserve_effective_context_string)) {
3033 preserve_effective_context = CONFIG_SAVE_FLAG_NONE;
3034 }
3035 res = ast_config_text_file_save2(dfn, cfg, "Manager", preserve_effective_context);
3036 ast_config_destroy(cfg);
3037 if (res) {
3038 astman_send_error(s, m, "Save of config failed");
3039 return 0;
3040 }
3041 astman_send_ack(s, m, NULL);
3042 if (!ast_strlen_zero(rld)) {
3043 if (ast_true(rld)) {
3044 ast_module_reload(NULL); /* Reload everything */
3045 } else if (!ast_false(rld)) {
3046 ast_module_reload(rld); /* Reload the specific module */
3047 }
3048 }
3049 } else {
3050 ast_config_destroy(cfg);
3051 switch(result) {
3052 case UNKNOWN_ACTION:
3053 astman_send_error(s, m, "Unknown action command");
3054 break;
3055 case UNKNOWN_CATEGORY:
3056 astman_send_error(s, m, "Given category does not exist");
3057 break;
3059 astman_send_error(s, m, "Category not specified");
3060 break;
3062 astman_send_error(s, m, "Problem with category, value, or line (if required)");
3063 break;
3064 case FAILURE_ALLOCATION:
3065 astman_send_error(s, m, "Memory allocation failure, this should not happen");
3066 break;
3067 case FAILURE_NEWCAT:
3068 astman_send_error(s, m, "Create category did not complete successfully");
3069 break;
3070 case FAILURE_DELCAT:
3071 astman_send_error(s, m, "Delete category did not complete successfully");
3072 break;
3073 case FAILURE_EMPTYCAT:
3074 astman_send_error(s, m, "Empty category did not complete successfully");
3075 break;
3076 case FAILURE_UPDATE:
3077 astman_send_error(s, m, "Update did not complete successfully");
3078 break;
3079 case FAILURE_DELETE:
3080 astman_send_error(s, m, "Delete did not complete successfully");
3081 break;
3082 case FAILURE_APPEND:
3083 astman_send_error(s, m, "Append did not complete successfully");
3084 break;
3085 case FAILURE_TEMPLATE:
3086 astman_send_error(s, m, "Template category not found");
3087 break;
3088 }
3089 }
3090 return 0;
3091}
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:2719
error_type
Definition: manager.c:108
void ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
Definition: main/config.c:469
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:2927
@ 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(), is_restricted_file(), NULL, 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 6438 of file manager.c.

6439{
6440 const char *event = astman_get_header(m, "UserEvent");
6441 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
6442 int x;
6443
6444 ast_str_reset(body);
6445
6446 for (x = 0; x < m->hdrcount; x++) {
6447 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:")) &&
6448 strncasecmp("Action:", m->headers[x], strlen("Action:"))) {
6449 ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
6450 }
6451 }
6452
6453 astman_send_ack(s, m, "Event Sent");
6454 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body));
6455 return 0;
6456}
static struct ast_threadstorage userevent_buf
Definition: manager.c:1886
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:254
#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 3167 of file manager.c.

3168{
3169 const char *timeouts = astman_get_header(m, "Timeout");
3170 int timeout = -1;
3171 int x;
3172 int needexit = 0;
3173 const char *id = astman_get_header(m, "ActionID");
3174 char idText[256];
3175
3176 if (!ast_strlen_zero(id)) {
3177 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
3178 } else {
3179 idText[0] = '\0';
3180 }
3181
3182 if (!ast_strlen_zero(timeouts)) {
3183 sscanf(timeouts, "%30i", &timeout);
3184 if (timeout < -1) {
3185 timeout = -1;
3186 }
3187 /* XXX maybe put an upper bound, or prevent the use of 0 ? */
3188 }
3189
3192 pthread_kill(s->session->waiting_thread, SIGURG);
3193 }
3195
3196 ao2_lock(s->session);
3197
3198 if (s->session->managerid) { /* AMI-over-HTTP session */
3199 /*
3200 * Make sure the timeout is within the expire time of the session,
3201 * as the client will likely abort the request if it does not see
3202 * data coming after some amount of time.
3203 */
3204 time_t now = time(NULL);
3205 int max = s->session->sessiontimeout - now - 10;
3206
3207 if (max < 0) { /* We are already late. Strange but possible. */
3208 max = 0;
3209 }
3210 if (timeout < 0 || timeout > max) {
3211 timeout = max;
3212 }
3213 if (!s->session->send_events) { /* make sure we record events */
3214 s->session->send_events = -1;
3215 }
3216 }
3217 ao2_unlock(s->session);
3218
3220 s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
3222 ast_debug(1, "Starting waiting for an event!\n");
3223
3224 for (x = 0; x < timeout || timeout < 0; x++) {
3225 ao2_lock(s->session);
3226 if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
3227 needexit = 1;
3228 }
3229 if (s->session->needdestroy) {
3230 needexit = 1;
3231 }
3232 ao2_unlock(s->session);
3233 /* We can have multiple HTTP session point to the same mansession entry.
3234 * The way we deal with it is not very nice: newcomers kick out the previous
3235 * HTTP session. XXX this needs to be improved.
3236 */
3238 if (s->session->waiting_thread != pthread_self()) {
3239 needexit = 1;
3240 }
3242 if (needexit) {
3243 break;
3244 }
3245 if (s->session->managerid == 0) { /* AMI session */
3247 break;
3248 }
3249 } else { /* HTTP session */
3250 sleep(1);
3251 }
3252 }
3253 ast_debug(1, "Finished waiting for an event!\n");
3254
3256 if (s->session->waiting_thread == pthread_self()) {
3257 struct eventqent *eqe = s->session->last_ev;
3258
3261
3262 ao2_lock(s->session);
3263 astman_send_response(s, m, "Success", "Waiting for Event completed.");
3264 while ((eqe = advance_event(eqe))) {
3265 if (((s->session->readperm & eqe->category) == eqe->category)
3266 && ((s->session->send_events & eqe->category) == eqe->category)
3268 astman_append(s, "%s", eqe->eventdata);
3269 }
3270 s->session->last_ev = eqe;
3271 }
3272 astman_append(s,
3273 "Event: WaitEventComplete\r\n"
3274 "%s"
3275 "\r\n", idText);
3276 ao2_unlock(s->session);
3277 } else {
3279 ast_debug(1, "Abandoning event request!\n");
3280 }
3281
3282 return 0;
3283}
#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:1576
static int should_send_event(struct ao2_container *includefilters, struct ao2_container *excludefilters, struct eventqent *eqe)
Definition: manager.c:5645
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
Definition: iostream.c:85
#define AST_RWLIST_NEXT
Definition: linkedlists.h:441
int category
Definition: manager.c:151
ast_mutex_t notify_lock
Definition: manager.c:308
pthread_t waiting_thread
Definition: manager.c:284
struct ast_iostream * stream
Definition: manager.c:281
struct eventqent * last_ev
Definition: manager.c:300
time_t sessiontimeout
Definition: manager.c:288
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::excludefilters, mansession_session::includefilters, mansession_session::last_ev, mansession_session::managerid, max, mansession_session::needdestroy, mansession_session::notify_lock, NULL, mansession_session::readperm, mansession_session::send_events, mansession::session, mansession_session::sessiontimeout, should_send_event(), 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 1576 of file manager.c.

1577{
1578 struct eventqent *next;
1579
1581 if ((next = AST_RWLIST_NEXT(e, eq_next))) {
1584 }
1586 return next;
1587}
int usecount
Definition: manager.c:150

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

4472{
4473 const char *unitamount;
4474 const char *unittype;
4475 struct ast_str *str = ast_str_alloca(32);
4476
4477 memset(entry, 0, sizeof(*entry));
4478
4479 ast_str_set(&str, 0, "UnitAmount(%u)", entry_num);
4480 unitamount = astman_get_header(m, ast_str_buffer(str));
4481
4482 ast_str_set(&str, 0, "UnitType(%u)", entry_num);
4483 unittype = astman_get_header(m, ast_str_buffer(str));
4484
4485 if (!ast_strlen_zero(unitamount) && (sscanf(unitamount, "%30u", &entry->amount) == 1)) {
4486 entry->valid_amount = 1;
4487 }
4488
4489 if (!ast_strlen_zero(unittype) && sscanf(unittype, "%30u", &entry->type) == 1) {
4490 entry->valid_type = 1;
4491 }
4492
4493 return 0;
4494}
const char * str
Definition: app_jack.c:150
unsigned int amount
Definition: aoc.h:180
unsigned int type
Definition: aoc.h:182
char valid_type
Definition: aoc.h:181
char valid_amount
Definition: aoc.h:179

References ast_aoc_unit_entry::amount, ast_str_alloca, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), astman_get_header(), str, ast_aoc_unit_entry::type, ast_aoc_unit_entry::valid_amount, and ast_aoc_unit_entry::valid_type.

Referenced by action_aoc_de_message().

◆ app_match()

static int app_match ( const char *  app,
const char *  data,
const char *  search 
)
static

Definition at line 5009 of file manager.c.

5010{
5011 /*
5012 * We use strcasestr so we don't have to trim any blanks
5013 * from the front or back of the string.
5014 */
5015 return !!(strcasestr(app, search));
5016}
char * strcasestr(const char *, const char *)

References app, and strcasestr().

◆ appdata_match()

static int appdata_match ( const char *  app,
const char *  data,
const char *  search 
)
static

Definition at line 5028 of file manager.c.

5029{
5030 if (ast_strlen_zero(data)) {
5031 return 0;
5032 }
5033 return !!(strstr(data, search));
5034}

References ast_strlen_zero().

◆ append_channel_vars()

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

Definition at line 7518 of file manager.c.

7519{
7520 struct varshead *vars;
7521 struct ast_var_t *var;
7522
7523 vars = ast_channel_get_manager_vars(chan);
7524 if (!vars) {
7525 return;
7526 }
7527
7528 AST_LIST_TRAVERSE(vars, var, entries) {
7529 ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", ast_channel_name(chan), var->name, var->value);
7530 }
7531 ao2_ref(vars, -1);
7532}
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:7925
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::@216 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  event_name_hash,
int  category 
)
static

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

Definition at line 7493 of file manager.c.

7494{
7495 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
7496 static int seq; /* sequence number */
7497
7498 if (!tmp) {
7499 return -1;
7500 }
7501
7502 /* need to init all fields, because ast_malloc() does not */
7503 tmp->usecount = 0;
7504 tmp->category = category;
7505 tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
7506 tmp->tv = ast_tvnow();
7508 AST_RWLIST_NEXT(tmp, eq_next) = NULL;
7509 strcpy(tmp->eventdata, str);
7510
7512 AST_RWLIST_INSERT_TAIL(&all_events, tmp, eq_next);
7514
7515 return 0;
7516}
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741
unsigned int seq
Definition: manager.c:152
struct timeval tv
Definition: manager.c:153
int event_name_hash
Definition: manager.c:154

References ast_atomic_fetchadd_int(), ast_malloc, AST_RWLIST_INSERT_TAIL, AST_RWLIST_NEXT, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_tvnow(), eventqent::category, eventqent::event_name_hash, NULL, seq, eventqent::seq, str, eventqent::tv, and eventqent::usecount.

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

1761{
1762 const char *action;
1763 int ret = 0;
1764 struct manager_action *act_found;
1765 struct mansession s = {.session = NULL, };
1766 struct message m = { 0 };
1767 char *dup_str;
1768 char *src;
1769 int x = 0;
1770 int curlen;
1771
1772 if (hook == NULL) {
1773 return -1;
1774 }
1775
1776 /* Create our own copy of the AMI action msg string. */
1777 src = dup_str = ast_strdup(msg);
1778 if (!dup_str) {
1779 return -1;
1780 }
1781
1782 /* convert msg string to message struct */
1783 curlen = strlen(src);
1784 for (x = 0; x < curlen; x++) {
1785 int cr; /* set if we have \r */
1786 if (src[x] == '\r' && x+1 < curlen && src[x+1] == '\n')
1787 cr = 2; /* Found. Update length to include \r\n */
1788 else if (src[x] == '\n')
1789 cr = 1; /* also accept \n only */
1790 else
1791 continue;
1792 /* don't keep empty lines */
1793 if (x && m.hdrcount < ARRAY_LEN(m.headers)) {
1794 /* ... but trim \r\n and terminate the header string */
1795 src[x] = '\0';
1796 m.headers[m.hdrcount++] = src;
1797 }
1798 x += cr;
1799 curlen -= x; /* remaining size */
1800 src += x; /* update pointer */
1801 x = -1; /* reset loop */
1802 }
1803
1804 action = astman_get_header(&m, "Action");
1805
1806 do {
1807 if (!strcasecmp(action, "login")) {
1808 break;
1809 }
1810
1811 act_found = action_find(action);
1812 if (!act_found) {
1813 break;
1814 }
1815
1816 /*
1817 * we have to simulate a session for this action request
1818 * to be able to pass it down for processing
1819 * This is necessary to meet the previous design of manager.c
1820 */
1821 s.hook = hook;
1822
1823 ret = -1;
1824 ao2_lock(act_found);
1825 if (act_found->registered && act_found->func) {
1826 struct ast_module *mod_ref = ast_module_running_ref(act_found->module);
1827
1828 ao2_unlock(act_found);
1829 /* If the action is in a module it must be running. */
1830 if (!act_found->module || mod_ref) {
1831 ret = act_found->func(&s, &m);
1832 ast_module_unref(mod_ref);
1833 }
1834 } else {
1835 ao2_unlock(act_found);
1836 }
1837 ao2_t_ref(act_found, -1, "done with found action object");
1838 } while (0);
1839
1840 ast_free(dup_str);
1841 return ret;
1842}
static struct manager_action * action_find(const char *name)
Definition: manager.c:434
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:469
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:323
struct manager_custom_hook * hook
Definition: manager.c:329

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

844{
845 const char *val = bigstr, *next;
846
847 do {
848 if ((next = strchr(val, delim))) {
849 if (!strncmp(val, smallstr, (next - val))) {
850 return 1;
851 } else {
852 continue;
853 }
854 } else {
855 return !strcmp(smallstr, val);
856 }
857 } while (*(val = (next + 1)));
858
859 return 0;
860}
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 680 of file manager.c.

681{
682 return manager_enabled;
683}
static int manager_enabled
Definition: manager.c:166

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

456{
457 return stasis_router;
458}
static struct stasis_message_router * stasis_router
The stasis_message_router for all Stasis Message Bus API messages.
Definition: manager.c:185

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

451{
452 return manager_topic;
453}
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:182

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(), 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 3421 of file manager.c.

3424{
3425 struct ast_channel *c = NULL;
3426 int causecode = 0; /* all values <= 0 mean 'do not set hangupcause in channel' */
3427 const char *id = astman_get_header(m, "ActionID");
3428 const char *name_or_regex = astman_get_header(m, "Channel");
3429 const char *cause = astman_get_header(m, "Cause");
3430 char idText[256];
3431 regex_t regexbuf;
3432 struct ast_channel_iterator *iter = NULL;
3433 struct ast_str *regex_string;
3434 int channels_matched = 0;
3435
3436 if (ast_strlen_zero(name_or_regex)) {
3437 astman_send_error(s, m, "No channel specified");
3438 return 0;
3439 }
3440
3441 if (!ast_strlen_zero(id)) {
3442 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
3443 } else {
3444 idText[0] = '\0';
3445 }
3446
3447 if (cause_validator) {
3448 causecode = cause_validator(name_or_regex, cause);
3449 } else if (!ast_strlen_zero(cause)) {
3450 char *endptr;
3451 causecode = strtol(cause, &endptr, 10);
3452 if (causecode < 0 || causecode > 127 || *endptr != '\0') {
3453 ast_log(LOG_NOTICE, "Invalid 'Cause: %s' in manager action Hangup\n", cause);
3454 /* keep going, better to hangup without cause than to not hang up at all */
3455 causecode = 0; /* do not set channel's hangupcause */
3456 }
3457 }
3458
3459 /************************************************/
3460 /* Regular explicit match channel byname hangup */
3461
3462 if (name_or_regex[0] != '/') {
3463 if (!(c = ast_channel_get_by_name(name_or_regex))) {
3464 ast_log(LOG_NOTICE, "Request to hangup non-existent channel: %s\n",
3465 name_or_regex);
3466 astman_send_error(s, m, "No such channel");
3467 return 0;
3468 }
3469
3470 ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
3471 (s->session->managerid ? "HTTP " : ""),
3472 s->session->username,
3475
3476 hangup_handler(c, causecode);
3478
3479 astman_send_ack(s, m, "Channel Hungup");
3480
3481 return 0;
3482 }
3483
3484 /***********************************************/
3485 /* find and hangup any channels matching regex */
3486
3487 regex_string = ast_str_create(strlen(name_or_regex));
3488 if (!regex_string) {
3489 astman_send_error(s, m, "Memory Allocation Failure");
3490 return 0;
3491 }
3492
3493 /* Make "/regex/" into "regex" */
3494 if (ast_regex_string_to_regex_pattern(name_or_regex, &regex_string) != 0) {
3495 astman_send_error(s, m, "Regex format invalid, Channel param should be /regex/");
3496 ast_free(regex_string);
3497 return 0;
3498 }
3499
3500 /* if regex compilation fails, hangup fails */
3501 if (regcomp(&regexbuf, ast_str_buffer(regex_string), REG_EXTENDED | REG_NOSUB)) {
3502 astman_send_error_va(s, m, "Regex compile failed on: %s", name_or_regex);
3503 ast_free(regex_string);
3504 return 0;
3505 }
3506
3507 astman_send_listack(s, m, "Channels hung up will follow", "start");
3508
3510 if (iter) {
3511 for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
3512 if (regexec(&regexbuf, ast_channel_name(c), 0, NULL, 0)) {
3513 continue;
3514 }
3515
3516 ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
3517 (s->session->managerid ? "HTTP " : ""),
3518 s->session->username,
3521
3522 hangup_handler(c, causecode);
3523 channels_matched++;
3524
3525 astman_append(s,
3526 "Event: ChannelHungup\r\n"
3527 "Channel: %s\r\n"
3528 "%s"
3529 "\r\n", ast_channel_name(c), idText);
3530 }
3532 }
3533
3534 regfree(&regexbuf);
3535 ast_free(regex_string);
3536
3537 astman_send_list_complete(s, m, "ChannelsHungupListComplete", channels_matched);
3538
3539 return 0;
3540}
#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 634 of file manager.c.

635{
636 RAII_VAR(struct ast_json *, event_info, NULL, ast_json_unref);
637 RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
639
640 if (!obj || !ast_manager_get_generic_type()) {
641 return;
642 }
643
644 ast_json_ref(obj);
645 event_info = ast_json_pack("{s: s, s: i, s: o}",
646 "type", type,
647 "class_type", class_type,
648 "event", obj);
649 if (!event_info) {
650 return;
651 }
652
653 payload = ast_json_payload_create(event_info);
654 if (!payload) {
655 return;
656 }
658 if (!message) {
659 return;
660 }
662}
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:450
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:1538
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 7821 of file manager.c.

7822{
7823 struct manager_action *cur;
7824
7825 cur = ao2_t_alloc(sizeof(*cur), action_destroy, action);
7826 if (!cur) {
7827 return -1;
7828 }
7829 if (ast_string_field_init(cur, 128)) {
7830 ao2_t_ref(cur, -1, "action object creation failed");
7831 return -1;
7832 }
7833
7834 if (ast_string_field_init_extended(cur, since)) {
7835 ao2_t_ref(cur, -1, "action object creation failed");
7836 return -1;
7837 }
7838
7839 cur->action = action;
7840 cur->authority = auth;
7841 cur->func = func;
7842 cur->module = module;
7843#ifdef AST_XML_DOCS
7845 char *tmpxml;
7846
7847 tmpxml = ast_xmldoc_build_since("manager", action, NULL);
7848 ast_string_field_set(cur, since, tmpxml);
7849 ast_free(tmpxml);
7850
7851 tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL);
7852 ast_string_field_set(cur, synopsis, tmpxml);
7853 ast_free(tmpxml);
7854
7855 tmpxml = ast_xmldoc_build_syntax("manager", action, NULL);
7856 ast_string_field_set(cur, syntax, tmpxml);
7857 ast_free(tmpxml);
7858
7859 tmpxml = ast_xmldoc_build_description("manager", action, NULL);
7860 ast_string_field_set(cur, description, tmpxml);
7861 ast_free(tmpxml);
7862
7863 tmpxml = ast_xmldoc_build_seealso("manager", action, NULL);
7864 ast_string_field_set(cur, seealso, tmpxml);
7865 ast_free(tmpxml);
7866
7867 tmpxml = ast_xmldoc_build_arguments("manager", action, NULL);
7868 ast_string_field_set(cur, arguments, tmpxml);
7869 ast_free(tmpxml);
7870
7873
7874 cur->docsrc = AST_XML_DOC;
7875 } else
7876#endif
7877 {
7880#ifdef AST_XML_DOCS
7881 cur->docsrc = AST_STATIC_DOC;
7882#endif
7883 }
7884 if (ast_manager_register_struct(cur)) {
7885 ao2_t_ref(cur, -1, "action object registration failed");
7886 return -1;
7887 }
7888
7889 ao2_t_ref(cur, -1, "action object registration successful");
7890 return 0;
7891}
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:407
static char * synopsis
Definition: func_enum.c:166
static int ast_manager_register_struct(struct manager_action *act)
Definition: manager.c:7766
static void action_destroy(void *obj)
Definition: manager.c:7807
#define ast_string_field_init_extended(x, field)
Initialize an extended string field.
Definition: stringfields.h:401
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:2578
char * ast_xmldoc_build_description(const char *type, const char *name, const char *module)
Generate description documentation from XML.
Definition: xmldoc.c:2356
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:2169
char * ast_xmldoc_build_synopsis(const char *type, const char *name, const char *module)
Generate synopsis documentation from XML.
Definition: xmldoc.c:2333
char * ast_xmldoc_build_since(const char *type, const char *name, const char *module)
Parse the <since> node content.
Definition: xmldoc.c:1787
@ 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:2648

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_init_extended, 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_since(), 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 665 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 7766 of file manager.c.

7767{
7768 struct manager_action *cur, *prev = NULL;
7769
7771 AST_RWLIST_TRAVERSE(&actions, cur, list) {
7772 int ret;
7773
7774 ret = strcasecmp(cur->action, act->action);
7775 if (ret == 0) {
7776 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
7778 return -1;
7779 }
7780 if (ret > 0) { /* Insert these alphabetically */
7781 break;
7782 }
7783 prev = cur;
7784 }
7785
7786 ao2_t_ref(act, +1, "action object added to list");
7787 act->registered = 1;
7788 if (prev) {
7789 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list);
7790 } else {
7791 AST_RWLIST_INSERT_HEAD(&actions, act, list);
7792 }
7793
7794 ast_verb(5, "Manager registered action %s\n", act->action);
7795
7797
7798 return 0;
7799}
#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 551 of file manager.c.

552{
553 struct ast_str *res = ast_str_create(1024);
554
555 if (!ast_json_is_null(blob)) {
556 manager_json_to_ast_str(blob, NULL, &res, exclusion_cb);
557 }
558
559 return res;
560}
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:510
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 7695 of file manager.c.

7696{
7697 struct manager_action *cur;
7698
7701 if (!strcasecmp(action, cur->action)) {
7703 break;
7704 }
7705 }
7708
7709 if (cur) {
7710 /*
7711 * We have removed the action object from the container so we
7712 * are no longer in a hurry.
7713 */
7714 ao2_lock(cur);
7715 cur->registered = 0;
7716 ao2_unlock(cur);
7717
7718 ao2_t_ref(cur, -1, "action object removed from list");
7719 ast_verb(5, "Manager unregistered action %s\n", action);
7720 }
7721
7722 return 0;
7723}
#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 673 of file manager.c.

674{
676 AST_RWLIST_REMOVE(&manager_hooks, hook, list);
678}
#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 685 of file manager.c.

686{
688}
static int webmanager_enabled
Definition: manager.c:168

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

1904{
1905 int res;
1906 va_list ap;
1907 struct ast_str *buf;
1908
1910 return;
1911 }
1912
1913 va_start(ap, fmt);
1914 res = ast_str_set_va(&buf, 0, fmt, ap);
1915 va_end(ap);
1916 if (res == AST_DYNSTR_BUILD_FAILED) {
1917 return;
1918 }
1919
1920 if (s->hook || (s->tcptls_session != NULL && s->tcptls_session->stream != NULL)) {
1922 } else {
1923 ast_verbose("No connection stream in astman_append, should not happen\n");
1924 }
1925}
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:1889
static struct ast_threadstorage astman_append_buf
Definition: manager.c:1884
static int send_string(struct mansession *s, char *string)
Definition: manager.c:1848
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
@ AST_DYNSTR_BUILD_FAILED
Definition: strings.h:943
struct ast_iostream * stream
Definition: tcptls.h:162
struct ast_tcptls_session_instance * tcptls_session
Definition: manager.c:326

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

1654{
1655 const struct ast_variable *v;
1656
1657 for (v = params; v && m->hdrcount < ARRAY_LEN(m->headers); v = v->next) {
1658 if (ast_asprintf((char**)&m->headers[m->hdrcount], "%s: %s", v->name, v->value) > -1) {
1659 ++m->hdrcount;
1660 }
1661 }
1662}

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

2637{
2638 char *buf;
2639
2640 buf = ast_alloca(2 * strlen(str) + 1);
2642 astman_append(s, "%s", buf);
2643}
#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:2618

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

1892{
1893 if (s->hook || (s->tcptls_session && s->tcptls_session->stream)) {
1895 } else {
1896 ast_verbose("No connection stream in astman_append, should not happen\n");
1897 }
1898}

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

1668{
1669 while (m->hdrcount) {
1670 --m->hdrcount;
1671 ast_free((void *) m->headers[m->hdrcount]);
1672 m->headers[m->hdrcount] = NULL;
1673 }
1674}

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

1644{
1646}
#define GET_HEADER_FIRST_MATCH
Definition: manager.c:1589

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

1730{
1732}
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:1734
@ ORDER_REVERSE
Definition: manager.h:290

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

1736{
1737 int varlen;
1738 int x;
1739 struct ast_variable *head = NULL;
1740
1741 static const char var_hdr[] = "Variable:";
1742
1743 /* Process all "Variable:" headers. */
1744 varlen = strlen(var_hdr);
1745 for (x = 0; x < m->hdrcount; x++) {
1746 if (strncasecmp(var_hdr, m->headers[x], varlen)) {
1747 continue;
1748 }
1749 head = man_do_variable_value(head, m->headers[x] + varlen);
1750 }
1751
1752 if (order == ORDER_NATURAL) {
1753 head = ast_variables_reverse(head);
1754 }
1755
1756 return head;
1757}
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:1685
struct ast_variable * ast_variables_reverse(struct ast_variable *var)
Reverse a variable list.
Definition: main/config.c:651
@ ORDER_NATURAL
Definition: manager.h:289

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

2444{
2445 if (new_live_dangerously && !live_dangerously)
2446 {
2447 ast_log(LOG_WARNING, "Manager Configuration load protection disabled.\n");
2448 }
2449
2450 if (!new_live_dangerously && live_dangerously)
2451 {
2452 ast_log(LOG_NOTICE, "Manager Configuration load protection enabled.\n");
2453 }
2454 live_dangerously = new_live_dangerously;
2455}

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

2015{
2016 astman_send_response_full(s, m, "Success", msg, NULL);
2017}

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

1983{
1984 astman_send_response_full(s, m, "Error", error, NULL);
1985}
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 1987 of file manager.c.

1988{
1989 int res;
1990 va_list ap;
1991 struct ast_str *buf;
1992 char *msg;
1993
1995 return;
1996 }
1997
1998 va_start(ap, fmt);
1999 res = ast_str_set_va(&buf, 0, fmt, ap);
2000 va_end(ap);
2001 if (res == AST_DYNSTR_BUILD_FAILED) {
2002 return;
2003 }
2004
2005 /* astman_append will use the same underlying buffer, so copy the message out
2006 * before sending the response */
2007 msg = ast_str_buffer(buf);
2008 if (msg) {
2009 msg = ast_strdupa(msg);
2010 }
2011 astman_send_response_full(s, m, "Error", msg, NULL);
2012}

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

2052{
2053 struct ast_str *buf = astman_send_list_complete_start_common(s, m, event_name, count);
2054 if (buf) {
2055 ast_str_append(&buf, 0, "\r\n");
2056 astman_flush(s, buf);
2057 }
2058}
static void astman_flush(struct mansession *s, struct ast_str *buf)
Definition: manager.c:1891
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:2029

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

2069{
2070 astman_append(s, "\r\n");
2071}

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

2061{
2062 struct ast_str *buf = astman_send_list_complete_start_common(s, m, event_name, count);
2063 if (buf) {
2064 astman_flush(s, buf);
2065 }
2066}

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

2030{
2031 const char *id = astman_get_header(m, "ActionID");
2032 struct ast_str *buf;
2033
2035 if (!buf) {
2036 return NULL;
2037 }
2038
2039 ast_str_set(&buf, 0, "Event: %s\r\n", event_name);
2040 if (!ast_strlen_zero(id)) {
2041 ast_str_append(&buf, 0, "ActionID: %s\r\n", id);
2042 }
2043 ast_str_append(&buf, 0,
2044 "EventList: Complete\r\n"
2045 "ListItems: %d\r\n",
2046 count);
2047
2048 return buf;
2049}

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

2025{
2026 astman_send_response_full(s, m, "Success", msg, listflag);
2027}

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

1978{
1979 astman_send_response_full(s, m, resp, msg, NULL);
1980}

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

1947{
1948 const char *id = astman_get_header(m, "ActionID");
1949 struct ast_str *buf;
1950
1952 if (!buf) {
1953 return;
1954 }
1955
1956 ast_str_set(&buf, 0, "Response: %s\r\n", resp);
1957
1958 if (!ast_strlen_zero(id)) {
1959 ast_str_append(&buf, 0, "ActionID: %s\r\n", id);
1960 }
1961
1962 if (listflag) {
1963 /* Start, complete, cancelled */
1964 ast_str_append(&buf, 0, "EventList: %s\r\n", listflag);
1965 }
1966
1967 if (msg != MSG_MOREDATA) {
1968 if (msg) {
1969 ast_str_append(&buf, 0, "Message: %s\r\n", msg);
1970 }
1971 ast_str_append(&buf, 0, "\r\n");
1972 }
1973
1974 astman_flush(s, buf);
1975}

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

◆ async_goto_with_discard_bridge_after()

static int async_goto_with_discard_bridge_after ( struct ast_channel chan,
const char *  context,
const char *  exten,
int  priority 
)
static

Definition at line 3946 of file manager.c.

3947{
3949 return ast_async_goto(chan, context, exten, priority);
3950}
void ast_bridge_discard_after_goto(struct ast_channel *chan)
Discard channel after bridge goto location.
Definition: bridge_after.c:384
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:6988

References ast_async_goto(), ast_bridge_discard_after_goto(), voicemailpwcheck::context, and priority.

Referenced by action_redirect().

◆ authenticate()

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

Definition at line 2328 of file manager.c.

2329{
2330 const char *username = astman_get_header(m, "Username");
2331 const char *password = astman_get_header(m, "Secret");
2332 int error = -1;
2333 struct ast_manager_user *user = NULL;
2334 regex_t *regex_filter;
2335 struct ao2_iterator filter_iter;
2336
2337 if (ast_strlen_zero(username)) { /* missing username */
2338 return -1;
2339 }
2340
2341 /* locate user in locked state */
2343
2344 if (!(user = get_manager_by_name_locked(username))) {
2345 report_invalid_user(s, username);
2346 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
2347 } else if (user->acl && (ast_apply_acl(user->acl, &s->session->addr, "Manager User ACL: ") == AST_SENSE_DENY)) {
2348 report_failed_acl(s, username);
2349 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
2350 } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
2351 const char *key = astman_get_header(m, "Key");
2352 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
2353 int x;
2354 int len = 0;
2355 char md5key[256] = "";
2356 struct MD5Context md5;
2357 unsigned char digest[16];
2358
2359 MD5Init(&md5);
2360 MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
2361 MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
2362 MD5Final(digest, &md5);
2363 for (x = 0; x < 16; x++)
2364 len += sprintf(md5key + len, "%02hhx", digest[x]);
2365 if (!strcmp(md5key, key)) {
2366 error = 0;
2367 } else {
2368 report_failed_challenge_response(s, key, md5key);
2369 }
2370 } else {
2371 ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n",
2372 S_OR(s->session->challenge, ""));
2373 }
2374 } else if (user->secret) {
2375 if (!strcmp(password, user->secret)) {
2376 error = 0;
2377 } else {
2378 report_inval_password(s, username);
2379 }
2380 }
2381
2382 if (error) {
2383 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
2385 return -1;
2386 }
2387
2388 /* auth complete */
2389
2390 /* All of the user parameters are copied to the session so that in the event
2391 * of a reload and a configuration change, the session parameters are not
2392 * changed. */
2393 ast_copy_string(s->session->username, username, sizeof(s->session->username));
2394 s->session->readperm = user->readperm;
2395 s->session->writeperm = user->writeperm;
2396 s->session->writetimeout = user->writetimeout;
2397 if (user->chanvars) {
2398 s->session->chanvars = ast_variables_dup(user->chanvars);
2399 }
2400
2401 filter_iter = ao2_iterator_init(user->includefilters, 0);
2402 while ((regex_filter = ao2_iterator_next(&filter_iter))) {
2403 ao2_t_link(s->session->includefilters, regex_filter, "add include user filter to session");
2404 ao2_t_ref(regex_filter, -1, "remove iterator ref");
2405 }
2406 ao2_iterator_destroy(&filter_iter);
2407
2408 filter_iter = ao2_iterator_init(user->excludefilters, 0);
2409 while ((regex_filter = ao2_iterator_next(&filter_iter))) {
2410 ao2_t_link(s->session->excludefilters, regex_filter, "add exclude user filter to session");
2411 ao2_t_ref(regex_filter, -1, "remove iterator ref");
2412 }
2413 ao2_iterator_destroy(&filter_iter);
2414
2415 s->session->sessionstart = time(NULL);
2417 set_eventmask(s, astman_get_header(m, "Events"));
2418
2420
2422 return 0;
2423}
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:55
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:1042
static void report_invalid_user(const struct mansession *s, const char *username)
Definition: manager.c:2108
static void report_failed_acl(const struct mansession *s, const char *username)
Definition: manager.c:2133
static void report_failed_challenge_response(const struct mansession *s, const char *response, const char *expected_response)
Definition: manager.c:2266
static void report_inval_password(const struct mansession *s, const char *username)
Definition: manager.c:2158
static void report_auth_success(const struct mansession *s)
Definition: manager.c:2183
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[MD5_DIGEST_LENGTH], struct MD5Context *context)
Definition: md5.c:120
Definition: md5.h:30
user descriptor, as read from the config file.
Definition: manager.c:342
struct timeval sessionstart_tv
Definition: manager.c:287
time_t sessionstart
Definition: manager.c:286
structure to hold users read from phoneprov_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::challenge, mansession_session::chanvars, error(), mansession_session::excludefilters, get_manager_by_name_locked(), mansession_session::includefilters, 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::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 815 of file manager.c.

816{
817 int i;
818 char *sep = "";
819
820 ast_str_reset(*res);
821 if (authority != EVENT_FLAG_SHUTDOWN) {
822 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
823 if (authority & perms[i].num) {
824 ast_str_append(res, 0, "%s%s", sep, perms[i].label);
825 sep = ",";
826 }
827 }
828 }
829
830 if (ast_str_strlen(*res) == 0) {
831 /* replace empty string with something sensible */
832 ast_str_append(res, 0, "<none>");
833 }
834
835 return ast_str_buffer(*res);
836}

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

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

967{
968 struct ao2_container *sessions;
969 struct mansession_session *newsession;
970
971 newsession = ao2_alloc(sizeof(*newsession), session_destructor);
972 if (!newsession) {
973 return NULL;
974 }
975
978 if (!newsession->includefilters || !newsession->excludefilters) {
979 ao2_ref(newsession, -1);
980 return NULL;
981 }
982
983 newsession->waiting_thread = AST_PTHREADT_NULL;
984 newsession->writetimeout = 100;
985 newsession->send_events = -1;
986 ast_sockaddr_copy(&newsession->addr, addr);
987
988 ast_mutex_init(&newsession->notify_lock);
989
990 sessions = ao2_global_obj_ref(mgr_sessions);
991 if (sessions) {
992 ao2_link(sessions, newsession);
993 ao2_ref(sessions, -1);
994 }
995
996 return newsession;
997}
#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:935
#define ast_mutex_init(pmutex)
Definition: lock.h:193
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::excludefilters, mansession_session::includefilters, mansession_session::notify_lock, NULL, mansession_session::send_events, session_destructor(), sessions, mansession_session::waiting_thread, 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 4239 of file manager.c.

4240{
4241 char *cmd_copy, *cur_cmd;
4242 char *cmd_words[AST_MAX_CMD_LEN] = { NULL, };
4243 int i;
4244
4245 cmd_copy = ast_strdupa(cmd);
4246 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) {
4247 cur_cmd = ast_strip(cur_cmd);
4248 if (ast_strlen_zero(cur_cmd)) {
4249 i--;
4250 continue;
4251 }
4252
4253 cmd_words[i] = cur_cmd;
4254 }
4255
4256 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) {
4257 int j, match = 1;
4258
4259 for (j = 0; command_blacklist[i].words[j]; j++) {
4260 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) {
4261 match = 0;
4262 break;
4263 }
4264 }
4265
4266 if (match) {
4267 return 1;
4268 }
4269 }
4270
4271 return 0;
4272}
#define AST_MAX_CMD_LEN
Definition: cli.h:48
static const struct @377 command_blacklist[]
#define MAX_BLACKLIST_CMD_LEN
Descriptor for a manager session, either on the AMI socket or over HTTP.
Definition: manager.c:220
const char * words[AST_MAX_CMD_LEN]
Definition: manager.c:222

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

1020{
1021 struct ao2_container *sessions;
1023 int inuse = 0;
1024
1025 sessions = ao2_global_obj_ref(mgr_sessions);
1026 if (sessions) {
1027 session = ao2_find(sessions, (char *) name, 0);
1028 ao2_ref(sessions, -1);
1029 if (session) {
1031 inuse = 1;
1032 }
1033 }
1034 return inuse;
1035}
#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 6661 of file manager.c.

6663{
6664 int res = 0;
6665 struct ao2_iterator iter;
6666 char *current_channel_uid;
6667
6668 iter = ao2_iterator_init(bridge_snapshot->channels, 0);
6669 while ((current_channel_uid = ao2_iterator_next(&iter))) {
6670 struct ast_channel_snapshot *current_channel_snapshot;
6671 int add_channel_res;
6672
6673 /* Don't add the original channel to the list - it's either already in there,
6674 * or it's the channel we want the map for */
6675 if (!strcmp(current_channel_uid, channel_snapshot->base->uniqueid)) {
6676 ao2_ref(current_channel_uid, -1);
6677 continue;
6678 }
6679
6680 current_channel_snapshot = ast_channel_snapshot_get_latest(current_channel_uid);
6681 if (!current_channel_snapshot) {
6682 ast_debug(5, "Unable to get channel snapshot\n");
6683 ao2_ref(current_channel_uid, -1);
6684 continue;
6685 }
6686
6687 add_channel_res = coreshowchannelmap_add_to_map(channel_map, current_channel_snapshot->base->name);
6688 if (add_channel_res) {
6689 res = 1;
6690 ao2_ref(current_channel_snapshot, -1);
6691 ao2_ref(current_channel_uid, -1);
6692 break;
6693 }
6694
6695 /* 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 */
6696 if (ast_begins_with(current_channel_snapshot->base->name, "Local")) {
6697 struct ast_channel_snapshot *other_local_snapshot;
6698 struct ast_bridge_snapshot *other_bridge_snapshot;
6699 int size = strlen(current_channel_snapshot->base->name);
6700 char other_local[size + 1];
6701
6702 /* Don't copy the trailing number - set it to 1 or 2, whichever one it currently is not */
6703 ast_copy_string(other_local, current_channel_snapshot->base->name, size);
6704 other_local[size - 1] = ast_ends_with(current_channel_snapshot->base->name, "1") ? '2' : '1';
6705 other_local[size] = '\0';
6706
6707 other_local_snapshot = ast_channel_snapshot_get_latest_by_name(other_local);
6708 if (!other_local_snapshot) {
6709 ast_debug(5, "Unable to get other local channel snapshot\n");
6710 ao2_ref(current_channel_snapshot, -1);
6711 ao2_ref(current_channel_uid, -1);
6712 continue;
6713 }
6714
6715 if (coreshowchannelmap_add_to_map(channel_map, other_local_snapshot->base->name)) {
6716 res = 1;
6717 ao2_ref(current_channel_snapshot, -1);
6718 ao2_ref(current_channel_uid, -1);
6719 ao2_ref(other_local_snapshot, -1);
6720 break;
6721 }
6722
6723 other_bridge_snapshot = ast_bridge_get_snapshot_by_uniqueid(other_local_snapshot->bridge->id);
6724 if (other_bridge_snapshot) {
6725 res = coreshowchannelmap_add_connected_channels(channel_map, other_local_snapshot, other_bridge_snapshot);
6726 }
6727
6728 ao2_ref(current_channel_snapshot, -1);
6729 ao2_ref(current_channel_uid, -1);
6730 ao2_ref(other_local_snapshot, -1);
6731 ao2_ref(other_bridge_snapshot, -1);
6732
6733 if (res) {
6734 break;
6735 }
6736 }
6737 }
6738 ao2_iterator_destroy(&iter);
6739
6740 return res;
6741}
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:6644
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
struct ao2_container * channels
Definition: bridge.h:335
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 6644 of file manager.c.

6645{
6646 char *str;
6647
6648 str = ast_strdup(s);
6649 if (!str) {
6650 ast_log(LOG_ERROR, "Unable to append channel to channel map\n");
6651 return 1;
6652 }
6653
6654 /* If this is a duplicate, it will be ignored */
6656
6657 return 0;
6658}
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 7272 of file manager.c.

7273{
7274 struct message m = { 0 };
7275 char header_buf[sizeof(s->session->inbuf)] = { '\0' };
7276 int res;
7277 int hdr_loss;
7278 time_t now;
7279
7280 hdr_loss = 0;
7281 for (;;) {
7282 /* Check if any events are pending and do them if needed */
7283 if (process_events(s)) {
7284 res = -1;
7285 break;
7286 }
7287 res = get_input(s, header_buf);
7288 if (res == 0) {
7289 /* No input line received. */
7290 if (!s->session->authenticated) {
7291 if (time(&now) == -1) {
7292 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
7293 res = -1;
7294 break;
7295 }
7296
7297 if (now - s->session->authstart > authtimeout) {
7298 if (displayconnects) {
7299 ast_verb(2, "Client from %s, failed to authenticate in %d seconds\n", ast_sockaddr_stringify_addr(&s->session->addr), authtimeout);
7300 }
7301 res = -1;
7302 break;
7303 }
7304 }
7305 continue;
7306 } else if (res > 0) {
7307 /* Input line received. */
7308 if (ast_strlen_zero(header_buf)) {
7309 if (hdr_loss) {
7310 mansession_lock(s);
7311 astman_send_error(s, &m, "Too many lines in message or allocation failure");
7313 res = 0;
7314 } else {
7315 switch (s->parsing) {
7316 case MESSAGE_OKAY:
7317 res = process_message(s, &m) ? -1 : 0;
7318 break;
7320 handle_parse_error(s, &m, "Failed to parse message: line too long");
7321 res = 0;
7322 break;
7323 }
7324 }
7325 break;
7326 } else if (m.hdrcount < ARRAY_LEN(m.headers)) {
7327 m.headers[m.hdrcount] = ast_strdup(header_buf);
7328 if (!m.headers[m.hdrcount]) {
7329 /* Allocation failure. */
7330 hdr_loss = 1;
7331 } else {
7332 ++m.hdrcount;
7333 }
7334 } else {
7335 /* Too many lines in message. */
7336 hdr_loss = 1;
7337 }
7338 } else {
7339 /* Input error. */
7340 break;
7341 }
7342 }
7343
7345
7346 return res;
7347}
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:7023
static void astman_free_headers(struct message *m)
Free headers inside message structure, but not the message structure itself.
Definition: manager.c:1667
static int displayconnects
Definition: manager.c:161
static int get_input(struct mansession *s, char *output)
Definition: manager.c:7151
static void handle_parse_error(struct mansession *s, struct message *m, char *error)
Definition: manager.c:7255
static int process_events(struct mansession *s)
Definition: manager.c:6410
static int authtimeout
Definition: manager.c:170
time_t authstart
Definition: manager.c:302
char inbuf[1025]
Definition: manager.c:294
enum mansession_message_parsing parsing
Definition: manager.c:327

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

924{
925 struct event_filter_entry *entry = obj;
926 if (entry->regex_filter) {
927 regfree(entry->regex_filter);
928 ast_free(entry->regex_filter);
929 }
930 ast_free(entry->event_name);
931 ast_free(entry->header_name);
932 ast_free(entry->string_filter);
933}
Definition: manager.c:403
char * string_filter
Definition: manager.c:406
char * event_name
Definition: manager.c:407
regex_t * regex_filter
Definition: manager.c:405
char * header_name
Definition: manager.c:409

References ast_free, event_filter_entry::event_name, event_filter_entry::header_name, event_filter_entry::regex_filter, and event_filter_entry::string_filter.

Referenced by manager_add_filter().

◆ fast_originate()

static void * fast_originate ( void *  data)
static

Definition at line 4391 of file manager.c.

4392{
4393 struct fast_originate_helper *in = data;
4394 int res;
4395 int reason = 0;
4396 struct ast_channel *chan = NULL, *chans[1];
4397 char requested_channel[AST_CHANNEL_NAME];
4398 struct ast_assigned_ids assignedids = {
4399 .uniqueid = in->channelid,
4400 .uniqueid2 = in->otherchannelid
4401 };
4402
4403 if (!ast_strlen_zero(in->app)) {
4404 res = ast_pbx_outgoing_app(in->tech, in->cap, in->data,
4405 in->timeout, in->app, in->appdata, &reason,
4407 S_OR(in->cid_num, NULL),
4408 S_OR(in->cid_name, NULL),
4409 in->vars, in->account, &chan, &assignedids);
4410 } else {
4411 res = ast_pbx_outgoing_exten(in->tech, in->cap, in->data,
4412 in->timeout, in->context, in->exten, in->priority, &reason,
4414 S_OR(in->cid_num, NULL),
4415 S_OR(in->cid_name, NULL),
4416 in->vars, in->account, &chan, in->early_media, &assignedids);
4417 }
4418
4419 if (!chan) {
4420 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);
4421 }
4422 /* Tell the manager what happened with the channel */
4423 chans[0] = chan;
4424 if (!ast_strlen_zero(in->app)) {
4425 ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
4426 "%s"
4427 "Response: %s\r\n"
4428 "Channel: %s\r\n"
4429 "Application: %s\r\n"
4430 "Data: %s\r\n"
4431 "Reason: %d\r\n"
4432 "Uniqueid: %s\r\n"
4433 "CallerIDNum: %s\r\n"
4434 "CallerIDName: %s\r\n",
4435 in->idtext, res ? "Failure" : "Success",
4436 chan ? ast_channel_name(chan) : requested_channel,
4437 in->app, in->appdata, reason,
4438 chan ? ast_channel_uniqueid(chan) : S_OR(in->channelid, "<unknown>"),
4439 S_OR(in->cid_num, "<unknown>"),
4440 S_OR(in->cid_name, "<unknown>")
4441 );
4442 } else {
4443 ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
4444 "%s"
4445 "Response: %s\r\n"
4446 "Channel: %s\r\n"
4447 "Context: %s\r\n"
4448 "Exten: %s\r\n"
4449 "Reason: %d\r\n"
4450 "Uniqueid: %s\r\n"
4451 "CallerIDNum: %s\r\n"
4452 "CallerIDName: %s\r\n",
4453 in->idtext, res ? "Failure" : "Success",
4454 chan ? ast_channel_name(chan) : requested_channel,
4455 in->context, in->exten, reason,
4456 chan ? ast_channel_uniqueid(chan) : S_OR(in->channelid, "<unknown>"),
4457 S_OR(in->cid_num, "<unknown>"),
4458 S_OR(in->cid_name, "<unknown>")
4459 );
4460 }
4461
4462 /* Locked and ref'd by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
4463 if (chan) {
4464 ast_channel_unlock(chan);
4465 ast_channel_unref(chan);
4466 }
4468 return NULL;
4469}
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define AST_CHANNEL_NAME
Definition: channel.h:173
#define ast_manager_event_multichan(category, event, nchans, chans, contents,...)
Definition: manager.h:261
#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:7935
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().

◆ file_in_modules_dir()

static int file_in_modules_dir ( const char *  filename)
static

Check if the given file path is in the modules dir or not.

Note
When the module is being loaded / reloaded / unloaded, the modules dir is automatically prepended
Returns
1 if inside modules dir
0 if outside modules dir
-1 on failure

Definition at line 6877 of file manager.c.

6878{
6879 char *stripped_filename;
6880 RAII_VAR(char *, path, NULL, ast_free);
6881 RAII_VAR(char *, real_path, NULL, ast_free);
6882
6883 /* Don't bother checking */
6884 if (live_dangerously) {
6885 return 1;
6886 }
6887
6888 stripped_filename = ast_strip(ast_strdupa(filename));
6889
6890 /* Always prepend the modules dir since that is what the code does for ModuleLoad */
6891 if (ast_asprintf(&path, "%s/%s", ast_config_AST_MODULE_DIR, stripped_filename) == -1) {
6892 return -1;
6893 }
6894
6895 real_path = realpath(path, NULL);
6896 if (!real_path) {
6897 return -1;
6898 }
6899
6900 return ast_begins_with(real_path, ast_config_AST_MODULE_DIR);
6901}
const char * ast_config_AST_MODULE_DIR
Definition: options.c:154

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

Referenced by manager_moduleload().

◆ filter_cmp_fn()

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

Definition at line 5592 of file manager.c.

5593{
5594 struct eventqent *eqe = arg;
5595 struct event_filter_entry *filter_entry = obj;
5596 char *line_buffer_start = NULL;
5597 char *line_buffer = NULL;
5598 char *line = NULL;
5599 int match = 0;
5600 int *result = data;
5601
5602 if (filter_entry->event_name_hash) {
5603 if (eqe->event_name_hash != filter_entry->event_name_hash) {
5604 goto done;
5605 }
5606 }
5607
5608 /* We're looking at the entire event data */
5609 if (!filter_entry->header_name) {
5610 match = match_eventdata(filter_entry, eqe->eventdata);
5611 goto done;
5612 }
5613
5614 /* We're looking at a specific header */
5615 line_buffer_start = ast_strdup(eqe->eventdata);
5616 line_buffer = line_buffer_start;
5617 if (!line_buffer_start) {
5618 goto done;
5619 }
5620
5621 while ((line = ast_read_line_from_buffer(&line_buffer))) {
5622 if (ast_begins_with(line, filter_entry->header_name)) {
5623 line += strlen(filter_entry->header_name);
5624 line = ast_skip_blanks(line);
5625 if (ast_strlen_zero(line)) {
5626 continue;
5627 }
5628 match = match_eventdata(filter_entry, line);
5629 if (match) {
5630 ast_free(line_buffer_start);
5631 line_buffer_start = NULL;
5632 break;
5633 }
5634 }
5635 }
5636
5637 ast_free(line_buffer_start);
5638
5639done:
5640
5641 *result = match;
5642 return match ? CMP_MATCH | CMP_STOP : 0;
5643}
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
static int match_eventdata(struct event_filter_entry *entry, const char *eventdata)
Test eventdata against a filter entry.
Definition: manager.c:5572
char * ast_read_line_from_buffer(char **buffer)
Read lines from a string buffer.
Definition: strings.c:385
unsigned int event_name_hash
Definition: manager.c:408
int done
Definition: test_amihooks.c:48

References ast_begins_with(), ast_free, ast_read_line_from_buffer(), ast_skip_blanks(), ast_strdup, ast_strlen_zero(), CMP_MATCH, CMP_STOP, done, eventqent::event_name_hash, event_filter_entry::event_name_hash, event_filter_entry::header_name, match(), match_eventdata(), NULL, and result.

Referenced by should_send_event().

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

778{
779 if (!(writepermlist & EVENT_FLAG_SYSTEM)
780 && (
781 strstr(evaluating, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */
782 strstr(evaluating, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
783 )) {
784 return 0;
785 }
786 return 1;
787}

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

3634{
3635 struct timeval now;
3636 long elapsed_seconds;
3637 struct ast_bridge *bridge;
3638 RAII_VAR(struct ast_str *, variable_str, NULL, ast_free);
3639 struct ast_str *write_transpath = ast_str_alloca(256);
3640 struct ast_str *read_transpath = ast_str_alloca(256);
3641 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
3642 struct ast_party_id effective_id;
3643 int i;
3644 RAII_VAR(struct ast_channel_snapshot *, snapshot,
3646 ao2_cleanup);
3647 RAII_VAR(struct ast_str *, snapshot_str, NULL, ast_free);
3648
3649 if (!snapshot) {
3650 return;
3651 }
3652
3653 snapshot_str = ast_manager_build_channel_state_string(snapshot);
3654 if (!snapshot_str) {
3655 return;
3656 }
3657
3658 if (all_variables) {
3659 variable_str = ast_str_create(2048);
3660 } else {
3661 variable_str = ast_str_create(1024);
3662 }
3663 if (!variable_str) {
3664 return;
3665 }
3666
3667 now = ast_tvnow();
3668 elapsed_seconds = ast_tvdiff_sec(now, ast_channel_creationtime(chan));
3669
3670 /* Even if all_variables has been specified, explicitly requested variables
3671 * may be global variables or dialplan functions */
3672 for (i = 0; i < varc; i++) {
3673 char valbuf[512], *ret = NULL;
3674
3675 if (vars[i][strlen(vars[i]) - 1] == ')') {
3676 if (ast_func_read(chan, vars[i], valbuf, sizeof(valbuf)) < 0) {
3677 valbuf[0] = '\0';
3678 }
3679 ret = valbuf;
3680 } else {
3681 pbx_retrieve_variable(chan, vars[i], &ret, valbuf, sizeof(valbuf), NULL);
3682 }
3683
3684 ast_str_append(&variable_str, 0, "Variable: %s=%s\r\n", vars[i], ret);
3685 }
3686
3687 /* Walk all channel variables and add them */
3688 if (all_variables) {
3689 struct ast_var_t *variables;
3690
3692 ast_str_append(&variable_str, 0, "Variable: %s=%s\r\n",
3693 ast_var_name(variables), ast_var_value(variables));
3694 }
3695 }
3696
3697 bridge = ast_channel_get_bridge(chan);
3698 effective_id = ast_channel_connected_effective_id(chan);
3699
3700 astman_append(s,
3701 "Event: Status\r\n"
3702 "Privilege: Call\r\n"
3703 "%s"
3704 "Type: %s\r\n"
3705 "DNID: %s\r\n"
3706 "EffectiveConnectedLineNum: %s\r\n"
3707 "EffectiveConnectedLineName: %s\r\n"
3708 "TimeToHangup: %ld\r\n"
3709 "BridgeID: %s\r\n"
3710 "Application: %s\r\n"
3711 "Data: %s\r\n"
3712 "Nativeformats: %s\r\n"
3713 "Readformat: %s\r\n"
3714 "Readtrans: %s\r\n"
3715 "Writeformat: %s\r\n"
3716 "Writetrans: %s\r\n"
3717 "Callgroup: %llu\r\n"
3718 "Pickupgroup: %llu\r\n"
3719 "Seconds: %ld\r\n"
3720 "%s"
3721 "%s"
3722 "\r\n",
3723 ast_str_buffer(snapshot_str),
3724 ast_channel_tech(chan)->type,
3725 S_OR(ast_channel_dialed(chan)->number.str, ""),
3726 S_COR(effective_id.number.valid, effective_id.number.str, "<unknown>"),
3727 S_COR(effective_id.name.valid, effective_id.name.str, "<unknown>"),
3728 (long)ast_channel_whentohangup(chan)->tv_sec,
3729 bridge ? bridge->uniqueid : "",
3730 ast_channel_appl(chan),
3731 ast_channel_data(chan),
3734 ast_translate_path_to_str(ast_channel_readtrans(chan), &read_transpath),
3736 ast_translate_path_to_str(ast_channel_writetrans(chan), &write_transpath),
3739 (long)elapsed_seconds,
3740 ast_str_buffer(variable_str),
3741 id_text);
3742 ++*count;
3743
3744 ao2_cleanup(bridge);
3745}
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:10535
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.
Structure that contains information about a bridge.
Definition: bridge.h:353
const ast_string_field uniqueid
Definition: bridge.h:405
Information needed to identify an endpoint in a call.
Definition: channel.h:340
Number structure.
Definition: app_followme.c:157
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 7151 of file manager.c.

7152{
7153 int res, x;
7154 int maxlen = sizeof(s->session->inbuf) - 1;
7155 char *src = s->session->inbuf;
7156 int timeout = -1;
7157 time_t now;
7158
7159 /*
7160 * Look for \r\n within the buffer. If found, copy to the output
7161 * buffer and return, trimming the \r\n (not used afterwards).
7162 */
7163 for (x = 0; x < s->session->inlen; x++) {
7164 int cr; /* set if we have \r */
7165 if (src[x] == '\r' && x+1 < s->session->inlen && src[x + 1] == '\n') {
7166 cr = 2; /* Found. Update length to include \r\n */
7167 } else if (src[x] == '\n') {
7168 cr = 1; /* also accept \n only */
7169 } else {
7170 continue;
7171 }
7172 memmove(output, src, x); /*... but trim \r\n */
7173 output[x] = '\0'; /* terminate the string */
7174 x += cr; /* number of bytes used */
7175 s->session->inlen -= x; /* remaining size */
7176 memmove(src, src + x, s->session->inlen); /* remove used bytes */
7177 return 1;
7178 }
7179 if (s->session->inlen >= maxlen) {
7180 /* no crlf found, and buffer full - sorry, too long for us
7181 * keep the last character in case we are in the middle of a CRLF. */
7182 ast_log(LOG_WARNING, "Discarding message from %s. Line too long: %.25s...\n", ast_sockaddr_stringify_addr(&s->session->addr), src);
7183 src[0] = src[s->session->inlen - 1];
7184 s->session->inlen = 1;
7186 }
7187 res = 0;
7188 while (res == 0) {
7189 /* calculate a timeout if we are not authenticated */
7190 if (!s->session->authenticated) {
7191 if(time(&now) == -1) {
7192 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
7193 return -1;
7194 }
7195
7196 timeout = (authtimeout - (now - s->session->authstart)) * 1000;
7197 if (timeout < 0) {
7198 /* we have timed out */
7199 return 0;
7200 }
7201 }
7202
7204 if (s->session->pending_event) {
7205 s->session->pending_event = 0;
7207 return 0;
7208 }
7209 s->session->waiting_thread = pthread_self();
7211
7213
7217 }
7218 if (res < 0) {
7219 if (s->session->kicked) {
7220 ast_debug(1, "Manager session has been kicked\n");
7221 return -1;
7222 }
7223 /* If we get a signal from some other thread (typically because
7224 * there are new events queued), return 0 to notify the caller.
7225 */
7226 if (errno == EINTR || errno == EAGAIN) {
7227 return 0;
7228 }
7229 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
7230 return -1;
7231 }
7232
7233 ao2_lock(s->session);
7234 res = ast_iostream_read(s->session->stream, src + s->session->inlen, maxlen - s->session->inlen);
7235 if (res < 1) {
7236 res = -1; /* error return */
7237 } else {
7238 s->session->inlen += res;
7239 src[s->session->inlen] = '\0';
7240 res = 0;
7241 }
7242 ao2_unlock(s->session);
7243 return res;
7244}
ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t count)
Read data from an iostream.
Definition: iostream.c:284
unsigned int kicked
Definition: manager.c:307

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

1043{
1044 struct ast_manager_user *user = NULL;
1045
1046 AST_RWLIST_TRAVERSE(&users, user, list) {
1047 if (!strcasecmp(user->username, name)) {
1048 break;
1049 }
1050 }
1051
1052 return user;
1053}
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 862 of file manager.c.

863{
864 int x = 0, ret = 0;
865
866 if (!instr) {
867 return 0;
868 }
869
870 for (x = 0; x < ARRAY_LEN(perms); x++) {
871 if (ast_instring(instr, perms[x].label, ',')) {
872 ret |= perms[x].num;
873 }
874 }
875
876 return ret;
877}
static int ast_instring(const char *bigstr, const char *smallstr, const char delim)
Definition: manager.c:843

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

695{
696 struct eventqent *ret;
697
700 /* the list is never empty now, but may become so when
701 * we optimize it in the future, so be prepared.
702 */
703 if (ret) {
705 }
707 return ret;
708}
#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 1408 of file manager.c.

1409{
1410 struct ao2_container *sessions;
1412 struct ao2_iterator i;
1413 int fd = -1;
1414 int found = 0;
1415
1416 switch (cmd) {
1417 case CLI_INIT:
1418 e->command = "manager kick session";
1419 e->usage =
1420 "Usage: manager kick session <file descriptor>\n"
1421 " Kick an active Asterisk Manager Interface session\n";
1422 return NULL;
1423 case CLI_GENERATE:
1424 return NULL;
1425 }
1426
1427 if (a->argc != 4) {
1428 return CLI_SHOWUSAGE;
1429 }
1430
1431 fd = atoi(a->argv[3]);
1432 if (fd <= 0) { /* STDOUT won't be a valid AMI fd either */
1433 ast_cli(a->fd, "Invalid AMI file descriptor: %s\n", a->argv[3]);
1434 return CLI_FAILURE;
1435 }
1436
1437 sessions = ao2_global_obj_ref(mgr_sessions);
1438 if (sessions) {
1440 ao2_ref(sessions, -1);
1441 while ((session = ao2_iterator_next(&i))) {
1443 if (session->stream) {
1444 if (ast_iostream_get_fd(session->stream) == fd) {
1445 if (session->kicked) {
1446 ast_cli(a->fd, "Manager session using file descriptor %d has already been kicked\n", fd);
1449 break;
1450 }
1451 fd = ast_iostream_get_fd(session->stream);
1452 found = fd;
1453 ast_cli(a->fd, "Kicking manager session connected using file descriptor %d\n", fd);
1454 ast_mutex_lock(&session->notify_lock);
1455 session->kicked = 1;
1456 if (session->waiting_thread != AST_PTHREADT_NULL) {
1457 pthread_kill(session->waiting_thread, SIGURG);
1458 }
1459 ast_mutex_unlock(&session->notify_lock);
1462 break;
1463 }
1464 }
1467 }
1469 }
1470
1471 if (!found) {
1472 ast_cli(a->fd, "No manager session found using file descriptor %d\n", fd);
1473 }
1474 return CLI_SUCCESS;
1475}
#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 1557 of file manager.c.

1558{
1559 switch (cmd) {
1560 case CLI_INIT:
1561 e->command = "manager reload";
1562 e->usage =
1563 "Usage: manager reload\n"
1564 " Reloads the manager configuration.\n";
1565 return NULL;
1566 case CLI_GENERATE:
1567 return NULL;
1568 }
1569 if (a->argc > 2) {
1570 return CLI_SHOWUSAGE;
1571 }
1572 reload_module();
1573 return CLI_SUCCESS;
1574}
static int reload_module(void)
Definition: manager.c:10075

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

1226{
1227 switch (cmd) {
1228 case CLI_INIT:
1229 e->command = "manager set debug [on|off]";
1230 e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n";
1231 return NULL;
1232 case CLI_GENERATE:
1233 return NULL;
1234 }
1235
1236 if (a->argc == 3) {
1237 ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off");
1238 } else if (a->argc == 4) {
1239 if (!strcasecmp(a->argv[3], "on")) {
1240 manager_debug = 1;
1241 } else if (!strcasecmp(a->argv[3], "off")) {
1242 manager_debug = 0;
1243 } else {
1244 return CLI_SHOWUSAGE;
1245 }
1246 }
1247 return CLI_SUCCESS;
1248}

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

7256{
7257 mansession_lock(s);
7258 astman_send_error(s, m, error);
7259 s->parsing = MESSAGE_OKAY;
7261}

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

1251{
1252 struct ast_manager_user *user = NULL;
1253 int l;
1254 struct ast_str *rauthority = ast_str_alloca(MAX_AUTH_PERM_STRING);
1255 struct ast_str *wauthority = ast_str_alloca(MAX_AUTH_PERM_STRING);
1256 struct ast_variable *v;
1257
1258 switch (cmd) {
1259 case CLI_INIT:
1260 e->command = "manager show user";
1261 e->usage =
1262 " Usage: manager show user <user>\n"
1263 " Display all information related to the manager user specified.\n";
1264 return NULL;
1265 case CLI_GENERATE:
1266 l = strlen(a->word);
1267 if (a->pos != 3) {
1268 return NULL;
1269 }
1271 AST_RWLIST_TRAVERSE(&users, user, list) {
1272 if (!strncasecmp(a->word, user->username, l)) {
1273 if (ast_cli_completion_add(ast_strdup(user->username))) {
1274 break;
1275 }
1276 }
1277 }
1279 return NULL;
1280 }
1281
1282 if (a->argc != 4) {
1283 return CLI_SHOWUSAGE;
1284 }
1285
1287
1288 if (!(user = get_manager_by_name_locked(a->argv[3]))) {
1289 ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]);
1291 return CLI_SUCCESS;
1292 }
1293
1294 ast_cli(a->fd, "\n");
1295 ast_cli(a->fd,
1296 " username: %s\n"
1297 " secret: %s\n"
1298 " ACL: %s\n"
1299 " read perm: %s\n"
1300 " write perm: %s\n"
1301 " displayconnects: %s\n"
1302 "allowmultiplelogin: %s\n",
1303 S_OR(user->username, "(N/A)"),
1304 (user->secret ? "<Set>" : "(N/A)"),
1305 ((user->acl && !ast_acl_list_is_empty(user->acl)) ? "yes" : "no"),
1306 user_authority_to_str(user->readperm, &rauthority),
1307 user_authority_to_str(user->writeperm, &wauthority),
1308 (user->displayconnects ? "yes" : "no"),
1309 (user->allowmultiplelogin ? "yes" : "no"));
1310 ast_cli(a->fd, " Variables: \n");
1311 for (v = user->chanvars ; v ; v = v->next) {
1312 ast_cli(a->fd, " %s = %s\n", v->name, v->value);
1313 }
1314 if (!ast_acl_list_is_empty(user->acl)) {
1315 ast_acl_output(a->fd, user->acl, NULL);
1316 }
1317
1319
1320 return CLI_SUCCESS;
1321}
void ast_acl_output(int fd, struct ast_acl_list *acl, const char *prefix)
output an ACL to the provided fd
Definition: acl.c:1115
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:2768
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:791

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

1324{
1325 struct ast_manager_user *user = NULL;
1326 int count_amu = 0;
1327 switch (cmd) {
1328 case CLI_INIT:
1329 e->command = "manager show users";
1330 e->usage =
1331 "Usage: manager show users\n"
1332 " Prints a listing of all managers that are currently configured on that\n"
1333 " system.\n";
1334 return NULL;
1335 case CLI_GENERATE:
1336 return NULL;
1337 }
1338 if (a->argc != 3) {
1339 return CLI_SHOWUSAGE;
1340 }
1341
1343
1344 /* If there are no users, print out something along those lines */
1345 if (AST_RWLIST_EMPTY(&users)) {
1346 ast_cli(a->fd, "There are no manager users.\n");
1348 return CLI_SUCCESS;
1349 }
1350
1351 ast_cli(a->fd, "\nusername\n--------\n");
1352
1353 AST_RWLIST_TRAVERSE(&users, user, list) {
1354 ast_cli(a->fd, "%s\n", user->username);
1355 count_amu++;
1356 }
1357
1359
1360 ast_cli(a->fd,"-------------------\n"
1361 "%d manager users configured.\n", count_amu);
1362 return CLI_SUCCESS;
1363}

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

1078{
1079 struct manager_action *cur;
1080 struct ast_str *authority;
1081 int num;
1082 int l;
1083 const char *auth_str;
1084
1085 switch (cmd) {
1086 case CLI_INIT:
1087 e->command = "manager show command";
1088 e->usage =
1089 "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n"
1090 " Shows the detailed description for a specific Asterisk manager interface command.\n";
1091 return NULL;
1092 case CLI_GENERATE:
1093 l = strlen(a->word);
1095 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1096 if (!strncasecmp(a->word, cur->action, l)) {
1098 break;
1099 }
1100 }
1101 }
1103 return NULL;
1104 }
1105 if (a->argc < 4) {
1106 return CLI_SHOWUSAGE;
1107 }
1108
1110
1112 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1113 for (num = 3; num < a->argc; num++) {
1114 if (!strcasecmp(cur->action, a->argv[num])) {
1115 auth_str = authority_to_str(cur->authority, &authority);
1116
1117#ifdef AST_XML_DOCS
1118 if (cur->docsrc == AST_XML_DOC) {
1119 char *synopsis = ast_xmldoc_printable(S_OR(cur->synopsis, "Not available"), 1);
1120 char *since = ast_xmldoc_printable(S_OR(cur->since, "Not available"), 1);
1121 char *description = ast_xmldoc_printable(S_OR(cur->description, "Not available"), 1);
1122 char *syntax = ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1);
1123 char *arguments = ast_xmldoc_printable(S_OR(cur->arguments, "Not available"), 1);
1124 char *privilege = ast_xmldoc_printable(S_OR(auth_str, "Not available"), 1);
1125 char *seealso = ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1);
1126 char *responses = ast_xmldoc_printable("None", 1);
1127
1128 if (!synopsis || !since || !description || !syntax || !arguments
1129 || !privilege || !seealso || !responses) {
1131 ast_free(since);
1132 ast_free(description);
1133 ast_free(syntax);
1134 ast_free(arguments);
1135 ast_free(privilege);
1136 ast_free(seealso);
1137 ast_free(responses);
1138 ast_cli(a->fd, "Allocation failure.\n");
1140
1141 return CLI_FAILURE;
1142 }
1143
1144 ast_cli(a->fd, "\n"
1145 "%s -= Info about Manager Command '%s' =- %s\n\n"
1146 COLORIZE_FMT "\n"
1147 "%s\n\n"
1148 COLORIZE_FMT "\n"
1149 "%s\n\n"
1150 COLORIZE_FMT "\n"
1151 "%s\n\n"
1152 COLORIZE_FMT "\n"
1153 "%s\n\n"
1154 COLORIZE_FMT "\n"
1155 "%s\n\n"
1156 COLORIZE_FMT "\n"
1157 "%s\n\n"
1158 COLORIZE_FMT "\n"
1159 "%s\n\n"
1160 COLORIZE_FMT "\n",
1162 COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
1163 COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
1164 COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
1165 COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), syntax,
1166 COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
1167 COLORIZE(COLOR_MAGENTA, 0, "[Privilege]"), privilege,
1168 COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso,
1169 COLORIZE(COLOR_MAGENTA, 0, "[List Responses]")
1170 );
1171
1172 if (!cur->list_responses) {
1173 ast_cli(a->fd, "%s\n\n", responses);
1174 } else {
1175 struct ast_xml_doc_item *temp;
1176 for (temp = cur->list_responses; temp; temp = AST_LIST_NEXT(temp, next)) {
1177 ast_cli(a->fd, "Event: %s\n", temp->name);
1178 print_event_instance(a, temp);
1179 }
1180 }
1181 ast_cli(a->fd,
1182 COLORIZE_FMT "\n",
1183 COLORIZE(COLOR_MAGENTA, 0, "[End List Responses]")
1184 );
1185
1186 ast_cli(a->fd, "\n"
1187 COLORIZE_FMT "\n",
1188 COLORIZE(COLOR_MAGENTA, 0, "[Final Response]")
1189 );
1190 if (!cur->final_response) {
1191 ast_cli(a->fd, "%s\n\n", responses);
1192 } else {
1193 ast_cli(a->fd, "Event: %s\n", cur->final_response->name);
1195 }
1196 ast_cli(a->fd,
1197 COLORIZE_FMT "\n",
1198 COLORIZE(COLOR_MAGENTA, 0, "[End Final Response]")
1199 );
1200
1202 ast_free(since);
1206 ast_free(privilege);
1208 ast_free(responses);
1209 } else
1210#endif
1211 {
1212 ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
1213 cur->action, cur->synopsis,
1214 auth_str,
1215 S_OR(cur->description, ""));
1216 }
1217 }
1218 }
1219 }
1221
1222 return CLI_SUCCESS;
1223}
static void print_event_instance(struct ast_cli_args *a, struct ast_xml_doc_item *instance)
Definition: manager.c:9261
#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 * since
Definition: xmldoc.h:82
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
const char * ast_term_reset(void)
Returns the terminal reset code.
Definition: term.c:357
#define COLOR_MAGENTA
Definition: term.h:60
const char * ast_term_color(int fgcolor, int bgcolor)
Return a color sequence string.
Definition: term.c:341
#define COLORIZE(fg, bg, str)
Definition: term.h:72
#define COLORIZE_FMT
Shortcut macros for coloring a set of text.
Definition: term.h:71
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_term_color(), ast_term_reset(), AST_XML_DOC, ast_xmldoc_printable(), manager_action::authority, authority_to_str(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, COLOR_MAGENTA, COLORIZE, COLORIZE_FMT, 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, ast_xml_doc_item::since, synopsis, manager_action::synopsis, manager_action::syntax, ast_xml_doc_item::syntax, 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 1366 of file manager.c.

1367{
1368 struct manager_action *cur;
1369 int name_len = 1;
1370 int space_remaining;
1371#define HSMC_FORMAT " %-*.*s %-.*s\n"
1372 switch (cmd) {
1373 case CLI_INIT:
1374 e->command = "manager show commands";
1375 e->usage =
1376 "Usage: manager show commands\n"
1377 " Prints a listing of all the available Asterisk manager interface commands.\n";
1378 return NULL;
1379 case CLI_GENERATE:
1380 return NULL;
1381 }
1382
1384 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1385 int incoming_len = strlen(cur->action);
1386 if (incoming_len > name_len) {
1387 name_len = incoming_len;
1388 }
1389 }
1390
1391 space_remaining = MGR_SHOW_TERMINAL_WIDTH - name_len - 4;
1392 if (space_remaining < 0) {
1393 space_remaining = 0;
1394 }
1395
1396 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, "Action", space_remaining, "Synopsis");
1397 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, "------", space_remaining, "--------");
1398
1399 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1400 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, cur->action, space_remaining, cur->synopsis);
1401 }
1403
1404 return CLI_SUCCESS;
1405}
#define MGR_SHOW_TERMINAL_WIDTH
Definition: manager.c:203
#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 1478 of file manager.c.

1479{
1480 struct ao2_container *sessions;
1482 time_t now = time(NULL);
1483#define HSMCONN_FORMAT1 " %-15.15s %-55.55s %-10.10s %-10.10s %-8.8s %-8.8s %-10.10s %-10.10s\n"
1484#define HSMCONN_FORMAT2 " %-15.15s %-55.55s %-10d %-10d %-8d %-8d %-10.10d %-10.10d\n"
1485 int count = 0;
1486 struct ao2_iterator i;
1487
1488 switch (cmd) {
1489 case CLI_INIT:
1490 e->command = "manager show connected";
1491 e->usage =
1492 "Usage: manager show connected\n"
1493 " Prints a listing of the users that are currently connected to the\n"
1494 "Asterisk manager interface.\n";
1495 return NULL;
1496 case CLI_GENERATE:
1497 return NULL;
1498 }
1499
1500 ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "ReadPerms", "WritePerms");
1501
1502 sessions = ao2_global_obj_ref(mgr_sessions);
1503 if (sessions) {
1505 ao2_ref(sessions, -1);
1506 while ((session = ao2_iterator_next(&i))) {
1508 ast_cli(a->fd, HSMCONN_FORMAT2, session->username,
1510 (int) (session->sessionstart),
1511 (int) (now - session->sessionstart),
1512 session->stream ? ast_iostream_get_fd(session->stream) : -1,
1513 session->inuse,
1514 session->readperm,
1515 session->writeperm);
1516 count++;
1519 }
1521 }
1522 ast_cli(a->fd, "%d users connected.\n", count);
1523
1524 return CLI_SUCCESS;
1525}
#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 1529 of file manager.c.

1530{
1531 struct eventqent *s;
1532 switch (cmd) {
1533 case CLI_INIT:
1534 e->command = "manager show eventq";
1535 e->usage =
1536 "Usage: manager show eventq\n"
1537 " Prints a listing of all events pending in the Asterisk manger\n"
1538 "event queue.\n";
1539 return NULL;
1540 case CLI_GENERATE:
1541 return NULL;
1542 }
1544 AST_RWLIST_TRAVERSE(&all_events, s, eq_next) {
1545 ast_cli(a->fd, "Usecount: %d\n", s->usecount);
1546 ast_cli(a->fd, "Category: %d\n", s->category);
1547 ast_cli(a->fd, "Event:\n%s", s->eventdata);
1548 }
1550
1551 return CLI_SUCCESS;
1552}

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

2720{
2721 int x;
2722 char hdr[40];
2723 const char *action, *cat, *var, *value, *match, *line, *options;
2724 struct ast_variable *v;
2725 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
2726 enum error_type result = 0;
2727
2728 for (x = 0; x < 100000; x++) { /* 100000 = the max number of allowed updates + 1 */
2729 unsigned int object = 0;
2730 char *dupoptions;
2731 int allowdups = 0;
2732 int istemplate = 0;
2733 int ignoreerror = 0;
2734 RAII_VAR(char *, inherit, NULL, ast_free);
2735 RAII_VAR(char *, catfilter, NULL, ast_free);
2736 char *token;
2737 int foundvar = 0;
2738 int foundcat = 0;
2739 struct ast_category *category = NULL;
2740
2741 snprintf(hdr, sizeof(hdr), "Action-%06d", x);
2742 action = astman_get_header(m, hdr);
2743 if (ast_strlen_zero(action)) /* breaks the for loop if no action header */
2744 break; /* this could cause problems if actions come in misnumbered */
2745
2746 snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
2747 cat = astman_get_header(m, hdr);
2748 if (ast_strlen_zero(cat)) { /* every action needs a category */
2750 break;
2751 }
2752
2753 snprintf(hdr, sizeof(hdr), "Var-%06d", x);
2754 var = astman_get_header(m, hdr);
2755
2756 snprintf(hdr, sizeof(hdr), "Value-%06d", x);
2757 value = astman_get_header(m, hdr);
2758
2759 if (!ast_strlen_zero(value) && *value == '>') {
2760 object = 1;
2761 value++;
2762 }
2763
2764 snprintf(hdr, sizeof(hdr), "Match-%06d", x);
2765 match = astman_get_header(m, hdr);
2766
2767 snprintf(hdr, sizeof(hdr), "Line-%06d", x);
2768 line = astman_get_header(m, hdr);
2769
2770 snprintf(hdr, sizeof(hdr), "Options-%06d", x);
2771 options = astman_get_header(m, hdr);
2772 if (!ast_strlen_zero(options)) {
2773 char copy[strlen(options) + 1];
2774 strcpy(copy, options); /* safe */
2775 dupoptions = copy;
2776 while ((token = ast_strsep(&dupoptions, ',', AST_STRSEP_STRIP))) {
2777 if (!strcasecmp("allowdups", token)) {
2778 allowdups = 1;
2779 continue;
2780 }
2781 if (!strcasecmp("template", token)) {
2782 istemplate = 1;
2783 continue;
2784 }
2785 if (!strcasecmp("ignoreerror", token)) {
2786 ignoreerror = 1;
2787 continue;
2788 }
2789 if (ast_begins_with(token, "inherit")) {
2790 char *c = ast_strsep(&token, '=', AST_STRSEP_STRIP);
2791 c = ast_strsep(&token, '=', AST_STRSEP_STRIP);
2792 if (c) {
2793 inherit = ast_strdup(c);
2794 }
2795 continue;
2796 }
2797 if (ast_begins_with(token, "catfilter")) {
2798 char *c = ast_strsep(&token, '=', AST_STRSEP_STRIP);
2799 c = ast_strsep(&token, '=', AST_STRSEP_STRIP);
2800 if (c) {
2801 catfilter = ast_strdup(c);
2802 }
2803 continue;
2804 }
2805 }
2806 }
2807
2808 if (!strcasecmp(action, "newcat")) {
2809 struct ast_category *template;
2810 char *tmpl_name = NULL;
2811
2812 if (!allowdups) {
2813 if (ast_category_get(cfg, cat, "TEMPLATES=include")) {
2814 if (ignoreerror) {
2815 continue;
2816 } else {
2817 result = FAILURE_NEWCAT; /* already exist */
2818 break;
2819 }
2820 }
2821 }
2822
2823 if (istemplate) {
2824 category = ast_category_new_template(cat, dfn, -1);
2825 } else {
2826 category = ast_category_new(cat, dfn, -1);
2827 }
2828
2829 if (!category) {
2831 break;
2832 }
2833
2834 if (inherit) {
2835 while ((tmpl_name = ast_strsep(&inherit, ',', AST_STRSEP_STRIP))) {
2836 if ((template = ast_category_get(cfg, tmpl_name, "TEMPLATES=restrict"))) {
2837 if (ast_category_inherit(category, template)) {
2839 break;
2840 }
2841 } else {
2842 ast_category_destroy(category);
2843 category = NULL;
2844 result = FAILURE_TEMPLATE; /* template not found */
2845 break;
2846 }
2847 }
2848 }
2849
2850 if (category != NULL) {
2851 if (ast_strlen_zero(match)) {
2852 ast_category_append(cfg, category);
2853 } else {
2854 if (ast_category_insert(cfg, category, match)) {
2855 ast_category_destroy(category);
2857 break;
2858 }
2859 }
2860 }
2861 } else if (!strcasecmp(action, "renamecat")) {
2862 if (ast_strlen_zero(value)) {
2864 break;
2865 }
2866
2867 foundcat = 0;
2868 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
2869 ast_category_rename(category, value);
2870 foundcat = 1;
2871 }
2872
2873 if (!foundcat) {
2875 break;
2876 }
2877 } else if (!strcasecmp(action, "delcat")) {
2878 foundcat = 0;
2879 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
2880 category = ast_category_delete(cfg, category);
2881 foundcat = 1;
2882 }
2883
2884 if (!foundcat && !ignoreerror) {
2886 break;
2887 }
2888 } else if (!strcasecmp(action, "emptycat")) {
2889 foundcat = 0;
2890 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
2891 ast_category_empty(category);
2892 foundcat = 1;
2893 }
2894
2895 if (!foundcat) {
2897 break;
2898 }
2899 } else if (!strcasecmp(action, "update")) {
2900 if (ast_strlen_zero(var)) {
2902 break;
2903 }
2904
2905 foundcat = 0;
2906 foundvar = 0;
2907 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
2908 if (!ast_variable_update(category, var, value, match, object)) {
2909 foundvar = 1;
2910 }
2911 foundcat = 1;
2912 }
2913
2914 if (!foundcat) {
2916 break;
2917 }
2918
2919 if (!foundvar) {
2921 break;
2922 }
2923 } else if (!strcasecmp(action, "delete")) {
2924 if ((ast_strlen_zero(var) && ast_strlen_zero(line))) {
2926 break;
2927 }
2928
2929 foundcat = 0;
2930 foundvar = 0;
2931 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
2932 if (!ast_variable_delete(category, var, match, line)) {
2933 foundvar = 1;
2934 }
2935 foundcat = 1;
2936 }
2937
2938 if (!foundcat) {
2940 break;
2941 }
2942
2943 if (!foundvar && !ignoreerror) {
2945 break;
2946 }
2947 } else if (!strcasecmp(action, "append")) {
2948 if (ast_strlen_zero(var)) {
2950 break;
2951 }
2952
2953 foundcat = 0;
2954 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
2955 if (!(v = ast_variable_new(var, value, dfn))) {
2957 break;
2958 }
2959 if (object || (match && !strcasecmp(match, "object"))) {
2960 v->object = 1;
2961 }
2962 ast_variable_append(category, v);
2963 foundcat = 1;
2964 }
2965
2966 if (!foundcat) {
2968 break;
2969 }
2970 } else if (!strcasecmp(action, "insert")) {
2971 if (ast_strlen_zero(var) || ast_strlen_zero(line)) {
2973 break;
2974 }
2975
2976 foundcat = 0;
2977 while ((category = ast_category_browse_filtered(cfg, cat, category, catfilter))) {
2978 if (!(v = ast_variable_new(var, value, dfn))) {
2980 break;
2981 }
2982 ast_variable_insert(category, v, line);
2983 foundcat = 1;
2984 }
2985
2986 if (!foundcat) {
2988 break;
2989 }
2990 }
2991 else {
2992 ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action);
2994 break;
2995 }
2996 }
2997 ast_free(str1);
2998 ast_free(str2);
2999 return result;
3000}
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:1568
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:1178
struct ast_category * ast_category_delete(struct ast_config *cfg, struct ast_category *cat)
Delete a category.
Definition: main/config.c:1695
void ast_category_rename(struct ast_category *cat, const char *name)
Definition: main/config.c:1563
int ast_variable_delete(struct ast_category *category, const char *variable, const char *match, const char *line)
Definition: main/config.c:1600
int ast_category_insert(struct ast_config *config, struct ast_category *cat, const char *match)
Inserts new category.
Definition: main/config.c:1266
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:1645
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:1727
void ast_variable_insert(struct ast_category *category, struct ast_variable *variable, const char *line)
Definition: main/config.c:585
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:1205
@ 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().

◆ is_originate_app_permitted()

static int is_originate_app_permitted ( const char *  app,
const char *  data,
int  permission 
)
static

Definition at line 5121 of file manager.c.

5123{
5124 int i;
5125
5126 for (i = 0; originate_app_permissions[i].search; i++) {
5127 if (originate_app_permissions[i].searchfn(app, data, originate_app_permissions[i].search)) {
5129 }
5130 }
5131
5132 return 1;
5133}
static struct originate_permissions_entry originate_app_permissions[]
Definition: manager.c:5085
int permission
Definition: manager.c:4995
const char * search
Definition: manager.c:4994

References app, originate_app_permissions, originate_permissions_entry::permission, and originate_permissions_entry::search.

Referenced by action_originate().

◆ is_restricted_file()

static int is_restricted_file ( 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 2464 of file manager.c.

2465{
2466 char *stripped_filename;
2467 RAII_VAR(char *, path, NULL, ast_free);
2468 RAII_VAR(char *, real_path, NULL, ast_std_free);
2469
2470 if (live_dangerously) {
2471 return 0;
2472 }
2473
2474 stripped_filename = ast_strip(ast_strdupa(filename));
2475
2476 /* If the file path starts with '/', don't prepend ast_config_AST_CONFIG_DIR */
2477 if (stripped_filename[0] == '/') {
2478 real_path = realpath(stripped_filename, NULL);
2479 } else {
2480 if (ast_asprintf(&path, "%s/%s", ast_config_AST_CONFIG_DIR, stripped_filename) == -1) {
2481 return -1;
2482 }
2483 real_path = realpath(path, NULL);
2484 }
2485
2486 if (!real_path) {
2487 return -1;
2488 }
2489
2490 if (!ast_begins_with(real_path, ast_config_AST_CONFIG_DIR)) {
2491 return 1;
2492 }
2493
2494 return 0;
2495}

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(), action_listcategories(), and 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 2618 of file manager.c.

2619{
2620 for (; *in; in++) {
2621 if (*in == '\\' || *in == '\"') {
2622 *out++ = '\\';
2623 }
2624 *out++ = *in;
2625 }
2626 *out = '\0';
2627}
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 6984 of file manager.c.

6985{
6986 struct ast_str *buf;
6987 int x;
6988
6989 if (!manager_debug) {
6990 return;
6991 }
6992
6993 buf = ast_str_create(256);
6994 if (!buf) {
6995 return;
6996 }
6997
6998 for (x = 0; x < m->hdrcount; ++x) {
6999 if (!strncasecmp(m->headers[x], "Secret", 6)) {
7000 ast_str_append(&buf, 0, "Secret: <redacted from logging>\n");
7001 } else {
7002 ast_str_append(&buf, 0, "%s\n", m->headers[x]);
7003 }
7004 }
7005
7006 ast_verbose("<--- Examining AMI action: -->\n%s\n", ast_str_buffer(buf));
7007 ast_free(buf);
7008}

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

1686{
1687 char *parse;
1689 AST_APP_ARG(vars)[64];
1690 );
1691
1692 hdr_val = ast_skip_blanks(hdr_val); /* ignore leading spaces in the value */
1693 parse = ast_strdupa(hdr_val);
1694
1695 /* Break the header value string into name=val pair items. */
1697 if (args.argc) {
1698 int y;
1699
1700 /* Process each name=val pair item. */
1701 for (y = 0; y < args.argc; y++) {
1702 struct ast_variable *cur;
1703 char *var;
1704 char *val;
1705
1706 if (!args.vars[y]) {
1707 continue;
1708 }
1709 var = val = args.vars[y];
1710 strsep(&val, "=");
1711
1712 /* XXX We may wish to trim whitespace from the strings. */
1713 if (!val || ast_strlen_zero(var)) {
1714 continue;
1715 }
1716
1717 /* Create new variable list node and prepend it to the list. */
1718 cur = ast_variable_new(var, val, "");
1719 if (cur) {
1720 cur->next = head;
1721 head = cur;
1722 }
1723 }
1724 }
1725
1726 return head;
1727}
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 *  criteria,
const char *  filter_pattern,
struct ao2_container includefilters,
struct ao2_container excludefilters 
)
static

Add an event filter to a manager session.

Parameters
criteriaSee examples in manager.conf.sample
filter_patternFilter pattern
includefilters,excludefilters
Returns
FILTER_ALLOC_FAILED Memory allocation failure
FILTER_COMPILE_FAIL If the filter did not compile
FILTER_FORMAT_ERROR If the criteria weren't formatted correctly
FILTER_SUCCESS Success

Examples: See examples in manager.conf.sample

Definition at line 5749 of file manager.c.

5752{
5753 RAII_VAR(struct event_filter_entry *, filter_entry,
5754 ao2_t_alloc(sizeof(*filter_entry), event_filter_destructor, "event_filter allocation"),
5755 ao2_cleanup);
5756 char *options_start = NULL;
5757 SCOPE_ENTER(3, "manager_add_filter(%s, %s, %p, %p)", criteria, filter_pattern, includefilters, excludefilters);
5758
5759 if (!filter_entry) {
5760 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_ALLOC_FAILED, LOG_WARNING, "Unable to allocate filter_entry");
5761 }
5762
5763 /*
5764 * At a minimum, criteria must be "eventfilter" but may contain additional
5765 * constraints.
5766 */
5767 if (ast_strlen_zero(criteria)) {
5769 }
5770
5771 /*
5772 * filter_pattern could be empty but it should never be NULL.
5773 */
5774 if (!filter_pattern) {
5775 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "Filter pattern was NULL");
5776 }
5777
5778 /*
5779 * For a legacy filter, if the first character of filter_pattern is
5780 * '!' then it's an exclude filter. It's also accepted as an alternative
5781 * to specifying "action(exclude)" for an advanced filter. If
5782 * "action" is specified however, it will take precedence.
5783 */
5784 if (filter_pattern[0] == '!') {
5785 filter_entry->is_excludefilter = 1;
5786 filter_pattern++;
5787 }
5788
5789 /*
5790 * This is the default
5791 */
5792 filter_entry->match_type = FILTER_MATCH_REGEX;
5793
5794 /*
5795 * If the criteria has a '(' in it, then it's an advanced filter.
5796 */
5797 options_start = strstr(criteria, "(");
5798
5799 /*
5800 * If it's a legacy filter, there MUST be a filter pattern.
5801 */
5802 if (!options_start && ast_strlen_zero(filter_pattern)) {
5804 "'%s = %s': Legacy filter with no filter pattern specified\n",
5805 criteria, filter_pattern);
5806 }
5807
5808 if (options_start) {
5809 /*
5810 * This is an advanced filter
5811 */
5812 char *temp = ast_strdupa(options_start + 1); /* skip over the leading '(' */
5813 char *saveptr = NULL;
5814 char *option = NULL;
5815 enum found_options {
5816 action_found = (1 << 0),
5817 name_found = (1 << 1),
5818 header_found = (1 << 2),
5819 method_found = (1 << 3),
5820 };
5821 enum found_options options_found = 0;
5822
5823 filter_entry->match_type = FILTER_MATCH_NONE;
5824
5825 ast_strip(temp);
5826 if (ast_strlen_zero(temp) || !ast_ends_with(temp, ")")) {
5828 "'%s = %s': Filter options not formatted correctly\n",
5829 criteria, filter_pattern);
5830 }
5831
5832 /*
5833 * These can actually be in any order...
5834 * action(include|exclude),name(<event_name>),header(<header_name>),method(<match_method>)
5835 * At least one of action, name, or header is required.
5836 */
5837 while ((option = strtok_r(temp, " ,)", &saveptr))) {
5838 if (!strncmp(option, "action", 6)) {
5839 char *method = strstr(option, "(");
5840 if (ast_strlen_zero(method)) {
5841 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': 'action' parameter not formatted correctly\n",
5842 criteria, filter_pattern);
5843 }
5844 method++;
5846 if (!strcmp(method, "include")) {
5847 filter_entry->is_excludefilter = 0;
5848 } else if (!strcmp(method, "exclude")) {
5849 filter_entry->is_excludefilter = 1;
5850 } else {
5851 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': 'action' option '%s' is unknown\n",
5852 criteria, filter_pattern, method);
5853 }
5854 options_found |= action_found;
5855 } else if (!strncmp(option, "name", 4)) {
5856 char *event_name = strstr(option, "(");
5857 event_name++;
5858 ast_strip(event_name);
5859 if (ast_strlen_zero(event_name)) {
5860 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': 'name' parameter not formatted correctly\n",
5861 criteria, filter_pattern);
5862 }
5863 filter_entry->event_name = ast_strdup(event_name);
5864 filter_entry->event_name_hash = ast_str_hash(event_name);
5865 options_found |= name_found;
5866 } else if (!strncmp(option, "header", 6)) {
5867 char *header_name = strstr(option, "(");
5868 header_name++;
5869 ast_strip(header_name);
5870 if (ast_strlen_zero(header_name)) {
5871 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': 'header' parameter not formatted correctly\n",
5872 criteria, filter_pattern);
5873 }
5874 if (!ast_ends_with(header_name, ":")) {
5875 filter_entry->header_name = ast_malloc(strlen(header_name) + 2);
5876 if (!filter_entry->header_name) {
5877 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_ALLOC_FAILED, LOG_ERROR, "Unable to allocate memory for header_name");
5878 }
5879 sprintf(filter_entry->header_name, "%s:", header_name); /* Safe */
5880 } else {
5881 filter_entry->header_name = ast_strdup(header_name);
5882 }
5883 options_found |= header_found;
5884 } else if (!strncmp(option, "method", 6)) {
5885 char *method = strstr(option, "(");
5886 method++;
5888 if (ast_strlen_zero(method)) {
5889 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': 'method' parameter not formatted correctly\n",
5890 criteria, filter_pattern);
5891 }
5892 if (!strcmp(method, "regex")) {
5893 filter_entry->match_type = FILTER_MATCH_REGEX;
5894 } else if (!strcmp(method, "exact")) {
5895 filter_entry->match_type = FILTER_MATCH_EXACT;
5896 } else if (!strcmp(method, "starts_with")) {
5897 filter_entry->match_type = FILTER_MATCH_STARTS_WITH;
5898 } else if (!strcmp(method, "ends_with")) {
5899 filter_entry->match_type = FILTER_MATCH_ENDS_WITH;
5900 } else if (!strcmp(method, "contains")) {
5901 filter_entry->match_type = FILTER_MATCH_CONTAINS;
5902 } else if (!strcmp(method, "none")) {
5903 filter_entry->match_type = FILTER_MATCH_NONE;
5904 } else {
5905 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': 'method' option '%s' is unknown\n",
5906 criteria, filter_pattern, method);
5907 }
5908 options_found |= method_found;
5909 } else {
5910 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': Filter option '%s' is unknown\n",
5911 criteria, filter_pattern, option);
5912 }
5913 temp = NULL;
5914 }
5915 if (!options_found) {
5917 "'%s = %s': No action, name, header, or method option found\n",
5918 criteria, filter_pattern);
5919 }
5920 if (ast_strlen_zero(filter_pattern) && filter_entry->match_type != FILTER_MATCH_NONE) {
5922 "'%s = %s': method can't be '%s' with no filter pattern\n",
5923 criteria, filter_pattern, match_type_names[filter_entry->match_type]);
5924 }
5925 if (!ast_strlen_zero(filter_pattern) && filter_entry->match_type == FILTER_MATCH_NONE) {
5927 "'%s = %s': method can't be 'none' with a filter pattern\n",
5928 criteria, filter_pattern);
5929 }
5930 if (!(options_found & name_found) && !(options_found & header_found) &&
5931 filter_entry->match_type == FILTER_MATCH_NONE) {
5933 "'%s = %s': No name or header option found and no filter pattern\n",
5934 criteria, filter_pattern);
5935 }
5936 }
5937
5938 if (!ast_strlen_zero(filter_pattern)) {
5939 if (filter_entry->match_type == FILTER_MATCH_REGEX) {
5940 filter_entry->regex_filter = ast_calloc(1, sizeof(regex_t));
5941 if (!filter_entry->regex_filter) {
5942 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_ALLOC_FAILED, LOG_ERROR, "Unable to allocate memory for regex_filter");
5943 }
5944 if (regcomp(filter_entry->regex_filter, filter_pattern, REG_EXTENDED | REG_NOSUB)) {
5945 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_COMPILE_FAIL, LOG_WARNING, "Unable to compile regex filter for '%s'", filter_pattern);
5946 }
5947 } else {
5948 filter_entry->string_filter = ast_strdup(filter_pattern);
5949 }
5950 }
5951
5952 ast_debug(2, "Event filter:\n"
5953 "conf entry: %s = %s\n"
5954 "event_name: %s (hash: %d)\n"
5955 "test_header: %s\n"
5956 "match_type: %s\n"
5957 "regex_filter: %p\n"
5958 "string filter: %s\n"
5959 "is excludefilter: %d\n",
5960 criteria, filter_pattern,
5961 S_OR(filter_entry->event_name, "<not used>"),
5962 filter_entry->event_name_hash,
5963 S_OR(filter_entry->header_name, "<not used>"),
5964 match_type_names[filter_entry->match_type],
5965 filter_entry->regex_filter,
5966 filter_entry->string_filter,
5967 filter_entry->is_excludefilter);
5968
5969 if (filter_entry->is_excludefilter) {
5970 ao2_t_link(excludefilters, filter_entry, "link new filter into exclude user container");
5971 } else {
5972 ao2_t_link(includefilters, filter_entry, "link new filter into include user container");
5973 }
5974
5975 SCOPE_EXIT_RTN_VALUE(FILTER_SUCCESS, "Filter added successfully");
5976}
static char * match_type_names[]
Definition: manager.c:394
static void event_filter_destructor(void *obj)
Definition: manager.c:923
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
#define SCOPE_ENTER(level,...)
const char * method
Definition: res_pjsip.c:1279

References ao2_cleanup, ao2_t_alloc, ao2_t_link, ast_calloc, ast_debug, ast_ends_with(), ast_malloc, ast_str_hash(), ast_strdup, ast_strdupa, ast_strip(), ast_strlen_zero(), event_filter_destructor(), FILTER_ALLOC_FAILED, FILTER_COMPILE_FAIL, FILTER_FORMAT_ERROR, FILTER_MATCH_CONTAINS, FILTER_MATCH_ENDS_WITH, FILTER_MATCH_EXACT, FILTER_MATCH_NONE, FILTER_MATCH_REGEX, FILTER_MATCH_STARTS_WITH, FILTER_SUCCESS, LOG_ERROR, LOG_WARNING, match_type_names, method, NULL, RAII_VAR, S_OR, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, and SCOPE_EXIT_RTN_VALUE.

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

570{
571 struct ao2_container *sessions;
572 struct ast_manager_event_blob *ev;
573
575 /* Not an AMI message; disregard */
576 return;
577 }
578
579 sessions = ao2_global_obj_ref(mgr_sessions);
581 /* Nobody is listening */
583 return;
584 }
585
587 if (!ev) {
588 /* Conversion failure */
590 return;
591 }
592
594 "%s", ev->extra_fields);
595 ao2_ref(ev, -1);
597}
#define manager_event_sessions(sessions, category, event, contents,...)
Definition: manager.c:562
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:503
const ast_string_field extra_fields
Definition: manager.h:508
const char * manager_event
Definition: manager.h:505

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

1060{
1061 struct ast_manager_user *user = NULL;
1062 int ret = 0;
1063
1065 if ((user = get_manager_by_name_locked(session->username))) {
1066 ret = user->displayconnects;
1067 }
1069
1070 return ret;
1071}

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

601{
602 struct ast_json_payload *payload;
603 int class_type;
604 const char *type;
605 struct ast_json *event;
606 struct ast_str *event_buffer;
607 struct ao2_container *sessions;
608
609 sessions = ao2_global_obj_ref(mgr_sessions);
611 /* Nobody is listening */
613 return;
614 }
615
616 payload = stasis_message_data(message);
617 class_type = ast_json_integer_get(ast_json_object_get(payload->json, "class_type"));
619 event = ast_json_object_get(payload->json, "event");
620
622 if (!event_buffer) {
623 ast_log(AST_LOG_WARNING, "Error while creating payload for event %s\n", type);
625 return;
626 }
627
629 "%s", ast_str_buffer(event_buffer));
630 ast_free(event_buffer);
632}
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:551
#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 485 of file manager.c.

488{
489 struct ast_str *key_str = ast_str_alloca(64);
490 ast_str_set(&key_str, 0, "%s(%zu)", key, index);
492 res, exclusion_cb);
493}

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

498{
499 if (parent_key) {
500 struct ast_str *key_str = ast_str_alloca(64);
501 ast_str_set(&key_str, 0, "%s/%s", parent_key, key);
503 res, exclusion_cb);
504 return;
505 }
506
507 manager_json_to_ast_str(obj, key, res, exclusion_cb);
508}

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

512{
513 struct ast_json_iter *i;
514
515 /* If obj or res is not given, just return */
516 if (!obj || !res) {
517 return;
518 }
519
520 if (!*res && !(*res = ast_str_create(1024))) {
521 return;
522 }
523
524 if (exclusion_cb && key && exclusion_cb(key)) {
525 return;
526 }
527
528 if (ast_json_typeof(obj) != AST_JSON_OBJECT &&
530 manager_json_value_str_append(obj, key, res);
531 return;
532 }
533
534 if (ast_json_typeof(obj) == AST_JSON_ARRAY) {
535 size_t j;
536 for (j = 0; j < ast_json_array_size(obj); ++j) {
538 key, j, res, exclusion_cb);
539 }
540 return;
541 }
542
543 for (i = ast_json_object_iter(obj); i;
544 i = ast_json_object_iter_next(obj, i)) {
547 key, res, exclusion_cb);
548 }
549}
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:485
static void manager_json_value_str_append(struct ast_json *value, const char *key, struct ast_str **res)
Definition: manager.c:460
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:495
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 460 of file manager.c.

462{
463 switch (ast_json_typeof(value)) {
464 case AST_JSON_STRING:
465 ast_str_append(res, 0, "%s: %s\r\n", key, ast_json_string_get(value));
466 break;
467 case AST_JSON_INTEGER:
468 ast_str_append(res, 0, "%s: %jd\r\n", key, ast_json_integer_get(value));
469 break;
470 case AST_JSON_TRUE:
471 ast_str_append(res, 0, "%s: True\r\n", key);
472 break;
473 case AST_JSON_FALSE:
474 ast_str_append(res, 0, "%s: False\r\n", key);
475 break;
476 default:
477 ast_str_append(res, 0, "%s: \r\n", key);
478 break;
479 }
480}
@ 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 6838 of file manager.c.

6839{
6840 const char *module = astman_get_header(m, "Module");
6841 const char *id = astman_get_header(m, "ActionID");
6842
6843 ast_debug(1, "**** ModuleCheck .so file %s\n", module);
6844 if (!ast_module_check(module)) {
6845 astman_send_error(s, m, "Module not loaded");
6846 return 0;
6847 }
6848
6849 astman_append(s, "Response: Success\r\n");
6850
6851 if (!ast_strlen_zero(id)) {
6852 astman_append(s, "ActionID: %s\r\n", id);
6853 }
6854
6855#if !defined(LOW_MEMORY)
6856 /* When we switched from subversion to git we lost the ability to
6857 * retrieve the 'ASTERISK_FILE_VERSION' from that file, but we retain
6858 * the response header here for backwards compatibility. */
6859 astman_append(s, "Version: \r\n");
6860#endif
6861
6862 astman_append(s, "\r\n");
6863
6864 return 0;
6865}
int ast_module_check(const char *name)
Check if module with the name given is loaded.
Definition: loader.c:2832

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

6904{
6905 int res;
6906 const char *module = astman_get_header(m, "Module");
6907 const char *loadtype = astman_get_header(m, "LoadType");
6908 const char *recursive = astman_get_header(m, "Recursive");
6909
6910 if (!loadtype || strlen(loadtype) == 0) {
6911 astman_send_error(s, m, "Incomplete ModuleLoad action.");
6912 }
6913 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) {
6914 astman_send_error(s, m, "Need module name");
6915 }
6916
6917 res = file_in_modules_dir(module);
6918 if (res == 0) {
6919 astman_send_error(s, m, "Module must be in the configured modules directory.");
6920 return 0;
6921 } else if (res == -1) {
6922 astman_send_error(s, m, "Module not found.");
6923 return 0;
6924 }
6925
6926 if (!strcasecmp(loadtype, "load")) {
6927 res = ast_load_resource(module);
6928 if (res) {
6929 astman_send_error(s, m, "Could not load module.");
6930 } else {
6931 astman_send_ack(s, m, "Module loaded.");
6932 }
6933 } else if (!strcasecmp(loadtype, "unload")) {
6934 res = ast_unload_resource(module, AST_FORCE_SOFT);
6935 if (res) {
6936 astman_send_error(s, m, "Could not unload module.");
6937 } else {
6938 astman_send_ack(s, m, "Module unloaded.");
6939 }
6940 } else if (!strcasecmp(loadtype, "refresh")) {
6941 res = ast_refresh_resource(module, AST_FORCE_SOFT, !ast_strlen_zero(recursive) && ast_true(recursive));
6942 if (res) {
6943 astman_send_error(s, m, "Could not refresh module.");
6944 } else {
6945 astman_send_ack(s, m, "Module unloaded and loaded.");
6946 }
6947 } else if (!strcasecmp(loadtype, "reload")) {
6948 /* TODO: Unify the ack/error messages here with action_reload */
6949 if (!ast_strlen_zero(module)) {
6950 enum ast_module_reload_result reload_res = ast_module_reload(module);
6951
6952 switch (reload_res) {
6954 astman_send_error(s, m, "No such module.");
6955 break;
6957 astman_send_error(s, m, "Module does not support reload action.");
6958 break;
6960 astman_send_error(s, m, "An unknown error occurred");
6961 break;
6963 astman_send_error(s, m, "A reload is in progress");
6964 break;
6966 astman_send_error(s, m, "Module not initialized");
6967 break;
6970 /* Treat a queued request as success */
6971 astman_send_ack(s, m, "Module reloaded.");
6972 break;
6973 }
6974 } else {
6975 ast_module_reload(NULL); /* Reload all modules */
6976 astman_send_ack(s, m, "All modules reloaded");
6977 }
6978 } else {
6979 astman_send_error(s, m, "Incomplete ModuleLoad action.");
6980 }
6981 return 0;
6982}
static int file_in_modules_dir(const char *filename)
Check if the given file path is in the modules dir or not.
Definition: manager.c:6877
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
Definition: loader.c:1457
enum ast_module_load_result ast_load_resource(const char *resource_name)
Load a module.
Definition: loader.c:1987
int ast_refresh_resource(const char *resource_name, enum ast_module_unload_mode force, int recursive)
Unload and load a module again.
Definition: loader.c:1416
@ 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_refresh_resource(), ast_strlen_zero(), ast_true(), ast_unload_resource(), astman_get_header(), astman_send_ack(), astman_send_error(), file_in_modules_dir(), 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 7725 of file manager.c.

7726{
7727 /* Notify managers of change */
7728 char hint[512];
7729
7730 hint[0] = '\0';
7731 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
7732
7733 switch(info->reason) {
7735 manager_event(EVENT_FLAG_CALL, "ExtensionStatus",
7736 "Exten: %s\r\n"
7737 "Context: %s\r\n"
7738 "Hint: %s\r\n"
7739 "Status: %d\r\n"
7740 "StatusText: %s\r\n",
7741 exten,
7742 context,
7743 hint,
7744 info->exten_state,
7745 ast_extension_state2str(info->exten_state));
7746 break;
7748 manager_event(EVENT_FLAG_CALL, "PresenceStatus",
7749 "Exten: %s\r\n"
7750 "Context: %s\r\n"
7751 "Hint: %s\r\n"
7752 "Status: %s\r\n"
7753 "Subtype: %s\r\n"
7754 "Message: %s\r\n",
7755 exten,
7756 context,
7757 hint,
7758 ast_presence_state2str(info->presence_state),
7759 info->presence_subtype,
7760 info->presence_message);
7761 break;
7762 }
7763 return 0;
7764}
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 999 of file manager.c.

1000{
1001 struct mansession_session *s = obj;
1002 char *str = arg;
1003 return !strcasecmp(s->username, str) ? CMP_MATCH : 0;
1004}

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

2075{
2076 ast_mutex_lock(&s->lock);
2077}
ast_mutex_t lock
Definition: manager.c:330

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

2081{
2083}

References ast_mutex_unlock, and mansession::lock.

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

◆ match_eventdata()

static int match_eventdata ( struct event_filter_entry entry,
const char *  eventdata 
)
static

Test eventdata against a filter entry.

Parameters
entryThe event_filter entry to match with
eventdataThe data to match against
Return values
0if no match
1if match

Definition at line 5572 of file manager.c.

5573{
5574 switch(entry->match_type) {
5575 case FILTER_MATCH_REGEX:
5576 return regexec(entry->regex_filter, eventdata, 0, NULL, 0) == 0;
5578 return ast_begins_with(eventdata, entry->string_filter);
5580 return ast_ends_with(eventdata, entry->string_filter);
5582 return strstr(eventdata, entry->string_filter) != NULL;
5583 case FILTER_MATCH_EXACT:
5584 return strcmp(eventdata, entry->string_filter) == 0;
5585 case FILTER_MATCH_NONE:
5586 return 1;
5587 }
5588
5589 return 0;
5590}
enum event_filter_match_type match_type
Definition: manager.c:404

References ast_begins_with(), ast_ends_with(), FILTER_MATCH_CONTAINS, FILTER_MATCH_ENDS_WITH, FILTER_MATCH_EXACT, FILTER_MATCH_NONE, FILTER_MATCH_REGEX, FILTER_MATCH_STARTS_WITH, event_filter_entry::match_type, NULL, event_filter_entry::regex_filter, and event_filter_entry::string_filter.

Referenced by filter_cmp_fn().

◆ print_event_instance()

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

Definition at line 9261 of file manager.c.

9262{
9263 char *since, *syntax, *description, *synopsis, *seealso, *arguments;
9264
9265 synopsis = ast_xmldoc_printable(AS_OR(instance->synopsis, "Not available"), 1);
9266 since = ast_xmldoc_printable(AS_OR(instance->since, "Not available"), 1);
9267 description = ast_xmldoc_printable(AS_OR(instance->description, "Not available"), 1);
9268 syntax = ast_xmldoc_printable(AS_OR(instance->syntax, "Not available"), 1);
9269 arguments = ast_xmldoc_printable(AS_OR(instance->arguments, "Not available"), 1);
9270 seealso = ast_xmldoc_printable(AS_OR(instance->seealso, "Not available"), 1);
9271
9272 if (!synopsis || !since || !description || !syntax || !arguments || !seealso) {
9273 ast_cli(a->fd, "Error: Memory allocation failed\n");
9274 goto free_docs;
9275 }
9276
9277 ast_cli(a->fd, "\n"
9278 "%s -= Info about Manager Event '%s' =- %s\n\n"
9279 COLORIZE_FMT "\n"
9280 "%s\n\n"
9281 COLORIZE_FMT "\n"
9282 "%s\n\n"
9283 COLORIZE_FMT "\n"
9284 "%s\n\n"
9285 COLORIZE_FMT "\n"
9286 "%s\n\n"
9287 COLORIZE_FMT "\n"
9288 "%s\n\n"
9289 COLORIZE_FMT "\n"
9290 "%s\n\n",
9292 COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
9293 COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
9294 COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
9295 COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), syntax,
9296 COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
9297 COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso
9298 );
9299
9300free_docs:
9302 ast_free(since);
9303 ast_free(description);
9304 ast_free(syntax);
9305 ast_free(arguments);
9306 ast_free(seealso);
9307}
#define AS_OR(a, b)
Definition: strings.h:49
struct ast_str * synopsis
Definition: xmldoc.h:64

References a, ast_xml_doc_item::arguments, AS_OR, ast_cli(), ast_free, ast_term_color(), ast_term_reset(), ast_xmldoc_printable(), COLOR_MAGENTA, COLORIZE, COLORIZE_FMT, ast_xml_doc_item::description, ast_xml_doc_item::name, ast_xml_doc_item::seealso, ast_xml_doc_item::since, synopsis, ast_xml_doc_item::synopsis, and ast_xml_doc_item::syntax.

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

6411{
6412 int ret = 0;
6413
6414 ao2_lock(s->session);
6415 if (s->session->stream != NULL) {
6416 struct eventqent *eqe = s->session->last_ev;
6417
6418 while ((eqe = advance_event(eqe))) {
6419 if (eqe->category == EVENT_FLAG_SHUTDOWN) {
6420 ast_debug(3, "Received CloseSession event\n");
6421 ret = -1;
6422 }
6423 if (!ret && s->session->authenticated &&
6424 (s->session->readperm & eqe->category) == eqe->category &&
6425 (s->session->send_events & eqe->category) == eqe->category) {
6427 if (send_string(s, eqe->eventdata) < 0 || s->write_error)
6428 ret = -1; /* don't send more */
6429 }
6430 }
6431 s->session->last_ev = eqe;
6432 }
6433 }
6434 ao2_unlock(s->session);
6435 return ret;
6436}
unsigned int write_error
Definition: manager.c:328

References advance_event(), ao2_lock, ao2_unlock, ast_debug, mansession_session::authenticated, eventqent::category, EVENT_FLAG_SHUTDOWN, mansession_session::excludefilters, mansession_session::includefilters, mansession_session::last_ev, NULL, mansession_session::readperm, mansession_session::send_events, send_string(), mansession::session, should_send_event(), 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 7023 of file manager.c.

7024{
7025 int ret = 0;
7026 struct manager_action *act_found;
7027 struct ast_manager_user *user = NULL;
7028 const char *username;
7029 const char *action;
7030
7031 action = __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY);
7032 if (ast_strlen_zero(action)) {
7033 report_req_bad_format(s, "NONE");
7034 mansession_lock(s);
7035 astman_send_error(s, m, "Missing action in request");
7037 return 0;
7038 }
7039
7040 log_action(m, action);
7041
7042 if (ast_shutting_down()) {
7043 ast_log(LOG_ERROR, "Unable to process manager action '%s'. Asterisk is shutting down.\n", action);
7044 mansession_lock(s);
7045 astman_send_error(s, m, "Asterisk is shutting down");
7047 return 0;
7048 }
7049
7050 if (!s->session->authenticated
7051 && strcasecmp(action, "Login")
7052 && strcasecmp(action, "Logoff")
7053 && strcasecmp(action, "Challenge")) {
7054 if (!s->session->authenticated) {
7055 report_req_not_allowed(s, action);
7056 }
7057 mansession_lock(s);
7058 astman_send_error(s, m, "Permission denied");
7060 return 0;
7061 }
7062
7063 if (!s->session->authenticated
7064 && (!strcasecmp(action, "Login")
7065 || !strcasecmp(action, "Challenge"))) {
7066 username = astman_get_header(m, "Username");
7067
7071 if (user && !user->allowmultiplelogin) {
7074 sleep(1);
7075 mansession_lock(s);
7076 astman_send_error(s, m, "Login Already In Use");
7078 return -1;
7079 }
7081 }
7082 }
7083
7084 act_found = action_find(action);
7085 if (act_found) {
7086 /* Found the requested AMI action. */
7087 int acted = 0;
7088
7089 if ((s->session->writeperm & act_found->authority)
7090 || act_found->authority == 0) {
7091 /* We have the authority to execute the action. */
7092 ret = -1;
7093 ao2_lock(act_found);
7094 if (act_found->registered && act_found->func) {
7095 struct ast_module *mod_ref = ast_module_running_ref(act_found->module);
7096
7097 ao2_unlock(act_found);
7098 if (mod_ref || !act_found->module) {
7099 ast_debug(1, "Running action '%s'\n", act_found->action);
7100 ret = act_found->func(s, m);
7101 acted = 1;
7102 ast_module_unref(mod_ref);
7103 }
7104 } else {
7105 ao2_unlock(act_found);
7106 }
7107 }
7108 if (!acted) {
7109 /*
7110 * We did not execute the action because access was denied, it
7111 * was no longer registered, or no action was really registered.
7112 * Complain about it and leave.
7113 */
7114 report_req_not_allowed(s, action);
7115 mansession_lock(s);
7116 astman_send_error(s, m, "Permission denied");
7118 }
7119 ao2_t_ref(act_found, -1, "done with found action object");
7120 } else {
7121 char buf[512];
7122
7123 report_req_bad_format(s, action);
7124 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
7125 mansession_lock(s);
7126 astman_send_error(s, m, buf);
7128 }
7129 if (ret) {
7130 return ret;
7131 }
7132 /* Once done with our message, deliver any pending events unless the
7133 requester doesn't want them as part of this response.
7134 */
7135 if (ast_strlen_zero(astman_get_header(m, "SuppressEvents"))) {
7136 return process_events(s);
7137 } else {
7138 return ret;
7139 }
7140}
int ast_shutting_down(void)
Definition: asterisk.c:1888
static void log_action(const struct message *m, const char *action)
Definition: manager.c:6984
static int check_manager_session_inuse(const char *name)
Definition: manager.c:1019
static void report_req_not_allowed(const struct mansession *s, const char *action)
Definition: manager.c:2208
static void report_session_limit(const struct mansession *s)
Definition: manager.c:2296
static void report_req_bad_format(const struct mansession *s, const char *action)
Definition: manager.c:2237
char username[80]
Definition: manager.c:343

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

715{
716 struct eventqent *ev;
717 struct timeval now = ast_tvnow();
718
720 while ( (ev = AST_RWLIST_FIRST(&all_events)) &&
721 ev->usecount == 0 && AST_RWLIST_NEXT(ev, eq_next)) {
723 ast_free(ev);
724 }
725
727 /* Never release the last event */
728 if (!AST_RWLIST_NEXT(ev, eq_next)) {
729 break;
730 }
731
732 /* 2.5 times whatever the HTTP timeout is (maximum 2.5 hours) is the maximum time that we will definitely cache an event */
733 if (ev->usecount == 0 && ast_tvdiff_sec(now, ev->tv) > (httptimeout > 3600 ? 3600 : httptimeout) * 2.5) {
735 ast_free(ev);
736 }
737 }
740}
static int httptimeout
Definition: manager.c:164
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:844
#define AST_RWLIST_FIRST
Definition: linkedlists.h:423

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

7452{
7453 struct ao2_container *sessions;
7455 time_t now = time(NULL);
7456 struct ao2_iterator i;
7457 int purged = 0;
7458
7459 sessions = ao2_global_obj_ref(mgr_sessions);
7460 if (!sessions) {
7461 return 0;
7462 }
7464 ao2_ref(sessions, -1);
7465
7466 /* The order of operations is significant */
7467 while (n_max > 0 && (session = ao2_iterator_next(&i))) {
7469 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) {
7470 if (session->authenticated
7471 && VERBOSITY_ATLEAST(2)
7473 ast_verb(2, "HTTP Manager '%s' timed out from %s\n",
7474 session->username, ast_sockaddr_stringify_addr(&session->addr));
7475 }
7478 n_max--;
7479 purged++;
7480 } else {
7483 }
7484 }
7486 return purged;
7487}
static void session_destroy(struct mansession_session *s)
Definition: manager.c:1006
#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_match()

static int queue_match ( const char *  app,
const char *  data,
const char *  search 
)
static

Definition at line 5048 of file manager.c.

5049{
5050 char *parse;
5052 AST_APP_ARG(queuename);
5055 AST_APP_ARG(announceoverride);
5056 AST_APP_ARG(queuetimeoutstr);
5057 AST_APP_ARG(agi);
5058 AST_APP_ARG(gosub);
5060 AST_APP_ARG(position);
5061 );
5062
5063 if (!strcasestr(app, "queue") || ast_strlen_zero(data)) {
5064 return 0;
5065 }
5066
5067 parse = ast_strdupa(data);
5069
5070 /*
5071 * The Queue application is fine unless the AGI parameter is set.
5072 * If it is, we need to check the user's permissions.
5073 */
5074 return !ast_strlen_zero(args.agi);
5075}
static char url[512]

References app, args, AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), options, strcasestr(), and url.

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

3838{
3840 size_t obj_size;
3841 int res;
3842
3843 obj_size = payload_size + sizeof(*obj);
3844
3845 obj = ast_malloc(obj_size);
3846 if (!obj) {
3847 return -1;
3848 }
3849
3850 obj->action = action;
3852 memcpy(obj->payload, payload, payload_size);
3853
3854 res = ast_queue_control_data(chan, AST_CONTROL_READ_ACTION, obj, obj_size);
3855
3856 ast_free(obj);
3857 return res;
3858}
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:1276
@ 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 3869 of file manager.c.

3870{
3871 return queue_read_action_payload(chan, (const unsigned char *)body,
3872 strlen(body) + 1, AST_FRAME_READ_ACTION_SEND_TEXT);
3873}
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:3836
@ 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 3885 of file manager.c.

3887{
3888 int res;
3889 struct ast_msg_data *obj;
3890
3892 NULL, NULL, content_type, body);
3893 if (!obj) {
3894 return -1;
3895 }
3896
3897 res = queue_read_action_payload(chan, (const unsigned char *)obj,
3899
3900 ast_free(obj);
3901 return res;
3902}
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 10075 of file manager.c.

10076{
10078}
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70

References __init_manager(), AST_MODULE_LOAD_FAILURE, and AST_MODULE_LOAD_SUCCESS.

Referenced by handle_manager_reload().

◆ report_auth_success()

static void report_auth_success ( const struct mansession s)
static

Definition at line 2183 of file manager.c.

2184{
2185 char session_id[32];
2186 struct ast_security_event_successful_auth successful_auth = {
2189 .common.service = "AMI",
2190 .common.account_id = s->session->username,
2191 .common.session_tv = &s->session->sessionstart_tv,
2192 .common.local_addr = {
2193 .addr = &s->tcptls_session->parent->local_address,
2194 .transport = mansession_get_transport(s),
2195 },
2196 .common.remote_addr = {
2197 .addr = &s->session->addr,
2198 .transport = mansession_get_transport(s),
2199 },
2200 .common.session_id = session_id,
2201 };
2202
2203 snprintf(session_id, sizeof(session_id), "%p", s->session);
2204
2205 ast_security_event_report(AST_SEC_EVT(&successful_auth));
2206}
static enum ast_transport mansession_get_transport(const struct mansession *s)
Definition: manager.c:2102
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 2133 of file manager.c.

2134{
2135 char session_id[32];
2136 struct ast_security_event_failed_acl failed_acl_event = {
2138 .common.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
2139 .common.service = "AMI",
2140 .common.account_id = username,
2141 .common.session_tv = &s->session->sessionstart_tv,
2142 .common.local_addr = {
2143 .addr = &s->tcptls_session->parent->local_address,
2144 .transport = mansession_get_transport(s),
2145 },
2146 .common.remote_addr = {
2147 .addr = &s->session->addr,
2148 .transport = mansession_get_transport(s),
2149 },
2150 .common.session_id = session_id,
2151 };
2152
2153 snprintf(session_id, sizeof(session_id), "%p", s->session);
2154
2155 ast_security_event_report(AST_SEC_EVT(&failed_acl_event));
2156}
#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 2266 of file manager.c.

2268{
2269 char session_id[32];
2270 struct ast_security_event_chal_resp_failed chal_resp_failed = {
2273 .common.service = "AMI",
2274 .common.account_id = s->session->username,
2275 .common.session_tv = &s->session->sessionstart_tv,
2276 .common.local_addr = {
2277 .addr = &s->tcptls_session->parent->local_address,
2278 .transport = mansession_get_transport(s),
2279 },
2280 .common.remote_addr = {
2281 .addr = &s->session->addr,
2282 .transport = mansession_get_transport(s),
2283 },
2284 .common.session_id = session_id,
2285
2286 .challenge = s->session->challenge,
2287 .response = response,
2288 .expected_response = expected_response,
2289 };
2290
2291 snprintf(session_id, sizeof(session_id), "%p", s->session);
2292
2293 ast_security_event_report(AST_SEC_EVT(&chal_resp_failed));
2294}
#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 2158 of file manager.c.

2159{
2160 char session_id[32];
2161 struct ast_security_event_inval_password inval_password = {
2164 .common.service = "AMI",
2165 .common.account_id = username,
2166 .common.session_tv = &s->session->sessionstart_tv,
2167 .common.local_addr = {
2168 .addr = &s->tcptls_session->parent->local_address,
2169 .transport = mansession_get_transport(s),
2170 },
2171 .common.remote_addr = {
2172 .addr = &s->session->addr,
2173 .transport = mansession_get_transport(s),
2174 },
2175 .common.session_id = session_id,
2176 };
2177
2178 snprintf(session_id, sizeof(session_id), "%p", s->session);
2179
2180 ast_security_event_report(AST_SEC_EVT(&inval_password));
2181}
#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 2108 of file manager.c.

2109{
2110 char session_id[32];
2111 struct ast_security_event_inval_acct_id inval_acct_id = {
2114 .common.service = "AMI",
2115 .common.account_id = username,
2116 .common.session_tv = &s->session->sessionstart_tv,
2117 .common.local_addr = {
2118 .addr = &s->tcptls_session->parent->local_address,
2119 .transport = mansession_get_transport(s),
2120 },
2121 .common.remote_addr = {
2122 .addr = &s->session->addr,
2123 .transport = mansession_get_transport(s),
2124 },
2125 .common.session_id = session_id,
2126 };
2127
2128 snprintf(session_id, sizeof(session_id), "%p", s);
2129
2130 ast_security_event_report(AST_SEC_EVT(&inval_acct_id));
2131}
#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 2237 of file manager.c.

2238{
2239 char session_id[32];
2240 char request_type[64];
2241 struct ast_security_event_req_bad_format req_bad_format = {
2244 .common.service = "AMI",
2245 .common.account_id = s->session->username,
2246 .common.session_tv = &s->session->sessionstart_tv,
2247 .common.local_addr = {
2248 .addr = &s->tcptls_session->parent->local_address,
2249 .transport = mansession_get_transport(s),
2250 },
2251 .common.remote_addr = {
2252 .addr = &s->session->addr,
2253 .transport = mansession_get_transport(s),
2254 },
2255 .common.session_id = session_id,
2256
2257 .request_type = request_type,
2258 };
2259
2260 snprintf(session_id, sizeof(session_id), "%p", s->session);
2261 snprintf(request_type, sizeof(request_type), "Action: %s", action);
2262
2263 ast_security_event_report(AST_SEC_EVT(&req_bad_format));
2264}
#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 2208 of file manager.c.

2209{
2210 char session_id[32];
2211 char request_type[64];
2212 struct ast_security_event_req_not_allowed req_not_allowed = {
2215 .common.service = "AMI",
2216 .common.account_id = s->session->username,
2217 .common.session_tv = &s->session->sessionstart_tv,
2218 .common.local_addr = {
2219 .addr = &s->tcptls_session->parent->local_address,
2220 .transport = mansession_get_transport(s),
2221 },
2222 .common.remote_addr = {
2223 .addr = &s->session->addr,
2224 .transport = mansession_get_transport(s),
2225 },
2226 .common.session_id = session_id,
2227
2228 .request_type = request_type,
2229 };
2230
2231 snprintf(session_id, sizeof(session_id), "%p", s->session);
2232 snprintf(request_type, sizeof(request_type), "Action: %s", action);
2233
2234 ast_security_event_report(AST_SEC_EVT(&req_not_allowed));
2235}
#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 2296 of file manager.c.

2297{
2298 char session_id[32];
2300 .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT,
2302 .common.service = "AMI",
2303 .common.account_id = s->session->username,
2304 .common.session_tv = &s->session->sessionstart_tv,
2305 .common.local_addr = {
2306 .addr = &s->tcptls_session->parent->local_address,
2307 .transport = mansession_get_transport(s),
2308 },
2309 .common.remote_addr = {
2310 .addr = &s->session->addr,
2311 .transport = mansession_get_transport(s),
2312 },
2313 .common.session_id = session_id,
2314 };
2315
2316 snprintf(session_id, sizeof(session_id), "%p", s->session);
2317
2319}
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().

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

1849{
1850 struct ast_iostream *stream;
1851 int len, res;
1852
1853 /* It's a result from one of the hook's action invocation */
1854 if (s->hook) {
1855 /*
1856 * to send responses, we're using the same function
1857 * as for receiving events. We call the event "HookResponse"
1858 */
1859 s->hook->helper(EVENT_FLAG_HOOKRESPONSE, "HookResponse", string);
1860 return 0;
1861 }
1862
1863 stream = s->stream ? s->stream : s->session->stream;
1864
1865 len = strlen(string);
1867 res = ast_iostream_write(stream, string, len);
1869
1870 if (res < len) {
1871 s->write_error = 1;
1872 }
1873
1874 return res;
1875}
void ast_iostream_set_timeout_inactivity(struct ast_iostream *stream, int timeout)
Set the iostream inactivity timeout timer.
Definition: iostream.c:122
ssize_t ast_iostream_write(struct ast_iostream *stream, const void *buffer, size_t count)
Write data to an iostream.
Definition: iostream.c:385
void ast_iostream_set_timeout_disable(struct ast_iostream *stream)
Disable the iostream timeout timer.
Definition: iostream.c:114
#define EVENT_FLAG_HOOKRESPONSE
Definition: manager.h:89
struct ast_iostream * stream
Definition: manager.c:325

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

1007{
1008 struct ao2_container *sessions;
1009
1010 sessions = ao2_global_obj_ref(mgr_sessions);
1011 if (sessions) {
1012 ao2_unlink(sessions, s);
1013 ao2_ref(sessions, -1);
1014 }
1016}
#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 935 of file manager.c.

936{
937 struct mansession_session *session = obj;
938 struct eventqent *eqe = session->last_ev;
939 struct ast_datastore *datastore;
940
941 /* Get rid of each of the data stores on the session */
942 while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) {
943 /* Free the data store */
944 ast_datastore_free(datastore);
945 }
946
947 if (eqe) {
949 }
950 if (session->chanvars) {
952 }
953
954 if (session->includefilters) {
955 ao2_t_ref(session->includefilters, -1, "decrement ref for include container, should be last one");
956 }
957
958 if (session->excludefilters) {
959 ao2_t_ref(session->excludefilters, -1, "decrement ref for exclude container, should be last one");
960 }
961
962 ast_mutex_destroy(&session->notify_lock);
963}
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:195
Structure for a data store object.
Definition: datastore.h:64
struct ast_datastore::@219 entry

References ao2_t_ref, ast_atomic_fetchadd_int(), ast_datastore_free(), AST_LIST_REMOVE_HEAD, ast_mutex_destroy, ast_variables_destroy(), ast_datastore::entry, 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 7357 of file manager.c.

7358{
7359 struct ast_tcptls_session_instance *ser = data;
7361 struct mansession s = {
7362 .tcptls_session = data,
7363 };
7364 int res;
7365 int arg = 1;
7366 struct ast_sockaddr ser_remote_address_tmp;
7367
7370 goto done;
7371 }
7372
7373 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
7374 session = build_mansession(&ser_remote_address_tmp);
7375
7376 if (session == NULL) {
7378 goto done;
7379 }
7380
7381 /* here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
7382 * This is necessary to prevent delays (caused by buffering) as we
7383 * write to the socket in bits and pieces. */
7384 if (setsockopt(ast_iostream_get_fd(ser->stream), IPPROTO_TCP, TCP_NODELAY, (char *) &arg, sizeof(arg)) < 0) {
7385 ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on manager connection: %s\n", strerror(errno));
7386 }
7388
7390 /* Hook to the tail of the event queue */
7391 session->last_ev = grab_last();
7392
7393 ast_mutex_init(&s.lock);
7394
7395 /* these fields duplicate those in the 'ser' structure */
7396 session->stream = s.stream = ser->stream;
7397 ast_sockaddr_copy(&session->addr, &ser_remote_address_tmp);
7398 s.session = session;
7399
7400 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
7401
7402 if(time(&session->authstart) == -1) {
7403 ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
7407 goto done;
7408 }
7410
7411 /*
7412 * We cannot let the stream exclusively wait for data to arrive.
7413 * We have to wake up the task to send async events.
7414 */
7416
7418 ast_tvnow(), authtimeout * 1000);
7419
7420 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */
7421 for (;;) {
7422 if ((res = do_message(&s)) < 0 || s.write_error || session->kicked) {
7423 break;
7424 }
7425 if (session->authenticated) {
7427 }
7428 }
7429 /* session is over, explain why and terminate */
7430 if (session->authenticated) {
7432 ast_verb(2, "Manager '%s' %s from %s\n", session->username, session->kicked ? "kicked" : "logged off", ast_sockaddr_stringify_addr(&session->addr));
7433 }
7434 } else {
7436 if (displayconnects) {
7437 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr));
7438 }
7439 }
7440
7442
7444done:
7445 ao2_ref(ser, -1);
7446 ser = NULL;
7447 return NULL;
7448}
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:966
static int do_message(struct mansession *s)
Definition: manager.c:7272
static struct eventqent * grab_last(void)
Definition: manager.c:694
static int authlimit
Definition: manager.c:171
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:149
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:140
void ast_iostream_nonblock(struct ast_iostream *stream)
Make an iostream non-blocking.
Definition: iostream.c:104
#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:151
struct ast_sockaddr remote_address
Definition: tcptls.h:153

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

2090{
2091 int maskint = strings_to_mask(eventmask);
2092
2093 ao2_lock(s->session);
2094 if (maskint >= 0) {
2095 s->session->send_events = maskint;
2096 }
2097 ao2_unlock(s->session);
2098
2099 return maskint;
2100}
static int strings_to_mask(const char *string)
Definition: manager.c:883

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

Referenced by action_events(), and authenticate().

◆ should_send_event()

static int should_send_event ( struct ao2_container includefilters,
struct ao2_container excludefilters,
struct eventqent eqe 
)
static

Definition at line 5645 of file manager.c.

5647{
5648 int result = 0;
5649
5650 if (manager_debug) {
5651 ast_verbose("<-- Examining AMI event (%u): -->\n%s\n", eqe->event_name_hash, eqe->eventdata);
5652 } else {
5653 ast_debug(4, "Examining AMI event (%u):\n%s\n", eqe->event_name_hash, eqe->eventdata);
5654 }
5655 if (!ao2_container_count(includefilters) && !ao2_container_count(excludefilters)) {
5656 return 1; /* no filtering means match all */
5657 } else if (ao2_container_count(includefilters) && !ao2_container_count(excludefilters)) {
5658 /* include filters only: implied exclude all filter processed first, then include filters */
5659 ao2_t_callback_data(includefilters, OBJ_NODATA, filter_cmp_fn, eqe, &result, "find filter in includefilters container");
5660 return result;
5661 } else if (!ao2_container_count(includefilters) && ao2_container_count(excludefilters)) {
5662 /* exclude filters only: implied include all filter processed first, then exclude filters */
5663 ao2_t_callback_data(excludefilters, OBJ_NODATA, filter_cmp_fn, eqe, &result, "find filter in excludefilters container");
5664 return !result;
5665 } else {
5666 /* include and exclude filters: implied exclude all filter processed first, then include filters, and lastly exclude filters */
5667 ao2_t_callback_data(includefilters, OBJ_NODATA, filter_cmp_fn, eqe, &result, "find filter in session filter container");
5668 if (result) {
5669 result = 0;
5670 ao2_t_callback_data(excludefilters, OBJ_NODATA, filter_cmp_fn, eqe, &result, "find filter in session filter container");
5671 return !result;
5672 }
5673 }
5674
5675 return result;
5676}
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 filter_cmp_fn(void *obj, void *arg, void *data, int flags)
Definition: manager.c:5592

References ao2_container_count(), ao2_t_callback_data, ast_debug, ast_verbose(), eventqent::event_name_hash, filter_cmp_fn(), manager_debug, OBJ_NODATA, and result.

Referenced by action_waitevent(), and process_events().

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

884{
885 const char *p;
886
887 if (ast_strlen_zero(string)) {
888 return -1;
889 }
890
891 for (p = string; *p; p++) {
892 if (*p < '0' || *p > '9') {
893 break;
894 }
895 }
896 if (!*p) { /* all digits */
897 return atoi(string);
898 }
899 if (ast_false(string)) {
900 return 0;
901 }
902 if (ast_true(string)) { /* all permissions */
903 int x, ret = 0;
904 for (x = 0; x < ARRAY_LEN(perms); x++) {
905 ret |= perms[x].num;
906 }
907 return ret;
908 }
909 return get_perm(string);
910}
static int get_perm(const char *instr)
Definition: manager.c:862

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

915{
916 int refcount = ao2_ref(s, -1);
917 if (manager_debug) {
918 ast_debug(1, "Mansession: %p refcount now %d\n", s, refcount - 1);
919 }
920 return NULL;
921}

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

792{
793 int i;
794 char *sep = "";
795
796 ast_str_reset(*res);
797 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
798 if ((authority & perms[i].num) == perms[i].num) {
799 ast_str_append(res, 0, "%s%s", sep, perms[i].label);
800 sep = ",";
801 }
802 }
803
804 if (ast_str_strlen(*res) == 0) {
805 /* replace empty string with something sensible */
806 ast_str_append(res, 0, "<none>");
807 }
808
809 return ast_str_buffer(*res);
810}

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

Referenced by handle_showmanager().

Variable Documentation

◆ acl_change_sub

struct stasis_subscription* acl_change_sub
static

Definition at line 179 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 162 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 171 of file manager.c.

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

◆ authtimeout

int authtimeout
static

Definition at line 170 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 165 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 176 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 196 of file manager.c.

Referenced by action_createconfig(), astman_live_dangerously(), file_in_modules_dir(), is_restricted_file(), and load_asterisk_conf().

◆ manager_channelvars

char* manager_channelvars
static

Definition at line 172 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 7535 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

◆ match_type_names

char* match_type_names[]
static

Definition at line 394 of file manager.c.

Referenced by manager_add_filter().

◆ originate_app_permissions

struct originate_permissions_entry originate_app_permissions[]
static

Definition at line 5085 of file manager.c.

Referenced by is_originate_app_permitted().

◆ 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 188 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 191 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 178 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 1886 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 222 of file manager.c.