Mon Mar 31 07:42:56 2008

Asterisk developer's documentation


AMI functions

callback to display queues status in manager More...

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

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_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)
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)
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 void free_session (struct mansession *s)
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 manager_event (int category, const char *event, const char *fmt,...)
 manager_event: Send AMI event to client
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 * 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 int displayconnects = 1
static int enabled
static struct manager_actionfirst_action
static int httptimeout = 60
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_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.
eventqentmaster_eventq = NULL
static int num_sessions
static struct permalias perms []
static int portno = DEFAULT_MANAGER_PORT
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

Detailed Description

callback to display queues status in manager


Define Documentation

#define ASTMAN_APPEND_BUF_INITSIZE   256

Definition at line 115 of file manager.c.

Referenced by astman_append().

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 112 of file manager.c.

Referenced by manager_event().


Function Documentation

static void* accept_thread ( void *  ignore  )  [static]

Definition at line 2304 of file manager.c.

References asock, ast_calloc, ast_inet_ntoa(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), ast_pthread_create_background, AST_PTHREADT_NULL, ast_verbose(), block_sockets, destroy_session(), displayconnects, errno, pollfd::events, pollfd::fd, ast_channel::flags, free, free_session(), LOG_WARNING, master_eventq, eventqent::next, num_sessions, option_verbose, poll(), POLLIN, s, session_do(), sessions, eventqent::usecount, and VERBOSE_PREFIX_2.

Referenced by init_manager(), and reload_config().

02305 {
02306    int as;
02307    struct sockaddr_in sin;
02308    socklen_t sinlen;
02309    struct eventqent *eqe;
02310    struct mansession *s;
02311    struct protoent *p;
02312    int arg = 1;
02313    int flags;
02314    pthread_attr_t attr;
02315    time_t now;
02316    struct pollfd pfds[1];
02317 
02318    pthread_attr_init(&attr);
02319    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02320 
02321    for (;;) {
02322       time(&now);
02323       AST_LIST_LOCK(&sessions);
02324       AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) {
02325          if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) {
02326             AST_LIST_REMOVE_CURRENT(&sessions, list);
02327             num_sessions--;
02328             if (s->authenticated && (option_verbose > 1) && displayconnects) {
02329                ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' timed out from %s\n",
02330                   s->username, ast_inet_ntoa(s->sin.sin_addr));
02331             }
02332             free_session(s);
02333             break;   
02334          }
02335       }
02336       AST_LIST_TRAVERSE_SAFE_END
02337       /* Purge master event queue of old, unused events, but make sure we
02338          always keep at least one in the queue */
02339       eqe = master_eventq;
02340       while (master_eventq->next && !master_eventq->usecount) {
02341          eqe = master_eventq;
02342          master_eventq = master_eventq->next;
02343          free(eqe);
02344       }
02345       AST_LIST_UNLOCK(&sessions);
02346 
02347       sinlen = sizeof(sin);
02348       pfds[0].fd = asock;
02349       pfds[0].events = POLLIN;
02350       /* Wait for something to happen, but timeout every few seconds so
02351          we can ditch any old manager sessions */
02352       if (poll(pfds, 1, 5000) < 1)
02353          continue;
02354       as = accept(asock, (struct sockaddr *)&sin, &sinlen);
02355       if (as < 0) {
02356          ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno));
02357          continue;
02358       }
02359       p = getprotobyname("tcp");
02360       if (p) {
02361          if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
02362             ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
02363          }
02364       }
02365       if (!(s = ast_calloc(1, sizeof(*s))))
02366          continue;
02367 
02368       memcpy(&s->sin, &sin, sizeof(sin));
02369       s->writetimeout = 100;
02370       s->waiting_thread = AST_PTHREADT_NULL;
02371 
02372       if (!block_sockets) {
02373          /* For safety, make sure socket is non-blocking */
02374          flags = fcntl(as, F_GETFL);
02375          fcntl(as, F_SETFL, flags | O_NONBLOCK);
02376       } else {
02377          flags = fcntl(as, F_GETFL);
02378          fcntl(as, F_SETFL, flags & ~O_NONBLOCK);
02379       }
02380       ast_mutex_init(&s->__lock);
02381       s->fd = as;
02382       s->send_events = -1;
02383       AST_LIST_LOCK(&sessions);
02384       AST_LIST_INSERT_HEAD(&sessions, s, list);
02385       num_sessions++;
02386       /* Find the last place in the master event queue and hook ourselves
02387          in there */
02388       s->eventq = master_eventq;
02389       while(s->eventq->next)
02390          s->eventq = s->eventq->next;
02391       ast_atomic_fetchadd_int(&s->eventq->usecount, 1);
02392       AST_LIST_UNLOCK(&sessions);
02393       if (ast_pthread_create_background(&s->t, &attr, session_do, s))
02394          destroy_session(s);
02395    }
02396    pthread_attr_destroy(&attr);
02397    return NULL;
02398 }

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

action_command: Manager command "command" - execute CLI command

Definition at line 1690 of file manager.c.

References ast_calloc, ast_cli_command(), ast_free, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), command_blacklist, s, S_OR, and term_strip().

Referenced by init_manager().

01691 {
01692    const char *cmd = astman_get_header(m, "Command");
01693    const char *id = astman_get_header(m, "ActionID");
01694    char *buf, *final_buf;
01695    char template[] = "/tmp/ast-ami-XXXXXX";  /* template for temporary file */
01696    int fd = mkstemp(template), i = 0;
01697    off_t l;
01698 
01699    for (i = 0; i < sizeof(command_blacklist) / sizeof(command_blacklist[0]); i++) {
01700       if (!strncmp(cmd, command_blacklist[i], strlen(command_blacklist[i]))) {
01701          astman_send_error(s, m, "Command blacklisted");
01702          return 0;
01703       }
01704    }
01705 
01706    astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
01707    if (!ast_strlen_zero(id))
01708       astman_append(s, "ActionID: %s\r\n", id);
01709    /* FIXME: Wedge a ActionID response in here, waiting for later changes */
01710    ast_cli_command(fd, cmd);  /* XXX need to change this to use a FILE * */
01711    l = lseek(fd, 0, SEEK_END);   /* how many chars available */
01712 
01713    /* This has a potential to overflow the stack.  Hence, use the heap. */
01714    buf = ast_calloc(1, l + 1);
01715    final_buf = ast_calloc(1, l + 1);
01716    if (buf) {
01717       lseek(fd, 0, SEEK_SET);
01718       read(fd, buf, l);
01719       buf[l] = '\0';
01720       if (final_buf) {
01721          term_strip(final_buf, buf, l);
01722          final_buf[l] = '\0';
01723       }
01724       astman_append(s, "%s", S_OR(final_buf, buf));
01725       ast_free(buf);
01726    }
01727    close(fd);
01728    unlink(template);
01729    astman_append(s, "--END COMMAND--\r\n\r\n");
01730    if (final_buf)
01731       ast_free(final_buf);
01732    return 0;
01733 }

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

Definition at line 1381 of file manager.c.

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

Referenced by init_manager().

01382 {
01383    const char *mask = astman_get_header(m, "EventMask");
01384    int res;
01385 
01386    res = set_eventmask(s, mask);
01387    if (res > 0)
01388       astman_send_response(s, m, "Events On", NULL);
01389    else if (res == 0)
01390       astman_send_response(s, m, "Events Off", NULL);
01391 
01392    return 0;
01393 }

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

Definition at line 1985 of file manager.c.

References ast_extension_state(), ast_get_hint(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), context, exten, and s.

Referenced by init_manager().

01986 {
01987    const char *exten = astman_get_header(m, "Exten");
01988    const char *context = astman_get_header(m, "Context");
01989    const char *id = astman_get_header(m,"ActionID");
01990    char idText[256] = "";
01991    char hint[256] = "";
01992    int status;
01993    if (ast_strlen_zero(exten)) {
01994       astman_send_error(s, m, "Extension not specified");
01995       return 0;
01996    }
01997    if (ast_strlen_zero(context))
01998       context = "default";
01999    status = ast_extension_state(NULL, context, exten);
02000    ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
02001         if (!ast_strlen_zero(id)) {
02002                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
02003         }
02004    astman_append(s, "Response: Success\r\n"
02005                     "%s"
02006                "Message: Extension Status\r\n"
02007                "Exten: %s\r\n"
02008                "Context: %s\r\n"
02009                "Hint: %s\r\n"
02010                "Status: %d\r\n\r\n",
02011                idText,exten, context, hint, status);
02012    return 0;
02013 }

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

Definition at line 1110 of file manager.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load_with_comments(), ast_strlen_zero(), ast_variable_browse(), astman_append(), astman_get_header(), astman_send_error(), lineno, ast_variable::name, ast_variable::next, s, and ast_variable::value.

Referenced by init_manager().

01111 {
01112    struct ast_config *cfg;
01113    const char *fn = astman_get_header(m, "Filename");
01114    int catcount = 0;
01115    int lineno = 0;
01116    char *category=NULL;
01117    struct ast_variable *v;
01118    char idText[256] = "";
01119    const char *id = astman_get_header(m, "ActionID");
01120 
01121    if (!ast_strlen_zero(id))
01122       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01123 
01124    if (ast_strlen_zero(fn)) {
01125       astman_send_error(s, m, "Filename not specified");
01126       return 0;
01127    }
01128    if (!(cfg = ast_config_load_with_comments(fn))) {
01129       astman_send_error(s, m, "Config file not found");
01130       return 0;
01131    }
01132    astman_append(s, "Response: Success\r\n%s", idText);
01133    while ((category = ast_category_browse(cfg, category))) {
01134       lineno = 0;
01135       astman_append(s, "Category-%06d: %s\r\n", catcount, category);
01136       for (v = ast_variable_browse(cfg, category); v; v = v->next)
01137          astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
01138       catcount++;
01139    }
01140    ast_config_destroy(cfg);
01141    astman_append(s, "\r\n");
01142 
01143    return 0;
01144 }

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

Definition at line 1473 of file manager.c.

References ast_channel_unlock, ast_func_read(), ast_get_channel_by_name_locked(), ast_strdupa, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), copy(), name, pbx_retrieve_variable(), and s.

Referenced by init_manager().

01474 {
01475    struct ast_channel *c = NULL;
01476    const char *name = astman_get_header(m, "Channel");
01477    const char *varname = astman_get_header(m, "Variable");
01478    const char *id = astman_get_header(m,"ActionID");
01479    char *varval;
01480    char workspace[1024] = "";
01481 
01482    if (ast_strlen_zero(varname)) {
01483       astman_send_error(s, m, "No variable specified");
01484       return 0;
01485    }
01486 
01487    if (!ast_strlen_zero(name)) {
01488       c = ast_get_channel_by_name_locked(name);
01489       if (!c) {
01490          astman_send_error(s, m, "No such channel");
01491          return 0;
01492       }
01493    }
01494 
01495    if (varname[strlen(varname) - 1] == ')') {
01496       char *copy = ast_strdupa(varname);
01497 
01498       ast_func_read(c, copy, workspace, sizeof(workspace));
01499       varval = workspace;
01500    } else {
01501       pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
01502    }
01503 
01504    if (c)
01505       ast_channel_unlock(c);
01506    astman_append(s, "Response: Success\r\n"
01507       "Variable: %s\r\nValue: %s\r\n", varname, varval);
01508    if (!ast_strlen_zero(id))
01509       astman_append(s, "ActionID: %s\r\n",id);
01510    astman_append(s, "\r\n");
01511 
01512    return 0;
01513 }

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

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

01411 {
01412    struct ast_channel *c = NULL;
01413    const char *name = astman_get_header(m, "Channel");
01414    if (ast_strlen_zero(name)) {
01415       astman_send_error(s, m, "No channel specified");
01416       return 0;
01417    }
01418    c = ast_get_channel_by_name_locked(name);
01419    if (!c) {
01420       astman_send_error(s, m, "No such channel");
01421       return 0;
01422    }
01423    ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
01424    ast_channel_unlock(c);
01425    astman_send_ack(s, m, "Channel Hungup");
01426    return 0;
01427 }

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

References manager_action::action, ast_strlen_zero(), astman_append(), astman_get_header(), manager_action::authority, authority_to_str(), first_action, manager_action::next, s, and manager_action::synopsis.

Referenced by init_manager().

01355 {
01356    struct manager_action *cur;
01357    char idText[256] = "";
01358    char temp[BUFSIZ];
01359    const char *id = astman_get_header(m,"ActionID");
01360 
01361    if (!ast_strlen_zero(id))
01362       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01363    astman_append(s, "Response: Success\r\n%s", idText);
01364    for (cur = first_action; cur; cur = cur->next) {
01365       if ((s->writeperm & cur->authority) == cur->authority)
01366          astman_append(s, "%s: %s (Priv: %s)\r\n", cur->action, cur->synopsis, authority_to_str(cur->authority, temp, sizeof(temp)));
01367    }
01368    astman_append(s, "\r\n");
01369 
01370    return 0;
01371 }

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

Definition at line 1399 of file manager.c.

References astman_send_response(), and s.

Referenced by init_manager().

01400 {
01401    astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
01402    return -1;
01403 }

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

Definition at line 1949 of file manager.c.

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

Referenced by init_manager().

01950 {
01951    const char *mailbox = astman_get_header(m, "Mailbox");
01952    const char *id = astman_get_header(m,"ActionID");
01953    char idText[256] = "";
01954    int newmsgs = 0, oldmsgs = 0;
01955    if (ast_strlen_zero(mailbox)) {
01956       astman_send_error(s, m, "Mailbox not specified");
01957       return 0;
01958    }
01959    ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs);
01960    if (!ast_strlen_zero(id)) {
01961       snprintf(idText, sizeof(idText), "ActionID: %s\r\n",id);
01962    }
01963    astman_append(s, "Response: Success\r\n"
01964                "%s"
01965                "Message: Mailbox Message Count\r\n"
01966                "Mailbox: %s\r\n"
01967                "NewMessages: %d\r\n"
01968                "OldMessages: %d\r\n" 
01969                "\r\n",
01970                 idText,mailbox, newmsgs, oldmsgs);
01971    return 0;
01972 }

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

Definition at line 1917 of file manager.c.

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

Referenced by init_manager().

01918 {
01919    const char *mailbox = astman_get_header(m, "Mailbox");
01920    const char *id = astman_get_header(m,"ActionID");
01921    char idText[256] = "";
01922    int ret;
01923    if (ast_strlen_zero(mailbox)) {
01924       astman_send_error(s, m, "Mailbox not specified");
01925       return 0;
01926    }
01927         if (!ast_strlen_zero(id))
01928                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01929    ret = ast_app_has_voicemail(mailbox, NULL);
01930    astman_append(s, "Response: Success\r\n"
01931                "%s"
01932                "Message: Mailbox Status\r\n"
01933                "Mailbox: %s\r\n"
01934                "Waiting: %d\r\n\r\n", idText, mailbox, ret);
01935    return 0;
01936 }

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

Definition at line 1799 of file manager.c.

References app, ast_callerid_parse(), ast_calloc, ast_findlabel_extension(), AST_FORMAT_SLINEAR, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pthread_create, ast_shrink_phone_number(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), context, ast_channel::data, exten, fast_originate(), name, ast_channel::priority, s, ast_channel::tech, and timeout.

Referenced by init_manager().

01800 {
01801    const char *name = astman_get_header(m, "Channel");
01802    const char *exten = astman_get_header(m, "Exten");
01803    const char *context = astman_get_header(m, "Context");
01804    const char *priority = astman_get_header(m, "Priority");
01805    const char *timeout = astman_get_header(m, "Timeout");
01806    const char *callerid = astman_get_header(m, "CallerID");
01807    const char *account = astman_get_header(m, "Account");
01808    const char *app = astman_get_header(m, "Application");
01809    const char *appdata = astman_get_header(m, "Data");
01810    const char *async = astman_get_header(m, "Async");
01811    const char *id = astman_get_header(m, "ActionID");
01812    struct ast_variable *vars = astman_get_variables(m);
01813    char *tech, *data;
01814    char *l = NULL, *n = NULL;
01815    int pi = 0;
01816    int res;
01817    int to = 30000;
01818    int reason = 0;
01819    char tmp[256];
01820    char tmp2[256];
01821    
01822    pthread_t th;
01823    pthread_attr_t attr;
01824    if (!name) {
01825       astman_send_error(s, m, "Channel not specified");
01826       return 0;
01827    }
01828    if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) {
01829       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
01830          astman_send_error(s, m, "Invalid priority\n");
01831          return 0;
01832       }
01833    }
01834    if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) {
01835       astman_send_error(s, m, "Invalid timeout\n");
01836       return 0;
01837    }
01838    ast_copy_string(tmp, name, sizeof(tmp));
01839    tech = tmp;
01840    data = strchr(tmp, '/');
01841    if (!data) {
01842       astman_send_error(s, m, "Invalid channel\n");
01843       return 0;
01844    }
01845    *data++ = '\0';
01846    ast_copy_string(tmp2, callerid, sizeof(tmp2));
01847    ast_callerid_parse(tmp2, &n, &l);
01848    if (n) {
01849       if (ast_strlen_zero(n))
01850          n = NULL;
01851    }
01852    if (l) {
01853       ast_shrink_phone_number(l);
01854       if (ast_strlen_zero(l))
01855          l = NULL;
01856    }
01857    if (ast_true(async)) {
01858       struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast));
01859       if (!fast) {
01860          res = -1;
01861       } else {
01862          if (!ast_strlen_zero(id))
01863             snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s\r\n", id);
01864          ast_copy_string(fast->tech, tech, sizeof(fast->tech));
01865             ast_copy_string(fast->data, data, sizeof(fast->data));
01866          ast_copy_string(fast->app, app, sizeof(fast->app));
01867          ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata));
01868          if (l)
01869             ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num));
01870          if (n)
01871             ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name));
01872          fast->vars = vars;   
01873          ast_copy_string(fast->context, context, sizeof(fast->context));
01874          ast_copy_string(fast->exten, exten, sizeof(fast->exten));
01875          ast_copy_string(fast->account, account, sizeof(fast->account));
01876          fast->timeout = to;
01877          fast->priority = pi;
01878          pthread_attr_init(&attr);
01879          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
01880          if (ast_pthread_create(&th, &attr, fast_originate, fast)) {
01881             res = -1;
01882          } else {
01883             res = 0;
01884          }
01885          pthread_attr_destroy(&attr);
01886       }
01887    } else if (!ast_strlen_zero(app)) {
01888          res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
01889       } else {
01890       if (exten && context && pi)
01891             res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL);
01892       else {
01893          astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
01894          return 0;
01895       }
01896    }   
01897    if (!res)
01898       astman_send_ack(s, m, "Originate successfully queued");
01899    else
01900       astman_send_error(s, m, "Originate failed");
01901    return 0;
01902 }

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

Definition at line 1098 of file manager.c.

References astman_send_response(), and s.

Referenced by init_manager().

01099 {
01100    astman_send_response(s, m, "Pong", NULL);
01101    return 0;
01102 }

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

action_redirect: The redirect manager command

Definition at line 1619 of file manager.c.

References ast_async_goto(), ast_channel_unlock, ast_check_hangup(), ast_findlabel_extension(), ast_get_channel_by_name_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, exten, name, and s.

Referenced by init_manager().

01620 {
01621    const char *name = astman_get_header(m, "Channel");
01622    const char *name2 = astman_get_header(m, "ExtraChannel");
01623    const char *exten = astman_get_header(m, "Exten");
01624    const char *context = astman_get_header(m, "Context");
01625    const char *priority = astman_get_header(m, "Priority");
01626    struct ast_channel *chan, *chan2 = NULL;
01627    int pi = 0;
01628    int res;
01629 
01630    if (ast_strlen_zero(name)) {
01631       astman_send_error(s, m, "Channel not specified");
01632       return 0;
01633    }
01634    if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) {
01635       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
01636          astman_send_error(s, m, "Invalid priority\n");
01637          return 0;
01638       }
01639    }
01640    /* XXX watch out, possible deadlock!!! */
01641    chan = ast_get_channel_by_name_locked(name);
01642    if (!chan) {
01643       char buf[BUFSIZ];
01644       snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
01645       astman_send_error(s, m, buf);
01646       return 0;
01647    }
01648    if (ast_check_hangup(chan)) {
01649       astman_send_error(s, m, "Redirect failed, channel not up.\n");
01650       ast_channel_unlock(chan);
01651       return 0;
01652    }
01653    if (!ast_strlen_zero(name2))
01654       chan2 = ast_get_channel_by_name_locked(name2);
01655    if (chan2 && ast_check_hangup(chan2)) {
01656       astman_send_error(s, m, "Redirect failed, extra channel not up.\n");
01657       ast_channel_unlock(chan);
01658       ast_channel_unlock(chan2);
01659       return 0;
01660    }
01661    res = ast_async_goto(chan, context, exten, pi);
01662    if (!res) {
01663       if (!ast_strlen_zero(name2)) {
01664          if (chan2)
01665             res = ast_async_goto(chan2, context, exten, pi);
01666          else
01667             res = -1;
01668          if (!res)
01669             astman_send_ack(s, m, "Dual Redirect successful");
01670          else
01671             astman_send_error(s, m, "Secondary redirect failed");
01672       } else
01673          astman_send_ack(s, m, "Redirect successful");
01674    } else
01675       astman_send_error(s, m, "Redirect failed");
01676    if (chan)
01677       ast_channel_unlock(chan);
01678    if (chan2)
01679       ast_channel_unlock(chan2);
01680    return 0;
01681 }

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

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

01437 {
01438         struct ast_channel *c = NULL;
01439    const char *name = astman_get_header(m, "Channel");
01440    const char *varname = astman_get_header(m, "Variable");
01441    const char *varval = astman_get_header(m, "Value");
01442    
01443    if (ast_strlen_zero(varname)) {
01444       astman_send_error(s, m, "No variable specified");
01445       return 0;
01446    }
01447    
01448    if (!ast_strlen_zero(name)) {
01449       c = ast_get_channel_by_name_locked(name);
01450       if (!c) {
01451          astman_send_error(s, m, "No such channel");
01452          return 0;
01453       }
01454    }
01455    
01456    pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
01457      
01458    if (c)
01459       ast_channel_unlock(c);
01460 
01461    astman_send_ack(s, m, "Variable Set"); 
01462 
01463    return 0;
01464 }

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

Manager "status" command to show channels.

Definition at line 1518 of file manager.c.

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

Referenced by init_manager().

01519 {
01520    const char *id = astman_get_header(m,"ActionID");
01521       const char *name = astman_get_header(m,"Channel");
01522    char idText[256] = "";
01523    struct ast_channel *c;
01524    char bridge[256];
01525    struct timeval now = ast_tvnow();
01526    long elapsed_seconds = 0;
01527    int all = ast_strlen_zero(name); /* set if we want all channels */
01528 
01529    if (!ast_strlen_zero(id))
01530       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01531    if (all)
01532       c = ast_channel_walk_locked(NULL);
01533    else {
01534       c = ast_get_channel_by_name_locked(name);
01535       if (!c) {
01536          astman_send_error(s, m, "No such channel");
01537          return 0;
01538       }
01539    }
01540    astman_send_ack(s, m, "Channel status will follow");
01541    /* if we look by name, we break after the first iteration */
01542    while (c) {
01543       if (c->_bridge)
01544          snprintf(bridge, sizeof(bridge), "Link: %s\r\n", c->_bridge->name);
01545       else
01546          bridge[0] = '\0';
01547       if (c->pbx) {
01548          if (c->cdr) {
01549             elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
01550          }
01551          astman_append(s,
01552          "Event: Status\r\n"
01553          "Privilege: Call\r\n"
01554          "Channel: %s\r\n"
01555          "CallerID: %s\r\n"      /* This parameter is deprecated and will be removed post-1.4 */
01556          "CallerIDNum: %s\r\n"
01557          "CallerIDName: %s\r\n"
01558          "Account: %s\r\n"
01559          "State: %s\r\n"
01560          "Context: %s\r\n"
01561          "Extension: %s\r\n"
01562          "Priority: %d\r\n"
01563          "Seconds: %ld\r\n"
01564          "%s"
01565          "Uniqueid: %s\r\n"
01566          "%s"
01567          "\r\n",
01568          c->name, 
01569          S_OR(c->cid.cid_num, "<unknown>"), 
01570          S_OR(c->cid.cid_num, "<unknown>"), 
01571          S_OR(c->cid.cid_name, "<unknown>"), 
01572          c->accountcode,
01573          ast_state2str(c->_state), c->context,
01574          c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, idText);
01575       } else {
01576          astman_append(s,
01577          "Event: Status\r\n"
01578          "Privilege: Call\r\n"
01579          "Channel: %s\r\n"
01580          "CallerID: %s\r\n"      /* This parameter is deprecated and will be removed post-1.4 */
01581          "CallerIDNum: %s\r\n"
01582          "CallerIDName: %s\r\n"
01583          "Account: %s\r\n"
01584          "State: %s\r\n"
01585          "%s"
01586          "Uniqueid: %s\r\n"
01587          "%s"
01588          "\r\n",
01589          c->name, 
01590          S_OR(c->cid.cid_num, "<unknown>"), 
01591          S_OR(c->cid.cid_num, "<unknown>"), 
01592          S_OR(c->cid.cid_name, "<unknown>"), 
01593          c->accountcode,
01594          ast_state2str(c->_state), bridge, c->uniqueid, idText);
01595       }
01596       ast_channel_unlock(c);
01597       if (!all)
01598          break;
01599       c = ast_channel_walk_locked(c);
01600    }
01601    astman_append(s,
01602    "Event: StatusComplete\r\n"
01603    "%s"
01604    "\r\n",idText);
01605    return 0;
01606 }

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

Definition at line 2022 of file manager.c.

References ast_channel_setwhentohangup(), ast_channel_unlock, ast_get_channel_by_name_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, s, and timeout.

Referenced by init_manager().

02023 {
02024    struct ast_channel *c = NULL;
02025    const char *name = astman_get_header(m, "Channel");
02026    int timeout = atoi(astman_get_header(m, "Timeout"));
02027    if (ast_strlen_zero(name)) {
02028       astman_send_error(s, m, "No channel specified");
02029       return 0;
02030    }
02031    if (!timeout) {
02032       astman_send_error(s, m, "No timeout specified");
02033       return 0;
02034    }
02035    c = ast_get_channel_by_name_locked(name);
02036    if (!c) {
02037       astman_send_error(s, m, "No such channel");
02038       return 0;
02039    }
02040    ast_channel_setwhentohangup(c, timeout);
02041    ast_channel_unlock(c);
02042    astman_send_ack(s, m, "Timeout Set");
02043    return 0;
02044 }

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

Definition at line 1221 of file manager.c.

References ast_config_destroy(), ast_config_load_with_comments(), ast_module_reload(), ast_strlen_zero(), ast_true(), astman_append(), astman_get_header(), astman_send_error(), config_text_file_save(), handle_updates(), and s.

Referenced by init_manager().

01222 {
01223    struct ast_config *cfg;
01224    const char *sfn = astman_get_header(m, "SrcFilename");
01225    const char *dfn = astman_get_header(m, "DstFilename");
01226    int res;
01227    char idText[256] = "";
01228    const char *id = astman_get_header(m, "ActionID");
01229    const char *rld = astman_get_header(m, "Reload");
01230 
01231    if (!ast_strlen_zero(id))
01232       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01233 
01234    if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
01235       astman_send_error(s, m, "Filename not specified");
01236       return 0;
01237    }
01238    if (!(cfg = ast_config_load_with_comments(sfn))) {
01239       astman_send_error(s, m, "Config file not found");
01240       return 0;
01241    }
01242    handle_updates(s, m, cfg);
01243    res = config_text_file_save(dfn, cfg, "Manager");
01244    ast_config_destroy(cfg);
01245    if (res) {
01246       astman_send_error(s, m, "Save of config failed");
01247       return 0;
01248    }
01249    astman_append(s, "Response: Success\r\n%s\r\n", idText);
01250    if (!ast_strlen_zero(rld)) {
01251       if (ast_true(rld))
01252          rld = NULL;
01253       ast_module_reload(rld); 
01254    }
01255    return 0;
01256 }

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

Definition at line 2079 of file manager.c.

References astman_get_header(), event, EVENT_FLAG_USER, message::hdrcount, message::headers, and manager_event().

Referenced by init_manager().

02080 {
02081    const char *event = astman_get_header(m, "UserEvent");
02082    char body[2048] = "";
02083    int x, bodylen = 0;
02084    for (x = 0; x < m->hdrcount; x++) {
02085       if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
02086          ast_copy_string(body + bodylen, m->headers[x], sizeof(body) - bodylen - 3);
02087          bodylen += strlen(m->headers[x]);
02088          ast_copy_string(body + bodylen, "\r\n", 3);
02089          bodylen += 2;
02090       }
02091    }
02092 
02093    manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body);
02094    return 0;
02095 }

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

Definition at line 1266 of file manager.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_strlen_zero(), ast_wait_for_input(), astman_append(), astman_get_header(), astman_send_response(), eventqent::category, eventqent::eventdata, LOG_DEBUG, option_debug, s, timeout, and unuse_eventqent().

Referenced by init_manager().

01267 {
01268    const char *timeouts = astman_get_header(m, "Timeout");
01269    int timeout = -1, max;
01270    int x;
01271    int needexit = 0;
01272    time_t now;
01273    struct eventqent *eqe;
01274    const char *id = astman_get_header(m,"ActionID");
01275    char idText[256] = "";
01276 
01277    if (!ast_strlen_zero(id))
01278       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01279 
01280    if (!ast_strlen_zero(timeouts)) {
01281       sscanf(timeouts, "%i", &timeout);
01282    }
01283    
01284    ast_mutex_lock(&s->__lock);
01285    if (s->waiting_thread != AST_PTHREADT_NULL) {
01286       pthread_kill(s->waiting_thread, SIGURG);
01287    }
01288    if (s->sessiontimeout) {
01289       time(&now);
01290       max = s->sessiontimeout - now - 10;
01291       if (max < 0)
01292          max = 0;
01293       if ((timeout < 0) || (timeout > max))
01294          timeout = max;
01295       if (!s->send_events)
01296          s->send_events = -1;
01297       /* Once waitevent is called, always queue events from now on */
01298    }
01299    ast_mutex_unlock(&s->__lock);
01300    s->waiting_thread = pthread_self();
01301    if (option_debug)
01302       ast_log(LOG_DEBUG, "Starting waiting for an event!\n");
01303    for (x=0; ((x < timeout) || (timeout < 0)); x++) {
01304       ast_mutex_lock(&s->__lock);
01305       if (s->eventq && s->eventq->next)
01306          needexit = 1;
01307       if (s->waiting_thread != pthread_self())
01308          needexit = 1;
01309       if (s->needdestroy)
01310          needexit = 1;
01311       ast_mutex_unlock(&s->__lock);
01312       if (needexit)
01313          break;
01314       if (s->fd > 0) {
01315          if (ast_wait_for_input(s->fd, 1000))
01316             break;
01317       } else {
01318          sleep(1);
01319       }
01320    }
01321    if (option_debug)
01322       ast_log(LOG_DEBUG, "Finished waiting for an event!\n");
01323    ast_mutex_lock(&s->__lock);
01324    if (s->waiting_thread == pthread_self()) {
01325       astman_send_response(s, m, "Success", "Waiting for Event...");
01326       /* Only show events if we're the most recent waiter */
01327       while(s->eventq->next) {
01328          eqe = s->eventq->next;
01329          if (((s->readperm & eqe->category) == eqe->category) &&
01330              ((s->send_events & eqe->category) == eqe->category)) {
01331             astman_append(s, "%s", eqe->eventdata);
01332          }
01333          unuse_eventqent(s->eventq);
01334          s->eventq = eqe;
01335       }
01336       astman_append(s,
01337          "Event: WaitEventComplete\r\n"
01338          "%s"
01339          "\r\n", idText);
01340       s->waiting_thread = AST_PTHREADT_NULL;
01341    } else {
01342       ast_log(LOG_DEBUG, "Abandoning event request!\n");
01343    }
01344    ast_mutex_unlock(&s->__lock);
01345    return 0;
01346 }

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

Definition at line 2400 of file manager.c.

References ast_malloc, master_eventq, eventqent::next, num_sessions, and eventqent::usecount.

Referenced by init_manager(), and manager_event().

02401 {
02402    struct eventqent *tmp, *prev = NULL;
02403    tmp = ast_malloc(sizeof(*tmp) + strlen(str));
02404 
02405    if (!tmp)
02406       return -1;
02407 
02408    tmp->next = NULL;
02409    tmp->category = category;
02410    strcpy(tmp->eventdata, str);
02411    
02412    if (master_eventq) {
02413       prev = master_eventq;
02414       while (prev->next) 
02415          prev = prev->next;
02416       prev->next = tmp;
02417    } else {
02418       master_eventq = tmp;
02419    }
02420    
02421    tmp->usecount = num_sessions;
02422    
02423    return 0;
02424 }

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

Definition at line 467 of file manager.c.

References AST_LIST_TRAVERSE, ast_manager_user::username, and users.

Referenced by handle_showmanager(), and init_manager().

00468 {
00469    struct ast_manager_user *user = NULL;
00470 
00471    AST_LIST_TRAVERSE(&users, user, list)
00472       if (!strcasecmp(user->username, name))
00473          break;
00474    return user;
00475 }

static int ast_instring ( const char *  bigstr,
const char *  smallstr,
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 854 of file manager.c.

References ast_variable::next.

Referenced by get_perm(), and strings_to_mask().

00855 {
00856    const char *val = bigstr, *next;
00857 
00858    do {
00859       if ((next = strchr(val, delim))) {
00860          if (!strncmp(val, smallstr, (next - val)))
00861             return 1;
00862          else
00863             continue;
00864       } else
00865          return !strcmp(smallstr, val);
00866 
00867    } while (*(val = (next + 1)));
00868 
00869    return 0;
00870 }

static int ast_is_number ( const char *  string  )  [static]

Definition at line 887 of file manager.c.

Referenced by strings_to_mask().

00888 {
00889    int ret = 1, x = 0;
00890 
00891    if (!string)
00892       return 0;
00893 
00894    for (x = 0; x < strlen(string); x++) {
00895       if (!(string[x] >= 48 && string[x] <= 57)) {
00896          ret = 0;
00897          break;
00898       }
00899    }
00900    
00901    return ret ? atoi(string) : 0;
00902 }

static AST_LIST_HEAD_STATIC ( users  ,
ast_manager_user   
) [static]

static AST_LIST_HEAD_STATIC ( sessions  ,
mansession   
) [static]

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 new command with manager, including online help. This is the preferred way to register a manager command

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

References ast_malloc, and ast_manager_register_struct().

Referenced by init_manager(), and load_module().

02547 {
02548    struct manager_action *cur;
02549 
02550    cur = ast_malloc(sizeof(*cur));
02551    if (!cur)
02552       return -1;
02553    
02554    cur->action = action;
02555    cur->authority = auth;
02556    cur->func = func;
02557    cur->synopsis = synopsis;
02558    cur->description = description;
02559    cur->next = NULL;
02560 
02561    ast_manager_register_struct(cur);
02562 
02563    return 0;
02564 }

static int ast_manager_register_struct ( struct manager_action act  )  [static]

Definition at line 2502 of file manager.c.

References manager_action::action, ast_log(), ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_verbose(), first_action, LOG_WARNING, manager_action::next, option_verbose, and VERBOSE_PREFIX_2.

Referenced by ast_manager_register2().

02503 {
02504    struct manager_action *cur, *prev = NULL;
02505    int ret;
02506 
02507    ast_rwlock_wrlock(&actionlock);
02508    cur = first_action;
02509    while (cur) { /* Walk the list of actions */
02510       ret = strcasecmp(cur->action, act->action);
02511       if (ret == 0) {
02512          ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
02513          ast_rwlock_unlock(&actionlock);
02514          return -1;
02515       } else if (ret > 0) {
02516          /* Insert these alphabetically */
02517          if (prev) {
02518             act->next = prev->next;
02519             prev->next = act;
02520          } else {
02521             act->next = first_action;
02522             first_action = act;
02523          }
02524          break;
02525       }
02526       prev = cur; 
02527       cur = cur->next;
02528    }
02529    
02530    if (!cur) {
02531       if (prev)
02532          prev->next = act;
02533       else
02534          first_action = act;
02535       act->next = NULL;
02536    }
02537 
02538    if (option_verbose > 1) 
02539       ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", act->action);
02540    ast_rwlock_unlock(&actionlock);
02541    return 0;
02542 }

int ast_manager_unregister ( char *  action  ) 

Parameters:
action Name of registred Action:

Definition at line 2473 of file manager.c.

References manager_action::action, ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_verbose(), first_action, free, manager_action::next, option_verbose, and VERBOSE_PREFIX_2.

Referenced by __unload_module(), and unload_module().

02474 {
02475    struct manager_action *cur, *prev;
02476 
02477    ast_rwlock_wrlock(&actionlock);
02478    cur = prev = first_action;
02479    while (cur) {
02480       if (!strcasecmp(action, cur->action)) {
02481          prev->next = cur->next;
02482          free(cur);
02483          if (option_verbose > 1) 
02484             ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action);
02485          ast_rwlock_unlock(&actionlock);
02486          return 0;
02487       }
02488       prev = cur;
02489       cur = cur->next;
02490    }
02491    ast_rwlock_unlock(&actionlock);
02492    return 0;
02493 }

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

Definition at line 477 of file manager.c.

References ast_calloc, ast_carefulwrite(), ast_dynamic_str_thread_set_va, ast_mutex_lock(), ast_mutex_unlock(), ASTMAN_APPEND_BUF_INITSIZE, and s.

Referenced by __iax2_show_peers(), __queues_show(), _sip_show_peer(), _sip_show_peers(), action_agents(), action_command(), action_extensionstate(), action_getconfig(), action_getvar(), action_listcommands(), action_mailboxcount(), action_mailboxstatus(), action_status(), action_updateconfig(), action_waitevent(), action_zapshowchannels(), ast_cli_netstats(), astman_send_error(), astman_send_response(), manager_dbget(), manager_iax2_show_netstats(), manager_iax2_show_peers(), manager_jabber_send(), manager_parking_status(), manager_queues_show(), manager_queues_status(), manager_sip_show_peer(), manager_sip_show_peers(), process_message(), and session_do().

00478 {
00479    va_list ap;
00480    struct ast_dynamic_str *buf;
00481 
00482    ast_mutex_lock(&s->__lock);
00483 
00484    if (!(buf = ast_dynamic_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) {
00485       ast_mutex_unlock(&s->__lock);
00486       return;
00487    }
00488 
00489    va_start(ap, fmt);
00490    ast_dynamic_str_thread_set_va(&buf, 0, &astman_append_buf, fmt, ap);
00491    va_end(ap);
00492    
00493    if (s->fd > -1)
00494       ast_carefulwrite(s->fd, buf->str, strlen(buf->str), s->writetimeout);
00495    else {
00496       if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) {
00497          ast_mutex_unlock(&s->__lock);
00498          return;
00499       }
00500 
00501       ast_dynamic_str_append(&s->outputstr, 0, "%s", buf->str);   
00502    }
00503 
00504    ast_mutex_unlock(&s->__lock);
00505 }

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

Get header from mananger transaction

Definition at line 757 of file manager.c.

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

Referenced by _sip_show_peer(), _sip_show_peers(), action_agent_callback_login(), action_agent_logoff(), action_agents(), action_bridge(), action_command(), action_devstate(), action_events(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_listcommands(), action_mailboxcount(), action_mailboxstatus(), action_originate(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), action_waitevent(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zapshowchannels(), astman_send_error(), astman_send_response(), authenticate(), change_monitor_action(), do_pause_or_unpause(), handle_updates(), manager_add_queue_member(), manager_dbget(), manager_dbput(), manager_iax2_show_peers(), manager_jabber_send(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queues_status(), manager_remove_queue_member(), manager_sip_show_peer(), manager_sip_show_peers(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().

00758 {
00759    char cmp[80];
00760    int x;
00761 
00762    snprintf(cmp, sizeof(cmp), "%s: ", var);
00763 
00764    for (x = 0; x < m->hdrcount; x++) {
00765       if (!strncasecmp(cmp, m->headers[x], strlen(cmp)))
00766          return m->headers[x] + strlen(cmp);
00767    }
00768 
00769    return "";
00770 }

struct ast_variable* astman_get_variables ( const struct message m  ) 

Get a linked list of the Variable: headers

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

00773 {
00774    int varlen, x, y;
00775    struct ast_variable *head = NULL, *cur;
00776    char *var, *val;
00777 
00778    char *parse;    
00779    AST_DECLARE_APP_ARGS(args,
00780       AST_APP_ARG(vars)[32];
00781    );
00782 
00783    varlen = strlen("Variable: ");   
00784 
00785    for (x = 0; x < m->hdrcount; x++) {
00786       if (strncasecmp("Variable: ", m->headers[x], varlen))
00787          continue;
00788 
00789       parse = ast_strdupa(m->headers[x] + varlen);
00790 
00791       AST_STANDARD_APP_ARGS(args, parse);
00792       if (args.argc) {
00793          for (y = 0; y < args.argc; y++) {
00794             if (!args.vars[y])
00795                continue;
00796             var = val = ast_strdupa(args.vars[y]);
00797             strsep(&val, "=");
00798             if (!val || ast_strlen_zero(var))
00799                continue;
00800             cur = ast_variable_new(var, val);
00801             if (head) {
00802                cur->next = head;
00803                head = cur;
00804             } else
00805                head = cur;
00806          }
00807       }
00808    }
00809 
00810    return head;
00811 }

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

Definition at line 844 of file manager.c.

References astman_send_response(), and s.

Referenced by action_agent_callback_login(), action_agent_logoff(), action_agents(), action_bridge(), action_hangup(), action_originate(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), action_zapshowchannels(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queues_status(), manager_remove_queue_member(), manager_sip_show_peers(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().

00845 {
00846    astman_send_response(s, m, "Success", msg);
00847 }

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

Note:
NOTE: Callers of astman_send_error(), astman_send_response() or astman_send_ack() must EITHER hold the session lock _or_ be running in an action callback (in which case s->busy will be non-zero). In either of these cases, there is no need to lock-protect the session's fd, since no other output will be sent (events will be queued), and no input will be read until either the current action finishes or get_input() obtains the session lock.

Definition at line 821 of file manager.c.

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

Referenced by _sip_show_peer(), action_agent_callback_login(), action_agent_logoff(), action_bridge(), action_command(), action_devstate(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_mailboxcount(), action_mailboxstatus(), action_originate(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_park(), manager_pause_queue_member(), manager_play_dtmf(), manager_remove_queue_member(), manager_sip_show_peer(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().

00822 {
00823    const char *id = astman_get_header(m,"ActionID");
00824 
00825    astman_append(s, "Response: Error\r\n");
00826    if (!ast_strlen_zero(id))
00827       astman_append(s, "ActionID: %s\r\n", id);
00828    astman_append(s, "Message: %s\r\n\r\n", error);
00829 }

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

Definition at line 831 of file manager.c.

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

Referenced by action_events(), action_logoff(), action_ping(), action_waitevent(), and astman_send_ack().

00832 {
00833    const char *id = astman_get_header(m,"ActionID");
00834 
00835    astman_append(s, "Response: %s\r\n", resp);
00836    if (!ast_strlen_zero(id))
00837       astman_append(s, "ActionID: %s\r\n", id);
00838    if (msg)
00839       astman_append(s, "Message: %s\r\n\r\n", msg);
00840    else
00841       astman_append(s, "\r\n");
00842 }

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

Definition at line 947 of file manager.c.

References ast_append_ha(), ast_apply_ha(), ast_category_browse(), ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load(), ast_free_ha(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_true(), ast_variable_browse(), astman_get_header(), events, key(), len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), ast_variable::name, ast_variable::next, password, s, S_OR, and ast_variable::value.

Referenced by authenticate_reply(), handle_response_invite(), process_message(), and registry_rerequest().

00948 {
00949    struct ast_config *cfg;
00950    char *cat;
00951    const char *user = astman_get_header(m, "Username");
00952    const char *pass = astman_get_header(m, "Secret");
00953    const char *authtype = astman_get_header(m, "AuthType");
00954    const char *key = astman_get_header(m, "Key");
00955    const char *events = astman_get_header(m, "Events");
00956    
00957    cfg = ast_config_load("manager.conf");
00958    if (!cfg)
00959       return -1;
00960    cat = ast_category_browse(cfg, NULL);
00961    while (cat) {
00962       if (strcasecmp(cat, "general")) {
00963          /* This is a user */
00964          if (!strcasecmp(cat, user)) {
00965             struct ast_variable *v;
00966             struct ast_ha *ha = NULL;
00967             char *password = NULL;
00968 
00969             for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
00970                if (!strcasecmp(v->name, "secret")) {
00971                   password = v->value;
00972                } else if (!strcasecmp(v->name, "displaysystemname")) {
00973                   if (ast_true(v->value)) {
00974                      if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
00975                         s->displaysystemname = 1;
00976                      } else {
00977                         ast_log(LOG_ERROR, "Can't enable displaysystemname in manager.conf - no system name configured in asterisk.conf\n");
00978                      }
00979                   }
00980                } else if (!strcasecmp(v->name, "permit") ||
00981                      !strcasecmp(v->name, "deny")) {
00982                   ha = ast_append_ha(v->name, v->value, ha);
00983                } else if (!strcasecmp(v->name, "writetimeout")) {
00984                   int val = atoi(v->value);
00985 
00986                   if (val < 100)
00987                      ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", v->value, v->lineno);
00988                   else
00989                      s->writetimeout = val;
00990                }
00991                      
00992             }
00993             if (ha && !ast_apply_ha(ha, &(s->sin))) {
00994                ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);
00995                ast_free_ha(ha);
00996                ast_config_destroy(cfg);
00997                return -1;
00998             } else if (ha)
00999                ast_free_ha(ha);
01000             if (!strcasecmp(authtype, "MD5")) {
01001                if (!ast_strlen_zero(key) && 
01002                    !ast_strlen_zero(s->challenge) && !ast_strlen_zero(password)) {
01003                   int x;
01004                   int len = 0;
01005                   char md5key[256] = "";
01006                   struct MD5Context md5;
01007                   unsigned char digest[16];
01008                   MD5Init(&md5);
01009                   MD5Update(&md5, (unsigned char *) s->challenge, strlen(s->challenge));
01010                   MD5Update(&md5, (unsigned char *) password, strlen(password));
01011                   MD5Final(digest, &md5);
01012                   for (x=0; x<16; x++)
01013                      len += sprintf(md5key + len, "%2.2x", digest[x]);
01014                   if (!strcmp(md5key, key))
01015                      break;
01016                   else {
01017                      ast_config_destroy(cfg);
01018                      return -1;
01019                   }
01020                } else {
01021                   ast_log(LOG_DEBUG, "MD5 authentication is not possible.  challenge: '%s'\n", 
01022                      S_OR(s->challenge, ""));
01023                   ast_config_destroy(cfg);
01024                   return -1;
01025                }
01026             } else if (password && !strcmp(password, pass)) {
01027                break;
01028             } else {
01029                ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);
01030                ast_config_destroy(cfg);
01031                return -1;
01032             }  
01033          }
01034       }
01035       cat = ast_category_browse(cfg, cat);
01036    }
01037    if (cat) {
01038       ast_copy_string(s->username, cat, sizeof(s->username));
01039       s->readperm = get_perm(ast_variable_retrieve(cfg, cat, "read"));
01040       s->writeperm = get_perm(ast_variable_retrieve(cfg, cat, "write"));
01041       ast_config_destroy(cfg);
01042       if (events)
01043          set_eventmask(s, events);
01044       return 0;
01045    }
01046    ast_config_destroy(cfg);
01047    cfg = ast_config_load("users.conf");
01048    if (!cfg)
01049       return -1;
01050    cat = ast_category_browse(cfg, NULL);
01051    while (cat) {
01052       struct ast_variable *v;
01053       const char *password = NULL;
01054       int hasmanager = 0;
01055       const char *readperms = NULL;
01056       const char *writeperms = NULL;
01057 
01058       if (strcasecmp(cat, user) || !strcasecmp(cat, "general")) {
01059          cat = ast_category_browse(cfg, cat);
01060          continue;
01061       }
01062       for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
01063          if (!strcasecmp(v->name, "secret"))
01064             password = v->value;
01065          else if (!strcasecmp(v->name, "hasmanager"))
01066             hasmanager = ast_true(v->value);
01067          else if (!strcasecmp(v->name, "managerread"))
01068             readperms = v->value;
01069          else if (!strcasecmp(v->name, "managerwrite"))
01070             writeperms = v->value;
01071       }
01072       if (!hasmanager)
01073          break;
01074       if (!password || strcmp(password, pass)) {
01075          ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);
01076          ast_config_destroy(cfg);
01077          return -1;
01078       }
01079       ast_copy_string(s->username, cat, sizeof(s->username));
01080       s->readperm = readperms ? get_perm(readperms) : -1;
01081       s->writeperm = writeperms ? get_perm(writeperms) : -1;
01082       ast_config_destroy(cfg);
01083       if (events)
01084          set_eventmask(s, events);
01085       return 0;
01086    }
01087    ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);
01088    ast_config_destroy(cfg);
01089    return -1;
01090 }

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

Convert authority code to string with serveral options.

Definition at line 201 of file manager.c.

References ast_strlen_zero(), and perms.

Referenced by action_listcommands(), handle_showmancmd(), handle_showmancmds(), and manager_event().

00202 {
00203    int running_total = 0, i;
00204 
00205    memset(res, 0, reslen);
00206    for (i = 0; i < (sizeof(perms) / sizeof(perms[0])) - 1; i++) {
00207       if (authority & perms[i].num) {
00208          if (*res) {
00209             strncat(res, ",", (reslen > running_total) ? reslen - running_total - 1 : 0);
00210             running_total++;
00211          }
00212          strncat(res, perms[i].label, (reslen > running_total) ? reslen - running_total - 1 : 0);
00213          running_total += strlen(perms[i].label);
00214       }
00215    }
00216 
00217    if (ast_strlen_zero(res))
00218       ast_copy_string(res, "<none>", reslen);
00219    
00220    return res;
00221 }

static char* complete_show_mancmd ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 223 of file manager.c.

References manager_action::action, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_strdup, first_action, and manager_action::next.

00224 {
00225    struct manager_action *cur;
00226    int which = 0;
00227    char *ret = NULL;
00228 
00229    ast_rwlock_rdlock(&actionlock);
00230    for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */
00231       if (!strncasecmp(word, cur->action, strlen(word)) && ++which > state) {
00232          ret = ast_strdup(cur->action);
00233          break;   /* make sure we exit even if ast_strdup() returns NULL */
00234       }
00235    }
00236    ast_rwlock_unlock(&actionlock);
00237 
00238    return ret;
00239 }

static int compress_char ( char  c  )  [static]

Definition at line 283 of file manager.c.

Referenced by member_hash_fn(), and variable_count_hash_fn().

00284 {
00285    c &= 0x7f;
00286    if (c < 32)
00287       return 0;
00288    else if (c >= 'a' && c <= 'z')
00289       return c - 64;
00290    else if (c > 'z')
00291       return '_';
00292    else
00293       return c - 32;
00294 }

static void destroy_session ( struct mansession s  )  [static]

Definition at line 748 of file manager.c.

References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, free_session(), s, and sessions.

Referenced by accept_thread(), and skinny_session().

00749 {
00750    AST_LIST_LOCK(&sessions);
00751    AST_LIST_REMOVE(&sessions, s, list);
00752    num_sessions--;
00753    free_session(s);
00754    AST_LIST_UNLOCK(&sessions);
00755 }

static int do_message ( struct mansession s  )  [static]

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

02234 {
02235    struct message m = { 0 };
02236    char header_buf[sizeof(s->inbuf)] = { '\0' };
02237    int res;
02238 
02239    for (;;) {
02240       /* Check if any events are pending and do them if needed */
02241       if (s->eventq->next) {
02242          if (process_events(s))
02243             return -1;
02244       }
02245       res = get_input(s, header_buf);
02246       if (res == 0) {
02247          continue;
02248       } else if (res > 0) {
02249          /* Strip trailing \r\n */
02250          if (strlen(header_buf) < 2)
02251             continue;
02252          header_buf[strlen(header_buf) - 2] = '\0';
02253          if (ast_strlen_zero(header_buf))
02254             return process_message(s, &m) ? -1 : 0;
02255          else if (m.hdrcount < (AST_MAX_MANHEADERS - 1))
02256             m.headers[m.hdrcount++] = ast_strdupa(header_buf);
02257       } else {
02258          return res;
02259       }
02260    }
02261 }

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

Definition at line 1735 of file manager.c.

References fast_originate_helper::account, fast_originate_helper::app, fast_originate_helper::appdata, AST_CHANNEL_NAME, ast_channel_unlock, AST_FORMAT_SLINEAR, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_strlen_zero(), fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, fast_originate_helper::data, EVENT_FLAG_CALL, fast_originate_helper::exten, free, fast_originate_helper::idtext, manager_event(), fast_originate_helper::priority, S_OR, fast_originate_helper::tech, fast_originate_helper::timeout, and fast_originate_helper::vars.

Referenced by action_originate().

01736 {
01737    struct fast_originate_helper *in = data;
01738    int res;
01739    int reason = 0;
01740    struct ast_channel *chan = NULL;
01741    char requested_channel[AST_CHANNEL_NAME];
01742 
01743    if (!ast_strlen_zero(in->app)) {
01744       res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, 
01745          S_OR(in->cid_num, NULL), 
01746          S_OR(in->cid_name, NULL),
01747          in->vars, in->account, &chan);
01748    } else {
01749       res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 
01750          S_OR(in->cid_num, NULL), 
01751          S_OR(in->cid_name, NULL),
01752          in->vars, in->account, &chan);
01753    }
01754 
01755    if (!chan)
01756       snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);   
01757    /* Tell the manager what happened with the channel */
01758    manager_event(EVENT_FLAG_CALL, "OriginateResponse",
01759       "%s"
01760       "Response: %s\r\n"
01761       "Channel: %s\r\n"
01762       "Context: %s\r\n"
01763       "Exten: %s\r\n"
01764       "Reason: %d\r\n"
01765       "Uniqueid: %s\r\n"
01766       "CallerID: %s\r\n"      /* This parameter is deprecated and will be removed post-1.4 */
01767       "CallerIDNum: %s\r\n"
01768       "CallerIDName: %s\r\n",
01769       in->idtext, res ? "Failure" : "Success", chan ? chan->name : requested_channel, in->context, in->exten, reason, 
01770       chan ? chan->uniqueid : "<null>",
01771       S_OR(in->cid_num, "<unknown>"),
01772       S_OR(in->cid_num, "<unknown>"),
01773       S_OR(in->cid_name, "<unknown>")
01774       );
01775 
01776    /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
01777    if (chan)
01778       ast_channel_unlock(chan);
01779    free(in);
01780    return NULL;
01781 }

static void free_session ( struct mansession s  )  [static]

Definition at line 732 of file manager.c.

References ast_mutex_destroy(), free, s, and unuse_eventqent().

Referenced by accept_thread(), and destroy_session().

00733 {
00734    struct eventqent *eqe;
00735    if (s->fd > -1)
00736       close(s->fd);
00737    if (s->outputstr)
00738       free(s->outputstr);
00739    ast_mutex_destroy(&s->__lock);
00740    while (s->eventq) {
00741       eqe = s->eventq;
00742       s->eventq = s->eventq->next;
00743       unuse_eventqent(eqe);
00744    }
00745    free(s);
00746 }

static int get_input ( struct mansession s,
char *  output 
) [static]

Definition at line 2179 of file manager.c.

References ast_channel::fds, and s.

Referenced by do_message(), and skinny_session().

02180 {
02181    /* output must have at least sizeof(s->inbuf) space */
02182    int res;
02183    int x;
02184    struct pollfd fds[1];
02185    for (x = 1; x < s->inlen; x++) {
02186       if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) {
02187          /* Copy output data up to and including \r\n */
02188          memcpy(output, s->inbuf, x + 1);
02189          /* Add trailing \0 */
02190          output[x+1] = '\0';
02191          /* Move remaining data back to the front */
02192          memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x);
02193          s->inlen -= (x + 1);
02194          return 1;
02195       }
02196    } 
02197    if (s->inlen >= sizeof(s->inbuf) - 1) {
02198       ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->sin.sin_addr), s->inbuf);
02199       s->inlen = 0;
02200    }
02201    fds[0].fd = s->fd;
02202    fds[0].events = POLLIN;
02203    do {
02204       ast_mutex_lock(&s->__lock);
02205       s->waiting_thread = pthread_self();
02206       ast_mutex_unlock(&s->__lock);
02207 
02208       res = poll(fds, 1, -1);
02209 
02210       ast_mutex_lock(&s->__lock);
02211       s->waiting_thread = AST_PTHREADT_NULL;
02212       ast_mutex_unlock(&s->__lock);
02213       if (res < 0) {
02214          if (errno == EINTR) {
02215             return 0;
02216          }
02217          ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));
02218          return -1;
02219       } else if (res > 0) {
02220          ast_mutex_lock(&s->__lock);
02221          res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen);
02222          ast_mutex_unlock(&s->__lock);
02223          if (res < 1)
02224             return -1;
02225          break;
02226       }
02227    } while(1);
02228    s->inlen += res;
02229    s->inbuf[s->inlen] = '\0';
02230    return 0;
02231 }

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

Definition at line 872 of file manager.c.

References ast_instring(), and perms.

00873 {
00874    int x = 0, ret = 0;
00875 
00876    if (!instr)
00877       return 0;
00878 
00879    for (x = 0; x < (sizeof(perms) / sizeof(perms[0])); x++) {
00880       if (ast_instring(instr, perms[x].label, ','))
00881          ret |= perms[x].num;
00882    }
00883    
00884    return ret;
00885 }

static int handle_showmanager ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 529 of file manager.c.

References ast_cli(), ast_get_manager_by_name_locked(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_manager_user::deny, ast_manager_user::displayconnects, ast_manager_user::permit, ast_manager_user::read, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_manager_user::secret, ast_manager_user::username, users, and ast_manager_user::write.

00530 {
00531    struct ast_manager_user *user = NULL;
00532 
00533    if (argc != 4)
00534       return RESULT_SHOWUSAGE;
00535 
00536    AST_LIST_LOCK(&users);
00537 
00538    if (!(user = ast_get_manager_by_name_locked(argv[3]))) {
00539       ast_cli(fd, "There is no manager called %s\n", argv[3]);
00540       AST_LIST_UNLOCK(&users);
00541       return -1;
00542    }
00543 
00544    ast_cli(fd,"\n");
00545    ast_cli(fd,
00546       "       username: %s\n"
00547       "         secret: %s\n"
00548       "           deny: %s\n"
00549       "         permit: %s\n"
00550       "           read: %s\n"
00551       "          write: %s\n"
00552       "displayconnects: %s\n",
00553       (user->username ? user->username : "(N/A)"),
00554       (user->secret ? "<Set>" : "(N/A)"),
00555       (user->deny ? user->deny : "(N/A)"),
00556       (user->permit ? user->permit : "(N/A)"),
00557       (user->read ? user->read : "(N/A)"),
00558       (user->write ? user->write : "(N/A)"),
00559       (user->displayconnects ? "yes" : "no"));
00560 
00561    AST_LIST_UNLOCK(&users);
00562 
00563    return RESULT_SUCCESS;
00564 }

static int handle_showmanagers ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 567 of file manager.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_manager_user::username, and users.

00568 {
00569    struct ast_manager_user *user = NULL;
00570    int count_amu = 0;
00571 
00572    if (argc != 3)
00573       return RESULT_SHOWUSAGE;
00574 
00575    AST_LIST_LOCK(&users);
00576 
00577    /* If there are no users, print out something along those lines */
00578    if (AST_LIST_EMPTY(&users)) {
00579       ast_cli(fd, "There are no manager users.\n");
00580       AST_LIST_UNLOCK(&users);
00581       return RESULT_SUCCESS;
00582    }
00583 
00584    ast_cli(fd, "\nusername\n--------\n");
00585 
00586    AST_LIST_TRAVERSE(&users, user, list) {
00587       ast_cli(fd, "%s\n", user->username);
00588       count_amu++;
00589    }
00590 
00591    AST_LIST_UNLOCK(&users);
00592 
00593    ast_cli(fd,"-------------------\n");
00594    ast_cli(fd,"%d manager users configured.\n", count_amu);
00595 
00596    return RESULT_SUCCESS;
00597 }

static int handle_showmancmd ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 507 of file manager.c.

References manager_action::action, ast_cli(), ast_rwlock_rdlock(), manager_action::authority, authority_to_str(), manager_action::description, first_action, manager_action::next, RESULT_SHOWUSAGE, and manager_action::synopsis.

00508 {
00509    struct manager_action *cur;
00510    char authority[80];
00511    int num;
00512 
00513    if (argc != 4)
00514       return RESULT_SHOWUSAGE;
00515 
00516    ast_rwlock_rdlock(&actionlock);
00517    for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */
00518       for (num = 3; num < argc; num++) {
00519          if (!strcasecmp(cur->action, argv[num])) {
00520             ast_cli(fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", cur->action, cur->synopsis, authority_to_str(cur->authority, authority, sizeof(authority) -1), cur->description ? cur->description : "");
00521          }
00522       }
00523    }
00524    ast_rwlock_unlock(&actionlock);
00525 
00526    return RESULT_SUCCESS;
00527 }

static int handle_showmancmds ( int  fd,
int  argc,
char *  argv[] 
) [static]

CLI command Should change to "manager show commands".

Definition at line 602 of file manager.c.

References manager_action::action, ast_cli(), ast_rwlock_rdlock(), ast_rwlock_unlock(), manager_action::authority, authority_to_str(), first_action, format, manager_action::next, RESULT_SUCCESS, and manager_action::synopsis.

00603 {
00604    struct manager_action *cur;
00605    char authority[80];
00606    char *format = "  %-15.15s  %-15.15s  %-55.55s\n";
00607 
00608    ast_cli(fd, format, "Action", "Privilege", "Synopsis");
00609    ast_cli(fd, format, "------", "---------", "--------");
00610    
00611    ast_rwlock_rdlock(&actionlock);
00612    for (cur = first_action; cur; cur = cur->next) /* Walk the list of actions */
00613       ast_cli(fd, format, cur->action, authority_to_str(cur->authority, authority, sizeof(authority) -1), cur->synopsis);
00614    ast_rwlock_unlock(&actionlock);
00615    
00616    return RESULT_SUCCESS;
00617 }

static int handle_showmanconn ( int  fd,
int  argc,
char *  argv[] 
) [static]

CLI command show manager connected.

Definition at line 621 of file manager.c.

References ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, format, RESULT_SUCCESS, s, and sessions.

00622 {
00623    struct mansession *s;
00624    char *format = "  %-15.15s  %-15.15s\n";
00625 
00626    ast_cli(fd, format, "Username", "IP Address");
00627    
00628    AST_LIST_LOCK(&sessions);
00629    AST_LIST_TRAVERSE(&sessions, s, list)
00630       ast_cli(fd, format,s->username, ast_inet_ntoa(s->sin.sin_addr));
00631    AST_LIST_UNLOCK(&sessions);
00632 
00633    return RESULT_SUCCESS;
00634 }

static int handle_showmaneventq ( int  fd,
int  argc,
char *  argv[] 
) [static]

CLI command show manager connected.

Definition at line 638 of file manager.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_UNLOCK, master_eventq, RESULT_SUCCESS, s, and sessions.

00639 {
00640    struct eventqent *s;
00641 
00642    AST_LIST_LOCK(&sessions);
00643    for (s = master_eventq; s; s = s->next) {
00644       ast_cli(fd, "Usecount: %d\n",s->usecount);
00645       ast_cli(fd, "Category: %d\n", s->category);
00646       ast_cli(fd, "Event:\n%s", s->eventdata);
00647    }
00648    AST_LIST_UNLOCK(&sessions);
00649 
00650    return RESULT_SUCCESS;
00651 }

static void handle_updates ( struct mansession s,
const struct message m,
struct ast_config cfg 
) [static]

Definition at line 1147 of file manager.c.

References ast_category_append(), ast_category_delete(), ast_category_get(), ast_category_new(), ast_category_rename(), ast_strlen_zero(), ast_variable_append(), ast_variable_delete(), ast_variable_new(), ast_variable_update(), astman_get_header(), match(), ast_variable::object, ast_variable::value, and var.

Referenced by action_updateconfig().

01148 {
01149    int x;
01150    char hdr[40];
01151    const char *action, *cat, *var, *value, *match;
01152    struct ast_category *category;
01153    struct ast_variable *v;
01154    
01155    for (x=0;x<100000;x++) {
01156       unsigned int object = 0;
01157 
01158       snprintf(hdr, sizeof(hdr), "Action-%06d", x);
01159       action = astman_get_header(m, hdr);
01160       if (ast_strlen_zero(action))
01161          break;
01162       snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
01163       cat = astman_get_header(m, hdr);
01164       snprintf(hdr, sizeof(hdr), "Var-%06d", x);
01165       var = astman_get_header(m, hdr);
01166       snprintf(hdr, sizeof(hdr), "Value-%06d", x);
01167       value = astman_get_header(m, hdr);
01168       if (!ast_strlen_zero(value) && *value == '>') {
01169          object = 1;
01170          value++;
01171       }
01172       snprintf(hdr, sizeof(hdr), "Match-%06d", x);
01173       match = astman_get_header(m, hdr);
01174       if (!strcasecmp(action, "newcat")) {
01175          if (!ast_strlen_zero(cat)) {
01176             category = ast_category_new(cat);
01177             if (category) {
01178                ast_category_append(cfg, category);
01179             }
01180          }
01181       } else if (!strcasecmp(action, "renamecat")) {
01182          if (!ast_strlen_zero(cat) && !ast_strlen_zero(value)) {
01183             category = ast_category_get(cfg, cat);
01184             if (category) 
01185                ast_category_rename(category, value);
01186          }
01187       } else if (!strcasecmp(action, "delcat")) {
01188          if (!ast_strlen_zero(cat))
01189             ast_category_delete(cfg, (char *) cat);
01190       } else if (!strcasecmp(action, "update")) {
01191          if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat)))
01192             ast_variable_update(category, var, value, match, object);
01193       } else if (!strcasecmp(action, "delete")) {
01194          if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat)))
01195             ast_variable_delete(category, (char *) var, (char *) match);
01196       } else if (!strcasecmp(action, "append")) {
01197          if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && 
01198             (category = ast_category_get(cfg, cat)) && 
01199             (v = ast_variable_new(var, value))){
01200             if (object || (match && !strcasecmp(match, "object")))
01201                v->object = 1;
01202             ast_variable_append(category, v);
01203          }
01204       }
01205    }
01206 }

static char* html_translate ( char *  in  )  [static]

Definition at line 418 of file manager.c.

References ast_build_string(), ast_malloc, len, and var.

00419 {
00420    int x;
00421    int colons = 0;
00422    int breaks = 0;
00423    size_t len;
00424    int count = 1;
00425    char *tmp, *var, *val, *out;
00426 
00427    for (x=0; in[x]; x++) {
00428       if (in[x] == ':')
00429          colons++;
00430       if (in[x] == '\n')
00431          breaks++;
00432    }
00433    len = strlen(in) + colons * 40 + breaks * 40; /* <tr><td></td><td></td></tr>, "<tr><td colspan=\"2\"><hr></td></tr> */
00434    out = ast_malloc(len);
00435    if (!out)
00436       return 0;
00437    tmp = out;
00438    while (*in) {
00439       var = in;
00440       while (*in && (*in >= 32))
00441          in++;
00442       if (*in) {
00443          if ((count % 4) == 0){
00444             ast_build_string(&tmp, &len, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
00445          }
00446          count = 0;
00447          while (*in && (*in < 32)) {
00448             *in = '\0';
00449             in++;
00450             count++;
00451          }
00452          val = strchr(var, ':');
00453          if (val) {
00454             *val = '\0';
00455             val++;
00456             if (*val == ' ')
00457                val++;
00458             ast_build_string(&tmp, &len, "<tr><td>%s</td><td>%s</td></tr>\r\n", var, val);
00459          }
00460       }
00461    }
00462    return out;
00463 }

int manager_event ( int  category,
const char *  event,
const char *  fmt,
  ... 
)

manager_event: Send AMI event to client

Definition at line 2427 of file manager.c.

References append_event(), ast_dynamic_str_thread_append(), ast_dynamic_str_thread_append_va, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, authority_to_str(), MANAGER_EVENT_BUF_INITSIZE, num_sessions, s, sessions, and timestampevents.

Referenced by __expire_registry(), __iax2_poke_noanswer(), __login_exec(), action_agent_callback_login(), action_userevent(), add_to_queue(), agent_logoff_maintenance(), aji_log_hook(), ast_change_name(), ast_channel_bridge(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_set_callerid(), ast_setstate(), bridge_exec(), change_hold_state(), conf_run(), expire_register(), fast_originate(), handle_init_event(), handle_response_peerpoke(), handle_response_register(), iax2_ack_registry(), join_queue(), leave_queue(), manager_log(), manager_state_cb(), notify_new_message(), park_call_full(), park_exec(), parse_register_contact(), pbx_extension_helper(), phase_e_handler(), post_manager_event(), quit_handler(), realtime_exec(), record_abandoned(), register_verify(), reload_logger(), reload_manager(), remove_from_queue(), ring_entry(), senddialevent(), set_member_paused(), sip_poke_noanswer(), sip_reg_timeout(), socket_process(), ss_thread(), try_calling(), update_registry(), update_status(), userevent_exec(), vm_execmain(), and zt_handle_event().

02428 {
02429    struct mansession *s;
02430    char auth[80];
02431    va_list ap;
02432    struct timeval now;
02433    struct ast_dynamic_str *buf;
02434 
02435    /* Abort if there aren't any manager sessions */
02436    if (!num_sessions)
02437       return 0;
02438 
02439    if (!(buf = ast_dynamic_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE)))
02440       return -1;
02441 
02442    ast_dynamic_str_thread_set(&buf, 0, &manager_event_buf,
02443          "Event: %s\r\nPrivilege: %s\r\n",
02444           event, authority_to_str(category, auth, sizeof(auth)));
02445 
02446    if (timestampevents) {
02447       now = ast_tvnow();
02448       ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf,
02449             "Timestamp: %ld.%06lu\r\n",
02450              now.tv_sec, (unsigned long) now.tv_usec);
02451    }
02452 
02453    va_start(ap, fmt);
02454    ast_dynamic_str_thread_append_va(&buf, 0, &manager_event_buf, fmt, ap);
02455    va_end(ap);
02456    
02457    ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, "\r\n");  
02458    
02459    /* Append event to master list and wake up any sleeping sessions */
02460    AST_LIST_LOCK(&sessions);
02461    append_event(buf->str, category);
02462    AST_LIST_TRAVERSE(&sessions, s, list) {
02463       ast_mutex_lock(&s->__lock);
02464       if (s->waiting_thread != AST_PTHREADT_NULL)
02465          pthread_kill(s->waiting_thread, SIGURG);
02466       ast_mutex_unlock(&s->__lock);
02467    }
02468    AST_LIST_UNLOCK(&sessions);
02469 
02470    return 0;
02471 }

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

Definition at line 2495 of file manager.c.

References EVENT_FLAG_CALL, and manager_event().

Referenced by init_manager().

02496 {
02497    /* Notify managers of change */
02498    manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nStatus: %d\r\n", exten, context, state);
02499    return 0;
02500 }

static int process_events ( struct mansession s  )  [static]

Definition at line 2046 of file manager.c.

References ast_calloc, ast_carefulwrite(), ast_mutex_lock(), ast_mutex_unlock(), eventqent::category, eventqent::eventdata, master_eventq, s, and unuse_eventqent().

Referenced by do_message().

02047 {
02048    struct eventqent *eqe;
02049    int ret = 0;
02050    ast_mutex_lock(&s->__lock);
02051    if (!s->eventq)
02052       s->eventq = master_eventq;
02053    while(s->eventq->next) {
02054       eqe = s->eventq->next;
02055       if ((s->authenticated && (s->readperm & eqe->category) == eqe->category) &&
02056                ((s->send_events & eqe->category) == eqe->category)) {
02057          if (s->fd > -1) {
02058             if (!ret && ast_carefulwrite(s->fd, eqe->eventdata, strlen(eqe->eventdata), s->writetimeout) < 0)
02059                ret = -1;
02060          } else if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) 
02061             ret = -1;
02062          else 
02063             ast_dynamic_str_append(&s->outputstr, 0, "%s", eqe->eventdata);
02064       }
02065       unuse_eventqent(s->eventq);
02066       s->eventq = eqe;
02067    }
02068    ast_mutex_unlock(&s->__lock);
02069    return ret;
02070 }

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

Definition at line 2097 of file manager.c.

References manager_action::action, ast_inet_ntoa(), ast_log(), ast_random(), ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_strlen_zero(), ast_verbose(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), authenticate(), manager_action::authority, displayconnects, first_action, manager_action::func, LOG_DEBUG, LOG_EVENT, manager_action::next, option_debug, option_verbose, s, and VERBOSE_PREFIX_2.

Referenced by do_message().

02098 {
02099    char action[80] = "";
02100    struct manager_action *tmp;
02101    const char *id = astman_get_header(m,"ActionID");
02102    char idText[256] = "";
02103    int ret = 0;
02104 
02105    ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action));
02106    if (option_debug)
02107       ast_log( LOG_DEBUG, "Manager received command '%s'\n", action );
02108 
02109    if (ast_strlen_zero(action)) {
02110       astman_send_error(s, m, "Missing action in request");
02111       return 0;
02112    }
02113    if (!ast_strlen_zero(id)) {
02114       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
02115    }
02116    if (!s->authenticated) {
02117       if (!strcasecmp(action, "Challenge")) {
02118          const char *authtype = astman_get_header(m, "AuthType");
02119 
02120          if (!strcasecmp(authtype, "MD5")) {
02121             if (ast_strlen_zero(s->challenge))
02122                snprintf(s->challenge, sizeof(s->challenge), "%ld", ast_random());
02123             astman_append(s, "Response: Success\r\n"
02124                   "%s"
02125                   "Challenge: %s\r\n\r\n",
02126                   idText, s->challenge);
02127             return 0;
02128          } else {
02129             astman_send_error(s, m, "Must specify AuthType");
02130             return 0;
02131          }
02132       } else if (!strcasecmp(action, "Login")) {
02133          if (authenticate(s, m)) {
02134             sleep(1);
02135             astman_send_error(s, m, "Authentication failed");
02136             return -1;
02137          } else {
02138             s->authenticated = 1;
02139             if (option_verbose > 1) {
02140                if (displayconnects) {
02141                   ast_verbose(VERBOSE_PREFIX_2 "%sManager '%s' logged on from %s\n", 
02142                      (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
02143                }
02144             }
02145             ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", 
02146                (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
02147             astman_send_ack(s, m, "Authentication accepted");
02148          }
02149       } else if (!strcasecmp(action, "Logoff")) {
02150          astman_send_ack(s, m, "See ya");
02151          return -1;
02152       } else
02153          astman_send_error(s, m, "Authentication Required");
02154    } else {
02155       if (!strcasecmp(action, "Login"))
02156          astman_send_ack(s, m, "Already logged in");
02157       else {
02158          ast_rwlock_rdlock(&actionlock);
02159          for (tmp = first_action; tmp; tmp = tmp->next) {      
02160             if (strcasecmp(action, tmp->action))
02161                continue;
02162             if ((s->writeperm & tmp->authority) == tmp->authority) {
02163                if (tmp->func(s, m))
02164                   ret = -1;
02165             } else
02166                astman_send_error(s, m, "Permission denied");
02167             break;
02168          }
02169          ast_rwlock_unlock(&actionlock);
02170          if (!tmp)
02171             astman_send_error(s, m, "Invalid/unknown command");
02172       }
02173    }
02174    if (ret)
02175       return ret;
02176    return process_events(s);
02177 }

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

Definition at line 2263 of file manager.c.

References ast_inet_ntoa(), ast_log(), ast_verbose(), astman_append(), displayconnects, do_message(), LOG_EVENT, option_verbose, s, and VERBOSE_PREFIX_2.

Referenced by accept_thread().

02264 {
02265    struct mansession *s = data;
02266    int res;
02267    
02268    astman_append(s, "Asterisk Call Manager/1.0\r\n");
02269    for (;;) {
02270       if ((res = do_message(s)) < 0)
02271          break;
02272    }
02273    if (s->authenticated) {
02274       if (option_verbose > 1) {
02275          if (displayconnects) 
02276             ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
02277       }
02278       ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
02279    } else {
02280       if (option_verbose > 1) {
02281          if (displayconnects)
02282             ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr));
02283       }
02284       ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr));
02285    }
02286 
02287    /* It is possible under certain circumstances for this session thread
02288       to complete its work and exit *before* the thread that created it
02289       has finished executing the ast_pthread_create_background() function.
02290       If this occurs, some versions of glibc appear to act in a buggy
02291       fashion and attempt to write data into memory that it thinks belongs
02292       to the thread but is in fact not owned by the thread (or may have
02293       been freed completely).
02294 
02295       Causing this thread to yield to other threads at least one time
02296       appears to work around this bug.
02297    */
02298    usleep(1);
02299 
02300    destroy_session(s);
02301    return NULL;
02302 }

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

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

Referenced by action_events().

00936 {
00937    int maskint = strings_to_mask(eventmask);
00938 
00939    ast_mutex_lock(&s->__lock);
00940    if (maskint >= 0) 
00941       s->send_events = maskint;
00942    ast_mutex_unlock(&s->__lock);
00943    
00944    return maskint;
00945 }

static int strings_to_mask ( const char *  string  )  [static]

Definition at line 904 of file manager.c.

References ast_false(), ast_instring(), ast_is_number(), ast_strlen_zero(), ast_true(), and perms.

Referenced by set_eventmask().

00905 {
00906    int x, ret = -1;
00907    
00908    x = ast_is_number(string);
00909 
00910    if (x)
00911       ret = x;
00912    else if (ast_strlen_zero(string))
00913       ret = -1;
00914    else if (ast_false(string))
00915       ret = 0;
00916    else if (ast_true(string)) {
00917       ret = 0;
00918       for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++)
00919          ret |= perms[x].num;    
00920    } else {
00921       ret = 0;
00922       for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) {
00923          if (ast_instring(string, perms[x].label, ',')) 
00924             ret |= perms[x].num;    
00925       }
00926    }
00927 
00928    return ret;
00929 }

static void unuse_eventqent ( struct eventqent e  )  [static]

Definition at line 726 of file manager.c.

References eventqent::next, and eventqent::usecount.

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

00727 {
00728    if (ast_atomic_dec_and_test(&e->usecount) && e->next)
00729       pthread_kill(t, SIGURG);
00730 }

static int variable_count_cmp_fn ( void *  obj,
void *  vstr,
int  flags 
) [static]

Definition at line 308 of file manager.c.

References variable_count::varname.

Referenced by xml_translate().

00309 {
00310    /* Due to the simplicity of struct variable_count, it makes no difference
00311     * if you pass in objects or strings, the same operation applies. This is
00312     * due to the fact that the hash occurs on the first element, which means
00313     * the address of both the struct and the string are exactly the same. */
00314    struct variable_count *vc = obj;
00315    char *str = vstr;
00316    return !strcmp(vc->varname, str) ? CMP_MATCH : 0;
00317 }

static int variable_count_hash_fn ( const void *  vvc,
const int  flags 
) [static]

Definition at line 296 of file manager.c.

References compress_char(), and variable_count::varname.

Referenced by xml_translate().

00297 {
00298    const struct variable_count *vc = vvc;
00299    int res = 0, i;
00300    for (i = 0; i < 5; i++) {
00301       if (vc->varname[i] == '\0')
00302          break;
00303       res += compress_char(vc->varname[i]) << (i * 6);
00304    }
00305    return res;
00306 }

static void xml_copy_escape ( char **  dst,
size_t *  maxlen,
const char *  src,
int  lower 
) [static]

Definition at line 241 of file manager.c.

Referenced by xml_translate().

00242 {
00243    while (*src && (*maxlen > 6)) {
00244       switch (*src) {
00245       case '<':
00246          strcpy(*dst, "&lt;");
00247          (*dst) += 4;
00248          *maxlen -= 4;
00249          break;
00250       case '>':
00251          strcpy(*dst, "&gt;");
00252          (*dst) += 4;
00253          *maxlen -= 4;
00254          break;
00255       case '\"':
00256          strcpy(*dst, "&quot;");
00257          (*dst) += 6;
00258          *maxlen -= 6;
00259          break;
00260       case '\'':
00261          strcpy(*dst, "&apos;");
00262          (*dst) += 6;
00263          *maxlen -= 6;
00264          break;
00265       case '&':
00266          strcpy(*dst, "&amp;");
00267          (*dst) += 5;
00268          *maxlen -= 5;
00269          break;      
00270       default:
00271          *(*dst)++ = lower ? tolower(*src) : *src;
00272          (*maxlen)--;
00273       }
00274       src++;
00275    }
00276 }

static char* xml_translate ( char *  in,
struct ast_variable vars 
) [static]

Definition at line 319 of file manager.c.

References ao2_alloc(), ao2_container_alloc(), ao2_find(), ao2_ref(), ast_build_string(), ast_malloc, variable_count::count, len, ast_variable::name, ast_variable::next, ast_variable::value, var, variable_count_cmp_fn(), variable_count_hash_fn(), and xml_copy_escape().

00320 {
00321    struct ast_variable *v;
00322    char *dest = NULL;
00323    char *out, *tmp, *var, *val;
00324    char *objtype = NULL;
00325    int colons = 0;
00326    int breaks = 0;
00327    size_t len;
00328    int count = 1;
00329    int escaped = 0;
00330    int inobj = 0;
00331    int x;
00332    struct variable_count *vc = NULL;
00333    struct ao2_container *vco = NULL;
00334 
00335    for (v = vars; v; v = v->next) {
00336       if (!dest && !strcasecmp(v->name, "ajaxdest"))
00337          dest = v->value;
00338       else if (!objtype && !strcasecmp(v->name, "ajaxobjtype")) 
00339          objtype = v->value;
00340    }
00341    if (!dest)
00342       dest = "unknown";
00343    if (!objtype)
00344       objtype = "generic";
00345    for (x = 0; in[x]; x++) {
00346       if (in[x] == ':')
00347          colons++;
00348       else if (in[x] == '\n')
00349          breaks++;
00350       else if (strchr("&\"<>\'", in[x]))
00351          escaped++;
00352    }
00353    len = (size_t) (strlen(in) + colons * 5 + breaks * (40 + strlen(dest) + strlen(objtype)) + escaped * 10); /* foo="bar", "<response type=\"object\" id=\"dest\"", "&amp;" */
00354    out = ast_malloc(len);
00355    if (!out)
00356       return 0;
00357    tmp = out;
00358    while (*in) {
00359       var = in;
00360       while (*in && (*in >= 32))
00361          in++;
00362       if (*in) {
00363          if ((count > 3) && inobj) {
00364             ast_build_string(&tmp, &len, " /></response>\n");
00365             inobj = 0;
00366 
00367             /* Entity is closed, so close out the name cache */
00368             ao2_ref(vco, -1);
00369             vco = NULL;
00370          }
00371          count = 0;
00372          while (*in && (*in < 32)) {
00373             *in = '\0';
00374             in++;
00375             count++;
00376          }
00377          val = strchr(var, ':');
00378          if (val) {
00379             *val = '\0';
00380             val++;
00381             if (*val == ' ')
00382                val++;
00383             if (!inobj) {
00384                vco = ao2_container_alloc(37, variable_count_hash_fn, variable_count_cmp_fn);
00385                ast_build_string(&tmp, &len, "<response type='object' id='%s'><%s", dest, objtype);
00386                inobj = 1;
00387             }
00388 
00389             /* Check if the var has been used already */
00390             if ((vc = ao2_find(vco, var, 0)))
00391                vc->count++;
00392             else {
00393                /* Create a new entry for this one */
00394                vc = ao2_alloc(sizeof(*vc), NULL);
00395                vc->varname = var;
00396                vc->count = 1;
00397                ao2_link(vco, vc);
00398             }
00399 
00400             ast_build_string(&tmp, &len, " ");
00401             xml_copy_escape(&tmp, &len, var, 1);
00402             if (vc->count > 1)
00403                ast_build_string(&tmp, &len, "-%d", vc->count);
00404             ast_build_string(&tmp, &len, "='");
00405             xml_copy_escape(&tmp, &len, val, 0);
00406             ast_build_string(&tmp, &len, "'");
00407             ao2_ref(vc, -1);
00408          }
00409       }
00410    }
00411    if (inobj)
00412       ast_build_string(&tmp, &len, " /></response>\n");
00413    if (vco)
00414       ao2_ref(vco, -1);
00415    return out;
00416 }


Variable Documentation

int asock = -1 [static]

Definition at line 99 of file manager.c.

Referenced by accept_thread(), and init_manager().

int block_sockets [static]

Definition at line 105 of file manager.c.

Referenced by accept_thread(), and init_manager().

struct ast_cli_entry cli_manager[] [static]

Definition at line 700 of file manager.c.

Referenced by init_manager().

struct ast_cli_entry cli_show_manager_command_deprecated [static]

Initial value:

 {
   { "show", "manager", "command", NULL },
   handle_showmancmd, NULL,
   NULL, complete_show_mancmd }

Definition at line 680 of file manager.c.

struct ast_cli_entry cli_show_manager_commands_deprecated [static]

Initial value:

 {
   { "show", "manager", "commands", NULL },
   handle_showmancmds, NULL,
   NULL }

Definition at line 685 of file manager.c.

struct ast_cli_entry cli_show_manager_connected_deprecated [static]

Initial value:

 {
   { "show", "manager", "connected", NULL },
   handle_showmanconn, NULL,
   NULL }

Definition at line 690 of file manager.c.

struct ast_cli_entry cli_show_manager_eventq_deprecated [static]

Initial value:

 {
   { "show", "manager", "eventq", NULL },
   handle_showmaneventq, NULL,
   NULL }

Definition at line 695 of file manager.c.

const char* command_blacklist[] [static]

Initial value:

 {
   "module load",
   "module unload",
}

Definition at line 133 of file manager.c.

Referenced by action_command().

int displayconnects = 1 [static]

Definition at line 100 of file manager.c.

Referenced by accept_thread(), init_manager(), process_message(), and session_do().

int enabled [static]

Definition at line 97 of file manager.c.

struct manager_action* first_action [static]

Definition at line 197 of file manager.c.

Referenced by action_listcommands(), ast_manager_register_struct(), ast_manager_unregister(), complete_show_mancmd(), handle_showmancmd(), handle_showmancmds(), and process_message().

int httptimeout = 60 [static]

Definition at line 102 of file manager.c.

Referenced by init_manager().

char mandescr_command[] [static]

Initial value:

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

Definition at line 1683 of file manager.c.

char mandescr_events[] [static]

Definition at line 1373 of file manager.c.

char mandescr_extensionstate[] [static]

Definition at line 1974 of file manager.c.

char mandescr_getconfig[] [static]

Initial value:

"Description: A 'GetConfig' action will dump the contents of a configuration\n"
"file by category and contents.\n"
"Variables:\n"
"   Filename: Configuration filename (e.g. foo.conf)\n"

Definition at line 1104 of file manager.c.

char mandescr_getvar[] [static]

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

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

char mandescr_logoff[] [static]

Initial value:

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

Definition at line 1395 of file manager.c.

char mandescr_mailboxcount[] [static]

Definition at line 1938 of file manager.c.

char mandescr_mailboxstatus[] [static]

Help text for manager command mailboxstatus.

Definition at line 1906 of file manager.c.

char mandescr_originate[] [static]

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

char mandescr_redirect[] [static]

Definition at line 1608 of file manager.c.

char mandescr_setvar[] [static]

Definition at line 1429 of file manager.c.

char mandescr_timeout[] [static]

Definition at line 2015 of file manager.c.

char mandescr_updateconfig[] [static]

Definition at line 1208 of file manager.c.

char mandescr_userevent[] [static]

Definition at line 2072 of file manager.c.

char mandescr_waitevent[] [static]

Manager WAITEVENT.

Definition at line 1259 of file manager.c.

struct eventqent* master_eventq = NULL

Definition at line 109 of file manager.c.

Referenced by accept_thread(), append_event(), handle_showmaneventq(), and process_events().

int num_sessions [static]

Definition at line 106 of file manager.c.

Referenced by accept_thread(), append_event(), and manager_event().

struct permalias perms[] [static]

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

int portno = DEFAULT_MANAGER_PORT [static]

Definition at line 98 of file manager.c.

Referenced by ast_netsock_bind(), create_addr(), init_manager(), process_sdp(), and set_config().

char showmanager_help[] [static]

Initial value:

" Usage: manager show user <user>\n"
"        Display all information related to the manager user specified.\n"

Definition at line 676 of file manager.c.

char showmanagers_help[] [static]

Initial value:

"Usage: manager show users\n"
"       Prints a listing of all managers that are currently configured on that\n"
" system.\n"

Definition at line 671 of file manager.c.

char showmancmd_help[] [static]

Initial value:

 
"Usage: manager show command <actionname>\n"
"  Shows the detailed description for a specific Asterisk manager interface command.\n"

Definition at line 653 of file manager.c.

char showmancmds_help[] [static]

Initial value:

 
"Usage: manager show commands\n"
"  Prints a listing of all the available Asterisk manager interface commands.\n"

Definition at line 657 of file manager.c.

char showmanconn_help[] [static]

Initial value:

 
"Usage: manager show connected\n"
"  Prints a listing of the users that are currently connected to the\n"
"Asterisk manager interface.\n"

Definition at line 661 of file manager.c.

char showmaneventq_help[] [static]

Initial value:

 
"Usage: manager show eventq\n"
"  Prints a listing of all events pending in the Asterisk manger\n"
"event queue.\n"

Definition at line 666 of file manager.c.

pthread_t t [static]

Definition at line 104 of file manager.c.

Referenced by __ast_register_translator(), __schedule_action(), acf_odbc_write(), add_sdp(), add_t38_sdp(), append_date(), ast_channel_bridge(), ast_check_timing(), ast_do_masquerade(), ast_get_time_t(), ast_httpd_helper_thread(), ast_log(), ast_pbx_start(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_de(), ast_translator_activate(), ast_translator_build_path(), ast_translator_deactivate(), ast_unregister_translator(), ast_verbose(), background_detect_exec(), build_mapping(), byteReverse(), calc_cost(), calc_txstamp(), callerid_genmsg(), callerid_getcarrier(), cdr_get_tv(), check_switch_expr(), check_user_full(), cli_prompt(), config_text_file_save(), destroy(), do_monitor(), does_peer_need_mwi(), dump_cmd_queues(), expr2_token_subst(), gen_match_to_pattern(), gen_tone(), gen_tones(), get_date(), get_trans_id(), handle_bchan(), handle_enbloc_call_message(), handle_hd_hf(), handle_offhook_message(), handle_save_dialplan(), handle_soft_key_event_message(), handle_stimulus_message(), iax2_datetime(), iax2_process_thread(), iax2_show_threads(), iax_template_parse(), init_manager(), launch_service(), listener(), local_new(), localsub(), lws2sws(), manager_log(), MD5Update(), misdn_read(), newpvt(), nv_background_detect_exec(), nv_detectfax_exec(), osp_create_provider(), osp_load(), packdate(), parse_moved_contact(), pgsql_log(), phase_d_handler(), phase_e_handler(), play_message_datetime(), prune_gateways(), rebuild_matrix(), register_verify(), rpt(), rpt_do_lstats(), rpt_exec(), rpt_tele_thread(), rxfax_exec(), send_request(), SHA1ProcessMessageBlock(), sms_readfile(), socket_read(), sqlite_log(), strip_quotes(), tdd_getcarrier(), time2sub(), transmit_notify_request_with_callerid(), transmit_notify_with_mwi(), transmit_state_notify(), txfax_exec(), vmu_tm(), and write_metadata().

int timestampevents [static]

Definition at line 101 of file manager.c.

Referenced by init_manager(), and manager_event().


Generated on Mon Mar 31 07:42:56 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1