Mon Oct 8 12:39:30 2012

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

Defines

#define ASTMAN_APPEND_BUF_INITSIZE   256
 initial allocated size for the astman_append_buf
#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.
#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.

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
}

Functions

int __ast_manager_event_multichan (int category, const char *event, int chancount, struct ast_channel **chans, const char *file, int line, const char *func, const char *fmt,...)
static const char * __astman_get_header (const struct message *m, char *var, int mode)
 Return a matching header value.
static void __init_astman_append_buf (void)
 thread local buffer for astman_append
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.
static int action_coresettings (struct mansession *s, const struct message *m)
 Show PBX core settings information.
static int action_coreshowchannels (struct mansession *s, const struct message *m)
 Manager command "CoreShowChannels" - List currently defined channels and some information about them.
static int action_corestatus (struct mansession *s, const struct message *m)
 Show PBX core status information.
static int action_createconfig (struct mansession *s, const struct message *m)
static void action_destroy (void *obj)
static int action_events (struct mansession *s, const struct message *m)
static int action_extensionstate (struct mansession *s, const struct message *m)
static 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
static int action_reload (struct mansession *s, const struct message *m)
 Send a reload event.
static int action_sendtext (struct mansession *s, const struct message *m)
static int action_setvar (struct mansession *s, const struct message *m)
static int action_status (struct mansession *s, const struct message *m)
 Manager "status" command to show channels.
static int action_timeout (struct mansession *s, const struct message *m)
static int action_updateconfig (struct mansession *s, const struct message *m)
static int action_userevent (struct mansession *s, const struct message *m)
static int action_waitevent (struct mansession *s, const struct message *m)
static struct eventqentadvance_event (struct eventqent *e)
static 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.
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 manager command with the manager interface.
void ast_manager_register_hook (struct manager_custom_hook *hook)
 Add a custom hook to be called when an event is fired.
static int ast_manager_register_struct (struct manager_action *act)
int ast_manager_unregister (char *action)
 Unregister a registered manager command.
void ast_manager_unregister_hook (struct manager_custom_hook *hook)
 Delete a custom hook to be called when an event is fired.
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)
 Get header from mananger transaction.
ast_variableastman_get_variables (const struct message *m)
 Get a linked list of the Variable: headers.
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
 Send ack in manager transaction.
void astman_send_error (struct mansession *s, const struct message *m, char *error)
 Send error in manager transaction.
void astman_send_listack (struct mansession *s, const struct message *m, char *msg, char *listflag)
 Send ack in manager list transaction.
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
 Send response in manager transaction.
static void astman_send_response_full (struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
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.
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.
static int check_blacklist (const char *cmd)
int check_manager_enabled (void)
 Check if AMI is enabled.
static int check_manager_session_inuse (const char *name)
int check_webmanager_enabled (void)
 Check if AMI/HTTP is enabled.
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.
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.
static char * handle_mandebug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showmanager (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showmanagers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showmancmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showmancmds (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list commands.
static char * handle_showmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list connected.
static char * handle_showmaneventq (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list eventq.
static enum error_type handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn)
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.
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.
static void mansession_unlock (struct mansession *s)
 Unlock the 'mansession' structure.
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.
static void report_auth_success (const struct mansession *s)
static void report_failed_acl (const struct mansession *s, const char *username)
static void report_failed_challenge_response (const struct mansession *s, const char *response, const char *expected_response)
static void report_inval_password (const struct mansession *s, const char *username)
static void report_invalid_user (const struct mansession *s, const char *username)
static void report_req_bad_format (const struct mansession *s, const char *action)
static void report_req_not_allowed (const struct mansession *s, const char *action)
static void report_session_limit (const struct mansession *s)
static int send_string (struct mansession *s, char *string)
static void session_destroy (struct mansession_session *s)
static void session_destructor (void *obj)
static void * session_do (void *data)
 The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ).
static int set_eventmask (struct mansession *s, const char *eventmask)
 Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm.
static int strings_to_mask (const char *string)
static struct mansession_sessionunref_mansession (struct mansession_session *s)
 Unreference manager session object. If no more references, then go ahead and delete it.
static int whitefilter_cmp_fn (void *obj, void *arg, void *data, int flags)

Variables

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 block_sockets
static int broken_events_action
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_BLOCKSOCKETS = 0
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 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 int webmanager_enabled = 0

Detailed Description

callback to display queues status in manager


Define Documentation

#define ASTMAN_APPEND_BUF_INITSIZE   256

initial allocated size for the astman_append_buf

Definition at line 2006 of file manager.c.

Referenced by astman_append().

#define DEFAULT_REALM   "asterisk"

Definition at line 902 of file manager.c.

Referenced by __init_manager(), and reload_config().

#define GET_HEADER_FIRST_MATCH   0

Definition at line 1763 of file manager.c.

Referenced by astman_get_header().

#define GET_HEADER_LAST_MATCH   1

Definition at line 1764 of file manager.c.

Referenced by __astman_get_header().

#define GET_HEADER_SKIP_EMPTY   2

Definition at line 1765 of file manager.c.

Referenced by __astman_get_header(), and process_message().

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 5111 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 919 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.

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

Definition at line 2047 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 834 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:
category Event category, matches manager authorization
event Event name
chancount Number of channels in chans parameter
chans A pointer to an array of channels involved in the event
contents Format string describing event
Since:
1.8

Definition at line 5113 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(), manager_custom_hook::helper, manager_debug, manager_event_buf, MANAGER_EVENT_BUF_INITSIZE, seq, timestampevents, and unref_mansession().

05115 {
05116    struct mansession_session *session;
05117    struct manager_custom_hook *hook;
05118    struct ast_str *auth = ast_str_alloca(80);
05119    const char *cat_str;
05120    va_list ap;
05121    struct timeval now;
05122    struct ast_str *buf;
05123    int i;
05124 
05125    if (!(sessions && ao2_container_count(sessions)) && AST_RWLIST_EMPTY(&manager_hooks)) {
05126       return 0;
05127    }
05128    
05129    if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) {
05130       return -1;
05131    }
05132 
05133    cat_str = authority_to_str(category, &auth);
05134    ast_str_set(&buf, 0,
05135          "Event: %s\r\nPrivilege: %s\r\n",
05136           event, cat_str);
05137 
05138    if (timestampevents) {
05139       now = ast_tvnow();
05140       ast_str_append(&buf, 0,
05141             "Timestamp: %ld.%06lu\r\n",
05142              (long)now.tv_sec, (unsigned long) now.tv_usec);
05143    }
05144    if (manager_debug) {
05145       static int seq;
05146       ast_str_append(&buf, 0,
05147             "SequenceNumber: %d\r\n",
05148              ast_atomic_fetchadd_int(&seq, 1));
05149       ast_str_append(&buf, 0,
05150             "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func);
05151    }
05152 
05153    va_start(ap, fmt);
05154    ast_str_append_va(&buf, 0, fmt, ap);
05155    va_end(ap);
05156    for (i = 0; i < chancount; i++) {
05157       append_channel_vars(&buf, chans[i]);
05158    }
05159 
05160    ast_str_append(&buf, 0, "\r\n");
05161 
05162    append_event(ast_str_buffer(buf), category);
05163 
05164    /* Wake up any sleeping sessions */
05165    if (sessions) {
05166       struct ao2_iterator i;
05167       i = ao2_iterator_init(sessions, 0);
05168       while ((session = ao2_iterator_next(&i))) {
05169          ao2_lock(session);
05170          if (session->waiting_thread != AST_PTHREADT_NULL) {
05171             pthread_kill(session->waiting_thread, SIGURG);
05172          } else {
05173             /* We have an event to process, but the mansession is
05174              * not waiting for it. We still need to indicate that there
05175              * is an event waiting so that get_input processes the pending
05176              * event instead of polling.
05177              */
05178             session->pending_event = 1;
05179          }
05180          ao2_unlock(session);
05181          unref_mansession(session);
05182       }
05183       ao2_iterator_destroy(&i);
05184    }
05185 
05186    if (!AST_RWLIST_EMPTY(&manager_hooks)) {
05187       AST_RWLIST_RDLOCK(&manager_hooks);
05188       AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
05189          hook->helper(category, event, ast_str_buffer(buf));
05190       }
05191       AST_RWLIST_UNLOCK(&manager_hooks);
05192    }
05193 
05194    return 0;
05195 }

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

01781 {
01782    int x, l = strlen(var);
01783    const char *result = "";
01784 
01785    for (x = 0; x < m->hdrcount; x++) {
01786       const char *h = m->headers[x];
01787       if (!strncasecmp(var, h, l) && h[l] == ':') {
01788          const char *value = h + l + 1;
01789          value = ast_skip_blanks(value); /* ignore leading spaces in the value */
01790          /* found a potential candidate */
01791          if ((mode & GET_HEADER_SKIP_EMPTY) && ast_strlen_zero(value)) {
01792             continue;   /* not interesting */
01793          }
01794          if (mode & GET_HEADER_LAST_MATCH) {
01795             result = value;   /* record the last match so far */
01796          } else {
01797             return value;
01798          }
01799       }
01800    }
01801 
01802    return result;
01803 }

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

02012 {

static void __init_manager_event_buf ( void   )  [static]

Definition at line 5110 of file manager.c.

05115 {

static void __init_manager_event_funcbuf ( void   )  [static]

Definition at line 5083 of file manager.c.

05086 {

static void __init_userevent_buf ( void   )  [static]

Definition at line 2003 of file manager.c.

02012 {

static int action_aocmessage ( struct mansession s,
const struct message m 
) [static]

Definition at line 3803 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().

03804 {
03805    const char *channel = astman_get_header(m, "Channel");
03806    const char *pchannel = astman_get_header(m, "ChannelPrefix");
03807    const char *msgtype = astman_get_header(m, "MsgType");
03808    const char *chargetype = astman_get_header(m, "ChargeType");
03809    const char *currencyname = astman_get_header(m, "CurrencyName");
03810    const char *currencyamount = astman_get_header(m, "CurrencyAmount");
03811    const char *mult = astman_get_header(m, "CurrencyMultiplier");
03812    const char *totaltype = astman_get_header(m, "TotalType");
03813    const char *aocbillingid = astman_get_header(m, "AOCBillingId");
03814    const char *association_id= astman_get_header(m, "ChargingAssociationId");
03815    const char *association_num = astman_get_header(m, "ChargingAssociationNumber");
03816    const char *association_plan = astman_get_header(m, "ChargingAssociationPlan");
03817 
03818    enum ast_aoc_type _msgtype;
03819    enum ast_aoc_charge_type _chargetype;
03820    enum ast_aoc_currency_multiplier _mult = AST_AOC_MULT_ONE;
03821    enum ast_aoc_total_type _totaltype = AST_AOC_TOTAL;
03822    enum ast_aoc_billing_id _billingid = AST_AOC_BILLING_NA;
03823    unsigned int _currencyamount = 0;
03824    int _association_id = 0;
03825    unsigned int _association_plan = 0;
03826    struct ast_channel *chan = NULL;
03827 
03828    struct ast_aoc_decoded *decoded = NULL;
03829    struct ast_aoc_encoded *encoded = NULL;
03830    size_t encoded_size = 0;
03831 
03832    if (ast_strlen_zero(channel) && ast_strlen_zero(pchannel)) {
03833       astman_send_error(s, m, "Channel and PartialChannel are not specified. Specify at least one of these.");
03834       goto aocmessage_cleanup;
03835    }
03836 
03837    if (!(chan = ast_channel_get_by_name(channel)) && !ast_strlen_zero(pchannel)) {
03838       chan = ast_channel_get_by_name_prefix(pchannel, strlen(pchannel));
03839    }
03840 
03841    if (!chan) {
03842       astman_send_error(s, m, "No such channel");
03843       goto aocmessage_cleanup;
03844    }
03845 
03846    if (ast_strlen_zero(msgtype) || (strcasecmp(msgtype, "d") && strcasecmp(msgtype, "e"))) {
03847       astman_send_error(s, m, "Invalid MsgType");
03848       goto aocmessage_cleanup;
03849    }
03850 
03851    if (ast_strlen_zero(chargetype)) {
03852       astman_send_error(s, m, "ChargeType not specified");
03853       goto aocmessage_cleanup;
03854    }
03855 
03856    _msgtype = strcasecmp(msgtype, "d") ? AST_AOC_E : AST_AOC_D;
03857 
03858    if (!strcasecmp(chargetype, "NA")) {
03859       _chargetype = AST_AOC_CHARGE_NA;
03860    } else if (!strcasecmp(chargetype, "Free")) {
03861       _chargetype = AST_AOC_CHARGE_FREE;
03862    } else if (!strcasecmp(chargetype, "Currency")) {
03863       _chargetype = AST_AOC_CHARGE_CURRENCY;
03864    } else if (!strcasecmp(chargetype, "Unit")) {
03865       _chargetype = AST_AOC_CHARGE_UNIT;
03866    } else {
03867       astman_send_error(s, m, "Invalid ChargeType");
03868       goto aocmessage_cleanup;
03869    }
03870 
03871    if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
03872 
03873       if (ast_strlen_zero(currencyamount) || (sscanf(currencyamount, "%30u", &_currencyamount) != 1)) {
03874          astman_send_error(s, m, "Invalid CurrencyAmount, CurrencyAmount is a required when ChargeType is Currency");
03875          goto aocmessage_cleanup;
03876       }
03877 
03878       if (ast_strlen_zero(mult)) {
03879          astman_send_error(s, m, "ChargeMultiplier unspecified, ChargeMultiplier is required when ChargeType is Currency.");
03880          goto aocmessage_cleanup;
03881       } else if (!strcasecmp(mult, "onethousandth")) {
03882          _mult = AST_AOC_MULT_ONETHOUSANDTH;
03883       } else if (!strcasecmp(mult, "onehundredth")) {
03884          _mult = AST_AOC_MULT_ONEHUNDREDTH;
03885       } else if (!strcasecmp(mult, "onetenth")) {
03886          _mult = AST_AOC_MULT_ONETENTH;
03887       } else if (!strcasecmp(mult, "one")) {
03888          _mult = AST_AOC_MULT_ONE;
03889       } else if (!strcasecmp(mult, "ten")) {
03890          _mult = AST_AOC_MULT_TEN;
03891       } else if (!strcasecmp(mult, "hundred")) {
03892          _mult = AST_AOC_MULT_HUNDRED;
03893       } else if (!strcasecmp(mult, "thousand")) {
03894          _mult = AST_AOC_MULT_THOUSAND;
03895       } else {
03896          astman_send_error(s, m, "Invalid ChargeMultiplier");
03897          goto aocmessage_cleanup;
03898       }
03899    }
03900 
03901    /* create decoded object and start setting values */
03902    if (!(decoded = ast_aoc_create(_msgtype, _chargetype, 0))) {
03903          astman_send_error(s, m, "Message Creation Failed");
03904          goto aocmessage_cleanup;
03905    }
03906 
03907    if (_msgtype == AST_AOC_D) {
03908       if (!ast_strlen_zero(totaltype) && !strcasecmp(totaltype, "subtotal")) {
03909          _totaltype = AST_AOC_SUBTOTAL;
03910       }
03911 
03912       if (ast_strlen_zero(aocbillingid)) {
03913          /* ignore this is optional */
03914       } else if (!strcasecmp(aocbillingid, "Normal")) {
03915          _billingid = AST_AOC_BILLING_NORMAL;
03916       } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
03917          _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
03918       } else if (!strcasecmp(aocbillingid, "CreditCard")) {
03919          _billingid = AST_AOC_BILLING_CREDIT_CARD;
03920       } else {
03921          astman_send_error(s, m, "Invalid AOC-D AOCBillingId");
03922          goto aocmessage_cleanup;
03923       }
03924    } else {
03925       if (ast_strlen_zero(aocbillingid)) {
03926          /* ignore this is optional */
03927       } else if (!strcasecmp(aocbillingid, "Normal")) {
03928          _billingid = AST_AOC_BILLING_NORMAL;
03929       } else if (!strcasecmp(aocbillingid, "ReverseCharge")) {
03930          _billingid = AST_AOC_BILLING_REVERSE_CHARGE;
03931       } else if (!strcasecmp(aocbillingid, "CreditCard")) {
03932          _billingid = AST_AOC_BILLING_CREDIT_CARD;
03933       } else if (!strcasecmp(aocbillingid, "CallFwdUnconditional")) {
03934          _billingid = AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL;
03935       } else if (!strcasecmp(aocbillingid, "CallFwdBusy")) {
03936          _billingid = AST_AOC_BILLING_CALL_FWD_BUSY;
03937       } else if (!strcasecmp(aocbillingid, "CallFwdNoReply")) {
03938          _billingid = AST_AOC_BILLING_CALL_FWD_NO_REPLY;
03939       } else if (!strcasecmp(aocbillingid, "CallDeflection")) {
03940          _billingid = AST_AOC_BILLING_CALL_DEFLECTION;
03941       } else if (!strcasecmp(aocbillingid, "CallTransfer")) {
03942          _billingid = AST_AOC_BILLING_CALL_TRANSFER;
03943       } else {
03944          astman_send_error(s, m, "Invalid AOC-E AOCBillingId");
03945          goto aocmessage_cleanup;
03946       }
03947 
03948       if (!ast_strlen_zero(association_id) && (sscanf(association_id, "%30d", &_association_id) != 1)) {
03949          astman_send_error(s, m, "Invalid ChargingAssociationId");
03950          goto aocmessage_cleanup;
03951       }
03952       if (!ast_strlen_zero(association_plan) && (sscanf(association_plan, "%30u", &_association_plan) != 1)) {
03953          astman_send_error(s, m, "Invalid ChargingAssociationPlan");
03954          goto aocmessage_cleanup;
03955       }
03956 
03957       if (_association_id) {
03958          ast_aoc_set_association_id(decoded, _association_id);
03959       } else if (!ast_strlen_zero(association_num)) {
03960          ast_aoc_set_association_number(decoded, association_num, _association_plan);
03961       }
03962    }
03963 
03964    if (_chargetype == AST_AOC_CHARGE_CURRENCY) {
03965       ast_aoc_set_currency_info(decoded, _currencyamount, _mult, ast_strlen_zero(currencyname) ? NULL : currencyname);
03966    } else if (_chargetype == AST_AOC_CHARGE_UNIT) {
03967       struct ast_aoc_unit_entry entry;
03968       int i;
03969 
03970       /* multiple unit entries are possible, lets get them all */
03971       for (i = 0; i < 32; i++) {
03972          if (aocmessage_get_unit_entry(m, &entry, i)) {
03973             break; /* that's the end then */
03974          }
03975 
03976          ast_aoc_add_unit_entry(decoded, entry.valid_amount, entry.amount, entry.valid_type, entry.type);
03977       }
03978 
03979       /* at least one unit entry is required */
03980       if (!i) {
03981          astman_send_error(s, m, "Invalid UnitAmount(0), At least one valid unit entry is required when ChargeType is set to Unit");
03982          goto aocmessage_cleanup;
03983       }
03984 
03985    }
03986 
03987    ast_aoc_set_billing_id(decoded, _billingid);
03988    ast_aoc_set_total_type(decoded, _totaltype);
03989 
03990 
03991    if ((encoded = ast_aoc_encode(decoded, &encoded_size, NULL)) && !ast_indicate_data(chan, AST_CONTROL_AOC, encoded, encoded_size)) {
03992       astman_send_ack(s, m, "AOC Message successfully queued on channel");
03993    } else {
03994       astman_send_error(s, m, "Error encoding AOC message, could not queue onto channel");
03995    }
03996 
03997 aocmessage_cleanup:
03998 
03999    ast_aoc_destroy_decoded(decoded);
04000    ast_aoc_destroy_encoded(encoded);
04001 
04002    if (chan) {
04003       chan = ast_channel_unref(chan);
04004    }
04005    return 0;
04006 }

static int action_atxfer ( struct mansession s,
const struct message m 
) [static]

Definition at line 3531 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, f, ast_frame_subclass::integer, name, pbx_builtin_setvar_helper(), and ast_frame::subclass.

Referenced by __init_manager().

03532 {
03533    const char *name = astman_get_header(m, "Channel");
03534    const char *exten = astman_get_header(m, "Exten");
03535    const char *context = astman_get_header(m, "Context");
03536    struct ast_channel *chan = NULL;
03537    struct ast_call_feature *atxfer_feature = NULL;
03538    char *feature_code = NULL;
03539 
03540    if (ast_strlen_zero(name)) {
03541       astman_send_error(s, m, "No channel specified");
03542       return 0;
03543    }
03544    if (ast_strlen_zero(exten)) {
03545       astman_send_error(s, m, "No extension specified");
03546       return 0;
03547    }
03548 
03549    if (!(atxfer_feature = ast_find_call_feature("atxfer"))) {
03550       astman_send_error(s, m, "No attended transfer feature found");
03551       return 0;
03552    }
03553 
03554    if (!(chan = ast_channel_get_by_name(name))) {
03555       astman_send_error(s, m, "Channel specified does not exist");
03556       return 0;
03557    }
03558 
03559    if (!ast_strlen_zero(context)) {
03560       pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context);
03561    }
03562 
03563    for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) {
03564       struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *feature_code };
03565       ast_queue_frame(chan, &f);
03566    }
03567 
03568    for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) {
03569       struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = *feature_code };
03570       ast_queue_frame(chan, &f);
03571    }
03572 
03573    chan = ast_channel_unref(chan);
03574 
03575    astman_send_ack(s, m, "Atxfer successfully queued");
03576 
03577    return 0;
03578 }

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

Definition at line 3086 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().

03087 {
03088    const char *authtype = astman_get_header(m, "AuthType");
03089 
03090    if (!strcasecmp(authtype, "MD5")) {
03091       if (ast_strlen_zero(s->session->challenge)) {
03092          snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
03093       }
03094       mansession_lock(s);
03095       astman_start_ack(s, m);
03096       astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
03097       mansession_unlock(s);
03098    } else {
03099       astman_send_error(s, m, "Must specify AuthType");
03100    }
03101    return 0;
03102 }

static int action_command ( struct mansession s,
const struct message m 
) [static]

Manager command "command" - execute CLI command.

Definition at line 3616 of file manager.c.

References ast_cli_command, 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().

03617 {
03618    const char *cmd = astman_get_header(m, "Command");
03619    const char *id = astman_get_header(m, "ActionID");
03620    char *buf = NULL, *final_buf = NULL;
03621    char template[] = "/tmp/ast-ami-XXXXXX";  /* template for temporary file */
03622    int fd;
03623    off_t l;
03624 
03625    if (ast_strlen_zero(cmd)) {
03626       astman_send_error(s, m, "No command provided");
03627       return 0;
03628    }
03629 
03630    if (check_blacklist(cmd)) {
03631       astman_send_error(s, m, "Command blacklisted");
03632       return 0;
03633    }
03634 
03635    if ((fd = mkstemp(template)) < 0) {
03636       ast_log(AST_LOG_WARNING, "Failed to create temporary file for command: %s\n", strerror(errno));
03637       astman_send_error(s, m, "Command response construction error");
03638       return 0;
03639    }
03640 
03641    astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
03642    if (!ast_strlen_zero(id)) {
03643       astman_append(s, "ActionID: %s\r\n", id);
03644    }
03645    /* FIXME: Wedge a ActionID response in here, waiting for later changes */
03646    ast_cli_command(fd, cmd);  /* XXX need to change this to use a FILE * */
03647    /* Determine number of characters available */
03648    if ((l = lseek(fd, 0, SEEK_END)) < 0) {
03649       ast_log(LOG_WARNING, "Failed to determine number of characters for command: %s\n", strerror(errno));
03650       goto action_command_cleanup;
03651    }
03652 
03653    /* This has a potential to overflow the stack.  Hence, use the heap. */
03654    buf = ast_malloc(l + 1);
03655    final_buf = ast_malloc(l + 1);
03656 
03657    if (!buf || !final_buf) {
03658       ast_log(LOG_WARNING, "Failed to allocate memory for temporary buffer\n");
03659       goto action_command_cleanup;
03660    }
03661 
03662    if (lseek(fd, 0, SEEK_SET) < 0) {
03663       ast_log(LOG_WARNING, "Failed to set position on temporary file for command: %s\n", strerror(errno));
03664       goto action_command_cleanup;
03665    }
03666 
03667    if (read(fd, buf, l) < 0) {
03668       ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
03669       goto action_command_cleanup;
03670    }
03671 
03672    buf[l] = '\0';
03673    term_strip(final_buf, buf, l);
03674    final_buf[l] = '\0';
03675    astman_append(s, "%s", final_buf);
03676 
03677 action_command_cleanup:
03678 
03679    close(fd);
03680    unlink(template);
03681    astman_append(s, "--END COMMAND--\r\n\r\n");
03682 
03683    ast_free(buf);
03684    ast_free(final_buf);
03685 
03686    return 0;
03687 }

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

Show PBX core settings information.

Definition at line 4352 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().

04353 {
04354    const char *actionid = astman_get_header(m, "ActionID");
04355    char idText[150];
04356 
04357    if (!ast_strlen_zero(actionid)) {
04358       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
04359    } else {
04360       idText[0] = '\0';
04361    }
04362 
04363    astman_append(s, "Response: Success\r\n"
04364          "%s"
04365          "AMIversion: %s\r\n"
04366          "AsteriskVersion: %s\r\n"
04367          "SystemName: %s\r\n"
04368          "CoreMaxCalls: %d\r\n"
04369          "CoreMaxLoadAvg: %f\r\n"
04370          "CoreRunUser: %s\r\n"
04371          "CoreRunGroup: %s\r\n"
04372          "CoreMaxFilehandles: %d\r\n"
04373          "CoreRealTimeEnabled: %s\r\n"
04374          "CoreCDRenabled: %s\r\n"
04375          "CoreHTTPenabled: %s\r\n"
04376          "\r\n",
04377          idText,
04378          AMI_VERSION,
04379          ast_get_version(),
04380          ast_config_AST_SYSTEM_NAME,
04381          option_maxcalls,
04382          option_maxload,
04383          ast_config_AST_RUN_USER,
04384          ast_config_AST_RUN_GROUP,
04385          option_maxfiles,
04386          AST_CLI_YESNO(ast_realtime_enabled()),
04387          AST_CLI_YESNO(check_cdr_enabled()),
04388          AST_CLI_YESNO(check_webmanager_enabled())
04389          );
04390    return 0;
04391 }

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 4461 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_connected_line::id, ast_party_caller::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().

04462 {
04463    const char *actionid = astman_get_header(m, "ActionID");
04464    char idText[256];
04465    struct ast_channel *c = NULL;
04466    int numchans = 0;
04467    int duration, durh, durm, durs;
04468    struct ast_channel_iterator *iter;
04469 
04470    if (!ast_strlen_zero(actionid)) {
04471       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
04472    } else {
04473       idText[0] = '\0';
04474    }
04475 
04476    if (!(iter = ast_channel_iterator_all_new())) {
04477       astman_send_error(s, m, "Memory Allocation Failure");
04478       return 1;
04479    }
04480 
04481    astman_send_listack(s, m, "Channels will follow", "start");
04482 
04483    for (; (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
04484       struct ast_channel *bc;
04485       char durbuf[10] = "";
04486 
04487       ast_channel_lock(c);
04488 
04489       bc = ast_bridged_channel(c);
04490       if (c->cdr && !ast_tvzero(c->cdr->start)) {
04491          duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
04492          durh = duration / 3600;
04493          durm = (duration % 3600) / 60;
04494          durs = duration % 60;
04495          snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
04496       }
04497 
04498       astman_append(s,
04499          "Event: CoreShowChannel\r\n"
04500          "%s"
04501          "Channel: %s\r\n"
04502          "UniqueID: %s\r\n"
04503          "Context: %s\r\n"
04504          "Extension: %s\r\n"
04505          "Priority: %d\r\n"
04506          "ChannelState: %d\r\n"
04507          "ChannelStateDesc: %s\r\n"
04508          "Application: %s\r\n"
04509          "ApplicationData: %s\r\n"
04510          "CallerIDnum: %s\r\n"
04511          "CallerIDname: %s\r\n"
04512          "ConnectedLineNum: %s\r\n"
04513          "ConnectedLineName: %s\r\n"
04514          "Duration: %s\r\n"
04515          "AccountCode: %s\r\n"
04516          "BridgedChannel: %s\r\n"
04517          "BridgedUniqueID: %s\r\n"
04518          "\r\n", idText, c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state,
04519          ast_state2str(c->_state), c->appl ? c->appl : "", c->data ? S_OR(c->data, "") : "",
04520          S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
04521          S_COR(c->caller.id.name.valid, c->caller.id.name.str, ""),
04522          S_COR(c->connected.id.number.valid, c->connected.id.number.str, ""),
04523          S_COR(c->connected.id.name.valid, c->connected.id.name.str, ""),
04524          durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : "");
04525 
04526       ast_channel_unlock(c);
04527 
04528       numchans++;
04529    }
04530 
04531    astman_append(s,
04532       "Event: CoreShowChannelsComplete\r\n"
04533       "EventList: Complete\r\n"
04534       "ListItems: %d\r\n"
04535       "%s"
04536       "\r\n", numchans, idText);
04537 
04538    ast_channel_iterator_destroy(iter);
04539 
04540    return 0;
04541 }

static int action_corestatus ( struct mansession s,
const struct message m 
) [static]

Show PBX core status information.

Definition at line 4394 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().

04395 {
04396    const char *actionid = astman_get_header(m, "ActionID");
04397    char idText[150];
04398    char startuptime[150], startupdate[150];
04399    char reloadtime[150], reloaddate[150];
04400    struct ast_tm tm;
04401 
04402    if (!ast_strlen_zero(actionid)) {
04403       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
04404    } else {
04405       idText[0] = '\0';
04406    }
04407 
04408    ast_localtime(&ast_startuptime, &tm, NULL);
04409    ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
04410    ast_strftime(startupdate, sizeof(startupdate), "%Y-%m-%d", &tm);
04411    ast_localtime(&ast_lastreloadtime, &tm, NULL);
04412    ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
04413    ast_strftime(reloaddate, sizeof(reloaddate), "%Y-%m-%d", &tm);
04414 
04415    astman_append(s, "Response: Success\r\n"
04416          "%s"
04417          "CoreStartupDate: %s\r\n"
04418          "CoreStartupTime: %s\r\n"
04419          "CoreReloadDate: %s\r\n"
04420          "CoreReloadTime: %s\r\n"
04421          "CoreCurrentCalls: %d\r\n"
04422          "\r\n",
04423          idText,
04424          startupdate,
04425          startuptime,
04426          reloaddate,
04427          reloadtime,
04428          ast_active_channels()
04429          );
04430    return 0;
04431 }

static int action_createconfig ( struct mansession s,
const struct message m 
) [static]

Definition at line 2862 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().

02863 {
02864    int fd;
02865    const char *fn = astman_get_header(m, "Filename");
02866    struct ast_str *filepath = ast_str_alloca(PATH_MAX);
02867    ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR);
02868    ast_str_append(&filepath, 0, "%s", fn);
02869 
02870    if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
02871       close(fd);
02872       astman_send_ack(s, m, "New configuration file created successfully");
02873    } else {
02874       astman_send_error(s, m, strerror(errno));
02875    }
02876 
02877    return 0;
02878 }

static void action_destroy ( void *  obj  )  [static]

Definition at line 5302 of file manager.c.

References ast_string_field_free_memory.

Referenced by ast_manager_register2().

05303 {
05304    struct manager_action *doomed = obj;
05305 
05306    if (doomed->synopsis) {
05307       /* The string fields were initialized. */
05308       ast_string_field_free_memory(doomed);
05309    }
05310 }

static int action_events ( struct mansession s,
const struct message m 
) [static]

Definition at line 3005 of file manager.c.

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

Referenced by __init_manager().

03006 {
03007    const char *mask = astman_get_header(m, "EventMask");
03008    int res, x;
03009    const char *id = astman_get_header(m, "ActionID");
03010    char id_text[256];
03011 
03012    if (!ast_strlen_zero(id)) {
03013       snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
03014    } else {
03015       id_text[0] = '\0';
03016    }
03017 
03018    res = set_eventmask(s, mask);
03019    if (broken_events_action) {
03020       /* if this option is set we should not return a response on
03021        * error, or when all events are set */
03022 
03023       if (res > 0) {
03024          for (x = 0; x < ARRAY_LEN(perms); x++) {
03025             if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) {
03026                return 0;
03027             }
03028          }
03029          astman_append(s, "Response: Success\r\n%s"
03030                 "Events: On\r\n\r\n", id_text);
03031       } else if (res == 0)
03032          astman_append(s, "Response: Success\r\n%s"
03033                 "Events: Off\r\n\r\n", id_text);
03034       return 0;
03035    }
03036 
03037    if (res > 0)
03038       astman_append(s, "Response: Success\r\n%s"
03039              "Events: On\r\n\r\n", id_text);
03040    else if (res == 0)
03041       astman_append(s, "Response: Success\r\n%s"
03042              "Events: Off\r\n\r\n", id_text);
03043    else
03044       astman_send_error(s, m, "Invalid event mask");
03045 
03046    return 0;
03047 }

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

Definition at line 4190 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().

04191 {
04192    const char *exten = astman_get_header(m, "Exten");
04193    const char *context = astman_get_header(m, "Context");
04194    char hint[256] = "";
04195    int status;
04196    if (ast_strlen_zero(exten)) {
04197       astman_send_error(s, m, "Extension not specified");
04198       return 0;
04199    }
04200    if (ast_strlen_zero(context)) {
04201       context = "default";
04202    }
04203    status = ast_extension_state(NULL, context, exten);
04204    ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
04205    astman_start_ack(s, m);
04206    astman_append(s,   "Message: Extension Status\r\n"
04207             "Exten: %s\r\n"
04208             "Context: %s\r\n"
04209             "Hint: %s\r\n"
04210             "Status: %d\r\n\r\n",
04211             exten, context, hint, status);
04212    return 0;
04213 }

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

Definition at line 1059 of file manager.c.

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

Referenced by process_message().

01060 {
01061    struct manager_action *act;
01062 
01063    AST_RWLIST_RDLOCK(&actions);
01064    AST_RWLIST_TRAVERSE(&actions, act, list) {
01065       if (!strcasecmp(name, act->action)) {
01066          ao2_t_ref(act, +1, "found action object");
01067          break;
01068       }
01069    }
01070    AST_RWLIST_UNLOCK(&actions);
01071 
01072    return act;
01073 }

static int action_getconfig ( struct mansession s,
const struct message m 
) [static]

Definition at line 2480 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(), 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().

02481 {
02482    struct ast_config *cfg;
02483    const char *fn = astman_get_header(m, "Filename");
02484    const char *category = astman_get_header(m, "Category");
02485    int catcount = 0;
02486    int lineno = 0;
02487    char *cur_category = NULL;
02488    struct ast_variable *v;
02489    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
02490 
02491    if (ast_strlen_zero(fn)) {
02492       astman_send_error(s, m, "Filename not specified");
02493       return 0;
02494    }
02495    cfg = ast_config_load2(fn, "manager", config_flags);
02496    if (cfg == CONFIG_STATUS_FILEMISSING) {
02497       astman_send_error(s, m, "Config file not found");
02498       return 0;
02499    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
02500       astman_send_error(s, m, "Config file has invalid format");
02501       return 0;
02502    }
02503 
02504    astman_start_ack(s, m);
02505    while ((cur_category = ast_category_browse(cfg, cur_category))) {
02506       if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) {
02507          lineno = 0;
02508          astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category);
02509          for (v = ast_variable_browse(cfg, cur_category); v; v = v->next) {
02510             astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
02511          }
02512          catcount++;
02513       }
02514    }
02515    if (!ast_strlen_zero(category) && catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
02516       astman_append(s, "No categories found\r\n");
02517    }
02518    ast_config_destroy(cfg);
02519    astman_append(s, "\r\n");
02520 
02521    return 0;
02522 }

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

Definition at line 2590 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(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by __init_manager().

02591 {
02592    struct ast_config *cfg;
02593    const char *fn = astman_get_header(m, "Filename");
02594    char *category = NULL;
02595    struct ast_variable *v;
02596    int comma1 = 0;
02597    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
02598 
02599    if (ast_strlen_zero(fn)) {
02600       astman_send_error(s, m, "Filename not specified");
02601       return 0;
02602    }
02603 
02604    if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
02605       astman_send_error(s, m, "Config file not found");
02606       return 0;
02607    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
02608       astman_send_error(s, m, "Config file has invalid format");
02609       return 0;
02610    }
02611 
02612    astman_start_ack(s, m);
02613    astman_append(s, "JSON: {");
02614    while ((category = ast_category_browse(cfg, category))) {
02615       int comma2 = 0;
02616 
02617       astman_append(s, "%s\"", comma1 ? "," : "");
02618       astman_append_json(s, category);
02619       astman_append(s, "\":[");
02620       comma1 = 1;
02621       for (v = ast_variable_browse(cfg, category); v; v = v->next) {
02622          astman_append(s, "%s\"", comma2 ? "," : "");
02623          astman_append_json(s, v->name);
02624          astman_append(s, "\":\"");
02625          astman_append_json(s, v->value);
02626          astman_append(s, "\"");
02627          comma2 = 1;
02628       }
02629       astman_append(s, "]");
02630    }
02631    astman_append(s, "}\r\n\r\n");
02632 
02633    ast_config_destroy(cfg);
02634 
02635    return 0;
02636 }

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

Definition at line 3180 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, name, pbx_retrieve_variable(), S_OR, mansession::session, and mansession_session::writeperm.

Referenced by __init_manager().

03181 {
03182    struct ast_channel *c = NULL;
03183    const char *name = astman_get_header(m, "Channel");
03184    const char *varname = astman_get_header(m, "Variable");
03185    char *varval;
03186    char workspace[1024];
03187 
03188    if (ast_strlen_zero(varname)) {
03189       astman_send_error(s, m, "No variable specified");
03190       return 0;
03191    }
03192 
03193    /* We don't want users with insufficient permissions using certain functions. */
03194    if (!(function_capable_string_allowed_with_auths(varname, s->session->writeperm))) {
03195       astman_send_error(s, m, "GetVar Access Forbidden: Variable");
03196       return 0;
03197    }
03198 
03199    if (!ast_strlen_zero(name)) {
03200       if (!(c = ast_channel_get_by_name(name))) {
03201          astman_send_error(s, m, "No such channel");
03202          return 0;
03203       }
03204    }
03205 
03206    workspace[0] = '\0';
03207    if (varname[strlen(varname) - 1] == ')') {
03208       if (!c) {
03209          c = ast_dummy_channel_alloc();
03210          if (c) {
03211             ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
03212          } else
03213             ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution.  Function results may be blank.\n");
03214       } else {
03215          ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
03216       }
03217       varval = workspace;
03218    } else {
03219       pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
03220    }
03221 
03222    if (c) {
03223       c = ast_channel_unref(c);
03224    }
03225 
03226    astman_start_ack(s, m);
03227    astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, S_OR(varval, ""));
03228 
03229    return 0;
03230 }

static int action_hangup ( struct mansession s,
const struct message m 
) [static]

Definition at line 3104 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(), cause, ast_channel::hangupcause, LOG_NOTICE, ast_channel::name, and name.

Referenced by __init_manager().

03105 {
03106    struct ast_channel *c = NULL;
03107    int causecode = 0; /* all values <= 0 mean 'do not set hangupcause in channel' */
03108    const char *name = astman_get_header(m, "Channel");
03109    const char *cause = astman_get_header(m, "Cause");
03110 
03111    if (ast_strlen_zero(name)) {
03112       astman_send_error(s, m, "No channel specified");
03113       return 0;
03114    }
03115 
03116    if (!ast_strlen_zero(cause)) {
03117       char *endptr;
03118       causecode = strtol(cause, &endptr, 10);
03119       if (causecode < 0 || causecode > 127 || *endptr != '\0') {
03120          ast_log(LOG_NOTICE, "Invalid 'Cause: %s' in manager action Hangup\n", cause);
03121          /* keep going, better to hangup without cause than to not hang up at all */
03122          causecode = 0; /* do not set channel's hangupcause */
03123       }
03124    }
03125 
03126    if (!(c = ast_channel_get_by_name(name))) {
03127       astman_send_error(s, m, "No such channel");
03128       return 0;
03129    }
03130 
03131    ast_channel_lock(c);
03132    if (causecode > 0) {
03133       ast_debug(1, "Setting hangupcause of channel %s to %d (is %d now)\n",
03134             c->name, causecode, c->hangupcause);
03135       c->hangupcause = causecode;
03136    }
03137    ast_softhangup_nolock(c, AST_SOFTHANGUP_EXPLICIT);
03138    ast_channel_unlock(c);
03139 
03140    c = ast_channel_unref(c);
03141 
03142    astman_send_ack(s, m, "Channel Hungup");
03143 
03144    return 0;
03145 }

static int action_listcategories ( struct mansession s,
const struct message m 
) [static]

Definition at line 2524 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(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, and CONFIG_STATUS_FILEINVALID.

Referenced by __init_manager().

02525 {
02526    struct ast_config *cfg;
02527    const char *fn = astman_get_header(m, "Filename");
02528    char *category = NULL;
02529    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
02530    int catcount = 0;
02531 
02532    if (ast_strlen_zero(fn)) {
02533       astman_send_error(s, m, "Filename not specified");
02534       return 0;
02535    }
02536    if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
02537       astman_send_error(s, m, "Config file not found");
02538       return 0;
02539    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
02540       astman_send_error(s, m, "Config file has invalid format");
02541       return 0;
02542    }
02543    astman_start_ack(s, m);
02544    while ((category = ast_category_browse(cfg, category))) {
02545       astman_append(s, "Category-%06d: %s\r\n", catcount, category);
02546       catcount++;
02547    }
02548    if (catcount == 0) { /* TODO: actually, a config with no categories doesn't even get loaded */
02549       astman_append(s, "Error: no categories found\r\n");
02550    }
02551    ast_config_destroy(cfg);
02552    astman_append(s, "\r\n");
02553 
02554    return 0;
02555 }

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

Definition at line 2986 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().

02987 {
02988    struct manager_action *cur;
02989    struct ast_str *temp = ast_str_alloca(256);
02990 
02991    astman_start_ack(s, m);
02992    AST_RWLIST_RDLOCK(&actions);
02993    AST_RWLIST_TRAVERSE(&actions, cur, list) {
02994       if ((s->session->writeperm & cur->authority) || cur->authority == 0) {
02995          astman_append(s, "%s: %s (Priv: %s)\r\n",
02996             cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
02997       }
02998    }
02999    AST_RWLIST_UNLOCK(&actions);
03000    astman_append(s, "\r\n");
03001 
03002    return 0;
03003 }

static int action_login ( struct mansession s,
const struct message m 
) [static]

Definition at line 3055 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::send_events, mansession::session, mansession_session::sin, unauth_sessions, and mansession_session::username.

Referenced by __init_manager().

03056 {
03057 
03058    /* still authenticated - don't process again */
03059    if (s->session->authenticated) {
03060       astman_send_ack(s, m, "Already authenticated");
03061       return 0;
03062    }
03063 
03064    if (authenticate(s, m)) {
03065       sleep(1);
03066       astman_send_error(s, m, "Authentication failed");
03067       return -1;
03068    }
03069    s->session->authenticated = 1;
03070    ast_atomic_fetchadd_int(&unauth_sessions, -1);
03071    if (manager_displayconnects(s->session)) {
03072       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));
03073    }
03074    astman_send_ack(s, m, "Authentication accepted");
03075    if ((s->session->send_events & EVENT_FLAG_SYSTEM)
03076       && ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
03077       struct ast_str *auth = ast_str_alloca(80);
03078       const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
03079       astman_append(s, "Event: FullyBooted\r\n"
03080          "Privilege: %s\r\n"
03081          "Status: Fully Booted\r\n\r\n", cat_str);
03082    }
03083    return 0;
03084 }

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

Definition at line 3049 of file manager.c.

References astman_send_response().

Referenced by __init_manager().

03050 {
03051    astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
03052    return -1;
03053 }

static int action_mailboxcount ( struct mansession s,
const struct message m 
) [static]

Definition at line 4169 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().

04170 {
04171    const char *mailbox = astman_get_header(m, "Mailbox");
04172    int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;;
04173 
04174    if (ast_strlen_zero(mailbox)) {
04175       astman_send_error(s, m, "Mailbox not specified");
04176       return 0;
04177    }
04178    ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs);
04179    astman_start_ack(s, m);
04180    astman_append(s,   "Message: Mailbox Message Count\r\n"
04181             "Mailbox: %s\r\n"
04182             "UrgMessages: %d\r\n"
04183             "NewMessages: %d\r\n"
04184             "OldMessages: %d\r\n"
04185             "\r\n",
04186             mailbox, urgentmsgs, newmsgs, oldmsgs);
04187    return 0;
04188 }

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

Definition at line 4152 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().

04153 {
04154    const char *mailbox = astman_get_header(m, "Mailbox");
04155    int ret;
04156 
04157    if (ast_strlen_zero(mailbox)) {
04158       astman_send_error(s, m, "Mailbox not specified");
04159       return 0;
04160    }
04161    ret = ast_app_has_voicemail(mailbox, NULL);
04162    astman_start_ack(s, m);
04163    astman_append(s, "Message: Mailbox Status\r\n"
04164           "Mailbox: %s\r\n"
04165           "Waiting: %d\r\n\r\n", mailbox, ret);
04166    return 0;
04167 }

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

Definition at line 4008 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(), name, mansession::session, strcasestr(), and mansession_session::writeperm.

Referenced by __init_manager().

04009 {
04010    const char *name = astman_get_header(m, "Channel");
04011    const char *exten = astman_get_header(m, "Exten");
04012    const char *context = astman_get_header(m, "Context");
04013    const char *priority = astman_get_header(m, "Priority");
04014    const char *timeout = astman_get_header(m, "Timeout");
04015    const char *callerid = astman_get_header(m, "CallerID");
04016    const char *account = astman_get_header(m, "Account");
04017    const char *app = astman_get_header(m, "Application");
04018    const char *appdata = astman_get_header(m, "Data");
04019    const char *async = astman_get_header(m, "Async");
04020    const char *id = astman_get_header(m, "ActionID");
04021    const char *codecs = astman_get_header(m, "Codecs");
04022    struct ast_variable *vars;
04023    char *tech, *data;
04024    char *l = NULL, *n = NULL;
04025    int pi = 0;
04026    int res;
04027    int to = 30000;
04028    int reason = 0;
04029    char tmp[256];
04030    char tmp2[256];
04031    format_t format = AST_FORMAT_SLINEAR;
04032 
04033    pthread_t th;
04034    if (ast_strlen_zero(name)) {
04035       astman_send_error(s, m, "Channel not specified");
04036       return 0;
04037    }
04038    if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
04039       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
04040          astman_send_error(s, m, "Invalid priority");
04041          return 0;
04042       }
04043    }
04044    if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
04045       astman_send_error(s, m, "Invalid timeout");
04046       return 0;
04047    }
04048    ast_copy_string(tmp, name, sizeof(tmp));
04049    tech = tmp;
04050    data = strchr(tmp, '/');
04051    if (!data) {
04052       astman_send_error(s, m, "Invalid channel");
04053       return 0;
04054    }
04055    *data++ = '\0';
04056    ast_copy_string(tmp2, callerid, sizeof(tmp2));
04057    ast_callerid_parse(tmp2, &n, &l);
04058    if (n) {
04059       if (ast_strlen_zero(n)) {
04060          n = NULL;
04061       }
04062    }
04063    if (l) {
04064       ast_shrink_phone_number(l);
04065       if (ast_strlen_zero(l)) {
04066          l = NULL;
04067       }
04068    }
04069    if (!ast_strlen_zero(codecs)) {
04070       format = 0;
04071       ast_parse_allow_disallow(NULL, &format, codecs, 1);
04072    }
04073    if (!ast_strlen_zero(app) && s->session) {
04074       int bad_appdata = 0;
04075       /* To run the System application (or anything else that goes to
04076        * shell), you must have the additional System privilege */
04077       if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
04078          && (
04079             strcasestr(app, "system") ||      /* System(rm -rf /)
04080                                                  TrySystem(rm -rf /)       */
04081             strcasestr(app, "exec") ||        /* Exec(System(rm -rf /))
04082                                                  TryExec(System(rm -rf /)) */
04083             strcasestr(app, "agi") ||         /* AGI(/bin/rm,-rf /)
04084                                                  EAGI(/bin/rm,-rf /)       */
04085             strcasestr(app, "mixmonitor") ||  /* MixMonitor(blah,,rm -rf)  */
04086             strcasestr(app, "externalivr") || /* ExternalIVR(rm -rf)       */
04087             (strstr(appdata, "SHELL") && (bad_appdata = 1)) ||       /* NoOp(${SHELL(rm -rf /)})  */
04088             (strstr(appdata, "EVAL") && (bad_appdata = 1))           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
04089             )) {
04090          char error_buf[64];
04091          snprintf(error_buf, sizeof(error_buf), "Originate Access Forbidden: %s", bad_appdata ? "Data" : "Application");
04092          astman_send_error(s, m, error_buf);
04093          return 0;
04094       }
04095    }
04096    /* Allocate requested channel variables */
04097    vars = astman_get_variables(m);
04098 
04099    if (ast_true(async)) {
04100       struct fast_originate_helper *fast;
04101 
04102       fast = ast_calloc(1, sizeof(*fast));
04103       if (!fast || ast_string_field_init(fast, 252)) {
04104          ast_free(fast);
04105          ast_variables_destroy(vars);
04106          res = -1;
04107       } else {
04108          if (!ast_strlen_zero(id)) {
04109             ast_string_field_build(fast, idtext, "ActionID: %s\r\n", id);
04110          }
04111          ast_string_field_set(fast, tech, tech);
04112          ast_string_field_set(fast, data, data);
04113          ast_string_field_set(fast, app, app);
04114          ast_string_field_set(fast, appdata, appdata);
04115          ast_string_field_set(fast, cid_num, l);
04116          ast_string_field_set(fast, cid_name, n);
04117          ast_string_field_set(fast, context, context);
04118          ast_string_field_set(fast, exten, exten);
04119          ast_string_field_set(fast, account, account);
04120          fast->vars = vars;
04121          fast->format = format;
04122          fast->timeout = to;
04123          fast->priority = pi;
04124          if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) {
04125             destroy_fast_originate_helper(fast);
04126             res = -1;
04127          } else {
04128             res = 0;
04129          }
04130       }
04131    } else if (!ast_strlen_zero(app)) {
04132       res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
04133       /* Any vars memory was passed to ast_pbx_outgoing_app(). */
04134    } else {
04135       if (exten && context && pi) {
04136          res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL);
04137          /* Any vars memory was passed to ast_pbx_outgoing_exten(). */
04138       } else {
04139          astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
04140          ast_variables_destroy(vars);
04141          return 0;
04142       }
04143    }
04144    if (!res) {
04145       astman_send_ack(s, m, "Originate successfully queued");
04146    } else {
04147       astman_send_error(s, m, "Originate failed");
04148    }
04149    return 0;
04150 }

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

Definition at line 2462 of file manager.c.

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

Referenced by __init_manager().

02463 {
02464    const char *actionid = astman_get_header(m, "ActionID");
02465    struct timeval now = ast_tvnow();
02466 
02467    astman_append(s, "Response: Success\r\n");
02468    if (!ast_strlen_zero(actionid)){
02469       astman_append(s, "ActionID: %s\r\n", actionid);
02470    }
02471    astman_append(
02472       s,
02473       "Ping: Pong\r\n"
02474       "Timestamp: %ld.%06lu\r\n"
02475       "\r\n",
02476       (long) now.tv_sec, (unsigned long) now.tv_usec);
02477    return 0;
02478 }

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

action_redirect: The redirect manager command

Definition at line 3431 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_findlabel_extension(), AST_FLAG_BRIDGE_HANGUP_DONT, ast_set_flag, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, exten, name, ast_channel::pbx, and ast_channel::priority.

Referenced by __init_manager().

03432 {
03433    const char *name = astman_get_header(m, "Channel");
03434    const char *name2 = astman_get_header(m, "ExtraChannel");
03435    const char *exten = astman_get_header(m, "Exten");
03436    const char *exten2 = astman_get_header(m, "ExtraExten");
03437    const char *context = astman_get_header(m, "Context");
03438    const char *context2 = astman_get_header(m, "ExtraContext");
03439    const char *priority = astman_get_header(m, "Priority");
03440    const char *priority2 = astman_get_header(m, "ExtraPriority");
03441    struct ast_channel *chan, *chan2 = NULL;
03442    int pi, pi2 = 0;
03443    int res;
03444 
03445    if (ast_strlen_zero(name)) {
03446       astman_send_error(s, m, "Channel not specified");
03447       return 0;
03448    }
03449 
03450    if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
03451       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
03452          astman_send_error(s, m, "Invalid priority");
03453          return 0;
03454       }
03455    }
03456 
03457    if (!ast_strlen_zero(priority2) && (sscanf(priority2, "%30d", &pi2) != 1)) {
03458       if ((pi2 = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL)) < 1) {
03459          astman_send_error(s, m, "Invalid ExtraPriority");
03460          return 0;
03461       }
03462    }
03463 
03464    if (!(chan = ast_channel_get_by_name(name))) {
03465       char buf[256];
03466       snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
03467       astman_send_error(s, m, buf);
03468       return 0;
03469    }
03470 
03471    if (ast_check_hangup_locked(chan)) {
03472       astman_send_error(s, m, "Redirect failed, channel not up.");
03473       chan = ast_channel_unref(chan);
03474       return 0;
03475    }
03476 
03477    if (!ast_strlen_zero(name2)) {
03478       chan2 = ast_channel_get_by_name(name2);
03479    }
03480 
03481    if (chan2 && ast_check_hangup_locked(chan2)) {
03482       astman_send_error(s, m, "Redirect failed, extra channel not up.");
03483       chan = ast_channel_unref(chan);
03484       chan2 = ast_channel_unref(chan2);
03485       return 0;
03486    }
03487 
03488    if (chan->pbx) {
03489       ast_channel_lock(chan);
03490       ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
03491       ast_channel_unlock(chan);
03492    }
03493 
03494    res = ast_async_goto(chan, context, exten, pi);
03495    if (!res) {
03496       if (!ast_strlen_zero(name2)) {
03497          if (chan2) {
03498             if (chan2->pbx) {
03499                ast_channel_lock(chan2);
03500                ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
03501                ast_channel_unlock(chan2);
03502             }
03503             if (!ast_strlen_zero(context2)) {
03504                res = ast_async_goto(chan2, context2, exten2, pi2);
03505             } else {
03506                res = ast_async_goto(chan2, context, exten, pi);
03507             }
03508          } else {
03509             res = -1;
03510          }
03511          if (!res) {
03512             astman_send_ack(s, m, "Dual Redirect successful");
03513          } else {
03514             astman_send_error(s, m, "Secondary redirect failed");
03515          }
03516       } else {
03517          astman_send_ack(s, m, "Redirect successful");
03518       }
03519    } else {
03520       astman_send_error(s, m, "Redirect failed");
03521    }
03522 
03523    chan = ast_channel_unref(chan);
03524    if (chan2) {
03525       chan2 = ast_channel_unref(chan2);
03526    }
03527 
03528    return 0;
03529 }

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

Send a reload event.

Definition at line 4434 of file manager.c.

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

Referenced by __init_manager().

04435 {
04436    const char *module = astman_get_header(m, "Module");
04437    int res = ast_module_reload(S_OR(module, NULL));
04438 
04439    switch (res) {
04440    case -1:
04441       astman_send_error(s, m, "A reload is in progress");
04442       break;
04443    case 0:
04444       astman_send_error(s, m, "No such module");
04445       break;
04446    case 1:
04447       astman_send_error(s, m, "Module does not support reload");
04448       break;
04449    case 2:
04450       astman_send_ack(s, m, "Module Reloaded");
04451       break;
04452    default:
04453       astman_send_error(s, m, "An unknown error occurred");
04454       break;
04455    }
04456    return 0;
04457 }

static int action_sendtext ( struct mansession s,
const struct message m 
) [static]

Definition at line 3396 of file manager.c.

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

Referenced by __init_manager().

03397 {
03398    struct ast_channel *c = NULL;
03399    const char *name = astman_get_header(m, "Channel");
03400    const char *textmsg = astman_get_header(m, "Message");
03401    int res = 0;
03402 
03403    if (ast_strlen_zero(name)) {
03404       astman_send_error(s, m, "No channel specified");
03405       return 0;
03406    }
03407 
03408    if (ast_strlen_zero(textmsg)) {
03409       astman_send_error(s, m, "No Message specified");
03410       return 0;
03411    }
03412 
03413    if (!(c = ast_channel_get_by_name(name))) {
03414       astman_send_error(s, m, "No such channel");
03415       return 0;
03416    }
03417 
03418    res = ast_sendtext(c, textmsg);
03419    c = ast_channel_unref(c);
03420 
03421    if (res >= 0) {
03422       astman_send_ack(s, m, "Success");
03423    } else {
03424       astman_send_error(s, m, "Failure");
03425    }
03426 
03427    return res;
03428 }

static int action_setvar ( struct mansession s,
const struct message m 
) [static]

Definition at line 3147 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(), name, pbx_builtin_setvar_helper(), and S_OR.

Referenced by __init_manager().

03148 {
03149    struct ast_channel *c = NULL;
03150    const char *name = astman_get_header(m, "Channel");
03151    const char *varname = astman_get_header(m, "Variable");
03152    const char *varval = astman_get_header(m, "Value");
03153    int res = 0;
03154    
03155    if (ast_strlen_zero(varname)) {
03156       astman_send_error(s, m, "No variable specified");
03157       return 0;
03158    }
03159 
03160    if (!ast_strlen_zero(name)) {
03161       if (!(c = ast_channel_get_by_name(name))) {
03162          astman_send_error(s, m, "No such channel");
03163          return 0;
03164       }
03165    }
03166 
03167    res = pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
03168 
03169    if (c) {
03170       c = ast_channel_unref(c);
03171    }
03172    if (res == 0) {
03173       astman_send_ack(s, m, "Variable Set"); 
03174    } else {
03175       astman_send_error(s, m, "Variable not set");
03176    }
03177    return 0;
03178 }

static int action_status ( struct mansession s,
const struct message m 
) [static]

Manager "status" command to show channels.

Definition at line 3234 of file manager.c.

References AST_APP_ARG, ast_channel_get_by_name(), ast_channel_iterator_all_new(), ast_channel_iterator_next(), ast_channel_lock, AST_DECLARE_APP_ARGS, ast_free, ast_func_read(), AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_create(), ast_str_reset(), ast_strdupa, ast_strlen_zero(), ast_tvnow(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::bridge, channels, function_capable_string_allowed_with_auths(), ast_channel::name, name, pbx_retrieve_variable(), S_OR, mansession::session, str, and mansession_session::writeperm.

Referenced by __init_manager().

03235 {
03236    const char *name = astman_get_header(m, "Channel");
03237    const char *cvariables = astman_get_header(m, "Variables");
03238    char *variables = ast_strdupa(S_OR(cvariables, ""));
03239    struct ast_channel *c;
03240    char bridge[256];
03241    struct timeval now = ast_tvnow();
03242    long elapsed_seconds = 0;
03243    int channels = 0;
03244    int all = ast_strlen_zero(name); /* set if we want all channels */
03245    const char *id = astman_get_header(m, "ActionID");
03246    char idText[256];
03247    AST_DECLARE_APP_ARGS(vars,
03248       AST_APP_ARG(name)[100];
03249    );
03250    struct ast_str *str = ast_str_create(1000);
03251    struct ast_channel_iterator *iter = NULL;
03252 
03253    if (!ast_strlen_zero(id)) {
03254       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
03255    } else {
03256       idText[0] = '\0';
03257    }
03258 
03259    if (!(function_capable_string_allowed_with_auths(variables, s->session->writeperm))) {
03260       astman_send_error(s, m, "Status Access Forbidden: Variables");
03261       return 0;
03262    }
03263 
03264    if (all) {
03265       if (!(iter = ast_channel_iterator_all_new())) {
03266          ast_free(str);
03267          astman_send_error(s, m, "Memory Allocation Failure");
03268          return 1;
03269       }
03270       c = ast_channel_iterator_next(iter);
03271    } else {
03272       if (!(c = ast_channel_get_by_name(name))) {
03273          astman_send_error(s, m, "No such channel");
03274          ast_free(str);
03275          return 0;
03276       }
03277    }
03278 
03279    astman_send_ack(s, m, "Channel status will follow");
03280 
03281    if (!ast_strlen_zero(cvariables)) {
03282       AST_STANDARD_APP_ARGS(vars, variables);
03283    }
03284 
03285    /* if we look by name, we break after the first iteration */
03286    for (; c; c = ast_channel_iterator_next(iter)) {
03287       ast_channel_lock(c);
03288 
03289       if (!ast_strlen_zero(cvariables)) {
03290          int i;
03291          ast_str_reset(str);
03292          for (i = 0; i < vars.argc; i++) {
03293             char valbuf[512], *ret = NULL;
03294 
03295             if (vars.name[i][strlen(vars.name[i]) - 1] == ')') {
03296                if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) {
03297                   valbuf[0] = '\0';
03298                }
03299                ret = valbuf;
03300             } else {
03301                pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL);
03302             }
03303 
03304             ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret);
03305          }
03306       }
03307 
03308       channels++;
03309       if (c->_bridge) {
03310          snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid);
03311       } else {
03312          bridge[0] = '\0';
03313       }
03314       if (c->pbx) {
03315          if (c->cdr) {
03316             elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
03317          }
03318          astman_append(s,
03319          "Event: Status\r\n"
03320          "Privilege: Call\r\n"
03321          "Channel: %s\r\n"
03322          "CallerIDNum: %s\r\n"
03323          "CallerIDName: %s\r\n"
03324          "ConnectedLineNum: %s\r\n"
03325          "ConnectedLineName: %s\r\n"
03326          "Accountcode: %s\r\n"
03327          "ChannelState: %d\r\n"
03328          "ChannelStateDesc: %s\r\n"
03329          "Context: %s\r\n"
03330          "Extension: %s\r\n"
03331          "Priority: %d\r\n"
03332          "Seconds: %ld\r\n"
03333          "%s"
03334          "Uniqueid: %s\r\n"
03335          "%s"
03336          "%s"
03337          "\r\n",
03338          c->name,
03339          S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<unknown>"),
03340          S_COR(c->caller.id.name.valid, c->caller.id.name.str, "<unknown>"),
03341          S_COR(c->connected.id.number.valid, c->connected.id.number.str, "<unknown>"),
03342          S_COR(c->connected.id.name.valid, c->connected.id.name.str, "<unknown>"),
03343          c->accountcode,
03344          c->_state,
03345          ast_state2str(c->_state), c->context,
03346          c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, ast_str_buffer(str), idText);
03347       } else {
03348          astman_append(s,
03349             "Event: Status\r\n"
03350             "Privilege: Call\r\n"
03351             "Channel: %s\r\n"
03352             "CallerIDNum: %s\r\n"
03353             "CallerIDName: %s\r\n"
03354             "ConnectedLineNum: %s\r\n"
03355             "ConnectedLineName: %s\r\n"
03356             "Account: %s\r\n"
03357             "State: %s\r\n"
03358             "%s"
03359             "Uniqueid: %s\r\n"
03360             "%s"
03361             "%s"
03362             "\r\n",
03363             c->name,
03364             S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<unknown>"),
03365             S_COR(c->caller.id.name.valid, c->caller.id.name.str, "<unknown>"),
03366             S_COR(c->connected.id.number.valid, c->connected.id.number.str, "<unknown>"),
03367             S_COR(c->connected.id.name.valid, c->connected.id.name.str, "<unknown>"),
03368             c->accountcode,
03369             ast_state2str(c->_state), bridge, c->uniqueid,
03370             ast_str_buffer(str), idText);
03371       }
03372 
03373       ast_channel_unlock(c);
03374       c = ast_channel_unref(c);
03375 
03376       if (!all) {
03377          break;
03378       }
03379    }
03380 
03381    if (iter) {
03382       ast_channel_iterator_destroy(iter);
03383    }
03384 
03385    astman_append(s,
03386       "Event: StatusComplete\r\n"
03387       "%s"
03388       "Items: %d\r\n"
03389       "\r\n", idText, channels);
03390 
03391    ast_free(str);
03392 
03393    return 0;
03394 }

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

Definition at line 4215 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(), astman_send_error(), and name.

Referenced by __init_manager().

04216 {
04217    struct ast_channel *c;
04218    const char *name = astman_get_header(m, "Channel");
04219    double timeout = atof(astman_get_header(m, "Timeout"));
04220    struct timeval when = { timeout, 0 };
04221 
04222    if (ast_strlen_zero(name)) {
04223       astman_send_error(s, m, "No channel specified");
04224       return 0;
04225    }
04226 
04227    if (!timeout || timeout < 0) {
04228       astman_send_error(s, m, "No timeout specified");
04229       return 0;
04230    }
04231 
04232    if (!(c = ast_channel_get_by_name(name))) {
04233       astman_send_error(s, m, "No such channel");
04234       return 0;
04235    }
04236 
04237    when.tv_usec = (timeout - when.tv_sec) * 1000000.0;
04238 
04239    ast_channel_lock(c);
04240    ast_channel_setwhentohangup_tv(c, when);
04241    ast_channel_unlock(c);
04242    c = ast_channel_unref(c);
04243 
04244    astman_send_ack(s, m, "Timeout Set");
04245 
04246    return 0;
04247 }

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

Definition at line 2784 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_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, handle_updates(), UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, and UNSPECIFIED_CATEGORY.

Referenced by __init_manager().

02785 {
02786    struct ast_config *cfg;
02787    const char *sfn = astman_get_header(m, "SrcFilename");
02788    const char *dfn = astman_get_header(m, "DstFilename");
02789    int res;
02790    const char *rld = astman_get_header(m, "Reload");
02791    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
02792    enum error_type result;
02793 
02794    if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
02795       astman_send_error(s, m, "Filename not specified");
02796       return 0;
02797    }
02798    if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) {
02799       astman_send_error(s, m, "Config file not found");
02800       return 0;
02801    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
02802       astman_send_error(s, m, "Config file has invalid format");
02803       return 0;
02804    }
02805    result = handle_updates(s, m, cfg, dfn);
02806    if (!result) {
02807       ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
02808       res = ast_config_text_file_save(dfn, cfg, "Manager");
02809       ast_config_destroy(cfg);
02810       if (res) {
02811          astman_send_error(s, m, "Save of config failed");
02812          return 0;
02813       }
02814       astman_send_ack(s, m, NULL);
02815       if (!ast_strlen_zero(rld)) {
02816          if (ast_true(rld)) {
02817             rld = NULL;
02818          }
02819          ast_module_reload(rld);
02820       }
02821    } else {
02822       ast_config_destroy(cfg);
02823       switch(result) {
02824       case UNKNOWN_ACTION:
02825          astman_send_error(s, m, "Unknown action command");
02826          break;
02827       case UNKNOWN_CATEGORY:
02828          astman_send_error(s, m, "Given category does not exist");
02829          break;
02830       case UNSPECIFIED_CATEGORY:
02831          astman_send_error(s, m, "Category not specified");
02832          break;
02833       case UNSPECIFIED_ARGUMENT:
02834          astman_send_error(s, m, "Problem with category, value, or line (if required)");
02835          break;
02836       case FAILURE_ALLOCATION:
02837          astman_send_error(s, m, "Memory allocation failure, this should not happen");
02838          break;
02839       case FAILURE_NEWCAT:
02840          astman_send_error(s, m, "Create category did not complete successfully");
02841          break;
02842       case FAILURE_DELCAT:
02843          astman_send_error(s, m, "Delete category did not complete successfully");
02844          break;
02845       case FAILURE_EMPTYCAT:
02846          astman_send_error(s, m, "Empty category did not complete successfully");
02847          break;
02848       case FAILURE_UPDATE:
02849          astman_send_error(s, m, "Update did not complete successfully");
02850          break;
02851       case FAILURE_DELETE:
02852          astman_send_error(s, m, "Delete did not complete successfully");
02853          break;
02854       case FAILURE_APPEND:
02855          astman_send_error(s, m, "Append did not complete successfully");
02856          break;
02857       }
02858    }
02859    return 0;
02860 }

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

Definition at line 4332 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().

04333 {
04334    const char *event = astman_get_header(m, "UserEvent");
04335    struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
04336    int x;
04337 
04338    ast_str_reset(body);
04339 
04340    for (x = 0; x < m->hdrcount; x++) {
04341       if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
04342          ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
04343       }
04344    }
04345 
04346    astman_send_ack(s, m, "Event Sent");   
04347    manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body));
04348    return 0;
04349 }

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

Definition at line 2880 of file manager.c.

References ao2_lock, ao2_unlock, ast_debug, AST_PTHREADT_NULL, AST_RWLIST_NEXT, ast_strlen_zero(), astman_get_header(), mansession_session::last_ev, mansession_session::managerid, mansession_session::needdestroy, mansession_session::send_events, mansession::session, mansession_session::sessiontimeout, and mansession_session::waiting_thread.

Referenced by __init_manager().

02881 {
02882    const char *timeouts = astman_get_header(m, "Timeout");
02883    int timeout = -1;
02884    int x;
02885    int needexit = 0;
02886    const char *id = astman_get_header(m, "ActionID");
02887    char idText[256];
02888 
02889    if (!ast_strlen_zero(id)) {
02890       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
02891    } else {
02892       idText[0] = '\0';
02893    }
02894 
02895    if (!ast_strlen_zero(timeouts)) {
02896       sscanf(timeouts, "%30i", &timeout);
02897       if (timeout < -1) {
02898          timeout = -1;
02899       }
02900       /* XXX maybe put an upper bound, or prevent the use of 0 ? */
02901    }
02902 
02903    ao2_lock(s->session);
02904    if (s->session->waiting_thread != AST_PTHREADT_NULL) {
02905       pthread_kill(s->session->waiting_thread, SIGURG);
02906    }
02907 
02908    if (s->session->managerid) { /* AMI-over-HTTP session */
02909       /*
02910        * Make sure the timeout is within the expire time of the session,
02911        * as the client will likely abort the request if it does not see
02912        * data coming after some amount of time.
02913        */
02914       time_t now = time(NULL);
02915       int max = s->session->sessiontimeout - now - 10;
02916 
02917       if (max < 0) { /* We are already late. Strange but possible. */
02918          max = 0;
02919       }
02920       if (timeout < 0 || timeout > max) {
02921          timeout = max;
02922       }
02923       if (!s->session->send_events) {  /* make sure we record events */
02924          s->session->send_events = -1;
02925       }
02926    }
02927    ao2_unlock(s->session);
02928 
02929    /* XXX should this go inside the lock ? */
02930    s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
02931    ast_debug(1, "Starting waiting for an event!\n");
02932 
02933    for (x = 0; x < timeout || timeout < 0; x++) {
02934       ao2_lock(s->session);
02935       if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
02936          needexit = 1;
02937       }
02938       /* We can have multiple HTTP session point to the same mansession entry.
02939        * The way we deal with it is not very nice: newcomers kick out the previous
02940        * HTTP session. XXX this needs to be improved.
02941        */
02942       if (s->session->waiting_thread != pthread_self()) {
02943          needexit = 1;
02944       }
02945       if (s->session->needdestroy) {
02946          needexit = 1;
02947       }
02948       ao2_unlock(s->session);
02949       if (needexit) {
02950          break;
02951       }
02952       if (s->session->managerid == 0) {   /* AMI session */
02953          if (ast_wait_for_input(s->session->fd, 1000)) {
02954             break;
02955          }
02956       } else { /* HTTP session */
02957          sleep(1);
02958       }
02959    }
02960    ast_debug(1, "Finished waiting for an event!\n");
02961 
02962    ao2_lock(s->session);
02963    if (s->session->waiting_thread == pthread_self()) {
02964       struct eventqent *eqe = s->session->last_ev;
02965       astman_send_response(s, m, "Success", "Waiting for Event completed.");
02966       while ((eqe = advance_event(eqe))) {
02967          if (((s->session->readperm & eqe->category) == eqe->category) &&
02968              ((s->session->send_events & eqe->category) == eqe->category)) {
02969             astman_append(s, "%s", eqe->eventdata);
02970          }
02971          s->session->last_ev = eqe;
02972       }
02973       astman_append(s,
02974          "Event: WaitEventComplete\r\n"
02975          "%s"
02976          "\r\n", idText);
02977       s->session->waiting_thread = AST_PTHREADT_NULL;
02978    } else {
02979       ast_debug(1, "Abandoning event request!\n");
02980    }
02981    ao2_unlock(s->session);
02982 
02983    return 0;
02984 }

static struct eventqent* advance_event ( struct eventqent e  )  [static]

Definition at line 1750 of file manager.c.

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

Referenced by process_events().

01751 {
01752    struct eventqent *next;
01753 
01754    AST_RWLIST_RDLOCK(&all_events);
01755    if ((next = AST_RWLIST_NEXT(e, eq_next))) {
01756       ast_atomic_fetchadd_int(&next->usecount, 1);
01757       ast_atomic_fetchadd_int(&e->usecount, -1);
01758    }
01759    AST_RWLIST_UNLOCK(&all_events);
01760    return next;
01761 }

static int aocmessage_get_unit_entry ( const struct message m,
struct ast_aoc_unit_entry entry,
unsigned int  entry_num 
) [static]

Definition at line 3778 of file manager.c.

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

Referenced by action_aocmessage().

03779 {
03780    const char *unitamount;
03781    const char *unittype;
03782    struct ast_str *str = ast_str_alloca(32);
03783 
03784    memset(entry, 0, sizeof(*entry));
03785 
03786    ast_str_set(&str, 0, "UnitAmount(%u)", entry_num);
03787    unitamount = astman_get_header(m, ast_str_buffer(str));
03788 
03789    ast_str_set(&str, 0, "UnitType(%u)", entry_num);
03790    unittype = astman_get_header(m, ast_str_buffer(str));
03791 
03792    if (!ast_strlen_zero(unitamount) && (sscanf(unitamount, "%30u", &entry->amount) == 1)) {
03793       entry->valid_amount = 1;
03794    }
03795 
03796    if (!ast_strlen_zero(unittype) && sscanf(unittype, "%30u", &entry->type) == 1) {
03797       entry->valid_type = 1;
03798    }
03799 
03800    return 0;
03801 }

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

Definition at line 5085 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_event_funcbuf, ast_channel::name, pbx_builtin_getvar_helper(), and var.

Referenced by __ast_manager_event_multichan().

05086 {
05087    struct manager_channel_variable *var;
05088 
05089    AST_RWLIST_RDLOCK(&channelvars);
05090    AST_LIST_TRAVERSE(&channelvars, var, entry) {
05091       const char *val;
05092       struct ast_str *res;
05093 
05094       if (var->isfunc) {
05095          res = ast_str_thread_get(&manager_event_funcbuf, 16);
05096          if (res && ast_func_read2(chan, var->name, &res, 0) == 0) {
05097             val = ast_str_buffer(res);
05098          } else {
05099             val = NULL;
05100          }
05101       } else {
05102          val = pbx_builtin_getvar_helper(chan, var->name);
05103       }
05104       ast_str_append(pbuf, 0, "ChanVariable(%s): %s=%s\r\n", chan->name, var->name, val ? val : "");
05105    }
05106    AST_RWLIST_UNLOCK(&channelvars);
05107 }

static int append_event ( const char *  str,
int  category 
) [static]

Definition at line 5059 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(), and seq.

Referenced by __ast_manager_event_multichan(), and __init_manager().

05060 {
05061    struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
05062    static int seq;   /* sequence number */
05063 
05064    if (!tmp) {
05065       return -1;
05066    }
05067 
05068    /* need to init all fields, because ast_malloc() does not */
05069    tmp->usecount = 0;
05070    tmp->category = category;
05071    tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
05072    tmp->tv = ast_tvnow();
05073    AST_RWLIST_NEXT(tmp, eq_next) = NULL;
05074    strcpy(tmp->eventdata, str);
05075 
05076    AST_RWLIST_WRLOCK(&all_events);
05077    AST_RWLIST_INSERT_TAIL(&all_events, tmp, eq_next);
05078    AST_RWLIST_UNLOCK(&all_events);
05079 
05080    return 0;
05081 }

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:
hook the file identifier specified in manager_custom_hook struct when registering a hook
msg ami action mesage string e.g. "Action: SipPeers\r\n"
Return values:
0 on Success
non-zero on Failure

Definition at line 1893 of file manager.c.

References ARRAY_LEN, ast_strdup, message::hdrcount, message::headers, and mansession::session.

01894 {
01895    const char *action;
01896    int ret = 0;
01897    struct manager_action *act_found;
01898    struct mansession s = {.session = NULL, };
01899    struct message m = { 0 };
01900    char *dup_str;
01901    char *src;
01902    int x = 0;
01903    int curlen;
01904 
01905    if (hook == NULL) {
01906       return -1;
01907    }
01908 
01909    /* Create our own copy of the AMI action msg string. */
01910    src = dup_str = ast_strdup(msg);
01911    if (!dup_str) {
01912       return -1;
01913    }
01914 
01915    /* convert msg string to message struct */
01916    curlen = strlen(src);
01917    for (x = 0; x < curlen; x++) {
01918       int cr;  /* set if we have \r */
01919       if (src[x] == '\r' && x+1 < curlen && src[x+1] == '\n')
01920          cr = 2;  /* Found. Update length to include \r\n */
01921       else if (src[x] == '\n')
01922          cr = 1;  /* also accept \n only */
01923       else
01924          continue;
01925       /* don't keep empty lines */
01926       if (x && m.hdrcount < ARRAY_LEN(m.headers)) {
01927          /* ... but trim \r\n and terminate the header string */
01928          src[x] = '\0';
01929          m.headers[m.hdrcount++] = src;
01930       }
01931       x += cr;
01932       curlen -= x;      /* remaining size */
01933       src += x;      /* update pointer */
01934       x = -1;        /* reset loop */
01935    }
01936 
01937    action = astman_get_header(&m, "Action");
01938    if (strcasecmp(action, "login")) {
01939       act_found = action_find(action);
01940       if (act_found) {
01941          /*
01942           * we have to simulate a session for this action request
01943           * to be able to pass it down for processing
01944           * This is necessary to meet the previous design of manager.c
01945           */
01946          s.hook = hook;
01947          s.f = (void*)1; /* set this to something so our request will make it through all functions that test it*/
01948 
01949          ao2_lock(act_found);
01950          if (act_found->registered && act_found->func) {
01951             ++act_found->active_count;
01952             ao2_unlock(act_found);
01953             ret = act_found->func(&s, &m);
01954             ao2_lock(act_found);
01955             --act_found->active_count;
01956          } else {
01957             ret = -1;
01958          }
01959          ao2_unlock(act_found);
01960          ao2_t_ref(act_found, -1, "done with found action object");
01961       }
01962    }
01963    ast_free(dup_str);
01964    return ret;
01965 }

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

References eventqent::next.

Referenced by get_perm().

01221 {
01222    const char *val = bigstr, *next;
01223 
01224    do {
01225       if ((next = strchr(val, delim))) {
01226          if (!strncmp(val, smallstr, (next - val))) {
01227             return 1;
01228          } else {
01229             continue;
01230          }
01231       } else {
01232          return !strcmp(smallstr, val);
01233       }
01234    } while (*(val = (next + 1)));
01235 
01236    return 0;
01237 }

int ast_manager_register2 ( const char *  action,
int  authority,
int(*)(struct mansession *s, const struct message *m)  func,
const char *  synopsis,
const char *  description 
)

Register a manager command with the manager interface.

Parameters:
action Name of the requested Action:
authority Required authority for this command
func Function to call for this command
synopsis Help text (one line, up to 30 chars) for CLI manager show commands
description Help text, several lines

Definition at line 5314 of file manager.c.

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

Referenced by load_module().

05315 {
05316    struct manager_action *cur;
05317 
05318    cur = ao2_alloc(sizeof(*cur), action_destroy);
05319    if (!cur) {
05320       return -1;
05321    }
05322    if (ast_string_field_init(cur, 128)) {
05323       ao2_t_ref(cur, -1, "action object creation failed");
05324       return -1;
05325    }
05326 
05327    cur->action = action;
05328    cur->authority = auth;
05329    cur->func = func;
05330 #ifdef AST_XML_DOCS
05331    if (ast_strlen_zero(synopsis) && ast_strlen_zero(description)) {
05332       char *tmpxml;
05333 
05334       tmpxml = ast_xmldoc_build_synopsis("manager", action, NULL);
05335       ast_string_field_set(cur, synopsis, tmpxml);
05336       ast_free(tmpxml);
05337 
05338       tmpxml = ast_xmldoc_build_syntax("manager", action, NULL);
05339       ast_string_field_set(cur, syntax, tmpxml);
05340       ast_free(tmpxml);
05341 
05342       tmpxml = ast_xmldoc_build_description("manager", action, NULL);
05343       ast_string_field_set(cur, description, tmpxml);
05344       ast_free(tmpxml);
05345 
05346       tmpxml = ast_xmldoc_build_seealso("manager", action, NULL);
05347       ast_string_field_set(cur, seealso, tmpxml);
05348       ast_free(tmpxml);
05349 
05350       tmpxml = ast_xmldoc_build_arguments("manager", action, NULL);
05351       ast_string_field_set(cur, arguments, tmpxml);
05352       ast_free(tmpxml);
05353 
05354       cur->docsrc = AST_XML_DOC;
05355    } else
05356 #endif
05357    {
05358       ast_string_field_set(cur, synopsis, synopsis);
05359       ast_string_field_set(cur, description, description);
05360 #ifdef AST_XML_DOCS
05361       cur->docsrc = AST_STATIC_DOC;
05362 #endif
05363    }
05364    if (ast_manager_register_struct(cur)) {
05365       ao2_t_ref(cur, -1, "action object registration failed");
05366       return -1;
05367    }
05368 
05369    ao2_t_ref(cur, -1, "action object registration successful");
05370    return 0;
05371 }

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:
hook struct manager_custom_hook object to add

Definition at line 1076 of file manager.c.

References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and manager_action::list.

static int ast_manager_register_struct ( struct manager_action act  )  [static]

Definition at line 5259 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().

05260 {
05261    struct manager_action *cur, *prev = NULL;
05262 
05263    AST_RWLIST_WRLOCK(&actions);
05264    AST_RWLIST_TRAVERSE(&actions, cur, list) {
05265       int ret;
05266 
05267       ret = strcasecmp(cur->action, act->action);
05268       if (ret == 0) {
05269          ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
05270          AST_RWLIST_UNLOCK(&actions);
05271          return -1;
05272       }
05273       if (ret > 0) { /* Insert these alphabetically */
05274          prev = cur;
05275          break;
05276       }
05277    }
05278 
05279    ao2_t_ref(act, +1, "action object added to list");
05280    act->registered = 1;
05281    if (prev) {
05282       AST_RWLIST_INSERT_AFTER(&actions, prev, act, list);
05283    } else {
05284       AST_RWLIST_INSERT_HEAD(&actions, act, list);
05285    }
05286 
05287    ast_verb(2, "Manager registered action %s\n", act->action);
05288 
05289    AST_RWLIST_UNLOCK(&actions);
05290 
05291    return 0;
05292 }

int ast_manager_unregister ( char *  action  ) 

Unregister a registered manager command.

Parameters:
action Name of registered Action:

Definition at line 5200 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(), and unload_module().

05201 {
05202    struct manager_action *cur;
05203 
05204    AST_RWLIST_WRLOCK(&actions);
05205    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) {
05206       if (!strcasecmp(action, cur->action)) {
05207          AST_RWLIST_REMOVE_CURRENT(list);
05208          break;
05209       }
05210    }
05211    AST_RWLIST_TRAVERSE_SAFE_END;
05212    AST_RWLIST_UNLOCK(&actions);
05213 
05214    if (cur) {
05215       time_t now;
05216 
05217       /*
05218        * We have removed the action object from the container so we
05219        * are no longer in a hurry.
05220        */
05221       ao2_lock(cur);
05222       cur->registered = 0;
05223       ao2_unlock(cur);
05224 
05225       /*
05226        * Wait up to 5 seconds for any active invocations to complete
05227        * before returning.  We have to wait instead of blocking
05228        * because we may be waiting for ourself to complete.
05229        */
05230       now = time(NULL);
05231       while (cur->active_count) {
05232          if (5 <= time(NULL) - now) {
05233             ast_debug(1,
05234                "Unregister manager action %s timed out waiting for %d active instances to complete\n",
05235                action, cur->active_count);
05236             break;
05237          }
05238 
05239          sched_yield();
05240       }
05241 
05242       ao2_t_ref(cur, -1, "action object removed from list");
05243       ast_verb(2, "Manager unregistered action %s\n", action);
05244    }
05245 
05246    return 0;
05247 }

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:
hook struct manager_custom_hook object to delete

Definition at line 1084 of file manager.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, and manager_action::list.

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

utility functions for creating AMI replies

Definition at line 2011 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(), _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(), 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().

02012 {
02013    va_list ap;
02014    struct ast_str *buf;
02015 
02016    if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) {
02017       return;
02018    }
02019 
02020    va_start(ap, fmt);
02021    ast_str_set_va(&buf, 0, fmt, ap);
02022    va_end(ap);
02023 
02024    if (s->f != NULL || s->session->f != NULL) {
02025       send_string(s, ast_str_buffer(buf));
02026    } else {
02027       ast_verbose("fd == -1 in astman_append, should not happen\n");
02028    }
02029 }

static void astman_append_json ( struct mansession s,
const char *  str 
) [static]

Definition at line 2581 of file manager.c.

References astman_append(), and json_escape().

Referenced by action_getconfigjson().

02582 {
02583    char *buf;
02584 
02585    buf = alloca(2 * strlen(str) + 1);
02586    json_escape(buf, str);
02587    astman_append(s, "%s", buf);
02588 }

const char* astman_get_header ( const struct message m,
char *  var 
)

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

01814 {
01815    return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH);
01816 }

struct ast_variable* astman_get_variables ( const struct message m  ) 

Get a linked list of the Variable: headers.

Definition at line 1871 of file manager.c.

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

Referenced by action_originate(), and manager_sipnotify().

01872 {
01873    int varlen;
01874    int x;
01875    struct ast_variable *head = NULL;
01876 
01877    static const char var_hdr[] = "Variable:";
01878 
01879    /* Process all "Variable:" headers. */
01880    varlen = strlen(var_hdr);
01881    for (x = 0; x < m->hdrcount; x++) {
01882       if (strncasecmp(var_hdr, m->headers[x], varlen)) {
01883          continue;
01884       }
01885       head = man_do_variable_value(head, m->headers[x] + varlen);
01886    }
01887 
01888    return head;
01889 }

void astman_send_ack ( struct mansession s,
const struct message m,
char *  msg 
)

Send ack in manager transaction.

Definition at line 2078 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(), meetmemute(), start_monitor_action(), and stop_monitor_action().

02079 {
02080    astman_send_response_full(s, m, "Success", msg, NULL);
02081 }

void astman_send_error ( struct mansession s,
const struct message m,
char *  error 
)

Send error in manager transaction.

Definition at line 2073 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(), 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().

02074 {
02075    astman_send_response_full(s, m, "Error", error, NULL);
02076 }

void astman_send_listack ( struct mansession s,
const struct message m,
char *  msg,
char *  listflag 
)

Send ack in manager list transaction.

Definition at line 2088 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().

02089 {
02090    astman_send_response_full(s, m, "Success", msg, listflag);
02091 }

void astman_send_response ( struct mansession s,
const struct message m,
char *  resp,
char *  msg 
)

Send response in manager transaction.

Definition at line 2068 of file manager.c.

References astman_send_response_full().

Referenced by action_logoff().

02069 {
02070    astman_send_response_full(s, m, resp, msg, NULL);
02071 }

static void astman_send_response_full ( struct mansession s,
const struct message m,
char *  resp,
char *  msg,
char *  listflag 
) [static]

Definition at line 2048 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().

02049 {
02050    const char *id = astman_get_header(m, "ActionID");
02051 
02052    astman_append(s, "Response: %s\r\n", resp);
02053    if (!ast_strlen_zero(id)) {
02054       astman_append(s, "ActionID: %s\r\n", id);
02055    }
02056    if (listflag) {
02057       astman_append(s, "EventList: %s\r\n", listflag);   /* Start, complete, cancelled */
02058    }
02059    if (msg == MSG_MOREDATA) {
02060       return;
02061    } else if (msg) {
02062       astman_append(s, "Message: %s\r\n\r\n", msg);
02063    } else {
02064       astman_append(s, "\r\n");
02065    }
02066 }

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

Definition at line 2083 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().

02084 {
02085    astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL);
02086 }

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

Definition at line 2365 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, mansession_session::challenge, get_manager_by_name_locked(), len(), LOG_NOTICE, md5(), MD5Final(), MD5Init(), MD5Update(), mansession_session::readperm, report_auth_success(), report_failed_acl(), report_failed_challenge_response(), report_inval_password(), report_invalid_user(), S_OR, mansession::session, mansession_session::sessionstart, mansession_session::sessionstart_tv, set_eventmask(), mansession_session::sin, user, mansession_session::username, mansession_session::whitefilters, mansession_session::writeperm, and mansession_session::writetimeout.

02366 {
02367    const char *username = astman_get_header(m, "Username");
02368    const char *password = astman_get_header(m, "Secret");
02369    int error = -1;
02370    struct ast_manager_user *user = NULL;
02371    regex_t *regex_filter;
02372    struct ao2_iterator filter_iter;
02373    struct ast_sockaddr addr;
02374 
02375    if (ast_strlen_zero(username)) { /* missing username */
02376       return -1;
02377    }
02378 
02379    /* locate user in locked state */
02380    AST_RWLIST_WRLOCK(&users);
02381 
02382    ast_sockaddr_from_sin(&addr, &s->session->sin);
02383 
02384    if (!(user = get_manager_by_name_locked(username))) {
02385       report_invalid_user(s, username);
02386       ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
02387    } else if (user->ha && !ast_apply_ha(user->ha, &addr)) {
02388       report_failed_acl(s, username);
02389       ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
02390    } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
02391       const char *key = astman_get_header(m, "Key");
02392       if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
02393          int x;
02394          int len = 0;
02395          char md5key[256] = "";
02396          struct MD5Context md5;
02397          unsigned char digest[16];
02398 
02399          MD5Init(&md5);
02400          MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
02401          MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
02402          MD5Final(digest, &md5);
02403          for (x = 0; x < 16; x++)
02404             len += sprintf(md5key + len, "%2.2x", digest[x]);
02405          if (!strcmp(md5key, key)) {
02406             error = 0;
02407          } else {
02408             report_failed_challenge_response(s, key, md5key);
02409          }
02410       } else {
02411          ast_debug(1, "MD5 authentication is not possible.  challenge: '%s'\n",
02412             S_OR(s->session->challenge, ""));
02413       }
02414    } else if (user->secret) {
02415       if (!strcmp(password, user->secret)) {
02416          error = 0;
02417       } else {
02418          report_inval_password(s, username);
02419       }
02420    }
02421 
02422    if (error) {
02423       ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
02424       AST_RWLIST_UNLOCK(&users);
02425       return -1;
02426    }
02427 
02428    /* auth complete */
02429 
02430    /* All of the user parameters are copied to the session so that in the event
02431      * of a reload and a configuration change, the session parameters are not
02432      * changed. */
02433    ast_copy_string(s->session->username, username, sizeof(s->session->username));
02434    s->session->readperm = user->readperm;
02435    s->session->writeperm = user->writeperm;
02436    s->session->writetimeout = user->writetimeout;
02437 
02438    filter_iter = ao2_iterator_init(user->whitefilters, 0);
02439    while ((regex_filter = ao2_iterator_next(&filter_iter))) {
02440       ao2_t_link(s->session->whitefilters, regex_filter, "add white user filter to session");
02441       ao2_t_ref(regex_filter, -1, "remove iterator ref");
02442    }
02443    ao2_iterator_destroy(&filter_iter);
02444 
02445    filter_iter = ao2_iterator_init(user->blackfilters, 0);
02446    while ((regex_filter = ao2_iterator_next(&filter_iter))) {
02447       ao2_t_link(s->session->blackfilters, regex_filter, "add black user filter to session");
02448       ao2_t_ref(regex_filter, -1, "remove iterator ref");
02449    }
02450    ao2_iterator_destroy(&filter_iter);
02451 
02452    s->session->sessionstart = time(NULL);
02453    s->session->sessionstart_tv = ast_tvnow();
02454    set_eventmask(s, astman_get_header(m, "Events"));
02455 
02456    report_auth_success(s);
02457 
02458    AST_RWLIST_UNLOCK(&users);
02459    return 0;
02460 }

static const char* authority_to_str ( int  authority,
struct ast_str **  res 
) [static]

Convert authority code to a list of options.

Definition at line 1196 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_showmanager(), handle_showmancmd(), and handle_showmancmds().

01197 {
01198    int i;
01199    char *sep = "";
01200 
01201    ast_str_reset(*res);
01202    for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
01203       if (authority & perms[i].num) {
01204          ast_str_append(res, 0, "%s%s", sep, perms[i].label);
01205          sep = ",";
01206       }
01207    }
01208 
01209    if (ast_str_strlen(*res) == 0)   /* replace empty string with something sensible */
01210       ast_str_append(res, 0, "<none>");
01211 
01212    return ast_str_buffer(*res);
01213 }

static int blackfilter_cmp_fn ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Definition at line 4263 of file manager.c.

References CMP_MATCH, and CMP_STOP.

Referenced by match_filter().

04264 {
04265    regex_t *regex_filter = obj;
04266    const char *eventdata = arg;
04267    int *result = data;
04268 
04269    if (!regexec(regex_filter, eventdata, 0, NULL, 0)) {
04270       *result = 0;
04271       return (CMP_MATCH | CMP_STOP);
04272    }
04273 
04274    *result = 1;
04275    return 0;
04276 }

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

References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, AST_PTHREADT_NULL, and session_destructor().

Referenced by session_do().

01338 {
01339    struct mansession_session *newsession;
01340 
01341    if (!(newsession = ao2_alloc(sizeof(*newsession), session_destructor))) {
01342       return NULL;
01343    }
01344 
01345    if (!(newsession->whitefilters = ao2_container_alloc(1, NULL, NULL))) {
01346       ao2_ref(newsession, -1);
01347       return NULL;
01348    }
01349 
01350    if (!(newsession->blackfilters = ao2_container_alloc(1, NULL, NULL))) {
01351       ao2_ref(newsession, -1); /* session_destructor will cleanup the other filter */
01352       return NULL;
01353    }
01354 
01355    newsession->fd = -1;
01356    newsession->waiting_thread = AST_PTHREADT_NULL;
01357    newsession->writetimeout = 100;
01358    newsession->send_events = -1;
01359    newsession->sin = sin;
01360 
01361    ao2_link(sessions, newsession);
01362 
01363    return newsession;
01364 }

static int check_blacklist ( const char *  cmd  )  [static]

Definition at line 3580 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().

03581 {
03582    char *cmd_copy, *cur_cmd;
03583    char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, };
03584    int i;
03585 
03586    cmd_copy = ast_strdupa(cmd);
03587    for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) {
03588       cur_cmd = ast_strip(cur_cmd);
03589       if (ast_strlen_zero(cur_cmd)) {
03590          i--;
03591          continue;
03592       }
03593 
03594       cmd_words[i] = cur_cmd;
03595    }
03596 
03597    for (i = 0; i < ARRAY_LEN(command_blacklist); i++) {
03598       int j, match = 1;
03599 
03600       for (j = 0; command_blacklist[i].words[j]; j++) {
03601          if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) {
03602             match = 0;
03603             break;
03604          }
03605       }
03606 
03607       if (match) {
03608          return 1;
03609       }
03610    }
03611 
03612    return 0;
03613 }

int check_manager_enabled ( void   ) 

Check if AMI is enabled.

Definition at line 1091 of file manager.c.

Referenced by handle_show_settings().

01092 {
01093    return manager_enabled;
01094 }

static int check_manager_session_inuse ( const char *  name  )  [static]

Definition at line 1380 of file manager.c.

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

Referenced by process_message().

01381 {
01382    struct mansession_session *session = ao2_find(sessions, (char *) name, 0);
01383    int inuse = 0;
01384 
01385    if (session) {
01386       inuse = 1;
01387       unref_mansession(session);
01388    }
01389    return inuse;
01390 }

int check_webmanager_enabled ( void   ) 

Check if AMI/HTTP is enabled.

Definition at line 1096 of file manager.c.

Referenced by action_coresettings(), and handle_show_settings().

01097 {
01098    return (webmanager_enabled && manager_enabled);
01099 }

static void destroy_fast_originate_helper ( struct fast_originate_helper doomed  )  [static]

Definition at line 3717 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().

03718 {
03719    ast_variables_destroy(doomed->vars);
03720    ast_string_field_free_memory(doomed);
03721    ast_free(doomed);
03722 }

static int do_message ( struct mansession s  )  [static]

Definition at line 4851 of file manager.c.

References ARRAY_LEN, ast_free, ast_inet_ntoa(), ast_log(), ast_strdup, ast_strlen_zero(), ast_verb, astman_send_error(), authtimeout, displayconnects, errno, get_input(), message::hdrcount, message::headers, mansession_session::inbuf, LOG_ERROR, mansession_lock(), mansession_unlock(), process_events(), process_message(), and mansession::session.

Referenced by session_do().

04852 {
04853    struct message m = { 0 };
04854    char header_buf[sizeof(s->session->inbuf)] = { '\0' };
04855    int res;
04856    int idx;
04857    int hdr_loss;
04858    time_t now;
04859 
04860    hdr_loss = 0;
04861    for (;;) {
04862       /* Check if any events are pending and do them if needed */
04863       if (process_events(s)) {
04864          res = -1;
04865          break;
04866       }
04867       res = get_input(s, header_buf);
04868       if (res == 0) {
04869          /* No input line received. */
04870          if (!s->session->authenticated) {
04871             if (time(&now) == -1) {
04872                ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
04873                res = -1;
04874                break;
04875             }
04876 
04877             if (now - s->session->authstart > authtimeout) {
04878                if (displayconnects) {
04879                   ast_verb(2, "Client from %s, failed to authenticate in %d seconds\n", ast_inet_ntoa(s->session->sin.sin_addr), authtimeout);
04880                }
04881                res = -1;
04882                break;
04883             }
04884          }
04885          continue;
04886       } else if (res > 0) {
04887          /* Input line received. */
04888          if (ast_strlen_zero(header_buf)) {
04889             if (hdr_loss) {
04890                mansession_lock(s);
04891                astman_send_error(s, &m, "Too many lines in message or allocation failure");
04892                mansession_unlock(s);
04893                res = 0;
04894             } else {
04895                res = process_message(s, &m) ? -1 : 0;
04896             }
04897             break;
04898          } else if (m.hdrcount < ARRAY_LEN(m.headers)) {
04899             m.headers[m.hdrcount] = ast_strdup(header_buf);
04900             if (!m.headers[m.hdrcount]) {
04901                /* Allocation failure. */
04902                hdr_loss = 1;
04903             } else {
04904                ++m.hdrcount;
04905             }
04906          } else {
04907             /* Too many lines in message. */
04908             hdr_loss = 1;
04909          }
04910       } else {
04911          /* Input error. */
04912          break;
04913       }
04914    }
04915 
04916    /* Free AMI request headers. */
04917    for (idx = 0; idx < m.hdrcount; ++idx) {
04918       ast_free((void *) m.headers[idx]);
04919    }
04920    return res;
04921 }

static void event_filter_destructor ( void *  obj  )  [static]

Definition at line 1300 of file manager.c.

01301 {
01302    regex_t *regex_filter = obj;
01303    regfree(regex_filter);
01304 }

static void* fast_originate ( void *  data  )  [static]

Definition at line 3724 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, 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().

03725 {
03726    struct fast_originate_helper *in = data;
03727    int res;
03728    int reason = 0;
03729    struct ast_channel *chan = NULL, *chans[1];
03730    char requested_channel[AST_CHANNEL_NAME];
03731 
03732    if (!ast_strlen_zero(in->app)) {
03733       res = ast_pbx_outgoing_app(in->tech, in->format, (char *) in->data,
03734          in->timeout, in->app, in->appdata, &reason, 1,
03735          S_OR(in->cid_num, NULL),
03736          S_OR(in->cid_name, NULL),
03737          in->vars, in->account, &chan);
03738    } else {
03739       res = ast_pbx_outgoing_exten(in->tech, in->format, (char *) in->data,
03740          in->timeout, in->context, in->exten, in->priority, &reason, 1,
03741          S_OR(in->cid_num, NULL),
03742          S_OR(in->cid_name, NULL),
03743          in->vars, in->account, &chan);
03744    }
03745    /* Any vars memory was passed to the ast_pbx_outgoing_xxx() calls. */
03746    in->vars = NULL;
03747 
03748    if (!chan) {
03749       snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);
03750    }
03751    /* Tell the manager what happened with the channel */
03752    chans[0] = chan;
03753    ast_manager_event_multichan(EVENT_FLAG_CALL, "OriginateResponse", chan ? 1 : 0, chans,
03754       "%s"
03755       "Response: %s\r\n"
03756       "Channel: %s\r\n"
03757       "Context: %s\r\n"
03758       "Exten: %s\r\n"
03759       "Reason: %d\r\n"
03760       "Uniqueid: %s\r\n"
03761       "CallerIDNum: %s\r\n"
03762       "CallerIDName: %s\r\n",
03763       in->idtext, res ? "Failure" : "Success",
03764       chan ? chan->name : requested_channel, in->context, in->exten, reason,
03765       chan ? chan->uniqueid : "<null>",
03766       S_OR(in->cid_num, "<unknown>"),
03767       S_OR(in->cid_name, "<unknown>")
03768       );
03769 
03770    /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
03771    if (chan) {
03772       ast_channel_unlock(chan);
03773    }
03774    destroy_fast_originate_helper(in);
03775    return NULL;
03776 }

static void free_channelvars ( void   )  [static]

Definition at line 7012 of file manager.c.

References ast_free, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, manager_channel_variable::entry, and var.

Referenced by __init_manager(), and load_channelvars().

07013 {
07014    struct manager_channel_variable *var;
07015    AST_RWLIST_WRLOCK(&channelvars);
07016    while ((var = AST_RWLIST_REMOVE_HEAD(&channelvars, entry))) {
07017       ast_free(var);
07018    }
07019    AST_RWLIST_UNLOCK(&channelvars);
07020 }

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

References EVENT_FLAG_SYSTEM.

Referenced by action_getvar(), and action_status().

01184 {
01185    if (!(writepermlist & EVENT_FLAG_SYSTEM)
01186       && (
01187          strstr(evaluating, "SHELL") ||       /* NoOp(${SHELL(rm -rf /)})  */
01188          strstr(evaluating, "EVAL")           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
01189       )) {
01190       return 0;
01191    }
01192    return 1;
01193 }

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

References mansession_session::inbuf, mansession_session::inlen, mansession::session, and ast_frame::src.

04755 {
04756    int res, x;
04757    int maxlen = sizeof(s->session->inbuf) - 1;
04758    char *src = s->session->inbuf;
04759    int timeout = -1;
04760    time_t now;
04761 
04762    /*
04763     * Look for \r\n within the buffer. If found, copy to the output
04764     * buffer and return, trimming the \r\n (not used afterwards).
04765     */
04766    for (x = 0; x < s->session->inlen; x++) {
04767       int cr;  /* set if we have \r */
04768       if (src[x] == '\r' && x+1 < s->session->inlen && src[x + 1] == '\n') {
04769          cr = 2;  /* Found. Update length to include \r\n */
04770       } else if (src[x] == '\n') {
04771          cr = 1;  /* also accept \n only */
04772       } else {
04773          continue;
04774       }
04775       memmove(output, src, x);   /*... but trim \r\n */
04776       output[x] = '\0';    /* terminate the string */
04777       x += cr;       /* number of bytes used */
04778       s->session->inlen -= x;       /* remaining size */
04779       memmove(src, src + x, s->session->inlen); /* remove used bytes */
04780       return 1;
04781    }
04782    if (s->session->inlen >= maxlen) {
04783       /* no crlf found, and buffer full - sorry, too long for us */
04784       ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src);
04785       s->session->inlen = 0;
04786    }
04787    res = 0;
04788    while (res == 0) {
04789       /* calculate a timeout if we are not authenticated */
04790       if (!s->session->authenticated) {
04791          if(time(&now) == -1) {
04792             ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
04793             return -1;
04794          }
04795 
04796          timeout = (authtimeout - (now - s->session->authstart)) * 1000;
04797          if (timeout < 0) {
04798             /* we have timed out */
04799             return 0;
04800          }
04801       }
04802 
04803       ao2_lock(s->session);
04804       if (s->session->pending_event) {
04805          s->session->pending_event = 0;
04806          ao2_unlock(s->session);
04807          return 0;
04808       }
04809       s->session->waiting_thread = pthread_self();
04810       ao2_unlock(s->session);
04811 
04812       res = ast_wait_for_input(s->session->fd, timeout);
04813 
04814       ao2_lock(s->session);
04815       s->session->waiting_thread = AST_PTHREADT_NULL;
04816       ao2_unlock(s->session);
04817    }
04818    if (res < 0) {
04819       /* If we get a signal from some other thread (typically because
04820        * there are new events queued), return 0 to notify the caller.
04821        */
04822       if (errno == EINTR || errno == EAGAIN) {
04823          return 0;
04824       }
04825       ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
04826       return -1;
04827    }
04828 
04829    ao2_lock(s->session);
04830    res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f);
04831    if (res < 1) {
04832       res = -1;   /* error return */
04833    } else {
04834       s->session->inlen += res;
04835       src[s->session->inlen] = '\0';
04836       res = 0;
04837    }
04838    ao2_unlock(s->session);
04839    return res;
04840 }

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

References AST_RWLIST_TRAVERSE, ast_manager_user::list, and user.

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

01398 {
01399    struct ast_manager_user *user = NULL;
01400 
01401    AST_RWLIST_TRAVERSE(&users, user, list) {
01402       if (!strcasecmp(user->username, name)) {
01403          break;
01404       }
01405    }
01406 
01407    return user;
01408 }

static int get_perm ( const char *  instr  )  [static]

Definition at line 1239 of file manager.c.

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

Referenced by strings_to_mask().

01240 {
01241    int x = 0, ret = 0;
01242 
01243    if (!instr) {
01244       return 0;
01245    }
01246 
01247    for (x = 0; x < ARRAY_LEN(perms); x++) {
01248       if (ast_instring(instr, perms[x].label, ',')) {
01249          ret |= perms[x].num;
01250       }
01251    }
01252 
01253    return ret;
01254 }

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

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

Referenced by session_do().

01106 {
01107    struct eventqent *ret;
01108 
01109    AST_RWLIST_WRLOCK(&all_events);
01110    ret = AST_RWLIST_LAST(&all_events);
01111    /* the list is never empty now, but may become so when
01112     * we optimize it in the future, so be prepared.
01113     */
01114    if (ret) {
01115       ast_atomic_fetchadd_int(&ret->usecount, 1);
01116    }
01117    AST_RWLIST_UNLOCK(&all_events);
01118    return ret;
01119 }

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 1731 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.

01732 {
01733    switch (cmd) {
01734    case CLI_INIT:
01735       e->command = "manager reload";
01736       e->usage =
01737          "Usage: manager reload\n"
01738          "       Reloads the manager configuration.\n";
01739       return NULL;
01740    case CLI_GENERATE:
01741       return NULL;
01742    }
01743    if (a->argc > 2) {
01744       return CLI_SHOWUSAGE;
01745    }
01746    reload_manager();
01747    return CLI_SUCCESS;
01748 }

static char* handle_mandebug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1505 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.

01506 {
01507    switch (cmd) {
01508    case CLI_INIT:
01509       e->command = "manager set debug [on|off]";
01510       e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n";
01511       return NULL;
01512    case CLI_GENERATE:
01513       return NULL;
01514    }
01515 
01516    if (a->argc == 3) {
01517       ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off");
01518    } else if (a->argc == 4) {
01519       if (!strcasecmp(a->argv[3], "on")) {
01520          manager_debug = 1;
01521       } else if (!strcasecmp(a->argv[3], "off")) {
01522          manager_debug = 0;
01523       } else {
01524          return CLI_SHOWUSAGE;
01525       }
01526    }
01527    return CLI_SUCCESS;
01528 }

static char* handle_showmanager ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1530 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, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_manager_by_name_locked(), ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, user, and ast_cli_args::word.

01531 {
01532    struct ast_manager_user *user = NULL;
01533    int l, which;
01534    char *ret = NULL;
01535    struct ast_str *rauthority = ast_str_alloca(128);
01536    struct ast_str *wauthority = ast_str_alloca(128);
01537 
01538    switch (cmd) {
01539    case CLI_INIT:
01540       e->command = "manager show user";
01541       e->usage =
01542          " Usage: manager show user <user>\n"
01543          "        Display all information related to the manager user specified.\n";
01544       return NULL;
01545    case CLI_GENERATE:
01546       l = strlen(a->word);
01547       which = 0;
01548       if (a->pos != 3) {
01549          return NULL;
01550       }
01551       AST_RWLIST_RDLOCK(&users);
01552       AST_RWLIST_TRAVERSE(&users, user, list) {
01553          if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) {
01554             ret = ast_strdup(user->username);
01555             break;
01556          }
01557       }
01558       AST_RWLIST_UNLOCK(&users);
01559       return ret;
01560    }
01561 
01562    if (a->argc != 4) {
01563       return CLI_SHOWUSAGE;
01564    }
01565 
01566    AST_RWLIST_RDLOCK(&users);
01567 
01568    if (!(user = get_manager_by_name_locked(a->argv[3]))) {
01569       ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]);
01570       AST_RWLIST_UNLOCK(&users);
01571       return CLI_SUCCESS;
01572    }
01573 
01574    ast_cli(a->fd, "\n");
01575    ast_cli(a->fd,
01576       "       username: %s\n"
01577       "         secret: %s\n"
01578       "            acl: %s\n"
01579       "      read perm: %s\n"
01580       "     write perm: %s\n"
01581       "displayconnects: %s\n",
01582       (user->username ? user->username : "(N/A)"),
01583       (user->secret ? "<Set>" : "(N/A)"),
01584       (user->ha ? "yes" : "no"),
01585       authority_to_str(user->readperm, &rauthority),
01586       authority_to_str(user->writeperm, &wauthority),
01587       (user->displayconnects ? "yes" : "no"));
01588 
01589    AST_RWLIST_UNLOCK(&users);
01590 
01591    return CLI_SUCCESS;
01592 }

static char* handle_showmanagers ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1594 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_manager_user::list, ast_cli_entry::usage, and user.

01595 {
01596    struct ast_manager_user *user = NULL;
01597    int count_amu = 0;
01598    switch (cmd) {
01599    case CLI_INIT:
01600       e->command = "manager show users";
01601       e->usage =
01602          "Usage: manager show users\n"
01603          "       Prints a listing of all managers that are currently configured on that\n"
01604          " system.\n";
01605       return NULL;
01606    case CLI_GENERATE:
01607       return NULL;
01608    }
01609    if (a->argc != 3) {
01610       return CLI_SHOWUSAGE;
01611    }
01612 
01613    AST_RWLIST_RDLOCK(&users);
01614 
01615    /* If there are no users, print out something along those lines */
01616    if (AST_RWLIST_EMPTY(&users)) {
01617       ast_cli(a->fd, "There are no manager users.\n");
01618       AST_RWLIST_UNLOCK(&users);
01619       return CLI_SUCCESS;
01620    }
01621 
01622    ast_cli(a->fd, "\nusername\n--------\n");
01623 
01624    AST_RWLIST_TRAVERSE(&users, user, list) {
01625       ast_cli(a->fd, "%s\n", user->username);
01626       count_amu++;
01627    }
01628 
01629    AST_RWLIST_UNLOCK(&users);
01630 
01631    ast_cli(a->fd,"-------------------\n"
01632             "%d manager users configured.\n", count_amu);
01633    return CLI_SUCCESS;
01634 }

static char* handle_showmancmd ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1428 of file manager.c.

References manager_action::action, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), 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, COLOR_MAGENTA, ast_cli_entry::command, manager_action::docsrc, ast_cli_args::fd, ast_cli_args::n, S_OR, term_color(), ast_cli_entry::usage, and ast_cli_args::word.

01429 {
01430    struct manager_action *cur;
01431    struct ast_str *authority;
01432    int num, l, which;
01433    char *ret = NULL;
01434 #ifdef AST_XML_DOCS
01435    char syntax_title[64], description_title[64], synopsis_title[64], seealso_title[64], arguments_title[64];
01436 #endif
01437 
01438    switch (cmd) {
01439    case CLI_INIT:
01440       e->command = "manager show command";
01441       e->usage =
01442          "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n"
01443          "  Shows the detailed description for a specific Asterisk manager interface command.\n";
01444       return NULL;
01445    case CLI_GENERATE:
01446       l = strlen(a->word);
01447       which = 0;
01448       AST_RWLIST_RDLOCK(&actions);
01449       AST_RWLIST_TRAVERSE(&actions, cur, list) {
01450          if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) {
01451             ret = ast_strdup(cur->action);
01452             break;   /* make sure we exit even if ast_strdup() returns NULL */
01453          }
01454       }
01455       AST_RWLIST_UNLOCK(&actions);
01456       return ret;
01457    }
01458    authority = ast_str_alloca(80);
01459    if (a->argc < 4) {
01460       return CLI_SHOWUSAGE;
01461    }
01462 
01463 #ifdef AST_XML_DOCS
01464    /* setup the titles */
01465    term_color(synopsis_title, "[Synopsis]\n", COLOR_MAGENTA, 0, 40);
01466    term_color(description_title, "[Description]\n", COLOR_MAGENTA, 0, 40);
01467    term_color(syntax_title, "[Syntax]\n", COLOR_MAGENTA, 0, 40);
01468    term_color(seealso_title, "[See Also]\n", COLOR_MAGENTA, 0, 40);
01469    term_color(arguments_title, "[Arguments]\n", COLOR_MAGENTA, 0, 40);
01470 #endif
01471 
01472    AST_RWLIST_RDLOCK(&actions);
01473    AST_RWLIST_TRAVERSE(&actions, cur, list) {
01474       for (num = 3; num < a->argc; num++) {
01475          if (!strcasecmp(cur->action, a->argv[num])) {
01476 #ifdef AST_XML_DOCS
01477             if (cur->docsrc == AST_XML_DOC) {
01478                ast_cli(a->fd, "%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n%s%s\n\n",
01479                   syntax_title,
01480                   ast_xmldoc_printable(S_OR(cur->syntax, "Not available"), 1),
01481                   synopsis_title,
01482                   ast_xmldoc_printable(S_OR(cur->synopsis, "Not available"), 1),
01483                   description_title,
01484                   ast_xmldoc_printable(S_OR(cur->description, "Not available"), 1),
01485                   arguments_title,
01486                   ast_xmldoc_printable(S_OR(cur->arguments, "Not available"), 1),
01487                   seealso_title,
01488                   ast_xmldoc_printable(S_OR(cur->seealso, "Not available"), 1));
01489             } else
01490 #endif
01491             {
01492                ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
01493                   cur->action, cur->synopsis,
01494                   authority_to_str(cur->authority, &authority),
01495                   S_OR(cur->description, ""));
01496             }
01497          }
01498       }
01499    }
01500    AST_RWLIST_UNLOCK(&actions);
01501 
01502    return CLI_SUCCESS;
01503 }

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 1637 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.

01638 {
01639    struct manager_action *cur;
01640    struct ast_str *authority;
01641 #define HSMC_FORMAT "  %-15.15s  %-15.15s  %-55.55s\n"
01642    switch (cmd) {
01643    case CLI_INIT:
01644       e->command = "manager show commands";
01645       e->usage =
01646          "Usage: manager show commands\n"
01647          "  Prints a listing of all the available Asterisk manager interface commands.\n";
01648       return NULL;
01649    case CLI_GENERATE:
01650       return NULL;
01651    }
01652    authority = ast_str_alloca(80);
01653    ast_cli(a->fd, HSMC_FORMAT, "Action", "Privilege", "Synopsis");
01654    ast_cli(a->fd, HSMC_FORMAT, "------", "---------", "--------");
01655 
01656    AST_RWLIST_RDLOCK(&actions);
01657    AST_RWLIST_TRAVERSE(&actions, cur, list) {
01658       ast_cli(a->fd, HSMC_FORMAT, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis);
01659    }
01660    AST_RWLIST_UNLOCK(&actions);
01661 
01662    return CLI_SUCCESS;
01663 }

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 1666 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, HSMCONN_FORMAT1, HSMCONN_FORMAT2, unref_mansession(), and ast_cli_entry::usage.

01667 {
01668    struct mansession_session *session;
01669    time_t now = time(NULL);
01670 #define HSMCONN_FORMAT1 "  %-15.15s  %-15.15s  %-10.10s  %-10.10s  %-8.8s  %-8.8s  %-5.5s  %-5.5s\n"
01671 #define HSMCONN_FORMAT2 "  %-15.15s  %-15.15s  %-10d  %-10d  %-8d  %-8d  %-5.5d  %-5.5d\n"
01672    int count = 0;
01673    struct ao2_iterator i;
01674 
01675    switch (cmd) {
01676    case CLI_INIT:
01677       e->command = "manager show connected";
01678       e->usage =
01679          "Usage: manager show connected\n"
01680          "  Prints a listing of the users that are currently connected to the\n"
01681          "Asterisk manager interface.\n";
01682       return NULL;
01683    case CLI_GENERATE:
01684       return NULL;
01685    }
01686 
01687    ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write");
01688 
01689    i = ao2_iterator_init(sessions, 0);
01690    while ((session = ao2_iterator_next(&i))) {
01691       ao2_lock(session);
01692       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);
01693       count++;
01694       ao2_unlock(session);
01695       unref_mansession(session);
01696    }
01697    ao2_iterator_destroy(&i);
01698    ast_cli(a->fd, "%d users connected.\n", count);
01699 
01700    return CLI_SUCCESS;
01701 }

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 1705 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, eventqent::eq_next, eventqent::eventdata, ast_cli_args::fd, ast_cli_entry::usage, and eventqent::usecount.

01706 {
01707    struct eventqent *s;
01708    switch (cmd) {
01709    case CLI_INIT:
01710       e->command = "manager show eventq";
01711       e->usage =
01712          "Usage: manager show eventq\n"
01713          "  Prints a listing of all events pending in the Asterisk manger\n"
01714          "event queue.\n";
01715       return NULL;
01716    case CLI_GENERATE:
01717       return NULL;
01718    }
01719    AST_RWLIST_RDLOCK(&all_events);
01720    AST_RWLIST_TRAVERSE(&all_events, s, eq_next) {
01721       ast_cli(a->fd, "Usecount: %d\n", s->usecount);
01722       ast_cli(a->fd, "Category: %d\n", s->category);
01723       ast_cli(a->fd, "Event:\n%s", s->eventdata);
01724    }
01725    AST_RWLIST_UNLOCK(&all_events);
01726 
01727    return CLI_SUCCESS;
01728 }

static enum error_type handle_updates ( struct mansession s,
const struct message m,
struct ast_config cfg,
const char *  dfn 
) [static]

Definition at line 2639 of file manager.c.

References ast_category_append(), ast_category_delete(), 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(), 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().

02640 {
02641    int x;
02642    char hdr[40];
02643    const char *action, *cat, *var, *value, *match, *line;
02644    struct ast_category *category;
02645    struct ast_variable *v;
02646    struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
02647    enum error_type result = 0;
02648 
02649    for (x = 0; x < 100000; x++) {   /* 100000 = the max number of allowed updates + 1 */
02650       unsigned int object = 0;
02651 
02652       snprintf(hdr, sizeof(hdr), "Action-%06d", x);
02653       action = astman_get_header(m, hdr);
02654       if (ast_strlen_zero(action))     /* breaks the for loop if no action header */
02655          break;                        /* this could cause problems if actions come in misnumbered */
02656 
02657       snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
02658       cat = astman_get_header(m, hdr);
02659       if (ast_strlen_zero(cat)) {      /* every action needs a category */
02660          result =  UNSPECIFIED_CATEGORY;
02661          break;
02662       }
02663 
02664       snprintf(hdr, sizeof(hdr), "Var-%06d", x);
02665       var = astman_get_header(m, hdr);
02666 
02667       snprintf(hdr, sizeof(hdr), "Value-%06d", x);
02668       value = astman_get_header(m, hdr);
02669 
02670       if (!ast_strlen_zero(value) && *value == '>') {
02671          object = 1;
02672          value++;
02673       }
02674 
02675       snprintf(hdr, sizeof(hdr), "Match-%06d", x);
02676       match = astman_get_header(m, hdr);
02677 
02678       snprintf(hdr, sizeof(hdr), "Line-%06d", x);
02679       line = astman_get_header(m, hdr);
02680 
02681       if (!strcasecmp(action, "newcat")) {
02682          if (ast_category_get(cfg,cat)) { /* check to make sure the cat doesn't */
02683             result = FAILURE_NEWCAT;   /* already exist */
02684             break;
02685          }
02686          if (!(category = ast_category_new(cat, dfn, -1))) {
02687             result = FAILURE_ALLOCATION;
02688             break;
02689          }
02690          if (ast_strlen_zero(match)) {
02691             ast_category_append(cfg, category);
02692          } else {
02693             ast_category_insert(cfg, category, match);
02694          }
02695       } else if (!strcasecmp(action, "renamecat")) {
02696          if (ast_strlen_zero(value)) {
02697             result = UNSPECIFIED_ARGUMENT;
02698             break;
02699          }
02700          if (!(category = ast_category_get(cfg, cat))) {
02701             result = UNKNOWN_CATEGORY;
02702             break;
02703          }
02704          ast_category_rename(category, value);
02705       } else if (!strcasecmp(action, "delcat")) {
02706          if (ast_category_delete(cfg, cat)) {
02707             result = FAILURE_DELCAT;
02708             break;
02709          }
02710       } else if (!strcasecmp(action, "emptycat")) {
02711          if (ast_category_empty(cfg, cat)) {
02712             result = FAILURE_EMPTYCAT;
02713             break;
02714          }
02715       } else if (!strcasecmp(action, "update")) {
02716          if (ast_strlen_zero(var)) {
02717             result = UNSPECIFIED_ARGUMENT;
02718             break;
02719          }
02720          if (!(category = ast_category_get(cfg,cat))) {
02721             result = UNKNOWN_CATEGORY;
02722             break;
02723          }
02724          if (ast_variable_update(category, var, value, match, object)) {
02725             result = FAILURE_UPDATE;
02726             break;
02727          }
02728       } else if (!strcasecmp(action, "delete")) {
02729          if ((ast_strlen_zero(var) && ast_strlen_zero(line))) {
02730             result = UNSPECIFIED_ARGUMENT;
02731             break;
02732          }
02733          if (!(category = ast_category_get(cfg, cat))) {
02734             result = UNKNOWN_CATEGORY;
02735             break;
02736          }
02737          if (ast_variable_delete(category, var, match, line)) {
02738             result = FAILURE_DELETE;
02739             break;
02740          }
02741       } else if (!strcasecmp(action, "append")) {
02742          if (ast_strlen_zero(var)) {
02743             result = UNSPECIFIED_ARGUMENT;
02744             break;
02745          }
02746          if (!(category = ast_category_get(cfg, cat))) {
02747             result = UNKNOWN_CATEGORY;
02748             break;
02749          }
02750          if (!(v = ast_variable_new(var, value, dfn))) {
02751             result = FAILURE_ALLOCATION;
02752             break;
02753          }
02754          if (object || (match && !strcasecmp(match, "object"))) {
02755             v->object = 1;
02756          }
02757          ast_variable_append(category, v);
02758       } else if (!strcasecmp(action, "insert")) {
02759          if (ast_strlen_zero(var) || ast_strlen_zero(line)) {
02760             result = UNSPECIFIED_ARGUMENT;
02761             break;
02762          }
02763          if (!(category = ast_category_get(cfg, cat))) {
02764             result = UNKNOWN_CATEGORY;
02765             break;
02766          }
02767          if (!(v = ast_variable_new(var, value, dfn))) {
02768             result = FAILURE_ALLOCATION;
02769             break;
02770          }
02771          ast_variable_insert(category, v, line);
02772       }
02773       else {
02774          ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action);
02775          result = UNKNOWN_ACTION;
02776          break;
02777       }
02778    }
02779    ast_free(str1);
02780    ast_free(str2);
02781    return result;
02782 }

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

Referenced by astman_append_json().

02562 {
02563    for (; *in; in++) {
02564       if (*in == '\\' || *in == '\"') {
02565          *out++ = '\\';
02566       }
02567       *out++ = *in;
02568    }
02569    *out = '\0';
02570 }

static struct ast_variable* man_do_variable_value ( struct ast_variable head,
const char *  hdr_val 
) [static]

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

Referenced by astman_get_variables().

01828 {
01829    char *parse;
01830    AST_DECLARE_APP_ARGS(args,
01831       AST_APP_ARG(vars)[64];
01832    );
01833 
01834    hdr_val = ast_skip_blanks(hdr_val); /* ignore leading spaces in the value */
01835    parse = ast_strdupa(hdr_val);
01836 
01837    /* Break the header value string into name=val pair items. */
01838    AST_STANDARD_APP_ARGS(args, parse);
01839    if (args.argc) {
01840       int y;
01841 
01842       /* Process each name=val pair item. */
01843       for (y = 0; y < args.argc; y++) {
01844          struct ast_variable *cur;
01845          char *var;
01846          char *val;
01847 
01848          if (!args.vars[y]) {
01849             continue;
01850          }
01851          var = val = args.vars[y];
01852          strsep(&val, "=");
01853 
01854          /* XXX We may wish to trim whitespace from the strings. */
01855          if (!val || ast_strlen_zero(var)) {
01856             continue;
01857          }
01858 
01859          /* Create new variable list node and prepend it to the list. */
01860          cur = ast_variable_new(var, val, "");
01861          if (cur) {
01862             cur->next = head;
01863             head = cur;
01864          }
01865       }
01866    }
01867 
01868    return head;
01869 }

static int manager_displayconnects ( struct mansession_session session  )  [static]

Get displayconnects config option.

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

Definition at line 1414 of file manager.c.

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

Referenced by action_login(), and purge_sessions().

01415 {
01416    struct ast_manager_user *user = NULL;
01417    int ret = 0;
01418 
01419    AST_RWLIST_RDLOCK(&users);
01420    if ((user = get_manager_by_name_locked (session->username))) {
01421       ret = user->displayconnects;
01422    }
01423    AST_RWLIST_UNLOCK(&users);
01424 
01425    return ret;
01426 }

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

Definition at line 4544 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().

04545 {
04546    int res;
04547    const char *module = astman_get_header(m, "Module");
04548    const char *id = astman_get_header(m, "ActionID");
04549    char idText[256];
04550 #if !defined(LOW_MEMORY)
04551    const char *version;
04552 #endif
04553    char filename[PATH_MAX];
04554    char *cut;
04555 
04556    ast_copy_string(filename, module, sizeof(filename));
04557    if ((cut = strchr(filename, '.'))) {
04558       *cut = '\0';
04559    } else {
04560       cut = filename + strlen(filename);
04561    }
04562    snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so");
04563    ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename);
04564    res = ast_module_check(filename);
04565    if (!res) {
04566       astman_send_error(s, m, "Module not loaded");
04567       return 0;
04568    }
04569    snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c");
04570    ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename);
04571 #if !defined(LOW_MEMORY)
04572    version = ast_file_version_find(filename);
04573 #endif
04574 
04575    if (!ast_strlen_zero(id)) {
04576       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
04577    } else {
04578       idText[0] = '\0';
04579    }
04580    astman_append(s, "Response: Success\r\n%s", idText);
04581 #if !defined(LOW_MEMORY)
04582    astman_append(s, "Version: %s\r\n\r\n", version ? version : "");
04583 #endif
04584    return 0;
04585 }

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

Definition at line 4587 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().

04588 {
04589    int res;
04590    const char *module = astman_get_header(m, "Module");
04591    const char *loadtype = astman_get_header(m, "LoadType");
04592 
04593    if (!loadtype || strlen(loadtype) == 0) {
04594       astman_send_error(s, m, "Incomplete ModuleLoad action.");
04595    }
04596    if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) {
04597       astman_send_error(s, m, "Need module name");
04598    }
04599 
04600    if (!strcasecmp(loadtype, "load")) {
04601       res = ast_load_resource(module);
04602       if (res) {
04603          astman_send_error(s, m, "Could not load module.");
04604       } else {
04605          astman_send_ack(s, m, "Module loaded.");
04606       }
04607    } else if (!strcasecmp(loadtype, "unload")) {
04608       res = ast_unload_resource(module, AST_FORCE_SOFT);
04609       if (res) {
04610          astman_send_error(s, m, "Could not unload module.");
04611       } else {
04612          astman_send_ack(s, m, "Module unloaded.");
04613       }
04614    } else if (!strcasecmp(loadtype, "reload")) {
04615       if (!ast_strlen_zero(module)) {
04616          res = ast_module_reload(module);
04617          if (res == 0) {
04618             astman_send_error(s, m, "No such module.");
04619          } else if (res == 1) {
04620             astman_send_error(s, m, "Module does not support reload action.");
04621          } else {
04622             astman_send_ack(s, m, "Module reloaded.");
04623          }
04624       } else {
04625          ast_module_reload(NULL);   /* Reload all modules */
04626          astman_send_ack(s, m, "All modules reloaded");
04627       }
04628    } else
04629       astman_send_error(s, m, "Incomplete ModuleLoad action.");
04630    return 0;
04631 }

static int manager_state_cb ( char *  context,
char *  exten,
int  state,
void *  data 
) [static]

Definition at line 5249 of file manager.c.

References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.

Referenced by __init_manager().

05250 {
05251    /* Notify managers of change */
05252    char hint[512];
05253    ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
05254 
05255    manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state);
05256    return 0;
05257 }

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

Definition at line 1366 of file manager.c.

References CMP_MATCH, str, and mansession_session::username.

01367 {
01368    struct mansession_session *s = obj;
01369    char *str = arg;
01370    return !strcasecmp(s->username, str) ? CMP_MATCH : 0;
01371 }

static struct sockaddr_in* mansession_encode_sin_local ( const struct mansession s,
struct sockaddr_in *  sin_local 
) [static]

Definition at line 2128 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().

02130 {
02131    ast_sockaddr_to_sin(&s->tcptls_session->parent->local_address,
02132              sin_local);
02133 
02134    return sin_local;
02135 }

static enum ast_security_event_transport_type mansession_get_transport ( const struct mansession s  )  [static]

Definition at line 2122 of file manager.c.

References AST_SECURITY_EVENT_TRANSPORT_TCP, AST_SECURITY_EVENT_TRANSPORT_TLS, ast_tcptls_session_instance::parent, mansession::tcptls_session, and ast_tcptls_session_args::tls_cfg.

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

static void mansession_lock ( struct mansession s  )  [static]

Lock the 'mansession' structure.

Definition at line 2094 of file manager.c.

References ast_mutex_lock, and mansession::lock.

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

02095 {
02096    ast_mutex_lock(&s->lock);
02097 }

static void mansession_unlock ( struct mansession s  )  [static]

Unlock the 'mansession' structure.

Definition at line 2100 of file manager.c.

References ast_mutex_unlock, and mansession::lock.

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

02101 {
02102    ast_mutex_unlock(&s->lock);
02103 }

static int match_filter ( struct mansession s,
char *  eventdata 
) [static]

Definition at line 4278 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 process_events().

04279 {
04280    int result = 0;
04281 
04282    ast_debug(3, "Examining event:\n%s\n", eventdata);
04283    if (!ao2_container_count(s->session->whitefilters) && !ao2_container_count(s->session->blackfilters)) {
04284       return 1; /* no filtering means match all */
04285    } else if (ao2_container_count(s->session->whitefilters) && !ao2_container_count(s->session->blackfilters)) {
04286       /* white filters only: implied black all filter processed first, then white filters */
04287       ao2_t_callback_data(s->session->whitefilters, OBJ_NODATA, whitefilter_cmp_fn, eventdata, &result, "find filter in session filter container"); 
04288    } else if (!ao2_container_count(s->session->whitefilters) && ao2_container_count(s->session->blackfilters)) {
04289       /* black filters only: implied white all filter processed first, then black filters */
04290       ao2_t_callback_data(s->session->blackfilters, OBJ_NODATA, blackfilter_cmp_fn, eventdata, &result, "find filter in session filter container"); 
04291    } else {
04292       /* white and black filters: implied black all filter processed first, then white filters, and lastly black filters */
04293       ao2_t_callback_data(s->session->whitefilters, OBJ_NODATA, whitefilter_cmp_fn, eventdata, &result, "find filter in session filter container"); 
04294       if (result) {
04295          result = 0;
04296          ao2_t_callback_data(s->session->blackfilters, OBJ_NODATA, blackfilter_cmp_fn, eventdata, &result, "find filter in session filter container"); 
04297       }
04298    }
04299 
04300    return result;
04301 }

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

References advance_event(), ao2_lock, ao2_unlock, mansession_session::authenticated, eventqent::category, eventqent::eventdata, 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().

04309 {
04310    int ret = 0;
04311 
04312    ao2_lock(s->session);
04313    if (s->session->f != NULL) {
04314       struct eventqent *eqe = s->session->last_ev;
04315 
04316       while ((eqe = advance_event(eqe))) {
04317          if (!ret && s->session->authenticated &&
04318              (s->session->readperm & eqe->category) == eqe->category &&
04319              (s->session->send_events & eqe->category) == eqe->category) {
04320                if (match_filter(s, eqe->eventdata)) {
04321                   if (send_string(s, eqe->eventdata) < 0)
04322                      ret = -1;   /* don't send more */
04323                }
04324          }
04325          s->session->last_ev = eqe;
04326       }
04327    }
04328    ao2_unlock(s->session);
04329    return ret;
04330 }

static int process_message ( struct mansession s,
const struct message m 
) [static]

Definition at line 4646 of file manager.c.

References __astman_get_header(), manager_action::action, action_find(), manager_action::active_count, allowmultiplelogin, 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, and mansession_session::writeperm.

Referenced by do_message().

04647 {
04648    int ret = 0;
04649    struct manager_action *act_found;
04650    const char *user;
04651    const char *action;
04652 
04653    action = __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY);
04654    if (ast_strlen_zero(action)) {
04655       report_req_bad_format(s, "NONE");
04656       mansession_lock(s);
04657       astman_send_error(s, m, "Missing action in request");
04658       mansession_unlock(s);
04659       return 0;
04660    }
04661 
04662    if (!s->session->authenticated
04663       && strcasecmp(action, "Login")
04664       && strcasecmp(action, "Logoff")
04665       && strcasecmp(action, "Challenge")) {
04666       if (!s->session->authenticated) {
04667          report_req_not_allowed(s, action);
04668       }
04669       mansession_lock(s);
04670       astman_send_error(s, m, "Permission denied");
04671       mansession_unlock(s);
04672       return 0;
04673    }
04674 
04675    if (!allowmultiplelogin
04676       && !s->session->authenticated
04677       && (!strcasecmp(action, "Login")
04678          || !strcasecmp(action, "Challenge"))) {
04679       user = astman_get_header(m, "Username");
04680 
04681       if (check_manager_session_inuse(user)) {
04682          report_session_limit(s);
04683          sleep(1);
04684          mansession_lock(s);
04685          astman_send_error(s, m, "Login Already In Use");
04686          mansession_unlock(s);
04687          return -1;
04688       }
04689    }
04690 
04691    act_found = action_find(action);
04692    if (act_found) {
04693       /* Found the requested AMI action. */
04694       int acted = 0;
04695 
04696       if ((s->session->writeperm & act_found->authority)
04697          || act_found->authority == 0) {
04698          /* We have the authority to execute the action. */
04699          ao2_lock(act_found);
04700          if (act_found->registered && act_found->func) {
04701             ast_debug(1, "Running action '%s'\n", act_found->action);
04702             ++act_found->active_count;
04703             ao2_unlock(act_found);
04704             ret = act_found->func(s, m);
04705             acted = 1;
04706             ao2_lock(act_found);
04707             --act_found->active_count;
04708          }
04709          ao2_unlock(act_found);
04710       }
04711       if (!acted) {
04712          /*
04713           * We did not execute the action because access was denied, it
04714           * was no longer registered, or no action was really registered.
04715           * Complain about it and leave.
04716           */
04717          report_req_not_allowed(s, action);
04718          mansession_lock(s);
04719          astman_send_error(s, m, "Permission denied");
04720          mansession_unlock(s);
04721       }
04722       ao2_t_ref(act_found, -1, "done with found action object");
04723    } else {
04724       char buf[512];
04725 
04726       report_req_bad_format(s, action);
04727       snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
04728       mansession_lock(s);
04729       astman_send_error(s, m, buf);
04730       mansession_unlock(s);
04731    }
04732    if (ret) {
04733       return ret;
04734    }
04735    /* Once done with our message, deliver any pending events unless the
04736       requester doesn't want them as part of this response.
04737    */
04738    if (ast_strlen_zero(astman_get_header(m, "SuppressEvents"))) {
04739       return process_events(s);
04740    } else {
04741       return ret;
04742    }
04743 }

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

Referenced by purge_old_stuff().

01126 {
01127    struct eventqent *ev;
01128    struct timeval now = ast_tvnow();
01129 
01130    AST_RWLIST_WRLOCK(&all_events);
01131    while ( (ev = AST_RWLIST_FIRST(&all_events)) &&
01132        ev->usecount == 0 && AST_RWLIST_NEXT(ev, eq_next)) {
01133       AST_RWLIST_REMOVE_HEAD(&all_events, eq_next);
01134       ast_free(ev);
01135    }
01136 
01137    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&all_events, ev, eq_next) {
01138       /* Never release the last event */
01139       if (!AST_RWLIST_NEXT(ev, eq_next)) {
01140          break;
01141       }
01142 
01143       /* 2.5 times whatever the HTTP timeout is (maximum 2.5 hours) is the maximum time that we will definitely cache an event */
01144       if (ev->usecount == 0 && ast_tvdiff_sec(now, ev->tv) > (httptimeout > 3600 ? 3600 : httptimeout) * 2.5) {
01145          AST_RWLIST_REMOVE_CURRENT(eq_next);
01146          ast_free(ev);
01147       }
01148    }
01149    AST_RWLIST_TRAVERSE_SAFE_END;
01150    AST_RWLIST_UNLOCK(&all_events);
01151 }

static void purge_sessions ( int  n_max  )  [static]

remove at most n_max stale session from the list.

Definition at line 5030 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().

05031 {
05032    struct mansession_session *session;
05033    time_t now = time(NULL);
05034    struct ao2_iterator i;
05035 
05036    i = ao2_iterator_init(sessions, 0);
05037    while ((session = ao2_iterator_next(&i)) && n_max > 0) {
05038       ao2_lock(session);
05039       if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) {
05040          if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) {
05041             ast_verb(2, "HTTP Manager '%s' timed out from %s\n",
05042                session->username, ast_inet_ntoa(session->sin.sin_addr));
05043          }
05044          ao2_unlock(session);
05045          session_destroy(session);
05046          n_max--;
05047       } else {
05048          ao2_unlock(session);
05049          unref_mansession(session);
05050       }
05051    }
05052    ao2_iterator_destroy(&i);
05053 }

static void report_auth_success ( const struct mansession s  )  [static]

Definition at line 2215 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().

02216 {
02217    struct sockaddr_in sin_local;
02218    char session_id[32];
02219    struct ast_security_event_successful_auth successful_auth = {
02220       .common.event_type = AST_SECURITY_EVENT_SUCCESSFUL_AUTH,
02221       .common.version    = AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION,
02222       .common.service    = "AMI",
02223       .common.account_id = s->session->username,
02224       .common.session_tv = &s->session->sessionstart_tv,
02225       .common.local_addr = {
02226          .sin       = mansession_encode_sin_local(s, &sin_local),
02227          .transport = mansession_get_transport(s),
02228       },
02229       .common.remote_addr = {
02230          .sin       = &s->session->sin,
02231          .transport = mansession_get_transport(s),
02232       },
02233       .common.session_id = session_id,
02234    };
02235 
02236    snprintf(session_id, sizeof(session_id), "%p", s->session);
02237 
02238    ast_security_event_report(AST_SEC_EVT(&successful_auth));
02239 }

static void report_failed_acl ( const struct mansession s,
const char *  username 
) [static]

Definition at line 2163 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().

02164 {
02165    struct sockaddr_in sin_local;
02166    char session_id[32];
02167    struct ast_security_event_failed_acl failed_acl_event = {
02168       .common.event_type = AST_SECURITY_EVENT_FAILED_ACL,
02169       .common.version    = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
02170       .common.service    = "AMI",
02171       .common.account_id = username,
02172       .common.session_tv = &s->session->sessionstart_tv,
02173       .common.local_addr = {
02174          .sin       = mansession_encode_sin_local(s, &sin_local),
02175          .transport = mansession_get_transport(s),
02176       },
02177       .common.remote_addr = {
02178          .sin       = &s->session->sin,
02179          .transport = mansession_get_transport(s),
02180       },
02181       .common.session_id = session_id,
02182    };
02183 
02184    snprintf(session_id, sizeof(session_id), "%p", s->session);
02185 
02186    ast_security_event_report(AST_SEC_EVT(&failed_acl_event));
02187 }

static void report_failed_challenge_response ( const struct mansession s,
const char *  response,
const char *  expected_response 
) [static]

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

Referenced by authenticate().

02303 {
02304    struct sockaddr_in sin_local;
02305    char session_id[32];
02306    struct ast_security_event_chal_resp_failed chal_resp_failed = {
02307       .common.event_type = AST_SECURITY_EVENT_CHAL_RESP_FAILED,
02308       .common.version    = AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION,
02309       .common.service    = "AMI",
02310       .common.account_id = s->session->username,
02311       .common.session_tv = &s->session->sessionstart_tv,
02312       .common.local_addr = {
02313          .sin       = mansession_encode_sin_local(s, &sin_local),
02314          .transport = mansession_get_transport(s),
02315       },
02316       .common.remote_addr = {
02317          .sin       = &s->session->sin,
02318          .transport = mansession_get_transport(s),
02319       },
02320       .common.session_id = session_id,
02321 
02322       .challenge         = s->session->challenge,
02323       .response          = response,
02324       .expected_response = expected_response,
02325    };
02326 
02327    snprintf(session_id, sizeof(session_id), "%p", s->session);
02328 
02329    ast_security_event_report(AST_SEC_EVT(&chal_resp_failed));
02330 }

static void report_inval_password ( const struct mansession s,
const char *  username 
) [static]

Definition at line 2189 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().

02190 {
02191    struct sockaddr_in sin_local;
02192    char session_id[32];
02193    struct ast_security_event_inval_password inval_password = {
02194       .common.event_type = AST_SECURITY_EVENT_INVAL_PASSWORD,
02195       .common.version    = AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION,
02196       .common.service    = "AMI",
02197       .common.account_id = username,
02198       .common.session_tv = &s->session->sessionstart_tv,
02199       .common.local_addr = {
02200          .sin       = mansession_encode_sin_local(s, &sin_local),
02201          .transport = mansession_get_transport(s),
02202       },
02203       .common.remote_addr = {
02204          .sin       = &s->session->sin,
02205          .transport = mansession_get_transport(s),
02206       },
02207       .common.session_id = session_id,
02208    };
02209 
02210    snprintf(session_id, sizeof(session_id), "%p", s->session);
02211 
02212    ast_security_event_report(AST_SEC_EVT(&inval_password));
02213 }

static void report_invalid_user ( const struct mansession s,
const char *  username 
) [static]

Definition at line 2137 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().

02138 {
02139    struct sockaddr_in sin_local;
02140    char session_id[32];
02141    struct ast_security_event_inval_acct_id inval_acct_id = {
02142       .common.event_type = AST_SECURITY_EVENT_INVAL_ACCT_ID,
02143       .common.version    = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION,
02144       .common.service    = "AMI",
02145       .common.account_id = username,
02146       .common.session_tv = &s->session->sessionstart_tv,
02147       .common.local_addr = {
02148          .sin       = mansession_encode_sin_local(s, &sin_local),
02149          .transport = mansession_get_transport(s),
02150       },
02151       .common.remote_addr = {
02152          .sin       = &s->session->sin,
02153          .transport = mansession_get_transport(s),
02154       },
02155       .common.session_id = session_id,
02156    };
02157 
02158    snprintf(session_id, sizeof(session_id), "%p", s);
02159 
02160    ast_security_event_report(AST_SEC_EVT(&inval_acct_id));
02161 }

static void report_req_bad_format ( const struct mansession s,
const char *  action 
) [static]

Definition at line 2271 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(), mansession::session, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.

Referenced by process_message().

02272 {
02273    struct sockaddr_in sin_local;
02274    char session_id[32];
02275    char request_type[64];
02276    struct ast_security_event_req_bad_format req_bad_format = {
02277       .common.event_type = AST_SECURITY_EVENT_REQ_BAD_FORMAT,
02278       .common.version    = AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION,
02279       .common.service    = "AMI",
02280       .common.account_id = s->session->username,
02281       .common.session_tv = &s->session->sessionstart_tv,
02282       .common.local_addr = {
02283          .sin       = mansession_encode_sin_local(s, &sin_local),
02284          .transport = mansession_get_transport(s),
02285       },
02286       .common.remote_addr = {
02287          .sin       = &s->session->sin,
02288          .transport = mansession_get_transport(s),
02289       },
02290       .common.session_id = session_id,
02291 
02292       .request_type      = request_type,
02293    };
02294 
02295    snprintf(session_id, sizeof(session_id), "%p", s->session);
02296    snprintf(request_type, sizeof(request_type), "Action: %s", action);
02297 
02298    ast_security_event_report(AST_SEC_EVT(&req_bad_format));
02299 }

static void report_req_not_allowed ( const struct mansession s,
const char *  action 
) [static]

Definition at line 2241 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(), mansession::session, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.

Referenced by process_message().

02242 {
02243    struct sockaddr_in sin_local;
02244    char session_id[32];
02245    char request_type[64];
02246    struct ast_security_event_req_not_allowed req_not_allowed = {
02247       .common.event_type = AST_SECURITY_EVENT_REQ_NOT_ALLOWED,
02248       .common.version    = AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION,
02249       .common.service    = "AMI",
02250       .common.account_id = s->session->username,
02251       .common.session_tv = &s->session->sessionstart_tv,
02252       .common.local_addr = {
02253          .sin       = mansession_encode_sin_local(s, &sin_local),
02254          .transport = mansession_get_transport(s),
02255       },
02256       .common.remote_addr = {
02257          .sin       = &s->session->sin,
02258          .transport = mansession_get_transport(s),
02259       },
02260       .common.session_id = session_id,
02261 
02262       .request_type      = request_type,
02263    };
02264 
02265    snprintf(session_id, sizeof(session_id), "%p", s->session);
02266    snprintf(request_type, sizeof(request_type), "Action: %s", action);
02267 
02268    ast_security_event_report(AST_SEC_EVT(&req_not_allowed));
02269 }

static void report_session_limit ( const struct mansession s  )  [static]

Definition at line 2332 of file manager.c.

References AST_SEC_EVT, ast_security_event_report(), AST_SECURITY_EVENT_SESSION_LIMIT, AST_SECURITY_EVENT_SESSION_LIMIT_VERSION, mansession_encode_sin_local(), mansession_get_transport(), mansession::session, session_limit, mansession_session::sessionstart_tv, mansession_session::sin, and mansession_session::username.

Referenced by process_message().

02333 {
02334    struct sockaddr_in sin_local;
02335    char session_id[32];
02336    struct ast_security_event_session_limit session_limit = {
02337       .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT,
02338       .common.version    = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION,
02339       .common.service    = "AMI",
02340       .common.account_id = s->session->username,
02341       .common.session_tv = &s->session->sessionstart_tv,
02342       .common.local_addr = {
02343          .sin       = mansession_encode_sin_local(s, &sin_local),
02344          .transport = mansession_get_transport(s),
02345       },
02346       .common.remote_addr = {
02347          .sin       = &s->session->sin,
02348          .transport = mansession_get_transport(s),
02349       },
02350       .common.session_id = session_id,
02351    };
02352 
02353    snprintf(session_id, sizeof(session_id), "%p", s->session);
02354 
02355    ast_security_event_report(AST_SEC_EVT(&session_limit));
02356 }

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

References ast_careful_fwrite(), EVENT_FLAG_HOOKRESPONSE, mansession_session::f, mansession::f, 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().

01973 {
01974    int res;
01975    FILE *f = s->f ? s->f : s->session->f;
01976    int fd = s->f ? s->fd : s->session->fd;
01977 
01978    /* It's a result from one of the hook's action invocation */
01979    if (s->hook) {
01980       /*
01981        * to send responses, we're using the same function
01982        * as for receiving events. We call the event "HookResponse"
01983        */
01984       s->hook->helper(EVENT_FLAG_HOOKRESPONSE, "HookResponse", string);
01985       return 0;
01986    }
01987        
01988    if ((res = ast_careful_fwrite(f, fd, string, strlen(string), s->session->writetimeout))) {
01989       s->write_error = 1;
01990    }
01991 
01992    return res;
01993 }

static void session_destroy ( struct mansession_session s  )  [static]

Definition at line 1373 of file manager.c.

References ao2_unlink, and unref_mansession().

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

01374 {
01375    unref_mansession(s);
01376    ao2_unlink(sessions, s);
01377 }

static void session_destructor ( void *  obj  )  [static]

Definition at line 1306 of file manager.c.

References ao2_t_callback, ao2_t_ref, ast_atomic_fetchadd_int(), ast_datastore_free(), AST_LIST_REMOVE_HEAD, mansession_session::blackfilters, mansession_session::datastores, ast_datastore::entry, mansession_session::f, mansession_session::last_ev, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, eventqent::usecount, and mansession_session::whitefilters.

Referenced by build_mansession().

01307 {
01308    struct mansession_session *session = obj;
01309    struct eventqent *eqe = session->last_ev;
01310    struct ast_datastore *datastore;
01311 
01312    /* Get rid of each of the data stores on the session */
01313    while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) {
01314       /* Free the data store */
01315       ast_datastore_free(datastore);
01316    }
01317 
01318    if (session->f != NULL) {
01319       fclose(session->f);
01320    }
01321    if (eqe) {
01322       ast_atomic_fetchadd_int(&eqe->usecount, -1);
01323    }
01324 
01325    if (session->whitefilters) {
01326       ao2_t_callback(session->whitefilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all white filters");
01327       ao2_t_ref(session->whitefilters, -1 , "decrement ref for white container, should be last one");
01328    }
01329 
01330    if (session->blackfilters) {
01331       ao2_t_callback(session->blackfilters, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL, "unlink all black filters");
01332       ao2_t_ref(session->blackfilters, -1 , "decrement ref for black container, should be last one");
01333    }
01334 }

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

References AMI_VERSION, ao2_lock, ao2_unlock, ast_atomic_fetchadd_int(), AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_mutex_init, ast_sockaddr_to_sin, astman_append(), authlimit, mansession_session::authstart, block_sockets, build_mansession(), mansession_session::datastores, do_message(), errno, mansession::f, mansession_session::f, ast_tcptls_session_instance::f, mansession::fd, mansession_session::fd, ast_tcptls_session_instance::fd, ast_frame::flags, grab_last(), mansession_session::last_ev, mansession::lock, LOG_ERROR, LOG_WARNING, ast_tcptls_session_instance::remote_address, mansession::session, session_destroy(), mansession_session::sin, mansession::tcptls_session, unauth_sessions, and mansession::write_error.

04932 {
04933    struct ast_tcptls_session_instance *ser = data;
04934    struct mansession_session *session;
04935    struct mansession s = {
04936       .tcptls_session = data,
04937    };
04938    int flags;
04939    int res;
04940    struct sockaddr_in ser_remote_address_tmp;
04941    struct protoent *p;
04942 
04943    if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) {
04944       fclose(ser->f);
04945       ast_atomic_fetchadd_int(&unauth_sessions, -1);
04946       goto done;
04947    }
04948 
04949    ast_sockaddr_to_sin(&ser->remote_address, &ser_remote_address_tmp);
04950    session = build_mansession(ser_remote_address_tmp);
04951 
04952    if (session == NULL) {
04953       fclose(ser->f);
04954       ast_atomic_fetchadd_int(&unauth_sessions, -1);
04955       goto done;
04956    }
04957 
04958    /* here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
04959     * This is necessary to prevent delays (caused by buffering) as we
04960     * write to the socket in bits and peices. */
04961    p = getprotobyname("tcp");
04962    if (p) {
04963       int arg = 1;
04964       if( setsockopt(ser->fd, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
04965          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));
04966       }
04967    } else {
04968       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");
04969    }
04970 
04971    flags = fcntl(ser->fd, F_GETFL);
04972    if (!block_sockets) { /* make sure socket is non-blocking */
04973       flags |= O_NONBLOCK;
04974    } else {
04975       flags &= ~O_NONBLOCK;
04976    }
04977    fcntl(ser->fd, F_SETFL, flags);
04978 
04979    ao2_lock(session);
04980    /* Hook to the tail of the event queue */
04981    session->last_ev = grab_last();
04982 
04983    ast_mutex_init(&s.lock);
04984 
04985    /* these fields duplicate those in the 'ser' structure */
04986    session->fd = s.fd = ser->fd;
04987    session->f = s.f = ser->f;
04988    session->sin = ser_remote_address_tmp;
04989    s.session = session;
04990 
04991    AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
04992 
04993    if(time(&session->authstart) == -1) {
04994       ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
04995       ast_atomic_fetchadd_int(&unauth_sessions, -1);
04996       ao2_unlock(session);
04997       session_destroy(session);
04998       goto done;
04999    }
05000    ao2_unlock(session);
05001 
05002    astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION);   /* welcome prompt */
05003    for (;;) {
05004       if ((res = do_message(&s)) < 0 || s.write_error) {
05005          break;
05006       }
05007    }
05008    /* session is over, explain why and terminate */
05009    if (session->authenticated) {
05010       if (manager_displayconnects(session)) {
05011          ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
05012       }
05013    } else {
05014       ast_atomic_fetchadd_int(&unauth_sessions, -1);
05015       if (displayconnects) {
05016          ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr));
05017       }
05018    }
05019 
05020    session_destroy(session);
05021 
05022    ast_mutex_destroy(&s.lock);
05023 done:
05024    ao2_ref(ser, -1);
05025    ser = NULL;
05026    return NULL;
05027 }

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

02110 {
02111    int maskint = strings_to_mask(eventmask);
02112 
02113    ao2_lock(s->session);
02114    if (maskint >= 0) {
02115       s->session->send_events = maskint;
02116    }
02117    ao2_unlock(s->session);
02118 
02119    return maskint;
02120 }

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

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

Referenced by set_eventmask().

01261 {
01262    const char *p;
01263 
01264    if (ast_strlen_zero(string)) {
01265       return -1;
01266    }
01267 
01268    for (p = string; *p; p++) {
01269       if (*p < '0' || *p > '9') {
01270          break;
01271       }
01272    }
01273    if (!*p) { /* all digits */
01274       return atoi(string);
01275    }
01276    if (ast_false(string)) {
01277       return 0;
01278    }
01279    if (ast_true(string)) { /* all permissions */
01280       int x, ret = 0;
01281       for (x = 0; x < ARRAY_LEN(perms); x++) {
01282          ret |= perms[x].num;
01283       }
01284       return ret;
01285    }
01286    return get_perm(string);
01287 }

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

01292 {
01293    int refcount = ao2_ref(s, -1);
01294         if (manager_debug) {
01295       ast_log(LOG_DEBUG, "Mansession: %p refcount now %d\n", s, refcount - 1);
01296    }
01297    return s;
01298 }

static int whitefilter_cmp_fn ( void *  obj,
void *  arg,
void *  data,
int  flags 
) [static]

Definition at line 4249 of file manager.c.

References CMP_MATCH, and CMP_STOP.

Referenced by match_filter().

04250 {
04251    regex_t *regex_filter = obj;
04252    const char *eventdata = arg;
04253    int *result = data;
04254 
04255    if (!regexec(regex_filter, eventdata, 0, NULL, 0)) {
04256       *result = 1;
04257       return (CMP_MATCH | CMP_STOP);
04258    }
04259 
04260    return 0;
04261 }


Variable Documentation

int allowmultiplelogin = 1 [static]

Definition at line 891 of file manager.c.

Referenced by handle_manager_show_settings(), and process_message().

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

Definition at line 2002 of file manager.c.

Referenced by astman_append().

int authlimit [static]

Definition at line 899 of file manager.c.

int authtimeout [static]

Definition at line 898 of file manager.c.

int block_sockets [static]

Definition at line 905 of file manager.c.

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

int broken_events_action [static]

Definition at line 894 of file manager.c.

Referenced by __init_manager(), and action_events().

struct { ... } command_blacklist[] [static]

Referenced by check_blacklist().

const int DEFAULT_AUTHLIMIT = 50 [static]

Default setting for authlimit

Definition at line 887 of file manager.c.

Referenced by __init_manager(), and reload_config().

const int DEFAULT_AUTHTIMEOUT = 30 [static]

Default setting for authtimeout

Definition at line 886 of file manager.c.

Referenced by __init_manager(), and reload_config().

const int DEFAULT_BLOCKSOCKETS = 0 [static]

Default setting for block-sockets

Definition at line 881 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_BROKENEVENTSACTION = 0 [static]

Default setting for brokeneventsaction

Definition at line 885 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_DISPLAYCONNECTS = 1 [static]

Default setting for displaying manager connections

Definition at line 882 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_ENABLED = 0 [static]

Default setting for manager to be enabled

Definition at line 879 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_HTTPTIMEOUT = 60 [static]

Default manager http timeout

Definition at line 884 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_MANAGERDEBUG = 0 [static]

Default setting for manager debug

Definition at line 888 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_TIMESTAMPEVENTS = 0 [static]

Default setting for timestampevents

Definition at line 883 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_WEBENABLED = 0 [static]

Default setting for the web interface to be enabled

Definition at line 880 of file manager.c.

Referenced by __init_manager().

int displayconnects [static]

Definition at line 890 of file manager.c.

Referenced by __init_manager(), do_message(), and handle_manager_show_settings().

char global_realm[MAXHOSTNAMELEN] [static]

Default realm

Definition at line 903 of file manager.c.

Referenced by __init_manager().

int httptimeout [static]

Definition at line 893 of file manager.c.

Referenced by __init_manager(), and handle_manager_show_settings().

char* manager_channelvars [static]

Definition at line 900 of file manager.c.

Referenced by handle_manager_show_settings(), and load_channelvars().

int manager_debug = 0 [static]

enable some debugging code in the manager

Definition at line 897 of file manager.c.

Referenced by __ast_manager_event_multichan(), __init_manager(), and handle_manager_show_settings().

int manager_enabled = 0 [static]

Definition at line 895 of file manager.c.

Referenced by __init_manager(), and handle_manager_show_settings().

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

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

Referenced by append_channel_vars().

struct permalias perms[] [static]

helper functions to convert back and forth between string and numeric representation of set of flags

Referenced by action_events(), authority_to_str(), get_perm(), and strings_to_mask().

struct ao2_container* sessions = NULL [static]

Definition at line 1009 of file manager.c.

int timestampevents [static]

Definition at line 892 of file manager.c.

Referenced by __ast_manager_event_multichan(), __init_manager(), and handle_manager_show_settings().

int unauth_sessions = 0 [static]

Definition at line 906 of file manager.c.

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

Definition at line 2003 of file manager.c.

Referenced by action_userevent().

int webmanager_enabled = 0 [static]

Definition at line 896 of file manager.c.

Referenced by __init_manager(), and handle_manager_show_settings().

const char* words[AST_MAX_CMD_LEN] [inherited]

Definition at line 921 of file manager.c.


Generated on Mon Oct 8 12:39:30 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7