Thu Oct 11 06:49:58 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  eventqent
struct  fast_originate_helper
 helper function for originate More...
struct  manager_hooks
 list of hooks registered More...
struct  mansession
struct  mansession_session
struct  permalias
struct  sessions
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 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

static const char * __astman_get_header (const struct message *m, char *var, int mode)
static void __fini_actions (void)
static void __fini_all_events (void)
static void __fini_manager_hooks (void)
static void __fini_users (void)
static void __init_actions (void)
static void __init_all_events (void)
static void __init_astman_append_buf (void)
 thread local buffer for astman_append
static void __init_manager_event_buf (void)
static void __init_manager_hooks (void)
static void __init_userevent_buf (void)
static void __init_users (void)
int __manager_event (int category, const char *event, const char *file, int line, const char *func, const char *fmt,...)
 manager_event: Send AMI event to client
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 int action_events (struct mansession *s, const struct message *m)
static int action_extensionstate (struct mansession *s, const struct message *m)
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 append_event (const char *str, int category)
static int ast_instring (const char *bigstr, const char *smallstr, const char delim)
int ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), const char *synopsis, const char *description)
 register a new command with manager, including online help. This is the preferred way to register a manager command
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,...)
const char * astman_get_header (const struct message *m, char *var)
 Get header from mananger transaction.
struct 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 char * authority_to_str (int authority, struct ast_str **res)
 Convert authority code to a list of options.
static int check_blacklist (const char *cmd)
int check_manager_enabled ()
 Event list management functions. We assume that the event list always has at least one element, and the delete code will not remove the last entry even if the.
static int check_manager_session_inuse (const char *name)
static int check_user_can_execute_function (const char *evaluating, int writepermlist)
 Checks to see if a string which can be used to evaluate functions should be rejected.
int check_webmanager_enabled ()
 Check if AMI/HTTP is enabled.
static void destroy_session (struct mansession_session *session)
static int do_message (struct mansession *s)
static void * fast_originate (void *data)
static void free_session (struct mansession_session *session)
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 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 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 int send_string (struct mansession *s, char *string)
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)

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
static struct ast_cli_entry cli_manager []
struct {
   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_TIMESTAMPEVENTS = 0
static const int DEFAULT_WEBENABLED = 0
static int displayconnects
static int httptimeout
static int manager_debug
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 char mandescr_atxfer []
static char mandescr_command []
static char mandescr_coresettings []
static char mandescr_coreshowchannels []
static char mandescr_corestatus []
static char mandescr_createconfig []
static char mandescr_events []
static char mandescr_extensionstate []
static char mandescr_getconfig []
static char mandescr_getconfigjson []
static char mandescr_getvar []
static char mandescr_hangup []
static char mandescr_listcategories []
static char mandescr_listcommands []
static char mandescr_logoff []
static char mandescr_mailboxcount []
static char mandescr_mailboxstatus []
 Help text for manager command mailboxstatus.
static char mandescr_modulecheck []
static char mandescr_moduleload []
static char mandescr_originate []
static char mandescr_ping []
 Manager PING.
static char mandescr_redirect []
static char mandescr_reload []
static char mandescr_sendtext []
static char mandescr_setvar []
static char mandescr_status []
static char mandescr_timeout []
static char mandescr_updateconfig []
static char mandescr_userevent []
static char mandescr_waitevent []
 Manager WAITEVENT.
static int num_sessions
static struct permalias perms []
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

callback to display list of locally configured nodes


Define Documentation

#define ASTMAN_APPEND_BUF_INITSIZE   256

initial allocated size for the astman_append_buf

Definition at line 1009 of file manager.c.

Referenced by astman_append().

#define GET_HEADER_FIRST_MATCH   0

Definition at line 908 of file manager.c.

Referenced by astman_get_header().

#define GET_HEADER_LAST_MATCH   1

Definition at line 909 of file manager.c.

Referenced by __astman_get_header().

#define GET_HEADER_SKIP_EMPTY   2

Definition at line 910 of file manager.c.

Referenced by __astman_get_header(), and process_message().

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 3458 of file manager.c.

Referenced by __manager_event().

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

Definition at line 158 of file manager.c.

Referenced by check_blacklist().

#define MSG_MOREDATA   ((char *)astman_send_response)

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

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

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


Function Documentation

static const char* __astman_get_header ( const struct message m,
char *  var,
int  mode 
) [static]

Definition at line 911 of file manager.c.

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

Referenced by astman_get_header(), and process_message().

00912 {
00913    int x, l = strlen(var);
00914    const char *result = "";
00915 
00916    for (x = 0; x < m->hdrcount; x++) {
00917       const char *h = m->headers[x];
00918       if (!strncasecmp(var, h, l) && h[l] == ':' && h[l+1] == ' ') {
00919          const char *value = h + l + 2;
00920          /* found a potential candidate */
00921          if (mode & GET_HEADER_SKIP_EMPTY && ast_strlen_zero(value))
00922             continue;   /* not interesting */
00923          if (mode & GET_HEADER_LAST_MATCH)
00924             result = value;   /* record the last match so far */
00925          else
00926             return value;
00927       }
00928    }
00929 
00930    return "";
00931 }

static void __fini_actions ( void   )  [static]

Definition at line 264 of file manager.c.

00271 {

static void __fini_all_events ( void   )  [static]

Definition at line 121 of file manager.c.

00159 {

static void __fini_manager_hooks ( void   )  [static]

Definition at line 267 of file manager.c.

00271 {

static void __fini_users ( void   )  [static]

Definition at line 261 of file manager.c.

00271 {

static void __init_actions ( void   )  [static]

Definition at line 264 of file manager.c.

00271 {

static void __init_all_events ( void   )  [static]

Definition at line 121 of file manager.c.

00159 {

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

01015 {

static void __init_manager_event_buf ( void   )  [static]

Definition at line 3457 of file manager.c.

03460 : Send AMI event to client */

static void __init_manager_hooks ( void   )  [static]

Definition at line 267 of file manager.c.

00271 {

static void __init_userevent_buf ( void   )  [static]

Definition at line 1006 of file manager.c.

01015 {

static void __init_users ( void   )  [static]

Definition at line 261 of file manager.c.

00271 {

int __manager_event ( int  category,
const char *  event,
const char *  file,
int  line,
const char *  func,
const char *  fmt,
  ... 
)

manager_event: Send AMI event to client

Definition at line 3461 of file manager.c.

References mansession_session::__lock, append_event(), ast_atomic_fetchadd_int(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_append_va(), ast_str_buffer(), ast_str_set(), ast_str_thread_get(), ast_tvnow(), authority_to_str(), buf, manager_custom_hook::helper, manager_event_buf, MANAGER_EVENT_BUF_INITSIZE, mansession_session::pending_event, eventqent::seq, and mansession_session::waiting_thread.

03463 {
03464    struct mansession_session *session;
03465    struct manager_custom_hook *hook;
03466    struct ast_str *auth = ast_str_alloca(80);
03467    const char *cat_str;
03468    va_list ap;
03469    struct timeval now;
03470    struct ast_str *buf;
03471 
03472    /* Abort if there are neither any manager sessions nor hooks */
03473    if (!num_sessions && AST_RWLIST_EMPTY(&manager_hooks))
03474       return 0;
03475 
03476    if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE)))
03477       return -1;
03478 
03479    cat_str = authority_to_str(category, &auth);
03480    ast_str_set(&buf, 0,
03481          "Event: %s\r\nPrivilege: %s\r\n",
03482           event, cat_str);
03483 
03484    if (timestampevents) {
03485       now = ast_tvnow();
03486       ast_str_append(&buf, 0,
03487             "Timestamp: %ld.%06lu\r\n",
03488              (long)now.tv_sec, (unsigned long) now.tv_usec);
03489    }
03490    if (manager_debug) {
03491       static int seq;
03492       ast_str_append(&buf, 0,
03493             "SequenceNumber: %d\r\n",
03494              ast_atomic_fetchadd_int(&seq, 1));
03495       ast_str_append(&buf, 0,
03496             "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func);
03497    }
03498 
03499    va_start(ap, fmt);
03500    ast_str_append_va(&buf, 0, fmt, ap);
03501    va_end(ap);
03502 
03503    ast_str_append(&buf, 0, "\r\n");
03504 
03505    append_event(ast_str_buffer(buf), category);
03506 
03507    if (num_sessions) {
03508       /* Wake up any sleeping sessions */
03509       AST_LIST_LOCK(&sessions);
03510       AST_LIST_TRAVERSE(&sessions, session, list) {
03511          ast_mutex_lock(&session->__lock);
03512          if (session->waiting_thread != AST_PTHREADT_NULL)
03513             pthread_kill(session->waiting_thread, SIGURG);
03514          else
03515             /* We have an event to process, but the mansession is
03516              * not waiting for it. We still need to indicate that there
03517              * is an event waiting so that get_input processes the pending
03518              * event instead of polling.
03519              */
03520             session->pending_event = 1;
03521          ast_mutex_unlock(&session->__lock);
03522       }
03523       AST_LIST_UNLOCK(&sessions);
03524    }
03525 
03526    if (!AST_RWLIST_EMPTY(&manager_hooks)) {
03527       AST_RWLIST_RDLOCK(&manager_hooks);
03528       AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
03529          hook->helper(category, event, ast_str_buffer(buf));
03530       }
03531       AST_RWLIST_UNLOCK(&manager_hooks);
03532    }
03533 
03534    return 0;
03535 }

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

Definition at line 2254 of file manager.c.

References ast_channel_unlock, ast_find_call_feature(), AST_FRAME_DTMF, ast_get_channel_by_name_locked(), ast_queue_frame(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), chan, context, ast_call_feature::exten, exten, name, and pbx_builtin_setvar_helper().

Referenced by __init_manager().

02255 {
02256    const char *name = astman_get_header(m, "Channel");
02257    const char *exten = astman_get_header(m, "Exten");
02258    const char *context = astman_get_header(m, "Context");
02259    struct ast_channel *chan = NULL;
02260    struct ast_call_feature *atxfer_feature = NULL;
02261    char *feature_code = NULL;
02262 
02263    if (ast_strlen_zero(name)) { 
02264       astman_send_error(s, m, "No channel specified");
02265       return 0;
02266    }
02267    if (ast_strlen_zero(exten)) {
02268       astman_send_error(s, m, "No extension specified");
02269       return 0;
02270    }
02271 
02272    if (!(atxfer_feature = ast_find_call_feature("atxfer"))) {
02273       astman_send_error(s, m, "No attended transfer feature found");
02274       return 0;
02275    }
02276 
02277    if (!(chan = ast_get_channel_by_name_locked(name))) {
02278       astman_send_error(s, m, "Channel specified does not exist");
02279       return 0;
02280    }
02281 
02282    if (!ast_strlen_zero(context)) {
02283       pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context);
02284    }
02285 
02286    for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) {
02287       struct ast_frame f = {AST_FRAME_DTMF, *feature_code};
02288       ast_queue_frame(chan, &f);
02289    }
02290 
02291    for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) {
02292       struct ast_frame f = {AST_FRAME_DTMF, *feature_code};
02293       ast_queue_frame(chan, &f);
02294    }
02295 
02296    astman_send_ack(s, m, "Atxfer successfully queued");
02297    ast_channel_unlock(chan);
02298 
02299    return 0;
02300 }

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

Definition at line 1829 of file manager.c.

References mansession_session::__lock, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), mansession_session::challenge, and mansession::session.

Referenced by __init_manager().

01830 {
01831    const char *authtype = astman_get_header(m, "AuthType");
01832 
01833    if (!strcasecmp(authtype, "MD5")) {
01834       if (ast_strlen_zero(s->session->challenge))
01835          snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
01836       ast_mutex_lock(&s->session->__lock);
01837       astman_start_ack(s, m);
01838       astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
01839       ast_mutex_unlock(&s->session->__lock);
01840    } else {
01841       astman_send_error(s, m, "Must specify AuthType");
01842    }
01843    return 0;
01844 }

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

Manager command "command" - execute CLI command.

Definition at line 2344 of file manager.c.

References ast_calloc, ast_cli_command, ast_free, ast_log(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), buf, check_blacklist(), errno, LOG_WARNING, S_OR, and term_strip().

Referenced by __init_manager().

02345 {
02346    const char *cmd = astman_get_header(m, "Command");
02347    const char *id = astman_get_header(m, "ActionID");
02348    char *buf, *final_buf;
02349    char template[] = "/tmp/ast-ami-XXXXXX";  /* template for temporary file */
02350    int fd;
02351    off_t l;
02352 
02353    if (ast_strlen_zero(cmd)) {
02354       astman_send_error(s, m, "No command provided");
02355       return 0;
02356    }
02357 
02358    if (check_blacklist(cmd)) {
02359       astman_send_error(s, m, "Command blacklisted");
02360       return 0;
02361    }
02362 
02363    fd = mkstemp(template);
02364 
02365    astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
02366    if (!ast_strlen_zero(id))
02367       astman_append(s, "ActionID: %s\r\n", id);
02368    /* FIXME: Wedge a ActionID response in here, waiting for later changes */
02369    ast_cli_command(fd, cmd);  /* XXX need to change this to use a FILE * */
02370    l = lseek(fd, 0, SEEK_END);   /* how many chars available */
02371 
02372    /* This has a potential to overflow the stack.  Hence, use the heap. */
02373    buf = ast_calloc(1, l + 1);
02374    final_buf = ast_calloc(1, l + 1);
02375    if (buf) {
02376       lseek(fd, 0, SEEK_SET);
02377       if (read(fd, buf, l) < 0) {
02378          ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
02379       }
02380       buf[l] = '\0';
02381       if (final_buf) {
02382          term_strip(final_buf, buf, l);
02383          final_buf[l] = '\0';
02384       }
02385       astman_append(s, "%s", S_OR(final_buf, buf));
02386       ast_free(buf);
02387    }
02388    close(fd);
02389    unlink(template);
02390    astman_append(s, "--END COMMAND--\r\n\r\n");
02391    if (final_buf)
02392       ast_free(final_buf);
02393    return 0;
02394 }

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

Show PBX core settings information.

Definition at line 2823 of file manager.c.

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

02824 {
02825    const char *actionid = astman_get_header(m, "ActionID");
02826    char idText[150];
02827 
02828    if (!ast_strlen_zero(actionid))
02829       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
02830    else
02831       idText[0] = '\0';
02832 
02833    astman_append(s, "Response: Success\r\n"
02834          "%s"
02835          "AMIversion: %s\r\n"
02836          "AsteriskVersion: %s\r\n"
02837          "SystemName: %s\r\n"
02838          "CoreMaxCalls: %d\r\n"
02839          "CoreMaxLoadAvg: %f\r\n"
02840          "CoreRunUser: %s\r\n"
02841          "CoreRunGroup: %s\r\n"
02842          "CoreMaxFilehandles: %d\r\n" 
02843          "CoreRealTimeEnabled: %s\r\n"
02844          "CoreCDRenabled: %s\r\n"
02845          "CoreHTTPenabled: %s\r\n"
02846          "\r\n",
02847          idText,
02848          AMI_VERSION,
02849          ast_get_version(), 
02850          ast_config_AST_SYSTEM_NAME,
02851          option_maxcalls,
02852          option_maxload,
02853          ast_config_AST_RUN_USER,
02854          ast_config_AST_RUN_GROUP,
02855          option_maxfiles,
02856          ast_realtime_enabled() ? "Yes" : "No",
02857          check_cdr_enabled() ? "Yes" : "No",
02858          check_webmanager_enabled() ? "Yes" : "No"
02859          );
02860    return 0;
02861 }

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

References ast_channel::_state, ast_channel::accountcode, ast_channel::appl, ast_bridged_channel(), ast_channel_unlock, ast_channel_walk_locked(), ast_state2str(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), astman_append(), astman_get_header(), astman_send_listack(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::data, ast_channel::exten, ast_channel::name, ast_channel::priority, S_OR, ast_cdr::start, and ast_channel::uniqueid.

Referenced by __init_manager().

02929 {
02930    const char *actionid = astman_get_header(m, "ActionID");
02931    char idText[256];
02932    struct ast_channel *c = NULL;
02933    int numchans = 0;
02934    int duration, durh, durm, durs;
02935 
02936    if (!ast_strlen_zero(actionid))
02937       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
02938    else
02939       idText[0] = '\0';
02940 
02941    astman_send_listack(s, m, "Channels will follow", "start"); 
02942 
02943    while ((c = ast_channel_walk_locked(c)) != NULL) {
02944       struct ast_channel *bc = ast_bridged_channel(c);
02945       char durbuf[10] = "";
02946 
02947       if (c->cdr && !ast_tvzero(c->cdr->start)) {
02948          duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
02949          durh = duration / 3600;
02950          durm = (duration % 3600) / 60;
02951          durs = duration % 60;
02952          snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
02953       }
02954 
02955       astman_append(s,
02956          "Event: CoreShowChannel\r\n"
02957          "%s"
02958          "Channel: %s\r\n"
02959          "UniqueID: %s\r\n"
02960          "Context: %s\r\n"
02961          "Extension: %s\r\n"
02962          "Priority: %d\r\n"
02963          "ChannelState: %d\r\n"
02964          "ChannelStateDesc: %s\r\n"
02965          "Application: %s\r\n"
02966          "ApplicationData: %s\r\n"
02967          "CallerIDnum: %s\r\n"
02968          "Duration: %s\r\n"
02969          "AccountCode: %s\r\n"
02970          "BridgedChannel: %s\r\n"
02971          "BridgedUniqueID: %s\r\n"
02972          "\r\n", idText, c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state,
02973          ast_state2str(c->_state), c->appl ? c->appl : "", c->data ? S_OR(c->data, "") : "",
02974          S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : "");
02975       ast_channel_unlock(c);
02976       numchans++;
02977    }
02978 
02979    astman_append(s,
02980       "Event: CoreShowChannelsComplete\r\n"
02981       "EventList: Complete\r\n"
02982       "ListItems: %d\r\n"
02983       "%s"
02984       "\r\n", numchans, idText);
02985 
02986    return 0;
02987 }

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

Show PBX core status information.

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

02870 {
02871    const char *actionid = astman_get_header(m, "ActionID");
02872    char idText[150];
02873    char startuptime[150];
02874    char reloadtime[150];
02875    struct ast_tm tm;
02876 
02877    if (!ast_strlen_zero(actionid))
02878       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
02879    else
02880       idText[0] = '\0';
02881 
02882    ast_localtime(&ast_startuptime, &tm, NULL);
02883    ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
02884    ast_localtime(&ast_lastreloadtime, &tm, NULL);
02885    ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
02886 
02887    astman_append(s, "Response: Success\r\n"
02888          "%s"
02889          "CoreStartupTime: %s\r\n"
02890          "CoreReloadTime: %s\r\n"
02891          "CoreCurrentCalls: %d\r\n"
02892          "\r\n",
02893          idText,
02894          startuptime,
02895          reloadtime,
02896          ast_active_channels()
02897          );
02898    return 0;
02899 }

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

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

01611 {
01612    int fd;
01613    const char *fn = astman_get_header(m, "Filename");
01614    struct ast_str *filepath = ast_str_alloca(PATH_MAX);
01615    ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR);
01616    ast_str_append(&filepath, 0, "%s", fn);
01617 
01618    if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
01619       close(fd);
01620       astman_send_ack(s, m, "New configuration file created successfully");
01621    } else {
01622       astman_send_error(s, m, strerror(errno));
01623    }
01624 
01625    return 0;
01626 }

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

Definition at line 1760 of file manager.c.

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

Referenced by __init_manager().

01761 {
01762    const char *mask = astman_get_header(m, "EventMask");
01763    int res, x;
01764 
01765    res = set_eventmask(s, mask);
01766    if (broken_events_action) {
01767       /* if this option is set we should not return a response on
01768        * error, or when all events are set */
01769 
01770       if (res > 0) {
01771          for (x = 0; x < ARRAY_LEN(perms); x++) {
01772             if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) {
01773                return 0;
01774             }
01775          }
01776          astman_append(s, "Response: Success\r\n"
01777                 "Events: On\r\n\r\n");
01778       } else if (res == 0)
01779          astman_append(s, "Response: Success\r\n"
01780                 "Events: Off\r\n\r\n");
01781       return 0;
01782    }
01783 
01784    if (res > 0)
01785       astman_append(s, "Response: Success\r\n"
01786              "Events: On\r\n\r\n");
01787    else if (res == 0)
01788       astman_append(s, "Response: Success\r\n"
01789              "Events: Off\r\n\r\n");
01790    else
01791       astman_send_error(s, m, "Invalid event mask");
01792 
01793    return 0;
01794 }

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

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

02706 {
02707    const char *exten = astman_get_header(m, "Exten");
02708    const char *context = astman_get_header(m, "Context");
02709    char hint[256] = "";
02710    int status;
02711    if (ast_strlen_zero(exten)) {
02712       astman_send_error(s, m, "Extension not specified");
02713       return 0;
02714    }
02715    if (ast_strlen_zero(context))
02716       context = "default";
02717    status = ast_extension_state(NULL, context, exten);
02718    ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
02719    astman_start_ack(s, m);
02720    astman_append(s,   "Message: Extension Status\r\n"
02721             "Exten: %s\r\n"
02722             "Context: %s\r\n"
02723             "Hint: %s\r\n"
02724             "Status: %d\r\n\r\n",
02725             exten, context, hint, status);
02726    return 0;
02727 }

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

Definition at line 1201 of file manager.c.

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

Referenced by __init_manager().

01202 {
01203    struct ast_config *cfg;
01204    const char *fn = astman_get_header(m, "Filename");
01205    const char *category = astman_get_header(m, "Category");
01206    int catcount = 0;
01207    int lineno = 0;
01208    char *cur_category = NULL;
01209    struct ast_variable *v;
01210    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
01211 
01212    if (ast_strlen_zero(fn)) {
01213       astman_send_error(s, m, "Filename not specified");
01214       return 0;
01215    }
01216    cfg = ast_config_load2(fn, "manager", config_flags);
01217    if (cfg == CONFIG_STATUS_FILEMISSING) {
01218       astman_send_error(s, m, "Config file not found");
01219       return 0;
01220    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
01221       astman_send_error(s, m, "Config file has invalid format");
01222       return 0;
01223    }
01224 
01225    astman_start_ack(s, m);
01226    while ((cur_category = ast_category_browse(cfg, cur_category))) {
01227       if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) {
01228          lineno = 0;
01229          astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category);
01230          for (v = ast_variable_browse(cfg, cur_category); v; v = v->next)
01231             astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
01232          catcount++;
01233       }
01234    }
01235    if (!ast_strlen_zero(category) && catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */
01236       astman_append(s, "No categories found\r\n");
01237    ast_config_destroy(cfg);
01238    astman_append(s, "\r\n");
01239 
01240    return 0;
01241 }

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

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

Referenced by __init_manager().

01303 {
01304    struct ast_config *cfg;
01305    const char *fn = astman_get_header(m, "Filename");
01306    char *category = NULL;
01307    struct ast_variable *v;
01308    int comma1 = 0;
01309    char *buf = NULL;
01310    unsigned int buf_len = 0;
01311    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
01312 
01313    if (ast_strlen_zero(fn)) {
01314       astman_send_error(s, m, "Filename not specified");
01315       return 0;
01316    }
01317 
01318    if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
01319       astman_send_error(s, m, "Config file not found");
01320       return 0;
01321    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
01322       astman_send_error(s, m, "Config file has invalid format");
01323       return 0;
01324    }
01325 
01326    buf_len = 512;
01327    buf = alloca(buf_len);
01328 
01329    astman_start_ack(s, m);
01330    astman_append(s, "JSON: {");
01331    while ((category = ast_category_browse(cfg, category))) {
01332       int comma2 = 0;
01333       if (buf_len < 2 * strlen(category) + 1) {
01334          buf_len *= 2;
01335          buf = alloca(buf_len);
01336       }
01337       json_escape(buf, category);
01338       astman_append(s, "%s\"%s\":[", comma1 ? "," : "", buf);
01339       if (!comma1)
01340          comma1 = 1;
01341       for (v = ast_variable_browse(cfg, category); v; v = v->next) {
01342          if (comma2)
01343             astman_append(s, ",");
01344          if (buf_len < 2 * strlen(v->name) + 1) {
01345             buf_len *= 2;
01346             buf = alloca(buf_len);
01347          }
01348          json_escape(buf, v->name);
01349          astman_append(s, "\"%s", buf);
01350          if (buf_len < 2 * strlen(v->value) + 1) {
01351             buf_len *= 2;
01352             buf = alloca(buf_len);
01353          }
01354          json_escape(buf, v->value);
01355          astman_append(s, "%s\"", buf);
01356          if (!comma2)
01357             comma2 = 1;
01358       }
01359       astman_append(s, "]");
01360    }
01361    astman_append(s, "}\r\n\r\n");
01362 
01363    ast_config_destroy(cfg);
01364 
01365    return 0;
01366 }

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

Definition at line 1921 of file manager.c.

References ast_channel_alloc, ast_channel_free(), ast_channel_unlock, ast_func_read(), ast_get_channel_by_name_locked(), ast_log(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), check_user_can_execute_function(), LOG_ERROR, name, pbx_retrieve_variable(), S_OR, mansession::session, and mansession_session::writeperm.

Referenced by __init_manager().

01922 {
01923    struct ast_channel *c = NULL;
01924    const char *name = astman_get_header(m, "Channel");
01925    const char *varname = astman_get_header(m, "Variable");
01926    char *varval;
01927    char workspace[1024] = "";
01928 
01929    if (ast_strlen_zero(varname)) {
01930       astman_send_error(s, m, "No variable specified");
01931       return 0;
01932    }
01933 
01934    /* We don't want users with insufficient permissions using certain functions. */
01935    if (!(check_user_can_execute_function(varname, s->session->writeperm))) {
01936       astman_send_error(s, m, "GetVar Access Forbidden: Variable");
01937       return 0;
01938    }
01939 
01940    if (!ast_strlen_zero(name)) {
01941       c = ast_get_channel_by_name_locked(name);
01942       if (!c) {
01943          astman_send_error(s, m, "No such channel");
01944          return 0;
01945       }
01946    }
01947 
01948    if (varname[strlen(varname) - 1] == ')') {
01949       if (!c) {
01950          c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/manager");
01951          if (c) {
01952             ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
01953             ast_channel_free(c);
01954             c = NULL;
01955          } else
01956             ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution.  Function results may be blank.\n");
01957       } else
01958          ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
01959       varval = workspace;
01960    } else {
01961       pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
01962    }
01963 
01964    if (c)
01965       ast_channel_unlock(c);
01966    astman_start_ack(s, m);
01967    astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, S_OR(varval, ""));
01968 
01969    return 0;
01970 }

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

Definition at line 1851 of file manager.c.

References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and name.

Referenced by __init_manager().

01852 {
01853    struct ast_channel *c = NULL;
01854    const char *name = astman_get_header(m, "Channel");
01855    if (ast_strlen_zero(name)) {
01856       astman_send_error(s, m, "No channel specified");
01857       return 0;
01858    }
01859    c = ast_get_channel_by_name_locked(name);
01860    if (!c) {
01861       astman_send_error(s, m, "No such channel");
01862       return 0;
01863    }
01864    ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
01865    ast_channel_unlock(c);
01866    astman_send_ack(s, m, "Channel Hungup");
01867    return 0;
01868 }

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

Definition at line 1249 of file manager.c.

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

Referenced by __init_manager().

01250 {
01251    struct ast_config *cfg;
01252    const char *fn = astman_get_header(m, "Filename");
01253    char *category = NULL;
01254    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
01255    int catcount = 0;
01256 
01257    if (ast_strlen_zero(fn)) {
01258       astman_send_error(s, m, "Filename not specified");
01259       return 0;
01260    }
01261    if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
01262       astman_send_error(s, m, "Config file not found");
01263       return 0;
01264    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
01265       astman_send_error(s, m, "Config file has invalid format");
01266       return 0;
01267    }
01268    astman_start_ack(s, m);
01269    while ((category = ast_category_browse(cfg, category))) {
01270       astman_append(s, "Category-%06d: %s\r\n", catcount, category);
01271       catcount++;
01272    }
01273    if (catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */
01274       astman_append(s, "Error: no categories found\r\n");
01275    ast_config_destroy(cfg);
01276    astman_append(s, "\r\n");
01277 
01278    return 0;
01279 }

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

Note:
The actionlock is read-locked by the caller of this function

Definition at line 1736 of file manager.c.

References manager_action::action, AST_RWLIST_TRAVERSE, ast_str_alloca, astman_append(), astman_start_ack(), manager_action::authority, authority_to_str(), mansession::session, manager_action::synopsis, and mansession_session::writeperm.

Referenced by __init_manager().

01737 {
01738    struct manager_action *cur;
01739    struct ast_str *temp = ast_str_alloca(BUFSIZ); /* XXX very large ? */
01740 
01741    astman_start_ack(s, m);
01742    AST_RWLIST_TRAVERSE(&actions, cur, list) {
01743       if (s->session->writeperm & cur->authority || cur->authority == 0)
01744          astman_append(s, "%s: %s (Priv: %s)\r\n",
01745             cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
01746    }
01747    astman_append(s, "\r\n");
01748 
01749    return 0;
01750 }

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

Definition at line 1806 of file manager.c.

References ast_atomic_fetchadd_int(), ast_inet_ntoa(), ast_log(), AST_OPT_FLAG_FULLY_BOOTED, ast_opt_send_fullybooted, 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, LOG_EVENT, manager_displayconnects(), mansession_session::managerid, mansession::session, mansession_session::sin, and mansession_session::username.

Referenced by __init_manager().

01807 {
01808    if (authenticate(s, m)) {
01809       sleep(1);
01810       astman_send_error(s, m, "Authentication failed");
01811       return -1;
01812    }
01813    s->session->authenticated = 1;
01814    ast_atomic_fetchadd_int(&unauth_sessions, -1);
01815    if (manager_displayconnects(s->session))
01816       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));
01817    ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_inet_ntoa(s->session->sin.sin_addr));
01818    astman_send_ack(s, m, "Authentication accepted");
01819    if (ast_opt_send_fullybooted && ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
01820       struct ast_str *auth = ast_str_alloca(80);
01821       const char *cat_str = authority_to_str(EVENT_FLAG_SYSTEM, &auth);
01822       astman_append(s, "Event: FullyBooted\r\n"
01823          "Privilege: %s\r\n"
01824          "Status: Fully Booted\r\n\r\n", cat_str);
01825    }
01826    return 0;
01827 }

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

Definition at line 1800 of file manager.c.

References astman_send_response().

Referenced by __init_manager().

01801 {
01802    astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
01803    return -1;
01804 }

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

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

02674 {
02675    const char *mailbox = astman_get_header(m, "Mailbox");
02676    int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;;
02677 
02678    if (ast_strlen_zero(mailbox)) {
02679       astman_send_error(s, m, "Mailbox not specified");
02680       return 0;
02681    }
02682    ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs);
02683    astman_start_ack(s, m);
02684    astman_append(s,   "Message: Mailbox Message Count\r\n"
02685             "Mailbox: %s\r\n"
02686             "UrgMessages: %d\r\n"
02687             "NewMessages: %d\r\n"
02688             "OldMessages: %d\r\n"
02689             "\r\n",
02690             mailbox, urgentmsgs, newmsgs, oldmsgs);
02691    return 0;
02692 }

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

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

02645 {
02646    const char *mailbox = astman_get_header(m, "Mailbox");
02647    int ret;
02648 
02649    if (ast_strlen_zero(mailbox)) {
02650       astman_send_error(s, m, "Mailbox not specified");
02651       return 0;
02652    }
02653    ret = ast_app_has_voicemail(mailbox, NULL);
02654    astman_start_ack(s, m);
02655    astman_append(s, "Message: Mailbox Status\r\n"
02656           "Mailbox: %s\r\n"
02657           "Waiting: %d\r\n\r\n", mailbox, ret);
02658    return 0;
02659 }

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

Definition at line 2479 of file manager.c.

References fast_originate_helper::account, fast_originate_helper::app, app, fast_originate_helper::appdata, 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_strlen_zero(), ast_true(), ast_variables_destroy(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, context, fast_originate_helper::data, ast_frame::data, EVENT_FLAG_SYSTEM, fast_originate_helper::exten, exten, fast_originate(), fast_originate_helper::format, format, fast_originate_helper::idtext, name, fast_originate_helper::priority, mansession::session, strcasestr(), fast_originate_helper::tech, fast_originate_helper::timeout, fast_originate_helper::vars, and mansession_session::writeperm.

Referenced by __init_manager().

02480 {
02481    const char *name = astman_get_header(m, "Channel");
02482    const char *exten = astman_get_header(m, "Exten");
02483    const char *context = astman_get_header(m, "Context");
02484    const char *priority = astman_get_header(m, "Priority");
02485    const char *timeout = astman_get_header(m, "Timeout");
02486    const char *callerid = astman_get_header(m, "CallerID");
02487    const char *account = astman_get_header(m, "Account");
02488    const char *app = astman_get_header(m, "Application");
02489    const char *appdata = astman_get_header(m, "Data");
02490    const char *async = astman_get_header(m, "Async");
02491    const char *id = astman_get_header(m, "ActionID");
02492    const char *codecs = astman_get_header(m, "Codecs");
02493    struct ast_variable *vars;
02494    char *tech, *data;
02495    char *l = NULL, *n = NULL;
02496    int pi = 0;
02497    int res;
02498    int to = 30000;
02499    int reason = 0;
02500    char tmp[256];
02501    char tmp2[256];
02502    int format = AST_FORMAT_SLINEAR;
02503 
02504    pthread_t th;
02505    if (ast_strlen_zero(name)) {
02506       astman_send_error(s, m, "Channel not specified");
02507       return 0;
02508    }
02509    if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
02510       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
02511          astman_send_error(s, m, "Invalid priority");
02512          return 0;
02513       }
02514    }
02515    if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
02516       astman_send_error(s, m, "Invalid timeout");
02517       return 0;
02518    }
02519    ast_copy_string(tmp, name, sizeof(tmp));
02520    tech = tmp;
02521    data = strchr(tmp, '/');
02522    if (!data) {
02523       astman_send_error(s, m, "Invalid channel");
02524       return 0;
02525    }
02526    *data++ = '\0';
02527    ast_copy_string(tmp2, callerid, sizeof(tmp2));
02528    ast_callerid_parse(tmp2, &n, &l);
02529    if (n) {
02530       if (ast_strlen_zero(n))
02531          n = NULL;
02532    }
02533    if (l) {
02534       ast_shrink_phone_number(l);
02535       if (ast_strlen_zero(l))
02536          l = NULL;
02537    }
02538    if (!ast_strlen_zero(codecs)) {
02539       format = 0;
02540       ast_parse_allow_disallow(NULL, &format, codecs, 1);
02541    }
02542    if (!ast_strlen_zero(app)) {
02543       /* To run the System application (or anything else that goes to
02544        * shell), you must have the additional System privilege */
02545       if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
02546          && (
02547             strcasestr(app, "system") ||      /* System(rm -rf /)
02548                                                  TrySystem(rm -rf /)       */
02549             strcasestr(app, "exec") ||        /* Exec(System(rm -rf /))
02550                                                  TryExec(System(rm -rf /)) */
02551             strcasestr(app, "agi") ||         /* AGI(/bin/rm,-rf /)
02552                                                  EAGI(/bin/rm,-rf /)       */
02553             strstr(appdata, "SHELL") ||       /* NoOp(${SHELL(rm -rf /)})  */
02554             strstr(appdata, "EVAL")           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
02555             )) {
02556          astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have.");
02557          return 0;
02558       }
02559    }
02560 
02561    /* Allocate requested channel variables */
02562    vars = astman_get_variables(m);
02563 
02564    if (ast_true(async)) {
02565       struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast));
02566       if (!fast) {
02567          res = -1;
02568       } else {
02569          if (!ast_strlen_zero(id))
02570             snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s", id);
02571          ast_copy_string(fast->tech, tech, sizeof(fast->tech));
02572             ast_copy_string(fast->data, data, sizeof(fast->data));
02573          ast_copy_string(fast->app, app, sizeof(fast->app));
02574          ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata));
02575          if (l)
02576             ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num));
02577          if (n)
02578             ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name));
02579          fast->vars = vars;
02580          ast_copy_string(fast->context, context, sizeof(fast->context));
02581          ast_copy_string(fast->exten, exten, sizeof(fast->exten));
02582          ast_copy_string(fast->account, account, sizeof(fast->account));
02583          fast->format = format;
02584          fast->timeout = to;
02585          fast->priority = pi;
02586          if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) {
02587             ast_free(fast);
02588             res = -1;
02589          } else {
02590             res = 0;
02591          }
02592       }
02593    } else if (!ast_strlen_zero(app)) {
02594       int bad_appdata = 0;
02595       /* To run the System application (or anything else that goes to shell), you must have the additional System privilege */
02596       if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
02597          && (
02598             strcasestr(app, "system") ||      /* System(rm -rf /)
02599                                                  TrySystem(rm -rf /)       */
02600             strcasestr(app, "exec") ||        /* Exec(System(rm -rf /))
02601                                                  TryExec(System(rm -rf /)) */
02602             strcasestr(app, "agi") ||         /* AGI(/bin/rm,-rf /)
02603                                                  EAGI(/bin/rm,-rf /)       */
02604             (strstr(appdata, "SHELL") && (bad_appdata = 1)) ||       /* NoOp(${SHELL(rm -rf /)})  */
02605             (strstr(appdata, "EVAL") && (bad_appdata = 1))           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
02606             )) {
02607          char error_buf[64];
02608          snprintf(error_buf, sizeof(error_buf), "Originate Access Forbidden: %s", bad_appdata ? "Data" : "Application");
02609          astman_send_error(s, m, error_buf);
02610          return 0;
02611       }
02612       res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
02613    } else {
02614       if (exten && context && pi)
02615          res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL);
02616       else {
02617          astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
02618          if (vars) {
02619             ast_variables_destroy(vars);
02620          }
02621          return 0;
02622       }
02623    }
02624    if (!res)
02625       astman_send_ack(s, m, "Originate successfully queued");
02626    else
02627       astman_send_error(s, m, "Originate failed");
02628    return 0;
02629 }

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

Definition at line 1182 of file manager.c.

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

Referenced by __init_manager().

01183 {
01184    const char *actionid = astman_get_header(m, "ActionID");
01185 
01186    astman_append(s, "Response: Success\r\n");
01187    if (!ast_strlen_zero(actionid)){
01188       astman_append(s, "ActionID: %s\r\n", actionid);
01189    }
01190    astman_append(s, "Ping: Pong\r\n\r\n");
01191    return 0;
01192 }

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

action_redirect: The redirect manager command

Definition at line 2170 of file manager.c.

References ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_findlabel_extension(), AST_FLAG_BRIDGE_HANGUP_DONT, ast_get_channel_by_name_locked(), ast_set_flag, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), buf, chan, context, exten, name, ast_channel::pbx, and ast_channel::priority.

Referenced by __init_manager().

02171 {
02172    const char *name = astman_get_header(m, "Channel");
02173    const char *name2 = astman_get_header(m, "ExtraChannel");
02174    const char *exten = astman_get_header(m, "Exten");
02175    const char *context = astman_get_header(m, "Context");
02176    const char *priority = astman_get_header(m, "Priority");
02177    struct ast_channel *chan, *chan2 = NULL;
02178    int pi = 0;
02179    int res;
02180 
02181    if (ast_strlen_zero(name)) {
02182       astman_send_error(s, m, "Channel not specified");
02183       return 0;
02184    }
02185    if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
02186       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
02187          astman_send_error(s, m, "Invalid priority");
02188          return 0;
02189       }
02190    }
02191    /* XXX watch out, possible deadlock - we are trying to get two channels!!! */
02192    chan = ast_get_channel_by_name_locked(name);
02193    if (!chan) {
02194       char buf[256];
02195       snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
02196       astman_send_error(s, m, buf);
02197       return 0;
02198    }
02199    if (ast_check_hangup(chan)) {
02200       astman_send_error(s, m, "Redirect failed, channel not up.");
02201       ast_channel_unlock(chan);
02202       return 0;
02203    }
02204    if (!ast_strlen_zero(name2))
02205       chan2 = ast_get_channel_by_name_locked(name2);
02206    if (chan2 && ast_check_hangup(chan2)) {
02207       astman_send_error(s, m, "Redirect failed, extra channel not up.");
02208       ast_channel_unlock(chan);
02209       ast_channel_unlock(chan2);
02210       return 0;
02211    }
02212    if (chan->pbx) {
02213       ast_channel_lock(chan);
02214       ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
02215       ast_channel_unlock(chan);
02216    }
02217    res = ast_async_goto(chan, context, exten, pi);
02218    if (!res) {
02219       if (!ast_strlen_zero(name2)) {
02220          if (chan2) {
02221             if (chan2->pbx) {
02222                ast_channel_lock(chan2);
02223                ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
02224                ast_channel_unlock(chan2);
02225             }
02226             res = ast_async_goto(chan2, context, exten, pi);
02227          } else {
02228             res = -1;
02229          }
02230          if (!res)
02231             astman_send_ack(s, m, "Dual Redirect successful");
02232          else
02233             astman_send_error(s, m, "Secondary redirect failed");
02234       } else
02235          astman_send_ack(s, m, "Redirect successful");
02236    } else
02237       astman_send_error(s, m, "Redirect failed");
02238    if (chan)
02239       ast_channel_unlock(chan);
02240    if (chan2)
02241       ast_channel_unlock(chan2);
02242    return 0;
02243 }

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

Send a reload event.

Definition at line 2908 of file manager.c.

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

Referenced by __init_manager().

02909 {
02910    const char *module = astman_get_header(m, "Module");
02911    int res = ast_module_reload(S_OR(module, NULL));
02912 
02913    if (res == 2)
02914       astman_send_ack(s, m, "Module Reloaded");
02915    else
02916       astman_send_error(s, m, s == 0 ? "No such module" : "Module does not support reload");
02917    return 0;
02918 }

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

Definition at line 2124 of file manager.c.

References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_sendtext(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and name.

Referenced by __init_manager().

02125 {
02126    struct ast_channel *c = NULL;
02127    const char *name = astman_get_header(m, "Channel");
02128    const char *textmsg = astman_get_header(m, "Message");
02129    int res = 0;
02130 
02131    if (ast_strlen_zero(name)) {
02132       astman_send_error(s, m, "No channel specified");
02133       return 0;
02134    }
02135 
02136    if (ast_strlen_zero(textmsg)) {
02137       astman_send_error(s, m, "No Message specified");
02138       return 0;
02139    }
02140 
02141    c = ast_get_channel_by_name_locked(name);
02142    if (!c) {
02143       astman_send_error(s, m, "No such channel");
02144       return 0;
02145    }
02146 
02147    res = ast_sendtext(c, textmsg);
02148    ast_channel_unlock(c);
02149 
02150    if (res >= 0) {
02151       astman_send_ack(s, m, "Success");
02152    } else {
02153       astman_send_error(s, m, "Failure");
02154    }
02155 
02156    return res;
02157 }

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

Definition at line 1877 of file manager.c.

References ast_channel_unlock, ast_func_write(), ast_get_channel_by_name_locked(), ast_strdupa, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, pbx_builtin_setvar_helper(), and S_OR.

Referenced by __init_manager().

01878 {
01879    struct ast_channel *c = NULL;
01880    const char *name = astman_get_header(m, "Channel");
01881    const char *varname = astman_get_header(m, "Variable");
01882    const char *varval = astman_get_header(m, "Value");
01883    int res = 0;
01884    
01885    if (ast_strlen_zero(varname)) {
01886       astman_send_error(s, m, "No variable specified");
01887       return 0;
01888    }
01889 
01890    if (!ast_strlen_zero(name)) {
01891       c = ast_get_channel_by_name_locked(name);
01892       if (!c) {
01893          astman_send_error(s, m, "No such channel");
01894          return 0;
01895       }
01896    }
01897    if (varname[strlen(varname)-1] == ')') {
01898       char *function = ast_strdupa(varname);
01899       res = ast_func_write(c, function, varval);
01900    } else {
01901       pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
01902    }
01903 
01904    if (c)
01905       ast_channel_unlock(c);
01906    if (res == 0) {
01907       astman_send_ack(s, m, "Variable Set"); 
01908    } else {
01909       astman_send_error(s, m, "Variable not set");
01910    }
01911    return 0;
01912 }

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

Manager "status" command to show channels.

Definition at line 1984 of file manager.c.

References ast_channel::_bridge, ast_channel::_state, ast_channel::accountcode, AST_APP_ARG, ast_channel_unlock, ast_channel_walk_locked(), AST_DECLARE_APP_ARGS, ast_free, ast_func_read(), ast_get_channel_by_name_locked(), AST_STANDARD_APP_ARGS, ast_state2str(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_strdupa, ast_strlen_zero(), ast_tvnow(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::bridge, ast_channel::cdr, check_user_can_execute_function(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, ast_channel::name, name, ast_channel::pbx, pbx_retrieve_variable(), ast_channel::priority, S_OR, mansession::session, ast_cdr::start, str, ast_channel::uniqueid, and mansession_session::writeperm.

Referenced by __init_manager().

01985 {
01986    const char *name = astman_get_header(m, "Channel");
01987    const char *cvariables = astman_get_header(m, "Variables");
01988    char *variables = ast_strdupa(S_OR(cvariables, ""));
01989    struct ast_channel *c;
01990    char bridge[256];
01991    struct timeval now = ast_tvnow();
01992    long elapsed_seconds = 0;
01993    int channels = 0;
01994    int all = ast_strlen_zero(name); /* set if we want all channels */
01995    const char *id = astman_get_header(m, "ActionID");
01996    char idText[256];
01997    AST_DECLARE_APP_ARGS(vars,
01998       AST_APP_ARG(name)[100];
01999    );
02000    struct ast_str *str = ast_str_create(1000);
02001 
02002    if (!ast_strlen_zero(id))
02003       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
02004    else
02005       idText[0] = '\0';
02006 
02007    if (!(check_user_can_execute_function(variables, s->session->writeperm))) {
02008       astman_send_error(s, m, "Status Access Forbidden: Variables");
02009       return 0;
02010    }
02011 
02012    if (all)
02013       c = ast_channel_walk_locked(NULL);
02014    else {
02015       c = ast_get_channel_by_name_locked(name);
02016       if (!c) {
02017          astman_send_error(s, m, "No such channel");
02018          ast_free(str);
02019          return 0;
02020       }
02021    }
02022    astman_send_ack(s, m, "Channel status will follow");
02023 
02024    if (!ast_strlen_zero(cvariables)) {
02025       AST_STANDARD_APP_ARGS(vars, variables);
02026    }
02027 
02028    /* if we look by name, we break after the first iteration */
02029    while (c) {
02030       if (!ast_strlen_zero(cvariables)) {
02031          int i;
02032          ast_str_reset(str);
02033          for (i = 0; i < vars.argc; i++) {
02034             char valbuf[512], *ret = NULL;
02035 
02036             if (vars.name[i][strlen(vars.name[i]) - 1] == ')') {
02037                if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) {
02038                   valbuf[0] = '\0';
02039                }
02040                ret = valbuf;
02041             } else {
02042                pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL);
02043             }
02044 
02045             ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret);
02046          }
02047       }
02048 
02049       channels++;
02050       if (c->_bridge)
02051          snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid);
02052       else
02053          bridge[0] = '\0';
02054       if (c->pbx) {
02055          if (c->cdr) {
02056             elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
02057          }
02058          astman_append(s,
02059          "Event: Status\r\n"
02060          "Privilege: Call\r\n"
02061          "Channel: %s\r\n"
02062          "CallerIDNum: %s\r\n"
02063          "CallerIDName: %s\r\n"
02064          "Accountcode: %s\r\n"
02065          "ChannelState: %d\r\n"
02066          "ChannelStateDesc: %s\r\n"
02067          "Context: %s\r\n"
02068          "Extension: %s\r\n"
02069          "Priority: %d\r\n"
02070          "Seconds: %ld\r\n"
02071          "%s"
02072          "Uniqueid: %s\r\n"
02073          "%s"
02074          "%s"
02075          "\r\n",
02076          c->name,
02077          S_OR(c->cid.cid_num, ""),
02078          S_OR(c->cid.cid_name, ""),
02079          c->accountcode,
02080          c->_state,
02081          ast_state2str(c->_state), c->context,
02082          c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, ast_str_buffer(str), idText);
02083       } else {
02084          astman_append(s,
02085          "Event: Status\r\n"
02086          "Privilege: Call\r\n"
02087          "Channel: %s\r\n"
02088          "CallerIDNum: %s\r\n"
02089          "CallerIDName: %s\r\n"
02090          "Account: %s\r\n"
02091          "State: %s\r\n"
02092          "%s"
02093          "Uniqueid: %s\r\n"
02094          "%s"
02095          "%s"
02096          "\r\n",
02097          c->name,
02098          S_OR(c->cid.cid_num, "<unknown>"),
02099          S_OR(c->cid.cid_name, "<unknown>"),
02100          c->accountcode,
02101          ast_state2str(c->_state), bridge, c->uniqueid, ast_str_buffer(str), idText);
02102       }
02103       ast_channel_unlock(c);
02104       if (!all)
02105          break;
02106       c = ast_channel_walk_locked(c);
02107    }
02108    astman_append(s,
02109    "Event: StatusComplete\r\n"
02110    "%s"
02111    "Items: %d\r\n"
02112    "\r\n", idText, channels);
02113    ast_free(str);
02114    return 0;
02115 }

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

Definition at line 2736 of file manager.c.

References ast_channel_setwhentohangup_tv(), ast_channel_unlock, ast_get_channel_by_name_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and name.

Referenced by __init_manager().

02737 {
02738    struct ast_channel *c;
02739    const char *name = astman_get_header(m, "Channel");
02740    double timeout = atof(astman_get_header(m, "Timeout"));
02741    struct timeval when = { timeout, 0 };
02742 
02743    if (ast_strlen_zero(name)) {
02744       astman_send_error(s, m, "No channel specified");
02745       return 0;
02746    }
02747    if (!timeout || timeout < 0) {
02748       astman_send_error(s, m, "No timeout specified");
02749       return 0;
02750    }
02751    c = ast_get_channel_by_name_locked(name);
02752    if (!c) {
02753       astman_send_error(s, m, "No such channel");
02754       return 0;
02755    }
02756 
02757    when.tv_usec = (timeout - when.tv_sec) * 1000000.0;
02758    ast_channel_setwhentohangup_tv(c, when);
02759    ast_channel_unlock(c);
02760    astman_send_ack(s, m, "Timeout Set");
02761    return 0;
02762 }

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

Definition at line 1526 of file manager.c.

References ast_config_destroy(), ast_config_load2(), ast_config_text_file_save(), ast_include_rename(), ast_module_reload(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_send_ack(), astman_send_error(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, FAILURE_ALLOCATION, FAILURE_APPEND, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, handle_updates(), UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, and UNSPECIFIED_CATEGORY.

Referenced by __init_manager().

01527 {
01528    struct ast_config *cfg;
01529    const char *sfn = astman_get_header(m, "SrcFilename");
01530    const char *dfn = astman_get_header(m, "DstFilename");
01531    int res;
01532    const char *rld = astman_get_header(m, "Reload");
01533    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
01534    enum error_type result;
01535 
01536    if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
01537       astman_send_error(s, m, "Filename not specified");
01538       return 0;
01539    }
01540    if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) {
01541       astman_send_error(s, m, "Config file not found");
01542       return 0;
01543    } else if (cfg == CONFIG_STATUS_FILEINVALID) {
01544       astman_send_error(s, m, "Config file has invalid format");
01545       return 0;
01546    }
01547    result = handle_updates(s, m, cfg, dfn);
01548    if (!result) {
01549       ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
01550       res = ast_config_text_file_save(dfn, cfg, "Manager");
01551       ast_config_destroy(cfg);
01552       if (res) {
01553          astman_send_error(s, m, "Save of config failed");
01554          return 0;
01555       }
01556       astman_send_ack(s, m, NULL);
01557       if (!ast_strlen_zero(rld)) {
01558          if (ast_true(rld))
01559             rld = NULL;
01560          ast_module_reload(rld);
01561       }
01562    } else {
01563       ast_config_destroy(cfg);
01564       switch(result) {
01565       case UNKNOWN_ACTION:
01566          astman_send_error(s, m, "Unknown action command");
01567          break;
01568       case UNKNOWN_CATEGORY:
01569          astman_send_error(s, m, "Given category does not exist");
01570          break;
01571       case UNSPECIFIED_CATEGORY:
01572          astman_send_error(s, m, "Category not specified");
01573          break;
01574       case UNSPECIFIED_ARGUMENT:
01575          astman_send_error(s, m, "Problem with category, value, or line (if required)");
01576          break;
01577       case FAILURE_ALLOCATION:
01578          astman_send_error(s, m, "Memory allocation failure, this should not happen");
01579          break;
01580       case FAILURE_NEWCAT:
01581          astman_send_error(s, m, "Create category did not complete successfully");
01582          break;
01583       case FAILURE_DELCAT:
01584          astman_send_error(s, m, "Delete category did not complete successfully");
01585          break;
01586       case FAILURE_EMPTYCAT:
01587          astman_send_error(s, m, "Empty category did not complete successfully");
01588          break;
01589       case FAILURE_UPDATE:
01590          astman_send_error(s, m, "Update did not complete successfully");
01591          break;
01592       case FAILURE_DELETE:
01593          astman_send_error(s, m, "Delete did not complete successfully");
01594          break;
01595       case FAILURE_APPEND:
01596          astman_send_error(s, m, "Append did not complete successfully");
01597          break;
01598       }
01599    }
01600    return 0;
01601 }

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

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

02799 {
02800    const char *event = astman_get_header(m, "UserEvent");
02801    struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
02802    int x;
02803 
02804    ast_str_reset(body);
02805 
02806    for (x = 0; x < m->hdrcount; x++) {
02807       if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
02808          ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
02809       }
02810    }
02811 
02812    astman_send_ack(s, m, "Event Sent");   
02813    manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body));
02814    return 0;
02815 }

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

Definition at line 1636 of file manager.c.

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

Referenced by __init_manager().

01637 {
01638    const char *timeouts = astman_get_header(m, "Timeout");
01639    int timeout = -1;
01640    int x;
01641    int needexit = 0;
01642    const char *id = astman_get_header(m, "ActionID");
01643    char idText[256];
01644 
01645    if (!ast_strlen_zero(id))
01646       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01647    else
01648       idText[0] = '\0';
01649 
01650    if (!ast_strlen_zero(timeouts)) {
01651       sscanf(timeouts, "%30i", &timeout);
01652       if (timeout < -1)
01653          timeout = -1;
01654       /* XXX maybe put an upper bound, or prevent the use of 0 ? */
01655    }
01656 
01657    ast_mutex_lock(&s->session->__lock);
01658    if (s->session->waiting_thread != AST_PTHREADT_NULL)
01659       pthread_kill(s->session->waiting_thread, SIGURG);
01660 
01661    if (s->session->managerid) { /* AMI-over-HTTP session */
01662       /*
01663        * Make sure the timeout is within the expire time of the session,
01664        * as the client will likely abort the request if it does not see
01665        * data coming after some amount of time.
01666        */
01667       time_t now = time(NULL);
01668       int max = s->session->sessiontimeout - now - 10;
01669 
01670       if (max < 0)   /* We are already late. Strange but possible. */
01671          max = 0;
01672       if (timeout < 0 || timeout > max)
01673          timeout = max;
01674       if (!s->session->send_events) /* make sure we record events */
01675          s->session->send_events = -1;
01676    }
01677    ast_mutex_unlock(&s->session->__lock);
01678 
01679    /* XXX should this go inside the lock ? */
01680    s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
01681    ast_debug(1, "Starting waiting for an event!\n");
01682 
01683    for (x = 0; x < timeout || timeout < 0; x++) {
01684       ast_mutex_lock(&s->session->__lock);
01685       if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
01686          needexit = 1;
01687       }
01688       /* We can have multiple HTTP session point to the same mansession entry.
01689        * The way we deal with it is not very nice: newcomers kick out the previous
01690        * HTTP session. XXX this needs to be improved.
01691        */
01692       if (s->session->waiting_thread != pthread_self())
01693          needexit = 1;
01694       if (s->session->needdestroy)
01695          needexit = 1;
01696       ast_mutex_unlock(&s->session->__lock);
01697       if (needexit)
01698          break;
01699       if (s->session->managerid == 0) {   /* AMI session */
01700          if (ast_wait_for_input(s->session->fd, 1000))
01701             break;
01702       } else { /* HTTP session */
01703          sleep(1);
01704       }
01705    }
01706    ast_debug(1, "Finished waiting for an event!\n");
01707    ast_mutex_lock(&s->session->__lock);
01708    if (s->session->waiting_thread == pthread_self()) {
01709       struct eventqent *eqe = s->session->last_ev;
01710       astman_send_response(s, m, "Success", "Waiting for Event completed.");
01711       while ((eqe = advance_event(eqe))) {
01712          if (((s->session->readperm & eqe->category) == eqe->category) &&
01713              ((s->session->send_events & eqe->category) == eqe->category)) {
01714             astman_append(s, "%s", eqe->eventdata);
01715          }
01716          s->session->last_ev = eqe;
01717       }
01718       astman_append(s,
01719          "Event: WaitEventComplete\r\n"
01720          "%s"
01721          "\r\n", idText);
01722       s->session->waiting_thread = AST_PTHREADT_NULL;
01723    } else {
01724       ast_debug(1, "Abandoning event request!\n");
01725    }
01726    ast_mutex_unlock(&s->session->__lock);
01727    return 0;
01728 }

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

Definition at line 857 of file manager.c.

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

Referenced by action_waitevent(), and process_events().

00858 {
00859    struct eventqent *next;
00860 
00861    AST_RWLIST_RDLOCK(&all_events);
00862    if ((next = AST_RWLIST_NEXT(e, eq_next))) {
00863       ast_atomic_fetchadd_int(&next->usecount, 1);
00864       ast_atomic_fetchadd_int(&e->usecount, -1);
00865    }
00866    AST_RWLIST_UNLOCK(&all_events);
00867    return next;
00868 }

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

Definition at line 3433 of file manager.c.

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

Referenced by __init_manager(), and __manager_event().

03434 {
03435    struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
03436    static int seq;   /* sequence number */
03437 
03438    if (!tmp)
03439       return -1;
03440 
03441    /* need to init all fields, because ast_malloc() does not */
03442    tmp->usecount = 0;
03443    tmp->category = category;
03444    tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
03445    tmp->tv = ast_tvnow();
03446    AST_RWLIST_NEXT(tmp, eq_next) = NULL;
03447    strcpy(tmp->eventdata, str);
03448 
03449    AST_RWLIST_WRLOCK(&all_events);
03450    AST_RWLIST_INSERT_TAIL(&all_events, tmp, eq_next);
03451    AST_RWLIST_UNLOCK(&all_events);
03452 
03453    return 0;
03454 }

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

References eventqent::next.

Referenced by get_perm().

00457 {
00458    const char *val = bigstr, *next;
00459 
00460    do {
00461       if ((next = strchr(val, delim))) {
00462          if (!strncmp(val, smallstr, (next - val)))
00463             return 1;
00464          else
00465             continue;
00466       } else
00467          return !strcmp(smallstr, val);
00468    } while (*(val = (next + 1)));
00469 
00470    return 0;
00471 }

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

register a new command with manager, including online help. This is the preferred way to register a manager command

Register a manager command with the manager interface.

Definition at line 3609 of file manager.c.

References manager_action::action, ast_calloc, ast_free, ast_manager_register_struct(), manager_action::authority, manager_action::description, manager_action::func, and manager_action::synopsis.

Referenced by __init_manager(), ast_features_init(), load_module(), and load_pbx().

03610 {
03611    struct manager_action *cur = NULL;
03612 
03613    if (!(cur = ast_calloc(1, sizeof(*cur))))
03614       return -1;
03615 
03616    cur->action = action;
03617    cur->authority = auth;
03618    cur->func = func;
03619    cur->synopsis = synopsis;
03620    cur->description = description;
03621 
03622    if (ast_manager_register_struct(cur)) {
03623       ast_free(cur);
03624       return -1;
03625    }
03626 
03627    return 0;
03628 }

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

References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

00271 {
00272    AST_RWLIST_WRLOCK(&manager_hooks);
00273    AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list);
00274    AST_RWLIST_UNLOCK(&manager_hooks);
00275    return;
00276 }

static int ast_manager_register_struct ( struct manager_action act  )  [static]

Definition at line 3573 of file manager.c.

References manager_action::action, ast_log(), AST_RWLIST_INSERT_AFTER, AST_RWLIST_INSERT_HEAD, AST_RWLIST_TIMEDWRLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_verb, LOG_ERROR, LOG_WARNING, and eventqent::tv.

Referenced by ast_manager_register2().

03574 {
03575    struct manager_action *cur, *prev = NULL;
03576    struct timespec tv = { 5, };
03577 
03578    if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) {
03579       ast_log(LOG_ERROR, "Could not obtain lock on manager list\n");
03580       return -1;
03581    }
03582    AST_RWLIST_TRAVERSE(&actions, cur, list) {
03583       int ret = strcasecmp(cur->action, act->action);
03584       if (ret == 0) {
03585          ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
03586          AST_RWLIST_UNLOCK(&actions);
03587          return -1;
03588       }
03589       if (ret > 0) { /* Insert these alphabetically */
03590          prev = cur;
03591          break;
03592       }
03593    }
03594 
03595    if (prev)
03596       AST_RWLIST_INSERT_AFTER(&actions, prev, act, list);
03597    else
03598       AST_RWLIST_INSERT_HEAD(&actions, act, list);
03599 
03600    ast_verb(2, "Manager registered action %s\n", act->action);
03601 
03602    AST_RWLIST_UNLOCK(&actions);
03603 
03604    return 0;
03605 }

int ast_manager_unregister ( char *  action  ) 

Unregister a registered manager command.

Parameters:
action Name of registered Action:

Definition at line 3540 of file manager.c.

References manager_action::action, ast_free, ast_log(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TIMEDWRLOCK, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, ast_verb, LOG_ERROR, and eventqent::tv.

Referenced by __unload_module(), and unload_module().

03541 {
03542    struct manager_action *cur;
03543    struct timespec tv = { 5, };
03544 
03545    if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) {
03546       ast_log(LOG_ERROR, "Could not obtain lock on manager list\n");
03547       return -1;
03548    }
03549    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) {
03550       if (!strcasecmp(action, cur->action)) {
03551          AST_RWLIST_REMOVE_CURRENT(list);
03552          ast_free(cur);
03553          ast_verb(2, "Manager unregistered action %s\n", action);
03554          break;
03555       }
03556    }
03557    AST_RWLIST_TRAVERSE_SAFE_END;
03558    AST_RWLIST_UNLOCK(&actions);
03559 
03560    return 0;
03561 }

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

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

00280 {
00281    AST_RWLIST_WRLOCK(&manager_hooks);
00282    AST_RWLIST_REMOVE(&manager_hooks, hook, list);
00283    AST_RWLIST_UNLOCK(&manager_hooks);
00284    return;
00285 }

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

utility functions for creating AMI replies

Definition at line 1014 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, buf, 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(), action_status(), action_waitevent(), ast_cli_netstats(), astman_send_response_full(), do_print(), manager_dbget(), manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_registry(), manager_jabber_send(), manager_list_voicemail_users(), manager_modulecheck(), manager_parking_status(), manager_queue_rule_show(), manager_queues_show(), manager_queues_status(), manager_queues_summary(), manager_rpt_local_nodes(), manager_rpt_status(), 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(), rpt_manager_do_stats(), rpt_manager_success(), and session_do().

01015 {
01016    va_list ap;
01017    struct ast_str *buf;
01018 
01019    if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE)))
01020       return;
01021 
01022    va_start(ap, fmt);
01023    ast_str_set_va(&buf, 0, fmt, ap);
01024    va_end(ap);
01025 
01026    if (s->f != NULL || s->session->f != NULL) {
01027       send_string(s, ast_str_buffer(buf));
01028    } else {
01029       ast_verbose("fd == -1 in astman_append, should not happen\n");
01030    }
01031 }

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

Get header from mananger transaction.

Definition at line 938 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_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(), astman_send_response_full(), authenticate(), change_monitor_action(), do_pause_or_unpause(), handle_updates(), manager_add_queue_member(), 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_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_rpt_status(), 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(), rpt_manager_do_stats(), rpt_manager_success(), start_monitor_action(), and stop_monitor_action().

00939 {
00940    return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH);
00941 }

struct ast_variable* astman_get_variables ( const struct message m  )  [read]

Get a linked list of the Variable: headers.

Definition at line 944 of file manager.c.

References AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_variable_new(), message::hdrcount, message::headers, parse(), strsep(), and var.

Referenced by action_originate(), and manager_sipnotify().

00945 {
00946    int varlen, x, y;
00947    struct ast_variable *head = NULL, *cur;
00948 
00949    AST_DECLARE_APP_ARGS(args,
00950       AST_APP_ARG(vars)[32];
00951    );
00952 
00953    varlen = strlen("Variable: ");
00954 
00955    for (x = 0; x < m->hdrcount; x++) {
00956       char *parse, *var, *val;
00957 
00958       if (strncasecmp("Variable: ", m->headers[x], varlen))
00959          continue;
00960       parse = ast_strdupa(m->headers[x] + varlen);
00961 
00962       AST_STANDARD_APP_ARGS(args, parse);
00963       if (!args.argc)
00964          continue;
00965       for (y = 0; y < args.argc; y++) {
00966          if (!args.vars[y])
00967             continue;
00968          var = val = ast_strdupa(args.vars[y]);
00969          strsep(&val, "=");
00970          if (!val || ast_strlen_zero(var))
00971             continue;
00972          cur = ast_variable_new(var, val, "");
00973          cur->next = head;
00974          head = cur;
00975       }
00976    }
00977 
00978    return head;
00979 }

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

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

Send error in manager transaction.

Definition at line 1072 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_atxfer(), action_bridge(), action_challenge(), action_command(), 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_pause_or_unpause(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_modulecheck(), manager_moduleload(), 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_rpt_status(), 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(), rpt_manager_do_stats(), start_monitor_action(), and stop_monitor_action().

01073 {
01074    astman_send_response_full(s, m, "Error", error, NULL);
01075 }

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

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

Send response in manager transaction.

Definition at line 1067 of file manager.c.

References astman_send_response_full().

Referenced by action_logoff(), and action_waitevent().

01068 {
01069    astman_send_response_full(s, m, resp, msg, NULL);
01070 }

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

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

01051 {
01052    const char *id = astman_get_header(m, "ActionID");
01053 
01054    astman_append(s, "Response: %s\r\n", resp);
01055    if (!ast_strlen_zero(id))
01056       astman_append(s, "ActionID: %s\r\n", id);
01057    if (listflag)
01058       astman_append(s, "EventList: %s\r\n", listflag);   /* Start, complete, cancelled */
01059    if (msg == MSG_MOREDATA)
01060       return;
01061    else if (msg)
01062       astman_append(s, "Message: %s\r\n\r\n", msg);
01063    else
01064       astman_append(s, "\r\n");
01065 }

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

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

Definition at line 1116 of file manager.c.

References ast_apply_ha(), ast_copy_string(), ast_debug, ast_inet_ntoa(), ast_log(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), astman_get_header(), mansession_session::challenge, get_manager_by_name_locked(), ast_manager_user::ha, len(), LOG_NOTICE, MD5Final(), MD5Init(), MD5Update(), ast_manager_user::readperm, mansession_session::readperm, S_OR, ast_manager_user::secret, mansession::session, mansession_session::sessionstart, set_eventmask(), mansession_session::sin, mansession_session::username, ast_manager_user::writeperm, mansession_session::writeperm, ast_manager_user::writetimeout, and mansession_session::writetimeout.

01117 {
01118    const char *username = astman_get_header(m, "Username");
01119    const char *password = astman_get_header(m, "Secret");
01120    int error = -1;
01121    struct ast_manager_user *user = NULL;
01122 
01123    if (ast_strlen_zero(username))   /* missing username */
01124       return -1;
01125 
01126    /* locate user in locked state */
01127    AST_RWLIST_WRLOCK(&users);
01128 
01129    if (!(user = get_manager_by_name_locked(username))) {
01130       ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
01131    } else if (user->ha && !ast_apply_ha(user->ha, &(s->session->sin))) {
01132       ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
01133    } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
01134       const char *key = astman_get_header(m, "Key");
01135       if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
01136          int x;
01137          int len = 0;
01138          char md5key[256] = "";
01139          struct MD5Context md5;
01140          unsigned char digest[16];
01141 
01142          MD5Init(&md5);
01143          MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
01144          MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
01145          MD5Final(digest, &md5);
01146          for (x = 0; x < 16; x++)
01147             len += sprintf(md5key + len, "%2.2x", digest[x]);
01148          if (!strcmp(md5key, key))
01149             error = 0;
01150       } else {
01151          ast_debug(1, "MD5 authentication is not possible.  challenge: '%s'\n", 
01152             S_OR(s->session->challenge, ""));
01153       }
01154    } else if (password && user->secret && !strcmp(password, user->secret))
01155       error = 0;
01156 
01157    if (error) {
01158       ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
01159       AST_RWLIST_UNLOCK(&users);
01160       return -1;
01161    }
01162 
01163    /* auth complete */
01164    
01165    ast_copy_string(s->session->username, username, sizeof(s->session->username));
01166    s->session->readperm = user->readperm;
01167    s->session->writeperm = user->writeperm;
01168    s->session->writetimeout = user->writetimeout;
01169    s->session->sessionstart = time(NULL);
01170    set_eventmask(s, astman_get_header(m, "Events"));
01171    
01172    AST_RWLIST_UNLOCK(&users);
01173    return 0;
01174 }

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

Convert authority code to a list of options.

Definition at line 432 of file manager.c.

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

Referenced by __manager_event(), action_listcommands(), action_login(), handle_showmanager(), handle_showmancmd(), and handle_showmancmds().

00433 {
00434    int i;
00435    char *sep = "";
00436 
00437    ast_str_reset(*res);
00438    for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
00439       if (authority & perms[i].num) {
00440          ast_str_append(res, 0, "%s%s", sep, perms[i].label);
00441          sep = ",";
00442       }
00443    }
00444 
00445    if (ast_str_strlen(*res) == 0)   /* replace empty string with something sensible */
00446       ast_str_append(res, 0, "<none>");
00447 
00448    return ast_str_buffer(*res);
00449 }

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

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

02303 {
02304    char *cmd_copy, *cur_cmd;
02305    char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, };
02306    int i;
02307 
02308    cmd_copy = ast_strdupa(cmd);
02309    for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) {
02310       cur_cmd = ast_strip(cur_cmd);
02311       if (ast_strlen_zero(cur_cmd)) {
02312          i--;
02313          continue;
02314       }
02315 
02316       cmd_words[i] = cur_cmd;
02317    }
02318 
02319    for (i = 0; i < ARRAY_LEN(command_blacklist); i++) {
02320       int j, match = 1;
02321 
02322       for (j = 0; command_blacklist[i].words[j]; j++) {
02323          if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) {
02324             match = 0;
02325             break;
02326          }
02327       }
02328 
02329       if (match) {
02330          return 1;
02331       }
02332    }
02333 
02334    return 0;
02335 }

int check_manager_enabled ( void   ) 

Event list management functions. We assume that the event list always has at least one element, and the delete code will not remove the last entry even if the.

Check if AMI is enabled.

Definition at line 330 of file manager.c.

Referenced by handle_show_settings().

00331 {
00332    return manager_enabled;
00333 }

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

Definition at line 515 of file manager.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, mansession_session::list, and mansession_session::username.

Referenced by process_message().

00516 {
00517    struct mansession_session *session = NULL;
00518 
00519    AST_LIST_LOCK(&sessions);
00520    AST_LIST_TRAVERSE(&sessions, session, list) {
00521       if (!strcasecmp(session->username, name)) 
00522          break;
00523    }
00524    AST_LIST_UNLOCK(&sessions);
00525 
00526    return session ? 1 : 0;
00527 }

static int check_user_can_execute_function ( 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 419 of file manager.c.

References EVENT_FLAG_SYSTEM.

Referenced by action_getvar(), and action_status().

00420 {
00421    if (!(writepermlist & EVENT_FLAG_SYSTEM)
00422       && (
00423          strstr(evaluating, "SHELL") ||       /* NoOp(${SHELL(rm -rf /)})  */
00424          strstr(evaluating, "EVAL")           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
00425       )) {
00426       return 0;
00427    }
00428    return 1;
00429 }

int check_webmanager_enabled ( void   ) 

Check if AMI/HTTP is enabled.

Definition at line 335 of file manager.c.

Referenced by action_coresettings(), and handle_show_settings().

00336 {
00337    return (webmanager_enabled && manager_enabled);
00338 }

static void destroy_session ( struct mansession_session session  )  [static]

Definition at line 893 of file manager.c.

References ast_atomic_fetchadd_int(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, and free_session().

00894 {
00895    AST_LIST_LOCK(&sessions);
00896    AST_LIST_REMOVE(&sessions, session, list);
00897    ast_atomic_fetchadd_int(&num_sessions, -1);
00898    free_session(session);
00899    AST_LIST_UNLOCK(&sessions);
00900 }

static int do_message ( struct mansession s  )  [static]

Definition at line 3267 of file manager.c.

References ast_inet_ntoa(), ast_log(), AST_MAX_MANHEADERS, ast_strdupa, ast_strlen_zero(), mansession_session::authenticated, mansession_session::authstart, errno, get_input(), message::hdrcount, message::headers, mansession_session::inbuf, LOG_ERROR, LOG_EVENT, process_events(), process_message(), mansession::session, and mansession_session::sin.

Referenced by session_do().

03268 {
03269    struct message m = { 0 };
03270    char header_buf[sizeof(s->session->inbuf)] = { '\0' };
03271    int res;
03272    time_t now;
03273 
03274    for (;;) {
03275       /* Check if any events are pending and do them if needed */
03276       if (process_events(s))
03277          return -1;
03278       res = get_input(s, header_buf);
03279       if (res == 0) {
03280          if (!s->session->authenticated) {
03281             if(time(&now) == -1) {
03282                ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
03283                return -1;
03284             }
03285 
03286             if (now - s->session->authstart > authtimeout) {
03287                ast_log(LOG_EVENT, "Client from %s, failed to authenticate in %d seconds\n", ast_inet_ntoa(s->session->sin.sin_addr), authtimeout);
03288                return -1;
03289             }
03290          }
03291          continue;
03292       } else if (res > 0) {
03293          if (ast_strlen_zero(header_buf))
03294             return process_message(s, &m) ? -1 : 0;
03295          else if (m.hdrcount < (AST_MAX_MANHEADERS - 1))
03296             m.headers[m.hdrcount++] = ast_strdupa(header_buf);
03297       } else {
03298          return res;
03299       }
03300    }
03301 }

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

Definition at line 2415 of file manager.c.

References fast_originate_helper::account, fast_originate_helper::app, fast_originate_helper::appdata, AST_CHANNEL_NAME, ast_channel_unlock, ast_free, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_strlen_zero(), chan, fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, fast_originate_helper::data, EVENT_FLAG_CALL, fast_originate_helper::exten, fast_originate_helper::format, fast_originate_helper::idtext, manager_event, 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().

02416 {
02417    struct fast_originate_helper *in = data;
02418    int res;
02419    int reason = 0;
02420    struct ast_channel *chan = NULL;
02421    char requested_channel[AST_CHANNEL_NAME];
02422 
02423    if (!ast_strlen_zero(in->app)) {
02424       res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1,
02425          S_OR(in->cid_num, NULL),
02426          S_OR(in->cid_name, NULL),
02427          in->vars, in->account, &chan);
02428    } else {
02429       res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1,
02430          S_OR(in->cid_num, NULL),
02431          S_OR(in->cid_name, NULL),
02432          in->vars, in->account, &chan);
02433    }
02434 
02435    if (!chan)
02436       snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);   
02437    /* Tell the manager what happened with the channel */
02438    manager_event(EVENT_FLAG_CALL, "OriginateResponse",
02439       "%s%s"
02440       "Response: %s\r\n"
02441       "Channel: %s\r\n"
02442       "Context: %s\r\n"
02443       "Exten: %s\r\n"
02444       "Reason: %d\r\n"
02445       "Uniqueid: %s\r\n"
02446       "CallerIDNum: %s\r\n"
02447       "CallerIDName: %s\r\n",
02448       in->idtext, ast_strlen_zero(in->idtext) ? "" : "\r\n", res ? "Failure" : "Success", 
02449       chan ? chan->name : requested_channel, in->context, in->exten, reason, 
02450       chan ? chan->uniqueid : "<null>",
02451       S_OR(in->cid_num, "<unknown>"),
02452       S_OR(in->cid_name, "<unknown>")
02453       );
02454 
02455    /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
02456    if (chan)
02457       ast_channel_unlock(chan);
02458    ast_free(in);
02459    return NULL;
02460 }

static void free_session ( struct mansession_session session  )  [static]

Definition at line 873 of file manager.c.

References mansession_session::__lock, ast_atomic_fetchadd_int(), ast_datastore_free(), ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_destroy(), mansession_session::datastores, ast_datastore::entry, mansession_session::f, mansession_session::last_ev, and eventqent::usecount.

Referenced by destroy_session(), and purge_sessions().

00874 {
00875    struct eventqent *eqe = session->last_ev;
00876    struct ast_datastore *datastore;
00877 
00878    /* Get rid of each of the data stores on the session */
00879    while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) {
00880       /* Free the data store */
00881       ast_datastore_free(datastore);
00882    }
00883 
00884    if (session->f != NULL)
00885       fclose(session->f);
00886    ast_mutex_destroy(&session->__lock);
00887    ast_free(session);
00888    if (eqe) {
00889       ast_atomic_fetchadd_int(&eqe->usecount, -1);
00890    }
00891 }

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

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

03182 {
03183    int res, x;
03184    int maxlen = sizeof(s->session->inbuf) - 1;
03185    char *src = s->session->inbuf;
03186    int timeout = -1;
03187    time_t now;
03188 
03189    /*
03190     * Look for \r\n within the buffer. If found, copy to the output
03191     * buffer and return, trimming the \r\n (not used afterwards).
03192     */
03193    for (x = 0; x < s->session->inlen; x++) {
03194       int cr;  /* set if we have \r */
03195       if (src[x] == '\r' && x+1 < s->session->inlen && src[x+1] == '\n')
03196          cr = 2;  /* Found. Update length to include \r\n */
03197       else if (src[x] == '\n')
03198          cr = 1;  /* also accept \n only */
03199       else
03200          continue;
03201       memmove(output, src, x);   /*... but trim \r\n */
03202       output[x] = '\0';    /* terminate the string */
03203       x += cr;       /* number of bytes used */
03204       s->session->inlen -= x;       /* remaining size */
03205       memmove(src, src + x, s->session->inlen); /* remove used bytes */
03206       return 1;
03207    }
03208    if (s->session->inlen >= maxlen) {
03209       /* no crlf found, and buffer full - sorry, too long for us */
03210       ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src);
03211       s->session->inlen = 0;
03212    }
03213    res = 0;
03214    while (res == 0) {
03215       /* calculate a timeout if we are not authenticated */
03216       if (!s->session->authenticated) {
03217          if(time(&now) == -1) {
03218             ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
03219             return -1;
03220          }
03221 
03222          timeout = (authtimeout - (now - s->session->authstart)) * 1000;
03223          if (timeout < 0) {
03224             /* we have timed out */
03225             return 0;
03226          }
03227       }
03228 
03229       /* XXX do we really need this locking ? */
03230       ast_mutex_lock(&s->session->__lock);
03231       if (s->session->pending_event) {
03232          s->session->pending_event = 0;
03233          ast_mutex_unlock(&s->session->__lock);
03234          return 0;
03235       }
03236       s->session->waiting_thread = pthread_self();
03237       ast_mutex_unlock(&s->session->__lock);
03238 
03239       res = ast_wait_for_input(s->session->fd, timeout);
03240 
03241       ast_mutex_lock(&s->session->__lock);
03242       s->session->waiting_thread = AST_PTHREADT_NULL;
03243       ast_mutex_unlock(&s->session->__lock);
03244    }
03245    if (res < 0) {
03246       /* If we get a signal from some other thread (typically because
03247        * there are new events queued), return 0 to notify the caller.
03248        */
03249       if (errno == EINTR || errno == EAGAIN)
03250          return 0;
03251       ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
03252       return -1;
03253    }
03254    ast_mutex_lock(&s->session->__lock);
03255    res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f);
03256    if (res < 1)
03257       res = -1;   /* error return */
03258    else {
03259       s->session->inlen += res;
03260       src[s->session->inlen] = '\0';
03261       res = 0;
03262    }
03263    ast_mutex_unlock(&s->session->__lock);
03264    return res;
03265 }

static struct ast_manager_user* get_manager_by_name_locked ( const char *  name  )  [static, read]

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

Definition at line 534 of file manager.c.

References AST_RWLIST_TRAVERSE, ast_manager_user::list, and ast_manager_user::username.

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

00535 {
00536    struct ast_manager_user *user = NULL;
00537 
00538    AST_RWLIST_TRAVERSE(&users, user, list)
00539       if (!strcasecmp(user->username, name))
00540          break;
00541    return user;
00542 }

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

Definition at line 473 of file manager.c.

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

Referenced by __init_manager(), and strings_to_mask().

00474 {
00475    int x = 0, ret = 0;
00476 
00477    if (!instr)
00478       return 0;
00479 
00480    for (x = 0; x < ARRAY_LEN(perms); x++) {
00481       if (ast_instring(instr, perms[x].label, ','))
00482          ret |= perms[x].num;
00483    }
00484 
00485    return ret;
00486 }

static struct eventqent* grab_last ( void   )  [static, read]

Grab a reference to the last event, update usecount as needed. Can handle a NULL pointer.

Definition at line 344 of file manager.c.

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

Referenced by generic_http_callback(), and session_do().

00345 {
00346    struct eventqent *ret;
00347 
00348    AST_RWLIST_RDLOCK(&all_events);
00349    ret = AST_RWLIST_LAST(&all_events);
00350    /* the list is never empty now, but may become so when
00351     * we optimize it in the future, so be prepared.
00352     */
00353    if (ret) {
00354       ast_atomic_fetchadd_int(&ret->usecount, 1);
00355    }
00356    AST_RWLIST_UNLOCK(&all_events);
00357    return ret;
00358 }

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

00828 {
00829    switch (cmd) {
00830    case CLI_INIT:
00831       e->command = "manager reload";
00832       e->usage =
00833          "Usage: manager reload\n"
00834          "       Reloads the manager configuration.\n";
00835       return NULL;
00836    case CLI_GENERATE:
00837       return NULL;
00838    }
00839    if (a->argc > 2)
00840       return CLI_SHOWUSAGE;
00841    reload_manager();
00842    return CLI_SUCCESS;
00843 }

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

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

00609 {
00610    switch (cmd) {
00611    case CLI_INIT:
00612       e->command = "manager set debug [on|off]";
00613       e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n";
00614       return NULL;
00615    case CLI_GENERATE:
00616       return NULL;   
00617    }
00618    if (a->argc == 3)
00619       ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off");
00620    else if (a->argc == 4) {
00621       if (!strcasecmp(a->argv[3], "on"))
00622          manager_debug = 1;
00623       else if (!strcasecmp(a->argv[3], "off"))
00624          manager_debug = 0;
00625       else
00626          return CLI_SHOWUSAGE;
00627    }
00628    return CLI_SUCCESS;
00629 }

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

Definition at line 631 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_manager_user::displayconnects, ast_cli_args::fd, get_manager_by_name_locked(), ast_manager_user::ha, ast_cli_args::n, ast_cli_args::pos, ast_manager_user::readperm, ast_manager_user::secret, ast_cli_entry::usage, ast_manager_user::username, ast_cli_args::word, and ast_manager_user::writeperm.

00632 {
00633    struct ast_manager_user *user = NULL;
00634    int l, which;
00635    char *ret = NULL;
00636    struct ast_str *rauthority = ast_str_alloca(128);
00637    struct ast_str *wauthority = ast_str_alloca(128);
00638 
00639    switch (cmd) {
00640    case CLI_INIT:
00641       e->command = "manager show user";
00642       e->usage = 
00643          " Usage: manager show user <user>\n"
00644          "        Display all information related to the manager user specified.\n";
00645       return NULL;
00646    case CLI_GENERATE:
00647       l = strlen(a->word);
00648       which = 0;
00649       if (a->pos != 3)
00650          return NULL;
00651       AST_RWLIST_RDLOCK(&users);
00652       AST_RWLIST_TRAVERSE(&users, user, list) {
00653          if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) {
00654             ret = ast_strdup(user->username);
00655             break;
00656          }
00657       }
00658       AST_RWLIST_UNLOCK(&users);
00659       return ret;
00660    }
00661 
00662    if (a->argc != 4)
00663       return CLI_SHOWUSAGE;
00664 
00665    AST_RWLIST_RDLOCK(&users);
00666 
00667    if (!(user = get_manager_by_name_locked(a->argv[3]))) {
00668       ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]);
00669       AST_RWLIST_UNLOCK(&users);
00670       return CLI_SUCCESS;
00671    }
00672 
00673    ast_cli(a->fd, "\n");
00674    ast_cli(a->fd,
00675       "       username: %s\n"
00676       "         secret: %s\n"
00677       "            acl: %s\n"
00678       "      read perm: %s\n"
00679       "     write perm: %s\n"
00680       "displayconnects: %s\n",
00681       (user->username ? user->username : "(N/A)"),
00682       (user->secret ? "<Set>" : "(N/A)"),
00683       (user->ha ? "yes" : "no"),
00684       authority_to_str(user->readperm, &rauthority),
00685       authority_to_str(user->writeperm, &wauthority),
00686       (user->displayconnects ? "yes" : "no"));
00687 
00688    AST_RWLIST_UNLOCK(&users);
00689 
00690    return CLI_SUCCESS;
00691 }

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

Definition at line 694 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 ast_manager_user::username.

00695 {
00696    struct ast_manager_user *user = NULL;
00697    int count_amu = 0;
00698    switch (cmd) {
00699    case CLI_INIT:
00700       e->command = "manager show users";
00701       e->usage = 
00702          "Usage: manager show users\n"
00703          "       Prints a listing of all managers that are currently configured on that\n"
00704          " system.\n";
00705       return NULL;
00706    case CLI_GENERATE:
00707       return NULL;
00708    }
00709    if (a->argc != 3)
00710       return CLI_SHOWUSAGE;
00711 
00712    AST_RWLIST_RDLOCK(&users);
00713 
00714    /* If there are no users, print out something along those lines */
00715    if (AST_RWLIST_EMPTY(&users)) {
00716       ast_cli(a->fd, "There are no manager users.\n");
00717       AST_RWLIST_UNLOCK(&users);
00718       return CLI_SUCCESS;
00719    }
00720 
00721    ast_cli(a->fd, "\nusername\n--------\n");
00722 
00723    AST_RWLIST_TRAVERSE(&users, user, list) {
00724       ast_cli(a->fd, "%s\n", user->username);
00725       count_amu++;
00726    }
00727 
00728    AST_RWLIST_UNLOCK(&users);
00729 
00730    ast_cli(a->fd, "-------------------\n");
00731    ast_cli(a->fd, "%d manager users configured.\n", count_amu);
00732 
00733    return CLI_SUCCESS;
00734 }

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

Definition at line 561 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, manager_action::authority, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, manager_action::description, ast_cli_args::fd, ast_cli_args::n, num, S_OR, manager_action::synopsis, ast_cli_entry::usage, and ast_cli_args::word.

00562 {
00563    struct manager_action *cur;
00564    struct ast_str *authority;
00565    int num, l, which;
00566    char *ret = NULL;
00567    switch (cmd) {
00568    case CLI_INIT:
00569       e->command = "manager show command";
00570       e->usage = 
00571          "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n"
00572          "  Shows the detailed description for a specific Asterisk manager interface command.\n";
00573       return NULL;
00574    case CLI_GENERATE:
00575       l = strlen(a->word);
00576       which = 0;
00577       AST_RWLIST_RDLOCK(&actions);
00578       AST_RWLIST_TRAVERSE(&actions, cur, list) {
00579          if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) {
00580             ret = ast_strdup(cur->action);
00581             break;   /* make sure we exit even if ast_strdup() returns NULL */
00582          }
00583       }
00584       AST_RWLIST_UNLOCK(&actions);
00585       return ret;
00586    }
00587    authority = ast_str_alloca(80);
00588    if (a->argc < 4) {
00589       return CLI_SHOWUSAGE;
00590    }
00591 
00592    AST_RWLIST_RDLOCK(&actions);
00593    AST_RWLIST_TRAVERSE(&actions, cur, list) {
00594       for (num = 3; num < a->argc; num++) {
00595          if (!strcasecmp(cur->action, a->argv[num])) {
00596             ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
00597                cur->action, cur->synopsis,
00598                authority_to_str(cur->authority, &authority),
00599                S_OR(cur->description, ""));
00600          }
00601       }
00602    }
00603    AST_RWLIST_UNLOCK(&actions);
00604 
00605    return CLI_SUCCESS;
00606 }

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 738 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, manager_action::synopsis, and ast_cli_entry::usage.

00739 {
00740    struct manager_action *cur;
00741    struct ast_str *authority;
00742 #define HSMC_FORMAT "  %-15.15s  %-15.15s  %-55.55s\n"
00743    switch (cmd) {
00744    case CLI_INIT:
00745       e->command = "manager show commands";
00746       e->usage = 
00747          "Usage: manager show commands\n"
00748          "  Prints a listing of all the available Asterisk manager interface commands.\n";
00749       return NULL;
00750    case CLI_GENERATE:
00751       return NULL;   
00752    }  
00753    authority = ast_str_alloca(80);
00754    ast_cli(a->fd, HSMC_FORMAT, "Action", "Privilege", "Synopsis");
00755    ast_cli(a->fd, HSMC_FORMAT, "------", "---------", "--------");
00756 
00757    AST_RWLIST_RDLOCK(&actions);
00758    AST_RWLIST_TRAVERSE(&actions, cur, list)
00759       ast_cli(a->fd, HSMC_FORMAT, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis);
00760    AST_RWLIST_UNLOCK(&actions);
00761 
00762    return CLI_SUCCESS;
00763 }

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

References ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, mansession_session::fd, ast_cli_args::fd, HSMCONN_FORMAT1, HSMCONN_FORMAT2, mansession_session::inuse, mansession_session::list, mansession_session::readperm, mansession_session::sessionstart, mansession_session::sin, ast_cli_entry::usage, mansession_session::username, and mansession_session::writeperm.

00767 {
00768    struct mansession_session *session;
00769    time_t now = time(NULL);
00770 #define HSMCONN_FORMAT1 "  %-15.15s  %-15.15s  %-10.10s  %-10.10s  %-8.8s  %-8.8s  %-5.5s  %-5.5s\n"
00771 #define HSMCONN_FORMAT2 "  %-15.15s  %-15.15s  %-10d  %-10d  %-8d  %-8d  %-5.5d  %-5.5d\n"
00772    int count = 0;
00773    switch (cmd) {
00774    case CLI_INIT:
00775       e->command = "manager show connected";
00776       e->usage = 
00777          "Usage: manager show connected\n"
00778          "  Prints a listing of the users that are currently connected to the\n"
00779          "Asterisk manager interface.\n";
00780       return NULL;
00781    case CLI_GENERATE:
00782       return NULL;   
00783    }
00784 
00785    ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write");
00786 
00787    AST_LIST_LOCK(&sessions);
00788    AST_LIST_TRAVERSE(&sessions, session, list) {
00789       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);
00790       count++;
00791    }
00792    AST_LIST_UNLOCK(&sessions);
00793 
00794    ast_cli(a->fd, "%d users connected.\n", count);
00795 
00796    return CLI_SUCCESS;
00797 }

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

00802 {
00803    struct eventqent *s;
00804    switch (cmd) {
00805    case CLI_INIT:
00806       e->command = "manager show eventq";
00807       e->usage = 
00808          "Usage: manager show eventq\n"
00809          "  Prints a listing of all events pending in the Asterisk manger\n"
00810          "event queue.\n";
00811       return NULL;
00812    case CLI_GENERATE:
00813       return NULL;
00814    }
00815    AST_RWLIST_RDLOCK(&all_events);
00816    AST_RWLIST_TRAVERSE(&all_events, s, eq_next) {
00817       ast_cli(a->fd, "Usecount: %d\n", s->usecount);
00818       ast_cli(a->fd, "Category: %d\n", s->category);
00819       ast_cli(a->fd, "Event:\n%s", s->eventdata);
00820    }
00821    AST_RWLIST_UNLOCK(&all_events);
00822 
00823    return CLI_SUCCESS;
00824 }

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

Definition at line 1369 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(), eventqent::category, FAILURE_ALLOCATION, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, LOG_WARNING, match(), ast_variable::object, UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, UNSPECIFIED_CATEGORY, and var.

Referenced by action_updateconfig().

01370 {
01371    int x;
01372    char hdr[40];
01373    const char *action, *cat, *var, *value, *match, *line;
01374    struct ast_category *category;
01375    struct ast_variable *v;
01376    struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
01377    enum error_type result = 0;
01378 
01379    for (x = 0; x < 100000; x++) {   /* 100000 = the max number of allowed updates + 1 */
01380       unsigned int object = 0;
01381 
01382       snprintf(hdr, sizeof(hdr), "Action-%06d", x);
01383       action = astman_get_header(m, hdr);
01384       if (ast_strlen_zero(action))     /* breaks the for loop if no action header */
01385          break;                        /* this could cause problems if actions come in misnumbered */
01386 
01387       snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
01388       cat = astman_get_header(m, hdr);
01389       if (ast_strlen_zero(cat)) {      /* every action needs a category */
01390          result =  UNSPECIFIED_CATEGORY;
01391          break;
01392       }
01393 
01394       snprintf(hdr, sizeof(hdr), "Var-%06d", x);
01395       var = astman_get_header(m, hdr);
01396 
01397       snprintf(hdr, sizeof(hdr), "Value-%06d", x);
01398       value = astman_get_header(m, hdr);
01399 
01400       if (!ast_strlen_zero(value) && *value == '>') {
01401          object = 1;
01402          value++;
01403       }
01404    
01405       snprintf(hdr, sizeof(hdr), "Match-%06d", x);
01406       match = astman_get_header(m, hdr);
01407 
01408       snprintf(hdr, sizeof(hdr), "Line-%06d", x);
01409       line = astman_get_header(m, hdr);
01410 
01411       if (!strcasecmp(action, "newcat")) {
01412          if (ast_category_get(cfg,cat)) { /* check to make sure the cat doesn't */
01413             result = FAILURE_NEWCAT;   /* already exist */
01414             break;
01415          }
01416          if (!(category = ast_category_new(cat, dfn, -1))) {
01417             result = FAILURE_ALLOCATION;
01418             break;
01419          }
01420          if (ast_strlen_zero(match)) {
01421             ast_category_append(cfg, category);
01422          } else
01423             ast_category_insert(cfg, category, match);
01424       } else if (!strcasecmp(action, "renamecat")) {
01425          if (ast_strlen_zero(value)) {
01426             result = UNSPECIFIED_ARGUMENT;
01427             break;
01428          }
01429          if (!(category = ast_category_get(cfg, cat))) {
01430             result = UNKNOWN_CATEGORY;
01431             break;
01432          }
01433          ast_category_rename(category, value);
01434       } else if (!strcasecmp(action, "delcat")) {
01435          if (ast_category_delete(cfg, cat)) {
01436             result = FAILURE_DELCAT;
01437             break;
01438          }
01439       } else if (!strcasecmp(action, "emptycat")) {
01440          if (ast_category_empty(cfg, cat)) {
01441             result = FAILURE_EMPTYCAT;
01442             break;
01443          }
01444       } else if (!strcasecmp(action, "update")) {
01445          if (ast_strlen_zero(var)) {
01446             result = UNSPECIFIED_ARGUMENT;
01447             break;
01448          }
01449          if (!(category = ast_category_get(cfg,cat))) {
01450             result = UNKNOWN_CATEGORY;
01451             break;
01452          }
01453          if (ast_variable_update(category, var, value, match, object)) {
01454             result = FAILURE_UPDATE;
01455             break;
01456          }
01457       } else if (!strcasecmp(action, "delete")) {
01458          if ((ast_strlen_zero(var) && ast_strlen_zero(line))) {
01459             result = UNSPECIFIED_ARGUMENT;
01460             break;
01461          }
01462          if (!(category = ast_category_get(cfg, cat))) {
01463             result = UNKNOWN_CATEGORY;
01464             break;
01465          }
01466          if (ast_variable_delete(category, var, match, line)) {
01467             result = FAILURE_DELETE;
01468             break;
01469          }
01470       } else if (!strcasecmp(action, "append")) {
01471          if (ast_strlen_zero(var)) {
01472             result = UNSPECIFIED_ARGUMENT;
01473             break;
01474          }
01475          if (!(category = ast_category_get(cfg, cat))) {
01476             result = UNKNOWN_CATEGORY; 
01477             break;
01478          }
01479          if (!(v = ast_variable_new(var, value, dfn))) {
01480             result = FAILURE_ALLOCATION;
01481             break;
01482          }
01483          if (object || (match && !strcasecmp(match, "object")))
01484             v->object = 1;
01485          ast_variable_append(category, v);
01486       } else if (!strcasecmp(action, "insert")) {
01487          if (ast_strlen_zero(var) || ast_strlen_zero(line)) {
01488             result = UNSPECIFIED_ARGUMENT;
01489             break;
01490          }
01491          if (!(category = ast_category_get(cfg, cat))) {
01492             result = UNKNOWN_CATEGORY;
01493             break;
01494          }
01495          if (!(v = ast_variable_new(var, value, dfn))) {
01496             result = FAILURE_ALLOCATION;
01497             break;
01498          }
01499          ast_variable_insert(category, v, line);
01500       }
01501       else {
01502          ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action);
01503          result = UNKNOWN_ACTION;
01504          break;
01505       }
01506    }
01507    ast_free(str1);
01508    ast_free(str2);
01509    return result;
01510 }

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

Referenced by action_getconfigjson().

01286 {
01287    for (; *in; in++) {
01288       if (*in == '\\' || *in == '\"')
01289          *out++ = '\\';
01290       *out++ = *in;
01291    }
01292    *out = '\0';
01293 }

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

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

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

00549 {
00550    struct ast_manager_user *user = NULL;
00551    int ret = 0;
00552 
00553    AST_RWLIST_RDLOCK(&users);
00554    if ((user = get_manager_by_name_locked (session->username)))
00555       ret = user->displayconnects;
00556    AST_RWLIST_UNLOCK(&users);
00557    
00558    return ret;
00559 }

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

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

03000 {
03001    int res;
03002    const char *module = astman_get_header(m, "Module");
03003    const char *id = astman_get_header(m, "ActionID");
03004    char idText[256];
03005 #if !defined(LOW_MEMORY)
03006    const char *version;
03007 #endif
03008    char filename[PATH_MAX];
03009    char *cut;
03010 
03011    ast_copy_string(filename, module, sizeof(filename));
03012    if ((cut = strchr(filename, '.'))) {
03013       *cut = '\0';
03014    } else {
03015       cut = filename + strlen(filename);
03016    }
03017    snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so");
03018    ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename);
03019    res = ast_module_check(filename);
03020    if (!res) {
03021       astman_send_error(s, m, "Module not loaded");
03022       return 0;
03023    }
03024    snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c");
03025    ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename);
03026 #if !defined(LOW_MEMORY)
03027    version = ast_file_version_find(filename);
03028 #endif
03029 
03030    if (!ast_strlen_zero(id))
03031       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
03032    else
03033       idText[0] = '\0';
03034    astman_append(s, "Response: Success\r\n%s", idText);
03035 #if !defined(LOW_MEMORY)
03036    astman_append(s, "Version: %s\r\n\r\n", version ? version : "");
03037 #endif
03038    return 0;
03039 }

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

Definition at line 3052 of file manager.c.

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

Referenced by __init_manager().

03053 {
03054    int res;
03055    const char *module = astman_get_header(m, "Module");
03056    const char *loadtype = astman_get_header(m, "LoadType");
03057 
03058    if (!loadtype || strlen(loadtype) == 0)
03059       astman_send_error(s, m, "Incomplete ModuleLoad action.");
03060    if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0)
03061       astman_send_error(s, m, "Need module name");
03062 
03063    if (!strcasecmp(loadtype, "load")) {
03064       res = ast_load_resource(module);
03065       if (res)
03066          astman_send_error(s, m, "Could not load module.");
03067       else
03068          astman_send_ack(s, m, "Module loaded.");
03069    } else if (!strcasecmp(loadtype, "unload")) {
03070       res = ast_unload_resource(module, AST_FORCE_SOFT);
03071       if (res)
03072          astman_send_error(s, m, "Could not unload module.");
03073       else
03074          astman_send_ack(s, m, "Module unloaded.");
03075    } else if (!strcasecmp(loadtype, "reload")) {
03076       if (module != NULL) {
03077          res = ast_module_reload(module);
03078          if (res == 0)
03079             astman_send_error(s, m, "No such module.");
03080          else if (res == 1)
03081             astman_send_error(s, m, "Module does not support reload action.");
03082          else
03083             astman_send_ack(s, m, "Module reloaded.");
03084       } else {
03085          ast_module_reload(NULL);   /* Reload all modules */
03086          astman_send_ack(s, m, "All modules reloaded");
03087       }
03088    } else 
03089       astman_send_error(s, m, "Incomplete ModuleLoad action.");
03090    return 0;
03091 }

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

Definition at line 3563 of file manager.c.

References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.

Referenced by __init_manager().

03564 {
03565    /* Notify managers of change */
03566    char hint[512];
03567    ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
03568 
03569    manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state);
03570    return 0;
03571 }

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

References mansession_session::__lock, advance_event(), ast_mutex_lock(), ast_mutex_unlock(), mansession_session::authenticated, eventqent::category, eventqent::eventdata, mansession_session::f, mansession_session::last_ev, mansession_session::readperm, mansession_session::send_events, send_string(), and mansession::session.

Referenced by do_message(), and process_message().

02770 {
02771    int ret = 0;
02772 
02773    ast_mutex_lock(&s->session->__lock);
02774    if (s->session->f != NULL) {
02775       struct eventqent *eqe = s->session->last_ev;
02776 
02777       while ((eqe = advance_event(eqe))) {
02778          if (!ret && s->session->authenticated &&
02779              (s->session->readperm & eqe->category) == eqe->category &&
02780              (s->session->send_events & eqe->category) == eqe->category) {
02781             if (send_string(s, eqe->eventdata) < 0)
02782                ret = -1;   /* don't send more */
02783          }
02784          s->session->last_ev = eqe;
02785       }
02786    }
02787    ast_mutex_unlock(&s->session->__lock);
02788    return ret;
02789 }

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

Definition at line 3106 of file manager.c.

References __astman_get_header(), mansession_session::__lock, manager_action::action, ast_copy_string(), ast_debug, ast_mutex_lock(), ast_mutex_unlock(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), astman_get_header(), astman_send_error(), mansession_session::authenticated, manager_action::authority, buf, check_manager_session_inuse(), manager_action::func, GET_HEADER_SKIP_EMPTY, process_events(), mansession::session, and mansession_session::writeperm.

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

03107 {
03108    char action[80] = "";
03109    int ret = 0;
03110    struct manager_action *tmp;
03111    const char *user = astman_get_header(m, "Username");
03112 
03113    ast_copy_string(action, __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY), sizeof(action));
03114    ast_debug(1, "Manager received command '%s'\n", action);
03115 
03116    if (ast_strlen_zero(action)) {
03117       ast_mutex_lock(&s->session->__lock);
03118       astman_send_error(s, m, "Missing action in request");
03119       ast_mutex_unlock(&s->session->__lock);
03120       return 0;
03121    }
03122 
03123    if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) {
03124       ast_mutex_lock(&s->session->__lock);
03125       astman_send_error(s, m, "Permission denied");
03126       ast_mutex_unlock(&s->session->__lock);
03127       return 0;
03128    }
03129 
03130    if (!allowmultiplelogin && !s->session->authenticated && user &&
03131       (!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) {
03132       if (check_manager_session_inuse(user)) {
03133          sleep(1);
03134          ast_mutex_lock(&s->session->__lock);
03135          astman_send_error(s, m, "Login Already In Use");
03136          ast_mutex_unlock(&s->session->__lock);
03137          return -1;
03138       }
03139    }
03140 
03141    AST_RWLIST_RDLOCK(&actions);
03142    AST_RWLIST_TRAVERSE(&actions, tmp, list) {
03143       if (strcasecmp(action, tmp->action))
03144          continue;
03145       if (s->session->writeperm & tmp->authority || tmp->authority == 0)
03146          ret = tmp->func(s, m);
03147       else
03148          astman_send_error(s, m, "Permission denied");
03149       break;
03150    }
03151    AST_RWLIST_UNLOCK(&actions);
03152 
03153    if (!tmp) {
03154       char buf[512];
03155       snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
03156       ast_mutex_lock(&s->session->__lock);
03157       astman_send_error(s, m, buf);
03158       ast_mutex_unlock(&s->session->__lock);
03159    }
03160    if (ret)
03161       return ret;
03162    /* Once done with our message, deliver any pending events unless the
03163       requester doesn't want them as part of this response.
03164    */
03165    if (ast_strlen_zero(astman_get_header(m, "SuppressEvents"))) {
03166       return process_events(s);
03167    } else {
03168       return ret;
03169    }
03170 }

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

References ast_free, AST_RWLIST_FIRST, AST_RWLIST_NEXT, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_tvdiff_sec(), ast_tvnow(), eventqent::tv, and eventqent::usecount.

Referenced by purge_old_stuff().

00365 {
00366    struct eventqent *ev;
00367    struct timeval now = ast_tvnow();
00368 
00369    AST_RWLIST_WRLOCK(&all_events);
00370    while ( (ev = AST_RWLIST_FIRST(&all_events)) &&
00371        ev->usecount == 0 && AST_RWLIST_NEXT(ev, eq_next)) {
00372       AST_RWLIST_REMOVE_HEAD(&all_events, eq_next);
00373       ast_free(ev);
00374    }
00375 
00376    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&all_events, ev, eq_next) {
00377       /* Never release the last event */
00378       if (!AST_RWLIST_NEXT(ev, eq_next)) {
00379          break;
00380       }
00381 
00382       /* 2.5 times whatever the HTTP timeout is (maximum 2.5 hours) is the maximum time that we will definitely cache an event */
00383       if (ev->usecount == 0 && ast_tvdiff_sec(now, ev->tv) > (httptimeout > 3600 ? 3600 : httptimeout) * 2.5) {
00384          AST_RWLIST_REMOVE_CURRENT(eq_next);
00385          ast_free(ev);
00386       }
00387    }
00388    AST_RWLIST_TRAVERSE_SAFE_END;
00389    AST_RWLIST_UNLOCK(&all_events);
00390 }

static void purge_sessions ( int  n_max  )  [static]

remove at most n_max stale session from the list.

Definition at line 3406 of file manager.c.

References ast_atomic_fetchadd_int(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verb, mansession_session::authenticated, free_session(), mansession_session::inuse, manager_displayconnects(), mansession_session::sessiontimeout, mansession_session::sin, mansession_session::username, and VERBOSITY_ATLEAST.

Referenced by purge_old_stuff().

03407 {
03408    struct mansession_session *session;
03409    time_t now = time(NULL);
03410 
03411    AST_LIST_LOCK(&sessions);
03412    AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, session, list) {
03413       if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) {
03414          AST_LIST_REMOVE_CURRENT(list);
03415          ast_atomic_fetchadd_int(&num_sessions, -1);
03416          if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) {
03417             ast_verb(2, "HTTP Manager '%s' timed out from %s\n",
03418                session->username, ast_inet_ntoa(session->sin.sin_addr));
03419          }
03420          free_session(session);  /* XXX outside ? */
03421          if (--n_max <= 0)
03422             break;
03423       }
03424    }
03425    AST_LIST_TRAVERSE_SAFE_END;
03426    AST_LIST_UNLOCK(&sessions);
03427 }

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

References ast_careful_fwrite(), mansession_session::f, mansession::f, f, mansession_session::fd, mansession::fd, mansession::session, mansession::write_error, and mansession_session::writetimeout.

Referenced by astman_append(), and process_events().

00986 {
00987    int res;
00988    FILE *f = s->f ? s->f : s->session->f;
00989    int fd = s->f ? s->fd : s->session->fd;
00990 
00991    if ((res = ast_careful_fwrite(f, fd, string, strlen(string), s->session->writetimeout))) {
00992       s->write_error = 1;
00993    }
00994 
00995    return res;
00996 }

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

References mansession_session::__lock, AMI_VERSION, ao2_ref, ast_atomic_fetchadd_int(), ast_calloc, ast_inet_ntoa(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), AST_PTHREADT_NULL, ast_verb, astman_append(), mansession_session::authenticated, mansession_session::authstart, mansession_session::datastores, destroy_session(), do_message(), errno, mansession_session::f, ast_tcptls_session_instance::f, mansession_session::fd, ast_tcptls_session_instance::fd, ast_frame::flags, grab_last(), mansession_session::last_ev, LOG_ERROR, LOG_EVENT, LOG_WARNING, manager_displayconnects(), ast_tcptls_session_instance::remote_address, s, mansession_session::send_events, mansession::session, mansession_session::sin, mansession_session::username, mansession_session::waiting_thread, mansession::write_error, and mansession_session::writetimeout.

03312 {
03313    struct ast_tcptls_session_instance *ser = data;
03314    struct mansession_session *session = NULL;
03315    struct mansession s = {.session = NULL, };
03316    int flags;
03317    int res;
03318    struct protoent *p;
03319 
03320    if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) {
03321       fclose(ser->f);
03322       ast_atomic_fetchadd_int(&unauth_sessions, -1);
03323       goto done;
03324    }
03325 
03326    if ((session = ast_calloc(1, sizeof(*session))) == NULL) {
03327       fclose(ser->f);
03328       ast_atomic_fetchadd_int(&unauth_sessions, -1);
03329       goto done;
03330    }
03331 
03332    /* here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
03333     * This is necessary to prevent delays (caused by buffering) as we
03334     * write to the socket in bits and peices. */
03335    p = getprotobyname("tcp");
03336    if (p) {
03337       int arg = 1;
03338       if( setsockopt(ser->fd, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
03339          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));
03340       }
03341    } else {
03342       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");
03343    }
03344 
03345    session->writetimeout = 100;
03346    session->waiting_thread = AST_PTHREADT_NULL;
03347 
03348    flags = fcntl(ser->fd, F_GETFL);
03349    if (!block_sockets) /* make sure socket is non-blocking */
03350       flags |= O_NONBLOCK;
03351    else
03352       flags &= ~O_NONBLOCK;
03353    fcntl(ser->fd, F_SETFL, flags);
03354 
03355    ast_mutex_init(&session->__lock);
03356    session->send_events = -1;
03357    /* Hook to the tail of the event queue */
03358    session->last_ev = grab_last();
03359 
03360    /* these fields duplicate those in the 'ser' structure */
03361    session->fd = ser->fd;
03362    session->f = ser->f;
03363    session->sin = ser->remote_address;
03364    s.session = session;
03365 
03366    AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
03367 
03368    AST_LIST_LOCK(&sessions);
03369    AST_LIST_INSERT_HEAD(&sessions, session, list);
03370    ast_atomic_fetchadd_int(&num_sessions, 1);
03371    AST_LIST_UNLOCK(&sessions);
03372 
03373    if(time(&session->authstart) == -1) {
03374       ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
03375       ast_atomic_fetchadd_int(&unauth_sessions, -1);
03376       destroy_session(session);
03377       goto done;
03378    }
03379 
03380    astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION);   /* welcome prompt */
03381    for (;;) {
03382       if ((res = do_message(&s)) < 0 || s.write_error)
03383          break;
03384    }
03385    /* session is over, explain why and terminate */
03386    if (session->authenticated) {
03387          if (manager_displayconnects(session))
03388          ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
03389       ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
03390    } else {
03391       ast_atomic_fetchadd_int(&unauth_sessions, -1);
03392          if (displayconnects)
03393          ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr));
03394       ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(session->sin.sin_addr));
03395    }
03396 
03397    destroy_session(session);
03398 
03399 done:
03400    ao2_ref(ser, -1);
03401    ser = NULL;
03402    return NULL;
03403 }

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

References mansession_session::__lock, ast_mutex_lock(), ast_mutex_unlock(), mansession_session::send_events, mansession::session, and strings_to_mask().

Referenced by action_events(), and authenticate().

01098 {
01099    int maskint = strings_to_mask(eventmask);
01100 
01101    ast_mutex_lock(&s->session->__lock);
01102    if (maskint >= 0)
01103       s->session->send_events = maskint;
01104    ast_mutex_unlock(&s->session->__lock);
01105 
01106    return maskint;
01107 }

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

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

Referenced by set_eventmask().

00493 {
00494    const char *p;
00495 
00496    if (ast_strlen_zero(string))
00497       return -1;
00498 
00499    for (p = string; *p; p++)
00500       if (*p < '0' || *p > '9')
00501          break;
00502    if (!*p) /* all digits */
00503       return atoi(string);
00504    if (ast_false(string))
00505       return 0;
00506    if (ast_true(string)) { /* all permissions */
00507       int x, ret = 0;
00508       for (x = 0; x < ARRAY_LEN(perms); x++)
00509          ret |= perms[x].num;
00510       return ret;
00511    }
00512    return get_perm(string);
00513 }


Variable Documentation

int allowmultiplelogin = 1 [static]

Definition at line 134 of file manager.c.

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

Definition at line 1005 of file manager.c.

Referenced by astman_append().

int authlimit [static]

Definition at line 141 of file manager.c.

int authtimeout [static]

Definition at line 140 of file manager.c.

int block_sockets [static]

Definition at line 143 of file manager.c.

int broken_events_action [static]

Definition at line 137 of file manager.c.

struct ast_cli_entry cli_manager[] [static]

Definition at line 846 of file manager.c.

Referenced by __init_manager().

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

Referenced by check_blacklist().

const int DEFAULT_AUTHLIMIT = 50 [static]

Default setting for authlimit

Definition at line 131 of file manager.c.

const int DEFAULT_AUTHTIMEOUT = 30 [static]

Default setting for authtimeout

Definition at line 130 of file manager.c.

const int DEFAULT_BLOCKSOCKETS = 0 [static]

Default setting for block-sockets

Definition at line 125 of file manager.c.

const int DEFAULT_BROKENEVENTSACTION = 0 [static]

Default setting for brokeneventsaction

Definition at line 129 of file manager.c.

const int DEFAULT_DISPLAYCONNECTS = 1 [static]

Default setting for displaying manager connections

Definition at line 126 of file manager.c.

const int DEFAULT_ENABLED = 0 [static]

Default setting for manager to be enabled

Definition at line 123 of file manager.c.

const int DEFAULT_HTTPTIMEOUT = 60 [static]

Default manager http timeout

Definition at line 128 of file manager.c.

const int DEFAULT_TIMESTAMPEVENTS = 0 [static]

Default setting for timestampevents

Definition at line 127 of file manager.c.

const int DEFAULT_WEBENABLED = 0 [static]

Default setting for the web interface to be enabled

Definition at line 124 of file manager.c.

int displayconnects [static]

Definition at line 133 of file manager.c.

int httptimeout [static]

Definition at line 136 of file manager.c.

int manager_debug [static]

enable some debugging code in the manager

Definition at line 147 of file manager.c.

int manager_enabled = 0 [static]

Definition at line 138 of file manager.c.

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

Definition at line 3457 of file manager.c.

Referenced by __manager_event().

char mandescr_atxfer[] [static]

Definition at line 2245 of file manager.c.

Referenced by __init_manager().

char mandescr_command[] [static]

Initial value:

"Description: Run a CLI command.\n"
"Variables: (Names marked with * are required)\n"
"  *Command: Asterisk CLI command to run\n"
"  ActionID: Optional Action id for message matching.\n"

Definition at line 2337 of file manager.c.

Referenced by __init_manager().

char mandescr_coresettings[] [static]

Initial value:

"Description: Query for Core PBX settings.\n"
"Variables: (Names marked with * are optional)\n"
"       *ActionID: ActionID of this transaction\n"

Definition at line 2817 of file manager.c.

Referenced by __init_manager().

char mandescr_coreshowchannels[] [static]

Initial value:

"Description: List currently defined channels and some information\n"
"             about them.\n"
"Variables:\n"
"          ActionID: Optional Action id for message matching.\n"

Definition at line 2920 of file manager.c.

Referenced by __init_manager().

char mandescr_corestatus[] [static]

Initial value:

"Description: Query for Core PBX status.\n"
"Variables: (Names marked with * are optional)\n"
"       *ActionID: ActionID of this transaction\n"

Definition at line 2863 of file manager.c.

Referenced by __init_manager().

char mandescr_createconfig[] [static]

Definition at line 1603 of file manager.c.

Referenced by __init_manager().

char mandescr_events[] [static]

Definition at line 1752 of file manager.c.

Referenced by __init_manager().

char mandescr_extensionstate[] [static]

Definition at line 2694 of file manager.c.

Referenced by __init_manager().

char mandescr_getconfig[] [static]

Definition at line 1194 of file manager.c.

Referenced by __init_manager().

char mandescr_getconfigjson[] [static]

Definition at line 1295 of file manager.c.

Referenced by __init_manager().

char mandescr_getvar[] [static]

Definition at line 1914 of file manager.c.

Referenced by __init_manager().

char mandescr_hangup[] [static]

Initial value:

"Description: Hangup a channel\n"
"Variables: \n"
"  Channel: The channel name to be hungup\n"

Definition at line 1846 of file manager.c.

Referenced by __init_manager().

char mandescr_listcategories[] [static]

Initial value:

"Description: A 'ListCategories' action will dump the categories in\n"
"a given file.\n"
"Variables:\n"
"   Filename: Configuration filename (e.g. foo.conf)\n"

Definition at line 1243 of file manager.c.

Referenced by __init_manager().

char mandescr_listcommands[] [static]

Initial value:

"Description: Returns the action name and synopsis for every\n"
"  action that is available to the user\n"
"Variables: NONE\n"

Definition at line 1730 of file manager.c.

Referenced by __init_manager().

char mandescr_logoff[] [static]

Initial value:

"Description: Logoff this manager session\n"
"Variables: NONE\n"

Definition at line 1796 of file manager.c.

Referenced by __init_manager().

char mandescr_mailboxcount[] [static]

Definition at line 2661 of file manager.c.

Referenced by __init_manager().

char mandescr_mailboxstatus[] [static]

Help text for manager command mailboxstatus.

Definition at line 2633 of file manager.c.

Referenced by __init_manager().

char mandescr_modulecheck[] [static]

Definition at line 2989 of file manager.c.

Referenced by __init_manager().

char mandescr_moduleload[] [static]

Definition at line 3041 of file manager.c.

Referenced by __init_manager().

char mandescr_originate[] [static]

Definition at line 2462 of file manager.c.

Referenced by __init_manager().

char mandescr_ping[] [static]

Initial value:

"Description: A 'Ping' action will ellicit a 'Pong' response.  Used to keep the\n"
"  manager connection open.\n"
"Variables: NONE\n"
Manager PING.

Definition at line 1177 of file manager.c.

Referenced by __init_manager().

char mandescr_redirect[] [static]

Definition at line 2159 of file manager.c.

Referenced by __init_manager().

char mandescr_reload[] [static]

Initial value:

"Description: Send a reload event.\n"
"Variables: (Names marked with * are optional)\n"
"       *ActionID: ActionID of this transaction\n"
"       *Module: Name of the module to reload\n"

Definition at line 2901 of file manager.c.

Referenced by __init_manager().

char mandescr_sendtext[] [static]

Definition at line 2117 of file manager.c.

Referenced by __init_manager().

char mandescr_setvar[] [static]

Definition at line 1870 of file manager.c.

Referenced by __init_manager().

char mandescr_status[] [static]

Definition at line 1972 of file manager.c.

Referenced by __init_manager().

char mandescr_timeout[] [static]

Definition at line 2729 of file manager.c.

Referenced by __init_manager().

char mandescr_updateconfig[] [static]

Definition at line 1512 of file manager.c.

Referenced by __init_manager().

char mandescr_userevent[] [static]

Definition at line 2791 of file manager.c.

Referenced by __init_manager().

char mandescr_waitevent[] [static]

Manager WAITEVENT.

Definition at line 1629 of file manager.c.

Referenced by __init_manager().

int num_sessions [static]

Definition at line 144 of file manager.c.

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

int timestampevents [static]

Definition at line 135 of file manager.c.

int unauth_sessions = 0 [static]

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

Referenced by action_userevent().

int webmanager_enabled = 0 [static]

Definition at line 139 of file manager.c.

char* words[AST_MAX_CMD_LEN] [inherited]

Definition at line 160 of file manager.c.


Generated on Thu Oct 11 06:49:58 2012 for Asterisk - the Open Source PBX by  doxygen 1.5.6