Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 569 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 1893 of file manager.c.

◆ DEFAULT_REALM

#define DEFAULT_REALM   "asterisk"

Definition at line 179 of file manager.c.

◆ EVENT_FLAG_SHUTDOWN

#define EVENT_FLAG_SHUTDOWN   -1

Fake event class used to end sessions at shutdown.

Definition at line 212 of file manager.c.

◆ GET_HEADER_FIRST_MATCH

#define GET_HEADER_FIRST_MATCH   0

Definition at line 1593 of file manager.c.

◆ GET_HEADER_LAST_MATCH

#define GET_HEADER_LAST_MATCH   1

Definition at line 1594 of file manager.c.

◆ GET_HEADER_SKIP_EMPTY

#define GET_HEADER_SKIP_EMPTY   2

Definition at line 1595 of file manager.c.

◆ MANAGER_EVENT_BUF_INITSIZE

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 7538 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 566 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 778 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 224 of file manager.c.

◆ MAX_VARS

#define MAX_VARS   128

Definition at line 209 of file manager.c.

◆ MGR_SHOW_TERMINAL_WIDTH

#define MGR_SHOW_TERMINAL_WIDTH   80

Definition at line 207 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 1941 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 127 of file manager.c.

127 {
128 FILTER_SUCCESS = 0,
132};
@ FILTER_SUCCESS
Definition: manager.c:128
@ FILTER_FORMAT_ERROR
Definition: manager.c:131
@ FILTER_COMPILE_FAIL
Definition: manager.c:130
@ FILTER_ALLOC_FAILED
Definition: manager.c:129

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

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

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

389 {
396};
@ FILTER_MATCH_ENDS_WITH
Definition: manager.c:393
@ FILTER_MATCH_CONTAINS
Definition: manager.c:394
@ FILTER_MATCH_STARTS_WITH
Definition: manager.c:392
@ FILTER_MATCH_REGEX
Definition: manager.c:390
@ FILTER_MATCH_NONE
Definition: manager.c:395
@ FILTER_MATCH_EXACT
Definition: manager.c:391

◆ mansession_message_parsing

Enumerator
MESSAGE_OKAY 
MESSAGE_LINE_TOO_LONG 

Definition at line 317 of file manager.c.

317 {
320};
@ MESSAGE_OKAY
Definition: manager.c:318
@ MESSAGE_LINE_TOO_LONG
Definition: manager.c:319

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

7675{
7676 struct ao2_container *sessions = ao2_global_obj_ref(mgr_sessions);
7677 va_list ap;
7678 int res;
7679
7681 /* Nobody is listening */
7683 return 0;
7684 }
7685
7686 va_start(ap, fmt);
7688 file, line, func, fmt, ap);
7689 va_end(ap);
7691 return res;
7692}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
static struct unistimsession * sessions
static int chancount
Definition: channel.c:93
#define any_manager_listeners(sessions)
Definition: manager.c:569
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:7540
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 1610 of file manager.c.

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

1896{

◆ __init_manager_event_buf()

static void __init_manager_event_buf ( void  )
static

Definition at line 7537 of file manager.c.

7551{

◆ __init_userevent_buf()

static void __init_userevent_buf ( void  )
static

Definition at line 1890 of file manager.c.

1896{

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

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

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

7551{
7553 const char *cat_str;
7554 struct timeval now;
7555 struct ast_str *buf;
7556 int i;
7557 int event_name_hash;
7558
7561 ast_debug(3, "AMI Event '%s' is globally disabled, skipping\n", event);
7562 /* Event is globally disabled */
7563 return -1;
7564 }
7565 }
7566
7568 if (!buf) {
7569 return -1;
7570 }
7571
7572 cat_str = authority_to_str(category, &auth);
7573 ast_str_set(&buf, 0,
7574 "Event: %s\r\n"
7575 "Privilege: %s\r\n",
7576 event, cat_str);
7577
7578 if (timestampevents) {
7579 now = ast_tvnow();
7580 ast_str_append(&buf, 0,
7581 "Timestamp: %ld.%06lu\r\n",
7582 (long)now.tv_sec, (unsigned long) now.tv_usec);
7583 }
7584 if (manager_debug) {
7585 static int seq;
7586
7587 ast_str_append(&buf, 0,
7588 "SequenceNumber: %d\r\n",
7590 ast_str_append(&buf, 0,
7591 "File: %s\r\n"
7592 "Line: %d\r\n"
7593 "Func: %s\r\n",
7594 file, line, func);
7595 }
7597 ast_str_append(&buf, 0,
7598 "SystemName: %s\r\n",
7600 }
7601
7602 ast_str_append_va(&buf, 0, fmt, ap);
7603 for (i = 0; i < chancount; i++) {
7605 }
7606
7607 ast_str_append(&buf, 0, "\r\n");
7608
7609 event_name_hash = ast_str_hash(event);
7610
7611 append_event(ast_str_buffer(buf), event_name_hash, category);
7612
7613 /* Wake up any sleeping sessions */
7614 if (sessions) {
7615 struct ao2_iterator iter;
7617
7618 iter = ao2_iterator_init(sessions, 0);
7619 while ((session = ao2_iterator_next(&iter))) {
7620 ast_mutex_lock(&session->notify_lock);
7621 if (session->waiting_thread != AST_PTHREADT_NULL) {
7622 pthread_kill(session->waiting_thread, SIGURG);
7623 } else {
7624 /* We have an event to process, but the mansession is
7625 * not waiting for it. We still need to indicate that there
7626 * is an event waiting so that get_input processes the pending
7627 * event instead of polling.
7628 */
7629 session->pending_event = 1;
7630 }
7631 ast_mutex_unlock(&session->notify_lock);
7633 }
7634 ao2_iterator_destroy(&iter);
7635 }
7636
7637 if (category != EVENT_FLAG_SHUTDOWN && !AST_RWLIST_EMPTY(&manager_hooks)) {
7638 struct manager_custom_hook *hook;
7639
7641 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
7642 hook->helper(category, event, ast_str_buffer(buf));
7643 }
7645 }
7646
7647 return 0;
7648}
static volatile unsigned int seq
Definition: app_sms.c:123
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:7495
static struct ast_threadstorage manager_event_buf
Definition: manager.c:7537
static int manager_debug
Definition: manager.c:173
static void append_channel_vars(struct ast_str **pbuf, struct ast_channel *chan)
Definition: manager.c:7520
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:918
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:819
#define MAX_AUTH_PERM_STRING
Definition: manager.c:778
static int timestampevents
Definition: manager.c:167
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition: manager.c:212
#define MANAGER_EVENT_BUF_INITSIZE
Definition: manager.c:7538
static char * manager_disabledevents
Definition: manager.c:177
#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:70
#define ast_mutex_unlock(a)
Definition: lock.h:194
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:761
#define ast_mutex_lock(a)
Definition: lock.h:193
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
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:447
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:370
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 10141 of file manager.c.

10143{
10145 return;
10146 }
10147
10148 /* For now, this is going to be performed simply and just execute a forced reload. */
10149 ast_log(LOG_NOTICE, "Reloading manager in response to ACL change event.\n");
10150 __init_manager(1, 1);
10151}
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:9644
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 235 of file manager.c.

236{
237 if (!acl_change_sub) {
242 }
243}
static struct stasis_subscription * acl_change_sub
Definition: manager.c:183
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:10141
#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 245 of file manager.c.

246{
248}
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 4500 of file manager.c.

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

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

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

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

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

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

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

4103{
4104 const char *name = astman_get_header(m, "Channel");
4105 const char *exten = astman_get_header(m, "Exten");
4106 const char *context = astman_get_header(m, "Context");
4107 struct ast_channel *chan;
4108
4109 if (ast_strlen_zero(name)) {
4110 astman_send_error(s, m, "No channel specified");
4111 return 0;
4112 }
4113
4114 if (ast_strlen_zero(exten)) {
4115 astman_send_error(s, m, "No extension specified");
4116 return 0;
4117 }
4118
4120 if (!chan) {
4121 astman_send_error(s, m, "Channel specified does not exist");
4122 return 0;
4123 }
4124
4125 if (ast_strlen_zero(context)) {
4127 }
4128
4129 switch (ast_bridge_transfer_blind(1, chan, exten, context, NULL, NULL)) {
4131 astman_send_error(s, m, "Transfer not permitted");
4132 break;
4134 astman_send_error(s, m, "Transfer invalid");
4135 break;
4137 astman_send_error(s, m, "Transfer failed");
4138 break;
4140 astman_send_ack(s, m, "Transfer succeeded");
4141 break;
4142 }
4143
4144 ast_channel_unref(chan);
4145 return 0;
4146}
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 4202 of file manager.c.

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

3408{
3409 const char *authtype = astman_get_header(m, "AuthType");
3410
3411 if (!strcasecmp(authtype, "MD5")) {
3413 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
3414 }
3415 mansession_lock(s);
3416 astman_start_ack(s, m);
3417 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
3419 } else {
3420 astman_send_error(s, m, "Must specify AuthType");
3421 }
3422 return 0;
3423}
static void mansession_unlock(struct mansession *s)
Unlock the 'mansession' structure.
Definition: manager.c:2084
static void mansession_lock(struct mansession *s)
Lock the 'mansession' structure.
Definition: manager.c:2078
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2023
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1907
char challenge[10]
Definition: manager.c:294
struct mansession_session * session
Definition: manager.c:328
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 4279 of file manager.c.

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

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

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

Referenced by __init_manager().

◆ action_coreshowchannelmap()

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

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

Definition at line 6749 of file manager.c.

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

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

Referenced by __init_manager().

◆ action_coreshowchannels()

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

Manager command "CoreShowChannels" - List currently defined channels and some information about them.

Definition at line 6581 of file manager.c.

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

6508{
6509 const char *actionid = astman_get_header(m, "ActionID");
6510 char idText[150];
6511 char startuptime[150], startupdate[150];
6512 char reloadtime[150], reloaddate[150];
6513 struct ast_tm tm;
6514
6515 if (!ast_strlen_zero(actionid)) {
6516 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6517 } else {
6518 idText[0] = '\0';
6519 }
6520
6522 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
6523 ast_strftime(startupdate, sizeof(startupdate), "%Y-%m-%d", &tm);
6525 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
6526 ast_strftime(reloaddate, sizeof(reloaddate), "%Y-%m-%d", &tm);
6527
6528 astman_append(s, "Response: Success\r\n"
6529 "%s"
6530 "CoreStartupDate: %s\r\n"
6531 "CoreStartupTime: %s\r\n"
6532 "CoreReloadDate: %s\r\n"
6533 "CoreReloadTime: %s\r\n"
6534 "CoreCurrentCalls: %d\r\n"
6535 "CoreProcessedCalls: %d\r\n"
6536 "\r\n",
6537 idText,
6538 startupdate,
6539 startuptime,
6540 reloaddate,
6541 reloadtime,
6544 );
6545 return 0;
6546}
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:499
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
struct timeval ast_lastreloadtime
Definition: asterisk.c:343
struct timeval ast_startuptime
Definition: asterisk.c:342
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 3097 of file manager.c.

3098{
3099 int fd;
3100 const char *fn = astman_get_header(m, "Filename");
3101 char *stripped_filename;
3102 RAII_VAR(char *, filepath, NULL, ast_free);
3103 RAII_VAR(char *, real_dir, NULL, ast_std_free);
3104 RAII_VAR(char *, real_path, NULL, ast_free);
3105 char *filename;
3106
3107 if (ast_strlen_zero(fn)) {
3108 astman_send_error(s, m, "Filename not specified");
3109 return 0;
3110 }
3111
3112 stripped_filename = ast_strip(ast_strdupa(fn));
3113
3114 /* If the file name is relative, prepend ast_config_AST_CONFIG_DIR */
3115 if (stripped_filename[0] != '/') {
3116 if (ast_asprintf(&filepath, "%s/%s", ast_config_AST_CONFIG_DIR, stripped_filename) == -1) {
3117 return -1;
3118 }
3119 } else {
3120 filepath = ast_strdup(stripped_filename);
3121 }
3122
3123 /*
3124 * We can't call is_restricted_file() here because it uses realpath() and...
3125 *
3126 * realpath() and other functions that canonicalize paths won't work with
3127 * a filename that doesn't exist, so we need to separate the directory
3128 * from the filename and canonicalize the directory first. We have to do
3129 * the separation manually because dirname() and basename() aren't all
3130 * that friendly to multi-threaded programs and there are different
3131 * versions of basename for glibc and POSIX.
3132 */
3133
3134 filename = strrchr(filepath, '/');
3135 if (!filename) {
3136 astman_send_error(s, m, "Filename is invalid");
3137 return 0;
3138 }
3139 *filename = '\0';
3140 filename++;
3141
3142 /* filepath just has the directory now so canonicalize it. */
3143 real_dir = realpath(filepath, NULL);
3144 if (ast_strlen_zero(real_dir)) {
3145 astman_send_error(s, m, strerror(errno));
3146 return 0;
3147 }
3148
3149 /* Check if the directory is restricted. */
3151 astman_send_error(s, m, "File requires escalated privileges");
3152 return 0;
3153 }
3154
3155 /* Create the final file path. */
3156 if (ast_asprintf(&real_path, "%s/%s", real_dir, filename) == -1) {
3157 astman_send_error(s, m, strerror(errno));
3158 return -1;
3159 }
3160
3161 if ((fd = open(real_path, O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
3162 close(fd);
3163 astman_send_ack(s, m, "New configuration file created successfully");
3164 } else {
3165 astman_send_error(s, m, strerror(errno));
3166 }
3167
3168 return 0;
3169}
#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:200
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151
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 7809 of file manager.c.

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

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

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

Referenced by __init_manager().

◆ action_extensionstate()

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

Definition at line 5464 of file manager.c.

5465{
5466 const char *exten = astman_get_header(m, "Exten");
5467 const char *context = astman_get_header(m, "Context");
5468 char hint[256];
5469 int status;
5470
5471 if (ast_strlen_zero(exten)) {
5472 astman_send_error(s, m, "Extension not specified");
5473 return 0;
5474 }
5475 if (ast_strlen_zero(context)) {
5476 context = "default";
5477 }
5479 hint[0] = '\0';
5480 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
5481 astman_start_ack(s, m);
5482 astman_append(s, "Message: Extension Status\r\n"
5483 "Exten: %s\r\n"
5484 "Context: %s\r\n"
5485 "Hint: %s\r\n"
5486 "Status: %d\r\n"
5487 "StatusText: %s\r\n"
5488 "\r\n",
5489 exten, context, hint, status,
5491 return 0;
5492}
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 5686 of file manager.c.

5687{
5688 const char *match_criteria = astman_get_header(m, "MatchCriteria");
5689 const char *filter = astman_get_header(m, "Filter");
5690 const char *operation = astman_get_header(m, "Operation");
5691 int res;
5692
5693 if (!strcasecmp(operation, "Add")) {
5694 char *criteria;
5695 int have_match = !ast_strlen_zero(match_criteria);
5696
5697 /* Create an eventfilter expression.
5698 * eventfilter[(match_criteria)]
5699 */
5700 res = ast_asprintf(&criteria, "eventfilter%s%s%s",
5701 S_COR(have_match, "(", ""), S_OR(match_criteria, ""),
5702 S_COR(have_match, ")", ""));
5703 if (res <= 0) {
5704 astman_send_error(s, m, "Internal Error. Failed to allocate storage for filter type");
5705 return 0;
5706 }
5707
5709 ast_std_free(criteria);
5710 if (res != FILTER_SUCCESS) {
5711 if (res == FILTER_ALLOC_FAILED) {
5712 astman_send_error(s, m, "Internal Error. Failed to allocate regex for filter");
5713 return 0;
5714 } else if (res == FILTER_COMPILE_FAIL) {
5715 astman_send_error(s, m,
5716 "Filter did not compile. Check the syntax of the filter given.");
5717 return 0;
5718 } else if (res == FILTER_FORMAT_ERROR) {
5719 astman_send_error(s, m,
5720 "Filter was formatted incorrectly. Check the syntax of the filter given.");
5721 return 0;
5722 } else {
5723 astman_send_error(s, m, "Internal Error. Failed adding filter.");
5724 return 0;
5725 }
5726 }
5727
5728 astman_send_ack(s, m, "Success");
5729 return 0;
5730 }
5731
5732 astman_send_error(s, m, "Unknown operation");
5733 return 0;
5734}
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:5753
#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:301
struct ao2_container * includefilters
Definition: manager.c:300

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

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

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

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

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

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

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

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

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

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

3290{
3291 struct manager_action *cur;
3293
3294 astman_start_ack(s, m);
3296 AST_RWLIST_TRAVERSE(&actions, cur, list) {
3297 if ((s->session->writeperm & cur->authority) || cur->authority == 0) {
3298 astman_append(s, "%s: %s (Priv: %s)\r\n",
3299 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
3300 }
3301 }
3303 astman_append(s, "\r\n");
3304
3305 return 0;
3306}

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

6831{
6832 if (ast_logger_rotate()) {
6833 astman_send_error(s, m, "Failed to reload the logger and rotate log files");
6834 return 0;
6835 }
6836
6837 astman_send_ack(s, m, "Reloaded the logger and rotated log files");
6838 return 0;
6839}
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 3358 of file manager.c.

3359{
3360
3361 /* still authenticated - don't process again */
3362 if (s->session->authenticated) {
3363 astman_send_ack(s, m, "Already authenticated");
3364 return 0;
3365 }
3366
3367 if (authenticate(s, m)) {
3368 sleep(1);
3369 astman_send_error(s, m, "Authentication failed");
3370 return -1;
3371 }
3372 s->session->authenticated = 1;
3375 ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_sockaddr_stringify_addr(&s->session->addr));
3376 }
3377 astman_send_ack(s, m, "Authentication accepted");
3382 const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
3383 long uptime = 0;
3384 long lastreloaded = 0;
3385 struct timeval tmp;
3386 struct timeval curtime = ast_tvnow();
3387
3388 if (ast_startuptime.tv_sec) {
3389 tmp = ast_tvsub(curtime, ast_startuptime);
3390 uptime = tmp.tv_sec;
3391 }
3392
3393 if (ast_lastreloadtime.tv_sec) {
3394 tmp = ast_tvsub(curtime, ast_lastreloadtime);
3395 lastreloaded = tmp.tv_sec;
3396 }
3397
3398 astman_append(s, "Event: FullyBooted\r\n"
3399 "Privilege: %s\r\n"
3400 "Uptime: %ld\r\n"
3401 "LastReload: %ld\r\n"
3402 "Status: Fully Booted\r\n\r\n", cat_str, uptime, lastreloaded);
3403 }
3404 return 0;
3405}
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:1063
static int unauth_sessions
Definition: manager.c:182
static int authenticate(struct mansession *s, const struct message *m)
Definition: manager.c:2332
struct ast_flags ast_options
Definition: options.c:61
@ AST_OPT_FLAG_FULLY_BOOTED
Definition: options.h:58
#define ast_verb(level,...)
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:286
struct ast_sockaddr addr
Definition: manager.c:284
uint32_t managerid
Definition: manager.c:289
char username[80]
Definition: manager.c:293
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 3352 of file manager.c.

3353{
3354 astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
3355 return -1;
3356}
void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg)
Send response in manager transaction.
Definition: manager.c:1981

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

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

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

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

References ao2_cleanup, app, ast_callerid_parse(), ast_calloc, ast_copy_string(), ast_exists_extension(), ast_findlabel_extension(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_remove_by_type(), ast_format_cap_update_by_allow_disallow(), ast_format_slin, ast_free, AST_MAX_PUBLIC_UNIQUEID, AST_MEDIA_TYPE_UNKNOWN, AST_OUTGOING_WAIT, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten_predial(), ast_pthread_create_detached, ast_shrink_phone_number(), ast_string_field_build, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_true(), ast_variables_destroy(), ast_variables_dup(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), astman_send_error_va(), fast_originate_helper::cap, mansession_session::chanvars, codecs, voicemailpwcheck::context, destroy_fast_originate_helper(), fast_originate_helper::early_media, 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 2429 of file manager.c.

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

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

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

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

6550{
6551 const char *module = astman_get_header(m, "Module");
6553
6554 switch (res) {
6556 astman_send_error(s, m, "No such module");
6557 break;
6559 astman_send_error(s, m, "Module does not support reload");
6560 break;
6562 astman_send_error(s, m, "An unknown error occurred");
6563 break;
6565 astman_send_error(s, m, "A reload is in progress");
6566 break;
6568 astman_send_error(s, m, "Module not initialized");
6569 break;
6572 /* Treat a queued request as success */
6573 astman_send_ack(s, m, "Module Reloaded");
6574 break;
6575 }
6576 return 0;
6577}
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 3908 of file manager.c.

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

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

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

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

3753{
3754 const char *name = astman_get_header(m, "Channel");
3755 const char *chan_variables = astman_get_header(m, "Variables");
3756 const char *all_chan_variables = astman_get_header(m, "AllVariables");
3757 int all_variables = 0;
3758 const char *id = astman_get_header(m, "ActionID");
3759 char *variables = ast_strdupa(S_OR(chan_variables, ""));
3760 struct ast_channel *chan;
3761 int channels = 0;
3762 int all = ast_strlen_zero(name); /* set if we want all channels */
3763 char id_text[256];
3764 struct ast_channel_iterator *it_chans = NULL;
3766 AST_APP_ARG(name)[100];
3767 );
3768
3769 if (!ast_strlen_zero(all_chan_variables)) {
3770 all_variables = ast_true(all_chan_variables);
3771 }
3772
3774 astman_send_error(s, m, "Status Access Forbidden: Variables");
3775 return 0;
3776 }
3777
3778 if (all) {
3779 if (!(it_chans = ast_channel_iterator_all_new())) {
3780 astman_send_error(s, m, "Memory Allocation Failure");
3781 return 1;
3782 }
3783 chan = ast_channel_iterator_next(it_chans);
3784 } else {
3786 if (!chan) {
3787 astman_send_error(s, m, "No such channel");
3788 return 0;
3789 }
3790 }
3791
3792 astman_send_listack(s, m, "Channel status will follow", "start");
3793
3794 if (!ast_strlen_zero(id)) {
3795 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
3796 } else {
3797 id_text[0] = '\0';
3798 }
3799
3800 if (!ast_strlen_zero(chan_variables)) {
3801 AST_STANDARD_APP_ARGS(vars, variables);
3802 }
3803
3804 /* if we look by name, we break after the first iteration */
3805 for (; chan; all ? chan = ast_channel_iterator_next(it_chans) : 0) {
3806 ast_channel_lock(chan);
3807
3808 generate_status(s, chan, vars.name, vars.argc, all_variables, id_text, &channels);
3809
3810 ast_channel_unlock(chan);
3811 chan = ast_channel_unref(chan);
3812 }
3813
3814 if (it_chans) {
3816 }
3817
3818 astman_send_list_complete_start(s, m, "StatusComplete", channels);
3819 astman_append(s, "Items: %d\r\n", channels);
3821
3822 return 0;
3823}
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1387
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1449
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1435
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:3637
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.

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

Referenced by __init_manager().

◆ action_timeout()

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

Definition at line 5534 of file manager.c.

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

References ast_channel_get_by_name(), ast_channel_lock, ast_channel_setwhentohangup_tv(), ast_channel_unlock, ast_channel_unref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), c, and name.

Referenced by __init_manager().

◆ action_updateconfig()

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

Definition at line 3006 of file manager.c.

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

6443{
6444 const char *event = astman_get_header(m, "UserEvent");
6445 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
6446 int x;
6447
6448 ast_str_reset(body);
6449
6450 for (x = 0; x < m->hdrcount; x++) {
6451 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:")) &&
6452 strncasecmp("Action:", m->headers[x], strlen("Action:"))) {
6453 ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
6454 }
6455 }
6456
6457 astman_send_ack(s, m, "Event Sent");
6458 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body));
6459 return 0;
6460}
static struct ast_threadstorage userevent_buf
Definition: manager.c:1890
#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 3171 of file manager.c.

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

1581{
1582 struct eventqent *next;
1583
1585 if ((next = AST_RWLIST_NEXT(e, eq_next))) {
1588 }
1590 return next;
1591}
int usecount
Definition: manager.c:154

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

4476{
4477 const char *unitamount;
4478 const char *unittype;
4479 struct ast_str *str = ast_str_alloca(32);
4480
4481 memset(entry, 0, sizeof(*entry));
4482
4483 ast_str_set(&str, 0, "UnitAmount(%u)", entry_num);
4484 unitamount = astman_get_header(m, ast_str_buffer(str));
4485
4486 ast_str_set(&str, 0, "UnitType(%u)", entry_num);
4487 unittype = astman_get_header(m, ast_str_buffer(str));
4488
4489 if (!ast_strlen_zero(unitamount) && (sscanf(unitamount, "%30u", &entry->amount) == 1)) {
4490 entry->valid_amount = 1;
4491 }
4492
4493 if (!ast_strlen_zero(unittype) && sscanf(unittype, "%30u", &entry->type) == 1) {
4494 entry->valid_type = 1;
4495 }
4496
4497 return 0;
4498}
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 5013 of file manager.c.

5014{
5015 /*
5016 * We use strcasestr so we don't have to trim any blanks
5017 * from the front or back of the string.
5018 */
5019 return !!(strcasestr(app, search));
5020}
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 5032 of file manager.c.

5033{
5034 if (ast_strlen_zero(data)) {
5035 return 0;
5036 }
5037 return !!(strstr(data, search));
5038}

References ast_strlen_zero().

◆ append_channel_vars()

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

Definition at line 7520 of file manager.c.

7521{
7522 struct varshead *vars;
7523 struct ast_var_t *var;
7524
7525 vars = ast_channel_get_manager_vars(chan);
7526 if (!vars) {
7527 return;
7528 }
7529
7530 AST_LIST_TRAVERSE(vars, var, entries) {
7531 ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", ast_channel_name(chan), var->name, var->value);
7532 }
7533 ao2_ref(vars, -1);
7534}
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:8009
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::@213 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 7495 of file manager.c.

7496{
7497 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
7498 static int seq; /* sequence number */
7499
7500 if (!tmp) {
7501 return -1;
7502 }
7503
7504 /* need to init all fields, because ast_malloc() does not */
7505 tmp->usecount = 0;
7506 tmp->category = category;
7507 tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
7508 tmp->tv = ast_tvnow();
7510 AST_RWLIST_NEXT(tmp, eq_next) = NULL;
7511 strcpy(tmp->eventdata, str);
7512
7514 AST_RWLIST_INSERT_TAIL(&all_events, tmp, eq_next);
7516
7517 return 0;
7518}
#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:156
struct timeval tv
Definition: manager.c:157
int event_name_hash
Definition: manager.c:158

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

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

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

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

685{
686 return manager_enabled;
687}
static int manager_enabled
Definition: manager.c:170

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

460{
461 return stasis_router;
462}
static struct stasis_message_router * stasis_router
The stasis_message_router for all Stasis Message Bus API messages.
Definition: manager.c:189

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

455{
456 return manager_topic;
457}
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:186

References manager_topic.

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

◆ ast_manager_hangup_helper()

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

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

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

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

Definition at line 3425 of file manager.c.

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

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

7824{
7825 struct manager_action *cur;
7826
7827 cur = ao2_t_alloc(sizeof(*cur), action_destroy, action);
7828 if (!cur) {
7829 return -1;
7830 }
7831 if (ast_string_field_init(cur, 128)) {
7832 ao2_t_ref(cur, -1, "action object creation failed");
7833 return -1;
7834 }
7835
7836 if (ast_string_field_init_extended(cur, since)) {
7837 ao2_t_ref(cur, -1, "action object creation failed");
7838 return -1;
7839 }
7840
7841 cur->action = action;
7842 cur->authority = auth;
7843 cur->func = func;
7844 cur->module = module;
7845#ifdef AST_XML_DOCS
7847 char *tmpxml;
7848
7849 tmpxml = ast_xmldoc_build_since("manager", action, NULL);
7850 ast_string_field_set(cur, since, tmpxml);
7851 ast_free(tmpxml);
7852
7853 tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL);
7854 ast_string_field_set(cur, synopsis, tmpxml);
7855 ast_free(tmpxml);
7856
7857 tmpxml = ast_xmldoc_build_syntax("manager", action, NULL);
7858 ast_string_field_set(cur, syntax, tmpxml);
7859 ast_free(tmpxml);
7860
7861 tmpxml = ast_xmldoc_build_description("manager", action, NULL);
7862 ast_string_field_set(cur, description, tmpxml);
7863 ast_free(tmpxml);
7864
7865 tmpxml = ast_xmldoc_build_seealso("manager", action, NULL);
7866 ast_string_field_set(cur, seealso, tmpxml);
7867 ast_free(tmpxml);
7868
7869 tmpxml = ast_xmldoc_build_arguments("manager", action, NULL);
7870 ast_string_field_set(cur, arguments, tmpxml);
7871 ast_free(tmpxml);
7872
7875
7876 cur->docsrc = AST_XML_DOC;
7877 } else
7878#endif
7879 {
7882#ifdef AST_XML_DOCS
7883 cur->docsrc = AST_STATIC_DOC;
7884#endif
7885 }
7886 if (ast_manager_register_struct(cur)) {
7887 ao2_t_ref(cur, -1, "action object registration failed");
7888 return -1;
7889 }
7890
7891 ao2_t_ref(cur, -1, "action object registration successful");
7892 return 0;
7893}
#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:7768
static void action_destroy(void *obj)
Definition: manager.c:7809
#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 669 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 7768 of file manager.c.

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

556{
557 struct ast_str *res = ast_str_create(1024);
558
559 if (!ast_json_is_null(blob)) {
560 manager_json_to_ast_str(blob, NULL, &res, exclusion_cb);
561 }
562
563 return res;
564}
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:514
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 7697 of file manager.c.

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

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

690{
692}
static int webmanager_enabled
Definition: manager.c:172

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

1908{
1909 int res;
1910 va_list ap;
1911 struct ast_str *buf;
1912
1914 return;
1915 }
1916
1917 va_start(ap, fmt);
1918 res = ast_str_set_va(&buf, 0, fmt, ap);
1919 va_end(ap);
1920 if (res == AST_DYNSTR_BUILD_FAILED) {
1921 return;
1922 }
1923
1924 if (s->hook || (s->tcptls_session != NULL && s->tcptls_session->stream != NULL)) {
1926 } else {
1927 ast_verbose("No connection stream in astman_append, should not happen\n");
1928 }
1929}
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:1893
static struct ast_threadstorage astman_append_buf
Definition: manager.c:1888
static int send_string(struct mansession *s, char *string)
Definition: manager.c:1852
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:330

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

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

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

2641{
2642 char *buf;
2643
2644 buf = ast_alloca(2 * strlen(str) + 1);
2646 astman_append(s, "%s", buf);
2647}
#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:2622

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

1896{
1897 if (s->hook || (s->tcptls_session && s->tcptls_session->stream)) {
1899 } else {
1900 ast_verbose("No connection stream in astman_append, should not happen\n");
1901 }
1902}

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

1672{
1673 while (m->hdrcount) {
1674 --m->hdrcount;
1675 ast_free((void *) m->headers[m->hdrcount]);
1676 m->headers[m->hdrcount] = NULL;
1677 }
1678}

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

1648{
1650}
#define GET_HEADER_FIRST_MATCH
Definition: manager.c:1593

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

1734{
1736}
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:1738
@ 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 1738 of file manager.c.

1740{
1741 int varlen;
1742 int x;
1743 struct ast_variable *head = NULL;
1744
1745 static const char var_hdr[] = "Variable:";
1746
1747 /* Process all "Variable:" headers. */
1748 varlen = strlen(var_hdr);
1749 for (x = 0; x < m->hdrcount; x++) {
1750 if (strncasecmp(var_hdr, m->headers[x], varlen)) {
1751 continue;
1752 }
1753 head = man_do_variable_value(head, m->headers[x] + varlen);
1754 }
1755
1756 if (order == ORDER_NATURAL) {
1757 head = ast_variables_reverse(head);
1758 }
1759
1760 return head;
1761}
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:1689
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 2447 of file manager.c.

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

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

2019{
2020 astman_send_response_full(s, m, "Success", msg, NULL);
2021}

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

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

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

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

2056{
2057 struct ast_str *buf = astman_send_list_complete_start_common(s, m, event_name, count);
2058 if (buf) {
2059 ast_str_append(&buf, 0, "\r\n");
2060 astman_flush(s, buf);
2061 }
2062}
static void astman_flush(struct mansession *s, struct ast_str *buf)
Definition: manager.c:1895
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:2033

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

2073{
2074 astman_append(s, "\r\n");
2075}

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

2065{
2066 struct ast_str *buf = astman_send_list_complete_start_common(s, m, event_name, count);
2067 if (buf) {
2068 astman_flush(s, buf);
2069 }
2070}

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

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

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

2029{
2030 astman_send_response_full(s, m, "Success", msg, listflag);
2031}

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

1982{
1983 astman_send_response_full(s, m, resp, msg, NULL);
1984}

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

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

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

3951{
3953 return ast_async_goto(chan, context, exten, priority);
3954}
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:6984

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

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

References mansession_session::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_t_link, ao2_t_ref, ast_apply_acl(), ast_copy_string(), ast_debug, ast_log, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, AST_SENSE_DENY, ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_tvnow(), ast_variables_dup(), astman_get_header(), mansession_session::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 819 of file manager.c.

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

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

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

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

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

1024{
1025 struct ao2_container *sessions;
1027 int inuse = 0;
1028
1029 sessions = ao2_global_obj_ref(mgr_sessions);
1030 if (sessions) {
1031 session = ao2_find(sessions, (char *) name, 0);
1032 ao2_ref(sessions, -1);
1033 if (session) {
1035 inuse = 1;
1036 }
1037 }
1038 return inuse;
1039}
#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 6665 of file manager.c.

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

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

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

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

928{
929 struct event_filter_entry *entry = obj;
930 if (entry->regex_filter) {
931 regfree(entry->regex_filter);
932 ast_free(entry->regex_filter);
933 }
934 ast_free(entry->event_name);
935 ast_free(entry->header_name);
936 ast_free(entry->string_filter);
937}
Definition: manager.c:407
char * string_filter
Definition: manager.c:410
char * event_name
Definition: manager.c:411
regex_t * regex_filter
Definition: manager.c:409
char * header_name
Definition: manager.c:413

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

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

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

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

5597{
5598 struct eventqent *eqe = arg;
5599 struct event_filter_entry *filter_entry = obj;
5600 char *line_buffer_start = NULL;
5601 char *line_buffer = NULL;
5602 char *line = NULL;
5603 int match = 0;
5604 int *result = data;
5605
5606 if (filter_entry->event_name_hash) {
5607 if (eqe->event_name_hash != filter_entry->event_name_hash) {
5608 goto done;
5609 }
5610 }
5611
5612 /* We're looking at the entire event data */
5613 if (!filter_entry->header_name) {
5614 match = match_eventdata(filter_entry, eqe->eventdata);
5615 goto done;
5616 }
5617
5618 /* We're looking at a specific header */
5619 line_buffer_start = ast_strdup(eqe->eventdata);
5620 line_buffer = line_buffer_start;
5621 if (!line_buffer_start) {
5622 goto done;
5623 }
5624
5625 while ((line = ast_read_line_from_buffer(&line_buffer))) {
5626 if (ast_begins_with(line, filter_entry->header_name)) {
5627 line += strlen(filter_entry->header_name);
5628 line = ast_skip_blanks(line);
5629 if (ast_strlen_zero(line)) {
5630 continue;
5631 }
5632 match = match_eventdata(filter_entry, line);
5633 if (match) {
5634 ast_free(line_buffer_start);
5635 line_buffer_start = NULL;
5636 break;
5637 }
5638 }
5639 }
5640
5641 ast_free(line_buffer_start);
5642
5643done:
5644
5645 *result = match;
5646 return match ? CMP_MATCH | CMP_STOP : 0;
5647}
@ 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:5576
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:412
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 781 of file manager.c.

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

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

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

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

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

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

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

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

699{
700 struct eventqent *ret;
701
704 /* the list is never empty now, but may become so when
705 * we optimize it in the future, so be prepared.
706 */
707 if (ret) {
709 }
711 return ret;
712}
#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 1412 of file manager.c.

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

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

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

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

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

7260{
7261 mansession_lock(s);
7262 astman_send_error(s, m, error);
7263 s->parsing = MESSAGE_OKAY;
7265}

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

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

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

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

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

1082{
1083 struct manager_action *cur;
1084 struct ast_str *authority;
1085 int num;
1086 int l;
1087 const char *auth_str;
1088
1089 switch (cmd) {
1090 case CLI_INIT:
1091 e->command = "manager show command";
1092 e->usage =
1093 "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n"
1094 " Shows the detailed description for a specific Asterisk manager interface command.\n";
1095 return NULL;
1096 case CLI_GENERATE:
1097 l = strlen(a->word);
1099 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1100 if (!strncasecmp(a->word, cur->action, l)) {
1102 break;
1103 }
1104 }
1105 }
1107 return NULL;
1108 }
1109 if (a->argc < 4) {
1110 return CLI_SHOWUSAGE;
1111 }
1112
1114
1116 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1117 for (num = 3; num < a->argc; num++) {
1118 if (!strcasecmp(cur->action, a->argv[num])) {
1119 auth_str = authority_to_str(cur->authority, &authority);
1120
1121#ifdef AST_XML_DOCS
1122 if (cur->docsrc == AST_XML_DOC) {
1123 char *synopsis = ast_xmldoc_printable(S_OR(cur->synopsis, "Not available"), 1);
1124 char *since = ast_xmldoc_printable(S_OR(cur->since, "Not available"), 1);
1125 char *description = ast_xmldoc_printable(S_OR(cur->description, "Not available"), 1);
1126 char *syntax = ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1);
1127 char *arguments = ast_xmldoc_printable(S_OR(cur->arguments, "Not available"), 1);
1128 char *privilege = ast_xmldoc_printable(S_OR(auth_str, "Not available"), 1);
1129 char *seealso = ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1);
1130 char *responses = ast_xmldoc_printable("None", 1);
1131
1132 if (!synopsis || !since || !description || !syntax || !arguments
1133 || !privilege || !seealso || !responses) {
1135 ast_free(since);
1136 ast_free(description);
1137 ast_free(syntax);
1138 ast_free(arguments);
1139 ast_free(privilege);
1140 ast_free(seealso);
1141 ast_free(responses);
1142 ast_cli(a->fd, "Allocation failure.\n");
1144
1145 return CLI_FAILURE;
1146 }
1147
1148 ast_cli(a->fd, "\n"
1149 "%s -= Info about Manager Command '%s' =- %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"
1161 "%s\n\n"
1162 COLORIZE_FMT "\n"
1163 "%s\n\n"
1164 COLORIZE_FMT "\n",
1166 COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
1167 COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
1168 COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
1169 COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), syntax,
1170 COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
1171 COLORIZE(COLOR_MAGENTA, 0, "[Privilege]"), privilege,
1172 COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso,
1173 COLORIZE(COLOR_MAGENTA, 0, "[List Responses]")
1174 );
1175
1176 if (!cur->list_responses) {
1177 ast_cli(a->fd, "%s\n\n", responses);
1178 } else {
1179 struct ast_xml_doc_item *temp;
1180 for (temp = cur->list_responses; temp; temp = AST_LIST_NEXT(temp, next)) {
1181 ast_cli(a->fd, "Event: %s\n", temp->name);
1182 print_event_instance(a, temp);
1183 }
1184 }
1185 ast_cli(a->fd,
1186 COLORIZE_FMT "\n",
1187 COLORIZE(COLOR_MAGENTA, 0, "[End List Responses]")
1188 );
1189
1190 ast_cli(a->fd, "\n"
1191 COLORIZE_FMT "\n",
1192 COLORIZE(COLOR_MAGENTA, 0, "[Final Response]")
1193 );
1194 if (!cur->final_response) {
1195 ast_cli(a->fd, "%s\n\n", responses);
1196 } else {
1197 ast_cli(a->fd, "Event: %s\n", cur->final_response->name);
1199 }
1200 ast_cli(a->fd,
1201 COLORIZE_FMT "\n",
1202 COLORIZE(COLOR_MAGENTA, 0, "[End Final Response]")
1203 );
1204
1206 ast_free(since);
1210 ast_free(privilege);
1212 ast_free(responses);
1213 } else
1214#endif
1215 {
1216 ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
1217 cur->action, cur->synopsis,
1218 auth_str,
1219 S_OR(cur->description, ""));
1220 }
1221 }
1222 }
1223 }
1225
1226 return CLI_SUCCESS;
1227}
static void print_event_instance(struct ast_cli_args *a, struct ast_xml_doc_item *instance)
Definition: manager.c:9263
#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 1370 of file manager.c.

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

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

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

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

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

5127{
5128 int i;
5129
5130 for (i = 0; originate_app_permissions[i].search; i++) {
5131 if (originate_app_permissions[i].searchfn(app, data, originate_app_permissions[i].search)) {
5133 }
5134 }
5135
5136 return 1;
5137}
static struct originate_permissions_entry originate_app_permissions[]
Definition: manager.c:5089
int permission
Definition: manager.c:4999
const char * search
Definition: manager.c:4998

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

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

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

2623{
2624 for (; *in; in++) {
2625 if (*in == '\\' || *in == '\"') {
2626 *out++ = '\\';
2627 }
2628 *out++ = *in;
2629 }
2630 *out = '\0';
2631}
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 6988 of file manager.c.

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

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

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

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

574{
575 struct ao2_container *sessions;
576 struct ast_manager_event_blob *ev;
577
579 /* Not an AMI message; disregard */
580 return;
581 }
582
583 sessions = ao2_global_obj_ref(mgr_sessions);
585 /* Nobody is listening */
587 return;
588 }
589
591 if (!ev) {
592 /* Conversion failure */
594 return;
595 }
596
598 "%s", ev->extra_fields);
599 ao2_ref(ev, -1);
601}
#define manager_event_sessions(sessions, category, event, contents,...)
Definition: manager.c:566
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 1063 of file manager.c.

1064{
1065 struct ast_manager_user *user = NULL;
1066 int ret = 0;
1067
1069 if ((user = get_manager_by_name_locked(session->username))) {
1070 ret = user->displayconnects;
1071 }
1073
1074 return ret;
1075}

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

605{
606 struct ast_json_payload *payload;
607 int class_type;
608 const char *type;
609 struct ast_json *event;
610 struct ast_str *event_buffer;
611 struct ao2_container *sessions;
612
613 sessions = ao2_global_obj_ref(mgr_sessions);
615 /* Nobody is listening */
617 return;
618 }
619
620 payload = stasis_message_data(message);
621 class_type = ast_json_integer_get(ast_json_object_get(payload->json, "class_type"));
623 event = ast_json_object_get(payload->json, "event");
624
626 if (!event_buffer) {
627 ast_log(AST_LOG_WARNING, "Error while creating payload for event %s\n", type);
629 return;
630 }
631
633 "%s", ast_str_buffer(event_buffer));
634 ast_free(event_buffer);
636}
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:555
#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 489 of file manager.c.

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

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

502{
503 if (parent_key) {
504 struct ast_str *key_str = ast_str_alloca(64);
505 ast_str_set(&key_str, 0, "%s/%s", parent_key, key);
507 res, exclusion_cb);
508 return;
509 }
510
511 manager_json_to_ast_str(obj, key, res, exclusion_cb);
512}

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

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

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

6843{
6844 const char *module = astman_get_header(m, "Module");
6845 const char *id = astman_get_header(m, "ActionID");
6846
6847 ast_debug(1, "**** ModuleCheck .so file %s\n", module);
6848 if (!ast_module_check(module)) {
6849 astman_send_error(s, m, "Module not loaded");
6850 return 0;
6851 }
6852
6853 astman_append(s, "Response: Success\r\n");
6854
6855 if (!ast_strlen_zero(id)) {
6856 astman_append(s, "ActionID: %s\r\n", id);
6857 }
6858
6859#if !defined(LOW_MEMORY)
6860 /* When we switched from subversion to git we lost the ability to
6861 * retrieve the 'ASTERISK_FILE_VERSION' from that file, but we retain
6862 * the response header here for backwards compatibility. */
6863 astman_append(s, "Version: \r\n");
6864#endif
6865
6866 astman_append(s, "\r\n");
6867
6868 return 0;
6869}
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 6907 of file manager.c.

6908{
6909 int res;
6910 const char *module = astman_get_header(m, "Module");
6911 const char *loadtype = astman_get_header(m, "LoadType");
6912 const char *recursive = astman_get_header(m, "Recursive");
6913
6914 if (!loadtype || strlen(loadtype) == 0) {
6915 astman_send_error(s, m, "Incomplete ModuleLoad action.");
6916 }
6917 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) {
6918 astman_send_error(s, m, "Need module name");
6919 }
6920
6921 res = file_in_modules_dir(module);
6922 if (res == 0) {
6923 astman_send_error(s, m, "Module must be in the configured modules directory.");
6924 return 0;
6925 } else if (res == -1) {
6926 astman_send_error(s, m, "Module not found.");
6927 return 0;
6928 }
6929
6930 if (!strcasecmp(loadtype, "load")) {
6931 res = ast_load_resource(module);
6932 if (res) {
6933 astman_send_error(s, m, "Could not load module.");
6934 } else {
6935 astman_send_ack(s, m, "Module loaded.");
6936 }
6937 } else if (!strcasecmp(loadtype, "unload")) {
6938 res = ast_unload_resource(module, AST_FORCE_SOFT);
6939 if (res) {
6940 astman_send_error(s, m, "Could not unload module.");
6941 } else {
6942 astman_send_ack(s, m, "Module unloaded.");
6943 }
6944 } else if (!strcasecmp(loadtype, "refresh")) {
6945 res = ast_refresh_resource(module, AST_FORCE_SOFT, !ast_strlen_zero(recursive) && ast_true(recursive));
6946 if (res) {
6947 astman_send_error(s, m, "Could not refresh module.");
6948 } else {
6949 astman_send_ack(s, m, "Module unloaded and loaded.");
6950 }
6951 } else if (!strcasecmp(loadtype, "reload")) {
6952 /* TODO: Unify the ack/error messages here with action_reload */
6953 if (!ast_strlen_zero(module)) {
6954 enum ast_module_reload_result reload_res = ast_module_reload(module);
6955
6956 switch (reload_res) {
6958 astman_send_error(s, m, "No such module.");
6959 break;
6961 astman_send_error(s, m, "Module does not support reload action.");
6962 break;
6964 astman_send_error(s, m, "An unknown error occurred");
6965 break;
6967 astman_send_error(s, m, "A reload is in progress");
6968 break;
6970 astman_send_error(s, m, "Module not initialized");
6971 break;
6974 /* Treat a queued request as success */
6975 astman_send_ack(s, m, "Module reloaded.");
6976 break;
6977 }
6978 } else {
6979 ast_module_reload(NULL); /* Reload all modules */
6980 astman_send_ack(s, m, "All modules reloaded");
6981 }
6982 } else {
6983 astman_send_error(s, m, "Incomplete ModuleLoad action.");
6984 }
6985 return 0;
6986}
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:6881
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 7727 of file manager.c.

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

1004{
1005 struct mansession_session *s = obj;
1006 char *str = arg;
1007 return !strcasecmp(s->username, str) ? CMP_MATCH : 0;
1008}

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

2079{
2080 ast_mutex_lock(&s->lock);
2081}
ast_mutex_t lock
Definition: manager.c:334

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

2085{
2087}

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

5577{
5578 switch(entry->match_type) {
5579 case FILTER_MATCH_REGEX:
5580 return regexec(entry->regex_filter, eventdata, 0, NULL, 0) == 0;
5582 return ast_begins_with(eventdata, entry->string_filter);
5584 return ast_ends_with(eventdata, entry->string_filter);
5586 return strstr(eventdata, entry->string_filter) != NULL;
5587 case FILTER_MATCH_EXACT:
5588 return strcmp(eventdata, entry->string_filter) == 0;
5589 case FILTER_MATCH_NONE:
5590 return 1;
5591 }
5592
5593 return 0;
5594}
enum event_filter_match_type match_type
Definition: manager.c:408

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

9264{
9265 char *since, *syntax, *description, *synopsis, *seealso, *arguments;
9266
9267 synopsis = ast_xmldoc_printable(AS_OR(instance->synopsis, "Not available"), 1);
9268 since = ast_xmldoc_printable(AS_OR(instance->since, "Not available"), 1);
9269 description = ast_xmldoc_printable(AS_OR(instance->description, "Not available"), 1);
9270 syntax = ast_xmldoc_printable(AS_OR(instance->syntax, "Not available"), 1);
9271 arguments = ast_xmldoc_printable(AS_OR(instance->arguments, "Not available"), 1);
9272 seealso = ast_xmldoc_printable(AS_OR(instance->seealso, "Not available"), 1);
9273
9274 if (!synopsis || !since || !description || !syntax || !arguments || !seealso) {
9275 ast_cli(a->fd, "Error: Memory allocation failed\n");
9276 goto free_docs;
9277 }
9278
9279 ast_cli(a->fd, "\n"
9280 "%s -= Info about Manager Event '%s' =- %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"
9291 COLORIZE_FMT "\n"
9292 "%s\n\n",
9294 COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
9295 COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
9296 COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
9297 COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), syntax,
9298 COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
9299 COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso
9300 );
9301
9302free_docs:
9304 ast_free(since);
9305 ast_free(description);
9306 ast_free(syntax);
9307 ast_free(arguments);
9308 ast_free(seealso);
9309}
#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 6414 of file manager.c.

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

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

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

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

719{
720 struct eventqent *ev;
721 struct timeval now = ast_tvnow();
722
724 while ( (ev = AST_RWLIST_FIRST(&all_events)) &&
725 ev->usecount == 0 && AST_RWLIST_NEXT(ev, eq_next)) {
727 ast_free(ev);
728 }
729
731 /* Never release the last event */
732 if (!AST_RWLIST_NEXT(ev, eq_next)) {
733 break;
734 }
735
736 /* 2.5 times whatever the HTTP timeout is (maximum 2.5 hours) is the maximum time that we will definitely cache an event */
737 if (ev->usecount == 0 && ast_tvdiff_sec(now, ev->tv) > (httptimeout > 3600 ? 3600 : httptimeout) * 2.5) {
739 ast_free(ev);
740 }
741 }
744}
static int httptimeout
Definition: manager.c:168
#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 7455 of file manager.c.

7456{
7457 struct ao2_container *sessions;
7459 time_t now = time(NULL);
7460 struct ao2_iterator i;
7461 int purged = 0;
7462
7463 sessions = ao2_global_obj_ref(mgr_sessions);
7464 if (!sessions) {
7465 return 0;
7466 }
7468 ao2_ref(sessions, -1);
7469 while ((session = ao2_iterator_next(&i)) && n_max > 0) {
7471 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) {
7472 if (session->authenticated
7473 && VERBOSITY_ATLEAST(2)
7475 ast_verb(2, "HTTP Manager '%s' timed out from %s\n",
7476 session->username, ast_sockaddr_stringify_addr(&session->addr));
7477 }
7480 n_max--;
7481 purged++;
7482 } else {
7485 }
7486 }
7488 return purged;
7489}
static void session_destroy(struct mansession_session *s)
Definition: manager.c:1010
#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 5052 of file manager.c.

5053{
5054 char *parse;
5056 AST_APP_ARG(queuename);
5059 AST_APP_ARG(announceoverride);
5060 AST_APP_ARG(queuetimeoutstr);
5061 AST_APP_ARG(agi);
5062 AST_APP_ARG(gosub);
5064 AST_APP_ARG(position);
5065 );
5066
5067 if (!strcasestr(app, "queue") || ast_strlen_zero(data)) {
5068 return 0;
5069 }
5070
5071 parse = ast_strdupa(data);
5073
5074 /*
5075 * The Queue application is fine unless the AGI parameter is set.
5076 * If it is, we need to check the user's permissions.
5077 */
5078 return !ast_strlen_zero(args.agi);
5079}
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 3840 of file manager.c.

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

3874{
3875 return queue_read_action_payload(chan, (const unsigned char *)body,
3876 strlen(body) + 1, AST_FRAME_READ_ACTION_SEND_TEXT);
3877}
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:3840
@ 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 3889 of file manager.c.

3891{
3892 int res;
3893 struct ast_msg_data *obj;
3894
3896 NULL, NULL, content_type, body);
3897 if (!obj) {
3898 return -1;
3899 }
3900
3901 res = queue_read_action_payload(chan, (const unsigned char *)obj,
3903
3904 ast_free(obj);
3905 return res;
3906}
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 10171 of file manager.c.

10172{
10174}
@ 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 2187 of file manager.c.

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

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

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

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

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

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

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

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

1853{
1854 struct ast_iostream *stream;
1855 int len, res;
1856
1857 /* It's a result from one of the hook's action invocation */
1858 if (s->hook) {
1859 /*
1860 * to send responses, we're using the same function
1861 * as for receiving events. We call the event "HookResponse"
1862 */
1863 s->hook->helper(EVENT_FLAG_HOOKRESPONSE, "HookResponse", string);
1864 return 0;
1865 }
1866
1867 stream = s->stream ? s->stream : s->session->stream;
1868
1869 len = strlen(string);
1871 res = ast_iostream_write(stream, string, len);
1873
1874 if (res < len) {
1875 s->write_error = 1;
1876 }
1877
1878 return res;
1879}
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:329

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

1011{
1012 struct ao2_container *sessions;
1013
1014 sessions = ao2_global_obj_ref(mgr_sessions);
1015 if (sessions) {
1016 ao2_unlink(sessions, s);
1017 ao2_ref(sessions, -1);
1018 }
1020}
#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 939 of file manager.c.

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

7362{
7363 struct ast_tcptls_session_instance *ser = data;
7365 struct mansession s = {
7366 .tcptls_session = data,
7367 };
7368 int res;
7369 int arg = 1;
7370 struct ast_sockaddr ser_remote_address_tmp;
7371
7374 goto done;
7375 }
7376
7377 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
7378 session = build_mansession(&ser_remote_address_tmp);
7379
7380 if (session == NULL) {
7382 goto done;
7383 }
7384
7385 /* here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
7386 * This is necessary to prevent delays (caused by buffering) as we
7387 * write to the socket in bits and pieces. */
7388 if (setsockopt(ast_iostream_get_fd(ser->stream), IPPROTO_TCP, TCP_NODELAY, (char *) &arg, sizeof(arg)) < 0) {
7389 ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on manager connection: %s\n", strerror(errno));
7390 }
7392
7394 /* Hook to the tail of the event queue */
7395 session->last_ev = grab_last();
7396
7397 ast_mutex_init(&s.lock);
7398
7399 /* these fields duplicate those in the 'ser' structure */
7400 session->stream = s.stream = ser->stream;
7401 ast_sockaddr_copy(&session->addr, &ser_remote_address_tmp);
7402 s.session = session;
7403
7404 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
7405
7406 if(time(&session->authstart) == -1) {
7407 ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
7411 goto done;
7412 }
7414
7415 /*
7416 * We cannot let the stream exclusively wait for data to arrive.
7417 * We have to wake up the task to send async events.
7418 */
7420
7422 ast_tvnow(), authtimeout * 1000);
7423
7424 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */
7425 for (;;) {
7426 if ((res = do_message(&s)) < 0 || s.write_error || session->kicked) {
7427 break;
7428 }
7429 if (session->authenticated) {
7431 }
7432 }
7433 /* session is over, explain why and terminate */
7434 if (session->authenticated) {
7436 ast_verb(2, "Manager '%s' %s from %s\n", session->username, session->kicked ? "kicked" : "logged off", ast_sockaddr_stringify_addr(&session->addr));
7437 }
7438 } else {
7440 if (displayconnects) {
7441 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr));
7442 }
7443 }
7444
7446
7448done:
7449 ao2_ref(ser, -1);
7450 ser = NULL;
7451 return NULL;
7452}
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:970
static int do_message(struct mansession *s)
Definition: manager.c:7276
static struct eventqent * grab_last(void)
Definition: manager.c:698
static int authlimit
Definition: manager.c:175
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 2093 of file manager.c.

2094{
2095 int maskint = strings_to_mask(eventmask);
2096
2097 ao2_lock(s->session);
2098 if (maskint >= 0) {
2099 s->session->send_events = maskint;
2100 }
2101 ao2_unlock(s->session);
2102
2103 return maskint;
2104}
static int strings_to_mask(const char *string)
Definition: manager.c:887

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

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

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

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

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

919{
920 int refcount = ao2_ref(s, -1);
921 if (manager_debug) {
922 ast_debug(1, "Mansession: %p refcount now %d\n", s, refcount - 1);
923 }
924 return NULL;
925}

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

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

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 183 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 166 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 175 of file manager.c.

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

◆ authtimeout

int authtimeout
static

Definition at line 174 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 169 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 180 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 200 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 176 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 7537 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 398 of file manager.c.

Referenced by manager_add_filter().

◆ originate_app_permissions

struct originate_permissions_entry originate_app_permissions[]
static

Definition at line 5089 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 192 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 195 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 182 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 1890 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 226 of file manager.c.