Mon Apr 30 07:47:39 2007

Asterisk developer's documentation


AMI functions

callback to display queues status in manager More...

Data Structures

struct  ast_manager_user
struct  eventqent
struct  fast_originate_helper
struct  mansession
struct  permalias

Defines

#define ASTMAN_APPEND_BUF_INITSIZE   256
#define MANAGER_EVENT_BUF_INITSIZE   256

Functions

static void * accept_thread (void *ignore)
static int action_command (struct mansession *s, const struct message *m)
 action_command: Manager command "command" - execute CLI command
static int action_events (struct mansession *s, const struct message *m)
static int action_extensionstate (struct mansession *s, const struct message *m)
static int action_getconfig (struct mansession *s, const struct message *m)
static int action_getvar (struct mansession *s, const struct message *m)
static int action_hangup (struct mansession *s, const struct message *m)
static int action_listcommands (struct mansession *s, const struct message *m)
static int action_logoff (struct mansession *s, const struct message *m)
static int action_mailboxcount (struct mansession *s, const struct message *m)
static int action_mailboxstatus (struct mansession *s, const struct message *m)
static int action_originate (struct mansession *s, const struct message *m)
static int action_ping (struct mansession *s, const struct message *m)
static int action_redirect (struct mansession *s, const struct message *m)
 action_redirect: The redirect manager command
static int action_setvar (struct mansession *s, const struct message *m)
static int action_status (struct mansession *s, const struct message *m)
 Manager "status" command to show channels.
static int action_timeout (struct mansession *s, const struct message *m)
static int action_updateconfig (struct mansession *s, const struct message *m)
static int action_userevent (struct mansession *s, const struct message *m)
static int action_waitevent (struct mansession *s, const struct message *m)
static int append_event (const char *str, int category)
static struct ast_manager_userast_get_manager_by_name_locked (const char *name)
static int ast_instring (const char *bigstr, const char *smallstr, char delim)
static int ast_is_number (char *string)
static AST_LIST_HEAD_STATIC (users, ast_manager_user)
static AST_LIST_HEAD_STATIC (sessions, mansession)
int ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), const char *synopsis, const char *description)
 register a new command with manager, including online help. This is the preferred way to register a manager command
static int ast_manager_register_struct (struct manager_action *act)
int ast_manager_unregister (char *action)
 AST_RWLOCK_DEFINE_STATIC (actionlock)
 AST_THREADSTORAGE (astman_append_buf, astman_append_buf_init)
 AST_THREADSTORAGE (manager_event_buf, manager_event_buf_init)
void astman_append (struct mansession *s, const char *fmt,...)
const char * astman_get_header (const struct message *m, char *var)
ast_variableastman_get_variables (const struct message *m)
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
void astman_send_error (struct mansession *s, const struct message *m, char *error)
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
static int authenticate (struct mansession *s, const struct message *m)
static char * authority_to_str (int authority, char *res, int reslen)
 Convert authority code to string with serveral options.
static char * complete_show_mancmd (const char *line, const char *word, int pos, int state)
static void destroy_session (struct mansession *s)
static int do_message (struct mansession *s)
static void * fast_originate (void *data)
static void free_session (struct mansession *s)
static int get_input (struct mansession *s, char *output)
static int get_perm (const char *instr)
static int handle_showmanager (int fd, int argc, char *argv[])
static int handle_showmanagers (int fd, int argc, char *argv[])
static int handle_showmancmd (int fd, int argc, char *argv[])
static int handle_showmancmds (int fd, int argc, char *argv[])
 CLI command Should change to "manager show commands".
static int handle_showmanconn (int fd, int argc, char *argv[])
 CLI command show manager connected.
static int handle_showmaneventq (int fd, int argc, char *argv[])
 CLI command show manager connected.
static void handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg)
static char * html_translate (char *in)
int manager_event (int category, const char *event, const char *fmt,...)
 manager_event: Send AMI event to client
static int manager_state_cb (char *context, char *exten, int state, void *data)
static int process_events (struct mansession *s)
static int process_message (struct mansession *s, const struct message *m)
static void * session_do (void *data)
static int set_eventmask (struct mansession *s, const char *eventmask)
 Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm.
static int strings_to_mask (const char *string)
static void unuse_eventqent (struct eventqent *e)
static void xml_copy_escape (char **dst, size_t *maxlen, const char *src, int lower)
static char * xml_translate (char *in, struct ast_variable *vars)

Variables

static int asock = -1
static int block_sockets
static struct ast_cli_entry cli_manager []
static struct ast_cli_entry cli_show_manager_command_deprecated
static struct ast_cli_entry cli_show_manager_commands_deprecated
static struct ast_cli_entry cli_show_manager_connected_deprecated
static struct ast_cli_entry cli_show_manager_eventq_deprecated
static int displayconnects = 1
static int enabled
static struct manager_actionfirst_action
static int httptimeout = 60
static char mandescr_command []
static char mandescr_events []
static char mandescr_extensionstate []
static char mandescr_getconfig []
static char mandescr_getvar []
static char mandescr_hangup []
static char mandescr_listcommands []
static char mandescr_logoff []
static char mandescr_mailboxcount []
static char mandescr_mailboxstatus []
 Help text for manager command mailboxstatus.
static char mandescr_originate []
static char mandescr_ping []
 Manager PING.
static char mandescr_redirect []
static char mandescr_setvar []
static char mandescr_timeout []
static char mandescr_updateconfig []
static char mandescr_userevent []
static char mandescr_waitevent []
 Manager WAITEVENT.
eventqentmaster_eventq = NULL
static int num_sessions
static struct permalias perms []
static int portno = DEFAULT_MANAGER_PORT
static char showmanager_help []
static char showmanagers_help []
static char showmancmd_help []
static char showmancmds_help []
static char showmanconn_help []
static char showmaneventq_help []
static pthread_t t
static int timestampevents

Detailed Description

callback to display queues status in manager


Define Documentation

#define ASTMAN_APPEND_BUF_INITSIZE   256

Definition at line 113 of file manager.c.

Referenced by astman_append().

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 110 of file manager.c.

Referenced by manager_event().


Function Documentation

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

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

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

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

action_command: Manager command "command" - execute CLI command

Definition at line 1611 of file manager.c.

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

Referenced by init_manager().

01612 {
01613    const char *cmd = astman_get_header(m, "Command");
01614    const char *id = astman_get_header(m, "ActionID");
01615    astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
01616    if (!ast_strlen_zero(id))
01617       astman_append(s, "ActionID: %s\r\n", id);
01618    /* FIXME: Wedge a ActionID response in here, waiting for later changes */
01619    ast_cli_command(s->fd, cmd);
01620    astman_append(s, "--END COMMAND--\r\n\r\n");
01621    return 0;
01622 }

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

Definition at line 1297 of file manager.c.

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

Referenced by init_manager().

01298 {
01299    const char *mask = astman_get_header(m, "EventMask");
01300    int res;
01301 
01302    res = set_eventmask(s, mask);
01303    if (res > 0)
01304       astman_send_response(s, m, "Events On", NULL);
01305    else if (res == 0)
01306       astman_send_response(s, m, "Events Off", NULL);
01307 
01308    return 0;
01309 }

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

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

01875 {
01876    const char *exten = astman_get_header(m, "Exten");
01877    const char *context = astman_get_header(m, "Context");
01878    const char *id = astman_get_header(m,"ActionID");
01879    char idText[256] = "";
01880    char hint[256] = "";
01881    int status;
01882    if (ast_strlen_zero(exten)) {
01883       astman_send_error(s, m, "Extension not specified");
01884       return 0;
01885    }
01886    if (ast_strlen_zero(context))
01887       context = "default";
01888    status = ast_extension_state(NULL, context, exten);
01889    ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
01890         if (!ast_strlen_zero(id)) {
01891                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01892         }
01893    astman_append(s, "Response: Success\r\n"
01894                     "%s"
01895                "Message: Extension Status\r\n"
01896                "Exten: %s\r\n"
01897                "Context: %s\r\n"
01898                "Hint: %s\r\n"
01899                "Status: %d\r\n\r\n",
01900                idText,exten, context, hint, status);
01901    return 0;
01902 }

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

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

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

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

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

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

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

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

01327 {
01328    struct ast_channel *c = NULL;
01329    const char *name = astman_get_header(m, "Channel");
01330    if (ast_strlen_zero(name)) {
01331       astman_send_error(s, m, "No channel specified");
01332       return 0;
01333    }
01334    c = ast_get_channel_by_name_locked(name);
01335    if (!c) {
01336       astman_send_error(s, m, "No such channel");
01337       return 0;
01338    }
01339    ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
01340    ast_channel_unlock(c);
01341    astman_send_ack(s, m, "Channel Hungup");
01342    return 0;
01343 }

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

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

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

Definition at line 1315 of file manager.c.

References astman_send_response(), and s.

Referenced by init_manager().

01316 {
01317    astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
01318    return -1;
01319 }

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

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

01839 {
01840    const char *mailbox = astman_get_header(m, "Mailbox");
01841    const char *id = astman_get_header(m,"ActionID");
01842    char idText[256] = "";
01843    int newmsgs = 0, oldmsgs = 0;
01844    if (ast_strlen_zero(mailbox)) {
01845       astman_send_error(s, m, "Mailbox not specified");
01846       return 0;
01847    }
01848    ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs);
01849    if (!ast_strlen_zero(id)) {
01850       snprintf(idText, sizeof(idText), "ActionID: %s\r\n",id);
01851    }
01852    astman_append(s, "Response: Success\r\n"
01853                "%s"
01854                "Message: Mailbox Message Count\r\n"
01855                "Mailbox: %s\r\n"
01856                "NewMessages: %d\r\n"
01857                "OldMessages: %d\r\n" 
01858                "\r\n",
01859                 idText,mailbox, newmsgs, oldmsgs);
01860    return 0;
01861 }

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

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

01807 {
01808    const char *mailbox = astman_get_header(m, "Mailbox");
01809    const char *id = astman_get_header(m,"ActionID");
01810    char idText[256] = "";
01811    int ret;
01812    if (ast_strlen_zero(mailbox)) {
01813       astman_send_error(s, m, "Mailbox not specified");
01814       return 0;
01815    }
01816         if (!ast_strlen_zero(id))
01817                 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01818    ret = ast_app_has_voicemail(mailbox, NULL);
01819    astman_append(s, "Response: Success\r\n"
01820                "%s"
01821                "Message: Mailbox Status\r\n"
01822                "Mailbox: %s\r\n"
01823                "Waiting: %d\r\n\r\n", idText, mailbox, ret);
01824    return 0;
01825 }

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

Definition at line 1688 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, exten, fast_originate(), name, ast_channel::priority, s, timeout, and fast_originate_helper::vars.

Referenced by init_manager().

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

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

Definition at line 1014 of file manager.c.

References astman_send_response(), and s.

Referenced by init_manager().

01015 {
01016    astman_send_response(s, m, "Pong", NULL);
01017    return 0;
01018 }

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

action_redirect: The redirect manager command

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

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

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

Definition at line 1352 of file manager.c.

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

Referenced by init_manager().

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

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

Manager "status" command to show channels.

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

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

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

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

01912 {
01913    struct ast_channel *c = NULL;
01914    const char *name = astman_get_header(m, "Channel");
01915    int timeout = atoi(astman_get_header(m, "Timeout"));
01916    if (ast_strlen_zero(name)) {
01917       astman_send_error(s, m, "No channel specified");
01918       return 0;
01919    }
01920    if (!timeout) {
01921       astman_send_error(s, m, "No timeout specified");
01922       return 0;
01923    }
01924    c = ast_get_channel_by_name_locked(name);
01925    if (!c) {
01926       astman_send_error(s, m, "No such channel");
01927       return 0;
01928    }
01929    ast_channel_setwhentohangup(c, timeout);
01930    ast_channel_unlock(c);
01931    astman_send_ack(s, m, "Timeout Set");
01932    return 0;
01933 }

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

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

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

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

Definition at line 1965 of file manager.c.

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

Referenced by init_manager().

01966 {
01967    const char *event = astman_get_header(m, "UserEvent");
01968    char body[2048] = "";
01969    int x, bodylen = 0;
01970    for (x = 0; x < m->hdrcount; x++) {
01971       if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
01972          ast_copy_string(body + bodylen, m->headers[x], sizeof(body) - bodylen - 3);
01973          bodylen += strlen(m->headers[x]);
01974          ast_copy_string(body + bodylen, "\r\n", 3);
01975          bodylen += 2;
01976       }
01977    }
01978 
01979    manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body);
01980    return 0;
01981 }

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

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

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

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

Definition at line 2274 of file manager.c.

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

Referenced by init_manager(), and manager_event().

02275 {
02276    struct eventqent *tmp, *prev = NULL;
02277    tmp = ast_malloc(sizeof(*tmp) + strlen(str));
02278 
02279    if (!tmp)
02280       return -1;
02281 
02282    tmp->next = NULL;
02283    tmp->category = category;
02284    strcpy(tmp->eventdata, str);
02285    
02286    if (master_eventq) {
02287       prev = master_eventq;
02288       while (prev->next) 
02289          prev = prev->next;
02290       prev->next = tmp;
02291    } else {
02292       master_eventq = tmp;
02293    }
02294    
02295    tmp->usecount = num_sessions;
02296    
02297    return 0;
02298 }

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

Definition at line 395 of file manager.c.

References AST_LIST_TRAVERSE, and ast_manager_user::username.

Referenced by handle_showmanager(), and init_manager().

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

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

References ast_variable::next.

Referenced by get_perm(), and strings_to_mask().

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

static int ast_is_number ( char *  string  )  [static]

Definition at line 815 of file manager.c.

Referenced by strings_to_mask().

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

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

References ast_malloc, and ast_manager_register_struct().

Referenced by init_manager(), and load_module().

02421 {
02422    struct manager_action *cur;
02423 
02424    cur = ast_malloc(sizeof(*cur));
02425    if (!cur)
02426       return -1;
02427    
02428    cur->action = action;
02429    cur->authority = auth;
02430    cur->func = func;
02431    cur->synopsis = synopsis;
02432    cur->description = description;
02433    cur->next = NULL;
02434 
02435    ast_manager_register_struct(cur);
02436 
02437    return 0;
02438 }

static int ast_manager_register_struct ( struct manager_action act  )  [static]

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

02377 {
02378    struct manager_action *cur, *prev = NULL;
02379    int ret;
02380 
02381    ast_rwlock_wrlock(&actionlock);
02382    cur = first_action;
02383    while (cur) { /* Walk the list of actions */
02384       ret = strcasecmp(cur->action, act->action);
02385       if (ret == 0) {
02386          ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
02387          ast_rwlock_unlock(&actionlock);
02388          return -1;
02389       } else if (ret > 0) {
02390          /* Insert these alphabetically */
02391          if (prev) {
02392             act->next = prev->next;
02393             prev->next = act;
02394          } else {
02395             act->next = first_action;
02396             first_action = act;
02397          }
02398          break;
02399       }
02400       prev = cur; 
02401       cur = cur->next;
02402    }
02403    
02404    if (!cur) {
02405       if (prev)
02406          prev->next = act;
02407       else
02408          first_action = act;
02409       act->next = NULL;
02410    }
02411 
02412    if (option_verbose > 1) 
02413       ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", act->action);
02414    ast_rwlock_unlock(&actionlock);
02415    return 0;
02416 }

int ast_manager_unregister ( char *  action  ) 

Parameters:
action Name of registred Action:

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

02348 {
02349    struct manager_action *cur, *prev;
02350 
02351    ast_rwlock_wrlock(&actionlock);
02352    cur = prev = first_action;
02353    while (cur) {
02354       if (!strcasecmp(action, cur->action)) {
02355          prev->next = cur->next;
02356          free(cur);
02357          if (option_verbose > 1) 
02358             ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action);
02359          ast_rwlock_unlock(&actionlock);
02360          return 0;
02361       }
02362       prev = cur;
02363       cur = cur->next;
02364    }
02365    ast_rwlock_unlock(&actionlock);
02366    return 0;
02367 }

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

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

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

Get header from mananger transaction

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

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

struct ast_variable* astman_get_variables ( const struct message m  ) 

Get a linked list of the Variable: headers

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 875 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_ERROR, LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), ast_variable::name, ast_variable::next, password, s, and ast_variable::value.

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

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

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

Convert authority code to string with serveral options.

Definition at line 194 of file manager.c.

References ast_strlen_zero(), and perms.

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

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

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

Definition at line 216 of file manager.c.

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

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

static void destroy_session ( struct mansession s  )  [static]

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

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

static int do_message ( struct mansession s  )  [static]

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

02120 {
02121    struct message m = { 0 };
02122    char header_buf[sizeof(s->inbuf)] = { '\0' };
02123    int res;
02124 
02125    for (;;) {
02126       /* Check if any events are pending and do them if needed */
02127       if (s->eventq->next) {
02128          if (process_events(s))
02129             return -1;
02130       }
02131       res = get_input(s, header_buf);
02132       if (res == 0) {
02133          continue;
02134       } else if (res > 0) {
02135          /* Strip trailing \r\n */
02136          if (strlen(header_buf) < 2)
02137             continue;
02138          header_buf[strlen(header_buf) - 2] = '\0';
02139          if (ast_strlen_zero(header_buf))
02140             return process_message(s, &m) ? -1 : 0;
02141          else if (m.hdrcount < (AST_MAX_MANHEADERS - 1))
02142             m.headers[m.hdrcount++] = ast_strdupa(header_buf);
02143       } else {
02144          return res;
02145       }
02146    }
02147 }

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

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

01625 {
01626    struct fast_originate_helper *in = data;
01627    int res;
01628    int reason = 0;
01629    struct ast_channel *chan = NULL;
01630    char requested_channel[AST_CHANNEL_NAME];
01631 
01632    if (!ast_strlen_zero(in->app)) {
01633       res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, 
01634          S_OR(in->cid_num, NULL), 
01635          S_OR(in->cid_name, NULL),
01636          in->vars, in->account, &chan);
01637    } else {
01638       res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 
01639          S_OR(in->cid_num, NULL), 
01640          S_OR(in->cid_name, NULL),
01641          in->vars, in->account, &chan);
01642    }
01643 
01644    if (!chan)
01645       snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);   
01646    /* Tell the manager what happened with the channel */
01647    manager_event(EVENT_FLAG_CALL, "OriginateResponse",
01648       "%s"
01649       "Response: %s\r\n"
01650       "Channel: %s\r\n"
01651       "Context: %s\r\n"
01652       "Exten: %s\r\n"
01653       "Reason: %d\r\n"
01654       "Uniqueid: %s\r\n"
01655       "CallerID: %s\r\n"      /* This parameter is deprecated and will be removed post-1.4 */
01656       "CallerIDNum: %s\r\n"
01657       "CallerIDName: %s\r\n",
01658       in->idtext, res ? "Failure" : "Success", chan ? chan->name : requested_channel, in->context, in->exten, reason, 
01659       chan ? chan->uniqueid : "<null>",
01660       S_OR(in->cid_num, "<unknown>"),
01661       S_OR(in->cid_num, "<unknown>"),
01662       S_OR(in->cid_name, "<unknown>")
01663       );
01664 
01665    /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
01666    if (chan)
01667       ast_channel_unlock(chan);
01668    free(in);
01669    return NULL;
01670 }

static void free_session ( struct mansession s  )  [static]

Definition at line 659 of file manager.c.

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

Referenced by accept_thread(), and destroy_session().

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

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

Definition at line 2065 of file manager.c.

References s.

Referenced by do_message(), and skinny_session().

02066 {
02067    /* output must have at least sizeof(s->inbuf) space */
02068    int res;
02069    int x;
02070    struct pollfd fds[1];
02071    for (x = 1; x < s->inlen; x++) {
02072       if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) {
02073          /* Copy output data up to and including \r\n */
02074          memcpy(output, s->inbuf, x + 1);
02075          /* Add trailing \0 */
02076          output[x+1] = '\0';
02077          /* Move remaining data back to the front */
02078          memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x);
02079          s->inlen -= (x + 1);
02080          return 1;
02081       }
02082    } 
02083    if (s->inlen >= sizeof(s->inbuf) - 1) {
02084       ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->sin.sin_addr), s->inbuf);
02085       s->inlen = 0;
02086    }
02087    fds[0].fd = s->fd;
02088    fds[0].events = POLLIN;
02089    do {
02090       ast_mutex_lock(&s->__lock);
02091       s->waiting_thread = pthread_self();
02092       ast_mutex_unlock(&s->__lock);
02093 
02094       res = poll(fds, 1, -1);
02095 
02096       ast_mutex_lock(&s->__lock);
02097       s->waiting_thread = AST_PTHREADT_NULL;
02098       ast_mutex_unlock(&s->__lock);
02099       if (res < 0) {
02100          if (errno == EINTR) {
02101             return 0;
02102          }
02103          ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));
02104          return -1;
02105       } else if (res > 0) {
02106          ast_mutex_lock(&s->__lock);
02107          res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen);
02108          ast_mutex_unlock(&s->__lock);
02109          if (res < 1)
02110             return -1;
02111          break;
02112       }
02113    } while(1);
02114    s->inlen += res;
02115    s->inbuf[s->inlen] = '\0';
02116    return 0;
02117 }

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

Definition at line 800 of file manager.c.

References ast_instring(), and perms.

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

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

Definition at line 456 of file manager.c.

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

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

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

Definition at line 494 of file manager.c.

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

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

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

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

Definition at line 436 of file manager.c.

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

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

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

CLI command Should change to "manager show commands".

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

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

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

CLI command show manager connected.

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

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

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

CLI command show manager connected.

Definition at line 565 of file manager.c.

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

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

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

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

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

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

Definition at line 346 of file manager.c.

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

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

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

manager_event: Send AMI event to client

Definition at line 2301 of file manager.c.

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

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

02302 {
02303    struct mansession *s;
02304    char auth[80];
02305    va_list ap;
02306    struct timeval now;
02307    struct ast_dynamic_str *buf;
02308 
02309    /* Abort if there aren't any manager sessions */
02310    if (!num_sessions)
02311       return 0;
02312 
02313    if (!(buf = ast_dynamic_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE)))
02314       return -1;
02315 
02316    ast_dynamic_str_thread_set(&buf, 0, &manager_event_buf,
02317          "Event: %s\r\nPrivilege: %s\r\n",
02318           event, authority_to_str(category, auth, sizeof(auth)));
02319 
02320    if (timestampevents) {
02321       now = ast_tvnow();
02322       ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf,
02323             "Timestamp: %ld.%06lu\r\n",
02324              now.tv_sec, (unsigned long) now.tv_usec);
02325    }
02326 
02327    va_start(ap, fmt);
02328    ast_dynamic_str_thread_append_va(&buf, 0, &manager_event_buf, fmt, ap);
02329    va_end(ap);
02330    
02331    ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, "\r\n");  
02332    
02333    /* Append event to master list and wake up any sleeping sessions */
02334    AST_LIST_LOCK(&sessions);
02335    append_event(buf->str, category);
02336    AST_LIST_TRAVERSE(&sessions, s, list) {
02337       ast_mutex_lock(&s->__lock);
02338       if (s->waiting_thread != AST_PTHREADT_NULL)
02339          pthread_kill(s->waiting_thread, SIGURG);
02340       ast_mutex_unlock(&s->__lock);
02341    }
02342    AST_LIST_UNLOCK(&sessions);
02343 
02344    return 0;
02345 }

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

Definition at line 2369 of file manager.c.

References EVENT_FLAG_CALL, and manager_event().

Referenced by init_manager().

02370 {
02371    /* Notify managers of change */
02372    manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nStatus: %d\r\n", exten, context, state);
02373    return 0;
02374 }

static int process_events ( struct mansession s  )  [static]

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

01936 {
01937    struct eventqent *eqe;
01938    int ret = 0;
01939    ast_mutex_lock(&s->__lock);
01940    if (s->fd > -1) {
01941       if (!s->eventq)
01942          s->eventq = master_eventq;
01943       while(s->eventq->next) {
01944          eqe = s->eventq->next;
01945          if ((s->authenticated && (s->readperm & eqe->category) == eqe->category) &&
01946              ((s->send_events & eqe->category) == eqe->category)) {
01947             if (!ret && ast_carefulwrite(s->fd, eqe->eventdata, strlen(eqe->eventdata), s->writetimeout) < 0)
01948                ret = -1;
01949          }
01950          unuse_eventqent(s->eventq);
01951          s->eventq = eqe;
01952       }
01953    }
01954    ast_mutex_unlock(&s->__lock);
01955    return ret;
01956 }

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

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

01984 {
01985    char action[80] = "";
01986    struct manager_action *tmp;
01987    const char *id = astman_get_header(m,"ActionID");
01988    char idText[256] = "";
01989    int ret = 0;
01990 
01991    ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action));
01992    if (option_debug)
01993       ast_log( LOG_DEBUG, "Manager received command '%s'\n", action );
01994 
01995    if (ast_strlen_zero(action)) {
01996       astman_send_error(s, m, "Missing action in request");
01997       return 0;
01998    }
01999    if (!ast_strlen_zero(id)) {
02000       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
02001    }
02002    if (!s->authenticated) {
02003       if (!strcasecmp(action, "Challenge")) {
02004          const char *authtype = astman_get_header(m, "AuthType");
02005 
02006          if (!strcasecmp(authtype, "MD5")) {
02007             if (ast_strlen_zero(s->challenge))
02008                snprintf(s->challenge, sizeof(s->challenge), "%ld", ast_random());
02009             astman_append(s, "Response: Success\r\n"
02010                   "%s"
02011                   "Challenge: %s\r\n\r\n",
02012                   idText, s->challenge);
02013             return 0;
02014          } else {
02015             astman_send_error(s, m, "Must specify AuthType");
02016             return 0;
02017          }
02018       } else if (!strcasecmp(action, "Login")) {
02019          if (authenticate(s, m)) {
02020             sleep(1);
02021             astman_send_error(s, m, "Authentication failed");
02022             return -1;
02023          } else {
02024             s->authenticated = 1;
02025             if (option_verbose > 1) {
02026                if (displayconnects) {
02027                   ast_verbose(VERBOSE_PREFIX_2 "%sManager '%s' logged on from %s\n", 
02028                      (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
02029                }
02030             }
02031             ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", 
02032                (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
02033             astman_send_ack(s, m, "Authentication accepted");
02034          }
02035       } else if (!strcasecmp(action, "Logoff")) {
02036          astman_send_ack(s, m, "See ya");
02037          return -1;
02038       } else
02039          astman_send_error(s, m, "Authentication Required");
02040    } else {
02041       if (!strcasecmp(action, "Login"))
02042          astman_send_ack(s, m, "Already logged in");
02043       else {
02044          ast_rwlock_rdlock(&actionlock);
02045          for (tmp = first_action; tmp; tmp = tmp->next) {      
02046             if (strcasecmp(action, tmp->action))
02047                continue;
02048             if ((s->writeperm & tmp->authority) == tmp->authority) {
02049                if (tmp->func(s, m))
02050                   ret = -1;
02051             } else
02052                astman_send_error(s, m, "Permission denied");
02053             break;
02054          }
02055          ast_rwlock_unlock(&actionlock);
02056          if (!tmp)
02057             astman_send_error(s, m, "Invalid/unknown command");
02058       }
02059    }
02060    if (ret)
02061       return ret;
02062    return process_events(s);
02063 }

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

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

02150 {
02151    struct mansession *s = data;
02152    int res;
02153    
02154    astman_append(s, "Asterisk Call Manager/1.0\r\n");
02155    for (;;) {
02156       if ((res = do_message(s)) < 0)
02157          break;
02158    }
02159    if (s->authenticated) {
02160       if (option_verbose > 1) {
02161          if (displayconnects) 
02162             ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
02163       }
02164       ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
02165    } else {
02166       if (option_verbose > 1) {
02167          if (displayconnects)
02168             ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr));
02169       }
02170       ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr));
02171    }
02172    destroy_session(s);
02173    return NULL;
02174 }

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

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

Referenced by action_events().

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

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

Definition at line 832 of file manager.c.

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

Referenced by set_eventmask().

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

static void unuse_eventqent ( struct eventqent e  )  [static]

Definition at line 653 of file manager.c.

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

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

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

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

Definition at line 234 of file manager.c.

Referenced by xml_translate().

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

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

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

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


Variable Documentation

int asock = -1 [static]

Definition at line 97 of file manager.c.

Referenced by accept_thread(), and init_manager().

int block_sockets [static]

Definition at line 103 of file manager.c.

Referenced by accept_thread(), and init_manager().

struct ast_cli_entry cli_manager[] [static]

Definition at line 627 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 607 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 612 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 617 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 622 of file manager.c.

int displayconnects = 1 [static]

Definition at line 98 of file manager.c.

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

int enabled [static]

Definition at line 95 of file manager.c.

struct manager_action* first_action [static]

Definition at line 190 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 100 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 1604 of file manager.c.

char mandescr_events[] [static]

Definition at line 1289 of file manager.c.

char mandescr_extensionstate[] [static]

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

char mandescr_getvar[] [static]

Definition at line 1387 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 1321 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 1264 of file manager.c.

char mandescr_logoff[] [static]

Initial value:

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

Definition at line 1311 of file manager.c.

char mandescr_mailboxcount[] [static]

Definition at line 1827 of file manager.c.

char mandescr_mailboxstatus[] [static]

Help text for manager command mailboxstatus.

Definition at line 1795 of file manager.c.

char mandescr_originate[] [static]

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

char mandescr_redirect[] [static]

Definition at line 1529 of file manager.c.

char mandescr_setvar[] [static]

Definition at line 1345 of file manager.c.

char mandescr_timeout[] [static]

Definition at line 1904 of file manager.c.

char mandescr_updateconfig[] [static]

Definition at line 1124 of file manager.c.

char mandescr_userevent[] [static]

Definition at line 1958 of file manager.c.

char mandescr_waitevent[] [static]

Manager WAITEVENT.

Definition at line 1175 of file manager.c.

struct eventqent* master_eventq = NULL

Definition at line 107 of file manager.c.

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

int num_sessions [static]

Definition at line 104 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 96 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 603 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 598 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 580 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 584 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 588 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 593 of file manager.c.

pthread_t t [static]

Definition at line 102 of file manager.c.

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

int timestampevents [static]

Definition at line 99 of file manager.c.

Referenced by init_manager(), and manager_event().


Generated on Mon Apr 30 07:47:40 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1