Wed Oct 28 11:46:23 2009

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 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.
#define NEW_EVENT(m)   (AST_LIST_NEXT(m->session->last_ev, eq_next))

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 void __fini_actions (void)
static void __fini_manager_hooks (void)
static void __fini_users (void)
static void __init_actions (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_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 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)
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 void ref_event (struct eventqent *e)
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)
static struct eventqentunref_event (struct eventqent *e)

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 block_sockets
static struct ast_cli_entry cli_manager []
struct {
   char *   words [AST_MAX_CMD_LEN]
command_blacklist []
static int displayconnects = 1
static int httptimeout = 60
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_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_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 struct ast_threadstorage userevent_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_userevent_buf , .custom_init = NULL , }
static int webmanager_enabled = 0

Detailed Description

callback to display queues status in manager


Define Documentation

#define ASTMAN_APPEND_BUF_INITSIZE   256

initial allocated size for the astman_append_buf

Definition at line 919 of file manager.c.

Referenced by astman_append().

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 3064 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 142 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 958 of file manager.c.

Referenced by astman_send_response_full(), and astman_start_ack().

#define NEW_EVENT (  )     (AST_LIST_NEXT(m->session->last_ev, eq_next))

Definition at line 217 of file manager.c.

Referenced by action_waitevent(), and process_events().


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


Function Documentation

static void __fini_actions ( void   )  [static]

Definition at line 243 of file manager.c.

00250 {

static void __fini_manager_hooks ( void   )  [static]

Definition at line 246 of file manager.c.

00250 {

static void __fini_users ( void   )  [static]

Definition at line 240 of file manager.c.

00250 {

static void __init_actions ( void   )  [static]

Definition at line 243 of file manager.c.

00250 {

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

00925 {

static void __init_manager_event_buf ( void   )  [static]

Definition at line 3063 of file manager.c.

03066 : Send AMI event to client */

static void __init_manager_hooks ( void   )  [static]

Definition at line 246 of file manager.c.

00250 {

static void __init_userevent_buf ( void   )  [static]

Definition at line 916 of file manager.c.

00925 {

static void __init_users ( void   )  [static]

Definition at line 240 of file manager.c.

00250 {

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 3067 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_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_append_va, 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, ast_str::str, and mansession_session::waiting_thread.

03069 {
03070    struct mansession_session *session;
03071    struct manager_custom_hook *hook;
03072    struct ast_str *auth = ast_str_alloca(80);
03073    const char *cat_str;
03074    va_list ap;
03075    struct timeval now;
03076    struct ast_str *buf;
03077 
03078    /* Abort if there aren't any manager sessions */
03079    if (!num_sessions)
03080       return 0;
03081 
03082    if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE)))
03083       return -1;
03084 
03085    cat_str = authority_to_str(category, &auth);
03086    ast_str_set(&buf, 0,
03087          "Event: %s\r\nPrivilege: %s\r\n",
03088           event, cat_str);
03089 
03090    if (timestampevents) {
03091       now = ast_tvnow();
03092       ast_str_append(&buf, 0,
03093             "Timestamp: %ld.%06lu\r\n",
03094              now.tv_sec, (unsigned long) now.tv_usec);
03095    }
03096    if (manager_debug) {
03097       static int seq;
03098       ast_str_append(&buf, 0,
03099             "SequenceNumber: %d\r\n",
03100              ast_atomic_fetchadd_int(&seq, 1));
03101       ast_str_append(&buf, 0,
03102             "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func);
03103    }
03104 
03105    va_start(ap, fmt);
03106    ast_str_append_va(&buf, 0, fmt, ap);
03107    va_end(ap);
03108 
03109    ast_str_append(&buf, 0, "\r\n");
03110 
03111    append_event(buf->str, category);
03112 
03113    /* Wake up any sleeping sessions */
03114    AST_LIST_LOCK(&sessions);
03115    AST_LIST_TRAVERSE(&sessions, session, list) {
03116       ast_mutex_lock(&session->__lock);
03117       if (session->waiting_thread != AST_PTHREADT_NULL)
03118          pthread_kill(session->waiting_thread, SIGURG);
03119       else
03120          /* We have an event to process, but the mansession is
03121           * not waiting for it. We still need to indicate that there
03122           * is an event waiting so that get_input processes the pending
03123           * event instead of polling.
03124           */
03125          session->pending_event = 1;
03126       ast_mutex_unlock(&session->__lock);
03127    }
03128    AST_LIST_UNLOCK(&sessions);
03129 
03130    AST_RWLIST_RDLOCK(&manager_hooks);
03131    AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
03132       hook->helper(category, event, buf->str);
03133    }
03134    AST_RWLIST_UNLOCK(&manager_hooks);
03135 
03136    return 0;
03137 }

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

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

01648 {
01649    const char *authtype = astman_get_header(m, "AuthType");
01650 
01651    if (!strcasecmp(authtype, "MD5")) {
01652       if (ast_strlen_zero(s->session->challenge))
01653          snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
01654       ast_mutex_lock(&s->session->__lock);
01655       astman_start_ack(s, m);
01656       astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
01657       ast_mutex_unlock(&s->session->__lock);
01658    } else {
01659       astman_send_error(s, m, "Must specify AuthType");
01660    }
01661    return 0;
01662 }

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

Manager command "command" - execute CLI command.

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

02045 {
02046    const char *cmd = astman_get_header(m, "Command");
02047    const char *id = astman_get_header(m, "ActionID");
02048    char *buf, *final_buf;
02049    char template[] = "/tmp/ast-ami-XXXXXX";  /* template for temporary file */
02050    int fd = mkstemp(template);
02051    off_t l;
02052 
02053    if (ast_strlen_zero(cmd)) {
02054       astman_send_error(s, m, "No command provided");
02055       return 0;
02056    }
02057 
02058    if (check_blacklist(cmd)) {
02059       astman_send_error(s, m, "Command blacklisted");
02060       return 0;
02061    }
02062 
02063    astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
02064    if (!ast_strlen_zero(id))
02065       astman_append(s, "ActionID: %s\r\n", id);
02066    /* FIXME: Wedge a ActionID response in here, waiting for later changes */
02067    ast_cli_command(fd, cmd);  /* XXX need to change this to use a FILE * */
02068    l = lseek(fd, 0, SEEK_END);   /* how many chars available */
02069 
02070    /* This has a potential to overflow the stack.  Hence, use the heap. */
02071    buf = ast_calloc(1, l + 1);
02072    final_buf = ast_calloc(1, l + 1);
02073    if (buf) {
02074       lseek(fd, 0, SEEK_SET);
02075       if (read(fd, buf, l) < 0) {
02076          ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
02077       }
02078       buf[l] = '\0';
02079       if (final_buf) {
02080          term_strip(final_buf, buf, l);
02081          final_buf[l] = '\0';
02082       }
02083       astman_append(s, "%s", S_OR(final_buf, buf));
02084       ast_free(buf);
02085    }
02086    close(fd);
02087    unlink(template);
02088    astman_append(s, "--END COMMAND--\r\n\r\n");
02089    if (final_buf)
02090       ast_free(final_buf);
02091    return 0;
02092 }

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

Show PBX core settings information.

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

02488 {
02489    const char *actionid = astman_get_header(m, "ActionID");
02490    char idText[150];
02491 
02492    if (!ast_strlen_zero(actionid))
02493       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
02494    else
02495       idText[0] = '\0';
02496 
02497    astman_append(s, "Response: Success\r\n"
02498          "%s"
02499          "AMIversion: %s\r\n"
02500          "AsteriskVersion: %s\r\n"
02501          "SystemName: %s\r\n"
02502          "CoreMaxCalls: %d\r\n"
02503          "CoreMaxLoadAvg: %f\r\n"
02504          "CoreRunUser: %s\r\n"
02505          "CoreRunGroup: %s\r\n"
02506          "CoreMaxFilehandles: %d\r\n" 
02507          "CoreRealTimeEnabled: %s\r\n"
02508          "CoreCDRenabled: %s\r\n"
02509          "CoreHTTPenabled: %s\r\n"
02510          "\r\n",
02511          idText,
02512          AMI_VERSION,
02513          ast_get_version(), 
02514          ast_config_AST_SYSTEM_NAME,
02515          option_maxcalls,
02516          option_maxload,
02517          ast_config_AST_RUN_USER,
02518          ast_config_AST_RUN_GROUP,
02519          option_maxfiles,
02520          ast_realtime_enabled() ? "Yes" : "No",
02521          check_cdr_enabled() ? "Yes" : "No",
02522          check_webmanager_enabled() ? "Yes" : "No"
02523          );
02524    return 0;
02525 }

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

02593 {
02594    const char *actionid = astman_get_header(m, "ActionID");
02595    char actionidtext[256];
02596    struct ast_channel *c = NULL;
02597    int numchans = 0;
02598    int duration, durh, durm, durs;
02599 
02600    if (!ast_strlen_zero(actionid))
02601       snprintf(actionidtext, sizeof(actionidtext), "ActionID: %s\r\n", actionid);
02602    else
02603       actionidtext[0] = '\0';
02604 
02605    astman_send_listack(s, m, "Channels will follow", "start"); 
02606 
02607    while ((c = ast_channel_walk_locked(c)) != NULL) {
02608       struct ast_channel *bc = ast_bridged_channel(c);
02609       char durbuf[10] = "";
02610 
02611       if (c->cdr && !ast_tvzero(c->cdr->start)) {
02612          duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
02613          durh = duration / 3600;
02614          durm = (duration % 3600) / 60;
02615          durs = duration % 60;
02616          snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
02617       }
02618 
02619       astman_append(s,
02620          "Channel: %s\r\n"
02621          "UniqueID: %s\r\n"
02622          "Context: %s\r\n"
02623          "Extension: %s\r\n"
02624          "Priority: %d\r\n"
02625          "ChannelState: %d\r\n"
02626          "ChannelStateDesc: %s\r\n"
02627          "Application: %s\r\n"
02628          "ApplicationData: %s\r\n"
02629          "CallerIDnum: %s\r\n"
02630          "Duration: %s\r\n"
02631          "AccountCode: %s\r\n"
02632          "BridgedChannel: %s\r\n"
02633          "BridgedUniqueID: %s\r\n"
02634          "\r\n", c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, ast_state2str(c->_state),
02635          c->appl ? c->appl : "", c->data ? S_OR(c->data, ""): "",
02636          S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : "");
02637       ast_channel_unlock(c);
02638       numchans++;
02639    }
02640 
02641    astman_append(s,
02642       "Event: CoreShowChannelsComplete\r\n"
02643       "EventList: Complete\r\n"
02644       "ListItems: %d\r\n"
02645       "%s"
02646       "\r\n", numchans, actionidtext);
02647 
02648    return 0;
02649 }

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

Show PBX core status information.

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

02534 {
02535    const char *actionid = astman_get_header(m, "ActionID");
02536    char idText[150];
02537    char startuptime[150];
02538    char reloadtime[150];
02539    struct ast_tm tm;
02540 
02541    if (!ast_strlen_zero(actionid))
02542       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
02543    else
02544       idText[0] = '\0';
02545 
02546    ast_localtime(&ast_startuptime, &tm, NULL);
02547    ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
02548    ast_localtime(&ast_lastreloadtime, &tm, NULL);
02549    ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
02550 
02551    astman_append(s, "Response: Success\r\n"
02552          "%s"
02553          "CoreStartupTime: %s\r\n"
02554          "CoreReloadTime: %s\r\n"
02555          "CoreCurrentCalls: %d\r\n"
02556          "\r\n",
02557          idText,
02558          startuptime,
02559          reloadtime,
02560          ast_active_channels()
02561          );
02562    return 0;
02563 }

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

Definition at line 1458 of file manager.c.

References ast_config_AST_CONFIG_DIR, AST_FILE_MODE, ast_str_alloca, ast_str_append(), ast_str_set(), astman_get_header(), astman_send_ack(), astman_send_error(), errno, and ast_str::str.

Referenced by __init_manager().

01459 {
01460    int fd;
01461    const char *fn = astman_get_header(m, "Filename");
01462    struct ast_str *filepath = ast_str_alloca(PATH_MAX);
01463    ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR);
01464    ast_str_append(&filepath, 0, "%s", fn);
01465 
01466    if ((fd = open(filepath->str, O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
01467       close(fd);
01468       astman_send_ack(s, m, "New configuration file created successfully");
01469    } else 
01470       astman_send_error(s, m, strerror(errno));
01471 
01472    return 0;
01473 }

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

Definition at line 1607 of file manager.c.

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

Referenced by __init_manager().

01608 {
01609    const char *mask = astman_get_header(m, "EventMask");
01610    int res;
01611 
01612    res = set_eventmask(s, mask);
01613    if (res > 0)
01614       astman_append(s, "Response: Success\r\n"
01615              "Events: On\r\n");
01616    else if (res == 0)
01617       astman_append(s, "Response: Success\r\n"
01618              "Events: Off\r\n");
01619    return 0;
01620 }

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

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

02373 {
02374    const char *exten = astman_get_header(m, "Exten");
02375    const char *context = astman_get_header(m, "Context");
02376    char hint[256] = "";
02377    int status;
02378    if (ast_strlen_zero(exten)) {
02379       astman_send_error(s, m, "Extension not specified");
02380       return 0;
02381    }
02382    if (ast_strlen_zero(context))
02383       context = "default";
02384    status = ast_extension_state(NULL, context, exten);
02385    ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
02386    astman_start_ack(s, m);
02387    astman_append(s,   "Message: Extension Status\r\n"
02388             "Exten: %s\r\n"
02389             "Context: %s\r\n"
02390             "Hint: %s\r\n"
02391             "Status: %d\r\n\r\n",
02392             exten, context, hint, status);
02393    return 0;
02394 }

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

Definition at line 1106 of file manager.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load, 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, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by __init_manager().

01107 {
01108    struct ast_config *cfg;
01109    const char *fn = astman_get_header(m, "Filename");
01110    const char *category = astman_get_header(m, "Category");
01111    int catcount = 0;
01112    int lineno = 0;
01113    char *cur_category = NULL;
01114    struct ast_variable *v;
01115    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
01116 
01117    if (ast_strlen_zero(fn)) {
01118       astman_send_error(s, m, "Filename not specified");
01119       return 0;
01120    }
01121    if (!(cfg = ast_config_load(fn, config_flags))) {
01122       astman_send_error(s, m, "Config file not found");
01123       return 0;
01124    }
01125 
01126    astman_start_ack(s, m);
01127    while ((cur_category = ast_category_browse(cfg, cur_category))) {
01128       if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) {
01129          lineno = 0;
01130          astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category);
01131          for (v = ast_variable_browse(cfg, cur_category); v; v = v->next)
01132             astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
01133          catcount++;
01134       }
01135    }
01136    if (!ast_strlen_zero(category) && catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */
01137       astman_append(s, "No categories found\r\n");
01138    ast_config_destroy(cfg);
01139    astman_append(s, "\r\n");
01140 
01141    return 0;
01142 }

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

Definition at line 1200 of file manager.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load, 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, json_escape(), ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by __init_manager().

01201 {
01202    struct ast_config *cfg;
01203    const char *fn = astman_get_header(m, "Filename");
01204    char *category = NULL;
01205    struct ast_variable *v;
01206    int comma1 = 0;
01207    char *buf = NULL;
01208    unsigned int buf_len = 0;
01209    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
01210 
01211    if (ast_strlen_zero(fn)) {
01212       astman_send_error(s, m, "Filename not specified");
01213       return 0;
01214    }
01215 
01216    if (!(cfg = ast_config_load(fn, config_flags))) {
01217       astman_send_error(s, m, "Config file not found");
01218       return 0;
01219    }
01220 
01221    buf_len = 512;
01222    buf = alloca(buf_len);
01223 
01224    astman_start_ack(s, m);
01225    astman_append(s, "JSON: {");
01226    while ((category = ast_category_browse(cfg, category))) {
01227       int comma2 = 0;
01228       if (buf_len < 2 * strlen(category) + 1) {
01229          buf_len *= 2;
01230          buf = alloca(buf_len);
01231       }
01232       json_escape(buf, category);
01233       astman_append(s, "%s\"%s\":[", comma1 ? "," : "", buf);
01234       if (!comma1)
01235          comma1 = 1;
01236       for (v = ast_variable_browse(cfg, category); v; v = v->next) {
01237          if (comma2)
01238             astman_append(s, ",");
01239          if (buf_len < 2 * strlen(v->name) + 1) {
01240             buf_len *= 2;
01241             buf = alloca(buf_len);
01242          }
01243          json_escape(buf, v->name);
01244          astman_append(s, "\"%s", buf);
01245          if (buf_len < 2 * strlen(v->value) + 1) {
01246             buf_len *= 2;
01247             buf = alloca(buf_len);
01248          }
01249          json_escape(buf, v->value);
01250          astman_append(s, "%s\"", buf);
01251          if (!comma2)
01252             comma2 = 1;
01253       }
01254       astman_append(s, "]");
01255    }
01256    astman_append(s, "}\r\n\r\n");
01257 
01258    ast_config_destroy(cfg);
01259 
01260    return 0;
01261 }

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

Definition at line 1732 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(), LOG_ERROR, name, and pbx_retrieve_variable().

Referenced by __init_manager().

01733 {
01734    struct ast_channel *c = NULL;
01735    const char *name = astman_get_header(m, "Channel");
01736    const char *varname = astman_get_header(m, "Variable");
01737    char *varval;
01738    char workspace[1024] = "";
01739 
01740    if (ast_strlen_zero(varname)) {
01741       astman_send_error(s, m, "No variable specified");
01742       return 0;
01743    }
01744 
01745    if (!ast_strlen_zero(name)) {
01746       c = ast_get_channel_by_name_locked(name);
01747       if (!c) {
01748          astman_send_error(s, m, "No such channel");
01749          return 0;
01750       }
01751    }
01752 
01753    if (varname[strlen(varname) - 1] == ')') {
01754       if (!c) {
01755          c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/manager");
01756          if (c) {
01757             ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
01758             ast_channel_free(c);
01759             c = NULL;
01760          } else
01761             ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution.  Function results may be blank.\n");
01762       } else
01763          ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
01764       varval = workspace;
01765    } else {
01766       pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
01767    }
01768 
01769    if (c)
01770       ast_channel_unlock(c);
01771    astman_start_ack(s, m);
01772    astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, varval);
01773 
01774    return 0;
01775 }

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

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

01670 {
01671    struct ast_channel *c = NULL;
01672    const char *name = astman_get_header(m, "Channel");
01673    if (ast_strlen_zero(name)) {
01674       astman_send_error(s, m, "No channel specified");
01675       return 0;
01676    }
01677    c = ast_get_channel_by_name_locked(name);
01678    if (!c) {
01679       astman_send_error(s, m, "No such channel");
01680       return 0;
01681    }
01682    ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
01683    ast_channel_unlock(c);
01684    astman_send_ack(s, m, "Channel Hungup");
01685    return 0;
01686 }

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

Definition at line 1150 of file manager.c.

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

Referenced by __init_manager().

01151 {
01152    struct ast_config *cfg;
01153    const char *fn = astman_get_header(m, "Filename");
01154    char *category = NULL;
01155    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
01156    int catcount = 0;
01157 
01158    if (ast_strlen_zero(fn)) {
01159       astman_send_error(s, m, "Filename not specified");
01160       return 0;
01161    }
01162    if (!(cfg = ast_config_load(fn, config_flags))) {
01163       astman_send_error(s, m, "Config file not found or file has invalid syntax");
01164       return 0;
01165    }
01166    astman_start_ack(s, m);
01167    while ((category = ast_category_browse(cfg, category))) {
01168       astman_append(s, "Category-%06d: %s\r\n", catcount, category);
01169       catcount++;
01170    }
01171    if (catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */
01172       astman_append(s, "Error: no categories found\r\n");
01173    ast_config_destroy(cfg);
01174    astman_append(s, "\r\n");
01175 
01176    return 0;
01177 }

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

01584 {
01585    struct manager_action *cur;
01586    struct ast_str *temp = ast_str_alloca(BUFSIZ); /* XXX very large ? */
01587 
01588    astman_start_ack(s, m);
01589    AST_RWLIST_TRAVERSE(&actions, cur, list) {
01590       if (s->session->writeperm & cur->authority || cur->authority == 0)
01591          astman_append(s, "%s: %s (Priv: %s)\r\n",
01592             cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
01593    }
01594    astman_append(s, "\r\n");
01595 
01596    return 0;
01597 }

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

Definition at line 1632 of file manager.c.

References ast_inet_ntoa(), ast_log(), ast_verb, astman_send_ack(), astman_send_error(), authenticate(), mansession_session::authenticated, LOG_EVENT, manager_displayconnects(), mansession_session::managerid, mansession::session, mansession_session::sin, and mansession_session::username.

Referenced by __init_manager().

01633 {
01634    if (authenticate(s, m)) {
01635       sleep(1);
01636       astman_send_error(s, m, "Authentication failed");
01637       return -1;
01638    }
01639    s->session->authenticated = 1;
01640    if (manager_displayconnects(s->session))
01641       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));
01642    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));
01643    astman_send_ack(s, m, "Authentication accepted");
01644    return 0;
01645 }

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

Definition at line 1626 of file manager.c.

References astman_send_response().

Referenced by __init_manager().

01627 {
01628    astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
01629    return -1;
01630 }

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

Definition at line 2341 of file manager.c.

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

Referenced by __init_manager().

02342 {
02343    const char *mailbox = astman_get_header(m, "Mailbox");
02344    int newmsgs = 0, oldmsgs = 0;
02345 
02346    if (ast_strlen_zero(mailbox)) {
02347       astman_send_error(s, m, "Mailbox not specified");
02348       return 0;
02349    }
02350    ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs);
02351    astman_start_ack(s, m);
02352    astman_append(s,   "Message: Mailbox Message Count\r\n"
02353             "Mailbox: %s\r\n"
02354             "NewMessages: %d\r\n"
02355             "OldMessages: %d\r\n"
02356             "\r\n",
02357             mailbox, newmsgs, oldmsgs);
02358    return 0;
02359 }

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

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

02314 {
02315    const char *mailbox = astman_get_header(m, "Mailbox");
02316    int ret;
02317 
02318    if (ast_strlen_zero(mailbox)) {
02319       astman_send_error(s, m, "Mailbox not specified");
02320       return 0;
02321    }
02322    ret = ast_app_has_voicemail(mailbox, NULL);
02323    astman_start_ack(s, m);
02324    astman_append(s, "Message: Mailbox Status\r\n"
02325           "Mailbox: %s\r\n"
02326           "Waiting: %d\r\n\r\n", mailbox, ret);
02327    return 0;
02328 }

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

Definition at line 2176 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(), 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_channel::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, ast_channel::priority, mansession::session, strcasestr(), fast_originate_helper::tech, ast_channel::tech, fast_originate_helper::timeout, fast_originate_helper::vars, and mansession_session::writeperm.

Referenced by __init_manager().

02177 {
02178    const char *name = astman_get_header(m, "Channel");
02179    const char *exten = astman_get_header(m, "Exten");
02180    const char *context = astman_get_header(m, "Context");
02181    const char *priority = astman_get_header(m, "Priority");
02182    const char *timeout = astman_get_header(m, "Timeout");
02183    const char *callerid = astman_get_header(m, "CallerID");
02184    const char *account = astman_get_header(m, "Account");
02185    const char *app = astman_get_header(m, "Application");
02186    const char *appdata = astman_get_header(m, "Data");
02187    const char *async = astman_get_header(m, "Async");
02188    const char *id = astman_get_header(m, "ActionID");
02189    const char *codecs = astman_get_header(m, "Codecs");
02190    struct ast_variable *vars = astman_get_variables(m);
02191    char *tech, *data;
02192    char *l = NULL, *n = NULL;
02193    int pi = 0;
02194    int res;
02195    int to = 30000;
02196    int reason = 0;
02197    char tmp[256];
02198    char tmp2[256];
02199    int format = AST_FORMAT_SLINEAR;
02200 
02201    pthread_t th;
02202    if (ast_strlen_zero(name)) {
02203       astman_send_error(s, m, "Channel not specified");
02204       return 0;
02205    }
02206    if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
02207       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
02208          astman_send_error(s, m, "Invalid priority");
02209          return 0;
02210       }
02211    }
02212    if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
02213       astman_send_error(s, m, "Invalid timeout");
02214       return 0;
02215    }
02216    ast_copy_string(tmp, name, sizeof(tmp));
02217    tech = tmp;
02218    data = strchr(tmp, '/');
02219    if (!data) {
02220       astman_send_error(s, m, "Invalid channel");
02221       return 0;
02222    }
02223    *data++ = '\0';
02224    ast_copy_string(tmp2, callerid, sizeof(tmp2));
02225    ast_callerid_parse(tmp2, &n, &l);
02226    if (n) {
02227       if (ast_strlen_zero(n))
02228          n = NULL;
02229    }
02230    if (l) {
02231       ast_shrink_phone_number(l);
02232       if (ast_strlen_zero(l))
02233          l = NULL;
02234    }
02235    if (!ast_strlen_zero(codecs)) {
02236       format = 0;
02237       ast_parse_allow_disallow(NULL, &format, codecs, 1);
02238    }
02239    if (ast_true(async)) {
02240       struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast));
02241       if (!fast) {
02242          res = -1;
02243       } else {
02244          if (!ast_strlen_zero(id))
02245             snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s", id);
02246          ast_copy_string(fast->tech, tech, sizeof(fast->tech));
02247             ast_copy_string(fast->data, data, sizeof(fast->data));
02248          ast_copy_string(fast->app, app, sizeof(fast->app));
02249          ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata));
02250          if (l)
02251             ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num));
02252          if (n)
02253             ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name));
02254          fast->vars = vars;
02255          ast_copy_string(fast->context, context, sizeof(fast->context));
02256          ast_copy_string(fast->exten, exten, sizeof(fast->exten));
02257          ast_copy_string(fast->account, account, sizeof(fast->account));
02258          fast->format = format;
02259          fast->timeout = to;
02260          fast->priority = pi;
02261          if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) {
02262             ast_free(fast);
02263             res = -1;
02264          } else {
02265             res = 0;
02266          }
02267       }
02268    } else if (!ast_strlen_zero(app)) {
02269       /* To run the System application (or anything else that goes to shell), you must have the additional System privilege */
02270       if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
02271          && (
02272             strcasestr(app, "system") == 0 || /* System(rm -rf /)
02273                                                  TrySystem(rm -rf /)       */
02274             strcasestr(app, "exec") ||        /* Exec(System(rm -rf /))
02275                                                  TryExec(System(rm -rf /)) */
02276             strcasestr(app, "agi") ||         /* AGI(/bin/rm,-rf /)
02277                                                  EAGI(/bin/rm,-rf /)       */
02278             strstr(appdata, "SHELL") ||       /* NoOp(${SHELL(rm -rf /)})  */
02279             strstr(appdata, "EVAL")           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
02280             )) {
02281          astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have.");
02282          return 0;
02283       }
02284       res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
02285    } else {
02286       if (exten && context && pi)
02287          res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL);
02288       else {
02289          astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
02290          return 0;
02291       }
02292    }
02293    if (!res)
02294       astman_send_ack(s, m, "Originate successfully queued");
02295    else
02296       astman_send_error(s, m, "Originate failed");
02297    return 0;
02298 }

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

Definition at line 1091 of file manager.c.

References astman_append().

Referenced by __init_manager().

01092 {
01093    astman_append(s, "Response: Success\r\n"
01094       "Ping: Pong\r\n"
01095       "\r\n");
01096    return 0;
01097 }

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

action_redirect: The redirect manager command

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

01928 {
01929    const char *name = astman_get_header(m, "Channel");
01930    const char *name2 = astman_get_header(m, "ExtraChannel");
01931    const char *exten = astman_get_header(m, "Exten");
01932    const char *context = astman_get_header(m, "Context");
01933    const char *priority = astman_get_header(m, "Priority");
01934    struct ast_channel *chan, *chan2 = NULL;
01935    int pi = 0;
01936    int res;
01937 
01938    if (ast_strlen_zero(name)) {
01939       astman_send_error(s, m, "Channel not specified");
01940       return 0;
01941    }
01942    if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
01943       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
01944          astman_send_error(s, m, "Invalid priority");
01945          return 0;
01946       }
01947    }
01948    /* XXX watch out, possible deadlock - we are trying to get two channels!!! */
01949    chan = ast_get_channel_by_name_locked(name);
01950    if (!chan) {
01951       char buf[256];
01952       snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
01953       astman_send_error(s, m, buf);
01954       return 0;
01955    }
01956    if (ast_check_hangup(chan)) {
01957       astman_send_error(s, m, "Redirect failed, channel not up.");
01958       ast_channel_unlock(chan);
01959       return 0;
01960    }
01961    if (!ast_strlen_zero(name2))
01962       chan2 = ast_get_channel_by_name_locked(name2);
01963    if (chan2 && ast_check_hangup(chan2)) {
01964       astman_send_error(s, m, "Redirect failed, extra channel not up.");
01965       ast_channel_unlock(chan);
01966       ast_channel_unlock(chan2);
01967       return 0;
01968    }
01969    if (chan->pbx) {
01970       ast_channel_lock(chan);
01971       ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
01972       ast_channel_unlock(chan);
01973    }
01974    res = ast_async_goto(chan, context, exten, pi);
01975    if (!res) {
01976       if (!ast_strlen_zero(name2)) {
01977          if (chan2) {
01978             if (chan2->pbx) {
01979                ast_channel_lock(chan2);
01980                ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
01981                ast_channel_unlock(chan2);
01982             }
01983             res = ast_async_goto(chan2, context, exten, pi);
01984          } else {
01985             res = -1;
01986          }
01987          if (!res)
01988             astman_send_ack(s, m, "Dual Redirect successful");
01989          else
01990             astman_send_error(s, m, "Secondary redirect failed");
01991       } else
01992          astman_send_ack(s, m, "Redirect successful");
01993    } else
01994       astman_send_error(s, m, "Redirect failed");
01995    if (chan)
01996       ast_channel_unlock(chan);
01997    if (chan2)
01998       ast_channel_unlock(chan2);
01999    return 0;
02000 }

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

Send a reload event.

Definition at line 2572 of file manager.c.

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

Referenced by __init_manager().

02573 {
02574    const char *module = astman_get_header(m, "Module");
02575    int res = ast_module_reload(S_OR(module, NULL));
02576 
02577    if (res == 2)
02578       astman_send_ack(s, m, "Module Reloaded");
02579    else
02580       astman_send_error(s, m, s == 0 ? "No such module" : "Module does not support reload");
02581    return 0;
02582 }

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

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

01883 {
01884    struct ast_channel *c = NULL;
01885    const char *name = astman_get_header(m, "Channel");
01886    const char *textmsg = astman_get_header(m, "Message");
01887    int res = 0;
01888 
01889    if (ast_strlen_zero(name)) {
01890       astman_send_error(s, m, "No channel specified");
01891       return 0;
01892    }
01893 
01894    if (ast_strlen_zero(textmsg)) {
01895       astman_send_error(s, m, "No Message specified");
01896       return 0;
01897    }
01898 
01899    c = ast_get_channel_by_name_locked(name);
01900    if (!c) {
01901       astman_send_error(s, m, "No such channel");
01902       return 0;
01903    }
01904 
01905    res = ast_sendtext(c, textmsg);
01906    ast_channel_unlock(c);
01907    
01908    if (res > 0)
01909       astman_send_ack(s, m, "Success");
01910    else
01911       astman_send_error(s, m, "Failure");
01912    
01913    return res;
01914 }

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

Definition at line 1695 of file manager.c.

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

Referenced by __init_manager().

01696 {
01697    struct ast_channel *c = NULL;
01698    const char *name = astman_get_header(m, "Channel");
01699    const char *varname = astman_get_header(m, "Variable");
01700    const char *varval = astman_get_header(m, "Value");
01701 
01702    if (ast_strlen_zero(varname)) {
01703       astman_send_error(s, m, "No variable specified");
01704       return 0;
01705    }
01706 
01707    if (!ast_strlen_zero(name)) {
01708       c = ast_get_channel_by_name_locked(name);
01709       if (!c) {
01710          astman_send_error(s, m, "No such channel");
01711          return 0;
01712       }
01713    }
01714 
01715    pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
01716 
01717    if (c)
01718       ast_channel_unlock(c);
01719 
01720    astman_send_ack(s, m, "Variable Set");
01721 
01722    return 0;
01723 }

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

Manager "status" command to show channels.

Definition at line 1780 of file manager.c.

References ast_channel::_bridge, ast_channel::_state, ast_channel::accountcode, ast_channel_unlock, ast_channel_walk_locked(), ast_get_channel_by_name_locked(), ast_state2str(), ast_strlen_zero(), ast_tvnow(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, ast_channel::name, name, ast_channel::pbx, ast_channel::priority, S_OR, ast_cdr::start, and ast_channel::uniqueid.

Referenced by __init_manager().

01781 {
01782    const char *name = astman_get_header(m, "Channel");
01783    struct ast_channel *c;
01784    char bridge[256];
01785    struct timeval now = ast_tvnow();
01786    long elapsed_seconds = 0;
01787    int channels = 0;
01788    int all = ast_strlen_zero(name); /* set if we want all channels */
01789    const char *id = astman_get_header(m, "ActionID");
01790    char idText[256];
01791 
01792    if (!ast_strlen_zero(id))
01793       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01794    else
01795       idText[0] = '\0';
01796 
01797    if (all)
01798       c = ast_channel_walk_locked(NULL);
01799    else {
01800       c = ast_get_channel_by_name_locked(name);
01801       if (!c) {
01802          astman_send_error(s, m, "No such channel");
01803          return 0;
01804       }
01805    }
01806    astman_send_ack(s, m, "Channel status will follow");
01807 
01808    /* if we look by name, we break after the first iteration */
01809    while (c) {
01810       channels++;
01811       if (c->_bridge)
01812          snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid);
01813       else
01814          bridge[0] = '\0';
01815       if (c->pbx) {
01816          if (c->cdr) {
01817             elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
01818          }
01819          astman_append(s,
01820          "Event: Status\r\n"
01821          "Privilege: Call\r\n"
01822          "Channel: %s\r\n"
01823          "CallerIDNum: %s\r\n"
01824          "CallerIDName: %s\r\n"
01825          "Accountcode: %s\r\n"
01826          "ChannelState: %d\r\n"
01827          "ChannelStateDesc: %s\r\n"
01828          "Context: %s\r\n"
01829          "Extension: %s\r\n"
01830          "Priority: %d\r\n"
01831          "Seconds: %ld\r\n"
01832          "%s"
01833          "Uniqueid: %s\r\n"
01834          "%s"
01835          "\r\n",
01836          c->name,
01837          S_OR(c->cid.cid_num, ""),
01838          S_OR(c->cid.cid_name, ""),
01839          c->accountcode,
01840          c->_state,
01841          ast_state2str(c->_state), c->context,
01842          c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, idText);
01843       } else {
01844          astman_append(s,
01845          "Event: Status\r\n"
01846          "Privilege: Call\r\n"
01847          "Channel: %s\r\n"
01848          "CallerIDNum: %s\r\n"
01849          "CallerIDName: %s\r\n"
01850          "Account: %s\r\n"
01851          "State: %s\r\n"
01852          "%s"
01853          "Uniqueid: %s\r\n"
01854          "%s"
01855          "\r\n",
01856          c->name,
01857          S_OR(c->cid.cid_num, "<unknown>"),
01858          S_OR(c->cid.cid_name, "<unknown>"),
01859          c->accountcode,
01860          ast_state2str(c->_state), bridge, c->uniqueid, idText);
01861       }
01862       ast_channel_unlock(c);
01863       if (!all)
01864          break;
01865       c = ast_channel_walk_locked(c);
01866    }
01867    astman_append(s,
01868    "Event: StatusComplete\r\n"
01869    "%s"
01870    "Items: %d\r\n"
01871    "\r\n", idText, channels);
01872    return 0;
01873 }

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

Definition at line 2403 of file manager.c.

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

02404 {
02405    struct ast_channel *c;
02406    const char *name = astman_get_header(m, "Channel");
02407    int timeout = atoi(astman_get_header(m, "Timeout"));
02408 
02409    if (ast_strlen_zero(name)) {
02410       astman_send_error(s, m, "No channel specified");
02411       return 0;
02412    }
02413    if (!timeout) {
02414       astman_send_error(s, m, "No timeout specified");
02415       return 0;
02416    }
02417    c = ast_get_channel_by_name_locked(name);
02418    if (!c) {
02419       astman_send_error(s, m, "No such channel");
02420       return 0;
02421    }
02422    ast_channel_setwhentohangup(c, timeout);
02423    ast_channel_unlock(c);
02424    astman_send_ack(s, m, "Timeout Set");
02425    return 0;
02426 }

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

Definition at line 1377 of file manager.c.

References ast_config_destroy(), ast_config_load, 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_text_file_save(), 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().

01378 {
01379    struct ast_config *cfg;
01380    const char *sfn = astman_get_header(m, "SrcFilename");
01381    const char *dfn = astman_get_header(m, "DstFilename");
01382    int res;
01383    const char *rld = astman_get_header(m, "Reload");
01384    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
01385    enum error_type result;
01386 
01387    if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
01388       astman_send_error(s, m, "Filename not specified");
01389       return 0;
01390    }
01391    if (!(cfg = ast_config_load(sfn, config_flags))) {
01392       astman_send_error(s, m, "Config file not found");
01393       return 0;
01394    }
01395    result = handle_updates(s, m, cfg, dfn);
01396    if (!result) {
01397       ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
01398       res = config_text_file_save(dfn, cfg, "Manager");
01399       ast_config_destroy(cfg);
01400       if (res) {
01401          astman_send_error(s, m, "Save of config failed");
01402          return 0;
01403       }
01404       astman_send_ack(s, m, NULL);
01405       if (!ast_strlen_zero(rld)) {
01406          if (ast_true(rld))
01407             rld = NULL;
01408          ast_module_reload(rld);
01409       }
01410    } else {
01411       ast_config_destroy(cfg);
01412       switch(result) {
01413       case UNKNOWN_ACTION:
01414          astman_send_error(s, m, "Unknown action command");
01415          break;
01416       case UNKNOWN_CATEGORY:
01417          astman_send_error(s, m, "Given category does not exist");
01418          break;
01419       case UNSPECIFIED_CATEGORY:
01420          astman_send_error(s, m, "Category not specified");
01421          break;
01422       case UNSPECIFIED_ARGUMENT:
01423          astman_send_error(s, m, "Problem with category, value, or line (if required)");
01424          break;
01425       case FAILURE_ALLOCATION:
01426          astman_send_error(s, m, "Memory allocation failure, this should not happen");
01427          break;
01428       case FAILURE_NEWCAT:
01429          astman_send_error(s, m, "Create category did not complete successfully");
01430          break;
01431       case FAILURE_DELCAT:
01432          astman_send_error(s, m, "Delete category did not complete successfully");
01433          break;
01434       case FAILURE_EMPTYCAT:
01435          astman_send_error(s, m, "Empty category did not complete successfully");
01436          break;
01437       case FAILURE_UPDATE:
01438          astman_send_error(s, m, "Update did not complete successfully");
01439          break;
01440       case FAILURE_DELETE:
01441          astman_send_error(s, m, "Delete did not complete successfully");
01442          break;
01443       case FAILURE_APPEND:
01444          astman_send_error(s, m, "Append did not complete successfully");
01445          break;
01446       }
01447    }
01448    return 0;
01449 }

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

Definition at line 2463 of file manager.c.

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

Referenced by __init_manager().

02464 {
02465    const char *event = astman_get_header(m, "UserEvent");
02466    struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
02467    int x;
02468 
02469    ast_str_reset(body);
02470 
02471    for (x = 0; x < m->hdrcount; x++) {
02472       if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
02473          ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
02474       }
02475    }
02476 
02477    manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body->str);
02478    return 0;
02479 }

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

Definition at line 1483 of file manager.c.

References mansession_session::__lock, ast_debug, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, 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, NEW_EVENT, mansession_session::readperm, ref_event(), mansession_session::send_events, mansession::session, mansession_session::sessiontimeout, unref_event(), and mansession_session::waiting_thread.

Referenced by __init_manager().

01484 {
01485    const char *timeouts = astman_get_header(m, "Timeout");
01486    int timeout = -1;
01487    int x;
01488    int needexit = 0;
01489    const char *id = astman_get_header(m, "ActionID");
01490    char idText[256];
01491 
01492    if (!ast_strlen_zero(id))
01493       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01494    else
01495       idText[0] = '\0';
01496 
01497    if (!ast_strlen_zero(timeouts)) {
01498       sscanf(timeouts, "%30i", &timeout);
01499       if (timeout < -1)
01500          timeout = -1;
01501       /* XXX maybe put an upper bound, or prevent the use of 0 ? */
01502    }
01503 
01504    ast_mutex_lock(&s->session->__lock);
01505    if (s->session->waiting_thread != AST_PTHREADT_NULL)
01506       pthread_kill(s->session->waiting_thread, SIGURG);
01507 
01508    if (s->session->managerid) { /* AMI-over-HTTP session */
01509       /*
01510        * Make sure the timeout is within the expire time of the session,
01511        * as the client will likely abort the request if it does not see
01512        * data coming after some amount of time.
01513        */
01514       time_t now = time(NULL);
01515       int max = s->session->sessiontimeout - now - 10;
01516 
01517       if (max < 0)   /* We are already late. Strange but possible. */
01518          max = 0;
01519       if (timeout < 0 || timeout > max)
01520          timeout = max;
01521       if (!s->session->send_events) /* make sure we record events */
01522          s->session->send_events = -1;
01523    }
01524    ast_mutex_unlock(&s->session->__lock);
01525 
01526    /* XXX should this go inside the lock ? */
01527    s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
01528    ast_debug(1, "Starting waiting for an event!\n");
01529 
01530    for (x = 0; x < timeout || timeout < 0; x++) {
01531       ast_mutex_lock(&s->session->__lock);
01532       if (NEW_EVENT(s))
01533          needexit = 1;
01534       /* We can have multiple HTTP session point to the same mansession entry.
01535        * The way we deal with it is not very nice: newcomers kick out the previous
01536        * HTTP session. XXX this needs to be improved.
01537        */
01538       if (s->session->waiting_thread != pthread_self())
01539          needexit = 1;
01540       if (s->session->needdestroy)
01541          needexit = 1;
01542       ast_mutex_unlock(&s->session->__lock);
01543       if (needexit)
01544          break;
01545       if (s->session->managerid == 0) {   /* AMI session */
01546          if (ast_wait_for_input(s->session->fd, 1000))
01547             break;
01548       } else { /* HTTP session */
01549          sleep(1);
01550       }
01551    }
01552    ast_debug(1, "Finished waiting for an event!\n");
01553    ast_mutex_lock(&s->session->__lock);
01554    if (s->session->waiting_thread == pthread_self()) {
01555       struct eventqent *eqe;
01556       astman_send_response(s, m, "Success", "Waiting for Event completed.");
01557       while ( (eqe = NEW_EVENT(s)) ) {
01558          ref_event(eqe);
01559          if (((s->session->readperm & eqe->category) == eqe->category) &&
01560              ((s->session->send_events & eqe->category) == eqe->category)) {
01561             astman_append(s, "%s", eqe->eventdata);
01562          }
01563          s->session->last_ev = unref_event(s->session->last_ev);
01564       }
01565       astman_append(s,
01566          "Event: WaitEventComplete\r\n"
01567          "%s"
01568          "\r\n", idText);
01569       s->session->waiting_thread = AST_PTHREADT_NULL;
01570    } else {
01571       ast_debug(1, "Abandoning event request!\n");
01572    }
01573    ast_mutex_unlock(&s->session->__lock);
01574    return 0;
01575 }

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

Definition at line 3040 of file manager.c.

References ast_atomic_fetchadd_int(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_UNLOCK, ast_malloc, eventqent::category, eventqent::eventdata, eventqent::seq, and eventqent::usecount.

Referenced by __init_manager(), and __manager_event().

03041 {
03042    struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
03043    static int seq;   /* sequence number */
03044 
03045    if (!tmp)
03046       return -1;
03047 
03048    /* need to init all fields, because ast_malloc() does not */
03049    tmp->usecount = 0;
03050    tmp->category = category;
03051    tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
03052    AST_LIST_NEXT(tmp, eq_next) = NULL;
03053    strcpy(tmp->eventdata, str);
03054 
03055    AST_LIST_LOCK(&all_events);
03056    AST_LIST_INSERT_TAIL(&all_events, tmp, eq_next);
03057    AST_LIST_UNLOCK(&all_events);
03058 
03059    return 0;
03060 }

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

References eventqent::next.

Referenced by get_perm().

00406 {
00407    const char *val = bigstr, *next;
00408 
00409    do {
00410       if ((next = strchr(val, delim))) {
00411          if (!strncmp(val, smallstr, (next - val)))
00412             return 1;
00413          else
00414             continue;
00415       } else
00416          return !strcmp(smallstr, val);
00417    } while (*(val = (next + 1)));
00418 
00419    return 0;
00420 }

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

03212 {
03213    struct manager_action *cur = NULL;
03214 
03215    if (!(cur = ast_calloc(1, sizeof(*cur))))
03216       return -1;
03217 
03218    cur->action = action;
03219    cur->authority = auth;
03220    cur->func = func;
03221    cur->synopsis = synopsis;
03222    cur->description = description;
03223 
03224    if (ast_manager_register_struct(cur)) {
03225       ast_free(cur);
03226       return -1;
03227    }
03228 
03229    return 0;
03230 }

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

References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

00250 {
00251    AST_RWLIST_WRLOCK(&manager_hooks);
00252    AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list);
00253    AST_RWLIST_UNLOCK(&manager_hooks);
00254    return;
00255 }

static int ast_manager_register_struct ( struct manager_action act  )  [static]

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

Referenced by ast_manager_register2().

03176 {
03177    struct manager_action *cur, *prev = NULL;
03178    struct timespec tv = { 5, };
03179 
03180    if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) {
03181       ast_log(LOG_ERROR, "Could not obtain lock on manager list\n");
03182       return -1;
03183    }
03184    AST_RWLIST_TRAVERSE(&actions, cur, list) {
03185       int ret = strcasecmp(cur->action, act->action);
03186       if (ret == 0) {
03187          ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
03188          AST_RWLIST_UNLOCK(&actions);
03189          return -1;
03190       }
03191       if (ret > 0) { /* Insert these alphabetically */
03192          prev = cur;
03193          break;
03194       }
03195    }
03196 
03197    if (prev)
03198       AST_RWLIST_INSERT_AFTER(&actions, prev, act, list);
03199    else
03200       AST_RWLIST_INSERT_HEAD(&actions, act, list);
03201 
03202    ast_verb(2, "Manager registered action %s\n", act->action);
03203 
03204    AST_RWLIST_UNLOCK(&actions);
03205 
03206    return 0;
03207 }

int ast_manager_unregister ( char *  action  ) 

Unregister a registered manager command.

Parameters:
action Name of registered Action:

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

Referenced by __unload_module(), and unload_module().

03143 {
03144    struct manager_action *cur;
03145    struct timespec tv = { 5, };
03146 
03147    if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) {
03148       ast_log(LOG_ERROR, "Could not obtain lock on manager list\n");
03149       return -1;
03150    }
03151    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) {
03152       if (!strcasecmp(action, cur->action)) {
03153          AST_RWLIST_REMOVE_CURRENT(list);
03154          ast_free(cur);
03155          ast_verb(2, "Manager unregistered action %s\n", action);
03156          break;
03157       }
03158    }
03159    AST_RWLIST_TRAVERSE_SAFE_END
03160    AST_RWLIST_UNLOCK(&actions);
03161 
03162    return 0;
03163 }

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

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

00259 {
00260    AST_RWLIST_WRLOCK(&manager_hooks);
00261    AST_RWLIST_REMOVE(&manager_hooks, hook, list);
00262    AST_RWLIST_UNLOCK(&manager_hooks);
00263    return;
00264 }

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

utility functions for creating AMI replies

Definition at line 924 of file manager.c.

References 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(), mansession::session, and ast_str::str.

Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), 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_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_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_show_dialplan_helper(), manager_show_registry(), manager_sip_show_peer(), manager_sip_show_peers(), and session_do().

00925 {
00926    va_list ap;
00927    struct ast_str *buf;
00928 
00929    if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE)))
00930       return;
00931 
00932    va_start(ap, fmt);
00933    ast_str_set_va(&buf, 0, fmt, ap);
00934    va_end(ap);
00935 
00936    if (s->f != NULL || s->session->f != NULL)
00937       send_string(s, buf->str);
00938    else
00939       ast_verbose("fd == -1 in astman_append, should not happen\n");
00940 }

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

Get header from mananger transaction.

Definition at line 845 of file manager.c.

References message::hdrcount, and message::headers.

Referenced by _sip_show_peer(), _sip_show_peers(), action_add_agi_cmd(), action_agent_logoff(), action_agents(), 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_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_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_rule_show(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_show_dialplan(), manager_show_registry(), manager_sip_show_peer(), manager_sip_show_peers(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().

00846 {
00847    int x, l = strlen(var);
00848 
00849    for (x = 0; x < m->hdrcount; x++) {
00850       const char *h = m->headers[x];
00851       if (!strncasecmp(var, h, l) && h[l] == ':' && h[l+1] == ' ')
00852          return h + l + 2;
00853    }
00854 
00855    return "";
00856 }

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

Get a linked list of the Variable: headers.

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

00859 {
00860    int varlen, x, y;
00861    struct ast_variable *head = NULL, *cur;
00862 
00863    AST_DECLARE_APP_ARGS(args,
00864       AST_APP_ARG(vars)[32];
00865    );
00866 
00867    varlen = strlen("Variable: ");
00868 
00869    for (x = 0; x < m->hdrcount; x++) {
00870       char *parse, *var, *val;
00871 
00872       if (strncasecmp("Variable: ", m->headers[x], varlen))
00873          continue;
00874       parse = ast_strdupa(m->headers[x] + varlen);
00875 
00876       AST_STANDARD_APP_ARGS(args, parse);
00877       if (!args.argc)
00878          continue;
00879       for (y = 0; y < args.argc; y++) {
00880          if (!args.vars[y])
00881             continue;
00882          var = val = ast_strdupa(args.vars[y]);
00883          strsep(&val, "=");
00884          if (!val || ast_strlen_zero(var))
00885             continue;
00886          cur = ast_variable_new(var, val, "");
00887          cur->next = head;
00888          head = cur;
00889       }
00890    }
00891 
00892    return head;
00893 }

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 
)

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

Send ack in manager list transaction.

Definition at line 996 of file manager.c.

References astman_send_response_full().

Referenced by action_coreshowchannels(), action_meetmelist(), manager_dpsendack(), manager_show_registry(), and manager_sip_show_peers().

00997 {
00998    astman_send_response_full(s, m, "Success", msg, listflag);
00999 }

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

Send response in manager transaction.

Definition at line 976 of file manager.c.

References astman_send_response_full().

Referenced by action_logoff(), and action_waitevent().

00977 {
00978    astman_send_response_full(s, m, resp, msg, NULL);
00979 }

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

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

00960 {
00961    const char *id = astman_get_header(m, "ActionID");
00962 
00963    astman_append(s, "Response: %s\r\n", resp);
00964    if (!ast_strlen_zero(id))
00965       astman_append(s, "ActionID: %s\r\n", id);
00966    if (listflag)
00967       astman_append(s, "Eventlist: %s\r\n", listflag);   /* Start, complete, cancelled */
00968    if (msg == MSG_MOREDATA)
00969       return;
00970    else if (msg)
00971       astman_append(s, "Message: %s\r\n\r\n", msg);
00972    else
00973       astman_append(s, "\r\n");
00974 }

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

Referenced by action_login(), authenticate_reply(), and registry_rerequest().

01026 {
01027    const char *username = astman_get_header(m, "Username");
01028    const char *password = astman_get_header(m, "Secret");
01029    int error = -1;
01030    struct ast_manager_user *user = NULL;
01031 
01032    if (ast_strlen_zero(username))   /* missing username */
01033       return -1;
01034 
01035    /* locate user in locked state */
01036    AST_RWLIST_WRLOCK(&users);
01037 
01038    if (!(user = get_manager_by_name_locked(username))) {
01039       ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
01040    } else if (user->ha && !ast_apply_ha(user->ha, &(s->session->sin))) {
01041       ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
01042    } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
01043       const char *key = astman_get_header(m, "Key");
01044       if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
01045          int x;
01046          int len = 0;
01047          char md5key[256] = "";
01048          struct MD5Context md5;
01049          unsigned char digest[16];
01050 
01051          MD5Init(&md5);
01052          MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
01053          MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
01054          MD5Final(digest, &md5);
01055          for (x = 0; x < 16; x++)
01056             len += sprintf(md5key + len, "%2.2x", digest[x]);
01057          if (!strcmp(md5key, key))
01058             error = 0;
01059       } else {
01060          ast_debug(1, "MD5 authentication is not possible.  challenge: '%s'\n", 
01061             S_OR(s->session->challenge, ""));
01062       }
01063    } else if (password && user->secret && !strcmp(password, user->secret))
01064       error = 0;
01065 
01066    if (error) {
01067       ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
01068       AST_RWLIST_UNLOCK(&users);
01069       return -1;
01070    }
01071 
01072    /* auth complete */
01073    
01074    ast_copy_string(s->session->username, username, sizeof(s->session->username));
01075    s->session->readperm = user->readperm;
01076    s->session->writeperm = user->writeperm;
01077    s->session->writetimeout = user->writetimeout;
01078    s->session->sessionstart = time(NULL);
01079    set_eventmask(s, astman_get_header(m, "Events"));
01080    
01081    AST_RWLIST_UNLOCK(&users);
01082    return 0;
01083 }

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

Convert authority code to a list of options.

Definition at line 381 of file manager.c.

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

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

00382 {
00383    int i;
00384    char *sep = "";
00385 
00386    (*res)->used = 0;
00387    for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
00388       if (authority & perms[i].num) {
00389          ast_str_append(res, 0, "%s%s", sep, perms[i].label);
00390          sep = ",";
00391       }
00392    }
00393 
00394    if ((*res)->used == 0)  /* replace empty string with something sensible */
00395       ast_str_append(res, 0, "<none>");
00396 
00397    return (*res)->str;
00398 }

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

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

02003 {
02004    char *cmd_copy, *cur_cmd;
02005    char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, };
02006    int i;
02007 
02008    cmd_copy = ast_strdupa(cmd);
02009    for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) {
02010       cur_cmd = ast_strip(cur_cmd);
02011       if (ast_strlen_zero(cur_cmd)) {
02012          i--;
02013          continue;
02014       }
02015 
02016       cmd_words[i] = cur_cmd;
02017    }
02018 
02019    for (i = 0; i < ARRAY_LEN(command_blacklist); i++) {
02020       int j, match = 1;
02021 
02022       for (j = 0; command_blacklist[i].words[j]; j++) {
02023          if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) {
02024             match = 0;
02025             break;
02026          }
02027       }
02028 
02029       if (match) {
02030          return 1;
02031       }
02032    }
02033 
02034    return 0;
02035 }

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

Referenced by handle_show_settings().

00310 {
00311    return manager_enabled;
00312 }

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

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

00465 {
00466    struct mansession_session *session = NULL;
00467 
00468    AST_LIST_LOCK(&sessions);
00469    AST_LIST_TRAVERSE(&sessions, session, list) {
00470       if (!strcasecmp(session->username, name)) 
00471          break;
00472    }
00473    AST_LIST_UNLOCK(&sessions);
00474 
00475    return session ? 1 : 0;
00476 }

int check_webmanager_enabled ( void   ) 

Check if AMI/HTTP is enabled.

Definition at line 314 of file manager.c.

Referenced by action_coresettings(), and handle_show_settings().

00315 {
00316    return (webmanager_enabled && manager_enabled);
00317 }

static void destroy_session ( struct mansession_session session  )  [static]

static int do_message ( struct mansession s  )  [static]

Definition at line 2907 of file manager.c.

References AST_MAX_MANHEADERS, ast_strdupa, ast_strlen_zero(), get_input(), message::hdrcount, message::headers, mansession_session::inbuf, process_events(), process_message(), and mansession::session.

Referenced by session_do().

02908 {
02909    struct message m = { 0 };
02910    char header_buf[sizeof(s->session->inbuf)] = { '\0' };
02911    int res;
02912 
02913    for (;;) {
02914       /* Check if any events are pending and do them if needed */
02915       if (process_events(s))
02916          return -1;
02917       res = get_input(s, header_buf);
02918       if (res == 0) {
02919          continue;
02920       } else if (res > 0) {
02921          if (ast_strlen_zero(header_buf))
02922             return process_message(s, &m) ? -1 : 0;
02923          else if (m.hdrcount < (AST_MAX_MANHEADERS - 1))
02924             m.headers[m.hdrcount++] = ast_strdupa(header_buf);
02925       } else {
02926          return res;
02927       }
02928    }
02929 }

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

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

02114 {
02115    struct fast_originate_helper *in = data;
02116    int res;
02117    int reason = 0;
02118    struct ast_channel *chan = NULL;
02119    char requested_channel[AST_CHANNEL_NAME];
02120 
02121    if (!ast_strlen_zero(in->app)) {
02122       res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1,
02123          S_OR(in->cid_num, NULL),
02124          S_OR(in->cid_name, NULL),
02125          in->vars, in->account, &chan);
02126    } else {
02127       res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1,
02128          S_OR(in->cid_num, NULL),
02129          S_OR(in->cid_name, NULL),
02130          in->vars, in->account, &chan);
02131    }
02132 
02133    if (!chan)
02134       snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);   
02135    /* Tell the manager what happened with the channel */
02136    manager_event(EVENT_FLAG_CALL, "OriginateResponse",
02137       "%s%s"
02138       "Response: %s\r\n"
02139       "Channel: %s\r\n"
02140       "Context: %s\r\n"
02141       "Exten: %s\r\n"
02142       "Reason: %d\r\n"
02143       "Uniqueid: %s\r\n"
02144       "CallerIDNum: %s\r\n"
02145       "CallerIDName: %s\r\n",
02146       in->idtext, ast_strlen_zero(in->idtext) ? "" : "\r\n", res ? "Failure" : "Success", 
02147       chan ? chan->name : requested_channel, in->context, in->exten, reason, 
02148       chan ? chan->uniqueid : "<null>",
02149       S_OR(in->cid_num, "<unknown>"),
02150       S_OR(in->cid_name, "<unknown>")
02151       );
02152 
02153    /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
02154    if (chan)
02155       ast_channel_unlock(chan);
02156    ast_free(in);
02157    return NULL;
02158 }

static void free_session ( struct mansession_session session  )  [static]

Definition at line 826 of file manager.c.

References mansession_session::__lock, ast_free, ast_mutex_destroy(), mansession_session::f, mansession_session::last_ev, and unref_event().

Referenced by destroy_session(), and purge_sessions().

00827 {
00828    struct eventqent *eqe = session->last_ev;
00829    if (session->f != NULL)
00830       fclose(session->f);
00831    ast_mutex_destroy(&session->__lock);
00832    ast_free(session);
00833    unref_event(eqe);
00834 }

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 2837 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(), errno, mansession_session::f, mansession_session::fd, mansession_session::inbuf, mansession_session::inlen, LOG_WARNING, mansession_session::pending_event, mansession::session, mansession_session::sin, and mansession_session::waiting_thread.

Referenced by do_message(), and skinny_session().

02838 {
02839    int res, x;
02840    int maxlen = sizeof(s->session->inbuf) - 1;
02841    char *src = s->session->inbuf;
02842 
02843    /*
02844     * Look for \r\n within the buffer. If found, copy to the output
02845     * buffer and return, trimming the \r\n (not used afterwards).
02846     */
02847    for (x = 0; x < s->session->inlen; x++) {
02848       int cr;  /* set if we have \r */
02849       if (src[x] == '\r' && x+1 < s->session->inlen && src[x+1] == '\n')
02850          cr = 2;  /* Found. Update length to include \r\n */
02851       else if (src[x] == '\n')
02852          cr = 1;  /* also accept \n only */
02853       else
02854          continue;
02855       memmove(output, src, x);   /*... but trim \r\n */
02856       output[x] = '\0';    /* terminate the string */
02857       x += cr;       /* number of bytes used */
02858       s->session->inlen -= x;       /* remaining size */
02859       memmove(src, src + x, s->session->inlen); /* remove used bytes */
02860       return 1;
02861    }
02862    if (s->session->inlen >= maxlen) {
02863       /* no crlf found, and buffer full - sorry, too long for us */
02864       ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src);
02865       s->session->inlen = 0;
02866    }
02867    res = 0;
02868    while (res == 0) {
02869       /* XXX do we really need this locking ? */
02870       ast_mutex_lock(&s->session->__lock);
02871       if (s->session->pending_event) {
02872          s->session->pending_event = 0;
02873          ast_mutex_unlock(&s->session->__lock);
02874          return 0;
02875       }
02876       s->session->waiting_thread = pthread_self();
02877       ast_mutex_unlock(&s->session->__lock);
02878 
02879       res = ast_wait_for_input(s->session->fd, -1);   /* return 0 on timeout ? */
02880 
02881       ast_mutex_lock(&s->session->__lock);
02882       s->session->waiting_thread = AST_PTHREADT_NULL;
02883       ast_mutex_unlock(&s->session->__lock);
02884    }
02885    if (res < 0) {
02886       /* If we get a signal from some other thread (typically because
02887        * there are new events queued), return 0 to notify the caller.
02888        */
02889       if (errno == EINTR || errno == EAGAIN)
02890          return 0;
02891       ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
02892       return -1;
02893    }
02894    ast_mutex_lock(&s->session->__lock);
02895    res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f);
02896    if (res < 1)
02897       res = -1;   /* error return */
02898    else {
02899       s->session->inlen += res;
02900       src[s->session->inlen] = '\0';
02901       res = 0;
02902    }
02903    ast_mutex_unlock(&s->session->__lock);
02904    return res;
02905 }

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

00484 {
00485    struct ast_manager_user *user = NULL;
00486 
00487    AST_RWLIST_TRAVERSE(&users, user, list)
00488       if (!strcasecmp(user->username, name))
00489          break;
00490    return user;
00491 }

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

Definition at line 422 of file manager.c.

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

Referenced by __init_manager(), and strings_to_mask().

00423 {
00424    int x = 0, ret = 0;
00425 
00426    if (!instr)
00427       return 0;
00428 
00429    for (x = 0; x < ARRAY_LEN(perms); x++) {
00430       if (ast_instring(instr, perms[x].label, ','))
00431          ret |= perms[x].num;
00432    }
00433 
00434    return ret;
00435 }

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

References ast_atomic_fetchadd_int(), AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_UNLOCK, and eventqent::usecount.

Referenced by generic_http_callback(), and session_do().

00324 {
00325    struct eventqent *ret;
00326 
00327    AST_LIST_LOCK(&all_events);
00328    ret = AST_LIST_LAST(&all_events);
00329    /* the list is never empty now, but may become so when
00330     * we optimize it in the future, so be prepared.
00331     */
00332    if (ret)
00333       ast_atomic_fetchadd_int(&ret->usecount, 1);
00334    AST_LIST_UNLOCK(&all_events);
00335    return ret;
00336 }

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

00777 {
00778    switch (cmd) {
00779    case CLI_INIT:
00780       e->command = "manager reload";
00781       e->usage =
00782          "Usage: manager reload\n"
00783          "       Reloads the manager configuration.\n";
00784       return NULL;
00785    case CLI_GENERATE:
00786       return NULL;
00787    }
00788    if (a->argc > 2)
00789       return CLI_SHOWUSAGE;
00790    reload_manager();
00791    return CLI_SUCCESS;
00792 }

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

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

00558 {
00559    switch (cmd) {
00560    case CLI_INIT:
00561       e->command = "manager debug [on|off]";
00562       e->usage = "Usage: manager debug [on|off]\n  Show, enable, disable debugging of the manager code.\n";
00563       return NULL;
00564    case CLI_GENERATE:
00565       return NULL;   
00566    }
00567    if (a->argc == 2)
00568       ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off");
00569    else if (a->argc == 3) {
00570       if (!strcasecmp(a->argv[2], "on"))
00571          manager_debug = 1;
00572       else if (!strcasecmp(a->argv[2], "off"))
00573          manager_debug = 0;
00574       else
00575          return CLI_SHOWUSAGE;
00576    }
00577    return CLI_SUCCESS;
00578 }

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

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

00581 {
00582    struct ast_manager_user *user = NULL;
00583    int l, which;
00584    char *ret = NULL;
00585    struct ast_str *rauthority = ast_str_alloca(128);
00586    struct ast_str *wauthority = ast_str_alloca(128);
00587 
00588    switch (cmd) {
00589    case CLI_INIT:
00590       e->command = "manager show user";
00591       e->usage = 
00592          " Usage: manager show user <user>\n"
00593          "        Display all information related to the manager user specified.\n";
00594       return NULL;
00595    case CLI_GENERATE:
00596       l = strlen(a->word);
00597       which = 0;
00598       if (a->pos != 3)
00599          return NULL;
00600       AST_RWLIST_RDLOCK(&users);
00601       AST_RWLIST_TRAVERSE(&users, user, list) {
00602          if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) {
00603             ret = ast_strdup(user->username);
00604             break;
00605          }
00606       }
00607       AST_RWLIST_UNLOCK(&users);
00608       return ret;
00609    }
00610 
00611    if (a->argc != 4)
00612       return CLI_SHOWUSAGE;
00613 
00614    AST_RWLIST_RDLOCK(&users);
00615 
00616    if (!(user = get_manager_by_name_locked(a->argv[3]))) {
00617       ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]);
00618       AST_RWLIST_UNLOCK(&users);
00619       return CLI_SUCCESS;
00620    }
00621 
00622    ast_cli(a->fd, "\n");
00623    ast_cli(a->fd,
00624       "       username: %s\n"
00625       "         secret: %s\n"
00626       "            acl: %s\n"
00627       "      read perm: %s\n"
00628       "     write perm: %s\n"
00629       "displayconnects: %s\n",
00630       (user->username ? user->username : "(N/A)"),
00631       (user->secret ? "<Set>" : "(N/A)"),
00632       (user->ha ? "yes" : "no"),
00633       authority_to_str(user->readperm, &rauthority),
00634       authority_to_str(user->writeperm, &wauthority),
00635       (user->displayconnects ? "yes" : "no"));
00636 
00637    AST_RWLIST_UNLOCK(&users);
00638 
00639    return CLI_SUCCESS;
00640 }

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

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

00644 {
00645    struct ast_manager_user *user = NULL;
00646    int count_amu = 0;
00647    switch (cmd) {
00648    case CLI_INIT:
00649       e->command = "manager show users";
00650       e->usage = 
00651          "Usage: manager show users\n"
00652          "       Prints a listing of all managers that are currently configured on that\n"
00653          " system.\n";
00654       return NULL;
00655    case CLI_GENERATE:
00656       return NULL;
00657    }
00658    if (a->argc != 3)
00659       return CLI_SHOWUSAGE;
00660 
00661    AST_RWLIST_RDLOCK(&users);
00662 
00663    /* If there are no users, print out something along those lines */
00664    if (AST_RWLIST_EMPTY(&users)) {
00665       ast_cli(a->fd, "There are no manager users.\n");
00666       AST_RWLIST_UNLOCK(&users);
00667       return CLI_SUCCESS;
00668    }
00669 
00670    ast_cli(a->fd, "\nusername\n--------\n");
00671 
00672    AST_RWLIST_TRAVERSE(&users, user, list) {
00673       ast_cli(a->fd, "%s\n", user->username);
00674       count_amu++;
00675    }
00676 
00677    AST_RWLIST_UNLOCK(&users);
00678 
00679    ast_cli(a->fd, "-------------------\n");
00680    ast_cli(a->fd, "%d manager users configured.\n", count_amu);
00681 
00682    return CLI_SUCCESS;
00683 }

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

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

00511 {
00512    struct manager_action *cur;
00513    struct ast_str *authority;
00514    int num, l, which;
00515    char *ret = NULL;
00516    switch (cmd) {
00517    case CLI_INIT:
00518       e->command = "manager show command";
00519       e->usage = 
00520          "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n"
00521          "  Shows the detailed description for a specific Asterisk manager interface command.\n";
00522       return NULL;
00523    case CLI_GENERATE:
00524       l = strlen(a->word);
00525       which = 0;
00526       AST_RWLIST_RDLOCK(&actions);
00527       AST_RWLIST_TRAVERSE(&actions, cur, list) {
00528          if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) {
00529             ret = ast_strdup(cur->action);
00530             break;   /* make sure we exit even if ast_strdup() returns NULL */
00531          }
00532       }
00533       AST_RWLIST_UNLOCK(&actions);
00534       return ret;
00535    }
00536    authority = ast_str_alloca(80);
00537    if (a->argc < 4) {
00538       return CLI_SHOWUSAGE;
00539    }
00540 
00541    AST_RWLIST_RDLOCK(&actions);
00542    AST_RWLIST_TRAVERSE(&actions, cur, list) {
00543       for (num = 3; num < a->argc; num++) {
00544          if (!strcasecmp(cur->action, a->argv[num])) {
00545             ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
00546                cur->action, cur->synopsis,
00547                authority_to_str(cur->authority, &authority),
00548                S_OR(cur->description, ""));
00549          }
00550       }
00551    }
00552    AST_RWLIST_UNLOCK(&actions);
00553 
00554    return CLI_SUCCESS;
00555 }

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

00688 {
00689    struct manager_action *cur;
00690    struct ast_str *authority;
00691 #define HSMC_FORMAT "  %-15.15s  %-15.15s  %-55.55s\n"
00692    switch (cmd) {
00693    case CLI_INIT:
00694       e->command = "manager show commands";
00695       e->usage = 
00696          "Usage: manager show commands\n"
00697          "  Prints a listing of all the available Asterisk manager interface commands.\n";
00698       return NULL;
00699    case CLI_GENERATE:
00700       return NULL;   
00701    }  
00702    authority = ast_str_alloca(80);
00703    ast_cli(a->fd, HSMC_FORMAT, "Action", "Privilege", "Synopsis");
00704    ast_cli(a->fd, HSMC_FORMAT, "------", "---------", "--------");
00705 
00706    AST_RWLIST_RDLOCK(&actions);
00707    AST_RWLIST_TRAVERSE(&actions, cur, list)
00708       ast_cli(a->fd, HSMC_FORMAT, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis);
00709    AST_RWLIST_UNLOCK(&actions);
00710 
00711    return CLI_SUCCESS;
00712 }

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

00716 {
00717    struct mansession_session *session;
00718    time_t now = time(NULL);
00719 #define HSMCONN_FORMAT1 "  %-15.15s  %-15.15s  %-10.10s  %-10.10s  %-8.8s  %-8.8s  %-5.5s  %-5.5s\n"
00720 #define HSMCONN_FORMAT2 "  %-15.15s  %-15.15s  %-10d  %-10d  %-8d  %-8d  %-5.5d  %-5.5d\n"
00721    int count = 0;
00722    switch (cmd) {
00723    case CLI_INIT:
00724       e->command = "manager show connected";
00725       e->usage = 
00726          "Usage: manager show connected\n"
00727          "  Prints a listing of the users that are currently connected to the\n"
00728          "Asterisk manager interface.\n";
00729       return NULL;
00730    case CLI_GENERATE:
00731       return NULL;   
00732    }
00733 
00734    ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write");
00735 
00736    AST_LIST_LOCK(&sessions);
00737    AST_LIST_TRAVERSE(&sessions, session, list) {
00738       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);
00739       count++;
00740    }
00741    AST_LIST_UNLOCK(&sessions);
00742 
00743    ast_cli(a->fd, "%d users connected.\n", count);
00744 
00745    return CLI_SUCCESS;
00746 }

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

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_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.

00751 {
00752    struct eventqent *s;
00753    switch (cmd) {
00754    case CLI_INIT:
00755       e->command = "manager show eventq";
00756       e->usage = 
00757          "Usage: manager show eventq\n"
00758          "  Prints a listing of all events pending in the Asterisk manger\n"
00759          "event queue.\n";
00760       return NULL;
00761    case CLI_GENERATE:
00762       return NULL;
00763    }
00764    AST_LIST_LOCK(&all_events);
00765    AST_LIST_TRAVERSE(&all_events, s, eq_next) {
00766       ast_cli(a->fd, "Usecount: %d\n", s->usecount);
00767       ast_cli(a->fd, "Category: %d\n", s->category);
00768       ast_cli(a->fd, "Event:\n%s", s->eventdata);
00769    }
00770    AST_LIST_UNLOCK(&all_events);
00771 
00772    return CLI_SUCCESS;
00773 }

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

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

01265 {
01266    int x;
01267    char hdr[40];
01268    const char *action, *cat, *var, *value, *match, *line;
01269    struct ast_category *category;
01270    struct ast_variable *v;
01271 
01272    for (x = 0; x < 100000; x++) {   /* 100000 = the max number of allowed updates + 1 */
01273       unsigned int object = 0;
01274 
01275       snprintf(hdr, sizeof(hdr), "Action-%06d", x);
01276       action = astman_get_header(m, hdr);
01277       if (ast_strlen_zero(action))     /* breaks the for loop if no action header */
01278          break;            /* this could cause problems if actions come in misnumbered */
01279 
01280       snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
01281       cat = astman_get_header(m, hdr);
01282       if (ast_strlen_zero(cat))     /* every action needs a category */
01283          return UNSPECIFIED_CATEGORY;
01284 
01285       snprintf(hdr, sizeof(hdr), "Var-%06d", x);
01286       var = astman_get_header(m, hdr);
01287 
01288       snprintf(hdr, sizeof(hdr), "Value-%06d", x);
01289       value = astman_get_header(m, hdr);
01290       if (!ast_strlen_zero(value) && *value == '>') {
01291          object = 1;
01292          value++;
01293       }
01294 
01295       snprintf(hdr, sizeof(hdr), "Match-%06d", x);
01296       match = astman_get_header(m, hdr);
01297 
01298       snprintf(hdr, sizeof(hdr), "Line-%06d", x);
01299       line = astman_get_header(m, hdr);
01300 
01301       if (!strcasecmp(action, "newcat")) {
01302          if (ast_category_get(cfg,cat))      /* check to make sure the cat doesn't */
01303             return FAILURE_NEWCAT;     /* already exist */
01304          if (!(category = ast_category_new(cat, dfn, -1)))
01305             return FAILURE_ALLOCATION;
01306          if (ast_strlen_zero(match)) {
01307             ast_category_append(cfg, category);
01308          } else
01309             ast_category_insert(cfg, category, match);
01310       } else if (!strcasecmp(action, "renamecat")) {
01311          if (ast_strlen_zero(value))
01312             return UNSPECIFIED_ARGUMENT;
01313          if (!(category = ast_category_get(cfg, cat)))
01314             return UNKNOWN_CATEGORY;
01315          ast_category_rename(category, value);
01316       } else if (!strcasecmp(action, "delcat")) {
01317          if (ast_category_delete(cfg, cat))
01318             return FAILURE_DELCAT;
01319       } else if (!strcasecmp(action, "emptycat")) {
01320          if (ast_category_empty(cfg, cat))
01321             return FAILURE_EMPTYCAT;
01322       } else if (!strcasecmp(action, "update")) {
01323          if (ast_strlen_zero(var))
01324             return UNSPECIFIED_ARGUMENT;
01325          if (!(category = ast_category_get(cfg,cat)))
01326             return UNKNOWN_CATEGORY;
01327          if (ast_variable_update(category, var, value, match, object))
01328             return FAILURE_UPDATE;
01329       } else if (!strcasecmp(action, "delete")) {
01330          if ((ast_strlen_zero(var) && ast_strlen_zero(line)))
01331             return UNSPECIFIED_ARGUMENT;
01332          if (!(category = ast_category_get(cfg, cat)))
01333             return UNKNOWN_CATEGORY;
01334          if (ast_variable_delete(category, var, match, line))
01335             return FAILURE_DELETE;
01336       } else if (!strcasecmp(action, "append")) {
01337          if (ast_strlen_zero(var))
01338             return UNSPECIFIED_ARGUMENT;
01339          if (!(category = ast_category_get(cfg, cat)))
01340             return UNKNOWN_CATEGORY;   
01341          if (!(v = ast_variable_new(var, value, dfn)))
01342             return FAILURE_ALLOCATION;
01343          if (object || (match && !strcasecmp(match, "object")))
01344             v->object = 1;
01345          ast_variable_append(category, v);
01346       } else if (!strcasecmp(action, "insert")) {
01347          if (ast_strlen_zero(var) || ast_strlen_zero(line))
01348             return UNSPECIFIED_ARGUMENT;
01349          if (!(category = ast_category_get(cfg, cat)))
01350             return UNKNOWN_CATEGORY;
01351          if (!(v = ast_variable_new(var, value, dfn)))
01352             return FAILURE_ALLOCATION;
01353          ast_variable_insert(category, v, line);
01354       }
01355       else {
01356          ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action);
01357          return UNKNOWN_ACTION;
01358       }
01359    }
01360    return 0;
01361 }

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

Referenced by action_getconfigjson().

01184 {
01185    for (; *in; in++) {
01186       if (*in == '\\' || *in == '\"')
01187          *out++ = '\\';
01188       *out++ = *in;
01189    }
01190    *out = '\0';
01191 }

static int manager_displayconnects ( struct mansession_session session  )  [static]

Get displayconnects config option.

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

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

00498 {
00499    struct ast_manager_user *user = NULL;
00500    int ret = 0;
00501 
00502    AST_RWLIST_RDLOCK(&users);
00503    if ((user = get_manager_by_name_locked (session->username)))
00504       ret = user->displayconnects;
00505    AST_RWLIST_UNLOCK(&users);
00506    
00507    return ret;
00508 }

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

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

02662 {
02663    int res;
02664    const char *module = astman_get_header(m, "Module");
02665    const char *id = astman_get_header(m, "ActionID");
02666    char idText[256];
02667 #if !defined(LOW_MEMORY)
02668    const char *version;
02669 #endif
02670    char filename[PATH_MAX];
02671    char *cut;
02672 
02673    ast_copy_string(filename, module, sizeof(filename));
02674    if ((cut = strchr(filename, '.'))) {
02675       *cut = '\0';
02676    } else {
02677       cut = filename + strlen(filename);
02678    }
02679    snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so");
02680    ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename);
02681    res = ast_module_check(filename);
02682    if (!res) {
02683       astman_send_error(s, m, "Module not loaded");
02684       return 0;
02685    }
02686    snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c");
02687    ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename);
02688 #if !defined(LOW_MEMORY)
02689    version = ast_file_version_find(filename);
02690 #endif
02691 
02692    if (!ast_strlen_zero(id))
02693       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
02694    else
02695       idText[0] = '\0';
02696    astman_append(s, "Response: Success\r\n%s", idText);
02697 #if !defined(LOW_MEMORY)
02698    astman_append(s, "Version: %s\r\n\r\n", version ? version : "");
02699 #endif
02700    return 0;
02701 }

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

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

02715 {
02716    int res;
02717    const char *module = astman_get_header(m, "Module");
02718    const char *loadtype = astman_get_header(m, "LoadType");
02719 
02720    if (!loadtype || strlen(loadtype) == 0)
02721       astman_send_error(s, m, "Incomplete ModuleLoad action.");
02722    if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0)
02723       astman_send_error(s, m, "Need module name");
02724 
02725    if (!strcasecmp(loadtype, "load")) {
02726       res = ast_load_resource(module);
02727       if (res)
02728          astman_send_error(s, m, "Could not load module.");
02729       else
02730          astman_send_ack(s, m, "Module loaded.");
02731    } else if (!strcasecmp(loadtype, "unload")) {
02732       res = ast_unload_resource(module, AST_FORCE_SOFT);
02733       if (res)
02734          astman_send_error(s, m, "Could not unload module.");
02735       else
02736          astman_send_ack(s, m, "Module unloaded.");
02737    } else if (!strcasecmp(loadtype, "reload")) {
02738       if (module != NULL) {
02739          res = ast_module_reload(module);
02740          if (res == 0)
02741             astman_send_error(s, m, "No such module.");
02742          else if (res == 1)
02743             astman_send_error(s, m, "Module does not support reload action.");
02744          else
02745             astman_send_ack(s, m, "Module reloaded.");
02746       } else {
02747          ast_module_reload(NULL);   /* Reload all modules */
02748          astman_send_ack(s, m, "All modules reloaded");
02749       }
02750    } else 
02751       astman_send_error(s, m, "Incomplete ModuleLoad action.");
02752    return 0;
02753 }

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

Definition at line 3165 of file manager.c.

References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.

Referenced by __init_manager().

03166 {
03167    /* Notify managers of change */
03168    char hint[512];
03169    ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
03170 
03171    manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state);
03172    return 0;
03173 }

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

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

Referenced by do_message(), and process_message().

02434 {
02435    int ret = 0;
02436 
02437    ast_mutex_lock(&s->session->__lock);
02438    if (s->session->f != NULL) {
02439       struct eventqent *eqe;
02440 
02441       while ( (eqe = NEW_EVENT(s)) ) {
02442          ref_event(eqe);
02443          if (!ret && s->session->authenticated &&
02444              (s->session->readperm & eqe->category) == eqe->category &&
02445              (s->session->send_events & eqe->category) == eqe->category) {
02446             if (send_string(s, eqe->eventdata) < 0)
02447                ret = -1;   /* don't send more */
02448          }
02449          s->session->last_ev = unref_event(s->session->last_ev);
02450       }
02451    }
02452    ast_mutex_unlock(&s->session->__lock);
02453    return ret;
02454 }

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

Definition at line 2768 of file manager.c.

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

Referenced by do_message(), and generic_http_callback().

02769 {
02770    char action[80] = "";
02771    int ret = 0;
02772    struct manager_action *tmp;
02773    const char *user = astman_get_header(m, "Username");
02774 
02775    ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action));
02776    ast_debug(1, "Manager received command '%s'\n", action);
02777 
02778    if (ast_strlen_zero(action)) {
02779       ast_mutex_lock(&s->session->__lock);
02780       astman_send_error(s, m, "Missing action in request");
02781       ast_mutex_unlock(&s->session->__lock);
02782       return 0;
02783    }
02784 
02785    if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) {
02786       ast_mutex_lock(&s->session->__lock);
02787       astman_send_error(s, m, "Permission denied");
02788       ast_mutex_unlock(&s->session->__lock);
02789       return 0;
02790    }
02791 
02792    if (!allowmultiplelogin && !s->session->authenticated && user &&
02793       (!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) {
02794       if (check_manager_session_inuse(user)) {
02795          sleep(1);
02796          ast_mutex_lock(&s->session->__lock);
02797          astman_send_error(s, m, "Login Already In Use");
02798          ast_mutex_unlock(&s->session->__lock);
02799          return -1;
02800       }
02801    }
02802 
02803    AST_RWLIST_RDLOCK(&actions);
02804    AST_RWLIST_TRAVERSE(&actions, tmp, list) {
02805       if (strcasecmp(action, tmp->action))
02806          continue;
02807       if (s->session->writeperm & tmp->authority || tmp->authority == 0)
02808          ret = tmp->func(s, m);
02809       else
02810          astman_send_error(s, m, "Permission denied");
02811       break;
02812    }
02813    AST_RWLIST_UNLOCK(&actions);
02814 
02815    if (!tmp) {
02816       char buf[512];
02817       snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
02818       ast_mutex_lock(&s->session->__lock);
02819       astman_send_error(s, m, buf);
02820       ast_mutex_unlock(&s->session->__lock);
02821    }
02822    if (ret)
02823       return ret;
02824    /* Once done with our message, deliver any pending events */
02825    return process_events(s);
02826 }

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

References ast_free, AST_LIST_FIRST, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and eventqent::usecount.

Referenced by purge_old_stuff().

00343 {
00344    struct eventqent *ev;
00345 
00346    AST_LIST_LOCK(&all_events);
00347    while ( (ev = AST_LIST_FIRST(&all_events)) &&
00348        ev->usecount == 0 && AST_LIST_NEXT(ev, eq_next)) {
00349       AST_LIST_REMOVE_HEAD(&all_events, eq_next);
00350       ast_free(ev);
00351    }
00352    AST_LIST_UNLOCK(&all_events);
00353 }

static void purge_sessions ( int  n_max  )  [static]

remove at most n_max stale session from the list.

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

03014 {
03015    struct mansession_session *session;
03016    time_t now = time(NULL);
03017 
03018    AST_LIST_LOCK(&sessions);
03019    AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, session, list) {
03020       if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) {
03021          AST_LIST_REMOVE_CURRENT(list);
03022          ast_atomic_fetchadd_int(&num_sessions, -1);
03023          if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) {
03024             ast_verb(2, "HTTP Manager '%s' timed out from %s\n",
03025                session->username, ast_inet_ntoa(session->sin.sin_addr));
03026          }
03027          free_session(session);  /* XXX outside ? */
03028          if (--n_max <= 0)
03029             break;
03030       }
03031    }
03032    AST_LIST_TRAVERSE_SAFE_END;
03033    AST_LIST_UNLOCK(&sessions);
03034 }

static void ref_event ( struct eventqent e  )  [static]

Definition at line 818 of file manager.c.

References ast_atomic_fetchadd_int(), and eventqent::usecount.

Referenced by action_waitevent(), and process_events().

00819 {
00820    ast_atomic_fetchadd_int(&e->usecount, 1);
00821 }

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

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

Referenced by astman_append(), and process_events().

00900 {
00901    if (s->f) {
00902       return ast_careful_fwrite(s->f, s->fd, string, strlen(string), s->session->writetimeout);
00903    } else {
00904       return ast_careful_fwrite(s->session->f, s->session->fd, string, strlen(string), s->session->writetimeout);
00905    }
00906 }

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

References mansession_session::__lock, AMI_VERSION, ao2_ref(), ast_atomic_fetchadd_int(), ast_calloc, ast_inet_ntoa(), 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, destroy_session(), do_message(), ast_tcptls_session_instance::f, mansession_session::f, mansession_session::fd, ast_tcptls_session_instance::fd, ast_channel::flags, grab_last(), mansession_session::last_ev, LOG_EVENT, manager_displayconnects(), ast_tcptls_session_instance::requestor, s, mansession_session::send_events, mansession::session, mansession_session::sin, mansession_session::username, mansession_session::waiting_thread, and mansession_session::writetimeout.

02940 {
02941    struct ast_tcptls_session_instance *ser = data;
02942    struct mansession_session *session = ast_calloc(1, sizeof(*session));
02943    struct mansession s = {.session = NULL, };
02944    int flags;
02945    int res;
02946 
02947    if (session == NULL)
02948       goto done;
02949 
02950    session->writetimeout = 100;
02951    session->waiting_thread = AST_PTHREADT_NULL;
02952 
02953    flags = fcntl(ser->fd, F_GETFL);
02954    if (!block_sockets) /* make sure socket is non-blocking */
02955       flags |= O_NONBLOCK;
02956    else
02957       flags &= ~O_NONBLOCK;
02958    fcntl(ser->fd, F_SETFL, flags);
02959 
02960    ast_mutex_init(&session->__lock);
02961    session->send_events = -1;
02962    /* these fields duplicate those in the 'ser' structure */
02963    session->fd = ser->fd;
02964    session->f = ser->f;
02965    session->sin = ser->requestor;
02966 
02967    AST_LIST_LOCK(&sessions);
02968    AST_LIST_INSERT_HEAD(&sessions, session, list);
02969    ast_atomic_fetchadd_int(&num_sessions, 1);
02970    AST_LIST_UNLOCK(&sessions);
02971    /* Hook to the tail of the event queue */
02972    session->last_ev = grab_last();
02973    session->f = ser->f;
02974    s.session = session;
02975    astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION);   /* welcome prompt */
02976    for (;;) {
02977       if ((res = do_message(&s)) < 0)
02978          break;
02979    }
02980    /* session is over, explain why and terminate */
02981    if (session->authenticated) {
02982          if (manager_displayconnects(session))
02983          ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
02984       ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
02985    } else {
02986          if (displayconnects)
02987          ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr));
02988       ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(session->sin.sin_addr));
02989    }
02990 
02991    /* It is possible under certain circumstances for this session thread
02992       to complete its work and exit *before* the thread that created it
02993       has finished executing the ast_pthread_create_background() function.
02994       If this occurs, some versions of glibc appear to act in a buggy
02995       fashion and attempt to write data into memory that it thinks belongs
02996       to the thread but is in fact not owned by the thread (or may have
02997       been freed completely).
02998 
02999       Causing this thread to yield to other threads at least one time
03000       appears to work around this bug.
03001    */
03002    usleep(1);
03003 
03004    destroy_session(session);
03005 
03006 done:
03007    ao2_ref(ser, -1);
03008    ser = NULL;
03009    return NULL;
03010 }

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

01007 {
01008    int maskint = strings_to_mask(eventmask);
01009 
01010    ast_mutex_lock(&s->session->__lock);
01011    if (maskint >= 0)
01012       s->session->send_events = maskint;
01013    ast_mutex_unlock(&s->session->__lock);
01014 
01015    return maskint;
01016 }

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

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

Referenced by set_eventmask().

00442 {
00443    const char *p;
00444 
00445    if (ast_strlen_zero(string))
00446       return -1;
00447 
00448    for (p = string; *p; p++)
00449       if (*p < '0' || *p > '9')
00450          break;
00451    if (!p)  /* all digits */
00452       return atoi(string);
00453    if (ast_false(string))
00454       return 0;
00455    if (ast_true(string)) { /* all permissions */
00456       int x, ret = 0;
00457       for (x = 0; x < ARRAY_LEN(perms); x++)
00458          ret |= perms[x].num;
00459       return ret;
00460    }
00461    return get_perm(string);
00462 }

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

Definition at line 812 of file manager.c.

References ast_atomic_fetchadd_int(), AST_LIST_NEXT, and eventqent::usecount.

Referenced by action_waitevent(), free_session(), and process_events().

00813 {
00814    ast_atomic_fetchadd_int(&e->usecount, -1);
00815    return AST_LIST_NEXT(e, eq_next);
00816 }


Variable Documentation

int allowmultiplelogin = 1 [static]

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

Referenced by astman_append().

int block_sockets [static]

Definition at line 128 of file manager.c.

struct ast_cli_entry cli_manager[] [static]

Definition at line 795 of file manager.c.

Referenced by __init_manager().

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

Referenced by check_blacklist().

int displayconnects = 1 [static]

Definition at line 121 of file manager.c.

int httptimeout = 60 [static]

Definition at line 124 of file manager.c.

int manager_debug [static]

enable some debugging code in the manager

Definition at line 131 of file manager.c.

int manager_enabled = 0 [static]

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

Referenced by __manager_event().

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 2037 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 2481 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 2584 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 2527 of file manager.c.

Referenced by __init_manager().

char mandescr_createconfig[] [static]

Definition at line 1451 of file manager.c.

Referenced by __init_manager().

char mandescr_events[] [static]

Definition at line 1599 of file manager.c.

Referenced by __init_manager().

char mandescr_extensionstate[] [static]

Definition at line 2361 of file manager.c.

Referenced by __init_manager().

char mandescr_getconfig[] [static]

Definition at line 1099 of file manager.c.

Referenced by __init_manager().

char mandescr_getconfigjson[] [static]

Definition at line 1193 of file manager.c.

Referenced by __init_manager().

char mandescr_getvar[] [static]

Definition at line 1725 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 1664 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 1144 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 1577 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 1622 of file manager.c.

Referenced by __init_manager().

char mandescr_mailboxcount[] [static]

Definition at line 2330 of file manager.c.

Referenced by __init_manager().

char mandescr_mailboxstatus[] [static]

Help text for manager command mailboxstatus.

Definition at line 2302 of file manager.c.

Referenced by __init_manager().

char mandescr_modulecheck[] [static]

Definition at line 2651 of file manager.c.

Referenced by __init_manager().

char mandescr_moduleload[] [static]

Definition at line 2703 of file manager.c.

Referenced by __init_manager().

char mandescr_originate[] [static]

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

Referenced by __init_manager().

char mandescr_redirect[] [static]

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

Referenced by __init_manager().

char mandescr_sendtext[] [static]

Definition at line 1875 of file manager.c.

Referenced by __init_manager().

char mandescr_setvar[] [static]

Definition at line 1688 of file manager.c.

Referenced by __init_manager().

char mandescr_timeout[] [static]

Definition at line 2396 of file manager.c.

Referenced by __init_manager().

char mandescr_updateconfig[] [static]

Definition at line 1363 of file manager.c.

Referenced by __init_manager().

char mandescr_userevent[] [static]

Definition at line 2456 of file manager.c.

Referenced by __init_manager().

char mandescr_waitevent[] [static]

Manager WAITEVENT.

Definition at line 1476 of file manager.c.

Referenced by __init_manager().

int num_sessions [static]

Definition at line 129 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 authority_to_str(), get_perm(), and strings_to_mask().

int timestampevents [static]

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

Referenced by action_userevent().

int webmanager_enabled = 0 [static]

Definition at line 126 of file manager.c.

char* words[AST_MAX_CMD_LEN] [inherited]

Definition at line 144 of file manager.c.


Generated on Wed Oct 28 11:46:24 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6