Asterisk - The Open Source Telephony Project GIT-master-f36a736
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 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 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 restrictedFile (const char *filename)
 Check if a file is restricted or not. More...
 
static int send_string (struct mansession *s, char *string)
 
static void session_destroy (struct mansession_session *s)
 
static void session_destructor (void *obj)
 
static void * session_do (void *data)
 The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ) More...
 
static int set_eventmask (struct mansession *s, const char *eventmask)
 Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm. More...
 
static int 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 568 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 1876 of file manager.c.

◆ DEFAULT_REALM

#define DEFAULT_REALM   "asterisk"

Definition at line 178 of file manager.c.

◆ EVENT_FLAG_SHUTDOWN

#define EVENT_FLAG_SHUTDOWN   -1

Fake event class used to end sessions at shutdown.

Definition at line 211 of file manager.c.

◆ GET_HEADER_FIRST_MATCH

#define GET_HEADER_FIRST_MATCH   0

Definition at line 1576 of file manager.c.

◆ GET_HEADER_LAST_MATCH

#define GET_HEADER_LAST_MATCH   1

Definition at line 1577 of file manager.c.

◆ GET_HEADER_SKIP_EMPTY

#define GET_HEADER_SKIP_EMPTY   2

Definition at line 1578 of file manager.c.

◆ MANAGER_EVENT_BUF_INITSIZE

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 7449 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 565 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 777 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 223 of file manager.c.

◆ MAX_VARS

#define MAX_VARS   128

Definition at line 208 of file manager.c.

◆ MGR_SHOW_TERMINAL_WIDTH

#define MGR_SHOW_TERMINAL_WIDTH   80

Definition at line 206 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 1924 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 126 of file manager.c.

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

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

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

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

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

◆ mansession_message_parsing

Enumerator
MESSAGE_OKAY 
MESSAGE_LINE_TOO_LONG 

Definition at line 316 of file manager.c.

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

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

7586{
7587 struct ao2_container *sessions = ao2_global_obj_ref(mgr_sessions);
7588 va_list ap;
7589 int res;
7590
7592 /* Nobody is listening */
7594 return 0;
7595 }
7596
7597 va_start(ap, fmt);
7599 file, line, func, fmt, ap);
7600 va_end(ap);
7602 return res;
7603}
#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:568
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:7451
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 1593 of file manager.c.

1594{
1595 int x, l = strlen(var);
1596 const char *result = "";
1597
1598 if (!m) {
1599 return result;
1600 }
1601
1602 for (x = 0; x < m->hdrcount; x++) {
1603 const char *h = m->headers[x];
1604 if (!strncasecmp(var, h, l) && h[l] == ':') {
1605 const char *value = h + l + 1;
1606 value = ast_skip_blanks(value); /* ignore leading spaces in the value */
1607 /* found a potential candidate */
1608 if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) {
1609 continue; /* not interesting */
1610 }
1611 if (mode & GET_HEADER_LAST_MATCH) {
1612 result = value; /* record the last match so far */
1613 } else {
1614 return value;
1615 }
1616 }
1617 }
1618
1619 return result;
1620}
#define var
Definition: ast_expr2f.c:605
static PGresult * result
Definition: cel_pgsql.c:84
#define GET_HEADER_LAST_MATCH
Definition: manager.c:1577
#define GET_HEADER_SKIP_EMPTY
Definition: manager.c:1578
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 1871 of file manager.c.

1879{

◆ __init_manager_event_buf()

static void __init_manager_event_buf ( void  )
static

Definition at line 7448 of file manager.c.

7462{

◆ __init_userevent_buf()

static void __init_userevent_buf ( void  )
static

Definition at line 1873 of file manager.c.

1879{

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

7572{
7573 va_list ap;
7574 int res;
7575
7576 va_start(ap, fmt);
7578 chancount, chans, file, line, func, fmt, ap);
7579 va_end(ap);
7580 return res;
7581}

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

7462{
7464 const char *cat_str;
7465 struct timeval now;
7466 struct ast_str *buf;
7467 int i;
7468 int event_name_hash;
7469
7472 ast_debug(3, "AMI Event '%s' is globally disabled, skipping\n", event);
7473 /* Event is globally disabled */
7474 return -1;
7475 }
7476 }
7477
7479 if (!buf) {
7480 return -1;
7481 }
7482
7483 cat_str = authority_to_str(category, &auth);
7484 ast_str_set(&buf, 0,
7485 "Event: %s\r\n"
7486 "Privilege: %s\r\n",
7487 event, cat_str);
7488
7489 if (timestampevents) {
7490 now = ast_tvnow();
7491 ast_str_append(&buf, 0,
7492 "Timestamp: %ld.%06lu\r\n",
7493 (long)now.tv_sec, (unsigned long) now.tv_usec);
7494 }
7495 if (manager_debug) {
7496 static int seq;
7497
7498 ast_str_append(&buf, 0,
7499 "SequenceNumber: %d\r\n",
7501 ast_str_append(&buf, 0,
7502 "File: %s\r\n"
7503 "Line: %d\r\n"
7504 "Func: %s\r\n",
7505 file, line, func);
7506 }
7508 ast_str_append(&buf, 0,
7509 "SystemName: %s\r\n",
7511 }
7512
7513 ast_str_append_va(&buf, 0, fmt, ap);
7514 for (i = 0; i < chancount; i++) {
7516 }
7517
7518 ast_str_append(&buf, 0, "\r\n");
7519
7520 event_name_hash = ast_str_hash(event);
7521
7522 append_event(ast_str_buffer(buf), event_name_hash, category);
7523
7524 /* Wake up any sleeping sessions */
7525 if (sessions) {
7526 struct ao2_iterator iter;
7528
7529 iter = ao2_iterator_init(sessions, 0);
7530 while ((session = ao2_iterator_next(&iter))) {
7531 ast_mutex_lock(&session->notify_lock);
7532 if (session->waiting_thread != AST_PTHREADT_NULL) {
7533 pthread_kill(session->waiting_thread, SIGURG);
7534 } else {
7535 /* We have an event to process, but the mansession is
7536 * not waiting for it. We still need to indicate that there
7537 * is an event waiting so that get_input processes the pending
7538 * event instead of polling.
7539 */
7540 session->pending_event = 1;
7541 }
7542 ast_mutex_unlock(&session->notify_lock);
7544 }
7545 ao2_iterator_destroy(&iter);
7546 }
7547
7548 if (category != EVENT_FLAG_SHUTDOWN && !AST_RWLIST_EMPTY(&manager_hooks)) {
7549 struct manager_custom_hook *hook;
7550
7552 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
7553 hook->helper(category, event, ast_str_buffer(buf));
7554 }
7556 }
7557
7558 return 0;
7559}
static volatile unsigned int seq
Definition: app_sms.c:120
static struct ast_mansession session
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static 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:7406
static struct ast_threadstorage manager_event_buf
Definition: manager.c:7448
static int manager_debug
Definition: manager.c:172
static void append_channel_vars(struct ast_str **pbuf, struct ast_channel *chan)
Definition: manager.c:7431
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:917
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:818
#define MAX_AUTH_PERM_STRING
Definition: manager.c:777
static int timestampevents
Definition: manager.c:166
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition: manager.c:211
#define MANAGER_EVENT_BUF_INITSIZE
Definition: manager.c:7449
static char * manager_disabledevents
Definition: manager.c:176
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:452
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_mutex_unlock(a)
Definition: lock.h:190
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:757
#define ast_mutex_lock(a)
Definition: lock.h:189
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
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:433
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
int ast_str_append_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Append to a dynamic string using a va_list.
Definition: strings.h:1048
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
Definition: strings.h:909
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Support for dynamic strings.
Definition: strings.h:623
manager_hook_t helper
Definition: manager.h:117
list of hooks registered
Definition: manager.c:369
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 10032 of file manager.c.

10034{
10036 return;
10037 }
10038
10039 /* For now, this is going to be performed simply and just execute a forced reload. */
10040 ast_log(LOG_NOTICE, "Reloading manager in response to ACL change event.\n");
10041 __init_manager(1, 1);
10042}
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:9535
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 234 of file manager.c.

235{
236 if (!acl_change_sub) {
241 }
242}
static struct stasis_subscription * acl_change_sub
Definition: manager.c:182
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager.c:10032
#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:1024
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:1078
#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 244 of file manager.c.

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

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

4412{
4413 const char *msgtype = astman_get_header(m, "MsgType");
4414 const char *chargetype = astman_get_header(m, "ChargeType");
4415 const char *currencyname = astman_get_header(m, "CurrencyName");
4416 const char *currencyamount = astman_get_header(m, "CurrencyAmount");
4417 const char *mult = astman_get_header(m, "CurrencyMultiplier");
4418 const char *totaltype = astman_get_header(m, "TotalType");
4419 const char *aocbillingid = astman_get_header(m, "AOCBillingId");
4420 const char *association_id= astman_get_header(m, "ChargingAssociationId");
4421 const char *association_num = astman_get_header(m, "ChargingAssociationNumber");
4422 const char *association_plan = astman_get_header(m, "ChargingAssociationPlan");
4423
4424 enum ast_aoc_type _msgtype;
4425 enum ast_aoc_charge_type _chargetype;
4427 enum ast_aoc_total_type _totaltype = AST_AOC_TOTAL;
4428 enum ast_aoc_billing_id _billingid = AST_AOC_BILLING_NA;
4429 unsigned int _currencyamount = 0;
4430 int _association_id = 0;
4431 unsigned int _association_plan = 0;
4432
4433 struct ast_aoc_decoded *decoded = NULL;
4434
4435 if (ast_strlen_zero(chargetype)) {
4436 astman_send_error(s, m, "ChargeType not specified");
4437 goto aocmessage_cleanup;
4438 }
4439
4440 _msgtype = strcasecmp(msgtype, "d") ? AST_AOC_E : AST_AOC_D;
4441
4442 if (!strcasecmp(chargetype, "NA")) {
4443 _chargetype = AST_AOC_CHARGE_NA;
4444 } else if (!strcasecmp(chargetype, "Free")) {
4445 _chargetype = AST_AOC_CHARGE_FREE;
4446 } else if (!strcasecmp(chargetype, "Currency")) {
4447 _chargetype = AST_AOC_CHARGE_CURRENCY;
4448 } else if (!strcasecmp(chargetype, "Unit")) {
4449 _chargetype = AST_AOC_CHARGE_UNIT;
4450 } else {
4451 astman_send_error(s, m, "Invalid ChargeType");
4452 goto aocmessage_cleanup;
4453 }
4454
4455 if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
4456
4457 if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u", &_currencyamount) != 1)) {
4458 astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when ChargeType is Currency");
4459 goto aocmessage_cleanup;
4460 }
4461
4462 if (ast_strlen_zero(mult)) {
4463 astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
4464 goto aocmessage_cleanup;
4465 } else if (!strcasecmp(mult, "onethousandth")) {
4467 } else if (!strcasecmp(mult, "onehundredth")) {
4469 } else if (!strcasecmp(mult, "onetenth")) {
4470 _mult = AST_AOC_MULT_ONETENTH;
4471 } else if (!strcasecmp(mult, "one")) {
4472 _mult = AST_AOC_MULT_ONE;
4473 } else if (!strcasecmp(mult, "ten")) {
4474 _mult = AST_AOC_MULT_TEN;
4475 } else if (!strcasecmp(mult, "hundred")) {
4476 _mult = AST_AOC_MULT_HUNDRED;
4477 } else if (!strcasecmp(mult, "thousand")) {
4478 _mult = AST_AOC_MULT_THOUSAND;
4479 } else {
4480 astman_send_error(s, m, "Invalid ChargeMultiplier");
4481 goto aocmessage_cleanup;
4482 }
4483 }
4484
4485 /* create decoded object and start setting values */
4486 if (!(decoded = ast_aoc_create(_msgtype, _chargetype, 0))) {
4487 astman_send_error(s, m, "Message Creation Failed");
4488 goto aocmessage_cleanup;
4489 }
4490
4491 if (_msgtype == AST_AOC_D) {
4492 if (!ast_strlen_zero(totaltype) && !strcasecmp(totaltype, "subtotal")) {
4493 _totaltype = AST_AOC_SUBTOTAL;
4494 }
4495
4496 if (ast_strlen_zero(aocbillingid)) {
4497 /* ignore this is optional */
4498 } else if (!strcasecmp(aocbillingid, "Normal")) {
4499 _billingid = AST_AOC_BILLING_NORMAL;
4500 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
4501 _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
4502 } else if (!strcasecmp(aocbillingid, "CreditCard")) {
4503 _billingid = AST_AOC_BILLING_CREDIT_CARD;
4504 } else {
4505 astman_send_error(s, m, "Invalid AOC-D AOCBillingId");
4506 goto aocmessage_cleanup;
4507 }
4508 } else {
4509 if (ast_strlen_zero(aocbillingid)) {
4510 /* ignore this is optional */
4511 } else if (!strcasecmp(aocbillingid, "Normal")) {
4512 _billingid = AST_AOC_BILLING_NORMAL;
4513 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
4514 _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
4515 } else if (!strcasecmp(aocbillingid, "CreditCard")) {
4516 _billingid = AST_AOC_BILLING_CREDIT_CARD;
4517 } else if (!strcasecmp(aocbillingid, "CallFwdUnconditional")) {
4519 } else if (!strcasecmp(aocbillingid, "CallFwdBusy")) {
4520 _billingid = AST_AOC_BILLING_CALL_FWD_BUSY;
4521 } else if (!strcasecmp(aocbillingid, "CallFwdNoReply")) {
4523 } else if (!strcasecmp(aocbillingid, "CallDeflection")) {
4525 } else if (!strcasecmp(aocbillingid, "CallTransfer")) {
4526 _billingid = AST_AOC_BILLING_CALL_TRANSFER;
4527 } else {
4528 astman_send_error(s, m, "Invalid AOC-E AOCBillingId");
4529 goto aocmessage_cleanup;
4530 }
4531
4532 if (!ast_strlen_zero(association_id) && (sscanf(association_id, "%30d", &_association_id) != 1)) {
4533 astman_send_error(s, m, "Invalid ChargingAssociationId");
4534 goto aocmessage_cleanup;
4535 }
4536 if (!ast_strlen_zero(association_plan) && (sscanf(association_plan, "%30u", &_association_plan) != 1)) {
4537 astman_send_error(s, m, "Invalid ChargingAssociationPlan");
4538 goto aocmessage_cleanup;
4539 }
4540
4541 if (_association_id) {
4542 ast_aoc_set_association_id(decoded, _association_id);
4543 } else if (!ast_strlen_zero(association_num)) {
4544 ast_aoc_set_association_number(decoded, association_num, _association_plan);
4545 }
4546 }
4547
4548 if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
4549 ast_aoc_set_currency_info(decoded, _currencyamount, _mult, ast_strlen_zero(currencyname) ? NULL : currencyname);
4550 } else if (_chargetype == AST_AOC_CHARGE_UNIT) {
4552 int i;
4553
4554 /* multiple unit entries are possible, lets get them all */
4555 for (i = 0; i < 32; i++) {
4556 if (aocmessage_get_unit_entry(m, &entry, i)) {
4557 break; /* that's the end then */
4558 }
4559
4560 ast_aoc_add_unit_entry(decoded, entry.valid_amount, entry.amount, entry.valid_type, entry.type);
4561 }
4562
4563 /* at least one unit entry is required */
4564 if (!i) {
4565 astman_send_error(s, m, "Invalid UnitAmount(0), At least one valid unit entry is required when ChargeType is set to Unit");
4566 goto aocmessage_cleanup;
4567 }
4568
4569 }
4570
4571 ast_aoc_set_billing_id(decoded, _billingid);
4572 ast_aoc_set_total_type(decoded, _totaltype);
4573
4574 return decoded;
4575
4576aocmessage_cleanup:
4577
4578 ast_aoc_destroy_decoded(decoded);
4579 return NULL;
4580}
ast_aoc_charge_type
Definition: aoc.h:69
@ AST_AOC_CHARGE_CURRENCY
Definition: aoc.h:72
@ AST_AOC_CHARGE_FREE
Definition: aoc.h:71
@ AST_AOC_CHARGE_UNIT
Definition: aoc.h:73
@ AST_AOC_CHARGE_NA
Definition: aoc.h:70
ast_aoc_currency_multiplier
Defines the currency multiplier for an aoc message.
Definition: aoc.h:34
@ AST_AOC_MULT_TEN
Definition: aoc.h:39
@ AST_AOC_MULT_ONEHUNDREDTH
Definition: aoc.h:36
@ AST_AOC_MULT_HUNDRED
Definition: aoc.h:40
@ AST_AOC_MULT_ONETENTH
Definition: aoc.h:37
@ AST_AOC_MULT_ONETHOUSANDTH
Definition: aoc.h:35
@ AST_AOC_MULT_THOUSAND
Definition: aoc.h:41
@ AST_AOC_MULT_ONE
Definition: aoc.h:38
struct ast_aoc_decoded * ast_aoc_create(const enum ast_aoc_type msg_type, const enum ast_aoc_charge_type charge_type, const enum ast_aoc_request requests)
creates a ast_aoc_decode object of a specific message type
Definition: aoc.c:276
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:307
int ast_aoc_set_association_number(struct ast_aoc_decoded *decoded, const char *num, uint8_t plan)
set the charging association number for an AOC-E message
Definition: aoc.c:1056
int ast_aoc_add_unit_entry(struct ast_aoc_decoded *decoded, const unsigned int amount_is_present, const unsigned int amount, const unsigned int type_is_present, const unsigned int type)
Adds a unit entry into the list of units.
Definition: aoc.c:977
ast_aoc_billing_id
Defines the billing id options for an aoc message.
Definition: aoc.h:49
@ AST_AOC_BILLING_CALL_FWD_BUSY
Definition: aoc.h:55
@ AST_AOC_BILLING_CALL_FWD_NO_REPLY
Definition: aoc.h:56
@ AST_AOC_BILLING_NORMAL
Definition: aoc.h:51
@ AST_AOC_BILLING_CALL_DEFLECTION
Definition: aoc.h:57
@ AST_AOC_BILLING_CREDIT_CARD
Definition: aoc.h:53
@ AST_AOC_BILLING_CALL_TRANSFER
Definition: aoc.h:58
@ AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL
Definition: aoc.h:54
@ AST_AOC_BILLING_REVERSE_CHARGE
Definition: aoc.h:52
@ AST_AOC_BILLING_NA
Definition: aoc.h:50
int ast_aoc_set_billing_id(struct ast_aoc_decoded *decoded, const enum ast_aoc_billing_id id)
set the billing id for a AOC-D or AST_AOC_E message
Definition: aoc.c:1024
int ast_aoc_set_currency_info(struct ast_aoc_decoded *decoded, const unsigned int amount, const enum ast_aoc_currency_multiplier multiplier, const char *name)
Sets the currency values for a AOC-D or AOC-E message.
Definition: aoc.c:919
int ast_aoc_set_association_id(struct ast_aoc_decoded *decoded, const int id)
set the charging association id for an AST_AOC_E message
Definition: aoc.c:1040
int ast_aoc_set_total_type(struct ast_aoc_decoded *decoded, const enum ast_aoc_total_type type)
Sets the type of total for a AOC-D message.
Definition: aoc.c:907
ast_aoc_type
Definition: aoc.h:62
@ AST_AOC_D
Definition: aoc.h:65
@ AST_AOC_E
Definition: aoc.h:66
ast_aoc_total_type
Definition: aoc.h:82
@ AST_AOC_TOTAL
Definition: aoc.h:83
@ AST_AOC_SUBTOTAL
Definition: aoc.h:84
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:1969
const char * astman_get_header(const struct message *m, char *var)
Return the first matching variable from an array.
Definition: manager.c:1630
static int aocmessage_get_unit_entry(const struct message *m, struct ast_aoc_unit_entry *entry, unsigned int entry_num)
Definition: manager.c:4386
Definition: aoc.h:178
Definition: search.h:40

References aocmessage_get_unit_entry(), ast_aoc_add_unit_entry(), AST_AOC_BILLING_CALL_DEFLECTION, AST_AOC_BILLING_CALL_FWD_BUSY, AST_AOC_BILLING_CALL_FWD_NO_REPLY, AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL, AST_AOC_BILLING_CALL_TRANSFER, AST_AOC_BILLING_CREDIT_CARD, AST_AOC_BILLING_NA, AST_AOC_BILLING_NORMAL, AST_AOC_BILLING_REVERSE_CHARGE, AST_AOC_CHARGE_CURRENCY, AST_AOC_CHARGE_FREE, AST_AOC_CHARGE_NA, AST_AOC_CHARGE_UNIT, ast_aoc_create(), AST_AOC_D, ast_aoc_destroy_decoded(), AST_AOC_E, AST_AOC_MULT_HUNDRED, AST_AOC_MULT_ONE, AST_AOC_MULT_ONEHUNDREDTH, AST_AOC_MULT_ONETENTH, AST_AOC_MULT_ONETHOUSANDTH, AST_AOC_MULT_TEN, AST_AOC_MULT_THOUSAND, ast_aoc_set_association_id(), ast_aoc_set_association_number(), ast_aoc_set_billing_id(), ast_aoc_set_currency_info(), ast_aoc_set_total_type(), AST_AOC_SUBTOTAL, AST_AOC_TOTAL, ast_strlen_zero(), astman_get_header(), astman_send_error(), and NULL.

Referenced by action_aocmessage().

◆ action_aoc_s_message()

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

Definition at line 4806 of file manager.c.

4808{
4809 struct ast_aoc_decoded *decoded = NULL;
4810 int hdrlen;
4811 int x;
4812 static const char hdr[] = "ChargedItem:";
4813 struct message sm = { 0 };
4814 int rates = 0;
4815
4816 if (!(decoded = ast_aoc_create(AST_AOC_S, 0, 0))) {
4817 astman_send_error(s, m, "Message Creation Failed");
4818 goto aocmessage_cleanup;
4819 }
4820
4821 hdrlen = strlen(hdr);
4822 for (x = 0; x < m->hdrcount; x++) {
4823 if (strncasecmp(hdr, m->headers[x], hdrlen) == 0) {
4824 if (rates > ast_aoc_s_get_count(decoded)) {
4825 if (action_aoc_s_submessage(s, &sm, decoded) == -1) {
4826 goto aocmessage_cleanup;
4827 }
4828 }
4829 ++rates;
4830 }
4831
4832 sm.headers[sm.hdrcount] = m->headers[x];
4833 ++sm.hdrcount;
4834 }
4835 if (rates > ast_aoc_s_get_count(decoded)) {
4836 if (action_aoc_s_submessage(s, &sm, decoded) == -1) {
4837 goto aocmessage_cleanup;
4838 }
4839 }
4840
4841 return decoded;
4842
4843aocmessage_cleanup:
4844
4845 ast_aoc_destroy_decoded(decoded);
4846 return NULL;
4847}
@ AST_AOC_S
Definition: aoc.h:64
unsigned int ast_aoc_s_get_count(struct ast_aoc_decoded *decoded)
get the number rates associated with an AOC-S message
Definition: aoc.c:756
static int action_aoc_s_submessage(struct mansession *s, const struct message *m, struct ast_aoc_decoded *decoded)
Definition: manager.c:4582

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

4584{
4585 const char *chargeditem = __astman_get_header(m, "ChargedItem", GET_HEADER_LAST_MATCH);
4586 const char *ratetype = __astman_get_header(m, "RateType", GET_HEADER_LAST_MATCH);
4587 const char *currencyname = __astman_get_header(m, "CurrencyName", GET_HEADER_LAST_MATCH);
4588 const char *currencyamount = __astman_get_header(m, "CurrencyAmount", GET_HEADER_LAST_MATCH);
4589 const char *mult = __astman_get_header(m, "CurrencyMultiplier", GET_HEADER_LAST_MATCH);
4590 const char *time = __astman_get_header(m, "Time", GET_HEADER_LAST_MATCH);
4591 const char *timescale = __astman_get_header(m, "TimeScale", GET_HEADER_LAST_MATCH);
4592 const char *granularity = __astman_get_header(m, "Granularity", GET_HEADER_LAST_MATCH);
4593 const char *granularitytimescale = __astman_get_header(m, "GranularityTimeScale", GET_HEADER_LAST_MATCH);
4594 const char *chargingtype = __astman_get_header(m, "ChargingType", GET_HEADER_LAST_MATCH);
4595 const char *volumeunit = __astman_get_header(m, "VolumeUnit", GET_HEADER_LAST_MATCH);
4596 const char *code = __astman_get_header(m, "Code", GET_HEADER_LAST_MATCH);
4597
4598 enum ast_aoc_s_charged_item _chargeditem;
4599 enum ast_aoc_s_rate_type _ratetype;
4601 unsigned int _currencyamount = 0;
4602 unsigned int _code;
4603 unsigned int _time = 0;
4604 enum ast_aoc_time_scale _scale = 0;
4605 unsigned int _granularity = 0;
4606 enum ast_aoc_time_scale _granularity_time_scale = AST_AOC_TIME_SCALE_MINUTE;
4607 int _step = 0;
4608 enum ast_aoc_volume_unit _volumeunit = 0;
4609
4610 if (ast_strlen_zero(chargeditem)) {
4611 astman_send_error(s, m, "ChargedItem not specified");
4612 goto aocmessage_cleanup;
4613 }
4614
4615 if (ast_strlen_zero(ratetype)) {
4616 astman_send_error(s, m, "RateType not specified");
4617 goto aocmessage_cleanup;
4618 }
4619
4620 if (!strcasecmp(chargeditem, "NA")) {
4621 _chargeditem = AST_AOC_CHARGED_ITEM_NA;
4622 } else if (!strcasecmp(chargeditem, "SpecialArrangement")) {
4624 } else if (!strcasecmp(chargeditem, "BasicCommunication")) {
4626 } else if (!strcasecmp(chargeditem, "CallAttempt")) {
4627 _chargeditem = AST_AOC_CHARGED_ITEM_CALL_ATTEMPT;
4628 } else if (!strcasecmp(chargeditem, "CallSetup")) {
4629 _chargeditem = AST_AOC_CHARGED_ITEM_CALL_SETUP;
4630 } else if (!strcasecmp(chargeditem, "UserUserInfo")) {
4632 } else if (!strcasecmp(chargeditem, "SupplementaryService")) {
4634 } else {
4635 astman_send_error(s, m, "Invalid ChargedItem");
4636 goto aocmessage_cleanup;
4637 }
4638
4639 if (!strcasecmp(ratetype, "NA")) {
4640 _ratetype = AST_AOC_RATE_TYPE_NA;
4641 } else if (!strcasecmp(ratetype, "Free")) {
4642 _ratetype = AST_AOC_RATE_TYPE_FREE;
4643 } else if (!strcasecmp(ratetype, "FreeFromBeginning")) {
4645 } else if (!strcasecmp(ratetype, "Duration")) {
4646 _ratetype = AST_AOC_RATE_TYPE_DURATION;
4647 } else if (!strcasecmp(ratetype, "Flat")) {
4648 _ratetype = AST_AOC_RATE_TYPE_FLAT;
4649 } else if (!strcasecmp(ratetype, "Volume")) {
4650 _ratetype = AST_AOC_RATE_TYPE_VOLUME;
4651 } else if (!strcasecmp(ratetype, "SpecialCode")) {
4653 } else {
4654 astman_send_error(s, m, "Invalid RateType");
4655 goto aocmessage_cleanup;
4656 }
4657
4658 if (_ratetype > AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING) {
4659 if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u",
4660 &_currencyamount) != 1)) {
4661 astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when RateType is non-free");
4662 goto aocmessage_cleanup;
4663 }
4664
4665 if (ast_strlen_zero(mult)) {
4666 astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
4667 goto aocmessage_cleanup;
4668 } else if (!strcasecmp(mult, "onethousandth")) {
4670 } else if (!strcasecmp(mult, "onehundredth")) {
4672 } else if (!strcasecmp(mult, "onetenth")) {
4673 _mult = AST_AOC_MULT_ONETENTH;
4674 } else if (!strcasecmp(mult, "one")) {
4675 _mult = AST_AOC_MULT_ONE;
4676 } else if (!strcasecmp(mult, "ten")) {
4677 _mult = AST_AOC_MULT_TEN;
4678 } else if (!strcasecmp(mult, "hundred")) {
4679 _mult = AST_AOC_MULT_HUNDRED;
4680 } else if (!strcasecmp(mult, "thousand")) {
4681 _mult = AST_AOC_MULT_THOUSAND;
4682 } else {
4683 astman_send_error(s, m, "Invalid ChargeMultiplier");
4684 goto aocmessage_cleanup;
4685 }
4686 }
4687
4688 if (_ratetype == AST_AOC_RATE_TYPE_DURATION) {
4689 if (ast_strlen_zero(timescale)) {
4690 astman_send_error(s, m, "TimeScale unspecified, TimeScale is required when RateType is Duration.");
4691 goto aocmessage_cleanup;
4692 } else if (!strcasecmp(timescale, "onehundredthsecond")) {
4694 } else if (!strcasecmp(timescale, "onetenthsecond")) {
4696 } else if (!strcasecmp(timescale, "second")) {
4698 } else if (!strcasecmp(timescale, "tenseconds")) {
4700 } else if (!strcasecmp(timescale, "minute")) {
4702 } else if (!strcasecmp(timescale, "hour")) {
4703 _scale = AST_AOC_TIME_SCALE_HOUR;
4704 } else if (!strcasecmp(timescale, "day")) {
4705 _scale = AST_AOC_TIME_SCALE_DAY;
4706 } else {
4707 astman_send_error(s, m, "Invalid TimeScale");
4708 goto aocmessage_cleanup;
4709 }
4710
4711 if (ast_strlen_zero(time) || (sscanf(time, "%30u", &_time) != 1)) {
4712 astman_send_error(s, m, "Invalid Time, Time is a required when RateType is Duration");
4713 goto aocmessage_cleanup;
4714 }
4715
4716 if (!ast_strlen_zero(granularity)) {
4717 if ((sscanf(time, "%30u", &_granularity) != 1)) {
4718 astman_send_error(s, m, "Invalid Granularity");
4719 goto aocmessage_cleanup;
4720 }
4721
4722 if (ast_strlen_zero(granularitytimescale)) {
4723 astman_send_error(s, m, "Invalid GranularityTimeScale, GranularityTimeScale is a required when Granularity is specified");
4724 } else if (!strcasecmp(granularitytimescale, "onehundredthsecond")) {
4725 _granularity_time_scale = AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
4726 } else if (!strcasecmp(granularitytimescale, "onetenthsecond")) {
4727 _granularity_time_scale = AST_AOC_TIME_SCALE_TENTH_SECOND;
4728 } else if (!strcasecmp(granularitytimescale, "second")) {
4729 _granularity_time_scale = AST_AOC_TIME_SCALE_SECOND;
4730 } else if (!strcasecmp(granularitytimescale, "tenseconds")) {
4731 _granularity_time_scale = AST_AOC_TIME_SCALE_TEN_SECOND;
4732 } else if (!strcasecmp(granularitytimescale, "minute")) {
4733 _granularity_time_scale = AST_AOC_TIME_SCALE_MINUTE;
4734 } else if (!strcasecmp(granularitytimescale, "hour")) {
4735 _granularity_time_scale = AST_AOC_TIME_SCALE_HOUR;
4736 } else if (!strcasecmp(granularitytimescale, "day")) {
4737 _granularity_time_scale = AST_AOC_TIME_SCALE_DAY;
4738 } else {
4739 astman_send_error(s, m, "Invalid GranularityTimeScale");
4740 goto aocmessage_cleanup;
4741 }
4742 }
4743
4744 if (ast_strlen_zero(chargingtype) || strcasecmp(chargingtype, "continuouscharging") == 0) {
4745 _step = 0;
4746 } else if (strcasecmp(chargingtype, "stepfunction") == 0 ) {
4747 _step = 1;
4748 } else {
4749 astman_send_error(s, m, "Invalid ChargingType");
4750 goto aocmessage_cleanup;
4751 }
4752 }
4753
4754 if (_ratetype == AST_AOC_RATE_TYPE_VOLUME) {
4755 if (ast_strlen_zero(volumeunit)) {
4756 astman_send_error(s, m, "VolumeUnit unspecified, VolumeUnit is required when RateType is Volume.");
4757 goto aocmessage_cleanup;
4758 } else if (!strcasecmp(timescale, "octet")) {
4759 _volumeunit = AST_AOC_VOLUME_UNIT_OCTET;
4760 } else if (!strcasecmp(timescale, "segment")) {
4761 _volumeunit = AST_AOC_VOLUME_UNIT_SEGMENT;
4762 } else if (!strcasecmp(timescale, "message")) {
4763 _volumeunit = AST_AOC_VOLUME_UNIT_MESSAGE;
4764 }else {
4765 astman_send_error(s, m, "Invalid VolumeUnit");
4766 goto aocmessage_cleanup;
4767 }
4768 }
4769
4771 || _ratetype == AST_AOC_RATE_TYPE_SPECIAL_CODE) {
4772 if (ast_strlen_zero(code) || (sscanf(code, "%30u", &_code) != 1)) {
4773 astman_send_error(s, m, "Invalid Code, Code is a required when ChargedItem is SpecialArrangement and when RateType is SpecialCode");
4774 goto aocmessage_cleanup;
4775 }
4776 }
4777
4778 if (_chargeditem == AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT) {
4779 ast_aoc_s_add_special_arrangement(decoded, _code);
4780 } else if (_ratetype == AST_AOC_RATE_TYPE_DURATION) {
4781 ast_aoc_s_add_rate_duration(decoded, _chargeditem, _currencyamount, _mult,
4782 currencyname, _time, _scale, _granularity, _granularity_time_scale, _step);
4783 } else if (_ratetype == AST_AOC_RATE_TYPE_FLAT) {
4784 ast_aoc_s_add_rate_flat(decoded, _chargeditem, _currencyamount, _mult,
4785 currencyname);
4786 } else if (_ratetype == AST_AOC_RATE_TYPE_VOLUME) {
4787 ast_aoc_s_add_rate_volume(decoded, _chargeditem, _volumeunit, _currencyamount,
4788 _mult, currencyname);
4789 } else if (_ratetype == AST_AOC_RATE_TYPE_SPECIAL_CODE) {
4790 ast_aoc_s_add_rate_special_charge_code(decoded, _chargeditem, _code);
4791 } else if (_ratetype == AST_AOC_RATE_TYPE_FREE) {
4792 ast_aoc_s_add_rate_free(decoded, _chargeditem, 0);
4793 } else if (_ratetype == AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING) {
4794 ast_aoc_s_add_rate_free(decoded, _chargeditem, 1);
4795 } else if (_ratetype == AST_AOC_RATE_TYPE_NA) {
4796 ast_aoc_s_add_rate_na(decoded, _chargeditem);
4797 }
4798
4799 return 0;
4800
4801aocmessage_cleanup:
4802
4803 return -1;
4804}
int ast_aoc_s_add_rate_duration(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name, unsigned long time, enum ast_aoc_time_scale time_scale, unsigned long granularity_time, enum ast_aoc_time_scale granularity_time_scale, int step_function)
Add AOC-S duration rate entry.
Definition: aoc.c:770
ast_aoc_s_charged_item
Definition: aoc.h:145
@ AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION
Definition: aoc.h:148
@ AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT
Definition: aoc.h:147
@ AST_AOC_CHARGED_ITEM_NA
Definition: aoc.h:146
@ AST_AOC_CHARGED_ITEM_USER_USER_INFO
Definition: aoc.h:151
@ AST_AOC_CHARGED_ITEM_CALL_SETUP
Definition: aoc.h:150
@ AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE
Definition: aoc.h:152
@ AST_AOC_CHARGED_ITEM_CALL_ATTEMPT
Definition: aoc.h:149
ast_aoc_time_scale
Definition: aoc.h:87
@ AST_AOC_TIME_SCALE_TEN_SECOND
Definition: aoc.h:91
@ AST_AOC_TIME_SCALE_DAY
Definition: aoc.h:94
@ AST_AOC_TIME_SCALE_TENTH_SECOND
Definition: aoc.h:89
@ AST_AOC_TIME_SCALE_MINUTE
Definition: aoc.h:92
@ AST_AOC_TIME_SCALE_SECOND
Definition: aoc.h:90
@ AST_AOC_TIME_SCALE_HOUR
Definition: aoc.h:93
@ AST_AOC_TIME_SCALE_HUNDREDTH_SECOND
Definition: aoc.h:88
ast_aoc_volume_unit
Definition: aoc.h:125
@ AST_AOC_VOLUME_UNIT_OCTET
Definition: aoc.h:126
@ AST_AOC_VOLUME_UNIT_SEGMENT
Definition: aoc.h:127
@ AST_AOC_VOLUME_UNIT_MESSAGE
Definition: aoc.h:128
int ast_aoc_s_add_rate_special_charge_code(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int code)
Add AOC-S special rate entry.
Definition: aoc.c:844
int ast_aoc_s_add_rate_free(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, int from_beginning)
Add AOC-S indicating charge item is free.
Definition: aoc.c:857
int ast_aoc_s_add_special_arrangement(struct ast_aoc_decoded *decoded, unsigned int code)
Add AOC-S special arrangement entry.
Definition: aoc.c:880
int ast_aoc_s_add_rate_flat(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S flat rate entry.
Definition: aoc.c:801
int ast_aoc_s_add_rate_volume(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, enum ast_aoc_volume_unit volume_unit, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S volume rate entry.
Definition: aoc.c:822
int ast_aoc_s_add_rate_na(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item)
Add AOC-S entry indicating charge item is not available.
Definition: aoc.c:869
ast_aoc_s_rate_type
Definition: aoc.h:155
@ AST_AOC_RATE_TYPE_VOLUME
Definition: aoc.h:161
@ AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING
Definition: aoc.h:158
@ AST_AOC_RATE_TYPE_SPECIAL_CODE
Definition: aoc.h:162
@ AST_AOC_RATE_TYPE_NA
Definition: aoc.h:156
@ AST_AOC_RATE_TYPE_DURATION
Definition: aoc.h:159
@ AST_AOC_RATE_TYPE_FLAT
Definition: aoc.h:160
@ AST_AOC_RATE_TYPE_FREE
Definition: aoc.h:157
static const char * __astman_get_header(const struct message *m, char *var, int mode)
Return a matching header value.
Definition: manager.c:1593

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

4850{
4851 const char *msgtype = astman_get_header(m, "MsgType");
4852 const char *channel = astman_get_header(m, "Channel");
4853 const char *pchannel = astman_get_header(m, "ChannelPrefix");
4854
4855 struct ast_channel *chan = NULL;
4856
4857 struct ast_aoc_decoded *decoded = NULL;
4858 struct ast_aoc_encoded *encoded = NULL;
4859 size_t encoded_size = 0;
4860
4861 if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) {
4862 astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these.");
4863 goto aocmessage_cleanup;
4864 }
4865
4866 if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) {
4867 chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel));
4868 }
4869
4870 if (!chan) {
4871 astman_send_error(s, m, "No such channel");
4872 goto aocmessage_cleanup;
4873 }
4874
4875 if (strcasecmp(msgtype, "d") == 0 || strcasecmp(msgtype, "e") == 0) {
4876 decoded = action_aoc_de_message(s, m);
4877 }
4878 else if (strcasecmp(msgtype, "s") == 0) {
4879 decoded = action_aoc_s_message(s, m);
4880 }
4881 else {
4882 astman_send_error(s, m, "Invalid MsgType");
4883 goto aocmessage_cleanup;
4884 }
4885
4886 if (!decoded) {
4887 goto aocmessage_cleanup;
4888 }
4889
4890 if ((encoded = ast_aoc_encode(decoded, &encoded_size, chan))
4891 && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) {
4892 astman_send_ack(s, m, "AOC Message successfully queued on channel");
4893 } else {
4894 astman_send_error(s, m, "Error encoding AOC message, could not queue onto channel");
4895 }
4896
4897aocmessage_cleanup:
4898
4899 ast_aoc_destroy_decoded(decoded);
4900 ast_aoc_destroy_encoded(encoded);
4901
4902 if (chan) {
4903 chan = ast_channel_unref(chan);
4904 }
4905 return 0;
4906}
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:313
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
Definition: aoc.c:650
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
Definition: channel.c:1453
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:4672
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3004
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1473
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2001
static struct ast_aoc_decoded * action_aoc_s_message(struct mansession *s, const struct message *m)
Definition: manager.c:4806
static struct ast_aoc_decoded * action_aoc_de_message(struct mansession *s, const struct message *m)
Definition: manager.c:4411
@ 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 4059 of file manager.c.

4060{
4061 const char *name = astman_get_header(m, "Channel");
4062 const char *exten = astman_get_header(m, "Exten");
4063 const char *context = astman_get_header(m, "Context");
4064 struct ast_channel *chan = NULL;
4065 char feature_code[AST_FEATURE_MAX_LEN];
4066 const char *digit;
4067
4068 if (ast_strlen_zero(name)) {
4069 astman_send_error(s, m, "No channel specified");
4070 return 0;
4071 }
4072 if (ast_strlen_zero(exten)) {
4073 astman_send_error(s, m, "No extension specified");
4074 return 0;
4075 }
4076
4077 if (!(chan = ast_channel_get_by_name(name))) {
4078 astman_send_error(s, m, "Channel specified does not exist");
4079 return 0;
4080 }
4081
4082 ast_channel_lock(chan);
4083 if (ast_get_builtin_feature(chan, "atxfer", feature_code, sizeof(feature_code)) ||
4084 ast_strlen_zero(feature_code)) {
4085 ast_channel_unlock(chan);
4086 astman_send_error(s, m, "No attended transfer feature code found");
4087 ast_channel_unref(chan);
4088 return 0;
4089 }
4090 ast_channel_unlock(chan);
4091
4092 if (!ast_strlen_zero(context)) {
4093 pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context);
4094 }
4095
4096 for (digit = feature_code; *digit; ++digit) {
4097 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
4098 ast_queue_frame(chan, &f);
4099 }
4100
4101 for (digit = exten; *digit; ++digit) {
4102 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
4103 ast_queue_frame(chan, &f);
4104 }
4105
4106 chan = ast_channel_unref(chan);
4107
4108 astman_send_ack(s, m, "Atxfer successfully queued");
4109
4110 return 0;
4111}
char digit
#define ast_channel_lock(chan)
Definition: channel.h:2968
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:2969
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 4013 of file manager.c.

4014{
4015 const char *name = astman_get_header(m, "Channel");
4016 const char *exten = astman_get_header(m, "Exten");
4017 const char *context = astman_get_header(m, "Context");
4018 struct ast_channel *chan;
4019
4020 if (ast_strlen_zero(name)) {
4021 astman_send_error(s, m, "No channel specified");
4022 return 0;
4023 }
4024
4025 if (ast_strlen_zero(exten)) {
4026 astman_send_error(s, m, "No extension specified");
4027 return 0;
4028 }
4029
4031 if (!chan) {
4032 astman_send_error(s, m, "Channel specified does not exist");
4033 return 0;
4034 }
4035
4036 if (ast_strlen_zero(context)) {
4038 }
4039
4040 switch (ast_bridge_transfer_blind(1, chan, exten, context, NULL, NULL)) {
4042 astman_send_error(s, m, "Transfer not permitted");
4043 break;
4045 astman_send_error(s, m, "Transfer invalid");
4046 break;
4048 astman_send_error(s, m, "Transfer failed");
4049 break;
4051 astman_send_ack(s, m, "Transfer succeeded");
4052 break;
4053 }
4054
4055 ast_channel_unref(chan);
4056 return 0;
4057}
enum ast_transfer_result ast_bridge_transfer_blind(int is_external, struct ast_channel *transferer, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
Blind transfer target to the extension and context provided.
Definition: bridge.c:4425
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
Definition: bridge.h:1102
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1100
@ AST_BRIDGE_TRANSFER_INVALID
Definition: bridge.h:1104
@ AST_BRIDGE_TRANSFER_FAIL
Definition: bridge.h:1106
const char * ast_channel_context(const struct ast_channel *chan)

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

Referenced by __init_manager().

◆ action_cancel_atxfer()

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

Definition at line 4113 of file manager.c.

4114{
4115 const char *name = astman_get_header(m, "Channel");
4116 struct ast_channel *chan = NULL;
4117 char *feature_code;
4118 const char *digit;
4119
4120 if (ast_strlen_zero(name)) {
4121 astman_send_error(s, m, "No channel specified");
4122 return 0;
4123 }
4124
4125 if (!(chan = ast_channel_get_by_name(name))) {
4126 astman_send_error(s, m, "Channel specified does not exist");
4127 return 0;
4128 }
4129
4130 ast_channel_lock(chan);
4131 feature_code = ast_get_chan_features_atxferabort(chan);
4132 ast_channel_unlock(chan);
4133
4134 if (!feature_code) {
4135 astman_send_error(s, m, "No disconnect feature code found");
4136 ast_channel_unref(chan);
4137 return 0;
4138 }
4139
4140 for (digit = feature_code; *digit; ++digit) {
4141 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
4142 ast_queue_frame(chan, &f);
4143 }
4144 ast_free(feature_code);
4145
4146 chan = ast_channel_unref(chan);
4147
4148 astman_send_ack(s, m, "CancelAtxfer successfully queued");
4149
4150 return 0;
4151}
#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 3324 of file manager.c.

3325{
3326 const char *authtype = astman_get_header(m, "AuthType");
3327
3328 if (!strcasecmp(authtype, "MD5")) {
3330 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
3331 }
3332 mansession_lock(s);
3333 astman_start_ack(s, m);
3334 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
3336 } else {
3337 astman_send_error(s, m, "Must specify AuthType");
3338 }
3339 return 0;
3340}
static void mansession_unlock(struct mansession *s)
Unlock the 'mansession' structure.
Definition: manager.c:2067
static void mansession_lock(struct mansession *s)
Lock the 'mansession' structure.
Definition: manager.c:2061
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2006
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1890
char challenge[10]
Definition: manager.c:293
struct mansession_session * session
Definition: manager.c:327
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 4190 of file manager.c.

4191{
4192 const char *cmd = astman_get_header(m, "Command");
4193 char *buf = NULL, *final_buf = NULL, *delim, *output;
4194 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */
4195 int fd, ret;
4196 off_t len;
4197
4198 if (ast_strlen_zero(cmd)) {
4199 astman_send_error(s, m, "No command provided");
4200 return 0;
4201 }
4202
4203 if (check_blacklist(cmd)) {
4204 astman_send_error(s, m, "Command blacklisted");
4205 return 0;
4206 }
4207
4208 if ((fd = mkstemp(template)) < 0) {
4209 astman_send_error_va(s, m, "Failed to create temporary file: %s", strerror(errno));
4210 return 0;
4211 }
4212
4213 ret = ast_cli_command(fd, cmd);
4214 astman_send_response_full(s, m, ret == RESULT_SUCCESS ? "Success" : "Error", MSG_MOREDATA, NULL);
4215
4216 /* Determine number of characters available */
4217 if ((len = lseek(fd, 0, SEEK_END)) < 0) {
4218 astman_append(s, "Message: Failed to determine number of characters: %s\r\n", strerror(errno));
4219 goto action_command_cleanup;
4220 }
4221
4222 /* This has a potential to overflow the stack. Hence, use the heap. */
4223 buf = ast_malloc(len + 1);
4224 final_buf = ast_malloc(len + 1);
4225
4226 if (!buf || !final_buf) {
4227 astman_append(s, "Message: Memory allocation failure\r\n");
4228 goto action_command_cleanup;
4229 }
4230
4231 if (lseek(fd, 0, SEEK_SET) < 0) {
4232 astman_append(s, "Message: Failed to set position on temporary file: %s\r\n", strerror(errno));
4233 goto action_command_cleanup;
4234 }
4235
4236 if (read(fd, buf, len) < 0) {
4237 astman_append(s, "Message: Failed to read from temporary file: %s\r\n", strerror(errno));
4238 goto action_command_cleanup;
4239 }
4240
4241 buf[len] = '\0';
4242 term_strip(final_buf, buf, len);
4243 final_buf[len] = '\0';
4244
4245 /* Trim trailing newline */
4246 if (len && final_buf[len - 1] == '\n') {
4247 final_buf[len - 1] = '\0';
4248 }
4249
4250 astman_append(s, "Message: Command output follows\r\n");
4251
4252 delim = final_buf;
4253 while ((output = strsep(&delim, "\n"))) {
4254 astman_append(s, "Output: %s\r\n", output);
4255 }
4256
4257action_command_cleanup:
4258 astman_append(s, "\r\n");
4259
4260 close(fd);
4261 unlink(template);
4262
4263 ast_free(buf);
4264 ast_free(final_buf);
4265
4266 return 0;
4267}
#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:1974
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:1933
static int check_blacklist(const char *cmd)
Definition: manager.c:4154
#define MSG_MOREDATA
Definition: manager.c:1924
char * strsep(char **str, const char *delims)
int errno
char * term_strip(char *outbuf, const char *inbuf, int maxout)
Remove colorings from a specified string.
Definition: term.c:362

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

Referenced by __init_manager().

◆ action_coresettings()

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

Show PBX core settings information.

Definition at line 6374 of file manager.c.

6375{
6376 const char *actionid = astman_get_header(m, "ActionID");
6377 char idText[150];
6378
6379 if (!ast_strlen_zero(actionid)) {
6380 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6381 } else {
6382 idText[0] = '\0';
6383 }
6384
6385 astman_append(s, "Response: Success\r\n"
6386 "%s"
6387 "AMIversion: %s\r\n"
6388 "AsteriskVersion: %s\r\n"
6389 "SystemName: %s\r\n"
6390 "CoreMaxCalls: %d\r\n"
6391 "CoreMaxLoadAvg: %f\r\n"
6392 "CoreRunUser: %s\r\n"
6393 "CoreRunGroup: %s\r\n"
6394 "CoreMaxFilehandles: %d\r\n"
6395 "CoreRealTimeEnabled: %s\r\n"
6396 "CoreCDRenabled: %s\r\n"
6397 "CoreHTTPenabled: %s\r\n"
6398 "SoundsSearchCustomDir: %s\r\n"
6399 "\r\n",
6400 idText,
6413 );
6414 return 0;
6415}
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:2927
#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:688
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:3559
#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 6660 of file manager.c.

6661{
6662 const char *actionid = astman_get_header(m, "ActionID");
6663 const char *channel_name = astman_get_header(m, "Channel");
6664 char *current_channel_name;
6665 char id_text[256];
6666 int total = 0;
6667 struct ao2_container *channel_map;
6668 struct ao2_iterator i;
6669 RAII_VAR(struct ast_bridge_snapshot *, bridge_snapshot, NULL, ao2_cleanup);
6670 RAII_VAR(struct ast_channel_snapshot *, channel_snapshot, NULL, ao2_cleanup);
6671
6672 if (!ast_strlen_zero(actionid)) {
6673 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
6674 } else {
6675 id_text[0] = '\0';
6676 }
6677
6678 if (ast_strlen_zero(channel_name)) {
6679 astman_send_error(s, m, "CoreShowChannelMap requires a channel.\n");
6680 return 0;
6681 }
6682
6683 channel_snapshot = ast_channel_snapshot_get_latest_by_name(channel_name);
6684 if (!channel_snapshot) {
6685 astman_send_error(s, m, "Could not get channel snapshot\n");
6686 return 0;
6687 }
6688
6689 if (ast_strlen_zero(channel_snapshot->bridge->id)) {
6690 astman_send_listack(s, m, "Channel map will follow", "start");
6691 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", 0);
6693 return 0;
6694 }
6695
6696 bridge_snapshot = ast_bridge_get_snapshot_by_uniqueid(channel_snapshot->bridge->id);
6697 if (!bridge_snapshot) {
6698 astman_send_listack(s, m, "Channel map will follow", "start");
6699 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", 0);
6701 return 0;
6702 }
6703
6705 if (!channel_map) {
6706 astman_send_error(s, m, "Could not create channel map\n");
6707 return 0;
6708 }
6709
6710 astman_send_listack(s, m, "Channel map will follow", "start");
6711
6712 if (coreshowchannelmap_add_connected_channels(channel_map, channel_snapshot, bridge_snapshot)) {
6713 astman_send_error(s, m, "Could not complete channel map\n");
6714 ao2_ref(channel_map, -1);
6715 return 0;
6716 }
6717
6718 i = ao2_iterator_init(channel_map, 0);
6719 while ((current_channel_name = ao2_iterator_next(&i))) {
6720 astman_append(s,
6721 "Event: CoreShowChannelMap\r\n"
6722 "%s"
6723 "Channel: %s\r\n"
6724 "ConnectedChannel: %s\r\n\r\n",
6725 id_text,
6726 channel_name,
6727 current_channel_name);
6728 total++;
6729 }
6731
6732 ao2_ref(channel_map, -1);
6733 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", total);
6735
6736 return 0;
6737}
@ 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:2011
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:2047
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:6576
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2055
struct ast_channel_snapshot * ast_channel_snapshot_get_latest_by_name(const char *name)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
static int total
Definition: res_adsi.c:970
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *bridge_id)
Returns the current snapshot for the bridge.
struct ao2_container * ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
Allocates a hash container for bare strings.
Definition: strings.c:200
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:314
Structure representing a snapshot of channel state.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

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

Referenced by __init_manager().

◆ action_coreshowchannels()

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

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

Definition at line 6492 of file manager.c.

6493{
6494 const char *actionid = astman_get_header(m, "ActionID");
6495 char idText[256];
6496 int numchans = 0;
6497 struct ao2_container *channels;
6498 struct ao2_iterator it_chans;
6499 struct ast_channel_snapshot *cs;
6500
6501 if (!ast_strlen_zero(actionid)) {
6502 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6503 } else {
6504 idText[0] = '\0';
6505 }
6506
6508
6509 astman_send_listack(s, m, "Channels will follow", "start");
6510
6511 it_chans = ao2_iterator_init(channels, 0);
6512 for (; (cs = ao2_iterator_next(&it_chans)); ao2_ref(cs, -1)) {
6514 char durbuf[16] = "";
6515
6516 if (!built) {
6517 continue;
6518 }
6519
6520 if (!ast_tvzero(cs->base->creationtime)) {
6521 int duration, durh, durm, durs;
6522
6523 duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->base->creationtime) / 1000);
6524 durh = duration / 3600;
6525 durm = (duration % 3600) / 60;
6526 durs = duration % 60;
6527 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
6528 }
6529
6530 astman_append(s,
6531 "Event: CoreShowChannel\r\n"
6532 "%s"
6533 "%s"
6534 "Application: %s\r\n"
6535 "ApplicationData: %s\r\n"
6536 "Duration: %s\r\n"
6537 "BridgeId: %s\r\n"
6538 "\r\n",
6539 idText,
6540 ast_str_buffer(built),
6541 cs->dialplan->appl,
6542 cs->dialplan->data,
6543 durbuf,
6544 cs->bridge->id);
6545
6546 numchans++;
6547
6548 ast_free(built);
6549 }
6550 ao2_iterator_destroy(&it_chans);
6551
6552 astman_send_list_complete(s, m, "CoreShowChannelsComplete", numchans);
6553
6554 ao2_ref(channels, -1);
6555 return 0;
6556}
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:2038
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 6418 of file manager.c.

6419{
6420 const char *actionid = astman_get_header(m, "ActionID");
6421 char idText[150];
6422 char startuptime[150], startupdate[150];
6423 char reloadtime[150], reloaddate[150];
6424 struct ast_tm tm;
6425
6426 if (!ast_strlen_zero(actionid)) {
6427 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6428 } else {
6429 idText[0] = '\0';
6430 }
6431
6433 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
6434 ast_strftime(startupdate, sizeof(startupdate), "%Y-%m-%d", &tm);
6436 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
6437 ast_strftime(reloaddate, sizeof(reloaddate), "%Y-%m-%d", &tm);
6438
6439 astman_append(s, "Response: Success\r\n"
6440 "%s"
6441 "CoreStartupDate: %s\r\n"
6442 "CoreStartupTime: %s\r\n"
6443 "CoreReloadDate: %s\r\n"
6444 "CoreReloadTime: %s\r\n"
6445 "CoreCurrentCalls: %d\r\n"
6446 "CoreProcessedCalls: %d\r\n"
6447 "\r\n",
6448 idText,
6449 startupdate,
6450 startuptime,
6451 reloaddate,
6452 reloadtime,
6455 );
6456 return 0;
6457}
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:499
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition: localtime.c:2524
struct timeval ast_lastreloadtime
Definition: asterisk.c:337
struct timeval ast_startuptime
Definition: asterisk.c:336
int ast_processed_calls(void)
Retrieve the total number of calls processed through the PBX since last restart.
Definition: pbx.c:4765

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

3071{
3072 int fd;
3073 const char *fn = astman_get_header(m, "Filename");
3074 struct ast_str *filepath = ast_str_alloca(PATH_MAX);
3075 ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR);
3076 ast_str_append(&filepath, 0, "%s", fn);
3077
3078 if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
3079 close(fd);
3080 astman_send_ack(s, m, "New configuration file created successfully");
3081 } else {
3082 astman_send_error(s, m, strerror(errno));
3083 }
3084
3085 return 0;
3086}
#define AST_FILE_MODE
Definition: asterisk.h:32
#define PATH_MAX
Definition: asterisk.h:40
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151

References ast_config_AST_CONFIG_DIR, AST_FILE_MODE, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), astman_get_header(), astman_send_ack(), astman_send_error(), errno, and PATH_MAX.

Referenced by __init_manager().

◆ action_destroy()

static void action_destroy ( void *  obj)
static

Definition at line 7720 of file manager.c.

7721{
7722 struct manager_action *doomed = obj;
7723
7724 if (doomed->synopsis) {
7725 /* The string fields were initialized. */
7727 }
7728 ao2_cleanup(doomed->final_response);
7729 ao2_cleanup(doomed->list_responses);
7730}
#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 3225 of file manager.c.

3226{
3227 const char *mask = astman_get_header(m, "EventMask");
3228 int res, x;
3229 const char *id = astman_get_header(m, "ActionID");
3230 char id_text[256];
3231
3232 if (!ast_strlen_zero(id)) {
3233 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
3234 } else {
3235 id_text[0] = '\0';
3236 }
3237
3238 res = set_eventmask(s, mask);
3240 /* if this option is set we should not return a response on
3241 * error, or when all events are set */
3242
3243 if (res > 0) {
3244 for (x = 0; x < ARRAY_LEN(perms); x++) {
3245 if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) {
3246 return 0;
3247 }
3248 }
3249 astman_append(s, "Response: Success\r\n%s"
3250 "Events: On\r\n\r\n", id_text);
3251 } else if (res == 0)
3252 astman_append(s, "Response: Success\r\n%s"
3253 "Events: Off\r\n\r\n", id_text);
3254 return 0;
3255 }
3256
3257 if (res > 0)
3258 astman_append(s, "Response: Success\r\n%s"
3259 "Events: On\r\n\r\n", id_text);
3260 else if (res == 0)
3261 astman_append(s, "Response: Success\r\n%s"
3262 "Events: Off\r\n\r\n", id_text);
3263 else
3264 astman_send_error(s, m, "Invalid event mask");
3265
3266 return 0;
3267}
static int broken_events_action
Definition: manager.c:168
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:2076
static const struct permalias perms[]
int num
Definition: manager.c:750
#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 5375 of file manager.c.

5376{
5377 const char *exten = astman_get_header(m, "Exten");
5378 const char *context = astman_get_header(m, "Context");
5379 char hint[256];
5380 int status;
5381
5382 if (ast_strlen_zero(exten)) {
5383 astman_send_error(s, m, "Extension not specified");
5384 return 0;
5385 }
5386 if (ast_strlen_zero(context)) {
5387 context = "default";
5388 }
5390 hint[0] = '\0';
5391 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
5392 astman_start_ack(s, m);
5393 astman_append(s, "Message: Extension Status\r\n"
5394 "Exten: %s\r\n"
5395 "Context: %s\r\n"
5396 "Hint: %s\r\n"
5397 "Status: %d\r\n"
5398 "StatusText: %s\r\n"
5399 "\r\n",
5400 exten, context, hint, status,
5402 return 0;
5403}
jack_status_t status
Definition: app_jack.c:146
const char * ast_extension_state2str(int extension_state)
Return string representation of the state of an extension.
Definition: pbx.c:3126
int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
If an extension hint exists, return non-zero.
Definition: pbx.c:4137
int ast_extension_state(struct ast_channel *c, const char *context, const char *exten)
Uses hint and devicestate callback to get the state of an extension.
Definition: pbx.c:3170

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

Referenced by __init_manager().

◆ action_filter()

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

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

See also
For more details look at manager_add_filter

Definition at line 5597 of file manager.c.

5598{
5599 const char *match_criteria = astman_get_header(m, "MatchCriteria");
5600 const char *filter = astman_get_header(m, "Filter");
5601 const char *operation = astman_get_header(m, "Operation");
5602 int res;
5603
5604 if (!strcasecmp(operation, "Add")) {
5605 char *criteria;
5606 int have_match = !ast_strlen_zero(match_criteria);
5607
5608 /* Create an eventfilter expression.
5609 * eventfilter[(match_criteria)]
5610 */
5611 res = ast_asprintf(&criteria, "eventfilter%s%s%s",
5612 S_COR(have_match, "(", ""), S_OR(match_criteria, ""),
5613 S_COR(have_match, ")", ""));
5614 if (res <= 0) {
5615 astman_send_error(s, m, "Internal Error. Failed to allocate storage for filter type");
5616 return 0;
5617 }
5618
5620 ast_std_free(criteria);
5621 if (res != FILTER_SUCCESS) {
5622 if (res == FILTER_ALLOC_FAILED) {
5623 astman_send_error(s, m, "Internal Error. Failed to allocate regex for filter");
5624 return 0;
5625 } else if (res == FILTER_COMPILE_FAIL) {
5626 astman_send_error(s, m,
5627 "Filter did not compile. Check the syntax of the filter given.");
5628 return 0;
5629 } else if (res == FILTER_FORMAT_ERROR) {
5630 astman_send_error(s, m,
5631 "Filter was formatted incorrectly. Check the syntax of the filter given.");
5632 return 0;
5633 } else {
5634 astman_send_error(s, m, "Internal Error. Failed adding filter.");
5635 return 0;
5636 }
5637 }
5638
5639 astman_send_ack(s, m, "Success");
5640 return 0;
5641 }
5642
5643 astman_send_error(s, m, "Unknown operation");
5644 return 0;
5645}
void ast_std_free(void *ptr)
Definition: astmm.c:1734
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:807
static enum add_filter_result manager_add_filter(const char *criteria, const char *filter_pattern, struct ao2_container *includefilters, struct ao2_container *excludefilters)
Add an event filter to a manager session.
Definition: manager.c:5664
#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:300
struct ao2_container * includefilters
Definition: manager.c:299

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

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

2485{
2486 struct ast_config *cfg;
2487 const char *fn = astman_get_header(m, "Filename");
2488 const char *category = astman_get_header(m, "Category");
2489 const char *filter = astman_get_header(m, "Filter");
2490 const char *category_name;
2491 int catcount = 0;
2492 int lineno = 0;
2493 int ret = 0;
2494 struct ast_category *cur_category = NULL;
2495 struct ast_variable *v;
2496 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2497
2498 if (ast_strlen_zero(fn)) {
2499 astman_send_error(s, m, "Filename not specified");
2500 return 0;
2501 }
2502
2503 ret = restrictedFile(fn);
2504 if (ret == 1) {
2505 astman_send_error(s, m, "File requires escalated priveledges");
2506 return 0;
2507 } else if (ret == -1) {
2508 astman_send_error(s, m, "Config file not found");
2509 return 0;
2510 }
2511
2512 cfg = ast_config_load2(fn, "manager", config_flags);
2513 if (cfg == CONFIG_STATUS_FILEMISSING) {
2514 astman_send_error(s, m, "Config file not found");
2515 return 0;
2516 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2517 astman_send_error(s, m, "Config file has invalid format");
2518 return 0;
2519 }
2520
2521 astman_start_ack(s, m);
2522 while ((cur_category = ast_category_browse_filtered(cfg, category, cur_category, filter))) {
2523 struct ast_str *templates;
2524
2525 category_name = ast_category_get_name(cur_category);
2526 lineno = 0;
2527 astman_append(s, "Category-%06d: %s\r\n", catcount, category_name);
2528
2529 if (ast_category_is_template(cur_category)) {
2530 astman_append(s, "IsTemplate-%06d: %d\r\n", catcount, 1);
2531 }
2532
2533 if ((templates = ast_category_get_templates(cur_category))
2534 && ast_str_strlen(templates) > 0) {
2535 astman_append(s, "Templates-%06d: %s\r\n", catcount, ast_str_buffer(templates));
2537 }
2538
2539 for (v = ast_category_first(cur_category); v; v = v->next) {
2540 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
2541 }
2542
2543 catcount++;
2544 }
2545
2546 if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
2547 astman_append(s, "No categories found\r\n");
2548 }
2549
2550 ast_config_destroy(cfg);
2551 astman_append(s, "\r\n");
2552
2553 return 0;
2554}
static int restrictedFile(const char *filename)
Check if a file is restricted or not.
Definition: manager.c:2451
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
Definition: main/config.c:1126
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:3336
#define CONFIG_STATUS_FILEMISSING
struct ast_str * ast_category_get_templates(const struct ast_category *category)
Return the template names this category inherits from.
Definition: main/config.c:1136
#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:1131
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
Definition: main/config.c:1255
@ CONFIG_FLAG_NOCACHE
@ CONFIG_FLAG_WITHCOMMENTS
struct ast_category * ast_category_browse_filtered(struct ast_config *config, const char *category_name, struct ast_category *prev, const char *filter)
Browse categories with filters.
Definition: main/config.c:1433
static struct templates templates
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
Structure used to handle boolean flags.
Definition: utils.h:199
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next

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

Referenced by __init_manager().

◆ action_getconfigjson()

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

Definition at line 2622 of file manager.c.

2623{
2624 struct ast_config *cfg;
2625 const char *fn = astman_get_header(m, "Filename");
2626 const char *filter = astman_get_header(m, "Filter");
2627 const char *category = astman_get_header(m, "Category");
2628 struct ast_category *cur_category = NULL;
2629 const char *category_name;
2630 struct ast_variable *v;
2631 int comma1 = 0;
2632 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2633
2634 if (ast_strlen_zero(fn)) {
2635 astman_send_error(s, m, "Filename not specified");
2636 return 0;
2637 }
2638
2639 if (restrictedFile(fn)) {
2640 astman_send_error(s, m, "File requires escalated priveledges");
2641 return 0;
2642 }
2643
2644 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
2645 astman_send_error(s, m, "Config file not found");
2646 return 0;
2647 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2648 astman_send_error(s, m, "Config file has invalid format");
2649 return 0;
2650 }
2651
2652 astman_start_ack(s, m);
2653 astman_append(s, "JSON: {");
2654 while ((cur_category = ast_category_browse_filtered(cfg, category, cur_category, filter))) {
2655 int comma2 = 0;
2656 struct ast_str *templates;
2657
2658 category_name = ast_category_get_name(cur_category);
2659 astman_append(s, "%s\"", comma1 ? "," : "");
2660 astman_append_json(s, category_name);
2661 astman_append(s, "\":{");
2662 comma1 = 1;
2663
2664 if (ast_category_is_template(cur_category)) {
2665 astman_append(s, "\"istemplate\":1");
2666 comma2 = 1;
2667 }
2668
2669 if ((templates = ast_category_get_templates(cur_category))
2670 && ast_str_strlen(templates) > 0) {
2671 astman_append(s, "%s", comma2 ? "," : "");
2672 astman_append(s, "\"templates\":\"%s\"", ast_str_buffer(templates));
2674 comma2 = 1;
2675 }
2676
2677 for (v = ast_category_first(cur_category); v; v = v->next) {
2678 astman_append(s, "%s\"", comma2 ? "," : "");
2679 astman_append_json(s, v->name);
2680 astman_append(s, "\":\"");
2682 astman_append(s, "\"");
2683 comma2 = 1;
2684 }
2685
2686 astman_append(s, "}");
2687 }
2688 astman_append(s, "}\r\n\r\n");
2689
2690 ast_config_destroy(cfg);
2691
2692 return 0;
2693}
static void astman_append_json(struct mansession *s, const char *str)
Definition: manager.c:2613

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

Referenced by __init_manager().

◆ action_getvar()

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

Definition at line 3502 of file manager.c.

3503{
3504 struct ast_channel *c = NULL;
3505 const char *name = astman_get_header(m, "Channel");
3506 const char *varname = astman_get_header(m, "Variable");
3507 char *varval;
3508 char workspace[1024];
3509
3510 if (ast_strlen_zero(varname)) {
3511 astman_send_error(s, m, "No variable specified");
3512 return 0;
3513 }
3514
3515 /* We don't want users with insufficient permissions using certain functions. */
3517 astman_send_error(s, m, "GetVar Access Forbidden: Variable");
3518 return 0;
3519 }
3520
3521 if (!ast_strlen_zero(name)) {
3522 if (!(c = ast_channel_get_by_name(name))) {
3523 astman_send_error(s, m, "No such channel");
3524 return 0;
3525 }
3526 }
3527
3528 workspace[0] = '\0';
3529 if (varname[strlen(varname) - 1] == ')') {
3530 if (!c) {
3532 if (c) {
3533 ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
3534 } else
3535 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n");
3536 } else {
3537 ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
3538 }
3539 varval = workspace;
3540 } else {
3541 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
3542 }
3543
3544 if (c) {
3546 }
3547
3548 astman_start_ack(s, m);
3549 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, S_OR(varval, ""));
3550
3551 return 0;
3552}
#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:780
#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 3463 of file manager.c.

3464{
3465 return ast_manager_hangup_helper(s, m,
3467}
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:3342

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

2557{
2558 struct ast_config *cfg;
2559 const char *fn = astman_get_header(m, "Filename");
2560 const char *match = astman_get_header(m, "Match");
2561 struct ast_category *category = NULL;
2562 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2563 int catcount = 0;
2564
2565 if (ast_strlen_zero(fn)) {
2566 astman_send_error(s, m, "Filename not specified");
2567 return 0;
2568 }
2569
2570 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
2571 astman_send_error(s, m, "Config file not found");
2572 return 0;
2573 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2574 astman_send_error(s, m, "Config file has invalid format");
2575 return 0;
2576 }
2577
2578 astman_start_ack(s, m);
2579 while ((category = ast_category_browse_filtered(cfg, NULL, category, match))) {
2580 astman_append(s, "Category-%06d: %s\r\n", catcount, ast_category_get_name(category));
2581 catcount++;
2582 }
2583
2584 if (catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
2585 astman_append(s, "Error: no categories found\r\n");
2586 }
2587
2588 ast_config_destroy(cfg);
2589 astman_append(s, "\r\n");
2590
2591 return 0;
2592}
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2362

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

Referenced by __init_manager().

◆ action_listcommands()

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

Definition at line 3206 of file manager.c.

3207{
3208 struct manager_action *cur;
3210
3211 astman_start_ack(s, m);
3213 AST_RWLIST_TRAVERSE(&actions, cur, list) {
3214 if ((s->session->writeperm & cur->authority) || cur->authority == 0) {
3215 astman_append(s, "%s: %s (Priv: %s)\r\n",
3216 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
3217 }
3218 }
3220 astman_append(s, "\r\n");
3221
3222 return 0;
3223}

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

6742{
6743 if (ast_logger_rotate()) {
6744 astman_send_error(s, m, "Failed to reload the logger and rotate log files");
6745 return 0;
6746 }
6747
6748 astman_send_ack(s, m, "Reloaded the logger and rotated log files");
6749 return 0;
6750}
int ast_logger_rotate(void)
Reload logger while rotating log files.
Definition: logger.c:1327

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

3276{
3277
3278 /* still authenticated - don't process again */
3279 if (s->session->authenticated) {
3280 astman_send_ack(s, m, "Already authenticated");
3281 return 0;
3282 }
3283
3284 if (authenticate(s, m)) {
3285 sleep(1);
3286 astman_send_error(s, m, "Authentication failed");
3287 return -1;
3288 }
3289 s->session->authenticated = 1;
3292 ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_sockaddr_stringify_addr(&s->session->addr));
3293 }
3294 astman_send_ack(s, m, "Authentication accepted");
3299 const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
3300 long uptime = 0;
3301 long lastreloaded = 0;
3302 struct timeval tmp;
3303 struct timeval curtime = ast_tvnow();
3304
3305 if (ast_startuptime.tv_sec) {
3306 tmp = ast_tvsub(curtime, ast_startuptime);
3307 uptime = tmp.tv_sec;
3308 }
3309
3310 if (ast_lastreloadtime.tv_sec) {
3311 tmp = ast_tvsub(curtime, ast_lastreloadtime);
3312 lastreloaded = tmp.tv_sec;
3313 }
3314
3315 astman_append(s, "Event: FullyBooted\r\n"
3316 "Privilege: %s\r\n"
3317 "Uptime: %ld\r\n"
3318 "LastReload: %ld\r\n"
3319 "Status: Fully Booted\r\n\r\n", cat_str, uptime, lastreloaded);
3320 }
3321 return 0;
3322}
static int tmp()
Definition: bt_open.c:389
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:1062
static int unauth_sessions
Definition: manager.c:181
static int authenticate(struct mansession *s, const struct message *m)
Definition: manager.c:2315
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:283
uint32_t managerid
Definition: manager.c:288
char username[80]
Definition: manager.c:292
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: extconf.c:2297
#define ast_test_flag(p, flag)
Definition: utils.h:63

References mansession_session::addr, ast_atomic_fetchadd_int(), ast_lastreloadtime, AST_OPT_FLAG_FULLY_BOOTED, ast_options, ast_sockaddr_stringify_addr(), ast_startuptime, ast_str_alloca, ast_test_flag, ast_tvnow(), ast_tvsub(), ast_verb, astman_append(), astman_send_ack(), astman_send_error(), authenticate(), mansession_session::authenticated, authority_to_str(), EVENT_FLAG_SYSTEM, manager_displayconnects(), mansession_session::managerid, MAX_AUTH_PERM_STRING, mansession_session::readperm, mansession_session::send_events, mansession::session, tmp(), unauth_sessions, and mansession_session::username.

Referenced by __init_manager().

◆ action_logoff()

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

Definition at line 3269 of file manager.c.

3270{
3271 astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
3272 return -1;
3273}
void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg)
Send response in manager transaction.
Definition: manager.c:1964

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

5355{
5356 const char *mailbox = astman_get_header(m, "Mailbox");
5357 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;;
5358
5359 if (ast_strlen_zero(mailbox)) {
5360 astman_send_error(s, m, "Mailbox not specified");
5361 return 0;
5362 }
5363 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs);
5364 astman_start_ack(s, m);
5365 astman_append(s, "Message: Mailbox Message Count\r\n"
5366 "Mailbox: %s\r\n"
5367 "UrgMessages: %d\r\n"
5368 "NewMessages: %d\r\n"
5369 "OldMessages: %d\r\n"
5370 "\r\n",
5371 mailbox, urgentmsgs, newmsgs, oldmsgs);
5372 return 0;
5373}
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 5337 of file manager.c.

5338{
5339 const char *mailbox = astman_get_header(m, "Mailbox");
5340 int ret;
5341
5342 if (ast_strlen_zero(mailbox)) {
5343 astman_send_error(s, m, "Mailbox not specified");
5344 return 0;
5345 }
5347 astman_start_ack(s, m);
5348 astman_append(s, "Message: Mailbox Status\r\n"
5349 "Mailbox: %s\r\n"
5350 "Waiting: %d\r\n\r\n", mailbox, ret);
5351 return 0;
5352}
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 5142 of file manager.c.

5143{
5144 const char *name = astman_get_header(m, "Channel");
5145 const char *exten = astman_get_header(m, "Exten");
5146 const char *context = astman_get_header(m, "Context");
5147 const char *priority = astman_get_header(m, "Priority");
5148 const char *timeout = astman_get_header(m, "Timeout");
5149 const char *callerid = astman_get_header(m, "CallerID");
5150 const char *account = astman_get_header(m, "Account");
5151 const char *app = astman_get_header(m, "Application");
5152 const char *appdata = astman_get_header(m, "Data");
5153 const char *async = astman_get_header(m, "Async");
5154 const char *id = astman_get_header(m, "ActionID");
5155 const char *codecs = astman_get_header(m, "Codecs");
5156 const char *early_media = astman_get_header(m, "Earlymedia");
5157 struct ast_assigned_ids assignedids = {
5158 .uniqueid = astman_get_header(m, "ChannelId"),
5159 .uniqueid2 = astman_get_header(m, "OtherChannelId"),
5160 };
5161 const char *gosub = astman_get_header(m, "PreDialGoSub");
5162
5163 struct ast_variable *vars = NULL;
5164 char *tech, *data;
5165 char *l = NULL, *n = NULL;
5166 int pi = 0;
5167 int res;
5168 int to = 30000;
5169 int reason = 0;
5170 char tmp[256];
5171 char tmp2[256];
5173 pthread_t th;
5174 int bridge_early = 0;
5175
5176 if (!cap) {
5177 astman_send_error(s, m, "Internal Error. Memory allocation failure.");
5178 return 0;
5179 }
5181
5182 if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid))
5183 || (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) {
5184 astman_send_error_va(s, m, "Uniqueid length exceeds maximum of %d\n",
5186 res = 0;
5187 goto fast_orig_cleanup;
5188 }
5189
5190 if (ast_strlen_zero(name)) {
5191 astman_send_error(s, m, "Channel not specified");
5192 res = 0;
5193 goto fast_orig_cleanup;
5194 }
5195 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
5196 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
5197 astman_send_error(s, m, "Invalid priority");
5198 res = 0;
5199 goto fast_orig_cleanup;
5200 }
5201 }
5202 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
5203 astman_send_error(s, m, "Invalid timeout");
5204 res = 0;
5205 goto fast_orig_cleanup;
5206 }
5207 ast_copy_string(tmp, name, sizeof(tmp));
5208 tech = tmp;
5209 data = strchr(tmp, '/');
5210 if (!data) {
5211 astman_send_error(s, m, "Invalid channel");
5212 res = 0;
5213 goto fast_orig_cleanup;
5214 }
5215 *data++ = '\0';
5216 ast_copy_string(tmp2, callerid, sizeof(tmp2));
5217 ast_callerid_parse(tmp2, &n, &l);
5218 if (n) {
5219 if (ast_strlen_zero(n)) {
5220 n = NULL;
5221 }
5222 }
5223 if (l) {
5225 if (ast_strlen_zero(l)) {
5226 l = NULL;
5227 }
5228 }
5229 if (!ast_strlen_zero(codecs)) {
5232 }
5233
5234 if (!ast_strlen_zero(app) && s->session) {
5235 if (!is_originate_app_permitted(app, appdata, s->session->writeperm)) {
5236 astman_send_error(s, m, "Originate Access Forbidden: app or data blacklisted");
5237 res = 0;
5238 goto fast_orig_cleanup;
5239 }
5240 }
5241
5242 /* Check early if the extension exists. If not, we need to bail out here. */
5243 if (exten && context && pi) {
5244 if (! ast_exists_extension(NULL, context, exten, pi, l)) {
5245 /* The extension does not exist. */
5246 astman_send_error(s, m, "Extension does not exist.");
5247 res = 0;
5248 goto fast_orig_cleanup;
5249 }
5250 }
5251
5252 /* Allocate requested channel variables */
5253 vars = astman_get_variables(m);
5254 if (s->session && s->session->chanvars) {
5255 struct ast_variable *v, *old;
5256 old = vars;
5257 vars = NULL;
5258
5259 /* The variables in the AMI originate action are appended at the end of the list, to override any user variables that apply */
5260
5262 if (old) {
5263 for (v = vars; v->next; v = v->next );
5264 v->next = old; /* Append originate variables at end of list */
5265 }
5266 }
5267
5268 /* For originate async - we can bridge in early media stage */
5269 bridge_early = ast_true(early_media);
5270
5271 if (ast_true(async)) {
5272 struct fast_originate_helper *fast;
5273
5274 fast = ast_calloc(1, sizeof(*fast));
5275 if (!fast || ast_string_field_init(fast, 252)) {
5276 ast_free(fast);
5278 res = -1;
5279 } else {
5280 if (!ast_strlen_zero(id)) {
5281 ast_string_field_build(fast, idtext, "ActionID: %s\r\n", id);
5282 }
5287 ast_string_field_set(fast, cid_num, l);
5292 ast_string_field_set(fast, channelid, assignedids.uniqueid);
5293 ast_string_field_set(fast, otherchannelid, assignedids.uniqueid2);
5294 fast->vars = vars;
5295 fast->cap = cap;
5296 cap = NULL; /* transfered originate helper the capabilities structure. It is now responsible for freeing it. */
5297 fast->timeout = to;
5298 fast->early_media = bridge_early;
5299 fast->priority = pi;
5302 res = -1;
5303 } else {
5304 res = 0;
5305 }
5306 }
5307 } else if (!ast_strlen_zero(app)) {
5308 res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason,
5310 assignedids.uniqueid ? &assignedids : NULL);
5312 } else {
5313 if (exten && context && pi) {
5315 context, exten, pi, &reason, AST_OUTGOING_WAIT,
5316 l, n, vars, account, NULL, bridge_early,
5317 assignedids.uniqueid ? &assignedids : NULL , gosub);
5319 } else {
5320 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
5322 res = 0;
5323 goto fast_orig_cleanup;
5324 }
5325 }
5326 if (!res) {
5327 astman_send_ack(s, m, "Originate successfully queued");
5328 } else {
5329 astman_send_error(s, m, "Originate failed");
5330 }
5331
5332fast_orig_cleanup:
5334 return 0;
5335}
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:5036
static void destroy_fast_originate_helper(struct fast_originate_helper *doomed)
Definition: manager.c:4298
struct ast_variable * astman_get_variables(const struct message *m)
Get a linked list of the Variable: headers.
Definition: manager.c:1716
static void * fast_originate(void *data)
Definition: manager.c:4306
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Definition: main/config.c:544
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
Find the priority of an extension that has the specified label.
Definition: pbx.c:4180
int ast_pbx_outgoing_exten_predial(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, int early_media, const struct ast_assigned_ids *assignedids, const char *predial_callee)
Definition: pbx.c:7926
@ AST_OUTGOING_WAIT
Definition: pbx.h:1141
int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, const struct ast_assigned_ids *assignedids)
Synchronously or asynchronously make an outbound call and execute an application on the channel.
Definition: pbx.c:7980
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4175
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure to pass both assignedid values to channel drivers.
Definition: channel.h: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:4270
const ast_string_field appdata
Definition: manager.c:4288
struct ast_variable * vars
Definition: manager.c:4290
const ast_string_field cid_num
Definition: manager.c:4288
const ast_string_field account
Definition: manager.c:4288
const ast_string_field tech
Definition: manager.c:4288
const ast_string_field data
Definition: manager.c:4288
const ast_string_field channelid
Definition: manager.c:4288
const ast_string_field otherchannelid
Definition: manager.c:4288
struct ast_format_cap * cap
Definition: manager.c:4272
const ast_string_field exten
Definition: manager.c:4288
const ast_string_field idtext
Definition: manager.c:4288
const ast_string_field cid_name
Definition: manager.c:4288
struct ast_variable * chanvars
Definition: manager.c:301
#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, tmp(), ast_assigned_ids::uniqueid, ast_assigned_ids::uniqueid2, fast_originate_helper::vars, and mansession_session::writeperm.

Referenced by __init_manager().

◆ action_ping()

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

Definition at line 2412 of file manager.c.

2413{
2414 const char *actionid = astman_get_header(m, "ActionID");
2415 struct timeval now = ast_tvnow();
2416
2417 astman_append(s, "Response: Success\r\n");
2418 if (!ast_strlen_zero(actionid)){
2419 astman_append(s, "ActionID: %s\r\n", actionid);
2420 }
2422 s,
2423 "Ping: Pong\r\n"
2424 "Timestamp: %ld.%06lu\r\n"
2425 "\r\n",
2426 (long) now.tv_sec, (unsigned long) now.tv_usec);
2427 return 0;
2428}

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

5406{
5407 const char *provider = astman_get_header(m, "Provider");
5409 char *subtype;
5410 char *message;
5411
5413 astman_send_error(s, m, "No provider specified");
5414 return 0;
5415 }
5416
5418 if (state == AST_PRESENCE_INVALID) {
5419 astman_send_error_va(s, m, "Invalid provider %s or provider in invalid state", provider);
5420 return 0;
5421 }
5422
5423 astman_start_ack(s, m);
5424 astman_append(s, "Message: Presence State\r\n"
5425 "State: %s\r\n", ast_presence_state2str(state));
5426
5427 if (!ast_strlen_zero(subtype)) {
5428 astman_append(s, "Subtype: %s\r\n", subtype);
5429 }
5430
5431 if (!ast_strlen_zero(message)) {
5432 /* XXX The Message header here is deprecated as it
5433 * duplicates the action response header 'Message'.
5434 * Remove it in the next major revision of AMI.
5435 */
5436 astman_append(s, "Message: %s\r\n"
5437 "PresenceMessage: %s\r\n",
5438 message, message);
5439 }
5440 astman_append(s, "\r\n");
5441
5442 return 0;
5443}
static struct prometheus_metrics_provider provider
Definition: bridges.c:201
enum cc_state state
Definition: ccss.c:393
ast_presence_state
Definition: presencestate.h:26
@ AST_PRESENCE_INVALID
Definition: presencestate.h:39
const char * ast_presence_state2str(enum ast_presence_state state)
Convert presence state to text string for output.

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

Referenced by __init_manager().

◆ action_redirect()

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

action_redirect: The redirect manager command

Definition at line 3868 of file manager.c.

3869{
3870 char buf[256];
3871 const char *name = astman_get_header(m, "Channel");
3872 const char *name2 = astman_get_header(m, "ExtraChannel");
3873 const char *exten = astman_get_header(m, "Exten");
3874 const char *exten2 = astman_get_header(m, "ExtraExten");
3875 const char *context = astman_get_header(m, "Context");
3876 const char *context2 = astman_get_header(m, "ExtraContext");
3877 const char *priority = astman_get_header(m, "Priority");
3878 const char *priority2 = astman_get_header(m, "ExtraPriority");
3879 struct ast_channel *chan;
3880 struct ast_channel *chan2;
3881 int pi = 0;
3882 int pi2 = 0;
3883 int res;
3884 int chan1_wait = 0;
3885 int chan2_wait = 0;
3886
3887 if (ast_strlen_zero(name)) {
3888 astman_send_error(s, m, "Channel not specified");
3889 return 0;
3890 }
3891
3892 if (ast_strlen_zero(context)) {
3893 astman_send_error(s, m, "Context not specified");
3894 return 0;
3895 }
3896 if (ast_strlen_zero(exten)) {
3897 astman_send_error(s, m, "Exten not specified");
3898 return 0;
3899 }
3901 astman_send_error(s, m, "Priority not specified");
3902 return 0;
3903 }
3904 if (sscanf(priority, "%30d", &pi) != 1) {
3906 }
3907 if (pi < 1) {
3908 astman_send_error(s, m, "Priority is invalid");
3909 return 0;
3910 }
3911
3912 if (!ast_strlen_zero(name2) && !ast_strlen_zero(context2)) {
3913 /* We have an ExtraChannel and an ExtraContext */
3914 if (ast_strlen_zero(exten2)) {
3915 astman_send_error(s, m, "ExtraExten not specified");
3916 return 0;
3917 }
3918 if (ast_strlen_zero(priority2)) {
3919 astman_send_error(s, m, "ExtraPriority not specified");
3920 return 0;
3921 }
3922 if (sscanf(priority2, "%30d", &pi2) != 1) {
3923 pi2 = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL);
3924 }
3925 if (pi2 < 1) {
3926 astman_send_error(s, m, "ExtraPriority is invalid");
3927 return 0;
3928 }
3929 }
3930
3932 if (!chan) {
3933 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
3934 astman_send_error(s, m, buf);
3935 return 0;
3936 }
3937 if (ast_check_hangup_locked(chan)) {
3938 astman_send_error(s, m, "Redirect failed, channel not up.");
3939 chan = ast_channel_unref(chan);
3940 return 0;
3941 }
3942
3943 if (ast_strlen_zero(name2)) {
3944 /* Single channel redirect in progress. */
3945 res = ast_async_goto(chan, context, exten, pi);
3946 if (!res) {
3947 astman_send_ack(s, m, "Redirect successful");
3948 } else {
3949 astman_send_error(s, m, "Redirect failed");
3950 }
3951 chan = ast_channel_unref(chan);
3952 return 0;
3953 }
3954
3955 chan2 = ast_channel_get_by_name(name2);
3956 if (!chan2) {
3957 snprintf(buf, sizeof(buf), "ExtraChannel does not exist: %s", name2);
3958 astman_send_error(s, m, buf);
3959 chan = ast_channel_unref(chan);
3960 return 0;
3961 }
3962 if (ast_check_hangup_locked(chan2)) {
3963 astman_send_error(s, m, "Redirect failed, extra channel not up.");
3964 chan2 = ast_channel_unref(chan2);
3965 chan = ast_channel_unref(chan);
3966 return 0;
3967 }
3968
3969 /* Dual channel redirect in progress. */
3970 ast_channel_lock(chan);
3971 if (ast_channel_is_bridged(chan)) {
3973 chan1_wait = 1;
3974 }
3975 ast_channel_unlock(chan);
3976
3977 ast_channel_lock(chan2);
3978 if (ast_channel_is_bridged(chan2)) {
3980 chan2_wait = 1;
3981 }
3982 ast_channel_unlock(chan2);
3983
3984 res = ast_async_goto(chan, context, exten, pi);
3985 if (!res) {
3986 if (!ast_strlen_zero(context2)) {
3987 res = ast_async_goto(chan2, context2, exten2, pi2);
3988 } else {
3989 res = ast_async_goto(chan2, context, exten, pi);
3990 }
3991 if (!res) {
3992 astman_send_ack(s, m, "Dual Redirect successful");
3993 } else {
3994 astman_send_error(s, m, "Secondary redirect failed");
3995 }
3996 } else {
3997 astman_send_error(s, m, "Redirect failed");
3998 }
3999
4000 /* Release the bridge wait. */
4001 if (chan1_wait) {
4003 }
4004 if (chan2_wait) {
4006 }
4007
4008 chan2 = ast_channel_unref(chan2);
4009 chan = ast_channel_unref(chan);
4010 return 0;
4011}
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11056
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:10567
@ AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT
Definition: channel.h:1055
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
Definition: pbx.c:6969
#define ast_set_flag(p, flag)
Definition: utils.h:70

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

Referenced by __init_manager().

◆ action_reload()

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

Send a reload event.

Definition at line 6460 of file manager.c.

6461{
6462 const char *module = astman_get_header(m, "Module");
6464
6465 switch (res) {
6467 astman_send_error(s, m, "No such module");
6468 break;
6470 astman_send_error(s, m, "Module does not support reload");
6471 break;
6473 astman_send_error(s, m, "An unknown error occurred");
6474 break;
6476 astman_send_error(s, m, "A reload is in progress");
6477 break;
6479 astman_send_error(s, m, "Module not initialized");
6480 break;
6483 /* Treat a queued request as success */
6484 astman_send_ack(s, m, "Module Reloaded");
6485 break;
6486 }
6487 return 0;
6488}
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:1721

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

3826{
3827 struct ast_channel *c;
3828 const char *name = astman_get_header(m, "Channel");
3829 const char *textmsg = astman_get_header(m, "Message");
3830 const char *content_type = astman_get_header(m, "Content-Type");
3831 int res;
3832
3833 if (ast_strlen_zero(name)) {
3834 astman_send_error(s, m, "No channel specified");
3835 return 0;
3836 }
3837
3838 if (ast_strlen_zero(textmsg)) {
3839 astman_send_error(s, m, "No Message specified");
3840 return 0;
3841 }
3842
3844 if (!c) {
3845 astman_send_error(s, m, "No such channel");
3846 return 0;
3847 }
3848
3849 /*
3850 * If the "extra" data is not available, then send using "string" only.
3851 * Doing such maintains backward compatibilities.
3852 */
3853 res = ast_strlen_zero(content_type) ? queue_sendtext(c, textmsg) :
3854 queue_sendtext_data(c, textmsg, content_type);
3855
3857
3858 if (res >= 0) {
3859 astman_send_ack(s, m, "Success");
3860 } else {
3861 astman_send_error(s, m, "Failure");
3862 }
3863
3864 return 0;
3865}
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:3806
static int queue_sendtext(struct ast_channel *chan, const char *body)
Queue a read action to send a text message.
Definition: manager.c:3790

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

3470{
3471 struct ast_channel *c = NULL;
3472 const char *name = astman_get_header(m, "Channel");
3473 const char *varname = astman_get_header(m, "Variable");
3474 const char *varval = astman_get_header(m, "Value");
3475 int res = 0;
3476
3477 if (ast_strlen_zero(varname)) {
3478 astman_send_error(s, m, "No variable specified");
3479 return 0;
3480 }
3481
3482 if (!ast_strlen_zero(name)) {
3483 if (!(c = ast_channel_get_by_name(name))) {
3484 astman_send_error(s, m, "No such channel");
3485 return 0;
3486 }
3487 }
3488
3489 res = pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
3490
3491 if (c) {
3493 }
3494 if (res == 0) {
3495 astman_send_ack(s, m, "Variable Set");
3496 } else {
3497 astman_send_error(s, m, "Variable not set");
3498 }
3499 return 0;
3500}

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

3670{
3671 const char *name = astman_get_header(m, "Channel");
3672 const char *chan_variables = astman_get_header(m, "Variables");
3673 const char *all_chan_variables = astman_get_header(m, "AllVariables");
3674 int all_variables = 0;
3675 const char *id = astman_get_header(m, "ActionID");
3676 char *variables = ast_strdupa(S_OR(chan_variables, ""));
3677 struct ast_channel *chan;
3678 int channels = 0;
3679 int all = ast_strlen_zero(name); /* set if we want all channels */
3680 char id_text[256];
3681 struct ast_channel_iterator *it_chans = NULL;
3683 AST_APP_ARG(name)[100];
3684 );
3685
3686 if (!ast_strlen_zero(all_chan_variables)) {
3687 all_variables = ast_true(all_chan_variables);
3688 }
3689
3691 astman_send_error(s, m, "Status Access Forbidden: Variables");
3692 return 0;
3693 }
3694
3695 if (all) {
3696 if (!(it_chans = ast_channel_iterator_all_new())) {
3697 astman_send_error(s, m, "Memory Allocation Failure");
3698 return 1;
3699 }
3700 chan = ast_channel_iterator_next(it_chans);
3701 } else {
3703 if (!chan) {
3704 astman_send_error(s, m, "No such channel");
3705 return 0;
3706 }
3707 }
3708
3709 astman_send_listack(s, m, "Channel status will follow", "start");
3710
3711 if (!ast_strlen_zero(id)) {
3712 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
3713 } else {
3714 id_text[0] = '\0';
3715 }
3716
3717 if (!ast_strlen_zero(chan_variables)) {
3718 AST_STANDARD_APP_ARGS(vars, variables);
3719 }
3720
3721 /* if we look by name, we break after the first iteration */
3722 for (; chan; all ? chan = ast_channel_iterator_next(it_chans) : 0) {
3723 ast_channel_lock(chan);
3724
3725 generate_status(s, chan, vars.name, vars.argc, all_variables, id_text, &channels);
3726
3727 ast_channel_unlock(chan);
3728 chan = ast_channel_unref(chan);
3729 }
3730
3731 if (it_chans) {
3733 }
3734
3735 astman_send_list_complete_start(s, m, "StatusComplete", channels);
3736 astman_append(s, "Items: %d\r\n", channels);
3738
3739 return 0;
3740}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1379
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1441
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1427
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:3554
#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 5445 of file manager.c.

5446{
5447 struct ast_channel *c;
5448 const char *name = astman_get_header(m, "Channel");
5449 double timeout = atof(astman_get_header(m, "Timeout"));
5450 struct timeval when = { timeout, 0 };
5451
5452 if (ast_strlen_zero(name)) {
5453 astman_send_error(s, m, "No channel specified");
5454 return 0;
5455 }
5456
5457 if (!timeout || timeout < 0) {
5458 astman_send_error(s, m, "No timeout specified");
5459 return 0;
5460 }
5461
5462 if (!(c = ast_channel_get_by_name(name))) {
5463 astman_send_error(s, m, "No such channel");
5464 return 0;
5465 }
5466
5467 when.tv_usec = (timeout - when.tv_sec) * 1000000.0;
5468
5473
5474 astman_send_ack(s, m, "Timeout Set");
5475
5476 return 0;
5477}
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 2979 of file manager.c.

2980{
2981 struct ast_config *cfg;
2982 const char *sfn = astman_get_header(m, "SrcFilename");
2983 const char *dfn = astman_get_header(m, "DstFilename");
2984 int res;
2985 const char *rld = astman_get_header(m, "Reload");
2986 int preserve_effective_context = CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT;
2987 const char *preserve_effective_context_string = astman_get_header(m, "PreserveEffectiveContext");
2988 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2989 enum error_type result;
2990
2991 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
2992 astman_send_error(s, m, "Filename not specified");
2993 return 0;
2994 }
2995 if (restrictedFile(sfn) || restrictedFile(dfn)) {
2996 astman_send_error(s, m, "File requires escalated priveledges");
2997 return 0;
2998 }
2999 if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) {
3000 astman_send_error(s, m, "Config file not found");
3001 return 0;
3002 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
3003 astman_send_error(s, m, "Config file has invalid format");
3004 return 0;
3005 }
3006 result = handle_updates(s, m, cfg, dfn);
3007 if (!result) {
3008 ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
3009 if (!ast_strlen_zero(preserve_effective_context_string) && !ast_true(preserve_effective_context_string)) {
3010 preserve_effective_context = CONFIG_SAVE_FLAG_NONE;
3011 }
3012 res = ast_config_text_file_save2(dfn, cfg, "Manager", preserve_effective_context);
3013 ast_config_destroy(cfg);
3014 if (res) {
3015 astman_send_error(s, m, "Save of config failed");
3016 return 0;
3017 }
3018 astman_send_ack(s, m, NULL);
3019 if (!ast_strlen_zero(rld)) {
3020 if (ast_true(rld)) {
3021 ast_module_reload(NULL); /* Reload everything */
3022 } else if (!ast_false(rld)) {
3023 ast_module_reload(rld); /* Reload the specific module */
3024 }
3025 }
3026 } else {
3027 ast_config_destroy(cfg);
3028 switch(result) {
3029 case UNKNOWN_ACTION:
3030 astman_send_error(s, m, "Unknown action command");
3031 break;
3032 case UNKNOWN_CATEGORY:
3033 astman_send_error(s, m, "Given category does not exist");
3034 break;
3036 astman_send_error(s, m, "Category not specified");
3037 break;
3039 astman_send_error(s, m, "Problem with category, value, or line (if required)");
3040 break;
3041 case FAILURE_ALLOCATION:
3042 astman_send_error(s, m, "Memory allocation failure, this should not happen");
3043 break;
3044 case FAILURE_NEWCAT:
3045 astman_send_error(s, m, "Create category did not complete successfully");
3046 break;
3047 case FAILURE_DELCAT:
3048 astman_send_error(s, m, "Delete category did not complete successfully");
3049 break;
3050 case FAILURE_EMPTYCAT:
3051 astman_send_error(s, m, "Empty category did not complete successfully");
3052 break;
3053 case FAILURE_UPDATE:
3054 astman_send_error(s, m, "Update did not complete successfully");
3055 break;
3056 case FAILURE_DELETE:
3057 astman_send_error(s, m, "Delete did not complete successfully");
3058 break;
3059 case FAILURE_APPEND:
3060 astman_send_error(s, m, "Append did not complete successfully");
3061 break;
3062 case FAILURE_TEMPLATE:
3063 astman_send_error(s, m, "Template category not found");
3064 break;
3065 }
3066 }
3067 return 0;
3068}
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:2696
error_type
Definition: manager.c:111
void ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
Definition: main/config.c:384
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:2740
@ CONFIG_SAVE_FLAG_NONE
@ CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"....
Definition: utils.c:2216

References ast_config_destroy(), ast_config_load2(), ast_config_text_file_save2(), ast_false(), ast_include_rename(), ast_module_reload(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_send_ack(), astman_send_error(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_SAVE_FLAG_NONE, CONFIG_SAVE_FLAG_PRESERVE_EFFECTIVE_CONTEXT, CONFIG_STATUS_FILEINVALID, FAILURE_ALLOCATION, FAILURE_APPEND, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_TEMPLATE, FAILURE_UPDATE, handle_updates(), NULL, restrictedFile(), result, UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, and UNSPECIFIED_CATEGORY.

Referenced by __init_manager().

◆ action_userevent()

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

Definition at line 6353 of file manager.c.

6354{
6355 const char *event = astman_get_header(m, "UserEvent");
6356 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
6357 int x;
6358
6359 ast_str_reset(body);
6360
6361 for (x = 0; x < m->hdrcount; x++) {
6362 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:")) &&
6363 strncasecmp("Action:", m->headers[x], strlen("Action:"))) {
6364 ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
6365 }
6366 }
6367
6368 astman_send_ack(s, m, "Event Sent");
6369 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body));
6370 return 0;
6371}
static struct ast_threadstorage userevent_buf
Definition: manager.c:1873
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:253
#define EVENT_FLAG_USER
Definition: manager.h:81
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:693

References ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), astman_get_header(), astman_send_ack(), EVENT_FLAG_USER, message::hdrcount, message::headers, manager_event, and userevent_buf.

Referenced by __init_manager().

◆ action_waitevent()

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

Definition at line 3088 of file manager.c.

3089{
3090 const char *timeouts = astman_get_header(m, "Timeout");
3091 int timeout = -1;
3092 int x;
3093 int needexit = 0;
3094 const char *id = astman_get_header(m, "ActionID");
3095 char idText[256];
3096
3097 if (!ast_strlen_zero(id)) {
3098 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
3099 } else {
3100 idText[0] = '\0';
3101 }
3102
3103 if (!ast_strlen_zero(timeouts)) {
3104 sscanf(timeouts, "%30i", &timeout);
3105 if (timeout < -1) {
3106 timeout = -1;
3107 }
3108 /* XXX maybe put an upper bound, or prevent the use of 0 ? */
3109 }
3110
3113 pthread_kill(s->session->waiting_thread, SIGURG);
3114 }
3116
3117 ao2_lock(s->session);
3118
3119 if (s->session->managerid) { /* AMI-over-HTTP session */
3120 /*
3121 * Make sure the timeout is within the expire time of the session,
3122 * as the client will likely abort the request if it does not see
3123 * data coming after some amount of time.
3124 */
3125 time_t now = time(NULL);
3126 int max = s->session->sessiontimeout - now - 10;
3127
3128 if (max < 0) { /* We are already late. Strange but possible. */
3129 max = 0;
3130 }
3131 if (timeout < 0 || timeout > max) {
3132 timeout = max;
3133 }
3134 if (!s->session->send_events) { /* make sure we record events */
3135 s->session->send_events = -1;
3136 }
3137 }
3138 ao2_unlock(s->session);
3139
3141 s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
3143 ast_debug(1, "Starting waiting for an event!\n");
3144
3145 for (x = 0; x < timeout || timeout < 0; x++) {
3146 ao2_lock(s->session);
3147 if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
3148 needexit = 1;
3149 }
3150 if (s->session->needdestroy) {
3151 needexit = 1;
3152 }
3153 ao2_unlock(s->session);
3154 /* We can have multiple HTTP session point to the same mansession entry.
3155 * The way we deal with it is not very nice: newcomers kick out the previous
3156 * HTTP session. XXX this needs to be improved.
3157 */
3159 if (s->session->waiting_thread != pthread_self()) {
3160 needexit = 1;
3161 }
3163 if (needexit) {
3164 break;
3165 }
3166 if (s->session->managerid == 0) { /* AMI session */
3168 break;
3169 }
3170 } else { /* HTTP session */
3171 sleep(1);
3172 }
3173 }
3174 ast_debug(1, "Finished waiting for an event!\n");
3175
3177 if (s->session->waiting_thread == pthread_self()) {
3178 struct eventqent *eqe = s->session->last_ev;
3179
3182
3183 ao2_lock(s->session);
3184 astman_send_response(s, m, "Success", "Waiting for Event completed.");
3185 while ((eqe = advance_event(eqe))) {
3186 if (((s->session->readperm & eqe->category) == eqe->category)
3187 && ((s->session->send_events & eqe->category) == eqe->category)
3189 astman_append(s, "%s", eqe->eventdata);
3190 }
3191 s->session->last_ev = eqe;
3192 }
3193 astman_append(s,
3194 "Event: WaitEventComplete\r\n"
3195 "%s"
3196 "\r\n", idText);
3197 ao2_unlock(s->session);
3198 } else {
3200 ast_debug(1, "Abandoning event request!\n");
3201 }
3202
3203 return 0;
3204}
#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:1563
static int should_send_event(struct ao2_container *includefilters, struct ao2_container *excludefilters, struct eventqent *eqe)
Definition: manager.c:5560
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:154
ast_mutex_t notify_lock
Definition: manager.c:311
pthread_t waiting_thread
Definition: manager.c:287
struct ast_iostream * stream
Definition: manager.c:284
struct eventqent * last_ev
Definition: manager.c:303
time_t sessiontimeout
Definition: manager.c:291
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 1563 of file manager.c.

1564{
1565 struct eventqent *next;
1566
1568 if ((next = AST_RWLIST_NEXT(e, eq_next))) {
1571 }
1573 return next;
1574}
int usecount
Definition: manager.c:153

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

4387{
4388 const char *unitamount;
4389 const char *unittype;
4390 struct ast_str *str = ast_str_alloca(32);
4391
4392 memset(entry, 0, sizeof(*entry));
4393
4394 ast_str_set(&str, 0, "UnitAmount(%u)", entry_num);
4395 unitamount = astman_get_header(m, ast_str_buffer(str));
4396
4397 ast_str_set(&str, 0, "UnitType(%u)", entry_num);
4398 unittype = astman_get_header(m, ast_str_buffer(str));
4399
4400 if (!ast_strlen_zero(unitamount) && (sscanf(unitamount, "%30u", &entry->amount) == 1)) {
4401 entry->valid_amount = 1;
4402 }
4403
4404 if (!ast_strlen_zero(unittype) && sscanf(unittype, "%30u", &entry->type) == 1) {
4405 entry->valid_type = 1;
4406 }
4407
4408 return 0;
4409}
const char * str
Definition: app_jack.c:147

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

Referenced by action_aoc_de_message().

◆ app_match()

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

Definition at line 4924 of file manager.c.

4925{
4926 /*
4927 * We use strcasestr so we don't have to trim any blanks
4928 * from the front or back of the string.
4929 */
4930 return !!(strcasestr(app, search));
4931}
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 4943 of file manager.c.

4944{
4945 if (ast_strlen_zero(data)) {
4946 return 0;
4947 }
4948 return !!(strstr(data, search));
4949}

References ast_strlen_zero().

◆ append_channel_vars()

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

Definition at line 7431 of file manager.c.

7432{
7433 struct varshead *vars;
7434 struct ast_var_t *var;
7435
7436 vars = ast_channel_get_manager_vars(chan);
7437 if (!vars) {
7438 return;
7439 }
7440
7441 AST_LIST_TRAVERSE(vars, var, entries) {
7442 ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", ast_channel_name(chan), var->name, var->value);
7443 }
7444 ao2_ref(vars, -1);
7445}
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:8005
const char * ast_channel_name(const struct ast_channel *chan)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
struct ast_var_t::@211 entries

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

Referenced by __manager_event_sessions_va().

◆ append_event()

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

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

Definition at line 7406 of file manager.c.

7407{
7408 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
7409 static int seq; /* sequence number */
7410
7411 if (!tmp) {
7412 return -1;
7413 }
7414
7415 /* need to init all fields, because ast_malloc() does not */
7416 tmp->usecount = 0;
7417 tmp->category = category;
7418 tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
7419 tmp->tv = ast_tvnow();
7420 tmp->event_name_hash = event_name_hash;
7421 AST_RWLIST_NEXT(tmp, eq_next) = NULL;
7422 strcpy(tmp->eventdata, str);
7423
7427
7428 return 0;
7429}
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741
int event_name_hash
Definition: manager.c:157

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

Referenced by __init_manager(), and __manager_event_sessions_va().

◆ ast_hook_send_action()

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

access for hooks to send action messages to ami

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

Definition at line 1747 of file manager.c.

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

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

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

684{
685 return manager_enabled;
686}
static int manager_enabled
Definition: manager.c:169

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

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

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

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

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

3345{
3346 struct ast_channel *c = NULL;
3347 int causecode = 0; /* all values <= 0 mean 'do not set hangupcause in channel' */
3348 const char *id = astman_get_header(m, "ActionID");
3349 const char *name_or_regex = astman_get_header(m, "Channel");
3350 const char *cause = astman_get_header(m, "Cause");
3351 char idText[256];
3352 regex_t regexbuf;
3353 struct ast_channel_iterator *iter = NULL;
3354 struct ast_str *regex_string;
3355 int channels_matched = 0;
3356
3357 if (ast_strlen_zero(name_or_regex)) {
3358 astman_send_error(s, m, "No channel specified");
3359 return 0;
3360 }
3361
3362 if (!ast_strlen_zero(id)) {
3363 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
3364 } else {
3365 idText[0] = '\0';
3366 }
3367
3368 if (cause_validator) {
3369 causecode = cause_validator(name_or_regex, cause);
3370 } else if (!ast_strlen_zero(cause)) {
3371 char *endptr;
3372 causecode = strtol(cause, &endptr, 10);
3373 if (causecode < 0 || causecode > 127 || *endptr != '\0') {
3374 ast_log(LOG_NOTICE, "Invalid 'Cause: %s' in manager action Hangup\n", cause);
3375 /* keep going, better to hangup without cause than to not hang up at all */
3376 causecode = 0; /* do not set channel's hangupcause */
3377 }
3378 }
3379
3380 /************************************************/
3381 /* Regular explicit match channel byname hangup */
3382
3383 if (name_or_regex[0] != '/') {
3384 if (!(c = ast_channel_get_by_name(name_or_regex))) {
3385 ast_log(LOG_NOTICE, "Request to hangup non-existent channel: %s\n",
3386 name_or_regex);
3387 astman_send_error(s, m, "No such channel");
3388 return 0;
3389 }
3390
3391 ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
3392 (s->session->managerid ? "HTTP " : ""),
3393 s->session->username,
3396
3397 hangup_handler(c, causecode);
3399
3400 astman_send_ack(s, m, "Channel Hungup");
3401
3402 return 0;
3403 }
3404
3405 /***********************************************/
3406 /* find and hangup any channels matching regex */
3407
3408 regex_string = ast_str_create(strlen(name_or_regex));
3409 if (!regex_string) {
3410 astman_send_error(s, m, "Memory Allocation Failure");
3411 return 0;
3412 }
3413
3414 /* Make "/regex/" into "regex" */
3415 if (ast_regex_string_to_regex_pattern(name_or_regex, &regex_string) != 0) {
3416 astman_send_error(s, m, "Regex format invalid, Channel param should be /regex/");
3417 ast_free(regex_string);
3418 return 0;
3419 }
3420
3421 /* if regex compilation fails, hangup fails */
3422 if (regcomp(&regexbuf, ast_str_buffer(regex_string), REG_EXTENDED | REG_NOSUB)) {
3423 astman_send_error_va(s, m, "Regex compile failed on: %s", name_or_regex);
3424 ast_free(regex_string);
3425 return 0;
3426 }
3427
3428 astman_send_listack(s, m, "Channels hung up will follow", "start");
3429
3431 if (iter) {
3432 for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
3433 if (regexec(&regexbuf, ast_channel_name(c), 0, NULL, 0)) {
3434 continue;
3435 }
3436
3437 ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
3438 (s->session->managerid ? "HTTP " : ""),
3439 s->session->username,
3442
3443 hangup_handler(c, causecode);
3444 channels_matched++;
3445
3446 astman_append(s,
3447 "Event: ChannelHungup\r\n"
3448 "Channel: %s\r\n"
3449 "%s"
3450 "\r\n", ast_channel_name(c), idText);
3451 }
3453 }
3454
3455 regfree(&regexbuf);
3456 ast_free(regex_string);
3457
3458 astman_send_list_complete(s, m, "ChannelsHungupListComplete", channels_matched);
3459
3460 return 0;
3461}
#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 637 of file manager.c.

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

7735{
7736 struct manager_action *cur;
7737
7738 cur = ao2_t_alloc(sizeof(*cur), action_destroy, action);
7739 if (!cur) {
7740 return -1;
7741 }
7742 if (ast_string_field_init(cur, 128)) {
7743 ao2_t_ref(cur, -1, "action object creation failed");
7744 return -1;
7745 }
7746
7747 cur->action = action;
7748 cur->authority = auth;
7749 cur->func = func;
7750 cur->module = module;
7751#ifdef AST_XML_DOCS
7753 char *tmpxml;
7754
7755 tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL);
7756 ast_string_field_set(cur, synopsis, tmpxml);
7757 ast_free(tmpxml);
7758
7759 tmpxml = ast_xmldoc_build_syntax("manager", action, NULL);
7760 ast_string_field_set(cur, syntax, tmpxml);
7761 ast_free(tmpxml);
7762
7763 tmpxml = ast_xmldoc_build_description("manager", action, NULL);
7764 ast_string_field_set(cur, description, tmpxml);
7765 ast_free(tmpxml);
7766
7767 tmpxml = ast_xmldoc_build_seealso("manager", action, NULL);
7768 ast_string_field_set(cur, seealso, tmpxml);
7769 ast_free(tmpxml);
7770
7771 tmpxml = ast_xmldoc_build_arguments("manager", action, NULL);
7772 ast_string_field_set(cur, arguments, tmpxml);
7773 ast_free(tmpxml);
7774
7777
7778 cur->docsrc = AST_XML_DOC;
7779 } else
7780#endif
7781 {
7784#ifdef AST_XML_DOCS
7785 cur->docsrc = AST_STATIC_DOC;
7786#endif
7787 }
7788 if (ast_manager_register_struct(cur)) {
7789 ao2_t_ref(cur, -1, "action object registration failed");
7790 return -1;
7791 }
7792
7793 ao2_t_ref(cur, -1, "action object registration successful");
7794 return 0;
7795}
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition: astobj2.h:407
static char * synopsis
Definition: func_enum.c:154
static int ast_manager_register_struct(struct manager_action *act)
Definition: manager.c:7679
static void action_destroy(void *obj)
Definition: manager.c:7720
const ast_string_field description
Definition: manager.h:163
enum ast_doc_src docsrc
Definition: manager.h:174
const ast_string_field seealso
Definition: manager.h:163
const ast_string_field syntax
Definition: manager.h:163
const ast_string_field arguments
Definition: manager.h:163
struct ast_xml_doc_item * ast_xmldoc_build_list_responses(const char *type, const char *name, const char *module)
Generate the [list responses] tag based on type of node ('application', 'function' or 'agi') and name...
Definition: xmldoc.c:2484
char * ast_xmldoc_build_description(const char *type, const char *name, const char *module)
Generate description documentation from XML.
Definition: xmldoc.c:2271
char * ast_xmldoc_build_syntax(const char *type, const char *name, const char *module)
Get the syntax for a specified application or function.
Definition: xmldoc.c:1252
char * ast_xmldoc_build_arguments(const char *type, const char *name, const char *module)
Generate the [arguments] tag based on type of node ('application', 'function' or 'agi') and name.
Definition: xmldoc.c:2084
char * ast_xmldoc_build_synopsis(const char *type, const char *name, const char *module)
Generate synopsis documentation from XML.
Definition: xmldoc.c:2248
@ AST_XML_DOC
Definition: xmldoc.h:31
@ AST_STATIC_DOC
Definition: xmldoc.h:32
char * ast_xmldoc_build_seealso(const char *type, const char *name, const char *module)
Parse the <see-also> node content.
Definition: xmldoc.c:1702
struct ast_xml_doc_item * ast_xmldoc_build_final_response(const char *type, const char *name, const char *module)
Generate the [final response] tag based on type of node ('application', 'function' or 'agi') and name...
Definition: xmldoc.c:2554

References manager_action::action, action_destroy(), ao2_t_alloc, ao2_t_ref, ast_free, ast_manager_register_struct(), AST_STATIC_DOC, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), AST_XML_DOC, ast_xmldoc_build_arguments(), ast_xmldoc_build_description(), ast_xmldoc_build_final_response(), ast_xmldoc_build_list_responses(), ast_xmldoc_build_seealso(), ast_xmldoc_build_synopsis(), ast_xmldoc_build_syntax(), manager_action::authority, manager_action::docsrc, manager_action::final_response, manager_action::func, manager_action::list_responses, manager_action::module, NULL, and synopsis.

◆ ast_manager_register_hook()

void ast_manager_register_hook ( struct manager_custom_hook hook)

Add a custom hook to be called when an event is fired.

Add a custom hook to be called when an event is fired

Parameters
hookstruct manager_custom_hook object to add

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

7680{
7681 struct manager_action *cur, *prev = NULL;
7682
7684 AST_RWLIST_TRAVERSE(&actions, cur, list) {
7685 int ret;
7686
7687 ret = strcasecmp(cur->action, act->action);
7688 if (ret == 0) {
7689 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
7691 return -1;
7692 }
7693 if (ret > 0) { /* Insert these alphabetically */
7694 break;
7695 }
7696 prev = cur;
7697 }
7698
7699 ao2_t_ref(act, +1, "action object added to list");
7700 act->registered = 1;
7701 if (prev) {
7702 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list);
7703 } else {
7704 AST_RWLIST_INSERT_HEAD(&actions, act, list);
7705 }
7706
7707 ast_verb(5, "Manager registered action %s\n", act->action);
7708
7710
7711 return 0;
7712}
#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 554 of file manager.c.

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

7609{
7610 struct manager_action *cur;
7611
7614 if (!strcasecmp(action, cur->action)) {
7616 break;
7617 }
7618 }
7621
7622 if (cur) {
7623 /*
7624 * We have removed the action object from the container so we
7625 * are no longer in a hurry.
7626 */
7627 ao2_lock(cur);
7628 cur->registered = 0;
7629 ao2_unlock(cur);
7630
7631 ao2_t_ref(cur, -1, "action object removed from list");
7632 ast_verb(5, "Manager unregistered action %s\n", action);
7633 }
7634
7635 return 0;
7636}
#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 676 of file manager.c.

677{
679 AST_RWLIST_REMOVE(&manager_hooks, hook, list);
681}
#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 688 of file manager.c.

689{
691}
static int webmanager_enabled
Definition: manager.c:171

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

1891{
1892 int res;
1893 va_list ap;
1894 struct ast_str *buf;
1895
1897 return;
1898 }
1899
1900 va_start(ap, fmt);
1901 res = ast_str_set_va(&buf, 0, fmt, ap);
1902 va_end(ap);
1903 if (res == AST_DYNSTR_BUILD_FAILED) {
1904 return;
1905 }
1906
1907 if (s->hook || (s->tcptls_session != NULL && s->tcptls_session->stream != NULL)) {
1909 } else {
1910 ast_verbose("No connection stream in astman_append, should not happen\n");
1911 }
1912}
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:1876
static struct ast_threadstorage astman_append_buf
Definition: manager.c:1871
static int send_string(struct mansession *s, char *string)
Definition: manager.c:1835
@ AST_DYNSTR_BUILD_FAILED
Definition: strings.h:943
int ast_str_set_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Set a dynamic string from a va_list.
Definition: strings.h:1030
struct ast_iostream * stream
Definition: tcptls.h:161
struct ast_tcptls_session_instance * tcptls_session
Definition: manager.c:329

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

1641{
1642 const struct ast_variable *v;
1643
1644 for (v = params; v && m->hdrcount < ARRAY_LEN(m->headers); v = v->next) {
1645 if (ast_asprintf((char**)&m->headers[m->hdrcount], "%s: %s", v->name, v->value) > -1) {
1646 ++m->hdrcount;
1647 }
1648 }
1649}

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

2614{
2615 char *buf;
2616
2617 buf = ast_alloca(2 * strlen(str) + 1);
2619 astman_append(s, "%s", buf);
2620}
#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:2595

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

1879{
1880 if (s->hook || (s->tcptls_session && s->tcptls_session->stream)) {
1882 } else {
1883 ast_verbose("No connection stream in astman_append, should not happen\n");
1884 }
1885}

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

1655{
1656 while (m->hdrcount) {
1657 --m->hdrcount;
1658 ast_free((void *) m->headers[m->hdrcount]);
1659 m->headers[m->hdrcount] = NULL;
1660 }
1661}

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

1631{
1633}
#define GET_HEADER_FIRST_MATCH
Definition: manager.c:1576

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

1717{
1719}
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:1721
@ ORDER_REVERSE
Definition: manager.h:289

References astman_get_variables_order(), and ORDER_REVERSE.

Referenced by action_originate().

◆ astman_get_variables_order()

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

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

Definition at line 1721 of file manager.c.

1723{
1724 int varlen;
1725 int x;
1726 struct ast_variable *head = NULL;
1727
1728 static const char var_hdr[] = "Variable:";
1729
1730 /* Process all "Variable:" headers. */
1731 varlen = strlen(var_hdr);
1732 for (x = 0; x < m->hdrcount; x++) {
1733 if (strncasecmp(var_hdr, m->headers[x], varlen)) {
1734 continue;
1735 }
1736 head = man_do_variable_value(head, m->headers[x] + varlen);
1737 }
1738
1739 if (order == ORDER_NATURAL) {
1740 head = ast_variables_reverse(head);
1741 }
1742
1743 return head;
1744}
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:1672
struct ast_variable * ast_variables_reverse(struct ast_variable *var)
Reverse a variable list.
Definition: main/config.c:566
@ ORDER_NATURAL
Definition: manager.h:288

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

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

◆ astman_live_dangerously()

void astman_live_dangerously ( int  new_live_dangerously)

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

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

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

Definition at line 2430 of file manager.c.

2431{
2432 if (new_live_dangerously && !live_dangerously)
2433 {
2434 ast_log(LOG_WARNING, "Manager Configuration load protection disabled.\n");
2435 }
2436
2437 if (!new_live_dangerously && live_dangerously)
2438 {
2439 ast_log(LOG_NOTICE, "Manager Configuration load protection enabled.\n");
2440 }
2441 live_dangerously = new_live_dangerously;
2442}
static int live_dangerously
Set to true (non-zero) to globally allow all dangerous AMI actions to run.
Definition: manager.c:199

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

2002{
2003 astman_send_response_full(s, m, "Success", msg, NULL);
2004}

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

1970{
1971 astman_send_response_full(s, m, "Error", error, NULL);
1972}
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 1974 of file manager.c.

1975{
1976 int res;
1977 va_list ap;
1978 struct ast_str *buf;
1979 char *msg;
1980
1982 return;
1983 }
1984
1985 va_start(ap, fmt);
1986 res = ast_str_set_va(&buf, 0, fmt, ap);
1987 va_end(ap);
1988 if (res == AST_DYNSTR_BUILD_FAILED) {
1989 return;
1990 }
1991
1992 /* astman_append will use the same underlying buffer, so copy the message out
1993 * before sending the response */
1994 msg = ast_str_buffer(buf);
1995 if (msg) {
1996 msg = ast_strdupa(msg);
1997 }
1998 astman_send_response_full(s, m, "Error", msg, NULL);
1999}

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

2039{
2040 struct ast_str *buf = astman_send_list_complete_start_common(s, m, event_name, count);
2041 if (buf) {
2042 ast_str_append(&buf, 0, "\r\n");
2043 astman_flush(s, buf);
2044 }
2045}
static void astman_flush(struct mansession *s, struct ast_str *buf)
Definition: manager.c:1878
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:2016

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

2056{
2057 astman_append(s, "\r\n");
2058}

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

2048{
2049 struct ast_str *buf = astman_send_list_complete_start_common(s, m, event_name, count);
2050 if (buf) {
2051 astman_flush(s, buf);
2052 }
2053}

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

2017{
2018 const char *id = astman_get_header(m, "ActionID");
2019 struct ast_str *buf;
2020
2022 if (!buf) {
2023 return NULL;
2024 }
2025
2026 ast_str_set(&buf, 0, "Event: %s\r\n", event_name);
2027 if (!ast_strlen_zero(id)) {
2028 ast_str_append(&buf, 0, "ActionID: %s\r\n", id);
2029 }
2030 ast_str_append(&buf, 0,
2031 "EventList: Complete\r\n"
2032 "ListItems: %d\r\n",
2033 count);
2034
2035 return buf;
2036}

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

2012{
2013 astman_send_response_full(s, m, "Success", msg, listflag);
2014}

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

1965{
1966 astman_send_response_full(s, m, resp, msg, NULL);
1967}

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

1934{
1935 const char *id = astman_get_header(m, "ActionID");
1936 struct ast_str *buf;
1937
1939 if (!buf) {
1940 return;
1941 }
1942
1943 ast_str_set(&buf, 0, "Response: %s\r\n", resp);
1944
1945 if (!ast_strlen_zero(id)) {
1946 ast_str_append(&buf, 0, "ActionID: %s\r\n", id);
1947 }
1948
1949 if (listflag) {
1950 /* Start, complete, cancelled */
1951 ast_str_append(&buf, 0, "EventList: %s\r\n", listflag);
1952 }
1953
1954 if (msg != MSG_MOREDATA) {
1955 if (msg) {
1956 ast_str_append(&buf, 0, "Message: %s\r\n", msg);
1957 }
1958 ast_str_append(&buf, 0, "\r\n");
1959 }
1960
1961 astman_flush(s, buf);
1962}

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

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

◆ astman_start_ack()

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

◆ authenticate()

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

Definition at line 2315 of file manager.c.

2316{
2317 const char *username = astman_get_header(m, "Username");
2318 const char *password = astman_get_header(m, "Secret");
2319 int error = -1;
2320 struct ast_manager_user *user = NULL;
2321 regex_t *regex_filter;
2322 struct ao2_iterator filter_iter;
2323
2324 if (ast_strlen_zero(username)) { /* missing username */
2325 return -1;
2326 }
2327
2328 /* locate user in locked state */
2330
2331 if (!(user = get_manager_by_name_locked(username))) {
2332 report_invalid_user(s, username);
2333 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
2334 } else if (user->acl && (ast_apply_acl(user->acl, &s->session->addr, "Manager User ACL: ") == AST_SENSE_DENY)) {
2335 report_failed_acl(s, username);
2336 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
2337 } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
2338 const char *key = astman_get_header(m, "Key");
2339 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
2340 int x;
2341 int len = 0;
2342 char md5key[256] = "";
2343 struct MD5Context md5;
2344 unsigned char digest[16];
2345
2346 MD5Init(&md5);
2347 MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
2348 MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
2349 MD5Final(digest, &md5);
2350 for (x = 0; x < 16; x++)
2351 len += sprintf(md5key + len, "%02hhx", digest[x]);
2352 if (!strcmp(md5key, key)) {
2353 error = 0;
2354 } else {
2355 report_failed_challenge_response(s, key, md5key);
2356 }
2357 } else {
2358 ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n",
2359 S_OR(s->session->challenge, ""));
2360 }
2361 } else if (user->secret) {
2362 if (!strcmp(password, user->secret)) {
2363 error = 0;
2364 } else {
2365 report_inval_password(s, username);
2366 }
2367 }
2368
2369 if (error) {
2370 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
2372 return -1;
2373 }
2374
2375 /* auth complete */
2376
2377 /* All of the user parameters are copied to the session so that in the event
2378 * of a reload and a configuration change, the session parameters are not
2379 * changed. */
2380 ast_copy_string(s->session->username, username, sizeof(s->session->username));
2381 s->session->readperm = user->readperm;
2382 s->session->writeperm = user->writeperm;
2383 s->session->writetimeout = user->writetimeout;
2384 if (user->chanvars) {
2385 s->session->chanvars = ast_variables_dup(user->chanvars);
2386 }
2387
2388 filter_iter = ao2_iterator_init(user->includefilters, 0);
2389 while ((regex_filter = ao2_iterator_next(&filter_iter))) {
2390 ao2_t_link(s->session->includefilters, regex_filter, "add include user filter to session");
2391 ao2_t_ref(regex_filter, -1, "remove iterator ref");
2392 }
2393 ao2_iterator_destroy(&filter_iter);
2394
2395 filter_iter = ao2_iterator_init(user->excludefilters, 0);
2396 while ((regex_filter = ao2_iterator_next(&filter_iter))) {
2397 ao2_t_link(s->session->excludefilters, regex_filter, "add exclude user filter to session");
2398 ao2_t_ref(regex_filter, -1, "remove iterator ref");
2399 }
2400 ao2_iterator_destroy(&filter_iter);
2401
2402 s->session->sessionstart = time(NULL);
2404 set_eventmask(s, astman_get_header(m, "Events"));
2405
2407
2409 return 0;
2410}
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition: acl.c:799
@ AST_SENSE_DENY
Definition: acl.h:37
#define ao2_t_link(container, obj, tag)
Definition: astobj2.h:1534
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_md5.c:52
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:1045
static void report_invalid_user(const struct mansession *s, const char *username)
Definition: manager.c:2095
static void report_failed_acl(const struct mansession *s, const char *username)
Definition: manager.c:2120
static void report_failed_challenge_response(const struct mansession *s, const char *response, const char *expected_response)
Definition: manager.c:2253
static void report_inval_password(const struct mansession *s, const char *username)
Definition: manager.c:2145
static void report_auth_success(const struct mansession *s)
Definition: manager.c:2170
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
Definition: md5.c:72
void MD5Init(struct MD5Context *context)
Definition: md5.c:57
void MD5Final(unsigned char digest[16], struct MD5Context *context)
Definition: md5.c:120
Definition: md5.h:26
user descriptor, as read from the config file.
Definition: manager.c:345
struct timeval sessionstart_tv
Definition: manager.c:290
time_t sessionstart
Definition: manager.c:289
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 818 of file manager.c.

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

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

970{
971 struct ao2_container *sessions;
972 struct mansession_session *newsession;
973
974 newsession = ao2_alloc(sizeof(*newsession), session_destructor);
975 if (!newsession) {
976 return NULL;
977 }
978
981 if (!newsession->includefilters || !newsession->excludefilters) {
982 ao2_ref(newsession, -1);
983 return NULL;
984 }
985
986 newsession->waiting_thread = AST_PTHREADT_NULL;
987 newsession->writetimeout = 100;
988 newsession->send_events = -1;
989 ast_sockaddr_copy(&newsession->addr, addr);
990
991 ast_mutex_init(&newsession->notify_lock);
992
993 sessions = ao2_global_obj_ref(mgr_sessions);
994 if (sessions) {
995 ao2_link(sessions, newsession);
996 ao2_ref(sessions, -1);
997 }
998
999 return newsession;
1000}
#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:938
#define ast_mutex_init(pmutex)
Definition: lock.h:186
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167

References mansession_session::addr, ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_list, ao2_global_obj_ref, ao2_link, ao2_ref, ast_mutex_init, AST_PTHREADT_NULL, ast_sockaddr_copy(), mansession_session::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 4154 of file manager.c.

4155{
4156 char *cmd_copy, *cur_cmd;
4157 char *cmd_words[AST_MAX_CMD_LEN] = { NULL, };
4158 int i;
4159
4160 cmd_copy = ast_strdupa(cmd);
4161 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) {
4162 cur_cmd = ast_strip(cur_cmd);
4163 if (ast_strlen_zero(cur_cmd)) {
4164 i--;
4165 continue;
4166 }
4167
4168 cmd_words[i] = cur_cmd;
4169 }
4170
4171 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) {
4172 int j, match = 1;
4173
4174 for (j = 0; command_blacklist[i].words[j]; j++) {
4175 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) {
4176 match = 0;
4177 break;
4178 }
4179 }
4180
4181 if (match) {
4182 return 1;
4183 }
4184 }
4185
4186 return 0;
4187}
#define AST_MAX_CMD_LEN
Definition: cli.h:48
static const struct @371 command_blacklist[]
#define MAX_BLACKLIST_CMD_LEN
Descriptor for a manager session, either on the AMI socket or over HTTP.
Definition: manager.c:223
const char * words[AST_MAX_CMD_LEN]
Definition: manager.c:225
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223

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

Referenced by action_command().

◆ check_manager_session_inuse()

static int check_manager_session_inuse ( const char *  name)
static

Definition at line 1022 of file manager.c.

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

6578{
6579 int res = 0;
6580 struct ao2_iterator iter;
6581 char *current_channel_uid;
6582
6583 iter = ao2_iterator_init(bridge_snapshot->channels, 0);
6584 while ((current_channel_uid = ao2_iterator_next(&iter))) {
6585 struct ast_channel_snapshot *current_channel_snapshot;
6586 int add_channel_res;
6587
6588 /* Don't add the original channel to the list - it's either already in there,
6589 * or it's the channel we want the map for */
6590 if (!strcmp(current_channel_uid, channel_snapshot->base->uniqueid)) {
6591 ao2_ref(current_channel_uid, -1);
6592 continue;
6593 }
6594
6595 current_channel_snapshot = ast_channel_snapshot_get_latest(current_channel_uid);
6596 if (!current_channel_snapshot) {
6597 ast_debug(5, "Unable to get channel snapshot\n");
6598 ao2_ref(current_channel_uid, -1);
6599 continue;
6600 }
6601
6602 add_channel_res = coreshowchannelmap_add_to_map(channel_map, current_channel_snapshot->base->name);
6603 if (add_channel_res) {
6604 res = 1;
6605 ao2_ref(current_channel_snapshot, -1);
6606 ao2_ref(current_channel_uid, -1);
6607 break;
6608 }
6609
6610 /* 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 */
6611 if (ast_begins_with(current_channel_snapshot->base->name, "Local")) {
6612 struct ast_channel_snapshot *other_local_snapshot;
6613 struct ast_bridge_snapshot *other_bridge_snapshot;
6614 int size = strlen(current_channel_snapshot->base->name);
6615 char other_local[size + 1];
6616
6617 /* Don't copy the trailing number - set it to 1 or 2, whichever one it currently is not */
6618 ast_copy_string(other_local, current_channel_snapshot->base->name, size);
6619 other_local[size - 1] = ast_ends_with(current_channel_snapshot->base->name, "1") ? '2' : '1';
6620 other_local[size] = '\0';
6621
6622 other_local_snapshot = ast_channel_snapshot_get_latest_by_name(other_local);
6623 if (!other_local_snapshot) {
6624 ast_debug(5, "Unable to get other local channel snapshot\n");
6625 ao2_ref(current_channel_snapshot, -1);
6626 ao2_ref(current_channel_uid, -1);
6627 continue;
6628 }
6629
6630 if (coreshowchannelmap_add_to_map(channel_map, other_local_snapshot->base->name)) {
6631 res = 1;
6632 ao2_ref(current_channel_snapshot, -1);
6633 ao2_ref(current_channel_uid, -1);
6634 ao2_ref(other_local_snapshot, -1);
6635 break;
6636 }
6637
6638 other_bridge_snapshot = ast_bridge_get_snapshot_by_uniqueid(other_local_snapshot->bridge->id);
6639 if (other_bridge_snapshot) {
6640 res = coreshowchannelmap_add_connected_channels(channel_map, other_local_snapshot, other_bridge_snapshot);
6641 }
6642
6643 ao2_ref(current_channel_snapshot, -1);
6644 ao2_ref(current_channel_uid, -1);
6645 ao2_ref(other_local_snapshot, -1);
6646 ao2_ref(other_bridge_snapshot, -1);
6647
6648 if (res) {
6649 break;
6650 }
6651 }
6652 }
6653 ao2_iterator_destroy(&iter);
6654
6655 return res;
6656}
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:6559
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
static int force_inline attribute_pure ast_ends_with(const char *str, const char *suffix)
Checks whether a string ends with another.
Definition: strings.h:116
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition: strings.h:97
struct ao2_container * channels
Definition: bridge.h:331
const ast_string_field uniqueid
const ast_string_field name

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

Referenced by action_coreshowchannelmap(), and coreshowchannelmap_add_connected_channels().

◆ coreshowchannelmap_add_to_map()

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

Helper function to add a channel name to the vector.

Definition at line 6559 of file manager.c.

6560{
6561 char *str;
6562
6563 str = ast_strdup(s);
6564 if (!str) {
6565 ast_log(LOG_ERROR, "Unable to append channel to channel map\n");
6566 return 1;
6567 }
6568
6569 /* If this is a duplicate, it will be ignored */
6571
6572 return 0;
6573}
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 7187 of file manager.c.

7188{
7189 struct message m = { 0 };
7190 char header_buf[sizeof(s->session->inbuf)] = { '\0' };
7191 int res;
7192 int hdr_loss;
7193 time_t now;
7194
7195 hdr_loss = 0;
7196 for (;;) {
7197 /* Check if any events are pending and do them if needed */
7198 if (process_events(s)) {
7199 res = -1;
7200 break;
7201 }
7202 res = get_input(s, header_buf);
7203 if (res == 0) {
7204 /* No input line received. */
7205 if (!s->session->authenticated) {
7206 if (time(&now) == -1) {
7207 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
7208 res = -1;
7209 break;
7210 }
7211
7212 if (now - s->session->authstart > authtimeout) {
7213 if (displayconnects) {
7214 ast_verb(2, "Client from %s, failed to authenticate in %d seconds\n", ast_sockaddr_stringify_addr(&s->session->addr), authtimeout);
7215 }
7216 res = -1;
7217 break;
7218 }
7219 }
7220 continue;
7221 } else if (res > 0) {
7222 /* Input line received. */
7223 if (ast_strlen_zero(header_buf)) {
7224 if (hdr_loss) {
7225 mansession_lock(s);
7226 astman_send_error(s, &m, "Too many lines in message or allocation failure");
7228 res = 0;
7229 } else {
7230 switch (s->parsing) {
7231 case MESSAGE_OKAY:
7232 res = process_message(s, &m) ? -1 : 0;
7233 break;
7235 handle_parse_error(s, &m, "Failed to parse message: line too long");
7236 res = 0;
7237 break;
7238 }
7239 }
7240 break;
7241 } else if (m.hdrcount < ARRAY_LEN(m.headers)) {
7242 m.headers[m.hdrcount] = ast_strdup(header_buf);
7243 if (!m.headers[m.hdrcount]) {
7244 /* Allocation failure. */
7245 hdr_loss = 1;
7246 } else {
7247 ++m.hdrcount;
7248 }
7249 } else {
7250 /* Too many lines in message. */
7251 hdr_loss = 1;
7252 }
7253 } else {
7254 /* Input error. */
7255 break;
7256 }
7257 }
7258
7260
7261 return res;
7262}
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:6938
static void astman_free_headers(struct message *m)
Free headers inside message structure, but not the message structure itself.
Definition: manager.c:1654
static int displayconnects
Definition: manager.c:164
static int get_input(struct mansession *s, char *output)
Definition: manager.c:7066
static void handle_parse_error(struct mansession *s, struct message *m, char *error)
Definition: manager.c:7170
static int process_events(struct mansession *s)
Definition: manager.c:6325
static int authtimeout
Definition: manager.c:173
time_t authstart
Definition: manager.c:305
char inbuf[1025]
Definition: manager.c:297
enum mansession_message_parsing parsing
Definition: manager.c:330

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

927{
928 struct event_filter_entry *entry = obj;
929 if (entry->regex_filter) {
930 regfree(entry->regex_filter);
931 ast_free(entry->regex_filter);
932 }
933 ast_free(entry->event_name);
934 ast_free(entry->header_name);
935 ast_free(entry->string_filter);
936}
Definition: manager.c:406

References ast_free.

Referenced by manager_add_filter().

◆ fast_originate()

static void * fast_originate ( void *  data)
static

Definition at line 4306 of file manager.c.

4307{
4308 struct fast_originate_helper *in = data;
4309 int res;
4310 int reason = 0;
4311 struct ast_channel *chan = NULL, *chans[1];
4312 char requested_channel[AST_CHANNEL_NAME];
4313 struct ast_assigned_ids assignedids = {
4314 .uniqueid = in->channelid,
4315 .uniqueid2 = in->otherchannelid
4316 };
4317
4318 if (!ast_strlen_zero(in->app)) {
4319 res = ast_pbx_outgoing_app(in->tech, in->cap, in->data,
4320 in->timeout, in->app, in->appdata, &reason,
4322 S_OR(in->cid_num, NULL),
4323 S_OR(in->cid_name, NULL),
4324 in->vars, in->account, &chan, &assignedids);
4325 } else {
4326 res = ast_pbx_outgoing_exten(in->tech, in->cap, in->data,
4327 in->timeout, in->context, in->exten, in->priority, &reason,
4329 S_OR(in->cid_num, NULL),
4330 S_OR(in->cid_name, NULL),
4331 in->vars, in->account, &chan, in->early_media, &assignedids);
4332 }
4333
4334 if (!chan) {
4335 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);
4336 }
4337 /* Tell the manager what happened with the channel */
4338 chans[0] = chan;
4339 if (!ast_strlen_zero(in->app)) {
4340 ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
4341 "%s"
4342 "Response: %s\r\n"
4343 "Channel: %s\r\n"
4344 "Application: %s\r\n"
4345 "Data: %s\r\n"
4346 "Reason: %d\r\n"
4347 "Uniqueid: %s\r\n"
4348 "CallerIDNum: %s\r\n"
4349 "CallerIDName: %s\r\n",
4350 in->idtext, res ? "Failure" : "Success",
4351 chan ? ast_channel_name(chan) : requested_channel,
4352 in->app, in->appdata, reason,
4353 chan ? ast_channel_uniqueid(chan) : S_OR(in->channelid, "<unknown>"),
4354 S_OR(in->cid_num, "<unknown>"),
4355 S_OR(in->cid_name, "<unknown>")
4356 );
4357 } else {
4358 ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
4359 "%s"
4360 "Response: %s\r\n"
4361 "Channel: %s\r\n"
4362 "Context: %s\r\n"
4363 "Exten: %s\r\n"
4364 "Reason: %d\r\n"
4365 "Uniqueid: %s\r\n"
4366 "CallerIDNum: %s\r\n"
4367 "CallerIDName: %s\r\n",
4368 in->idtext, res ? "Failure" : "Success",
4369 chan ? ast_channel_name(chan) : requested_channel,
4370 in->context, in->exten, reason,
4371 chan ? ast_channel_uniqueid(chan) : S_OR(in->channelid, "<unknown>"),
4372 S_OR(in->cid_num, "<unknown>"),
4373 S_OR(in->cid_name, "<unknown>")
4374 );
4375 }
4376
4377 /* Locked and ref'd by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
4378 if (chan) {
4379 ast_channel_unlock(chan);
4380 ast_channel_unref(chan);
4381 }
4383 return NULL;
4384}
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:260
#define EVENT_FLAG_CALL
Definition: manager.h:76
int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, int early_media, const struct ast_assigned_ids *assignedids)
Synchronously or asynchronously make an outbound call and send it to a particular extension.
Definition: pbx.c:7916
FILE * in
Definition: utils/frame.c:33

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

Referenced by action_originate().

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

6793{
6794 char *stripped_filename;
6795 RAII_VAR(char *, path, NULL, ast_free);
6796 RAII_VAR(char *, real_path, NULL, ast_free);
6797
6798 /* Don't bother checking */
6799 if (live_dangerously) {
6800 return 1;
6801 }
6802
6803 stripped_filename = ast_strip(ast_strdupa(filename));
6804
6805 /* Always prepend the modules dir since that is what the code does for ModuleLoad */
6806 if (ast_asprintf(&path, "%s/%s", ast_config_AST_MODULE_DIR, stripped_filename) == -1) {
6807 return -1;
6808 }
6809
6810 real_path = realpath(path, NULL);
6811 if (!real_path) {
6812 return -1;
6813 }
6814
6815 return ast_begins_with(real_path, ast_config_AST_MODULE_DIR);
6816}
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 5507 of file manager.c.

5508{
5509 struct eventqent *eqe = arg;
5510 struct event_filter_entry *filter_entry = obj;
5511 char *line_buffer_start = NULL;
5512 char *line_buffer = NULL;
5513 char *line = NULL;
5514 int match = 0;
5515 int *result = data;
5516
5517 if (filter_entry->event_name_hash) {
5518 if (eqe->event_name_hash != filter_entry->event_name_hash) {
5519 goto done;
5520 }
5521 }
5522
5523 /* We're looking at the entire event data */
5524 if (!filter_entry->header_name) {
5525 match = match_eventdata(filter_entry, eqe->eventdata);
5526 goto done;
5527 }
5528
5529 /* We're looking at a specific header */
5530 line_buffer_start = ast_strdup(eqe->eventdata);
5531 line_buffer = line_buffer_start;
5532 if (!line_buffer_start) {
5533 goto done;
5534 }
5535
5536 while ((line = ast_read_line_from_buffer(&line_buffer))) {
5537 if (ast_begins_with(line, filter_entry->header_name)) {
5538 line += strlen(filter_entry->header_name);
5539 line = ast_skip_blanks(line);
5540 if (ast_strlen_zero(line)) {
5541 continue;
5542 }
5543 match = match_eventdata(filter_entry, line);
5544 if (match) {
5545 ast_free(line_buffer_start);
5546 line_buffer_start = NULL;
5547 break;
5548 }
5549 }
5550 }
5551
5552 ast_free(line_buffer_start);
5553
5554done:
5555
5556 *result = match;
5557 return match ? CMP_MATCH | CMP_STOP : 0;
5558}
@ 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:5487
char * ast_read_line_from_buffer(char **buffer)
Read lines from a string buffer.
Definition: strings.c:371
unsigned int event_name_hash
Definition: manager.c:411
char * header_name
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 780 of file manager.c.

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

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

3555{
3556 struct timeval now;
3557 long elapsed_seconds;
3558 struct ast_bridge *bridge;
3559 RAII_VAR(struct ast_str *, variable_str, NULL, ast_free);
3560 struct ast_str *write_transpath = ast_str_alloca(256);
3561 struct ast_str *read_transpath = ast_str_alloca(256);
3562 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
3563 struct ast_party_id effective_id;
3564 int i;
3565 RAII_VAR(struct ast_channel_snapshot *, snapshot,
3567 ao2_cleanup);
3568 RAII_VAR(struct ast_str *, snapshot_str, NULL, ast_free);
3569
3570 if (!snapshot) {
3571 return;
3572 }
3573
3574 snapshot_str = ast_manager_build_channel_state_string(snapshot);
3575 if (!snapshot_str) {
3576 return;
3577 }
3578
3579 if (all_variables) {
3580 variable_str = ast_str_create(2048);
3581 } else {
3582 variable_str = ast_str_create(1024);
3583 }
3584 if (!variable_str) {
3585 return;
3586 }
3587
3588 now = ast_tvnow();
3589 elapsed_seconds = ast_tvdiff_sec(now, ast_channel_creationtime(chan));
3590
3591 /* Even if all_variables has been specified, explicitly requested variables
3592 * may be global variables or dialplan functions */
3593 for (i = 0; i < varc; i++) {
3594 char valbuf[512], *ret = NULL;
3595
3596 if (vars[i][strlen(vars[i]) - 1] == ')') {
3597 if (ast_func_read(chan, vars[i], valbuf, sizeof(valbuf)) < 0) {
3598 valbuf[0] = '\0';
3599 }
3600 ret = valbuf;
3601 } else {
3602 pbx_retrieve_variable(chan, vars[i], &ret, valbuf, sizeof(valbuf), NULL);
3603 }
3604
3605 ast_str_append(&variable_str, 0, "Variable: %s=%s\r\n", vars[i], ret);
3606 }
3607
3608 /* Walk all channel variables and add them */
3609 if (all_variables) {
3610 struct ast_var_t *variables;
3611
3613 ast_str_append(&variable_str, 0, "Variable: %s=%s\r\n",
3614 ast_var_name(variables), ast_var_value(variables));
3615 }
3616 }
3617
3618 bridge = ast_channel_get_bridge(chan);
3619 effective_id = ast_channel_connected_effective_id(chan);
3620
3621 astman_append(s,
3622 "Event: Status\r\n"
3623 "Privilege: Call\r\n"
3624 "%s"
3625 "Type: %s\r\n"
3626 "DNID: %s\r\n"
3627 "EffectiveConnectedLineNum: %s\r\n"
3628 "EffectiveConnectedLineName: %s\r\n"
3629 "TimeToHangup: %ld\r\n"
3630 "BridgeID: %s\r\n"
3631 "Application: %s\r\n"
3632 "Data: %s\r\n"
3633 "Nativeformats: %s\r\n"
3634 "Readformat: %s\r\n"
3635 "Readtrans: %s\r\n"
3636 "Writeformat: %s\r\n"
3637 "Writetrans: %s\r\n"
3638 "Callgroup: %llu\r\n"
3639 "Pickupgroup: %llu\r\n"
3640 "Seconds: %ld\r\n"
3641 "%s"
3642 "%s"
3643 "\r\n",
3644 ast_str_buffer(snapshot_str),
3645 ast_channel_tech(chan)->type,
3646 S_OR(ast_channel_dialed(chan)->number.str, ""),
3647 S_COR(effective_id.number.valid, effective_id.number.str, "<unknown>"),
3648 S_COR(effective_id.name.valid, effective_id.name.str, "<unknown>"),
3649 (long)ast_channel_whentohangup(chan)->tv_sec,
3650 bridge ? bridge->uniqueid : "",
3651 ast_channel_appl(chan),
3652 ast_channel_data(chan),
3655 ast_translate_path_to_str(ast_channel_readtrans(chan), &read_transpath),
3657 ast_translate_path_to_str(ast_channel_writetrans(chan), &write_transpath),
3660 (long)elapsed_seconds,
3661 ast_str_buffer(variable_str),
3662 id_text);
3663 ++*count;
3664
3665 ao2_cleanup(bridge);
3666}
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:10556
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:349
const ast_string_field uniqueid
Definition: bridge.h:401
Information needed to identify an endpoint in a call.
Definition: channel.h:340
Number structure.
Definition: app_followme.c:154
int64_t ast_tvdiff_sec(struct timeval end, struct timeval start)
Computes the difference (in seconds) between two struct timeval instances.
Definition: time.h:73
const char * ast_translate_path_to_str(struct ast_trans_pvt *t, struct ast_str **str)
Puts a string representation of the translation path into outbuf.
Definition: translate.c:930

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

Referenced by action_status().

◆ get_input()

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

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

Note
* \r\n is the only valid terminator for the line.
* (Note that, later, '\0' will be considered as the end-of-line marker,
* so everything between the '\0' and the '\r\n' will not be used).
* Also note that we assume output to have at least "maxlen" space.
* 

Definition at line 7066 of file manager.c.

7067{
7068 int res, x;
7069 int maxlen = sizeof(s->session->inbuf) - 1;
7070 char *src = s->session->inbuf;
7071 int timeout = -1;
7072 time_t now;
7073
7074 /*
7075 * Look for \r\n within the buffer. If found, copy to the output
7076 * buffer and return, trimming the \r\n (not used afterwards).
7077 */
7078 for (x = 0; x < s->session->inlen; x++) {
7079 int cr; /* set if we have \r */
7080 if (src[x] == '\r' && x+1 < s->session->inlen && src[x + 1] == '\n') {
7081 cr = 2; /* Found. Update length to include \r\n */
7082 } else if (src[x] == '\n') {
7083 cr = 1; /* also accept \n only */
7084 } else {
7085 continue;
7086 }
7087 memmove(output, src, x); /*... but trim \r\n */
7088 output[x] = '\0'; /* terminate the string */
7089 x += cr; /* number of bytes used */
7090 s->session->inlen -= x; /* remaining size */
7091 memmove(src, src + x, s->session->inlen); /* remove used bytes */
7092 return 1;
7093 }
7094 if (s->session->inlen >= maxlen) {
7095 /* no crlf found, and buffer full - sorry, too long for us
7096 * keep the last character in case we are in the middle of a CRLF. */
7097 ast_log(LOG_WARNING, "Discarding message from %s. Line too long: %.25s...\n", ast_sockaddr_stringify_addr(&s->session->addr), src);
7098 src[0] = src[s->session->inlen - 1];
7099 s->session->inlen = 1;
7101 }
7102 res = 0;
7103 while (res == 0) {
7104 /* calculate a timeout if we are not authenticated */
7105 if (!s->session->authenticated) {
7106 if(time(&now) == -1) {
7107 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
7108 return -1;
7109 }
7110
7111 timeout = (authtimeout - (now - s->session->authstart)) * 1000;
7112 if (timeout < 0) {
7113 /* we have timed out */
7114 return 0;
7115 }
7116 }
7117
7119 if (s->session->pending_event) {
7120 s->session->pending_event = 0;
7122 return 0;
7123 }
7124 s->session->waiting_thread = pthread_self();
7126
7128
7132 }
7133 if (res < 0) {
7134 if (s->session->kicked) {
7135 ast_debug(1, "Manager session has been kicked\n");
7136 return -1;
7137 }
7138 /* If we get a signal from some other thread (typically because
7139 * there are new events queued), return 0 to notify the caller.
7140 */
7141 if (errno == EINTR || errno == EAGAIN) {
7142 return 0;
7143 }
7144 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
7145 return -1;
7146 }
7147
7148 ao2_lock(s->session);
7149 res = ast_iostream_read(s->session->stream, src + s->session->inlen, maxlen - s->session->inlen);
7150 if (res < 1) {
7151 res = -1; /* error return */
7152 } else {
7153 s->session->inlen += res;
7154 src[s->session->inlen] = '\0';
7155 res = 0;
7156 }
7157 ao2_unlock(s->session);
7158 return res;
7159}
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:310

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

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

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

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

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

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

1545{
1546 switch (cmd) {
1547 case CLI_INIT:
1548 e->command = "manager reload";
1549 e->usage =
1550 "Usage: manager reload\n"
1551 " Reloads the manager configuration.\n";
1552 return NULL;
1553 case CLI_GENERATE:
1554 return NULL;
1555 }
1556 if (a->argc > 2) {
1557 return CLI_SHOWUSAGE;
1558 }
1559 reload_module();
1560 return CLI_SUCCESS;
1561}
static int reload_module(void)
Definition: manager.c:10062

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

1213{
1214 switch (cmd) {
1215 case CLI_INIT:
1216 e->command = "manager set debug [on|off]";
1217 e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n";
1218 return NULL;
1219 case CLI_GENERATE:
1220 return NULL;
1221 }
1222
1223 if (a->argc == 3) {
1224 ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off");
1225 } else if (a->argc == 4) {
1226 if (!strcasecmp(a->argv[3], "on")) {
1227 manager_debug = 1;
1228 } else if (!strcasecmp(a->argv[3], "off")) {
1229 manager_debug = 0;
1230 } else {
1231 return CLI_SHOWUSAGE;
1232 }
1233 }
1234 return CLI_SUCCESS;
1235}

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

7171{
7172 mansession_lock(s);
7173 astman_send_error(s, m, error);
7174 s->parsing = MESSAGE_OKAY;
7176}

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

1238{
1239 struct ast_manager_user *user = NULL;
1240 int l;
1241 struct ast_str *rauthority = ast_str_alloca(MAX_AUTH_PERM_STRING);
1242 struct ast_str *wauthority = ast_str_alloca(MAX_AUTH_PERM_STRING);
1243 struct ast_variable *v;
1244
1245 switch (cmd) {
1246 case CLI_INIT:
1247 e->command = "manager show user";
1248 e->usage =
1249 " Usage: manager show user <user>\n"
1250 " Display all information related to the manager user specified.\n";
1251 return NULL;
1252 case CLI_GENERATE:
1253 l = strlen(a->word);
1254 if (a->pos != 3) {
1255 return NULL;
1256 }
1258 AST_RWLIST_TRAVERSE(&users, user, list) {
1259 if (!strncasecmp(a->word, user->username, l)) {
1260 if (ast_cli_completion_add(ast_strdup(user->username))) {
1261 break;
1262 }
1263 }
1264 }
1266 return NULL;
1267 }
1268
1269 if (a->argc != 4) {
1270 return CLI_SHOWUSAGE;
1271 }
1272
1274
1275 if (!(user = get_manager_by_name_locked(a->argv[3]))) {
1276 ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]);
1278 return CLI_SUCCESS;
1279 }
1280
1281 ast_cli(a->fd, "\n");
1282 ast_cli(a->fd,
1283 " username: %s\n"
1284 " secret: %s\n"
1285 " ACL: %s\n"
1286 " read perm: %s\n"
1287 " write perm: %s\n"
1288 " displayconnects: %s\n"
1289 "allowmultiplelogin: %s\n",
1290 S_OR(user->username, "(N/A)"),
1291 (user->secret ? "<Set>" : "(N/A)"),
1292 ((user->acl && !ast_acl_list_is_empty(user->acl)) ? "yes" : "no"),
1293 user_authority_to_str(user->readperm, &rauthority),
1294 user_authority_to_str(user->writeperm, &wauthority),
1295 (user->displayconnects ? "yes" : "no"),
1296 (user->allowmultiplelogin ? "yes" : "no"));
1297 ast_cli(a->fd, " Variables: \n");
1298 for (v = user->chanvars ; v ; v = v->next) {
1299 ast_cli(a->fd, " %s = %s\n", v->name, v->value);
1300 }
1301 if (!ast_acl_list_is_empty(user->acl)) {
1302 ast_acl_output(a->fd, user->acl, NULL);
1303 }
1304
1306
1307 return CLI_SUCCESS;
1308}
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:794

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

1311{
1312 struct ast_manager_user *user = NULL;
1313 int count_amu = 0;
1314 switch (cmd) {
1315 case CLI_INIT:
1316 e->command = "manager show users";
1317 e->usage =
1318 "Usage: manager show users\n"
1319 " Prints a listing of all managers that are currently configured on that\n"
1320 " system.\n";
1321 return NULL;
1322 case CLI_GENERATE:
1323 return NULL;
1324 }
1325 if (a->argc != 3) {
1326 return CLI_SHOWUSAGE;
1327 }
1328
1330
1331 /* If there are no users, print out something along those lines */
1332 if (AST_RWLIST_EMPTY(&users)) {
1333 ast_cli(a->fd, "There are no manager users.\n");
1335 return CLI_SUCCESS;
1336 }
1337
1338 ast_cli(a->fd, "\nusername\n--------\n");
1339
1340 AST_RWLIST_TRAVERSE(&users, user, list) {
1341 ast_cli(a->fd, "%s\n", user->username);
1342 count_amu++;
1343 }
1344
1346
1347 ast_cli(a->fd,"-------------------\n"
1348 "%d manager users configured.\n", count_amu);
1349 return CLI_SUCCESS;
1350}

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

1081{
1082 struct manager_action *cur;
1083 struct ast_str *authority;
1084 int num;
1085 int l;
1086 const char *auth_str;
1087#ifdef AST_XML_DOCS
1088 char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64];
1089 char arguments_title[64], privilege_title[64], final_response_title[64], list_responses_title[64];
1090#endif
1091
1092 switch (cmd) {
1093 case CLI_INIT:
1094 e->command = "manager show command";
1095 e->usage =
1096 "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n"
1097 " Shows the detailed description for a specific Asterisk manager interface command.\n";
1098 return NULL;
1099 case CLI_GENERATE:
1100 l = strlen(a->word);
1102 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1103 if (!strncasecmp(a->word, cur->action, l)) {
1105 break;
1106 }
1107 }
1108 }
1110 return NULL;
1111 }
1112 if (a->argc < 4) {
1113 return CLI_SHOWUSAGE;
1114 }
1115
1117
1118#ifdef AST_XML_DOCS
1119 /* setup the titles */
1120 term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
1121 term_color(description_title, "[Description]\n", COLOR_MAGENTA, 0, 40);
1122 term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
1123 term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40);
1124 term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
1125 term_color(privilege_title, "[Privilege]\n", COLOR_MAGENTA, 0, 40);
1126 term_color(final_response_title, "[Final Response]\n", COLOR_MAGENTA, 0, 40);
1127 term_color(list_responses_title, "[List Responses]\n", COLOR_MAGENTA, 0, 40);
1128#endif
1129
1131 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1132 for (num = 3; num < a->argc; num++) {
1133 if (!strcasecmp(cur->action, a->argv[num])) {
1134 auth_str = authority_to_str(cur->authority, &authority);
1135
1136#ifdef AST_XML_DOCS
1137 if (cur->docsrc == AST_XML_DOC) {
1138 char *syntax = ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1);
1139 char *synopsis = ast_xmldoc_printable(S_OR(cur->synopsis, "Not available"), 1);
1140 char *description = ast_xmldoc_printable(S_OR(cur->description, "Not available"), 1);
1141 char *arguments = ast_xmldoc_printable(S_OR(cur->arguments, "Not available"), 1);
1142 char *seealso = ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1);
1143 char *privilege = ast_xmldoc_printable(S_OR(auth_str, "Not available"), 1);
1144 char *responses = ast_xmldoc_printable("None", 1);
1145
1146 if (!syntax || !synopsis || !description || !arguments
1147 || !seealso || !privilege || !responses) {
1148 ast_free(syntax);
1150 ast_free(description);
1151 ast_free(arguments);
1152 ast_free(seealso);
1153 ast_free(privilege);
1154 ast_free(responses);
1155 ast_cli(a->fd, "Allocation failure.\n");
1157
1158 return CLI_FAILURE;
1159 }
1160
1161 ast_cli(a->fd, "%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s",
1162 syntax_title, syntax,
1163 synopsis_title, synopsis,
1164 description_title, description,
1165 arguments_title, arguments,
1166 seealso_title, seealso,
1167 privilege_title, privilege,
1168 list_responses_title);
1169
1170 if (!cur->list_responses) {
1171 ast_cli(a->fd, "%s\n\n", responses);
1172 } else {
1173 struct ast_xml_doc_item *temp;
1174 for (temp = cur->list_responses; temp; temp = AST_LIST_NEXT(temp, next)) {
1175 ast_cli(a->fd, "Event: %s\n", temp->name);
1176 print_event_instance(a, temp);
1177 }
1178 }
1179
1180 ast_cli(a->fd, "%s", final_response_title);
1181
1182 if (!cur->final_response) {
1183 ast_cli(a->fd, "%s\n\n", responses);
1184 } else {
1185 ast_cli(a->fd, "Event: %s\n", cur->final_response->name);
1187 }
1188
1194 ast_free(privilege);
1195 ast_free(responses);
1196 } else
1197#endif
1198 {
1199 ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
1200 cur->action, cur->synopsis,
1201 auth_str,
1202 S_OR(cur->description, ""));
1203 }
1204 }
1205 }
1206 }
1208
1209 return CLI_SUCCESS;
1210}
static void print_event_instance(struct ast_cli_args *a, struct ast_xml_doc_item *instance)
Definition: manager.c:9165
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
Struct that contains the XML documentation for a particular item. Note that this is an ao2 ref counte...
Definition: xmldoc.h:56
struct ast_str * syntax
Definition: xmldoc.h:58
struct ast_xml_doc_item * next
Definition: xmldoc.h:80
struct ast_str * arguments
Definition: xmldoc.h:62
struct ast_str * description
Definition: xmldoc.h:66
const ast_string_field name
Definition: xmldoc.h:74
struct ast_str * seealso
Definition: xmldoc.h:60
#define COLOR_MAGENTA
Definition: term.h:60
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
Definition: term.c:235
char * ast_xmldoc_printable(const char *bwinput, int withcolors)
Colorize and put delimiters (instead of tags) to the xmldoc output.
Definition: xmldoc.c:241

References a, manager_action::action, manager_action::arguments, ast_xml_doc_item::arguments, ast_cli(), ast_cli_completion_add(), ast_free, AST_LIST_NEXT, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, AST_XML_DOC, ast_xmldoc_printable(), manager_action::authority, authority_to_str(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, COLOR_MAGENTA, ast_cli_entry::command, manager_action::description, ast_xml_doc_item::description, manager_action::docsrc, manager_action::final_response, manager_action::list_responses, MAX_AUTH_PERM_STRING, ast_xml_doc_item::name, ast_xml_doc_item::next, NULL, print_event_instance(), S_OR, manager_action::seealso, ast_xml_doc_item::seealso, synopsis, manager_action::synopsis, manager_action::syntax, ast_xml_doc_item::syntax, term_color(), and ast_cli_entry::usage.

◆ handle_showmancmds()

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

CLI command manager list commands.

Definition at line 1353 of file manager.c.

1354{
1355 struct manager_action *cur;
1356 int name_len = 1;
1357 int space_remaining;
1358#define HSMC_FORMAT " %-*.*s %-.*s\n"
1359 switch (cmd) {
1360 case CLI_INIT:
1361 e->command = "manager show commands";
1362 e->usage =
1363 "Usage: manager show commands\n"
1364 " Prints a listing of all the available Asterisk manager interface commands.\n";
1365 return NULL;
1366 case CLI_GENERATE:
1367 return NULL;
1368 }
1369
1371 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1372 int incoming_len = strlen(cur->action);
1373 if (incoming_len > name_len) {
1374 name_len = incoming_len;
1375 }
1376 }
1377
1378 space_remaining = MGR_SHOW_TERMINAL_WIDTH - name_len - 4;
1379 if (space_remaining < 0) {
1380 space_remaining = 0;
1381 }
1382
1383 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, "Action", space_remaining, "Synopsis");
1384 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, "------", space_remaining, "--------");
1385
1386 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1387 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, cur->action, space_remaining, cur->synopsis);
1388 }
1390
1391 return CLI_SUCCESS;
1392}
#define MGR_SHOW_TERMINAL_WIDTH
Definition: manager.c:206
#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 1465 of file manager.c.

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

1517{
1518 struct eventqent *s;
1519 switch (cmd) {
1520 case CLI_INIT:
1521 e->command = "manager show eventq";
1522 e->usage =
1523 "Usage: manager show eventq\n"
1524 " Prints a listing of all events pending in the Asterisk manger\n"
1525 "event queue.\n";
1526 return NULL;
1527 case CLI_GENERATE:
1528 return NULL;
1529 }
1531 AST_RWLIST_TRAVERSE(&all_events, s, eq_next) {
1532 ast_cli(a->fd, "Usecount: %d\n", s->usecount);
1533 ast_cli(a->fd, "Category: %d\n", s->category);
1534 ast_cli(a->fd, "Event:\n%s", s->eventdata);
1535 }
1537
1538 return CLI_SUCCESS;
1539}

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

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

5038{
5039 int i;
5040
5041 for (i = 0; originate_app_permissions[i].search; i++) {
5042 if (originate_app_permissions[i].searchfn(app, data, originate_app_permissions[i].search)) {
5044 }
5045 }
5046
5047 return 1;
5048}
static struct originate_permissions_entry originate_app_permissions[]
Definition: manager.c:5000
int permission
Definition: manager.c:4910
const char * search
Definition: manager.c:4909

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

Referenced by action_originate().

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

2596{
2597 for (; *in; in++) {
2598 if (*in == '\\' || *in == '\"') {
2599 *out++ = '\\';
2600 }
2601 *out++ = *in;
2602 }
2603 *out = '\0';
2604}
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 6899 of file manager.c.

6900{
6901 struct ast_str *buf;
6902 int x;
6903
6904 if (!manager_debug) {
6905 return;
6906 }
6907
6908 buf = ast_str_create(256);
6909 if (!buf) {
6910 return;
6911 }
6912
6913 for (x = 0; x < m->hdrcount; ++x) {
6914 if (!strncasecmp(m->headers[x], "Secret", 6)) {
6915 ast_str_append(&buf, 0, "Secret: <redacted from logging>\n");
6916 } else {
6917 ast_str_append(&buf, 0, "%s\n", m->headers[x]);
6918 }
6919 }
6920
6921 ast_verbose("<--- Examining AMI action: -->\n%s\n", ast_str_buffer(buf));
6922 ast_free(buf);
6923}

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

1673{
1674 char *parse;
1676 AST_APP_ARG(vars)[64];
1677 );
1678
1679 hdr_val = ast_skip_blanks(hdr_val); /* ignore leading spaces in the value */
1680 parse = ast_strdupa(hdr_val);
1681
1682 /* Break the header value string into name=val pair items. */
1684 if (args.argc) {
1685 int y;
1686
1687 /* Process each name=val pair item. */
1688 for (y = 0; y < args.argc; y++) {
1689 struct ast_variable *cur;
1690 char *var;
1691 char *val;
1692
1693 if (!args.vars[y]) {
1694 continue;
1695 }
1696 var = val = args.vars[y];
1697 strsep(&val, "=");
1698
1699 /* XXX We may wish to trim whitespace from the strings. */
1700 if (!val || ast_strlen_zero(var)) {
1701 continue;
1702 }
1703
1704 /* Create new variable list node and prepend it to the list. */
1705 cur = ast_variable_new(var, val, "");
1706 if (cur) {
1707 cur->next = head;
1708 head = cur;
1709 }
1710 }
1711 }
1712
1713 return head;
1714}
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 5664 of file manager.c.

5667{
5668 RAII_VAR(struct event_filter_entry *, filter_entry,
5669 ao2_t_alloc(sizeof(*filter_entry), event_filter_destructor, "event_filter allocation"),
5670 ao2_cleanup);
5671 char *options_start = NULL;
5672 SCOPE_ENTER(3, "manager_add_filter(%s, %s, %p, %p)", criteria, filter_pattern, includefilters, excludefilters);
5673
5674 if (!filter_entry) {
5675 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_ALLOC_FAILED, LOG_WARNING, "Unable to allocate filter_entry");
5676 }
5677
5678 /*
5679 * At a minimum, criteria must be "eventfilter" but may contain additional
5680 * constraints.
5681 */
5682 if (ast_strlen_zero(criteria)) {
5684 }
5685
5686 /*
5687 * filter_pattern could be empty but it should never be NULL.
5688 */
5689 if (!filter_pattern) {
5690 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "Filter pattern was NULL");
5691 }
5692
5693 /*
5694 * For a legacy filter, if the first character of filter_pattern is
5695 * '!' then it's an exclude filter. It's also accepted as an alternative
5696 * to specifying "action(exclude)" for an advanced filter. If
5697 * "action" is specified however, it will take precedence.
5698 */
5699 if (filter_pattern[0] == '!') {
5700 filter_entry->is_excludefilter = 1;
5701 filter_pattern++;
5702 }
5703
5704 /*
5705 * This is the default
5706 */
5707 filter_entry->match_type = FILTER_MATCH_REGEX;
5708
5709 /*
5710 * If the criteria has a '(' in it, then it's an advanced filter.
5711 */
5712 options_start = strstr(criteria, "(");
5713
5714 /*
5715 * If it's a legacy filter, there MUST be a filter pattern.
5716 */
5717 if (!options_start && ast_strlen_zero(filter_pattern)) {
5719 "'%s = %s': Legacy filter with no filter pattern specified\n",
5720 criteria, filter_pattern);
5721 }
5722
5723 if (options_start) {
5724 /*
5725 * This is an advanced filter
5726 */
5727 char *temp = ast_strdupa(options_start + 1); /* skip over the leading '(' */
5728 char *saveptr = NULL;
5729 char *option = NULL;
5730 enum found_options {
5731 action_found = (1 << 0),
5732 name_found = (1 << 1),
5733 header_found = (1 << 2),
5734 method_found = (1 << 3),
5735 };
5736 enum found_options options_found = 0;
5737
5738 filter_entry->match_type = FILTER_MATCH_NONE;
5739
5740 ast_strip(temp);
5741 if (ast_strlen_zero(temp) || !ast_ends_with(temp, ")")) {
5743 "'%s = %s': Filter options not formatted correctly\n",
5744 criteria, filter_pattern);
5745 }
5746
5747 /*
5748 * These can actually be in any order...
5749 * action(include|exclude),name(<event_name>),header(<header_name>),method(<match_method>)
5750 * At least one of action, name, or header is required.
5751 */
5752 while ((option = strtok_r(temp, " ,)", &saveptr))) {
5753 if (!strncmp(option, "action", 6)) {
5754 char *method = strstr(option, "(");
5755 if (ast_strlen_zero(method)) {
5756 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': 'action' parameter not formatted correctly\n",
5757 criteria, filter_pattern);
5758 }
5759 method++;
5761 if (!strcmp(method, "include")) {
5762 filter_entry->is_excludefilter = 0;
5763 } else if (!strcmp(method, "exclude")) {
5764 filter_entry->is_excludefilter = 1;
5765 } else {
5766 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': 'action' option '%s' is unknown\n",
5767 criteria, filter_pattern, method);
5768 }
5769 options_found |= action_found;
5770 } else if (!strncmp(option, "name", 4)) {
5771 char *event_name = strstr(option, "(");
5772 event_name++;
5773 ast_strip(event_name);
5774 if (ast_strlen_zero(event_name)) {
5775 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': 'name' parameter not formatted correctly\n",
5776 criteria, filter_pattern);
5777 }
5778 filter_entry->event_name = ast_strdup(event_name);
5779 filter_entry->event_name_hash = ast_str_hash(event_name);
5780 options_found |= name_found;
5781 } else if (!strncmp(option, "header", 6)) {
5782 char *header_name = strstr(option, "(");
5783 header_name++;
5784 ast_strip(header_name);
5785 if (ast_strlen_zero(header_name)) {
5786 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': 'header' parameter not formatted correctly\n",
5787 criteria, filter_pattern);
5788 }
5789 if (!ast_ends_with(header_name, ":")) {
5790 filter_entry->header_name = ast_malloc(strlen(header_name) + 2);
5791 if (!filter_entry->header_name) {
5792 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_ALLOC_FAILED, LOG_ERROR, "Unable to allocate memory for header_name");
5793 }
5794 sprintf(filter_entry->header_name, "%s:", header_name); /* Safe */
5795 } else {
5796 filter_entry->header_name = ast_strdup(header_name);
5797 }
5798 options_found |= header_found;
5799 } else if (!strncmp(option, "method", 6)) {
5800 char *method = strstr(option, "(");
5801 method++;
5803 if (ast_strlen_zero(method)) {
5804 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': 'method' parameter not formatted correctly\n",
5805 criteria, filter_pattern);
5806 }
5807 if (!strcmp(method, "regex")) {
5808 filter_entry->match_type = FILTER_MATCH_REGEX;
5809 } else if (!strcmp(method, "exact")) {
5810 filter_entry->match_type = FILTER_MATCH_EXACT;
5811 } else if (!strcmp(method, "starts_with")) {
5812 filter_entry->match_type = FILTER_MATCH_STARTS_WITH;
5813 } else if (!strcmp(method, "ends_with")) {
5814 filter_entry->match_type = FILTER_MATCH_ENDS_WITH;
5815 } else if (!strcmp(method, "contains")) {
5816 filter_entry->match_type = FILTER_MATCH_CONTAINS;
5817 } else if (!strcmp(method, "none")) {
5818 filter_entry->match_type = FILTER_MATCH_NONE;
5819 } else {
5820 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': 'method' option '%s' is unknown\n",
5821 criteria, filter_pattern, method);
5822 }
5823 options_found |= method_found;
5824 } else {
5825 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_FORMAT_ERROR, LOG_WARNING, "'%s = %s': Filter option '%s' is unknown\n",
5826 criteria, filter_pattern, option);
5827 }
5828 temp = NULL;
5829 }
5830 if (!options_found) {
5832 "'%s = %s': No action, name, header, or method option found\n",
5833 criteria, filter_pattern);
5834 }
5835 if (ast_strlen_zero(filter_pattern) && filter_entry->match_type != FILTER_MATCH_NONE) {
5837 "'%s = %s': method can't be '%s' with no filter pattern\n",
5838 criteria, filter_pattern, match_type_names[filter_entry->match_type]);
5839 }
5840 if (!ast_strlen_zero(filter_pattern) && filter_entry->match_type == FILTER_MATCH_NONE) {
5842 "'%s = %s': method can't be 'none' with a filter pattern\n",
5843 criteria, filter_pattern);
5844 }
5845 if (!(options_found & name_found) && !(options_found & header_found) &&
5846 filter_entry->match_type == FILTER_MATCH_NONE) {
5848 "'%s = %s': No name or header option found and no filter pattern\n",
5849 criteria, filter_pattern);
5850 }
5851 }
5852
5853 if (!ast_strlen_zero(filter_pattern)) {
5854 if (filter_entry->match_type == FILTER_MATCH_REGEX) {
5855 filter_entry->regex_filter = ast_calloc(1, sizeof(regex_t));
5856 if (!filter_entry->regex_filter) {
5857 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_ALLOC_FAILED, LOG_ERROR, "Unable to allocate memory for regex_filter");
5858 }
5859 if (regcomp(filter_entry->regex_filter, filter_pattern, REG_EXTENDED | REG_NOSUB)) {
5860 SCOPE_EXIT_LOG_RTN_VALUE(FILTER_COMPILE_FAIL, LOG_WARNING, "Unable to compile regex filter for '%s'", filter_pattern);
5861 }
5862 } else {
5863 filter_entry->string_filter = ast_strdup(filter_pattern);
5864 }
5865 }
5866
5867 ast_debug(2, "Event filter:\n"
5868 "conf entry: %s = %s\n"
5869 "event_name: %s (hash: %d)\n"
5870 "test_header: %s\n"
5871 "match_type: %s\n"
5872 "regex_filter: %p\n"
5873 "string filter: %s\n"
5874 "is excludefilter: %d\n",
5875 criteria, filter_pattern,
5876 S_OR(filter_entry->event_name, "<not used>"),
5877 filter_entry->event_name_hash,
5878 S_OR(filter_entry->header_name, "<not used>"),
5879 match_type_names[filter_entry->match_type],
5880 filter_entry->regex_filter,
5881 filter_entry->string_filter,
5882 filter_entry->is_excludefilter);
5883
5884 if (filter_entry->is_excludefilter) {
5885 ao2_t_link(excludefilters, filter_entry, "link new filter into exclude user container");
5886 } else {
5887 ao2_t_link(includefilters, filter_entry, "link new filter into include user container");
5888 }
5889
5890 SCOPE_EXIT_RTN_VALUE(FILTER_SUCCESS, "Filter added successfully");
5891}
static char * match_type_names[]
Definition: manager.c:397
static void event_filter_destructor(void *obj)
Definition: manager.c:926
#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 571 of file manager.c.

573{
574 struct ao2_container *sessions;
575 struct ast_manager_event_blob *ev;
576
578 /* Not an AMI message; disregard */
579 return;
580 }
581
582 sessions = ao2_global_obj_ref(mgr_sessions);
584 /* Nobody is listening */
586 return;
587 }
588
590 if (!ev) {
591 /* Conversion failure */
593 return;
594 }
595
597 "%s", ev->extra_fields);
598 ao2_ref(ev, -1);
600}
#define manager_event_sessions(sessions, category, event, contents,...)
Definition: manager.c:565
struct ast_manager_event_blob * stasis_message_to_ami(struct stasis_message *msg)
Build the AMI representation of the message.
int stasis_message_can_be_ami(struct stasis_message *msg)
Determine if the given message can be converted to AMI.
Struct containing info for an AMI event to send out.
Definition: manager.h:502
const ast_string_field extra_fields
Definition: manager.h:507
const char * manager_event
Definition: manager.h:504

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

Referenced by manager_subscriptions_init().

◆ manager_displayconnects()

static int manager_displayconnects ( struct mansession_session session)
static

Get displayconnects config option.

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

Definition at line 1062 of file manager.c.

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

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

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

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

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

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

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

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

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

6754{
6755 const char *module = astman_get_header(m, "Module");
6756 const char *id = astman_get_header(m, "ActionID");
6757
6758 ast_debug(1, "**** ModuleCheck .so file %s\n", module);
6759 if (!ast_module_check(module)) {
6760 astman_send_error(s, m, "Module not loaded");
6761 return 0;
6762 }
6763
6764 astman_append(s, "Response: Success\r\n");
6765
6766 if (!ast_strlen_zero(id)) {
6767 astman_append(s, "ActionID: %s\r\n", id);
6768 }
6769
6770#if !defined(LOW_MEMORY)
6771 /* When we switched from subversion to git we lost the ability to
6772 * retrieve the 'ASTERISK_FILE_VERSION' from that file, but we retain
6773 * the response header here for backwards compatibility. */
6774 astman_append(s, "Version: \r\n");
6775#endif
6776
6777 astman_append(s, "\r\n");
6778
6779 return 0;
6780}
int ast_module_check(const char *name)
Check if module with the name given is loaded.
Definition: loader.c:2823

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

6819{
6820 int res;
6821 const char *module = astman_get_header(m, "Module");
6822 const char *loadtype = astman_get_header(m, "LoadType");
6823 const char *recursive = astman_get_header(m, "Recursive");
6824
6825 if (!loadtype || strlen(loadtype) == 0) {
6826 astman_send_error(s, m, "Incomplete ModuleLoad action.");
6827 }
6828 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) {
6829 astman_send_error(s, m, "Need module name");
6830 }
6831
6832 res = file_in_modules_dir(module);
6833 if (res == 0) {
6834 astman_send_error(s, m, "Module must be in the configured modules directory.");
6835 return 0;
6836 } else if (res == -1) {
6837 astman_send_error(s, m, "Module not found.");
6838 return 0;
6839 }
6840
6841 if (!strcasecmp(loadtype, "load")) {
6842 res = ast_load_resource(module);
6843 if (res) {
6844 astman_send_error(s, m, "Could not load module.");
6845 } else {
6846 astman_send_ack(s, m, "Module loaded.");
6847 }
6848 } else if (!strcasecmp(loadtype, "unload")) {
6849 res = ast_unload_resource(module, AST_FORCE_SOFT);
6850 if (res) {
6851 astman_send_error(s, m, "Could not unload module.");
6852 } else {
6853 astman_send_ack(s, m, "Module unloaded.");
6854 }
6855 } else if (!strcasecmp(loadtype, "refresh")) {
6856 res = ast_refresh_resource(module, AST_FORCE_SOFT, !ast_strlen_zero(recursive) && ast_true(recursive));
6857 if (res) {
6858 astman_send_error(s, m, "Could not refresh module.");
6859 } else {
6860 astman_send_ack(s, m, "Module unloaded and loaded.");
6861 }
6862 } else if (!strcasecmp(loadtype, "reload")) {
6863 /* TODO: Unify the ack/error messages here with action_reload */
6864 if (!ast_strlen_zero(module)) {
6865 enum ast_module_reload_result reload_res = ast_module_reload(module);
6866
6867 switch (reload_res) {
6869 astman_send_error(s, m, "No such module.");
6870 break;
6872 astman_send_error(s, m, "Module does not support reload action.");
6873 break;
6875 astman_send_error(s, m, "An unknown error occurred");
6876 break;
6878 astman_send_error(s, m, "A reload is in progress");
6879 break;
6881 astman_send_error(s, m, "Module not initialized");
6882 break;
6885 /* Treat a queued request as success */
6886 astman_send_ack(s, m, "Module reloaded.");
6887 break;
6888 }
6889 } else {
6890 ast_module_reload(NULL); /* Reload all modules */
6891 astman_send_ack(s, m, "All modules reloaded");
6892 }
6893 } else {
6894 astman_send_error(s, m, "Incomplete ModuleLoad action.");
6895 }
6896 return 0;
6897}
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:6792
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
Definition: loader.c:1448
enum ast_module_load_result ast_load_resource(const char *resource_name)
Load a module.
Definition: loader.c:1978
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:1407
@ 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 7638 of file manager.c.

7639{
7640 /* Notify managers of change */
7641 char hint[512];
7642
7643 hint[0] = '\0';
7644 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
7645
7646 switch(info->reason) {
7648 manager_event(EVENT_FLAG_CALL, "ExtensionStatus",
7649 "Exten: %s\r\n"
7650 "Context: %s\r\n"
7651 "Hint: %s\r\n"
7652 "Status: %d\r\n"
7653 "StatusText: %s\r\n",
7654 exten,
7655 context,
7656 hint,
7657 info->exten_state,
7658 ast_extension_state2str(info->exten_state));
7659 break;
7661 manager_event(EVENT_FLAG_CALL, "PresenceStatus",
7662 "Exten: %s\r\n"
7663 "Context: %s\r\n"
7664 "Hint: %s\r\n"
7665 "Status: %s\r\n"
7666 "Subtype: %s\r\n"
7667 "Message: %s\r\n",
7668 exten,
7669 context,
7670 hint,
7671 ast_presence_state2str(info->presence_state),
7672 info->presence_subtype,
7673 info->presence_message);
7674 break;
7675 }
7676 return 0;
7677}
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 1002 of file manager.c.

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

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

2062{
2063 ast_mutex_lock(&s->lock);
2064}
ast_mutex_t lock
Definition: manager.c:333

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

2068{
2070}

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

5488{
5489 switch(entry->match_type) {
5490 case FILTER_MATCH_REGEX:
5491 return regexec(entry->regex_filter, eventdata, 0, NULL, 0) == 0;
5493 return ast_begins_with(eventdata, entry->string_filter);
5495 return ast_ends_with(eventdata, entry->string_filter);
5497 return strstr(eventdata, entry->string_filter) != NULL;
5498 case FILTER_MATCH_EXACT:
5499 return strcmp(eventdata, entry->string_filter) == 0;
5500 case FILTER_MATCH_NONE:
5501 return 1;
5502 }
5503
5504 return 0;
5505}

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, and NULL.

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

9166{
9167 char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64], arguments_title[64];
9168
9169 term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
9170 term_color(description_title, "[Description]\n", COLOR_MAGENTA, 0, 40);
9171 term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
9172 term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40);
9173 term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
9174
9175 if (!ast_strlen_zero(ast_str_buffer(instance->synopsis))) {
9177 ast_cli(a->fd, "%s%s\n\n", synopsis_title, synopsis);
9179 }
9180 if (!ast_strlen_zero(ast_str_buffer(instance->syntax))) {
9181 char *syntax = ast_xmldoc_printable(ast_str_buffer(instance->syntax), 1);
9182 ast_cli(a->fd, "%s%s\n\n", syntax_title, syntax);
9183 ast_free(syntax);
9184 }
9185 if (!ast_strlen_zero(ast_str_buffer(instance->description))) {
9186 char *description = ast_xmldoc_printable(ast_str_buffer(instance->description), 1);
9187 ast_cli(a->fd, "%s%s\n\n", description_title, description);
9188 ast_free(description);
9189 }
9190 if (!ast_strlen_zero(ast_str_buffer(instance->arguments))) {
9191 char *arguments = ast_xmldoc_printable(ast_str_buffer(instance->arguments), 1);
9192 ast_cli(a->fd, "%s%s\n\n", arguments_title, arguments);
9193 ast_free(arguments);
9194 }
9195 if (!ast_strlen_zero(ast_str_buffer(instance->seealso))) {
9196 char *seealso = ast_xmldoc_printable(ast_str_buffer(instance->seealso), 1);
9197 ast_cli(a->fd, "%s%s\n\n", seealso_title, seealso);
9198 ast_free(seealso);
9199 }
9200}
struct ast_str * synopsis
Definition: xmldoc.h:64

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

Referenced by handle_manager_show_event(), and handle_showmancmd().

◆ process_events()

static int process_events ( struct mansession s)
static

Send any applicable events to the client listening on this socket. Wait only for a finite time on each event, and drop all events whether they are successfully sent or not.

Definition at line 6325 of file manager.c.

6326{
6327 int ret = 0;
6328
6329 ao2_lock(s->session);
6330 if (s->session->stream != NULL) {
6331 struct eventqent *eqe = s->session->last_ev;
6332
6333 while ((eqe = advance_event(eqe))) {
6334 if (eqe->category == EVENT_FLAG_SHUTDOWN) {
6335 ast_debug(3, "Received CloseSession event\n");
6336 ret = -1;
6337 }
6338 if (!ret && s->session->authenticated &&
6339 (s->session->readperm & eqe->category) == eqe->category &&
6340 (s->session->send_events & eqe->category) == eqe->category) {
6342 if (send_string(s, eqe->eventdata) < 0 || s->write_error)
6343 ret = -1; /* don't send more */
6344 }
6345 }
6346 s->session->last_ev = eqe;
6347 }
6348 }
6349 ao2_unlock(s->session);
6350 return ret;
6351}
unsigned int write_error
Definition: manager.c:331

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

6939{
6940 int ret = 0;
6941 struct manager_action *act_found;
6942 struct ast_manager_user *user = NULL;
6943 const char *username;
6944 const char *action;
6945
6946 action = __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY);
6947 if (ast_strlen_zero(action)) {
6948 report_req_bad_format(s, "NONE");
6949 mansession_lock(s);
6950 astman_send_error(s, m, "Missing action in request");
6952 return 0;
6953 }
6954
6955 log_action(m, action);
6956
6957 if (ast_shutting_down()) {
6958 ast_log(LOG_ERROR, "Unable to process manager action '%s'. Asterisk is shutting down.\n", action);
6959 mansession_lock(s);
6960 astman_send_error(s, m, "Asterisk is shutting down");
6962 return 0;
6963 }
6964
6965 if (!s->session->authenticated
6966 && strcasecmp(action, "Login")
6967 && strcasecmp(action, "Logoff")
6968 && strcasecmp(action, "Challenge")) {
6969 if (!s->session->authenticated) {
6970 report_req_not_allowed(s, action);
6971 }
6972 mansession_lock(s);
6973 astman_send_error(s, m, "Permission denied");
6975 return 0;
6976 }
6977
6978 if (!s->session->authenticated
6979 && (!strcasecmp(action, "Login")
6980 || !strcasecmp(action, "Challenge"))) {
6981 username = astman_get_header(m, "Username");
6982
6986 if (user && !user->allowmultiplelogin) {
6989 sleep(1);
6990 mansession_lock(s);
6991 astman_send_error(s, m, "Login Already In Use");
6993 return -1;
6994 }
6996 }
6997 }
6998
6999 act_found = action_find(action);
7000 if (act_found) {
7001 /* Found the requested AMI action. */
7002 int acted = 0;
7003
7004 if ((s->session->writeperm & act_found->authority)
7005 || act_found->authority == 0) {
7006 /* We have the authority to execute the action. */
7007 ret = -1;
7008 ao2_lock(act_found);
7009 if (act_found->registered && act_found->func) {
7010 struct ast_module *mod_ref = ast_module_running_ref(act_found->module);
7011
7012 ao2_unlock(act_found);
7013 if (mod_ref || !act_found->module) {
7014 ast_debug(1, "Running action '%s'\n", act_found->action);
7015 ret = act_found->func(s, m);
7016 acted = 1;
7017 ast_module_unref(mod_ref);
7018 }
7019 } else {
7020 ao2_unlock(act_found);
7021 }
7022 }
7023 if (!acted) {
7024 /*
7025 * We did not execute the action because access was denied, it
7026 * was no longer registered, or no action was really registered.
7027 * Complain about it and leave.
7028 */
7029 report_req_not_allowed(s, action);
7030 mansession_lock(s);
7031 astman_send_error(s, m, "Permission denied");
7033 }
7034 ao2_t_ref(act_found, -1, "done with found action object");
7035 } else {
7036 char buf[512];
7037
7038 report_req_bad_format(s, action);
7039 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
7040 mansession_lock(s);
7041 astman_send_error(s, m, buf);
7043 }
7044 if (ret) {
7045 return ret;
7046 }
7047 /* Once done with our message, deliver any pending events unless the
7048 requester doesn't want them as part of this response.
7049 */
7050 if (ast_strlen_zero(astman_get_header(m, "SuppressEvents"))) {
7051 return process_events(s);
7052 } else {
7053 return ret;
7054 }
7055}
int ast_shutting_down(void)
Definition: asterisk.c:1877
static void log_action(const struct message *m, const char *action)
Definition: manager.c:6899
static int check_manager_session_inuse(const char *name)
Definition: manager.c:1022
static void report_req_not_allowed(const struct mansession *s, const char *action)
Definition: manager.c:2195
static void report_session_limit(const struct mansession *s)
Definition: manager.c:2283
static void report_req_bad_format(const struct mansession *s, const char *action)
Definition: manager.c:2224
char username[80]
Definition: manager.c:346

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

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

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

7367{
7368 struct ao2_container *sessions;
7370 time_t now = time(NULL);
7371 struct ao2_iterator i;
7372 int purged = 0;
7373
7374 sessions = ao2_global_obj_ref(mgr_sessions);
7375 if (!sessions) {
7376 return 0;
7377 }
7379 ao2_ref(sessions, -1);
7380 while ((session = ao2_iterator_next(&i)) && n_max > 0) {
7382 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) {
7383 if (session->authenticated
7384 && VERBOSITY_ATLEAST(2)
7386 ast_verb(2, "HTTP Manager '%s' timed out from %s\n",
7387 session->username, ast_sockaddr_stringify_addr(&session->addr));
7388 }
7391 n_max--;
7392 purged++;
7393 } else {
7396 }
7397 }
7399 return purged;
7400}
static void session_destroy(struct mansession_session *s)
Definition: manager.c:1009
#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 4963 of file manager.c.

4964{
4965 char *parse;
4967 AST_APP_ARG(queuename);
4970 AST_APP_ARG(announceoverride);
4971 AST_APP_ARG(queuetimeoutstr);
4972 AST_APP_ARG(agi);
4973 AST_APP_ARG(gosub);
4975 AST_APP_ARG(position);
4976 );
4977
4978 if (!strcasestr(app, "queue") || ast_strlen_zero(data)) {
4979 return 0;
4980 }
4981
4982 parse = ast_strdupa(data);
4984
4985 /*
4986 * The Queue application is fine unless the AGI parameter is set.
4987 * If it is, we need to check the user's permissions.
4988 */
4989 return !ast_strlen_zero(args.agi);
4990}
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 3757 of file manager.c.

3759{
3761 size_t obj_size;
3762 int res;
3763
3764 obj_size = payload_size + sizeof(*obj);
3765
3766 obj = ast_malloc(obj_size);
3767 if (!obj) {
3768 return -1;
3769 }
3770
3771 obj->action = action;
3773 memcpy(obj->payload, payload, payload_size);
3774
3775 res = ast_queue_control_data(chan, AST_CONTROL_READ_ACTION, obj, obj_size);
3776
3777 ast_free(obj);
3778 return res;
3779}
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:1257
@ 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 3790 of file manager.c.

3791{
3792 return queue_read_action_payload(chan, (const unsigned char *)body,
3793 strlen(body) + 1, AST_FRAME_READ_ACTION_SEND_TEXT);
3794}
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:3757
@ 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 3806 of file manager.c.

3808{
3809 int res;
3810 struct ast_msg_data *obj;
3811
3813 NULL, NULL, content_type, body);
3814 if (!obj) {
3815 return -1;
3816 }
3817
3818 res = queue_read_action_payload(chan, (const unsigned char *)obj,
3820
3821 ast_free(obj);
3822 return res;
3823}
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 10062 of file manager.c.

10063{
10065}
@ 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 2170 of file manager.c.

2171{
2172 char session_id[32];
2173 struct ast_security_event_successful_auth successful_auth = {
2176 .common.service = "AMI",
2177 .common.account_id = s->session->username,
2178 .common.session_tv = &s->session->sessionstart_tv,
2179 .common.local_addr = {
2180 .addr = &s->tcptls_session->parent->local_address,
2181 .transport = mansession_get_transport(s),
2182 },
2183 .common.remote_addr = {
2184 .addr = &s->session->addr,
2185 .transport = mansession_get_transport(s),
2186 },
2187 .common.session_id = session_id,
2188 };
2189
2190 snprintf(session_id, sizeof(session_id), "%p", s->session);
2191
2192 ast_security_event_report(AST_SEC_EVT(&successful_auth));
2193}
static enum ast_transport mansession_get_transport(const struct mansession *s)
Definition: manager.c:2089
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 2120 of file manager.c.

2121{
2122 char session_id[32];
2123 struct ast_security_event_failed_acl failed_acl_event = {
2125 .common.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
2126 .common.service = "AMI",
2127 .common.account_id = username,
2128 .common.session_tv = &s->session->sessionstart_tv,
2129 .common.local_addr = {
2130 .addr = &s->tcptls_session->parent->local_address,
2131 .transport = mansession_get_transport(s),
2132 },
2133 .common.remote_addr = {
2134 .addr = &s->session->addr,
2135 .transport = mansession_get_transport(s),
2136 },
2137 .common.session_id = session_id,
2138 };
2139
2140 snprintf(session_id, sizeof(session_id), "%p", s->session);
2141
2142 ast_security_event_report(AST_SEC_EVT(&failed_acl_event));
2143}
#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 2253 of file manager.c.

2255{
2256 char session_id[32];
2257 struct ast_security_event_chal_resp_failed chal_resp_failed = {
2260 .common.service = "AMI",
2261 .common.account_id = s->session->username,
2262 .common.session_tv = &s->session->sessionstart_tv,
2263 .common.local_addr = {
2264 .addr = &s->tcptls_session->parent->local_address,
2265 .transport = mansession_get_transport(s),
2266 },
2267 .common.remote_addr = {
2268 .addr = &s->session->addr,
2269 .transport = mansession_get_transport(s),
2270 },
2271 .common.session_id = session_id,
2272
2273 .challenge = s->session->challenge,
2274 .response = response,
2275 .expected_response = expected_response,
2276 };
2277
2278 snprintf(session_id, sizeof(session_id), "%p", s->session);
2279
2280 ast_security_event_report(AST_SEC_EVT(&chal_resp_failed));
2281}
#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 2145 of file manager.c.

2146{
2147 char session_id[32];
2148 struct ast_security_event_inval_password inval_password = {
2151 .common.service = "AMI",
2152 .common.account_id = username,
2153 .common.session_tv = &s->session->sessionstart_tv,
2154 .common.local_addr = {
2155 .addr = &s->tcptls_session->parent->local_address,
2156 .transport = mansession_get_transport(s),
2157 },
2158 .common.remote_addr = {
2159 .addr = &s->session->addr,
2160 .transport = mansession_get_transport(s),
2161 },
2162 .common.session_id = session_id,
2163 };
2164
2165 snprintf(session_id, sizeof(session_id), "%p", s->session);
2166
2167 ast_security_event_report(AST_SEC_EVT(&inval_password));
2168}
#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 2095 of file manager.c.

2096{
2097 char session_id[32];
2098 struct ast_security_event_inval_acct_id inval_acct_id = {
2101 .common.service = "AMI",
2102 .common.account_id = username,
2103 .common.session_tv = &s->session->sessionstart_tv,
2104 .common.local_addr = {
2105 .addr = &s->tcptls_session->parent->local_address,
2106 .transport = mansession_get_transport(s),
2107 },
2108 .common.remote_addr = {
2109 .addr = &s->session->addr,
2110 .transport = mansession_get_transport(s),
2111 },
2112 .common.session_id = session_id,
2113 };
2114
2115 snprintf(session_id, sizeof(session_id), "%p", s);
2116
2117 ast_security_event_report(AST_SEC_EVT(&inval_acct_id));
2118}
#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 2224 of file manager.c.

2225{
2226 char session_id[32];
2227 char request_type[64];
2228 struct ast_security_event_req_bad_format req_bad_format = {
2231 .common.service = "AMI",
2232 .common.account_id = s->session->username,
2233 .common.session_tv = &s->session->sessionstart_tv,
2234 .common.local_addr = {
2235 .addr = &s->tcptls_session->parent->local_address,
2236 .transport = mansession_get_transport(s),
2237 },
2238 .common.remote_addr = {
2239 .addr = &s->session->addr,
2240 .transport = mansession_get_transport(s),
2241 },
2242 .common.session_id = session_id,
2243
2244 .request_type = request_type,
2245 };
2246
2247 snprintf(session_id, sizeof(session_id), "%p", s->session);
2248 snprintf(request_type, sizeof(request_type), "Action: %s", action);
2249
2250 ast_security_event_report(AST_SEC_EVT(&req_bad_format));
2251}
#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 2195 of file manager.c.

2196{
2197 char session_id[32];
2198 char request_type[64];
2199 struct ast_security_event_req_not_allowed req_not_allowed = {
2202 .common.service = "AMI",
2203 .common.account_id = s->session->username,
2204 .common.session_tv = &s->session->sessionstart_tv,
2205 .common.local_addr = {
2206 .addr = &s->tcptls_session->parent->local_address,
2207 .transport = mansession_get_transport(s),
2208 },
2209 .common.remote_addr = {
2210 .addr = &s->session->addr,
2211 .transport = mansession_get_transport(s),
2212 },
2213 .common.session_id = session_id,
2214
2215 .request_type = request_type,
2216 };
2217
2218 snprintf(session_id, sizeof(session_id), "%p", s->session);
2219 snprintf(request_type, sizeof(request_type), "Action: %s", action);
2220
2221 ast_security_event_report(AST_SEC_EVT(&req_not_allowed));
2222}
#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 2283 of file manager.c.

2284{
2285 char session_id[32];
2287 .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT,
2289 .common.service = "AMI",
2290 .common.account_id = s->session->username,
2291 .common.session_tv = &s->session->sessionstart_tv,
2292 .common.local_addr = {
2293 .addr = &s->tcptls_session->parent->local_address,
2294 .transport = mansession_get_transport(s),
2295 },
2296 .common.remote_addr = {
2297 .addr = &s->session->addr,
2298 .transport = mansession_get_transport(s),
2299 },
2300 .common.session_id = session_id,
2301 };
2302
2303 snprintf(session_id, sizeof(session_id), "%p", s->session);
2304
2306}
static int session_limit
Definition: http.c:106
#define AST_SECURITY_EVENT_SESSION_LIMIT_VERSION
Event descriptor version.
@ AST_SECURITY_EVENT_SESSION_LIMIT
Session limit reached.
Request denied because of a session limit.

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

Referenced by process_message().

◆ restrictedFile()

static int restrictedFile ( const char *  filename)
static

Check if a file is restricted or not.

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

Definition at line 2451 of file manager.c.

2452{
2453 char *stripped_filename;
2454 RAII_VAR(char *, path, NULL, ast_free);
2455 RAII_VAR(char *, real_path, NULL, ast_std_free);
2456
2457 if (live_dangerously) {
2458 return 0;
2459 }
2460
2461 stripped_filename = ast_strip(ast_strdupa(filename));
2462
2463 /* If the file path starts with '/', don't prepend ast_config_AST_CONFIG_DIR */
2464 if (stripped_filename[0] == '/') {
2465 real_path = realpath(stripped_filename, NULL);
2466 } else {
2467 if (ast_asprintf(&path, "%s/%s", ast_config_AST_CONFIG_DIR, stripped_filename) == -1) {
2468 return -1;
2469 }
2470 real_path = realpath(path, NULL);
2471 }
2472
2473 if (!real_path) {
2474 return -1;
2475 }
2476
2477 if (!ast_begins_with(real_path, ast_config_AST_CONFIG_DIR)) {
2478 return 1;
2479 }
2480
2481 return 0;
2482}

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

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

◆ send_string()

static int send_string ( struct mansession s,
char *  string 
)
static

helper function to send a string to the socket. Return -1 on error (e.g. buffer full).

Definition at line 1835 of file manager.c.

1836{
1837 struct ast_iostream *stream;
1838 int len, res;
1839
1840 /* It's a result from one of the hook's action invocation */
1841 if (s->hook) {
1842 /*
1843 * to send responses, we're using the same function
1844 * as for receiving events. We call the event "HookResponse"
1845 */
1846 s->hook->helper(EVENT_FLAG_HOOKRESPONSE, "HookResponse", string);
1847 return 0;
1848 }
1849
1850 stream = s->stream ? s->stream : s->session->stream;
1851
1852 len = strlen(string);
1854 res = ast_iostream_write(stream, string, len);
1856
1857 if (res < len) {
1858 s->write_error = 1;
1859 }
1860
1861 return res;
1862}
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:328

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

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

939{
940 struct mansession_session *session = obj;
941 struct eventqent *eqe = session->last_ev;
942 struct ast_datastore *datastore;
943
944 /* Get rid of each of the data stores on the session */
945 while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) {
946 /* Free the data store */
947 ast_datastore_free(datastore);
948 }
949
950 if (eqe) {
952 }
953 if (session->chanvars) {
955 }
956
957 if (session->includefilters) {
958 ao2_t_ref(session->includefilters, -1, "decrement ref for include container, should be last one");
959 }
960
961 if (session->excludefilters) {
962 ao2_t_ref(session->excludefilters, -1, "decrement ref for exclude container, should be last one");
963 }
964
965 ast_mutex_destroy(&session->notify_lock);
966}
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define ast_mutex_destroy(a)
Definition: lock.h:188
Structure for a data store object.
Definition: datastore.h:64

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

Referenced by build_mansession().

◆ session_do()

static void * session_do ( void *  data)
static

The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). )

Definition at line 7272 of file manager.c.

7273{
7274 struct ast_tcptls_session_instance *ser = data;
7276 struct mansession s = {
7277 .tcptls_session = data,
7278 };
7279 int res;
7280 int arg = 1;
7281 struct ast_sockaddr ser_remote_address_tmp;
7282
7285 goto done;
7286 }
7287
7288 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
7289 session = build_mansession(&ser_remote_address_tmp);
7290
7291 if (session == NULL) {
7293 goto done;
7294 }
7295
7296 /* here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
7297 * This is necessary to prevent delays (caused by buffering) as we
7298 * write to the socket in bits and pieces. */
7299 if (setsockopt(ast_iostream_get_fd(ser->stream), IPPROTO_TCP, TCP_NODELAY, (char *) &arg, sizeof(arg)) < 0) {
7300 ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on manager connection: %s\n", strerror(errno));
7301 }
7303
7305 /* Hook to the tail of the event queue */
7306 session->last_ev = grab_last();
7307
7308 ast_mutex_init(&s.lock);
7309
7310 /* these fields duplicate those in the 'ser' structure */
7311 session->stream = s.stream = ser->stream;
7312 ast_sockaddr_copy(&session->addr, &ser_remote_address_tmp);
7313 s.session = session;
7314
7315 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
7316
7317 if(time(&session->authstart) == -1) {
7318 ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
7322 goto done;
7323 }
7325
7326 /*
7327 * We cannot let the stream exclusively wait for data to arrive.
7328 * We have to wake up the task to send async events.
7329 */
7331
7333 ast_tvnow(), authtimeout * 1000);
7334
7335 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */
7336 for (;;) {
7337 if ((res = do_message(&s)) < 0 || s.write_error || session->kicked) {
7338 break;
7339 }
7340 if (session->authenticated) {
7342 }
7343 }
7344 /* session is over, explain why and terminate */
7345 if (session->authenticated) {
7347 ast_verb(2, "Manager '%s' %s from %s\n", session->username, session->kicked ? "kicked" : "logged off", ast_sockaddr_stringify_addr(&session->addr));
7348 }
7349 } else {
7351 if (displayconnects) {
7352 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr));
7353 }
7354 }
7355
7357
7359done:
7360 ao2_ref(ser, -1);
7361 ser = NULL;
7362 return NULL;
7363}
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:969
static int do_message(struct mansession *s)
Definition: manager.c:7187
static struct eventqent * grab_last(void)
Definition: manager.c:697
static int authlimit
Definition: manager.c:174
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:150
struct ast_sockaddr remote_address
Definition: tcptls.h:152

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

2077{
2078 int maskint = strings_to_mask(eventmask);
2079
2080 ao2_lock(s->session);
2081 if (maskint >= 0) {
2082 s->session->send_events = maskint;
2083 }
2084 ao2_unlock(s->session);
2085
2086 return maskint;
2087}
static int strings_to_mask(const char *string)
Definition: manager.c:886

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

5562{
5563 int result = 0;
5564
5565 if (manager_debug) {
5566 ast_verbose("<-- Examining AMI event (%u): -->\n%s\n", eqe->event_name_hash, eqe->eventdata);
5567 } else {
5568 ast_debug(4, "Examining AMI event (%u):\n%s\n", eqe->event_name_hash, eqe->eventdata);
5569 }
5570 if (!ao2_container_count(includefilters) && !ao2_container_count(excludefilters)) {
5571 return 1; /* no filtering means match all */
5572 } else if (ao2_container_count(includefilters) && !ao2_container_count(excludefilters)) {
5573 /* include filters only: implied exclude all filter processed first, then include filters */
5574 ao2_t_callback_data(includefilters, OBJ_NODATA, filter_cmp_fn, eqe, &result, "find filter in includefilters container");
5575 return result;
5576 } else if (!ao2_container_count(includefilters) && ao2_container_count(excludefilters)) {
5577 /* exclude filters only: implied include all filter processed first, then exclude filters */
5578 ao2_t_callback_data(excludefilters, OBJ_NODATA, filter_cmp_fn, eqe, &result, "find filter in excludefilters container");
5579 return !result;
5580 } else {
5581 /* include and exclude filters: implied exclude all filter processed first, then include filters, and lastly exclude filters */
5582 ao2_t_callback_data(includefilters, OBJ_NODATA, filter_cmp_fn, eqe, &result, "find filter in session filter container");
5583 if (result) {
5584 result = 0;
5585 ao2_t_callback_data(excludefilters, OBJ_NODATA, filter_cmp_fn, eqe, &result, "find filter in session filter container");
5586 return !result;
5587 }
5588 }
5589
5590 return result;
5591}
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:5507

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

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

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

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

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

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

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 182 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 165 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 174 of file manager.c.

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

◆ authtimeout

int authtimeout
static

Definition at line 173 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 168 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 179 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 199 of file manager.c.

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

◆ manager_channelvars

char* manager_channelvars
static

Definition at line 175 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 7448 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 397 of file manager.c.

Referenced by manager_add_filter().

◆ originate_app_permissions

struct originate_permissions_entry originate_app_permissions[]
static

Definition at line 5000 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 191 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 194 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 181 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 1873 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 225 of file manager.c.