Fri Jul 24 00:42:02 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 GET_HEADER_FIRST_MATCH   0
#define GET_HEADER_LAST_MATCH   1
#define GET_HEADER_SKIP_EMPTY   2
#define MANAGER_EVENT_BUF_INITSIZE   256
#define MAX_BLACKLIST_CMD_LEN   2
 Descriptor for a manager session, either on the AMI socket or over HTTP.
#define MSG_MOREDATA   ((char *)astman_send_response)
 send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field.
#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 const char * __astman_get_header (const struct message *m, char *var, int mode)
static void __init_astman_append_buf (void)
 thread local buffer for astman_append
static void __init_manager_event_buf (void)
static void __init_userevent_buf (void)
int __manager_event (int category, const char *event, const char *file, int line, const char *func, const char *fmt,...)
 manager_event: Send AMI event to client
static int action_atxfer (struct mansession *s, const struct message *m)
static int action_challenge (struct mansession *s, const struct message *m)
static int action_command (struct mansession *s, const struct message *m)
 Manager command "command" - execute CLI command.
static int action_coresettings (struct mansession *s, const struct message *m)
 Show PBX core settings information.
static int action_coreshowchannels (struct mansession *s, const struct message *m)
 Manager command "CoreShowChannels" - List currently defined channels and some information about them.
static int action_corestatus (struct mansession *s, const struct message *m)
 Show PBX core status information.
static int action_createconfig (struct mansession *s, const struct message *m)
static int action_events (struct mansession *s, const struct message *m)
static int action_extensionstate (struct mansession *s, const struct message *m)
static int action_getconfig (struct mansession *s, const struct message *m)
static int action_getconfigjson (struct mansession *s, const struct message *m)
static int action_getvar (struct mansession *s, const struct message *m)
static int action_hangup (struct mansession *s, const struct message *m)
static int action_listcategories (struct mansession *s, const struct message *m)
static int action_listcommands (struct mansession *s, const struct message *m)
static int action_login (struct mansession *s, const struct message *m)
static int action_logoff (struct mansession *s, const struct message *m)
static int action_mailboxcount (struct mansession *s, const struct message *m)
static int action_mailboxstatus (struct mansession *s, const struct message *m)
static int action_originate (struct mansession *s, const struct message *m)
static int action_ping (struct mansession *s, const struct message *m)
static int action_redirect (struct mansession *s, const struct message *m)
 action_redirect: The redirect manager command
static int action_reload (struct mansession *s, const struct message *m)
 Send a reload event.
static int action_sendtext (struct mansession *s, const struct message *m)
static int action_setvar (struct mansession *s, const struct message *m)
static int action_status (struct mansession *s, const struct message *m)
 Manager "status" command to show channels.
static int action_timeout (struct mansession *s, const struct message *m)
static int action_updateconfig (struct mansession *s, const struct message *m)
static int action_userevent (struct mansession *s, const struct message *m)
static int action_waitevent (struct mansession *s, const struct message *m)
static 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 manager command with the manager interface.
void ast_manager_register_hook (struct manager_custom_hook *hook)
 Add a custom hook to be called when an event is fired.
static int ast_manager_register_struct (struct manager_action *act)
int ast_manager_unregister (char *action)
 Unregister a registered manager command.
void ast_manager_unregister_hook (struct manager_custom_hook *hook)
 Delete a custom hook to be called when an event is fired.
void astman_append (struct mansession *s, const char *fmt,...)
const char * astman_get_header (const struct message *m, char *var)
 Get header from mananger transaction.
ast_variableastman_get_variables (const struct message *m)
 Get a linked list of the Variable: headers.
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
 Send ack in manager transaction.
void astman_send_error (struct mansession *s, const struct message *m, char *error)
 Send error in manager transaction.
void astman_send_listack (struct mansession *s, const struct message *m, char *msg, char *listflag)
 Send ack in manager list transaction.
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
 Send response in manager transaction.
static void astman_send_response_full (struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
static void astman_start_ack (struct mansession *s, const struct message *m)
static int authenticate (struct mansession *s, const struct message *m)
static 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 ()
 Check if AMI is enabled.
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_atxfer []
static char mandescr_command []
static char mandescr_coresettings []
static char mandescr_coreshowchannels []
static char mandescr_corestatus []
static char mandescr_createconfig []
static char mandescr_events []
static char mandescr_extensionstate []
static char mandescr_getconfig []
static char mandescr_getconfigjson []
static char mandescr_getvar []
static char mandescr_hangup []
static char mandescr_listcategories []
static char mandescr_listcommands []
static char mandescr_logoff []
static char mandescr_mailboxcount []
static char mandescr_mailboxstatus []
 Help text for manager command mailboxstatus.
static char mandescr_modulecheck []
static char mandescr_moduleload []
static char mandescr_originate []
static char mandescr_ping []
 Manager PING.
static char mandescr_redirect []
static char mandescr_reload []
static char mandescr_sendtext []
static char mandescr_setvar []
static char mandescr_status []
static char mandescr_timeout []
static char mandescr_updateconfig []
static char mandescr_userevent []
static char mandescr_waitevent []
 Manager WAITEVENT.
static int num_sessions
static struct permalias perms []
static int timestampevents
static 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 963 of file manager.c.

Referenced by astman_append().

#define GET_HEADER_FIRST_MATCH   0

Definition at line 866 of file manager.c.

Referenced by astman_get_header().

#define GET_HEADER_LAST_MATCH   1

Definition at line 867 of file manager.c.

Referenced by __astman_get_header().

#define GET_HEADER_SKIP_EMPTY   2

Definition at line 868 of file manager.c.

Referenced by __astman_get_header(), and process_message().

#define MANAGER_EVENT_BUF_INITSIZE   256

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

Referenced by check_blacklist().

#define MSG_MOREDATA   ((char *)astman_send_response)

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

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

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


Function Documentation

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

Definition at line 869 of file manager.c.

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

Referenced by astman_get_header(), and process_message().

00870 {
00871    int x, l = strlen(var);
00872    const char *result = "";
00873 
00874    for (x = 0; x < m->hdrcount; x++) {
00875       const char *h = m->headers[x];
00876       if (!strncasecmp(var, h, l) && h[l] == ':' && h[l+1] == ' ') {
00877          const char *value = h + l + 2;
00878          /* found a potential candidate */
00879          if (mode & GET_HEADER_SKIP_EMPTY && ast_strlen_zero(value))
00880             continue;   /* not interesting */
00881          if (mode & GET_HEADER_LAST_MATCH)
00882             result = value;   /* record the last match so far */
00883          else
00884             return value;
00885       }
00886    }
00887 
00888    return "";
00889 }

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

00969 {

static void __init_manager_event_buf ( void   )  [static]

Definition at line 3259 of file manager.c.

03262 : Send AMI event to client */

static void __init_userevent_buf ( void   )  [static]

Definition at line 960 of file manager.c.

00969 {

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 3263 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, seq, and mansession_session::waiting_thread.

03265 {
03266    struct mansession_session *session;
03267    struct manager_custom_hook *hook;
03268    struct ast_str *auth = ast_str_alloca(80);
03269    const char *cat_str;
03270    va_list ap;
03271    struct timeval now;
03272    struct ast_str *buf;
03273 
03274    /* Abort if there aren't any manager sessions */
03275    if (!num_sessions)
03276       return 0;
03277 
03278    if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE)))
03279       return -1;
03280 
03281    cat_str = authority_to_str(category, &auth);
03282    ast_str_set(&buf, 0,
03283          "Event: %s\r\nPrivilege: %s\r\n",
03284           event, cat_str);
03285 
03286    if (timestampevents) {
03287       now = ast_tvnow();
03288       ast_str_append(&buf, 0,
03289             "Timestamp: %ld.%06lu\r\n",
03290              (long)now.tv_sec, (unsigned long) now.tv_usec);
03291    }
03292    if (manager_debug) {
03293       static int seq;
03294       ast_str_append(&buf, 0,
03295             "SequenceNumber: %d\r\n",
03296              ast_atomic_fetchadd_int(&seq, 1));
03297       ast_str_append(&buf, 0,
03298             "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func);
03299    }
03300 
03301    va_start(ap, fmt);
03302    ast_str_append_va(&buf, 0, fmt, ap);
03303    va_end(ap);
03304 
03305    ast_str_append(&buf, 0, "\r\n");
03306 
03307    append_event(buf->str, category);
03308 
03309    /* Wake up any sleeping sessions */
03310    AST_LIST_LOCK(&sessions);
03311    AST_LIST_TRAVERSE(&sessions, session, list) {
03312       ast_mutex_lock(&session->__lock);
03313       if (session->waiting_thread != AST_PTHREADT_NULL)
03314          pthread_kill(session->waiting_thread, SIGURG);
03315       else
03316          /* We have an event to process, but the mansession is
03317           * not waiting for it. We still need to indicate that there
03318           * is an event waiting so that get_input processes the pending
03319           * event instead of polling.
03320           */
03321          session->pending_event = 1;
03322       ast_mutex_unlock(&session->__lock);
03323    }
03324    AST_LIST_UNLOCK(&sessions);
03325 
03326    AST_RWLIST_RDLOCK(&manager_hooks);
03327    AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
03328       hook->helper(category, event, buf->str);
03329    }
03330    AST_RWLIST_UNLOCK(&manager_hooks);
03331 
03332    return 0;
03333 }

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

Definition at line 2141 of file manager.c.

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

Referenced by __init_manager().

02142 {
02143    const char *name = astman_get_header(m, "Channel");
02144    const char *exten = astman_get_header(m, "Exten");
02145    const char *context = astman_get_header(m, "Context");
02146    struct ast_channel *chan = NULL;
02147    struct ast_call_feature *atxfer_feature = NULL;
02148    char *feature_code = NULL;
02149 
02150    if (ast_strlen_zero(name)) { 
02151       astman_send_error(s, m, "No channel specified");
02152       return 0;
02153    }
02154    if (ast_strlen_zero(exten)) {
02155       astman_send_error(s, m, "No extension specified");
02156       return 0;
02157    }
02158 
02159    if (!(atxfer_feature = ast_find_call_feature("atxfer"))) {
02160       astman_send_error(s, m, "No attended transfer feature found");
02161       return 0;
02162    }
02163 
02164    if (!(chan = ast_get_channel_by_name_locked(name))) {
02165       astman_send_error(s, m, "Channel specified does not exist");
02166       return 0;
02167    }
02168 
02169    if (!ast_strlen_zero(context)) {
02170       pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context);
02171    }
02172 
02173    for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) {
02174       struct ast_frame f = {AST_FRAME_DTMF, *feature_code};
02175       ast_queue_frame(chan, &f);
02176    }
02177 
02178    for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) {
02179       struct ast_frame f = {AST_FRAME_DTMF, *feature_code};
02180       ast_queue_frame(chan, &f);
02181    }
02182 
02183    astman_send_ack(s, m, "Atxfer successfully queued");
02184    ast_channel_unlock(chan);
02185 
02186    return 0;
02187 }

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

Definition at line 1736 of file manager.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and s.

Referenced by __init_manager().

01737 {
01738    const char *authtype = astman_get_header(m, "AuthType");
01739 
01740    if (!strcasecmp(authtype, "MD5")) {
01741       if (ast_strlen_zero(s->session->challenge))
01742          snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
01743       ast_mutex_lock(&s->session->__lock);
01744       astman_start_ack(s, m);
01745       astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
01746       ast_mutex_unlock(&s->session->__lock);
01747    } else {
01748       astman_send_error(s, m, "Must specify AuthType");
01749    }
01750    return 0;
01751 }

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

Manager command "command" - execute CLI command.

Definition at line 2231 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, S_OR, and term_strip().

Referenced by __init_manager().

02232 {
02233    const char *cmd = astman_get_header(m, "Command");
02234    const char *id = astman_get_header(m, "ActionID");
02235    char *buf, *final_buf;
02236    char template[] = "/tmp/ast-ami-XXXXXX";  /* template for temporary file */
02237    int fd = mkstemp(template);
02238    off_t l;
02239 
02240    if (ast_strlen_zero(cmd)) {
02241       astman_send_error(s, m, "No command provided");
02242       return 0;
02243    }
02244 
02245    if (check_blacklist(cmd)) {
02246       astman_send_error(s, m, "Command blacklisted");
02247       return 0;
02248    }
02249 
02250    astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
02251    if (!ast_strlen_zero(id))
02252       astman_append(s, "ActionID: %s\r\n", id);
02253    /* FIXME: Wedge a ActionID response in here, waiting for later changes */
02254    ast_cli_command(fd, cmd);  /* XXX need to change this to use a FILE * */
02255    l = lseek(fd, 0, SEEK_END);   /* how many chars available */
02256 
02257    /* This has a potential to overflow the stack.  Hence, use the heap. */
02258    buf = ast_calloc(1, l + 1);
02259    final_buf = ast_calloc(1, l + 1);
02260    if (buf) {
02261       lseek(fd, 0, SEEK_SET);
02262       if (read(fd, buf, l) < 0) {
02263          ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
02264       }
02265       buf[l] = '\0';
02266       if (final_buf) {
02267          term_strip(final_buf, buf, l);
02268          final_buf[l] = '\0';
02269       }
02270       astman_append(s, "%s", S_OR(final_buf, buf));
02271       ast_free(buf);
02272    }
02273    close(fd);
02274    unlink(template);
02275    astman_append(s, "--END COMMAND--\r\n\r\n");
02276    if (final_buf)
02277       ast_free(final_buf);
02278    return 0;
02279 }

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

Show PBX core settings information.

Definition at line 2679 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, option_maxload, and s.

Referenced by __init_manager().

02680 {
02681    const char *actionid = astman_get_header(m, "ActionID");
02682    char idText[150];
02683 
02684    if (!ast_strlen_zero(actionid))
02685       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
02686    else
02687       idText[0] = '\0';
02688 
02689    astman_append(s, "Response: Success\r\n"
02690          "%s"
02691          "AMIversion: %s\r\n"
02692          "AsteriskVersion: %s\r\n"
02693          "SystemName: %s\r\n"
02694          "CoreMaxCalls: %d\r\n"
02695          "CoreMaxLoadAvg: %f\r\n"
02696          "CoreRunUser: %s\r\n"
02697          "CoreRunGroup: %s\r\n"
02698          "CoreMaxFilehandles: %d\r\n" 
02699          "CoreRealTimeEnabled: %s\r\n"
02700          "CoreCDRenabled: %s\r\n"
02701          "CoreHTTPenabled: %s\r\n"
02702          "\r\n",
02703          idText,
02704          AMI_VERSION,
02705          ast_get_version(), 
02706          ast_config_AST_SYSTEM_NAME,
02707          option_maxcalls,
02708          option_maxload,
02709          ast_config_AST_RUN_USER,
02710          ast_config_AST_RUN_GROUP,
02711          option_maxfiles,
02712          ast_realtime_enabled() ? "Yes" : "No",
02713          check_cdr_enabled() ? "Yes" : "No",
02714          check_webmanager_enabled() ? "Yes" : "No"
02715          );
02716    return 0;
02717 }

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 2784 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, S_OR, ast_cdr::start, and ast_channel::uniqueid.

Referenced by __init_manager().

02785 {
02786    const char *actionid = astman_get_header(m, "ActionID");
02787    char actionidtext[256];
02788    struct ast_channel *c = NULL;
02789    int numchans = 0;
02790    int duration, durh, durm, durs;
02791 
02792    if (!ast_strlen_zero(actionid))
02793       snprintf(actionidtext, sizeof(actionidtext), "ActionID: %s\r\n", actionid);
02794    else
02795       actionidtext[0] = '\0';
02796 
02797    astman_send_listack(s, m, "Channels will follow", "start"); 
02798 
02799    while ((c = ast_channel_walk_locked(c)) != NULL) {
02800       struct ast_channel *bc = ast_bridged_channel(c);
02801       char durbuf[10] = "";
02802 
02803       if (c->cdr && !ast_tvzero(c->cdr->start)) {
02804          duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
02805          durh = duration / 3600;
02806          durm = (duration % 3600) / 60;
02807          durs = duration % 60;
02808          snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
02809       }
02810 
02811       astman_append(s,
02812          "Event: CoreShowChannel\r\n"
02813          "Channel: %s\r\n"
02814          "UniqueID: %s\r\n"
02815          "Context: %s\r\n"
02816          "Extension: %s\r\n"
02817          "Priority: %d\r\n"
02818          "ChannelState: %d\r\n"
02819          "ChannelStateDesc: %s\r\n"
02820          "Application: %s\r\n"
02821          "ApplicationData: %s\r\n"
02822          "CallerIDnum: %s\r\n"
02823          "Duration: %s\r\n"
02824          "AccountCode: %s\r\n"
02825          "BridgedChannel: %s\r\n"
02826          "BridgedUniqueID: %s\r\n"
02827          "\r\n", c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, ast_state2str(c->_state),
02828          c->appl ? c->appl : "", c->data ? S_OR(c->data, ""): "",
02829          S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : "");
02830       ast_channel_unlock(c);
02831       numchans++;
02832    }
02833 
02834    astman_append(s,
02835       "Event: CoreShowChannelsComplete\r\n"
02836       "EventList: Complete\r\n"
02837       "ListItems: %d\r\n"
02838       "%s"
02839       "\r\n", numchans, actionidtext);
02840 
02841    return 0;
02842 }

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

Show PBX core status information.

Definition at line 2725 of file manager.c.

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

Referenced by __init_manager().

02726 {
02727    const char *actionid = astman_get_header(m, "ActionID");
02728    char idText[150];
02729    char startuptime[150];
02730    char reloadtime[150];
02731    struct ast_tm tm;
02732 
02733    if (!ast_strlen_zero(actionid))
02734       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
02735    else
02736       idText[0] = '\0';
02737 
02738    ast_localtime(&ast_startuptime, &tm, NULL);
02739    ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
02740    ast_localtime(&ast_lastreloadtime, &tm, NULL);
02741    ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);
02742 
02743    astman_append(s, "Response: Success\r\n"
02744          "%s"
02745          "CoreStartupTime: %s\r\n"
02746          "CoreReloadTime: %s\r\n"
02747          "CoreCurrentCalls: %d\r\n"
02748          "\r\n",
02749          idText,
02750          startuptime,
02751          reloadtime,
02752          ast_active_channels()
02753          );
02754    return 0;
02755 }

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

Definition at line 1547 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, s, and ast_str::str.

Referenced by __init_manager().

01548 {
01549    int fd;
01550    const char *fn = astman_get_header(m, "Filename");
01551    struct ast_str *filepath = ast_str_alloca(PATH_MAX);
01552    ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR);
01553    ast_str_append(&filepath, 0, "%s", fn);
01554 
01555    if ((fd = open(filepath->str, O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
01556       close(fd);
01557       astman_send_ack(s, m, "New configuration file created successfully");
01558    } else 
01559       astman_send_error(s, m, strerror(errno));
01560 
01561    return 0;
01562 }

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

Definition at line 1696 of file manager.c.

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

Referenced by __init_manager().

01697 {
01698    const char *mask = astman_get_header(m, "EventMask");
01699    int res;
01700 
01701    res = set_eventmask(s, mask);
01702    if (res > 0)
01703       astman_append(s, "Response: Success\r\n"
01704              "Events: On\r\n");
01705    else if (res == 0)
01706       astman_append(s, "Response: Success\r\n"
01707              "Events: Off\r\n");
01708    return 0;
01709 }

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

Definition at line 2561 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(), s, and status.

Referenced by __init_manager().

02562 {
02563    const char *exten = astman_get_header(m, "Exten");
02564    const char *context = astman_get_header(m, "Context");
02565    char hint[256] = "";
02566    int status;
02567    if (ast_strlen_zero(exten)) {
02568       astman_send_error(s, m, "Extension not specified");
02569       return 0;
02570    }
02571    if (ast_strlen_zero(context))
02572       context = "default";
02573    status = ast_extension_state(NULL, context, exten);
02574    ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
02575    astman_start_ack(s, m);
02576    astman_append(s,   "Message: Extension Status\r\n"
02577             "Exten: %s\r\n"
02578             "Context: %s\r\n"
02579             "Hint: %s\r\n"
02580             "Status: %d\r\n\r\n",
02581             exten, context, hint, status);
02582    return 0;
02583 }

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

Definition at line 1151 of file manager.c.

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

Referenced by __init_manager().

01152 {
01153    struct ast_config *cfg;
01154    const char *fn = astman_get_header(m, "Filename");
01155    const char *category = astman_get_header(m, "Category");
01156    int catcount = 0;
01157    int lineno = 0;
01158    char *cur_category = NULL;
01159    struct ast_variable *v;
01160    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
01161 
01162    if (ast_strlen_zero(fn)) {
01163       astman_send_error(s, m, "Filename not specified");
01164       return 0;
01165    }
01166    if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
01167       astman_send_error(s, m, "Config file not found");
01168       return 0;
01169    }
01170 
01171    astman_start_ack(s, m);
01172    while ((cur_category = ast_category_browse(cfg, cur_category))) {
01173       if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) {
01174          lineno = 0;
01175          astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category);
01176          for (v = ast_variable_browse(cfg, cur_category); v; v = v->next)
01177             astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
01178          catcount++;
01179       }
01180    }
01181    if (!ast_strlen_zero(category) && catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */
01182       astman_append(s, "No categories found\r\n");
01183    ast_config_destroy(cfg);
01184    astman_append(s, "\r\n");
01185 
01186    return 0;
01187 }

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

Definition at line 1245 of file manager.c.

References ast_category_browse(), ast_config_load2(), ast_strlen_zero(), ast_variable_browse(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), buf, eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, config_flags, json_escape(), ast_variable::name, ast_variable::next, s, and ast_variable::value.

Referenced by __init_manager().

01246 {
01247    struct ast_config *cfg;
01248    const char *fn = astman_get_header(m, "Filename");
01249    char *category = NULL;
01250    struct ast_variable *v;
01251    int comma1 = 0;
01252    char *buf = NULL;
01253    unsigned int buf_len = 0;
01254    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
01255 
01256    if (ast_strlen_zero(fn)) {
01257       astman_send_error(s, m, "Filename not specified");
01258       return 0;
01259    }
01260 
01261    if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
01262       astman_send_error(s, m, "Config file not found");
01263       return 0;
01264    }
01265 
01266    buf_len = 512;
01267    buf = alloca(buf_len);
01268 
01269    astman_start_ack(s, m);
01270    astman_append(s, "JSON: {");
01271    while ((category = ast_category_browse(cfg, category))) {
01272       int comma2 = 0;
01273       if (buf_len < 2 * strlen(category) + 1) {
01274          buf_len *= 2;
01275          buf = alloca(buf_len);
01276       }
01277       json_escape(buf, category);
01278       astman_append(s, "%s\"%s\":[", comma1 ? "," : "", buf);
01279       if (!comma1)
01280          comma1 = 1;
01281       for (v = ast_variable_browse(cfg, category); v; v = v->next) {
01282          if (comma2)
01283             astman_append(s, ",");
01284          if (buf_len < 2 * strlen(v->name) + 1) {
01285             buf_len *= 2;
01286             buf = alloca(buf_len);
01287          }
01288          json_escape(buf, v->name);
01289          astman_append(s, "\"%s", buf);
01290          if (buf_len < 2 * strlen(v->value) + 1) {
01291             buf_len *= 2;
01292             buf = alloca(buf_len);
01293          }
01294          json_escape(buf, v->value);
01295          astman_append(s, "%s\"", buf);
01296          if (!comma2)
01297             comma2 = 1;
01298       }
01299       astman_append(s, "]");
01300    }
01301    astman_append(s, "}\r\n\r\n");
01302 
01303    ast_config_destroy(cfg);
01304 
01305    return 0;
01306 }

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

Definition at line 1821 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, pbx_retrieve_variable(), and s.

Referenced by __init_manager().

01822 {
01823    struct ast_channel *c = NULL;
01824    const char *name = astman_get_header(m, "Channel");
01825    const char *varname = astman_get_header(m, "Variable");
01826    char *varval;
01827    char workspace[1024] = "";
01828 
01829    if (ast_strlen_zero(varname)) {
01830       astman_send_error(s, m, "No variable specified");
01831       return 0;
01832    }
01833 
01834    if (!ast_strlen_zero(name)) {
01835       c = ast_get_channel_by_name_locked(name);
01836       if (!c) {
01837          astman_send_error(s, m, "No such channel");
01838          return 0;
01839       }
01840    }
01841 
01842    if (varname[strlen(varname) - 1] == ')') {
01843       if (!c) {
01844          c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/manager");
01845          if (c) {
01846             ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
01847             ast_channel_free(c);
01848          } else
01849             ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution.  Function results may be blank.\n");
01850       } else
01851          ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
01852       varval = workspace;
01853    } else {
01854       pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
01855    }
01856 
01857    if (c)
01858       ast_channel_unlock(c);
01859    astman_start_ack(s, m);
01860    astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, varval);
01861 
01862    return 0;
01863 }

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

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

Referenced by __init_manager().

01759 {
01760    struct ast_channel *c = NULL;
01761    const char *name = astman_get_header(m, "Channel");
01762    if (ast_strlen_zero(name)) {
01763       astman_send_error(s, m, "No channel specified");
01764       return 0;
01765    }
01766    c = ast_get_channel_by_name_locked(name);
01767    if (!c) {
01768       astman_send_error(s, m, "No such channel");
01769       return 0;
01770    }
01771    ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
01772    ast_channel_unlock(c);
01773    astman_send_ack(s, m, "Channel Hungup");
01774    return 0;
01775 }

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

Definition at line 1195 of file manager.c.

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

Referenced by __init_manager().

01196 {
01197    struct ast_config *cfg;
01198    const char *fn = astman_get_header(m, "Filename");
01199    char *category = NULL;
01200    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
01201    int catcount = 0;
01202 
01203    if (ast_strlen_zero(fn)) {
01204       astman_send_error(s, m, "Filename not specified");
01205       return 0;
01206    }
01207    if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
01208       astman_send_error(s, m, "Config file not found or file has invalid syntax");
01209       return 0;
01210    }
01211    astman_start_ack(s, m);
01212    while ((category = ast_category_browse(cfg, category))) {
01213       astman_append(s, "Category-%06d: %s\r\n", catcount, category);
01214       catcount++;
01215    }
01216    if (catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */
01217       astman_append(s, "Error: no categories found\r\n");
01218    ast_config_destroy(cfg);
01219    astman_append(s, "\r\n");
01220 
01221    return 0;
01222 }

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 1672 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(), s, and manager_action::synopsis.

Referenced by __init_manager().

01673 {
01674    struct manager_action *cur;
01675    struct ast_str *temp = ast_str_alloca(BUFSIZ); /* XXX very large ? */
01676 
01677    astman_start_ack(s, m);
01678    AST_RWLIST_TRAVERSE(&actions, cur, list) {
01679       if (s->session->writeperm & cur->authority || cur->authority == 0)
01680          astman_append(s, "%s: %s (Priv: %s)\r\n",
01681             cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
01682    }
01683    astman_append(s, "\r\n");
01684 
01685    return 0;
01686 }

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

Definition at line 1721 of file manager.c.

References ast_inet_ntoa(), ast_log(), ast_verb, astman_send_ack(), astman_send_error(), authenticate(), LOG_EVENT, manager_displayconnects(), and s.

Referenced by __init_manager().

01722 {
01723    if (authenticate(s, m)) {
01724       sleep(1);
01725       astman_send_error(s, m, "Authentication failed");
01726       return -1;
01727    }
01728    s->session->authenticated = 1;
01729    if (manager_displayconnects(s->session))
01730       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));
01731    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));
01732    astman_send_ack(s, m, "Authentication accepted");
01733    return 0;
01734 }

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

Definition at line 1715 of file manager.c.

References astman_send_response(), and s.

Referenced by __init_manager().

01716 {
01717    astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
01718    return -1;
01719 }

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

Definition at line 2529 of file manager.c.

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

Referenced by __init_manager().

02530 {
02531    const char *mailbox = astman_get_header(m, "Mailbox");
02532    int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;;
02533 
02534    if (ast_strlen_zero(mailbox)) {
02535       astman_send_error(s, m, "Mailbox not specified");
02536       return 0;
02537    }
02538    ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs);
02539    astman_start_ack(s, m);
02540    astman_append(s,   "Message: Mailbox Message Count\r\n"
02541             "Mailbox: %s\r\n"
02542             "UrgMessages: %d\r\n"
02543             "NewMessages: %d\r\n"
02544             "OldMessages: %d\r\n"
02545             "\r\n",
02546             mailbox, urgentmsgs, newmsgs, oldmsgs);
02547    return 0;
02548 }

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

Definition at line 2500 of file manager.c.

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

Referenced by __init_manager().

02501 {
02502    const char *mailbox = astman_get_header(m, "Mailbox");
02503    int ret;
02504 
02505    if (ast_strlen_zero(mailbox)) {
02506       astman_send_error(s, m, "Mailbox not specified");
02507       return 0;
02508    }
02509    ret = ast_app_has_voicemail(mailbox, NULL);
02510    astman_start_ack(s, m);
02511    astman_append(s, "Message: Mailbox Status\r\n"
02512           "Mailbox: %s\r\n"
02513           "Waiting: %d\r\n\r\n", mailbox, ret);
02514    return 0;
02515 }

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

Definition at line 2363 of file manager.c.

References app, ast_callerid_parse(), ast_calloc, ast_copy_string(), ast_findlabel_extension(), AST_FORMAT_SLINEAR, ast_free, ast_parse_allow_disallow(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pthread_create_detached, ast_shrink_phone_number(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), ast_frame::data, EVENT_FLAG_SYSTEM, fast_originate(), format, s, and strcasestr().

Referenced by __init_manager().

02364 {
02365    const char *name = astman_get_header(m, "Channel");
02366    const char *exten = astman_get_header(m, "Exten");
02367    const char *context = astman_get_header(m, "Context");
02368    const char *priority = astman_get_header(m, "Priority");
02369    const char *timeout = astman_get_header(m, "Timeout");
02370    const char *callerid = astman_get_header(m, "CallerID");
02371    const char *account = astman_get_header(m, "Account");
02372    const char *app = astman_get_header(m, "Application");
02373    const char *appdata = astman_get_header(m, "Data");
02374    const char *async = astman_get_header(m, "Async");
02375    const char *id = astman_get_header(m, "ActionID");
02376    const char *codecs = astman_get_header(m, "Codecs");
02377    struct ast_variable *vars = astman_get_variables(m);
02378    char *tech, *data;
02379    char *l = NULL, *n = NULL;
02380    int pi = 0;
02381    int res;
02382    int to = 30000;
02383    int reason = 0;
02384    char tmp[256];
02385    char tmp2[256];
02386    int format = AST_FORMAT_SLINEAR;
02387 
02388    pthread_t th;
02389    if (ast_strlen_zero(name)) {
02390       astman_send_error(s, m, "Channel not specified");
02391       return 0;
02392    }
02393    if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) {
02394       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
02395          astman_send_error(s, m, "Invalid priority");
02396          return 0;
02397       }
02398    }
02399    if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) {
02400       astman_send_error(s, m, "Invalid timeout");
02401       return 0;
02402    }
02403    ast_copy_string(tmp, name, sizeof(tmp));
02404    tech = tmp;
02405    data = strchr(tmp, '/');
02406    if (!data) {
02407       astman_send_error(s, m, "Invalid channel");
02408       return 0;
02409    }
02410    *data++ = '\0';
02411    ast_copy_string(tmp2, callerid, sizeof(tmp2));
02412    ast_callerid_parse(tmp2, &n, &l);
02413    if (n) {
02414       if (ast_strlen_zero(n))
02415          n = NULL;
02416    }
02417    if (l) {
02418       ast_shrink_phone_number(l);
02419       if (ast_strlen_zero(l))
02420          l = NULL;
02421    }
02422    if (!ast_strlen_zero(codecs)) {
02423       format = 0;
02424       ast_parse_allow_disallow(NULL, &format, codecs, 1);
02425    }
02426    if (ast_true(async)) {
02427       struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast));
02428       if (!fast) {
02429          res = -1;
02430       } else {
02431          if (!ast_strlen_zero(id))
02432             snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s", id);
02433          ast_copy_string(fast->tech, tech, sizeof(fast->tech));
02434             ast_copy_string(fast->data, data, sizeof(fast->data));
02435          ast_copy_string(fast->app, app, sizeof(fast->app));
02436          ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata));
02437          if (l)
02438             ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num));
02439          if (n)
02440             ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name));
02441          fast->vars = vars;
02442          ast_copy_string(fast->context, context, sizeof(fast->context));
02443          ast_copy_string(fast->exten, exten, sizeof(fast->exten));
02444          ast_copy_string(fast->account, account, sizeof(fast->account));
02445          fast->format = format;
02446          fast->timeout = to;
02447          fast->priority = pi;
02448          if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) {
02449             ast_free(fast);
02450             res = -1;
02451          } else {
02452             res = 0;
02453          }
02454       }
02455    } else if (!ast_strlen_zero(app)) {
02456       /* To run the System application (or anything else that goes to shell), you must have the additional System privilege */
02457       if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
02458          && (
02459             strcasestr(app, "system") == 0 || /* System(rm -rf /)
02460                                                  TrySystem(rm -rf /)       */
02461             strcasestr(app, "exec") ||        /* Exec(System(rm -rf /))
02462                                                  TryExec(System(rm -rf /)) */
02463             strcasestr(app, "agi") ||         /* AGI(/bin/rm,-rf /)
02464                                                  EAGI(/bin/rm,-rf /)       */
02465             strstr(appdata, "SHELL") ||       /* NoOp(${SHELL(rm -rf /)})  */
02466             strstr(appdata, "EVAL")           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
02467             )) {
02468          astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have.");
02469          return 0;
02470       }
02471       res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
02472    } else {
02473       if (exten && context && pi)
02474          res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL);
02475       else {
02476          astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
02477          return 0;
02478       }
02479    }
02480    if (!res)
02481       astman_send_ack(s, m, "Originate successfully queued");
02482    else
02483       astman_send_error(s, m, "Originate failed");
02484    return 0;
02485 }

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

Definition at line 1136 of file manager.c.

References astman_append(), and s.

Referenced by __init_manager().

01137 {
01138    astman_append(s, "Response: Success\r\n"
01139       "Ping: Pong\r\n"
01140       "\r\n");
01141    return 0;
01142 }

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

action_redirect: The redirect manager command

Definition at line 2057 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, ast_channel::priority, and s.

Referenced by __init_manager().

02058 {
02059    const char *name = astman_get_header(m, "Channel");
02060    const char *name2 = astman_get_header(m, "ExtraChannel");
02061    const char *exten = astman_get_header(m, "Exten");
02062    const char *context = astman_get_header(m, "Context");
02063    const char *priority = astman_get_header(m, "Priority");
02064    struct ast_channel *chan, *chan2 = NULL;
02065    int pi = 0;
02066    int res;
02067 
02068    if (ast_strlen_zero(name)) {
02069       astman_send_error(s, m, "Channel not specified");
02070       return 0;
02071    }
02072    if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) {
02073       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
02074          astman_send_error(s, m, "Invalid priority");
02075          return 0;
02076       }
02077    }
02078    /* XXX watch out, possible deadlock - we are trying to get two channels!!! */
02079    chan = ast_get_channel_by_name_locked(name);
02080    if (!chan) {
02081       char buf[256];
02082       snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
02083       astman_send_error(s, m, buf);
02084       return 0;
02085    }
02086    if (ast_check_hangup(chan)) {
02087       astman_send_error(s, m, "Redirect failed, channel not up.");
02088       ast_channel_unlock(chan);
02089       return 0;
02090    }
02091    if (!ast_strlen_zero(name2))
02092       chan2 = ast_get_channel_by_name_locked(name2);
02093    if (chan2 && ast_check_hangup(chan2)) {
02094       astman_send_error(s, m, "Redirect failed, extra channel not up.");
02095       ast_channel_unlock(chan);
02096       ast_channel_unlock(chan2);
02097       return 0;
02098    }
02099    if (chan->pbx) {
02100       ast_channel_lock(chan);
02101       ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
02102       ast_channel_unlock(chan);
02103    }
02104    res = ast_async_goto(chan, context, exten, pi);
02105    if (!res) {
02106       if (!ast_strlen_zero(name2)) {
02107          if (chan2) {
02108             if (chan2->pbx) {
02109                ast_channel_lock(chan2);
02110                ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
02111                ast_channel_unlock(chan2);
02112             }
02113             res = ast_async_goto(chan2, context, exten, pi);
02114          } else {
02115             res = -1;
02116          }
02117          if (!res)
02118             astman_send_ack(s, m, "Dual Redirect successful");
02119          else
02120             astman_send_error(s, m, "Secondary redirect failed");
02121       } else
02122          astman_send_ack(s, m, "Redirect successful");
02123    } else
02124       astman_send_error(s, m, "Redirect failed");
02125    if (chan)
02126       ast_channel_unlock(chan);
02127    if (chan2)
02128       ast_channel_unlock(chan2);
02129    return 0;
02130 }

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

Send a reload event.

Definition at line 2764 of file manager.c.

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

Referenced by __init_manager().

02765 {
02766    const char *module = astman_get_header(m, "Module");
02767    int res = ast_module_reload(S_OR(module, NULL));
02768 
02769    if (res == 2)
02770       astman_send_ack(s, m, "Module Reloaded");
02771    else
02772       astman_send_error(s, m, s == 0 ? "No such module" : "Module does not support reload");
02773    return 0;
02774 }

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

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

Referenced by __init_manager().

02013 {
02014    struct ast_channel *c = NULL;
02015    const char *name = astman_get_header(m, "Channel");
02016    const char *textmsg = astman_get_header(m, "Message");
02017    int res = 0;
02018 
02019    if (ast_strlen_zero(name)) {
02020       astman_send_error(s, m, "No channel specified");
02021       return 0;
02022    }
02023 
02024    if (ast_strlen_zero(textmsg)) {
02025       astman_send_error(s, m, "No Message specified");
02026       return 0;
02027    }
02028 
02029    c = ast_get_channel_by_name_locked(name);
02030    if (!c) {
02031       astman_send_error(s, m, "No such channel");
02032       return 0;
02033    }
02034 
02035    res = ast_sendtext(c, textmsg);
02036    ast_channel_unlock(c);
02037    
02038    if (res > 0)
02039       astman_send_ack(s, m, "Success");
02040    else
02041       astman_send_error(s, m, "Failure");
02042    
02043    return res;
02044 }

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

Definition at line 1784 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(), s, and S_OR.

Referenced by __init_manager().

01785 {
01786    struct ast_channel *c = NULL;
01787    const char *name = astman_get_header(m, "Channel");
01788    const char *varname = astman_get_header(m, "Variable");
01789    const char *varval = astman_get_header(m, "Value");
01790 
01791    if (ast_strlen_zero(varname)) {
01792       astman_send_error(s, m, "No variable specified");
01793       return 0;
01794    }
01795 
01796    if (!ast_strlen_zero(name)) {
01797       c = ast_get_channel_by_name_locked(name);
01798       if (!c) {
01799          astman_send_error(s, m, "No such channel");
01800          return 0;
01801       }
01802    }
01803 
01804    pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
01805 
01806    if (c)
01807       ast_channel_unlock(c);
01808 
01809    astman_send_ack(s, m, "Variable Set");
01810 
01811    return 0;
01812 }

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

Manager "status" command to show channels.

Definition at line 1877 of file manager.c.

References AST_APP_ARG, ast_channel_walk_locked(), AST_DECLARE_APP_ARGS, ast_free, ast_func_read(), ast_get_channel_by_name_locked(), AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_create(), ast_str_reset(), ast_strdupa, ast_strlen_zero(), ast_tvnow(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::name, name, pbx_retrieve_variable(), s, S_OR, and str.

Referenced by __init_manager().

01878 {
01879    const char *name = astman_get_header(m, "Channel");
01880    const char *cvariables = astman_get_header(m, "Variables");
01881    char *variables = ast_strdupa(S_OR(cvariables, ""));
01882    struct ast_channel *c;
01883    char bridge[256];
01884    struct timeval now = ast_tvnow();
01885    long elapsed_seconds = 0;
01886    int channels = 0;
01887    int all = ast_strlen_zero(name); /* set if we want all channels */
01888    const char *id = astman_get_header(m, "ActionID");
01889    char idText[256];
01890    AST_DECLARE_APP_ARGS(vars,
01891       AST_APP_ARG(name)[100];
01892    );
01893    struct ast_str *str = ast_str_create(1000);
01894 
01895    if (!ast_strlen_zero(id))
01896       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01897    else
01898       idText[0] = '\0';
01899 
01900    if (all)
01901       c = ast_channel_walk_locked(NULL);
01902    else {
01903       c = ast_get_channel_by_name_locked(name);
01904       if (!c) {
01905          astman_send_error(s, m, "No such channel");
01906          ast_free(str);
01907          return 0;
01908       }
01909    }
01910    astman_send_ack(s, m, "Channel status will follow");
01911 
01912    if (!ast_strlen_zero(cvariables)) {
01913       AST_STANDARD_APP_ARGS(vars, variables);
01914    }
01915 
01916    /* if we look by name, we break after the first iteration */
01917    while (c) {
01918       if (!ast_strlen_zero(cvariables)) {
01919          int i;
01920          ast_str_reset(str);
01921          for (i = 0; i < vars.argc; i++) {
01922             char valbuf[512], *ret = NULL;
01923 
01924             if (vars.name[i][strlen(vars.name[i]) - 1] == ')') {
01925                if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) {
01926                   valbuf[0] = '\0';
01927                }
01928                ret = valbuf;
01929             } else {
01930                pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL);
01931             }
01932 
01933             ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret);
01934          }
01935       }
01936 
01937       channels++;
01938       if (c->_bridge)
01939          snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid);
01940       else
01941          bridge[0] = '\0';
01942       if (c->pbx) {
01943          if (c->cdr) {
01944             elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
01945          }
01946          astman_append(s,
01947          "Event: Status\r\n"
01948          "Privilege: Call\r\n"
01949          "Channel: %s\r\n"
01950          "CallerIDNum: %s\r\n"
01951          "CallerIDName: %s\r\n"
01952          "Accountcode: %s\r\n"
01953          "ChannelState: %d\r\n"
01954          "ChannelStateDesc: %s\r\n"
01955          "Context: %s\r\n"
01956          "Extension: %s\r\n"
01957          "Priority: %d\r\n"
01958          "Seconds: %ld\r\n"
01959          "%s"
01960          "Uniqueid: %s\r\n"
01961          "%s"
01962          "%s"
01963          "\r\n",
01964          c->name,
01965          S_OR(c->cid.cid_num, ""),
01966          S_OR(c->cid.cid_name, ""),
01967          c->accountcode,
01968          c->_state,
01969          ast_state2str(c->_state), c->context,
01970          c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, str->str, idText);
01971       } else {
01972          astman_append(s,
01973          "Event: Status\r\n"
01974          "Privilege: Call\r\n"
01975          "Channel: %s\r\n"
01976          "CallerIDNum: %s\r\n"
01977          "CallerIDName: %s\r\n"
01978          "Account: %s\r\n"
01979          "State: %s\r\n"
01980          "%s"
01981          "Uniqueid: %s\r\n"
01982          "%s"
01983          "%s"
01984          "\r\n",
01985          c->name,
01986          S_OR(c->cid.cid_num, "<unknown>"),
01987          S_OR(c->cid.cid_name, "<unknown>"),
01988          c->accountcode,
01989          ast_state2str(c->_state), bridge, c->uniqueid, str->str, idText);
01990       }
01991       ast_channel_unlock(c);
01992       if (!all)
01993          break;
01994       c = ast_channel_walk_locked(c);
01995    }
01996    astman_append(s,
01997    "Event: StatusComplete\r\n"
01998    "%s"
01999    "Items: %d\r\n"
02000    "\r\n", idText, channels);
02001    ast_free(str);
02002    return 0;
02003 }

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

Definition at line 2592 of file manager.c.

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

Referenced by __init_manager().

02593 {
02594    struct ast_channel *c;
02595    const char *name = astman_get_header(m, "Channel");
02596    double timeout = atof(astman_get_header(m, "Timeout"));
02597    struct timeval when = { timeout, 0 };
02598 
02599    if (ast_strlen_zero(name)) {
02600       astman_send_error(s, m, "No channel specified");
02601       return 0;
02602    }
02603    if (!timeout || timeout < 0) {
02604       astman_send_error(s, m, "No timeout specified");
02605       return 0;
02606    }
02607    c = ast_get_channel_by_name_locked(name);
02608    if (!c) {
02609       astman_send_error(s, m, "No such channel");
02610       return 0;
02611    }
02612 
02613    when.tv_usec = (timeout - when.tv_sec) * 1000000.0;
02614    ast_channel_setwhentohangup_tv(c, when);
02615    ast_channel_unlock(c);
02616    astman_send_ack(s, m, "Timeout Set");
02617    return 0;
02618 }

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

Definition at line 1466 of file manager.c.

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

Referenced by __init_manager().

01467 {
01468    struct ast_config *cfg;
01469    const char *sfn = astman_get_header(m, "SrcFilename");
01470    const char *dfn = astman_get_header(m, "DstFilename");
01471    int res;
01472    const char *rld = astman_get_header(m, "Reload");
01473    struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
01474    enum error_type result;
01475 
01476    if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
01477       astman_send_error(s, m, "Filename not specified");
01478       return 0;
01479    }
01480    if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) {
01481       astman_send_error(s, m, "Config file not found");
01482       return 0;
01483    }
01484    result = handle_updates(s, m, cfg, dfn);
01485    if (!result) {
01486       ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
01487       res = config_text_file_save(dfn, cfg, "Manager");
01488       ast_config_destroy(cfg);
01489       if (res) {
01490          astman_send_error(s, m, "Save of config failed");
01491          return 0;
01492       }
01493       astman_send_ack(s, m, NULL);
01494       if (!ast_strlen_zero(rld)) {
01495          if (ast_true(rld))
01496             rld = NULL;
01497          ast_module_reload(rld);
01498       }
01499    } else {
01500       ast_config_destroy(cfg);
01501       switch(result) {
01502       case UNKNOWN_ACTION:
01503          astman_send_error(s, m, "Unknown action command");
01504          break;
01505       case UNKNOWN_CATEGORY:
01506          astman_send_error(s, m, "Given category does not exist");
01507          break;
01508       case UNSPECIFIED_CATEGORY:
01509          astman_send_error(s, m, "Category not specified");
01510          break;
01511       case UNSPECIFIED_ARGUMENT:
01512          astman_send_error(s, m, "Problem with category, value, or line (if required)");
01513          break;
01514       case FAILURE_ALLOCATION:
01515          astman_send_error(s, m, "Memory allocation failure, this should not happen");
01516          break;
01517       case FAILURE_NEWCAT:
01518          astman_send_error(s, m, "Create category did not complete successfully");
01519          break;
01520       case FAILURE_DELCAT:
01521          astman_send_error(s, m, "Delete category did not complete successfully");
01522          break;
01523       case FAILURE_EMPTYCAT:
01524          astman_send_error(s, m, "Empty category did not complete successfully");
01525          break;
01526       case FAILURE_UPDATE:
01527          astman_send_error(s, m, "Update did not complete successfully");
01528          break;
01529       case FAILURE_DELETE:
01530          astman_send_error(s, m, "Delete did not complete successfully");
01531          break;
01532       case FAILURE_APPEND:
01533          astman_send_error(s, m, "Append did not complete successfully");
01534          break;
01535       }
01536    }
01537    return 0;
01538 }

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

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

02656 {
02657    const char *event = astman_get_header(m, "UserEvent");
02658    struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
02659    int x;
02660 
02661    ast_str_reset(body);
02662 
02663    for (x = 0; x < m->hdrcount; x++) {
02664       if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
02665          ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
02666       }
02667    }
02668 
02669    manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body->str);
02670    return 0;
02671 }

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

Definition at line 1572 of file manager.c.

References ast_debug, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_strlen_zero(), ast_wait_for_input(), astman_get_header(), NEW_EVENT, and s.

Referenced by __init_manager().

01573 {
01574    const char *timeouts = astman_get_header(m, "Timeout");
01575    int timeout = -1;
01576    int x;
01577    int needexit = 0;
01578    const char *id = astman_get_header(m, "ActionID");
01579    char idText[256];
01580 
01581    if (!ast_strlen_zero(id))
01582       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01583    else
01584       idText[0] = '\0';
01585 
01586    if (!ast_strlen_zero(timeouts)) {
01587       sscanf(timeouts, "%i", &timeout);
01588       if (timeout < -1)
01589          timeout = -1;
01590       /* XXX maybe put an upper bound, or prevent the use of 0 ? */
01591    }
01592 
01593    ast_mutex_lock(&s->session->__lock);
01594    if (s->session->waiting_thread != AST_PTHREADT_NULL)
01595       pthread_kill(s->session->waiting_thread, SIGURG);
01596 
01597    if (s->session->managerid) { /* AMI-over-HTTP session */
01598       /*
01599        * Make sure the timeout is within the expire time of the session,
01600        * as the client will likely abort the request if it does not see
01601        * data coming after some amount of time.
01602        */
01603       time_t now = time(NULL);
01604       int max = s->session->sessiontimeout - now - 10;
01605 
01606       if (max < 0)   /* We are already late. Strange but possible. */
01607          max = 0;
01608       if (timeout < 0 || timeout > max)
01609          timeout = max;
01610       if (!s->session->send_events) /* make sure we record events */
01611          s->session->send_events = -1;
01612    }
01613    ast_mutex_unlock(&s->session->__lock);
01614 
01615    /* XXX should this go inside the lock ? */
01616    s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
01617    ast_debug(1, "Starting waiting for an event!\n");
01618 
01619    for (x = 0; x < timeout || timeout < 0; x++) {
01620       ast_mutex_lock(&s->session->__lock);
01621       if (NEW_EVENT(s))
01622          needexit = 1;
01623       /* We can have multiple HTTP session point to the same mansession entry.
01624        * The way we deal with it is not very nice: newcomers kick out the previous
01625        * HTTP session. XXX this needs to be improved.
01626        */
01627       if (s->session->waiting_thread != pthread_self())
01628          needexit = 1;
01629       if (s->session->needdestroy)
01630          needexit = 1;
01631       ast_mutex_unlock(&s->session->__lock);
01632       if (needexit)
01633          break;
01634       if (s->session->managerid == 0) {   /* AMI session */
01635          if (ast_wait_for_input(s->session->fd, 1000))
01636             break;
01637       } else { /* HTTP session */
01638          sleep(1);
01639       }
01640    }
01641    ast_debug(1, "Finished waiting for an event!\n");
01642    ast_mutex_lock(&s->session->__lock);
01643    if (s->session->waiting_thread == pthread_self()) {
01644       struct eventqent *eqe;
01645       astman_send_response(s, m, "Success", "Waiting for Event completed.");
01646       while ( (eqe = NEW_EVENT(s)) ) {
01647          ref_event(eqe);
01648          if (((s->session->readperm & eqe->category) == eqe->category) &&
01649              ((s->session->send_events & eqe->category) == eqe->category)) {
01650             astman_append(s, "%s", eqe->eventdata);
01651          }
01652          s->session->last_ev = unref_event(s->session->last_ev);
01653       }
01654       astman_append(s,
01655          "Event: WaitEventComplete\r\n"
01656          "%s"
01657          "\r\n", idText);
01658       s->session->waiting_thread = AST_PTHREADT_NULL;
01659    } else {
01660       ast_debug(1, "Abandoning event request!\n");
01661    }
01662    ast_mutex_unlock(&s->session->__lock);
01663    return 0;
01664 }

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

Definition at line 3236 of file manager.c.

References ast_atomic_fetchadd_int(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_UNLOCK, ast_malloc, and seq.

Referenced by __init_manager(), and __manager_event().

03237 {
03238    struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
03239    static int seq;   /* sequence number */
03240 
03241    if (!tmp)
03242       return -1;
03243 
03244    /* need to init all fields, because ast_malloc() does not */
03245    tmp->usecount = 0;
03246    tmp->category = category;
03247    tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
03248    AST_LIST_NEXT(tmp, eq_next) = NULL;
03249    strcpy(tmp->eventdata, str);
03250 
03251    AST_LIST_LOCK(&all_events);
03252    AST_LIST_INSERT_TAIL(&all_events, tmp, eq_next);
03253    AST_LIST_UNLOCK(&all_events);
03254 
03255    return 0;
03256 }

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

References eventqent::next.

Referenced by get_perm().

00414 {
00415    const char *val = bigstr, *next;
00416 
00417    do {
00418       if ((next = strchr(val, delim))) {
00419          if (!strncmp(val, smallstr, (next - val)))
00420             return 1;
00421          else
00422             continue;
00423       } else
00424          return !strcmp(smallstr, val);
00425    } while (*(val = (next + 1)));
00426 
00427    return 0;
00428 }

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

Register a manager command with the manager interface.

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

Definition at line 3407 of file manager.c.

References ast_calloc, ast_free, and ast_manager_register_struct().

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

03408 {
03409    struct manager_action *cur = NULL;
03410 
03411    if (!(cur = ast_calloc(1, sizeof(*cur))))
03412       return -1;
03413 
03414    cur->action = action;
03415    cur->authority = auth;
03416    cur->func = func;
03417    cur->synopsis = synopsis;
03418    cur->description = description;
03419 
03420    if (ast_manager_register_struct(cur)) {
03421       ast_free(cur);
03422       return -1;
03423    }
03424 
03425    return 0;
03426 }

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

References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

00257 {
00258    AST_RWLIST_WRLOCK(&manager_hooks);
00259    AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list);
00260    AST_RWLIST_UNLOCK(&manager_hooks);
00261    return;
00262 }

static int ast_manager_register_struct ( struct manager_action act  )  [static]

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

03372 {
03373    struct manager_action *cur, *prev = NULL;
03374    struct timespec tv = { 5, };
03375 
03376    if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) {
03377       ast_log(LOG_ERROR, "Could not obtain lock on manager list\n");
03378       return -1;
03379    }
03380    AST_RWLIST_TRAVERSE(&actions, cur, list) {
03381       int ret = strcasecmp(cur->action, act->action);
03382       if (ret == 0) {
03383          ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
03384          AST_RWLIST_UNLOCK(&actions);
03385          return -1;
03386       }
03387       if (ret > 0) { /* Insert these alphabetically */
03388          prev = cur;
03389          break;
03390       }
03391    }
03392 
03393    if (prev)
03394       AST_RWLIST_INSERT_AFTER(&actions, prev, act, list);
03395    else
03396       AST_RWLIST_INSERT_HEAD(&actions, act, list);
03397 
03398    ast_verb(2, "Manager registered action %s\n", act->action);
03399 
03400    AST_RWLIST_UNLOCK(&actions);
03401 
03402    return 0;
03403 }

int ast_manager_unregister ( char *  action  ) 

Unregister a registered manager command.

Parameters:
action Name of registered Action:

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

03339 {
03340    struct manager_action *cur;
03341    struct timespec tv = { 5, };
03342 
03343    if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) {
03344       ast_log(LOG_ERROR, "Could not obtain lock on manager list\n");
03345       return -1;
03346    }
03347    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) {
03348       if (!strcasecmp(action, cur->action)) {
03349          AST_RWLIST_REMOVE_CURRENT(list);
03350          ast_free(cur);
03351          ast_verb(2, "Manager unregistered action %s\n", action);
03352          break;
03353       }
03354    }
03355    AST_RWLIST_TRAVERSE_SAFE_END;
03356    AST_RWLIST_UNLOCK(&actions);
03357 
03358    return 0;
03359 }

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

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

00266 {
00267    AST_RWLIST_WRLOCK(&manager_hooks);
00268    AST_RWLIST_REMOVE(&manager_hooks, hook, list);
00269    AST_RWLIST_UNLOCK(&manager_hooks);
00270    return;
00271 }

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

utility functions for creating AMI replies

Definition at line 968 of file manager.c.

References ast_str_set_va(), ast_str_thread_get(), ast_verbose, astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE, buf, s, and send_string().

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(), 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_rpt_local_nodes(), manager_rpt_status(), manager_show_dialplan_helper(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), rpt_manager_do_stats(), rpt_manager_success(), and session_do().

00969 {
00970    va_list ap;
00971    struct ast_str *buf;
00972 
00973    if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE)))
00974       return;
00975 
00976    va_start(ap, fmt);
00977    ast_str_set_va(&buf, 0, fmt, ap);
00978    va_end(ap);
00979 
00980    if (s->f != NULL || s->session->f != NULL) {
00981       send_string(s, buf->str);
00982    } else {
00983       ast_verbose("fd == -1 in astman_append, should not happen\n");
00984    }
00985 }

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

Get header from mananger transaction.

Definition at line 896 of file manager.c.

References __astman_get_header(), and GET_HEADER_FIRST_MATCH.

Referenced by _sip_show_peer(), _sip_show_peers(), action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_atxfer(), action_bridge(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), action_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_rpt_status(), manager_show_dialplan(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), meetmemute(), process_message(), rpt_manager_do_stats(), rpt_manager_success(), start_monitor_action(), and stop_monitor_action().

00897 {
00898    return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH);
00899 }

struct ast_variable* astman_get_variables ( const struct message m  ) 

Get a linked list of the Variable: headers.

Definition at line 902 of file manager.c.

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

Referenced by action_originate(), and manager_sipnotify().

00903 {
00904    int varlen, x, y;
00905    struct ast_variable *head = NULL, *cur;
00906 
00907    AST_DECLARE_APP_ARGS(args,
00908       AST_APP_ARG(vars)[32];
00909    );
00910 
00911    varlen = strlen("Variable: ");
00912 
00913    for (x = 0; x < m->hdrcount; x++) {
00914       char *parse, *var, *val;
00915 
00916       if (strncasecmp("Variable: ", m->headers[x], varlen))
00917          continue;
00918       parse = ast_strdupa(m->headers[x] + varlen);
00919 
00920       AST_STANDARD_APP_ARGS(args, parse);
00921       if (!args.argc)
00922          continue;
00923       for (y = 0; y < args.argc; y++) {
00924          if (!args.vars[y])
00925             continue;
00926          var = val = ast_strdupa(args.vars[y]);
00927          strsep(&val, "=");
00928          if (!val || ast_strlen_zero(var))
00929             continue;
00930          cur = ast_variable_new(var, val, "");
00931          cur->next = head;
00932          head = cur;
00933       }
00934    }
00935 
00936    return head;
00937 }

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

Send ack in manager transaction.

Definition at line 1031 of file manager.c.

References astman_send_response_full(), and s.

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

01032 {
01033    astman_send_response_full(s, m, "Success", msg, NULL);
01034 }

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

Send error in manager transaction.

Definition at line 1026 of file manager.c.

References astman_send_response_full(), and s.

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

01027 {
01028    astman_send_response_full(s, m, "Error", error, NULL);
01029 }

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

Send ack in manager list transaction.

Definition at line 1041 of file manager.c.

References astman_send_response_full(), and s.

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

01042 {
01043    astman_send_response_full(s, m, "Success", msg, listflag);
01044 }

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

Send response in manager transaction.

Definition at line 1021 of file manager.c.

References astman_send_response_full(), and s.

Referenced by action_logoff().

01022 {
01023    astman_send_response_full(s, m, resp, msg, NULL);
01024 }

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

Definition at line 1004 of file manager.c.

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

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

01005 {
01006    const char *id = astman_get_header(m, "ActionID");
01007 
01008    astman_append(s, "Response: %s\r\n", resp);
01009    if (!ast_strlen_zero(id))
01010       astman_append(s, "ActionID: %s\r\n", id);
01011    if (listflag)
01012       astman_append(s, "Eventlist: %s\r\n", listflag);   /* Start, complete, cancelled */
01013    if (msg == MSG_MOREDATA)
01014       return;
01015    else if (msg)
01016       astman_append(s, "Message: %s\r\n\r\n", msg);
01017    else
01018       astman_append(s, "\r\n");
01019 }

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

Definition at line 1036 of file manager.c.

References astman_send_response_full(), MSG_MOREDATA, and s.

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

01037 {
01038    astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL);
01039 }

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

Definition at line 1070 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(), get_manager_by_name_locked(), len(), LOG_NOTICE, md5(), MD5Final(), MD5Init(), MD5Update(), s, S_OR, set_eventmask(), and user.

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

01071 {
01072    const char *username = astman_get_header(m, "Username");
01073    const char *password = astman_get_header(m, "Secret");
01074    int error = -1;
01075    struct ast_manager_user *user = NULL;
01076 
01077    if (ast_strlen_zero(username))   /* missing username */
01078       return -1;
01079 
01080    /* locate user in locked state */
01081    AST_RWLIST_WRLOCK(&users);
01082 
01083    if (!(user = get_manager_by_name_locked(username))) {
01084       ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
01085    } else if (user->ha && !ast_apply_ha(user->ha, &(s->session->sin))) {
01086       ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
01087    } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
01088       const char *key = astman_get_header(m, "Key");
01089       if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
01090          int x;
01091          int len = 0;
01092          char md5key[256] = "";
01093          struct MD5Context md5;
01094          unsigned char digest[16];
01095 
01096          MD5Init(&md5);
01097          MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
01098          MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
01099          MD5Final(digest, &md5);
01100          for (x = 0; x < 16; x++)
01101             len += sprintf(md5key + len, "%2.2x", digest[x]);
01102          if (!strcmp(md5key, key))
01103             error = 0;
01104       } else {
01105          ast_debug(1, "MD5 authentication is not possible.  challenge: '%s'\n", 
01106             S_OR(s->session->challenge, ""));
01107       }
01108    } else if (password && user->secret && !strcmp(password, user->secret))
01109       error = 0;
01110 
01111    if (error) {
01112       ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
01113       AST_RWLIST_UNLOCK(&users);
01114       return -1;
01115    }
01116 
01117    /* auth complete */
01118    
01119    ast_copy_string(s->session->username, username, sizeof(s->session->username));
01120    s->session->readperm = user->readperm;
01121    s->session->writeperm = user->writeperm;
01122    s->session->writetimeout = user->writetimeout;
01123    s->session->sessionstart = time(NULL);
01124    set_eventmask(s, astman_get_header(m, "Events"));
01125    
01126    AST_RWLIST_UNLOCK(&users);
01127    return 0;
01128 }

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

Convert authority code to a list of options.

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

00390 {
00391    int i;
00392    char *sep = "";
00393 
00394    (*res)->used = 0;
00395    for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
00396       if (authority & perms[i].num) {
00397          ast_str_append(res, 0, "%s%s", sep, perms[i].label);
00398          sep = ",";
00399       }
00400    }
00401 
00402    if ((*res)->used == 0)  /* replace empty string with something sensible */
00403       ast_str_append(res, 0, "<none>");
00404 
00405    return (*res)->str;
00406 }

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

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

02190 {
02191    char *cmd_copy, *cur_cmd;
02192    char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, };
02193    int i;
02194 
02195    cmd_copy = ast_strdupa(cmd);
02196    for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) {
02197       cur_cmd = ast_strip(cur_cmd);
02198       if (ast_strlen_zero(cur_cmd)) {
02199          i--;
02200          continue;
02201       }
02202 
02203       cmd_words[i] = cur_cmd;
02204    }
02205 
02206    for (i = 0; i < ARRAY_LEN(command_blacklist); i++) {
02207       int j, match = 1;
02208 
02209       for (j = 0; command_blacklist[i].words[j]; j++) {
02210          if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) {
02211             match = 0;
02212             break;
02213          }
02214       }
02215 
02216       if (match) {
02217          return 1;
02218       }
02219    }
02220 
02221    return 0;
02222 }

int check_manager_enabled ( void   ) 

Check if AMI is enabled.

Definition at line 316 of file manager.c.

Referenced by handle_show_settings().

00317 {
00318    return manager_enabled;
00319 }

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

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

00473 {
00474    struct mansession_session *session = NULL;
00475 
00476    AST_LIST_LOCK(&sessions);
00477    AST_LIST_TRAVERSE(&sessions, session, list) {
00478       if (!strcasecmp(session->username, name)) 
00479          break;
00480    }
00481    AST_LIST_UNLOCK(&sessions);
00482 
00483    return session ? 1 : 0;
00484 }

int check_webmanager_enabled ( void   ) 

Check if AMI/HTTP is enabled.

Definition at line 321 of file manager.c.

Referenced by action_coresettings(), and handle_show_settings().

00322 {
00323    return (webmanager_enabled && manager_enabled);
00324 }

static void destroy_session ( struct mansession_session session  )  [static]

Definition at line 851 of file manager.c.

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

Referenced by accept_thread(), and skinny_session().

00852 {
00853    AST_LIST_LOCK(&sessions);
00854    AST_LIST_REMOVE(&sessions, session, list);
00855    ast_atomic_fetchadd_int(&num_sessions, -1);
00856    free_session(session);
00857    AST_LIST_UNLOCK(&sessions);
00858 }

static int do_message ( struct mansession s  )  [static]

Definition at line 3100 of file manager.c.

References AST_MAX_MANHEADERS, ast_strdupa, ast_strlen_zero(), get_input(), message::hdrcount, message::headers, process_events(), process_message(), and s.

Referenced by session_do().

03101 {
03102    struct message m = { 0 };
03103    char header_buf[sizeof(s->session->inbuf)] = { '\0' };
03104    int res;
03105 
03106    for (;;) {
03107       /* Check if any events are pending and do them if needed */
03108       if (process_events(s))
03109          return -1;
03110       res = get_input(s, header_buf);
03111       if (res == 0) {
03112          continue;
03113       } else if (res > 0) {
03114          if (ast_strlen_zero(header_buf))
03115             return process_message(s, &m) ? -1 : 0;
03116          else if (m.hdrcount < (AST_MAX_MANHEADERS - 1))
03117             m.headers[m.hdrcount++] = ast_strdupa(header_buf);
03118       } else {
03119          return res;
03120       }
03121    }
03122 }

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

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

02301 {
02302    struct fast_originate_helper *in = data;
02303    int res;
02304    int reason = 0;
02305    struct ast_channel *chan = NULL;
02306    char requested_channel[AST_CHANNEL_NAME];
02307 
02308    if (!ast_strlen_zero(in->app)) {
02309       res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1,
02310          S_OR(in->cid_num, NULL),
02311          S_OR(in->cid_name, NULL),
02312          in->vars, in->account, &chan);
02313    } else {
02314       res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1,
02315          S_OR(in->cid_num, NULL),
02316          S_OR(in->cid_name, NULL),
02317          in->vars, in->account, &chan);
02318    }
02319 
02320    if (!chan)
02321       snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);   
02322    /* Tell the manager what happened with the channel */
02323    manager_event(EVENT_FLAG_CALL, "OriginateResponse",
02324       "%s%s"
02325       "Response: %s\r\n"
02326       "Channel: %s\r\n"
02327       "Context: %s\r\n"
02328       "Exten: %s\r\n"
02329       "Reason: %d\r\n"
02330       "Uniqueid: %s\r\n"
02331       "CallerIDNum: %s\r\n"
02332       "CallerIDName: %s\r\n",
02333       in->idtext, ast_strlen_zero(in->idtext) ? "" : "\r\n", res ? "Failure" : "Success", 
02334       chan ? chan->name : requested_channel, in->context, in->exten, reason, 
02335       chan ? chan->uniqueid : "<null>",
02336       S_OR(in->cid_num, "<unknown>"),
02337       S_OR(in->cid_name, "<unknown>")
02338       );
02339 
02340    /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
02341    if (chan)
02342       ast_channel_unlock(chan);
02343    ast_free(in);
02344    return NULL;
02345 }

static void free_session ( struct mansession_session session  )  [static]

Definition at line 833 of file manager.c.

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

Referenced by destroy_session(), and purge_sessions().

00834 {
00835    struct eventqent *eqe = session->last_ev;
00836    struct ast_datastore *datastore;
00837 
00838    /* Get rid of each of the data stores on the session */
00839    while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) {
00840       /* Free the data store */
00841       ast_datastore_free(datastore);
00842    }
00843 
00844    if (session->f != NULL)
00845       fclose(session->f);
00846    ast_mutex_destroy(&session->__lock);
00847    ast_free(session);
00848    unref_event(eqe);
00849 }

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

References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_wait_for_input(), errno, LOG_WARNING, s, and ast_frame::src.

Referenced by do_message(), and skinny_session().

03031 {
03032    int res, x;
03033    int maxlen = sizeof(s->session->inbuf) - 1;
03034    char *src = s->session->inbuf;
03035 
03036    /*
03037     * Look for \r\n within the buffer. If found, copy to the output
03038     * buffer and return, trimming the \r\n (not used afterwards).
03039     */
03040    for (x = 0; x < s->session->inlen; x++) {
03041       int cr;  /* set if we have \r */
03042       if (src[x] == '\r' && x+1 < s->session->inlen && src[x+1] == '\n')
03043          cr = 2;  /* Found. Update length to include \r\n */
03044       else if (src[x] == '\n')
03045          cr = 1;  /* also accept \n only */
03046       else
03047          continue;
03048       memmove(output, src, x);   /*... but trim \r\n */
03049       output[x] = '\0';    /* terminate the string */
03050       x += cr;       /* number of bytes used */
03051       s->session->inlen -= x;       /* remaining size */
03052       memmove(src, src + x, s->session->inlen); /* remove used bytes */
03053       return 1;
03054    }
03055    if (s->session->inlen >= maxlen) {
03056       /* no crlf found, and buffer full - sorry, too long for us */
03057       ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src);
03058       s->session->inlen = 0;
03059    }
03060    res = 0;
03061    while (res == 0) {
03062       /* XXX do we really need this locking ? */
03063       ast_mutex_lock(&s->session->__lock);
03064       if (s->session->pending_event) {
03065          s->session->pending_event = 0;
03066          ast_mutex_unlock(&s->session->__lock);
03067          return 0;
03068       }
03069       s->session->waiting_thread = pthread_self();
03070       ast_mutex_unlock(&s->session->__lock);
03071 
03072       res = ast_wait_for_input(s->session->fd, -1);   /* return 0 on timeout ? */
03073 
03074       ast_mutex_lock(&s->session->__lock);
03075       s->session->waiting_thread = AST_PTHREADT_NULL;
03076       ast_mutex_unlock(&s->session->__lock);
03077    }
03078    if (res < 0) {
03079       /* If we get a signal from some other thread (typically because
03080        * there are new events queued), return 0 to notify the caller.
03081        */
03082       if (errno == EINTR || errno == EAGAIN)
03083          return 0;
03084       ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
03085       return -1;
03086    }
03087    ast_mutex_lock(&s->session->__lock);
03088    res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f);
03089    if (res < 1)
03090       res = -1;   /* error return */
03091    else {
03092       s->session->inlen += res;
03093       src[s->session->inlen] = '\0';
03094       res = 0;
03095    }
03096    ast_mutex_unlock(&s->session->__lock);
03097    return res;
03098 }

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

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

Definition at line 491 of file manager.c.

References AST_RWLIST_TRAVERSE, ast_manager_user::list, and user.

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

00492 {
00493    struct ast_manager_user *user = NULL;
00494 
00495    AST_RWLIST_TRAVERSE(&users, user, list)
00496       if (!strcasecmp(user->username, name))
00497          break;
00498    return user;
00499 }

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

Definition at line 430 of file manager.c.

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

Referenced by strings_to_mask().

00431 {
00432    int x = 0, ret = 0;
00433 
00434    if (!instr)
00435       return 0;
00436 
00437    for (x = 0; x < ARRAY_LEN(perms); x++) {
00438       if (ast_instring(instr, perms[x].label, ','))
00439          ret |= perms[x].num;
00440    }
00441 
00442    return ret;
00443 }

static struct eventqent* grab_last ( void   )  [static]

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

Definition at line 330 of file manager.c.

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

Referenced by session_do().

00331 {
00332    struct eventqent *ret;
00333 
00334    AST_LIST_LOCK(&all_events);
00335    ret = AST_LIST_LAST(&all_events);
00336    /* the list is never empty now, but may become so when
00337     * we optimize it in the future, so be prepared.
00338     */
00339    if (ret)
00340       ast_atomic_fetchadd_int(&ret->usecount, 1);
00341    AST_LIST_UNLOCK(&all_events);
00342    return ret;
00343 }

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

00784 {
00785    switch (cmd) {
00786    case CLI_INIT:
00787       e->command = "manager reload";
00788       e->usage =
00789          "Usage: manager reload\n"
00790          "       Reloads the manager configuration.\n";
00791       return NULL;
00792    case CLI_GENERATE:
00793       return NULL;
00794    }
00795    if (a->argc > 2)
00796       return CLI_SHOWUSAGE;
00797    reload_manager();
00798    return CLI_SUCCESS;
00799 }

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

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

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

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

Definition at line 587 of file manager.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_manager_by_name_locked(), ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, user, and ast_cli_args::word.

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

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

Definition at line 650 of file manager.c.

References ast_cli_args::argc, ast_cli(), AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_manager_user::list, ast_cli_entry::usage, and user.

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

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

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

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

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

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

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

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

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

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, eventqent::eq_next, ast_cli_args::fd, s, and ast_cli_entry::usage.

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

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

Definition at line 1309 of file manager.c.

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

Referenced by action_updateconfig().

01310 {
01311    int x;
01312    char hdr[40];
01313    const char *action, *cat, *var, *value, *match, *line;
01314    struct ast_category *category;
01315    struct ast_variable *v;
01316    struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
01317    enum error_type result = 0;
01318 
01319    for (x = 0; x < 100000; x++) {   /* 100000 = the max number of allowed updates + 1 */
01320       unsigned int object = 0;
01321 
01322       snprintf(hdr, sizeof(hdr), "Action-%06d", x);
01323       action = astman_get_header(m, hdr);
01324       if (ast_strlen_zero(action))     /* breaks the for loop if no action header */
01325          break;            /* this could cause problems if actions come in misnumbered */
01326 
01327       snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
01328       cat = astman_get_header(m, hdr);
01329       if (ast_strlen_zero(cat)) {      /* every action needs a category */
01330          result =  UNSPECIFIED_CATEGORY;
01331          break;
01332       }
01333 
01334       snprintf(hdr, sizeof(hdr), "Var-%06d", x);
01335       var = astman_get_header(m, hdr);
01336 
01337       snprintf(hdr, sizeof(hdr), "Value-%06d", x);
01338       value = astman_get_header(m, hdr);
01339 
01340       if (!ast_strlen_zero(value) && *value == '>') {
01341          object = 1;
01342          value++;
01343       }
01344    
01345       snprintf(hdr, sizeof(hdr), "Match-%06d", x);
01346       match = astman_get_header(m, hdr);
01347 
01348       snprintf(hdr, sizeof(hdr), "Line-%06d", x);
01349       line = astman_get_header(m, hdr);
01350 
01351       if (!strcasecmp(action, "newcat")) {
01352          if (ast_category_get(cfg,cat)) { /* check to make sure the cat doesn't */
01353             result = FAILURE_NEWCAT;   /* already exist */
01354             break;
01355          }
01356          if (!(category = ast_category_new(cat, dfn, -1))) {
01357             result = FAILURE_ALLOCATION;
01358             break;
01359          }
01360          if (ast_strlen_zero(match)) {
01361             ast_category_append(cfg, category);
01362          } else
01363             ast_category_insert(cfg, category, match);
01364       } else if (!strcasecmp(action, "renamecat")) {
01365          if (ast_strlen_zero(value)) {
01366             result = UNSPECIFIED_ARGUMENT;
01367             break;
01368          }
01369          if (!(category = ast_category_get(cfg, cat))) {
01370             result = UNKNOWN_CATEGORY;
01371             break;
01372          }
01373          ast_category_rename(category, value);
01374       } else if (!strcasecmp(action, "delcat")) {
01375          if (ast_category_delete(cfg, cat)) {
01376             result = FAILURE_DELCAT;
01377             break;
01378          }
01379       } else if (!strcasecmp(action, "emptycat")) {
01380          if (ast_category_empty(cfg, cat)) {
01381             result = FAILURE_EMPTYCAT;
01382             break;
01383          }
01384       } else if (!strcasecmp(action, "update")) {
01385          if (ast_strlen_zero(var)) {
01386             result = UNSPECIFIED_ARGUMENT;
01387             break;
01388          }
01389          if (!(category = ast_category_get(cfg,cat))) {
01390             result = UNKNOWN_CATEGORY;
01391             break;
01392          }
01393          if (ast_variable_update(category, var, value, match, object)) {
01394             result = FAILURE_UPDATE;
01395             break;
01396          }
01397       } else if (!strcasecmp(action, "delete")) {
01398          if ((ast_strlen_zero(var) && ast_strlen_zero(line))) {
01399             result = UNSPECIFIED_ARGUMENT;
01400             break;
01401          }
01402          if (!(category = ast_category_get(cfg, cat))) {
01403             result = UNKNOWN_CATEGORY;
01404             break;
01405          }
01406          if (ast_variable_delete(category, var, match, line)) {
01407             result = FAILURE_DELETE;
01408             break;
01409          }
01410       } else if (!strcasecmp(action, "append")) {
01411          if (ast_strlen_zero(var)) {
01412             result = UNSPECIFIED_ARGUMENT;
01413             break;
01414          }
01415          if (!(category = ast_category_get(cfg, cat))) {
01416             result = UNKNOWN_CATEGORY; 
01417             break;
01418          }
01419          if (!(v = ast_variable_new(var, value, dfn))) {
01420             result = FAILURE_ALLOCATION;
01421             break;
01422          }
01423          if (object || (match && !strcasecmp(match, "object")))
01424             v->object = 1;
01425          ast_variable_append(category, v);
01426       } else if (!strcasecmp(action, "insert")) {
01427          if (ast_strlen_zero(var) || ast_strlen_zero(line)) {
01428             result = UNSPECIFIED_ARGUMENT;
01429             break;
01430          }
01431          if (!(category = ast_category_get(cfg, cat))) {
01432             result = UNKNOWN_CATEGORY;
01433             break;
01434          }
01435          if (!(v = ast_variable_new(var, value, dfn))) {
01436             result = FAILURE_ALLOCATION;
01437             break;
01438          }
01439          ast_variable_insert(category, v, line);
01440       }
01441       else {
01442          ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action);
01443          result = UNKNOWN_ACTION;
01444          break;
01445       }
01446    }
01447    ast_free(str1);
01448    ast_free(str2);
01449    return result;
01450 }

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

Referenced by action_getconfigjson().

01229 {
01230    for (; *in; in++) {
01231       if (*in == '\\' || *in == '\"')
01232          *out++ = '\\';
01233       *out++ = *in;
01234    }
01235    *out = '\0';
01236 }

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

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

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

00506 {
00507    struct ast_manager_user *user = NULL;
00508    int ret = 0;
00509 
00510    AST_RWLIST_RDLOCK(&users);
00511    if ((user = get_manager_by_name_locked (session->username)))
00512       ret = user->displayconnects;
00513    AST_RWLIST_UNLOCK(&users);
00514    
00515    return ret;
00516 }

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

Definition at line 2854 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, s, and version.

Referenced by __init_manager().

02855 {
02856    int res;
02857    const char *module = astman_get_header(m, "Module");
02858    const char *id = astman_get_header(m, "ActionID");
02859    char idText[256];
02860 #if !defined(LOW_MEMORY)
02861    const char *version;
02862 #endif
02863    char filename[PATH_MAX];
02864    char *cut;
02865 
02866    ast_copy_string(filename, module, sizeof(filename));
02867    if ((cut = strchr(filename, '.'))) {
02868       *cut = '\0';
02869    } else {
02870       cut = filename + strlen(filename);
02871    }
02872    snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so");
02873    ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename);
02874    res = ast_module_check(filename);
02875    if (!res) {
02876       astman_send_error(s, m, "Module not loaded");
02877       return 0;
02878    }
02879    snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c");
02880    ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename);
02881 #if !defined(LOW_MEMORY)
02882    version = ast_file_version_find(filename);
02883 #endif
02884 
02885    if (!ast_strlen_zero(id))
02886       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
02887    else
02888       idText[0] = '\0';
02889    astman_append(s, "Response: Success\r\n%s", idText);
02890 #if !defined(LOW_MEMORY)
02891    astman_append(s, "Version: %s\r\n\r\n", version ? version : "");
02892 #endif
02893    return 0;
02894 }

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

Definition at line 2907 of file manager.c.

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

Referenced by __init_manager().

02908 {
02909    int res;
02910    const char *module = astman_get_header(m, "Module");
02911    const char *loadtype = astman_get_header(m, "LoadType");
02912 
02913    if (!loadtype || strlen(loadtype) == 0)
02914       astman_send_error(s, m, "Incomplete ModuleLoad action.");
02915    if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0)
02916       astman_send_error(s, m, "Need module name");
02917 
02918    if (!strcasecmp(loadtype, "load")) {
02919       res = ast_load_resource(module);
02920       if (res)
02921          astman_send_error(s, m, "Could not load module.");
02922       else
02923          astman_send_ack(s, m, "Module loaded.");
02924    } else if (!strcasecmp(loadtype, "unload")) {
02925       res = ast_unload_resource(module, AST_FORCE_SOFT);
02926       if (res)
02927          astman_send_error(s, m, "Could not unload module.");
02928       else
02929          astman_send_ack(s, m, "Module unloaded.");
02930    } else if (!strcasecmp(loadtype, "reload")) {
02931       if (module != NULL) {
02932          res = ast_module_reload(module);
02933          if (res == 0)
02934             astman_send_error(s, m, "No such module.");
02935          else if (res == 1)
02936             astman_send_error(s, m, "Module does not support reload action.");
02937          else
02938             astman_send_ack(s, m, "Module reloaded.");
02939       } else {
02940          ast_module_reload(NULL);   /* Reload all modules */
02941          astman_send_ack(s, m, "All modules reloaded");
02942       }
02943    } else 
02944       astman_send_error(s, m, "Incomplete ModuleLoad action.");
02945    return 0;
02946 }

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

Definition at line 3361 of file manager.c.

References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.

Referenced by __init_manager().

03362 {
03363    /* Notify managers of change */
03364    char hint[512];
03365    ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);
03366 
03367    manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state);
03368    return 0;
03369 }

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

References ast_mutex_lock(), ast_mutex_unlock(), NEW_EVENT, ref_event(), s, send_string(), and unref_event().

Referenced by do_message(), and process_message().

02626 {
02627    int ret = 0;
02628 
02629    ast_mutex_lock(&s->session->__lock);
02630    if (s->session->f != NULL) {
02631       struct eventqent *eqe;
02632 
02633       while ( (eqe = NEW_EVENT(s)) ) {
02634          ref_event(eqe);
02635          if (!ret && s->session->authenticated &&
02636              (s->session->readperm & eqe->category) == eqe->category &&
02637              (s->session->send_events & eqe->category) == eqe->category) {
02638             if (send_string(s, eqe->eventdata) < 0)
02639                ret = -1;   /* don't send more */
02640          }
02641          s->session->last_ev = unref_event(s->session->last_ev);
02642       }
02643    }
02644    ast_mutex_unlock(&s->session->__lock);
02645    return ret;
02646 }

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

Definition at line 2961 of file manager.c.

References __astman_get_header(), 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(), manager_action::authority, buf, check_manager_session_inuse(), manager_action::func, GET_HEADER_SKIP_EMPTY, process_events(), and s.

Referenced by do_message().

02962 {
02963    char action[80] = "";
02964    int ret = 0;
02965    struct manager_action *tmp;
02966    const char *user = astman_get_header(m, "Username");
02967 
02968    ast_copy_string(action, __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY), sizeof(action));
02969    ast_debug(1, "Manager received command '%s'\n", action);
02970 
02971    if (ast_strlen_zero(action)) {
02972       ast_mutex_lock(&s->session->__lock);
02973       astman_send_error(s, m, "Missing action in request");
02974       ast_mutex_unlock(&s->session->__lock);
02975       return 0;
02976    }
02977 
02978    if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) {
02979       ast_mutex_lock(&s->session->__lock);
02980       astman_send_error(s, m, "Permission denied");
02981       ast_mutex_unlock(&s->session->__lock);
02982       return 0;
02983    }
02984 
02985    if (!allowmultiplelogin && !s->session->authenticated && user &&
02986       (!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) {
02987       if (check_manager_session_inuse(user)) {
02988          sleep(1);
02989          ast_mutex_lock(&s->session->__lock);
02990          astman_send_error(s, m, "Login Already In Use");
02991          ast_mutex_unlock(&s->session->__lock);
02992          return -1;
02993       }
02994    }
02995 
02996    AST_RWLIST_RDLOCK(&actions);
02997    AST_RWLIST_TRAVERSE(&actions, tmp, list) {
02998       if (strcasecmp(action, tmp->action))
02999          continue;
03000       if (s->session->writeperm & tmp->authority || tmp->authority == 0)
03001          ret = tmp->func(s, m);
03002       else
03003          astman_send_error(s, m, "Permission denied");
03004       break;
03005    }
03006    AST_RWLIST_UNLOCK(&actions);
03007 
03008    if (!tmp) {
03009       char buf[512];
03010       snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
03011       ast_mutex_lock(&s->session->__lock);
03012       astman_send_error(s, m, buf);
03013       ast_mutex_unlock(&s->session->__lock);
03014    }
03015    if (ret)
03016       return ret;
03017    /* Once done with our message, deliver any pending events */
03018    return process_events(s);
03019 }

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

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

Referenced by purge_old_stuff().

00350 {
00351    struct eventqent *ev;
00352 
00353    AST_LIST_LOCK(&all_events);
00354    while ( (ev = AST_LIST_FIRST(&all_events)) &&
00355        ev->usecount == 0 && AST_LIST_NEXT(ev, eq_next)) {
00356       AST_LIST_REMOVE_HEAD(&all_events, eq_next);
00357       ast_free(ev);
00358    }
00359    AST_LIST_UNLOCK(&all_events);
00360 }

static void purge_sessions ( int  n_max  )  [static]

remove at most n_max stale session from the list.

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

03210 {
03211    struct mansession_session *session;
03212    time_t now = time(NULL);
03213 
03214    AST_LIST_LOCK(&sessions);
03215    AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, session, list) {
03216       if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) {
03217          AST_LIST_REMOVE_CURRENT(list);
03218          ast_atomic_fetchadd_int(&num_sessions, -1);
03219          if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) {
03220             ast_verb(2, "HTTP Manager '%s' timed out from %s\n",
03221                session->username, ast_inet_ntoa(session->sin.sin_addr));
03222          }
03223          free_session(session);  /* XXX outside ? */
03224          if (--n_max <= 0)
03225             break;
03226       }
03227    }
03228    AST_LIST_TRAVERSE_SAFE_END;
03229    AST_LIST_UNLOCK(&sessions);
03230 }

static void ref_event ( struct eventqent e  )  [static]

Definition at line 825 of file manager.c.

References ast_atomic_fetchadd_int(), and eventqent::usecount.

Referenced by process_events().

00826 {
00827    ast_atomic_fetchadd_int(&e->usecount, 1);
00828 }

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

References ast_careful_fwrite(), and s.

Referenced by astman_append(), and process_events().

00944 {
00945    if (s->f) {
00946       return ast_careful_fwrite(s->f, s->fd, string, strlen(string), s->session->writetimeout);
00947    } else {
00948       return ast_careful_fwrite(s->session->f, s->session->fd, string, strlen(string), s->session->writetimeout);
00949    }
00950 }

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

References AMI_VERSION, ast_atomic_fetchadd_int(), ast_calloc, ast_inet_ntoa(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), AST_PTHREADT_NULL, ast_verb, astman_append(), do_message(), ast_tcptls_session_instance::f, ast_tcptls_session_instance::fd, ast_frame::flags, grab_last(), LOG_EVENT, manager_displayconnects(), ast_tcptls_session_instance::remote_address, and s.

03133 {
03134    struct ast_tcptls_session_instance *ser = data;
03135    struct mansession_session *session = ast_calloc(1, sizeof(*session));
03136    struct mansession s = {.session = NULL, };
03137    int flags;
03138    int res;
03139 
03140    if (session == NULL)
03141       goto done;
03142 
03143    session->writetimeout = 100;
03144    session->waiting_thread = AST_PTHREADT_NULL;
03145 
03146    flags = fcntl(ser->fd, F_GETFL);
03147    if (!block_sockets) /* make sure socket is non-blocking */
03148       flags |= O_NONBLOCK;
03149    else
03150       flags &= ~O_NONBLOCK;
03151    fcntl(ser->fd, F_SETFL, flags);
03152 
03153    ast_mutex_init(&session->__lock);
03154    session->send_events = -1;
03155    /* Hook to the tail of the event queue */
03156    session->last_ev = grab_last();
03157 
03158    /* these fields duplicate those in the 'ser' structure */
03159    session->fd = ser->fd;
03160    session->f = ser->f;
03161    session->sin = ser->remote_address;
03162    s.session = session;
03163 
03164    AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);
03165 
03166    AST_LIST_LOCK(&sessions);
03167    AST_LIST_INSERT_HEAD(&sessions, session, list);
03168    ast_atomic_fetchadd_int(&num_sessions, 1);
03169    AST_LIST_UNLOCK(&sessions);
03170 
03171    astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION);   /* welcome prompt */
03172    for (;;) {
03173       if ((res = do_message(&s)) < 0)
03174          break;
03175    }
03176    /* session is over, explain why and terminate */
03177    if (session->authenticated) {
03178          if (manager_displayconnects(session))
03179          ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
03180       ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
03181    } else {
03182          if (displayconnects)
03183          ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr));
03184       ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(session->sin.sin_addr));
03185    }
03186 
03187    /* It is possible under certain circumstances for this session thread
03188       to complete its work and exit *before* the thread that created it
03189       has finished executing the ast_pthread_create_background() function.
03190       If this occurs, some versions of glibc appear to act in a buggy
03191       fashion and attempt to write data into memory that it thinks belongs
03192       to the thread but is in fact not owned by the thread (or may have
03193       been freed completely).
03194 
03195       Causing this thread to yield to other threads at least one time
03196       appears to work around this bug.
03197    */
03198    usleep(1);
03199 
03200    destroy_session(session);
03201 
03202 done:
03203    ao2_ref(ser, -1);
03204    ser = NULL;
03205    return NULL;
03206 }

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

References ast_mutex_lock(), ast_mutex_unlock(), s, and strings_to_mask().

Referenced by action_events(), and authenticate().

01052 {
01053    int maskint = strings_to_mask(eventmask);
01054 
01055    ast_mutex_lock(&s->session->__lock);
01056    if (maskint >= 0)
01057       s->session->send_events = maskint;
01058    ast_mutex_unlock(&s->session->__lock);
01059 
01060    return maskint;
01061 }

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

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

Referenced by set_eventmask().

00450 {
00451    const char *p;
00452 
00453    if (ast_strlen_zero(string))
00454       return -1;
00455 
00456    for (p = string; *p; p++)
00457       if (*p < '0' || *p > '9')
00458          break;
00459    if (!p)  /* all digits */
00460       return atoi(string);
00461    if (ast_false(string))
00462       return 0;
00463    if (ast_true(string)) { /* all permissions */
00464       int x, ret = 0;
00465       for (x = 0; x < ARRAY_LEN(perms); x++)
00466          ret |= perms[x].num;
00467       return ret;
00468    }
00469    return get_perm(string);
00470 }

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

Definition at line 819 of file manager.c.

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

Referenced by free_session(), and process_events().

00820 {
00821    ast_atomic_fetchadd_int(&e->usecount, -1);
00822    return AST_LIST_NEXT(e, eq_next);
00823 }


Variable Documentation

int allowmultiplelogin = 1 [static]

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

Referenced by astman_append().

int block_sockets [static]

Definition at line 129 of file manager.c.

struct ast_cli_entry cli_manager[] [static]

Definition at line 802 of file manager.c.

Referenced by __init_manager().

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

Referenced by check_blacklist().

int displayconnects = 1 [static]

Definition at line 122 of file manager.c.

int httptimeout = 60 [static]

Definition at line 125 of file manager.c.

int manager_debug [static]

enable some debugging code in the manager

Definition at line 132 of file manager.c.

int manager_enabled = 0 [static]

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

Referenced by __manager_event().

char mandescr_atxfer[] [static]

Definition at line 2132 of file manager.c.

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

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

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

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

char mandescr_createconfig[] [static]

Definition at line 1540 of file manager.c.

Referenced by __init_manager().

char mandescr_events[] [static]

Definition at line 1688 of file manager.c.

char mandescr_extensionstate[] [static]

Definition at line 2550 of file manager.c.

char mandescr_getconfig[] [static]

Definition at line 1144 of file manager.c.

Referenced by __init_manager().

char mandescr_getconfigjson[] [static]

Definition at line 1238 of file manager.c.

Referenced by __init_manager().

char mandescr_getvar[] [static]

Definition at line 1814 of file manager.c.

char mandescr_hangup[] [static]

Initial value:

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

Definition at line 1753 of file manager.c.

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

char mandescr_logoff[] [static]

Initial value:

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

Definition at line 1711 of file manager.c.

char mandescr_mailboxcount[] [static]

Definition at line 2517 of file manager.c.

char mandescr_mailboxstatus[] [static]

Help text for manager command mailboxstatus.

Definition at line 2489 of file manager.c.

char mandescr_modulecheck[] [static]

Definition at line 2844 of file manager.c.

char mandescr_moduleload[] [static]

Definition at line 2896 of file manager.c.

char mandescr_originate[] [static]

Definition at line 2347 of file manager.c.

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

Referenced by __init_manager().

char mandescr_redirect[] [static]

Definition at line 2046 of file manager.c.

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

char mandescr_sendtext[] [static]

Definition at line 2005 of file manager.c.

char mandescr_setvar[] [static]

Definition at line 1777 of file manager.c.

char mandescr_status[] [static]

Definition at line 1865 of file manager.c.

char mandescr_timeout[] [static]

Definition at line 2585 of file manager.c.

char mandescr_updateconfig[] [static]

Definition at line 1452 of file manager.c.

Referenced by __init_manager().

char mandescr_userevent[] [static]

Definition at line 2648 of file manager.c.

char mandescr_waitevent[] [static]

Manager WAITEVENT.

Definition at line 1565 of file manager.c.

Referenced by __init_manager().

int num_sessions [static]

Definition at line 130 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 124 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 960 of file manager.c.

Referenced by action_userevent().

int webmanager_enabled = 0 [static]

Definition at line 127 of file manager.c.

char* words[AST_MAX_CMD_LEN] [inherited]

Definition at line 145 of file manager.c.


Generated on Fri Jul 24 00:42:02 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7