Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Enumerations | Functions | Variables
AMI functions

Data Structures

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

Macros

#define any_manager_listeners(sessions)   ((sessions && ao2_container_count(sessions)) || !AST_RWLIST_EMPTY(&manager_hooks))
 
#define ASTMAN_APPEND_BUF_INITSIZE   256
 initial allocated size for the astman_append_buf and astman_send_*_va
 
#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. More...
 
#define MAX_VARS   128
 
#define MGR_SHOW_TERMINAL_WIDTH   80
 
#define MSG_MOREDATA   ((char *)astman_send_response)
 

Enumerations

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

Functions

int __ast_manager_event_multichan (int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt,...)
 
static const char * __astman_get_header (const struct message *m, char *var, int mode)
 Return a matching header value. More...
 
static void __init_astman_append_buf (void)
 thread local buffer for astman_append More...
 
static void __init_manager_event_buf (void)
 
static void __init_userevent_buf (void)
 
static int __manager_event_sessions (struct ao2_container *sessions, int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt,...)
 
static int __manager_event_sessions_va (struct ao2_container *sessions, int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt, va_list ap)
 
static void acl_change_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void acl_change_stasis_subscribe (void)
 
static void acl_change_stasis_unsubscribe (void)
 
static struct ast_aoc_decodedaction_aoc_de_message (struct mansession *s, const struct message *m)
 
static struct ast_aoc_decodedaction_aoc_s_message (struct mansession *s, const struct message *m)
 
static int action_aoc_s_submessage (struct mansession *s, const struct message *m, struct ast_aoc_decoded *decoded)
 
static int action_aocmessage (struct mansession *s, const struct message *m)
 
static int action_atxfer (struct mansession *s, const struct message *m)
 
static int action_blind_transfer (struct mansession *s, const struct message *m)
 
static int action_cancel_atxfer (struct mansession *s, const struct message *m)
 
static int action_challenge (struct mansession *s, const struct message *m)
 
static int action_command (struct mansession *s, const struct message *m)
 Manager command "command" - execute CLI command.
 
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. More...
 
static struct manager_actionaction_find (const char *name)
 
static int action_getconfig (struct mansession *s, const struct message *m)
 
static int action_getconfigjson (struct mansession *s, const struct message *m)
 
static int action_getvar (struct mansession *s, const struct message *m)
 
static int action_hangup (struct mansession *s, const struct message *m)
 
static int action_listcategories (struct mansession *s, const struct message *m)
 
static int action_listcommands (struct mansession *s, const struct message *m)
 
static int action_loggerrotate (struct mansession *s, const struct message *m)
 Manager command "LoggerRotate" - reloads and rotates the logger in the same manner as the CLI command 'logger rotate'.
 
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 (mgr_sessions)
 
static AO2_GLOBAL_OBJ_STATIC (event_docs)
 A container of event documentation nodes.
 
static int aocmessage_get_unit_entry (const struct message *m, struct ast_aoc_unit_entry *entry, unsigned int entry_num)
 
static void append_channel_vars (struct ast_str **pbuf, struct ast_channel *chan)
 
static int append_event (const char *str, int category)
 events are appended to a queue from where they can be dispatched to clients.
 
int ast_hook_send_action (struct manager_custom_hook *hook, const char *msg)
 access for hooks to send action messages to ami More...
 
static int ast_instring (const char *bigstr, const char *smallstr, const char delim)
 
int ast_manager_check_enabled (void)
 Check if AMI is enabled.
 
struct stasis_message_routerast_manager_get_message_router (void)
 Get the stasis_message_router for AMI. More...
 
struct stasis_topicast_manager_get_topic (void)
 Get the Stasis Message Bus API topic for AMI. More...
 
int ast_manager_hangup_helper (struct mansession *s, const struct message *m, manager_hangup_handler_t hangup_handler, manager_hangup_cause_validator_t cause_validator)
 A manager helper function that hangs up a channel using a supplied channel type specific hangup function and cause code validator. More...
 
void ast_manager_publish_event (const char *type, int class_type, struct ast_json *obj)
 Publish an event to AMI. More...
 
int ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), struct ast_module *module, const char *synopsis, const char *description)
 register a new command with manager, including online help. This is the preferred way to register a manager command More...
 
void ast_manager_register_hook (struct manager_custom_hook *hook)
 Add a custom hook to be called when an event is fired. More...
 
static int ast_manager_register_struct (struct manager_action *act)
 
struct ast_strast_manager_str_from_json_object (struct ast_json *blob, key_exclusion_cb exclusion_cb)
 Convert a JSON object into an AMI compatible string. More...
 
int ast_manager_unregister (const char *action)
 support functions to register/unregister AMI action handlers, More...
 
void ast_manager_unregister_hook (struct manager_custom_hook *hook)
 Delete a custom hook to be called when an event is fired. More...
 
int ast_webmanager_check_enabled (void)
 Check if AMI/HTTP is enabled.
 
void astman_append (struct mansession *s, const char *fmt,...)
 
static void astman_append_headers (struct message *m, const struct ast_variable *params)
 Append additional headers into the message structure from params. More...
 
static void astman_append_json (struct mansession *s, const char *str)
 
static void astman_flush (struct mansession *s, struct ast_str *buf)
 
static void astman_free_headers (struct message *m)
 Free headers inside message structure, but not the message structure itself.
 
const char * astman_get_header (const struct message *m, char *var)
 Return the first matching variable from an array. More...
 
struct ast_variableastman_get_variables (const struct message *m)
 Get a linked list of the Variable: headers. More...
 
struct ast_variableastman_get_variables_order (const struct message *m, enum variable_orders order)
 Get a linked list of the Variable: headers with order specified.
 
void astman_live_dangerously (int new_live_dangerously)
 Enable/disable the inclusion of 'dangerous' configurations outside of the ast_config_AST_CONFIG_DIR. More...
 
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
 Send ack in manager transaction.
 
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. More...
 
void astman_send_list_complete_start (struct mansession *s, const struct message *m, const char *event_name, int count)
 Start the list complete event. More...
 
static struct ast_strastman_send_list_complete_start_common (struct mansession *s, const struct message *m, const char *event_name, int count)
 
void astman_send_listack (struct mansession *s, const struct message *m, char *msg, char *listflag)
 Send ack in manager transaction to begin a list. More...
 
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
 Send response in manager transaction.
 
static void astman_send_response_full (struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
 send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field. More...
 
static void astman_start_ack (struct mansession *s, const struct message *m)
 
static int authenticate (struct mansession *s, const struct message *m)
 
static const char * authority_to_str (int authority, struct ast_str **res)
 Convert authority code to a list of options. Note that the EVENT_FLAG_ALL authority will always be returned.
 
static int blackfilter_cmp_fn (void *obj, void *arg, void *data, int flags)
 
static struct mansession_sessionbuild_mansession (const struct ast_sockaddr *addr)
 Allocate manager session structure and add it to the list of sessions.
 
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 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 void json_escape (char *out, const char *in)
 
static void log_action (const struct message *m, const char *action)
 
static struct ast_variableman_do_variable_value (struct ast_variable *head, const char *hdr_val)
 
static enum add_filter_result manager_add_filter (const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters)
 Add an event filter to a manager session. More...
 
static void manager_default_msg_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static int manager_displayconnects (struct mansession_session *session)
 Get displayconnects config option. More...
 
static void manager_generic_msg_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void manager_json_array_with_key (struct ast_json *obj, const char *key, size_t index, struct ast_str **res, key_exclusion_cb exclusion_cb)
 
static void manager_json_obj_with_key (struct ast_json *obj, const char *key, const char *parent_key, struct ast_str **res, key_exclusion_cb exclusion_cb)
 
static void manager_json_to_ast_str (struct ast_json *obj, const char *key, struct ast_str **res, key_exclusion_cb exclusion_cb)
 
static void manager_json_value_str_append (struct ast_json *value, const char *key, struct ast_str **res)
 
static int manager_modulecheck (struct mansession *s, const struct message *m)
 Manager function to check if module is loaded.
 
static int manager_moduleload (struct mansession *s, const struct message *m)
 
static int manager_state_cb (const char *context, const char *exten, struct ast_state_cb_info *info, void *data)
 
static int mansession_cmp_fn (void *obj, void *arg, int flags)
 
static enum ast_transport mansession_get_transport (const struct mansession *s)
 
static void mansession_lock (struct mansession *s)
 Lock the 'mansession' structure.
 
static void mansession_unlock (struct mansession *s)
 Unlock the 'mansession' structure.
 
static int match_filter (struct mansession *s, char *eventdata)
 
static void print_event_instance (struct ast_cli_args *a, struct ast_xml_doc_item *instance)
 
static int process_events (struct mansession *s)
 
static int process_message (struct mansession *s, const struct message *m)
 Process an AMI message, performing desired action. Return 0 on success, -1 on error that require the session to be destroyed.
 
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_read_action_payload (struct ast_channel *chan, const unsigned char *payload, size_t payload_size, enum ast_frame_read_action action)
 Queue a given read action containing a payload onto a channel. More...
 
static int queue_sendtext (struct ast_channel *chan, const char *body)
 Queue a read action to send a text message. More...
 
static int queue_sendtext_data (struct ast_channel *chan, const char *body, const char *content_type)
 Queue a read action to send a text data message. More...
 
static int reload_module (void)
 
static void report_auth_success (const struct mansession *s)
 
static void report_failed_acl (const struct mansession *s, const char *username)
 
static void report_failed_challenge_response (const struct mansession *s, const char *response, const char *expected_response)
 
static void report_inval_password (const struct mansession *s, const char *username)
 
static void report_invalid_user (const struct mansession *s, const char *username)
 
static void report_req_bad_format (const struct mansession *s, const char *action)
 
static void report_req_not_allowed (const struct mansession *s, const char *action)
 
static void report_session_limit (const struct mansession *s)
 
static int restrictedFile (const char *filename)
 Check if a file is restricted or not. More...
 
static int send_string (struct mansession *s, char *string)
 
static void session_destroy (struct mansession_session *s)
 
static void session_destructor (void *obj)
 
static void * session_do (void *data)
 The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). )
 
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 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.
 
static int whitefilter_cmp_fn (void *obj, void *arg, void *data, int flags)
 

Variables

static struct stasis_subscriptionacl_change_sub
 
static struct actions actions = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct all_events all_events = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static int allowmultiplelogin = 1
 
static struct ast_threadstorage astman_append_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_astman_append_buf , .custom_init = NULL , }
 
static int authlimit
 
static int authtimeout
 
static int broken_events_action = 0
 
struct {
   const char *   words [AST_MAX_CMD_LEN]
 
command_blacklist []
 
static int displayconnects = 1
 
static char global_realm [MAXHOSTNAMELEN]
 
static int httptimeout = 60
 
static int live_dangerously
 Set to true (non-zero) to globally allow all dangerous AMI actions to run.
 
static char * manager_channelvars
 
static int manager_debug = 0
 
static char * manager_disabledevents
 
static int manager_enabled = 0
 
static struct ast_threadstorage manager_event_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_buf , .custom_init = NULL , }
 
static struct manager_hooks manager_hooks = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct stasis_topicmanager_topic
 A stasis_topic that all topics AMI cares about will be forwarded to.
 
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 ast_threadstorage userevent_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_userevent_buf , .custom_init = NULL , }
 
static struct users users = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static int webmanager_enabled = 0
 
 STASIS_MESSAGE_TYPE_DEFN (ast_manager_get_generic_type)
 Define AMI message types.
 

Detailed Description

Macro Definition Documentation

#define MAX_AUTH_PERM_STRING   150

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

Definition at line 2203 of file manager.c.

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

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

Referenced by action_command(), and astman_send_response_full().

Enumeration Type Documentation

enum error_type

Doxygen group

Definition at line 1572 of file manager.c.

1572  {
1573  UNKNOWN_ACTION = 1,
1574  UNKNOWN_CATEGORY,
1575  UNSPECIFIED_CATEGORY,
1576  UNSPECIFIED_ARGUMENT,
1577  FAILURE_ALLOCATION,
1578  FAILURE_NEWCAT,
1579  FAILURE_DELCAT,
1580  FAILURE_EMPTYCAT,
1581  FAILURE_UPDATE,
1582  FAILURE_DELETE,
1583  FAILURE_APPEND,
1584  FAILURE_TEMPLATE
1585 };

Function Documentation

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

References ao2_global_obj_ref.

8035 {
8036  struct ao2_container *sessions = ao2_global_obj_ref(mgr_sessions);
8037  va_list ap;
8038  int res;
8039 
8040  if (!any_manager_listeners(sessions)) {
8041  /* Nobody is listening */
8042  ao2_cleanup(sessions);
8043  return 0;
8044  }
8045 
8046  va_start(ap, fmt);
8047  res = __manager_event_sessions_va(sessions, category, event, chancount, chans,
8048  file, line, func, fmt, ap);
8049  va_end(ap);
8050  ao2_cleanup(sessions);
8051  return res;
8052 }
Definition: astman.c:222
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
Generic container type.
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 3013 of file manager.c.

References ast_skip_blanks().

Referenced by astman_get_header(), and process_message().

3014 {
3015  int x, l = strlen(var);
3016  const char *result = "";
3017 
3018  if (!m) {
3019  return result;
3020  }
3021 
3022  for (x = 0; x < m->hdrcount; x++) {
3023  const char *h = m->headers[x];
3024  if (!strncasecmp(var, h, l) && h[l] == ':') {
3025  const char *value = h + l + 1;
3026  value = ast_skip_blanks(value); /* ignore leading spaces in the value */
3027  /* found a potential candidate */
3028  if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) {
3029  continue; /* not interesting */
3030  }
3031  if (mode & GET_HEADER_LAST_MATCH) {
3032  result = value; /* record the last match so far */
3033  } else {
3034  return value;
3035  }
3036  }
3037  }
3038 
3039  return result;
3040 }
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
static void __init_astman_append_buf ( void  )
static

thread local buffer for astman_append

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

Definition at line 3291 of file manager.c.

3299 {
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 6716 of file manager.c.

References astman_get_header(), astman_send_ack(), astman_send_error(), mansession_session::blackfilters, manager_add_filter(), and mansession_session::whitefilters.

6717 {
6718  const char *filter = astman_get_header(m, "Filter");
6719  const char *operation = astman_get_header(m, "Operation");
6720  int res;
6721 
6722  if (!strcasecmp(operation, "Add")) {
6723  res = manager_add_filter(filter, s->session->whitefilters, s->session->blackfilters);
6724 
6725  if (res != FILTER_SUCCESS) {
6726  if (res == FILTER_ALLOC_FAILED) {
6727  astman_send_error(s, m, "Internal Error. Failed to allocate regex for filter");
6728  return 0;
6729  } else if (res == FILTER_COMPILE_FAIL) {
6730  astman_send_error(s, m, "Filter did not compile. Check the syntax of the filter given.");
6731  return 0;
6732  } else {
6733  astman_send_error(s, m, "Internal Error. Failed adding filter.");
6734  return 0;
6735  }
6736  }
6737 
6738  astman_send_ack(s, m, "Success");
6739  return 0;
6740  }
6741 
6742  astman_send_error(s, m, "Unknown operation");
6743  return 0;
6744 }
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3421
struct ao2_container * blackfilters
Definition: manager.c:1759
const char * astman_get_header(const struct message *m, char *var)
Return the first matching variable from an array.
Definition: manager.c:3050
struct ao2_container * whitefilters
Definition: manager.c:1758
static enum add_filter_result manager_add_filter(const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters)
Add an event filter to a manager session.
Definition: manager.c:6768
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:807
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3389
static AO2_GLOBAL_OBJ_STATIC ( mgr_sessions  )
static

Active manager connection sessions container.

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

References ast_module_running_ref, ast_module_unref, ast_strdup, astman_get_header(), manager_action::func, manager_action::module, and manager_action::registered.

3168 {
3169  const char *action;
3170  int ret = 0;
3171  struct manager_action *act_found;
3172  struct mansession s = {.session = NULL, };
3173  struct message m = { 0 };
3174  char *dup_str;
3175  char *src;
3176  int x = 0;
3177  int curlen;
3178 
3179  if (hook == NULL) {
3180  return -1;
3181  }
3182 
3183  /* Create our own copy of the AMI action msg string. */
3184  src = dup_str = ast_strdup(msg);
3185  if (!dup_str) {
3186  return -1;
3187  }
3188 
3189  /* convert msg string to message struct */
3190  curlen = strlen(src);
3191  for (x = 0; x < curlen; x++) {
3192  int cr; /* set if we have \r */
3193  if (src[x] == '\r' && x+1 < curlen && src[x+1] == '\n')
3194  cr = 2; /* Found. Update length to include \r\n */
3195  else if (src[x] == '\n')
3196  cr = 1; /* also accept \n only */
3197  else
3198  continue;
3199  /* don't keep empty lines */
3200  if (x && m.hdrcount < ARRAY_LEN(m.headers)) {
3201  /* ... but trim \r\n and terminate the header string */
3202  src[x] = '\0';
3203  m.headers[m.hdrcount++] = src;
3204  }
3205  x += cr;
3206  curlen -= x; /* remaining size */
3207  src += x; /* update pointer */
3208  x = -1; /* reset loop */
3209  }
3210 
3211  action = astman_get_header(&m, "Action");
3212 
3213  do {
3214  if (!strcasecmp(action, "login")) {
3215  break;
3216  }
3217 
3218  act_found = action_find(action);
3219  if (!act_found) {
3220  break;
3221  }
3222 
3223  /*
3224  * we have to simulate a session for this action request
3225  * to be able to pass it down for processing
3226  * This is necessary to meet the previous design of manager.c
3227  */
3228  s.hook = hook;
3229 
3230  ret = -1;
3231  ao2_lock(act_found);
3232  if (act_found->registered && act_found->func) {
3233  struct ast_module *mod_ref = ast_module_running_ref(act_found->module);
3234 
3235  ao2_unlock(act_found);
3236  /* If the action is in a module it must be running. */
3237  if (!act_found->module || mod_ref) {
3238  ret = act_found->func(&s, &m);
3239  ast_module_unref(mod_ref);
3240  }
3241  } else {
3242  ao2_unlock(act_found);
3243  }
3244  ao2_t_ref(act_found, -1, "done with found action object");
3245  } while (0);
3246 
3247  ast_free(dup_str);
3248  return ret;
3249 }
int(* func)(struct mansession *s, const struct message *m)
Definition: manager.h:171
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
struct ast_module * module
Definition: manager.h:172
const char * astman_get_header(const struct message *m, char *var)
Return the first matching variable from an array.
Definition: manager.c:3050
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, 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.
Definition: manager.c:1785
#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
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 2272 of file manager.c.

2273 {
2274  const char *val = bigstr, *next;
2275 
2276  do {
2277  if ((next = strchr(val, delim))) {
2278  if (!strncmp(val, smallstr, (next - val))) {
2279  return 1;
2280  } else {
2281  continue;
2282  }
2283  } else {
2284  return !strcmp(smallstr, val);
2285  }
2286  } while (*(val = (next + 1)));
2287 
2288  return 0;
2289 }
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 1885 of file manager.c.

References stasis_router.

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

1886 {
1887  return stasis_router;
1888 }
static struct stasis_message_router * stasis_router
The stasis_message_router for all Stasis Message Bus API messages.
Definition: manager.c:1647
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 1880 of file manager.c.

References manager_topic.

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

1881 {
1882  return manager_topic;
1883 }
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:1644
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 4762 of file manager.c.

References mansession_session::addr, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_unref, ast_regex_string_to_regex_pattern(), ast_sockaddr_stringify_addr(), ast_str_buffer(), ast_str_create, astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), astman_send_error_va(), astman_send_listack(), mansession_session::managerid, and mansession_session::username.

Referenced by pjsip_action_hangup().

4765 {
4766  struct ast_channel *c = NULL;
4767  int causecode = 0; /* all values <= 0 mean 'do not set hangupcause in channel' */
4768  const char *id = astman_get_header(m, "ActionID");
4769  const char *name_or_regex = astman_get_header(m, "Channel");
4770  const char *cause = astman_get_header(m, "Cause");
4771  char idText[256];
4772  regex_t regexbuf;
4773  struct ast_channel_iterator *iter = NULL;
4774  struct ast_str *regex_string;
4775  int channels_matched = 0;
4776 
4777  if (ast_strlen_zero(name_or_regex)) {
4778  astman_send_error(s, m, "No channel specified");
4779  return 0;
4780  }
4781 
4782  if (!ast_strlen_zero(id)) {
4783  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
4784  } else {
4785  idText[0] = '\0';
4786  }
4787 
4788  if (cause_validator) {
4789  causecode = cause_validator(name_or_regex, cause);
4790  } else if (!ast_strlen_zero(cause)) {
4791  char *endptr;
4792  causecode = strtol(cause, &endptr, 10);
4793  if (causecode < 0 || causecode > 127 || *endptr != '\0') {
4794  ast_log(LOG_NOTICE, "Invalid 'Cause: %s' in manager action Hangup\n", cause);
4795  /* keep going, better to hangup without cause than to not hang up at all */
4796  causecode = 0; /* do not set channel's hangupcause */
4797  }
4798  }
4799 
4800  /************************************************/
4801  /* Regular explicit match channel byname hangup */
4802 
4803  if (name_or_regex[0] != '/') {
4804  if (!(c = ast_channel_get_by_name(name_or_regex))) {
4805  ast_log(LOG_NOTICE, "Request to hangup non-existent channel: %s\n",
4806  name_or_regex);
4807  astman_send_error(s, m, "No such channel");
4808  return 0;
4809  }
4810 
4811  ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
4812  (s->session->managerid ? "HTTP " : ""),
4813  s->session->username,
4814  ast_sockaddr_stringify_addr(&s->session->addr),
4815  ast_channel_name(c));
4816 
4817  hangup_handler(c, causecode);
4818  c = ast_channel_unref(c);
4819 
4820  astman_send_ack(s, m, "Channel Hungup");
4821 
4822  return 0;
4823  }
4824 
4825  /***********************************************/
4826  /* find and hangup any channels matching regex */
4827 
4828  regex_string = ast_str_create(strlen(name_or_regex));
4829  if (!regex_string) {
4830  astman_send_error(s, m, "Memory Allocation Failure");
4831  return 0;
4832  }
4833 
4834  /* Make "/regex/" into "regex" */
4835  if (ast_regex_string_to_regex_pattern(name_or_regex, &regex_string) != 0) {
4836  astman_send_error(s, m, "Regex format invalid, Channel param should be /regex/");
4837  ast_free(regex_string);
4838  return 0;
4839  }
4840 
4841  /* if regex compilation fails, hangup fails */
4842  if (regcomp(&regexbuf, ast_str_buffer(regex_string), REG_EXTENDED | REG_NOSUB)) {
4843  astman_send_error_va(s, m, "Regex compile failed on: %s", name_or_regex);
4844  ast_free(regex_string);
4845  return 0;
4846  }
4847 
4848  astman_send_listack(s, m, "Channels hung up will follow", "start");
4849 
4851  if (iter) {
4852  for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
4853  if (regexec(&regexbuf, ast_channel_name(c), 0, NULL, 0)) {
4854  continue;
4855  }
4856 
4857  ast_verb(3, "%sManager '%s' from %s, hanging up channel: %s\n",
4858  (s->session->managerid ? "HTTP " : ""),
4859  s->session->username,
4860  ast_sockaddr_stringify_addr(&s->session->addr),
4861  ast_channel_name(c));
4862 
4863  hangup_handler(c, causecode);
4864  channels_matched++;
4865 
4866  astman_append(s,
4867  "Event: ChannelHungup\r\n"
4868  "Channel: %s\r\n"
4869  "%s"
4870  "\r\n", ast_channel_name(c), idText);
4871  }
4873  }
4874 
4875  regfree(&regexbuf);
4876  ast_free(regex_string);
4877 
4878  astman_send_list_complete(s, m, "ChannelsHungupListComplete", channels_matched);
4879 
4880  return 0;
4881 }
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
Main Channel structure associated with a channel.
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3310
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1422
char username[80]
Definition: manager.c:1751
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3421
struct ast_sockaddr addr
Definition: manager.c:1742
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:3394
const char * astman_get_header(const struct message *m, char *var)
Return the first matching variable from an array.
Definition: manager.c:3050
Support for dynamic strings.
Definition: strings.h:623
int ast_regex_string_to_regex_pattern(const char *regex_string, struct ast_str **regex_pattern)
Given a string regex_string in the form of "/regex/", convert it into the form of "regex"...
Definition: utils.c:2179
uint32_t managerid
Definition: manager.c:1747
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1360
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1408
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3389
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
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:3431
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 2063 of file manager.c.

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

Referenced by really_quit(), and reset_user_pw().

2064 {
2065  RAII_VAR(struct ast_json *, event_info, NULL, ast_json_unref);
2066  RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
2067  RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
2068 
2069  if (!obj || !ast_manager_get_generic_type()) {
2070  return;
2071  }
2072 
2073  ast_json_ref(obj);
2074  event_info = ast_json_pack("{s: s, s: i, s: o}",
2075  "type", type,
2076  "class_type", class_type,
2077  "event", obj);
2078  if (!event_info) {
2079  return;
2080  }
2081 
2082  payload = ast_json_payload_create(event_info);
2083  if (!payload) {
2084  return;
2085  }
2087  if (!message) {
2088  return;
2089  }
2091 }
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
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
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct stasis_message_type * ast_manager_get_generic_type(void)
Get the stasis_message_type for generic messages.
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1511
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
Definition: manager.c:1880
Abstract JSON element (object, array, string, int, ...).
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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 8183 of file manager.c.

References manager_action::action, AST_STATIC_DOC, ast_string_field_init, ast_string_field_set, AST_XML_DOC, ast_xmldoc_build_arguments(), ast_xmldoc_build_description(), ast_xmldoc_build_final_response(), ast_xmldoc_build_list_responses(), ast_xmldoc_build_seealso(), ast_xmldoc_build_synopsis(), ast_xmldoc_build_syntax(), manager_action::authority, manager_action::docsrc, manager_action::final_response, manager_action::func, manager_action::list_responses, and manager_action::module.

8184 {
8185  struct manager_action *cur;
8186 
8187  cur = ao2_t_alloc(sizeof(*cur), action_destroy, action);
8188  if (!cur) {
8189  return -1;
8190  }
8191  if (ast_string_field_init(cur, 128)) {
8192  ao2_t_ref(cur, -1, "action object creation failed");
8193  return -1;
8194  }
8195 
8196  cur->action = action;
8197  cur->authority = auth;
8198  cur->func = func;
8199  cur->module = module;
8200 #ifdef AST_XML_DOCS
8201  if (ast_strlen_zero(synopsis) && ast_strlen_zero(description)) {
8202  char *tmpxml;
8203 
8204  tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL);
8205  ast_string_field_set(cur, synopsis, tmpxml);
8206  ast_free(tmpxml);
8207 
8208  tmpxml = ast_xmldoc_build_syntax("manager", action, NULL);
8209  ast_string_field_set(cur, syntax, tmpxml);
8210  ast_free(tmpxml);
8211 
8212  tmpxml = ast_xmldoc_build_description("manager", action, NULL);
8213  ast_string_field_set(cur, description, tmpxml);
8214  ast_free(tmpxml);
8215 
8216  tmpxml = ast_xmldoc_build_seealso("manager", action, NULL);
8217  ast_string_field_set(cur, seealso, tmpxml);
8218  ast_free(tmpxml);
8219 
8220  tmpxml = ast_xmldoc_build_arguments("manager", action, NULL);
8221  ast_string_field_set(cur, arguments, tmpxml);
8222  ast_free(tmpxml);
8223 
8224  cur->final_response = ast_xmldoc_build_final_response("manager", action, NULL);
8225  cur->list_responses = ast_xmldoc_build_list_responses("manager", action, NULL);
8226 
8227  cur->docsrc = AST_XML_DOC;
8228  } else
8229 #endif
8230  {
8233 #ifdef AST_XML_DOCS
8234  cur->docsrc = AST_STATIC_DOC;
8235 #endif
8236  }
8237  if (ast_manager_register_struct(cur)) {
8238  ao2_t_ref(cur, -1, "action object registration failed");
8239  return -1;
8240  }
8241 
8242  ao2_t_ref(cur, -1, "action object registration successful");
8243  return 0;
8244 }
int(* func)(struct mansession *s, const struct message *m)
Definition: manager.h:171
char * ast_xmldoc_build_description(const char *type, const char *name, const char *module)
Generate description documentation from XML.
Definition: xmldoc.c:2271
const char * action
Definition: manager.h:156
struct ast_xml_doc_item * list_responses
Definition: manager.h:165
char * ast_xmldoc_build_synopsis(const char *type, const char *name, const char *module)
Generate synopsis documentation from XML.
Definition: xmldoc.c:2248
char * ast_xmldoc_build_arguments(const char *type, const char *name, const char *module)
Generate the [arguments] tag based on type of node ('application', 'function' or 'agi') and name...
Definition: xmldoc.c:2084
struct ast_xml_doc_item * ast_xmldoc_build_final_response(const char *type, const char *name, const char *module)
Generate the [final response] tag based on type of node ('application', 'function' or 'agi') and name...
Definition: xmldoc.c:2554
struct ast_xml_doc_item * ast_xmldoc_build_list_responses(const char *type, const char *name, const char *module)
Generate the [list responses] tag based on type of node ('application', 'function' or 'agi') and name...
Definition: xmldoc.c:2484
struct ast_module * module
Definition: manager.h:172
enum ast_doc_src docsrc
Definition: manager.h:174
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
const ast_string_field description
Definition: manager.h:163
const ast_string_field arguments
Definition: manager.h:163
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_seealso(const char *type, const char *name, const char *module)
Parse the node content.
Definition: xmldoc.c:1702
const ast_string_field synopsis
Definition: manager.h:163
struct ast_xml_doc_item * final_response
Definition: manager.h:167
const ast_string_field seealso
Definition: manager.h:163
const ast_string_field syntax
Definition: manager.h:163
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
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 2094 of file manager.c.

References AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

2095 {
2097  AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list);
2099 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
list of hooks registered
Definition: manager.c:1828
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
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 1981 of file manager.c.

References ast_json_is_null(), and ast_str_create.

Referenced by mwi_app_event_cb().

1982 {
1983  struct ast_str *res = ast_str_create(1024);
1984 
1985  if (!ast_json_is_null(blob)) {
1986  manager_json_to_ast_str(blob, NULL, &res, exclusion_cb);
1987  }
1988 
1989  return res;
1990 }
int ast_json_is_null(const struct ast_json *value)
Check if value is JSON null.
Definition: json.c:273
Support for dynamic strings.
Definition: strings.h:623
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_manager_unregister ( const char *  action)

support functions to register/unregister AMI action handlers,

Unregister a registered manager command.

Definition at line 8057 of file manager.c.

References manager_action::action, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and manager_action::registered.

Referenced by load_module(), unload_module(), and unload_parking_manager().

8058 {
8059  struct manager_action *cur;
8060 
8062  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) {
8063  if (!strcasecmp(action, cur->action)) {
8064  AST_RWLIST_REMOVE_CURRENT(list);
8065  break;
8066  }
8067  }
8068  AST_RWLIST_TRAVERSE_SAFE_END;
8070 
8071  if (cur) {
8072  /*
8073  * We have removed the action object from the container so we
8074  * are no longer in a hurry.
8075  */
8076  ao2_lock(cur);
8077  cur->registered = 0;
8078  ao2_unlock(cur);
8079 
8080  ao2_t_ref(cur, -1, "action object removed from list");
8081  ast_verb(5, "Manager unregistered action %s\n", action);
8082  }
8083 
8084  return 0;
8085 }
const char * action
Definition: manager.h:156
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
unsigned int registered
TRUE if the AMI action is registered and the callback can be called.
Definition: manager.h:183
list of actions registered
Definition: manager.c:1825
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
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 2102 of file manager.c.

References AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

2103 {
2105  AST_RWLIST_REMOVE(&manager_hooks, hook, list);
2107 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
list of hooks registered
Definition: manager.c:1828
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
void astman_append ( struct mansession s,
const char *  fmt,
  ... 
)

utility functions for creating AMI replies

Definition at line 3310 of file manager.c.

References AST_DYNSTR_BUILD_FAILED, ast_str_buffer(), ast_str_set_va(), ast_str_thread_get(), ASTMAN_APPEND_BUF_INITSIZE, send_string(), and ast_tcptls_session_instance::stream.

Referenced by action_command(), action_coresettings(), action_coreshowchannelmap(), action_coreshowchannels(), action_corestatus(), action_status(), append_vmbox_info_astman(), append_vmu_info_astman(), ast_manager_hangup_helper(), astman_send_list_complete_end(), do_print(), manager_modulecheck(), manager_mute_mixmonitor(), manager_queues_status(), manager_queues_summary(), manager_show_dialplan(), manager_show_dialplan_helper(), session_do(), and sig_pri_ami_show_spans().

3311 {
3312  int res;
3313  va_list ap;
3314  struct ast_str *buf;
3315 
3316  if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) {
3317  return;
3318  }
3319 
3320  va_start(ap, fmt);
3321  res = ast_str_set_va(&buf, 0, fmt, ap);
3322  va_end(ap);
3323  if (res == AST_DYNSTR_BUILD_FAILED) {
3324  return;
3325  }
3326 
3327  if (s->hook || (s->tcptls_session != NULL && s->tcptls_session->stream != NULL)) {
3328  send_string(s, ast_str_buffer(buf));
3329  } else {
3330  ast_verbose("No connection stream in astman_append, should not happen\n");
3331  }
3332 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
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
#define ASTMAN_APPEND_BUF_INITSIZE
initial allocated size for the astman_append_buf and astman_send_*_va
Definition: manager.c:3296
Support for dynamic strings.
Definition: strings.h:623
static int send_string(struct mansession *s, char *string)
Definition: manager.c:3255
struct ast_iostream * stream
Definition: tcptls.h:161
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
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 3060 of file manager.c.

References ast_asprintf, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by generic_http_callback().

3061 {
3062  const struct ast_variable *v;
3063 
3064  for (v = params; v && m->hdrcount < ARRAY_LEN(m->headers); v = v->next) {
3065  if (ast_asprintf((char**)&m->headers[m->hdrcount], "%s: %s", v->name, v->value) > -1) {
3066  ++m->hdrcount;
3067  }
3068  }
3069 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
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 3050 of file manager.c.

References __astman_get_header().

Referenced by action_add_agi_cmd(), action_bridge(), action_command(), action_coresettings(), action_coreshowchannelmap(), action_coreshowchannels(), action_corestatus(), action_filter(), action_redirect(), action_reload(), action_status(), ast_hook_send_action(), ast_manager_hangup_helper(), astman_send_response_full(), handle_updates(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_list_voicemail_users(), manager_modulecheck(), manager_mute_mixmonitor(), manager_queues_status(), manager_queues_summary(), manager_show_dialplan(), and process_message().

3051 {
3052  return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH);
3053 }
static const char * __astman_get_header(const struct message *m, char *var, int mode)
Return a matching header value.
Definition: manager.c:3013
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 3136 of file manager.c.

References astman_get_variables_order().

3137 {
3138  return astman_get_variables_order(m, ORDER_REVERSE);
3139 }
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:3141
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 3850 of file manager.c.

3851 {
3852  if (new_live_dangerously && !live_dangerously)
3853  {
3854  ast_log(LOG_WARNING, "Manager Configuration load protection disabled.\n");
3855  }
3856 
3857  if (!new_live_dangerously && live_dangerously)
3858  {
3859  ast_log(LOG_NOTICE, "Manager Configuration load protection enabled.\n");
3860  }
3861  live_dangerously = new_live_dangerously;
3862 }
static int live_dangerously
Set to true (non-zero) to globally allow all dangerous AMI actions to run.
Definition: manager.c:1658
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 3475 of file manager.c.

References astman_append().

Referenced by action_coreshowchannelmap(), action_status(), append_vmbox_info_astman(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_list_voicemail_users(), manager_queues_status(), manager_queues_summary(), and manager_show_dialplan().

3476 {
3477  astman_append(s, "\r\n");
3478 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3310
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 3467 of file manager.c.

Referenced by action_coreshowchannelmap(), action_status(), append_vmbox_info_astman(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_list_voicemail_users(), manager_queues_status(), manager_queues_summary(), and manager_show_dialplan().

3468 {
3469  struct ast_str *buf = astman_send_list_complete_start_common(s, m, event_name, count);
3470  if (buf) {
3471  astman_flush(s, buf);
3472  }
3473 }
Support for dynamic strings.
Definition: strings.h:623
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 3431 of file manager.c.

References astman_send_response_full().

Referenced by action_coreshowchannelmap(), action_coreshowchannels(), action_status(), append_vmbox_info_astman(), ast_manager_hangup_helper(), manager_dpsendack(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_list_voicemail_users(), manager_queues_status(), and manager_queues_summary().

3432 {
3433  astman_send_response_full(s, m, "Success", msg, listflag);
3434 }
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:3353
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 3353 of file manager.c.

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

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

3354 {
3355  const char *id = astman_get_header(m, "ActionID");
3356  struct ast_str *buf;
3357 
3358  buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE);
3359  if (!buf) {
3360  return;
3361  }
3362 
3363  ast_str_set(&buf, 0, "Response: %s\r\n", resp);
3364 
3365  if (!ast_strlen_zero(id)) {
3366  ast_str_append(&buf, 0, "ActionID: %s\r\n", id);
3367  }
3368 
3369  if (listflag) {
3370  /* Start, complete, cancelled */
3371  ast_str_append(&buf, 0, "EventList: %s\r\n", listflag);
3372  }
3373 
3374  if (msg != MSG_MOREDATA) {
3375  if (msg) {
3376  ast_str_append(&buf, 0, "Message: %s\r\n", msg);
3377  }
3378  ast_str_append(&buf, 0, "\r\n");
3379  }
3380 
3381  astman_flush(s, buf);
3382 }
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
const char * astman_get_header(const struct message *m, char *var)
Return the first matching variable from an array.
Definition: manager.c:3050
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
#define ASTMAN_APPEND_BUF_INITSIZE
initial allocated size for the astman_append_buf and astman_send_*_va
Definition: manager.c:3296
#define MSG_MOREDATA
Definition: manager.c:3344
Support for dynamic strings.
Definition: strings.h:623
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
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 7519 of file manager.c.

References mansession_session::addr, ast_debug, ast_iostream_get_fd(), ast_iostream_read(), ast_sockaddr_stringify_addr(), mansession_session::authenticated, mansession_session::inbuf, mansession_session::inlen, mansession_session::kicked, mansession_session::notify_lock, mansession_session::pending_event, mansession_session::stream, and mansession_session::waiting_thread.

7520 {
7521  int res, x;
7522  int maxlen = sizeof(s->session->inbuf) - 1;
7523  char *src = s->session->inbuf;
7524  int timeout = -1;
7525  time_t now;
7526 
7527  /*
7528  * Look for \r\n within the buffer. If found, copy to the output
7529  * buffer and return, trimming the \r\n (not used afterwards).
7530  */
7531  for (x = 0; x < s->session->inlen; x++) {
7532  int cr; /* set if we have \r */
7533  if (src[x] == '\r' && x+1 < s->session->inlen && src[x + 1] == '\n') {
7534  cr = 2; /* Found. Update length to include \r\n */
7535  } else if (src[x] == '\n') {
7536  cr = 1; /* also accept \n only */
7537  } else {
7538  continue;
7539  }
7540  memmove(output, src, x); /*... but trim \r\n */
7541  output[x] = '\0'; /* terminate the string */
7542  x += cr; /* number of bytes used */
7543  s->session->inlen -= x; /* remaining size */
7544  memmove(src, src + x, s->session->inlen); /* remove used bytes */
7545  return 1;
7546  }
7547  if (s->session->inlen >= maxlen) {
7548  /* no crlf found, and buffer full - sorry, too long for us
7549  * keep the last character in case we are in the middle of a CRLF. */
7550  ast_log(LOG_WARNING, "Discarding message from %s. Line too long: %.25s...\n", ast_sockaddr_stringify_addr(&s->session->addr), src);
7551  src[0] = src[s->session->inlen - 1];
7552  s->session->inlen = 1;
7553  s->parsing = MESSAGE_LINE_TOO_LONG;
7554  }
7555  res = 0;
7556  while (res == 0) {
7557  /* calculate a timeout if we are not authenticated */
7558  if (!s->session->authenticated) {
7559  if(time(&now) == -1) {
7560  ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
7561  return -1;
7562  }
7563 
7564  timeout = (authtimeout - (now - s->session->authstart)) * 1000;
7565  if (timeout < 0) {
7566  /* we have timed out */
7567  return 0;
7568  }
7569  }
7570 
7571  ast_mutex_lock(&s->session->notify_lock);
7572  if (s->session->pending_event) {
7573  s->session->pending_event = 0;
7574  ast_mutex_unlock(&s->session->notify_lock);
7575  return 0;
7576  }
7577  s->session->waiting_thread = pthread_self();
7578  ast_mutex_unlock(&s->session->notify_lock);
7579 
7580  res = ast_wait_for_input(ast_iostream_get_fd(s->session->stream), timeout);
7581 
7582  ast_mutex_lock(&s->session->notify_lock);
7583  s->session->waiting_thread = AST_PTHREADT_NULL;
7584  ast_mutex_unlock(&s->session->notify_lock);
7585  }
7586  if (res < 0) {
7587  if (s->session->kicked) {
7588  ast_debug(1, "Manager session has been kicked\n");
7589  return -1;
7590  }
7591  /* If we get a signal from some other thread (typically because
7592  * there are new events queued), return 0 to notify the caller.
7593  */
7594  if (errno == EINTR || errno == EAGAIN) {
7595  return 0;
7596  }
7597  ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
7598  return -1;
7599  }
7600 
7601  ao2_lock(s->session);
7602  res = ast_iostream_read(s->session->stream, src + s->session->inlen, maxlen - s->session->inlen);
7603  if (res < 1) {
7604  res = -1; /* error return */
7605  } else {
7606  s->session->inlen += res;
7607  src[s->session->inlen] = '\0';
7608  res = 0;
7609  }
7610  ao2_unlock(s->session);
7611  return res;
7612 }
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
pthread_t waiting_thread
Definition: manager.c:1746
unsigned int kicked
Definition: manager.c:1769
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
Definition: iostream.c:85
struct ast_sockaddr addr
Definition: manager.c:1742
ssize_t ast_iostream_read(struct ast_iostream *stream, void *buffer, size_t count)
Read data from an iostream.
Definition: iostream.c:284
ast_mutex_t notify_lock
Definition: manager.c:1770
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_iostream * stream
Definition: manager.c:1743
char inbuf[1025]
Definition: manager.c:1756
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 2465 of file manager.c.

Referenced by function_amiclient(), manager_displayconnects(), and process_message().

2466 {
2467  struct ast_manager_user *user = NULL;
2468 
2469  AST_RWLIST_TRAVERSE(&users, user, list) {
2470  if (!strcasecmp(user->username, name)) {
2471  break;
2472  }
2473  }
2474 
2475  return user;
2476 }
user descriptor, as read from the config file.
Definition: manager.c:1804
list of users found in the config file
structure to hold users read from users.conf
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 2123 of file manager.c.

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

Referenced by generic_http_callback(), and session_do().

2124 {
2125  struct eventqent *ret;
2126 
2128  ret = AST_RWLIST_LAST(&all_events);
2129  /* the list is never empty now, but may become so when
2130  * we optimize it in the future, so be prepared.
2131  */
2132  if (ret) {
2134  }
2136  return ret;
2137 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:757
int usecount
Definition: manager.c:1613
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
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 4015 of file manager.c.

4016 {
4017  for (; *in; in++) {
4018  if (*in == '\\' || *in == '\"') {
4019  *out++ = '\\';
4020  }
4021  *out++ = *in;
4022  }
4023  *out = '\0';
4024 }
static enum add_filter_result manager_add_filter ( const char *  filter_pattern,
struct ao2_container whitefilters,
struct ao2_container blackfilters 
)
static

Add an event filter to a manager session.

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

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

Examples:

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

Definition at line 6768 of file manager.c.

References ao2_ref.

Referenced by action_filter().

6768  {
6769  regex_t *new_filter = ao2_t_alloc(sizeof(*new_filter), event_filter_destructor, "event_filter allocation");
6770  int is_blackfilter;
6771 
6772  if (!new_filter) {
6773  return FILTER_ALLOC_FAILED;
6774  }
6775 
6776  if (filter_pattern[0] == '!') {
6777  is_blackfilter = 1;
6778  filter_pattern++;
6779  } else {
6780  is_blackfilter = 0;
6781  }
6782 
6783  if (regcomp(new_filter, filter_pattern, REG_EXTENDED | REG_NOSUB)) {
6784  ao2_t_ref(new_filter, -1, "failed to make regex");
6785  return FILTER_COMPILE_FAIL;
6786  }
6787 
6788  if (is_blackfilter) {
6789  ao2_t_link(blackfilters, new_filter, "link new filter into black user container");
6790  } else {
6791  ao2_t_link(whitefilters, new_filter, "link new filter into white user container");
6792  }
6793 
6794  ao2_ref(new_filter, -1);
6795 
6796  return FILTER_SUCCESS;
6797 }
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
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 2482 of file manager.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_manager_user::displayconnects, get_manager_by_name_locked(), and mansession_session::username.

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

2483 {
2484  struct ast_manager_user *user = NULL;
2485  int ret = 0;
2486 
2488  if ((user = get_manager_by_name_locked(session->username))) {
2489  ret = user->displayconnects;
2490  }
2492 
2493  return ret;
2494 }
char username[80]
Definition: manager.c:1751
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:2465
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
user descriptor, as read from the config file.
Definition: manager.c:1804
list of users found in the config file
structure to hold users read from users.conf
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
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 6833 of file manager.c.

References ast_debug, mansession_session::authenticated, EVENT_FLAG_SHUTDOWN, mansession_session::last_ev, mansession_session::readperm, mansession_session::send_events, send_string(), and mansession_session::stream.

Referenced by process_message().

6834 {
6835  int ret = 0;
6836 
6837  ao2_lock(s->session);
6838  if (s->session->stream != NULL) {
6839  struct eventqent *eqe = s->session->last_ev;
6840 
6841  while ((eqe = advance_event(eqe))) {
6842  if (eqe->category == EVENT_FLAG_SHUTDOWN) {
6843  ast_debug(3, "Received CloseSession event\n");
6844  ret = -1;
6845  }
6846  if (!ret && s->session->authenticated &&
6847  (s->session->readperm & eqe->category) == eqe->category &&
6848  (s->session->send_events & eqe->category) == eqe->category) {
6849  if (match_filter(s, eqe->eventdata)) {
6850  if (send_string(s, eqe->eventdata) < 0 || s->write_error)
6851  ret = -1; /* don't send more */
6852  }
6853  }
6854  s->session->last_ev = eqe;
6855  }
6856  }
6857  ao2_unlock(s->session);
6858  return ret;
6859 }
struct eventqent * last_ev
Definition: manager.c:1762
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_iostream * stream
Definition: manager.c:1743
static int send_string(struct mansession *s, char *string)
Definition: manager.c:3255
#define EVENT_FLAG_SHUTDOWN
Fake event class used to end sessions at shutdown.
Definition: manager.c:1670
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 2143 of file manager.c.

References AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_tvdiff_sec(), ast_tvnow(), eventqent::tv, and eventqent::usecount.

Referenced by purge_old_stuff().

2144 {
2145  struct eventqent *ev;
2146  struct timeval now = ast_tvnow();
2147 
2149  while ( (ev = AST_RWLIST_FIRST(&all_events)) &&
2150  ev->usecount == 0 && AST_RWLIST_NEXT(ev, eq_next)) {
2151  AST_RWLIST_REMOVE_HEAD(&all_events, eq_next);
2152  ast_free(ev);
2153  }
2154 
2155  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&all_events, ev, eq_next) {
2156  /* Never release the last event */
2157  if (!AST_RWLIST_NEXT(ev, eq_next)) {
2158  break;
2159  }
2160 
2161  /* 2.5 times whatever the HTTP timeout is (maximum 2.5 hours) is the maximum time that we will definitely cache an event */
2162  if (ev->usecount == 0 && ast_tvdiff_sec(now, ev->tv) > (httptimeout > 3600 ? 3600 : httptimeout) * 2.5) {
2163  AST_RWLIST_REMOVE_CURRENT(eq_next);
2164  ast_free(ev);
2165  }
2166  }
2167  AST_RWLIST_TRAVERSE_SAFE_END;
2169 }
struct timeval tv
Definition: manager.c:1616
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
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
int usecount
Definition: manager.c:1613
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
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 5177 of file manager.c.

References AST_CONTROL_READ_ACTION, ast_malloc, and ast_queue_control_data().

Referenced by queue_sendtext(), and queue_sendtext_data().

5179 {
5180  struct ast_control_read_action_payload *obj;
5181  size_t obj_size;
5182  int res;
5183 
5184  obj_size = payload_size + sizeof(*obj);
5185 
5186  obj = ast_malloc(obj_size);
5187  if (!obj) {
5188  return -1;
5189  }
5190 
5191  obj->action = action;
5192  obj->payload_size = payload_size;
5193  memcpy(obj->payload, payload, payload_size);
5194 
5195  res = ast_queue_control_data(chan, AST_CONTROL_READ_ACTION, obj, obj_size);
5196 
5197  ast_free(obj);
5198  return res;
5199 }
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
Definition: channel.c:1238
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 5210 of file manager.c.

References queue_read_action_payload().

5211 {
5212  return queue_read_action_payload(chan, (const unsigned char *)body,
5213  strlen(body) + 1, AST_FRAME_READ_ACTION_SEND_TEXT);
5214 }
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:5177
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 5226 of file manager.c.

References ast_msg_data_alloc2(), ast_msg_data_get_length(), and queue_read_action_payload().

5228 {
5229  int res;
5230  struct ast_msg_data *obj;
5231 
5232  obj = ast_msg_data_alloc2(AST_MSG_DATA_SOURCE_TYPE_UNKNOWN,
5233  NULL, NULL, content_type, body);
5234  if (!obj) {
5235  return -1;
5236  }
5237 
5238  res = queue_read_action_payload(chan, (const unsigned char *)obj,
5239  ast_msg_data_get_length(obj), AST_FRAME_READ_ACTION_SEND_TEXT_DATA);
5240 
5241  ast_free(obj);
5242  return res;
5243 }
size_t ast_msg_data_get_length(struct ast_msg_data *msg)
Get length of the structure.
Structure used to transport a message through the frame core.
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:5177
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.
static int restrictedFile ( const char *  filename)
static

Check if a file is restricted or not.

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

Definition at line 3871 of file manager.c.

References ast_asprintf, ast_begins_with(), ast_strdupa, ast_strip(), and RAII_VAR.

3872 {
3873  char *stripped_filename;
3874  RAII_VAR(char *, path, NULL, ast_free);
3875  RAII_VAR(char *, real_path, NULL, ast_std_free);
3876 
3877  if (live_dangerously) {
3878  return 0;
3879  }
3880 
3881  stripped_filename = ast_strip(ast_strdupa(filename));
3882 
3883  /* If the file path starts with '/', don't prepend ast_config_AST_CONFIG_DIR */
3884  if (stripped_filename[0] == '/') {
3885  real_path = realpath(stripped_filename, NULL);
3886  } else {
3887  if (ast_asprintf(&path, "%s/%s", ast_config_AST_CONFIG_DIR, stripped_filename) == -1) {
3888  return -1;
3889  }
3890  real_path = realpath(path, NULL);
3891  }
3892 
3893  if (!real_path) {
3894  return -1;
3895  }
3896 
3897  if (!ast_begins_with(real_path, ast_config_AST_CONFIG_DIR)) {
3898  return 1;
3899  }
3900 
3901  return 0;
3902 }
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
static int live_dangerously
Set to true (non-zero) to globally allow all dangerous AMI actions to run.
Definition: manager.c:1658
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
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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 3255 of file manager.c.

References ast_iostream_set_timeout_disable(), ast_iostream_set_timeout_inactivity(), ast_iostream_write(), manager_custom_hook::helper, mansession_session::stream, and mansession_session::writetimeout.

Referenced by astman_append(), and process_events().

3256 {
3257  struct ast_iostream *stream;
3258  int len, res;
3259 
3260  /* It's a result from one of the hook's action invocation */
3261  if (s->hook) {
3262  /*
3263  * to send responses, we're using the same function
3264  * as for receiving events. We call the event "HookResponse"
3265  */
3266  s->hook->helper(EVENT_FLAG_HOOKRESPONSE, "HookResponse", string);
3267  return 0;
3268  }
3269 
3270  stream = s->stream ? s->stream : s->session->stream;
3271 
3272  len = strlen(string);
3274  res = ast_iostream_write(stream, string, len);
3276 
3277  if (res < len) {
3278  s->write_error = 1;
3279  }
3280 
3281  return res;
3282 }
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_inactivity(struct ast_iostream *stream, int timeout)
Set the iostream inactivity timeout timer.
Definition: iostream.c:122
void ast_iostream_set_timeout_disable(struct ast_iostream *stream)
Disable the iostream timeout timer.
Definition: iostream.c:114
struct ast_iostream * stream
Definition: manager.c:1743
manager_hook_t helper
Definition: manager.h:117
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 2312 of file manager.c.

References ast_false(), and ast_true().

Referenced by set_eventmask().

2313 {
2314  const char *p;
2315 
2316  if (ast_strlen_zero(string)) {
2317  return -1;
2318  }
2319 
2320  for (p = string; *p; p++) {
2321  if (*p < '0' || *p > '9') {
2322  break;
2323  }
2324  }
2325  if (!*p) { /* all digits */
2326  return atoi(string);
2327  }
2328  if (ast_false(string)) {
2329  return 0;
2330  }
2331  if (ast_true(string)) { /* all permissions */
2332  int x, ret = 0;
2333  for (x = 0; x < ARRAY_LEN(perms); x++) {
2334  ret |= perms[x].num;
2335  }
2336  return ret;
2337  }
2338  return get_perm(string);
2339 }
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: utils.c:2199
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
Definition: utils.c:2216

Variable Documentation

const { ... } command_blacklist[]
Initial value:
= {
{{ "module", "load", NULL }},
{{ "module", "unload", NULL }},
{{ "restart", "gracefully", NULL }},
}
char global_realm[MAXHOSTNAMELEN]
static

Default realm

Definition at line 1638 of file manager.c.

int manager_debug = 0
static

enable some debugging code in the manager

Definition at line 1631 of file manager.c.