Sat Apr 12 07:12:50 2008

Asterisk developer's documentation


manager.c File Reference

The Asterisk Management Interface - AMI. More...

#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include "asterisk/channel.h"
#include "asterisk/file.h"
#include "asterisk/manager.h"
#include "asterisk/config.h"
#include "asterisk/callerid.h"
#include "asterisk/lock.h"
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/md5.h"
#include "asterisk/acl.h"
#include "asterisk/utils.h"
#include "asterisk/http.h"
#include "asterisk/threadstorage.h"
#include "asterisk/linkedlists.h"
#include "asterisk/term.h"
#include "asterisk/astobj2.h"

Include dependency graph for manager.c:

Go to the source code of this file.

Data Structures

struct  ast_manager_user
struct  eventqent
struct  fast_originate_helper
struct  mansession
struct  permalias
struct  variable_count

Defines

#define ASTMAN_APPEND_BUF_INITSIZE   256
#define MANAGER_EVENT_BUF_INITSIZE   256

Enumerations

enum  { FORMAT_RAW, FORMAT_HTML, FORMAT_XML }

Functions

static void * accept_thread (void *ignore)
static int action_command (struct mansession *s, const struct message *m)
 action_command: Manager command "command" - execute CLI command
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_getvar (struct mansession *s, const struct message *m)
static int action_hangup (struct mansession *s, const struct message *m)
static int action_listcommands (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_message (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_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 struct ast_manager_userast_get_manager_by_name_locked (const char *name)
static int ast_instring (const char *bigstr, const char *smallstr, char delim)
static int ast_is_number (const char *string)
static AST_LIST_HEAD_STATIC (users, ast_manager_user)
static AST_LIST_HEAD_STATIC (sessions, mansession)
int ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), const char *synopsis, const char *description)
 register a new command with manager, including online help. This is the preferred way to register a manager command
static int ast_manager_register_struct (struct manager_action *act)
int ast_manager_unregister (char *action)
 AST_RWLOCK_DEFINE_STATIC (actionlock)
 AST_THREADSTORAGE (astman_append_buf, astman_append_buf_init)
 AST_THREADSTORAGE (manager_event_buf, manager_event_buf_init)
void astman_append (struct mansession *s, const char *fmt,...)
const char * astman_get_header (const struct message *m, char *var)
struct ast_variableastman_get_variables (const struct message *m)
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
void astman_send_error (struct mansession *s, const struct message *m, char *error)
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
int astman_verify_session_readpermissions (unsigned long ident, int perm)
 Verify a session's read permissions against a permission mask.
int astman_verify_session_writepermissions (unsigned long ident, int perm)
 Verify a session's write permissions against a permission mask.
static int authenticate (struct mansession *s, const struct message *m)
static char * authority_to_str (int authority, char *res, int reslen)
 Convert authority code to string with serveral options.
static char * complete_show_mancmd (const char *line, const char *word, int pos, int state)
static int compress_char (char c)
static void destroy_session (struct mansession *s)
static int do_message (struct mansession *s)
static void * fast_originate (void *data)
static struct mansessionfind_session (unsigned long ident)
static void free_session (struct mansession *s)
static char * generic_http_callback (int format, struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
static int get_input (struct mansession *s, char *output)
static int get_perm (const char *instr)
static int handle_showmanager (int fd, int argc, char *argv[])
static int handle_showmanagers (int fd, int argc, char *argv[])
static int handle_showmancmd (int fd, int argc, char *argv[])
static int handle_showmancmds (int fd, int argc, char *argv[])
 CLI command Should change to "manager show commands".
static int handle_showmanconn (int fd, int argc, char *argv[])
 CLI command show manager connected.
static int handle_showmaneventq (int fd, int argc, char *argv[])
 CLI command show manager connected.
static void handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg)
static char * html_translate (char *in)
int init_manager (void)
int manager_event (int category, const char *event, const char *fmt,...)
 manager_event: Send AMI event to client
static char * manager_http_callback (struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
static int manager_state_cb (char *context, char *exten, int state, void *data, char *cid_num, char *cid_name)
static char * mxml_http_callback (struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
static int process_events (struct mansession *s)
static int process_message (struct mansession *s, const struct message *m)
static char * rawman_http_callback (struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength)
int reload_manager (void)
static void * session_do (void *data)
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 void unuse_eventqent (struct eventqent *e)
static int variable_count_cmp_fn (void *obj, void *vstr, int flags)
static int variable_count_hash_fn (const void *vvc, const int flags)
static void xml_copy_escape (char **dst, size_t *maxlen, const char *src, int lower)
static char * xml_translate (char *in, struct ast_variable *vars)

Variables

static int asock = -1
static int block_sockets
static struct ast_cli_entry cli_manager []
static struct ast_cli_entry cli_show_manager_command_deprecated
static struct ast_cli_entry cli_show_manager_commands_deprecated
static struct ast_cli_entry cli_show_manager_connected_deprecated
static struct ast_cli_entry cli_show_manager_eventq_deprecated
static const char * command_blacklist []
static char * contenttype [] = { "plain", "html", "xml" }
static int displayconnects = 1
static int enabled
static struct manager_actionfirst_action
static int httptimeout = 60
struct ast_http_uri manageruri
struct ast_http_uri managerxmluri
static char mandescr_command []
static char mandescr_events []
static char mandescr_extensionstate []
static char mandescr_getconfig []
static char mandescr_getvar []
static char mandescr_hangup []
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_message []
static char mandescr_originate []
static char mandescr_ping []
 Manager PING.
static char mandescr_redirect []
static char mandescr_setvar []
static char mandescr_timeout []
static char mandescr_updateconfig []
static char mandescr_userevent []
static char mandescr_waitevent []
 Manager WAITEVENT.
struct eventqentmaster_eventq = NULL
static int num_sessions
static struct permalias perms []
static int portno = DEFAULT_MANAGER_PORT
struct ast_http_uri rawmanuri
static int registered = 0
static char showmanager_help []
static char showmanagers_help []
static char showmancmd_help []
static char showmancmds_help []
static char showmanconn_help []
static char showmaneventq_help []
static pthread_t t
static int timestampevents
static int webregged = 0


Detailed Description

The Asterisk Management Interface - AMI.

Author:
Mark Spencer <markster@digium.com>
Channel Management and more

manager.conf

Definition in file manager.c.


Enumeration Type Documentation

anonymous enum

Enumerator:
FORMAT_RAW 
FORMAT_HTML 
FORMAT_XML 

Definition at line 2714 of file manager.c.

02714      {
02715    FORMAT_RAW,
02716    FORMAT_HTML,
02717    FORMAT_XML,
02718 };


Function Documentation

int astman_verify_session_readpermissions ( unsigned long  ident,
int  perm 
)

Verify a session's read permissions against a permission mask.

Parameters:
ident session identity
perm permission mask to verify
Returns:
1 if the session has the permission mask capabilities, otherwise 0

Definition at line 2676 of file manager.c.

References mansession::__lock, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), mansession::managerid, mansession::readperm, and s.

02677 {
02678    int result = 0;
02679    struct mansession *s;
02680 
02681    AST_LIST_LOCK(&sessions);
02682    AST_LIST_TRAVERSE(&sessions, s, list) {
02683       ast_mutex_lock(&s->__lock);
02684       if ((s->managerid == ident) && (s->readperm & perm)) {
02685          result = 1;
02686          ast_mutex_unlock(&s->__lock);
02687          break;
02688       }
02689       ast_mutex_unlock(&s->__lock);
02690    }
02691    AST_LIST_UNLOCK(&sessions);
02692    return result;
02693 }

int astman_verify_session_writepermissions ( unsigned long  ident,
int  perm 
)

Verify a session's write permissions against a permission mask.

Parameters:
ident session identity
perm permission mask to verify
Returns:
1 if the session has the permission mask capabilities, otherwise 0

Definition at line 2695 of file manager.c.

References mansession::__lock, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), mansession::managerid, s, and mansession::writeperm.

02696 {
02697    int result = 0;
02698    struct mansession *s;
02699 
02700    AST_LIST_LOCK(&sessions);
02701    AST_LIST_TRAVERSE(&sessions, s, list) {
02702       ast_mutex_lock(&s->__lock);
02703       if ((s->managerid == ident) && (s->writeperm & perm)) {
02704          result = 1;
02705          ast_mutex_unlock(&s->__lock);
02706          break;
02707       }
02708       ast_mutex_unlock(&s->__lock);
02709    }
02710    AST_LIST_UNLOCK(&sessions);
02711    return result;
02712 }

static struct mansession* find_session ( unsigned long  ident  )  [static, read]

END Doxygen group

Definition at line 2658 of file manager.c.

References mansession::__lock, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), mansession::inuse, mansession::managerid, mansession::needdestroy, s, and mansession::sessiontimeout.

Referenced by generic_http_callback().

02659 {
02660    struct mansession *s;
02661 
02662    AST_LIST_LOCK(&sessions);
02663    AST_LIST_TRAVERSE(&sessions, s, list) {
02664       ast_mutex_lock(&s->__lock);
02665       if (s->sessiontimeout && (s->managerid == ident) && !s->needdestroy) {
02666          s->inuse++;
02667          break;
02668       }
02669       ast_mutex_unlock(&s->__lock);
02670    }
02671    AST_LIST_UNLOCK(&sessions);
02672 
02673    return s;
02674 }

static char* generic_http_callback ( int  format,
struct sockaddr_in *  requestor,
const char *  uri,
struct ast_variable params,
int *  status,
char **  title,
int *  contentlength 
) [static]

Definition at line 2721 of file manager.c.

References mansession::__lock, ast_build_string(), ast_calloc, ast_http_error(), ast_http_setcookie(), ast_inet_ntoa(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_MAX_MANHEADERS, ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_verbose(), mansession::authenticated, destroy_session(), mansession::eventq, mansession::fd, find_session(), FORMAT_HTML, FORMAT_XML, free, message::hdrcount, message::headers, html_translate(), mansession::inuse, len, LOG_DEBUG, LOG_EVENT, malloc, mansession::managerid, ast_variable::name, mansession::needdestroy, eventqent::next, ast_variable::next, option_verbose, mansession::outputstr, process_message(), s, mansession::send_events, mansession::sessiontimeout, mansession::sin, strdup, eventqent::usecount, mansession::username, ast_variable::value, VERBOSE_PREFIX_2, mansession::waiting_thread, and xml_translate().

Referenced by manager_http_callback(), mxml_http_callback(), and rawman_http_callback().

02722 {
02723    struct mansession *s = NULL;
02724    unsigned long ident = 0;
02725    char workspace[512];
02726    char cookie[128];
02727    size_t len = sizeof(workspace);
02728    int blastaway = 0;
02729    char *c = workspace;
02730    char *retval = NULL;
02731    struct ast_variable *v;
02732 
02733    for (v = params; v; v = v->next) {
02734       if (!strcasecmp(v->name, "mansession_id")) {
02735          sscanf(v->value, "%lx", &ident);
02736          break;
02737       }
02738    }
02739    
02740    if (!(s = find_session(ident))) {
02741       /* Create new session */
02742       if (!(s = ast_calloc(1, sizeof(*s)))) {
02743          *status = 500;
02744          goto generic_callback_out;
02745       }
02746       memcpy(&s->sin, requestor, sizeof(s->sin));
02747       s->fd = -1;
02748       s->waiting_thread = AST_PTHREADT_NULL;
02749       s->send_events = 0;
02750       ast_mutex_init(&s->__lock);
02751       ast_mutex_lock(&s->__lock);
02752       s->inuse = 1;
02753       s->managerid = rand() | (unsigned long)s;
02754       AST_LIST_LOCK(&sessions);
02755       AST_LIST_INSERT_HEAD(&sessions, s, list);
02756       /* Hook into the last spot in the event queue */
02757       s->eventq = master_eventq;
02758       while (s->eventq->next)
02759          s->eventq = s->eventq->next;
02760       ast_atomic_fetchadd_int(&s->eventq->usecount, 1);
02761       ast_atomic_fetchadd_int(&num_sessions, 1);
02762       AST_LIST_UNLOCK(&sessions);
02763    }
02764 
02765    /* Reset HTTP timeout.  If we're not yet authenticated, keep it extremely short */
02766    time(&s->sessiontimeout);
02767    if (!s->authenticated && (httptimeout > 5))
02768       s->sessiontimeout += 5;
02769    else
02770       s->sessiontimeout += httptimeout;
02771    ast_mutex_unlock(&s->__lock);
02772    
02773    if (s) {
02774       struct message m = { 0 };
02775       char tmp[80];
02776       unsigned int x;
02777       size_t hdrlen;
02778 
02779       for (x = 0, v = params; v && (x < AST_MAX_MANHEADERS); x++, v = v->next) {
02780          hdrlen = strlen(v->name) + strlen(v->value) + 3;
02781          m.headers[m.hdrcount] = alloca(hdrlen);
02782          snprintf((char *) m.headers[m.hdrcount], hdrlen, "%s: %s", v->name, v->value);
02783          m.hdrcount = x + 1;
02784       }
02785 
02786       if (process_message(s, &m)) {
02787          if (s->authenticated) {
02788             if (option_verbose > 1) {
02789                if (displayconnects) 
02790                   ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));    
02791             }
02792             ast_log(LOG_EVENT, "HTTP Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
02793          } else {
02794             if (option_verbose > 1) {
02795                if (displayconnects)
02796                   ast_verbose(VERBOSE_PREFIX_2 "HTTP Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr));
02797             }
02798             ast_log(LOG_EVENT, "HTTP Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr));
02799          }
02800          s->needdestroy = 1;
02801       }
02802       ast_build_string(&c, &len, "Content-type: text/%s\r\n", contenttype[format]);
02803       sprintf(tmp, "%08lx", s->managerid);
02804       ast_build_string(&c, &len, "%s\r\n", ast_http_setcookie("mansession_id", tmp, httptimeout, cookie, sizeof(cookie)));
02805       if (format == FORMAT_HTML)
02806          ast_build_string(&c, &len, "<title>Asterisk&trade; Manager Interface</title>");
02807       if (format == FORMAT_XML) {
02808          ast_build_string(&c, &len, "<ajax-response>\n");
02809       } else if (format == FORMAT_HTML) {
02810          ast_build_string(&c, &len, "<body bgcolor=\"#ffffff\"><table align=center bgcolor=\"#f1f1f1\" width=\"500\">\r\n");
02811          ast_build_string(&c, &len, "<tr><td colspan=\"2\" bgcolor=\"#f1f1ff\"><h1>&nbsp;&nbsp;Manager Tester</h1></td></tr>\r\n");
02812       }
02813       ast_mutex_lock(&s->__lock);
02814       if (s->outputstr) {
02815          char *tmp;
02816          if (format == FORMAT_XML)
02817             tmp = xml_translate(s->outputstr->str, params);
02818          else if (format == FORMAT_HTML)
02819             tmp = html_translate(s->outputstr->str);
02820          else
02821             tmp = s->outputstr->str;
02822          if (tmp) {
02823             retval = malloc(strlen(workspace) + strlen(tmp) + 128);
02824             if (retval) {
02825                strcpy(retval, workspace);
02826                strcpy(retval + strlen(retval), tmp);
02827                c = retval + strlen(retval);
02828                len = 120;
02829             }
02830          }
02831          if (tmp != s->outputstr->str)
02832             free(tmp);
02833          free(s->outputstr);
02834          s->outputstr = NULL;
02835       }
02836       ast_mutex_unlock(&s->__lock);
02837       /* Still okay because c would safely be pointing to workspace even
02838          if retval failed to allocate above */
02839       if (format == FORMAT_XML) {
02840          ast_build_string(&c, &len, "</ajax-response>\n");
02841       } else if (format == FORMAT_HTML)
02842          ast_build_string(&c, &len, "</table></body>\r\n");
02843    } else {
02844       *status = 500;
02845       *title = strdup("Server Error");
02846    }
02847    ast_mutex_lock(&s->__lock);
02848    if (s->needdestroy) {
02849       if (s->inuse == 1) {
02850          ast_log(LOG_DEBUG, "Need destroy, doing it now!\n");
02851          blastaway = 1;
02852       } else {
02853          ast_log(LOG_DEBUG, "Need destroy, but can't do it yet!\n");
02854          if (s->waiting_thread != AST_PTHREADT_NULL)
02855             pthread_kill(s->waiting_thread, SIGURG);
02856          s->inuse--;
02857       }
02858    } else
02859       s->inuse--;
02860    ast_mutex_unlock(&s->__lock);
02861    
02862    if (blastaway)
02863       destroy_session(s);
02864 generic_callback_out:
02865    if (*status != 200)
02866       return ast_http_error(500, "Server Error", NULL, "Internal Server Error (out of memory)\n"); 
02867    return retval;
02868 }

int init_manager ( void   ) 

Called by Asterisk initialization

Definition at line 2909 of file manager.c.

References accept_thread(), action_command(), action_events(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_listcommands(), action_logoff(), action_mailboxcount(), action_mailboxstatus(), action_message(), action_originate(), action_ping(), action_redirect(), action_setvar(), action_status(), action_timeout(), action_updateconfig(), action_userevent(), action_waitevent(), append_event(), ast_calloc, ast_category_browse(), ast_cli_register_multiple(), ast_config_destroy(), ast_config_load(), ast_extension_state_add(), ast_get_manager_by_name_locked(), ast_http_uri_link(), ast_http_uri_unlink(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_manager_register, ast_manager_register2(), ast_pthread_create_background, ast_strdup, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), DEFAULT_MANAGER_PORT, ast_manager_user::deny, ast_manager_user::displayconnects, errno, EVENT_FLAG_CALL, EVENT_FLAG_COMMAND, EVENT_FLAG_CONFIG, EVENT_FLAG_USER, ast_channel::flags, free, ast_manager_user::keep, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, manager_state_cb(), ast_variable::name, ast_variable::next, option_verbose, ast_manager_user::permit, ast_manager_user::read, ast_manager_user::secret, ast_manager_user::username, users, ast_variable::value, var, and ast_manager_user::write.

Referenced by main(), and reload_manager().

02910 {
02911    struct ast_config *cfg = NULL;
02912    const char *val;
02913    char *cat = NULL;
02914    int oldportno = portno;
02915    static struct sockaddr_in ba;
02916    int x = 1;
02917    int flags;
02918    int webenabled = 0;
02919    int newhttptimeout = 60;
02920    struct ast_manager_user *user = NULL;
02921 
02922    if (!registered) {
02923       /* Register default actions */
02924       ast_manager_register2("Ping", 0, action_ping, "Keepalive command", mandescr_ping);
02925       ast_manager_register2("Events", 0, action_events, "Control Event Flow", mandescr_events);
02926       ast_manager_register2("Logoff", 0, action_logoff, "Logoff Manager", mandescr_logoff);
02927       ast_manager_register2("Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel", mandescr_hangup);
02928       ast_manager_register2("Message", EVENT_FLAG_CALL, action_message, "Send Message", mandescr_message);
02929       ast_manager_register("Status", EVENT_FLAG_CALL, action_status, "Lists channel status" );
02930       ast_manager_register2("Setvar", EVENT_FLAG_CALL, action_setvar, "Set Channel Variable", mandescr_setvar );
02931       ast_manager_register2("Getvar", EVENT_FLAG_CALL, action_getvar, "Gets a Channel Variable", mandescr_getvar );
02932       ast_manager_register2("GetConfig", EVENT_FLAG_CONFIG, action_getconfig, "Retrieve configuration", mandescr_getconfig);
02933       ast_manager_register2("UpdateConfig", EVENT_FLAG_CONFIG, action_updateconfig, "Update basic configuration", mandescr_updateconfig);
02934       ast_manager_register2("Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect (transfer) a call", mandescr_redirect );
02935       ast_manager_register2("Originate", EVENT_FLAG_CALL, action_originate, "Originate Call", mandescr_originate);
02936       ast_manager_register2("Command", EVENT_FLAG_COMMAND, action_command, "Execute Asterisk CLI Command", mandescr_command );
02937       ast_manager_register2("ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status", mandescr_extensionstate );
02938       ast_manager_register2("AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout );
02939       ast_manager_register2("MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus );
02940       ast_manager_register2("MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount );
02941       ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands);
02942       ast_manager_register2("UserEvent", EVENT_FLAG_USER, action_userevent, "Send an arbitrary event", mandescr_userevent);
02943       ast_manager_register2("WaitEvent", 0, action_waitevent, "Wait for an event to occur", mandescr_waitevent);
02944 
02945       ast_cli_register_multiple(cli_manager, sizeof(cli_manager) / sizeof(struct ast_cli_entry));
02946       ast_extension_state_add(NULL, NULL, manager_state_cb, NULL);
02947       registered = 1;
02948       /* Append placeholder event so master_eventq never runs dry */
02949       append_event("Event: Placeholder\r\n\r\n", 0);
02950    }
02951    portno = DEFAULT_MANAGER_PORT;
02952    displayconnects = 1;
02953    cfg = ast_config_load("manager.conf");
02954    if (!cfg) {
02955       ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf.  Call management disabled.\n");
02956       return 0;
02957    }
02958    val = ast_variable_retrieve(cfg, "general", "enabled");
02959    if (val)
02960       enabled = ast_true(val);
02961 
02962    val = ast_variable_retrieve(cfg, "general", "block-sockets");
02963    if (val)
02964       block_sockets = ast_true(val);
02965 
02966    val = ast_variable_retrieve(cfg, "general", "webenabled");
02967    if (val)
02968       webenabled = ast_true(val);
02969 
02970    if ((val = ast_variable_retrieve(cfg, "general", "port"))) {
02971       if (sscanf(val, "%d", &portno) != 1) {
02972          ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
02973          portno = DEFAULT_MANAGER_PORT;
02974       }
02975    }
02976 
02977    if ((val = ast_variable_retrieve(cfg, "general", "displayconnects")))
02978       displayconnects = ast_true(val);
02979 
02980    if ((val = ast_variable_retrieve(cfg, "general", "timestampevents")))
02981       timestampevents = ast_true(val);
02982 
02983    if ((val = ast_variable_retrieve(cfg, "general", "httptimeout")))
02984       newhttptimeout = atoi(val);
02985 
02986    memset(&ba, 0, sizeof(ba));
02987    ba.sin_family = AF_INET;
02988    ba.sin_port = htons(portno);
02989 
02990    if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) {
02991       if (!inet_aton(val, &ba.sin_addr)) { 
02992          ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val);
02993          memset(&ba.sin_addr, 0, sizeof(ba.sin_addr));
02994       }
02995    }
02996    
02997 
02998    if ((asock > -1) && ((portno != oldportno) || !enabled)) {
02999 #if 0
03000       /* Can't be done yet */
03001       close(asock);
03002       asock = -1;
03003 #else
03004       ast_log(LOG_WARNING, "Unable to change management port / enabled\n");
03005 #endif
03006    }
03007 
03008    AST_LIST_LOCK(&users);
03009 
03010    while ((cat = ast_category_browse(cfg, cat))) {
03011       struct ast_variable *var = NULL;
03012 
03013       if (!strcasecmp(cat, "general"))
03014          continue;
03015 
03016       /* Look for an existing entry, if none found - create one and add it to the list */
03017       if (!(user = ast_get_manager_by_name_locked(cat))) {
03018          if (!(user = ast_calloc(1, sizeof(*user))))
03019             break;
03020          /* Copy name over */
03021          ast_copy_string(user->username, cat, sizeof(user->username));
03022          /* Insert into list */
03023          AST_LIST_INSERT_TAIL(&users, user, list);
03024       }
03025 
03026       /* Make sure we keep this user and don't destroy it during cleanup */
03027       user->keep = 1;
03028 
03029       var = ast_variable_browse(cfg, cat);
03030       while (var) {
03031          if (!strcasecmp(var->name, "secret")) {
03032             if (user->secret)
03033                free(user->secret);
03034             user->secret = ast_strdup(var->value);
03035          } else if (!strcasecmp(var->name, "deny") ) {
03036             if (user->deny)
03037                free(user->deny);
03038             user->deny = ast_strdup(var->value);
03039          } else if (!strcasecmp(var->name, "permit") ) {
03040             if (user->permit)
03041                free(user->permit);
03042             user->permit = ast_strdup(var->value);
03043          }  else if (!strcasecmp(var->name, "read") ) {
03044             if (user->read)
03045                free(user->read);
03046             user->read = ast_strdup(var->value);
03047          }  else if (!strcasecmp(var->name, "write") ) {
03048             if (user->write)
03049                free(user->write);
03050             user->write = ast_strdup(var->value);
03051          }  else if (!strcasecmp(var->name, "displayconnects") )
03052             user->displayconnects = ast_true(var->value);
03053          else
03054             ast_log(LOG_DEBUG, "%s is an unknown option.\n", var->name);
03055          var = var->next;
03056       }
03057    }
03058 
03059    /* Perform cleanup - essentially prune out old users that no longer exist */
03060    AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, list) {
03061       if (user->keep) {
03062          user->keep = 0;
03063          continue;
03064       }
03065       /* We do not need to keep this user so take them out of the list */
03066       AST_LIST_REMOVE_CURRENT(&users, list);
03067       /* Free their memory now */
03068       if (user->secret)
03069          free(user->secret);
03070       if (user->deny)
03071          free(user->deny);
03072       if (user->permit)
03073          free(user->permit);
03074       if (user->read)
03075          free(user->read);
03076       if (user->write)
03077          free(user->write);
03078       free(user);
03079    }
03080    AST_LIST_TRAVERSE_SAFE_END
03081 
03082    AST_LIST_UNLOCK(&users);
03083 
03084    ast_config_destroy(cfg);
03085    
03086    if (webenabled && enabled) {
03087       if (!webregged) {
03088          ast_http_uri_link(&rawmanuri);
03089          ast_http_uri_link(&manageruri);
03090          ast_http_uri_link(&managerxmluri);
03091          webregged = 1;
03092       }
03093    } else {
03094       if (webregged) {
03095          ast_http_uri_unlink(&rawmanuri);
03096          ast_http_uri_unlink(&manageruri);
03097          ast_http_uri_unlink(&managerxmluri);
03098          webregged = 0;
03099       }
03100    }
03101 
03102    if (newhttptimeout > 0)
03103       httptimeout = newhttptimeout;
03104 
03105    /* If not enabled, do nothing */
03106    if (!enabled)
03107       return 0;
03108 
03109    if (asock < 0) {
03110       asock = socket(AF_INET, SOCK_STREAM, 0);
03111       if (asock < 0) {
03112          ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
03113          return -1;
03114       }
03115       setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
03116       if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) {
03117          ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno));
03118          close(asock);
03119          asock = -1;
03120          return -1;
03121       }
03122       if (listen(asock, 2)) {
03123          ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno));
03124          close(asock);
03125          asock = -1;
03126          return -1;
03127       }
03128       flags = fcntl(asock, F_GETFL);
03129       fcntl(asock, F_SETFL, flags | O_NONBLOCK);
03130       if (option_verbose)
03131          ast_verbose("Asterisk Management interface listening on port %d\n", portno);
03132       ast_pthread_create_background(&t, NULL, accept_thread, NULL);
03133    }
03134    return 0;
03135 }

static char* manager_http_callback ( struct sockaddr_in *  requestor,
const char *  uri,
struct ast_variable params,
int *  status,
char **  title,
int *  contentlength 
) [static]

Definition at line 2870 of file manager.c.

References FORMAT_HTML, and generic_http_callback().

02871 {
02872    return generic_http_callback(FORMAT_HTML, requestor, uri, params, status, title, contentlength);
02873 }

static char* mxml_http_callback ( struct sockaddr_in *  requestor,
const char *  uri,
struct ast_variable params,
int *  status,
char **  title,
int *  contentlength 
) [static]

Definition at line 2875 of file manager.c.

References FORMAT_XML, and generic_http_callback().

02876 {
02877    return generic_http_callback(FORMAT_XML, requestor, uri, params, status, title, contentlength);
02878 }

static char* rawman_http_callback ( struct sockaddr_in *  requestor,
const char *  uri,
struct ast_variable params,
int *  status,
char **  title,
int *  contentlength 
) [static]

Definition at line 2880 of file manager.c.

References FORMAT_RAW, and generic_http_callback().

02881 {
02882    return generic_http_callback(FORMAT_RAW, requestor, uri, params, status, title, contentlength);
02883 }

int reload_manager ( void   ) 

Definition at line 3137 of file manager.c.

References EVENT_FLAG_SYSTEM, init_manager(), and manager_event().

03138 {
03139    manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n");
03140    return init_manager();
03141 }


Variable Documentation

char* contenttype[] = { "plain", "html", "xml" } [static]

Definition at line 2719 of file manager.c.

Definition at line 2892 of file manager.c.

Definition at line 2899 of file manager.c.

Definition at line 2885 of file manager.c.

int registered = 0 [static]

Definition at line 2906 of file manager.c.

int webregged = 0 [static]

Definition at line 2907 of file manager.c.


Generated on Sat Apr 12 07:12:50 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.5