Asterisk - The Open Source Telephony Project GIT-master-7988d11
Loading...
Searching...
No Matches
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
 
#define DEFAULT_REALM   "asterisk"
 
#define EVENT_FLAG_SHUTDOWN   -1
 Fake event class used to end sessions at shutdown.
 
#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.
 
#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.
 
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.
 
static int action_coresettings (struct mansession *s, const struct message *m)
 Show PBX core settings information.
 
static int action_coreshowchannelmap (struct mansession *s, const struct message *m)
 Manager command "CoreShowChannelMap" - Lists all channels connected to the specified channel.
 
static int action_coreshowchannels (struct mansession *s, const struct message *m)
 Manager command "CoreShowChannels" - List currently defined channels and some information about them.
 
static int action_corestatus (struct mansession *s, const struct message *m)
 Show PBX core status information.
 
static int action_createconfig (struct mansession *s, const struct message *m)
 
static void action_destroy (void *obj)
 
static int action_events (struct mansession *s, const struct message *m)
 
static int action_extensionstate (struct mansession *s, const struct message *m)
 
static int action_filter (struct mansession *s, const struct message *m)
 Manager command to add an event filter to a manager session.
 
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'.
 
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
 
static int action_reload (struct mansession *s, const struct message *m)
 Send a reload event.
 
static int action_sendtext (struct mansession *s, const struct message *m)
 
static int action_setvar (struct mansession *s, const struct message *m)
 
static int action_status (struct mansession *s, const struct message *m)
 Manager "status" command to show channels.
 
static int action_timeout (struct mansession *s, const struct message *m)
 
static int action_updateconfig (struct mansession *s, const struct message *m)
 
static int action_userevent (struct mansession *s, const struct message *m)
 
static int action_waitevent (struct mansession *s, const struct message *m)
 
static struct eventqentadvance_event (struct eventqent *e)
 
static AO2_GLOBAL_OBJ_STATIC (event_docs)
 A container of event documentation nodes.
 
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.
 
int ast_hook_send_action (struct manager_custom_hook *hook, const char *msg)
 access for hooks to send action messages to ami
 
static int ast_instring (const char *bigstr, const char *smallstr, const char delim)
 
int ast_manager_check_enabled (void)
 Check if AMI is enabled.
 
struct stasis_message_routerast_manager_get_message_router (void)
 Get the stasis_message_router for AMI.
 
struct stasis_topicast_manager_get_topic (void)
 Get the Stasis Message Bus API topic for AMI.
 
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.
 
void ast_manager_publish_event (const char *type, int class_type, struct ast_json *obj)
 Publish an event to AMI.
 
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
 
void ast_manager_register_hook (struct manager_custom_hook *hook)
 Add a custom hook to be called when an event is fired.
 
static int ast_manager_register_struct (struct manager_action *act)
 
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.
 
int ast_manager_unregister (const char *action)
 support functions to register/unregister AMI action handlers,
 
void ast_manager_unregister_hook (struct manager_custom_hook *hook)
 Delete a custom hook to be called when an event is fired.
 
 AST_THREADSTORAGE_CUSTOM_SCOPE (astman_append_buf, NULL, ast_free_ptr, static)
 thread local buffer for astman_append
 
 AST_THREADSTORAGE_CUSTOM_SCOPE (manager_event_buf, NULL, ast_free_ptr, static)
 
 AST_THREADSTORAGE_CUSTOM_SCOPE (userevent_buf, NULL, ast_free_ptr, static)
 
int ast_webmanager_check_enabled (void)
 Check if AMI/HTTP is enabled.
 
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.
 
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.
 
const char * astman_get_header (const struct message *m, char *var)
 Return the first matching variable from an array.
 
struct ast_variableastman_get_variables (const struct message *m)
 Get a linked list of the Variable: headers.
 
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.
 
void astman_live_dangerously (int new_live_dangerously)
 Enable/disable the inclusion of 'dangerous' configurations outside of the ast_config_AST_CONFIG_DIR.
 
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
 Send ack in manager transaction.
 
void astman_send_error (struct mansession *s, const struct message *m, char *error)
 Send error in manager transaction.
 
void astman_send_error_va (struct mansession *s, const struct message *m, const char *fmt,...)
 Send error in manager transaction (with va_args support)
 
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.
 
void astman_send_list_complete_start (struct mansession *s, const struct message *m, const char *event_name, int count)
 Start the list complete event.
 
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.
 
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
 Send response in manager transaction.
 
static void astman_send_response_full (struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
 send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field.
 
static void astman_start_ack (struct mansession *s, const struct message *m)
 
static int async_goto_with_discard_bridge_after (struct ast_channel *chan, const char *context, const char *exten, int priority)
 
static int authenticate (struct mansession *s, const struct message *m)
 
static const char * authority_to_str (int authority, struct ast_str **res)
 Convert authority code to a list of options. Note that the EVENT_FLAG_ALL authority will always be returned.
 
static struct mansession_sessionbuild_mansession (const struct ast_sockaddr *addr)
 Allocate manager session structure and add it to the list of sessions.
 
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.
 
static int coreshowchannelmap_add_to_map (struct ao2_container *c, const char *s)
 Helper function to add a channel name to the vector.
 
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.
 
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.
 
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.
 
static char * handle_manager_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager reload.
 
static char * handle_mandebug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static 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.
 
static char * handle_showmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list connected.
 
static char * handle_showmaneventq (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list eventq.
 
static enum error_type handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn)
 helper function for action_updateconfig
 
static int is_originate_app_permitted (const char *app, const char *data, int permission)
 
static int is_restricted_file (const char *filename)
 Check if a file is restricted or not.
 
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.
 
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.
 
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.
 
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 void manager_subscription_change_msg_cb (void *userdata, struct stasis_subscription *sub, struct stasis_message *message)
 Callback for subscription change messages.
 
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.
 
static void mansession_unlock (struct mansession *s)
 Unlock the 'mansession' structure.
 
static int match_eventdata (struct event_filter_entry *entry, const char *eventdata)
 Test eventdata against a filter entry.
 
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.
 
static void purge_events (void)
 
static int purge_sessions (int n_max)
 remove at most n_max stale session from the list.
 
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.
 
static int queue_sendtext (struct ast_channel *chan, const char *body)
 Queue a read action to send a text message.
 
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.
 
static int reload_module (void)
 
static void report_auth_success (const struct mansession *s)
 
static void report_failed_acl (const struct mansession *s, const char *username)
 
static void report_failed_challenge_response (const struct mansession *s, const char *response, const char *expected_response)
 
static void report_inval_password (const struct mansession *s, const char *username)
 
static void report_invalid_user (const struct mansession *s, const char *username)
 
static void report_req_bad_format (const struct mansession *s, const char *action)
 
static void report_req_not_allowed (const struct mansession *s, const char *action)
 
static void report_session_limit (const struct mansession *s)
 
static int send_string (struct mansession *s, char *string)
 
static void session_destroy (struct mansession_session *s)
 
static void session_destructor (void *obj)
 
static void * session_do (void *data)
 The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). )
 
static int set_eventmask (struct mansession *s, const char *eventmask)
 Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm.
 
static int 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.
 
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.
 

Variables

static struct stasis_subscriptionacl_change_sub
 
static struct actions actions = AST_RWLIST_HEAD_INIT_VALUE
 
static struct all_events all_events = AST_RWLIST_HEAD_INIT_VALUE
 
static int allowmultiplelogin = 1
 
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.
 
static char * manager_channelvars
 
static int manager_debug = 0
 
static char * manager_disabledevents
 
static int manager_enabled = 0
 
static struct manager_hooks manager_hooks = AST_RWLIST_HEAD_INIT_VALUE
 
static struct stasis_topicmanager_topic
 A stasis_topic that all topics AMI cares about will be forwarded to.
 
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.
 
static struct stasis_forwardsecurity_topic_forwarder
 The stasis_subscription for forwarding the Security topic to the AMI topic.
 
static struct stasis_message_routerstasis_router
 The stasis_message_router for all Stasis Message Bus API messages.
 
static int subscribed = 0
 
static int timestampevents
 
static int unauth_sessions = 0
 
static struct users users = AST_RWLIST_HEAD_INIT_VALUE
 
static int webmanager_enabled = 0
 
 STASIS_MESSAGE_TYPE_DEFN (ast_manager_get_generic_type)
 Define AMI message types.
 

Detailed Description

Macro Definition Documentation

◆ any_manager_listeners

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

Definition at line 565 of file manager.c.

◆ ASTMAN_APPEND_BUF_INITSIZE

#define ASTMAN_APPEND_BUF_INITSIZE   256

initial allocated size for the astman_append_buf and astman_send_*_va

Definition at line 1907 of file manager.c.

◆ DEFAULT_REALM

#define DEFAULT_REALM   "asterisk"

Definition at line 175 of file manager.c.

◆ EVENT_FLAG_SHUTDOWN

#define EVENT_FLAG_SHUTDOWN   -1

Fake event class used to end sessions at shutdown.

Definition at line 208 of file manager.c.

◆ GET_HEADER_FIRST_MATCH

#define GET_HEADER_FIRST_MATCH   0

Definition at line 1607 of file manager.c.

◆ GET_HEADER_LAST_MATCH

#define GET_HEADER_LAST_MATCH   1

Definition at line 1608 of file manager.c.

◆ GET_HEADER_SKIP_EMPTY

#define GET_HEADER_SKIP_EMPTY   2

Definition at line 1609 of file manager.c.

◆ MANAGER_EVENT_BUF_INITSIZE

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 7557 of file manager.c.

◆ manager_event_sessions

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

Definition at line 562 of file manager.c.

◆ MAX_AUTH_PERM_STRING

#define MAX_AUTH_PERM_STRING   150

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

Definition at line 786 of file manager.c.

◆ MAX_BLACKLIST_CMD_LEN

#define MAX_BLACKLIST_CMD_LEN   2

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

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

Definition at line 220 of file manager.c.

◆ MAX_VARS

#define MAX_VARS   128

Definition at line 205 of file manager.c.

◆ MGR_SHOW_TERMINAL_WIDTH

#define MGR_SHOW_TERMINAL_WIDTH   80

Definition at line 203 of file manager.c.

◆ MSG_MOREDATA

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

Definition at line 1955 of file manager.c.

Enumeration Type Documentation

◆ add_filter_result

Enumerator
FILTER_SUCCESS 
FILTER_ALLOC_FAILED 
FILTER_COMPILE_FAIL 
FILTER_FORMAT_ERROR 

Definition at line 123 of file manager.c.

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

◆ error_type

enum error_type

Doxygen group

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

Definition at line 108 of file manager.c.

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

◆ event_filter_match_type

Enumerator
FILTER_MATCH_REGEX 
FILTER_MATCH_EXACT 
FILTER_MATCH_STARTS_WITH 
FILTER_MATCH_ENDS_WITH 
FILTER_MATCH_CONTAINS 
FILTER_MATCH_NONE 

Definition at line 385 of file manager.c.

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

◆ mansession_message_parsing

Enumerator
MESSAGE_OKAY 
MESSAGE_LINE_TOO_LONG 

Definition at line 313 of file manager.c.

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

Function Documentation

◆ __ast_manager_event_multichan()

int __ast_manager_event_multichan ( int  category,
const char *  event,
int  chancount,
struct ast_channel **  chans,
const char *  file,
int  line,
const char *  func,
const char *  contents,
  ... 
)

External routines may send asterisk manager events this way

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

Definition at line 7691 of file manager.c.

7694{
7695 struct ao2_container *sessions = ao2_global_obj_ref(mgr_sessions);
7696 va_list ap;
7697 int res;
7698
7700 /* Nobody is listening */
7702 return 0;
7703 }
7704
7705 va_start(ap, fmt);
7707 file, line, func, fmt, ap);
7708 va_end(ap);
7710 return res;
7711}
#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:97
#define any_manager_listeners(sessions)
Definition manager.c:565
static int __manager_event_sessions_va(struct ao2_container *sessions, int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt, va_list ap)
Definition manager.c:7559
Generic container type.
Definition astman.c:88

References __manager_event_sessions_va(), any_manager_listeners, ao2_cleanup, ao2_global_obj_ref, chancount, ast_category::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 1624 of file manager.c.

1625{
1626 int x, l = strlen(var);
1627 const char *result = "";
1628
1629 if (!m) {
1630 return result;
1631 }
1632
1633 for (x = 0; x < m->hdrcount; x++) {
1634 const char *h = m->headers[x];
1635 if (!strncasecmp(var, h, l) && h[l] == ':') {
1636 const char *value = h + l + 1;
1637 value = ast_skip_blanks(value); /* ignore leading spaces in the value */
1638 /* found a potential candidate */
1639 if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) {
1640 continue; /* not interesting */
1641 }
1642 if (mode & GET_HEADER_LAST_MATCH) {
1643 result = value; /* record the last match so far */
1644 } else {
1645 return value;
1646 }
1647 }
1648 }
1649
1650 return result;
1651}
#define var
Definition ast_expr2f.c:605
static PGresult * result
Definition cel_pgsql.c:84
#define GET_HEADER_LAST_MATCH
Definition manager.c:1608
#define GET_HEADER_SKIP_EMPTY
Definition manager.c:1609
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
char *attribute_pure 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().

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

7680{
7681 va_list ap;
7682 int res;
7683
7684 va_start(ap, fmt);
7686 chancount, chans, file, line, func, fmt, ap);
7687 va_end(ap);
7688 return res;
7689}

References __manager_event_sessions_va(), chancount, ast_category::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 7559 of file manager.c.

7570{
7572 const char *cat_str;
7573 struct timeval now;
7574 struct ast_str *buf;
7575 int i;
7576 int event_name_hash;
7577
7580 ast_debug(3, "AMI Event '%s' is globally disabled, skipping\n", event);
7581 /* Event is globally disabled */
7582 return -1;
7583 }
7584 }
7585
7586 buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE);
7587 if (!buf) {
7588 return -1;
7589 }
7590
7591 cat_str = authority_to_str(category, &auth);
7592 ast_str_set(&buf, 0,
7593 "Event: %s\r\n"
7594 "Privilege: %s\r\n",
7595 event, cat_str);
7596
7597 if (timestampevents) {
7598 now = ast_tvnow();
7599 ast_str_append(&buf, 0,
7600 "Timestamp: %ld.%06lu\r\n",
7601 (long)now.tv_sec, (unsigned long) now.tv_usec);
7602 }
7603 if (manager_debug) {
7604 static int seq;
7605
7606 ast_str_append(&buf, 0,
7607 "SequenceNumber: %d\r\n",
7609 ast_str_append(&buf, 0,
7610 "File: %s\r\n"
7611 "Line: %d\r\n"
7612 "Func: %s\r\n",
7613 file, line, func);
7614 }
7616 ast_str_append(&buf, 0,
7617 "SystemName: %s\r\n",
7619 }
7620
7621 ast_str_append_va(&buf, 0, fmt, ap);
7622 for (i = 0; i < chancount; i++) {
7624 }
7625
7626 ast_str_append(&buf, 0, "\r\n");
7627
7628 event_name_hash = ast_str_hash(event);
7629
7630 append_event(ast_str_buffer(buf), event_name_hash, category);
7631
7632 /* Wake up any sleeping sessions */
7633 if (sessions) {
7634 struct ao2_iterator iter;
7636
7637 iter = ao2_iterator_init(sessions, 0);
7638 while ((session = ao2_iterator_next(&iter))) {
7639 ast_mutex_lock(&session->notify_lock);
7640 if (session->waiting_thread != AST_PTHREADT_NULL) {
7641 pthread_kill(session->waiting_thread, SIGURG);
7642 } else {
7643 /* We have an event to process, but the mansession is
7644 * not waiting for it. We still need to indicate that there
7645 * is an event waiting so that get_input processes the pending
7646 * event instead of polling.
7647 */
7648 session->pending_event = 1;
7649 }
7650 ast_mutex_unlock(&session->notify_lock);
7652 }
7653 ao2_iterator_destroy(&iter);
7654 }
7655
7656 if (category != EVENT_FLAG_SHUTDOWN && !AST_RWLIST_EMPTY(&manager_hooks)) {
7657 struct manager_custom_hook *hook;
7658
7661 hook->helper(category, event, ast_str_buffer(buf));
7662 }
7664 }
7665
7666 return 0;
7667}
static volatile unsigned int seq
Definition app_sms.c:126
static struct ast_mansession session
#define ao2_iterator_next(iter)
Definition astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
char buf[BUFSIZE]
Definition eagi_proxy.c:66
static int append_event(const char *str, int event_name_hash, int category)
events are appended to a queue from where they can be dispatched to clients.
Definition manager.c:7514
static int manager_debug
Definition manager.c:169
static void append_channel_vars(struct ast_str **pbuf, struct ast_channel *chan)
Definition manager.c:7539
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:926
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:827
#define MAX_AUTH_PERM_STRING
Definition manager.c:786
static int timestampevents
Definition manager.c:163
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition manager.c:208
#define MANAGER_EVENT_BUF_INITSIZE
Definition manager.c:7557
static char * manager_disabledevents
Definition manager.c:173
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_RWLIST_EMPTY
#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.
#define AST_RWLIST_TRAVERSE
#define AST_PTHREADT_NULL
Definition lock.h:73
#define ast_mutex_unlock(a)
Definition lock.h:197
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition lock.h:764
#define ast_mutex_lock(a)
Definition lock.h:196
const char * ast_config_AST_SYSTEM_NAME
Definition options.c:171
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition strings.h:1139
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition strings.h:1259
#define ast_str_alloca(init_len)
Definition strings.h:848
int ast_in_delimited_string(const char *needle, const char *haystack, char delim)
Check if there is an exact match for 'needle' between delimiters in 'haystack'.
Definition strings.c:466
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition strings.h:1113
int ast_str_append_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Append to a dynamic string using a va_list.
Definition strings.h:1048
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
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
struct manager_custom_hook::@248 list
manager_hook_t helper
Definition manager.h:117
list of hooks registered
Definition manager.c:366
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition time.h:159

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, append_channel_vars(), append_event(), ast_atomic_fetchadd_int(), ast_config_AST_SYSTEM_NAME, ast_debug, ast_in_delimited_string(), ast_mutex_lock, ast_mutex_unlock, AST_PTHREADT_NULL, AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_append_va(), ast_str_buffer(), ast_str_hash(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), ast_tvnow(), authority_to_str(), buf, chancount, EVENT_FLAG_SHUTDOWN, ast_category::file, manager_custom_hook::helper, manager_debug, manager_disabledevents, 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 10102 of file manager.c.

10104{
10106 return;
10107 }
10108
10109 /* For now, this is going to be performed simply and just execute a forced reload. */
10110 ast_log(LOG_NOTICE, "Reloading manager in response to ACL change event.\n");
10111 __init_manager(1, 1);
10112}
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:9699

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

Referenced by acl_change_stasis_subscribe().

◆ acl_change_stasis_subscribe()

static void acl_change_stasis_subscribe ( void  )
static

Definition at line 231 of file manager.c.

232{
233 if (!acl_change_sub) {
238 }
239}
static struct stasis_subscription * acl_change_sub
Definition manager.c:179
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition manager.c:10102
#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:1090
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:1144
#define stasis_subscribe(topic, callback, data)
Definition stasis.h:649

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

Referenced by __init_manager().

◆ acl_change_stasis_unsubscribe()

static void acl_change_stasis_unsubscribe ( void  )
static

Definition at line 241 of file manager.c.

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

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

4515{
4516 const char *msgtype = astman_get_header(m, "MsgType");
4517 const char *chargetype = astman_get_header(m, "ChargeType");
4518 const char *currencyname = astman_get_header(m, "CurrencyName");
4519 const char *currencyamount = astman_get_header(m, "CurrencyAmount");
4520 const char *mult = astman_get_header(m, "CurrencyMultiplier");
4521 const char *totaltype = astman_get_header(m, "TotalType");
4522 const char *aocbillingid = astman_get_header(m, "AOCBillingId");
4523 const char *association_id= astman_get_header(m, "ChargingAssociationId");
4524 const char *association_num = astman_get_header(m, "ChargingAssociationNumber");
4525 const char *association_plan = astman_get_header(m, "ChargingAssociationPlan");
4526
4527 enum ast_aoc_type _msgtype;
4528 enum ast_aoc_charge_type _chargetype;
4530 enum ast_aoc_total_type _totaltype = AST_AOC_TOTAL;
4531 enum ast_aoc_billing_id _billingid = AST_AOC_BILLING_NA;
4532 unsigned int _currencyamount = 0;
4533 int _association_id = 0;
4534 unsigned int _association_plan = 0;
4535
4536 struct ast_aoc_decoded *decoded = NULL;
4537
4538 if (ast_strlen_zero(chargetype)) {
4539 astman_send_error(s, m, "ChargeType not specified");
4540 goto aocmessage_cleanup;
4541 }
4542
4543 _msgtype = strcasecmp(msgtype, "d") ? AST_AOC_E : AST_AOC_D;
4544
4545 if (!strcasecmp(chargetype, "NA")) {
4546 _chargetype = AST_AOC_CHARGE_NA;
4547 } else if (!strcasecmp(chargetype, "Free")) {
4548 _chargetype = AST_AOC_CHARGE_FREE;
4549 } else if (!strcasecmp(chargetype, "Currency")) {
4550 _chargetype = AST_AOC_CHARGE_CURRENCY;
4551 } else if (!strcasecmp(chargetype, "Unit")) {
4552 _chargetype = AST_AOC_CHARGE_UNIT;
4553 } else {
4554 astman_send_error(s, m, "Invalid ChargeType");
4555 goto aocmessage_cleanup;
4556 }
4557
4558 if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
4559
4560 if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u", &_currencyamount) != 1)) {
4561 astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when ChargeType is Currency");
4562 goto aocmessage_cleanup;
4563 }
4564
4565 if (ast_strlen_zero(mult)) {
4566 astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
4567 goto aocmessage_cleanup;
4568 } else if (!strcasecmp(mult, "onethousandth")) {
4570 } else if (!strcasecmp(mult, "onehundredth")) {
4572 } else if (!strcasecmp(mult, "onetenth")) {
4573 _mult = AST_AOC_MULT_ONETENTH;
4574 } else if (!strcasecmp(mult, "one")) {
4575 _mult = AST_AOC_MULT_ONE;
4576 } else if (!strcasecmp(mult, "ten")) {
4577 _mult = AST_AOC_MULT_TEN;
4578 } else if (!strcasecmp(mult, "hundred")) {
4579 _mult = AST_AOC_MULT_HUNDRED;
4580 } else if (!strcasecmp(mult, "thousand")) {
4581 _mult = AST_AOC_MULT_THOUSAND;
4582 } else {
4583 astman_send_error(s, m, "Invalid ChargeMultiplier");
4584 goto aocmessage_cleanup;
4585 }
4586 }
4587
4588 /* create decoded object and start setting values */
4589 if (!(decoded = ast_aoc_create(_msgtype, _chargetype, 0))) {
4590 astman_send_error(s, m, "Message Creation Failed");
4591 goto aocmessage_cleanup;
4592 }
4593
4594 if (_msgtype == AST_AOC_D) {
4595 if (!ast_strlen_zero(totaltype) && !strcasecmp(totaltype, "subtotal")) {
4596 _totaltype = AST_AOC_SUBTOTAL;
4597 }
4598
4599 if (ast_strlen_zero(aocbillingid)) {
4600 /* ignore this is optional */
4601 } else if (!strcasecmp(aocbillingid, "Normal")) {
4602 _billingid = AST_AOC_BILLING_NORMAL;
4603 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
4604 _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
4605 } else if (!strcasecmp(aocbillingid, "CreditCard")) {
4606 _billingid = AST_AOC_BILLING_CREDIT_CARD;
4607 } else {
4608 astman_send_error(s, m, "Invalid AOC-D AOCBillingId");
4609 goto aocmessage_cleanup;
4610 }
4611 } else {
4612 if (ast_strlen_zero(aocbillingid)) {
4613 /* ignore this is optional */
4614 } else if (!strcasecmp(aocbillingid, "Normal")) {
4615 _billingid = AST_AOC_BILLING_NORMAL;
4616 } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
4617 _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
4618 } else if (!strcasecmp(aocbillingid, "CreditCard")) {
4619 _billingid = AST_AOC_BILLING_CREDIT_CARD;
4620 } else if (!strcasecmp(aocbillingid, "CallFwdUnconditional")) {
4622 } else if (!strcasecmp(aocbillingid, "CallFwdBusy")) {
4623 _billingid = AST_AOC_BILLING_CALL_FWD_BUSY;
4624 } else if (!strcasecmp(aocbillingid, "CallFwdNoReply")) {
4626 } else if (!strcasecmp(aocbillingid, "CallDeflection")) {
4628 } else if (!strcasecmp(aocbillingid, "CallTransfer")) {
4629 _billingid = AST_AOC_BILLING_CALL_TRANSFER;
4630 } else {
4631 astman_send_error(s, m, "Invalid AOC-E AOCBillingId");
4632 goto aocmessage_cleanup;
4633 }
4634
4635 if (!ast_strlen_zero(association_id) && (sscanf(association_id, "%30d", &_association_id) != 1)) {
4636 astman_send_error(s, m, "Invalid ChargingAssociationId");
4637 goto aocmessage_cleanup;
4638 }
4639 if (!ast_strlen_zero(association_plan) && (sscanf(association_plan, "%30u", &_association_plan) != 1)) {
4640 astman_send_error(s, m, "Invalid ChargingAssociationPlan");
4641 goto aocmessage_cleanup;
4642 }
4643
4644 if (_association_id) {
4645 ast_aoc_set_association_id(decoded, _association_id);
4646 } else if (!ast_strlen_zero(association_num)) {
4647 ast_aoc_set_association_number(decoded, association_num, _association_plan);
4648 }
4649 }
4650
4651 if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
4652 ast_aoc_set_currency_info(decoded, _currencyamount, _mult, ast_strlen_zero(currencyname) ? NULL : currencyname);
4653 } else if (_chargetype == AST_AOC_CHARGE_UNIT) {
4654 struct ast_aoc_unit_entry entry;
4655 int i;
4656
4657 /* multiple unit entries are possible, lets get them all */
4658 for (i = 0; i < 32; i++) {
4659 if (aocmessage_get_unit_entry(m, &entry, i)) {
4660 break; /* that's the end then */
4661 }
4662
4663 ast_aoc_add_unit_entry(decoded, entry.valid_amount, entry.amount, entry.valid_type, entry.type);
4664 }
4665
4666 /* at least one unit entry is required */
4667 if (!i) {
4668 astman_send_error(s, m, "Invalid UnitAmount(0), At least one valid unit entry is required when ChargeType is set to Unit");
4669 goto aocmessage_cleanup;
4670 }
4671
4672 }
4673
4674 ast_aoc_set_billing_id(decoded, _billingid);
4675 ast_aoc_set_total_type(decoded, _totaltype);
4676
4677 return decoded;
4678
4679aocmessage_cleanup:
4680
4681 ast_aoc_destroy_decoded(decoded);
4682 return NULL;
4683}
ast_aoc_charge_type
Definition aoc.h:69
@ AST_AOC_CHARGE_CURRENCY
Definition aoc.h:72
@ AST_AOC_CHARGE_FREE
Definition aoc.h:71
@ AST_AOC_CHARGE_UNIT
Definition aoc.h:73
@ AST_AOC_CHARGE_NA
Definition aoc.h:70
ast_aoc_currency_multiplier
Defines the currency multiplier for an aoc message.
Definition aoc.h:34
@ AST_AOC_MULT_TEN
Definition aoc.h:39
@ AST_AOC_MULT_ONEHUNDREDTH
Definition aoc.h:36
@ AST_AOC_MULT_HUNDRED
Definition aoc.h:40
@ AST_AOC_MULT_ONETENTH
Definition aoc.h:37
@ AST_AOC_MULT_ONETHOUSANDTH
Definition aoc.h:35
@ AST_AOC_MULT_THOUSAND
Definition aoc.h:41
@ AST_AOC_MULT_ONE
Definition aoc.h:38
struct ast_aoc_decoded * ast_aoc_create(const enum ast_aoc_type msg_type, const enum ast_aoc_charge_type charge_type, const enum ast_aoc_request requests)
creates a ast_aoc_decode object of a specific message type
Definition aoc.c:285
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition aoc.c:316
int ast_aoc_set_association_number(struct ast_aoc_decoded *decoded, const char *num, uint8_t plan)
set the charging association number for an AOC-E message
Definition aoc.c:1065
int ast_aoc_add_unit_entry(struct ast_aoc_decoded *decoded, const unsigned int amount_is_present, const unsigned int amount, const unsigned int type_is_present, const unsigned int type)
Adds a unit entry into the list of units.
Definition aoc.c:986
ast_aoc_billing_id
Defines the billing id options for an aoc message.
Definition aoc.h:49
@ AST_AOC_BILLING_CALL_FWD_BUSY
Definition aoc.h:55
@ AST_AOC_BILLING_CALL_FWD_NO_REPLY
Definition aoc.h:56
@ AST_AOC_BILLING_NORMAL
Definition aoc.h:51
@ AST_AOC_BILLING_CALL_DEFLECTION
Definition aoc.h:57
@ AST_AOC_BILLING_CREDIT_CARD
Definition aoc.h:53
@ AST_AOC_BILLING_CALL_TRANSFER
Definition aoc.h:58
@ AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL
Definition aoc.h:54
@ AST_AOC_BILLING_REVERSE_CHARGE
Definition aoc.h:52
@ AST_AOC_BILLING_NA
Definition aoc.h:50
int ast_aoc_set_billing_id(struct ast_aoc_decoded *decoded, const enum ast_aoc_billing_id id)
set the billing id for a AOC-D or AST_AOC_E message
Definition aoc.c:1033
int ast_aoc_set_currency_info(struct ast_aoc_decoded *decoded, const unsigned int amount, const enum ast_aoc_currency_multiplier multiplier, const char *name)
Sets the currency values for a AOC-D or AOC-E message.
Definition aoc.c:928
int ast_aoc_set_association_id(struct ast_aoc_decoded *decoded, const int id)
set the charging association id for an AST_AOC_E message
Definition aoc.c:1049
int ast_aoc_set_total_type(struct ast_aoc_decoded *decoded, const enum ast_aoc_total_type type)
Sets the type of total for a AOC-D message.
Definition aoc.c:916
ast_aoc_type
Definition aoc.h:62
@ AST_AOC_D
Definition aoc.h:65
@ AST_AOC_E
Definition aoc.h:66
ast_aoc_total_type
Definition aoc.h:82
@ AST_AOC_TOTAL
Definition aoc.h:83
@ AST_AOC_SUBTOTAL
Definition aoc.h:84
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition manager.c:2000
const char * astman_get_header(const struct message *m, char *var)
Return the first matching variable from an array.
Definition manager.c:1661
static int aocmessage_get_unit_entry(const struct message *m, struct ast_aoc_unit_entry *entry, unsigned int entry_num)
Definition manager.c:4489
Definition aoc.h:178

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

Referenced by action_aocmessage().

◆ action_aoc_s_message()

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

Definition at line 4909 of file manager.c.

4911{
4912 struct ast_aoc_decoded *decoded = NULL;
4913 int hdrlen;
4914 int x;
4915 static const char hdr[] = "ChargedItem:";
4916 struct message sm = { 0 };
4917 int rates = 0;
4918
4919 if (!(decoded = ast_aoc_create(AST_AOC_S, 0, 0))) {
4920 astman_send_error(s, m, "Message Creation Failed");
4921 goto aocmessage_cleanup;
4922 }
4923
4924 hdrlen = strlen(hdr);
4925 for (x = 0; x < m->hdrcount; x++) {
4926 if (strncasecmp(hdr, m->headers[x], hdrlen) == 0) {
4927 if (rates > ast_aoc_s_get_count(decoded)) {
4928 if (action_aoc_s_submessage(s, &sm, decoded) == -1) {
4929 goto aocmessage_cleanup;
4930 }
4931 }
4932 ++rates;
4933 }
4934
4935 sm.headers[sm.hdrcount] = m->headers[x];
4936 ++sm.hdrcount;
4937 }
4938 if (rates > ast_aoc_s_get_count(decoded)) {
4939 if (action_aoc_s_submessage(s, &sm, decoded) == -1) {
4940 goto aocmessage_cleanup;
4941 }
4942 }
4943
4944 return decoded;
4945
4946aocmessage_cleanup:
4947
4948 ast_aoc_destroy_decoded(decoded);
4949 return NULL;
4950}
@ AST_AOC_S
Definition aoc.h:64
unsigned int ast_aoc_s_get_count(struct ast_aoc_decoded *decoded)
get the number rates associated with an AOC-S message
Definition aoc.c:765
static int action_aoc_s_submessage(struct mansession *s, const struct message *m, struct ast_aoc_decoded *decoded)
Definition manager.c:4685

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

4687{
4688 const char *chargeditem = __astman_get_header(m, "ChargedItem", GET_HEADER_LAST_MATCH);
4689 const char *ratetype = __astman_get_header(m, "RateType", GET_HEADER_LAST_MATCH);
4690 const char *currencyname = __astman_get_header(m, "CurrencyName", GET_HEADER_LAST_MATCH);
4691 const char *currencyamount = __astman_get_header(m, "CurrencyAmount", GET_HEADER_LAST_MATCH);
4692 const char *mult = __astman_get_header(m, "CurrencyMultiplier", GET_HEADER_LAST_MATCH);
4693 const char *time = __astman_get_header(m, "Time", GET_HEADER_LAST_MATCH);
4694 const char *timescale = __astman_get_header(m, "TimeScale", GET_HEADER_LAST_MATCH);
4695 const char *granularity = __astman_get_header(m, "Granularity", GET_HEADER_LAST_MATCH);
4696 const char *granularitytimescale = __astman_get_header(m, "GranularityTimeScale", GET_HEADER_LAST_MATCH);
4697 const char *chargingtype = __astman_get_header(m, "ChargingType", GET_HEADER_LAST_MATCH);
4698 const char *volumeunit = __astman_get_header(m, "VolumeUnit", GET_HEADER_LAST_MATCH);
4699 const char *code = __astman_get_header(m, "Code", GET_HEADER_LAST_MATCH);
4700
4701 enum ast_aoc_s_charged_item _chargeditem;
4702 enum ast_aoc_s_rate_type _ratetype;
4704 unsigned int _currencyamount = 0;
4705 unsigned int _code;
4706 unsigned int _time = 0;
4707 enum ast_aoc_time_scale _scale = 0;
4708 unsigned int _granularity = 0;
4709 enum ast_aoc_time_scale _granularity_time_scale = AST_AOC_TIME_SCALE_MINUTE;
4710 int _step = 0;
4711 enum ast_aoc_volume_unit _volumeunit = 0;
4712
4713 if (ast_strlen_zero(chargeditem)) {
4714 astman_send_error(s, m, "ChargedItem not specified");
4715 goto aocmessage_cleanup;
4716 }
4717
4718 if (ast_strlen_zero(ratetype)) {
4719 astman_send_error(s, m, "RateType not specified");
4720 goto aocmessage_cleanup;
4721 }
4722
4723 if (!strcasecmp(chargeditem, "NA")) {
4724 _chargeditem = AST_AOC_CHARGED_ITEM_NA;
4725 } else if (!strcasecmp(chargeditem, "SpecialArrangement")) {
4727 } else if (!strcasecmp(chargeditem, "BasicCommunication")) {
4729 } else if (!strcasecmp(chargeditem, "CallAttempt")) {
4730 _chargeditem = AST_AOC_CHARGED_ITEM_CALL_ATTEMPT;
4731 } else if (!strcasecmp(chargeditem, "CallSetup")) {
4732 _chargeditem = AST_AOC_CHARGED_ITEM_CALL_SETUP;
4733 } else if (!strcasecmp(chargeditem, "UserUserInfo")) {
4735 } else if (!strcasecmp(chargeditem, "SupplementaryService")) {
4737 } else {
4738 astman_send_error(s, m, "Invalid ChargedItem");
4739 goto aocmessage_cleanup;
4740 }
4741
4742 if (!strcasecmp(ratetype, "NA")) {
4743 _ratetype = AST_AOC_RATE_TYPE_NA;
4744 } else if (!strcasecmp(ratetype, "Free")) {
4745 _ratetype = AST_AOC_RATE_TYPE_FREE;
4746 } else if (!strcasecmp(ratetype, "FreeFromBeginning")) {
4748 } else if (!strcasecmp(ratetype, "Duration")) {
4749 _ratetype = AST_AOC_RATE_TYPE_DURATION;
4750 } else if (!strcasecmp(ratetype, "Flat")) {
4751 _ratetype = AST_AOC_RATE_TYPE_FLAT;
4752 } else if (!strcasecmp(ratetype, "Volume")) {
4753 _ratetype = AST_AOC_RATE_TYPE_VOLUME;
4754 } else if (!strcasecmp(ratetype, "SpecialCode")) {
4756 } else {
4757 astman_send_error(s, m, "Invalid RateType");
4758 goto aocmessage_cleanup;
4759 }
4760
4761 if (_ratetype > AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING) {
4762 if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u",
4763 &_currencyamount) != 1)) {
4764 astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when RateType is non-free");
4765 goto aocmessage_cleanup;
4766 }
4767
4768 if (ast_strlen_zero(mult)) {
4769 astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
4770 goto aocmessage_cleanup;
4771 } else if (!strcasecmp(mult, "onethousandth")) {
4773 } else if (!strcasecmp(mult, "onehundredth")) {
4775 } else if (!strcasecmp(mult, "onetenth")) {
4776 _mult = AST_AOC_MULT_ONETENTH;
4777 } else if (!strcasecmp(mult, "one")) {
4778 _mult = AST_AOC_MULT_ONE;
4779 } else if (!strcasecmp(mult, "ten")) {
4780 _mult = AST_AOC_MULT_TEN;
4781 } else if (!strcasecmp(mult, "hundred")) {
4782 _mult = AST_AOC_MULT_HUNDRED;
4783 } else if (!strcasecmp(mult, "thousand")) {
4784 _mult = AST_AOC_MULT_THOUSAND;
4785 } else {
4786 astman_send_error(s, m, "Invalid ChargeMultiplier");
4787 goto aocmessage_cleanup;
4788 }
4789 }
4790
4791 if (_ratetype == AST_AOC_RATE_TYPE_DURATION) {
4792 if (ast_strlen_zero(timescale)) {
4793 astman_send_error(s, m, "TimeScale unspecified, TimeScale is required when RateType is Duration.");
4794 goto aocmessage_cleanup;
4795 } else if (!strcasecmp(timescale, "onehundredthsecond")) {
4797 } else if (!strcasecmp(timescale, "onetenthsecond")) {
4799 } else if (!strcasecmp(timescale, "second")) {
4801 } else if (!strcasecmp(timescale, "tenseconds")) {
4803 } else if (!strcasecmp(timescale, "minute")) {
4805 } else if (!strcasecmp(timescale, "hour")) {
4806 _scale = AST_AOC_TIME_SCALE_HOUR;
4807 } else if (!strcasecmp(timescale, "day")) {
4808 _scale = AST_AOC_TIME_SCALE_DAY;
4809 } else {
4810 astman_send_error(s, m, "Invalid TimeScale");
4811 goto aocmessage_cleanup;
4812 }
4813
4814 if (ast_strlen_zero(time) || (sscanf(time, "%30u", &_time) != 1)) {
4815 astman_send_error(s, m, "Invalid Time, Time is a required when RateType is Duration");
4816 goto aocmessage_cleanup;
4817 }
4818
4819 if (!ast_strlen_zero(granularity)) {
4820 if ((sscanf(time, "%30u", &_granularity) != 1)) {
4821 astman_send_error(s, m, "Invalid Granularity");
4822 goto aocmessage_cleanup;
4823 }
4824
4825 if (ast_strlen_zero(granularitytimescale)) {
4826 astman_send_error(s, m, "Invalid GranularityTimeScale, GranularityTimeScale is a required when Granularity is specified");
4827 } else if (!strcasecmp(granularitytimescale, "onehundredthsecond")) {
4828 _granularity_time_scale = AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
4829 } else if (!strcasecmp(granularitytimescale, "onetenthsecond")) {
4830 _granularity_time_scale = AST_AOC_TIME_SCALE_TENTH_SECOND;
4831 } else if (!strcasecmp(granularitytimescale, "second")) {
4832 _granularity_time_scale = AST_AOC_TIME_SCALE_SECOND;
4833 } else if (!strcasecmp(granularitytimescale, "tenseconds")) {
4834 _granularity_time_scale = AST_AOC_TIME_SCALE_TEN_SECOND;
4835 } else if (!strcasecmp(granularitytimescale, "minute")) {
4836 _granularity_time_scale = AST_AOC_TIME_SCALE_MINUTE;
4837 } else if (!strcasecmp(granularitytimescale, "hour")) {
4838 _granularity_time_scale = AST_AOC_TIME_SCALE_HOUR;
4839 } else if (!strcasecmp(granularitytimescale, "day")) {
4840 _granularity_time_scale = AST_AOC_TIME_SCALE_DAY;
4841 } else {
4842 astman_send_error(s, m, "Invalid GranularityTimeScale");
4843 goto aocmessage_cleanup;
4844 }
4845 }
4846
4847 if (ast_strlen_zero(chargingtype) || strcasecmp(chargingtype, "continuouscharging") == 0) {
4848 _step = 0;
4849 } else if (strcasecmp(chargingtype, "stepfunction") == 0 ) {
4850 _step = 1;
4851 } else {
4852 astman_send_error(s, m, "Invalid ChargingType");
4853 goto aocmessage_cleanup;
4854 }
4855 }
4856
4857 if (_ratetype == AST_AOC_RATE_TYPE_VOLUME) {
4858 if (ast_strlen_zero(volumeunit)) {
4859 astman_send_error(s, m, "VolumeUnit unspecified, VolumeUnit is required when RateType is Volume.");
4860 goto aocmessage_cleanup;
4861 } else if (!strcasecmp(timescale, "octet")) {
4862 _volumeunit = AST_AOC_VOLUME_UNIT_OCTET;
4863 } else if (!strcasecmp(timescale, "segment")) {
4864 _volumeunit = AST_AOC_VOLUME_UNIT_SEGMENT;
4865 } else if (!strcasecmp(timescale, "message")) {
4866 _volumeunit = AST_AOC_VOLUME_UNIT_MESSAGE;
4867 }else {
4868 astman_send_error(s, m, "Invalid VolumeUnit");
4869 goto aocmessage_cleanup;
4870 }
4871 }
4872
4874 || _ratetype == AST_AOC_RATE_TYPE_SPECIAL_CODE) {
4875 if (ast_strlen_zero(code) || (sscanf(code, "%30u", &_code) != 1)) {
4876 astman_send_error(s, m, "Invalid Code, Code is a required when ChargedItem is SpecialArrangement and when RateType is SpecialCode");
4877 goto aocmessage_cleanup;
4878 }
4879 }
4880
4881 if (_chargeditem == AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT) {
4882 ast_aoc_s_add_special_arrangement(decoded, _code);
4883 } else if (_ratetype == AST_AOC_RATE_TYPE_DURATION) {
4884 ast_aoc_s_add_rate_duration(decoded, _chargeditem, _currencyamount, _mult,
4885 currencyname, _time, _scale, _granularity, _granularity_time_scale, _step);
4886 } else if (_ratetype == AST_AOC_RATE_TYPE_FLAT) {
4887 ast_aoc_s_add_rate_flat(decoded, _chargeditem, _currencyamount, _mult,
4888 currencyname);
4889 } else if (_ratetype == AST_AOC_RATE_TYPE_VOLUME) {
4890 ast_aoc_s_add_rate_volume(decoded, _chargeditem, _volumeunit, _currencyamount,
4891 _mult, currencyname);
4892 } else if (_ratetype == AST_AOC_RATE_TYPE_SPECIAL_CODE) {
4893 ast_aoc_s_add_rate_special_charge_code(decoded, _chargeditem, _code);
4894 } else if (_ratetype == AST_AOC_RATE_TYPE_FREE) {
4895 ast_aoc_s_add_rate_free(decoded, _chargeditem, 0);
4896 } else if (_ratetype == AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING) {
4897 ast_aoc_s_add_rate_free(decoded, _chargeditem, 1);
4898 } else if (_ratetype == AST_AOC_RATE_TYPE_NA) {
4899 ast_aoc_s_add_rate_na(decoded, _chargeditem);
4900 }
4901
4902 return 0;
4903
4904aocmessage_cleanup:
4905
4906 return -1;
4907}
int ast_aoc_s_add_rate_duration(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name, unsigned long time, enum ast_aoc_time_scale time_scale, unsigned long granularity_time, enum ast_aoc_time_scale granularity_time_scale, int step_function)
Add AOC-S duration rate entry.
Definition aoc.c:779
ast_aoc_s_charged_item
Definition aoc.h:145
@ AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION
Definition aoc.h:148
@ AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT
Definition aoc.h:147
@ AST_AOC_CHARGED_ITEM_NA
Definition aoc.h:146
@ AST_AOC_CHARGED_ITEM_USER_USER_INFO
Definition aoc.h:151
@ AST_AOC_CHARGED_ITEM_CALL_SETUP
Definition aoc.h:150
@ AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE
Definition aoc.h:152
@ AST_AOC_CHARGED_ITEM_CALL_ATTEMPT
Definition aoc.h:149
ast_aoc_time_scale
Definition aoc.h:87
@ AST_AOC_TIME_SCALE_TEN_SECOND
Definition aoc.h:91
@ AST_AOC_TIME_SCALE_DAY
Definition aoc.h:94
@ AST_AOC_TIME_SCALE_TENTH_SECOND
Definition aoc.h:89
@ AST_AOC_TIME_SCALE_MINUTE
Definition aoc.h:92
@ AST_AOC_TIME_SCALE_SECOND
Definition aoc.h:90
@ AST_AOC_TIME_SCALE_HOUR
Definition aoc.h:93
@ AST_AOC_TIME_SCALE_HUNDREDTH_SECOND
Definition aoc.h:88
ast_aoc_volume_unit
Definition aoc.h:125
@ AST_AOC_VOLUME_UNIT_OCTET
Definition aoc.h:126
@ AST_AOC_VOLUME_UNIT_SEGMENT
Definition aoc.h:127
@ AST_AOC_VOLUME_UNIT_MESSAGE
Definition aoc.h:128
int ast_aoc_s_add_rate_special_charge_code(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int code)
Add AOC-S special rate entry.
Definition aoc.c:853
int ast_aoc_s_add_rate_free(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, int from_beginning)
Add AOC-S indicating charge item is free.
Definition aoc.c:866
int ast_aoc_s_add_special_arrangement(struct ast_aoc_decoded *decoded, unsigned int code)
Add AOC-S special arrangement entry.
Definition aoc.c:889
int ast_aoc_s_add_rate_flat(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S flat rate entry.
Definition aoc.c:810
int ast_aoc_s_add_rate_volume(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item, enum ast_aoc_volume_unit volume_unit, unsigned int amount, enum ast_aoc_currency_multiplier multiplier, const char *currency_name)
Add AOC-S volume rate entry.
Definition aoc.c:831
int ast_aoc_s_add_rate_na(struct ast_aoc_decoded *decoded, enum ast_aoc_s_charged_item charged_item)
Add AOC-S entry indicating charge item is not available.
Definition aoc.c:878
ast_aoc_s_rate_type
Definition aoc.h:155
@ AST_AOC_RATE_TYPE_VOLUME
Definition aoc.h:161
@ AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING
Definition aoc.h:158
@ AST_AOC_RATE_TYPE_SPECIAL_CODE
Definition aoc.h:162
@ AST_AOC_RATE_TYPE_NA
Definition aoc.h:156
@ AST_AOC_RATE_TYPE_DURATION
Definition aoc.h:159
@ AST_AOC_RATE_TYPE_FLAT
Definition aoc.h:160
@ AST_AOC_RATE_TYPE_FREE
Definition aoc.h:157
static const char * __astman_get_header(const struct message *m, char *var, int mode)
Return a matching header value.
Definition manager.c:1624

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

4953{
4954 const char *msgtype = astman_get_header(m, "MsgType");
4955 const char *channel = astman_get_header(m, "Channel");
4956 const char *pchannel = astman_get_header(m, "ChannelPrefix");
4957
4958 struct ast_channel *chan = NULL;
4959
4960 struct ast_aoc_decoded *decoded = NULL;
4961 struct ast_aoc_encoded *encoded = NULL;
4962 size_t encoded_size = 0;
4963
4964 if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) {
4965 astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these.");
4966 goto aocmessage_cleanup;
4967 }
4968
4969 if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) {
4970 chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel));
4971 }
4972
4973 if (!chan) {
4974 astman_send_error(s, m, "No such channel");
4975 goto aocmessage_cleanup;
4976 }
4977
4978 if (strcasecmp(msgtype, "d") == 0 || strcasecmp(msgtype, "e") == 0) {
4979 decoded = action_aoc_de_message(s, m);
4980 }
4981 else if (strcasecmp(msgtype, "s") == 0) {
4982 decoded = action_aoc_s_message(s, m);
4983 }
4984 else {
4985 astman_send_error(s, m, "Invalid MsgType");
4986 goto aocmessage_cleanup;
4987 }
4988
4989 if (!decoded) {
4990 goto aocmessage_cleanup;
4991 }
4992
4993 if ((encoded = ast_aoc_encode(decoded, &encoded_size, chan))
4994 && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) {
4995 astman_send_ack(s, m, "AOC Message successfully queued on channel");
4996 } else {
4997 astman_send_error(s, m, "Error encoding AOC message, could not queue onto channel");
4998 }
4999
5000aocmessage_cleanup:
5001
5002 ast_aoc_destroy_decoded(decoded);
5003 ast_aoc_destroy_encoded(encoded);
5004
5005 if (chan) {
5006 chan = ast_channel_unref(chan);
5007 }
5008 return 0;
5009}
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition aoc.c:322
struct ast_aoc_encoded * ast_aoc_encode(struct ast_aoc_decoded *decoded, size_t *out_size, struct ast_channel *chan)
encodes a decoded aoc structure so it can be passed on the wire
Definition aoc.c:659
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
Definition channel.c:1400
struct ast_channel * ast_channel_get_by_name(const char *search)
Find a channel by name or uniqueid.
Definition channel.c:1417
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:4710
#define ast_channel_unref(c)
Decrease channel reference count.
Definition channel.h:3025
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition manager.c:2032
static struct ast_aoc_decoded * action_aoc_s_message(struct mansession *s, const struct message *m)
Definition manager.c:4909
static struct ast_aoc_decoded * action_aoc_de_message(struct mansession *s, const struct message *m)
Definition manager.c:4514
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 4162 of file manager.c.

4163{
4164 const char *name = astman_get_header(m, "Channel");
4165 const char *exten = astman_get_header(m, "Exten");
4166 const char *context = astman_get_header(m, "Context");
4167 struct ast_channel *chan = NULL;
4168 char feature_code[AST_FEATURE_MAX_LEN];
4169 const char *digit;
4170
4171 if (ast_strlen_zero(name)) {
4172 astman_send_error(s, m, "No channel specified");
4173 return 0;
4174 }
4175 if (ast_strlen_zero(exten)) {
4176 astman_send_error(s, m, "No extension specified");
4177 return 0;
4178 }
4179
4180 if (!(chan = ast_channel_get_by_name(name))) {
4181 astman_send_error(s, m, "Channel specified does not exist");
4182 return 0;
4183 }
4184
4185 ast_channel_lock(chan);
4186 if (ast_get_builtin_feature(chan, "atxfer", feature_code, sizeof(feature_code)) ||
4187 ast_strlen_zero(feature_code)) {
4188 ast_channel_unlock(chan);
4189 astman_send_error(s, m, "No attended transfer feature code found");
4190 ast_channel_unref(chan);
4191 return 0;
4192 }
4193 ast_channel_unlock(chan);
4194
4195 if (!ast_strlen_zero(context)) {
4196 pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context);
4197 }
4198
4199 for (digit = feature_code; *digit; ++digit) {
4200 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
4201 ast_queue_frame(chan, &f);
4202 }
4203
4204 for (digit = exten; *digit; ++digit) {
4205 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
4206 ast_queue_frame(chan, &f);
4207 }
4208
4209 chan = ast_channel_unref(chan);
4210
4211 astman_send_ack(s, m, "Atxfer successfully queued");
4212
4213 return 0;
4214}
char digit
#define ast_channel_lock(chan)
Definition channel.h:2989
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:1171
#define ast_channel_unlock(chan)
Definition channel.h:2990
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]
char context[AST_MAX_CONTEXT]
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass

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(), digit, ast_frame_subclass::integer, name, NULL, pbx_builtin_setvar_helper(), and ast_frame::subclass.

Referenced by __init_manager().

◆ action_blind_transfer()

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

Definition at line 4116 of file manager.c.

4117{
4118 const char *name = astman_get_header(m, "Channel");
4119 const char *exten = astman_get_header(m, "Exten");
4120 const char *context = astman_get_header(m, "Context");
4121 struct ast_channel *chan;
4122
4123 if (ast_strlen_zero(name)) {
4124 astman_send_error(s, m, "No channel specified");
4125 return 0;
4126 }
4127
4128 if (ast_strlen_zero(exten)) {
4129 astman_send_error(s, m, "No extension specified");
4130 return 0;
4131 }
4132
4134 if (!chan) {
4135 astman_send_error(s, m, "Channel specified does not exist");
4136 return 0;
4137 }
4138
4139 if (ast_strlen_zero(context)) {
4141 }
4142
4143 switch (ast_bridge_transfer_blind(1, chan, exten, context, NULL, NULL)) {
4145 astman_send_error(s, m, "Transfer not permitted");
4146 break;
4148 astman_send_error(s, m, "Transfer invalid");
4149 break;
4151 astman_send_error(s, m, "Transfer failed");
4152 break;
4154 astman_send_ack(s, m, "Transfer succeeded");
4155 break;
4156 }
4157
4158 ast_channel_unref(chan);
4159 return 0;
4160}
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:4504
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
Definition bridge.h:1106
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition bridge.h:1104
@ AST_BRIDGE_TRANSFER_INVALID
Definition bridge.h:1108
@ AST_BRIDGE_TRANSFER_FAIL
Definition bridge.h:1110
const char * ast_channel_context(const struct ast_channel *chan)

References ast_bridge_transfer_blind(), AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_NOT_PERMITTED, AST_BRIDGE_TRANSFER_SUCCESS, ast_channel_context(), ast_channel_get_by_name(), ast_channel_unref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), 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 4216 of file manager.c.

4217{
4218 const char *name = astman_get_header(m, "Channel");
4219 struct ast_channel *chan = NULL;
4220 char *feature_code;
4221 const char *digit;
4222
4223 if (ast_strlen_zero(name)) {
4224 astman_send_error(s, m, "No channel specified");
4225 return 0;
4226 }
4227
4228 if (!(chan = ast_channel_get_by_name(name))) {
4229 astman_send_error(s, m, "Channel specified does not exist");
4230 return 0;
4231 }
4232
4233 ast_channel_lock(chan);
4234 feature_code = ast_get_chan_features_atxferabort(chan);
4235 ast_channel_unlock(chan);
4236
4237 if (!feature_code) {
4238 astman_send_error(s, m, "No disconnect feature code found");
4239 ast_channel_unref(chan);
4240 return 0;
4241 }
4242
4243 for (digit = feature_code; *digit; ++digit) {
4244 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *digit };
4245 ast_queue_frame(chan, &f);
4246 }
4247 ast_free(feature_code);
4248
4249 chan = ast_channel_unref(chan);
4250
4251 astman_send_ack(s, m, "CancelAtxfer successfully queued");
4252
4253 return 0;
4254}
#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, ast_frame_subclass::integer, name, NULL, and ast_frame::subclass.

Referenced by __init_manager().

◆ action_challenge()

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

Definition at line 3421 of file manager.c.

3422{
3423 const char *authtype = astman_get_header(m, "AuthType");
3424
3425 if (!strcasecmp(authtype, "MD5")) {
3427 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
3428 }
3429 mansession_lock(s);
3430 astman_start_ack(s, m);
3431 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
3433 } else {
3434 astman_send_error(s, m, "Must specify AuthType");
3435 }
3436 return 0;
3437}
static void mansession_unlock(struct mansession *s)
Unlock the 'mansession' structure.
Definition manager.c:2098
static void mansession_lock(struct mansession *s)
Lock the 'mansession' structure.
Definition manager.c:2092
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition manager.c:2037
void astman_append(struct mansession *s, const char *fmt,...)
Definition manager.c:1921
char challenge[10]
Definition manager.c:290
struct mansession_session * session
Definition manager.c:324
long int ast_random(void)
Definition utils.c:2346

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

4294{
4295 const char *cmd = astman_get_header(m, "Command");
4296 char *buf = NULL, *final_buf = NULL, *delim, *output;
4297 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */
4298 int fd, ret;
4299 off_t len;
4300
4301 if (ast_strlen_zero(cmd)) {
4302 astman_send_error(s, m, "No command provided");
4303 return 0;
4304 }
4305
4306 if (check_blacklist(cmd)) {
4307 astman_send_error(s, m, "Command blacklisted");
4308 return 0;
4309 }
4310
4311 if ((fd = mkstemp(template)) < 0) {
4312 astman_send_error_va(s, m, "Failed to create temporary file: %s", strerror(errno));
4313 return 0;
4314 }
4315
4316 ret = ast_cli_command(fd, cmd);
4317 astman_send_response_full(s, m, ret == RESULT_SUCCESS ? "Success" : "Error", MSG_MOREDATA, NULL);
4318
4319 /* Determine number of characters available */
4320 if ((len = lseek(fd, 0, SEEK_END)) < 0) {
4321 astman_append(s, "Message: Failed to determine number of characters: %s\r\n", strerror(errno));
4322 goto action_command_cleanup;
4323 }
4324
4325 /* This has a potential to overflow the stack. Hence, use the heap. */
4326 buf = ast_malloc(len + 1);
4327 final_buf = ast_malloc(len + 1);
4328
4329 if (!buf || !final_buf) {
4330 astman_append(s, "Message: Memory allocation failure\r\n");
4331 goto action_command_cleanup;
4332 }
4333
4334 if (lseek(fd, 0, SEEK_SET) < 0) {
4335 astman_append(s, "Message: Failed to set position on temporary file: %s\r\n", strerror(errno));
4336 goto action_command_cleanup;
4337 }
4338
4339 if (read(fd, buf, len) < 0) {
4340 astman_append(s, "Message: Failed to read from temporary file: %s\r\n", strerror(errno));
4341 goto action_command_cleanup;
4342 }
4343
4344 buf[len] = '\0';
4345 term_strip(final_buf, buf, len);
4346 final_buf[len] = '\0';
4347
4348 /* Trim trailing newline */
4349 if (len && final_buf[len - 1] == '\n') {
4350 final_buf[len - 1] = '\0';
4351 }
4352
4353 astman_append(s, "Message: Command output follows\r\n");
4354
4355 delim = final_buf;
4356 while ((output = strsep(&delim, "\n"))) {
4357 astman_append(s, "Output: %s\r\n", output);
4358 }
4359
4360action_command_cleanup:
4361 astman_append(s, "\r\n");
4362
4363 close(fd);
4364 unlink(template);
4365
4366 ast_free(buf);
4367 ast_free(final_buf);
4368
4369 return 0;
4370}
char * strsep(char **str, const char *delims)
#define ast_malloc(len)
A wrapper for malloc()
Definition astmm.h:191
#define RESULT_SUCCESS
Definition cli.h:40
#define ast_cli_command(fd, s)
Definition cli.h:232
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:2005
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:1964
static int check_blacklist(const char *cmd)
Definition manager.c:4257
#define MSG_MOREDATA
Definition manager.c:1955
int errno
char * term_strip(char *outbuf, const char *inbuf, int maxout)
Remove colorings from a specified string.
Definition term.c:362

References ast_cli_command, 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 6480 of file manager.c.

6481{
6482 const char *actionid = astman_get_header(m, "ActionID");
6483 char idText[150];
6484
6485 if (!ast_strlen_zero(actionid)) {
6486 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6487 } else {
6488 idText[0] = '\0';
6489 }
6490
6491 astman_append(s, "Response: Success\r\n"
6492 "%s"
6493 "AMIversion: %s\r\n"
6494 "AsteriskVersion: %s\r\n"
6495 "SystemName: %s\r\n"
6496 "CoreMaxCalls: %d\r\n"
6497 "CoreMaxLoadAvg: %f\r\n"
6498 "CoreRunUser: %s\r\n"
6499 "CoreRunGroup: %s\r\n"
6500 "CoreMaxFilehandles: %d\r\n"
6501 "CoreRealTimeEnabled: %s\r\n"
6502 "CoreCDRenabled: %s\r\n"
6503 "CoreHTTPenabled: %s\r\n"
6504 "SoundsSearchCustomDir: %s\r\n"
6505 "\r\n",
6506 idText,
6519 );
6520 return 0;
6521}
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:2994
#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:697
int ast_option_maxfiles
Definition options.c:82
int ast_option_maxcalls
Definition options.c:80
double ast_option_maxload
Definition options.c:78
int ast_realtime_enabled(void)
Check if there's any realtime engines loaded.
#define AMI_VERSION
Definition manager.h:57
#define ast_opt_sounds_search_custom
Definition options.h:148
const char * ast_config_AST_RUN_GROUP
Definition options.c:170
const char * ast_config_AST_RUN_USER
Definition options.c:169

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

Referenced by __init_manager().

◆ action_coreshowchannelmap()

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

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

Definition at line 6766 of file manager.c.

6767{
6768 const char *actionid = astman_get_header(m, "ActionID");
6769 const char *channel_name = astman_get_header(m, "Channel");
6770 char *current_channel_name;
6771 char id_text[256];
6772 int total = 0;
6773 struct ao2_container *channel_map;
6774 struct ao2_iterator i;
6775 RAII_VAR(struct ast_bridge_snapshot *, bridge_snapshot, NULL, ao2_cleanup);
6776 RAII_VAR(struct ast_channel_snapshot *, channel_snapshot, NULL, ao2_cleanup);
6777
6778 if (!ast_strlen_zero(actionid)) {
6779 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", actionid);
6780 } else {
6781 id_text[0] = '\0';
6782 }
6783
6784 if (ast_strlen_zero(channel_name)) {
6785 astman_send_error(s, m, "CoreShowChannelMap requires a channel.\n");
6786 return 0;
6787 }
6788
6789 channel_snapshot = ast_channel_snapshot_get_latest_by_name(channel_name);
6790 if (!channel_snapshot) {
6791 astman_send_error(s, m, "Could not get channel snapshot\n");
6792 return 0;
6793 }
6794
6795 if (ast_strlen_zero(channel_snapshot->bridge->id)) {
6796 astman_send_listack(s, m, "Channel map will follow", "start");
6797 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", 0);
6799 return 0;
6800 }
6801
6802 bridge_snapshot = ast_bridge_get_snapshot_by_uniqueid(channel_snapshot->bridge->id);
6803 if (!bridge_snapshot) {
6804 astman_send_listack(s, m, "Channel map will follow", "start");
6805 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", 0);
6807 return 0;
6808 }
6809
6811 if (!channel_map) {
6812 astman_send_error(s, m, "Could not create channel map\n");
6813 return 0;
6814 }
6815
6816 astman_send_listack(s, m, "Channel map will follow", "start");
6817
6818 if (coreshowchannelmap_add_connected_channels(channel_map, channel_snapshot, bridge_snapshot)) {
6819 astman_send_error(s, m, "Could not complete channel map\n");
6820 ao2_ref(channel_map, -1);
6821 return 0;
6822 }
6823
6824 i = ao2_iterator_init(channel_map, 0);
6825 while ((current_channel_name = ao2_iterator_next(&i))) {
6826 astman_append(s,
6827 "Event: CoreShowChannelMap\r\n"
6828 "%s"
6829 "Channel: %s\r\n"
6830 "ConnectedChannel: %s\r\n\r\n",
6831 id_text,
6832 channel_name,
6833 current_channel_name);
6834 total++;
6835 }
6837
6838 ao2_ref(channel_map, -1);
6839 astman_send_list_complete_start(s, m, "CoreShowChannelMapComplete", total);
6841
6842 return 0;
6843}
@ 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:2042
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:2078
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:6682
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition manager.c:2086
struct ast_channel_snapshot * ast_channel_snapshot_get_latest_by_name(const char *name)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
static int total
Definition res_adsi.c:970
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *bridge_id)
Returns the current snapshot for the bridge.
struct ao2_container * ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
Allocates a hash container for bare strings.
Definition strings.c:200
Structure that contains a snapshot of information about a bridge.
Definition bridge.h:318
Structure representing a snapshot of channel state.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981

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

6599{
6600 const char *actionid = astman_get_header(m, "ActionID");
6601 char idText[256];
6602 int numchans = 0;
6603 struct ao2_container *channels;
6604 struct ao2_iterator it_chans;
6605 struct ast_channel_snapshot *cs;
6606
6607 if (!ast_strlen_zero(actionid)) {
6608 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6609 } else {
6610 idText[0] = '\0';
6611 }
6612
6614
6615 astman_send_listack(s, m, "Channels will follow", "start");
6616
6617 it_chans = ao2_iterator_init(channels, 0);
6618 for (; (cs = ao2_iterator_next(&it_chans)); ao2_ref(cs, -1)) {
6620 char durbuf[16] = "";
6621
6622 if (!built) {
6623 continue;
6624 }
6625
6626 if (!ast_tvzero(cs->base->creationtime)) {
6627 int duration, durh, durm, durs;
6628
6629 duration = (int)(ast_tvdiff_ms(ast_tvnow(), cs->base->creationtime) / 1000);
6630 durh = duration / 3600;
6631 durm = (duration % 3600) / 60;
6632 durs = duration % 60;
6633 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
6634 }
6635
6636 astman_append(s,
6637 "Event: CoreShowChannel\r\n"
6638 "%s"
6639 "%s"
6640 "Application: %s\r\n"
6641 "ApplicationData: %s\r\n"
6642 "Duration: %s\r\n"
6643 "BridgeId: %s\r\n"
6644 "\r\n",
6645 idText,
6646 ast_str_buffer(built),
6647 cs->dialplan->appl,
6648 cs->dialplan->data,
6649 durbuf,
6650 cs->bridge->id);
6651
6652 numchans++;
6653
6654 ast_free(built);
6655 }
6656 ao2_iterator_destroy(&it_chans);
6657
6658 astman_send_list_complete(s, m, "CoreShowChannelsComplete", numchans);
6659
6660 ao2_ref(channels, -1);
6661 return 0;
6662}
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:2069
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 6524 of file manager.c.

6525{
6526 const char *actionid = astman_get_header(m, "ActionID");
6527 char idText[150];
6528 char startuptime[150], startupdate[150];
6529 char reloadtime[150], reloaddate[150];
6530 struct ast_tm tm;
6531
6532 if (!ast_strlen_zero(actionid)) {
6533 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
6534 } else {
6535 idText[0] = '\0';
6536 }
6537
6539 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
6540 ast_strftime(startupdate, sizeof(startupdate), "%Y-%m-%d", &tm);
6542 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
6543 ast_strftime(reloaddate, sizeof(reloaddate), "%Y-%m-%d", &tm);
6544
6545 astman_append(s, "Response: Success\r\n"
6546 "%s"
6547 "CoreStartupDate: %s\r\n"
6548 "CoreStartupTime: %s\r\n"
6549 "CoreReloadDate: %s\r\n"
6550 "CoreReloadTime: %s\r\n"
6551 "CoreCurrentCalls: %d\r\n"
6552 "CoreProcessedCalls: %d\r\n"
6553 "\r\n",
6554 idText,
6555 startupdate,
6556 startuptime,
6557 reloaddate,
6558 reloadtime,
6561 );
6562 return 0;
6563}
int ast_active_channels(void)
returns number of active/allocated channels
Definition channel.c:500
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:345
struct timeval ast_startuptime
Definition asterisk.c:344
int ast_processed_calls(void)
Retrieve the total number of calls processed through the PBX since last restart.
Definition pbx.c:4801

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

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

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

Referenced by __init_manager().

◆ action_destroy()

static void action_destroy ( void *  obj)
static

Definition at line 7828 of file manager.c.

7829{
7830 struct manager_action *doomed = obj;
7831
7832 if (doomed->synopsis) {
7833 /* The string fields were initialized. */
7835 }
7836 ao2_cleanup(doomed->final_response);
7837 ao2_cleanup(doomed->list_responses);
7838}
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
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 3322 of file manager.c.

3323{
3324 const char *mask = astman_get_header(m, "EventMask");
3325 int res, x;
3326 const char *id = astman_get_header(m, "ActionID");
3327 char id_text[256];
3328
3329 if (!ast_strlen_zero(id)) {
3330 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
3331 } else {
3332 id_text[0] = '\0';
3333 }
3334
3335 res = set_eventmask(s, mask);
3337 /* if this option is set we should not return a response on
3338 * error, or when all events are set */
3339
3340 if (res > 0) {
3341 for (x = 0; x < ARRAY_LEN(perms); x++) {
3342 if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) {
3343 return 0;
3344 }
3345 }
3346 astman_append(s, "Response: Success\r\n%s"
3347 "Events: On\r\n\r\n", id_text);
3348 } else if (res == 0)
3349 astman_append(s, "Response: Success\r\n%s"
3350 "Events: Off\r\n\r\n", id_text);
3351 return 0;
3352 }
3353
3354 if (res > 0)
3355 astman_append(s, "Response: Success\r\n%s"
3356 "Events: On\r\n\r\n", id_text);
3357 else if (res == 0)
3358 astman_append(s, "Response: Success\r\n%s"
3359 "Events: Off\r\n\r\n", id_text);
3360 else
3361 astman_send_error(s, m, "Invalid event mask");
3362
3363 return 0;
3364}
static int broken_events_action
Definition manager.c:165
static int set_eventmask(struct mansession *s, const char *eventmask)
Rather than braindead on,off this now can also accept a specific int mask value or a ',...
Definition manager.c:2107
static const struct permalias perms[]
int num
Definition manager.c:759
#define ARRAY_LEN(a)
Definition utils.h:706

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

5479{
5480 const char *exten = astman_get_header(m, "Exten");
5481 const char *context = astman_get_header(m, "Context");
5482 char hint[256];
5483 int status;
5484
5485 if (ast_strlen_zero(exten)) {
5486 astman_send_error(s, m, "Extension not specified");
5487 return 0;
5488 }
5489 if (ast_strlen_zero(context)) {
5490 context = "default";
5491 }
5492 status = ast_extension_state(NULL, context, exten);
5493 hint[0] = '\0';
5494 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
5495 astman_start_ack(s, m);
5496 astman_append(s, "Message: Extension Status\r\n"
5497 "Exten: %s\r\n"
5498 "Context: %s\r\n"
5499 "Hint: %s\r\n"
5500 "Status: %d\r\n"
5501 "StatusText: %s\r\n"
5502 "\r\n",
5503 exten, context, hint, status,
5505 return 0;
5506}
jack_status_t status
Definition app_jack.c:149
const char * ast_extension_state2str(int extension_state)
Return string representation of the state of an extension.
Definition pbx.c:3162
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:4173
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:3206

References ast_extension_state(), ast_extension_state2str(), ast_get_hint(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), 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 5703 of file manager.c.

5704{
5705 const char *match_criteria = astman_get_header(m, "MatchCriteria");
5706 const char *filter = astman_get_header(m, "Filter");
5707 const char *operation = astman_get_header(m, "Operation");
5708 int res;
5709
5710 if (!strcasecmp(operation, "Add")) {
5711 char *criteria;
5712 int have_match = !ast_strlen_zero(match_criteria);
5713
5714 /* Create an eventfilter expression.
5715 * eventfilter[(match_criteria)]
5716 */
5717 res = ast_asprintf(&criteria, "eventfilter%s%s%s",
5718 S_COR(have_match, "(", ""), S_OR(match_criteria, ""),
5719 S_COR(have_match, ")", ""));
5720 if (res <= 0) {
5721 astman_send_error(s, m, "Internal Error. Failed to allocate storage for filter type");
5722 return 0;
5723 }
5724
5726 ast_free(criteria);
5727 if (res != FILTER_SUCCESS) {
5728 if (res == FILTER_ALLOC_FAILED) {
5729 astman_send_error(s, m, "Internal Error. Failed to allocate regex for filter");
5730 return 0;
5731 } else if (res == FILTER_COMPILE_FAIL) {
5732 astman_send_error(s, m,
5733 "Filter did not compile. Check the syntax of the filter given.");
5734 return 0;
5735 } else if (res == FILTER_FORMAT_ERROR) {
5736 astman_send_error(s, m,
5737 "Filter was formatted incorrectly. Check the syntax of the filter given.");
5738 return 0;
5739 } else {
5740 astman_send_error(s, m, "Internal Error. Failed adding filter.");
5741 return 0;
5742 }
5743 }
5744
5745 astman_send_ack(s, m, "Success");
5746 return 0;
5747 }
5748
5749 astman_send_error(s, m, "Unknown operation");
5750 return 0;
5751}
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
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:5770
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition strings.h:80
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition strings.h:87
struct ao2_container * excludefilters
Definition manager.c:297
struct ao2_container * includefilters
Definition manager.c:296

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

Referenced by __init_manager().

◆ action_find()

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

Definition at line 434 of file manager.c.

435{
436 struct manager_action *act;
437
440 if (!strcasecmp(name, act->action)) {
441 ao2_t_ref(act, +1, "found action object");
442 break;
443 }
444 }
446
447 return act;
448}
#define ao2_t_ref(o, delta, tag)
Definition astobj2.h:460
list of actions registered
Definition manager.c:363
struct manager_action::@249 list
const char * action
Definition manager.h:156

References manager_action::action, ao2_t_ref, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, manager_action::list, 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 2515 of file manager.c.

2516{
2517 struct ast_config *cfg;
2518 const char *fn = astman_get_header(m, "Filename");
2519 const char *category = astman_get_header(m, "Category");
2520 const char *filter = astman_get_header(m, "Filter");
2521 const char *category_name;
2522 int catcount = 0;
2523 int lineno = 0;
2524 int ret = 0;
2525 struct ast_category *cur_category = NULL;
2526 struct ast_variable *v;
2527 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2528
2529 if (ast_strlen_zero(fn)) {
2530 astman_send_error(s, m, "Filename not specified");
2531 return 0;
2532 }
2533
2534 ret = is_restricted_file(fn);
2535 if (ret == 1) {
2536 astman_send_error(s, m, "File requires escalated privileges");
2537 return 0;
2538 } else if (ret == -1) {
2539 astman_send_error(s, m, "Config file not found");
2540 return 0;
2541 }
2542
2543 cfg = ast_config_load2(fn, "manager", config_flags);
2544 if (cfg == CONFIG_STATUS_FILEMISSING) {
2545 astman_send_error(s, m, "Config file not found");
2546 return 0;
2547 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2548 astman_send_error(s, m, "Config file has invalid format");
2549 return 0;
2550 }
2551
2552 astman_start_ack(s, m);
2553 while ((cur_category = ast_category_browse_filtered(cfg, category, cur_category, filter))) {
2554 struct ast_str *templates;
2555
2556 category_name = ast_category_get_name(cur_category);
2557 lineno = 0;
2558 astman_append(s, "Category-%06d: %s\r\n", catcount, category_name);
2559
2560 if (ast_category_is_template(cur_category)) {
2561 astman_append(s, "IsTemplate-%06d: %d\r\n", catcount, 1);
2562 }
2563
2564 if ((templates = ast_category_get_templates(cur_category))
2565 && ast_str_strlen(templates) > 0) {
2566 astman_append(s, "Templates-%06d: %s\r\n", catcount, ast_str_buffer(templates));
2568 }
2569
2570 for (v = ast_category_first(cur_category); v; v = v->next) {
2571 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
2572 }
2573
2574 catcount++;
2575 }
2576
2577 if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
2578 astman_append(s, "No categories found\r\n");
2579 }
2580
2581 ast_config_destroy(cfg);
2582 astman_append(s, "\r\n");
2583
2584 return 0;
2585}
static int is_restricted_file(const char *filename)
Check if a file is restricted or not.
Definition manager.c:2482
const char * ast_category_get_name(const struct ast_category *category)
Return the name of the category.
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
#define CONFIG_STATUS_FILEMISSING
struct ast_str * ast_category_get_templates(const struct ast_category *category)
Return the template names this category inherits from.
@ CONFIG_FLAG_NOCACHE
@ CONFIG_FLAG_WITHCOMMENTS
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition extconf.c:1287
int ast_category_is_template(const struct ast_category *category)
Check if category is a template.
struct ast_variable * ast_category_first(struct ast_category *cat)
given a pointer to a category, return the root variable.
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.
size_t attribute_pure 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:220
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next

References ast_category_browse_filtered(), ast_category_first(), ast_category_get_name(), ast_category_get_templates(), ast_category_is_template(), ast_config_destroy(), ast_config_load2(), ast_free, ast_str_buffer(), ast_str_strlen(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, filter(), is_restricted_file(), ast_variable::name, ast_variable::next, NULL, 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 2663 of file manager.c.

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

References ast_category_browse_filtered(), ast_category_first(), ast_category_get_name(), ast_category_get_templates(), ast_category_is_template(), ast_config_destroy(), ast_config_load2(), ast_free, ast_str_buffer(), ast_str_strlen(), ast_strlen_zero(), astman_append(), astman_append_json(), astman_get_header(), astman_send_error(), astman_start_ack(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, filter(), is_restricted_file(), ast_variable::name, ast_variable::next, NULL, 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 3599 of file manager.c.

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

3561{
3562 return ast_manager_hangup_helper(s, m,
3564}
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:469
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:3439

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

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

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

Referenced by __init_manager().

◆ action_listcommands()

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

Definition at line 3303 of file manager.c.

3304{
3305 struct manager_action *cur;
3307
3308 astman_start_ack(s, m);
3310 AST_RWLIST_TRAVERSE(&actions, cur, list) {
3311 if ((s->session->writeperm & cur->authority) || cur->authority == 0) {
3312 astman_append(s, "%s: %s (Priv: %s)\r\n",
3313 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
3314 }
3315 }
3317 astman_append(s, "\r\n");
3318
3319 return 0;
3320}

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

6848{
6849 if (ast_logger_rotate()) {
6850 astman_send_error(s, m, "Failed to reload the logger and rotate log files");
6851 return 0;
6852 }
6853
6854 astman_send_ack(s, m, "Reloaded the logger and rotated log files");
6855 return 0;
6856}
int ast_logger_rotate(void)
Reload logger while rotating log files.
Definition logger.c:1307

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

3373{
3374
3375 /* still authenticated - don't process again */
3376 if (s->session->authenticated) {
3377 astman_send_ack(s, m, "Already authenticated");
3378 return 0;
3379 }
3380
3381 if (authenticate(s, m)) {
3382 sleep(1);
3383 astman_send_error(s, m, "Authentication failed");
3384 return -1;
3385 }
3386 s->session->authenticated = 1;
3389 ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_sockaddr_stringify_addr(&s->session->addr));
3390 }
3391 astman_send_ack(s, m, "Authentication accepted");
3394 && ast_fully_booted) {
3396 const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
3397 long uptime = 0;
3398 long lastreloaded = 0;
3399 struct timeval tmp;
3400 struct timeval curtime = ast_tvnow();
3401
3402 if (ast_startuptime.tv_sec) {
3403 tmp = ast_tvsub(curtime, ast_startuptime);
3404 uptime = tmp.tv_sec;
3405 }
3406
3407 if (ast_lastreloadtime.tv_sec) {
3408 tmp = ast_tvsub(curtime, ast_lastreloadtime);
3409 lastreloaded = tmp.tv_sec;
3410 }
3411
3412 astman_append(s, "Event: FullyBooted\r\n"
3413 "Privilege: %s\r\n"
3414 "Uptime: %ld\r\n"
3415 "LastReload: %ld\r\n"
3416 "Status: Fully Booted\r\n\r\n", cat_str, uptime, lastreloaded);
3417 }
3418 return 0;
3419}
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition manager.c:1071
static int unauth_sessions
Definition manager.c:178
static int authenticate(struct mansession *s, const struct message *m)
Definition manager.c:2346
#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
#define ast_fully_booted
Definition options.h:127
uint32_t managerid
Definition manager.c:285
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition extconf.c:2295

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

Referenced by __init_manager().

◆ action_logoff()

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

Definition at line 3366 of file manager.c.

3367{
3368 astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
3369 return -1;
3370}
void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg)
Send response in manager transaction.
Definition manager.c:1995

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

5458{
5459 const char *mailbox = astman_get_header(m, "Mailbox");
5460 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;;
5461
5462 if (ast_strlen_zero(mailbox)) {
5463 astman_send_error(s, m, "Mailbox not specified");
5464 return 0;
5465 }
5466 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs);
5467 astman_start_ack(s, m);
5468 astman_append(s, "Message: Mailbox Message Count\r\n"
5469 "Mailbox: %s\r\n"
5470 "UrgMessages: %d\r\n"
5471 "NewMessages: %d\r\n"
5472 "OldMessages: %d\r\n"
5473 "\r\n",
5474 mailbox, urgentmsgs, newmsgs, oldmsgs);
5475 return 0;
5476}
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(), and astman_start_ack().

Referenced by __init_manager().

◆ action_mailboxstatus()

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

Definition at line 5440 of file manager.c.

5441{
5442 const char *mailbox = astman_get_header(m, "Mailbox");
5443 int ret;
5444
5445 if (ast_strlen_zero(mailbox)) {
5446 astman_send_error(s, m, "Mailbox not specified");
5447 return 0;
5448 }
5449 ret = ast_app_has_voicemail(mailbox, NULL);
5450 astman_start_ack(s, m);
5451 astman_append(s, "Message: Mailbox Status\r\n"
5452 "Mailbox: %s\r\n"
5453 "Waiting: %d\r\n\r\n", mailbox, ret);
5454 return 0;
5455}
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(), and NULL.

Referenced by __init_manager().

◆ action_originate()

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

Definition at line 5245 of file manager.c.

5246{
5247 const char *name = astman_get_header(m, "Channel");
5248 const char *exten = astman_get_header(m, "Exten");
5249 const char *context = astman_get_header(m, "Context");
5250 const char *priority = astman_get_header(m, "Priority");
5251 const char *timeout = astman_get_header(m, "Timeout");
5252 const char *callerid = astman_get_header(m, "CallerID");
5253 const char *account = astman_get_header(m, "Account");
5254 const char *app = astman_get_header(m, "Application");
5255 const char *appdata = astman_get_header(m, "Data");
5256 const char *async = astman_get_header(m, "Async");
5257 const char *id = astman_get_header(m, "ActionID");
5258 const char *codecs = astman_get_header(m, "Codecs");
5259 const char *early_media = astman_get_header(m, "Earlymedia");
5260 struct ast_assigned_ids assignedids = {
5261 .uniqueid = astman_get_header(m, "ChannelId"),
5262 .uniqueid2 = astman_get_header(m, "OtherChannelId"),
5263 };
5264 const char *gosub = astman_get_header(m, "PreDialGoSub");
5265
5266 struct ast_variable *vars = NULL;
5267 char *tech, *data;
5268 char *l = NULL, *n = NULL;
5269 int pi = 0;
5270 int res;
5271 int to = 30000;
5272 int reason = 0;
5273 char tmp[256];
5274 char tmp2[256];
5276 pthread_t th;
5277 int bridge_early = 0;
5278
5279 if (!cap) {
5280 astman_send_error(s, m, "Internal Error. Memory allocation failure.");
5281 return 0;
5282 }
5284
5285 if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid))
5286 || (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) {
5287 astman_send_error_va(s, m, "Uniqueid length exceeds maximum of %d\n",
5289 res = 0;
5290 goto fast_orig_cleanup;
5291 }
5292
5293 if (ast_strlen_zero(name)) {
5294 astman_send_error(s, m, "Channel not specified");
5295 res = 0;
5296 goto fast_orig_cleanup;
5297 }
5298 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
5299 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
5300 astman_send_error(s, m, "Invalid priority");
5301 res = 0;
5302 goto fast_orig_cleanup;
5303 }
5304 }
5305 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
5306 astman_send_error(s, m, "Invalid timeout");
5307 res = 0;
5308 goto fast_orig_cleanup;
5309 }
5310 ast_copy_string(tmp, name, sizeof(tmp));
5311 tech = tmp;
5312 data = strchr(tmp, '/');
5313 if (!data) {
5314 astman_send_error(s, m, "Invalid channel");
5315 res = 0;
5316 goto fast_orig_cleanup;
5317 }
5318 *data++ = '\0';
5319 ast_copy_string(tmp2, callerid, sizeof(tmp2));
5320 ast_callerid_parse(tmp2, &n, &l);
5321 if (n) {
5322 if (ast_strlen_zero(n)) {
5323 n = NULL;
5324 }
5325 }
5326 if (l) {
5328 if (ast_strlen_zero(l)) {
5329 l = NULL;
5330 }
5331 }
5332 if (!ast_strlen_zero(codecs)) {
5335 }
5336
5337 if (!ast_strlen_zero(app) && s->session) {
5338 if (!is_originate_app_permitted(app, appdata, s->session->writeperm)) {
5339 astman_send_error(s, m, "Originate Access Forbidden: app or data blacklisted");
5340 res = 0;
5341 goto fast_orig_cleanup;
5342 }
5343 }
5344
5345 /* Check early if the extension exists. If not, we need to bail out here. */
5346 if (exten && context && pi) {
5347 if (! ast_exists_extension(NULL, context, exten, pi, l)) {
5348 /* The extension does not exist. */
5349 astman_send_error(s, m, "Extension does not exist.");
5350 res = 0;
5351 goto fast_orig_cleanup;
5352 }
5353 }
5354
5355 /* Allocate requested channel variables */
5356 vars = astman_get_variables(m);
5357 if (s->session && s->session->chanvars) {
5358 struct ast_variable *v, *old;
5359 old = vars;
5360 vars = NULL;
5361
5362 /* The variables in the AMI originate action are appended at the end of the list, to override any user variables that apply */
5363
5365 if (old) {
5366 for (v = vars; v->next; v = v->next );
5367 v->next = old; /* Append originate variables at end of list */
5368 }
5369 }
5370
5371 /* For originate async - we can bridge in early media stage */
5372 bridge_early = ast_true(early_media);
5373
5374 if (ast_true(async)) {
5375 struct fast_originate_helper *fast;
5376
5377 fast = ast_calloc(1, sizeof(*fast));
5378 if (!fast || ast_string_field_init(fast, 252)) {
5379 ast_free(fast);
5381 res = -1;
5382 } else {
5383 if (!ast_strlen_zero(id)) {
5384 ast_string_field_build(fast, idtext, "ActionID: %s\r\n", id);
5385 }
5390 ast_string_field_set(fast, cid_num, l);
5395 ast_string_field_set(fast, channelid, assignedids.uniqueid);
5396 ast_string_field_set(fast, otherchannelid, assignedids.uniqueid2);
5397 fast->vars = vars;
5398 fast->cap = cap;
5399 cap = NULL; /* transferred originate helper the capabilities structure. It is now responsible for freeing it. */
5400 fast->timeout = to;
5401 fast->early_media = bridge_early;
5402 fast->priority = pi;
5405 res = -1;
5406 } else {
5407 res = 0;
5408 }
5409 }
5410 } else if (!ast_strlen_zero(app)) {
5411 res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason,
5413 assignedids.uniqueid ? &assignedids : NULL);
5415 } else {
5416 if (exten && context && pi) {
5418 context, exten, pi, &reason, AST_OUTGOING_WAIT,
5419 l, n, vars, account, NULL, bridge_early,
5420 assignedids.uniqueid ? &assignedids : NULL , gosub);
5422 } else {
5423 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
5425 res = 0;
5426 goto fast_orig_cleanup;
5427 }
5428 }
5429 if (!res) {
5430 astman_send_ack(s, m, "Originate successfully queued");
5431 } else {
5432 astman_send_error(s, m, "Originate failed");
5433 }
5434
5435fast_orig_cleanup:
5437 return 0;
5438}
static const char app[]
#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.
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:5139
static void destroy_fast_originate_helper(struct fast_originate_helper *doomed)
Definition manager.c:4401
struct ast_variable * astman_get_variables(const struct message *m)
Get a linked list of the Variable: headers.
Definition manager.c:1747
static void * fast_originate(void *data)
Definition manager.c:4409
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition extconf.c:1260
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:4216
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:7970
@ AST_OUTGOING_WAIT
Definition pbx.h:1145
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:8024
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:4211
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
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:2233
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:4373
const ast_string_field appdata
Definition manager.c:4391
struct ast_variable * vars
Definition manager.c:4393
const ast_string_field cid_num
Definition manager.c:4391
const ast_string_field account
Definition manager.c:4391
const ast_string_field tech
Definition manager.c:4391
const ast_string_field data
Definition manager.c:4391
const ast_string_field context
Definition manager.c:4391
const ast_string_field channelid
Definition manager.c:4391
const ast_string_field otherchannelid
Definition manager.c:4391
struct ast_format_cap * cap
Definition manager.c:4375
const ast_string_field exten
Definition manager.c:4391
const ast_string_field idtext
Definition manager.c:4391
const ast_string_field cid_name
Definition manager.c:4391
struct ast_variable * chanvars
Definition manager.c:298
#define ast_pthread_create_detached(a, b, c, d)
Definition utils.h:628

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, destroy_fast_originate_helper(), fast_originate_helper::early_media, fast_originate(), is_originate_app_permitted(), name, ast_variable::next, NULL, priority, fast_originate_helper::priority, mansession::session, fast_originate_helper::timeout, ast_assigned_ids::uniqueid, ast_assigned_ids::uniqueid2, fast_originate_helper::vars, and mansession_session::writeperm.

Referenced by __init_manager().

◆ action_ping()

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

Definition at line 2443 of file manager.c.

2444{
2445 const char *actionid = astman_get_header(m, "ActionID");
2446 struct timeval now = ast_tvnow();
2447
2448 astman_append(s, "Response: Success\r\n");
2449 if (!ast_strlen_zero(actionid)){
2450 astman_append(s, "ActionID: %s\r\n", actionid);
2451 }
2453 s,
2454 "Ping: Pong\r\n"
2455 "Timestamp: %ld.%06lu\r\n"
2456 "\r\n",
2457 (long) now.tv_sec, (unsigned long) now.tv_usec);
2458 return 0;
2459}

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

5509{
5510 const char *provider = astman_get_header(m, "Provider");
5512 char *subtype;
5513 char *message;
5514
5516 astman_send_error(s, m, "No provider specified");
5517 return 0;
5518 }
5519
5521 if (state == AST_PRESENCE_INVALID) {
5522 astman_send_error_va(s, m, "Invalid provider %s or provider in invalid state", provider);
5523 return 0;
5524 }
5525
5526 astman_start_ack(s, m);
5527 astman_append(s, "Message: Presence State\r\n"
5528 "State: %s\r\n", ast_presence_state2str(state));
5529
5530 if (!ast_strlen_zero(subtype)) {
5531 astman_append(s, "Subtype: %s\r\n", subtype);
5532 }
5533
5534 if (!ast_strlen_zero(message)) {
5535 /* XXX The Message header here is deprecated as it
5536 * duplicates the action response header 'Message'.
5537 * Remove it in the next major revision of AMI.
5538 */
5539 astman_append(s, "Message: %s\r\n"
5540 "PresenceMessage: %s\r\n",
5541 message, message);
5542 }
5543 astman_append(s, "\r\n");
5544
5545 ast_free(subtype);
5547
5548 return 0;
5549}
static struct prometheus_metrics_provider provider
Definition bridges.c:201
ast_presence_state
@ AST_PRESENCE_INVALID
const char * ast_presence_state2str(enum ast_presence_state state)
Convert presence state to text string for output.

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

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

3972{
3973 char buf[256];
3974 const char *name = astman_get_header(m, "Channel");
3975 const char *name2 = astman_get_header(m, "ExtraChannel");
3976 const char *exten = astman_get_header(m, "Exten");
3977 const char *exten2 = astman_get_header(m, "ExtraExten");
3978 const char *context = astman_get_header(m, "Context");
3979 const char *context2 = astman_get_header(m, "ExtraContext");
3980 const char *priority = astman_get_header(m, "Priority");
3981 const char *priority2 = astman_get_header(m, "ExtraPriority");
3982 struct ast_channel *chan;
3983 struct ast_channel *chan2;
3984 int pi = 0;
3985 int pi2 = 0;
3986 int res;
3987 int chan1_wait = 0;
3988 int chan2_wait = 0;
3989
3990 if (ast_strlen_zero(name)) {
3991 astman_send_error(s, m, "Channel not specified");
3992 return 0;
3993 }
3994
3995 if (ast_strlen_zero(context)) {
3996 astman_send_error(s, m, "Context not specified");
3997 return 0;
3998 }
3999 if (ast_strlen_zero(exten)) {
4000 astman_send_error(s, m, "Exten not specified");
4001 return 0;
4002 }
4004 astman_send_error(s, m, "Priority not specified");
4005 return 0;
4006 }
4007 if (sscanf(priority, "%30d", &pi) != 1) {
4009 }
4010 if (pi < 1) {
4011 astman_send_error(s, m, "Priority is invalid");
4012 return 0;
4013 }
4014
4015 if (!ast_strlen_zero(name2) && !ast_strlen_zero(context2)) {
4016 /* We have an ExtraChannel and an ExtraContext */
4017 if (ast_strlen_zero(exten2)) {
4018 astman_send_error(s, m, "ExtraExten not specified");
4019 return 0;
4020 }
4021 if (ast_strlen_zero(priority2)) {
4022 astman_send_error(s, m, "ExtraPriority not specified");
4023 return 0;
4024 }
4025 if (sscanf(priority2, "%30d", &pi2) != 1) {
4026 pi2 = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL);
4027 }
4028 if (pi2 < 1) {
4029 astman_send_error(s, m, "ExtraPriority is invalid");
4030 return 0;
4031 }
4032 }
4033
4035 if (!chan) {
4036 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
4037 astman_send_error(s, m, buf);
4038 return 0;
4039 }
4040 if (ast_check_hangup_locked(chan)) {
4041 astman_send_error(s, m, "Redirect failed, channel not up.");
4042 chan = ast_channel_unref(chan);
4043 return 0;
4044 }
4045
4046 if (ast_strlen_zero(name2)) {
4047 /* Single channel redirect in progress. */
4049 if (!res) {
4050 astman_send_ack(s, m, "Redirect successful");
4051 } else {
4052 astman_send_error(s, m, "Redirect failed");
4053 }
4054 chan = ast_channel_unref(chan);
4055 return 0;
4056 }
4057
4058 chan2 = ast_channel_get_by_name(name2);
4059 if (!chan2) {
4060 snprintf(buf, sizeof(buf), "ExtraChannel does not exist: %s", name2);
4061 astman_send_error(s, m, buf);
4062 chan = ast_channel_unref(chan);
4063 return 0;
4064 }
4065 if (ast_check_hangup_locked(chan2)) {
4066 astman_send_error(s, m, "Redirect failed, extra channel not up.");
4067 chan2 = ast_channel_unref(chan2);
4068 chan = ast_channel_unref(chan);
4069 return 0;
4070 }
4071
4072 /* Dual channel redirect in progress. */
4073 ast_channel_lock(chan);
4074 if (ast_channel_is_bridged(chan)) {
4076 chan1_wait = 1;
4077 }
4078 ast_channel_unlock(chan);
4079
4080 ast_channel_lock(chan2);
4081 if (ast_channel_is_bridged(chan2)) {
4083 chan2_wait = 1;
4084 }
4085 ast_channel_unlock(chan2);
4086
4088 if (!res) {
4089 if (!ast_strlen_zero(context2)) {
4090 res = async_goto_with_discard_bridge_after(chan2, context2, exten2, pi2);
4091 } else {
4093 }
4094 if (!res) {
4095 astman_send_ack(s, m, "Dual Redirect successful");
4096 } else {
4097 astman_send_error(s, m, "Secondary redirect failed");
4098 }
4099 } else {
4100 astman_send_error(s, m, "Redirect failed");
4101 }
4102
4103 /* Release the bridge wait. */
4104 if (chan1_wait) {
4106 }
4107 if (chan2_wait) {
4109 }
4110
4111 chan2 = ast_channel_unref(chan2);
4112 chan = ast_channel_unref(chan);
4113 return 0;
4114}
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition channel.c:11144
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_check_hangup_locked(struct ast_channel *chan)
Definition channel.c:460
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition channel.c:10655
@ AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT
Definition channel.h:1055
static int async_goto_with_discard_bridge_after(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition manager.c:3964
#define ast_set_flag(p, flag)
Definition utils.h:71

References ast_channel_clear_flag(), ast_channel_flags(), ast_channel_get_by_name(), ast_channel_is_bridged(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_check_hangup_locked(), ast_findlabel_extension(), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT, ast_set_flag, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), async_goto_with_discard_bridge_after(), buf, 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 6566 of file manager.c.

6567{
6568 const char *module = astman_get_header(m, "Module");
6570
6571 switch (res) {
6573 astman_send_error(s, m, "No such module");
6574 break;
6576 astman_send_error(s, m, "Module does not support reload");
6577 break;
6579 astman_send_error(s, m, "An unknown error occurred");
6580 break;
6582 astman_send_error(s, m, "A reload is in progress");
6583 break;
6585 astman_send_error(s, m, "Module not initialized");
6586 break;
6589 /* Treat a queued request as success */
6590 astman_send_ack(s, m, "Module Reloaded");
6591 break;
6592 }
6593 return 0;
6594}
ast_module_reload_result
Possible return types for ast_module_reload.
Definition module.h:109
@ AST_MODULE_RELOAD_IN_PROGRESS
Definition module.h:114
@ AST_MODULE_RELOAD_QUEUED
Definition module.h:111
@ AST_MODULE_RELOAD_SUCCESS
Definition module.h:110
@ AST_MODULE_RELOAD_ERROR
Definition module.h:113
@ AST_MODULE_RELOAD_NOT_IMPLEMENTED
Definition module.h:116
@ AST_MODULE_RELOAD_NOT_FOUND
Definition module.h:112
@ AST_MODULE_RELOAD_UNINITIALIZED
Definition module.h:115
enum ast_module_reload_result ast_module_reload(const char *name)
Reload asterisk modules.
Definition loader.c:1730

References ast_module_reload(), AST_MODULE_RELOAD_ERROR, AST_MODULE_RELOAD_IN_PROGRESS, AST_MODULE_RELOAD_NOT_FOUND, AST_MODULE_RELOAD_NOT_IMPLEMENTED, AST_MODULE_RELOAD_QUEUED, AST_MODULE_RELOAD_SUCCESS, AST_MODULE_RELOAD_UNINITIALIZED, astman_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 3922 of file manager.c.

3923{
3924 struct ast_channel *c;
3925 const char *name = astman_get_header(m, "Channel");
3926 const char *textmsg = astman_get_header(m, "Message");
3927 const char *content_type = astman_get_header(m, "Content-Type");
3928 int res;
3929
3930 if (ast_strlen_zero(name)) {
3931 astman_send_error(s, m, "No channel specified");
3932 return 0;
3933 }
3934
3935 if (ast_strlen_zero(textmsg)) {
3936 astman_send_error(s, m, "No Message specified");
3937 return 0;
3938 }
3939
3941 if (!c) {
3942 astman_send_error(s, m, "No such channel");
3943 return 0;
3944 }
3945
3946 /*
3947 * If the "extra" data is not available, then send using "string" only.
3948 * Doing such maintains backward compatibilities.
3949 */
3950 res = ast_strlen_zero(content_type) ? queue_sendtext(c, textmsg) :
3951 queue_sendtext_data(c, textmsg, content_type);
3952
3954
3955 if (res >= 0) {
3956 astman_send_ack(s, m, "Success");
3957 } else {
3958 astman_send_error(s, m, "Failure");
3959 }
3960
3961 return 0;
3962}
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:3903
static int queue_sendtext(struct ast_channel *chan, const char *body)
Queue a read action to send a text message.
Definition manager.c:3887

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

3567{
3568 struct ast_channel *c = NULL;
3569 const char *name = astman_get_header(m, "Channel");
3570 const char *varname = astman_get_header(m, "Variable");
3571 const char *varval = astman_get_header(m, "Value");
3572 int res = 0;
3573
3574 if (ast_strlen_zero(varname)) {
3575 astman_send_error(s, m, "No variable specified");
3576 return 0;
3577 }
3578
3579 if (!ast_strlen_zero(name)) {
3580 if (!(c = ast_channel_get_by_name(name))) {
3581 astman_send_error(s, m, "No such channel");
3582 return 0;
3583 }
3584 }
3585
3586 res = pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
3587
3588 if (c) {
3590 }
3591 if (res == 0) {
3592 astman_send_ack(s, m, "Variable Set");
3593 } else {
3594 astman_send_error(s, m, "Variable not set");
3595 }
3596 return 0;
3597}

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

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

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

Referenced by __init_manager().

◆ action_timeout()

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

Definition at line 5551 of file manager.c.

5552{
5553 struct ast_channel *c;
5554 const char *name = astman_get_header(m, "Channel");
5555 double timeout = atof(astman_get_header(m, "Timeout"));
5556 struct timeval when = { timeout, 0 };
5557
5558 if (ast_strlen_zero(name)) {
5559 astman_send_error(s, m, "No channel specified");
5560 return 0;
5561 }
5562
5563 if (!timeout || timeout < 0) {
5564 astman_send_error(s, m, "No timeout specified");
5565 return 0;
5566 }
5567
5568 if (!(c = ast_channel_get_by_name(name))) {
5569 astman_send_error(s, m, "No such channel");
5570 return 0;
5571 }
5572
5573 when.tv_usec = (timeout - when.tv_sec) * 1000000.0;
5574
5579
5580 astman_send_ack(s, m, "Timeout Set");
5581
5582 return 0;
5583}
void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
Set when to hang a channel up.
Definition channel.c:511

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

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

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

Referenced by __init_manager().

◆ action_userevent()

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

Definition at line 6459 of file manager.c.

6460{
6461 const char *event = astman_get_header(m, "UserEvent");
6462 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
6463 int x;
6464
6465 ast_str_reset(body);
6466
6467 for (x = 0; x < m->hdrcount; x++) {
6468 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:")) &&
6469 strncasecmp("Action:", m->headers[x], strlen("Action:"))) {
6470 ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
6471 }
6472 }
6473
6474 astman_send_ack(s, m, "Event Sent");
6475 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body));
6476 return 0;
6477}
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition manager.h:255
#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, and manager_event.

Referenced by __init_manager().

◆ action_waitevent()

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

Definition at line 3185 of file manager.c.

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

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, eventqent::eventdata, 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 1594 of file manager.c.

1595{
1596 struct eventqent *next;
1597
1599 if ((next = AST_RWLIST_NEXT(e, eq_next))) {
1602 }
1604 return next;
1605}
struct eventqent::@397 eq_next
int usecount
Definition manager.c:150
struct eventqent * next
Definition manager.c:155

References ast_atomic_fetchadd_int(), AST_RWLIST_NEXT, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, eventqent::eq_next, eventqent::next, 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 4489 of file manager.c.

4490{
4491 const char *unitamount;
4492 const char *unittype;
4493 struct ast_str *str = ast_str_alloca(32);
4494
4495 memset(entry, 0, sizeof(*entry));
4496
4497 ast_str_set(&str, 0, "UnitAmount(%u)", entry_num);
4498 unitamount = astman_get_header(m, ast_str_buffer(str));
4499
4500 ast_str_set(&str, 0, "UnitType(%u)", entry_num);
4501 unittype = astman_get_header(m, ast_str_buffer(str));
4502
4503 if (!ast_strlen_zero(unitamount) && (sscanf(unitamount, "%30u", &entry->amount) == 1)) {
4504 entry->valid_amount = 1;
4505 }
4506
4507 if (!ast_strlen_zero(unittype) && sscanf(unittype, "%30u", &entry->type) == 1) {
4508 entry->valid_type = 1;
4509 }
4510
4511 return 0;
4512}
const char * str
Definition app_jack.c:150
unsigned int amount
Definition aoc.h:180
unsigned int type
Definition aoc.h:182
char valid_type
Definition aoc.h:181
char valid_amount
Definition aoc.h:179

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

Referenced by action_aoc_de_message().

◆ app_match()

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

Definition at line 5027 of file manager.c.

5028{
5029 /*
5030 * We use strcasestr so we don't have to trim any blanks
5031 * from the front or back of the string.
5032 */
5033 return !!(strcasestr(app, search));
5034}
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 5046 of file manager.c.

5047{
5048 if (ast_strlen_zero(data)) {
5049 return 0;
5050 }
5051 return !!(strstr(data, search));
5052}

References ast_strlen_zero().

◆ append_channel_vars()

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

Definition at line 7539 of file manager.c.

7540{
7541 struct varshead *vars;
7542 struct ast_var_t *var;
7543
7544 vars = ast_channel_get_manager_vars(chan);
7545 if (!vars) {
7546 return;
7547 }
7548
7549 AST_LIST_TRAVERSE(vars, var, entries) {
7550 ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", ast_channel_name(chan), var->name, var->value);
7551 }
7552 ao2_ref(vars, -1);
7553}
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:8030
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.
struct ast_var_t::@220 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 7514 of file manager.c.

7515{
7516 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
7517 static int seq; /* sequence number */
7518
7519 if (!tmp) {
7520 return -1;
7521 }
7522
7523 /* need to init all fields, because ast_malloc() does not */
7524 tmp->usecount = 0;
7525 tmp->category = category;
7526 tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
7527 tmp->tv = ast_tvnow();
7530 strcpy(tmp->eventdata, str);
7531
7535
7536 return 0;
7537}
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition linkedlists.h:52
#define AST_RWLIST_INSERT_TAIL
unsigned int seq
Definition manager.c:152
struct timeval tv
Definition manager.c:153
int event_name_hash
Definition manager.c:154

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

Referenced by __init_manager(), and __manager_event_sessions_va().

◆ ast_hook_send_action()

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

access for hooks to send action messages to ami

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

Definition at line 1778 of file manager.c.

1779{
1780 const char *action;
1781 int ret = 0;
1782 struct manager_action *act_found;
1783 struct mansession s = {.session = NULL, };
1784 struct message m = { 0 };
1785 char *dup_str;
1786 char *src;
1787 int x = 0;
1788 int curlen;
1789
1790 if (hook == NULL) {
1791 return -1;
1792 }
1793
1794 /* Create our own copy of the AMI action msg string. */
1795 src = dup_str = ast_strdup(msg);
1796 if (!dup_str) {
1797 return -1;
1798 }
1799
1800 /* convert msg string to message struct */
1801 curlen = strlen(src);
1802 for (x = 0; x < curlen; x++) {
1803 int cr; /* set if we have \r */
1804 if (src[x] == '\r' && x+1 < curlen && src[x+1] == '\n')
1805 cr = 2; /* Found. Update length to include \r\n */
1806 else if (src[x] == '\n')
1807 cr = 1; /* also accept \n only */
1808 else
1809 continue;
1810 /* don't keep empty lines */
1811 if (x && m.hdrcount < ARRAY_LEN(m.headers)) {
1812 /* ... but trim \r\n and terminate the header string */
1813 src[x] = '\0';
1814 m.headers[m.hdrcount++] = src;
1815 }
1816 x += cr;
1817 curlen -= x; /* remaining size */
1818 src += x; /* update pointer */
1819 x = -1; /* reset loop */
1820 }
1821
1822 action = astman_get_header(&m, "Action");
1823
1824 do {
1825 if (!strcasecmp(action, "login")) {
1826 break;
1827 }
1828
1829 act_found = action_find(action);
1830 if (!act_found) {
1831 break;
1832 }
1833
1834 /*
1835 * we have to simulate a session for this action request
1836 * to be able to pass it down for processing
1837 * This is necessary to meet the previous design of manager.c
1838 */
1839 s.hook = hook;
1840
1841 ret = -1;
1842 ao2_lock(act_found);
1843 if (act_found->registered && act_found->func) {
1844 struct ast_module *mod_ref = ast_module_running_ref(act_found->module);
1845
1846 ao2_unlock(act_found);
1847 /* If the action is in a module it must be running. */
1848 if (!act_found->module || mod_ref) {
1849 ret = act_found->func(&s, &m);
1850 ast_module_unref(mod_ref);
1851 }
1852 } else {
1853 ao2_unlock(act_found);
1854 }
1855 ao2_t_ref(act_found, -1, "done with found action object");
1856 } while (0);
1857
1858 ast_free(dup_str);
1859 return ret;
1860}
static struct manager_action * action_find(const char *name)
Definition manager.c:434
#define ast_module_unref(mod)
Release a reference to the module.
Definition module.h:483
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition module.h:469
int(* func)(struct mansession *s, const struct message *m)
Definition manager.h:171
unsigned int registered
TRUE if the AMI action is registered and the callback can be called.
Definition manager.h:183
In case you didn't read that giant block of text above the mansession_session struct,...
Definition manager.c:323
struct manager_custom_hook * hook
Definition manager.c:329

References action_find(), ao2_lock, ao2_t_ref, ao2_unlock, ARRAY_LEN, ast_free, ast_module_running_ref, ast_module_unref, ast_strdup, astman_get_header(), manager_action::func, message::hdrcount, message::headers, mansession::hook, 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 855 of file manager.c.

856{
857 const char *val = bigstr, *next;
858
859 do {
860 if ((next = strchr(val, delim))) {
861 if (!strncmp(val, smallstr, (next - val))) {
862 return 1;
863 } else {
864 continue;
865 }
866 } else {
867 return !strcmp(smallstr, val);
868 }
869 } while (*(val = (next + 1)));
870
871 return 0;
872}

Referenced by get_perm().

◆ ast_manager_check_enabled()

int ast_manager_check_enabled ( void  )

Check if AMI is enabled.

Definition at line 692 of file manager.c.

693{
694 return manager_enabled;
695}
static int manager_enabled
Definition manager.c:166

References manager_enabled.

Referenced by handle_show_settings().

◆ ast_manager_get_message_router()

struct stasis_message_router * ast_manager_get_message_router ( void  )

Get the stasis_message_router for AMI.

Since
12
Returns
The stasis_message_router for AMI
Return values
NULLon error

Definition at line 455 of file manager.c.

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

References stasis_router.

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

◆ ast_manager_get_topic()

struct stasis_topic * ast_manager_get_topic ( void  )

Get the Stasis Message Bus API topic for AMI.

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

Definition at line 450 of file manager.c.

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

References manager_topic.

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

◆ ast_manager_hangup_helper()

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

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

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

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

Definition at line 3439 of file manager.c.

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

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

647{
648 RAII_VAR(struct ast_json *, event_info, NULL, ast_json_unref);
649 RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
651
652 if (!obj || !ast_manager_get_generic_type()) {
653 return;
654 }
655
656 ast_json_ref(obj);
657 event_info = ast_json_pack("{s: s, s: i, s: o}",
658 "type", type,
659 "class_type", class_type,
660 "event", obj);
661 if (!event_info) {
662 return;
663 }
664
665 payload = ast_json_payload_create(event_info);
666 if (!payload) {
667 return;
668 }
670 if (!message) {
671 return;
672 }
674}
static const char type[]
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
Definition manager.c:450
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition json.c:73
struct ast_json_payload * ast_json_payload_create(struct ast_json *json)
Create an ao2 object to pass json blobs as data payloads for stasis.
Definition json.c:756
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition json.c:612
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition json.c:67
struct stasis_message_type * ast_manager_get_generic_type(void)
Get the stasis_message_type for generic messages.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition stasis.c:1578
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 7842 of file manager.c.

7843{
7844 struct manager_action *cur;
7845
7846 cur = ao2_t_alloc(sizeof(*cur), action_destroy, action);
7847 if (!cur) {
7848 return -1;
7849 }
7850 if (ast_string_field_init(cur, 128)) {
7851 ao2_t_ref(cur, -1, "action object creation failed");
7852 return -1;
7853 }
7854
7855 if (ast_string_field_init_extended(cur, since)) {
7856 ao2_t_ref(cur, -1, "action object creation failed");
7857 return -1;
7858 }
7859
7860 if (ast_string_field_init_extended(cur, provided_by)) {
7861 ao2_t_ref(cur, -1, "action object creation failed");
7862 return -1;
7863 }
7864
7865 cur->action = action;
7866 cur->authority = auth;
7867 cur->func = func;
7868 cur->module = module;
7869#ifdef AST_XML_DOCS
7871 char *tmpxml;
7872
7873 tmpxml = ast_xmldoc_build_since("manager", action, NULL);
7874 ast_string_field_set(cur, since, tmpxml);
7875 ast_free(tmpxml);
7876
7877 tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL);
7878 ast_string_field_set(cur, synopsis, tmpxml);
7879 ast_free(tmpxml);
7880
7881 tmpxml = ast_xmldoc_build_provided_by("manager", action, NULL);
7882 ast_string_field_set(cur, provided_by, tmpxml);
7883 ast_free(tmpxml);
7884
7885 tmpxml = ast_xmldoc_build_syntax("manager", action, NULL);
7886 ast_string_field_set(cur, syntax, tmpxml);
7887 ast_free(tmpxml);
7888
7889 tmpxml = ast_xmldoc_build_description("manager", action, NULL);
7890 ast_string_field_set(cur, description, tmpxml);
7891 ast_free(tmpxml);
7892
7893 tmpxml = ast_xmldoc_build_seealso("manager", action, NULL);
7894 ast_string_field_set(cur, seealso, tmpxml);
7895 ast_free(tmpxml);
7896
7897 tmpxml = ast_xmldoc_build_arguments("manager", action, NULL);
7898 ast_string_field_set(cur, arguments, tmpxml);
7899 ast_free(tmpxml);
7900
7903
7904 cur->docsrc = AST_XML_DOC;
7905 } else
7906#endif
7907 {
7910#ifdef AST_XML_DOCS
7911 cur->docsrc = AST_STATIC_DOC;
7912#endif
7913 }
7914 if (ast_manager_register_struct(cur)) {
7915 ao2_t_ref(cur, -1, "action object registration failed");
7916 return -1;
7917 }
7918
7919 ao2_t_ref(cur, -1, "action object registration successful");
7920 return 0;
7921}
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
Definition astobj2.h:407
static char * synopsis
Definition func_enum.c:166
static int ast_manager_register_struct(struct manager_action *act)
Definition manager.c:7787
static void action_destroy(void *obj)
Definition manager.c:7828
#define ast_string_field_init_extended(x, field)
Initialize an extended string field.
struct ast_module *enum ast_doc_src docsrc
Definition manager.h:174
const ast_string_field description
Definition manager.h:163
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:2648
char * ast_xmldoc_build_description(const char *type, const char *name, const char *module)
Generate description documentation from XML.
Definition xmldoc.c:2418
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:2231
char * ast_xmldoc_build_synopsis(const char *type, const char *name, const char *module)
Generate synopsis documentation from XML.
Definition xmldoc.c:2395
char * ast_xmldoc_build_since(const char *type, const char *name, const char *module)
Parse the <since> node content.
Definition xmldoc.c:1792
@ 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:1707
char * ast_xmldoc_build_provided_by(const char *type, const char *name, const char *module)
Generate provided-by documentation from XML.
Definition xmldoc.c:1844
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:2718

References manager_action::action, action_destroy(), ao2_t_alloc, ao2_t_ref, ast_free, ast_manager_register_struct(), AST_STATIC_DOC, ast_string_field_init, ast_string_field_init_extended, ast_string_field_set, ast_strlen_zero(), AST_XML_DOC, ast_xmldoc_build_arguments(), ast_xmldoc_build_description(), ast_xmldoc_build_final_response(), ast_xmldoc_build_list_responses(), ast_xmldoc_build_provided_by(), ast_xmldoc_build_seealso(), ast_xmldoc_build_since(), ast_xmldoc_build_synopsis(), ast_xmldoc_build_syntax(), manager_action::authority, manager_action::docsrc, manager_action::final_response, manager_action::func, manager_action::list_responses, 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 677 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 7787 of file manager.c.

7788{
7789 struct manager_action *cur, *prev = NULL;
7790
7793 int ret;
7794
7795 ret = strcasecmp(cur->action, act->action);
7796 if (ret == 0) {
7797 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
7799 return -1;
7800 }
7801 if (ret > 0) { /* Insert these alphabetically */
7802 break;
7803 }
7804 prev = cur;
7805 }
7806
7807 ao2_t_ref(act, +1, "action object added to list");
7808 act->registered = 1;
7809 if (prev) {
7810 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list);
7811 } else {
7813 }
7814
7815 ast_verb(5, "Manager registered action %s\n", act->action);
7816
7818
7819 return 0;
7820}
#define LOG_WARNING
#define AST_RWLIST_INSERT_AFTER
#define AST_RWLIST_INSERT_HEAD

References manager_action::action, ao2_t_ref, ast_log, AST_RWLIST_INSERT_AFTER, AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, LOG_WARNING, NULL, ast_category::prev, and manager_action::registered.

Referenced by ast_manager_register2().

◆ ast_manager_str_from_json_object()

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

Convert a JSON object into an AMI compatible string.

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

Definition at line 551 of file manager.c.

552{
553 struct ast_str *res = ast_str_create(1024);
554
555 if (!ast_json_is_null(blob)) {
556 manager_json_to_ast_str(blob, NULL, &res, exclusion_cb);
557 }
558
559 return res;
560}
static void manager_json_to_ast_str(struct ast_json *obj, const char *key, struct ast_str **res, key_exclusion_cb exclusion_cb)
Definition manager.c:510
int ast_json_is_null(const struct ast_json *value)
Check if value is JSON null.
Definition json.c:273

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

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

◆ ast_manager_unregister()

int ast_manager_unregister ( const char *  action)

support functions to register/unregister AMI action handlers,

Unregister a registered manager command.

Definition at line 7716 of file manager.c.

7717{
7718 struct manager_action *cur;
7719
7722 if (!strcasecmp(action, cur->action)) {
7724 break;
7725 }
7726 }
7729
7730 if (cur) {
7731 /*
7732 * We have removed the action object from the container so we
7733 * are no longer in a hurry.
7734 */
7735 ao2_lock(cur);
7736 cur->registered = 0;
7737 ao2_unlock(cur);
7738
7739 ao2_t_ref(cur, -1, "action object removed from list");
7740 ast_verb(5, "Manager unregistered action %s\n", action);
7741 }
7742
7743 return 0;
7744}
#define AST_RWLIST_REMOVE_CURRENT
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
#define AST_RWLIST_TRAVERSE_SAFE_END

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(), __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(), load_module(), local_shutdown(), manager_bridging_cleanup(), manager_shutdown(), message_shutdown(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), 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 685 of file manager.c.

686{
688 AST_RWLIST_REMOVE(&manager_hooks, hook, list);
690}
#define AST_RWLIST_REMOVE

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

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

◆ AST_THREADSTORAGE_CUSTOM_SCOPE() [1/3]

AST_THREADSTORAGE_CUSTOM_SCOPE ( astman_append_buf  ,
NULL  ,
ast_free_ptr  ,
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.

◆ AST_THREADSTORAGE_CUSTOM_SCOPE() [2/3]

AST_THREADSTORAGE_CUSTOM_SCOPE ( manager_event_buf  ,
NULL  ,
ast_free_ptr  ,
static   
)

◆ AST_THREADSTORAGE_CUSTOM_SCOPE() [3/3]

AST_THREADSTORAGE_CUSTOM_SCOPE ( userevent_buf  ,
NULL  ,
ast_free_ptr  ,
static   
)

◆ ast_webmanager_check_enabled()

int ast_webmanager_check_enabled ( void  )

Check if AMI/HTTP is enabled.

Definition at line 697 of file manager.c.

698{
700}
static int webmanager_enabled
Definition manager.c:168

References manager_enabled, and webmanager_enabled.

Referenced by action_coresettings(), and handle_show_settings().

◆ astman_append()

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

utility functions for creating AMI replies

Definition at line 1921 of file manager.c.

1922{
1923 int res;
1924 va_list ap;
1925 struct ast_str *buf;
1926
1927 if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) {
1928 return;
1929 }
1930
1931 va_start(ap, fmt);
1932 res = ast_str_set_va(&buf, 0, fmt, ap);
1933 va_end(ap);
1934 if (res == AST_DYNSTR_BUILD_FAILED) {
1935 return;
1936 }
1937
1938 if (s->hook || (s->tcptls_session != NULL && s->tcptls_session->stream != NULL)) {
1940 } else {
1941 ast_verbose("No connection stream in astman_append, should not happen\n");
1942 }
1943}
#define ASTMAN_APPEND_BUF_INITSIZE
initial allocated size for the astman_append_buf and astman_send_*_va
Definition manager.c:1907
static int send_string(struct mansession *s, char *string)
Definition manager.c:1866
#define ast_verbose(...)
int ast_str_set_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Set a dynamic string from a va_list.
Definition strings.h:1030
@ AST_DYNSTR_BUILD_FAILED
Definition strings.h:943
struct ast_iostream * stream
Definition tcptls.h:162
struct ast_tcptls_session_instance * tcptls_session
Definition manager.c:326

References AST_DYNSTR_BUILD_FAILED, ast_str_buffer(), ast_str_set_va(), ast_str_thread_get(), ast_verbose, ASTMAN_APPEND_BUF_INITSIZE, buf, mansession::hook, NULL, send_string(), ast_iostream::start, 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_maint_entry_cb(), ami_outbound_registration_task(), ami_registrations_aor(), ami_show_maintenance(), 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 1671 of file manager.c.

1672{
1673 const struct ast_variable *v;
1674
1675 for (v = params; v && m->hdrcount < ARRAY_LEN(m->headers); v = v->next) {
1676 if (ast_asprintf((char**)&m->headers[m->hdrcount], "%s: %s", v->name, v->value) > -1) {
1677 ++m->hdrcount;
1678 }
1679 }
1680}

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

2655{
2656 char *buf;
2657
2658 buf = ast_alloca(2 * strlen(str) + 1);
2660 astman_append(s, "%s", buf);
2661}
#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:2636

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

1910{
1911 if (s->hook || (s->tcptls_session && s->tcptls_session->stream)) {
1913 } else {
1914 ast_verbose("No connection stream in astman_append, should not happen\n");
1915 }
1916}

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

1686{
1687 while (m->hdrcount) {
1688 --m->hdrcount;
1689 ast_free((void *) m->headers[m->hdrcount]);
1690 m->headers[m->hdrcount] = NULL;
1691 }
1692}

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

1662{
1664}
#define GET_HEADER_FIRST_MATCH
Definition manager.c:1607

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_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), action_waitevent(), ami_register(), ami_set_maintenance(), ami_show_aors(), ami_show_auths(), ami_show_contacts(), ami_show_endpoint(), ami_show_endpoints(), ami_show_maintenance(), 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 1747 of file manager.c.

1748{
1750}
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:1752
@ ORDER_REVERSE
Definition manager.h:291

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

1754{
1755 int varlen;
1756 int x;
1757 struct ast_variable *head = NULL;
1758
1759 static const char var_hdr[] = "Variable:";
1760
1761 /* Process all "Variable:" headers. */
1762 varlen = strlen(var_hdr);
1763 for (x = 0; x < m->hdrcount; x++) {
1764 if (strncasecmp(var_hdr, m->headers[x], varlen)) {
1765 continue;
1766 }
1767 head = man_do_variable_value(head, m->headers[x] + varlen);
1768 }
1769
1770 if (order == ORDER_NATURAL) {
1771 head = ast_variables_reverse(head);
1772 }
1773
1774 return head;
1775}
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:1703
struct ast_variable * ast_variables_reverse(struct ast_variable *var)
Reverse a variable list.
@ ORDER_NATURAL
Definition manager.h:290

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

2462{
2463 if (new_live_dangerously && !live_dangerously)
2464 {
2465 ast_log(LOG_WARNING, "Manager Configuration load protection disabled.\n");
2466 }
2467
2468 if (!new_live_dangerously && live_dangerously)
2469 {
2470 ast_log(LOG_NOTICE, "Manager Configuration load protection enabled.\n");
2471 }
2472 live_dangerously = new_live_dangerously;
2473}

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

2033{
2034 astman_send_response_full(s, m, "Success", msg, NULL);
2035}

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

2001{
2002 astman_send_response_full(s, m, "Error", error, NULL);
2003}

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

2006{
2007 int res;
2008 va_list ap;
2009 struct ast_str *buf;
2010 char *msg;
2011
2012 if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) {
2013 return;
2014 }
2015
2016 va_start(ap, fmt);
2017 res = ast_str_set_va(&buf, 0, fmt, ap);
2018 va_end(ap);
2019 if (res == AST_DYNSTR_BUILD_FAILED) {
2020 return;
2021 }
2022
2023 /* astman_append will use the same underlying buffer, so copy the message out
2024 * before sending the response */
2025 msg = ast_str_buffer(buf);
2026 if (msg) {
2027 msg = ast_strdupa(msg);
2028 }
2029 astman_send_response_full(s, m, "Error", msg, NULL);
2030}

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

Referenced by action_command(), action_originate(), action_presencestate(), ami_set_maintenance(), 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 2069 of file manager.c.

2070{
2071 struct ast_str *buf = astman_send_list_complete_start_common(s, m, event_name, count);
2072 if (buf) {
2073 ast_str_append(&buf, 0, "\r\n");
2074 astman_flush(s, buf);
2075 }
2076}
static void astman_flush(struct mansession *s, struct ast_str *buf)
Definition manager.c:1909
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:2047

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

2087{
2088 astman_append(s, "\r\n");
2089}

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

2079{
2080 struct ast_str *buf = astman_send_list_complete_start_common(s, m, event_name, count);
2081 if (buf) {
2082 astman_flush(s, buf);
2083 }
2084}

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

2048{
2049 const char *id = astman_get_header(m, "ActionID");
2050 struct ast_str *buf;
2051
2052 buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE);
2053 if (!buf) {
2054 return NULL;
2055 }
2056
2057 ast_str_set(&buf, 0, "Event: %s\r\n", event_name);
2058 if (!ast_strlen_zero(id)) {
2059 ast_str_append(&buf, 0, "ActionID: %s\r\n", id);
2060 }
2061 ast_str_append(&buf, 0,
2062 "EventList: Complete\r\n"
2063 "ListItems: %d\r\n",
2064 count);
2065
2066 return buf;
2067}

References ast_str_append(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), 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 2042 of file manager.c.

2043{
2044 astman_send_response_full(s, m, "Success", msg, listflag);
2045}

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

1996{
1997 astman_send_response_full(s, m, resp, msg, NULL);
1998}

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

1965{
1966 const char *id = astman_get_header(m, "ActionID");
1967 struct ast_str *buf;
1968
1969 buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE);
1970 if (!buf) {
1971 return;
1972 }
1973
1974 ast_str_set(&buf, 0, "Response: %s\r\n", resp);
1975
1976 if (!ast_strlen_zero(id)) {
1977 ast_str_append(&buf, 0, "ActionID: %s\r\n", id);
1978 }
1979
1980 if (listflag) {
1981 /* Start, complete, cancelled */
1982 ast_str_append(&buf, 0, "EventList: %s\r\n", listflag);
1983 }
1984
1985 if (msg != MSG_MOREDATA) {
1986 if (msg) {
1987 ast_str_append(&buf, 0, "Message: %s\r\n", msg);
1988 }
1989 ast_str_append(&buf, 0, "\r\n");
1990 }
1991
1992 astman_flush(s, buf);
1993}

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

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

◆ astman_start_ack()

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

◆ async_goto_with_discard_bridge_after()

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

Definition at line 3964 of file manager.c.

3965{
3967 return ast_async_goto(chan, context, exten, priority);
3968}
void ast_bridge_discard_after_goto(struct ast_channel *chan)
Discard channel after bridge goto location.
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:7013

References ast_async_goto(), ast_bridge_discard_after_goto(), and priority.

Referenced by action_redirect().

◆ authenticate()

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

Definition at line 2346 of file manager.c.

2347{
2348 const char *username = astman_get_header(m, "Username");
2349 const char *password = astman_get_header(m, "Secret");
2350 int error = -1;
2351 struct ast_manager_user *user = NULL;
2352 regex_t *regex_filter;
2353 struct ao2_iterator filter_iter;
2354
2355 if (ast_strlen_zero(username)) { /* missing username */
2356 return -1;
2357 }
2358
2359 /* locate user in locked state */
2361
2362 if (!(user = get_manager_by_name_locked(username))) {
2363 report_invalid_user(s, username);
2364 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
2365 } else if (user->acl && (ast_apply_acl(user->acl, &s->session->addr, "Manager User ACL: ") == AST_SENSE_DENY)) {
2366 report_failed_acl(s, username);
2367 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
2368 } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
2369 const char *key = astman_get_header(m, "Key");
2370 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
2371 int x;
2372 int len = 0;
2373 char md5key[256] = "";
2374 struct MD5Context md5;
2375 unsigned char digest[16];
2376
2377 MD5Init(&md5);
2378 MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
2379 MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
2380 MD5Final(digest, &md5);
2381 for (x = 0; x < 16; x++)
2382 len += sprintf(md5key + len, "%02hhx", digest[x]);
2383 if (!strcmp(md5key, key)) {
2384 error = 0;
2385 } else {
2386 report_failed_challenge_response(s, key, md5key);
2387 }
2388 } else {
2389 ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n",
2390 S_OR(s->session->challenge, ""));
2391 }
2392 } else if (user->secret) {
2393 if (!strcmp(password, user->secret)) {
2394 error = 0;
2395 } else {
2396 report_inval_password(s, username);
2397 }
2398 }
2399
2400 if (error) {
2401 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_sockaddr_stringify_addr(&s->session->addr), username);
2403 return -1;
2404 }
2405
2406 /* auth complete */
2407
2408 /* All of the user parameters are copied to the session so that in the event
2409 * of a reload and a configuration change, the session parameters are not
2410 * changed. */
2411 ast_copy_string(s->session->username, username, sizeof(s->session->username));
2412 s->session->readperm = user->readperm;
2413 s->session->writeperm = user->writeperm;
2414 s->session->writetimeout = user->writetimeout;
2415 if (user->chanvars) {
2416 s->session->chanvars = ast_variables_dup(user->chanvars);
2417 }
2418
2419 filter_iter = ao2_iterator_init(user->includefilters, 0);
2420 while ((regex_filter = ao2_iterator_next(&filter_iter))) {
2421 ao2_t_link(s->session->includefilters, regex_filter, "add include user filter to session");
2422 ao2_t_ref(regex_filter, -1, "remove iterator ref");
2423 }
2424 ao2_iterator_destroy(&filter_iter);
2425
2426 filter_iter = ao2_iterator_init(user->excludefilters, 0);
2427 while ((regex_filter = ao2_iterator_next(&filter_iter))) {
2428 ao2_t_link(s->session->excludefilters, regex_filter, "add exclude user filter to session");
2429 ao2_t_ref(regex_filter, -1, "remove iterator ref");
2430 }
2431 ao2_iterator_destroy(&filter_iter);
2432
2433 s->session->sessionstart = time(NULL);
2435 set_eventmask(s, astman_get_header(m, "Events"));
2436
2438
2440 return 0;
2441}
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition acl.c:799
@ AST_SENSE_DENY
Definition acl.h:37
#define ao2_t_link(container, obj, tag)
Definition astobj2.h:1534
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition func_md5.c:55
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition manager.c:1054
static void report_invalid_user(const struct mansession *s, const char *username)
Definition manager.c:2126
static void report_failed_acl(const struct mansession *s, const char *username)
Definition manager.c:2151
static void report_failed_challenge_response(const struct mansession *s, const char *response, const char *expected_response)
Definition manager.c:2284
static void report_inval_password(const struct mansession *s, const char *username)
Definition manager.c:2176
static void report_auth_success(const struct mansession *s)
Definition manager.c:2201
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
Definition md5.c:72
void MD5Init(struct MD5Context *context)
Definition md5.c:57
void MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], struct MD5Context *context)
Definition md5.c:120
user descriptor, as read from the config file.
Definition manager.c:342
struct ast_sockaddr addr
Definition manager.c:280
struct timeval sessionstart_tv
Definition manager.c:287
char username[80]
Definition manager.c:289
time_t sessionstart
Definition manager.c:286
structure to hold users read from phoneprov_users.conf
list of users found in the config file
int error(const char *format,...)

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

828{
829 int i;
830 char *sep = "";
831
832 ast_str_reset(*res);
833 if (authority != EVENT_FLAG_SHUTDOWN) {
834 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
835 if (authority & perms[i].num) {
836 ast_str_append(res, 0, "%s%s", sep, perms[i].label);
837 sep = ",";
838 }
839 }
840 }
841
842 if (ast_str_strlen(*res) == 0) {
843 /* replace empty string with something sensible */
844 ast_str_append(res, 0, "<none>");
845 }
846
847 return ast_str_buffer(*res);
848}

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

979{
980 struct ao2_container *sessions;
981 struct mansession_session *newsession;
982
983 newsession = ao2_alloc(sizeof(*newsession), session_destructor);
984 if (!newsession) {
985 return NULL;
986 }
987
990 if (!newsession->includefilters || !newsession->excludefilters) {
991 ao2_ref(newsession, -1);
992 return NULL;
993 }
994
995 newsession->waiting_thread = AST_PTHREADT_NULL;
996 newsession->writetimeout = 100;
997 newsession->send_events = -1;
998 ast_sockaddr_copy(&newsession->addr, addr);
999
1000 ast_mutex_init(&newsession->notify_lock);
1001
1002 sessions = ao2_global_obj_ref(mgr_sessions);
1003 if (sessions) {
1004 ao2_link(sessions, newsession);
1005 ao2_ref(sessions, -1);
1006 }
1007
1008 return newsession;
1009}
#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:947
#define ast_mutex_init(pmutex)
Definition lock.h:193
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition netsock2.h:167

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

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

◆ check_blacklist()

static int check_blacklist ( const char *  cmd)
static

Definition at line 4257 of file manager.c.

4258{
4259 char *cmd_copy, *cur_cmd;
4260 char *cmd_words[AST_MAX_CMD_LEN] = { NULL, };
4261 int i;
4262
4263 cmd_copy = ast_strdupa(cmd);
4264 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) {
4265 cur_cmd = ast_strip(cur_cmd);
4266 if (ast_strlen_zero(cur_cmd)) {
4267 i--;
4268 continue;
4269 }
4270
4271 cmd_words[i] = cur_cmd;
4272 }
4273
4274 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) {
4275 int j, match = 1;
4276
4277 for (j = 0; command_blacklist[i].words[j]; j++) {
4278 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) {
4279 match = 0;
4280 break;
4281 }
4282 }
4283
4284 if (match) {
4285 return 1;
4286 }
4287 }
4288
4289 return 0;
4290}
#define AST_MAX_CMD_LEN
Definition cli.h:48
#define MAX_BLACKLIST_CMD_LEN
Descriptor for a manager session, either on the AMI socket or over HTTP.
Definition manager.c:220
static const struct @396 command_blacklist[]
const char * words[AST_MAX_CMD_LEN]
Definition manager.c:222

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

Referenced by action_command().

◆ check_manager_session_inuse()

static int check_manager_session_inuse ( const char *  name)
static

Definition at line 1031 of file manager.c.

1032{
1033 struct ao2_container *sessions;
1035 int inuse = 0;
1036
1037 sessions = ao2_global_obj_ref(mgr_sessions);
1038 if (sessions) {
1039 session = ao2_find(sessions, (char *) name, 0);
1040 ao2_ref(sessions, -1);
1041 if (session) {
1043 inuse = 1;
1044 }
1045 }
1046 return inuse;
1047}
#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 6682 of file manager.c.

6684{
6685 int res = 0;
6686 struct ao2_iterator iter;
6687 char *current_channel_uid;
6688
6689 iter = ao2_iterator_init(bridge_snapshot->channels, 0);
6690 while ((current_channel_uid = ao2_iterator_next(&iter))) {
6691 struct ast_channel_snapshot *current_channel_snapshot;
6692 int add_channel_res;
6693
6694 /* Don't add the original channel to the list - it's either already in there,
6695 * or it's the channel we want the map for */
6696 if (!strcmp(current_channel_uid, channel_snapshot->base->uniqueid)) {
6697 ao2_ref(current_channel_uid, -1);
6698 continue;
6699 }
6700
6701 current_channel_snapshot = ast_channel_snapshot_get_latest(current_channel_uid);
6702 if (!current_channel_snapshot) {
6703 ast_debug(5, "Unable to get channel snapshot\n");
6704 ao2_ref(current_channel_uid, -1);
6705 continue;
6706 }
6707
6708 add_channel_res = coreshowchannelmap_add_to_map(channel_map, current_channel_snapshot->base->name);
6709 if (add_channel_res) {
6710 res = 1;
6711 ao2_ref(current_channel_snapshot, -1);
6712 ao2_ref(current_channel_uid, -1);
6713 break;
6714 }
6715
6716 /* 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 */
6717 if (ast_begins_with(current_channel_snapshot->base->name, "Local")) {
6718 struct ast_channel_snapshot *other_local_snapshot;
6719 struct ast_bridge_snapshot *other_bridge_snapshot;
6720 int size = strlen(current_channel_snapshot->base->name);
6721 char other_local[size + 1];
6722
6723 /* Don't copy the trailing number - set it to 1 or 2, whichever one it currently is not */
6724 ast_copy_string(other_local, current_channel_snapshot->base->name, size);
6725 other_local[size - 1] = ast_ends_with(current_channel_snapshot->base->name, "1") ? '2' : '1';
6726 other_local[size] = '\0';
6727
6728 other_local_snapshot = ast_channel_snapshot_get_latest_by_name(other_local);
6729 if (!other_local_snapshot) {
6730 ast_debug(5, "Unable to get other local channel snapshot\n");
6731 ao2_ref(current_channel_snapshot, -1);
6732 ao2_ref(current_channel_uid, -1);
6733 continue;
6734 }
6735
6736 if (coreshowchannelmap_add_to_map(channel_map, other_local_snapshot->base->name)) {
6737 res = 1;
6738 ao2_ref(current_channel_snapshot, -1);
6739 ao2_ref(current_channel_uid, -1);
6740 ao2_ref(other_local_snapshot, -1);
6741 break;
6742 }
6743
6744 other_bridge_snapshot = ast_bridge_get_snapshot_by_uniqueid(other_local_snapshot->bridge->id);
6745 if (other_bridge_snapshot) {
6746 res = coreshowchannelmap_add_connected_channels(channel_map, other_local_snapshot, other_bridge_snapshot);
6747 }
6748
6749 ao2_ref(current_channel_snapshot, -1);
6750 ao2_ref(current_channel_uid, -1);
6751 ao2_ref(other_local_snapshot, -1);
6752 ao2_ref(other_bridge_snapshot, -1);
6753
6754 if (res) {
6755 break;
6756 }
6757 }
6758 }
6759 ao2_iterator_destroy(&iter);
6760
6761 return res;
6762}
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:6665
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
static int force_inline attribute_pure ast_ends_with(const char *str, const char *suffix)
Checks whether a string ends with another.
Definition strings.h:116
struct ao2_container * channels
Definition bridge.h:335
const ast_string_field uniqueid
const ast_string_field name

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

Referenced by action_coreshowchannelmap(), and coreshowchannelmap_add_connected_channels().

◆ coreshowchannelmap_add_to_map()

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

Helper function to add a channel name to the vector.

Definition at line 6665 of file manager.c.

6666{
6667 char *str;
6668
6669 str = ast_strdup(s);
6670 if (!str) {
6671 ast_log(LOG_ERROR, "Unable to append channel to channel map\n");
6672 return 1;
6673 }
6674
6675 /* If this is a duplicate, it will be ignored */
6677
6678 return 0;
6679}
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 7293 of file manager.c.

7294{
7295 struct message m = { 0 };
7296 char header_buf[sizeof(s->session->inbuf)] = { '\0' };
7297 int res;
7298 int hdr_loss;
7299 time_t now;
7300
7301 hdr_loss = 0;
7302 for (;;) {
7303 /* Check if any events are pending and do them if needed */
7304 if (process_events(s)) {
7305 res = -1;
7306 break;
7307 }
7308 res = get_input(s, header_buf);
7309 if (res == 0) {
7310 /* No input line received. */
7311 if (!s->session->authenticated) {
7312 if (time(&now) == -1) {
7313 ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
7314 res = -1;
7315 break;
7316 }
7317
7318 if (now - s->session->authstart > authtimeout) {
7319 if (displayconnects) {
7320 ast_verb(2, "Client from %s, failed to authenticate in %d seconds\n", ast_sockaddr_stringify_addr(&s->session->addr), authtimeout);
7321 }
7322 res = -1;
7323 break;
7324 }
7325 }
7326 continue;
7327 } else if (res > 0) {
7328 /* Input line received. */
7329 if (ast_strlen_zero(header_buf)) {
7330 if (hdr_loss) {
7331 mansession_lock(s);
7332 astman_send_error(s, &m, "Too many lines in message or allocation failure");
7334 res = 0;
7335 } else {
7336 switch (s->parsing) {
7337 case MESSAGE_OKAY:
7338 res = process_message(s, &m) ? -1 : 0;
7339 break;
7341 handle_parse_error(s, &m, "Failed to parse message: line too long");
7342 res = 0;
7343 break;
7344 }
7345 }
7346 break;
7347 } else if (m.hdrcount < ARRAY_LEN(m.headers)) {
7348 m.headers[m.hdrcount] = ast_strdup(header_buf);
7349 if (!m.headers[m.hdrcount]) {
7350 /* Allocation failure. */
7351 hdr_loss = 1;
7352 } else {
7353 ++m.hdrcount;
7354 }
7355 } else {
7356 /* Too many lines in message. */
7357 hdr_loss = 1;
7358 }
7359 } else {
7360 /* Input error. */
7361 break;
7362 }
7363 }
7364
7366
7367 return res;
7368}
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:7044
static void astman_free_headers(struct message *m)
Free headers inside message structure, but not the message structure itself.
Definition manager.c:1685
static int displayconnects
Definition manager.c:161
static int get_input(struct mansession *s, char *output)
Definition manager.c:7172
static void handle_parse_error(struct mansession *s, struct message *m, char *error)
Definition manager.c:7276
static int process_events(struct mansession *s)
Definition manager.c:6431
static int authtimeout
Definition manager.c:170
char inbuf[1025]
Definition manager.c:294
enum mansession_message_parsing parsing
Definition manager.c:327

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

Referenced by session_do().

◆ event_filter_destructor()

static void event_filter_destructor ( void *  obj)
static

Definition at line 935 of file manager.c.

936{
937 struct event_filter_entry *entry = obj;
938 if (entry->regex_filter) {
939 regfree(entry->regex_filter);
940 ast_free(entry->regex_filter);
941 }
942 ast_free(entry->event_name);
943 ast_free(entry->header_name);
944 ast_free(entry->string_filter);
945}
Definition manager.c:403
char * string_filter
Definition manager.c:406
char * event_name
Definition manager.c:407
regex_t * regex_filter
Definition manager.c:405
char * header_name
Definition manager.c:409

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

Referenced by manager_add_filter().

◆ fast_originate()

static void * fast_originate ( void *  data)
static

Definition at line 4409 of file manager.c.

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

6899{
6900 char *stripped_filename;
6901 RAII_VAR(char *, path, NULL, ast_free);
6902 RAII_VAR(char *, real_path, NULL, ast_free);
6903
6904 /* Don't bother checking */
6905 if (live_dangerously) {
6906 return 1;
6907 }
6908
6909 stripped_filename = ast_strip(ast_strdupa(filename));
6910
6911 /* Always prepend the modules dir since that is what the code does for ModuleLoad */
6912 if (ast_asprintf(&path, "%s/%s", ast_config_AST_MODULE_DIR, stripped_filename) == -1) {
6913 return -1;
6914 }
6915
6916 real_path = realpath(path, NULL);
6917 if (!real_path) {
6918 return -1;
6919 }
6920
6921 return ast_begins_with(real_path, ast_config_AST_MODULE_DIR);
6922}
const char * ast_config_AST_MODULE_DIR
Definition options.c:154

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

Referenced by manager_moduleload().

◆ filter_cmp_fn()

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

Definition at line 5613 of file manager.c.

5614{
5615 struct eventqent *eqe = arg;
5616 struct event_filter_entry *filter_entry = obj;
5617 char *line_buffer_start = NULL;
5618 char *line_buffer = NULL;
5619 char *line = NULL;
5620 int match = 0;
5621 int *result = data;
5622
5623 if (filter_entry->event_name_hash) {
5624 if (eqe->event_name_hash != filter_entry->event_name_hash) {
5625 goto done;
5626 }
5627 }
5628
5629 /* We're looking at the entire event data */
5630 if (!filter_entry->header_name) {
5631 match = match_eventdata(filter_entry, eqe->eventdata);
5632 goto done;
5633 }
5634
5635 /* We're looking at a specific header */
5636 line_buffer_start = ast_strdup(eqe->eventdata);
5637 line_buffer = line_buffer_start;
5638 if (!line_buffer_start) {
5639 goto done;
5640 }
5641
5642 while ((line = ast_read_line_from_buffer(&line_buffer))) {
5643 if (ast_begins_with(line, filter_entry->header_name)) {
5644 line += strlen(filter_entry->header_name);
5645 line = ast_skip_blanks(line);
5646 if (ast_strlen_zero(line)) {
5647 continue;
5648 }
5649 match = match_eventdata(filter_entry, line);
5650 if (match) {
5651 ast_free(line_buffer_start);
5652 line_buffer_start = NULL;
5653 break;
5654 }
5655 }
5656 }
5657
5658 ast_free(line_buffer_start);
5659
5660done:
5661
5662 *result = match;
5663 return match ? CMP_MATCH | CMP_STOP : 0;
5664}
@ 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:5593
char * ast_read_line_from_buffer(char **buffer)
Read lines from a string buffer.
Definition strings.c:385
unsigned int event_name_hash
Definition manager.c:408
int done

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, eventqent::eventdata, 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 789 of file manager.c.

790{
791 if (!(writepermlist & EVENT_FLAG_SYSTEM)
792 && (
793 strstr(evaluating, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */
794 strstr(evaluating, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
795 )) {
796 return 0;
797 }
798 return 1;
799}

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

3652{
3653 struct timeval now;
3654 long elapsed_seconds;
3655 struct ast_bridge *bridge;
3656 RAII_VAR(struct ast_str *, variable_str, NULL, ast_free);
3657 struct ast_str *write_transpath = ast_str_alloca(256);
3658 struct ast_str *read_transpath = ast_str_alloca(256);
3659 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
3660 struct ast_party_id effective_id;
3661 int i;
3662 RAII_VAR(struct ast_channel_snapshot *, snapshot,
3664 ao2_cleanup);
3665 RAII_VAR(struct ast_str *, snapshot_str, NULL, ast_free);
3666
3667 if (!snapshot) {
3668 return;
3669 }
3670
3671 snapshot_str = ast_manager_build_channel_state_string(snapshot);
3672 if (!snapshot_str) {
3673 return;
3674 }
3675
3676 if (all_variables) {
3677 variable_str = ast_str_create(2048);
3678 } else {
3679 variable_str = ast_str_create(1024);
3680 }
3681 if (!variable_str) {
3682 return;
3683 }
3684
3685 now = ast_tvnow();
3686 elapsed_seconds = ast_tvdiff_sec(now, ast_channel_creationtime(chan));
3687
3688 /* Even if all_variables has been specified, explicitly requested variables
3689 * may be global variables or dialplan functions */
3690 for (i = 0; i < varc; i++) {
3691 char valbuf[512], *ret = NULL;
3692
3693 if (vars[i][strlen(vars[i]) - 1] == ')') {
3694 if (ast_func_read(chan, vars[i], valbuf, sizeof(valbuf)) < 0) {
3695 valbuf[0] = '\0';
3696 }
3697 ret = valbuf;
3698 } else {
3699 pbx_retrieve_variable(chan, vars[i], &ret, valbuf, sizeof(valbuf), NULL);
3700 }
3701
3702 ast_str_append(&variable_str, 0, "Variable: %s=%s\r\n", vars[i], ret);
3703 }
3704
3705 /* Walk all channel variables and add them */
3706 if (all_variables) {
3707 struct ast_var_t *variables;
3708
3710 ast_str_append(&variable_str, 0, "Variable: %s=%s\r\n",
3711 ast_var_name(variables), ast_var_value(variables));
3712 }
3713 }
3714
3715 bridge = ast_channel_get_bridge(chan);
3716 effective_id = ast_channel_connected_effective_id(chan);
3717
3718 astman_append(s,
3719 "Event: Status\r\n"
3720 "Privilege: Call\r\n"
3721 "%s"
3722 "Type: %s\r\n"
3723 "DNID: %s\r\n"
3724 "EffectiveConnectedLineNum: %s\r\n"
3725 "EffectiveConnectedLineName: %s\r\n"
3726 "TimeToHangup: %ld\r\n"
3727 "BridgeID: %s\r\n"
3728 "Application: %s\r\n"
3729 "Data: %s\r\n"
3730 "Nativeformats: %s\r\n"
3731 "Readformat: %s\r\n"
3732 "Readtrans: %s\r\n"
3733 "Writeformat: %s\r\n"
3734 "Writetrans: %s\r\n"
3735 "Callgroup: %llu\r\n"
3736 "Pickupgroup: %llu\r\n"
3737 "Seconds: %ld\r\n"
3738 "%s"
3739 "%s"
3740 "\r\n",
3741 ast_str_buffer(snapshot_str),
3742 ast_channel_tech(chan)->type,
3743 S_OR(ast_channel_dialed(chan)->number.str, ""),
3744 S_COR(effective_id.number.valid, effective_id.number.str, "<unknown>"),
3745 S_COR(effective_id.name.valid, effective_id.name.str, "<unknown>"),
3746 (long)ast_channel_whentohangup(chan)->tv_sec,
3747 bridge ? bridge->uniqueid : "",
3748 ast_channel_appl(chan),
3749 ast_channel_data(chan),
3752 ast_translate_path_to_str(ast_channel_readtrans(chan), &read_transpath),
3754 ast_translate_path_to_str(ast_channel_writetrans(chan), &write_transpath),
3757 (long)elapsed_seconds,
3758 ast_str_buffer(variable_str),
3759 id_text);
3760 ++*count;
3761
3762 ao2_cleanup(bridge);
3763}
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:10644
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)
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
const char * ast_var_name(const struct ast_var_t *var)
Definition chanvars.c:60
const char * ast_var_value(const struct ast_var_t *var)
Definition chanvars.c:80
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition format.c:334
#define AST_FORMAT_CAP_NAMES_LEN
Definition format_cap.h:324
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition format_cap.c:734
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
Structure that contains information about a bridge.
Definition bridge.h:353
const ast_string_field uniqueid
Definition bridge.h:405
Structure to describe a channel "technology", ie a channel driver See for examples:
Definition channel.h:648
Information needed to identify an endpoint in a call.
Definition channel.h:340
Number structure.
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:1145

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

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

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

Referenced by do_message().

◆ get_manager_by_name_locked()

static struct ast_manager_user * get_manager_by_name_locked ( const char *  name)
static

lookup an entry in the list of registered users. must be called with the list lock held.

Definition at line 1054 of file manager.c.

1055{
1056 struct ast_manager_user *user = NULL;
1057
1059 if (!strcasecmp(user->username, name)) {
1060 break;
1061 }
1062 }
1063
1064 return user;
1065}
struct ast_manager_user::@399 list

References AST_RWLIST_TRAVERSE, ast_manager_user::list, name, and NULL.

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

875{
876 int x = 0, ret = 0;
877
878 if (!instr) {
879 return 0;
880 }
881
882 for (x = 0; x < ARRAY_LEN(perms); x++) {
883 if (ast_instring(instr, perms[x].label, ',')) {
884 ret |= perms[x].num;
885 }
886 }
887
888 return ret;
889}
static int ast_instring(const char *bigstr, const char *smallstr, const char delim)
Definition manager.c:855

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

707{
708 struct eventqent *ret;
709
712 /* the list is never empty now, but may become so when
713 * we optimize it in the future, so be prepared.
714 */
715 if (ret) {
717 }
719 return ret;
720}
#define AST_RWLIST_LAST

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

1427{
1428 struct ao2_container *sessions;
1430 struct ao2_iterator i;
1431 int fd = -1;
1432 int found = 0;
1433
1434 switch (cmd) {
1435 case CLI_INIT:
1436 e->command = "manager kick session";
1437 e->usage =
1438 "Usage: manager kick session <file descriptor>\n"
1439 " Kick an active Asterisk Manager Interface session\n";
1440 return NULL;
1441 case CLI_GENERATE:
1442 return NULL;
1443 }
1444
1445 if (a->argc != 4) {
1446 return CLI_SHOWUSAGE;
1447 }
1448
1449 fd = atoi(a->argv[3]);
1450 if (fd <= 0) { /* STDOUT won't be a valid AMI fd either */
1451 ast_cli(a->fd, "Invalid AMI file descriptor: %s\n", a->argv[3]);
1452 return CLI_FAILURE;
1453 }
1454
1455 sessions = ao2_global_obj_ref(mgr_sessions);
1456 if (sessions) {
1458 ao2_ref(sessions, -1);
1459 while ((session = ao2_iterator_next(&i))) {
1461 if (session->stream) {
1462 if (ast_iostream_get_fd(session->stream) == fd) {
1463 if (session->kicked) {
1464 ast_cli(a->fd, "Manager session using file descriptor %d has already been kicked\n", fd);
1467 break;
1468 }
1469 fd = ast_iostream_get_fd(session->stream);
1470 found = fd;
1471 ast_cli(a->fd, "Kicking manager session connected using file descriptor %d\n", fd);
1472 ast_mutex_lock(&session->notify_lock);
1473 session->kicked = 1;
1474 if (session->waiting_thread != AST_PTHREADT_NULL) {
1475 pthread_kill(session->waiting_thread, SIGURG);
1476 }
1477 ast_mutex_unlock(&session->notify_lock);
1480 break;
1481 }
1482 }
1485 }
1487 }
1488
1489 if (!found) {
1490 ast_cli(a->fd, "No manager session found using file descriptor %d\n", fd);
1491 }
1492 return CLI_SUCCESS;
1493}
#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 1575 of file manager.c.

1576{
1577 switch (cmd) {
1578 case CLI_INIT:
1579 e->command = "manager reload";
1580 e->usage =
1581 "Usage: manager reload\n"
1582 " Reloads the manager configuration.\n";
1583 return NULL;
1584 case CLI_GENERATE:
1585 return NULL;
1586 }
1587 if (a->argc > 2) {
1588 return CLI_SHOWUSAGE;
1589 }
1590 reload_module();
1591 return CLI_SUCCESS;
1592}
static int reload_module(void)
Definition manager.c:10132

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

1244{
1245 switch (cmd) {
1246 case CLI_INIT:
1247 e->command = "manager set debug [on|off]";
1248 e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n";
1249 return NULL;
1250 case CLI_GENERATE:
1251 return NULL;
1252 }
1253
1254 if (a->argc == 3) {
1255 ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off");
1256 } else if (a->argc == 4) {
1257 if (!strcasecmp(a->argv[3], "on")) {
1258 manager_debug = 1;
1259 } else if (!strcasecmp(a->argv[3], "off")) {
1260 manager_debug = 0;
1261 } else {
1262 return CLI_SHOWUSAGE;
1263 }
1264 }
1265 return CLI_SUCCESS;
1266}

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

7277{
7278 mansession_lock(s);
7279 astman_send_error(s, m, error);
7280 s->parsing = MESSAGE_OKAY;
7282}

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

1269{
1270 struct ast_manager_user *user = NULL;
1271 int l;
1272 struct ast_str *rauthority = ast_str_alloca(MAX_AUTH_PERM_STRING);
1273 struct ast_str *wauthority = ast_str_alloca(MAX_AUTH_PERM_STRING);
1274 struct ast_variable *v;
1275
1276 switch (cmd) {
1277 case CLI_INIT:
1278 e->command = "manager show user";
1279 e->usage =
1280 " Usage: manager show user <user>\n"
1281 " Display all information related to the manager user specified.\n";
1282 return NULL;
1283 case CLI_GENERATE:
1284 l = strlen(a->word);
1285 if (a->pos != 3) {
1286 return NULL;
1287 }
1289 AST_RWLIST_TRAVERSE(&users, user, list) {
1290 if (!strncasecmp(a->word, user->username, l)) {
1291 if (ast_cli_completion_add(ast_strdup(user->username))) {
1292 break;
1293 }
1294 }
1295 }
1297 return NULL;
1298 }
1299
1300 if (a->argc != 4) {
1301 return CLI_SHOWUSAGE;
1302 }
1303
1305
1306 if (!(user = get_manager_by_name_locked(a->argv[3]))) {
1307 ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]);
1309 return CLI_SUCCESS;
1310 }
1311
1312 ast_cli(a->fd, "\n");
1313 ast_cli(a->fd,
1314 " username: %s\n"
1315 " secret: %s\n"
1316 " ACL: %s\n"
1317 " read perm: %s\n"
1318 " write perm: %s\n"
1319 " displayconnects: %s\n"
1320 "allowmultiplelogin: %s\n",
1321 S_OR(user->username, "(N/A)"),
1322 (user->secret ? "<Set>" : "(N/A)"),
1323 ((user->acl && !ast_acl_list_is_empty(user->acl)) ? "yes" : "no"),
1324 user_authority_to_str(user->readperm, &rauthority),
1325 user_authority_to_str(user->writeperm, &wauthority),
1326 (user->displayconnects ? "yes" : "no"),
1327 (user->allowmultiplelogin ? "yes" : "no"));
1328 ast_cli(a->fd, " Variables: \n");
1329 for (v = user->chanvars ; v ; v = v->next) {
1330 ast_cli(a->fd, " %s = %s\n", v->name, v->value);
1331 }
1332 if (!ast_acl_list_is_empty(user->acl)) {
1333 ast_acl_output(a->fd, user->acl, NULL);
1334 }
1335
1337
1338 return CLI_SUCCESS;
1339}
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:2845
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:803
static int allowmultiplelogin
Definition manager.c:162

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

1342{
1343 struct ast_manager_user *user = NULL;
1344 int count_amu = 0;
1345 switch (cmd) {
1346 case CLI_INIT:
1347 e->command = "manager show users";
1348 e->usage =
1349 "Usage: manager show users\n"
1350 " Prints a listing of all managers that are currently configured on that\n"
1351 " system.\n";
1352 return NULL;
1353 case CLI_GENERATE:
1354 return NULL;
1355 }
1356 if (a->argc != 3) {
1357 return CLI_SHOWUSAGE;
1358 }
1359
1361
1362 /* If there are no users, print out something along those lines */
1363 if (AST_RWLIST_EMPTY(&users)) {
1364 ast_cli(a->fd, "There are no manager users.\n");
1366 return CLI_SUCCESS;
1367 }
1368
1369 ast_cli(a->fd, "\nusername\n--------\n");
1370
1372 ast_cli(a->fd, "%s\n", user->username);
1373 count_amu++;
1374 }
1375
1377
1378 ast_cli(a->fd,"-------------------\n"
1379 "%d manager users configured.\n", count_amu);
1380 return CLI_SUCCESS;
1381}

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, ast_manager_user::list, 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 1089 of file manager.c.

1090{
1091 struct manager_action *cur;
1092 struct ast_str *authority;
1093 int num;
1094 int l;
1095 const char *auth_str;
1096
1097 switch (cmd) {
1098 case CLI_INIT:
1099 e->command = "manager show command";
1100 e->usage =
1101 "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n"
1102 " Shows the detailed description for a specific Asterisk manager interface command.\n";
1103 return NULL;
1104 case CLI_GENERATE:
1105 l = strlen(a->word);
1107 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1108 if (!strncasecmp(a->word, cur->action, l)) {
1110 break;
1111 }
1112 }
1113 }
1115 return NULL;
1116 }
1117 if (a->argc < 4) {
1118 return CLI_SHOWUSAGE;
1119 }
1120
1122
1124 AST_RWLIST_TRAVERSE(&actions, cur, list) {
1125 for (num = 3; num < a->argc; num++) {
1126 if (!strcasecmp(cur->action, a->argv[num])) {
1127 auth_str = authority_to_str(cur->authority, &authority);
1128
1129#ifdef AST_XML_DOCS
1130 if (cur->docsrc == AST_XML_DOC) {
1131 char *synopsis = ast_xmldoc_printable(S_OR(cur->synopsis, "Not available"), 1);
1132 char *provided_by = ast_xmldoc_printable(S_OR(cur->provided_by, "Not available"), 1);
1133 char *since = ast_xmldoc_printable(S_OR(cur->since, "Not available"), 1);
1134 char *description = ast_xmldoc_printable(S_OR(cur->description, "Not available"), 1);
1135 char *syntax = ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1);
1136 char *arguments = ast_xmldoc_printable(S_OR(cur->arguments, "Not available"), 1);
1137 char *privilege = ast_xmldoc_printable(S_OR(auth_str, "Not available"), 1);
1138 char *seealso = ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1);
1139 char *responses = ast_xmldoc_printable("None", 1);
1140
1141 if (!synopsis || !provided_by || !since || !description || !syntax || !arguments
1142 || !privilege || !seealso || !responses) {
1144 ast_free(provided_by);
1145 ast_free(since);
1146 ast_free(description);
1147 ast_free(syntax);
1148 ast_free(arguments);
1149 ast_free(privilege);
1150 ast_free(seealso);
1151 ast_free(responses);
1152 ast_cli(a->fd, "Allocation failure.\n");
1154
1155 return CLI_FAILURE;
1156 }
1157
1158 ast_cli(a->fd, "\n"
1159 "%s -= Info about Manager Command '%s' =- %s\n\n"
1160 COLORIZE_FMT "\n"
1161 "%s\n\n"
1162 COLORIZE_FMT "\n"
1163 "%s\n\n"
1164 COLORIZE_FMT "\n"
1165 "%s\n\n"
1166 COLORIZE_FMT "\n"
1167 "%s\n\n"
1168 COLORIZE_FMT "\n"
1169 "%s\n\n"
1170 COLORIZE_FMT "\n"
1171 "%s\n\n"
1172 COLORIZE_FMT "\n"
1173 "%s\n\n"
1174 COLORIZE_FMT "\n"
1175 "%s\n\n"
1176 COLORIZE_FMT "\n",
1178 COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
1179 COLORIZE(COLOR_MAGENTA, 0, "[Provided By]"), provided_by,
1180 COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
1181 COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
1182 COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), syntax,
1183 COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
1184 COLORIZE(COLOR_MAGENTA, 0, "[Privilege]"), privilege,
1185 COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso,
1186 COLORIZE(COLOR_MAGENTA, 0, "[List Responses]")
1187 );
1188
1189 if (!cur->list_responses) {
1190 ast_cli(a->fd, "%s\n\n", responses);
1191 } else {
1192 struct ast_xml_doc_item *temp;
1193 for (temp = cur->list_responses; temp; temp = AST_LIST_NEXT(temp, next)) {
1194 ast_cli(a->fd, "Event: %s\n", temp->name);
1195 print_event_instance(a, temp);
1196 }
1197 }
1198 ast_cli(a->fd,
1199 COLORIZE_FMT "\n",
1200 COLORIZE(COLOR_MAGENTA, 0, "[End List Responses]")
1201 );
1202
1203 ast_cli(a->fd, "\n"
1204 COLORIZE_FMT "\n",
1205 COLORIZE(COLOR_MAGENTA, 0, "[Final Response]")
1206 );
1207 if (!cur->final_response) {
1208 ast_cli(a->fd, "%s\n\n", responses);
1209 } else {
1210 ast_cli(a->fd, "Event: %s\n", cur->final_response->name);
1212 }
1213 ast_cli(a->fd,
1214 COLORIZE_FMT "\n",
1215 COLORIZE(COLOR_MAGENTA, 0, "[End Final Response]")
1216 );
1217
1220 ast_free(since);
1224 ast_free(privilege);
1226 ast_free(responses);
1227 } else
1228#endif
1229 {
1230 ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
1231 cur->action, cur->synopsis,
1232 auth_str,
1233 S_OR(cur->description, ""));
1234 }
1235 }
1236 }
1237 }
1239
1240 return CLI_SUCCESS;
1241}
static void print_event_instance(struct ast_cli_args *a, struct ast_xml_doc_item *instance)
Definition manager.c:9298
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
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_str * provided_by
Definition xmldoc.h:84
struct ast_xml_doc_item * next
Definition xmldoc.h:80
struct ast_str * arguments
Definition xmldoc.h:62
struct ast_str * since
Definition xmldoc.h:82
struct ast_str * description
Definition xmldoc.h:66
const ast_string_field name
Definition xmldoc.h:74
struct ast_str * seealso
Definition xmldoc.h:60
const char * ast_term_reset(void)
Returns the terminal reset code.
Definition term.c:357
#define COLOR_MAGENTA
Definition term.h:60
const char * ast_term_color(int fgcolor, int bgcolor)
Return a color sequence string.
Definition term.c:341
#define COLORIZE(fg, bg, str)
Definition term.h:72
#define COLORIZE_FMT
Shortcut macros for coloring a set of text.
Definition term.h:71
char * ast_xmldoc_printable(const char *bwinput, int withcolors)
Colorize and put delimiters (instead of tags) to the xmldoc output.
Definition xmldoc.c:241

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

◆ handle_showmancmds()

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

CLI command manager list commands.

Definition at line 1384 of file manager.c.

1385{
1386 struct manager_action *cur;
1387 int name_len = 1;
1388 int space_remaining;
1389#define HSMC_FORMAT " %-*.*s %-.*s\n"
1390 switch (cmd) {
1391 case CLI_INIT:
1392 e->command = "manager show commands";
1393 e->usage =
1394 "Usage: manager show commands\n"
1395 " Prints a listing of all the available Asterisk manager interface commands.\n";
1396 return NULL;
1397 case CLI_GENERATE:
1398 return NULL;
1399 }
1400
1403 int incoming_len = strlen(cur->action);
1404 if (incoming_len > name_len) {
1405 name_len = incoming_len;
1406 }
1407 }
1408
1409 space_remaining = MGR_SHOW_TERMINAL_WIDTH - name_len - 4;
1410 if (space_remaining < 0) {
1411 space_remaining = 0;
1412 }
1413
1414 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, "Action", space_remaining, "Synopsis");
1415 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, "------", space_remaining, "--------");
1416
1418 ast_cli(a->fd, HSMC_FORMAT, name_len, name_len, cur->action, space_remaining, cur->synopsis);
1419 }
1421
1422 return CLI_SUCCESS;
1423}
#define MGR_SHOW_TERMINAL_WIDTH
Definition manager.c:203
#define HSMC_FORMAT

References a, manager_action::action, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, HSMC_FORMAT, manager_action::list, 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 1496 of file manager.c.

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

1548{
1549 struct eventqent *s;
1550 switch (cmd) {
1551 case CLI_INIT:
1552 e->command = "manager show eventq";
1553 e->usage =
1554 "Usage: manager show eventq\n"
1555 " Prints a listing of all events pending in the Asterisk manger\n"
1556 "event queue.\n";
1557 return NULL;
1558 case CLI_GENERATE:
1559 return NULL;
1560 }
1563 ast_cli(a->fd, "Usecount: %d\n", s->usecount);
1564 ast_cli(a->fd, "Category: %d\n", s->category);
1565 ast_cli(a->fd, "Event:\n%s", s->eventdata);
1566 }
1568
1569 return CLI_SUCCESS;
1570}

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, eventqent::eq_next, eventqent::eventdata, 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 2737 of file manager.c.

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

5141{
5142 int i;
5143
5144 for (i = 0; originate_app_permissions[i].search; i++) {
5145 if (originate_app_permissions[i].searchfn(app, data, originate_app_permissions[i].search)) {
5147 }
5148 }
5149
5150 return 1;
5151}
static struct originate_permissions_entry originate_app_permissions[]
Definition manager.c:5103
int permission
Definition manager.c:5013
const char * search
Definition manager.c:5012

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

Referenced by action_originate().

◆ is_restricted_file()

static int is_restricted_file ( const char *  filename)
static

Check if a file is restricted or not.

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

Definition at line 2482 of file manager.c.

2483{
2484 char *stripped_filename;
2485 RAII_VAR(char *, path, NULL, ast_free);
2486 RAII_VAR(char *, real_path, NULL, ast_std_free);
2487
2488 if (live_dangerously) {
2489 return 0;
2490 }
2491
2492 stripped_filename = ast_strip(ast_strdupa(filename));
2493
2494 /* If the file path starts with '/', don't prepend ast_config_AST_CONFIG_DIR */
2495 if (stripped_filename[0] == '/') {
2496 real_path = realpath(stripped_filename, NULL);
2497 } else {
2498 if (ast_asprintf(&path, "%s/%s", ast_config_AST_CONFIG_DIR, stripped_filename) == -1) {
2499 return -1;
2500 }
2501 real_path = realpath(path, NULL);
2502 }
2503
2504 if (!real_path) {
2505 return -1;
2506 }
2507
2508 if (!ast_begins_with(real_path, ast_config_AST_CONFIG_DIR)) {
2509 return 1;
2510 }
2511
2512 return 0;
2513}

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

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

◆ json_escape()

static void json_escape ( char *  out,
const char *  in 
)
static

The amount of space in out must be at least ( 2 * strlen(in) + 1 )

Definition at line 2636 of file manager.c.

2637{
2638 for (; *in; in++) {
2639 if (*in == '\\' || *in == '\"') {
2640 *out++ = '\\';
2641 }
2642 *out++ = *in;
2643 }
2644 *out = '\0';
2645}
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 7005 of file manager.c.

7006{
7007 struct ast_str *buf;
7008 int x;
7009
7010 if (!manager_debug) {
7011 return;
7012 }
7013
7014 buf = ast_str_create(256);
7015 if (!buf) {
7016 return;
7017 }
7018
7019 for (x = 0; x < m->hdrcount; ++x) {
7020 if (!strncasecmp(m->headers[x], "Secret", 6)) {
7021 ast_str_append(&buf, 0, "Secret: <redacted from logging>\n");
7022 } else {
7023 ast_str_append(&buf, 0, "%s\n", m->headers[x]);
7024 }
7025 }
7026
7027 ast_verbose("<--- Examining AMI action: -->\n%s\n", ast_str_buffer(buf));
7028 ast_free(buf);
7029}

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

1704{
1705 char *parse;
1707 AST_APP_ARG(vars)[64];
1708 );
1709
1710 hdr_val = ast_skip_blanks(hdr_val); /* ignore leading spaces in the value */
1711 parse = ast_strdupa(hdr_val);
1712
1713 /* Break the header value string into name=val pair items. */
1715 if (args.argc) {
1716 int y;
1717
1718 /* Process each name=val pair item. */
1719 for (y = 0; y < args.argc; y++) {
1720 struct ast_variable *cur;
1721 char *var;
1722 char *val;
1723
1724 if (!args.vars[y]) {
1725 continue;
1726 }
1727 var = val = args.vars[y];
1728 strsep(&val, "=");
1729
1730 /* XXX We may wish to trim whitespace from the strings. */
1731 if (!val || ast_strlen_zero(var)) {
1732 continue;
1733 }
1734
1735 /* Create new variable list node and prepend it to the list. */
1736 cur = ast_variable_new(var, val, "");
1737 if (cur) {
1738 cur->next = head;
1739 head = cur;
1740 }
1741 }
1742 }
1743
1744 return head;
1745}
static struct @522 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 5770 of file manager.c.

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

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

Referenced by __init_manager(), and action_filter().

◆ manager_default_msg_cb()

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

Definition at line 568 of file manager.c.

570{
571 struct ao2_container *sessions = data;
572 struct ast_manager_event_blob *ev;
573
574 /*
575 * This callback only receives messages that can be turned into AMI events, so
576 * no need to check that the message can be turned into an event before checking for listeners.
577 */
579 /* Nobody is listening */
580 return;
581 }
582
584 if (!ev) {
585 /* Conversion failure */
586 return;
587 }
588
590 "%s", ev->extra_fields);
591 ao2_ref(ev, -1);
592}
#define manager_event_sessions(sessions, category, event, contents,...)
Definition manager.c:562
struct ast_manager_event_blob * stasis_message_to_ami(struct stasis_message *msg)
Build the AMI representation of the message.
Struct containing info for an AMI event to send out.
Definition manager.h:504
const ast_string_field extra_fields
Definition manager.h:509
const char * manager_event
Definition manager.h:506

References any_manager_listeners, ao2_ref, ast_manager_event_blob::event_flags, ast_manager_event_blob::extra_fields, ast_manager_event_blob::manager_event, manager_event_sessions, sessions, 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 1071 of file manager.c.

1072{
1073 struct ast_manager_user *user = NULL;
1074 int ret = 0;
1075
1077 if ((user = get_manager_by_name_locked(session->username))) {
1078 ret = user->displayconnects;
1079 }
1081
1082 return ret;
1083}

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

596{
597 struct ast_json_payload *payload;
598 int class_type;
599 const char *type;
600 struct ast_json *event;
601 struct ast_str *event_buffer;
602 struct ao2_container *sessions = data;
603
605 /* Nobody is listening */
606 return;
607 }
608
609 payload = stasis_message_data(message);
610 class_type = ast_json_integer_get(ast_json_object_get(payload->json, "class_type"));
612 event = ast_json_object_get(payload->json, "event");
613
615 if (!event_buffer) {
616 ast_log(AST_LOG_WARNING, "Error while creating payload for event %s\n", type);
617 return;
618 }
619
621 "%s", ast_str_buffer(event_buffer));
622 ast_free(event_buffer);
623}
struct ast_str * ast_manager_str_from_json_object(struct ast_json *blob, key_exclusion_cb exclusion_cb)
Convert a JSON object into an AMI compatible string.
Definition manager.c:551
#define AST_LOG_WARNING
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition json.c:283
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition json.c:407
intmax_t ast_json_integer_get(const struct ast_json *integer)
Get the value from a JSON integer.
Definition json.c:332
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct ast_json * json
Definition json.h:1083

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

Referenced by manager_subscriptions_init().

◆ manager_json_array_with_key()

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

Definition at line 485 of file manager.c.

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

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

Referenced by manager_json_to_ast_str().

◆ manager_json_obj_with_key()

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

Definition at line 495 of file manager.c.

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

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

Referenced by manager_json_to_ast_str().

◆ manager_json_to_ast_str()

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

Definition at line 510 of file manager.c.

512{
513 struct ast_json_iter *i;
514
515 /* If obj or res is not given, just return */
516 if (!obj || !res) {
517 return;
518 }
519
520 if (!*res && !(*res = ast_str_create(1024))) {
521 return;
522 }
523
524 if (exclusion_cb && key && exclusion_cb(key)) {
525 return;
526 }
527
528 if (ast_json_typeof(obj) != AST_JSON_OBJECT &&
530 manager_json_value_str_append(obj, key, res);
531 return;
532 }
533
534 if (ast_json_typeof(obj) == AST_JSON_ARRAY) {
535 size_t j;
536 for (j = 0; j < ast_json_array_size(obj); ++j) {
538 key, j, res, exclusion_cb);
539 }
540 return;
541 }
542
543 for (i = ast_json_object_iter(obj); i;
544 i = ast_json_object_iter_next(obj, i)) {
547 key, res, exclusion_cb);
548 }
549}
static void manager_json_array_with_key(struct ast_json *obj, const char *key, size_t index, struct ast_str **res, key_exclusion_cb exclusion_cb)
Definition manager.c:485
static void manager_json_value_str_append(struct ast_json *value, const char *key, struct ast_str **res)
Definition manager.c:460
static void manager_json_obj_with_key(struct ast_json *obj, const char *key, const char *parent_key, struct ast_str **res, key_exclusion_cb exclusion_cb)
Definition manager.c:495
struct ast_json * ast_json_object_iter_value(struct ast_json_iter *iter)
Get the value from an iterator.
Definition json.c:455
enum ast_json_type ast_json_typeof(const struct ast_json *value)
Get the type of value.
Definition json.c:78
struct ast_json_iter * ast_json_object_iter_next(struct ast_json *object, struct ast_json_iter *iter)
Get the next iterator.
Definition json.c:447
struct ast_json * ast_json_array_get(const struct ast_json *array, size_t index)
Get an element from an array.
Definition json.c:370
struct ast_json_iter * ast_json_object_iter(struct ast_json *object)
Get an iterator pointing to the first field in a JSON object.
Definition json.c:439
@ AST_JSON_ARRAY
Definition json.h:165
@ AST_JSON_OBJECT
Definition json.h:164
const char * ast_json_object_iter_key(struct ast_json_iter *iter)
Get the key from an iterator.
Definition json.c:451
size_t ast_json_array_size(const struct ast_json *array)
Get the size of a JSON array.
Definition json.c:366
Iterator for JSON object key/values.

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

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

◆ manager_json_value_str_append()

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

Definition at line 460 of file manager.c.

462{
463 switch (ast_json_typeof(value)) {
464 case AST_JSON_STRING:
465 ast_str_append(res, 0, "%s: %s\r\n", key, ast_json_string_get(value));
466 break;
467 case AST_JSON_INTEGER:
468 ast_str_append(res, 0, "%s: %jd\r\n", key, ast_json_integer_get(value));
469 break;
470 case AST_JSON_TRUE:
471 ast_str_append(res, 0, "%s: True\r\n", key);
472 break;
473 case AST_JSON_FALSE:
474 ast_str_append(res, 0, "%s: False\r\n", key);
475 break;
476 default:
477 ast_str_append(res, 0, "%s: \r\n", key);
478 break;
479 }
480}
@ AST_JSON_STRING
Definition json.h:166
@ AST_JSON_FALSE
Definition json.h:170
@ AST_JSON_INTEGER
Definition json.h:167
@ AST_JSON_TRUE
Definition json.h:169

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

Referenced by manager_json_to_ast_str().

◆ manager_modulecheck()

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

Manager function to check if module is loaded.

Definition at line 6859 of file manager.c.

6860{
6861 const char *module = astman_get_header(m, "Module");
6862 const char *id = astman_get_header(m, "ActionID");
6863
6864 ast_debug(1, "**** ModuleCheck .so file %s\n", module);
6865 if (!ast_module_check(module)) {
6866 astman_send_error(s, m, "Module not loaded");
6867 return 0;
6868 }
6869
6870 astman_append(s, "Response: Success\r\n");
6871
6872 if (!ast_strlen_zero(id)) {
6873 astman_append(s, "ActionID: %s\r\n", id);
6874 }
6875
6876#if !defined(LOW_MEMORY)
6877 /* When we switched from subversion to git we lost the ability to
6878 * retrieve the 'ASTERISK_FILE_VERSION' from that file, but we retain
6879 * the response header here for backwards compatibility. */
6880 astman_append(s, "Version: \r\n");
6881#endif
6882
6883 astman_append(s, "\r\n");
6884
6885 return 0;
6886}
int ast_module_check(const char *name)
Check if module with the name given is loaded.
Definition loader.c:2832

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

Referenced by __init_manager().

◆ manager_moduleload()

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

Definition at line 6924 of file manager.c.

6925{
6926 int res;
6927 const char *module = astman_get_header(m, "Module");
6928 const char *loadtype = astman_get_header(m, "LoadType");
6929 const char *recursive = astman_get_header(m, "Recursive");
6930
6931 if (!loadtype || strlen(loadtype) == 0) {
6932 astman_send_error(s, m, "Incomplete ModuleLoad action.");
6933 }
6934 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) {
6935 astman_send_error(s, m, "Need module name");
6936 }
6937
6938 res = file_in_modules_dir(module);
6939 if (res == 0) {
6940 astman_send_error(s, m, "Module must be in the configured modules directory.");
6941 return 0;
6942 } else if (res == -1) {
6943 astman_send_error(s, m, "Module not found.");
6944 return 0;
6945 }
6946
6947 if (!strcasecmp(loadtype, "load")) {
6948 res = ast_load_resource(module);
6949 if (res) {
6950 astman_send_error(s, m, "Could not load module.");
6951 } else {
6952 astman_send_ack(s, m, "Module loaded.");
6953 }
6954 } else if (!strcasecmp(loadtype, "unload")) {
6955 res = ast_unload_resource(module, AST_FORCE_SOFT);
6956 if (res) {
6957 astman_send_error(s, m, "Could not unload module.");
6958 } else {
6959 astman_send_ack(s, m, "Module unloaded.");
6960 }
6961 } else if (!strcasecmp(loadtype, "refresh")) {
6962 res = ast_refresh_resource(module, AST_FORCE_SOFT, !ast_strlen_zero(recursive) && ast_true(recursive));
6963 if (res) {
6964 astman_send_error(s, m, "Could not refresh module.");
6965 } else {
6966 astman_send_ack(s, m, "Module unloaded and loaded.");
6967 }
6968 } else if (!strcasecmp(loadtype, "reload")) {
6969 /* TODO: Unify the ack/error messages here with action_reload */
6970 if (!ast_strlen_zero(module)) {
6971 enum ast_module_reload_result reload_res = ast_module_reload(module);
6972
6973 switch (reload_res) {
6975 astman_send_error(s, m, "No such module.");
6976 break;
6978 astman_send_error(s, m, "Module does not support reload action.");
6979 break;
6981 astman_send_error(s, m, "An unknown error occurred");
6982 break;
6984 astman_send_error(s, m, "A reload is in progress");
6985 break;
6987 astman_send_error(s, m, "Module not initialized");
6988 break;
6991 /* Treat a queued request as success */
6992 astman_send_ack(s, m, "Module reloaded.");
6993 break;
6994 }
6995 } else {
6996 ast_module_reload(NULL); /* Reload all modules */
6997 astman_send_ack(s, m, "All modules reloaded");
6998 }
6999 } else {
7000 astman_send_error(s, m, "Incomplete ModuleLoad action.");
7001 }
7002 return 0;
7003}
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:6898
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
Definition loader.c:1457
enum ast_module_load_result ast_load_resource(const char *resource_name)
Load a module.
Definition loader.c:1987
int ast_refresh_resource(const char *resource_name, enum ast_module_unload_mode force, int recursive)
Unload and load a module again.
Definition loader.c:1416
@ AST_FORCE_SOFT
Definition module.h:62

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

Referenced by __init_manager().

◆ manager_state_cb()

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

Definition at line 7746 of file manager.c.

7747{
7748 /* Notify managers of change */
7749 char hint[512];
7750
7751 hint[0] = '\0';
7752 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
7753
7754 switch(info->reason) {
7756 manager_event(EVENT_FLAG_CALL, "ExtensionStatus",
7757 "Exten: %s\r\n"
7758 "Context: %s\r\n"
7759 "Hint: %s\r\n"
7760 "Status: %d\r\n"
7761 "StatusText: %s\r\n",
7762 exten,
7763 context,
7764 hint,
7765 info->exten_state,
7766 ast_extension_state2str(info->exten_state));
7767 break;
7769 manager_event(EVENT_FLAG_CALL, "PresenceStatus",
7770 "Exten: %s\r\n"
7771 "Context: %s\r\n"
7772 "Hint: %s\r\n"
7773 "Status: %s\r\n"
7774 "Subtype: %s\r\n"
7775 "Message: %s\r\n",
7776 exten,
7777 context,
7778 hint,
7779 ast_presence_state2str(info->presence_state),
7780 info->presence_subtype,
7781 info->presence_message);
7782 break;
7783 }
7784 return 0;
7785}
@ 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(), EVENT_FLAG_CALL, manager_event, and NULL.

Referenced by __init_manager().

◆ manager_subscription_change_msg_cb()

static void manager_subscription_change_msg_cb ( void *  userdata,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Callback for subscription change messages.

Parameters
userdataThe subscription user data (in our case a pointer to the sessions container)
subThe subscription
messageThe message

Definition at line 631 of file manager.c.

633{
634 /*
635 * When the subscription unsubscribes a final message is sent to the subscription
636 * to indicate it. We use this to manage the lifetime of the sessions container
637 * pointer stored with the subscription. When the subscription is done we drop
638 * the reference to the sessions container (userdata) so it can be cleaned up
639 * if needed.
640 */
642 ao2_cleanup(userdata);
643 }
644}
static struct stasis_subscription * sub
Statsd channel stats. Exmaple of how to subscribe to Stasis events.
int stasis_subscription_final_message(struct stasis_subscription *sub, struct stasis_message *msg)
Determine whether a message is the final message to be received on a subscription.
Definition stasis.c:1241

References ao2_cleanup, stasis_subscription_final_message(), and sub.

Referenced by manager_subscriptions_init().

◆ mansession_cmp_fn()

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

Definition at line 1011 of file manager.c.

1012{
1013 struct mansession_session *s = obj;
1014 char *str = arg;
1015 return !strcasecmp(s->username, str) ? CMP_MATCH : 0;
1016}

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

2093{
2094 ast_mutex_lock(&s->lock);
2095}
ast_mutex_t lock
Definition manager.c:330

References ast_mutex_lock, and mansession::lock.

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

◆ mansession_unlock()

static void mansession_unlock ( struct mansession s)
static

Unlock the 'mansession' structure.

Definition at line 2098 of file manager.c.

2099{
2101}

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

5594{
5595 switch(entry->match_type) {
5596 case FILTER_MATCH_REGEX:
5597 return regexec(entry->regex_filter, eventdata, 0, NULL, 0) == 0;
5599 return ast_begins_with(eventdata, entry->string_filter);
5601 return ast_ends_with(eventdata, entry->string_filter);
5603 return strstr(eventdata, entry->string_filter) != NULL;
5604 case FILTER_MATCH_EXACT:
5605 return strcmp(eventdata, entry->string_filter) == 0;
5606 case FILTER_MATCH_NONE:
5607 return 1;
5608 }
5609
5610 return 0;
5611}
enum event_filter_match_type match_type
Definition manager.c:404

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

Referenced by filter_cmp_fn().

◆ print_event_instance()

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

Definition at line 9298 of file manager.c.

9299{
9300 char *since, *syntax, *provided_by, *description, *synopsis, *seealso, *arguments;
9301
9302 synopsis = ast_xmldoc_printable(AS_OR(instance->synopsis, "Not available"), 1);
9303 provided_by = ast_xmldoc_printable(AS_OR(instance->provided_by, "Not available"), 1);
9304 since = ast_xmldoc_printable(AS_OR(instance->since, "Not available"), 1);
9305 description = ast_xmldoc_printable(AS_OR(instance->description, "Not available"), 1);
9306 syntax = ast_xmldoc_printable(AS_OR(instance->syntax, "Not available"), 1);
9307 arguments = ast_xmldoc_printable(AS_OR(instance->arguments, "Not available"), 1);
9308 seealso = ast_xmldoc_printable(AS_OR(instance->seealso, "Not available"), 1);
9309
9310 if (!synopsis || !provided_by || !since || !description || !syntax || !arguments || !seealso) {
9311 ast_cli(a->fd, "Error: Memory allocation failed\n");
9312 goto free_docs;
9313 }
9314
9315 ast_cli(a->fd, "\n"
9316 "%s -= Info about Manager Event '%s' =- %s\n\n"
9317 COLORIZE_FMT "\n"
9318 "%s\n\n"
9319 COLORIZE_FMT "\n"
9320 "%s\n\n"
9321 COLORIZE_FMT "\n"
9322 "%s\n\n"
9323 COLORIZE_FMT "\n"
9324 "%s\n\n"
9325 COLORIZE_FMT "\n"
9326 "%s\n\n"
9327 COLORIZE_FMT "\n"
9328 "%s\n\n"
9329 COLORIZE_FMT "\n"
9330 "%s\n\n",
9332 COLORIZE(COLOR_MAGENTA, 0, "[Synopsis]"), synopsis,
9333 COLORIZE(COLOR_MAGENTA, 0, "[Provided By]"), provided_by,
9334 COLORIZE(COLOR_MAGENTA, 0, "[Since]"), since,
9335 COLORIZE(COLOR_MAGENTA, 0, "[Description]"), description,
9336 COLORIZE(COLOR_MAGENTA, 0, "[Syntax]"), syntax,
9337 COLORIZE(COLOR_MAGENTA, 0, "[Arguments]"), arguments,
9338 COLORIZE(COLOR_MAGENTA, 0, "[See Also]"), seealso
9339 );
9340
9341free_docs:
9343 ast_free(since);
9344 ast_free(description);
9345 ast_free(syntax);
9346 ast_free(arguments);
9347 ast_free(seealso);
9348}
#define AS_OR(a, b)
Definition strings.h:49
struct ast_str * synopsis
Definition xmldoc.h:64

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

Referenced by handle_manager_show_event(), and handle_showmancmd().

◆ process_events()

static int process_events ( struct mansession s)
static

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

Definition at line 6431 of file manager.c.

6432{
6433 int ret = 0;
6434
6435 ao2_lock(s->session);
6436 if (s->session->stream != NULL) {
6437 struct eventqent *eqe = s->session->last_ev;
6438
6439 while ((eqe = advance_event(eqe))) {
6440 if (eqe->category == EVENT_FLAG_SHUTDOWN) {
6441 ast_debug(3, "Received CloseSession event\n");
6442 ret = -1;
6443 }
6444 if (!ret && s->session->authenticated &&
6445 (s->session->readperm & eqe->category) == eqe->category &&
6446 (s->session->send_events & eqe->category) == eqe->category) {
6448 if (send_string(s, eqe->eventdata) < 0 || s->write_error)
6449 ret = -1; /* don't send more */
6450 }
6451 }
6452 s->session->last_ev = eqe;
6453 }
6454 }
6455 ao2_unlock(s->session);
6456 return ret;
6457}
unsigned int write_error
Definition manager.c:328

References advance_event(), ao2_lock, ao2_unlock, ast_debug, mansession_session::authenticated, eventqent::category, EVENT_FLAG_SHUTDOWN, eventqent::eventdata, 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 7044 of file manager.c.

7045{
7046 int ret = 0;
7047 struct manager_action *act_found;
7048 struct ast_manager_user *user = NULL;
7049 const char *username;
7050 const char *action;
7051
7052 action = __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY);
7053 if (ast_strlen_zero(action)) {
7054 report_req_bad_format(s, "NONE");
7055 mansession_lock(s);
7056 astman_send_error(s, m, "Missing action in request");
7058 return 0;
7059 }
7060
7061 log_action(m, action);
7062
7063 if (ast_shutting_down()) {
7064 ast_log(LOG_ERROR, "Unable to process manager action '%s'. Asterisk is shutting down.\n", action);
7065 mansession_lock(s);
7066 astman_send_error(s, m, "Asterisk is shutting down");
7068 return 0;
7069 }
7070
7071 if (!s->session->authenticated
7072 && strcasecmp(action, "Login")
7073 && strcasecmp(action, "Logoff")
7074 && strcasecmp(action, "Challenge")) {
7075 if (!s->session->authenticated) {
7076 report_req_not_allowed(s, action);
7077 }
7078 mansession_lock(s);
7079 astman_send_error(s, m, "Permission denied");
7081 return 0;
7082 }
7083
7084 if (!s->session->authenticated
7085 && (!strcasecmp(action, "Login")
7086 || !strcasecmp(action, "Challenge"))) {
7087 username = astman_get_header(m, "Username");
7088
7092 if (user && !user->allowmultiplelogin) {
7095 sleep(1);
7096 mansession_lock(s);
7097 astman_send_error(s, m, "Login Already In Use");
7099 return -1;
7100 }
7102 }
7103 }
7104
7105 act_found = action_find(action);
7106 if (act_found) {
7107 /* Found the requested AMI action. */
7108 int acted = 0;
7109
7110 if ((s->session->writeperm & act_found->authority)
7111 || act_found->authority == 0) {
7112 /* We have the authority to execute the action. */
7113 ret = -1;
7114 ao2_lock(act_found);
7115 if (act_found->registered && act_found->func) {
7116 struct ast_module *mod_ref = ast_module_running_ref(act_found->module);
7117
7118 ao2_unlock(act_found);
7119 if (mod_ref || !act_found->module) {
7120 ast_debug(1, "Running action '%s'\n", act_found->action);
7121 ret = act_found->func(s, m);
7122 acted = 1;
7123 ast_module_unref(mod_ref);
7124 }
7125 } else {
7126 ao2_unlock(act_found);
7127 }
7128 }
7129 if (!acted) {
7130 /*
7131 * We did not execute the action because access was denied, it
7132 * was no longer registered, or no action was really registered.
7133 * Complain about it and leave.
7134 */
7135 report_req_not_allowed(s, action);
7136 mansession_lock(s);
7137 astman_send_error(s, m, "Permission denied");
7139 }
7140 ao2_t_ref(act_found, -1, "done with found action object");
7141 } else {
7142 char buf[512];
7143
7144 report_req_bad_format(s, action);
7145 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
7146 mansession_lock(s);
7147 astman_send_error(s, m, buf);
7149 }
7150 if (ret) {
7151 return ret;
7152 }
7153 /* Once done with our message, deliver any pending events unless the
7154 requester doesn't want them as part of this response.
7155 */
7156 if (ast_strlen_zero(astman_get_header(m, "SuppressEvents"))) {
7157 return process_events(s);
7158 } else {
7159 return ret;
7160 }
7161}
int ast_shutting_down(void)
Definition asterisk.c:1889
static void log_action(const struct message *m, const char *action)
Definition manager.c:7005
static int check_manager_session_inuse(const char *name)
Definition manager.c:1031
static void report_req_not_allowed(const struct mansession *s, const char *action)
Definition manager.c:2226
static void report_session_limit(const struct mansession *s)
Definition manager.c:2314
static void report_req_bad_format(const struct mansession *s, const char *action)
Definition manager.c:2255
char username[80]
Definition manager.c:343

References __astman_get_header(), manager_action::action, action_find(), ao2_lock, ao2_t_ref, ao2_unlock, ast_debug, ast_log, ast_module_running_ref, ast_module_unref, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_shutting_down(), ast_strlen_zero(), astman_get_header(), astman_send_error(), mansession_session::authenticated, manager_action::authority, buf, check_manager_session_inuse(), manager_action::func, GET_HEADER_SKIP_EMPTY, get_manager_by_name_locked(), log_action(), LOG_ERROR, mansession_lock(), mansession_unlock(), 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 726 of file manager.c.

727{
728 struct eventqent *ev;
729 struct timeval now = ast_tvnow();
730
732 while ( (ev = AST_RWLIST_FIRST(&all_events)) &&
733 ev->usecount == 0 && AST_RWLIST_NEXT(ev, eq_next)) {
735 ast_free(ev);
736 }
737
739 /* Never release the last event */
740 if (!AST_RWLIST_NEXT(ev, eq_next)) {
741 break;
742 }
743
744 /* 2.5 times whatever the HTTP timeout is (maximum 2.5 hours) is the maximum time that we will definitely cache an event */
745 if (ev->usecount == 0 && ast_tvdiff_sec(now, ev->tv) > (httptimeout > 3600 ? 3600 : httptimeout) * 2.5) {
747 ast_free(ev);
748 }
749 }
752}
static int httptimeout
Definition manager.c:164
#define AST_RWLIST_REMOVE_HEAD
#define AST_RWLIST_FIRST

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

7473{
7474 struct ao2_container *sessions;
7476 time_t now = time(NULL);
7477 struct ao2_iterator i;
7478 int purged = 0;
7479
7480 sessions = ao2_global_obj_ref(mgr_sessions);
7481 if (!sessions) {
7482 return 0;
7483 }
7485 ao2_ref(sessions, -1);
7486
7487 /* The order of operations is significant */
7488 while (n_max > 0 && (session = ao2_iterator_next(&i))) {
7490 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) {
7491 if (session->authenticated
7492 && VERBOSITY_ATLEAST(2)
7494 ast_verb(2, "HTTP Manager '%s' timed out from %s\n",
7495 session->username, ast_sockaddr_stringify_addr(&session->addr));
7496 }
7499 n_max--;
7500 purged++;
7501 } else {
7504 }
7505 }
7507 return purged;
7508}
static void session_destroy(struct mansession_session *s)
Definition manager.c:1018
#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 5066 of file manager.c.

5067{
5068 char *parse;
5070 AST_APP_ARG(queuename);
5073 AST_APP_ARG(announceoverride);
5074 AST_APP_ARG(queuetimeoutstr);
5075 AST_APP_ARG(agi);
5076 AST_APP_ARG(gosub);
5078 AST_APP_ARG(position);
5079 );
5080
5081 if (!strcasestr(app, "queue") || ast_strlen_zero(data)) {
5082 return 0;
5083 }
5084
5085 parse = ast_strdupa(data);
5087
5088 /*
5089 * The Queue application is fine unless the AGI parameter is set.
5090 * If it is, we need to check the user's permissions.
5091 */
5092 return !ast_strlen_zero(args.agi);
5093}
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 3854 of file manager.c.

3856{
3858 size_t obj_size;
3859 int res;
3860
3861 obj_size = payload_size + sizeof(*obj);
3862
3863 obj = ast_malloc(obj_size);
3864 if (!obj) {
3865 return -1;
3866 }
3867
3868 obj->action = action;
3870 memcpy(obj->payload, payload, payload_size);
3871
3872 res = ast_queue_control_data(chan, AST_CONTROL_READ_ACTION, obj, obj_size);
3873
3874 ast_free(obj);
3875 return res;
3876}
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:1296
@ AST_CONTROL_READ_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 3887 of file manager.c.

3888{
3889 return queue_read_action_payload(chan, (const unsigned char *)body,
3890 strlen(body) + 1, AST_FRAME_READ_ACTION_SEND_TEXT);
3891}
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:3854
@ 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 3903 of file manager.c.

3905{
3906 int res;
3907 struct ast_msg_data *obj;
3908
3910 NULL, NULL, content_type, body);
3911 if (!obj) {
3912 return -1;
3913 }
3914
3915 res = queue_read_action_payload(chan, (const unsigned char *)obj,
3917
3918 ast_free(obj);
3919 return res;
3920}
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 10132 of file manager.c.

10133{
10135}
@ 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 2201 of file manager.c.

2202{
2203 char session_id[32];
2204 struct ast_security_event_successful_auth successful_auth = {
2207 .common.service = "AMI",
2208 .common.account_id = s->session->username,
2209 .common.session_tv = &s->session->sessionstart_tv,
2210 .common.local_addr = {
2211 .addr = &s->tcptls_session->parent->local_address,
2212 .transport = mansession_get_transport(s),
2213 },
2214 .common.remote_addr = {
2215 .addr = &s->session->addr,
2216 .transport = mansession_get_transport(s),
2217 },
2218 .common.session_id = session_id,
2219 };
2220
2221 snprintf(session_id, sizeof(session_id), "%p", s->session);
2222
2223 ast_security_event_report(AST_SEC_EVT(&successful_auth));
2224}
static enum ast_transport mansession_get_transport(const struct mansession *s)
Definition manager.c:2120
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 2151 of file manager.c.

2152{
2153 char session_id[32];
2154 struct ast_security_event_failed_acl failed_acl_event = {
2156 .common.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
2157 .common.service = "AMI",
2158 .common.account_id = username,
2159 .common.session_tv = &s->session->sessionstart_tv,
2160 .common.local_addr = {
2161 .addr = &s->tcptls_session->parent->local_address,
2162 .transport = mansession_get_transport(s),
2163 },
2164 .common.remote_addr = {
2165 .addr = &s->session->addr,
2166 .transport = mansession_get_transport(s),
2167 },
2168 .common.session_id = session_id,
2169 };
2170
2171 snprintf(session_id, sizeof(session_id), "%p", s->session);
2172
2173 ast_security_event_report(AST_SEC_EVT(&failed_acl_event));
2174}
#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 2284 of file manager.c.

2286{
2287 char session_id[32];
2288 struct ast_security_event_chal_resp_failed chal_resp_failed = {
2291 .common.service = "AMI",
2292 .common.account_id = s->session->username,
2293 .common.session_tv = &s->session->sessionstart_tv,
2294 .common.local_addr = {
2295 .addr = &s->tcptls_session->parent->local_address,
2296 .transport = mansession_get_transport(s),
2297 },
2298 .common.remote_addr = {
2299 .addr = &s->session->addr,
2300 .transport = mansession_get_transport(s),
2301 },
2302 .common.session_id = session_id,
2303
2304 .challenge = s->session->challenge,
2305 .response = response,
2306 .expected_response = expected_response,
2307 };
2308
2309 snprintf(session_id, sizeof(session_id), "%p", s->session);
2310
2311 ast_security_event_report(AST_SEC_EVT(&chal_resp_failed));
2312}
#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 2176 of file manager.c.

2177{
2178 char session_id[32];
2179 struct ast_security_event_inval_password inval_password = {
2182 .common.service = "AMI",
2183 .common.account_id = username,
2184 .common.session_tv = &s->session->sessionstart_tv,
2185 .common.local_addr = {
2186 .addr = &s->tcptls_session->parent->local_address,
2187 .transport = mansession_get_transport(s),
2188 },
2189 .common.remote_addr = {
2190 .addr = &s->session->addr,
2191 .transport = mansession_get_transport(s),
2192 },
2193 .common.session_id = session_id,
2194 };
2195
2196 snprintf(session_id, sizeof(session_id), "%p", s->session);
2197
2198 ast_security_event_report(AST_SEC_EVT(&inval_password));
2199}
#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 2126 of file manager.c.

2127{
2128 char session_id[32];
2129 struct ast_security_event_inval_acct_id inval_acct_id = {
2132 .common.service = "AMI",
2133 .common.account_id = username,
2134 .common.session_tv = &s->session->sessionstart_tv,
2135 .common.local_addr = {
2136 .addr = &s->tcptls_session->parent->local_address,
2137 .transport = mansession_get_transport(s),
2138 },
2139 .common.remote_addr = {
2140 .addr = &s->session->addr,
2141 .transport = mansession_get_transport(s),
2142 },
2143 .common.session_id = session_id,
2144 };
2145
2146 snprintf(session_id, sizeof(session_id), "%p", s);
2147
2148 ast_security_event_report(AST_SEC_EVT(&inval_acct_id));
2149}
#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 2255 of file manager.c.

2256{
2257 char session_id[32];
2258 char request_type[64];
2259 struct ast_security_event_req_bad_format req_bad_format = {
2262 .common.service = "AMI",
2263 .common.account_id = s->session->username,
2264 .common.session_tv = &s->session->sessionstart_tv,
2265 .common.local_addr = {
2266 .addr = &s->tcptls_session->parent->local_address,
2267 .transport = mansession_get_transport(s),
2268 },
2269 .common.remote_addr = {
2270 .addr = &s->session->addr,
2271 .transport = mansession_get_transport(s),
2272 },
2273 .common.session_id = session_id,
2274
2275 .request_type = request_type,
2276 };
2277
2278 snprintf(session_id, sizeof(session_id), "%p", s->session);
2279 snprintf(request_type, sizeof(request_type), "Action: %s", action);
2280
2281 ast_security_event_report(AST_SEC_EVT(&req_bad_format));
2282}
#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 2226 of file manager.c.

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

2315{
2316 char session_id[32];
2320 .common.service = "AMI",
2321 .common.account_id = s->session->username,
2322 .common.session_tv = &s->session->sessionstart_tv,
2323 .common.local_addr = {
2324 .addr = &s->tcptls_session->parent->local_address,
2325 .transport = mansession_get_transport(s),
2326 },
2327 .common.remote_addr = {
2328 .addr = &s->session->addr,
2329 .transport = mansession_get_transport(s),
2330 },
2331 .common.session_id = session_id,
2332 };
2333
2334 snprintf(session_id, sizeof(session_id), "%p", s->session);
2335
2337}
static int session_limit
Definition http.c:107
#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.
struct ast_security_event_common common
Common security event descriptor elements.

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

Referenced by process_message().

◆ send_string()

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

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

Definition at line 1866 of file manager.c.

1867{
1868 struct ast_iostream *stream;
1869 int len, res;
1870
1871 /* It's a result from one of the hook's action invocation */
1872 if (s->hook) {
1873 /*
1874 * to send responses, we're using the same function
1875 * as for receiving events. We call the event "HookResponse"
1876 */
1877 s->hook->helper(EVENT_FLAG_HOOKRESPONSE, "HookResponse", string);
1878 return 0;
1879 }
1880
1881 stream = s->stream ? s->stream : s->session->stream;
1882
1883 len = strlen(string);
1885 res = ast_iostream_write(stream, string, len);
1887
1888 if (res < len) {
1889 s->write_error = 1;
1890 }
1891
1892 return res;
1893}
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 timeval start
Definition iostream.c:41
struct ast_iostream * stream
Definition manager.c:325

References ast_iostream_set_timeout_disable(), ast_iostream_set_timeout_inactivity(), ast_iostream_write(), EVENT_FLAG_HOOKRESPONSE, manager_custom_hook::helper, mansession::hook, len(), mansession::session, ast_iostream::start, 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 1018 of file manager.c.

1019{
1020 struct ao2_container *sessions;
1021
1022 sessions = ao2_global_obj_ref(mgr_sessions);
1023 if (sessions) {
1024 ao2_unlink(sessions, s);
1025 ao2_ref(sessions, -1);
1026 }
1028}
#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 947 of file manager.c.

948{
949 struct mansession_session *session = obj;
950 struct eventqent *eqe = session->last_ev;
951 struct ast_datastore *datastore;
952
953 /* Get rid of each of the data stores on the session */
954 while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) {
955 /* Free the data store */
956 ast_datastore_free(datastore);
957 }
958
959 if (eqe) {
961 }
962 if (session->chanvars) {
964 }
965
966 if (session->includefilters) {
967 ao2_t_ref(session->includefilters, -1, "decrement ref for include container, should be last one");
968 }
969
970 if (session->excludefilters) {
971 ao2_t_ref(session->excludefilters, -1, "decrement ref for exclude container, should be last one");
972 }
973
974 ast_mutex_destroy(&session->notify_lock);
975}
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.
#define ast_mutex_destroy(a)
Definition lock.h:195
Structure for a data store object.
Definition datastore.h:64
struct ast_datastore::@223 entry

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

Referenced by build_mansession().

◆ session_do()

static void * session_do ( void *  data)
static

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

Definition at line 7378 of file manager.c.

7379{
7380 struct ast_tcptls_session_instance *ser = data;
7382 struct mansession s = {
7383 .tcptls_session = data,
7384 };
7385 int res;
7386 int arg = 1;
7387 struct ast_sockaddr ser_remote_address_tmp;
7388
7391 goto done;
7392 }
7393
7394 ast_sockaddr_copy(&ser_remote_address_tmp, &ser->remote_address);
7395 session = build_mansession(&ser_remote_address_tmp);
7396
7397 if (session == NULL) {
7399 goto done;
7400 }
7401
7402 /* here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
7403 * This is necessary to prevent delays (caused by buffering) as we
7404 * write to the socket in bits and pieces. */
7405 if (setsockopt(ast_iostream_get_fd(ser->stream), IPPROTO_TCP, TCP_NODELAY, (char *) &arg, sizeof(arg)) < 0) {
7406 ast_log(LOG_WARNING, "Failed to set TCP_NODELAY on manager connection: %s\n", strerror(errno));
7407 }
7409
7411 /* Hook to the tail of the event queue */
7412 session->last_ev = grab_last();
7413
7414 ast_mutex_init(&s.lock);
7415
7416 /* these fields duplicate those in the 'ser' structure */
7417 session->stream = s.stream = ser->stream;
7418 ast_sockaddr_copy(&session->addr, &ser_remote_address_tmp);
7419 s.session = session;
7420
7421 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
7422
7423 if(time(&session->authstart) == -1) {
7424 ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
7428 goto done;
7429 }
7431
7432 /*
7433 * We cannot let the stream exclusively wait for data to arrive.
7434 * We have to wake up the task to send async events.
7435 */
7437
7439 ast_tvnow(), authtimeout * 1000);
7440
7441 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */
7442 for (;;) {
7443 if ((res = do_message(&s)) < 0 || s.write_error || session->kicked) {
7444 break;
7445 }
7446 if (session->authenticated) {
7448 }
7449 }
7450 /* session is over, explain why and terminate */
7451 if (session->authenticated) {
7453 ast_verb(2, "Manager '%s' %s from %s\n", session->username, session->kicked ? "kicked" : "logged off", ast_sockaddr_stringify_addr(&session->addr));
7454 }
7455 } else {
7457 if (displayconnects) {
7458 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_sockaddr_stringify_addr(&session->addr));
7459 }
7460 }
7461
7463
7465done:
7466 ao2_ref(ser, -1);
7467 ser = NULL;
7468 return NULL;
7469}
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:978
static int do_message(struct mansession *s)
Definition manager.c:7293
static struct eventqent * grab_last(void)
Definition manager.c:706
static int authlimit
Definition manager.c:171
void ast_iostream_set_exclusive_input(struct ast_iostream *stream, int exclusive_input)
Set the iostream if it can exclusively depend upon the set timeouts.
Definition iostream.c:149
void ast_iostream_set_timeout_sequence(struct ast_iostream *stream, struct timeval start, int timeout)
Set the iostream I/O sequence timeout timer.
Definition iostream.c:140
void ast_iostream_nonblock(struct ast_iostream *stream)
Make an iostream non-blocking.
Definition iostream.c:104
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Socket address structure.
Definition netsock2.h:97
describes a server instance
Definition tcptls.h:151
struct ast_sockaddr remote_address
Definition tcptls.h:153

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

◆ set_eventmask()

static int set_eventmask ( struct mansession s,
const char *  eventmask 
)
static

Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm.

Definition at line 2107 of file manager.c.

2108{
2109 int maskint = strings_to_mask(eventmask);
2110
2111 ao2_lock(s->session);
2112 if (maskint >= 0) {
2113 s->session->send_events = maskint;
2114 }
2115 ao2_unlock(s->session);
2116
2117 return maskint;
2118}
static int strings_to_mask(const char *string)
Definition manager.c:895

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

5668{
5669 int result = 0;
5670
5671 if (manager_debug) {
5672 ast_verbose("<-- Examining AMI event (%u): -->\n%s\n", eqe->event_name_hash, eqe->eventdata);
5673 } else {
5674 ast_debug(4, "Examining AMI event (%u):\n%s\n", eqe->event_name_hash, eqe->eventdata);
5675 }
5676 if (!ao2_container_count(includefilters) && !ao2_container_count(excludefilters)) {
5677 return 1; /* no filtering means match all */
5678 } else if (ao2_container_count(includefilters) && !ao2_container_count(excludefilters)) {
5679 /* include filters only: implied exclude all filter processed first, then include filters */
5680 ao2_t_callback_data(includefilters, OBJ_NODATA, filter_cmp_fn, eqe, &result, "find filter in includefilters container");
5681 return result;
5682 } else if (!ao2_container_count(includefilters) && ao2_container_count(excludefilters)) {
5683 /* exclude filters only: implied include all filter processed first, then exclude filters */
5684 ao2_t_callback_data(excludefilters, OBJ_NODATA, filter_cmp_fn, eqe, &result, "find filter in excludefilters container");
5685 return !result;
5686 } else {
5687 /* include and exclude filters: implied exclude all filter processed first, then include filters, and lastly exclude filters */
5688 ao2_t_callback_data(includefilters, OBJ_NODATA, filter_cmp_fn, eqe, &result, "find filter in session filter container");
5689 if (result) {
5690 result = 0;
5691 ao2_t_callback_data(excludefilters, OBJ_NODATA, filter_cmp_fn, eqe, &result, "find filter in session filter container");
5692 return !result;
5693 }
5694 }
5695
5696 return result;
5697}
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:5613

References ao2_container_count(), ao2_t_callback_data, ast_debug, ast_verbose, eventqent::event_name_hash, eventqent::eventdata, 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 895 of file manager.c.

896{
897 const char *p;
898
899 if (ast_strlen_zero(string)) {
900 return -1;
901 }
902
903 for (p = string; *p; p++) {
904 if (*p < '0' || *p > '9') {
905 break;
906 }
907 }
908 if (!*p) { /* all digits */
909 return atoi(string);
910 }
911 if (ast_false(string)) {
912 return 0;
913 }
914 if (ast_true(string)) { /* all permissions */
915 int x, ret = 0;
916 for (x = 0; x < ARRAY_LEN(perms); x++) {
917 ret |= perms[x].num;
918 }
919 return ret;
920 }
921 return get_perm(string);
922}
static int get_perm(const char *instr)
Definition manager.c:874

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

927{
928 int refcount = ao2_ref(s, -1);
929 if (manager_debug) {
930 ast_debug(1, "Mansession: %p refcount now %d\n", s, refcount - 1);
931 }
932 return NULL;
933}

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

804{
805 int i;
806 char *sep = "";
807
808 ast_str_reset(*res);
809 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
810 if ((authority & perms[i].num) == perms[i].num) {
811 ast_str_append(res, 0, "%s%s", sep, perms[i].label);
812 sep = ",";
813 }
814 }
815
816 if (ast_str_strlen(*res) == 0) {
817 /* replace empty string with something sensible */
818 ast_str_append(res, 0, "<none>");
819 }
820
821 return ast_str_buffer(*res);
822}

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

Referenced by handle_showmanager().

Variable Documentation

◆ acl_change_sub

struct stasis_subscription* acl_change_sub
static

Definition at line 179 of file manager.c.

Referenced by acl_change_stasis_subscribe(), and acl_change_stasis_unsubscribe().

◆ actions

◆ all_events

◆ allowmultiplelogin

int allowmultiplelogin = 1
static

Definition at line 162 of file manager.c.

Referenced by __init_manager(), and handle_manager_show_settings().

◆ authlimit

int authlimit
static

Definition at line 171 of file manager.c.

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

◆ authtimeout

int authtimeout
static

Definition at line 170 of file manager.c.

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

◆ broken_events_action

int broken_events_action = 0
static

Definition at line 165 of file manager.c.

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

◆ [struct]

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

Referenced by check_blacklist().

◆ displayconnects

int displayconnects = 1
static

◆ global_realm

char global_realm[MAXHOSTNAMELEN]
static

Default realm

Definition at line 176 of file manager.c.

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

◆ httptimeout

int httptimeout = 60
static

◆ live_dangerously

int live_dangerously
static

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

Definition at line 196 of file manager.c.

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

◆ manager_channelvars

char* manager_channelvars
static

Definition at line 172 of file manager.c.

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

◆ manager_debug

int manager_debug = 0
static

◆ manager_disabledevents

char* manager_disabledevents
static

◆ manager_enabled

int manager_enabled = 0
static

◆ manager_hooks

◆ manager_topic

struct stasis_topic* manager_topic
static

◆ match_type_names

char* match_type_names[]
static

Definition at line 394 of file manager.c.

394 {
395 [FILTER_MATCH_REGEX] = "regex",
396 [FILTER_MATCH_EXACT] = "exact",
397 [FILTER_MATCH_STARTS_WITH] = "starts_with",
398 [FILTER_MATCH_ENDS_WITH] = "ends_with",
399 [FILTER_MATCH_CONTAINS] = "contains",
400 [FILTER_MATCH_NONE] = "none",
401};

Referenced by manager_add_filter().

◆ originate_app_permissions

struct originate_permissions_entry originate_app_permissions[]
static

Definition at line 5103 of file manager.c.

5103 {
5104 /*
5105 * The app_match function checks if the search string is
5106 * anywhere in the app parameter. The check is case-insensitive.
5107 */
5108 { "agi", EVENT_FLAG_SYSTEM, app_match },
5109 { "dbdeltree", EVENT_FLAG_SYSTEM, app_match },
5110 { "exec", EVENT_FLAG_SYSTEM, app_match },
5111 { "externalivr", EVENT_FLAG_SYSTEM, app_match },
5112 { "mixmonitor", EVENT_FLAG_SYSTEM, app_match },
5113 { "originate", EVENT_FLAG_SYSTEM, app_match },
5114 { "reload", EVENT_FLAG_SYSTEM, app_match },
5115 { "system", EVENT_FLAG_SYSTEM, app_match },
5116 /*
5117 * Since the queue_match function specifically checks
5118 * for the presence of the AGI parameter, we'll allow
5119 * the call if the user has either the AGI or SYSTEM
5120 * permission.
5121 */
5123 /*
5124 * The appdata_match function checks if the search string is
5125 * anywhere in the appdata parameter. Unlike app_match,
5126 * the check is case-sensitive. These are generally
5127 * dialplan functions.
5128 */
5129 { "CURL", EVENT_FLAG_SYSTEM, appdata_match },
5131 { "EVAL", EVENT_FLAG_SYSTEM, appdata_match },
5132 { "FILE", EVENT_FLAG_SYSTEM, appdata_match },
5133 { "ODBC", EVENT_FLAG_SYSTEM, appdata_match },
5134 { "REALTIME", EVENT_FLAG_SYSTEM, appdata_match },
5135 { "SHELL", EVENT_FLAG_SYSTEM, appdata_match },
5136 { NULL, 0 },
5137};
static int app_match(const char *app, const char *data, const char *search)
Definition manager.c:5027
static int queue_match(const char *app, const char *data, const char *search)
Definition manager.c:5066
static int appdata_match(const char *app, const char *data, const char *search)
Definition manager.c:5046
#define EVENT_FLAG_AGI
Definition manager.h:88

Referenced by is_originate_app_permitted().

◆ perms

const struct permalias perms[]
static

◆ rtp_topic_forwarder

struct stasis_forward* rtp_topic_forwarder
static

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

Definition at line 188 of file manager.c.

Referenced by manager_shutdown(), and manager_subscriptions_init().

◆ security_topic_forwarder

struct stasis_forward* security_topic_forwarder
static

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

Definition at line 191 of file manager.c.

Referenced by manager_shutdown(), and manager_subscriptions_init().

◆ stasis_router

struct stasis_message_router* stasis_router
static

◆ subscribed

int subscribed = 0
static

◆ timestampevents

int timestampevents
static

◆ unauth_sessions

int unauth_sessions = 0
static

Definition at line 178 of file manager.c.

Referenced by action_login(), and session_do().

◆ users

◆ webmanager_enabled

int webmanager_enabled = 0
static

◆ words

const char* words[AST_MAX_CMD_LEN]

Definition at line 222 of file manager.c.