Mon May 14 04:54:00 2007

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

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

Referenced by astman_append().

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 111 of file manager.c.

Referenced by manager_event().


Function Documentation

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

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

02199 {
02200    int as;
02201    struct sockaddr_in sin;
02202    socklen_t sinlen;
02203    struct eventqent *eqe;
02204    struct mansession *s;
02205    struct protoent *p;
02206    int arg = 1;
02207    int flags;
02208    pthread_attr_t attr;
02209    time_t now;
02210    struct pollfd pfds[1];
02211 
02212    pthread_attr_init(&attr);
02213    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
02214 
02215    for (;;) {
02216       time(&now);
02217       AST_LIST_LOCK(&sessions);
02218       AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) {
02219          if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) {
02220             AST_LIST_REMOVE_CURRENT(&sessions, list);
02221             if (s->authenticated && (option_verbose > 1) && displayconnects) {
02222                ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' timed out from %s\n",
02223                   s->username, ast_inet_ntoa(s->sin.sin_addr));
02224             }
02225             free_session(s);
02226             break;   
02227          }
02228       }
02229       AST_LIST_TRAVERSE_SAFE_END
02230       /* Purge master event queue of old, unused events, but make sure we
02231          always keep at least one in the queue */
02232       eqe = master_eventq;
02233       while (master_eventq->next && !master_eventq->usecount) {
02234          eqe = master_eventq;
02235          master_eventq = master_eventq->next;
02236          free(eqe);
02237       }
02238       AST_LIST_UNLOCK(&sessions);
02239       if (s)
02240          ast_atomic_fetchadd_int(&num_sessions, -1);
02241 
02242       sinlen = sizeof(sin);
02243       pfds[0].fd = asock;
02244       pfds[0].events = POLLIN;
02245       /* Wait for something to happen, but timeout every few seconds so
02246          we can ditch any old manager sessions */
02247       if (poll(pfds, 1, 5000) < 1)
02248          continue;
02249       as = accept(asock, (struct sockaddr *)&sin, &sinlen);
02250       if (as < 0) {
02251          ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno));
02252          continue;
02253       }
02254       p = getprotobyname("tcp");
02255       if (p) {
02256          if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
02257             ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
02258          }
02259       }
02260       if (!(s = ast_calloc(1, sizeof(*s))))
02261          continue;
02262 
02263       ast_atomic_fetchadd_int(&num_sessions, 1);
02264       
02265       memcpy(&s->sin, &sin, sizeof(sin));
02266       s->writetimeout = 100;
02267       s->waiting_thread = AST_PTHREADT_NULL;
02268 
02269       if (!block_sockets) {
02270          /* For safety, make sure socket is non-blocking */
02271          flags = fcntl(as, F_GETFL);
02272          fcntl(as, F_SETFL, flags | O_NONBLOCK);
02273       } else {
02274          flags = fcntl(as, F_GETFL);
02275          fcntl(as, F_SETFL, flags & ~O_NONBLOCK);
02276       }
02277       ast_mutex_init(&s->__lock);
02278       s->fd = as;
02279       s->send_events = -1;
02280       AST_LIST_LOCK(&sessions);
02281       AST_LIST_INSERT_HEAD(&sessions, s, list);
02282       /* Find the last place in the master event queue and hook ourselves
02283          in there */
02284       s->eventq = master_eventq;
02285       while(s->eventq->next)
02286          s->eventq = s->eventq->next;
02287       AST_LIST_UNLOCK(&sessions);
02288       ast_atomic_fetchadd_int(&s->eventq->usecount, 1);
02289       if (ast_pthread_create_background(&s->t, &attr, session_do, s))
02290          destroy_session(s);
02291    }
02292    pthread_attr_destroy(&attr);
02293    return NULL;
02294 }

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

action_command: Manager command "command" - execute CLI command

Definition at line 1617 of file manager.c.

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

Referenced by init_manager().

01618 {
01619    const char *cmd = astman_get_header(m, "Command");
01620    const char *id = astman_get_header(m, "ActionID");
01621    char *buf, *final_buf;
01622    char template[] = "/tmp/ast-ami-XXXXXX";  /* template for temporary file */
01623    int fd = mkstemp(template);
01624    off_t l;
01625 
01626    astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
01627    if (!ast_strlen_zero(id))
01628       astman_append(s, "ActionID: %s\r\n", id);
01629    /* FIXME: Wedge a ActionID response in here, waiting for later changes */
01630    ast_cli_command(fd, cmd);  /* XXX need to change this to use a FILE * */
01631    l = lseek(fd, 0, SEEK_END);   /* how many chars available */
01632    buf = alloca(l + 1);
01633    final_buf = alloca(l + 1);
01634    lseek(fd, 0, SEEK_SET);
01635    read(fd, buf, l);
01636    buf[l] = '\0';
01637    close(fd);
01638    unlink(template);
01639    term_strip(final_buf, buf, l);
01640    final_buf[l] = '\0';
01641    astman_append(s, final_buf);
01642    astman_append(s, "--END COMMAND--\r\n\r\n");
01643    return 0;
01644 }

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

Definition at line 1303 of file manager.c.

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

Referenced by init_manager().

01304 {
01305    const char *mask = astman_get_header(m, "EventMask");
01306    int res;
01307 
01308    res = set_eventmask(s, mask);
01309    if (res > 0)
01310       astman_send_response(s, m, "Events On", NULL);
01311    else if (res == 0)
01312       astman_send_response(s, m, "Events Off", NULL);
01313 
01314    return 0;
01315 }

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

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

01897 {
01898    const char *exten = astman_get_header(m, "Exten");
01899    const char *context = astman_get_header(m, "Context");
01900    const char *id = astman_get_header(m,"ActionID");
01901    char idText[256] = "";
01902    char hint[256] = "";
01903    int status;
01904    if (ast_strlen_zero(exten)) {
01905       astman_send_error(s, m, "Extension not specified");
01906       return 0;
01907    }
01908    if (ast_strlen_zero(context))
01909       context = "default";
01910    status = ast_extension_state(NULL, context, exten);
01911    ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
01912         if (!ast_strlen_zero(id)) {
01913                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01914         }
01915    astman_append(s, "Response: Success\r\n"
01916                     "%s"
01917                "Message: Extension Status\r\n"
01918                "Exten: %s\r\n"
01919                "Context: %s\r\n"
01920                "Hint: %s\r\n"
01921                "Status: %d\r\n\r\n",
01922                idText,exten, context, hint, status);
01923    return 0;
01924 }

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

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

01033 {
01034    struct ast_config *cfg;
01035    const char *fn = astman_get_header(m, "Filename");
01036    int catcount = 0;
01037    int lineno = 0;
01038    char *category=NULL;
01039    struct ast_variable *v;
01040    char idText[256] = "";
01041    const char *id = astman_get_header(m, "ActionID");
01042 
01043    if (!ast_strlen_zero(id))
01044       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01045 
01046    if (ast_strlen_zero(fn)) {
01047       astman_send_error(s, m, "Filename not specified");
01048       return 0;
01049    }
01050    if (!(cfg = ast_config_load_with_comments(fn))) {
01051       astman_send_error(s, m, "Config file not found");
01052       return 0;
01053    }
01054    astman_append(s, "Response: Success\r\n%s", idText);
01055    while ((category = ast_category_browse(cfg, category))) {
01056       lineno = 0;
01057       astman_append(s, "Category-%06d: %s\r\n", catcount, category);
01058       for (v = ast_variable_browse(cfg, category); v; v = v->next)
01059          astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
01060       catcount++;
01061    }
01062    ast_config_destroy(cfg);
01063    astman_append(s, "\r\n");
01064 
01065    return 0;
01066 }

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

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

01401 {
01402    struct ast_channel *c = NULL;
01403    const char *name = astman_get_header(m, "Channel");
01404    const char *varname = astman_get_header(m, "Variable");
01405    const char *id = astman_get_header(m,"ActionID");
01406    char *varval;
01407    char workspace[1024] = "";
01408 
01409    if (ast_strlen_zero(varname)) {
01410       astman_send_error(s, m, "No variable specified");
01411       return 0;
01412    }
01413 
01414    if (!ast_strlen_zero(name)) {
01415       c = ast_get_channel_by_name_locked(name);
01416       if (!c) {
01417          astman_send_error(s, m, "No such channel");
01418          return 0;
01419       }
01420    }
01421 
01422    if (varname[strlen(varname) - 1] == ')') {
01423       char *copy = ast_strdupa(varname);
01424 
01425       ast_func_read(c, copy, workspace, sizeof(workspace));
01426       varval = workspace;
01427    } else {
01428       pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
01429    }
01430 
01431    if (c)
01432       ast_channel_unlock(c);
01433    astman_append(s, "Response: Success\r\n"
01434       "Variable: %s\r\nValue: %s\r\n", varname, varval);
01435    if (!ast_strlen_zero(id))
01436       astman_append(s, "ActionID: %s\r\n",id);
01437    astman_append(s, "\r\n");
01438 
01439    return 0;
01440 }

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

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

01333 {
01334    struct ast_channel *c = NULL;
01335    const char *name = astman_get_header(m, "Channel");
01336    if (ast_strlen_zero(name)) {
01337       astman_send_error(s, m, "No channel specified");
01338       return 0;
01339    }
01340    c = ast_get_channel_by_name_locked(name);
01341    if (!c) {
01342       astman_send_error(s, m, "No such channel");
01343       return 0;
01344    }
01345    ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
01346    ast_channel_unlock(c);
01347    astman_send_ack(s, m, "Channel Hungup");
01348    return 0;
01349 }

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

01277 {
01278    struct manager_action *cur;
01279    char idText[256] = "";
01280    char temp[BUFSIZ];
01281    const char *id = astman_get_header(m,"ActionID");
01282 
01283    if (!ast_strlen_zero(id))
01284       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01285    astman_append(s, "Response: Success\r\n%s", idText);
01286    for (cur = first_action; cur; cur = cur->next) {
01287       if ((s->writeperm & cur->authority) == cur->authority)
01288          astman_append(s, "%s: %s (Priv: %s)\r\n", cur->action, cur->synopsis, authority_to_str(cur->authority, temp, sizeof(temp)));
01289    }
01290    astman_append(s, "\r\n");
01291 
01292    return 0;
01293 }

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

Definition at line 1321 of file manager.c.

References astman_send_response(), and s.

Referenced by init_manager().

01322 {
01323    astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
01324    return -1;
01325 }

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

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

01861 {
01862    const char *mailbox = astman_get_header(m, "Mailbox");
01863    const char *id = astman_get_header(m,"ActionID");
01864    char idText[256] = "";
01865    int newmsgs = 0, oldmsgs = 0;
01866    if (ast_strlen_zero(mailbox)) {
01867       astman_send_error(s, m, "Mailbox not specified");
01868       return 0;
01869    }
01870    ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs);
01871    if (!ast_strlen_zero(id)) {
01872       snprintf(idText, sizeof(idText), "ActionID: %s\r\n",id);
01873    }
01874    astman_append(s, "Response: Success\r\n"
01875                "%s"
01876                "Message: Mailbox Message Count\r\n"
01877                "Mailbox: %s\r\n"
01878                "NewMessages: %d\r\n"
01879                "OldMessages: %d\r\n" 
01880                "\r\n",
01881                 idText,mailbox, newmsgs, oldmsgs);
01882    return 0;
01883 }

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

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

01829 {
01830    const char *mailbox = astman_get_header(m, "Mailbox");
01831    const char *id = astman_get_header(m,"ActionID");
01832    char idText[256] = "";
01833    int ret;
01834    if (ast_strlen_zero(mailbox)) {
01835       astman_send_error(s, m, "Mailbox not specified");
01836       return 0;
01837    }
01838         if (!ast_strlen_zero(id))
01839                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01840    ret = ast_app_has_voicemail(mailbox, NULL);
01841    astman_append(s, "Response: Success\r\n"
01842                "%s"
01843                "Message: Mailbox Status\r\n"
01844                "Mailbox: %s\r\n"
01845                "Waiting: %d\r\n\r\n", idText, mailbox, ret);
01846    return 0;
01847 }

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

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

01711 {
01712    const char *name = astman_get_header(m, "Channel");
01713    const char *exten = astman_get_header(m, "Exten");
01714    const char *context = astman_get_header(m, "Context");
01715    const char *priority = astman_get_header(m, "Priority");
01716    const char *timeout = astman_get_header(m, "Timeout");
01717    const char *callerid = astman_get_header(m, "CallerID");
01718    const char *account = astman_get_header(m, "Account");
01719    const char *app = astman_get_header(m, "Application");
01720    const char *appdata = astman_get_header(m, "Data");
01721    const char *async = astman_get_header(m, "Async");
01722    const char *id = astman_get_header(m, "ActionID");
01723    struct ast_variable *vars = astman_get_variables(m);
01724    char *tech, *data;
01725    char *l = NULL, *n = NULL;
01726    int pi = 0;
01727    int res;
01728    int to = 30000;
01729    int reason = 0;
01730    char tmp[256];
01731    char tmp2[256];
01732    
01733    pthread_t th;
01734    pthread_attr_t attr;
01735    if (!name) {
01736       astman_send_error(s, m, "Channel not specified");
01737       return 0;
01738    }
01739    if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) {
01740       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
01741          astman_send_error(s, m, "Invalid priority\n");
01742          return 0;
01743       }
01744    }
01745    if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) {
01746       astman_send_error(s, m, "Invalid timeout\n");
01747       return 0;
01748    }
01749    ast_copy_string(tmp, name, sizeof(tmp));
01750    tech = tmp;
01751    data = strchr(tmp, '/');
01752    if (!data) {
01753       astman_send_error(s, m, "Invalid channel\n");
01754       return 0;
01755    }
01756    *data++ = '\0';
01757    ast_copy_string(tmp2, callerid, sizeof(tmp2));
01758    ast_callerid_parse(tmp2, &n, &l);
01759    if (n) {
01760       if (ast_strlen_zero(n))
01761          n = NULL;
01762    }
01763    if (l) {
01764       ast_shrink_phone_number(l);
01765       if (ast_strlen_zero(l))
01766          l = NULL;
01767    }
01768    if (ast_true(async)) {
01769       struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast));
01770       if (!fast) {
01771          res = -1;
01772       } else {
01773          if (!ast_strlen_zero(id))
01774             snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s\r\n", id);
01775          ast_copy_string(fast->tech, tech, sizeof(fast->tech));
01776             ast_copy_string(fast->data, data, sizeof(fast->data));
01777          ast_copy_string(fast->app, app, sizeof(fast->app));
01778          ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata));
01779          if (l)
01780             ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num));
01781          if (n)
01782             ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name));
01783          fast->vars = vars;   
01784          ast_copy_string(fast->context, context, sizeof(fast->context));
01785          ast_copy_string(fast->exten, exten, sizeof(fast->exten));
01786          ast_copy_string(fast->account, account, sizeof(fast->account));
01787          fast->timeout = to;
01788          fast->priority = pi;
01789          pthread_attr_init(&attr);
01790          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
01791          if (ast_pthread_create(&th, &attr, fast_originate, fast)) {
01792             res = -1;
01793          } else {
01794             res = 0;
01795          }
01796          pthread_attr_destroy(&attr);
01797       }
01798    } else if (!ast_strlen_zero(app)) {
01799          res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
01800       } else {
01801       if (exten && context && pi)
01802             res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL);
01803       else {
01804          astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
01805          return 0;
01806       }
01807    }   
01808    if (!res)
01809       astman_send_ack(s, m, "Originate successfully queued");
01810    else
01811       astman_send_error(s, m, "Originate failed");
01812    return 0;
01813 }

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

Definition at line 1020 of file manager.c.

References astman_send_response(), and s.

Referenced by init_manager().

01021 {
01022    astman_send_response(s, m, "Pong", NULL);
01023    return 0;
01024 }

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

action_redirect: The redirect manager command

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

01547 {
01548    const char *name = astman_get_header(m, "Channel");
01549    const char *name2 = astman_get_header(m, "ExtraChannel");
01550    const char *exten = astman_get_header(m, "Exten");
01551    const char *context = astman_get_header(m, "Context");
01552    const char *priority = astman_get_header(m, "Priority");
01553    struct ast_channel *chan, *chan2 = NULL;
01554    int pi = 0;
01555    int res;
01556 
01557    if (ast_strlen_zero(name)) {
01558       astman_send_error(s, m, "Channel not specified");
01559       return 0;
01560    }
01561    if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) {
01562       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
01563          astman_send_error(s, m, "Invalid priority\n");
01564          return 0;
01565       }
01566    }
01567    /* XXX watch out, possible deadlock!!! */
01568    chan = ast_get_channel_by_name_locked(name);
01569    if (!chan) {
01570       char buf[BUFSIZ];
01571       snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
01572       astman_send_error(s, m, buf);
01573       return 0;
01574    }
01575    if (ast_check_hangup(chan)) {
01576       astman_send_error(s, m, "Redirect failed, channel not up.\n");
01577       ast_channel_unlock(chan);
01578       return 0;
01579    }
01580    if (!ast_strlen_zero(name2))
01581       chan2 = ast_get_channel_by_name_locked(name2);
01582    if (chan2 && ast_check_hangup(chan2)) {
01583       astman_send_error(s, m, "Redirect failed, extra channel not up.\n");
01584       ast_channel_unlock(chan);
01585       ast_channel_unlock(chan2);
01586       return 0;
01587    }
01588    res = ast_async_goto(chan, context, exten, pi);
01589    if (!res) {
01590       if (!ast_strlen_zero(name2)) {
01591          if (chan2)
01592             res = ast_async_goto(chan2, context, exten, pi);
01593          else
01594             res = -1;
01595          if (!res)
01596             astman_send_ack(s, m, "Dual Redirect successful");
01597          else
01598             astman_send_error(s, m, "Secondary redirect failed");
01599       } else
01600          astman_send_ack(s, m, "Redirect successful");
01601    } else
01602       astman_send_error(s, m, "Redirect failed");
01603    if (chan)
01604       ast_channel_unlock(chan);
01605    if (chan2)
01606       ast_channel_unlock(chan2);
01607    return 0;
01608 }

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

Definition at line 1358 of file manager.c.

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

Referenced by init_manager().

01359 {
01360         struct ast_channel *c = NULL;
01361    const char *name = astman_get_header(m, "Channel");
01362    const char *varname = astman_get_header(m, "Variable");
01363    const char *varval = astman_get_header(m, "Value");
01364    
01365    if (ast_strlen_zero(varname)) {
01366       astman_send_error(s, m, "No variable specified");
01367       return 0;
01368    }
01369    
01370    if (ast_strlen_zero(varval)) {
01371       astman_send_error(s, m, "No value specified");
01372       return 0;
01373    }
01374 
01375    if (!ast_strlen_zero(name)) {
01376       c = ast_get_channel_by_name_locked(name);
01377       if (!c) {
01378          astman_send_error(s, m, "No such channel");
01379          return 0;
01380       }
01381    }
01382    
01383    pbx_builtin_setvar_helper(c, varname, varval);
01384      
01385    if (c)
01386       ast_channel_unlock(c);
01387 
01388    astman_send_ack(s, m, "Variable Set"); 
01389 
01390    return 0;
01391 }

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

Manager "status" command to show channels.

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

01446 {
01447    const char *id = astman_get_header(m,"ActionID");
01448       const char *name = astman_get_header(m,"Channel");
01449    char idText[256] = "";
01450    struct ast_channel *c;
01451    char bridge[256];
01452    struct timeval now = ast_tvnow();
01453    long elapsed_seconds = 0;
01454    int all = ast_strlen_zero(name); /* set if we want all channels */
01455 
01456    if (!ast_strlen_zero(id))
01457       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01458    if (all)
01459       c = ast_channel_walk_locked(NULL);
01460    else {
01461       c = ast_get_channel_by_name_locked(name);
01462       if (!c) {
01463          astman_send_error(s, m, "No such channel");
01464          return 0;
01465       }
01466    }
01467    astman_send_ack(s, m, "Channel status will follow");
01468    /* if we look by name, we break after the first iteration */
01469    while (c) {
01470       if (c->_bridge)
01471          snprintf(bridge, sizeof(bridge), "Link: %s\r\n", c->_bridge->name);
01472       else
01473          bridge[0] = '\0';
01474       if (c->pbx) {
01475          if (c->cdr) {
01476             elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
01477          }
01478          astman_append(s,
01479          "Event: Status\r\n"
01480          "Privilege: Call\r\n"
01481          "Channel: %s\r\n"
01482          "CallerID: %s\r\n"      /* This parameter is deprecated and will be removed post-1.4 */
01483          "CallerIDNum: %s\r\n"
01484          "CallerIDName: %s\r\n"
01485          "Account: %s\r\n"
01486          "State: %s\r\n"
01487          "Context: %s\r\n"
01488          "Extension: %s\r\n"
01489          "Priority: %d\r\n"
01490          "Seconds: %ld\r\n"
01491          "%s"
01492          "Uniqueid: %s\r\n"
01493          "%s"
01494          "\r\n",
01495          c->name, 
01496          S_OR(c->cid.cid_num, "<unknown>"), 
01497          S_OR(c->cid.cid_num, "<unknown>"), 
01498          S_OR(c->cid.cid_name, "<unknown>"), 
01499          c->accountcode,
01500          ast_state2str(c->_state), c->context,
01501          c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, idText);
01502       } else {
01503          astman_append(s,
01504          "Event: Status\r\n"
01505          "Privilege: Call\r\n"
01506          "Channel: %s\r\n"
01507          "CallerID: %s\r\n"      /* This parameter is deprecated and will be removed post-1.4 */
01508          "CallerIDNum: %s\r\n"
01509          "CallerIDName: %s\r\n"
01510          "Account: %s\r\n"
01511          "State: %s\r\n"
01512          "%s"
01513          "Uniqueid: %s\r\n"
01514          "%s"
01515          "\r\n",
01516          c->name, 
01517          S_OR(c->cid.cid_num, "<unknown>"), 
01518          S_OR(c->cid.cid_num, "<unknown>"), 
01519          S_OR(c->cid.cid_name, "<unknown>"), 
01520          c->accountcode,
01521          ast_state2str(c->_state), bridge, c->uniqueid, idText);
01522       }
01523       ast_channel_unlock(c);
01524       if (!all)
01525          break;
01526       c = ast_channel_walk_locked(c);
01527    }
01528    astman_append(s,
01529    "Event: StatusComplete\r\n"
01530    "%s"
01531    "\r\n",idText);
01532    return 0;
01533 }

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

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

01934 {
01935    struct ast_channel *c = NULL;
01936    const char *name = astman_get_header(m, "Channel");
01937    int timeout = atoi(astman_get_header(m, "Timeout"));
01938    if (ast_strlen_zero(name)) {
01939       astman_send_error(s, m, "No channel specified");
01940       return 0;
01941    }
01942    if (!timeout) {
01943       astman_send_error(s, m, "No timeout specified");
01944       return 0;
01945    }
01946    c = ast_get_channel_by_name_locked(name);
01947    if (!c) {
01948       astman_send_error(s, m, "No such channel");
01949       return 0;
01950    }
01951    ast_channel_setwhentohangup(c, timeout);
01952    ast_channel_unlock(c);
01953    astman_send_ack(s, m, "Timeout Set");
01954    return 0;
01955 }

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

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

01144 {
01145    struct ast_config *cfg;
01146    const char *sfn = astman_get_header(m, "SrcFilename");
01147    const char *dfn = astman_get_header(m, "DstFilename");
01148    int res;
01149    char idText[256] = "";
01150    const char *id = astman_get_header(m, "ActionID");
01151    const char *rld = astman_get_header(m, "Reload");
01152 
01153    if (!ast_strlen_zero(id))
01154       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01155 
01156    if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
01157       astman_send_error(s, m, "Filename not specified");
01158       return 0;
01159    }
01160    if (!(cfg = ast_config_load_with_comments(sfn))) {
01161       astman_send_error(s, m, "Config file not found");
01162       return 0;
01163    }
01164    handle_updates(s, m, cfg);
01165    res = config_text_file_save(dfn, cfg, "Manager");
01166    ast_config_destroy(cfg);
01167    if (res) {
01168       astman_send_error(s, m, "Save of config failed");
01169       return 0;
01170    }
01171    astman_append(s, "Response: Success\r\n%s\r\n", idText);
01172    if (!ast_strlen_zero(rld)) {
01173       if (ast_true(rld))
01174          rld = NULL;
01175       ast_module_reload(rld); 
01176    }
01177    return 0;
01178 }

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

Definition at line 1987 of file manager.c.

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

Referenced by init_manager().

01988 {
01989    const char *event = astman_get_header(m, "UserEvent");
01990    char body[2048] = "";
01991    int x, bodylen = 0;
01992    for (x = 0; x < m->hdrcount; x++) {
01993       if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
01994          ast_copy_string(body + bodylen, m->headers[x], sizeof(body) - bodylen - 3);
01995          bodylen += strlen(m->headers[x]);
01996          ast_copy_string(body + bodylen, "\r\n", 3);
01997          bodylen += 2;
01998       }
01999    }
02000 
02001    manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body);
02002    return 0;
02003 }

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

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

01189 {
01190    const char *timeouts = astman_get_header(m, "Timeout");
01191    int timeout = -1, max;
01192    int x;
01193    int needexit = 0;
01194    time_t now;
01195    struct eventqent *eqe;
01196    const char *id = astman_get_header(m,"ActionID");
01197    char idText[256] = "";
01198 
01199    if (!ast_strlen_zero(id))
01200       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01201 
01202    if (!ast_strlen_zero(timeouts)) {
01203       sscanf(timeouts, "%i", &timeout);
01204    }
01205    
01206    ast_mutex_lock(&s->__lock);
01207    if (s->waiting_thread != AST_PTHREADT_NULL) {
01208       pthread_kill(s->waiting_thread, SIGURG);
01209    }
01210    if (s->sessiontimeout) {
01211       time(&now);
01212       max = s->sessiontimeout - now - 10;
01213       if (max < 0)
01214          max = 0;
01215       if ((timeout < 0) || (timeout > max))
01216          timeout = max;
01217       if (!s->send_events)
01218          s->send_events = -1;
01219       /* Once waitevent is called, always queue events from now on */
01220    }
01221    ast_mutex_unlock(&s->__lock);
01222    s->waiting_thread = pthread_self();
01223    if (option_debug)
01224       ast_log(LOG_DEBUG, "Starting waiting for an event!\n");
01225    for (x=0; ((x < timeout) || (timeout < 0)); x++) {
01226       ast_mutex_lock(&s->__lock);
01227       if (s->eventq && s->eventq->next)
01228          needexit = 1;
01229       if (s->waiting_thread != pthread_self())
01230          needexit = 1;
01231       if (s->needdestroy)
01232          needexit = 1;
01233       ast_mutex_unlock(&s->__lock);
01234       if (needexit)
01235          break;
01236       if (s->fd > 0) {
01237          if (ast_wait_for_input(s->fd, 1000))
01238             break;
01239       } else {
01240          sleep(1);
01241       }
01242    }
01243    if (option_debug)
01244       ast_log(LOG_DEBUG, "Finished waiting for an event!\n");
01245    ast_mutex_lock(&s->__lock);
01246    if (s->waiting_thread == pthread_self()) {
01247       astman_send_response(s, m, "Success", "Waiting for Event...");
01248       /* Only show events if we're the most recent waiter */
01249       while(s->eventq->next) {
01250          eqe = s->eventq->next;
01251          if (((s->readperm & eqe->category) == eqe->category) &&
01252              ((s->send_events & eqe->category) == eqe->category)) {
01253             astman_append(s, "%s", eqe->eventdata);
01254          }
01255          unuse_eventqent(s->eventq);
01256          s->eventq = eqe;
01257       }
01258       astman_append(s,
01259          "Event: WaitEventComplete\r\n"
01260          "%s"
01261          "\r\n", idText);
01262       s->waiting_thread = AST_PTHREADT_NULL;
01263    } else {
01264       ast_log(LOG_DEBUG, "Abandoning event request!\n");
01265    }
01266    ast_mutex_unlock(&s->__lock);
01267    return 0;
01268 }

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

Definition at line 2296 of file manager.c.

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

Referenced by init_manager(), and manager_event().

02297 {
02298    struct eventqent *tmp, *prev = NULL;
02299    tmp = ast_malloc(sizeof(*tmp) + strlen(str));
02300 
02301    if (!tmp)
02302       return -1;
02303 
02304    tmp->next = NULL;
02305    tmp->category = category;
02306    strcpy(tmp->eventdata, str);
02307    
02308    if (master_eventq) {
02309       prev = master_eventq;
02310       while (prev->next) 
02311          prev = prev->next;
02312       prev->next = tmp;
02313    } else {
02314       master_eventq = tmp;
02315    }
02316    
02317    tmp->usecount = num_sessions;
02318    
02319    return 0;
02320 }

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

Definition at line 396 of file manager.c.

References AST_LIST_TRAVERSE, and ast_manager_user::username.

Referenced by handle_showmanager(), and init_manager().

00397 {
00398    struct ast_manager_user *user = NULL;
00399 
00400    AST_LIST_TRAVERSE(&users, user, list)
00401       if (!strcasecmp(user->username, name))
00402          break;
00403    return user;
00404 }

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

References ast_variable::next.

Referenced by get_perm(), and strings_to_mask().

00784 {
00785    const char *val = bigstr, *next;
00786 
00787    do {
00788       if ((next = strchr(val, delim))) {
00789          if (!strncmp(val, smallstr, (next - val)))
00790             return 1;
00791          else
00792             continue;
00793       } else
00794          return !strcmp(smallstr, val);
00795 
00796    } while (*(val = (next + 1)));
00797 
00798    return 0;
00799 }

static int ast_is_number ( char *  string  )  [static]

Definition at line 816 of file manager.c.

Referenced by strings_to_mask().

00817 {
00818    int ret = 1, x = 0;
00819 
00820    if (!string)
00821       return 0;
00822 
00823    for (x = 0; x < strlen(string); x++) {
00824       if (!(string[x] >= 48 && string[x] <= 57)) {
00825          ret = 0;
00826          break;
00827       }
00828    }
00829    
00830    return ret ? atoi(string) : 0;
00831 }

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

References ast_malloc, and ast_manager_register_struct().

Referenced by init_manager(), and load_module().

02443 {
02444    struct manager_action *cur;
02445 
02446    cur = ast_malloc(sizeof(*cur));
02447    if (!cur)
02448       return -1;
02449    
02450    cur->action = action;
02451    cur->authority = auth;
02452    cur->func = func;
02453    cur->synopsis = synopsis;
02454    cur->description = description;
02455    cur->next = NULL;
02456 
02457    ast_manager_register_struct(cur);
02458 
02459    return 0;
02460 }

static int ast_manager_register_struct ( struct manager_action act  )  [static]

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

02399 {
02400    struct manager_action *cur, *prev = NULL;
02401    int ret;
02402 
02403    ast_rwlock_wrlock(&actionlock);
02404    cur = first_action;
02405    while (cur) { /* Walk the list of actions */
02406       ret = strcasecmp(cur->action, act->action);
02407       if (ret == 0) {
02408          ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
02409          ast_rwlock_unlock(&actionlock);
02410          return -1;
02411       } else if (ret > 0) {
02412          /* Insert these alphabetically */
02413          if (prev) {
02414             act->next = prev->next;
02415             prev->next = act;
02416          } else {
02417             act->next = first_action;
02418             first_action = act;
02419          }
02420          break;
02421       }
02422       prev = cur; 
02423       cur = cur->next;
02424    }
02425    
02426    if (!cur) {
02427       if (prev)
02428          prev->next = act;
02429       else
02430          first_action = act;
02431       act->next = NULL;
02432    }
02433 
02434    if (option_verbose > 1) 
02435       ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", act->action);
02436    ast_rwlock_unlock(&actionlock);
02437    return 0;
02438 }

int ast_manager_unregister ( char *  action  ) 

Parameters:
action Name of registred Action:

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

02370 {
02371    struct manager_action *cur, *prev;
02372 
02373    ast_rwlock_wrlock(&actionlock);
02374    cur = prev = first_action;
02375    while (cur) {
02376       if (!strcasecmp(action, cur->action)) {
02377          prev->next = cur->next;
02378          free(cur);
02379          if (option_verbose > 1) 
02380             ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action);
02381          ast_rwlock_unlock(&actionlock);
02382          return 0;
02383       }
02384       prev = cur;
02385       cur = cur->next;
02386    }
02387    ast_rwlock_unlock(&actionlock);
02388    return 0;
02389 }

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

00407 {
00408    va_list ap;
00409    struct ast_dynamic_str *buf;
00410 
00411    ast_mutex_lock(&s->__lock);
00412 
00413    if (!(buf = ast_dynamic_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) {
00414       ast_mutex_unlock(&s->__lock);
00415       return;
00416    }
00417 
00418    va_start(ap, fmt);
00419    ast_dynamic_str_thread_set_va(&buf, 0, &astman_append_buf, fmt, ap);
00420    va_end(ap);
00421    
00422    if (s->fd > -1)
00423       ast_carefulwrite(s->fd, buf->str, strlen(buf->str), s->writetimeout);
00424    else {
00425       if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) {
00426          ast_mutex_unlock(&s->__lock);
00427          return;
00428       }
00429 
00430       ast_dynamic_str_append(&s->outputstr, 0, "%s", buf->str);   
00431    }
00432 
00433    ast_mutex_unlock(&s->__lock);
00434 }

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

Get header from mananger transaction

Definition at line 686 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_command(), 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().

00687 {
00688    char cmp[80];
00689    int x;
00690 
00691    snprintf(cmp, sizeof(cmp), "%s: ", var);
00692 
00693    for (x = 0; x < m->hdrcount; x++) {
00694       if (!strncasecmp(cmp, m->headers[x], strlen(cmp)))
00695          return m->headers[x] + strlen(cmp);
00696    }
00697 
00698    return "";
00699 }

struct ast_variable* astman_get_variables ( const struct message m  ) 

Get a linked list of the Variable: headers

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

00702 {
00703    int varlen, x, y;
00704    struct ast_variable *head = NULL, *cur;
00705    char *var, *val;
00706 
00707    char *parse;    
00708    AST_DECLARE_APP_ARGS(args,
00709       AST_APP_ARG(vars)[32];
00710    );
00711 
00712    varlen = strlen("Variable: ");   
00713 
00714    for (x = 0; x < m->hdrcount; x++) {
00715       if (strncasecmp("Variable: ", m->headers[x], varlen))
00716          continue;
00717 
00718       parse = ast_strdupa(m->headers[x] + varlen);
00719 
00720       AST_STANDARD_APP_ARGS(args, parse);
00721       if (args.argc) {
00722          for (y = 0; y < args.argc; y++) {
00723             if (!args.vars[y])
00724                continue;
00725             var = val = ast_strdupa(args.vars[y]);
00726             strsep(&val, "=");
00727             if (!val || ast_strlen_zero(var))
00728                continue;
00729             cur = ast_variable_new(var, val);
00730             if (head) {
00731                cur->next = head;
00732                head = cur;
00733             } else
00734                head = cur;
00735          }
00736       }
00737    }
00738 
00739    return head;
00740 }

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

Definition at line 773 of file manager.c.

References astman_send_response(), and s.

Referenced by action_agent_callback_login(), action_agent_logoff(), action_agents(), 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().

00774 {
00775    astman_send_response(s, m, "Success", msg);
00776 }

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

00751 {
00752    const char *id = astman_get_header(m,"ActionID");
00753 
00754    astman_append(s, "Response: Error\r\n");
00755    if (!ast_strlen_zero(id))
00756       astman_append(s, "ActionID: %s\r\n", id);
00757    astman_append(s, "Message: %s\r\n\r\n", error);
00758 }

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

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

00761 {
00762    const char *id = astman_get_header(m,"ActionID");
00763 
00764    astman_append(s, "Response: %s\r\n", resp);
00765    if (!ast_strlen_zero(id))
00766       astman_append(s, "ActionID: %s\r\n", id);
00767    if (msg)
00768       astman_append(s, "Message: %s\r\n\r\n", msg);
00769    else
00770       astman_append(s, "\r\n");
00771 }

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

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

00877 {
00878    struct ast_config *cfg;
00879    char *cat;
00880    const char *user = astman_get_header(m, "Username");
00881    const char *pass = astman_get_header(m, "Secret");
00882    const char *authtype = astman_get_header(m, "AuthType");
00883    const char *key = astman_get_header(m, "Key");
00884    const char *events = astman_get_header(m, "Events");
00885    
00886    cfg = ast_config_load("manager.conf");
00887    if (!cfg)
00888       return -1;
00889    cat = ast_category_browse(cfg, NULL);
00890    while (cat) {
00891       if (strcasecmp(cat, "general")) {
00892          /* This is a user */
00893          if (!strcasecmp(cat, user)) {
00894             struct ast_variable *v;
00895             struct ast_ha *ha = NULL;
00896             char *password = NULL;
00897 
00898             for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
00899                if (!strcasecmp(v->name, "secret")) {
00900                   password = v->value;
00901                } else if (!strcasecmp(v->name, "displaysystemname")) {
00902                   if (ast_true(v->value)) {
00903                      if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
00904                         s->displaysystemname = 1;
00905                      } else {
00906                         ast_log(LOG_ERROR, "Can't enable displaysystemname in manager.conf - no system name configured in asterisk.conf\n");
00907                      }
00908                   }
00909                } else if (!strcasecmp(v->name, "permit") ||
00910                      !strcasecmp(v->name, "deny")) {
00911                   ha = ast_append_ha(v->name, v->value, ha);
00912                } else if (!strcasecmp(v->name, "writetimeout")) {
00913                   int val = atoi(v->value);
00914 
00915                   if (val < 100)
00916                      ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", v->value, v->lineno);
00917                   else
00918                      s->writetimeout = val;
00919                }
00920                      
00921             }
00922             if (ha && !ast_apply_ha(ha, &(s->sin))) {
00923                ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);
00924                ast_free_ha(ha);
00925                ast_config_destroy(cfg);
00926                return -1;
00927             } else if (ha)
00928                ast_free_ha(ha);
00929             if (!strcasecmp(authtype, "MD5")) {
00930                if (!ast_strlen_zero(key) && 
00931                    !ast_strlen_zero(s->challenge) && !ast_strlen_zero(password)) {
00932                   int x;
00933                   int len = 0;
00934                   char md5key[256] = "";
00935                   struct MD5Context md5;
00936                   unsigned char digest[16];
00937                   MD5Init(&md5);
00938                   MD5Update(&md5, (unsigned char *) s->challenge, strlen(s->challenge));
00939                   MD5Update(&md5, (unsigned char *) password, strlen(password));
00940                   MD5Final(digest, &md5);
00941                   for (x=0; x<16; x++)
00942                      len += sprintf(md5key + len, "%2.2x", digest[x]);
00943                   if (!strcmp(md5key, key))
00944                      break;
00945                   else {
00946                      ast_config_destroy(cfg);
00947                      return -1;
00948                   }
00949                } else {
00950                   ast_log(LOG_DEBUG, "MD5 authentication is not possible.  challenge: '%s'\n", 
00951                      S_OR(s->challenge, ""));
00952                   ast_config_destroy(cfg);
00953                   return -1;
00954                }
00955             } else if (password && !strcmp(password, pass)) {
00956                break;
00957             } else {
00958                ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);
00959                ast_config_destroy(cfg);
00960                return -1;
00961             }  
00962          }
00963       }
00964       cat = ast_category_browse(cfg, cat);
00965    }
00966    if (cat) {
00967       ast_copy_string(s->username, cat, sizeof(s->username));
00968       s->readperm = get_perm(ast_variable_retrieve(cfg, cat, "read"));
00969       s->writeperm = get_perm(ast_variable_retrieve(cfg, cat, "write"));
00970       ast_config_destroy(cfg);
00971       if (events)
00972          set_eventmask(s, events);
00973       return 0;
00974    }
00975    ast_config_destroy(cfg);
00976    cfg = ast_config_load("users.conf");
00977    if (!cfg)
00978       return -1;
00979    cat = ast_category_browse(cfg, NULL);
00980    while (cat) {
00981       struct ast_variable *v;
00982       const char *password = NULL;
00983       int hasmanager = 0;
00984       if (strcasecmp(cat, user) || !strcasecmp(cat, "general")) {
00985          cat = ast_category_browse(cfg, cat);
00986          continue;
00987       }
00988       for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
00989          if (!strcasecmp(v->name, "secret"))
00990             password = v->value;
00991          else if (!strcasecmp(v->name, "hasmanager"))
00992             hasmanager = ast_true(v->value);
00993       }
00994       if (!hasmanager)
00995          break;
00996       if (!password || strcmp(password, pass)) {
00997          ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);
00998          ast_config_destroy(cfg);
00999          return -1;
01000       }
01001       ast_copy_string(s->username, cat, sizeof(s->username));
01002       s->readperm = -1;
01003       s->writeperm = -1;
01004       ast_config_destroy(cfg);
01005       if (events)
01006          set_eventmask(s, events);
01007       return 0;
01008    }
01009    ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user);
01010    ast_config_destroy(cfg);
01011    return -1;
01012 }

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

Convert authority code to string with serveral options.

Definition at line 195 of file manager.c.

References ast_strlen_zero(), and perms.

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

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

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

Definition at line 217 of file manager.c.

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

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

static void destroy_session ( struct mansession s  )  [static]

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

00677 {
00678    AST_LIST_LOCK(&sessions);
00679    AST_LIST_REMOVE(&sessions, s, list);
00680    AST_LIST_UNLOCK(&sessions);
00681 
00682    ast_atomic_fetchadd_int(&num_sessions, -1);
00683    free_session(s);
00684 }

static int do_message ( struct mansession s  )  [static]

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

02142 {
02143    struct message m = { 0 };
02144    char header_buf[sizeof(s->inbuf)] = { '\0' };
02145    int res;
02146 
02147    for (;;) {
02148       /* Check if any events are pending and do them if needed */
02149       if (s->eventq->next) {
02150          if (process_events(s))
02151             return -1;
02152       }
02153       res = get_input(s, header_buf);
02154       if (res == 0) {
02155          continue;
02156       } else if (res > 0) {
02157          /* Strip trailing \r\n */
02158          if (strlen(header_buf) < 2)
02159             continue;
02160          header_buf[strlen(header_buf) - 2] = '\0';
02161          if (ast_strlen_zero(header_buf))
02162             return process_message(s, &m) ? -1 : 0;
02163          else if (m.hdrcount < (AST_MAX_MANHEADERS - 1))
02164             m.headers[m.hdrcount++] = ast_strdupa(header_buf);
02165       } else {
02166          return res;
02167       }
02168    }
02169 }

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

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

01647 {
01648    struct fast_originate_helper *in = data;
01649    int res;
01650    int reason = 0;
01651    struct ast_channel *chan = NULL;
01652    char requested_channel[AST_CHANNEL_NAME];
01653 
01654    if (!ast_strlen_zero(in->app)) {
01655       res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, 
01656          S_OR(in->cid_num, NULL), 
01657          S_OR(in->cid_name, NULL),
01658          in->vars, in->account, &chan);
01659    } else {
01660       res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 
01661          S_OR(in->cid_num, NULL), 
01662          S_OR(in->cid_name, NULL),
01663          in->vars, in->account, &chan);
01664    }
01665 
01666    if (!chan)
01667       snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);   
01668    /* Tell the manager what happened with the channel */
01669    manager_event(EVENT_FLAG_CALL, "OriginateResponse",
01670       "%s"
01671       "Response: %s\r\n"
01672       "Channel: %s\r\n"
01673       "Context: %s\r\n"
01674       "Exten: %s\r\n"
01675       "Reason: %d\r\n"
01676       "Uniqueid: %s\r\n"
01677       "CallerID: %s\r\n"      /* This parameter is deprecated and will be removed post-1.4 */
01678       "CallerIDNum: %s\r\n"
01679       "CallerIDName: %s\r\n",
01680       in->idtext, res ? "Failure" : "Success", chan ? chan->name : requested_channel, in->context, in->exten, reason, 
01681       chan ? chan->uniqueid : "<null>",
01682       S_OR(in->cid_num, "<unknown>"),
01683       S_OR(in->cid_num, "<unknown>"),
01684       S_OR(in->cid_name, "<unknown>")
01685       );
01686 
01687    /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
01688    if (chan)
01689       ast_channel_unlock(chan);
01690    free(in);
01691    return NULL;
01692 }

static void free_session ( struct mansession s  )  [static]

Definition at line 660 of file manager.c.

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

Referenced by accept_thread(), and destroy_session().

00661 {
00662    struct eventqent *eqe;
00663    if (s->fd > -1)
00664       close(s->fd);
00665    if (s->outputstr)
00666       free(s->outputstr);
00667    ast_mutex_destroy(&s->__lock);
00668    while (s->eventq) {
00669       eqe = s->eventq;
00670       s->eventq = s->eventq->next;
00671       unuse_eventqent(eqe);
00672    }
00673    free(s);
00674 }

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

Definition at line 2087 of file manager.c.

References ast_channel::fds, and s.

Referenced by do_message(), and skinny_session().

02088 {
02089    /* output must have at least sizeof(s->inbuf) space */
02090    int res;
02091    int x;
02092    struct pollfd fds[1];
02093    for (x = 1; x < s->inlen; x++) {
02094       if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) {
02095          /* Copy output data up to and including \r\n */
02096          memcpy(output, s->inbuf, x + 1);
02097          /* Add trailing \0 */
02098          output[x+1] = '\0';
02099          /* Move remaining data back to the front */
02100          memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x);
02101          s->inlen -= (x + 1);
02102          return 1;
02103       }
02104    } 
02105    if (s->inlen >= sizeof(s->inbuf) - 1) {
02106       ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->sin.sin_addr), s->inbuf);
02107       s->inlen = 0;
02108    }
02109    fds[0].fd = s->fd;
02110    fds[0].events = POLLIN;
02111    do {
02112       ast_mutex_lock(&s->__lock);
02113       s->waiting_thread = pthread_self();
02114       ast_mutex_unlock(&s->__lock);
02115 
02116       res = poll(fds, 1, -1);
02117 
02118       ast_mutex_lock(&s->__lock);
02119       s->waiting_thread = AST_PTHREADT_NULL;
02120       ast_mutex_unlock(&s->__lock);
02121       if (res < 0) {
02122          if (errno == EINTR) {
02123             return 0;
02124          }
02125          ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));
02126          return -1;
02127       } else if (res > 0) {
02128          ast_mutex_lock(&s->__lock);
02129          res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen);
02130          ast_mutex_unlock(&s->__lock);
02131          if (res < 1)
02132             return -1;
02133          break;
02134       }
02135    } while(1);
02136    s->inlen += res;
02137    s->inbuf[s->inlen] = '\0';
02138    return 0;
02139 }

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

Definition at line 801 of file manager.c.

References ast_instring(), and perms.

00802 {
00803    int x = 0, ret = 0;
00804 
00805    if (!instr)
00806       return 0;
00807 
00808    for (x = 0; x < (sizeof(perms) / sizeof(perms[0])); x++) {
00809       if (ast_instring(instr, perms[x].label, ','))
00810          ret |= perms[x].num;
00811    }
00812    
00813    return ret;
00814 }

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

Definition at line 457 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, and ast_manager_user::write.

00458 {
00459    struct ast_manager_user *user = NULL;
00460 
00461    if (argc != 4)
00462       return RESULT_SHOWUSAGE;
00463 
00464    AST_LIST_LOCK(&users);
00465 
00466    if (!(user = ast_get_manager_by_name_locked(argv[3]))) {
00467       ast_cli(fd, "There is no manager called %s\n", argv[3]);
00468       AST_LIST_UNLOCK(&users);
00469       return -1;
00470    }
00471 
00472    ast_cli(fd,"\n");
00473    ast_cli(fd,
00474       "       username: %s\n"
00475       "         secret: %s\n"
00476       "           deny: %s\n"
00477       "         permit: %s\n"
00478       "           read: %s\n"
00479       "          write: %s\n"
00480       "displayconnects: %s\n",
00481       (user->username ? user->username : "(N/A)"),
00482       (user->secret ? "<Set>" : "(N/A)"),
00483       (user->deny ? user->deny : "(N/A)"),
00484       (user->permit ? user->permit : "(N/A)"),
00485       (user->read ? user->read : "(N/A)"),
00486       (user->write ? user->write : "(N/A)"),
00487       (user->displayconnects ? "yes" : "no"));
00488 
00489    AST_LIST_UNLOCK(&users);
00490 
00491    return RESULT_SUCCESS;
00492 }

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

Definition at line 495 of file manager.c.

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

00496 {
00497    struct ast_manager_user *user = NULL;
00498    int count_amu = 0;
00499 
00500    if (argc != 3)
00501       return RESULT_SHOWUSAGE;
00502 
00503    AST_LIST_LOCK(&users);
00504 
00505    /* If there are no users, print out something along those lines */
00506    if (AST_LIST_EMPTY(&users)) {
00507       ast_cli(fd, "There are no manager users.\n");
00508       AST_LIST_UNLOCK(&users);
00509       return RESULT_SUCCESS;
00510    }
00511 
00512    ast_cli(fd, "\nusername\n--------\n");
00513 
00514    AST_LIST_TRAVERSE(&users, user, list) {
00515       ast_cli(fd, "%s\n", user->username);
00516       count_amu++;
00517    }
00518 
00519    AST_LIST_UNLOCK(&users);
00520 
00521    ast_cli(fd,"-------------------\n");
00522    ast_cli(fd,"%d manager users configured.\n", count_amu);
00523 
00524    return RESULT_SUCCESS;
00525 }

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

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

Definition at line 437 of file manager.c.

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

00438 {
00439    struct manager_action *cur;
00440    char authority[80];
00441    int num;
00442 
00443    if (argc != 4)
00444       return RESULT_SHOWUSAGE;
00445 
00446    for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */
00447       for (num = 3; num < argc; num++) {
00448          if (!strcasecmp(cur->action, argv[num])) {
00449             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 : "");
00450          }
00451       }
00452    }
00453 
00454    return RESULT_SUCCESS;
00455 }

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

CLI command Should change to "manager show commands".

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

00531 {
00532    struct manager_action *cur;
00533    char authority[80];
00534    char *format = "  %-15.15s  %-15.15s  %-55.55s\n";
00535 
00536    ast_cli(fd, format, "Action", "Privilege", "Synopsis");
00537    ast_cli(fd, format, "------", "---------", "--------");
00538    
00539    ast_rwlock_rdlock(&actionlock);
00540    for (cur = first_action; cur; cur = cur->next) /* Walk the list of actions */
00541       ast_cli(fd, format, cur->action, authority_to_str(cur->authority, authority, sizeof(authority) -1), cur->synopsis);
00542    ast_rwlock_unlock(&actionlock);
00543    
00544    return RESULT_SUCCESS;
00545 }

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

CLI command show manager connected.

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

00550 {
00551    struct mansession *s;
00552    char *format = "  %-15.15s  %-15.15s\n";
00553 
00554    ast_cli(fd, format, "Username", "IP Address");
00555    
00556    AST_LIST_LOCK(&sessions);
00557    AST_LIST_TRAVERSE(&sessions, s, list)
00558       ast_cli(fd, format,s->username, ast_inet_ntoa(s->sin.sin_addr));
00559    AST_LIST_UNLOCK(&sessions);
00560 
00561    return RESULT_SUCCESS;
00562 }

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

CLI command show manager connected.

Definition at line 566 of file manager.c.

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

00567 {
00568    struct eventqent *s;
00569 
00570    AST_LIST_LOCK(&sessions);
00571    for (s = master_eventq; s; s = s->next) {
00572       ast_cli(fd, "Usecount: %d\n",s->usecount);
00573       ast_cli(fd, "Category: %d\n", s->category);
00574       ast_cli(fd, "Event:\n%s", s->eventdata);
00575    }
00576    AST_LIST_UNLOCK(&sessions);
00577 
00578    return RESULT_SUCCESS;
00579 }

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

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

01070 {
01071    int x;
01072    char hdr[40];
01073    const char *action, *cat, *var, *value, *match;
01074    struct ast_category *category;
01075    struct ast_variable *v;
01076    
01077    for (x=0;x<100000;x++) {
01078       unsigned int object = 0;
01079 
01080       snprintf(hdr, sizeof(hdr), "Action-%06d", x);
01081       action = astman_get_header(m, hdr);
01082       if (ast_strlen_zero(action))
01083          break;
01084       snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
01085       cat = astman_get_header(m, hdr);
01086       snprintf(hdr, sizeof(hdr), "Var-%06d", x);
01087       var = astman_get_header(m, hdr);
01088       snprintf(hdr, sizeof(hdr), "Value-%06d", x);
01089       value = astman_get_header(m, hdr);
01090       if (!ast_strlen_zero(value) && *value == '>') {
01091          object = 1;
01092          value++;
01093       }
01094       snprintf(hdr, sizeof(hdr), "Match-%06d", x);
01095       match = astman_get_header(m, hdr);
01096       if (!strcasecmp(action, "newcat")) {
01097          if (!ast_strlen_zero(cat)) {
01098             category = ast_category_new(cat);
01099             if (category) {
01100                ast_category_append(cfg, category);
01101             }
01102          }
01103       } else if (!strcasecmp(action, "renamecat")) {
01104          if (!ast_strlen_zero(cat) && !ast_strlen_zero(value)) {
01105             category = ast_category_get(cfg, cat);
01106             if (category) 
01107                ast_category_rename(category, value);
01108          }
01109       } else if (!strcasecmp(action, "delcat")) {
01110          if (!ast_strlen_zero(cat))
01111             ast_category_delete(cfg, (char *) cat);
01112       } else if (!strcasecmp(action, "update")) {
01113          if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat)))
01114             ast_variable_update(category, var, value, match, object);
01115       } else if (!strcasecmp(action, "delete")) {
01116          if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat)))
01117             ast_variable_delete(category, (char *) var, (char *) match);
01118       } else if (!strcasecmp(action, "append")) {
01119          if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && 
01120             (category = ast_category_get(cfg, cat)) && 
01121             (v = ast_variable_new(var, value))){
01122             if (object || (match && !strcasecmp(match, "object")))
01123                v->object = 1;
01124             ast_variable_append(category, v);
01125          }
01126       }
01127    }
01128 }

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

Definition at line 347 of file manager.c.

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

00348 {
00349    int x;
00350    int colons = 0;
00351    int breaks = 0;
00352    size_t len;
00353    int count = 1;
00354    char *tmp, *var, *val, *out;
00355 
00356    for (x=0; in[x]; x++) {
00357       if (in[x] == ':')
00358          colons++;
00359       if (in[x] == '\n')
00360          breaks++;
00361    }
00362    len = strlen(in) + colons * 40 + breaks * 40; /* <tr><td></td><td></td></tr>, "<tr><td colspan=\"2\"><hr></td></tr> */
00363    out = ast_malloc(len);
00364    if (!out)
00365       return 0;
00366    tmp = out;
00367    while (*in) {
00368       var = in;
00369       while (*in && (*in >= 32))
00370          in++;
00371       if (*in) {
00372          if ((count % 4) == 0){
00373             ast_build_string(&tmp, &len, "<tr><td colspan=\"2\"><hr></td></tr>\r\n");
00374          }
00375          count = 0;
00376          while (*in && (*in < 32)) {
00377             *in = '\0';
00378             in++;
00379             count++;
00380          }
00381          val = strchr(var, ':');
00382          if (val) {
00383             *val = '\0';
00384             val++;
00385             if (*val == ' ')
00386                val++;
00387             ast_build_string(&tmp, &len, "<tr><td>%s</td><td>%s</td></tr>\r\n", var, val);
00388          }
00389       }
00390    }
00391    return out;
00392 }

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

manager_event: Send AMI event to client

Definition at line 2323 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_park_call(), ast_set_callerid(), ast_setstate(), changethread(), 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_exec(), parse_register_contact(), pbx_extension_helper(), phase_e_handler(), post_manager_event(), process_sdp(), 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().

02324 {
02325    struct mansession *s;
02326    char auth[80];
02327    va_list ap;
02328    struct timeval now;
02329    struct ast_dynamic_str *buf;
02330 
02331    /* Abort if there aren't any manager sessions */
02332    if (!num_sessions)
02333       return 0;
02334 
02335    if (!(buf = ast_dynamic_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE)))
02336       return -1;
02337 
02338    ast_dynamic_str_thread_set(&buf, 0, &manager_event_buf,
02339          "Event: %s\r\nPrivilege: %s\r\n",
02340           event, authority_to_str(category, auth, sizeof(auth)));
02341 
02342    if (timestampevents) {
02343       now = ast_tvnow();
02344       ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf,
02345             "Timestamp: %ld.%06lu\r\n",
02346              now.tv_sec, (unsigned long) now.tv_usec);
02347    }
02348 
02349    va_start(ap, fmt);
02350    ast_dynamic_str_thread_append_va(&buf, 0, &manager_event_buf, fmt, ap);
02351    va_end(ap);
02352    
02353    ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, "\r\n");  
02354    
02355    /* Append event to master list and wake up any sleeping sessions */
02356    AST_LIST_LOCK(&sessions);
02357    append_event(buf->str, category);
02358    AST_LIST_TRAVERSE(&sessions, s, list) {
02359       ast_mutex_lock(&s->__lock);
02360       if (s->waiting_thread != AST_PTHREADT_NULL)
02361          pthread_kill(s->waiting_thread, SIGURG);
02362       ast_mutex_unlock(&s->__lock);
02363    }
02364    AST_LIST_UNLOCK(&sessions);
02365 
02366    return 0;
02367 }

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

Definition at line 2391 of file manager.c.

References EVENT_FLAG_CALL, and manager_event().

Referenced by init_manager().

02392 {
02393    /* Notify managers of change */
02394    manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nStatus: %d\r\n", exten, context, state);
02395    return 0;
02396 }

static int process_events ( struct mansession s  )  [static]

Definition at line 1957 of file manager.c.

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

Referenced by do_message().

01958 {
01959    struct eventqent *eqe;
01960    int ret = 0;
01961    ast_mutex_lock(&s->__lock);
01962    if (s->fd > -1) {
01963       if (!s->eventq)
01964          s->eventq = master_eventq;
01965       while(s->eventq->next) {
01966          eqe = s->eventq->next;
01967          if ((s->authenticated && (s->readperm & eqe->category) == eqe->category) &&
01968              ((s->send_events & eqe->category) == eqe->category)) {
01969             if (!ret && ast_carefulwrite(s->fd, eqe->eventdata, strlen(eqe->eventdata), s->writetimeout) < 0)
01970                ret = -1;
01971          }
01972          unuse_eventqent(s->eventq);
01973          s->eventq = eqe;
01974       }
01975    }
01976    ast_mutex_unlock(&s->__lock);
01977    return ret;
01978 }

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

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

02006 {
02007    char action[80] = "";
02008    struct manager_action *tmp;
02009    const char *id = astman_get_header(m,"ActionID");
02010    char idText[256] = "";
02011    int ret = 0;
02012 
02013    ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action));
02014    if (option_debug)
02015       ast_log( LOG_DEBUG, "Manager received command '%s'\n", action );
02016 
02017    if (ast_strlen_zero(action)) {
02018       astman_send_error(s, m, "Missing action in request");
02019       return 0;
02020    }
02021    if (!ast_strlen_zero(id)) {
02022       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
02023    }
02024    if (!s->authenticated) {
02025       if (!strcasecmp(action, "Challenge")) {
02026          const char *authtype = astman_get_header(m, "AuthType");
02027 
02028          if (!strcasecmp(authtype, "MD5")) {
02029             if (ast_strlen_zero(s->challenge))
02030                snprintf(s->challenge, sizeof(s->challenge), "%ld", ast_random());
02031             astman_append(s, "Response: Success\r\n"
02032                   "%s"
02033                   "Challenge: %s\r\n\r\n",
02034                   idText, s->challenge);
02035             return 0;
02036          } else {
02037             astman_send_error(s, m, "Must specify AuthType");
02038             return 0;
02039          }
02040       } else if (!strcasecmp(action, "Login")) {
02041          if (authenticate(s, m)) {
02042             sleep(1);
02043             astman_send_error(s, m, "Authentication failed");
02044             return -1;
02045          } else {
02046             s->authenticated = 1;
02047             if (option_verbose > 1) {
02048                if (displayconnects) {
02049                   ast_verbose(VERBOSE_PREFIX_2 "%sManager '%s' logged on from %s\n", 
02050                      (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
02051                }
02052             }
02053             ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", 
02054                (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
02055             astman_send_ack(s, m, "Authentication accepted");
02056          }
02057       } else if (!strcasecmp(action, "Logoff")) {
02058          astman_send_ack(s, m, "See ya");
02059          return -1;
02060       } else
02061          astman_send_error(s, m, "Authentication Required");
02062    } else {
02063       if (!strcasecmp(action, "Login"))
02064          astman_send_ack(s, m, "Already logged in");
02065       else {
02066          ast_rwlock_rdlock(&actionlock);
02067          for (tmp = first_action; tmp; tmp = tmp->next) {      
02068             if (strcasecmp(action, tmp->action))
02069                continue;
02070             if ((s->writeperm & tmp->authority) == tmp->authority) {
02071                if (tmp->func(s, m))
02072                   ret = -1;
02073             } else
02074                astman_send_error(s, m, "Permission denied");
02075             break;
02076          }
02077          ast_rwlock_unlock(&actionlock);
02078          if (!tmp)
02079             astman_send_error(s, m, "Invalid/unknown command");
02080       }
02081    }
02082    if (ret)
02083       return ret;
02084    return process_events(s);
02085 }

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

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

02172 {
02173    struct mansession *s = data;
02174    int res;
02175    
02176    astman_append(s, "Asterisk Call Manager/1.0\r\n");
02177    for (;;) {
02178       if ((res = do_message(s)) < 0)
02179          break;
02180    }
02181    if (s->authenticated) {
02182       if (option_verbose > 1) {
02183          if (displayconnects) 
02184             ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
02185       }
02186       ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
02187    } else {
02188       if (option_verbose > 1) {
02189          if (displayconnects)
02190             ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr));
02191       }
02192       ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr));
02193    }
02194    destroy_session(s);
02195    return NULL;
02196 }

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

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

Referenced by action_events().

00865 {
00866    int maskint = strings_to_mask(eventmask);
00867 
00868    ast_mutex_lock(&s->__lock);
00869    if (maskint >= 0) 
00870       s->send_events = maskint;
00871    ast_mutex_unlock(&s->__lock);
00872    
00873    return maskint;
00874 }

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

Definition at line 833 of file manager.c.

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

Referenced by set_eventmask().

00834 {
00835    int x, ret = -1;
00836    
00837    x = ast_is_number((char *) string);
00838 
00839    if (x)
00840       ret = x;
00841    else if (ast_strlen_zero(string))
00842       ret = -1;
00843    else if (ast_false(string))
00844       ret = 0;
00845    else if (ast_true(string)) {
00846       ret = 0;
00847       for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++)
00848          ret |= perms[x].num;    
00849    } else {
00850       ret = 0;
00851       for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) {
00852          if (ast_instring(string, perms[x].label, ',')) 
00853             ret |= perms[x].num;    
00854       }
00855    }
00856 
00857    return ret;
00858 }

static void unuse_eventqent ( struct eventqent e  )  [static]

Definition at line 654 of file manager.c.

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

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

00655 {
00656    if (ast_atomic_dec_and_test(&e->usecount) && e->next)
00657       pthread_kill(t, SIGURG);
00658 }

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

Definition at line 235 of file manager.c.

Referenced by xml_translate().

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

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

Definition at line 272 of file manager.c.

References ast_build_string(), ast_malloc, len, ast_variable::name, ast_variable::next, ast_variable::value, var, and xml_copy_escape().

00273 {
00274    struct ast_variable *v;
00275    char *dest = NULL;
00276    char *out, *tmp, *var, *val;
00277    char *objtype = NULL;
00278    int colons = 0;
00279    int breaks = 0;
00280    size_t len;
00281    int count = 1;
00282    int escaped = 0;
00283    int inobj = 0;
00284    int x;
00285    
00286    for (v = vars; v; v = v->next) {
00287       if (!dest && !strcasecmp(v->name, "ajaxdest"))
00288          dest = v->value;
00289       else if (!objtype && !strcasecmp(v->name, "ajaxobjtype")) 
00290          objtype = v->value;
00291    }
00292    if (!dest)
00293       dest = "unknown";
00294    if (!objtype)
00295       objtype = "generic";
00296    for (x = 0; in[x]; x++) {
00297       if (in[x] == ':')
00298          colons++;
00299       else if (in[x] == '\n')
00300          breaks++;
00301       else if (strchr("&\"<>", in[x]))
00302          escaped++;
00303    }
00304    len = (size_t) (strlen(in) + colons * 5 + breaks * (40 + strlen(dest) + strlen(objtype)) + escaped * 10); /* foo="bar", "<response type=\"object\" id=\"dest\"", "&amp;" */
00305    out = ast_malloc(len);
00306    if (!out)
00307       return 0;
00308    tmp = out;
00309    while (*in) {
00310       var = in;
00311       while (*in && (*in >= 32))
00312          in++;
00313       if (*in) {
00314          if ((count > 3) && inobj) {
00315             ast_build_string(&tmp, &len, " /></response>\n");
00316             inobj = 0;
00317          }
00318          count = 0;
00319          while (*in && (*in < 32)) {
00320             *in = '\0';
00321             in++;
00322             count++;
00323          }
00324          val = strchr(var, ':');
00325          if (val) {
00326             *val = '\0';
00327             val++;
00328             if (*val == ' ')
00329                val++;
00330             if (!inobj) {
00331                ast_build_string(&tmp, &len, "<response type='object' id='%s'><%s", dest, objtype);
00332                inobj = 1;
00333             }
00334             ast_build_string(&tmp, &len, " ");           
00335             xml_copy_escape(&tmp, &len, var, 1);
00336             ast_build_string(&tmp, &len, "='");
00337             xml_copy_escape(&tmp, &len, val, 0);
00338             ast_build_string(&tmp, &len, "'");
00339          }
00340       }
00341    }
00342    if (inobj)
00343       ast_build_string(&tmp, &len, " /></response>\n");
00344    return out;
00345 }


Variable Documentation

int asock = -1 [static]

Definition at line 98 of file manager.c.

Referenced by accept_thread(), and init_manager().

int block_sockets [static]

Definition at line 104 of file manager.c.

Referenced by accept_thread(), and init_manager().

struct ast_cli_entry cli_manager[] [static]

Definition at line 628 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 608 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 613 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 618 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 623 of file manager.c.

int displayconnects = 1 [static]

Definition at line 99 of file manager.c.

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

int enabled [static]

Definition at line 96 of file manager.c.

struct manager_action* first_action [static]

Definition at line 191 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 101 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 1610 of file manager.c.

char mandescr_events[] [static]

Definition at line 1295 of file manager.c.

char mandescr_extensionstate[] [static]

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

char mandescr_getvar[] [static]

Definition at line 1393 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 1327 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 1270 of file manager.c.

char mandescr_logoff[] [static]

Initial value:

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

Definition at line 1317 of file manager.c.

char mandescr_mailboxcount[] [static]

Definition at line 1849 of file manager.c.

char mandescr_mailboxstatus[] [static]

Help text for manager command mailboxstatus.

Definition at line 1817 of file manager.c.

char mandescr_originate[] [static]

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

char mandescr_redirect[] [static]

Definition at line 1535 of file manager.c.

char mandescr_setvar[] [static]

Definition at line 1351 of file manager.c.

char mandescr_timeout[] [static]

Definition at line 1926 of file manager.c.

char mandescr_updateconfig[] [static]

Definition at line 1130 of file manager.c.

char mandescr_userevent[] [static]

Definition at line 1980 of file manager.c.

char mandescr_waitevent[] [static]

Manager WAITEVENT.

Definition at line 1181 of file manager.c.

struct eventqent* master_eventq = NULL

Definition at line 108 of file manager.c.

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

int num_sessions [static]

Definition at line 105 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 97 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 604 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 599 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 581 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 585 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 589 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 594 of file manager.c.

pthread_t t [static]

Definition at line 103 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_hd_hf(), handle_offhook_message(), handle_soft_key_event_message(), handle_stimulus_message(), iax2_datetime(), iax2_show_threads(), iax_template_parse(), init_manager(), launch_service(), listener(), localsub(), lws2sws(), manager_log(), MD5Update(), newpvt(), nv_background_detect_exec(), nv_detectfax_exec(), osp_create_provider(), osp_load(), packdate(), phase_d_handler(), phase_e_handler(), play_message_datetime(), prune_gateways(), rebuild_matrix(), register_verify(), rpt(), rpt_do_lstats(), rpt_tele_thread(), rxfax_exec(), send_request(), SHA1ProcessMessageBlock(), sms_readfile(), socket_read(), sqlite_log(), statechange_queue(), strip_quotes(), tdd_getcarrier(), time1(), time2(), 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 100 of file manager.c.

Referenced by init_manager(), and manager_event().


Generated on Mon May 14 04:54:00 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1