Wed Jan 8 2020 09:50:22

Asterisk developer's documentation


AMI functions

callback to display queues status in manager More...

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  channelvars
 
struct  eventqent
 
struct  fast_originate_helper
 helper function for originate More...
 
struct  manager_channel_variable
 
struct  manager_hooks
 list of hooks registered More...
 
struct  mansession
 
struct  mansession_session
 
struct  permalias
 
struct  users
 list of users found in the config file More...
 

Macros

#define ASTMAN_APPEND_BUF_INITSIZE   256
 initial allocated size for the astman_append_buf More...
 
#define DEFAULT_REALM   "asterisk"
 
#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 MAX_BLACKLIST_CMD_LEN   2
 Descriptor for a manager session, either on the AMI socket or over HTTP. More...
 
#define MSG_MOREDATA   ((char *)astman_send_response)
 send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field. More...
 

Enumerations

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
}
 
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_manager_event_funcbuf (void)
 
static void __init_userevent_buf (void)
 
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_challenge (struct mansession *s, const struct message *m)
 
static int action_command (struct mansession *s, const struct message *m)
 Manager command "command" - execute CLI command. More...
 
static int action_coresettings (struct mansession *s, const struct message *m)
 Show PBX core settings information. More...
 
static int action_coreshowchannels (struct mansession *s, const struct message *m)
 Manager command "CoreShowChannels" - List currently defined channels and some information about them. More...
 
static int action_corestatus (struct mansession *s, const struct message *m)
 Show PBX core status information. More...
 
static int action_createconfig (struct mansession *s, const struct message *m)
 
static void action_destroy (void *obj)
 
static int action_events (struct mansession *s, const struct message *m)
 
static int action_extensionstate (struct mansession *s, const struct message *m)
 
static 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_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_redirect (struct mansession *s, const struct message *m)
 action_redirect: The redirect manager command More...
 
static int action_reload (struct mansession *s, const struct message *m)
 Send a reload event. More...
 
static int action_sendtext (struct mansession *s, const struct message *m)
 
static int action_setvar (struct mansession *s, const struct message *m)
 
static int action_status (struct mansession *s, const struct message *m)
 Manager "status" command to show channels. More...
 
static int action_timeout (struct mansession *s, const struct message *m)
 
static int action_updateconfig (struct mansession *s, const struct message *m)
 
static int action_userevent (struct mansession *s, const struct message *m)
 
static int action_waitevent (struct mansession *s, const struct message *m)
 
static struct eventqentadvance_event (struct eventqent *e)
 
static 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)
 
int ast_hook_send_action (struct manager_custom_hook *hook, const char *msg)
 Registered hooks can call this function to invoke actions and they will receive responses through registered callback. More...
 
static int ast_instring (const char *bigstr, const char *smallstr, const char delim)
 
int ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), 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)
 
int ast_manager_unregister (char *action)
 Unregister a registered manager command. More...
 
void ast_manager_unregister_hook (struct manager_custom_hook *hook)
 Delete a custom hook to be called when an event is fired. More...
 
void astman_append (struct mansession *s, const char *fmt,...)
 
static void astman_append_json (struct mansession *s, const char *str)
 
const char * astman_get_header (const struct message *m, char *var)
 Return the first matching variable from an array. More...
 
struct ast_variableastman_get_variables (const struct message *m)
 Get a linked list of the Variable: headers. More...
 
struct ast_variableastman_get_variables_order (const struct message *m, enum variable_orders order)
 Get a linked list of the Variable: headers with order specified. More...
 
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
 Send ack in manager transaction. More...
 
void astman_send_error (struct mansession *s, const struct message *m, char *error)
 Send error in manager transaction. More...
 
void astman_send_listack (struct mansession *s, const struct message *m, char *msg, char *listflag)
 Send ack in manager list transaction. More...
 
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
 Send response in manager transaction. More...
 
static void astman_send_response_full (struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
 
static void astman_start_ack (struct mansession *s, const struct message *m)
 
static int authenticate (struct mansession *s, const struct message *m)
 
static const char * authority_to_str (int authority, struct ast_str **res)
 Convert authority code to a list of options. Note that the EVENT_FLAG_ALL authority will always be returned. More...
 
static int blackfilter_cmp_fn (void *obj, void *arg, void *data, int flags)
 
static struct mansession_sessionbuild_mansession (struct sockaddr_in sin)
 Allocate manager session structure and add it to the list of sessions. More...
 
static int check_blacklist (const char *cmd)
 
int check_manager_enabled (void)
 Check if AMI is enabled. More...
 
static int check_manager_session_inuse (const char *name)
 
int check_webmanager_enabled (void)
 Check if AMI/HTTP is enabled. More...
 
static void destroy_fast_originate_helper (struct fast_originate_helper *doomed)
 
static int do_message (struct mansession *s)
 
static void event_filter_destructor (void *obj)
 
static void * fast_originate (void *data)
 
static void free_channelvars (void)
 
static int function_capable_string_allowed_with_auths (const char *evaluating, int writepermlist)
 Checks to see if a string which can be used to evaluate functions should be rejected. More...
 
static 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_manager_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager reload. More...
 
static char * handle_mandebug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void handle_parse_error (struct mansession *s, struct message *m, char *error)
 
static char * handle_showmanager (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showmanagers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showmancmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_showmancmds (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list commands. More...
 
static char * handle_showmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list connected. More...
 
static char * handle_showmaneventq (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list eventq. More...
 
static enum error_type handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn)
 
static void json_escape (char *out, const char *in)
 
static struct ast_variableman_do_variable_value (struct ast_variable *head, const char *hdr_val)
 
static int manager_displayconnects (struct mansession_session *session)
 Get displayconnects config option. More...
 
static int manager_modulecheck (struct mansession *s, const struct message *m)
 
static int manager_moduleload (struct mansession *s, const struct message *m)
 
static int manager_state_cb (char *context, char *exten, int state, void *data)
 
static int mansession_cmp_fn (void *obj, void *arg, int flags)
 
static struct sockaddr_in * mansession_encode_sin_local (const struct mansession *s, struct sockaddr_in *sin_local)
 
static enum
ast_security_event_transport_type 
mansession_get_transport (const struct mansession *s)
 
static void mansession_lock (struct mansession *s)
 Lock the 'mansession' structure. More...
 
static void mansession_unlock (struct mansession *s)
 Unlock the 'mansession' structure. More...
 
static int match_filter (struct mansession *s, char *eventdata)
 
static int process_events (struct mansession *s)
 
static int process_message (struct mansession *s, const struct message *m)
 
static void purge_events (void)
 
static void purge_sessions (int n_max)
 remove at most n_max stale session from the list. More...
 
static void report_auth_success (const struct mansession *s)
 
static void report_failed_acl (const struct mansession *s, const char *username)
 
static void report_failed_challenge_response (const struct mansession *s, const char *response, const char *expected_response)
 
static void report_inval_password (const struct mansession *s, const char *username)
 
static void report_invalid_user (const struct mansession *s, const char *username)
 
static void report_req_bad_format (const struct mansession *s, const char *action)
 
static void report_req_not_allowed (const struct mansession *s, const char *action)
 
static void report_session_limit (const struct mansession *s)
 
static int send_string (struct mansession *s, char *string)
 
static void session_destroy (struct mansession_session *s)
 
static void session_destructor (void *obj)
 
static void * session_do (void *data)
 The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ) More...
 
static int set_eventmask (struct mansession *s, const char *eventmask)
 Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm. More...
 
static int strings_to_mask (const char *string)
 
static struct mansession_sessionunref_mansession (struct mansession_session *s)
 Unreference manager session object. If no more references, then go ahead and delete it. More...
 
static const char * user_authority_to_str (int authority, struct ast_str **res)
 Convert authority code to a list of options for a user. This will only display those authority codes that have an explicit match on authority. More...
 
static int whitefilter_cmp_fn (void *obj, void *arg, void *data, int flags)
 

Variables

static struct actions actions = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static struct all_events all_events = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
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
 
static struct channelvars channelvars = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
struct {
   const char *   words [AST_MAX_CMD_LEN]
 
command_blacklist []
 
static const int DEFAULT_AUTHLIMIT = 50
 
static const int DEFAULT_AUTHTIMEOUT = 30
 
static const int DEFAULT_BROKENEVENTSACTION = 0
 
static const int DEFAULT_DISPLAYCONNECTS = 1
 
static const int DEFAULT_ENABLED = 0
 
static const int DEFAULT_HTTPTIMEOUT = 60
 
static const int DEFAULT_MANAGERDEBUG = 0
 
static const int DEFAULT_TIMESTAMPEVENTS = 0
 
static const int DEFAULT_WEBENABLED = 0
 
static int displayconnects
 
static char global_realm [MAXHOSTNAMELEN]
 
static int httptimeout
 
static char * manager_channelvars
 
static int manager_debug = 0
 
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 ast_threadstorage manager_event_funcbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_funcbuf , .custom_init = NULL , }
 
static struct manager_hooks manager_hooks = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static struct permalias perms []
 
static struct ao2_containersessions = NULL
 
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 } , }
 
static int webmanager_enabled = 0
 

Detailed Description

callback to display queues status in manager

Macro Definition Documentation

#define ASTMAN_APPEND_BUF_INITSIZE   256

initial allocated size for the astman_append_buf

Definition at line 2063 of file manager.c.

Referenced by astman_append().

#define DEFAULT_REALM   "asterisk"

Definition at line 911 of file manager.c.

Referenced by manager_set_defaults(), and reload_config().

#define GET_HEADER_FIRST_MATCH   0

Definition at line 1806 of file manager.c.

Referenced by astman_get_header().

#define GET_HEADER_LAST_MATCH   1

Definition at line 1807 of file manager.c.

Referenced by __astman_get_header().

#define GET_HEADER_SKIP_EMPTY   2

Definition at line 1808 of file manager.c.

Referenced by __astman_get_header(), and process_message().

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 5266 of file manager.c.

Referenced by __ast_manager_event_multichan().

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

Referenced by check_blacklist().

#define MSG_MOREDATA   ((char *)astman_send_response)

send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field.

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.

Use the explicit constant MSG_MOREDATA to remove the empty line. XXX MSG_MOREDATA should go to a header file.

Definition at line 2104 of file manager.c.

Referenced by astman_send_response_full(), and astman_start_ack().

Enumeration Type Documentation

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 

Definition at line 844 of file manager.c.

Enumerator
MESSAGE_OKAY 
MESSAGE_LINE_TOO_LONG 

Definition at line 1002 of file manager.c.

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
contentsFormat string describing event
Since
1.8

Definition at line 5268 of file manager.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, append_channel_vars(), append_event(), ast_atomic_fetchadd_int(), 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_set(), ast_str_thread_get(), ast_tvnow(), authority_to_str(), chancount, manager_custom_hook::helper, manager_event_buf, MANAGER_EVENT_BUF_INITSIZE, mansession_session::pending_event, eventqent::seq, unref_mansession(), and mansession_session::waiting_thread.

5270 {
5271  struct mansession_session *session;
5272  struct manager_custom_hook *hook;
5273  struct ast_str *auth = ast_str_alloca(80);
5274  const char *cat_str;
5275  va_list ap;
5276  struct timeval now;
5277  struct ast_str *buf;
5278  int i;
5279 
5281  return 0;
5282  }
5283 
5285  return -1;
5286  }
5287 
5288  cat_str = authority_to_str(category, &auth);
5289  ast_str_set(&buf, 0,
5290  "Event: %s\r\nPrivilege: %s\r\n",
5291  event, cat_str);
5292 
5293  if (timestampevents) {
5294  now = ast_tvnow();
5295  ast_str_append(&buf, 0,
5296  "Timestamp: %ld.%06lu\r\n",
5297  (long)now.tv_sec, (unsigned long) now.tv_usec);
5298  }
5299  if (manager_debug) {
5300  static int seq;
5301  ast_str_append(&buf, 0,
5302  "SequenceNumber: %d\r\n",
5303  ast_atomic_fetchadd_int(&seq, 1));
5304  ast_str_append(&buf, 0,
5305  "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func);
5306  }
5307 
5308  va_start(ap, fmt);
5309  ast_str_append_va(&buf, 0, fmt, ap);
5310  va_end(ap);
5311  for (i = 0; i < chancount; i++) {
5312  append_channel_vars(&buf, chans[i]);
5313  }
5314 
5315  ast_str_append(&buf, 0, "\r\n");
5316 
5317  append_event(ast_str_buffer(buf), category);
5318 
5319  /* Wake up any sleeping sessions */
5320  if (sessions) {
5321  struct ao2_iterator i;
5322  i = ao2_iterator_init(sessions, 0);
5323  while ((session = ao2_iterator_next(&i))) {
5324  ao2_lock(session);
5325  if (session->waiting_thread != AST_PTHREADT_NULL) {
5326  pthread_kill(session->waiting_thread, SIGURG);
5327  } else {
5328  /* We have an event to process, but the mansession is
5329  * not waiting for it. We still need to indicate that there
5330  * is an event waiting so that get_input processes the pending
5331  * event instead of polling.
5332  */
5333  session->pending_event = 1;
5334  }
5335  ao2_unlock(session);
5336  unref_mansession(session);
5337  }
5339  }
5340 
5343  AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
5344  hook->helper(category, event, ast_str_buffer(buf));
5345  }
5347  }
5348 
5349  return 0;
5350 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
Definition: astobj2.c:470
pthread_t waiting_thread
Definition: manager.c:975
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
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:900
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
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:1235
#define ast_str_alloca(init_len)
Definition: strings.h:608
#define MANAGER_EVENT_BUF_INITSIZE
Definition: manager.c:5266
static int append_event(const char *str, int category)
Definition: manager.c:5214
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:1330
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
static void append_channel_vars(struct ast_str **pbuf, struct ast_channel *chan)
Definition: manager.c:5240
static struct ast_threadstorage manager_event_buf
Definition: manager.c:5265
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:874
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define ao2_lock(a)
Definition: astobj2.h:488
static int timestampevents
Definition: manager.c:901
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:451
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
static int manager_debug
Definition: manager.c:906
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:809
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
static volatile unsigned int seq
Definition: app_sms.c:118
static int chancount
Definition: channel.c:102
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
list of hooks registered
Definition: manager.c:1061
manager_hook_t helper
Definition: manager.h:101
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:669
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 1823 of file manager.c.

References ast_skip_blanks(), ast_strlen_zero(), GET_HEADER_LAST_MATCH, GET_HEADER_SKIP_EMPTY, message::hdrcount, message::headers, and value.

Referenced by astman_get_header(), and process_message().

1824 {
1825  int x, l = strlen(var);
1826  const char *result = "";
1827 
1828  if (!m) {
1829  return result;
1830  }
1831 
1832  for (x = 0; x < m->hdrcount; x++) {
1833  const char *h = m->headers[x];
1834  if (!strncasecmp(var, h, l) && h[l] == ':') {
1835  const char *value = h + l + 1;
1836  value = ast_skip_blanks(value); /* ignore leading spaces in the value */
1837  /* found a potential candidate */
1838  if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) {
1839  continue; /* not interesting */
1840  }
1841  if (mode & GET_HEADER_LAST_MATCH) {
1842  result = value; /* record the last match so far */
1843  } else {
1844  return value;
1845  }
1846  }
1847  }
1848 
1849  return result;
1850 }
#define GET_HEADER_LAST_MATCH
Definition: manager.c:1807
#define var
Definition: ast_expr2f.c:606
int value
Definition: syslog.c:39
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define GET_HEADER_SKIP_EMPTY
Definition: manager.c:1808
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:97
const char * headers[AST_MAX_MANHEADERS]
Definition: manager.h:135
unsigned int hdrcount
Definition: manager.h:134
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 2059 of file manager.c.

2069 {
static void __init_manager_event_buf ( void  )
static

Definition at line 5265 of file manager.c.

5270 {
static void __init_manager_event_funcbuf ( void  )
static

Definition at line 5238 of file manager.c.

5241 {
static void __init_userevent_buf ( void  )
static

Definition at line 2060 of file manager.c.

2069 {
static int action_aocmessage ( struct mansession s,
const struct message m 
)
static

Definition at line 3919 of file manager.c.

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_destroy_encoded(), AST_AOC_E, ast_aoc_encode(), 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_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(), ast_aoc_unit_entry::type, ast_aoc_unit_entry::valid_amount, and ast_aoc_unit_entry::valid_type.

Referenced by __init_manager().

3920 {
3921  const char *channel = astman_get_header(m, "Channel");
3922  const char *pchannel = astman_get_header(m, "ChannelPrefix");
3923  const char *msgtype = astman_get_header(m, "MsgType");
3924  const char *chargetype = astman_get_header(m, "ChargeType");
3925  const char *currencyname = astman_get_header(m, "CurrencyName");
3926  const char *currencyamount = astman_get_header(m, "CurrencyAmount");
3927  const char *mult = astman_get_header(m, "CurrencyMultiplier");
3928  const char *totaltype = astman_get_header(m, "TotalType");
3929  const char *aocbillingid = astman_get_header(m, "AOCBillingId");
3930  const char *association_id= astman_get_header(m, "ChargingAssociationId");
3931  const char *association_num = astman_get_header(m, "ChargingAssociationNumber");
3932  const char *association_plan = astman_get_header(m, "ChargingAssociationPlan");
3933 
3934  enum ast_aoc_type _msgtype;
3935  enum ast_aoc_charge_type _chargetype;
3937  enum ast_aoc_total_type _totaltype = AST_AOC_TOTAL;
3938  enum ast_aoc_billing_id _billingid = AST_AOC_BILLING_NA;
3939  unsigned int _currencyamount = 0;
3940  int _association_id = 0;
3941  unsigned int _association_plan = 0;
3942  struct ast_channel *chan = NULL;
3943 
3944  struct ast_aoc_decoded *decoded = NULL;
3945  struct ast_aoc_encoded *encoded = NULL;
3946  size_t encoded_size = 0;
3947 
3948  if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) {
3949  astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these.");
3950  goto aocmessage_cleanup;
3951  }
3952 
3953  if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) {
3954  chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel));
3955  }
3956 
3957  if (!chan) {
3958  astman_send_error(s, m, "No such channel");
3959  goto aocmessage_cleanup;
3960  }
3961 
3962  if (ast_strlen_zero(msgtype) || (strcasecmp(msgtype, "d") && strcasecmp(msgtype, "e"))) {
3963  astman_send_error(s, m, "Invalid MsgType");
3964  goto aocmessage_cleanup;
3965  }
3966 
3967  if (ast_strlen_zero(chargetype)) {
3968  astman_send_error(s, m, "ChargeType not specified");
3969  goto aocmessage_cleanup;
3970  }
3971 
3972  _msgtype = strcasecmp(msgtype, "d") ? AST_AOC_E : AST_AOC_D;
3973 
3974  if (!strcasecmp(chargetype, "NA")) {
3975  _chargetype = AST_AOC_CHARGE_NA;
3976  } else if (!strcasecmp(chargetype, "Free")) {
3977  _chargetype = AST_AOC_CHARGE_FREE;
3978  } else if (!strcasecmp(chargetype, "Currency")) {
3979  _chargetype = AST_AOC_CHARGE_CURRENCY;
3980  } else if (!strcasecmp(chargetype, "Unit")) {
3981  _chargetype = AST_AOC_CHARGE_UNIT;
3982  } else {
3983  astman_send_error(s, m, "Invalid ChargeType");
3984  goto aocmessage_cleanup;
3985  }
3986 
3987  if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
3988 
3989  if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u", &_currencyamount) != 1)) {
3990  astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when ChargeType is Currency");
3991  goto aocmessage_cleanup;
3992  }
3993 
3994  if (ast_strlen_zero(mult)) {
3995  astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
3996  goto aocmessage_cleanup;
3997  } else if (!strcasecmp(mult, "onethousandth")) {
3999  } else if (!strcasecmp(mult, "onehundredth")) {
4000  _mult = AST_AOC_MULT_ONEHUNDREDTH;
4001  } else if (!strcasecmp(mult, "onetenth")) {
4002  _mult = AST_AOC_MULT_ONETENTH;
4003  } else if (!strcasecmp(mult, "one")) {
4004  _mult = AST_AOC_MULT_ONE;
4005  } else if (!strcasecmp(mult, "ten")) {
4006  _mult = AST_AOC_MULT_TEN;
4007  } else if (!strcasecmp(mult, "hundred")) {
4008  _mult = AST_AOC_MULT_HUNDRED;
4009  } else if (!strcasecmp(mult, "thousand")) {
4010  _mult = AST_AOC_MULT_THOUSAND;
4011  } else {
4012  astman_send_error(s, m, "Invalid ChargeMultiplier");
4013  goto aocmessage_cleanup;
4014  }
4015  }
4016 
4017  /* create decoded object and start setting values */
4018  if (!(decoded = ast_aoc_create(_msgtype, _chargetype, 0))) {
4019  astman_send_error(s, m, "Message Creation Failed");
4020  goto aocmessage_cleanup;
4021  }
4022 
4023  if (_msgtype == AST_AOC_D) {
4024  if (!ast_strlen_zero(totaltype) && !strcasecmp(totaltype, "subtotal")) {
4025  _totaltype = AST_AOC_SUBTOTAL;
4026  }
4027 
4028  if (ast_strlen_zero(aocbillingid)) {
4029  /* ignore this is optional */
4030  } else if (!strcasecmp(aocbillingid, "Normal")) {
4031  _billingid = AST_AOC_BILLING_NORMAL;
4032  } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
4033  _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
4034  } else if (!strcasecmp(aocbillingid, "CreditCard")) {
4035  _billingid = AST_AOC_BILLING_CREDIT_CARD;
4036  } else {
4037  astman_send_error(s, m, "Invalid AOC-D AOCBillingId");
4038  goto aocmessage_cleanup;
4039  }
4040  } else {
4041  if (ast_strlen_zero(aocbillingid)) {
4042  /* ignore this is optional */
4043  } else if (!strcasecmp(aocbillingid, "Normal")) {
4044  _billingid = AST_AOC_BILLING_NORMAL;
4045  } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
4046  _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
4047  } else if (!strcasecmp(aocbillingid, "CreditCard")) {
4048  _billingid = AST_AOC_BILLING_CREDIT_CARD;
4049  } else if (!strcasecmp(aocbillingid, "CallFwdUnconditional")) {
4051  } else if (!strcasecmp(aocbillingid, "CallFwdBusy")) {
4052  _billingid = AST_AOC_BILLING_CALL_FWD_BUSY;
4053  } else if (!strcasecmp(aocbillingid, "CallFwdNoReply")) {
4054  _billingid = AST_AOC_BILLING_CALL_FWD_NO_REPLY;
4055  } else if (!strcasecmp(aocbillingid, "CallDeflection")) {
4056  _billingid = AST_AOC_BILLING_CALL_DEFLECTION;
4057  } else if (!strcasecmp(aocbillingid, "CallTransfer")) {
4058  _billingid = AST_AOC_BILLING_CALL_TRANSFER;
4059  } else {
4060  astman_send_error(s, m, "Invalid AOC-E AOCBillingId");
4061  goto aocmessage_cleanup;
4062  }
4063 
4064  if (!ast_strlen_zero(association_id) && (sscanf(association_id, "%30d", &_association_id) != 1)) {
4065  astman_send_error(s, m, "Invalid ChargingAssociationId");
4066  goto aocmessage_cleanup;
4067  }
4068  if (!ast_strlen_zero(association_plan) && (sscanf(association_plan, "%30u", &_association_plan) != 1)) {
4069  astman_send_error(s, m, "Invalid ChargingAssociationPlan");
4070  goto aocmessage_cleanup;
4071  }
4072 
4073  if (_association_id) {
4074  ast_aoc_set_association_id(decoded, _association_id);
4075  } else if (!ast_strlen_zero(association_num)) {
4076  ast_aoc_set_association_number(decoded, association_num, _association_plan);
4077  }
4078  }
4079 
4080  if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
4081  ast_aoc_set_currency_info(decoded, _currencyamount, _mult, ast_strlen_zero(currencyname) ? NULL : currencyname);
4082  } else if (_chargetype == AST_AOC_CHARGE_UNIT) {
4083  struct ast_aoc_unit_entry entry;
4084  int i;
4085 
4086  /* multiple unit entries are possible, lets get them all */
4087  for (i = 0; i < 32; i++) {
4088  if (aocmessage_get_unit_entry(m, &entry, i)) {
4089  break; /* that's the end then */
4090  }
4091 
4092  ast_aoc_add_unit_entry(decoded, entry.valid_amount, entry.amount, entry.valid_type, entry.type);
4093  }
4094 
4095  /* at least one unit entry is required */
4096  if (!i) {
4097  astman_send_error(s, m, "Invalid UnitAmount(0), At least one valid unit entry is required when ChargeType is set to Unit");
4098  goto aocmessage_cleanup;
4099  }
4100 
4101  }
4102 
4103  ast_aoc_set_billing_id(decoded, _billingid);
4104  ast_aoc_set_total_type(decoded, _totaltype);
4105 
4106 
4107  if ((encoded = ast_aoc_encode(decoded, &encoded_size, NULL)) && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) {
4108  astman_send_ack(s, m, "AOC Message successfully queued on channel");
4109  } else {
4110  astman_send_error(s, m, "Error encoding AOC message, could not queue onto channel");
4111  }
4112 
4113 aocmessage_cleanup:
4114 
4115  ast_aoc_destroy_decoded(decoded);
4116  ast_aoc_destroy_encoded(encoded);
4117 
4118  if (chan) {
4119  chan = ast_channel_unref(chan);
4120  }
4121  return 0;
4122 }
Main Channel structure associated with a channel.
Definition: channel.h:742
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:846
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
void * ast_aoc_destroy_decoded(struct ast_aoc_decoded *decoded)
free an ast_aoc_decoded object
Definition: aoc.c:176
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:4447
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
ast_aoc_currency_multiplier
Defines the currency multiplier for an aoc message.
Definition: aoc.h:34
ast_aoc_total_type
Definition: aoc.h:82
static int aocmessage_get_unit_entry(const struct message *m, struct ast_aoc_unit_entry *entry, unsigned int entry_num)
Definition: manager.c:3894
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:1808
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
int ast_aoc_set_association_number(struct ast_aoc_decoded *decoded, const char *num, uint8_t plan)
set the charging accociation number for an AOC-E message
Definition: aoc.c:925
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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:519
ast_aoc_charge_type
Definition: aoc.h:69
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:893
ast_aoc_type
Definition: aoc.h:62
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:776
void * ast_aoc_destroy_encoded(struct ast_aoc_encoded *encoded)
free an ast_aoc_encoded object
Definition: aoc.c:182
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:145
ast_aoc_billing_id
Defines the billing id options for an aoc message.
Definition: aoc.h:49
Definition: aoc.h:66
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:909
Definition: aoc.h:178
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
Definition: aoc.h:65
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:788
static int action_atxfer ( struct mansession s,
const struct message m 
)
static

Definition at line 3647 of file manager.c.

References ast_channel_get_by_name(), ast_channel_unref, ast_find_call_feature(), AST_FRAME_DTMF, ast_queue_frame(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, ast_call_feature::exten, exten, and pbx_builtin_setvar_helper().

Referenced by __init_manager().

3648 {
3649  const char *name = astman_get_header(m, "Channel");
3650  const char *exten = astman_get_header(m, "Exten");
3651  const char *context = astman_get_header(m, "Context");
3652  struct ast_channel *chan = NULL;
3653  struct ast_call_feature *atxfer_feature = NULL;
3654  char *feature_code = NULL;
3655 
3656  if (ast_strlen_zero(name)) {
3657  astman_send_error(s, m, "No channel specified");
3658  return 0;
3659  }
3660  if (ast_strlen_zero(exten)) {
3661  astman_send_error(s, m, "No extension specified");
3662  return 0;
3663  }
3664 
3665  if (!(atxfer_feature = ast_find_call_feature("atxfer"))) {
3666  astman_send_error(s, m, "No attended transfer feature found");
3667  return 0;
3668  }
3669 
3670  if (!(chan = ast_channel_get_by_name(name))) {
3671  astman_send_error(s, m, "Channel specified does not exist");
3672  return 0;
3673  }
3674 
3675  if (!ast_strlen_zero(context)) {
3676  pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context);
3677  }
3678 
3679  for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) {
3680  struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *feature_code };
3681  ast_queue_frame(chan, &f);
3682  }
3683 
3684  for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) {
3685  struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *feature_code };
3686  ast_queue_frame(chan, &f);
3687  }
3688 
3689  chan = ast_channel_unref(chan);
3690 
3691  astman_send_ack(s, m, "Atxfer successfully queued");
3692 
3693  return 0;
3694 }
char exten[FEATURE_MAX_LEN]
Definition: features.h:69
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
#define AST_FRAME_DTMF
Definition: frame.h:128
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
static const char name[]
static struct ast_format f[]
Definition: format_g726.c:181
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...
Definition: pbx.c:10546
Data structure associated with a single frame of data.
Definition: frame.h:142
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
struct ast_call_feature * ast_find_call_feature(const char *name)
look for a call feature entry by its sname
Definition: features.c:3160
static int action_challenge ( struct mansession s,
const struct message m 
)
static

Definition at line 3149 of file manager.c.

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

3150 {
3151  const char *authtype = astman_get_header(m, "AuthType");
3152 
3153  if (!strcasecmp(authtype, "MD5")) {
3154  if (ast_strlen_zero(s->session->challenge)) {
3155  snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
3156  }
3157  mansession_lock(s);
3158  astman_start_ack(s, m);
3159  astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
3160  mansession_unlock(s);
3161  } else {
3162  astman_send_error(s, m, "Must specify AuthType");
3163  }
3164  return 0;
3165 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
static void mansession_unlock(struct mansession *s)
Unlock the &#39;mansession&#39; structure.
Definition: manager.c:2157
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2140
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
long int ast_random(void)
Definition: utils.c:1640
static void mansession_lock(struct mansession *s)
Lock the &#39;mansession&#39; structure.
Definition: manager.c:2151
char challenge[10]
Definition: manager.c:981
struct mansession_session * session
Definition: manager.c:1013
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int action_command ( struct mansession s,
const struct message m 
)
static

Manager command "command" - execute CLI command.

Definition at line 3732 of file manager.c.

References ast_free, ast_log(), AST_LOG_WARNING, ast_malloc, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), check_blacklist(), errno, LOG_WARNING, and term_strip().

Referenced by __init_manager().

3733 {
3734  const char *cmd = astman_get_header(m, "Command");
3735  const char *id = astman_get_header(m, "ActionID");
3736  char *buf = NULL, *final_buf = NULL;
3737  char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */
3738  int fd;
3739  off_t l;
3740 
3741  if (ast_strlen_zero(cmd)) {
3742  astman_send_error(s, m, "No command provided");
3743  return 0;
3744  }
3745 
3746  if (check_blacklist(cmd)) {
3747  astman_send_error(s, m, "Command blacklisted");
3748  return 0;
3749  }
3750 
3751  if ((fd = mkstemp(template)) < 0) {
3752  ast_log(AST_LOG_WARNING, "Failed to create temporary file for command: %s\n", strerror(errno));
3753  astman_send_error(s, m, "Command response construction error");
3754  return 0;
3755  }
3756 
3757  astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
3758  if (!ast_strlen_zero(id)) {
3759  astman_append(s, "ActionID: %s\r\n", id);
3760  }
3761  /* FIXME: Wedge a ActionID response in here, waiting for later changes */
3762  ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */
3763  /* Determine number of characters available */
3764  if ((l = lseek(fd, 0, SEEK_END)) < 0) {
3765  ast_log(LOG_WARNING, "Failed to determine number of characters for command: %s\n", strerror(errno));
3766  goto action_command_cleanup;
3767  }
3768 
3769  /* This has a potential to overflow the stack. Hence, use the heap. */
3770  buf = ast_malloc(l + 1);
3771  final_buf = ast_malloc(l + 1);
3772 
3773  if (!buf || !final_buf) {
3774  ast_log(LOG_WARNING, "Failed to allocate memory for temporary buffer\n");
3775  goto action_command_cleanup;
3776  }
3777 
3778  if (lseek(fd, 0, SEEK_SET) < 0) {
3779  ast_log(LOG_WARNING, "Failed to set position on temporary file for command: %s\n", strerror(errno));
3780  goto action_command_cleanup;
3781  }
3782 
3783  if (read(fd, buf, l) < 0) {
3784  ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
3785  goto action_command_cleanup;
3786  }
3787 
3788  buf[l] = '\0';
3789  term_strip(final_buf, buf, l);
3790  final_buf[l] = '\0';
3791  astman_append(s, "%s", final_buf);
3792 
3793 action_command_cleanup:
3794 
3795  close(fd);
3796  unlink(template);
3797  astman_append(s, "--END COMMAND--\r\n\r\n");
3798 
3799  ast_free(buf);
3800  ast_free(final_buf);
3801 
3802  return 0;
3803 }
static int check_blacklist(const char *cmd)
Definition: manager.c:3696
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
#define LOG_WARNING
Definition: logger.h:144
#define AST_LOG_WARNING
Definition: logger.h:149
char * term_strip(char *outbuf, const char *inbuf, int maxout)
Definition: term.c:287
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
ast_cli_command
calling arguments for new-style handlers.
Definition: cli.h:145
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
#define ast_free(a)
Definition: astmm.h:97
#define ast_malloc(a)
Definition: astmm.h:91
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int action_coresettings ( struct mansession s,
const struct message m 
)
static

Show PBX core settings information.

Definition at line 4468 of file manager.c.

References AMI_VERSION, AST_CLI_YESNO, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SYSTEM_NAME, ast_get_version(), ast_realtime_enabled(), ast_strlen_zero(), astman_append(), astman_get_header(), check_cdr_enabled(), check_webmanager_enabled(), option_maxcalls, option_maxfiles, and option_maxload.

Referenced by __init_manager().

4469 {
4470  const char *actionid = astman_get_header(m, "ActionID");
4471  char idText[150];
4472 
4473  if (!ast_strlen_zero(actionid)) {
4474  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
4475  } else {
4476  idText[0] = '\0';
4477  }
4478 
4479  astman_append(s, "Response: Success\r\n"
4480  "%s"
4481  "AMIversion: %s\r\n"
4482  "AsteriskVersion: %s\r\n"
4483  "SystemName: %s\r\n"
4484  "CoreMaxCalls: %d\r\n"
4485  "CoreMaxLoadAvg: %f\r\n"
4486  "CoreRunUser: %s\r\n"
4487  "CoreRunGroup: %s\r\n"
4488  "CoreMaxFilehandles: %d\r\n"
4489  "CoreRealTimeEnabled: %s\r\n"
4490  "CoreCDRenabled: %s\r\n"
4491  "CoreHTTPenabled: %s\r\n"
4492  "\r\n",
4493  idText,
4494  AMI_VERSION,
4495  ast_get_version(),
4505  );
4506  return 0;
4507 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
int ast_realtime_enabled(void)
Check if there&#39;s any realtime engines loaded.
Definition: config.c:2601
const char * ast_get_version(void)
Retrieve the Asterisk version string.
Definition: version.c:14
const char * ast_config_AST_RUN_USER
Definition: asterisk.c:271
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
int option_maxfiles
Definition: asterisk.c:185
const char * ast_config_AST_SYSTEM_NAME
Definition: asterisk.c:273
const char * ast_config_AST_RUN_GROUP
Definition: asterisk.c:272
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AMI_VERSION
Definition: manager.h:57
double option_maxload
Definition: asterisk.c:183
int check_webmanager_enabled(void)
Check if AMI/HTTP is enabled.
Definition: manager.c:1112
#define AST_CLI_YESNO(x)
return Yes or No depending on the argument. This is used in many places in CLI command, having a function to generate this helps maintaining a consistent output (and possibly emitting the output in other languages, at some point).
Definition: cli.h:65
int check_cdr_enabled(void)
Return TRUE if CDR subsystem is enabled.
Definition: cdr.c:120
int option_maxcalls
Definition: asterisk.c:184
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 4577 of file manager.c.

References ast_channel::_state, ast_channel::accountcode, ast_channel::appl, ast_bridged_channel(), ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_state2str(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), astman_append(), astman_get_header(), astman_send_error(), astman_send_listack(), ast_channel::caller, ast_channel::cdr, ast_channel::connected, ast_channel::context, ast_channel::data, ast_channel::exten, ast_party_caller::id, ast_party_connected_line::id, ast_party_id::name, ast_channel::name, ast_party_id::number, ast_channel::priority, S_COR, S_OR, ast_cdr::start, ast_party_name::str, ast_party_number::str, ast_channel::uniqueid, ast_party_name::valid, and ast_party_number::valid.

Referenced by __init_manager().

4578 {
4579  const char *actionid = astman_get_header(m, "ActionID");
4580  char idText[256];
4581  struct ast_channel *c = NULL;
4582  int numchans = 0;
4583  int duration, durh, durm, durs;
4584  struct ast_channel_iterator *iter;
4585 
4586  if (!ast_strlen_zero(actionid)) {
4587  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
4588  } else {
4589  idText[0] = '\0';
4590  }
4591 
4592  if (!(iter = ast_channel_iterator_all_new())) {
4593  astman_send_error(s, m, "Memory Allocation Failure");
4594  return 1;
4595  }
4596 
4597  astman_send_listack(s, m, "Channels will follow", "start");
4598 
4599  for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
4600  struct ast_channel *bc;
4601  char durbuf[10] = "";
4602 
4603  ast_channel_lock(c);
4604 
4605  bc = ast_bridged_channel(c);
4606  if (c->cdr && !ast_tvzero(c->cdr->start)) {
4607  duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
4608  durh = duration / 3600;
4609  durm = (duration % 3600) / 60;
4610  durs = duration % 60;
4611  snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
4612  }
4613 
4614  astman_append(s,
4615  "Event: CoreShowChannel\r\n"
4616  "%s"
4617  "Channel: %s\r\n"
4618  "UniqueID: %s\r\n"
4619  "Context: %s\r\n"
4620  "Extension: %s\r\n"
4621  "Priority: %d\r\n"
4622  "ChannelState: %u\r\n"
4623  "ChannelStateDesc: %s\r\n"
4624  "Application: %s\r\n"
4625  "ApplicationData: %s\r\n"
4626  "CallerIDnum: %s\r\n"
4627  "CallerIDname: %s\r\n"
4628  "ConnectedLineNum: %s\r\n"
4629  "ConnectedLineName: %s\r\n"
4630  "Duration: %s\r\n"
4631  "AccountCode: %s\r\n"
4632  "BridgedChannel: %s\r\n"
4633  "BridgedUniqueID: %s\r\n"
4634  "\r\n", idText, c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state,
4635  ast_state2str(c->_state), c->appl ? c->appl : "", c->data ? S_OR(c->data, "") : "",
4636  S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
4637  S_COR(c->caller.id.name.valid, c->caller.id.name.str, ""),
4639  S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""),
4640  durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : "");
4641 
4642  ast_channel_unlock(c);
4643 
4644  numchans++;
4645  }
4646 
4647  astman_append(s,
4648  "Event: CoreShowChannelsComplete\r\n"
4649  "EventList: Complete\r\n"
4650  "ListItems: %d\r\n"
4651  "%s"
4652  "\r\n", numchans, idText);
4653 
4655 
4656  return 0;
4657 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1715
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int priority
Definition: channel.h:841
const ast_string_field uniqueid
Definition: channel.h:787
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
char * str
Subscriber name (Malloced)
Definition: channel.h:214
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
struct ast_cdr * cdr
Definition: channel.h:766
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
const char * ast_state2str(enum ast_channel_state)
Gives the string form of a given channel state.
Definition: channel.c:1007
const char * data
Definition: channel.h:755
const char * appl
Definition: channel.h:754
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#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:83
enum ast_channel_state _state
Definition: channel.h:839
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
const ast_string_field name
Definition: channel.h:787
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct timeval start
Definition: cdr.h:100
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1649
const ast_string_field accountcode
Definition: channel.h:787
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1701
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager list transaction.
Definition: manager.c:2145
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int action_corestatus ( struct mansession s,
const struct message m 
)
static

Show PBX core status information.

Definition at line 4510 of file manager.c.

References ast_active_channels(), ast_lastreloadtime, ast_localtime(), ast_startuptime, ast_strftime(), ast_strlen_zero(), astman_append(), and astman_get_header().

Referenced by __init_manager().

4511 {
4512  const char *actionid = astman_get_header(m, "ActionID");
4513  char idText[150];
4514  char startuptime[150], startupdate[150];
4515  char reloadtime[150], reloaddate[150];
4516  struct ast_tm tm;
4517 
4518  if (!ast_strlen_zero(actionid)) {
4519  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
4520  } else {
4521  idText[0] = '\0';
4522  }
4523 
4524  ast_localtime(&ast_startuptime, &tm, NULL);
4525  ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
4526  ast_strftime(startupdate, sizeof(startupdate), "%Y-%m-%d", &tm);
4527  ast_localtime(&ast_lastreloadtime, &tm, NULL);
4528  ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
4529  ast_strftime(reloaddate, sizeof(reloaddate), "%Y-%m-%d", &tm);
4530 
4531  astman_append(s, "Response: Success\r\n"
4532  "%s"
4533  "CoreStartupDate: %s\r\n"
4534  "CoreStartupTime: %s\r\n"
4535  "CoreReloadDate: %s\r\n"
4536  "CoreReloadTime: %s\r\n"
4537  "CoreCurrentCalls: %d\r\n"
4538  "\r\n",
4539  idText,
4540  startupdate,
4541  startuptime,
4542  reloaddate,
4543  reloadtime,
4545  );
4546  return 0;
4547 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
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:1570
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct timeval ast_lastreloadtime
Definition: asterisk.c:219
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:2351
struct timeval ast_startuptime
Definition: asterisk.c:218
int ast_active_channels(void)
returns number of active/allocated channels
Definition: channel.c:848
static int action_createconfig ( struct mansession s,
const struct message m 
)
static

Definition at line 2923 of file manager.c.

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

Referenced by __init_manager().

2924 {
2925  int fd;
2926  const char *fn = astman_get_header(m, "Filename");
2927  struct ast_str *filepath = ast_str_alloca(PATH_MAX);
2928  ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR);
2929  ast_str_append(&filepath, 0, "%s", fn);
2930 
2931  if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
2932  close(fd);
2933  astman_send_ack(s, m, "New configuration file created successfully");
2934  } else {
2935  astman_send_error(s, m, strerror(errno));
2936  }
2937 
2938  return 0;
2939 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
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:900
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
#define ast_str_alloca(init_len)
Definition: strings.h:608
#define AST_FILE_MODE
Definition: asterisk.h:36
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
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:874
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
const char * ast_config_AST_CONFIG_DIR
Definition: asterisk.c:256
int errno
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static void action_destroy ( void *  obj)
static

Definition at line 5457 of file manager.c.

References ast_string_field_free_memory.

Referenced by ast_manager_register2().

5458 {
5459  struct manager_action *doomed = obj;
5460 
5461  if (doomed->synopsis) {
5462  /* The string fields were initialized. */
5464  }
5465 }
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
static int action_events ( struct mansession s,
const struct message m 
)
static

Definition at line 3067 of file manager.c.

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

Referenced by __init_manager().

3068 {
3069  const char *mask = astman_get_header(m, "EventMask");
3070  int res, x;
3071  const char *id = astman_get_header(m, "ActionID");
3072  char id_text[256];
3073 
3074  if (!ast_strlen_zero(id)) {
3075  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
3076  } else {
3077  id_text[0] = '\0';
3078  }
3079 
3080  res = set_eventmask(s, mask);
3081  if (broken_events_action) {
3082  /* if this option is set we should not return a response on
3083  * error, or when all events are set */
3084 
3085  if (res > 0) {
3086  for (x = 0; x < ARRAY_LEN(perms); x++) {
3087  if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) {
3088  return 0;
3089  }
3090  }
3091  astman_append(s, "Response: Success\r\n%s"
3092  "Events: On\r\n\r\n", id_text);
3093  } else if (res == 0)
3094  astman_append(s, "Response: Success\r\n%s"
3095  "Events: Off\r\n\r\n", id_text);
3096  return 0;
3097  }
3098 
3099  if (res > 0)
3100  astman_append(s, "Response: Success\r\n%s"
3101  "Events: On\r\n\r\n", id_text);
3102  else if (res == 0)
3103  astman_append(s, "Response: Success\r\n%s"
3104  "Events: Off\r\n\r\n", id_text);
3105  else
3106  astman_send_error(s, m, "Invalid event mask");
3107 
3108  return 0;
3109 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct permalias perms[]
int num
Definition: manager.c:1174
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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 &#39;...
Definition: manager.c:2166
static int broken_events_action
Definition: manager.c:903
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int action_extensionstate ( struct mansession s,
const struct message m 
)
static

Definition at line 4306 of file manager.c.

References ast_extension_state(), ast_get_hint(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), context, exten, and status.

Referenced by __init_manager().

4307 {
4308  const char *exten = astman_get_header(m, "Exten");
4309  const char *context = astman_get_header(m, "Context");
4310  char hint[256] = "";
4311  int status;
4312  if (ast_strlen_zero(exten)) {
4313  astman_send_error(s, m, "Extension not specified");
4314  return 0;
4315  }
4316  if (ast_strlen_zero(context)) {
4317  context = "default";
4318  }
4319  status = ast_extension_state(NULL, context, exten);
4320  ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
4321  astman_start_ack(s, m);
4322  astman_append(s, "Message: Extension Status\r\n"
4323  "Exten: %s\r\n"
4324  "Context: %s\r\n"
4325  "Hint: %s\r\n"
4326  "Status: %d\r\n\r\n",
4327  exten, context, hint, status);
4328  return 0;
4329 }
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:5362
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2140
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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:4914
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
jack_status_t status
Definition: app_jack.c:143
static struct manager_action* action_find ( const char *  name)
static

Definition at line 1075 of file manager.c.

References manager_action::action, ao2_t_ref, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, and AST_RWLIST_UNLOCK.

Referenced by ast_hook_send_action(), and process_message().

1076 {
1077  struct manager_action *act;
1078 
1080  AST_RWLIST_TRAVERSE(&actions, act, list) {
1081  if (!strcasecmp(name, act->action)) {
1082  ao2_t_ref(act, +1, "found action object");
1083  break;
1084  }
1085  }
1087 
1088  return act;
1089 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:471
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * action
Definition: manager.h:140
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
list of actions registered
Definition: manager.c:1058
static const char name[]
static int action_getconfig ( struct mansession s,
const struct message m 
)
static

Definition at line 2537 of file manager.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), ast_variable_browse(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by __init_manager().

2538 {
2539  struct ast_config *cfg;
2540  const char *fn = astman_get_header(m, "Filename");
2541  const char *category = astman_get_header(m, "Category");
2542  int catcount = 0;
2543  int lineno = 0;
2544  char *cur_category = NULL;
2545  struct ast_variable *v;
2546  struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2547 
2548  if (ast_strlen_zero(fn)) {
2549  astman_send_error(s, m, "Filename not specified");
2550  return 0;
2551  }
2552  cfg = ast_config_load2(fn, "manager", config_flags);
2553  if (cfg == CONFIG_STATUS_FILEMISSING) {
2554  astman_send_error(s, m, "Config file not found");
2555  return 0;
2556  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2557  astman_send_error(s, m, "Config file has invalid format");
2558  return 0;
2559  }
2560 
2561  astman_start_ack(s, m);
2562  while ((cur_category = ast_category_browse(cfg, cur_category))) {
2563  if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) {
2564  lineno = 0;
2565  astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category);
2566  for (v = ast_variable_browse(cfg, cur_category); v; v = v->next) {
2567  astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
2568  }
2569  catcount++;
2570  }
2571  }
2572  if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
2573  astman_append(s, "No categories found\r\n");
2574  }
2575  ast_config_destroy(cfg);
2576  astman_append(s, "\r\n");
2577 
2578  return 0;
2579 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2140
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
#define CONFIG_STATUS_FILEMISSING
Definition: config.h:50
const char * value
Definition: config.h:79
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
const char * name
Definition: config.h:77
Structure used to handle boolean flags.
Definition: utils.h:200
struct ast_variable * next
Definition: config.h:82
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int action_getconfigjson ( struct mansession s,
const struct message m 
)
static

Definition at line 2647 of file manager.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), ast_variable_browse(), astman_append(), astman_append_json(), astman_get_header(), astman_send_error(), astman_start_ack(), eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by __init_manager().

2648 {
2649  struct ast_config *cfg;
2650  const char *fn = astman_get_header(m, "Filename");
2651  char *category = NULL;
2652  struct ast_variable *v;
2653  int comma1 = 0;
2654  struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2655 
2656  if (ast_strlen_zero(fn)) {
2657  astman_send_error(s, m, "Filename not specified");
2658  return 0;
2659  }
2660 
2661  if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
2662  astman_send_error(s, m, "Config file not found");
2663  return 0;
2664  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2665  astman_send_error(s, m, "Config file has invalid format");
2666  return 0;
2667  }
2668 
2669  astman_start_ack(s, m);
2670  astman_append(s, "JSON: {");
2671  while ((category = ast_category_browse(cfg, category))) {
2672  int comma2 = 0;
2673 
2674  astman_append(s, "%s\"", comma1 ? "," : "");
2675  astman_append_json(s, category);
2676  astman_append(s, "\":[");
2677  comma1 = 1;
2678  for (v = ast_variable_browse(cfg, category); v; v = v->next) {
2679  astman_append(s, "%s\"", comma2 ? "," : "");
2680  astman_append_json(s, v->name);
2681  astman_append(s, "\":\"");
2682  astman_append_json(s, v->value);
2683  astman_append(s, "\"");
2684  comma2 = 1;
2685  }
2686  astman_append(s, "]");
2687  }
2688  astman_append(s, "}\r\n\r\n");
2689 
2690  ast_config_destroy(cfg);
2691 
2692  return 0;
2693 }
static void astman_append_json(struct mansession *s, const char *str)
Definition: manager.c:2638
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2140
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
const char * value
Definition: config.h:79
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
const char * name
Definition: config.h:77
Structure used to handle boolean flags.
Definition: utils.h:200
struct ast_variable * next
Definition: config.h:82
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int action_getvar ( struct mansession s,
const struct message m 
)
static

Definition at line 3243 of file manager.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(), function_capable_string_allowed_with_auths(), LOG_ERROR, pbx_retrieve_variable(), S_OR, mansession::session, and mansession_session::writeperm.

Referenced by __init_manager().

3244 {
3245  struct ast_channel *c = NULL;
3246  const char *name = astman_get_header(m, "Channel");
3247  const char *varname = astman_get_header(m, "Variable");
3248  char *varval;
3249  char workspace[1024];
3250 
3251  if (ast_strlen_zero(varname)) {
3252  astman_send_error(s, m, "No variable specified");
3253  return 0;
3254  }
3255 
3256  /* We don't want users with insufficient permissions using certain functions. */
3258  astman_send_error(s, m, "GetVar Access Forbidden: Variable");
3259  return 0;
3260  }
3261 
3262  if (!ast_strlen_zero(name)) {
3263  if (!(c = ast_channel_get_by_name(name))) {
3264  astman_send_error(s, m, "No such channel");
3265  return 0;
3266  }
3267  }
3268 
3269  workspace[0] = '\0';
3270  if (varname[strlen(varname) - 1] == ')') {
3271  if (!c) {
3273  if (c) {
3274  ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
3275  } else
3276  ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n");
3277  } else {
3278  ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
3279  }
3280  varval = workspace;
3281  } else {
3282  pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
3283  }
3284 
3285  if (c) {
3286  c = ast_channel_unref(c);
3287  }
3288 
3289  astman_start_ack(s, m);
3290  astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, S_OR(varval, ""));
3291 
3292  return 0;
3293 }
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
Definition: pbx.c:4177
Main Channel structure associated with a channel.
Definition: channel.h:742
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2140
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define LOG_ERROR
Definition: logger.h:155
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.
Definition: pbx.c:3434
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
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:1199
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
struct mansession_session * session
Definition: manager.c:1013
struct ast_channel * ast_dummy_channel_alloc(void)
Create a fake channel structure.
Definition: channel.c:1391
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int action_hangup ( struct mansession s,
const struct message m 
)
static

Definition at line 3167 of file manager.c.

References ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_debug, ast_log(), AST_SOFTHANGUP_EXPLICIT, ast_softhangup_nolock(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::hangupcause, LOG_NOTICE, and ast_channel::name.

Referenced by __init_manager().

3168 {
3169  struct ast_channel *c = NULL;
3170  int causecode = 0; /* all values <= 0 mean 'do not set hangupcause in channel' */
3171  const char *name = astman_get_header(m, "Channel");
3172  const char *cause = astman_get_header(m, "Cause");
3173 
3174  if (ast_strlen_zero(name)) {
3175  astman_send_error(s, m, "No channel specified");
3176  return 0;
3177  }
3178 
3179  if (!ast_strlen_zero(cause)) {
3180  char *endptr;
3181  causecode = strtol(cause, &endptr, 10);
3182  if (causecode < 0 || causecode > 127 || *endptr != '\0') {
3183  ast_log(LOG_NOTICE, "Invalid 'Cause: %s' in manager action Hangup\n", cause);
3184  /* keep going, better to hangup without cause than to not hang up at all */
3185  causecode = 0; /* do not set channel's hangupcause */
3186  }
3187  }
3188 
3189  if (!(c = ast_channel_get_by_name(name))) {
3190  astman_send_error(s, m, "No such channel");
3191  return 0;
3192  }
3193 
3194  ast_channel_lock(c);
3195  if (causecode > 0) {
3196  ast_debug(1, "Setting hangupcause of channel %s to %d (is %d now)\n",
3197  c->name, causecode, c->hangupcause);
3198  c->hangupcause = causecode;
3199  }
3201  ast_channel_unlock(c);
3202 
3203  c = ast_channel_unref(c);
3204 
3205  astman_send_ack(s, m, "Channel Hungup");
3206 
3207  return 0;
3208 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2733
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static const char name[]
int hangupcause
Definition: channel.h:849
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int action_listcategories ( struct mansession s,
const struct message m 
)
static

Definition at line 2581 of file manager.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, and CONFIG_STATUS_FILEINVALID.

Referenced by __init_manager().

2582 {
2583  struct ast_config *cfg;
2584  const char *fn = astman_get_header(m, "Filename");
2585  char *category = NULL;
2586  struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2587  int catcount = 0;
2588 
2589  if (ast_strlen_zero(fn)) {
2590  astman_send_error(s, m, "Filename not specified");
2591  return 0;
2592  }
2593  if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
2594  astman_send_error(s, m, "Config file not found");
2595  return 0;
2596  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2597  astman_send_error(s, m, "Config file has invalid format");
2598  return 0;
2599  }
2600  astman_start_ack(s, m);
2601  while ((category = ast_category_browse(cfg, category))) {
2602  astman_append(s, "Category-%06d: %s\r\n", catcount, category);
2603  catcount++;
2604  }
2605  if (catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
2606  astman_append(s, "Error: no categories found\r\n");
2607  }
2608  ast_config_destroy(cfg);
2609  astman_append(s, "\r\n");
2610 
2611  return 0;
2612 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2140
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
Structure used to handle boolean flags.
Definition: utils.h:200
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int action_listcommands ( struct mansession s,
const struct message m 
)
static

Definition at line 3048 of file manager.c.

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(), mansession::session, and mansession_session::writeperm.

Referenced by __init_manager().

3049 {
3050  struct manager_action *cur;
3051  struct ast_str *temp = ast_str_alloca(256);
3052 
3053  astman_start_ack(s, m);
3055  AST_RWLIST_TRAVERSE(&actions, cur, list) {
3056  if ((s->session->writeperm & cur->authority) || cur->authority == 0) {
3057  astman_append(s, "%s: %s (Priv: %s)\r\n",
3058  cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
3059  }
3060  }
3062  astman_append(s, "\r\n");
3063 
3064  return 0;
3065 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2140
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * action
Definition: manager.h:140
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:1235
#define ast_str_alloca(init_len)
Definition: strings.h:608
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
list of actions registered
Definition: manager.c:1058
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
struct mansession_session * session
Definition: manager.c:1013
static int action_login ( struct mansession s,
const struct message m 
)
static

Definition at line 3117 of file manager.c.

References ast_atomic_fetchadd_int(), ast_inet_ntoa(), AST_OPT_FLAG_FULLY_BOOTED, ast_options, ast_str_alloca, ast_test_flag, 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, mansession_session::readperm, mansession_session::send_events, mansession::session, mansession_session::sin, unauth_sessions, and mansession_session::username.

Referenced by __init_manager().

3118 {
3119 
3120  /* still authenticated - don't process again */
3121  if (s->session->authenticated) {
3122  astman_send_ack(s, m, "Already authenticated");
3123  return 0;
3124  }
3125 
3126  if (authenticate(s, m)) {
3127  sleep(1);
3128  astman_send_error(s, m, "Authentication failed");
3129  return -1;
3130  }
3131  s->session->authenticated = 1;
3133  if (manager_displayconnects(s->session)) {
3134  ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_inet_ntoa(s->session->sin.sin_addr));
3135  }
3136  astman_send_ack(s, m, "Authentication accepted");
3140  struct ast_str *auth = ast_str_alloca(80);
3141  const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
3142  astman_append(s, "Event: FullyBooted\r\n"
3143  "Privilege: %s\r\n"
3144  "Status: Fully Booted\r\n\r\n", cat_str);
3145  }
3146  return 0;
3147 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
char username[80]
Definition: manager.c:980
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int authenticate(struct mansession *s, const struct message *m)
Definition: manager.c:2422
struct sockaddr_in sin
Definition: manager.c:970
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
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:1235
#define ast_str_alloca(init_len)
Definition: strings.h:608
static int unauth_sessions
Definition: manager.c:914
#define ast_verb(level,...)
Definition: logger.h:243
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
uint32_t managerid
Definition: manager.c:976
struct ast_flags ast_options
Definition: asterisk.c:178
struct mansession_session * session
Definition: manager.c:1013
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:1452
static int action_logoff ( struct mansession s,
const struct message m 
)
static

Definition at line 3111 of file manager.c.

References astman_send_response().

Referenced by __init_manager().

3112 {
3113  astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
3114  return -1;
3115 }
void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg)
Send response in manager transaction.
Definition: manager.c:2125
static int action_mailboxcount ( struct mansession s,
const struct message m 
)
static

Definition at line 4285 of file manager.c.

References ast_app_inboxcount2(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and mailbox.

Referenced by __init_manager().

4286 {
4287  const char *mailbox = astman_get_header(m, "Mailbox");
4288  int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;;
4289 
4290  if (ast_strlen_zero(mailbox)) {
4291  astman_send_error(s, m, "Mailbox not specified");
4292  return 0;
4293  }
4294  ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs);
4295  astman_start_ack(s, m);
4296  astman_append(s, "Message: Mailbox Message Count\r\n"
4297  "Mailbox: %s\r\n"
4298  "UrgMessages: %d\r\n"
4299  "NewMessages: %d\r\n"
4300  "OldMessages: %d\r\n"
4301  "\r\n",
4302  mailbox, urgentmsgs, newmsgs, oldmsgs);
4303  return 0;
4304 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2140
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_app_inboxcount2(const char *mailbox, int *urgentmsgs, int *newmsgs, int *oldmsgs)
Determine number of urgent/new/old messages in a mailbox.
Definition: app.c:455
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static int action_mailboxstatus ( struct mansession s,
const struct message m 
)
static

Definition at line 4268 of file manager.c.

References ast_app_has_voicemail(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and mailbox.

Referenced by __init_manager().

4269 {
4270  const char *mailbox = astman_get_header(m, "Mailbox");
4271  int ret;
4272 
4273  if (ast_strlen_zero(mailbox)) {
4274  astman_send_error(s, m, "Mailbox not specified");
4275  return 0;
4276  }
4277  ret = ast_app_has_voicemail(mailbox, NULL);
4278  astman_start_ack(s, m);
4279  astman_append(s, "Message: Mailbox Status\r\n"
4280  "Mailbox: %s\r\n"
4281  "Waiting: %d\r\n\r\n", mailbox, ret);
4282  return 0;
4283 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
static void astman_start_ack(struct mansession *s, const struct message *m)
Definition: manager.c:2140
int ast_app_has_voicemail(const char *mailbox, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to &quot;INBOX&quot;. If folder is &quot;INBOX&quot;, includes the number of messages in the &quot;Urgent&quot; folder.
Definition: app.c:421
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static char mailbox[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:197
static int action_originate ( struct mansession s,
const struct message m 
)
static

Definition at line 4124 of file manager.c.

References app, ast_callerid_parse(), ast_calloc, ast_copy_string(), ast_findlabel_extension(), AST_FORMAT_SLINEAR, ast_free, ast_parse_allow_disallow(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), 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(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), cid_name, cid_num, context, ast_frame::data, destroy_fast_originate_helper(), EVENT_FLAG_SYSTEM, exten, fast_originate(), format, fast_originate_helper::format, fast_originate_helper::priority, mansession::session, strcasestr(), fast_originate_helper::timeout, fast_originate_helper::vars, and mansession_session::writeperm.

Referenced by __init_manager().

4125 {
4126  const char *name = astman_get_header(m, "Channel");
4127  const char *exten = astman_get_header(m, "Exten");
4128  const char *context = astman_get_header(m, "Context");
4129  const char *priority = astman_get_header(m, "Priority");
4130  const char *timeout = astman_get_header(m, "Timeout");
4131  const char *callerid = astman_get_header(m, "CallerID");
4132  const char *account = astman_get_header(m, "Account");
4133  const char *app = astman_get_header(m, "Application");
4134  const char *appdata = astman_get_header(m, "Data");
4135  const char *async = astman_get_header(m, "Async");
4136  const char *id = astman_get_header(m, "ActionID");
4137  const char *codecs = astman_get_header(m, "Codecs");
4138  struct ast_variable *vars;
4139  char *tech, *data;
4140  char *l = NULL, *n = NULL;
4141  int pi = 0;
4142  int res;
4143  int to = 30000;
4144  int reason = 0;
4145  char tmp[256];
4146  char tmp2[256];
4148 
4149  pthread_t th;
4150  if (ast_strlen_zero(name)) {
4151  astman_send_error(s, m, "Channel not specified");
4152  return 0;
4153  }
4154  if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
4155  if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
4156  astman_send_error(s, m, "Invalid priority");
4157  return 0;
4158  }
4159  }
4160  if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
4161  astman_send_error(s, m, "Invalid timeout");
4162  return 0;
4163  }
4164  ast_copy_string(tmp, name, sizeof(tmp));
4165  tech = tmp;
4166  data = strchr(tmp, '/');
4167  if (!data) {
4168  astman_send_error(s, m, "Invalid channel");
4169  return 0;
4170  }
4171  *data++ = '\0';
4172  ast_copy_string(tmp2, callerid, sizeof(tmp2));
4173  ast_callerid_parse(tmp2, &n, &l);
4174  if (n) {
4175  if (ast_strlen_zero(n)) {
4176  n = NULL;
4177  }
4178  }
4179  if (l) {
4181  if (ast_strlen_zero(l)) {
4182  l = NULL;
4183  }
4184  }
4185  if (!ast_strlen_zero(codecs)) {
4186  format = 0;
4187  ast_parse_allow_disallow(NULL, &format, codecs, 1);
4188  }
4189  if (!ast_strlen_zero(app) && s->session) {
4190  int bad_appdata = 0;
4191  /* To run the System application (or anything else that goes to
4192  * shell), you must have the additional System privilege */
4193  if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
4194  && (
4195  strcasestr(app, "system") || /* System(rm -rf /)
4196  TrySystem(rm -rf /) */
4197  strcasestr(app, "exec") || /* Exec(System(rm -rf /))
4198  TryExec(System(rm -rf /)) */
4199  strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /)
4200  EAGI(/bin/rm,-rf /) */
4201  strcasestr(app, "mixmonitor") || /* MixMonitor(blah,,rm -rf) */
4202  strcasestr(app, "externalivr") || /* ExternalIVR(rm -rf) */
4203  (strstr(appdata, "SHELL") && (bad_appdata = 1)) || /* NoOp(${SHELL(rm -rf /)}) */
4204  (strstr(appdata, "EVAL") && (bad_appdata = 1)) /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
4205  )) {
4206  char error_buf[64];
4207  snprintf(error_buf, sizeof(error_buf), "Originate Access Forbidden: %s", bad_appdata ? "Data" : "Application");
4208  astman_send_error(s, m, error_buf);
4209  return 0;
4210  }
4211  }
4212  /* Allocate requested channel variables */
4213  vars = astman_get_variables(m);
4214 
4215  if (ast_true(async)) {
4216  struct fast_originate_helper *fast;
4217 
4218  fast = ast_calloc(1, sizeof(*fast));
4219  if (!fast || ast_string_field_init(fast, 252)) {
4220  ast_free(fast);
4221  ast_variables_destroy(vars);
4222  res = -1;
4223  } else {
4224  if (!ast_strlen_zero(id)) {
4225  ast_string_field_build(fast, idtext, "ActionID: %s\r\n", id);
4226  }
4227  ast_string_field_set(fast, tech, tech);
4228  ast_string_field_set(fast, data, data);
4229  ast_string_field_set(fast, app, app);
4230  ast_string_field_set(fast, appdata, appdata);
4231  ast_string_field_set(fast, cid_num, l);
4232  ast_string_field_set(fast, cid_name, n);
4233  ast_string_field_set(fast, context, context);
4234  ast_string_field_set(fast, exten, exten);
4235  ast_string_field_set(fast, account, account);
4236  fast->vars = vars;
4237  fast->format = format;
4238  fast->timeout = to;
4239  fast->priority = pi;
4240  if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) {
4242  res = -1;
4243  } else {
4244  res = 0;
4245  }
4246  }
4247  } else if (!ast_strlen_zero(app)) {
4248  res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
4249  /* Any vars memory was passed to ast_pbx_outgoing_app(). */
4250  } else {
4251  if (exten && context && pi) {
4252  res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL);
4253  /* Any vars memory was passed to ast_pbx_outgoing_exten(). */
4254  } else {
4255  astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
4256  ast_variables_destroy(vars);
4257  return 0;
4258  }
4259  }
4260  if (!res) {
4261  astman_send_ack(s, m, "Originate successfully queued");
4262  } else {
4263  astman_send_error(s, m, "Originate failed");
4264  }
4265  return 0;
4266 }
helper function for originate
Definition: manager.c:3806
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:422
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:157
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static void destroy_fast_originate_helper(struct fast_originate_helper *doomed)
Definition: manager.c:3833
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
static const char app[]
Definition: app_adsiprog.c:49
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:249
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_variable * vars
Definition: manager.c:3823
int ast_pbx_outgoing_exten(const char *type, format_t format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
Definition: pbx.c:9375
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
int64_t format_t
Definition: frame_defs.h:32
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:5405
struct ast_variable * astman_get_variables(const struct message *m)
Get a linked list of the Variable: headers.
Definition: manager.c:1918
static const char name[]
#define ast_free(a)
Definition: astmm.h:97
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:367
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:158
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static void * fast_originate(void *data)
Definition: manager.c:3840
const ast_string_field idtext
Definition: manager.c:3821
struct mansession_session * session
Definition: manager.c:1013
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
int ast_pbx_outgoing_app(const char *type, format_t format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
Definition: pbx.c:9544
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()&#39;s, .&#39;s, and -&#39;s...
Definition: callerid.c:948
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
char * strcasestr(const char *, const char *)
static snd_pcm_format_t format
Definition: chan_alsa.c:93
int ast_parse_allow_disallow(struct ast_codec_pref *pref, format_t *mask, const char *list, int allowing)
Parse an &quot;allow&quot; or &quot;deny&quot; line in a channel or device configuration and update the capabilities mask...
Definition: frame.c:1272
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1009
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
static int action_ping ( struct mansession s,
const struct message m 
)
static

Definition at line 2519 of file manager.c.

References ast_strlen_zero(), ast_tvnow(), astman_append(), and astman_get_header().

Referenced by __init_manager().

2520 {
2521  const char *actionid = astman_get_header(m, "ActionID");
2522  struct timeval now = ast_tvnow();
2523 
2524  astman_append(s, "Response: Success\r\n");
2525  if (!ast_strlen_zero(actionid)){
2526  astman_append(s, "ActionID: %s\r\n", actionid);
2527  }
2528  astman_append(
2529  s,
2530  "Ping: Pong\r\n"
2531  "Timestamp: %ld.%06lu\r\n"
2532  "\r\n",
2533  (long) now.tv_sec, (unsigned long) now.tv_usec);
2534  return 0;
2535 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int action_redirect ( struct mansession s,
const struct message m 
)
static

action_redirect: The redirect manager command

Definition at line 3494 of file manager.c.

References ast_async_goto(), ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_check_hangup_locked(), ast_clear_flag, ast_findlabel_extension(), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT, AST_FLAG_BRIDGE_HANGUP_DONT, ast_set_flag, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, exten, ast_channel::pbx, and ast_channel::priority.

Referenced by __init_manager().

3495 {
3496  char buf[256];
3497  const char *name = astman_get_header(m, "Channel");
3498  const char *name2 = astman_get_header(m, "ExtraChannel");
3499  const char *exten = astman_get_header(m, "Exten");
3500  const char *exten2 = astman_get_header(m, "ExtraExten");
3501  const char *context = astman_get_header(m, "Context");
3502  const char *context2 = astman_get_header(m, "ExtraContext");
3503  const char *priority = astman_get_header(m, "Priority");
3504  const char *priority2 = astman_get_header(m, "ExtraPriority");
3505  struct ast_channel *chan;
3506  struct ast_channel *chan2;
3507  int pi = 0;
3508  int pi2 = 0;
3509  int res;
3510 
3511  if (ast_strlen_zero(name)) {
3512  astman_send_error(s, m, "Channel not specified");
3513  return 0;
3514  }
3515 
3516  if (ast_strlen_zero(context)) {
3517  astman_send_error(s, m, "Context not specified");
3518  return 0;
3519  }
3520  if (ast_strlen_zero(exten)) {
3521  astman_send_error(s, m, "Exten not specified");
3522  return 0;
3523  }
3524  if (ast_strlen_zero(priority)) {
3525  astman_send_error(s, m, "Priority not specified");
3526  return 0;
3527  }
3528  if (sscanf(priority, "%30d", &pi) != 1) {
3529  pi = ast_findlabel_extension(NULL, context, exten, priority, NULL);
3530  }
3531  if (pi < 1) {
3532  astman_send_error(s, m, "Priority is invalid");
3533  return 0;
3534  }
3535 
3536  if (!ast_strlen_zero(name2) && !ast_strlen_zero(context2)) {
3537  /* We have an ExtraChannel and an ExtraContext */
3538  if (ast_strlen_zero(exten2)) {
3539  astman_send_error(s, m, "ExtraExten not specified");
3540  return 0;
3541  }
3542  if (ast_strlen_zero(priority2)) {
3543  astman_send_error(s, m, "ExtraPriority not specified");
3544  return 0;
3545  }
3546  if (sscanf(priority2, "%30d", &pi2) != 1) {
3547  pi2 = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL);
3548  }
3549  if (pi2 < 1) {
3550  astman_send_error(s, m, "ExtraPriority is invalid");
3551  return 0;
3552  }
3553  }
3554 
3555  chan = ast_channel_get_by_name(name);
3556  if (!chan) {
3557  snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
3558  astman_send_error(s, m, buf);
3559  return 0;
3560  }
3561  if (ast_check_hangup_locked(chan)) {
3562  astman_send_error(s, m, "Redirect failed, channel not up.");
3563  chan = ast_channel_unref(chan);
3564  return 0;
3565  }
3566 
3567  if (ast_strlen_zero(name2)) {
3568  /* Single channel redirect in progress. */
3569  if (chan->pbx) {
3570  ast_channel_lock(chan);
3571  /* don't let the after-bridge code run the h-exten */
3573  ast_channel_unlock(chan);
3574  }
3575  res = ast_async_goto(chan, context, exten, pi);
3576  if (!res) {
3577  astman_send_ack(s, m, "Redirect successful");
3578  } else {
3579  astman_send_error(s, m, "Redirect failed");
3580  }
3581  chan = ast_channel_unref(chan);
3582  return 0;
3583  }
3584 
3585  chan2 = ast_channel_get_by_name(name2);
3586  if (!chan2) {
3587  snprintf(buf, sizeof(buf), "ExtraChannel does not exist: %s", name2);
3588  astman_send_error(s, m, buf);
3589  chan = ast_channel_unref(chan);
3590  return 0;
3591  }
3592  if (ast_check_hangup_locked(chan2)) {
3593  astman_send_error(s, m, "Redirect failed, extra channel not up.");
3594  chan2 = ast_channel_unref(chan2);
3595  chan = ast_channel_unref(chan);
3596  return 0;
3597  }
3598 
3599  /* Dual channel redirect in progress. */
3600  if (chan->pbx) {
3601  ast_channel_lock(chan);
3602  /* don't let the after-bridge code run the h-exten */
3605  ast_channel_unlock(chan);
3606  }
3607  if (chan2->pbx) {
3608  ast_channel_lock(chan2);
3609  /* don't let the after-bridge code run the h-exten */
3612  ast_channel_unlock(chan2);
3613  }
3614  res = ast_async_goto(chan, context, exten, pi);
3615  if (!res) {
3616  if (!ast_strlen_zero(context2)) {
3617  res = ast_async_goto(chan2, context2, exten2, pi2);
3618  } else {
3619  res = ast_async_goto(chan2, context, exten, pi);
3620  }
3621  if (!res) {
3622  astman_send_ack(s, m, "Dual Redirect successful");
3623  } else {
3624  astman_send_error(s, m, "Secondary redirect failed");
3625  }
3626  } else {
3627  astman_send_error(s, m, "Redirect failed");
3628  }
3629 
3630  /* Release the bridge wait. */
3631  if (chan->pbx) {
3632  ast_channel_lock(chan);
3634  ast_channel_unlock(chan);
3635  }
3636  if (chan2->pbx) {
3637  ast_channel_lock(chan2);
3639  ast_channel_unlock(chan2);
3640  }
3641 
3642  chan2 = ast_channel_unref(chan2);
3643  chan = ast_channel_unref(chan);
3644  return 0;
3645 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
#define ast_set_flag(p, flag)
Definition: utils.h:70
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:820
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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:5405
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static const char name[]
#define ast_clear_flag(p, flag)
Definition: utils.h:77
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:8731
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
struct ast_pbx * pbx
Definition: channel.h:761
static int action_reload ( struct mansession s,
const struct message m 
)
static

Send a reload event.

Definition at line 4550 of file manager.c.

References ast_module_reload(), astman_get_header(), astman_send_ack(), astman_send_error(), and S_OR.

Referenced by __init_manager().

4551 {
4552  const char *module = astman_get_header(m, "Module");
4553  int res = ast_module_reload(S_OR(module, NULL));
4554 
4555  switch (res) {
4556  case -1:
4557  astman_send_error(s, m, "A reload is in progress");
4558  break;
4559  case 0:
4560  astman_send_error(s, m, "No such module");
4561  break;
4562  case 1:
4563  astman_send_error(s, m, "Module does not support reload");
4564  break;
4565  case 2:
4566  astman_send_ack(s, m, "Module Reloaded");
4567  break;
4568  default:
4569  astman_send_error(s, m, "An unknown error occurred");
4570  break;
4571  }
4572  return 0;
4573 }
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
int ast_module_reload(const char *name)
Reload asterisk modules.
Definition: loader.c:721
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int action_sendtext ( struct mansession s,
const struct message m 
)
static

Definition at line 3459 of file manager.c.

References ast_channel_get_by_name(), ast_channel_unref, ast_sendtext(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), and astman_send_error().

Referenced by __init_manager().

3460 {
3461  struct ast_channel *c = NULL;
3462  const char *name = astman_get_header(m, "Channel");
3463  const char *textmsg = astman_get_header(m, "Message");
3464  int res = 0;
3465 
3466  if (ast_strlen_zero(name)) {
3467  astman_send_error(s, m, "No channel specified");
3468  return 0;
3469  }
3470 
3471  if (ast_strlen_zero(textmsg)) {
3472  astman_send_error(s, m, "No Message specified");
3473  return 0;
3474  }
3475 
3476  if (!(c = ast_channel_get_by_name(name))) {
3477  astman_send_error(s, m, "No such channel");
3478  return 0;
3479  }
3480 
3481  res = ast_sendtext(c, textmsg);
3482  c = ast_channel_unref(c);
3483 
3484  if (res >= 0) {
3485  astman_send_ack(s, m, "Success");
3486  } else {
3487  astman_send_error(s, m, "Failure");
3488  }
3489 
3490  return 0;
3491 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static const char name[]
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
int ast_sendtext(struct ast_channel *chan, const char *text)
Sends text to a channel.
Definition: channel.c:4687
static int action_setvar ( struct mansession s,
const struct message m 
)
static

Definition at line 3210 of file manager.c.

References ast_channel_get_by_name(), ast_channel_unref, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), pbx_builtin_setvar_helper(), and S_OR.

Referenced by __init_manager().

3211 {
3212  struct ast_channel *c = NULL;
3213  const char *name = astman_get_header(m, "Channel");
3214  const char *varname = astman_get_header(m, "Variable");
3215  const char *varval = astman_get_header(m, "Value");
3216  int res = 0;
3217 
3218  if (ast_strlen_zero(varname)) {
3219  astman_send_error(s, m, "No variable specified");
3220  return 0;
3221  }
3222 
3223  if (!ast_strlen_zero(name)) {
3224  if (!(c = ast_channel_get_by_name(name))) {
3225  astman_send_error(s, m, "No such channel");
3226  return 0;
3227  }
3228  }
3229 
3230  res = pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
3231 
3232  if (c) {
3233  c = ast_channel_unref(c);
3234  }
3235  if (res == 0) {
3236  astman_send_ack(s, m, "Variable Set");
3237  } else {
3238  astman_send_error(s, m, "Variable not set");
3239  }
3240  return 0;
3241 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static const char name[]
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...
Definition: pbx.c:10546
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int action_status ( struct mansession s,
const struct message m 
)
static

Manager "status" command to show channels.

Definition at line 3297 of file manager.c.

References ast_channel::_bridge, ast_channel::_state, ast_channel::accountcode, 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_free, ast_func_read(), AST_STANDARD_APP_ARGS, ast_state2str(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_strdupa, ast_strlen_zero(), ast_tvnow(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::bridge, ast_channel::caller, ast_channel::cdr, channels, ast_channel::connected, ast_channel::context, ast_channel::exten, function_capable_string_allowed_with_auths(), ast_party_caller::id, ast_party_connected_line::id, ast_party_id::name, ast_channel::name, ast_party_id::number, ast_channel::pbx, pbx_retrieve_variable(), ast_channel::priority, S_COR, S_OR, mansession::session, ast_cdr::start, str, ast_party_name::str, ast_party_number::str, ast_channel::uniqueid, ast_party_name::valid, ast_party_number::valid, and mansession_session::writeperm.

Referenced by __init_manager().

3298 {
3299  const char *name = astman_get_header(m, "Channel");
3300  const char *cvariables = astman_get_header(m, "Variables");
3301  char *variables = ast_strdupa(S_OR(cvariables, ""));
3302  struct ast_channel *c;
3303  char bridge[256];
3304  struct timeval now = ast_tvnow();
3305  long elapsed_seconds = 0;
3306  int channels = 0;
3307  int all = ast_strlen_zero(name); /* set if we want all channels */
3308  const char *id = astman_get_header(m, "ActionID");
3309  char idText[256];
3310  AST_DECLARE_APP_ARGS(vars,
3311  AST_APP_ARG(name)[100];
3312  );
3313  struct ast_str *str = ast_str_create(1000);
3314  struct ast_channel_iterator *iter = NULL;
3315 
3316  if (!ast_strlen_zero(id)) {
3317  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
3318  } else {
3319  idText[0] = '\0';
3320  }
3321 
3323  astman_send_error(s, m, "Status Access Forbidden: Variables");
3324  return 0;
3325  }
3326 
3327  if (all) {
3328  if (!(iter = ast_channel_iterator_all_new())) {
3329  ast_free(str);
3330  astman_send_error(s, m, "Memory Allocation Failure");
3331  return 1;
3332  }
3333  c = ast_channel_iterator_next(iter);
3334  } else {
3335  if (!(c = ast_channel_get_by_name(name))) {
3336  astman_send_error(s, m, "No such channel");
3337  ast_free(str);
3338  return 0;
3339  }
3340  }
3341 
3342  astman_send_ack(s, m, "Channel status will follow");
3343 
3344  if (!ast_strlen_zero(cvariables)) {
3345  AST_STANDARD_APP_ARGS(vars, variables);
3346  }
3347 
3348  /* if we look by name, we break after the first iteration */
3349  for (; c; c = ast_channel_iterator_next(iter)) {
3350  ast_channel_lock(c);
3351 
3352  if (!ast_strlen_zero(cvariables)) {
3353  int i;
3354  ast_str_reset(str);
3355  for (i = 0; i < vars.argc; i++) {
3356  char valbuf[512], *ret = NULL;
3357 
3358  if (vars.name[i][strlen(vars.name[i]) - 1] == ')') {
3359  if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) {
3360  valbuf[0] = '\0';
3361  }
3362  ret = valbuf;
3363  } else {
3364  pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL);
3365  }
3366 
3367  ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret);
3368  }
3369  }
3370 
3371  channels++;
3372  if (c->_bridge) {
3373  snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid);
3374  } else {
3375  bridge[0] = '\0';
3376  }
3377  if (c->pbx) {
3378  if (c->cdr) {
3379  elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
3380  }
3381  astman_append(s,
3382  "Event: Status\r\n"
3383  "Privilege: Call\r\n"
3384  "Channel: %s\r\n"
3385  "CallerIDNum: %s\r\n"
3386  "CallerIDName: %s\r\n"
3387  "ConnectedLineNum: %s\r\n"
3388  "ConnectedLineName: %s\r\n"
3389  "Accountcode: %s\r\n"
3390  "ChannelState: %u\r\n"
3391  "ChannelStateDesc: %s\r\n"
3392  "Context: %s\r\n"
3393  "Extension: %s\r\n"
3394  "Priority: %d\r\n"
3395  "Seconds: %ld\r\n"
3396  "%s"
3397  "Uniqueid: %s\r\n"
3398  "%s"
3399  "%s"
3400  "\r\n",
3401  c->name,
3402  S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<unknown>"),
3403  S_COR(c->caller.id.name.valid, c->caller.id.name.str, "<unknown>"),
3404  S_COR(c->connected.id.number.valid, c->connected.id.number.str, "<unknown>"),
3405  S_COR(c->connected.id.name.valid, c->connected.id.name.str, "<unknown>"),
3406  c->accountcode,
3407  c->_state,
3408  ast_state2str(c->_state), c->context,
3409  c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, ast_str_buffer(str), idText);
3410  } else {
3411  astman_append(s,
3412  "Event: Status\r\n"
3413  "Privilege: Call\r\n"
3414  "Channel: %s\r\n"
3415  "CallerIDNum: %s\r\n"
3416  "CallerIDName: %s\r\n"
3417  "ConnectedLineNum: %s\r\n"
3418  "ConnectedLineName: %s\r\n"
3419  "Account: %s\r\n"
3420  "State: %s\r\n"
3421  "%s"
3422  "Uniqueid: %s\r\n"
3423  "%s"
3424  "%s"
3425  "\r\n",
3426  c->name,
3427  S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<unknown>"),
3428  S_COR(c->caller.id.name.valid, c->caller.id.name.str, "<unknown>"),
3429  S_COR(c->connected.id.number.valid, c->connected.id.number.str, "<unknown>"),
3430  S_COR(c->connected.id.name.valid, c->connected.id.name.str, "<unknown>"),
3431  c->accountcode,
3432  ast_state2str(c->_state), bridge, c->uniqueid,
3433  ast_str_buffer(str), idText);
3434  }
3435 
3436  ast_channel_unlock(c);
3437  c = ast_channel_unref(c);
3438 
3439  if (!all) {
3440  break;
3441  }
3442  }
3443 
3444  if (iter) {
3446  }
3447 
3448  astman_append(s,
3449  "Event: StatusComplete\r\n"
3450  "%s"
3451  "Items: %d\r\n"
3452  "\r\n", idText, channels);
3453 
3454  ast_free(str);
3455 
3456  return 0;
3457 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
Definition: pbx.c:4177
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1715
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int priority
Definition: channel.h:841
const ast_string_field uniqueid
Definition: channel.h:787
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
char * str
Subscriber name (Malloced)
Definition: channel.h:214
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:900
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
struct ast_cdr * cdr
Definition: channel.h:766
const char * str
Definition: app_jack.c:144
const char * ast_state2str(enum ast_channel_state)
Gives the string form of a given channel state.
Definition: channel.c:1007
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#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:83
static struct channel_usage channels
struct ast_channel * _bridge
Definition: channel.h:748
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
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.
Definition: pbx.c:3434
enum ast_channel_state _state
Definition: channel.h:839
const ast_string_field name
Definition: channel.h:787
struct ast_bridge * bridge
Definition: channel.h:865
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct timeval start
Definition: cdr.h:100
static const char name[]
#define ast_free(a)
Definition: astmm.h:97
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:436
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:1199
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1649
const ast_string_field accountcode
Definition: channel.h:787
struct mansession_session * session
Definition: manager.c:1013
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1701
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
struct ast_pbx * pbx
Definition: channel.h:761
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int action_timeout ( struct mansession s,
const struct message m 
)
static

Definition at line 4331 of file manager.c.

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(), and astman_send_error().

Referenced by __init_manager().

4332 {
4333  struct ast_channel *c;
4334  const char *name = astman_get_header(m, "Channel");
4335  double timeout = atof(astman_get_header(m, "Timeout"));
4336  struct timeval when = { timeout, 0 };
4337 
4338  if (ast_strlen_zero(name)) {
4339  astman_send_error(s, m, "No channel specified");
4340  return 0;
4341  }
4342 
4343  if (!timeout || timeout < 0) {
4344  astman_send_error(s, m, "No timeout specified");
4345  return 0;
4346  }
4347 
4348  if (!(c = ast_channel_get_by_name(name))) {
4349  astman_send_error(s, m, "No such channel");
4350  return 0;
4351  }
4352 
4353  when.tv_usec = (timeout - when.tv_sec) * 1000000.0;
4354 
4355  ast_channel_lock(c);
4357  ast_channel_unlock(c);
4358  c = ast_channel_unref(c);
4359 
4360  astman_send_ack(s, m, "Timeout Set");
4361 
4362  return 0;
4363 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
void ast_channel_setwhentohangup_tv(struct ast_channel *chan, struct timeval offset)
Set when to hang a channel up.
Definition: channel.c:871
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static const char name[]
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int action_updateconfig ( struct mansession s,
const struct message m 
)
static

Definition at line 2845 of file manager.c.

References ast_config_destroy(), ast_config_load2(), ast_config_text_file_save(), 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_STATUS_FILEINVALID, FAILURE_ALLOCATION, FAILURE_APPEND, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, handle_updates(), UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, and UNSPECIFIED_CATEGORY.

Referenced by __init_manager().

2846 {
2847  struct ast_config *cfg;
2848  const char *sfn = astman_get_header(m, "SrcFilename");
2849  const char *dfn = astman_get_header(m, "DstFilename");
2850  int res;
2851  const char *rld = astman_get_header(m, "Reload");
2852  struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
2853  enum error_type result;
2854 
2855  if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
2856  astman_send_error(s, m, "Filename not specified");
2857  return 0;
2858  }
2859  if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) {
2860  astman_send_error(s, m, "Config file not found");
2861  return 0;
2862  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2863  astman_send_error(s, m, "Config file has invalid format");
2864  return 0;
2865  }
2866  result = handle_updates(s, m, cfg, dfn);
2867  if (!result) {
2868  ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
2869  res = ast_config_text_file_save(dfn, cfg, "Manager");
2870  ast_config_destroy(cfg);
2871  if (res) {
2872  astman_send_error(s, m, "Save of config failed");
2873  return 0;
2874  }
2875  astman_send_ack(s, m, NULL);
2876  if (!ast_strlen_zero(rld)) {
2877  if (ast_true(rld)) {
2878  rld = NULL;
2879  }
2880  ast_module_reload(rld);
2881  }
2882  } else {
2883  ast_config_destroy(cfg);
2884  switch(result) {
2885  case UNKNOWN_ACTION:
2886  astman_send_error(s, m, "Unknown action command");
2887  break;
2888  case UNKNOWN_CATEGORY:
2889  astman_send_error(s, m, "Given category does not exist");
2890  break;
2891  case UNSPECIFIED_CATEGORY:
2892  astman_send_error(s, m, "Category not specified");
2893  break;
2894  case UNSPECIFIED_ARGUMENT:
2895  astman_send_error(s, m, "Problem with category, value, or line (if required)");
2896  break;
2897  case FAILURE_ALLOCATION:
2898  astman_send_error(s, m, "Memory allocation failure, this should not happen");
2899  break;
2900  case FAILURE_NEWCAT:
2901  astman_send_error(s, m, "Create category did not complete successfully");
2902  break;
2903  case FAILURE_DELCAT:
2904  astman_send_error(s, m, "Delete category did not complete successfully");
2905  break;
2906  case FAILURE_EMPTYCAT:
2907  astman_send_error(s, m, "Empty category did not complete successfully");
2908  break;
2909  case FAILURE_UPDATE:
2910  astman_send_error(s, m, "Update did not complete successfully");
2911  break;
2912  case FAILURE_DELETE:
2913  astman_send_error(s, m, "Delete did not complete successfully");
2914  break;
2915  case FAILURE_APPEND:
2916  astman_send_error(s, m, "Append did not complete successfully");
2917  break;
2918  }
2919  }
2920  return 0;
2921 }
error_type
Definition: manager.c:844
void ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file)
Definition: config.c:380
int ast_config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator)
Definition: config.c:1977
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static enum error_type handle_updates(struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn)
Definition: manager.c:2696
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
int ast_module_reload(const char *name)
Reload asterisk modules.
Definition: loader.c:721
Structure used to handle boolean flags.
Definition: utils.h:200
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int action_userevent ( struct mansession s,
const struct message m 
)
static

Definition at line 4448 of file manager.c.

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

Referenced by __init_manager().

4449 {
4450  const char *event = astman_get_header(m, "UserEvent");
4451  struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
4452  int x;
4453 
4454  ast_str_reset(body);
4455 
4456  for (x = 0; x < m->hdrcount; x++) {
4457  if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
4458  ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
4459  }
4460  }
4461 
4462  astman_send_ack(s, m, "Event Sent");
4463  manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body));
4464  return 0;
4465 }
static struct ast_threadstorage userevent_buf
Definition: manager.c:2060
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
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:900
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
#define EVENT_FLAG_USER
Definition: manager.h:77
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:436
const char * headers[AST_MAX_MANHEADERS]
Definition: manager.h:135
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:669
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
unsigned int hdrcount
Definition: manager.h:134
static int action_waitevent ( struct mansession s,
const struct message m 
)
static

Definition at line 2941 of file manager.c.

References advance_event(), ao2_lock, ao2_unlock, ast_debug, AST_PTHREADT_NULL, AST_RWLIST_NEXT, ast_strlen_zero(), ast_wait_for_input(), astman_append(), astman_get_header(), astman_send_response(), eventqent::category, mansession_session::fd, mansession_session::last_ev, mansession_session::managerid, match_filter(), mansession_session::needdestroy, mansession_session::readperm, mansession_session::send_events, mansession::session, mansession_session::sessiontimeout, and mansession_session::waiting_thread.

Referenced by __init_manager().

2942 {
2943  const char *timeouts = astman_get_header(m, "Timeout");
2944  int timeout = -1;
2945  int x;
2946  int needexit = 0;
2947  const char *id = astman_get_header(m, "ActionID");
2948  char idText[256];
2949 
2950  if (!ast_strlen_zero(id)) {
2951  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
2952  } else {
2953  idText[0] = '\0';
2954  }
2955 
2956  if (!ast_strlen_zero(timeouts)) {
2957  sscanf(timeouts, "%30i", &timeout);
2958  if (timeout < -1) {
2959  timeout = -1;
2960  }
2961  /* XXX maybe put an upper bound, or prevent the use of 0 ? */
2962  }
2963 
2964  ao2_lock(s->session);
2966  pthread_kill(s->session->waiting_thread, SIGURG);
2967  }
2968 
2969  if (s->session->managerid) { /* AMI-over-HTTP session */
2970  /*
2971  * Make sure the timeout is within the expire time of the session,
2972  * as the client will likely abort the request if it does not see
2973  * data coming after some amount of time.
2974  */
2975  time_t now = time(NULL);
2976  int max = s->session->sessiontimeout - now - 10;
2977 
2978  if (max < 0) { /* We are already late. Strange but possible. */
2979  max = 0;
2980  }
2981  if (timeout < 0 || timeout > max) {
2982  timeout = max;
2983  }
2984  if (!s->session->send_events) { /* make sure we record events */
2985  s->session->send_events = -1;
2986  }
2987  }
2988  ao2_unlock(s->session);
2989 
2990  /* XXX should this go inside the lock ? */
2991  s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
2992  ast_debug(1, "Starting waiting for an event!\n");
2993 
2994  for (x = 0; x < timeout || timeout < 0; x++) {
2995  ao2_lock(s->session);
2996  if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
2997  needexit = 1;
2998  }
2999  /* We can have multiple HTTP session point to the same mansession entry.
3000  * The way we deal with it is not very nice: newcomers kick out the previous
3001  * HTTP session. XXX this needs to be improved.
3002  */
3003  if (s->session->waiting_thread != pthread_self()) {
3004  needexit = 1;
3005  }
3006  if (s->session->needdestroy) {
3007  needexit = 1;
3008  }
3009  ao2_unlock(s->session);
3010  if (needexit) {
3011  break;
3012  }
3013  if (s->session->managerid == 0) { /* AMI session */
3014  if (ast_wait_for_input(s->session->fd, 1000)) {
3015  break;
3016  }
3017  } else { /* HTTP session */
3018  sleep(1);
3019  }
3020  }
3021  ast_debug(1, "Finished waiting for an event!\n");
3022 
3023  ao2_lock(s->session);
3024  if (s->session->waiting_thread == pthread_self()) {
3025  struct eventqent *eqe = s->session->last_ev;
3026  astman_send_response(s, m, "Success", "Waiting for Event completed.");
3027  while ((eqe = advance_event(eqe))) {
3028  if (((s->session->readperm & eqe->category) == eqe->category)
3029  && ((s->session->send_events & eqe->category) == eqe->category)
3030  && match_filter(s, eqe->eventdata)) {
3031  astman_append(s, "%s", eqe->eventdata);
3032  }
3033  s->session->last_ev = eqe;
3034  }
3035  astman_append(s,
3036  "Event: WaitEventComplete\r\n"
3037  "%s"
3038  "\r\n", idText);
3040  } else {
3041  ast_debug(1, "Abandoning event request!\n");
3042  }
3043  ao2_unlock(s->session);
3044 
3045  return 0;
3046 }
#define AST_RWLIST_NEXT
Definition: linkedlists.h:440
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
pthread_t waiting_thread
Definition: manager.c:975
struct eventqent * last_ev
Definition: manager.c:989
#define ao2_unlock(a)
Definition: astobj2.h:497
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
time_t sessiontimeout
Definition: manager.c:979
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_PTHREADT_NULL
Definition: lock.h:65
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ao2_lock(a)
Definition: astobj2.h:488
static struct eventqent * advance_event(struct eventqent *e)
Definition: manager.c:1793
void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg)
Send response in manager transaction.
Definition: manager.c:2125
static int match_filter(struct mansession *s, char *eventdata)
Definition: manager.c:4394
uint32_t managerid
Definition: manager.c:976
int category
Definition: manager.c:880
struct mansession_session * session
Definition: manager.c:1013
int ast_wait_for_input(int fd, int ms)
Definition: utils.c:1255
static struct eventqent* advance_event ( struct eventqent e)
static

Definition at line 1793 of file manager.c.

References ast_atomic_fetchadd_int(), AST_RWLIST_NEXT, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and eventqent::usecount.

Referenced by action_waitevent(), and process_events().

1794 {
1795  struct eventqent *next;
1796 
1798  if ((next = AST_RWLIST_NEXT(e, eq_next))) {
1799  ast_atomic_fetchadd_int(&next->usecount, 1);
1801  }
1803  return next;
1804 }
#define AST_RWLIST_NEXT
Definition: linkedlists.h:440
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
int usecount
Definition: manager.c:879
static int aocmessage_get_unit_entry ( const struct message m,
struct ast_aoc_unit_entry entry,
unsigned int  entry_num 
)
static

Definition at line 3894 of file manager.c.

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

3895 {
3896  const char *unitamount;
3897  const char *unittype;
3898  struct ast_str *str = ast_str_alloca(32);
3899 
3900  memset(entry, 0, sizeof(*entry));
3901 
3902  ast_str_set(&str, 0, "UnitAmount(%u)", entry_num);
3903  unitamount = astman_get_header(m, ast_str_buffer(str));
3904 
3905  ast_str_set(&str, 0, "UnitType(%u)", entry_num);
3906  unittype = astman_get_header(m, ast_str_buffer(str));
3907 
3908  if (!ast_strlen_zero(unitamount) && (sscanf(unitamount, "%30u", &entry->amount) == 1)) {
3909  entry->valid_amount = 1;
3910  }
3911 
3912  if (!ast_strlen_zero(unittype) && sscanf(unittype, "%30u", &entry->type) == 1) {
3913  entry->valid_type = 1;
3914  }
3915 
3916  return 0;
3917 }
char valid_amount
Definition: aoc.h:179
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
unsigned int type
Definition: aoc.h:182
#define ast_str_alloca(init_len)
Definition: strings.h:608
const char * str
Definition: app_jack.c:144
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
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:874
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
char valid_type
Definition: aoc.h:181
unsigned int amount
Definition: aoc.h:180
static void append_channel_vars ( struct ast_str **  pbuf,
struct ast_channel chan 
)
static

Definition at line 5240 of file manager.c.

References ast_func_read2(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_str_append(), ast_str_buffer(), ast_str_thread_get(), manager_channel_variable::isfunc, manager_event_funcbuf, ast_channel::name, manager_channel_variable::name, pbx_builtin_getvar_helper(), and var.

Referenced by __ast_manager_event_multichan().

5241 {
5242  struct manager_channel_variable *var;
5243 
5246  const char *val;
5247  struct ast_str *res;
5248 
5249  if (var->isfunc) {
5251  if (res && ast_func_read2(chan, var->name, &res, 0) == 0) {
5252  val = ast_str_buffer(res);
5253  } else {
5254  val = NULL;
5255  }
5256  } else {
5257  val = pbx_builtin_getvar_helper(chan, var->name);
5258  }
5259  ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", chan->name, var->name, val ? val : "");
5260  }
5262 }
Definition: ast_expr2.c:325
int ast_func_read2(struct ast_channel *chan, const char *function, struct ast_str **str, ssize_t maxlen)
executes a read operation on a function
Definition: pbx.c:4216
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define var
Definition: ast_expr2f.c:606
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:900
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
unsigned int isfunc
Definition: manager.c:1027
struct manager_channel_variable::@288 entry
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
static struct ast_threadstorage manager_event_funcbuf
Definition: manager.c:5238
const ast_string_field name
Definition: channel.h:787
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
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:669
static int append_event ( const char *  str,
int  category 
)
static

Definition at line 5214 of file manager.c.

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::seq, eventqent::tv, and eventqent::usecount.

Referenced by __ast_manager_event_multichan(), and __init_manager().

5215 {
5216  struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
5217  static int seq; /* sequence number */
5218 
5219  if (!tmp) {
5220  return -1;
5221  }
5222 
5223  /* need to init all fields, because ast_malloc() does not */
5224  tmp->usecount = 0;
5225  tmp->category = category;
5226  tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
5227  tmp->tv = ast_tvnow();
5228  AST_RWLIST_NEXT(tmp, eq_next) = NULL;
5229  strcpy(tmp->eventdata, str);
5230 
5232  AST_RWLIST_INSERT_TAIL(&all_events, tmp, eq_next);
5234 
5235  return 0;
5236 }
struct timeval tv
Definition: manager.c:882
#define AST_RWLIST_NEXT
Definition: linkedlists.h:440
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
const char * str
Definition: app_jack.c:144
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
int usecount
Definition: manager.c:879
int category
Definition: manager.c:880
static volatile unsigned int seq
Definition: app_sms.c:118
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
unsigned int seq
Definition: manager.c:881
#define ast_malloc(a)
Definition: astmm.h:91
int ast_hook_send_action ( struct manager_custom_hook hook,
const char *  msg 
)

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

Parameters
hookthe file identifier specified in manager_custom_hook struct when registering a hook
msgami action mesage string e.g. "Action: SipPeers\r\n"
Return values
0on Success
non-zeroon Failure

Definition at line 1950 of file manager.c.

References action_find(), manager_action::active_count, ao2_lock, ao2_t_ref, ao2_unlock, ARRAY_LEN, ast_free, ast_strdup, astman_get_header(), mansession::f, manager_action::func, message::hdrcount, message::headers, mansession::hook, manager_action::registered, and mansession::session.

1951 {
1952  const char *action;
1953  int ret = 0;
1954  struct manager_action *act_found;
1955  struct mansession s = {.session = NULL, };
1956  struct message m = { 0 };
1957  char *dup_str;
1958  char *src;
1959  int x = 0;
1960  int curlen;
1961 
1962  if (hook == NULL) {
1963  return -1;
1964  }
1965 
1966  /* Create our own copy of the AMI action msg string. */
1967  src = dup_str = ast_strdup(msg);
1968  if (!dup_str) {
1969  return -1;
1970  }
1971 
1972  /* convert msg string to message struct */
1973  curlen = strlen(src);
1974  for (x = 0; x < curlen; x++) {
1975  int cr; /* set if we have \r */
1976  if (src[x] == '\r' && x+1 < curlen && src[x+1] == '\n')
1977  cr = 2; /* Found. Update length to include \r\n */
1978  else if (src[x] == '\n')
1979  cr = 1; /* also accept \n only */
1980  else
1981  continue;
1982  /* don't keep empty lines */
1983  if (x && m.hdrcount < ARRAY_LEN(m.headers)) {
1984  /* ... but trim \r\n and terminate the header string */
1985  src[x] = '\0';
1986  m.headers[m.hdrcount++] = src;
1987  }
1988  x += cr;
1989  curlen -= x; /* remaining size */
1990  src += x; /* update pointer */
1991  x = -1; /* reset loop */
1992  }
1993 
1994  action = astman_get_header(&m, "Action");
1995  if (strcasecmp(action, "login")) {
1996  act_found = action_find(action);
1997  if (act_found) {
1998  /*
1999  * we have to simulate a session for this action request
2000  * to be able to pass it down for processing
2001  * This is necessary to meet the previous design of manager.c
2002  */
2003  s.hook = hook;
2004  s.f = (void*)1; /* set this to something so our request will make it through all functions that test it*/
2005 
2006  ao2_lock(act_found);
2007  if (act_found->registered && act_found->func) {
2008  ++act_found->active_count;
2009  ao2_unlock(act_found);
2010  ret = act_found->func(&s, &m);
2011  ao2_lock(act_found);
2012  --act_found->active_count;
2013  } else {
2014  ret = -1;
2015  }
2016  ao2_unlock(act_found);
2017  ao2_t_ref(act_found, -1, "done with found action object");
2018  }
2019  }
2020  ast_free(dup_str);
2021  return ret;
2022 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:471
FILE * f
Definition: manager.c:1015
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define ast_strdup(a)
Definition: astmm.h:109
#define ao2_unlock(a)
Definition: astobj2.h:497
static struct manager_action * action_find(const char *name)
Definition: manager.c:1075
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
unsigned int registered
TRUE if the AMI action is registered and the callback can be called.
Definition: manager.h:162
#define ao2_lock(a)
Definition: astobj2.h:488
unsigned int active_count
Definition: manager.h:164
#define ast_free(a)
Definition: astmm.h:97
int(* func)(struct mansession *s, const struct message *m)
Definition: manager.h:151
const char * headers[AST_MAX_MANHEADERS]
Definition: manager.h:135
struct mansession_session * session
Definition: manager.c:1013
struct manager_custom_hook * hook
Definition: manager.c:1019
unsigned int hdrcount
Definition: manager.h:134
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 1259 of file manager.c.

Referenced by get_perm().

1260 {
1261  const char *val = bigstr, *next;
1262 
1263  do {
1264  if ((next = strchr(val, delim))) {
1265  if (!strncmp(val, smallstr, (next - val))) {
1266  return 1;
1267  } else {
1268  continue;
1269  }
1270  } else {
1271  return !strcmp(smallstr, val);
1272  }
1273  } while (*(val = (next + 1)));
1274 
1275  return 0;
1276 }
Definition: ast_expr2.c:325
int ast_manager_register2 ( const char *  action,
int  auth,
int(*)(struct mansession *s, const struct message *m)  func,
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 5469 of file manager.c.

References manager_action::action, action_destroy(), ao2_alloc, ao2_t_ref, ast_free, ast_manager_register_struct(), AST_STATIC_DOC, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), AST_XML_DOC, ast_xmldoc_build_arguments(), ast_xmldoc_build_description(), ast_xmldoc_build_seealso(), ast_xmldoc_build_synopsis(), ast_xmldoc_build_syntax(), manager_action::authority, manager_action::docsrc, and manager_action::func.

Referenced by load_module().

5470 {
5471  struct manager_action *cur;
5472 
5473  cur = ao2_alloc(sizeof(*cur), action_destroy);
5474  if (!cur) {
5475  return -1;
5476  }
5477  if (ast_string_field_init(cur, 128)) {
5478  ao2_t_ref(cur, -1, "action object creation failed");
5479  return -1;
5480  }
5481 
5482  cur->action = action;
5483  cur->authority = auth;
5484  cur->func = func;
5485 #ifdef AST_XML_DOCS
5486  if (ast_strlen_zero(synopsis) && ast_strlen_zero(description)) {
5487  char *tmpxml;
5488 
5489  tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL);
5490  ast_string_field_set(cur, synopsis, tmpxml);
5491  ast_free(tmpxml);
5492 
5493  tmpxml = ast_xmldoc_build_syntax("manager", action, NULL);
5494  ast_string_field_set(cur, syntax, tmpxml);
5495  ast_free(tmpxml);
5496 
5497  tmpxml = ast_xmldoc_build_description("manager", action, NULL);
5498  ast_string_field_set(cur, description, tmpxml);
5499  ast_free(tmpxml);
5500 
5501  tmpxml = ast_xmldoc_build_seealso("manager", action, NULL);
5502  ast_string_field_set(cur, seealso, tmpxml);
5503  ast_free(tmpxml);
5504 
5505  tmpxml = ast_xmldoc_build_arguments("manager", action, NULL);
5506  ast_string_field_set(cur, arguments, tmpxml);
5507  ast_free(tmpxml);
5508 
5509  cur->docsrc = AST_XML_DOC;
5510  } else
5511 #endif
5512  {
5514  ast_string_field_set(cur, description, description);
5515 #ifdef AST_XML_DOCS
5516  cur->docsrc = AST_STATIC_DOC;
5517 #endif
5518  }
5519  if (ast_manager_register_struct(cur)) {
5520  ao2_t_ref(cur, -1, "action object registration failed");
5521  return -1;
5522  }
5523 
5524  ao2_t_ref(cur, -1, "action object registration successful");
5525  return 0;
5526 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:471
char * ast_xmldoc_build_description(const char *type, const char *name, const char *module)
Generate description documentation from XML.
Definition: xmldoc.c:1899
const char * action
Definition: manager.h:140
static int ast_manager_register_struct(struct manager_action *act)
Definition: manager.c:5414
char * ast_xmldoc_build_synopsis(const char *type, const char *name, const char *module)
Generate synopsis documentation from XML.
Definition: xmldoc.c:1894
char * ast_xmldoc_build_arguments(const char *type, const char *name, const char *module)
Generate the [arguments] tag based on type of node (&#39;application&#39;, &#39;function&#39; or &#39;agi&#39;) and name...
Definition: xmldoc.c:1761
enum ast_doc_src docsrc
Definition: manager.h:153
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:249
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
static char * synopsis
Definition: func_enum.c:156
#define ast_free(a)
Definition: astmm.h:97
int(* func)(struct mansession *s, const struct message *m)
Definition: manager.h:151
static void action_destroy(void *obj)
Definition: manager.c:5457
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:1156
char * ast_xmldoc_build_seealso(const char *type, const char *name, const char *module)
Parse the &lt;see-also&gt; node content.
Definition: xmldoc.c:1461
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
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 1092 of file manager.c.

References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

1093 {
1095  AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list);
1097 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
list of hooks registered
Definition: manager.c:1061
static int ast_manager_register_struct ( struct manager_action act)
static

Definition at line 5414 of file manager.c.

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, and manager_action::registered.

Referenced by ast_manager_register2().

5415 {
5416  struct manager_action *cur, *prev = NULL;
5417 
5419  AST_RWLIST_TRAVERSE(&actions, cur, list) {
5420  int ret;
5421 
5422  ret = strcasecmp(cur->action, act->action);
5423  if (ret == 0) {
5424  ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
5426  return -1;
5427  }
5428  if (ret > 0) { /* Insert these alphabetically */
5429  prev = cur;
5430  break;
5431  }
5432  }
5433 
5434  ao2_t_ref(act, +1, "action object added to list");
5435  act->registered = 1;
5436  if (prev) {
5437  AST_RWLIST_INSERT_AFTER(&actions, prev, act, list);
5438  } else {
5439  AST_RWLIST_INSERT_HEAD(&actions, act, list);
5440  }
5441 
5442  ast_verb(2, "Manager registered action %s\n", act->action);
5443 
5445 
5446  return 0;
5447 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:471
#define AST_RWLIST_INSERT_AFTER
Definition: linkedlists.h:687
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * action
Definition: manager.h:140
#define ast_verb(level,...)
Definition: logger.h:243
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:703
unsigned int registered
TRUE if the AMI action is registered and the callback can be called.
Definition: manager.h:162
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
list of actions registered
Definition: manager.c:1058
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_manager_unregister ( char *  action)

Unregister a registered manager command.

Parameters
actionName of registered Action:

Definition at line 5355 of file manager.c.

References manager_action::action, manager_action::active_count, ao2_lock, ao2_t_ref, ao2_unlock, ast_debug, 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(), astdb_shutdown(), data_shutdown(), features_shutdown(), manager_shutdown(), unload_module(), and unload_pbx().

5356 {
5357  struct manager_action *cur;
5358 
5361  if (!strcasecmp(action, cur->action)) {
5363  break;
5364  }
5365  }
5368 
5369  if (cur) {
5370  time_t now;
5371 
5372  /*
5373  * We have removed the action object from the container so we
5374  * are no longer in a hurry.
5375  */
5376  ao2_lock(cur);
5377  cur->registered = 0;
5378  ao2_unlock(cur);
5379 
5380  /*
5381  * Wait up to 5 seconds for any active invocations to complete
5382  * before returning. We have to wait instead of blocking
5383  * because we may be waiting for ourself to complete.
5384  */
5385  now = time(NULL);
5386  while (cur->active_count) {
5387  if (5 <= time(NULL) - now) {
5388  ast_debug(1,
5389  "Unregister manager action %s timed out waiting for %u active instances to complete\n",
5390  action, cur->active_count);
5391  break;
5392  }
5393 
5394  sched_yield();
5395  }
5396 
5397  ao2_t_ref(cur, -1, "action object removed from list");
5398  ast_verb(2, "Manager unregistered action %s\n", action);
5399  }
5400 
5401  return 0;
5402 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:471
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * action
Definition: manager.h:140
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ast_verb(level,...)
Definition: logger.h:243
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
unsigned int registered
TRUE if the AMI action is registered and the callback can be called.
Definition: manager.h:162
#define ao2_lock(a)
Definition: astobj2.h:488
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:565
unsigned int active_count
Definition: manager.h:164
list of actions registered
Definition: manager.c:1058
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
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 1100 of file manager.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

1101 {
1103  AST_RWLIST_REMOVE(&manager_hooks, hook, list);
1105 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
list of hooks registered
Definition: manager.c:1061
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:870
void astman_append ( struct mansession s,
const char *  fmt,
  ... 
)

utility functions for creating AMI replies

Definition at line 2068 of file manager.c.

References ast_str_buffer(), ast_str_set_va(), ast_str_thread_get(), ast_verbose(), astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE, mansession_session::f, mansession::f, send_string(), and mansession::session.

Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers_one(), _skinny_show_device(), _skinny_show_devices(), _skinny_show_line(), _skinny_show_lines(), action_agents(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_ping(), action_status(), action_waitevent(), ast_cli_netstats(), astman_append_json(), astman_send_response_full(), data_result_manager_output(), do_print(), manager_data_get(), manager_dbget(), manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), manager_jabber_send(), manager_list_voicemail_users(), manager_modulecheck(), manager_mute_mixmonitor(), manager_mutestream(), manager_parking_status(), manager_queue_rule_show(), manager_queues_show(), manager_queues_status(), manager_queues_summary(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_skinny_show_device(), manager_skinny_show_devices(), manager_skinny_show_line(), manager_skinny_show_lines(), and session_do().

2069 {
2070  va_list ap;
2071  struct ast_str *buf;
2072 
2074  return;
2075  }
2076 
2077  va_start(ap, fmt);
2078  ast_str_set_va(&buf, 0, fmt, ap);
2079  va_end(ap);
2080 
2081  if (s->f != NULL || s->session->f != NULL) {
2082  send_string(s, ast_str_buffer(buf));
2083  } else {
2084  ast_verbose("fd == -1 in astman_append, should not happen\n");
2085  }
2086 }
FILE * f
Definition: manager.c:1015
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
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:792
#define ASTMAN_APPEND_BUF_INITSIZE
initial allocated size for the astman_append_buf
Definition: manager.c:2063
static struct ast_threadstorage astman_append_buf
Definition: manager.c:2059
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
static int send_string(struct mansession *s, char *string)
Definition: manager.c:2029
struct mansession_session * session
Definition: manager.c:1013
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:669
static void astman_append_json ( struct mansession s,
const char *  str 
)
static

Definition at line 2638 of file manager.c.

References ast_alloca, astman_append(), and json_escape().

Referenced by action_getconfigjson().

2639 {
2640  char *buf;
2641 
2642  buf = ast_alloca(2 * strlen(str) + 1);
2643  json_escape(buf, str);
2644  astman_append(s, "%s", buf);
2645 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
static void json_escape(char *out, const char *in)
Definition: manager.c:2618
const char * str
Definition: app_jack.c:144
const char* astman_get_header ( const struct message m,
char *  var 
)

Return the first matching variable from an array.

Get header from mananger transaction.

Note
This is the legacy function and is implemented in therms of __astman_get_header().
Never returns NULL.

Definition at line 1860 of file manager.c.

References __astman_get_header(), and GET_HEADER_FIRST_MATCH.

Referenced by _sip_show_peer(), _sip_show_peers(), _skinny_show_devices(), _skinny_show_lines(), action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_aocmessage(), action_atxfer(), action_bridge(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), action_ping(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), action_waitevent(), aocmessage_get_unit_entry(), ast_hook_send_action(), astman_send_response_full(), authenticate(), change_monitor_action(), do_pause_or_unpause(), handle_updates(), manager_add_queue_member(), manager_data_get(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), manager_jabber_send(), manager_list_voicemail_users(), manager_modulecheck(), manager_moduleload(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_reload(), manager_queue_reset(), manager_queue_rule_show(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_show_dialplan(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), manager_skinny_show_device(), manager_skinny_show_devices(), manager_skinny_show_line(), manager_skinny_show_lines(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().

1861 {
1863 }
static const char * __astman_get_header(const struct message *m, char *var, int mode)
Return a matching header value.
Definition: manager.c:1823
#define var
Definition: ast_expr2f.c:606
#define GET_HEADER_FIRST_MATCH
Definition: manager.c:1806
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 1918 of file manager.c.

References astman_get_variables_order(), and ORDER_REVERSE.

Referenced by action_originate().

1919 {
1921 }
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:1923
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 1923 of file manager.c.

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

Referenced by astman_get_variables(), and manager_sipnotify().

1925 {
1926  int varlen;
1927  int x;
1928  struct ast_variable *head = NULL;
1929 
1930  static const char var_hdr[] = "Variable:";
1931 
1932  /* Process all "Variable:" headers. */
1933  varlen = strlen(var_hdr);
1934  for (x = 0; x < m->hdrcount; x++) {
1935  if (strncasecmp(var_hdr, m->headers[x], varlen)) {
1936  continue;
1937  }
1938  head = man_do_variable_value(head, m->headers[x] + varlen);
1939  }
1940 
1941  if (order == ORDER_NATURAL) {
1942  head = ast_variables_reverse(head);
1943  }
1944 
1945  return head;
1946 }
static struct ast_variable * man_do_variable_value(struct ast_variable *head, const char *hdr_val)
Definition: manager.c:1874
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
struct ast_variable * ast_variables_reverse(struct ast_variable *var)
Reverse a variable list.
Definition: config.c:562
const char * headers[AST_MAX_MANHEADERS]
Definition: manager.h:135
unsigned int hdrcount
Definition: manager.h:134
void astman_send_ack ( struct mansession s,
const struct message m,
char *  msg 
)

Send ack in manager transaction.

Definition at line 2135 of file manager.c.

References astman_send_response_full().

Referenced by action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_aocmessage(), action_atxfer(), action_bridge(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_dahdishowchannels(), action_hangup(), action_login(), action_originate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_list_voicemail_users(), manager_moduleload(), manager_optimize_away(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_reload(), manager_queue_reset(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_sipnotify(), meetmemute(), start_monitor_action(), and stop_monitor_action().

2136 {
2137  astman_send_response_full(s, m, "Success", msg, NULL);
2138 }
static void astman_send_response_full(struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
Definition: manager.c:2105
void astman_send_error ( struct mansession s,
const struct message m,
char *  error 
)

Send error in manager transaction.

Definition at line 2130 of file manager.c.

References astman_send_response_full().

Referenced by _sip_qualify_peer(), _sip_show_peer(), action_add_agi_cmd(), action_agent_logoff(), action_aocmessage(), action_atxfer(), action_bridge(), action_challenge(), action_command(), action_coreshowchannels(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), change_monitor_action(), do_message(), do_pause_or_unpause(), handle_parse_error(), manager_add_queue_member(), manager_data_get(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_modulecheck(), manager_moduleload(), manager_mute_mixmonitor(), manager_mutestream(), manager_optimize_away(), manager_park(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_reload(), manager_queue_reset(), manager_remove_queue_member(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sipnotify(), manager_skinny_show_device(), manager_skinny_show_line(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().

2131 {
2132  astman_send_response_full(s, m, "Error", error, NULL);
2133 }
static void astman_send_response_full(struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
Definition: manager.c:2105
void astman_send_listack ( struct mansession s,
const struct message m,
char *  msg,
char *  listflag 
)

Send ack in manager list transaction.

Definition at line 2145 of file manager.c.

References astman_send_response_full().

Referenced by action_coreshowchannels(), action_meetmelist(), manager_dpsendack(), manager_iax2_show_peers(), manager_iax2_show_registry(), manager_show_registry(), manager_sip_show_peers(), manager_skinny_show_devices(), and manager_skinny_show_lines().

2146 {
2147  astman_send_response_full(s, m, "Success", msg, listflag);
2148 }
static void astman_send_response_full(struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
Definition: manager.c:2105
void astman_send_response ( struct mansession s,
const struct message m,
char *  resp,
char *  msg 
)

Send response in manager transaction.

Definition at line 2125 of file manager.c.

References astman_send_response_full().

Referenced by action_logoff(), and action_waitevent().

2126 {
2127  astman_send_response_full(s, m, resp, msg, NULL);
2128 }
static void astman_send_response_full(struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
Definition: manager.c:2105
static void astman_send_response_full ( struct mansession s,
const struct message m,
char *  resp,
char *  msg,
char *  listflag 
)
static

Definition at line 2105 of file manager.c.

References ast_strlen_zero(), astman_append(), astman_get_header(), and MSG_MOREDATA.

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

2106 {
2107  const char *id = astman_get_header(m, "ActionID");
2108 
2109  astman_append(s, "Response: %s\r\n", resp);
2110  if (!ast_strlen_zero(id)) {
2111  astman_append(s, "ActionID: %s\r\n", id);
2112  }
2113  if (listflag) {
2114  astman_append(s, "EventList: %s\r\n", listflag); /* Start, complete, cancelled */
2115  }
2116  if (msg == MSG_MOREDATA) {
2117  return;
2118  } else if (msg) {
2119  astman_append(s, "Message: %s\r\n\r\n", msg);
2120  } else {
2121  astman_append(s, "\r\n");
2122  }
2123 }
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define MSG_MOREDATA
send a response with an optional message, and terminate it with an empty line. m is used only to grab...
Definition: manager.c:2104
static void astman_start_ack ( struct mansession s,
const struct message m 
)
static

Definition at line 2140 of file manager.c.

References astman_send_response_full(), and MSG_MOREDATA.

Referenced by action_challenge(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_mailboxcount(), and action_mailboxstatus().

2141 {
2142  astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL);
2143 }
static void astman_send_response_full(struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
Definition: manager.c:2105
#define MSG_MOREDATA
send a response with an optional message, and terminate it with an empty line. m is used only to grab...
Definition: manager.c:2104
static int authenticate ( struct mansession s,
const struct message m 
)
static

Definition at line 2422 of file manager.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_t_link, ao2_t_ref, ast_apply_ha(), ast_copy_string(), ast_debug, ast_inet_ntoa(), ast_log(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_sockaddr_from_sin, ast_strlen_zero(), ast_tvnow(), astman_get_header(), mansession_session::blackfilters, ast_manager_user::blackfilters, mansession_session::challenge, get_manager_by_name_locked(), ast_manager_user::ha, len(), LOG_NOTICE, MD5Final(), MD5Init(), MD5Update(), mansession_session::readperm, ast_manager_user::readperm, report_auth_success(), report_failed_acl(), report_failed_challenge_response(), report_inval_password(), report_invalid_user(), S_OR, ast_manager_user::secret, mansession::session, mansession_session::sessionstart, mansession_session::sessionstart_tv, set_eventmask(), mansession_session::sin, mansession_session::username, mansession_session::whitefilters, ast_manager_user::whitefilters, mansession_session::writeperm, ast_manager_user::writeperm, mansession_session::writetimeout, and ast_manager_user::writetimeout.

Referenced by action_login().

2423 {
2424  const char *username = astman_get_header(m, "Username");
2425  const char *password = astman_get_header(m, "Secret");
2426  int error = -1;
2427  struct ast_manager_user *user = NULL;
2428  regex_t *regex_filter;
2429  struct ao2_iterator filter_iter;
2430  struct ast_sockaddr addr;
2431 
2432  if (ast_strlen_zero(username)) { /* missing username */
2433  return -1;
2434  }
2435 
2436  /* locate user in locked state */
2438 
2439  ast_sockaddr_from_sin(&addr, &s->session->sin);
2440 
2441  if (!(user = get_manager_by_name_locked(username))) {
2442  report_invalid_user(s, username);
2443  ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
2444  } else if (user->ha && !ast_apply_ha(user->ha, &addr)) {
2445  report_failed_acl(s, username);
2446  ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
2447  } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
2448  const char *key = astman_get_header(m, "Key");
2449  if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
2450  int x;
2451  int len = 0;
2452  char md5key[256] = "";
2453  struct MD5Context md5;
2454  unsigned char digest[16];
2455 
2456  MD5Init(&md5);
2457  MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
2458  MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
2459  MD5Final(digest, &md5);
2460  for (x = 0; x < 16; x++)
2461  len += sprintf(md5key + len, "%2.2x", (unsigned)digest[x]);
2462  if (!strcmp(md5key, key)) {
2463  error = 0;
2464  } else {
2465  report_failed_challenge_response(s, key, md5key);
2466  }
2467  } else {
2468  ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n",
2469  S_OR(s->session->challenge, ""));
2470  }
2471  } else if (user->secret) {
2472  if (!strcmp(password, user->secret)) {
2473  error = 0;
2474  } else {
2475  report_inval_password(s, username);
2476  }
2477  }
2478 
2479  if (error) {
2480  ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
2482  return -1;
2483  }
2484 
2485  /* auth complete */
2486 
2487  /* All of the user parameters are copied to the session so that in the event
2488  * of a reload and a configuration change, the session parameters are not
2489  * changed. */
2490  ast_copy_string(s->session->username, username, sizeof(s->session->username));
2491  s->session->readperm = user->readperm;
2492  s->session->writeperm = user->writeperm;
2493  s->session->writetimeout = user->writetimeout;
2494 
2495  filter_iter = ao2_iterator_init(user->whitefilters, 0);
2496  while ((regex_filter = ao2_iterator_next(&filter_iter))) {
2497  ao2_t_link(s->session->whitefilters, regex_filter, "add white user filter to session");
2498  ao2_t_ref(regex_filter, -1, "remove iterator ref");
2499  }
2500  ao2_iterator_destroy(&filter_iter);
2501 
2502  filter_iter = ao2_iterator_init(user->blackfilters, 0);
2503  while ((regex_filter = ao2_iterator_next(&filter_iter))) {
2504  ao2_t_link(s->session->blackfilters, regex_filter, "add black user filter to session");
2505  ao2_t_ref(regex_filter, -1, "remove iterator ref");
2506  }
2507  ao2_iterator_destroy(&filter_iter);
2508 
2509  s->session->sessionstart = time(NULL);
2511  set_eventmask(s, astman_get_header(m, "Events"));
2512 
2514 
2516  return 0;
2517 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:471
struct ao2_container * blackfilters
Definition: manager.c:1049
struct ao2_container * whitefilters
Definition: manager.c:1048
char username[80]
Definition: manager.c:980
static void report_invalid_user(const struct mansession *s, const char *username)
Definition: manager.c:2194
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
int ast_apply_ha(const struct ast_ha *ha, const struct ast_sockaddr *addr)
Apply a set of rules to a given IP address.
Definition: acl.c:518
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:1435
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
void MD5Final(unsigned char digest[16], struct MD5Context *context)
Definition: md5.c:122
struct sockaddr_in sin
Definition: manager.c:970
struct ast_ha * ha
Definition: manager.c:1042
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
static void report_failed_challenge_response(const struct mansession *s, const char *response, const char *expected_response)
Definition: manager.c:2358
user descriptor, as read from the config file.
Definition: manager.c:1039
struct ao2_container * blackfilters
Definition: manager.c:995
list of users found in the config file
Socket address structure.
Definition: netsock2.h:63
void MD5Init(struct MD5Context *context)
Definition: md5.c:59
#define ao2_t_link(arg1, arg2, arg3)
Add an object to a container.
Definition: astobj2.h:784
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ao2_container * whitefilters
Definition: manager.c:994
static void report_inval_password(const struct mansession *s, const char *username)
Definition: manager.c:2246
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct timeval sessionstart_tv
Definition: manager.c:978
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
Definition: md5.c:74
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_md5.c:54
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 &#39;...
Definition: manager.c:2166
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static void report_failed_acl(const struct mansession *s, const char *username)
Definition: manager.c:2220
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
static void report_auth_success(const struct mansession *s)
Definition: manager.c:2272
structure to hold users read from users.conf
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
Definition: md5.h:26
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
char challenge[10]
Definition: manager.c:981
struct mansession_session * session
Definition: manager.c:1013
time_t sessionstart
Definition: manager.c:977
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 1235 of file manager.c.

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

Referenced by __ast_manager_event_multichan(), action_listcommands(), action_login(), handle_showmancmd(), and handle_showmancmds().

1236 {
1237  int i;
1238  char *sep = "";
1239 
1240  ast_str_reset(*res);
1241  for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
1242  if (authority & perms[i].num) {
1243  ast_str_append(res, 0, "%s%s", sep, perms[i].label);
1244  sep = ",";
1245  }
1246  }
1247 
1248  if (ast_str_strlen(*res) == 0) /* replace empty string with something sensible */
1249  ast_str_append(res, 0, "<none>");
1250 
1251  return ast_str_buffer(*res);
1252 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct permalias perms[]
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
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:900
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:436
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:471
static int blackfilter_cmp_fn ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 4379 of file manager.c.

References CMP_MATCH, CMP_STOP, and ast_frame::data.

Referenced by match_filter().

4380 {
4381  regex_t *regex_filter = obj;
4382  const char *eventdata = arg;
4383  int *result = data;
4384 
4385  if (!regexec(regex_filter, eventdata, 0, NULL, 0)) {
4386  *result = 0;
4387  return (CMP_MATCH | CMP_STOP);
4388  }
4389 
4390  *result = 1;
4391  return 0;
4392 }
static struct mansession_session* build_mansession ( struct sockaddr_in  sin)
static

Allocate manager session structure and add it to the list of sessions.

Definition at line 1375 of file manager.c.

References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, AST_PTHREADT_NULL, mansession_session::blackfilters, mansession_session::fd, mansession_session::send_events, session_destructor(), mansession_session::sin, mansession_session::waiting_thread, mansession_session::whitefilters, and mansession_session::writetimeout.

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

1376 {
1377  struct mansession_session *newsession;
1378 
1379  if (!(newsession = ao2_alloc(sizeof(*newsession), session_destructor))) {
1380  return NULL;
1381  }
1382 
1383  if (!(newsession->whitefilters = ao2_container_alloc(1, NULL, NULL))) {
1384  ao2_ref(newsession, -1);
1385  return NULL;
1386  }
1387 
1388  if (!(newsession->blackfilters = ao2_container_alloc(1, NULL, NULL))) {
1389  ao2_ref(newsession, -1); /* session_destructor will cleanup the other filter */
1390  return NULL;
1391  }
1392 
1393  newsession->fd = -1;
1394  newsession->waiting_thread = AST_PTHREADT_NULL;
1395  newsession->writetimeout = 100;
1396  newsession->send_events = -1;
1397  newsession->sin = sin;
1398 
1399  ao2_link(sessions, newsession);
1400 
1401  return newsession;
1402 }
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
pthread_t waiting_thread
Definition: manager.c:975
struct sockaddr_in sin
Definition: manager.c:970
static void session_destructor(void *obj)
Definition: manager.c:1345
struct ao2_container * blackfilters
Definition: manager.c:995
struct ao2_container * whitefilters
Definition: manager.c:994
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
static int check_blacklist ( const char *  cmd)
static

Definition at line 3696 of file manager.c.

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

Referenced by action_command().

3697 {
3698  char *cmd_copy, *cur_cmd;
3699  char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, };
3700  int i;
3701 
3702  cmd_copy = ast_strdupa(cmd);
3703  for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) {
3704  cur_cmd = ast_strip(cur_cmd);
3705  if (ast_strlen_zero(cur_cmd)) {
3706  i--;
3707  continue;
3708  }
3709 
3710  cmd_words[i] = cur_cmd;
3711  }
3712 
3713  for (i = 0; i < ARRAY_LEN(command_blacklist); i++) {
3714  int j, match = 1;
3715 
3716  for (j = 0; command_blacklist[i].words[j]; j++) {
3717  if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) {
3718  match = 0;
3719  break;
3720  }
3721  }
3722 
3723  if (match) {
3724  return 1;
3725  }
3726  }
3727 
3728  return 0;
3729 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char * strsep(char **str, const char *delims)
#define MAX_BLACKLIST_CMD_LEN
Descriptor for a manager session, either on the AMI socket or over HTTP.
Definition: manager.c:927
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
const char * words[AST_MAX_CMD_LEN]
Definition: manager.c:929
static struct @286 command_blacklist[]
static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2069
int check_manager_enabled ( void  )

Check if AMI is enabled.

Definition at line 1107 of file manager.c.

References manager_enabled.

Referenced by handle_show_settings().

1108 {
1109  return manager_enabled;
1110 }
static int manager_enabled
Definition: manager.c:904
static int check_manager_session_inuse ( const char *  name)
static

Definition at line 1418 of file manager.c.

References ao2_find, mansession_session::inuse, and unref_mansession().

Referenced by process_message().

1419 {
1420  struct mansession_session *session = ao2_find(sessions, (char *) name, 0);
1421  int inuse = 0;
1422 
1423  if (session) {
1424  inuse = 1;
1425  unref_mansession(session);
1426  }
1427  return inuse;
1428 }
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:1330
#define ao2_find(arg1, arg2, arg3)
Definition: astobj2.h:964
static const char name[]
int check_webmanager_enabled ( void  )

Check if AMI/HTTP is enabled.

Definition at line 1112 of file manager.c.

Referenced by action_coresettings(), and handle_show_settings().

1113 {
1114  return (webmanager_enabled && manager_enabled);
1115 }
static int manager_enabled
Definition: manager.c:904
static int webmanager_enabled
Definition: manager.c:905
static void destroy_fast_originate_helper ( struct fast_originate_helper doomed)
static

Definition at line 3833 of file manager.c.

References ast_free, ast_string_field_free_memory, ast_variables_destroy(), and fast_originate_helper::vars.

Referenced by action_originate(), and fast_originate().

3834 {
3835  ast_variables_destroy(doomed->vars);
3837  ast_free(doomed);
3838 }
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
struct ast_variable * vars
Definition: manager.c:3823
#define ast_free(a)
Definition: astmm.h:97
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:253
static int do_message ( struct mansession s)
static

Definition at line 4985 of file manager.c.

References ARRAY_LEN, ast_free, ast_inet_ntoa(), ast_log(), ast_strdup, ast_strlen_zero(), ast_verb, astman_send_error(), mansession_session::authenticated, mansession_session::authstart, 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(), mansession::session, and mansession_session::sin.

Referenced by session_do().

4986 {
4987  struct message m = { 0 };
4988  char header_buf[sizeof(s->session->inbuf)] = { '\0' };
4989  int res;
4990  int idx;
4991  int hdr_loss;
4992  time_t now;
4993 
4994  hdr_loss = 0;
4995  for (;;) {
4996  /* Check if any events are pending and do them if needed */
4997  if (process_events(s)) {
4998  res = -1;
4999  break;
5000  }
5001  res = get_input(s, header_buf);
5002  if (res == 0) {
5003  /* No input line received. */
5004  if (!s->session->authenticated) {
5005  if (time(&now) == -1) {
5006  ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
5007  res = -1;
5008  break;
5009  }
5010 
5011  if (now - s->session->authstart > authtimeout) {
5012  if (displayconnects) {
5013  ast_verb(2, "Client from %s, failed to authenticate in %d seconds\n", ast_inet_ntoa(s->session->sin.sin_addr), authtimeout);
5014  }
5015  res = -1;
5016  break;
5017  }
5018  }
5019  continue;
5020  } else if (res > 0) {
5021  /* Input line received. */
5022  if (ast_strlen_zero(header_buf)) {
5023  if (hdr_loss) {
5024  mansession_lock(s);
5025  astman_send_error(s, &m, "Too many lines in message or allocation failure");
5026  mansession_unlock(s);
5027  res = 0;
5028  } else {
5029  switch (s->parsing) {
5030  case MESSAGE_OKAY:
5031  res = process_message(s, &m) ? -1 : 0;
5032  break;
5033  case MESSAGE_LINE_TOO_LONG:
5034  handle_parse_error(s, &m, "Failed to parse message: line too long");
5035  res = 0;
5036  break;
5037  }
5038  }
5039  break;
5040  } else if (m.hdrcount < ARRAY_LEN(m.headers)) {
5041  m.headers[m.hdrcount] = ast_strdup(header_buf);
5042  if (!m.headers[m.hdrcount]) {
5043  /* Allocation failure. */
5044  hdr_loss = 1;
5045  } else {
5046  ++m.hdrcount;
5047  }
5048  } else {
5049  /* Too many lines in message. */
5050  hdr_loss = 1;
5051  }
5052  } else {
5053  /* Input error. */
5054  break;
5055  }
5056  }
5057 
5058  /* Free AMI request headers. */
5059  for (idx = 0; idx < m.hdrcount; ++idx) {
5060  ast_free((void *) m.headers[idx]);
5061  }
5062  return res;
5063 }
static int get_input(struct mansession *s, char *output)
Definition: manager.c:4870
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static void mansession_unlock(struct mansession *s)
Unlock the &#39;mansession&#39; structure.
Definition: manager.c:2157
#define ast_strdup(a)
Definition: astmm.h:109
static int displayconnects
Definition: manager.c:899
time_t authstart
Definition: manager.c:991
struct sockaddr_in sin
Definition: manager.c:970
static int authtimeout
Definition: manager.c:907
static int process_events(struct mansession *s)
Definition: manager.c:4424
#define ast_verb(level,...)
Definition: logger.h:243
static int process_message(struct mansession *s, const struct message *m)
Definition: manager.c:4762
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
enum mansession_message_parsing parsing
Definition: manager.c:1017
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
#define ast_free(a)
Definition: astmm.h:97
char inbuf[1025]
Definition: manager.c:985
static void mansession_lock(struct mansession *s)
Lock the &#39;mansession&#39; structure.
Definition: manager.c:2151
const char * headers[AST_MAX_MANHEADERS]
Definition: manager.h:135
struct mansession_session * session
Definition: manager.c:1013
static void handle_parse_error(struct mansession *s, struct message *m, char *error)
Definition: manager.c:4968
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
unsigned int hdrcount
Definition: manager.h:134
static void event_filter_destructor ( void *  obj)
static

Definition at line 1339 of file manager.c.

Referenced by __init_manager().

1340 {
1341  regex_t *regex_filter = obj;
1342  regfree(regex_filter);
1343 }
static void* fast_originate ( void *  data)
static

Definition at line 3840 of file manager.c.

References fast_originate_helper::account, fast_originate_helper::app, fast_originate_helper::appdata, AST_CHANNEL_NAME, ast_channel_unlock, ast_manager_event_multichan, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_strlen_zero(), fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, ast_frame::data, fast_originate_helper::data, destroy_fast_originate_helper(), EVENT_FLAG_CALL, fast_originate_helper::exten, fast_originate_helper::format, fast_originate_helper::idtext, ast_channel::name, fast_originate_helper::priority, S_OR, fast_originate_helper::tech, fast_originate_helper::timeout, ast_channel::uniqueid, and fast_originate_helper::vars.

Referenced by action_originate().

3841 {
3842  struct fast_originate_helper *in = data;
3843  int res;
3844  int reason = 0;
3845  struct ast_channel *chan = NULL, *chans[1];
3846  char requested_channel[AST_CHANNEL_NAME];
3847 
3848  if (!ast_strlen_zero(in->app)) {
3849  res = ast_pbx_outgoing_app(in->tech, in->format, (char *) in->data,
3850  in->timeout, in->app, in->appdata, &reason, 1,
3851  S_OR(in->cid_num, NULL),
3852  S_OR(in->cid_name, NULL),
3853  in->vars, in->account, &chan);
3854  } else {
3855  res = ast_pbx_outgoing_exten(in->tech, in->format, (char *) in->data,
3856  in->timeout, in->context, in->exten, in->priority, &reason, 1,
3857  S_OR(in->cid_num, NULL),
3858  S_OR(in->cid_name, NULL),
3859  in->vars, in->account, &chan);
3860  }
3861  /* Any vars memory was passed to the ast_pbx_outgoing_xxx() calls. */
3862  in->vars = NULL;
3863 
3864  if (!chan) {
3865  snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);
3866  }
3867  /* Tell the manager what happened with the channel */
3868  chans[0] = chan;
3869  ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
3870  "%s"
3871  "Response: %s\r\n"
3872  "Channel: %s\r\n"
3873  "Context: %s\r\n"
3874  "Exten: %s\r\n"
3875  "Reason: %d\r\n"
3876  "Uniqueid: %s\r\n"
3877  "CallerIDNum: %s\r\n"
3878  "CallerIDName: %s\r\n",
3879  in->idtext, res ? "Failure" : "Success",
3880  chan ? chan->name : requested_channel, in->context, in->exten, reason,
3881  chan ? chan->uniqueid : "<null>",
3882  S_OR(in->cid_num, "<unknown>"),
3883  S_OR(in->cid_name, "<unknown>")
3884  );
3885 
3886  /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
3887  if (chan) {
3888  ast_channel_unlock(chan);
3889  }
3891  return NULL;
3892 }
helper function for originate
Definition: manager.c:3806
Main Channel structure associated with a channel.
Definition: channel.h:742
const ast_string_field tech
Definition: manager.c:3821
const ast_string_field account
Definition: manager.c:3821
const ast_string_field uniqueid
Definition: channel.h:787
#define EVENT_FLAG_CALL
Definition: manager.h:72
static void destroy_fast_originate_helper(struct fast_originate_helper *doomed)
Definition: manager.c:3833
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
const ast_string_field cid_num
Definition: manager.c:3821
const ast_string_field exten
Definition: manager.c:3821
struct ast_variable * vars
Definition: manager.c:3823
int ast_pbx_outgoing_exten(const char *type, format_t format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
Definition: pbx.c:9375
const ast_string_field appdata
Definition: manager.c:3821
const ast_string_field name
Definition: channel.h:787
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define AST_CHANNEL_NAME
Definition: channel.h:137
const ast_string_field cid_name
Definition: manager.c:3821
const ast_string_field data
Definition: manager.c:3821
const ast_string_field context
Definition: manager.c:3821
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
const ast_string_field app
Definition: manager.c:3821
#define ast_manager_event_multichan(category, event, nchans, chans, contents,...)
Definition: manager.h:226
const ast_string_field idtext
Definition: manager.c:3821
int ast_pbx_outgoing_app(const char *type, format_t format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
Definition: pbx.c:9544
static void free_channelvars ( void  )
static

Definition at line 7252 of file manager.c.

References ast_free, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and var.

Referenced by load_channelvars(), and manager_set_defaults().

7254 {
7255  struct manager_channel_variable *var;
7257  while ((var = AST_RWLIST_REMOVE_HEAD(&channelvars, entry))) {
7258  ast_free(var);
7259  }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define var
Definition: ast_expr2f.c:606
struct manager_channel_variable::@288 entry
#define ast_free(a)
Definition: astmm.h:97
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:829
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 1199 of file manager.c.

References EVENT_FLAG_SYSTEM.

Referenced by action_getvar(), and action_status().

1200 {
1201  if (!(writepermlist & EVENT_FLAG_SYSTEM)
1202  && (
1203  strstr(evaluating, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */
1204  strstr(evaluating, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
1205  )) {
1206  return 0;
1207  }
1208  return 1;
1209 }
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
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 4870 of file manager.c.

References ao2_lock, ao2_unlock, ast_inet_ntoa(), ast_log(), AST_PTHREADT_NULL, ast_wait_for_input(), mansession_session::authenticated, mansession_session::authstart, errno, mansession_session::f, mansession_session::fd, mansession_session::inbuf, mansession_session::inlen, LOG_ERROR, LOG_WARNING, MESSAGE_LINE_TOO_LONG, mansession::parsing, mansession_session::pending_event, mansession::session, mansession_session::sin, ast_frame::src, and mansession_session::waiting_thread.

Referenced by do_message().

4871 {
4872  int res, x;
4873  int maxlen = sizeof(s->session->inbuf) - 1;
4874  char *src = s->session->inbuf;
4875  int timeout = -1;
4876  time_t now;
4877 
4878  /*
4879  * Look for \r\n within the buffer. If found, copy to the output
4880  * buffer and return, trimming the \r\n (not used afterwards).
4881  */
4882  for (x = 0; x < s->session->inlen; x++) {
4883  int cr; /* set if we have \r */
4884  if (src[x] == '\r' && x+1 < s->session->inlen && src[x + 1] == '\n') {
4885  cr = 2; /* Found. Update length to include \r\n */
4886  } else if (src[x] == '\n') {
4887  cr = 1; /* also accept \n only */
4888  } else {
4889  continue;
4890  }
4891  memmove(output, src, x); /*... but trim \r\n */
4892  output[x] = '\0'; /* terminate the string */
4893  x += cr; /* number of bytes used */
4894  s->session->inlen -= x; /* remaining size */
4895  memmove(src, src + x, s->session->inlen); /* remove used bytes */
4896  return 1;
4897  }
4898  if (s->session->inlen >= maxlen) {
4899  /* no crlf found, and buffer full - sorry, too long for us */
4900  ast_log(LOG_WARNING, "Discarding message from %s. Line too long: %.25s...\n", ast_inet_ntoa(s->session->sin.sin_addr), src);
4901  s->session->inlen = 0;
4903  }
4904  res = 0;
4905  while (res == 0) {
4906  /* calculate a timeout if we are not authenticated */
4907  if (!s->session->authenticated) {
4908  if(time(&now) == -1) {
4909  ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
4910  return -1;
4911  }
4912 
4913  timeout = (authtimeout - (now - s->session->authstart)) * 1000;
4914  if (timeout < 0) {
4915  /* we have timed out */
4916  return 0;
4917  }
4918  }
4919 
4920  ao2_lock(s->session);
4921  if (s->session->pending_event) {
4922  s->session->pending_event = 0;
4923  ao2_unlock(s->session);
4924  return 0;
4925  }
4926  s->session->waiting_thread = pthread_self();
4927  ao2_unlock(s->session);
4928 
4929  res = ast_wait_for_input(s->session->fd, timeout);
4930 
4931  ao2_lock(s->session);
4933  ao2_unlock(s->session);
4934  }
4935  if (res < 0) {
4936  /* If we get a signal from some other thread (typically because
4937  * there are new events queued), return 0 to notify the caller.
4938  */
4939  if (errno == EINTR || errno == EAGAIN) {
4940  return 0;
4941  }
4942  ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
4943  return -1;
4944  }
4945 
4946  ao2_lock(s->session);
4947  res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f);
4948  if (res < 1) {
4949  res = -1; /* error return */
4950  } else {
4951  s->session->inlen += res;
4952  src[s->session->inlen] = '\0';
4953  res = 0;
4954  }
4955  ao2_unlock(s->session);
4956  return res;
4957 }
pthread_t waiting_thread
Definition: manager.c:975
#define LOG_WARNING
Definition: logger.h:144
time_t authstart
Definition: manager.c:991
struct sockaddr_in sin
Definition: manager.c:970
static int authtimeout
Definition: manager.c:907
#define ao2_unlock(a)
Definition: astobj2.h:497
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define ao2_lock(a)
Definition: astobj2.h:488
enum mansession_message_parsing parsing
Definition: manager.c:1017
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
char inbuf[1025]
Definition: manager.c:985
struct mansession_session * session
Definition: manager.c:1013
int ast_wait_for_input(int fd, int ms)
Definition: utils.c:1255
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 1435 of file manager.c.

References AST_RWLIST_TRAVERSE, user, and ast_manager_user::username.

Referenced by __init_manager(), auth_http_callback(), authenticate(), handle_showmanager(), and manager_displayconnects().

1436 {
1437  struct ast_manager_user *user = NULL;
1438 
1439  AST_RWLIST_TRAVERSE(&users, user, list) {
1440  if (!strcasecmp(user->username, name)) {
1441  break;
1442  }
1443  }
1444 
1445  return user;
1446 }
static char user[512]
char username[80]
Definition: manager.c:1040
user descriptor, as read from the config file.
Definition: manager.c:1039
list of users found in the config file
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
static const char name[]
structure to hold users read from users.conf
static int get_perm ( const char *  instr)
static

Definition at line 1278 of file manager.c.

References ARRAY_LEN, ast_instring(), permalias::num, and perms.

Referenced by __init_manager(), and strings_to_mask().

1279 {
1280  int x = 0, ret = 0;
1281 
1282  if (!instr) {
1283  return 0;
1284  }
1285 
1286  for (x = 0; x < ARRAY_LEN(perms); x++) {
1287  if (ast_instring(instr, perms[x].label, ',')) {
1288  ret |= perms[x].num;
1289  }
1290  }
1291 
1292  return ret;
1293 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct permalias perms[]
int num
Definition: manager.c:1174
static int ast_instring(const char *bigstr, const char *smallstr, const char delim)
Definition: manager.c:1259
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 1121 of file manager.c.

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

1122 {
1123  struct eventqent *ret;
1124 
1126  ret = AST_RWLIST_LAST(&all_events);
1127  /* the list is never empty now, but may become so when
1128  * we optimize it in the future, so be prepared.
1129  */
1130  if (ret) {
1132  }
1134  return ret;
1135 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
int usecount
Definition: manager.c:879
#define AST_RWLIST_LAST
Definition: linkedlists.h:430
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 1774 of file manager.c.

References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, reload_manager(), and ast_cli_entry::usage.

1775 {
1776  switch (cmd) {
1777  case CLI_INIT:
1778  e->command = "manager reload";
1779  e->usage =
1780  "Usage: manager reload\n"
1781  " Reloads the manager configuration.\n";
1782  return NULL;
1783  case CLI_GENERATE:
1784  return NULL;
1785  }
1786  if (a->argc > 2) {
1787  return CLI_SHOWUSAGE;
1788  }
1789  reload_manager();
1790  return CLI_SUCCESS;
1791 }
int reload_manager(void)
Called by Asterisk module functions and the CLI command.
Definition: manager.c:7267
const int argc
Definition: cli.h:154
Definition: cli.h:146
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_mandebug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1548 of file manager.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

1549 {
1550  switch (cmd) {
1551  case CLI_INIT:
1552  e->command = "manager set debug [on|off]";
1553  e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n";
1554  return NULL;
1555  case CLI_GENERATE:
1556  return NULL;
1557  }
1558 
1559  if (a->argc == 3) {
1560  ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off");
1561  } else if (a->argc == 4) {
1562  if (!strcasecmp(a->argv[3], "on")) {
1563  manager_debug = 1;
1564  } else if (!strcasecmp(a->argv[3], "off")) {
1565  manager_debug = 0;
1566  } else {
1567  return CLI_SHOWUSAGE;
1568  }
1569  }
1570  return CLI_SUCCESS;
1571 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
static int manager_debug
Definition: manager.c:906
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static void handle_parse_error ( struct mansession s,
struct message m,
char *  error 
)
static

Definition at line 4968 of file manager.c.

References astman_send_error(), mansession_lock(), mansession_unlock(), MESSAGE_OKAY, and mansession::parsing.

Referenced by do_message().

4969 {
4970  mansession_lock(s);
4971  astman_send_error(s, m, error);
4972  s->parsing = MESSAGE_OKAY;
4973  mansession_unlock(s);
4974 }
static void mansession_unlock(struct mansession *s)
Unlock the &#39;mansession&#39; structure.
Definition: manager.c:2157
enum mansession_message_parsing parsing
Definition: manager.c:1017
static void mansession_lock(struct mansession *s)
Lock the &#39;mansession&#39; structure.
Definition: manager.c:2151
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static char* handle_showmanager ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1573 of file manager.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), 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, ast_manager_user::displayconnects, ast_cli_args::fd, get_manager_by_name_locked(), ast_manager_user::ha, ast_cli_args::n, ast_cli_args::pos, ast_manager_user::readperm, ast_manager_user::secret, ast_cli_entry::usage, user_authority_to_str(), ast_manager_user::username, ast_cli_args::word, and ast_manager_user::writeperm.

1574 {
1575  struct ast_manager_user *user = NULL;
1576  int l, which;
1577  char *ret = NULL;
1578  struct ast_str *rauthority = ast_str_alloca(128);
1579  struct ast_str *wauthority = ast_str_alloca(128);
1580 
1581  switch (cmd) {
1582  case CLI_INIT:
1583  e->command = "manager show user";
1584  e->usage =
1585  " Usage: manager show user <user>\n"
1586  " Display all information related to the manager user specified.\n";
1587  return NULL;
1588  case CLI_GENERATE:
1589  l = strlen(a->word);
1590  which = 0;
1591  if (a->pos != 3) {
1592  return NULL;
1593  }
1595  AST_RWLIST_TRAVERSE(&users, user, list) {
1596  if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) {
1597  ret = ast_strdup(user->username);
1598  break;
1599  }
1600  }
1602  return ret;
1603  }
1604 
1605  if (a->argc != 4) {
1606  return CLI_SHOWUSAGE;
1607  }
1608 
1610 
1611  if (!(user = get_manager_by_name_locked(a->argv[3]))) {
1612  ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]);
1614  return CLI_SUCCESS;
1615  }
1616 
1617  ast_cli(a->fd, "\n");
1618  ast_cli(a->fd,
1619  " username: %s\n"
1620  " secret: %s\n"
1621  " acl: %s\n"
1622  " read perm: %s\n"
1623  " write perm: %s\n"
1624  "displayconnects: %s\n",
1625  (user->username ? user->username : "(N/A)"),
1626  (user->secret ? "<Set>" : "(N/A)"),
1627  (user->ha ? "yes" : "no"),
1628  user_authority_to_str(user->readperm, &rauthority),
1629  user_authority_to_str(user->writeperm, &wauthority),
1630  (user->displayconnects ? "yes" : "no"));
1631 
1633 
1634  return CLI_SUCCESS;
1635 }
char username[80]
Definition: manager.c:1040
#define ast_strdup(a)
Definition: astmm.h:109
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:1435
const int argc
Definition: cli.h:154
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
struct ast_ha * ha
Definition: manager.c:1042
#define ast_str_alloca(init_len)
Definition: strings.h:608
user descriptor, as read from the config file.
Definition: manager.c:1039
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
list of users found in the config file
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
const char *const * argv
Definition: cli.h:155
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:1213
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
structure to hold users read from users.conf
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
const int pos
Definition: cli.h:158
static char* handle_showmanagers ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1637 of file manager.c.

References ast_cli_args::argc, 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_cli_args::fd, ast_cli_entry::usage, and ast_manager_user::username.

1638 {
1639  struct ast_manager_user *user = NULL;
1640  int count_amu = 0;
1641  switch (cmd) {
1642  case CLI_INIT:
1643  e->command = "manager show users";
1644  e->usage =
1645  "Usage: manager show users\n"
1646  " Prints a listing of all managers that are currently configured on that\n"
1647  " system.\n";
1648  return NULL;
1649  case CLI_GENERATE:
1650  return NULL;
1651  }
1652  if (a->argc != 3) {
1653  return CLI_SHOWUSAGE;
1654  }
1655 
1657 
1658  /* If there are no users, print out something along those lines */
1659  if (AST_RWLIST_EMPTY(&users)) {
1660  ast_cli(a->fd, "There are no manager users.\n");
1662  return CLI_SUCCESS;
1663  }
1664 
1665  ast_cli(a->fd, "\nusername\n--------\n");
1666 
1667  AST_RWLIST_TRAVERSE(&users, user, list) {
1668  ast_cli(a->fd, "%s\n", user->username);
1669  count_amu++;
1670  }
1671 
1673 
1674  ast_cli(a->fd,"-------------------\n"
1675  "%d manager users configured.\n", count_amu);
1676  return CLI_SUCCESS;
1677 }
char username[80]
Definition: manager.c:1040
const int argc
Definition: cli.h:154
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
user descriptor, as read from the config file.
Definition: manager.c:1039
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
list of users found in the config file
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define AST_RWLIST_EMPTY
Definition: linkedlists.h:451
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
structure to hold users read from users.conf
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_showmancmd ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1466 of file manager.c.

References manager_action::action, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_free, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, AST_XML_DOC, ast_xmldoc_printable(), manager_action::authority, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, COLOR_MAGENTA, ast_cli_entry::command, manager_action::docsrc, ast_cli_args::fd, ast_cli_args::n, S_OR, synopsis, term_color(), ast_cli_entry::usage, and ast_cli_args::word.

1467 {
1468  struct manager_action *cur;
1469  struct ast_str *authority;
1470  int num, l, which;
1471  char *ret = NULL;
1472 #ifdef AST_XML_DOCS
1473  char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64], arguments_title[64];
1474 #endif
1475 
1476  switch (cmd) {
1477  case CLI_INIT:
1478  e->command = "manager show command";
1479  e->usage =
1480  "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n"
1481  " Shows the detailed description for a specific Asterisk manager interface command.\n";
1482  return NULL;
1483  case CLI_GENERATE:
1484  l = strlen(a->word);
1485  which = 0;
1487  AST_RWLIST_TRAVERSE(&actions, cur, list) {
1488  if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) {
1489  ret = ast_strdup(cur->action);
1490  break; /* make sure we exit even if ast_strdup() returns NULL */
1491  }
1492  }
1494  return ret;
1495  }
1496  authority = ast_str_alloca(80);
1497  if (a->argc < 4) {
1498  return CLI_SHOWUSAGE;
1499  }
1500 
1501 #ifdef AST_XML_DOCS
1502  /* setup the titles */
1503  term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
1504  term_color(description_title, "[Description]\n", COLOR_MAGENTA, 0, 40);
1505  term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
1506  term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40);
1507  term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
1508 #endif
1509 
1511  AST_RWLIST_TRAVERSE(&actions, cur, list) {
1512  for (num = 3; num < a->argc; num++) {
1513  if (!strcasecmp(cur->action, a->argv[num])) {
1514 #ifdef AST_XML_DOCS
1515  if (cur->docsrc == AST_XML_DOC) {
1516  char *syntax = ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1);
1517  char *synopsis = ast_xmldoc_printable(S_OR(cur->synopsis, "Not available"), 1);
1518  char *description = ast_xmldoc_printable(S_OR(cur->description, "Not available"), 1);
1519  char *arguments = ast_xmldoc_printable(S_OR(cur->arguments, "Not available"), 1);
1520  char *seealso = ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1);
1521  ast_cli(a->fd, "%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n",
1522  syntax_title, syntax,
1523  synopsis_title, synopsis,
1524  description_title, description,
1525  arguments_title, arguments,
1526  seealso_title, seealso);
1527  ast_free(syntax);
1528  ast_free(synopsis);
1529  ast_free(description);
1530  ast_free(arguments);
1531  ast_free(seealso);
1532  } else
1533 #endif
1534  {
1535  ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
1536  cur->action, cur->synopsis,
1537  authority_to_str(cur->authority, &authority),
1538  S_OR(cur->description, ""));
1539  }
1540  }
1541  }
1542  }
1544 
1545  return CLI_SUCCESS;
1546 }
#define ast_strdup(a)
Definition: astmm.h:109
const int argc
Definition: cli.h:154
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * action
Definition: manager.h:140
Definition: cli.h:146
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:1235
#define ast_str_alloca(init_len)
Definition: strings.h:608
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
enum ast_doc_src docsrc
Definition: manager.h:153
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
list of actions registered
Definition: manager.c:1058
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Definition: term.c:184
const char *const * argv
Definition: cli.h:155
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
#define CLI_SHOWUSAGE
Definition: cli.h:44
static char * synopsis
Definition: func_enum.c:156
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
char * ast_xmldoc_printable(const char *bwinput, int withcolors)
Colorize and put delimiters (instead of tags) to the xmldoc output.
Definition: xmldoc.c:315
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
#define COLOR_MAGENTA
Definition: term.h:57
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 1680 of file manager.c.

References manager_action::action, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, manager_action::authority, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HSMC_FORMAT, and ast_cli_entry::usage.

1681 {
1682  struct manager_action *cur;
1683  struct ast_str *authority;
1684 #define HSMC_FORMAT " %-15.15s %-15.15s %-55.55s\n"
1685  switch (cmd) {
1686  case CLI_INIT:
1687  e->command = "manager show commands";
1688  e->usage =
1689  "Usage: manager show commands\n"
1690  " Prints a listing of all the available Asterisk manager interface commands.\n";
1691  return NULL;
1692  case CLI_GENERATE:
1693  return NULL;
1694  }
1695  authority = ast_str_alloca(80);
1696  ast_cli(a->fd, HSMC_FORMAT, "Action", "Privilege", "Synopsis");
1697  ast_cli(a->fd, HSMC_FORMAT, "------", "---------", "--------");
1698 
1700  AST_RWLIST_TRAVERSE(&actions, cur, list) {
1701  ast_cli(a->fd, HSMC_FORMAT, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis);
1702  }
1704 
1705  return CLI_SUCCESS;
1706 }
#define HSMC_FORMAT
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * action
Definition: manager.h:140
Definition: cli.h:146
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:1235
#define ast_str_alloca(init_len)
Definition: strings.h:608
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
list of actions registered
Definition: manager.c:1058
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
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 1709 of file manager.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, ast_cli(), ast_inet_ntoa(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, mansession_session::fd, HSMCONN_FORMAT1, HSMCONN_FORMAT2, mansession_session::inuse, mansession_session::readperm, mansession_session::sessionstart, mansession_session::sin, unref_mansession(), ast_cli_entry::usage, mansession_session::username, and mansession_session::writeperm.

1710 {
1711  struct mansession_session *session;
1712  time_t now = time(NULL);
1713 #define HSMCONN_FORMAT1 " %-15.15s %-15.15s %-10.10s %-10.10s %-8.8s %-8.8s %-5.5s %-5.5s\n"
1714 #define HSMCONN_FORMAT2 " %-15.15s %-15.15s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\n"
1715  int count = 0;
1716  struct ao2_iterator i;
1717 
1718  switch (cmd) {
1719  case CLI_INIT:
1720  e->command = "manager show connected";
1721  e->usage =
1722  "Usage: manager show connected\n"
1723  " Prints a listing of the users that are currently connected to the\n"
1724  "Asterisk manager interface.\n";
1725  return NULL;
1726  case CLI_GENERATE:
1727  return NULL;
1728  }
1729 
1730  ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write");
1731 
1732  i = ao2_iterator_init(sessions, 0);
1733  while ((session = ao2_iterator_next(&i))) {
1734  ao2_lock(session);
1735  ast_cli(a->fd, HSMCONN_FORMAT2, session->username, ast_inet_ntoa(session->sin.sin_addr), (int)(session->sessionstart), (int)(now - session->sessionstart), session->fd, session->inuse, session->readperm, session->writeperm);
1736  count++;
1737  ao2_unlock(session);
1738  unref_mansession(session);
1739  }
1741  ast_cli(a->fd, "%d users connected.\n", count);
1742 
1743  return CLI_SUCCESS;
1744 }
char username[80]
Definition: manager.c:980
#define HSMCONN_FORMAT1
#define HSMCONN_FORMAT2
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
struct sockaddr_in sin
Definition: manager.c:970
Definition: cli.h:146
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
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:1330
const int fd
Definition: cli.h:153
#define ao2_lock(a)
Definition: astobj2.h:488
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
char * command
Definition: cli.h:180
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
time_t sessionstart
Definition: manager.c:977
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 1748 of file manager.c.

References ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, eventqent::category, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_entry::usage, and eventqent::usecount.

1749 {
1750  struct eventqent *s;
1751  switch (cmd) {
1752  case CLI_INIT:
1753  e->command = "manager show eventq";
1754  e->usage =
1755  "Usage: manager show eventq\n"
1756  " Prints a listing of all events pending in the Asterisk manger\n"
1757  "event queue.\n";
1758  return NULL;
1759  case CLI_GENERATE:
1760  return NULL;
1761  }
1763  AST_RWLIST_TRAVERSE(&all_events, s, eq_next) {
1764  ast_cli(a->fd, "Usecount: %d\n", s->usecount);
1765  ast_cli(a->fd, "Category: %d\n", s->category);
1766  ast_cli(a->fd, "Event:\n%s", s->eventdata);
1767  }
1769 
1770  return CLI_SUCCESS;
1771 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:153
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
int usecount
Definition: manager.c:879
char * command
Definition: cli.h:180
int category
Definition: manager.c:880
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static enum error_type handle_updates ( struct mansession s,
const struct message m,
struct ast_config cfg,
const char *  dfn 
)
static

Definition at line 2696 of file manager.c.

References ast_category_append(), ast_category_delete(), ast_category_destroy(), ast_category_empty(), ast_category_get(), ast_category_insert(), ast_category_new(), ast_category_rename(), ast_free, ast_log(), ast_str_create(), ast_strlen_zero(), ast_variable_append(), ast_variable_delete(), ast_variable_insert(), ast_variable_new(), ast_variable_update(), astman_get_header(), eventqent::category, FAILURE_ALLOCATION, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, LOG_WARNING, match(), ast_variable::object, UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, UNSPECIFIED_CATEGORY, value, and var.

Referenced by action_updateconfig().

2697 {
2698  int x;
2699  char hdr[40];
2700  const char *action, *cat, *var, *value, *match, *line;
2701  struct ast_category *category;
2702  struct ast_variable *v;
2703  struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
2704  enum error_type result = 0;
2705 
2706  for (x = 0; x < 100000; x++) { /* 100000 = the max number of allowed updates + 1 */
2707  unsigned int object = 0;
2708 
2709  snprintf(hdr, sizeof(hdr), "Action-%06d", x);
2710  action = astman_get_header(m, hdr);
2711  if (ast_strlen_zero(action)) /* breaks the for loop if no action header */
2712  break; /* this could cause problems if actions come in misnumbered */
2713 
2714  snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
2715  cat = astman_get_header(m, hdr);
2716  if (ast_strlen_zero(cat)) { /* every action needs a category */
2717  result = UNSPECIFIED_CATEGORY;
2718  break;
2719  }
2720 
2721  snprintf(hdr, sizeof(hdr), "Var-%06d", x);
2722  var = astman_get_header(m, hdr);
2723 
2724  snprintf(hdr, sizeof(hdr), "Value-%06d", x);
2725  value = astman_get_header(m, hdr);
2726 
2727  if (!ast_strlen_zero(value) && *value == '>') {
2728  object = 1;
2729  value++;
2730  }
2731 
2732  snprintf(hdr, sizeof(hdr), "Match-%06d", x);
2733  match = astman_get_header(m, hdr);
2734 
2735  snprintf(hdr, sizeof(hdr), "Line-%06d", x);
2736  line = astman_get_header(m, hdr);
2737 
2738  if (!strcasecmp(action, "newcat")) {
2739  if (ast_category_get(cfg,cat)) { /* check to make sure the cat doesn't */
2740  result = FAILURE_NEWCAT; /* already exist */
2741  break;
2742  }
2743  if (!(category = ast_category_new(cat, dfn, -1))) {
2744  result = FAILURE_ALLOCATION;
2745  break;
2746  }
2747  if (ast_strlen_zero(match)) {
2748  ast_category_append(cfg, category);
2749  } else {
2750  if (ast_category_insert(cfg, category, match)) {
2751  result = FAILURE_NEWCAT;
2752  ast_category_destroy(category);
2753  break;
2754  }
2755  }
2756  } else if (!strcasecmp(action, "renamecat")) {
2757  if (ast_strlen_zero(value)) {
2758  result = UNSPECIFIED_ARGUMENT;
2759  break;
2760  }
2761  if (!(category = ast_category_get(cfg, cat))) {
2762  result = UNKNOWN_CATEGORY;
2763  break;
2764  }
2765  ast_category_rename(category, value);
2766  } else if (!strcasecmp(action, "delcat")) {
2767  if (ast_category_delete(cfg, cat)) {
2768  result = FAILURE_DELCAT;
2769  break;
2770  }
2771  } else if (!strcasecmp(action, "emptycat")) {
2772  if (ast_category_empty(cfg, cat)) {
2773  result = FAILURE_EMPTYCAT;
2774  break;
2775  }
2776  } else if (!strcasecmp(action, "update")) {
2777  if (ast_strlen_zero(var)) {
2778  result = UNSPECIFIED_ARGUMENT;
2779  break;
2780  }
2781  if (!(category = ast_category_get(cfg,cat))) {
2782  result = UNKNOWN_CATEGORY;
2783  break;
2784  }
2785  if (ast_variable_update(category, var, value, match, object)) {
2786  result = FAILURE_UPDATE;
2787  break;
2788  }
2789  } else if (!strcasecmp(action, "delete")) {
2790  if ((ast_strlen_zero(var) && ast_strlen_zero(line))) {
2791  result = UNSPECIFIED_ARGUMENT;
2792  break;
2793  }
2794  if (!(category = ast_category_get(cfg, cat))) {
2795  result = UNKNOWN_CATEGORY;
2796  break;
2797  }
2798  if (ast_variable_delete(category, var, match, line)) {
2799  result = FAILURE_DELETE;
2800  break;
2801  }
2802  } else if (!strcasecmp(action, "append")) {
2803  if (ast_strlen_zero(var)) {
2804  result = UNSPECIFIED_ARGUMENT;
2805  break;
2806  }
2807  if (!(category = ast_category_get(cfg, cat))) {
2808  result = UNKNOWN_CATEGORY;
2809  break;
2810  }
2811  if (!(v = ast_variable_new(var, value, dfn))) {
2812  result = FAILURE_ALLOCATION;
2813  break;
2814  }
2815  if (object || (match && !strcasecmp(match, "object"))) {
2816  v->object = 1;
2817  }
2818  ast_variable_append(category, v);
2819  } else if (!strcasecmp(action, "insert")) {
2820  if (ast_strlen_zero(var) || ast_strlen_zero(line)) {
2821  result = UNSPECIFIED_ARGUMENT;
2822  break;
2823  }
2824  if (!(category = ast_category_get(cfg, cat))) {
2825  result = UNKNOWN_CATEGORY;
2826  break;
2827  }
2828  if (!(v = ast_variable_new(var, value, dfn))) {
2829  result = FAILURE_ALLOCATION;
2830  break;
2831  }
2832  ast_variable_insert(category, v, line);
2833  }
2834  else {
2835  ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action);
2836  result = UNKNOWN_ACTION;
2837  break;
2838  }
2839  }
2840  ast_free(str1);
2841  ast_free(str2);
2842  return result;
2843 }
int ast_variable_delete(struct ast_category *category, const char *variable, const char *match, const char *line)
Definition: config.c:897
int ast_category_delete(struct ast_config *cfg, const char *category)
Definition: config.c:976
#define LOG_WARNING
Definition: logger.h:144
error_type
Definition: manager.c:844
int ast_category_insert(struct ast_config *config, struct ast_category *cat, const char *match)
Inserts new category.
Definition: config.c:730
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
int object
Definition: config.h:88
#define var
Definition: ast_expr2f.c:606
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
int value
Definition: syslog.c:39
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category structure.
Definition: config.c:673
struct ast_category * ast_category_get(const struct ast_config *config, const char *category_name)
Retrieve a category if it exists.
Definition: config.c:709
void ast_category_destroy(struct ast_category *cat)
Definition: config.c:762
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: config.c:483
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
int ast_variable_update(struct ast_category *category, const char *variable, const char *value, const char *match, unsigned int object)
Update variable value within a config.
Definition: config.c:942
void ast_category_append(struct ast_config *config, struct ast_category *cat)
Definition: config.c:719
void ast_variable_insert(struct ast_category *category, struct ast_variable *variable, const char *line)
Definition: config.c:496
void ast_category_rename(struct ast_category *cat, const char *name)
Definition: config.c:867
static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2069
int ast_category_empty(struct ast_config *cfg, const char *category)
Removes and destroys all variables within a category.
Definition: config.c:1021
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
static void json_escape ( char *  out,
const char *  in 
)
static

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

Definition at line 2618 of file manager.c.

Referenced by astman_append_json().

2619 {
2620  for (; *in; in++) {
2621  if (*in == '\\' || *in == '\"') {
2622  *out++ = '\\';
2623  }
2624  *out++ = *in;
2625  }
2626  *out = '\0';
2627 }
static struct ast_variable* man_do_variable_value ( struct ast_variable head,
const char *  hdr_val 
)
static

Definition at line 1874 of file manager.c.

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, parse(), strsep(), and var.

Referenced by astman_get_variables_order().

1875 {
1876  char *parse;
1878  AST_APP_ARG(vars)[64];
1879  );
1880 
1881  hdr_val = ast_skip_blanks(hdr_val); /* ignore leading spaces in the value */
1882  parse = ast_strdupa(hdr_val);
1883 
1884  /* Break the header value string into name=val pair items. */
1885  AST_STANDARD_APP_ARGS(args, parse);
1886  if (args.argc) {
1887  int y;
1888 
1889  /* Process each name=val pair item. */
1890  for (y = 0; y < args.argc; y++) {
1891  struct ast_variable *cur;
1892  char *var;
1893  char *val;
1894 
1895  if (!args.vars[y]) {
1896  continue;
1897  }
1898  var = val = args.vars[y];
1899  strsep(&val, "=");
1900 
1901  /* XXX We may wish to trim whitespace from the strings. */
1902  if (!val || ast_strlen_zero(var)) {
1903  continue;
1904  }
1905 
1906  /* Create new variable list node and prepend it to the list. */
1907  cur = ast_variable_new(var, val, "");
1908  if (cur) {
1909  cur->next = head;
1910  head = cur;
1911  }
1912  }
1913  }
1914 
1915  return head;
1916 }
char * strsep(char **str, const char *delims)
Definition: ast_expr2.c:325
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:97
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
struct ast_variable * next
Definition: config.h:82
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
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 1452 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 action_login(), generic_http_callback(), purge_sessions(), and session_do().

1453 {
1454  struct ast_manager_user *user = NULL;
1455  int ret = 0;
1456 
1458  if ((user = get_manager_by_name_locked (session->username))) {
1459  ret = user->displayconnects;
1460  }
1462 
1463  return ret;
1464 }
char username[80]
Definition: manager.c:980
static struct ast_manager_user * get_manager_by_name_locked(const char *name)
Definition: manager.c:1435
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
user descriptor, as read from the config file.
Definition: manager.c:1039
list of users found in the config file
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
structure to hold users read from users.conf
static int manager_modulecheck ( struct mansession s,
const struct message m 
)
static

Definition at line 4660 of file manager.c.

References ast_copy_string(), ast_file_version_find(), ast_log(), ast_module_check(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), LOG_DEBUG, and version.

Referenced by __init_manager().

4661 {
4662  int res;
4663  const char *module = astman_get_header(m, "Module");
4664  const char *id = astman_get_header(m, "ActionID");
4665  char idText[256];
4666 #if !defined(LOW_MEMORY)
4667  const char *version;
4668 #endif
4669  char filename[PATH_MAX];
4670  char *cut;
4671 
4672  ast_copy_string(filename, module, sizeof(filename));
4673  if ((cut = strchr(filename, '.'))) {
4674  *cut = '\0';
4675  } else {
4676  cut = filename + strlen(filename);
4677  }
4678  snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so");
4679  ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename);
4680  res = ast_module_check(filename);
4681  if (!res) {
4682  astman_send_error(s, m, "Module not loaded");
4683  return 0;
4684  }
4685  snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c");
4686  ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename);
4687 #if !defined(LOW_MEMORY)
4688  version = ast_file_version_find(filename);
4689 #endif
4690 
4691  if (!ast_strlen_zero(id)) {
4692  snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
4693  } else {
4694  idText[0] = '\0';
4695  }
4696  astman_append(s, "Response: Success\r\n%s", idText);
4697 #if !defined(LOW_MEMORY)
4698  astman_append(s, "Version: %s\r\n\r\n", version ? version : "");
4699 #endif
4700  return 0;
4701 }
uint32_t version
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
#define LOG_DEBUG
Definition: logger.h:122
int ast_module_check(const char *name)
Check if module with the name given is loaded.
Definition: loader.c:1255
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
const char * ast_file_version_find(const char *file)
Find version for given module name.
Definition: asterisk.c:376
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int manager_moduleload ( struct mansession s,
const struct message m 
)
static

Definition at line 4703 of file manager.c.

References AST_FORCE_SOFT, ast_load_resource(), ast_module_reload(), ast_strlen_zero(), ast_unload_resource(), astman_get_header(), astman_send_ack(), and astman_send_error().

Referenced by __init_manager().

4704 {
4705  int res;
4706  const char *module = astman_get_header(m, "Module");
4707  const char *loadtype = astman_get_header(m, "LoadType");
4708 
4709  if (!loadtype || strlen(loadtype) == 0) {
4710  astman_send_error(s, m, "Incomplete ModuleLoad action.");
4711  }
4712  if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) {
4713  astman_send_error(s, m, "Need module name");
4714  }
4715 
4716  if (!strcasecmp(loadtype, "load")) {
4717  res = ast_load_resource(module);
4718  if (res) {
4719  astman_send_error(s, m, "Could not load module.");
4720  } else {
4721  astman_send_ack(s, m, "Module loaded.");
4722  }
4723  } else if (!strcasecmp(loadtype, "unload")) {
4724  res = ast_unload_resource(module, AST_FORCE_SOFT);
4725  if (res) {
4726  astman_send_error(s, m, "Could not unload module.");
4727  } else {
4728  astman_send_ack(s, m, "Module unloaded.");
4729  }
4730  } else if (!strcasecmp(loadtype, "reload")) {
4731  if (!ast_strlen_zero(module)) {
4732  res = ast_module_reload(module);
4733  if (res == 0) {
4734  astman_send_error(s, m, "No such module.");
4735  } else if (res == 1) {
4736  astman_send_error(s, m, "Module does not support reload action.");
4737  } else {
4738  astman_send_ack(s, m, "Module reloaded.");
4739  }
4740  } else {
4741  ast_module_reload(NULL); /* Reload all modules */
4742  astman_send_ack(s, m, "All modules reloaded");
4743  }
4744  } else
4745  astman_send_error(s, m, "Incomplete ModuleLoad action.");
4746  return 0;
4747 }
enum ast_module_load_result ast_load_resource(const char *resource_name)
Load a module.
Definition: loader.c:947
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode)
Unload a module.
Definition: loader.c:551
int ast_module_reload(const char *name)
Reload asterisk modules.
Definition: loader.c:721
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int manager_state_cb ( char *  context,
char *  exten,
int  state,
void *  data 
)
static

Definition at line 5404 of file manager.c.

References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.

Referenced by __init_manager().

5405 {
5406  /* Notify managers of change */
5407  char hint[512];
5408  ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
5409 
5410  manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state);
5411  return 0;
5412 }
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:5362
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
#define EVENT_FLAG_CALL
Definition: manager.h:72
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
static int mansession_cmp_fn ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1404 of file manager.c.

References CMP_MATCH, str, and mansession_session::username.

Referenced by __init_manager().

1405 {
1406  struct mansession_session *s = obj;
1407  char *str = arg;
1408  return !strcasecmp(s->username, str) ? CMP_MATCH : 0;
1409 }
char username[80]
Definition: manager.c:980
const char * str
Definition: app_jack.c:144
static struct sockaddr_in* mansession_encode_sin_local ( const struct mansession s,
struct sockaddr_in *  sin_local 
)
static

Definition at line 2185 of file manager.c.

References ast_sockaddr_to_sin, ast_tcptls_session_args::local_address, ast_tcptls_session_instance::parent, and mansession::tcptls_session.

Referenced by report_auth_success(), report_failed_acl(), report_failed_challenge_response(), report_inval_password(), report_invalid_user(), report_req_bad_format(), report_req_not_allowed(), and report_session_limit().

2187 {
2189  sin_local);
2190 
2191  return sin_local;
2192 }
struct ast_tcptls_session_args * parent
Definition: tcptls.h:208
struct ast_tcptls_session_instance * tcptls_session
Definition: manager.c:1014
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
struct ast_sockaddr local_address
Definition: tcptls.h:124
static void mansession_lock ( struct mansession s)
static

Lock the 'mansession' structure.

Definition at line 2151 of file manager.c.

References ast_mutex_lock, and mansession::lock.

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

2152 {
2153  ast_mutex_lock(&s->lock);
2154 }
#define ast_mutex_lock(a)
Definition: lock.h:155
ast_mutex_t lock
Definition: manager.c:1020
static void mansession_unlock ( struct mansession s)
static

Unlock the 'mansession' structure.

Definition at line 2157 of file manager.c.

References ast_mutex_unlock, and mansession::lock.

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

2158 {
2159  ast_mutex_unlock(&s->lock);
2160 }
ast_mutex_t lock
Definition: manager.c:1020
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int match_filter ( struct mansession s,
char *  eventdata 
)
static

Definition at line 4394 of file manager.c.

References ao2_container_count(), ao2_t_callback_data, ast_debug, blackfilter_cmp_fn(), mansession_session::blackfilters, OBJ_NODATA, mansession::session, whitefilter_cmp_fn(), and mansession_session::whitefilters.

Referenced by action_waitevent(), and process_events().

4395 {
4396  int result = 0;
4397 
4398  ast_debug(3, "Examining event:\n%s\n", eventdata);
4400  return 1; /* no filtering means match all */
4402  /* white filters only: implied black all filter processed first, then white filters */
4403  ao2_t_callback_data(s->session->whitefilters, OBJ_NODATA, whitefilter_cmp_fn, eventdata, &result, "find filter in session filter container");
4405  /* black filters only: implied white all filter processed first, then black filters */
4406  ao2_t_callback_data(s->session->blackfilters, OBJ_NODATA, blackfilter_cmp_fn, eventdata, &result, "find filter in session filter container");
4407  } else {
4408  /* white and black filters: implied black all filter processed first, then white filters, and lastly black filters */
4409  ao2_t_callback_data(s->session->whitefilters, OBJ_NODATA, whitefilter_cmp_fn, eventdata, &result, "find filter in session filter container");
4410  if (result) {
4411  result = 0;
4412  ao2_t_callback_data(s->session->blackfilters, OBJ_NODATA, blackfilter_cmp_fn, eventdata, &result, "find filter in session filter container");
4413  }
4414  }
4415 
4416  return result;
4417 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
Definition: astobj2.c:470
#define ao2_t_callback_data(arg1, arg2, arg3, arg4, arg5, arg6)
ao2_callback_data() is a generic function that applies cb_fn() to all objects in a container...
Definition: astobj2.h:942
struct ao2_container * blackfilters
Definition: manager.c:995
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ao2_container * whitefilters
Definition: manager.c:994
static int blackfilter_cmp_fn(void *obj, void *arg, void *data, int flags)
Definition: manager.c:4379
static int whitefilter_cmp_fn(void *obj, void *arg, void *data, int flags)
Definition: manager.c:4365
struct mansession_session * session
Definition: manager.c:1013
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 4424 of file manager.c.

References advance_event(), ao2_lock, ao2_unlock, mansession_session::authenticated, eventqent::category, mansession_session::f, mansession_session::last_ev, match_filter(), mansession_session::readperm, mansession_session::send_events, send_string(), and mansession::session.

Referenced by do_message(), and process_message().

4425 {
4426  int ret = 0;
4427 
4428  ao2_lock(s->session);
4429  if (s->session->f != NULL) {
4430  struct eventqent *eqe = s->session->last_ev;
4431 
4432  while ((eqe = advance_event(eqe))) {
4433  if (!ret && s->session->authenticated &&
4434  (s->session->readperm & eqe->category) == eqe->category &&
4435  (s->session->send_events & eqe->category) == eqe->category) {
4436  if (match_filter(s, eqe->eventdata)) {
4437  if (send_string(s, eqe->eventdata) < 0)
4438  ret = -1; /* don't send more */
4439  }
4440  }
4441  s->session->last_ev = eqe;
4442  }
4443  }
4444  ao2_unlock(s->session);
4445  return ret;
4446 }
struct eventqent * last_ev
Definition: manager.c:989
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ao2_lock(a)
Definition: astobj2.h:488
static struct eventqent * advance_event(struct eventqent *e)
Definition: manager.c:1793
static int match_filter(struct mansession *s, char *eventdata)
Definition: manager.c:4394
static int send_string(struct mansession *s, char *string)
Definition: manager.c:2029
int category
Definition: manager.c:880
struct mansession_session * session
Definition: manager.c:1013
static int process_message ( struct mansession s,
const struct message m 
)
static

Definition at line 4762 of file manager.c.

References __astman_get_header(), manager_action::action, action_find(), manager_action::active_count, ao2_lock, ao2_t_ref, ao2_unlock, ast_debug, ast_strlen_zero(), astman_get_header(), astman_send_error(), mansession_session::authenticated, manager_action::authority, check_manager_session_inuse(), manager_action::func, GET_HEADER_SKIP_EMPTY, mansession_lock(), mansession_unlock(), process_events(), manager_action::registered, report_req_bad_format(), report_req_not_allowed(), report_session_limit(), mansession::session, user, and mansession_session::writeperm.

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

4763 {
4764  int ret = 0;
4765  struct manager_action *act_found;
4766  const char *user;
4767  const char *action;
4768 
4769  action = __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY);
4770  if (ast_strlen_zero(action)) {
4771  report_req_bad_format(s, "NONE");
4772  mansession_lock(s);
4773  astman_send_error(s, m, "Missing action in request");
4774  mansession_unlock(s);
4775  return 0;
4776  }
4777 
4778  if (!s->session->authenticated
4779  && strcasecmp(action, "Login")
4780  && strcasecmp(action, "Logoff")
4781  && strcasecmp(action, "Challenge")) {
4782  if (!s->session->authenticated) {
4783  report_req_not_allowed(s, action);
4784  }
4785  mansession_lock(s);
4786  astman_send_error(s, m, "Permission denied");
4787  mansession_unlock(s);
4788  return 0;
4789  }
4790 
4791  if (!allowmultiplelogin
4792  && !s->session->authenticated
4793  && (!strcasecmp(action, "Login")
4794  || !strcasecmp(action, "Challenge"))) {
4795  user = astman_get_header(m, "Username");
4796 
4797  if (!ast_strlen_zero(user) && check_manager_session_inuse(user)) {
4799  sleep(1);
4800  mansession_lock(s);
4801  astman_send_error(s, m, "Login Already In Use");
4802  mansession_unlock(s);
4803  return -1;
4804  }
4805  }
4806 
4807  act_found = action_find(action);
4808  if (act_found) {
4809  /* Found the requested AMI action. */
4810  int acted = 0;
4811 
4812  if ((s->session->writeperm & act_found->authority)
4813  || act_found->authority == 0) {
4814  /* We have the authority to execute the action. */
4815  ao2_lock(act_found);
4816  if (act_found->registered && act_found->func) {
4817  ast_debug(1, "Running action '%s'\n", act_found->action);
4818  ++act_found->active_count;
4819  ao2_unlock(act_found);
4820  ret = act_found->func(s, m);
4821  acted = 1;
4822  ao2_lock(act_found);
4823  --act_found->active_count;
4824  }
4825  ao2_unlock(act_found);
4826  }
4827  if (!acted) {
4828  /*
4829  * We did not execute the action because access was denied, it
4830  * was no longer registered, or no action was really registered.
4831  * Complain about it and leave.
4832  */
4833  report_req_not_allowed(s, action);
4834  mansession_lock(s);
4835  astman_send_error(s, m, "Permission denied");
4836  mansession_unlock(s);
4837  }
4838  ao2_t_ref(act_found, -1, "done with found action object");
4839  } else {
4840  char buf[512];
4841 
4842  report_req_bad_format(s, action);
4843  snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
4844  mansession_lock(s);
4845  astman_send_error(s, m, buf);
4846  mansession_unlock(s);
4847  }
4848  if (ret) {
4849  return ret;
4850  }
4851  /* Once done with our message, deliver any pending events unless the
4852  requester doesn't want them as part of this response.
4853  */
4854  if (ast_strlen_zero(astman_get_header(m, "SuppressEvents"))) {
4855  return process_events(s);
4856  } else {
4857  return ret;
4858  }
4859 }
static char user[512]
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:471
static const char * __astman_get_header(const struct message *m, char *var, int mode)
Return a matching header value.
Definition: manager.c:1823
static void mansession_unlock(struct mansession *s)
Unlock the &#39;mansession&#39; structure.
Definition: manager.c:2157
const char * action
Definition: manager.h:140
static void report_req_not_allowed(const struct mansession *s, const char *action)
Definition: manager.c:2298
static void report_session_limit(const struct mansession *s)
Definition: manager.c:2389
static int process_events(struct mansession *s)
Definition: manager.c:4424
#define ao2_unlock(a)
Definition: astobj2.h:497
static struct manager_action * action_find(const char *name)
Definition: manager.c:1075
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static int check_manager_session_inuse(const char *name)
Definition: manager.c:1418
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
unsigned int registered
TRUE if the AMI action is registered and the callback can be called.
Definition: manager.h:162
#define GET_HEADER_SKIP_EMPTY
Definition: manager.c:1808
#define ao2_lock(a)
Definition: astobj2.h:488
unsigned int active_count
Definition: manager.h:164
int(* func)(struct mansession *s, const struct message *m)
Definition: manager.h:151
static void mansession_lock(struct mansession *s)
Lock the &#39;mansession&#39; structure.
Definition: manager.c:2151
struct mansession_session * session
Definition: manager.c:1013
static int allowmultiplelogin
Definition: manager.c:900
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static void report_req_bad_format(const struct mansession *s, const char *action)
Definition: manager.c:2328
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 1141 of file manager.c.

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(), eventqent::tv, and eventqent::usecount.

Referenced by purge_old_stuff().

1142 {
1143  struct eventqent *ev;
1144  struct timeval now = ast_tvnow();
1145 
1147  while ( (ev = AST_RWLIST_FIRST(&all_events)) &&
1148  ev->usecount == 0 && AST_RWLIST_NEXT(ev, eq_next)) {
1150  ast_free(ev);
1151  }
1152 
1154  /* Never release the last event */
1155  if (!AST_RWLIST_NEXT(ev, eq_next)) {
1156  break;
1157  }
1158 
1159  /* 2.5 times whatever the HTTP timeout is (maximum 2.5 hours) is the maximum time that we will definitely cache an event */
1160  if (ev->usecount == 0 && ast_tvdiff_sec(now, ev->tv) > (httptimeout > 3600 ? 3600 : httptimeout) * 2.5) {
1161  AST_RWLIST_REMOVE_CURRENT(eq_next);
1162  ast_free(ev);
1163  }
1164  }
1167 }
struct timeval tv
Definition: manager.c:882
#define AST_RWLIST_NEXT
Definition: linkedlists.h:440
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
int64_t ast_tvdiff_sec(struct timeval end, struct timeval start)
Computes the difference (in seconds) between two struct timeval instances.
Definition: time.h:56
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
static int httptimeout
Definition: manager.c:902
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:565
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:542
int usecount
Definition: manager.c:879
#define ast_free(a)
Definition: astmm.h:97
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:829
#define AST_RWLIST_FIRST
Definition: linkedlists.h:422
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:602
static void purge_sessions ( int  n_max)
static

remove at most n_max stale session from the list.

Definition at line 5181 of file manager.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_unlock, ast_inet_ntoa(), ast_verb, mansession_session::authenticated, mansession_session::inuse, manager_displayconnects(), session_destroy(), mansession_session::sessiontimeout, mansession_session::sin, unref_mansession(), mansession_session::username, and VERBOSITY_ATLEAST.

Referenced by purge_old_stuff().

5182 {
5183  struct mansession_session *session;
5184  time_t now = time(NULL);
5185  struct ao2_iterator i;
5186 
5187  if (!sessions) {
5188  return;
5189  }
5190 
5191  i = ao2_iterator_init(sessions, 0);
5192  while ((session = ao2_iterator_next(&i)) && n_max > 0) {
5193  ao2_lock(session);
5194  if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) {
5195  if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) {
5196  ast_verb(2, "HTTP Manager '%s' timed out from %s\n",
5197  session->username, ast_inet_ntoa(session->sin.sin_addr));
5198  }
5199  ao2_unlock(session);
5200  session_destroy(session);
5201  n_max--;
5202  } else {
5203  ao2_unlock(session);
5204  unref_mansession(session);
5205  }
5206  }
5208 }
char username[80]
Definition: manager.c:980
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define VERBOSITY_ATLEAST(level)
Definition: logger.h:241
struct sockaddr_in sin
Definition: manager.c:970
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
#define ast_verb(level,...)
Definition: logger.h:243
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:1330
time_t sessiontimeout
Definition: manager.c:979
#define ao2_lock(a)
Definition: astobj2.h:488
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
static void session_destroy(struct mansession_session *s)
Definition: manager.c:1411
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:1452
static void report_auth_success ( const struct mansession s)
static

Definition at line 2272 of file manager.c.

References 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, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.

Referenced by authenticate().

2273 {
2274  struct sockaddr_in sin_local;
2275  char session_id[32];
2276  struct ast_security_event_successful_auth successful_auth = {
2279  .common.service = "AMI",
2280  .common.account_id = s->session->username,
2281  .common.session_tv = &s->session->sessionstart_tv,
2282  .common.local_addr = {
2283  .sin = mansession_encode_sin_local(s, &sin_local),
2284  .transport = mansession_get_transport(s),
2285  },
2286  .common.remote_addr = {
2287  .sin = &s->session->sin,
2288  .transport = mansession_get_transport(s),
2289  },
2290  .common.session_id = session_id,
2291  };
2292 
2293  snprintf(session_id, sizeof(session_id), "%p", s->session);
2294 
2295  ast_security_event_report(AST_SEC_EVT(&successful_auth));
2296 }
int ast_security_event_report(const struct ast_security_event_common *sec)
Report a security event.
enum ast_security_event_type event_type
The security event sub-type.
FYI FWIW, Successful authentication has occurred.
char username[80]
Definition: manager.c:980
struct sockaddr_in sin
Definition: manager.c:970
#define AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION
Event descriptor version.
#define AST_SEC_EVT(e)
struct timeval sessionstart_tv
Definition: manager.c:978
static enum ast_security_event_transport_type mansession_get_transport(const struct mansession *s)
Definition: manager.c:2179
struct ast_security_event_common common
Common security event descriptor elements.
struct mansession_session * session
Definition: manager.c:1013
static struct sockaddr_in * mansession_encode_sin_local(const struct mansession *s, struct sockaddr_in *sin_local)
Definition: manager.c:2185
static void report_failed_acl ( const struct mansession s,
const char *  username 
)
static

Definition at line 2220 of file manager.c.

References 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, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, mansession_session::sessionstart_tv, and mansession_session::sin.

Referenced by authenticate().

2221 {
2222  struct sockaddr_in sin_local;
2223  char session_id[32];
2224  struct ast_security_event_failed_acl failed_acl_event = {
2226  .common.version = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
2227  .common.service = "AMI",
2228  .common.account_id = username,
2229  .common.session_tv = &s->session->sessionstart_tv,
2230  .common.local_addr = {
2231  .sin = mansession_encode_sin_local(s, &sin_local),
2232  .transport = mansession_get_transport(s),
2233  },
2234  .common.remote_addr = {
2235  .sin = &s->session->sin,
2236  .transport = mansession_get_transport(s),
2237  },
2238  .common.session_id = session_id,
2239  };
2240 
2241  snprintf(session_id, sizeof(session_id), "%p", s->session);
2242 
2243  ast_security_event_report(AST_SEC_EVT(&failed_acl_event));
2244 }
int ast_security_event_report(const struct ast_security_event_common *sec)
Report a security event.
enum ast_security_event_type event_type
The security event sub-type.
Checking against an IP access control list failed.
struct sockaddr_in sin
Definition: manager.c:970
#define AST_SEC_EVT(e)
#define AST_SECURITY_EVENT_FAILED_ACL_VERSION
Event descriptor version.
struct timeval sessionstart_tv
Definition: manager.c:978
struct ast_security_event_common common
Common security event descriptor elements.
static enum ast_security_event_transport_type mansession_get_transport(const struct mansession *s)
Definition: manager.c:2179
struct mansession_session * session
Definition: manager.c:1013
static struct sockaddr_in * mansession_encode_sin_local(const struct mansession *s, struct sockaddr_in *sin_local)
Definition: manager.c:2185
static void report_failed_challenge_response ( const struct mansession s,
const char *  response,
const char *  expected_response 
)
static

Definition at line 2358 of file manager.c.

References 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, mansession_encode_sin_local(), mansession_get_transport(), ast_security_event_chal_resp_failed::response, mansession::session, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.

Referenced by authenticate().

2360 {
2361  struct sockaddr_in sin_local;
2362  char session_id[32];
2363  struct ast_security_event_chal_resp_failed chal_resp_failed = {
2366  .common.service = "AMI",
2367  .common.account_id = s->session->username,
2368  .common.session_tv = &s->session->sessionstart_tv,
2369  .common.local_addr = {
2370  .sin = mansession_encode_sin_local(s, &sin_local),
2371  .transport = mansession_get_transport(s),
2372  },
2373  .common.remote_addr = {
2374  .sin = &s->session->sin,
2375  .transport = mansession_get_transport(s),
2376  },
2377  .common.session_id = session_id,
2378 
2379  .challenge = s->session->challenge,
2380  .response = response,
2381  .expected_response = expected_response,
2382  };
2383 
2384  snprintf(session_id, sizeof(session_id), "%p", s->session);
2385 
2386  ast_security_event_report(AST_SEC_EVT(&chal_resp_failed));
2387 }
int ast_security_event_report(const struct ast_security_event_common *sec)
Report a security event.
enum ast_security_event_type event_type
The security event sub-type.
char username[80]
Definition: manager.c:980
const char * expected_response
Response expected to be received.
An attempt at challenge/response auth failed.
struct sockaddr_in sin
Definition: manager.c:970
const char * response
Response received.
struct ast_security_event_common common
Common security event descriptor elements.
#define AST_SEC_EVT(e)
struct timeval sessionstart_tv
Definition: manager.c:978
static enum ast_security_event_transport_type mansession_get_transport(const struct mansession *s)
Definition: manager.c:2179
An attempt at challenge/response authentication failed.
char challenge[10]
Definition: manager.c:981
struct mansession_session * session
Definition: manager.c:1013
#define AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION
Event descriptor version.
static struct sockaddr_in * mansession_encode_sin_local(const struct mansession *s, struct sockaddr_in *sin_local)
Definition: manager.c:2185
static void report_inval_password ( const struct mansession s,
const char *  username 
)
static

Definition at line 2246 of file manager.c.

References 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, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, mansession_session::sessionstart_tv, and mansession_session::sin.

Referenced by authenticate().

2247 {
2248  struct sockaddr_in sin_local;
2249  char session_id[32];
2250  struct ast_security_event_inval_password inval_password = {
2253  .common.service = "AMI",
2254  .common.account_id = username,
2255  .common.session_tv = &s->session->sessionstart_tv,
2256  .common.local_addr = {
2257  .sin = mansession_encode_sin_local(s, &sin_local),
2258  .transport = mansession_get_transport(s),
2259  },
2260  .common.remote_addr = {
2261  .sin = &s->session->sin,
2262  .transport = mansession_get_transport(s),
2263  },
2264  .common.session_id = session_id,
2265  };
2266 
2267  snprintf(session_id, sizeof(session_id), "%p", s->session);
2268 
2269  ast_security_event_report(AST_SEC_EVT(&inval_password));
2270 }
int ast_security_event_report(const struct ast_security_event_common *sec)
Report a security event.
An attempt at basic password authentication failed.
enum ast_security_event_type event_type
The security event sub-type.
struct sockaddr_in sin
Definition: manager.c:970
#define AST_SEC_EVT(e)
An attempt at basic password auth failed.
struct ast_security_event_common common
Common security event descriptor elements.
struct timeval sessionstart_tv
Definition: manager.c:978
static enum ast_security_event_transport_type mansession_get_transport(const struct mansession *s)
Definition: manager.c:2179
#define AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION
Event descriptor version.
struct mansession_session * session
Definition: manager.c:1013
static struct sockaddr_in * mansession_encode_sin_local(const struct mansession *s, struct sockaddr_in *sin_local)
Definition: manager.c:2185
static void report_invalid_user ( const struct mansession s,
const char *  username 
)
static

Definition at line 2194 of file manager.c.

References 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, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, mansession_session::sessionstart_tv, and mansession_session::sin.

Referenced by authenticate().

2195 {
2196  struct sockaddr_in sin_local;
2197  char session_id[32];
2198  struct ast_security_event_inval_acct_id inval_acct_id = {
2200  .common.version = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION,
2201  .common.service = "AMI",
2202  .common.account_id = username,
2203  .common.session_tv = &s->session->sessionstart_tv,
2204  .common.local_addr = {
2205  .sin = mansession_encode_sin_local(s, &sin_local),
2206  .transport = mansession_get_transport(s),
2207  },
2208  .common.remote_addr = {
2209  .sin = &s->session->sin,
2210  .transport = mansession_get_transport(s),
2211  },
2212  .common.session_id = session_id,
2213  };
2214 
2215  snprintf(session_id, sizeof(session_id), "%p", s);
2216 
2217  ast_security_event_report(AST_SEC_EVT(&inval_acct_id));
2218 }
int ast_security_event_report(const struct ast_security_event_common *sec)
Report a security event.
enum ast_security_event_type event_type
The security event sub-type.
struct sockaddr_in sin
Definition: manager.c:970
struct ast_security_event_common common
Common security event descriptor elements.
#define AST_SEC_EVT(e)
struct timeval sessionstart_tv
Definition: manager.c:978
#define AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION
Event descriptor version.
static enum ast_security_event_transport_type mansession_get_transport(const struct mansession *s)
Definition: manager.c:2179
Invalid account ID specified (invalid username, for example)
struct mansession_session * session
Definition: manager.c:1013
static struct sockaddr_in * mansession_encode_sin_local(const struct mansession *s, struct sockaddr_in *sin_local)
Definition: manager.c:2185
static void report_req_bad_format ( const struct mansession s,
const char *  action 
)
static

Definition at line 2328 of file manager.c.

References 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, mansession_encode_sin_local(), mansession_get_transport(), ast_security_event_req_bad_format::request_type, mansession::session, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.

Referenced by process_message().

2329 {
2330  struct sockaddr_in sin_local;
2331  char session_id[32];
2332  char request_type[64];
2333  struct ast_security_event_req_bad_format req_bad_format = {
2336  .common.service = "AMI",
2337  .common.account_id = s->session->username,
2338  .common.session_tv = &s->session->sessionstart_tv,
2339  .common.local_addr = {
2340  .sin = mansession_encode_sin_local(s, &sin_local),
2341  .transport = mansession_get_transport(s),
2342  },
2343  .common.remote_addr = {
2344  .sin = &s->session->sin,
2345  .transport = mansession_get_transport(s),
2346  },
2347  .common.session_id = session_id,
2348 
2349  .request_type = request_type,
2350  };
2351 
2352  snprintf(session_id, sizeof(session_id), "%p", s->session);
2353  snprintf(request_type, sizeof(request_type), "Action: %s", action);
2354 
2355  ast_security_event_report(AST_SEC_EVT(&req_bad_format));
2356 }
int ast_security_event_report(const struct ast_security_event_common *sec)
Report a security event.
enum ast_security_event_type event_type
The security event sub-type.
char username[80]
Definition: manager.c:980
struct sockaddr_in sin
Definition: manager.c:970
struct ast_security_event_common common
Common security event descriptor elements.
#define AST_SEC_EVT(e)
const char * request_type
Request type that was made.
Request received with bad formatting.
struct timeval sessionstart_tv
Definition: manager.c:978
static enum ast_security_event_transport_type mansession_get_transport(const struct mansession *s)
Definition: manager.c:2179
#define AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION
Event descriptor version.
struct mansession_session * session
Definition: manager.c:1013
Invalid formatting of request.
static struct sockaddr_in * mansession_encode_sin_local(const struct mansession *s, struct sockaddr_in *sin_local)
Definition: manager.c:2185
static void report_req_not_allowed ( const struct mansession s,
const char *  action 
)
static

Definition at line 2298 of file manager.c.

References 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, mansession_encode_sin_local(), mansession_get_transport(), ast_security_event_req_not_allowed::request_type, mansession::session, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.

Referenced by process_message().

2299 {
2300  struct sockaddr_in sin_local;
2301  char session_id[32];
2302  char request_type[64];
2303  struct ast_security_event_req_not_allowed req_not_allowed = {
2306  .common.service = "AMI",
2307  .common.account_id = s->session->username,
2308  .common.session_tv = &s->session->sessionstart_tv,
2309  .common.local_addr = {
2310  .sin = mansession_encode_sin_local(s, &sin_local),
2311  .transport = mansession_get_transport(s),
2312  },
2313  .common.remote_addr = {
2314  .sin = &s->session->sin,
2315  .transport = mansession_get_transport(s),
2316  },
2317  .common.session_id = session_id,
2318 
2319  .request_type = request_type,
2320  };
2321 
2322  snprintf(session_id, sizeof(session_id), "%p", s->session);
2323  snprintf(request_type, sizeof(request_type), "Action: %s", action);
2324 
2325  ast_security_event_report(AST_SEC_EVT(&req_not_allowed));
2326 }
int ast_security_event_report(const struct ast_security_event_common *sec)
Report a security event.
enum ast_security_event_type event_type
The security event sub-type.
char username[80]
Definition: manager.c:980
struct sockaddr_in sin
Definition: manager.c:970
A request was made that is not allowed.
#define AST_SEC_EVT(e)
struct timeval sessionstart_tv
Definition: manager.c:978
static enum ast_security_event_transport_type mansession_get_transport(const struct mansession *s)
Definition: manager.c:2179
struct ast_security_event_common common
Common security event descriptor elements.
struct mansession_session * session
Definition: manager.c:1013
static struct sockaddr_in * mansession_encode_sin_local(const struct mansession *s, struct sockaddr_in *sin_local)
Definition: manager.c:2185
Request denied because it&#39;s not allowed.
const char * request_type
Request type that was made.
#define AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION
Event descriptor version.
static void report_session_limit ( const struct mansession s)
static

Definition at line 2389 of file manager.c.

References 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, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.

Referenced by process_message().

2390 {
2391  struct sockaddr_in sin_local;
2392  char session_id[32];
2394  .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT,
2395  .common.version = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION,
2396  .common.service = "AMI",
2397  .common.account_id = s->session->username,
2398  .common.session_tv = &s->session->sessionstart_tv,
2399  .common.local_addr = {
2400  .sin = mansession_encode_sin_local(s, &sin_local),
2401  .transport = mansession_get_transport(s),
2402  },
2403  .common.remote_addr = {
2404  .sin = &s->session->sin,
2405  .transport = mansession_get_transport(s),
2406  },
2407  .common.session_id = session_id,
2408  };
2409 
2410  snprintf(session_id, sizeof(session_id), "%p", s->session);
2411 
2412  ast_security_event_report(AST_SEC_EVT(&session_limit));
2413 }
int ast_security_event_report(const struct ast_security_event_common *sec)
Report a security event.
char username[80]
Definition: manager.c:980
struct sockaddr_in sin
Definition: manager.c:970
#define AST_SEC_EVT(e)
Request denied because of a session limit.
struct timeval sessionstart_tv
Definition: manager.c:978
static enum ast_security_event_transport_type mansession_get_transport(const struct mansession *s)
Definition: manager.c:2179
static int session_limit
Definition: http.c:73
struct mansession_session * session
Definition: manager.c:1013
static struct sockaddr_in * mansession_encode_sin_local(const struct mansession *s, struct sockaddr_in *sin_local)
Definition: manager.c:2185
#define AST_SECURITY_EVENT_SESSION_LIMIT_VERSION
Event descriptor version.
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 2029 of file manager.c.

References ast_careful_fwrite(), EVENT_FLAG_HOOKRESPONSE, f, mansession_session::f, mansession::f, mansession_session::fd, mansession::fd, manager_custom_hook::helper, mansession::hook, mansession::session, mansession::write_error, and mansession_session::writetimeout.

Referenced by astman_append(), and process_events().

2030 {
2031  int res;
2032  FILE *f = s->f ? s->f : s->session->f;
2033  int fd = s->f ? s->fd : s->session->fd;
2034 
2035  /* It's a result from one of the hook's action invocation */
2036  if (s->hook) {
2037  /*
2038  * to send responses, we're using the same function
2039  * as for receiving events. We call the event "HookResponse"
2040  */
2041  s->hook->helper(EVENT_FLAG_HOOKRESPONSE, "HookResponse", string);
2042  return 0;
2043  }
2044 
2045  if ((res = ast_careful_fwrite(f, fd, string, strlen(string), s->session->writetimeout))) {
2046  s->write_error = 1;
2047  }
2048 
2049  return res;
2050 }
FILE * f
Definition: manager.c:1015
int ast_careful_fwrite(FILE *f, int fd, const char *s, size_t len, int timeoutms)
Write data to a file stream with a timeout.
Definition: utils.c:1369
int write_error
Definition: manager.c:1018
#define EVENT_FLAG_HOOKRESPONSE
Definition: manager.h:85
static struct ast_format f[]
Definition: format_g726.c:181
manager_hook_t helper
Definition: manager.h:101
struct mansession_session * session
Definition: manager.c:1013
struct manager_custom_hook * hook
Definition: manager.c:1019
static void session_destroy ( struct mansession_session s)
static

Definition at line 1411 of file manager.c.

References ao2_unlink, and unref_mansession().

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

1412 {
1413  ao2_unlink(sessions, s);
1414  unref_mansession(s);
1415 }
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:1330
#define ao2_unlink(arg1, arg2)
Definition: astobj2.h:817
static void session_destructor ( void *  obj)
static

Definition at line 1345 of file manager.c.

References ao2_t_ref, ast_atomic_fetchadd_int(), ast_datastore_free(), AST_LIST_REMOVE_HEAD, mansession_session::blackfilters, mansession_session::datastores, mansession_session::f, mansession_session::last_ev, eventqent::usecount, and mansession_session::whitefilters.

Referenced by build_mansession().

1346 {
1347  struct mansession_session *session = obj;
1348  struct eventqent *eqe = session->last_ev;
1349  struct ast_datastore *datastore;
1350 
1351  /* Get rid of each of the data stores on the session */
1352  while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) {
1353  /* Free the data store */
1354  ast_datastore_free(datastore);
1355  }
1356 
1357  if (session->f != NULL) {
1358  fflush(session->f);
1359  fclose(session->f);
1360  }
1361  if (eqe) {
1362  ast_atomic_fetchadd_int(&eqe->usecount, -1);
1363  }
1364 
1365  if (session->whitefilters) {
1366  ao2_t_ref(session->whitefilters, -1, "decrement ref for white container, should be last one");
1367  }
1368 
1369  if (session->blackfilters) {
1370  ao2_t_ref(session->blackfilters, -1, "decrement ref for black container, should be last one");
1371  }
1372 }
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:471
struct ast_datastore::@163 entry
struct mansession_session::mansession_datastores datastores
struct eventqent * last_ev
Definition: manager.c:989
Structure for a data store object.
Definition: datastore.h:54
struct ao2_container * blackfilters
Definition: manager.c:995
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:65
struct ao2_container * whitefilters
Definition: manager.c:994
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
int usecount
Definition: manager.c:879
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 5073 of file manager.c.

References AMI_VERSION, ao2_lock, ao2_ref, ao2_unlock, ast_atomic_fetchadd_int(), ast_inet_ntoa(), AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_sockaddr_to_sin, ast_tcptls_stream_set_exclusive_input(), ast_tcptls_stream_set_timeout_disable(), ast_tcptls_stream_set_timeout_sequence(), ast_tvnow(), ast_verb, astman_append(), mansession_session::authenticated, mansession_session::authstart, build_mansession(), ast_frame::data, mansession_session::datastores, do_message(), errno, ast_tcptls_session_instance::f, mansession_session::f, mansession::f, ast_tcptls_session_instance::fd, mansession_session::fd, mansession::fd, ast_frame::flags, grab_last(), mansession_session::last_ev, mansession::lock, LOG_ERROR, LOG_WARNING, manager_displayconnects(), ast_tcptls_session_instance::remote_address, mansession::session, session_destroy(), mansession_session::sin, ast_tcptls_session_instance::stream_cookie, mansession::tcptls_session, unauth_sessions, mansession_session::username, and mansession::write_error.

5074 {
5075  struct ast_tcptls_session_instance *ser = data;
5076  struct mansession_session *session;
5077  struct mansession s = {
5078  .tcptls_session = data,
5079  };
5080  int flags;
5081  int res;
5082  struct sockaddr_in ser_remote_address_tmp;
5083  struct protoent *p;
5084 
5086  fclose(ser->f);
5088  goto done;
5089  }
5090 
5091  ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp);
5092  session = build_mansession(ser_remote_address_tmp);
5093 
5094  if (session == NULL) {
5095  fclose(ser->f);
5097  goto done;
5098  }
5099 
5100  /* here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
5101  * This is necessary to prevent delays (caused by buffering) as we
5102  * write to the socket in bits and pieces. */
5103  p = getprotobyname("tcp");
5104  if (p) {
5105  int arg = 1;
5106  if( setsockopt(ser->fd, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
5107  ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\nSome manager actions may be slow to respond.\n", strerror(errno));
5108  }
5109  } else {
5110  ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY, getprotobyname(\"tcp\") failed\nSome manager actions may be slow to respond.\n");
5111  }
5112 
5113  /* make sure socket is non-blocking */
5114  flags = fcntl(ser->fd, F_GETFL);
5115  flags |= O_NONBLOCK;
5116  fcntl(ser->fd, F_SETFL, flags);
5117 
5118  ao2_lock(session);
5119  /* Hook to the tail of the event queue */
5120  session->last_ev = grab_last();
5121 
5122  ast_mutex_init(&s.lock);
5123 
5124  /* these fields duplicate those in the 'ser' structure */
5125  session->fd = s.fd = ser->fd;
5126  session->f = s.f = ser->f;
5127  session->sin = ser_remote_address_tmp;
5128  s.session = session;
5129 
5131 
5132  if(time(&session->authstart) == -1) {
5133  ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
5135  ao2_unlock(session);
5136  session_destroy(session);
5137  goto done;
5138  }
5139  ao2_unlock(session);
5140 
5141  /*
5142  * We cannot let the stream exclusively wait for data to arrive.
5143  * We have to wake up the task to send async events.
5144  */
5146 
5148  ast_tvnow(), authtimeout * 1000);
5149 
5150  astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */
5151  for (;;) {
5152  if ((res = do_message(&s)) < 0 || s.write_error) {
5153  break;
5154  }
5155  if (session->authenticated) {
5157  }
5158  }
5159  /* session is over, explain why and terminate */
5160  if (session->authenticated) {
5161  if (manager_displayconnects(session)) {
5162  ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
5163  }
5164  } else {
5166  if (displayconnects) {
5167  ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr));
5168  }
5169  }
5170 
5171  session_destroy(session);
5172 
5173  ast_mutex_destroy(&s.lock);
5174 done:
5175  ao2_ref(ser, -1);
5176  ser = NULL;
5177  return NULL;
5178 }
FILE * f
Definition: manager.c:1015
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
char username[80]
Definition: manager.c:980
static int displayconnects
Definition: manager.c:899
struct mansession_session::mansession_datastores datastores
#define LOG_WARNING
Definition: logger.h:144
time_t authstart
Definition: manager.c:991
struct eventqent * last_ev
Definition: manager.c:989
struct sockaddr_in sin
Definition: manager.c:970
static int authtimeout
Definition: manager.c:907
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
#define ao2_unlock(a)
Definition: astobj2.h:497
ast_mutex_t lock
Definition: manager.c:1020
static int unauth_sessions
Definition: manager.c:914
#define ast_verb(level,...)
Definition: logger.h:243
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
static int authlimit
Definition: manager.c:908
void ast_tcptls_stream_set_exclusive_input(struct ast_tcptls_stream *stream, int exclusive_input)
Set the TCP/TLS stream I/O if it can exclusively depend upon the set timeouts.
Definition: tcptls.c:107
struct ast_tcptls_stream * stream_cookie
Definition: tcptls.h:218
#define AMI_VERSION
Definition: manager.h:57
struct ast_tcptls_session_instance * tcptls_session
Definition: manager.c:1014
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int write_error
Definition: manager.c:1018
int errno
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:666
static int do_message(struct mansession *s)
Definition: manager.c:4985
static struct eventqent * grab_last(void)
Definition: manager.c:1121
static void session_destroy(struct mansession_session *s)
Definition: manager.c:1411
struct mansession_session * session
Definition: manager.c:1013
void ast_tcptls_stream_set_timeout_sequence(struct ast_tcptls_stream *stream, struct timeval start, int timeout)
Set the TCP/TLS stream I/O sequence timeout timer.
Definition: tcptls.c:99
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
static struct mansession_session * build_mansession(struct sockaddr_in sin)
Allocate manager session structure and add it to the list of sessions.
Definition: manager.c:1375
#define ast_mutex_init(pmutex)
Definition: lock.h:152
#define ast_mutex_destroy(a)
Definition: lock.h:154
void ast_tcptls_stream_set_timeout_disable(struct ast_tcptls_stream *stream)
Disable the TCP/TLS stream timeout timer.
Definition: tcptls.c:84
static int manager_displayconnects(struct mansession_session *session)
Get displayconnects config option.
Definition: manager.c:1452
struct ast_sockaddr remote_address
Definition: tcptls.h:207
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 2166 of file manager.c.

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

Referenced by action_events(), and authenticate().

2167 {
2168  int maskint = strings_to_mask(eventmask);
2169 
2170  ao2_lock(s->session);
2171  if (maskint >= 0) {
2172  s->session->send_events = maskint;
2173  }
2174  ao2_unlock(s->session);
2175 
2176  return maskint;
2177 }
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ao2_lock(a)
Definition: astobj2.h:488
static int strings_to_mask(const char *string)
Definition: manager.c:1299
struct mansession_session * session
Definition: manager.c:1013
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 1299 of file manager.c.

References ARRAY_LEN, ast_false(), ast_strlen_zero(), ast_true(), get_perm(), permalias::num, and perms.

Referenced by set_eventmask().

1300 {
1301  const char *p;
1302 
1303  if (ast_strlen_zero(string)) {
1304  return -1;
1305  }
1306 
1307  for (p = string; *p; p++) {
1308  if (*p < '0' || *p > '9') {
1309  break;
1310  }
1311  }
1312  if (!*p) { /* all digits */
1313  return atoi(string);
1314  }
1315  if (ast_false(string)) {
1316  return 0;
1317  }
1318  if (ast_true(string)) { /* all permissions */
1319  int x, ret = 0;
1320  for (x = 0; x < ARRAY_LEN(perms); x++) {
1321  ret |= perms[x].num;
1322  }
1323  return ret;
1324  }
1325  return get_perm(string);
1326 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct permalias perms[]
int num
Definition: manager.c:1174
static int get_perm(const char *instr)
Definition: manager.c:1278
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is &quot;false&quot;...
Definition: utils.c:1550
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 1330 of file manager.c.

References ao2_ref, ast_log(), and LOG_DEBUG.

Referenced by __ast_manager_event_multichan(), astman_is_authed(), astman_verify_session_readpermissions(), astman_verify_session_writepermissions(), check_manager_session_inuse(), find_session(), find_session_by_nonce(), handle_showmanconn(), purge_sessions(), and session_destroy().

1331 {
1332  int refcount = ao2_ref(s, -1);
1333  if (manager_debug) {
1334  ast_log(LOG_DEBUG, "Mansession: %p refcount now %d\n", s, refcount - 1);
1335  }
1336  return s;
1337 }
#define LOG_DEBUG
Definition: logger.h:122
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static int manager_debug
Definition: manager.c:906
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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 1213 of file manager.c.

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

Referenced by handle_showmanager().

1214 {
1215  int i;
1216  char *sep = "";
1217 
1218  ast_str_reset(*res);
1219  for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
1220  if ((authority & perms[i].num) == perms[i].num) {
1221  ast_str_append(res, 0, "%s%s", sep, perms[i].label);
1222  sep = ",";
1223  }
1224  }
1225 
1226  if (ast_str_strlen(*res) == 0) /* replace empty string with something sensible */
1227  ast_str_append(res, 0, "<none>");
1228 
1229  return ast_str_buffer(*res);
1230 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct permalias perms[]
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
int num
Definition: manager.c:1174
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:900
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:436
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:471
static int whitefilter_cmp_fn ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 4365 of file manager.c.

References CMP_MATCH, CMP_STOP, and ast_frame::data.

Referenced by match_filter().

4366 {
4367  regex_t *regex_filter = obj;
4368  const char *eventdata = arg;
4369  int *result = data;
4370 
4371  if (!regexec(regex_filter, eventdata, 0, NULL, 0)) {
4372  *result = 1;
4373  return (CMP_MATCH | CMP_STOP);
4374  }
4375 
4376  return 0;
4377 }

Variable Documentation

struct actions actions = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
struct all_events all_events = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
int allowmultiplelogin = 1
static

Definition at line 900 of file manager.c.

struct ast_threadstorage astman_append_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_astman_append_buf , .custom_init = NULL , }
static

Definition at line 2059 of file manager.c.

Referenced by astman_append().

int authlimit
static

Definition at line 908 of file manager.c.

int authtimeout
static

Definition at line 907 of file manager.c.

int broken_events_action
static

Definition at line 903 of file manager.c.

struct channelvars channelvars = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
struct { ... } command_blacklist[]
Initial value:
= {
{{ "module", "load", NULL }},
{{ "module", "unload", NULL }},
{{ "restart", "gracefully", NULL }},
}

Referenced by check_blacklist().

const int DEFAULT_AUTHLIMIT = 50
static

Default setting for authlimit

Definition at line 896 of file manager.c.

Referenced by manager_set_defaults(), and reload_config().

const int DEFAULT_AUTHTIMEOUT = 30
static

Default setting for authtimeout

Definition at line 895 of file manager.c.

Referenced by manager_set_defaults(), and reload_config().

const int DEFAULT_BROKENEVENTSACTION = 0
static

Default setting for brokeneventsaction

Definition at line 894 of file manager.c.

Referenced by manager_set_defaults().

const int DEFAULT_DISPLAYCONNECTS = 1
static

Default setting for displaying manager connections

Definition at line 891 of file manager.c.

Referenced by manager_set_defaults().

const int DEFAULT_ENABLED = 0
static

Default setting for manager to be enabled

Definition at line 889 of file manager.c.

Referenced by manager_set_defaults().

const int DEFAULT_HTTPTIMEOUT = 60
static

Default manager http timeout

Definition at line 893 of file manager.c.

Referenced by __init_manager(), and manager_set_defaults().

const int DEFAULT_MANAGERDEBUG = 0
static

Default setting for manager debug

Definition at line 897 of file manager.c.

Referenced by manager_set_defaults().

const int DEFAULT_TIMESTAMPEVENTS = 0
static

Default setting for timestampevents

Definition at line 892 of file manager.c.

Referenced by manager_set_defaults().

const int DEFAULT_WEBENABLED = 0
static

Default setting for the web interface to be enabled

Definition at line 890 of file manager.c.

Referenced by manager_set_defaults().

int displayconnects
static

Definition at line 899 of file manager.c.

Referenced by __init_manager().

char global_realm[MAXHOSTNAMELEN]
static

Default realm

Definition at line 912 of file manager.c.

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

int httptimeout
static

Definition at line 902 of file manager.c.

char* manager_channelvars
static

Definition at line 909 of file manager.c.

int manager_debug = 0
static

enable some debugging code in the manager

Definition at line 906 of file manager.c.

int manager_enabled = 0
static

Definition at line 904 of file manager.c.

Referenced by check_manager_enabled().

struct ast_threadstorage manager_event_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_buf , .custom_init = NULL , }
static

Definition at line 5265 of file manager.c.

Referenced by __ast_manager_event_multichan().

struct ast_threadstorage manager_event_funcbuf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_funcbuf , .custom_init = NULL , }
static

Definition at line 5238 of file manager.c.

Referenced by append_channel_vars().

struct manager_hooks manager_hooks = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
struct ao2_container* sessions = NULL
static

Definition at line 1023 of file manager.c.

int timestampevents
static

Definition at line 901 of file manager.c.

int unauth_sessions = 0
static

Definition at line 914 of file manager.c.

Referenced by action_login(), and session_do().

struct ast_threadstorage userevent_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_userevent_buf , .custom_init = NULL , }
static

Definition at line 2060 of file manager.c.

Referenced by action_userevent().

struct users users = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
int webmanager_enabled = 0
static

Definition at line 905 of file manager.c.

const char* words[AST_MAX_CMD_LEN]

Definition at line 929 of file manager.c.