Fri Aug 24 02:28:03 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 (const char *string)
static AST_LIST_HEAD_STATIC (users, ast_manager_user)
static AST_LIST_HEAD_STATIC (sessions, mansession)
int ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), const char *synopsis, const char *description)
 register a new command with manager, including online help. This is the preferred way to register a manager command
static int ast_manager_register_struct (struct manager_action *act)
int ast_manager_unregister (char *action)
 AST_RWLOCK_DEFINE_STATIC (actionlock)
 AST_THREADSTORAGE (astman_append_buf, astman_append_buf_init)
 AST_THREADSTORAGE (manager_event_buf, manager_event_buf_init)
void astman_append (struct mansession *s, const char *fmt,...)
const char * astman_get_header (const struct message *m, char *var)
ast_variableastman_get_variables (const struct message *m)
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
void astman_send_error (struct mansession *s, const struct message *m, char *error)
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
static int authenticate (struct mansession *s, const struct message *m)
static char * authority_to_str (int authority, char *res, int reslen)
 Convert authority code to string with serveral options.
static char * complete_show_mancmd (const char *line, const char *word, int pos, int state)
static 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 const char * command_blacklist []
static int displayconnects = 1
static int enabled
static struct manager_actionfirst_action
static int httptimeout = 60
static char mandescr_command []
static char mandescr_events []
static char mandescr_extensionstate []
static char mandescr_getconfig []
static char mandescr_getvar []
static char mandescr_hangup []
static char mandescr_listcommands []
static char mandescr_logoff []
static char mandescr_mailboxcount []
static char mandescr_mailboxstatus []
 Help text for manager command mailboxstatus.
static char mandescr_originate []
static char mandescr_ping []
 Manager PING.
static char mandescr_redirect []
static char mandescr_setvar []
static char mandescr_timeout []
static char mandescr_updateconfig []
static char mandescr_userevent []
static char mandescr_waitevent []
 Manager WAITEVENT.
eventqentmaster_eventq = NULL
static int num_sessions
static struct permalias perms []
static int portno = DEFAULT_MANAGER_PORT
static char showmanager_help []
static char showmanagers_help []
static char showmancmd_help []
static char showmancmds_help []
static char showmanconn_help []
static char showmaneventq_help []
static pthread_t t
static int timestampevents

Detailed Description

callback to display queues status in manager


Define Documentation

#define ASTMAN_APPEND_BUF_INITSIZE   256

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

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

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

action_command: Manager command "command" - execute CLI command

Definition at line 1618 of file manager.c.

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

Referenced by init_manager().

01619 {
01620    const char *cmd = astman_get_header(m, "Command");
01621    const char *id = astman_get_header(m, "ActionID");
01622    char *buf, *final_buf;
01623    char template[] = "/tmp/ast-ami-XXXXXX";  /* template for temporary file */
01624    int fd = mkstemp(template), i = 0;
01625    off_t l;
01626 
01627    for (i = 0; i < sizeof(command_blacklist) / sizeof(command_blacklist[0]); i++) {
01628       if (!strncmp(cmd, command_blacklist[i], strlen(command_blacklist[i]))) {
01629          astman_send_error(s, m, "Command blacklisted");
01630          return 0;
01631       }
01632    }
01633 
01634    astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
01635    if (!ast_strlen_zero(id))
01636       astman_append(s, "ActionID: %s\r\n", id);
01637    /* FIXME: Wedge a ActionID response in here, waiting for later changes */
01638    ast_cli_command(fd, cmd);  /* XXX need to change this to use a FILE * */
01639    l = lseek(fd, 0, SEEK_END);   /* how many chars available */
01640 
01641    /* This has a potential to overflow the stack.  Hence, use the heap. */
01642    buf = ast_calloc(1, l + 1);
01643    final_buf = ast_calloc(1, l + 1);
01644    if (buf) {
01645       lseek(fd, 0, SEEK_SET);
01646       read(fd, buf, l);
01647       buf[l] = '\0';
01648       if (final_buf) {
01649          term_strip(final_buf, buf, l);
01650          final_buf[l] = '\0';
01651       }
01652       astman_append(s, S_OR(final_buf, buf));
01653       ast_free(buf);
01654    }
01655    close(fd);
01656    unlink(template);
01657    astman_append(s, "--END COMMAND--\r\n\r\n");
01658    if (final_buf)
01659       ast_free(final_buf);
01660    return 0;
01661 }

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

Definition at line 1309 of file manager.c.

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

Referenced by init_manager().

01310 {
01311    const char *mask = astman_get_header(m, "EventMask");
01312    int res;
01313 
01314    res = set_eventmask(s, mask);
01315    if (res > 0)
01316       astman_send_response(s, m, "Events On", NULL);
01317    else if (res == 0)
01318       astman_send_response(s, m, "Events Off", NULL);
01319 
01320    return 0;
01321 }

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

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

01914 {
01915    const char *exten = astman_get_header(m, "Exten");
01916    const char *context = astman_get_header(m, "Context");
01917    const char *id = astman_get_header(m,"ActionID");
01918    char idText[256] = "";
01919    char hint[256] = "";
01920    int status;
01921    if (ast_strlen_zero(exten)) {
01922       astman_send_error(s, m, "Extension not specified");
01923       return 0;
01924    }
01925    if (ast_strlen_zero(context))
01926       context = "default";
01927    status = ast_extension_state(NULL, context, exten);
01928    ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
01929         if (!ast_strlen_zero(id)) {
01930                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01931         }
01932    astman_append(s, "Response: Success\r\n"
01933                     "%s"
01934                "Message: Extension Status\r\n"
01935                "Exten: %s\r\n"
01936                "Context: %s\r\n"
01937                "Hint: %s\r\n"
01938                "Status: %d\r\n\r\n",
01939                idText,exten, context, hint, status);
01940    return 0;
01941 }

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

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

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

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

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

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

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

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

01339 {
01340    struct ast_channel *c = NULL;
01341    const char *name = astman_get_header(m, "Channel");
01342    if (ast_strlen_zero(name)) {
01343       astman_send_error(s, m, "No channel specified");
01344       return 0;
01345    }
01346    c = ast_get_channel_by_name_locked(name);
01347    if (!c) {
01348       astman_send_error(s, m, "No such channel");
01349       return 0;
01350    }
01351    ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
01352    ast_channel_unlock(c);
01353    astman_send_ack(s, m, "Channel Hungup");
01354    return 0;
01355 }

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

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

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

Definition at line 1327 of file manager.c.

References astman_send_response(), and s.

Referenced by init_manager().

01328 {
01329    astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
01330    return -1;
01331 }

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

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

01878 {
01879    const char *mailbox = astman_get_header(m, "Mailbox");
01880    const char *id = astman_get_header(m,"ActionID");
01881    char idText[256] = "";
01882    int newmsgs = 0, oldmsgs = 0;
01883    if (ast_strlen_zero(mailbox)) {
01884       astman_send_error(s, m, "Mailbox not specified");
01885       return 0;
01886    }
01887    ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs);
01888    if (!ast_strlen_zero(id)) {
01889       snprintf(idText, sizeof(idText), "ActionID: %s\r\n",id);
01890    }
01891    astman_append(s, "Response: Success\r\n"
01892                "%s"
01893                "Message: Mailbox Message Count\r\n"
01894                "Mailbox: %s\r\n"
01895                "NewMessages: %d\r\n"
01896                "OldMessages: %d\r\n" 
01897                "\r\n",
01898                 idText,mailbox, newmsgs, oldmsgs);
01899    return 0;
01900 }

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

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

01846 {
01847    const char *mailbox = astman_get_header(m, "Mailbox");
01848    const char *id = astman_get_header(m,"ActionID");
01849    char idText[256] = "";
01850    int ret;
01851    if (ast_strlen_zero(mailbox)) {
01852       astman_send_error(s, m, "Mailbox not specified");
01853       return 0;
01854    }
01855         if (!ast_strlen_zero(id))
01856                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01857    ret = ast_app_has_voicemail(mailbox, NULL);
01858    astman_append(s, "Response: Success\r\n"
01859                "%s"
01860                "Message: Mailbox Status\r\n"
01861                "Mailbox: %s\r\n"
01862                "Waiting: %d\r\n\r\n", idText, mailbox, ret);
01863    return 0;
01864 }

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

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

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

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

Definition at line 1026 of file manager.c.

References astman_send_response(), and s.

Referenced by init_manager().

01027 {
01028    astman_send_response(s, m, "Pong", NULL);
01029    return 0;
01030 }

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

action_redirect: The redirect manager command

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

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

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

Definition at line 1364 of file manager.c.

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

Referenced by init_manager().

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

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

Manager "status" command to show channels.

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

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

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

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

01951 {
01952    struct ast_channel *c = NULL;
01953    const char *name = astman_get_header(m, "Channel");
01954    int timeout = atoi(astman_get_header(m, "Timeout"));
01955    if (ast_strlen_zero(name)) {
01956       astman_send_error(s, m, "No channel specified");
01957       return 0;
01958    }
01959    if (!timeout) {
01960       astman_send_error(s, m, "No timeout specified");
01961       return 0;
01962    }
01963    c = ast_get_channel_by_name_locked(name);
01964    if (!c) {
01965       astman_send_error(s, m, "No such channel");
01966       return 0;
01967    }
01968    ast_channel_setwhentohangup(c, timeout);
01969    ast_channel_unlock(c);
01970    astman_send_ack(s, m, "Timeout Set");
01971    return 0;
01972 }

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

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

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

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

Definition at line 2004 of file manager.c.

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

Referenced by init_manager().

02005 {
02006    const char *event = astman_get_header(m, "UserEvent");
02007    char body[2048] = "";
02008    int x, bodylen = 0;
02009    for (x = 0; x < m->hdrcount; x++) {
02010       if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
02011          ast_copy_string(body + bodylen, m->headers[x], sizeof(body) - bodylen - 3);
02012          bodylen += strlen(m->headers[x]);
02013          ast_copy_string(body + bodylen, "\r\n", 3);
02014          bodylen += 2;
02015       }
02016    }
02017 
02018    manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body);
02019    return 0;
02020 }

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

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

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

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

Definition at line 2313 of file manager.c.

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

Referenced by init_manager(), and manager_event().

02314 {
02315    struct eventqent *tmp, *prev = NULL;
02316    tmp = ast_malloc(sizeof(*tmp) + strlen(str));
02317 
02318    if (!tmp)
02319       return -1;
02320 
02321    tmp->next = NULL;
02322    tmp->category = category;
02323    strcpy(tmp->eventdata, str);
02324    
02325    if (master_eventq) {
02326       prev = master_eventq;
02327       while (prev->next) 
02328          prev = prev->next;
02329       prev->next = tmp;
02330    } else {
02331       master_eventq = tmp;
02332    }
02333    
02334    tmp->usecount = num_sessions;
02335    
02336    return 0;
02337 }

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

Definition at line 401 of file manager.c.

References AST_LIST_TRAVERSE, ast_manager_user::username, and users.

Referenced by handle_showmanager(), and init_manager().

00402 {
00403    struct ast_manager_user *user = NULL;
00404 
00405    AST_LIST_TRAVERSE(&users, user, list)
00406       if (!strcasecmp(user->username, name))
00407          break;
00408    return user;
00409 }

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

References ast_variable::next.

Referenced by get_perm(), and strings_to_mask().

00790 {
00791    const char *val = bigstr, *next;
00792 
00793    do {
00794       if ((next = strchr(val, delim))) {
00795          if (!strncmp(val, smallstr, (next - val)))
00796             return 1;
00797          else
00798             continue;
00799       } else
00800          return !strcmp(smallstr, val);
00801 
00802    } while (*(val = (next + 1)));
00803 
00804    return 0;
00805 }

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

Definition at line 822 of file manager.c.

Referenced by strings_to_mask().

00823 {
00824    int ret = 1, x = 0;
00825 
00826    if (!string)
00827       return 0;
00828 
00829    for (x = 0; x < strlen(string); x++) {
00830       if (!(string[x] >= 48 && string[x] <= 57)) {
00831          ret = 0;
00832          break;
00833       }
00834    }
00835    
00836    return ret ? atoi(string) : 0;
00837 }

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

References ast_malloc, and ast_manager_register_struct().

Referenced by init_manager(), and load_module().

02460 {
02461    struct manager_action *cur;
02462 
02463    cur = ast_malloc(sizeof(*cur));
02464    if (!cur)
02465       return -1;
02466    
02467    cur->action = action;
02468    cur->authority = auth;
02469    cur->func = func;
02470    cur->synopsis = synopsis;
02471    cur->description = description;
02472    cur->next = NULL;
02473 
02474    ast_manager_register_struct(cur);
02475 
02476    return 0;
02477 }

static int ast_manager_register_struct ( struct manager_action act  )  [static]

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

02416 {
02417    struct manager_action *cur, *prev = NULL;
02418    int ret;
02419 
02420    ast_rwlock_wrlock(&actionlock);
02421    cur = first_action;
02422    while (cur) { /* Walk the list of actions */
02423       ret = strcasecmp(cur->action, act->action);
02424       if (ret == 0) {
02425          ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
02426          ast_rwlock_unlock(&actionlock);
02427          return -1;
02428       } else if (ret > 0) {
02429          /* Insert these alphabetically */
02430          if (prev) {
02431             act->next = prev->next;
02432             prev->next = act;
02433          } else {
02434             act->next = first_action;
02435             first_action = act;
02436          }
02437          break;
02438       }
02439       prev = cur; 
02440       cur = cur->next;
02441    }
02442    
02443    if (!cur) {
02444       if (prev)
02445          prev->next = act;
02446       else
02447          first_action = act;
02448       act->next = NULL;
02449    }
02450 
02451    if (option_verbose > 1) 
02452       ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", act->action);
02453    ast_rwlock_unlock(&actionlock);
02454    return 0;
02455 }

int ast_manager_unregister ( char *  action  ) 

Parameters:
action Name of registred Action:

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

02387 {
02388    struct manager_action *cur, *prev;
02389 
02390    ast_rwlock_wrlock(&actionlock);
02391    cur = prev = first_action;
02392    while (cur) {
02393       if (!strcasecmp(action, cur->action)) {
02394          prev->next = cur->next;
02395          free(cur);
02396          if (option_verbose > 1) 
02397             ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action);
02398          ast_rwlock_unlock(&actionlock);
02399          return 0;
02400       }
02401       prev = cur;
02402       cur = cur->next;
02403    }
02404    ast_rwlock_unlock(&actionlock);
02405    return 0;
02406 }

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

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

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

Get header from mananger transaction

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

00693 {
00694    char cmp[80];
00695    int x;
00696 
00697    snprintf(cmp, sizeof(cmp), "%s: ", var);
00698 
00699    for (x = 0; x < m->hdrcount; x++) {
00700       if (!strncasecmp(cmp, m->headers[x], strlen(cmp)))
00701          return m->headers[x] + strlen(cmp);
00702    }
00703 
00704    return "";
00705 }

struct ast_variable* astman_get_variables ( const struct message m  ) 

Get a linked list of the Variable: headers

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

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

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

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

00780 {
00781    astman_send_response(s, m, "Success", msg);
00782 }

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 756 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_command(), 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().

00757 {
00758    const char *id = astman_get_header(m,"ActionID");
00759 
00760    astman_append(s, "Response: Error\r\n");
00761    if (!ast_strlen_zero(id))
00762       astman_append(s, "ActionID: %s\r\n", id);
00763    astman_append(s, "Message: %s\r\n\r\n", error);
00764 }

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

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

00767 {
00768    const char *id = astman_get_header(m,"ActionID");
00769 
00770    astman_append(s, "Response: %s\r\n", resp);
00771    if (!ast_strlen_zero(id))
00772       astman_append(s, "ActionID: %s\r\n", id);
00773    if (msg)
00774       astman_append(s, "Message: %s\r\n\r\n", msg);
00775    else
00776       astman_append(s, "\r\n");
00777 }

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

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

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

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

Convert authority code to string with serveral options.

Definition at line 200 of file manager.c.

References ast_strlen_zero(), and perms.

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

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

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

Definition at line 222 of file manager.c.

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

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

static void destroy_session ( struct mansession s  )  [static]

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

00683 {
00684    AST_LIST_LOCK(&sessions);
00685    AST_LIST_REMOVE(&sessions, s, list);
00686    AST_LIST_UNLOCK(&sessions);
00687 
00688    ast_atomic_fetchadd_int(&num_sessions, -1);
00689    free_session(s);
00690 }

static int do_message ( struct mansession s  )  [static]

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

02159 {
02160    struct message m = { 0 };
02161    char header_buf[sizeof(s->inbuf)] = { '\0' };
02162    int res;
02163 
02164    for (;;) {
02165       /* Check if any events are pending and do them if needed */
02166       if (s->eventq->next) {
02167          if (process_events(s))
02168             return -1;
02169       }
02170       res = get_input(s, header_buf);
02171       if (res == 0) {
02172          continue;
02173       } else if (res > 0) {
02174          /* Strip trailing \r\n */
02175          if (strlen(header_buf) < 2)
02176             continue;
02177          header_buf[strlen(header_buf) - 2] = '\0';
02178          if (ast_strlen_zero(header_buf))
02179             return process_message(s, &m) ? -1 : 0;
02180          else if (m.hdrcount < (AST_MAX_MANHEADERS - 1))
02181             m.headers[m.hdrcount++] = ast_strdupa(header_buf);
02182       } else {
02183          return res;
02184       }
02185    }
02186 }

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

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

01664 {
01665    struct fast_originate_helper *in = data;
01666    int res;
01667    int reason = 0;
01668    struct ast_channel *chan = NULL;
01669    char requested_channel[AST_CHANNEL_NAME];
01670 
01671    if (!ast_strlen_zero(in->app)) {
01672       res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, 
01673          S_OR(in->cid_num, NULL), 
01674          S_OR(in->cid_name, NULL),
01675          in->vars, in->account, &chan);
01676    } else {
01677       res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 
01678          S_OR(in->cid_num, NULL), 
01679          S_OR(in->cid_name, NULL),
01680          in->vars, in->account, &chan);
01681    }
01682 
01683    if (!chan)
01684       snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);   
01685    /* Tell the manager what happened with the channel */
01686    manager_event(EVENT_FLAG_CALL, "OriginateResponse",
01687       "%s"
01688       "Response: %s\r\n"
01689       "Channel: %s\r\n"
01690       "Context: %s\r\n"
01691       "Exten: %s\r\n"
01692       "Reason: %d\r\n"
01693       "Uniqueid: %s\r\n"
01694       "CallerID: %s\r\n"      /* This parameter is deprecated and will be removed post-1.4 */
01695       "CallerIDNum: %s\r\n"
01696       "CallerIDName: %s\r\n",
01697       in->idtext, res ? "Failure" : "Success", chan ? chan->name : requested_channel, in->context, in->exten, reason, 
01698       chan ? chan->uniqueid : "<null>",
01699       S_OR(in->cid_num, "<unknown>"),
01700       S_OR(in->cid_num, "<unknown>"),
01701       S_OR(in->cid_name, "<unknown>")
01702       );
01703 
01704    /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
01705    if (chan)
01706       ast_channel_unlock(chan);
01707    free(in);
01708    return NULL;
01709 }

static void free_session ( struct mansession s  )  [static]

Definition at line 666 of file manager.c.

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

Referenced by accept_thread(), and destroy_session().

00667 {
00668    struct eventqent *eqe;
00669    if (s->fd > -1)
00670       close(s->fd);
00671    if (s->outputstr)
00672       free(s->outputstr);
00673    ast_mutex_destroy(&s->__lock);
00674    while (s->eventq) {
00675       eqe = s->eventq;
00676       s->eventq = s->eventq->next;
00677       unuse_eventqent(eqe);
00678    }
00679    free(s);
00680 }

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

Definition at line 2104 of file manager.c.

References ast_channel::fds, and s.

Referenced by do_message(), and skinny_session().

02105 {
02106    /* output must have at least sizeof(s->inbuf) space */
02107    int res;
02108    int x;
02109    struct pollfd fds[1];
02110    for (x = 1; x < s->inlen; x++) {
02111       if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) {
02112          /* Copy output data up to and including \r\n */
02113          memcpy(output, s->inbuf, x + 1);
02114          /* Add trailing \0 */
02115          output[x+1] = '\0';
02116          /* Move remaining data back to the front */
02117          memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x);
02118          s->inlen -= (x + 1);
02119          return 1;
02120       }
02121    } 
02122    if (s->inlen >= sizeof(s->inbuf) - 1) {
02123       ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->sin.sin_addr), s->inbuf);
02124       s->inlen = 0;
02125    }
02126    fds[0].fd = s->fd;
02127    fds[0].events = POLLIN;
02128    do {
02129       ast_mutex_lock(&s->__lock);
02130       s->waiting_thread = pthread_self();
02131       ast_mutex_unlock(&s->__lock);
02132 
02133       res = poll(fds, 1, -1);
02134 
02135       ast_mutex_lock(&s->__lock);
02136       s->waiting_thread = AST_PTHREADT_NULL;
02137       ast_mutex_unlock(&s->__lock);
02138       if (res < 0) {
02139          if (errno == EINTR) {
02140             return 0;
02141          }
02142          ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));
02143          return -1;
02144       } else if (res > 0) {
02145          ast_mutex_lock(&s->__lock);
02146          res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen);
02147          ast_mutex_unlock(&s->__lock);
02148          if (res < 1)
02149             return -1;
02150          break;
02151       }
02152    } while(1);
02153    s->inlen += res;
02154    s->inbuf[s->inlen] = '\0';
02155    return 0;
02156 }

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

Definition at line 807 of file manager.c.

References ast_instring(), and perms.

00808 {
00809    int x = 0, ret = 0;
00810 
00811    if (!instr)
00812       return 0;
00813 
00814    for (x = 0; x < (sizeof(perms) / sizeof(perms[0])); x++) {
00815       if (ast_instring(instr, perms[x].label, ','))
00816          ret |= perms[x].num;
00817    }
00818    
00819    return ret;
00820 }

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

Definition at line 463 of file manager.c.

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

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

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

Definition at line 501 of file manager.c.

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

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

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

Definition at line 441 of file manager.c.

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

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

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

CLI command Should change to "manager show commands".

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

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

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

CLI command show manager connected.

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

00556 {
00557    struct mansession *s;
00558    char *format = "  %-15.15s  %-15.15s\n";
00559 
00560    ast_cli(fd, format, "Username", "IP Address");
00561    
00562    AST_LIST_LOCK(&sessions);
00563    AST_LIST_TRAVERSE(&sessions, s, list)
00564       ast_cli(fd, format,s->username, ast_inet_ntoa(s->sin.sin_addr));
00565    AST_LIST_UNLOCK(&sessions);
00566 
00567    return RESULT_SUCCESS;
00568 }

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

CLI command show manager connected.

Definition at line 572 of file manager.c.

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

00573 {
00574    struct eventqent *s;
00575 
00576    AST_LIST_LOCK(&sessions);
00577    for (s = master_eventq; s; s = s->next) {
00578       ast_cli(fd, "Usecount: %d\n",s->usecount);
00579       ast_cli(fd, "Category: %d\n", s->category);
00580       ast_cli(fd, "Event:\n%s", s->eventdata);
00581    }
00582    AST_LIST_UNLOCK(&sessions);
00583 
00584    return RESULT_SUCCESS;
00585 }

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

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

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

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

Definition at line 352 of file manager.c.

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

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

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

manager_event: Send AMI event to client

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

02341 {
02342    struct mansession *s;
02343    char auth[80];
02344    va_list ap;
02345    struct timeval now;
02346    struct ast_dynamic_str *buf;
02347 
02348    /* Abort if there aren't any manager sessions */
02349    if (!num_sessions)
02350       return 0;
02351 
02352    if (!(buf = ast_dynamic_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE)))
02353       return -1;
02354 
02355    ast_dynamic_str_thread_set(&buf, 0, &manager_event_buf,
02356          "Event: %s\r\nPrivilege: %s\r\n",
02357           event, authority_to_str(category, auth, sizeof(auth)));
02358 
02359    if (timestampevents) {
02360       now = ast_tvnow();
02361       ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf,
02362             "Timestamp: %ld.%06lu\r\n",
02363              now.tv_sec, (unsigned long) now.tv_usec);
02364    }
02365 
02366    va_start(ap, fmt);
02367    ast_dynamic_str_thread_append_va(&buf, 0, &manager_event_buf, fmt, ap);
02368    va_end(ap);
02369    
02370    ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, "\r\n");  
02371    
02372    /* Append event to master list and wake up any sleeping sessions */
02373    AST_LIST_LOCK(&sessions);
02374    append_event(buf->str, category);
02375    AST_LIST_TRAVERSE(&sessions, s, list) {
02376       ast_mutex_lock(&s->__lock);
02377       if (s->waiting_thread != AST_PTHREADT_NULL)
02378          pthread_kill(s->waiting_thread, SIGURG);
02379       ast_mutex_unlock(&s->__lock);
02380    }
02381    AST_LIST_UNLOCK(&sessions);
02382 
02383    return 0;
02384 }

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

Definition at line 2408 of file manager.c.

References EVENT_FLAG_CALL, and manager_event().

Referenced by init_manager().

02409 {
02410    /* Notify managers of change */
02411    manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nStatus: %d\r\n", exten, context, state);
02412    return 0;
02413 }

static int process_events ( struct mansession s  )  [static]

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

01975 {
01976    struct eventqent *eqe;
01977    int ret = 0;
01978    ast_mutex_lock(&s->__lock);
01979    if (s->fd > -1) {
01980       if (!s->eventq)
01981          s->eventq = master_eventq;
01982       while(s->eventq->next) {
01983          eqe = s->eventq->next;
01984          if ((s->authenticated && (s->readperm & eqe->category) == eqe->category) &&
01985              ((s->send_events & eqe->category) == eqe->category)) {
01986             if (!ret && ast_carefulwrite(s->fd, eqe->eventdata, strlen(eqe->eventdata), s->writetimeout) < 0)
01987                ret = -1;
01988          }
01989          unuse_eventqent(s->eventq);
01990          s->eventq = eqe;
01991       }
01992    }
01993    ast_mutex_unlock(&s->__lock);
01994    return ret;
01995 }

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

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

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

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

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

02189 {
02190    struct mansession *s = data;
02191    int res;
02192    
02193    astman_append(s, "Asterisk Call Manager/1.0\r\n");
02194    for (;;) {
02195       if ((res = do_message(s)) < 0)
02196          break;
02197    }
02198    if (s->authenticated) {
02199       if (option_verbose > 1) {
02200          if (displayconnects) 
02201             ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
02202       }
02203       ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
02204    } else {
02205       if (option_verbose > 1) {
02206          if (displayconnects)
02207             ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr));
02208       }
02209       ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr));
02210    }
02211    destroy_session(s);
02212    return NULL;
02213 }

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

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

Referenced by action_events().

00871 {
00872    int maskint = strings_to_mask(eventmask);
00873 
00874    ast_mutex_lock(&s->__lock);
00875    if (maskint >= 0) 
00876       s->send_events = maskint;
00877    ast_mutex_unlock(&s->__lock);
00878    
00879    return maskint;
00880 }

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

Definition at line 839 of file manager.c.

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

Referenced by set_eventmask().

00840 {
00841    int x, ret = -1;
00842    
00843    x = ast_is_number(string);
00844 
00845    if (x)
00846       ret = x;
00847    else if (ast_strlen_zero(string))
00848       ret = -1;
00849    else if (ast_false(string))
00850       ret = 0;
00851    else if (ast_true(string)) {
00852       ret = 0;
00853       for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++)
00854          ret |= perms[x].num;    
00855    } else {
00856       ret = 0;
00857       for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) {
00858          if (ast_instring(string, perms[x].label, ',')) 
00859             ret |= perms[x].num;    
00860       }
00861    }
00862 
00863    return ret;
00864 }

static void unuse_eventqent ( struct eventqent e  )  [static]

Definition at line 660 of file manager.c.

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

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

00661 {
00662    if (ast_atomic_dec_and_test(&e->usecount) && e->next)
00663       pthread_kill(t, SIGURG);
00664 }

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

Definition at line 240 of file manager.c.

Referenced by xml_translate().

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

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

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

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


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 634 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 614 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 619 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 624 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 629 of file manager.c.

const char* command_blacklist[] [static]

Initial value:

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

Definition at line 132 of file manager.c.

Referenced by action_command().

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

char mandescr_events[] [static]

Definition at line 1301 of file manager.c.

char mandescr_extensionstate[] [static]

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

char mandescr_getvar[] [static]

Definition at line 1394 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 1333 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 1276 of file manager.c.

char mandescr_logoff[] [static]

Initial value:

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

Definition at line 1323 of file manager.c.

char mandescr_mailboxcount[] [static]

Definition at line 1866 of file manager.c.

char mandescr_mailboxstatus[] [static]

Help text for manager command mailboxstatus.

Definition at line 1834 of file manager.c.

char mandescr_originate[] [static]

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

char mandescr_redirect[] [static]

Definition at line 1536 of file manager.c.

char mandescr_setvar[] [static]

Definition at line 1357 of file manager.c.

char mandescr_timeout[] [static]

Definition at line 1943 of file manager.c.

char mandescr_updateconfig[] [static]

Definition at line 1136 of file manager.c.

char mandescr_userevent[] [static]

Definition at line 1997 of file manager.c.

char mandescr_waitevent[] [static]

Manager WAITEVENT.

Definition at line 1187 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 610 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 605 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 587 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 591 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 595 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 600 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_enbloc_call_message(), handle_hd_hf(), handle_offhook_message(), handle_save_dialplan(), handle_soft_key_event_message(), handle_stimulus_message(), iax2_datetime(), iax2_process_thread(), iax2_show_threads(), iax_template_parse(), init_manager(), launch_service(), listener(), local_new(), localsub(), lws2sws(), manager_log(), MD5Update(), newpvt(), nv_background_detect_exec(), nv_detectfax_exec(), osp_create_provider(), osp_load(), packdate(), parse_moved_contact(), pgsql_log(), phase_d_handler(), phase_e_handler(), play_message_datetime(), prune_gateways(), rebuild_matrix(), register_verify(), rpt(), rpt_do_lstats(), rpt_exec(), rpt_tele_thread(), rxfax_exec(), send_request(), SHA1ProcessMessageBlock(), sms_readfile(), socket_read(), sqlite_log(), 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 Fri Aug 24 02:28:03 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1