Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:02:06 2007

Asterisk developer's documentation :: Codename Pineapple


AMI functions


Data Structures

struct  ast_manager_user
 user descriptor, as read from the config file. More...
struct  eventqent
struct  fast_originate_helper
struct  mansession
struct  permalias

Defines

#define ASTMAN_APPEND_BUF_INITSIZE   256
#define MANAGER_EVENT_BUF_INITSIZE   256
#define MSG_MOREDATA   ((char *)astman_send_response)
 send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field.
#define NEW_EVENT(m)   (AST_LIST_NEXT(m->last_ev, eq_next))

Functions

int __manager_event (int category, const char *event, const char *file, int line, const char *func, const char *fmt,...)
 manager_event: Send AMI event to client
static int action_challenge (struct mansession *s, const struct message *m)
static int action_command (struct mansession *s, const struct message *m)
 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_login (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_sendtext (struct mansession *s, const struct message *m)
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 int ast_instring (const char *bigstr, const char *smallstr, const char delim)
static AST_LIST_HEAD_STATIC (users, ast_manager_user)
 list of users found in the config file
static AST_LIST_HEAD_STATIC (sessions, mansession)
static AST_LIST_HEAD_STATIC (all_events, eventqent)
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
void ast_manager_register_hook (struct manager_custom_hook *hook)
 Add a custom hook to be called when an event is fired.
static int ast_manager_register_struct (struct manager_action *act)
int ast_manager_unregister (char *action)
void ast_manager_unregister_hook (struct manager_custom_hook *hook)
 Delete a custom hook to be called when an event is fired.
static AST_RWLIST_HEAD_STATIC (manager_hooks, manager_custom_hook)
 AST_RWLOCK_DEFINE_STATIC (actionlock)
 AST_THREADSTORAGE (manager_event_buf)
 AST_THREADSTORAGE (astman_append_buf)
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_listack (struct mansession *s, const struct message *m, char *msg, char *listflag)
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
static void astman_send_response_full (struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag)
static void astman_start_ack (struct mansession *s, const struct message *m)
static int authenticate (struct mansession *s, const struct message *m)
static char * authority_to_str (int authority, struct ast_str **res)
 Convert authority code to a list of 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 struct ast_manager_userget_manager_by_name_locked (const char *name)
static int get_perm (const char *instr)
static struct eventqentgrab_last (void)
 Event list management functions. We assume that the event list always has at least one element, and the delete code will not remove the last entry even if the.
static int handle_mandebug (int fd, int argc, char *argv[])
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 manager list commands.
static int handle_showmanconn (int fd, int argc, char *argv[])
 CLI command manager list connected.
static int handle_showmaneventq (int fd, int argc, char *argv[])
 CLI command manager list eventq.
static void handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg)
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 purge_events (void)
static void purge_sessions (int n_max)
 remove at most n_max stale session from the list.
static void ref_event (struct eventqent *e)
static int send_string (struct mansession *s, char *string)
static void * session_do (void *data)
 The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ).
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 struct eventqentunref_event (struct eventqent *e)

Variables

static int block_sockets
static struct ast_cli_entry cli_manager []
static int displayconnects = 1
static struct manager_actionfirst_action
 list of actions registered
static int httptimeout = 60
static int manager_debug
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_sendtext []
static char mandescr_setvar []
static char mandescr_timeout []
static char mandescr_updateconfig []
static char mandescr_userevent []
static char mandescr_waitevent []
 Manager WAITEVENT.
static int num_sessions
static struct permalias perms []
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 int timestampevents


Define Documentation

#define ASTMAN_APPEND_BUF_INITSIZE   256
 

Definition at line 756 of file manager.c.

Referenced by astman_append().

#define MANAGER_EVENT_BUF_INITSIZE   256
 

Definition at line 2318 of file manager.c.

Referenced by __manager_event().

#define MSG_MOREDATA   ((char *)astman_send_response)
 

send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field.

Use the explicit constant MSG_MOREDATA to remove the empty line. XXX MSG_MOREDATA should go to a header file.

Definition at line 795 of file manager.c.

Referenced by astman_send_response_full(), and astman_start_ack().

#define NEW_EVENT  )     (AST_LIST_NEXT(m->last_ev, eq_next))
 

Definition at line 151 of file manager.c.

Referenced by action_waitevent(), and process_events().


Function Documentation

int __manager_event int  category,
const char *  event,
const char *  file,
int  line,
const char *  func,
const char *  fmt,
  ...
 

manager_event: Send AMI event to client

Definition at line 2321 of file manager.c.

References append_event(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_append_va, authority_to_str(), manager_custom_hook::helper, manager_debug, MANAGER_EVENT_BUF_INITSIZE, num_sessions, s, seq, sessions, ast_str::str, and timestampevents.

02323 {
02324    struct mansession *s;
02325    struct manager_custom_hook *hook;
02326    struct ast_str *auth = ast_str_alloca(80);
02327    const char *cat_str;
02328    va_list ap;
02329    struct timeval now;
02330    struct ast_str *buf;
02331 
02332    /* Abort if there aren't any manager sessions */
02333    if (!num_sessions)
02334       return 0;
02335 
02336    if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE)))
02337       return -1;
02338 
02339    cat_str = authority_to_str(category, &auth);
02340    ast_str_set(&buf, 0,
02341          "Event: %s\r\nPrivilege: %s\r\n",
02342           event, cat_str);
02343 
02344    if (timestampevents) {
02345       now = ast_tvnow();
02346       ast_str_append(&buf, 0,
02347             "Timestamp: %ld.%06lu\r\n",
02348              now.tv_sec, (unsigned long) now.tv_usec);
02349    }
02350    if (manager_debug) {
02351       static int seq;
02352       ast_str_append(&buf, 0,
02353             "SequenceNumber: %d\r\n",
02354              ast_atomic_fetchadd_int(&seq, 1));
02355       ast_str_append(&buf, 0,
02356             "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func);
02357    }
02358 
02359    va_start(ap, fmt);
02360    ast_str_append_va(&buf, 0, fmt, ap);
02361    va_end(ap);
02362 
02363    ast_str_append(&buf, 0, "\r\n");
02364 
02365    append_event(buf->str, category);
02366 
02367    /* Wake up any sleeping sessions */
02368    AST_LIST_LOCK(&sessions);
02369    AST_LIST_TRAVERSE(&sessions, s, list) {
02370       ast_mutex_lock(&s->__lock);
02371       if (s->waiting_thread != AST_PTHREADT_NULL)
02372          pthread_kill(s->waiting_thread, SIGURG);
02373       ast_mutex_unlock(&s->__lock);
02374    }
02375    AST_LIST_UNLOCK(&sessions);
02376 
02377    AST_RWLIST_RDLOCK(&manager_hooks);
02378    if (!AST_RWLIST_EMPTY(&manager_hooks)) {
02379       AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
02380          hook->helper(category, event, buf->str);
02381       }
02382    }
02383    AST_RWLIST_UNLOCK(&manager_hooks);
02384 
02385    return 0;
02386 }

static int action_challenge struct mansession s,
const struct message m
[static]
 

Definition at line 1326 of file manager.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and s.

Referenced by init_manager().

01327 {
01328    const char *authtype = astman_get_header(m, "AuthType");
01329 
01330    if (!strcasecmp(authtype, "MD5")) {
01331       if (ast_strlen_zero(s->challenge))
01332          snprintf(s->challenge, sizeof(s->challenge), "%ld", ast_random());
01333       ast_mutex_lock(&s->__lock);
01334       astman_start_ack(s, m);
01335       astman_append(s, "Challenge: %s\r\n\r\n", s->challenge);
01336       ast_mutex_unlock(&s->__lock);
01337    } else {
01338       astman_send_error(s, m, "Must specify AuthType");
01339    }
01340    return 0;
01341 }

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

Manager command "command" - execute CLI command.

Definition at line 1653 of file manager.c.

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

Referenced by init_manager().

01654 {
01655    const char *cmd = astman_get_header(m, "Command");
01656    const char *id = astman_get_header(m, "ActionID");
01657    char *buf;
01658    char template[] = "/tmp/ast-ami-XXXXXX";  /* template for temporary file */
01659    int fd = mkstemp(template);
01660    off_t l;
01661 
01662    astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
01663    if (!ast_strlen_zero(id))
01664       astman_append(s, "ActionID: %s\r\n", id);
01665    /* FIXME: Wedge a ActionID response in here, waiting for later changes */
01666    ast_cli_command(fd, cmd);  /* XXX need to change this to use a FILE * */
01667    l = lseek(fd, 0, SEEK_END);   /* how many chars available */
01668    buf = alloca(l+1);
01669    lseek(fd, 0, SEEK_SET);
01670    read(fd, buf, l);
01671    buf[l] = '\0';
01672    close(fd);
01673    unlink(template);
01674    astman_append(s, buf);
01675    astman_append(s, "--END COMMAND--\r\n\r\n");
01676    return 0;
01677 }

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

Definition at line 1284 of file manager.c.

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

Referenced by init_manager().

01285 {
01286    const char *mask = astman_get_header(m, "EventMask");
01287    int res;
01288 
01289    res = set_eventmask(s, mask);
01290    if (res > 0)
01291       astman_send_response(s, m, "Events On", NULL);
01292    else if (res == 0)
01293       astman_send_response(s, m, "Events Off", NULL);
01294 
01295    return 0;
01296 }

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

Definition at line 1935 of file manager.c.

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

Referenced by init_manager().

01936 {
01937    const char *exten = astman_get_header(m, "Exten");
01938    const char *context = astman_get_header(m, "Context");
01939    char hint[256] = "";
01940    int status;
01941    if (ast_strlen_zero(exten)) {
01942       astman_send_error(s, m, "Extension not specified");
01943       return 0;
01944    }
01945    if (ast_strlen_zero(context))
01946       context = "default";
01947    status = ast_extension_state(NULL, context, exten);
01948    ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
01949    astman_start_ack(s, m);
01950    astman_append(s,   "Message: Extension Status\r\n"
01951             "Exten: %s\r\n"
01952             "Context: %s\r\n"
01953             "Hint: %s\r\n"
01954             "Status: %d\r\n\r\n",
01955             exten, context, hint, status);
01956    return 0;
01957 }

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

Definition at line 1019 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(), astman_start_ack(), lineno, ast_variable::name, ast_variable::next, s, and ast_variable::value.

Referenced by init_manager().

01020 {
01021    struct ast_config *cfg;
01022    const char *fn = astman_get_header(m, "Filename");
01023    int catcount = 0;
01024    int lineno = 0;
01025    char *category=NULL;
01026    struct ast_variable *v;
01027 
01028    if (ast_strlen_zero(fn)) {
01029       astman_send_error(s, m, "Filename not specified");
01030       return 0;
01031    }
01032    if (!(cfg = ast_config_load_with_comments(fn))) {
01033       astman_send_error(s, m, "Config file not found");
01034       return 0;
01035    }
01036    astman_start_ack(s, m);
01037    while ((category = ast_category_browse(cfg, category))) {
01038       lineno = 0;
01039       astman_append(s, "Category-%06d: %s\r\n", catcount, category);
01040       for (v = ast_variable_browse(cfg, category); v; v = v->next)
01041          astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
01042       catcount++;
01043    }
01044    ast_config_destroy(cfg);
01045    astman_append(s, "\r\n");
01046 
01047    return 0;
01048 }

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

Definition at line 1416 of file manager.c.

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

Referenced by init_manager().

01417 {
01418    struct ast_channel *c = NULL;
01419    const char *name = astman_get_header(m, "Channel");
01420    const char *varname = astman_get_header(m, "Variable");
01421    char *varval;
01422    char workspace[1024];
01423 
01424    if (ast_strlen_zero(varname)) {
01425       astman_send_error(s, m, "No variable specified");
01426       return 0;
01427    }
01428 
01429    if (!ast_strlen_zero(name)) {
01430       c = ast_get_channel_by_name_locked(name);
01431       if (!c) {
01432          astman_send_error(s, m, "No such channel");
01433          return 0;
01434       }
01435    }
01436 
01437    if (varname[strlen(varname) - 1] == ')') {
01438       ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
01439    } else {
01440       pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
01441    }
01442 
01443    if (c)
01444       ast_channel_unlock(c);
01445    astman_start_ack(s, m);
01446    astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, varval);
01447 
01448    return 0;
01449 }

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

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

01349 {
01350    struct ast_channel *c = NULL;
01351    const char *name = astman_get_header(m, "Channel");
01352    if (ast_strlen_zero(name)) {
01353       astman_send_error(s, m, "No channel specified");
01354       return 0;
01355    }
01356    c = ast_get_channel_by_name_locked(name);
01357    if (!c) {
01358       astman_send_error(s, m, "No such channel");
01359       return 0;
01360    }
01361    ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
01362    ast_channel_unlock(c);
01363    astman_send_ack(s, m, "Channel Hungup");
01364    return 0;
01365 }

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

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

Referenced by init_manager().

01261 {
01262    struct manager_action *cur;
01263    struct ast_str *temp = ast_str_alloca(BUFSIZ); /* XXX very large ? */
01264 
01265    astman_start_ack(s, m);
01266    for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */
01267       if ((s->writeperm & cur->authority) == cur->authority)
01268          astman_append(s, "%s: %s (Priv: %s)\r\n",
01269             cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
01270    }
01271    astman_append(s, "\r\n");
01272 
01273    return 0;
01274 }

static int action_login struct mansession s,
const struct message m
[static]
 

Definition at line 1308 of file manager.c.

References ast_inet_ntoa(), ast_log(), ast_verbose(), astman_send_ack(), astman_send_error(), authenticate(), displayconnects, LOG_EVENT, option_verbose, s, and VERBOSE_PREFIX_2.

Referenced by init_manager().

01309 {
01310    if (authenticate(s, m)) {
01311       sleep(1);
01312       astman_send_error(s, m, "Authentication failed");
01313       return -1;
01314    }
01315    s->authenticated = 1;
01316    if (option_verbose > 1) {
01317       if (displayconnects) {
01318          ast_verbose(VERBOSE_PREFIX_2 "%sManager '%s' logged on from %s\n", (s->managerid ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
01319       }
01320    }
01321    ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", (s->managerid ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr));
01322    astman_send_ack(s, m, "Authentication accepted");
01323    return 0;
01324 }

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

Definition at line 1302 of file manager.c.

References astman_send_response(), and s.

Referenced by init_manager().

01303 {
01304    astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
01305    return -1;
01306 }

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

Definition at line 1904 of file manager.c.

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

Referenced by init_manager().

01905 {
01906    const char *mailbox = astman_get_header(m, "Mailbox");
01907    int newmsgs = 0, oldmsgs = 0;
01908 
01909    if (ast_strlen_zero(mailbox)) {
01910       astman_send_error(s, m, "Mailbox not specified");
01911       return 0;
01912    }
01913    ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs);
01914    astman_start_ack(s, m);
01915    astman_append(s,   "Message: Mailbox Message Count\r\n"
01916             "Mailbox: %s\r\n"
01917             "NewMessages: %d\r\n"
01918             "OldMessages: %d\r\n"
01919             "\r\n",
01920             mailbox, newmsgs, oldmsgs);
01921    return 0;
01922 }

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

Definition at line 1876 of file manager.c.

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

Referenced by init_manager().

01877 {
01878    const char *mailbox = astman_get_header(m, "Mailbox");
01879    int ret;
01880 
01881    if (ast_strlen_zero(mailbox)) {
01882       astman_send_error(s, m, "Mailbox not specified");
01883       return 0;
01884    }
01885    ret = ast_app_has_voicemail(mailbox, NULL);
01886    astman_start_ack(s, m);
01887    astman_append(s, "Message: Mailbox Status\r\n"
01888           "Mailbox: %s\r\n"
01889           "Waiting: %d\r\n\r\n", mailbox, ret);
01890    return 0;
01891 }

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

Definition at line 1758 of file manager.c.

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

Referenced by init_manager().

01759 {
01760    const char *name = astman_get_header(m, "Channel");
01761    const char *exten = astman_get_header(m, "Exten");
01762    const char *context = astman_get_header(m, "Context");
01763    const char *priority = astman_get_header(m, "Priority");
01764    const char *timeout = astman_get_header(m, "Timeout");
01765    const char *callerid = astman_get_header(m, "CallerID");
01766    const char *account = astman_get_header(m, "Account");
01767    const char *app = astman_get_header(m, "Application");
01768    const char *appdata = astman_get_header(m, "Data");
01769    const char *async = astman_get_header(m, "Async");
01770    const char *id = astman_get_header(m, "ActionID");
01771    struct ast_variable *vars = astman_get_variables(m);
01772    char *tech, *data;
01773    char *l = NULL, *n = NULL;
01774    int pi = 0;
01775    int res;
01776    int to = 30000;
01777    int reason = 0;
01778    char tmp[256];
01779    char tmp2[256];
01780 
01781    pthread_t th;
01782    pthread_attr_t attr;
01783    if (!name) {
01784       astman_send_error(s, m, "Channel not specified");
01785       return 0;
01786    }
01787    if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) {
01788       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
01789          astman_send_error(s, m, "Invalid priority\n");
01790          return 0;
01791       }
01792    }
01793    if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) {
01794       astman_send_error(s, m, "Invalid timeout\n");
01795       return 0;
01796    }
01797    ast_copy_string(tmp, name, sizeof(tmp));
01798    tech = tmp;
01799    data = strchr(tmp, '/');
01800    if (!data) {
01801       astman_send_error(s, m, "Invalid channel\n");
01802       return 0;
01803    }
01804    *data++ = '\0';
01805    ast_copy_string(tmp2, callerid, sizeof(tmp2));
01806    ast_callerid_parse(tmp2, &n, &l);
01807    if (n) {
01808       if (ast_strlen_zero(n))
01809          n = NULL;
01810    }
01811    if (l) {
01812       ast_shrink_phone_number(l);
01813       if (ast_strlen_zero(l))
01814          l = NULL;
01815    }
01816    if (ast_true(async)) {
01817       struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast));
01818       if (!fast) {
01819          res = -1;
01820       } else {
01821          if (!ast_strlen_zero(id))
01822             snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s\r\n", id);
01823          ast_copy_string(fast->tech, tech, sizeof(fast->tech));
01824             ast_copy_string(fast->data, data, sizeof(fast->data));
01825          ast_copy_string(fast->app, app, sizeof(fast->app));
01826          ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata));
01827          if (l)
01828             ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num));
01829          if (n)
01830             ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name));
01831          fast->vars = vars;
01832          ast_copy_string(fast->context, context, sizeof(fast->context));
01833          ast_copy_string(fast->exten, exten, sizeof(fast->exten));
01834          ast_copy_string(fast->account, account, sizeof(fast->account));
01835          fast->timeout = to;
01836          fast->priority = pi;
01837          pthread_attr_init(&attr);
01838          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
01839          if (ast_pthread_create(&th, &attr, fast_originate, fast)) {
01840             res = -1;
01841          } else {
01842             res = 0;
01843          }
01844          pthread_attr_destroy(&attr);
01845       }
01846    } else if (!ast_strlen_zero(app)) {
01847          res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
01848       } else {
01849       if (exten && context && pi)
01850             res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL);
01851       else {
01852          astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
01853          return 0;
01854       }
01855    }
01856    if (!res)
01857       astman_send_ack(s, m, "Originate successfully queued");
01858    else
01859       astman_send_error(s, m, "Originate failed");
01860    return 0;
01861 }

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

Definition at line 1007 of file manager.c.

References astman_send_response(), and s.

Referenced by init_manager().

01008 {
01009    astman_send_response(s, m, "Pong", NULL);
01010    return 0;
01011 }

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

action_redirect: The redirect manager command

Definition at line 1593 of file manager.c.

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

Referenced by init_manager().

01594 {
01595    const char *name = astman_get_header(m, "Channel");
01596    const char *name2 = astman_get_header(m, "ExtraChannel");
01597    const char *exten = astman_get_header(m, "Exten");
01598    const char *context = astman_get_header(m, "Context");
01599    const char *priority = astman_get_header(m, "Priority");
01600    struct ast_channel *chan, *chan2 = NULL;
01601    int pi = 0;
01602    int res;
01603 
01604    if (ast_strlen_zero(name)) {
01605       astman_send_error(s, m, "Channel not specified");
01606       return 0;
01607    }
01608    if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) {
01609       if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
01610          astman_send_error(s, m, "Invalid priority\n");
01611          return 0;
01612       }
01613    }
01614    /* XXX watch out, possible deadlock - we are trying to get two channels!!! */
01615    chan = ast_get_channel_by_name_locked(name);
01616    if (!chan) {
01617       char buf[BUFSIZ];
01618       snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
01619       astman_send_error(s, m, buf);
01620       return 0;
01621    }
01622    if (!ast_strlen_zero(name2))
01623       chan2 = ast_get_channel_by_name_locked(name2);
01624    res = ast_async_goto(chan, context, exten, pi);
01625    if (!res) {
01626       if (!ast_strlen_zero(name2)) {
01627          if (chan2)
01628             res = ast_async_goto(chan2, context, exten, pi);
01629          else
01630             res = -1;
01631          if (!res)
01632             astman_send_ack(s, m, "Dual Redirect successful");
01633          else
01634             astman_send_error(s, m, "Secondary redirect failed");
01635       } else
01636          astman_send_ack(s, m, "Redirect successful");
01637    } else
01638       astman_send_error(s, m, "Redirect failed");
01639    if (chan)
01640       ast_channel_unlock(chan);
01641    if (chan2)
01642       ast_channel_unlock(chan2);
01643    return 0;
01644 }

static int action_sendtext struct mansession s,
const struct message m
[static]
 

Definition at line 1548 of file manager.c.

References ast_get_channel_by_name_locked(), ast_mutex_unlock(), ast_sendtext(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::lock, name, and s.

Referenced by init_manager().

01549 {
01550    struct ast_channel *c = NULL;
01551    const char *name = astman_get_header(m, "Channel");
01552    const char *textmsg = astman_get_header(m, "Message");
01553    int res = 0;
01554 
01555    if (ast_strlen_zero(name)) {
01556       astman_send_error(s, m, "No channel specified");
01557       return 0;
01558    }
01559 
01560    if (ast_strlen_zero(textmsg)) {
01561       astman_send_error(s, m, "No Message specified");
01562       return 0;
01563    }
01564 
01565    c = ast_get_channel_by_name_locked(name);
01566    if (!c) {
01567       astman_send_error(s, m, "No such channel");
01568       return 0;
01569    }
01570 
01571    res = ast_sendtext(c, textmsg);
01572    ast_mutex_unlock(&c->lock);
01573    
01574    if (res > 0)
01575       astman_send_ack(s, m, "Success");
01576    else
01577       astman_send_error(s, m, "Failure");
01578    
01579    return res;
01580 }

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

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

01375 {
01376         struct ast_channel *c = NULL;
01377    const char *name = astman_get_header(m, "Channel");
01378    const char *varname = astman_get_header(m, "Variable");
01379    const char *varval = astman_get_header(m, "Value");
01380 
01381    if (ast_strlen_zero(varname)) {
01382       astman_send_error(s, m, "No variable specified");
01383       return 0;
01384    }
01385 
01386    if (ast_strlen_zero(varval)) {
01387       astman_send_error(s, m, "No value specified");
01388       return 0;
01389    }
01390 
01391    if (!ast_strlen_zero(name)) {
01392       c = ast_get_channel_by_name_locked(name);
01393       if (!c) {
01394          astman_send_error(s, m, "No such channel");
01395          return 0;
01396       }
01397    }
01398 
01399    pbx_builtin_setvar_helper(c, varname, varval);
01400 
01401    if (c)
01402       ast_channel_unlock(c);
01403 
01404    astman_send_ack(s, m, "Variable Set");
01405 
01406    return 0;
01407 }

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

Manager "status" command to show channels.

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

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

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

Definition at line 1966 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, and s.

Referenced by init_manager().

01967 {
01968    struct ast_channel *c;
01969    const char *name = astman_get_header(m, "Channel");
01970    int timeout = atoi(astman_get_header(m, "Timeout"));
01971 
01972    if (ast_strlen_zero(name)) {
01973       astman_send_error(s, m, "No channel specified");
01974       return 0;
01975    }
01976    if (!timeout) {
01977       astman_send_error(s, m, "No timeout specified");
01978       return 0;
01979    }
01980    c = ast_get_channel_by_name_locked(name);
01981    if (!c) {
01982       astman_send_error(s, m, "No such channel");
01983       return 0;
01984    }
01985    ast_channel_setwhentohangup(c, timeout);
01986    ast_channel_unlock(c);
01987    astman_send_ack(s, m, "Timeout Set");
01988    return 0;
01989 }

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

Definition at line 1119 of file manager.c.

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

Referenced by init_manager().

01120 {
01121    struct ast_config *cfg;
01122    const char *sfn = astman_get_header(m, "SrcFilename");
01123    const char *dfn = astman_get_header(m, "DstFilename");
01124    int res;
01125    const char *rld = astman_get_header(m, "Reload");
01126 
01127    if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
01128       astman_send_error(s, m, "Filename not specified");
01129       return 0;
01130    }
01131    if (!(cfg = ast_config_load_with_comments(sfn))) {
01132       astman_send_error(s, m, "Config file not found");
01133       return 0;
01134    }
01135    handle_updates(s, m, cfg);
01136    res = config_text_file_save(dfn, cfg, "Manager");
01137    ast_config_destroy(cfg);
01138    if (res) {
01139       astman_send_error(s, m, "Save of config failed");
01140       return 0;
01141    }
01142    astman_send_ack(s, m, NULL);
01143    if (!ast_strlen_zero(rld)) {
01144       if (ast_true(rld))
01145          rld = NULL;
01146       ast_module_reload(rld);
01147    }
01148    return 0;
01149 }

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

Definition at line 2026 of file manager.c.

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

Referenced by init_manager().

02027 {
02028    const char *event = astman_get_header(m, "UserEvent");
02029    char body[2048] = "";
02030    int x, bodylen = 0;
02031    for (x = 0; x < m->hdrcount; x++) {
02032       if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
02033          ast_copy_string(body + bodylen, m->headers[x], sizeof(body) - bodylen - 3);
02034          bodylen += strlen(m->headers[x]);
02035          ast_copy_string(body + bodylen, "\r\n", 3);
02036          bodylen += 2;
02037       }
02038    }
02039 
02040    manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body);
02041    return 0;
02042 }

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

Definition at line 1159 of file manager.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_strlen_zero(), ast_wait_for_input(), astman_get_header(), LOG_DEBUG, NEW_EVENT, option_debug, and s.

Referenced by init_manager().

01160 {
01161    const char *timeouts = astman_get_header(m, "Timeout");
01162    int timeout = -1;
01163    int x;
01164    int needexit = 0;
01165    const char *id = astman_get_header(m,"ActionID");
01166    char idText[256] = "";
01167 
01168    if (!ast_strlen_zero(id))
01169       snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
01170 
01171    if (!ast_strlen_zero(timeouts)) {
01172       sscanf(timeouts, "%i", &timeout);
01173       if (timeout < -1)
01174          timeout = -1;
01175       /* XXX maybe put an upper bound, or prevent the use of 0 ? */
01176    }
01177 
01178    ast_mutex_lock(&s->__lock);
01179    if (s->waiting_thread != AST_PTHREADT_NULL)
01180       pthread_kill(s->waiting_thread, SIGURG);
01181 
01182    if (s->managerid) { /* AMI-over-HTTP session */
01183       /*
01184        * Make sure the timeout is within the expire time of the session,
01185        * as the client will likely abort the request if it does not see
01186        * data coming after some amount of time.
01187        */
01188       time_t now = time(NULL);
01189       int max = s->sessiontimeout - now - 10;
01190 
01191       if (max < 0)   /* We are already late. Strange but possible. */
01192          max = 0;
01193       if (timeout < 0 || timeout > max)
01194          timeout = max;
01195       if (!s->send_events) /* make sure we record events */
01196          s->send_events = -1;
01197    }
01198    ast_mutex_unlock(&s->__lock);
01199 
01200    /* XXX should this go inside the lock ? */
01201    s->waiting_thread = pthread_self(); /* let new events wake up this thread */
01202    if (option_debug)
01203       ast_log(LOG_DEBUG, "Starting waiting for an event!\n");
01204 
01205    for (x=0; x < timeout || timeout < 0; x++) {
01206       ast_mutex_lock(&s->__lock);
01207       if (NEW_EVENT(s))
01208          needexit = 1;
01209       /* We can have multiple HTTP session point to the same mansession entry.
01210        * The way we deal with it is not very nice: newcomers kick out the previous
01211        * HTTP session. XXX this needs to be improved.
01212        */
01213       if (s->waiting_thread != pthread_self())
01214          needexit = 1;
01215       if (s->needdestroy)
01216          needexit = 1;
01217       ast_mutex_unlock(&s->__lock);
01218       if (needexit)
01219          break;
01220       if (s->managerid == 0) {   /* AMI session */
01221          if (ast_wait_for_input(s->fd, 1000))
01222             break;
01223       } else { /* HTTP session */
01224          sleep(1);
01225       }
01226    }
01227    if (option_debug)
01228       ast_log(LOG_DEBUG, "Finished waiting for an event!\n");
01229    ast_mutex_lock(&s->__lock);
01230    if (s->waiting_thread == pthread_self()) {
01231       struct eventqent *eqe;
01232       astman_send_response(s, m, "Success", "Waiting for Event completed.");
01233       while ( (eqe = NEW_EVENT(s)) ) {
01234          ref_event(eqe);
01235          if (((s->readperm & eqe->category) == eqe->category) &&
01236              ((s->send_events & eqe->category) == eqe->category)) {
01237             astman_append(s, "%s", eqe->eventdata);
01238          }
01239          s->last_ev = unref_event(s->last_ev);
01240       }
01241       astman_append(s,
01242          "Event: WaitEventComplete\r\n"
01243          "%s"
01244          "\r\n", idText);
01245       s->waiting_thread = AST_PTHREADT_NULL;
01246    } else {
01247       if (option_debug)
01248          ast_log(LOG_DEBUG, "Abandoning event request!\n");
01249    }
01250    ast_mutex_unlock(&s->__lock);
01251    return 0;
01252 }

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

Definition at line 2294 of file manager.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_UNLOCK, ast_malloc, and seq.

Referenced by __manager_event(), and init_manager().

02295 {
02296    struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
02297    static int seq;   /* sequence number */
02298 
02299    if (!tmp)
02300       return -1;
02301 
02302    /* need to init all fields, because ast_malloc() does not */
02303    tmp->usecount = 0;
02304    tmp->category = category;
02305    tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
02306    AST_LIST_NEXT(tmp, eq_next) = NULL;
02307    strcpy(tmp->eventdata, str);
02308 
02309    AST_LIST_LOCK(&all_events);
02310    AST_LIST_INSERT_TAIL(&all_events, tmp, eq_next);
02311    AST_LIST_UNLOCK(&all_events);
02312 
02313    return 0;
02314 }

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

Referenced by get_perm().

00324 {
00325    const char *val = bigstr, *next;
00326 
00327    do {
00328       if ((next = strchr(val, delim))) {
00329          if (!strncmp(val, smallstr, (next - val)))
00330             return 1;
00331          else
00332             continue;
00333       } else
00334          return !strcmp(smallstr, val);
00335    } while (*(val = (next + 1)));
00336 
00337    return 0;
00338 }

static AST_LIST_HEAD_STATIC users  ,
ast_manager_user 
[static]
 

list of users found in the config file

static AST_LIST_HEAD_STATIC sessions  ,
mansession 
[static]
 

static AST_LIST_HEAD_STATIC all_events  ,
eventqent 
[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 2449 of file manager.c.

References ast_malloc, and ast_manager_register_struct().

Referenced by init_manager(), load_module(), and sip_cli_and_manager_commands_register().

02450 {
02451    struct manager_action *cur;
02452 
02453    cur = ast_malloc(sizeof(*cur));
02454    if (!cur)
02455       return -1;
02456 
02457    cur->action = action;
02458    cur->authority = auth;
02459    cur->func = func;
02460    cur->synopsis = synopsis;
02461    cur->description = description;
02462    cur->next = NULL;
02463 
02464    ast_manager_register_struct(cur);
02465 
02466    return 0;
02467 }

void ast_manager_register_hook struct manager_custom_hook hook  ) 
 

Add a custom hook to be called when an event is fired.

Parameters:
hook struct manager_custom_hook object to add

Definition at line 182 of file manager.c.

References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

00183 {
00184    AST_RWLIST_WRLOCK(&manager_hooks);
00185    AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list);
00186    AST_RWLIST_UNLOCK(&manager_hooks);
00187    return;
00188 }

static int ast_manager_register_struct struct manager_action act  )  [static]
 

Definition at line 2419 of file manager.c.

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

Referenced by ast_manager_register2().

02420 {
02421    struct manager_action *cur, *prev = NULL;
02422    int ret;
02423 
02424    ast_rwlock_wrlock(&actionlock);
02425    for (cur = first_action; cur; prev = cur, cur = cur->next) {
02426       ret = strcasecmp(cur->action, act->action);
02427       if (ret == 0) {
02428          ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
02429          ast_rwlock_unlock(&actionlock);
02430          return -1;
02431       }
02432       if (ret > 0)   /* Insert these alphabetically */
02433          break;
02434    }
02435    if (prev)
02436       prev->next = act;
02437    else
02438       first_action = act;
02439    act->next = cur;
02440 
02441    if (option_verbose > 1)
02442       ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", act->action);
02443    ast_rwlock_unlock(&actionlock);
02444    return 0;
02445 }

int ast_manager_unregister char *  action  ) 
 

Parameters:
action Name of registred Action:

Definition at line 2391 of file manager.c.

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

Referenced by __unload_module(), sip_cli_and_manager_commands_unregister(), and unload_module().

02392 {
02393    struct manager_action *cur, *prev;
02394 
02395    ast_rwlock_wrlock(&actionlock);
02396    for (cur = first_action, prev = NULL; cur; prev = cur, cur = cur->next) {
02397       if (!strcasecmp(action, cur->action)) {
02398          if (prev)
02399             prev->next = cur->next;
02400          else
02401             first_action = cur->next;
02402          free(cur);
02403          if (option_verbose > 1)
02404             ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action);
02405          break;
02406       }
02407    }
02408    ast_rwlock_unlock(&actionlock);
02409    return 0;
02410 }

void ast_manager_unregister_hook struct manager_custom_hook hook  ) 
 

Delete a custom hook to be called when an event is fired.

Parameters:
hook struct manager_custom_hook object to delete

Definition at line 191 of file manager.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

00192 {
00193    AST_RWLIST_WRLOCK(&manager_hooks);
00194    AST_RWLIST_REMOVE(&manager_hooks, hook, list);
00195    AST_RWLIST_UNLOCK(&manager_hooks);
00196    return;
00197 }

static AST_RWLIST_HEAD_STATIC manager_hooks  ,
manager_custom_hook 
[static]
 

AST_RWLOCK_DEFINE_STATIC actionlock   ) 
 

AST_THREADSTORAGE manager_event_buf   ) 
 

AST_THREADSTORAGE astman_append_buf   ) 
 

void astman_append struct mansession s,
const char *  fmt,
  ...
 

utility functions for creating AMI replies

Definition at line 761 of file manager.c.

References ast_str_set_va, ast_verbose(), ASTMAN_APPEND_BUF_INITSIZE, s, send_string(), and ast_str::str.

Referenced by __iax2_show_peers(), _sip_show_device(), _sip_show_devices(), _sip_show_peer(), _sip_show_peers(), action_agents(), action_challenge(), action_command(), action_extensionstate(), action_getconfig(), action_getvar(), action_listcommands(), action_mailboxcount(), action_mailboxstatus(), action_status(), action_zapshowchannels(), astman_send_response_full(), manager_dbget(), manager_iax2_show_netstats(), manager_iax2_show_peers(), manager_jabber_send(), manager_parking_status(), manager_show_dialplan_helper(), manager_sip_show_device(), manager_sip_show_devices(), manager_sip_show_peer(), manager_sip_show_peers(), and session_do().

00762 {
00763    va_list ap;
00764    struct ast_str *buf;
00765 
00766    if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE)))
00767       return;
00768 
00769    va_start(ap, fmt);
00770    ast_str_set_va(&buf, 0, fmt, ap);
00771    va_end(ap);
00772 
00773    if (s->f != NULL)
00774       send_string(s, buf->str);
00775    else
00776       ast_verbose("fd == -1 in astman_append, should not happen\n");
00777 }

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

Get header from mananger transaction

Definition at line 672 of file manager.c.

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

Referenced by _sip_show_devices(), _sip_show_peers(), action_agent_logoff(), action_agents(), action_challenge(), action_command(), action_events(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_mailboxcount(), action_mailboxstatus(), action_originate(), action_redirect(), action_sendtext(), 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_response_full(), authenticate(), change_monitor_action(), do_pause_or_unpause(), handle_updates(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_iax2_show_peers(), manager_jabber_send(), manager_park(), manager_parking_status(), manager_show_dialplan(), manager_sip_show_device(), manager_sip_show_devices(), manager_sip_show_peer(), manager_sip_show_peers(), process_message(), start_monitor_action(), and stop_monitor_action().

00673 {
00674    int x, l = strlen(var);
00675 
00676    for (x = 0; x < m->hdrcount; x++) {
00677       const char *h = m->headers[x];
00678       if (!strncasecmp(var, h, l) && h[l] == ':' && h[l+1] == ' ')
00679          return h + l + 2;
00680    }
00681 
00682    return "";
00683 }

struct ast_variable* astman_get_variables const struct message m  ) 
 

Get a linked list of the Variable: headers

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

00686 {
00687    int varlen, x, y;
00688    struct ast_variable *head = NULL, *cur;
00689 
00690    AST_DECLARE_APP_ARGS(args,
00691       AST_APP_ARG(vars)[32];
00692    );
00693 
00694    varlen = strlen("Variable: ");
00695 
00696    for (x = 0; x < m->hdrcount; x++) {
00697       char *parse, *var, *val;
00698 
00699       if (strncasecmp("Variable: ", m->headers[x], varlen))
00700          continue;
00701       parse = ast_strdupa(m->headers[x] + varlen);
00702 
00703       AST_STANDARD_APP_ARGS(args, parse);
00704       if (!args.argc)
00705          continue;
00706       for (y = 0; y < args.argc; y++) {
00707          if (!args.vars[y])
00708             continue;
00709          var = val = ast_strdupa(args.vars[y]);
00710          strsep(&val, "=");
00711          if (!val || ast_strlen_zero(var))
00712             continue;
00713          cur = ast_variable_new(var, val);
00714          cur->next = head;
00715          head = cur;
00716       }
00717    }
00718 
00719    return head;
00720 }

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

Definition at line 823 of file manager.c.

References astman_send_response_full(), and s.

Referenced by action_agent_logoff(), action_agents(), action_hangup(), action_login(), action_originate(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), action_zapshowchannels(), change_monitor_action(), do_pause_or_unpause(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_park(), manager_parking_status(), manager_sip_show_devices(), start_monitor_action(), and stop_monitor_action().

00824 {
00825    astman_send_response_full(s, m, "Success", msg, NULL);
00826 }

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

Send error in manager transaction

Definition at line 818 of file manager.c.

References astman_send_response_full(), and s.

Referenced by _sip_show_device(), _sip_show_peer(), action_agent_logoff(), action_challenge(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_originate(), action_redirect(), action_sendtext(), 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_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_park(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_sip_show_device(), manager_sip_show_peer(), process_message(), start_monitor_action(), and stop_monitor_action().

00819 {
00820    astman_send_response_full(s, m, "Error", error, NULL);
00821 }

void astman_send_listack struct mansession s,
const struct message m,
char *  msg,
char *  listflag
 

Definition at line 833 of file manager.c.

References astman_send_response_full(), and s.

Referenced by manager_dpsendack(), and manager_sip_show_peers().

00834 {
00835    astman_send_response_full(s, m, "Success", msg, listflag);
00836 }

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

Definition at line 813 of file manager.c.

References astman_send_response_full(), and s.

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

00814 {
00815    astman_send_response_full(s, m, resp, msg, NULL);
00816 }

static void astman_send_response_full struct mansession s,
const struct message m,
char *  resp,
char *  msg,
char *  listflag
[static]
 

Definition at line 796 of file manager.c.

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

Referenced by astman_send_ack(), astman_send_error(), astman_send_listack(), astman_send_response(), and astman_start_ack().

00797 {
00798    const char *id = astman_get_header(m,"ActionID");
00799 
00800    astman_append(s, "Response: %s\r\n", resp);
00801    if (!ast_strlen_zero(id))
00802       astman_append(s, "ActionID: %s\r\n", id);
00803    if (listflag)
00804       astman_append(s, "Eventlist: %s\r\n", listflag);   /* Start, complete, cancelled */
00805    if (msg == MSG_MOREDATA)
00806       return;
00807    else if (msg)
00808       astman_append(s, "Message: %s\r\n\r\n", msg);
00809    else
00810       astman_append(s, "\r\n");
00811 }

static void astman_start_ack struct mansession s,
const struct message m
[static]
 

Definition at line 828 of file manager.c.

References astman_send_response_full(), MSG_MOREDATA, and s.

Referenced by action_challenge(), action_extensionstate(), action_getconfig(), action_getvar(), action_listcommands(), action_mailboxcount(), and action_mailboxstatus().

00829 {
00830    astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL);
00831 }

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

Definition at line 862 of file manager.c.

References ast_append_ha(), ast_category_browse(), ast_config_load(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_variable_browse(), astman_get_header(), error(), get_perm(), ast_variable::lineno, LOG_WARNING, ast_variable::name, ast_variable::next, s, and ast_variable::value.

Referenced by action_login(), authenticate_reply(), and registry_rerequest().

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

static char* authority_to_str int  authority,
struct ast_str **  res
[static]
 

Convert authority code to a list of options.

Definition at line 299 of file manager.c.

References ast_str_append(), and perms.

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

00300 {
00301    int i;
00302    char *sep = "";
00303 
00304    (*res)->used = 0;
00305    for (i = 0; i < (sizeof(perms) / sizeof(perms[0])) - 1; i++) {
00306       if (authority & perms[i].num) {
00307          ast_str_append(res, 0, "%s%s", sep, perms[i].label);
00308          sep = ",";
00309       }
00310    }
00311 
00312    if ((*res)->used == 0)  /* replace empty string with something sensible */
00313       ast_str_append(res, 0, "<none>");
00314 
00315    return (*res)->str;
00316 }

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

Definition at line 382 of file manager.c.

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

00383 {
00384    struct manager_action *cur;
00385    int l = strlen(word), which = 0;
00386    char *ret = NULL;
00387 
00388    ast_rwlock_rdlock(&actionlock);
00389    for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */
00390       if (!strncasecmp(word, cur->action, l) && ++which > state) {
00391          ret = ast_strdup(cur->action);
00392          break;   /* make sure we exit even if ast_strdup() returns NULL */
00393       }
00394    }
00395    ast_rwlock_unlock(&actionlock);
00396 
00397    return ret;
00398 }

static void destroy_session struct mansession s  )  [static]
 

Definition at line 662 of file manager.c.

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

Referenced by accept_thread().

00663 {
00664    AST_LIST_LOCK(&sessions);
00665    AST_LIST_REMOVE(&sessions, s, list);
00666    AST_LIST_UNLOCK(&sessions);
00667 
00668    ast_atomic_fetchadd_int(&num_sessions, -1);
00669    free_session(s);
00670 }

static int do_message struct mansession s  )  [static]
 

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

02175 {
02176    struct message m = { 0 };
02177    char header_buf[sizeof(s->inbuf)] = { '\0' };
02178    int res;
02179 
02180    for (;;) {
02181       /* Check if any events are pending and do them if needed */
02182       if (process_events(s))
02183          return -1;
02184       res = get_input(s, header_buf);
02185       if (res == 0) {
02186          continue;
02187       } else if (res > 0) {
02188          if (ast_strlen_zero(header_buf))
02189             return process_message(s, &m) ? -1 : 0;
02190          else if (m.hdrcount < (AST_MAX_MANHEADERS - 1))
02191             m.headers[m.hdrcount++] = ast_strdupa(header_buf);
02192       } else {
02193          return res;
02194       }
02195    }
02196 }

static void* fast_originate void *  data  )  [static]
 

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

01697 {
01698    struct fast_originate_helper *in = data;
01699    int res;
01700    int reason = 0;
01701    struct ast_channel *chan = NULL;
01702    char requested_channel[AST_CHANNEL_NAME];
01703 
01704    if (!ast_strlen_zero(in->app)) {
01705       res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1,
01706          S_OR(in->cid_num, NULL),
01707          S_OR(in->cid_name, NULL),
01708          in->vars, in->account, &chan);
01709    } else {
01710       res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1,
01711          S_OR(in->cid_num, NULL),
01712          S_OR(in->cid_name, NULL),
01713          in->vars, in->account, &chan);
01714    }
01715 
01716    if (!chan)
01717       snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);   
01718    /* Tell the manager what happened with the channel */
01719    manager_event(EVENT_FLAG_CALL, "OriginateResponse",
01720       "%s"
01721       "Response: %s\r\n"
01722       "Channel: %s\r\n"
01723       "Context: %s\r\n"
01724       "Exten: %s\r\n"
01725       "Reason: %d\r\n"
01726       "Uniqueid: %s\r\n"
01727       "CallerIDNum: %s\r\n"
01728       "CallerIDName: %s\r\n",
01729       in->idtext, res ? "Failure" : "Success", chan ? chan->name : requested_channel, in->context, in->exten, reason, 
01730       chan ? chan->uniqueid : "<null>",
01731       S_OR(in->cid_num, "<unknown>"),
01732       S_OR(in->cid_name, "<unknown>")
01733       );
01734 
01735    /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
01736    if (chan)
01737       ast_channel_unlock(chan);
01738    free(in);
01739    return NULL;
01740 }

static void free_session struct mansession s  )  [static]
 

Definition at line 652 of file manager.c.

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

Referenced by destroy_session(), and purge_sessions().

00653 {
00654    struct eventqent *eqe = s->last_ev;
00655    if (s->f != NULL)
00656       fclose(s->f);
00657    ast_mutex_destroy(&s->__lock);
00658    free(s);
00659    unref_event(eqe);
00660 }

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

Read one full line (including crlf) from the manager socket.
is the only valid terminator for the line. (Note that, later, '' will be considered as the end-of-line marker, so everything between the '' and the '
' will not be used). Also note that we assume output to have at least "maxlen" space.

Definition at line 2109 of file manager.c.

References s.

Referenced by do_message(), and skinny_session().

02110 {
02111    int res, x;
02112    int maxlen = sizeof(s->inbuf) - 1;
02113    char *src = s->inbuf;
02114 
02115    /*
02116     * Look for \r\n within the buffer. If found, copy to the output
02117     * buffer and return, trimming the \r\n (not used afterwards).
02118     */
02119    for (x = 0; x < s->inlen; x++) {
02120       int cr;  /* set if we have \r */
02121       if (src[x] == '\r' && x+1 < s->inlen && src[x+1] == '\n')
02122          cr = 2;  /* Found. Update length to include \r\n */
02123       else if (src[x] == '\n')
02124          cr = 1;  /* also accept \n only */
02125       else
02126          continue;
02127       memmove(output, src, x);   /*... but trim \r\n */
02128       output[x] = '\0';    /* terminate the string */
02129       x += cr;       /* number of bytes used */
02130       s->inlen -= x;       /* remaining size */
02131       memmove(src, src + x, s->inlen); /* remove used bytes */
02132       return 1;
02133    }
02134    if (s->inlen >= maxlen) {
02135       /* no crlf found, and buffer full - sorry, too long for us */
02136       ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->sin.sin_addr), src);
02137       s->inlen = 0;
02138    }
02139    res = 0;
02140    while (res == 0) {
02141       /* XXX do we really need this locking ? */
02142       ast_mutex_lock(&s->__lock);
02143       s->waiting_thread = pthread_self();
02144       ast_mutex_unlock(&s->__lock);
02145 
02146       res = ast_wait_for_input(s->fd, -1);   /* return 0 on timeout ? */
02147 
02148       ast_mutex_lock(&s->__lock);
02149       s->waiting_thread = AST_PTHREADT_NULL;
02150       ast_mutex_unlock(&s->__lock);
02151    }
02152    if (res < 0) {
02153       /* If we get a signal from some other thread (typically because
02154        * there are new events queued), return 0 to notify the caller.
02155        */
02156       if (errno == EINTR)
02157          return 0;
02158       ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
02159       return -1;
02160    }
02161    ast_mutex_lock(&s->__lock);
02162    res = fread(src + s->inlen, 1, maxlen - s->inlen, s->f);
02163    if (res < 1)
02164       res = -1;   /* error return */
02165    else {
02166       s->inlen += res;
02167       src[s->inlen] = '\0';
02168       res = 0;
02169    }
02170    ast_mutex_unlock(&s->__lock);
02171    return res;
02172 }

static struct ast_manager_user* get_manager_by_name_locked const char *  name  )  [static]
 

lookup an entry in the list of registered users. must be called with the list lock held.

Definition at line 404 of file manager.c.

References AST_LIST_TRAVERSE, and ast_manager_user::username.

Referenced by handle_showmanager().

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

static int get_perm const char *  instr  )  [static]
 

Definition at line 340 of file manager.c.

References ast_instring(), and perms.

Referenced by authenticate().

00341 {
00342    int x = 0, ret = 0;
00343 
00344    if (!instr)
00345       return 0;
00346 
00347    for (x = 0; x < (sizeof(perms) / sizeof(perms[0])); x++) {
00348       if (ast_instring(instr, perms[x].label, ','))
00349          ret |= perms[x].num;
00350    }
00351 
00352    return ret;
00353 }

static struct eventqent* grab_last void   )  [static]
 

Event list management functions. We assume that the event list always has at least one element, and the delete code will not remove the last entry even if the.

Grab a reference to the last event, update usecount as needed. Can handle a NULL pointer.

Definition at line 246 of file manager.c.

References AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_UNLOCK, and eventqent::usecount.

Referenced by session_do().

00247 {
00248    struct eventqent *ret;
00249 
00250    AST_LIST_LOCK(&all_events);
00251    ret = AST_LIST_LAST(&all_events);
00252    /* the list is never empty now, but may become so when
00253     * we optimize it in the future, so be prepared.
00254     */
00255    if (ret)
00256       ast_atomic_fetchadd_int(&ret->usecount, 1);
00257    AST_LIST_UNLOCK(&all_events);
00258    return ret;
00259 }

static int handle_mandebug int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 438 of file manager.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00439 {
00440    if (argc == 2)
00441       ast_cli(fd, "manager debug is %s\n", manager_debug? "on" : "off");
00442    else if (argc == 3) {
00443       if (!strcasecmp(argv[2], "on"))
00444          manager_debug = 1;
00445       else if (!strcasecmp(argv[2], "off"))
00446          manager_debug = 0;
00447       else
00448          return RESULT_SHOWUSAGE;
00449    }
00450    return RESULT_SUCCESS;
00451 }

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

Definition at line 453 of file manager.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_manager_user::deny, ast_manager_user::displayconnects, get_manager_by_name_locked(), 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.

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

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

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

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

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

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

00416 {
00417    struct manager_action *cur;
00418    struct ast_str *authority = ast_str_alloca(80);
00419    int num;
00420 
00421    if (argc != 4)
00422       return RESULT_SHOWUSAGE;
00423 
00424    for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */
00425       for (num = 3; num < argc; num++) {
00426          if (!strcasecmp(cur->action, argv[num])) {
00427             ast_cli(fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
00428                cur->action, cur->synopsis,
00429                authority_to_str(cur->authority, &authority),
00430                S_OR(cur->description, "") );
00431          }
00432       }
00433    }
00434 
00435    return RESULT_SUCCESS;
00436 }

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

CLI command manager list commands.

Definition at line 525 of file manager.c.

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

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

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

CLI command manager list connected.

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

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

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

CLI command manager list eventq.

Definition at line 560 of file manager.c.

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

00561 {
00562    struct eventqent *s;
00563 
00564    AST_LIST_LOCK(&all_events);
00565    AST_LIST_TRAVERSE(&all_events, s, eq_next) {
00566       ast_cli(fd, "Usecount: %d\n",s->usecount);
00567       ast_cli(fd, "Category: %d\n", s->category);
00568       ast_cli(fd, "Event:\n%s", s->eventdata);
00569    }
00570    AST_LIST_UNLOCK(&all_events);
00571 
00572    return RESULT_SUCCESS;
00573 }

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

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

01052 {
01053    int x;
01054    char hdr[40];
01055    const char *action, *cat, *var, *value, *match;
01056    struct ast_category *category;
01057    struct ast_variable *v;
01058 
01059    for (x=0;x<100000;x++) {
01060       snprintf(hdr, sizeof(hdr), "Action-%06d", x);
01061       action = astman_get_header(m, hdr);
01062       if (ast_strlen_zero(action))
01063          break;
01064       snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
01065       cat = astman_get_header(m, hdr);
01066       snprintf(hdr, sizeof(hdr), "Var-%06d", x);
01067       var = astman_get_header(m, hdr);
01068       snprintf(hdr, sizeof(hdr), "Value-%06d", x);
01069       value = astman_get_header(m, hdr);
01070       snprintf(hdr, sizeof(hdr), "Match-%06d", x);
01071       match = astman_get_header(m, hdr);
01072       if (!strcasecmp(action, "newcat")) {
01073          if (!ast_strlen_zero(cat)) {
01074             category = ast_category_new(cat);
01075             if (category) {
01076                ast_category_append(cfg, category);
01077             }
01078          }
01079       } else if (!strcasecmp(action, "renamecat")) {
01080          if (!ast_strlen_zero(cat) && !ast_strlen_zero(value)) {
01081             category = ast_category_get(cfg, cat);
01082             if (category)
01083                ast_category_rename(category, value);
01084          }
01085       } else if (!strcasecmp(action, "delcat")) {
01086          if (!ast_strlen_zero(cat))
01087             ast_category_delete(cfg, cat);
01088       } else if (!strcasecmp(action, "update")) {
01089          if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat)))
01090             ast_variable_update(category, var, value, match);
01091       } else if (!strcasecmp(action, "delete")) {
01092          if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat)))
01093             ast_variable_delete(category, var, match);
01094       } else if (!strcasecmp(action, "append")) {
01095          if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) &&
01096             (category = ast_category_get(cfg, cat)) &&
01097             (v = ast_variable_new(var, value))){
01098             if (match && !strcasecmp(match, "object"))
01099                v->object = 1;
01100             ast_variable_append(category, v);
01101          }
01102       }
01103    }
01104 }

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

Definition at line 2412 of file manager.c.

References EVENT_FLAG_CALL, and manager_event.

Referenced by init_manager().

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

static int process_events struct mansession s  )  [static]
 

Send any applicable events to the client listening on this socket. Wait only for a finite time on each event, and drop all events whether they are successfully sent or not.

Definition at line 1996 of file manager.c.

References ast_mutex_lock(), ast_mutex_unlock(), NEW_EVENT, ref_event(), s, send_string(), and unref_event().

Referenced by do_message().

01997 {
01998    int ret = 0;
01999 
02000    ast_mutex_lock(&s->__lock);
02001    if (s->f != NULL) {
02002       struct eventqent *eqe;
02003 
02004       while ( (eqe = NEW_EVENT(s)) ) {
02005          ref_event(eqe);
02006          if (!ret && s->authenticated &&
02007              (s->readperm & eqe->category) == eqe->category &&
02008              (s->send_events & eqe->category) == eqe->category) {
02009             if (send_string(s, eqe->eventdata) < 0)
02010                ret = -1;   /* don't send more */
02011          }
02012          s->last_ev = unref_event(s->last_ev);
02013       }
02014    }
02015    ast_mutex_unlock(&s->__lock);
02016    return ret;
02017 }

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

Definition at line 2057 of file manager.c.

References manager_action::action, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rwlock_rdlock(), ast_strlen_zero(), astman_get_header(), astman_send_error(), manager_action::authority, first_action, manager_action::func, LOG_DEBUG, manager_action::next, option_debug, and s.

Referenced by do_message().

02058 {
02059    char action[80] = "";
02060    int ret = 0;
02061    struct manager_action *tmp;
02062 
02063    ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action));
02064    if (option_debug)
02065       ast_log(LOG_DEBUG, "Manager received command '%s'\n", action);
02066 
02067    if (ast_strlen_zero(action)) {
02068       astman_send_error(s, m, "Missing action in request");
02069       return 0;
02070    }
02071 
02072    if (!s->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) {
02073       ast_mutex_lock(&s->__lock);
02074       astman_send_error(s, m, "Permission denied");
02075       ast_mutex_unlock(&s->__lock);
02076       return 0;
02077    }
02078    ast_rwlock_rdlock(&actionlock);  
02079    for (tmp = first_action ; tmp; tmp = tmp->next) {
02080       if (strcasecmp(action, tmp->action))
02081          continue;
02082       if ((s->writeperm & tmp->authority) == tmp->authority) {
02083          if (tmp->func(s, m)) {  /* error */
02084             return -1;
02085          }
02086       } else
02087          astman_send_error(s, m, "Permission denied");
02088       break;
02089    }
02090    ast_rwlock_unlock(&actionlock);
02091    if (!tmp) {
02092       ast_mutex_lock(&s->__lock);
02093       astman_send_error(s, m, "Invalid/unknown command. Use Action: ListCommands to show available commands.");
02094       ast_mutex_unlock(&s->__lock);
02095    }
02096    if (ret)
02097       return ret;
02098    /* Once done with our message, deliver any pending events */
02099    return process_events(s);
02100 }

static void purge_events void   )  [static]
 

Purge unused events. Remove elements from the head as long as their usecount is 0 and there is a next element.

Definition at line 265 of file manager.c.

References AST_LIST_FIRST, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and eventqent::usecount.

Referenced by purge_old_stuff().

00266 {
00267    struct eventqent *ev;
00268 
00269    AST_LIST_LOCK(&all_events);
00270    while ( (ev = AST_LIST_FIRST(&all_events)) &&
00271        ev->usecount == 0 && AST_LIST_NEXT(ev, eq_next)) {
00272       AST_LIST_REMOVE_HEAD(&all_events, eq_next);
00273       free(ev);
00274    }
00275    AST_LIST_UNLOCK(&all_events);
00276 }

static void purge_sessions int  n_max  )  [static]
 

remove at most n_max stale session from the list.

Definition at line 2267 of file manager.c.

References ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free_session(), num_sessions, option_verbose, s, and sessions.

Referenced by purge_old_stuff().

02268 {
02269    struct mansession *s;
02270    time_t now = time(NULL);
02271 
02272    AST_LIST_LOCK(&sessions);
02273    AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) {
02274       if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) {
02275          AST_LIST_REMOVE_CURRENT(&sessions, list);
02276          ast_atomic_fetchadd_int(&num_sessions, -1);
02277          if (s->authenticated && (option_verbose > 1) && displayconnects) {
02278             ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' timed out from %s\n",
02279                s->username, ast_inet_ntoa(s->sin.sin_addr));
02280          }
02281          free_session(s);  /* XXX outside ? */
02282          if (--n_max <= 0)
02283             break;
02284       }
02285    }
02286    AST_LIST_TRAVERSE_SAFE_END
02287    AST_LIST_UNLOCK(&sessions);
02288 }

static void ref_event struct eventqent e  )  [static]
 

Definition at line 644 of file manager.c.

References eventqent::usecount.

Referenced by process_events().

00645 {
00646    ast_atomic_fetchadd_int(&e->usecount, 1);
00647 }

static int send_string struct mansession s,
char *  string
[static]
 

helper function to send a string to the socket. Return -1 on error (e.g. buffer full).

Definition at line 726 of file manager.c.

References pollfd::fd, len, poll(), POLLOUT, and s.

Referenced by astman_append(), and process_events().

00727 {
00728    int len = strlen(string);  /* residual length */
00729    char *src = string;
00730    struct timeval start = ast_tvnow();
00731    int n = 0;
00732 
00733    for (;;) {
00734       int elapsed;
00735       struct pollfd fd;
00736       n = fwrite(src, 1, len, s->f);   /* try to write the string, non blocking */
00737       if (n == len /* ok */ || n < 0 /* error */)
00738          break;
00739       len -= n;   /* skip already written data */
00740       src += n;
00741       fd.fd = s->fd;
00742       fd.events = POLLOUT;
00743       n = -1;     /* error marker */
00744       elapsed = ast_tvdiff_ms(ast_tvnow(), start);
00745       if (elapsed > s->writetimeout)
00746          break;
00747       if (poll(&fd, 1, s->writetimeout - elapsed) < 1)
00748          break;
00749    }
00750    fflush(s->f);
00751    return n < 0 ? -1 : 0;
00752 }

static void* session_do void *  data  )  [static]
 

The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ).

Definition at line 2206 of file manager.c.

References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_mutex_init(), AST_PTHREADT_NULL, astman_append(), block_sockets, do_message(), server_instance::f, server_instance::fd, grab_last(), num_sessions, server_instance::requestor, s, and sessions.

02207 {
02208    struct server_instance *ser = data;
02209    struct mansession *s = ast_calloc(1, sizeof(*s));
02210    int flags;
02211    int res;
02212 
02213    if (s == NULL)
02214       goto done;
02215 
02216    s->writetimeout = 100;
02217    s->waiting_thread = AST_PTHREADT_NULL;
02218 
02219    flags = fcntl(ser->fd, F_GETFL);
02220    if (!block_sockets) /* make sure socket is non-blocking */
02221       flags |= O_NONBLOCK;
02222    else
02223       flags &= ~O_NONBLOCK;
02224    fcntl(ser->fd, F_SETFL, flags);
02225 
02226    ast_mutex_init(&s->__lock);
02227    s->send_events = -1;
02228    /* these fields duplicate those in the 'ser' structure */
02229    s->fd = ser->fd;
02230    s->f = ser->f;
02231    s->sin = ser->requestor;
02232 
02233    ast_atomic_fetchadd_int(&num_sessions, 1);
02234    AST_LIST_LOCK(&sessions);
02235    AST_LIST_INSERT_HEAD(&sessions, s, list);
02236    AST_LIST_UNLOCK(&sessions);
02237    /* Hook to the tail of the event queue */
02238    s->last_ev = grab_last();
02239    s->f = ser->f;
02240    astman_append(s, "Asterisk Call Manager/1.0\r\n"); /* welcome prompt */
02241    for (;;) {
02242       if ((res = do_message(s)) < 0)
02243          break;
02244    }
02245    /* session is over, explain why and terminate */
02246    if (s->authenticated) {
02247       if (option_verbose > 1) {
02248          if (displayconnects)
02249             ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
02250       }
02251       ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
02252    } else {
02253       if (option_verbose > 1) {
02254          if (displayconnects)
02255             ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr));
02256       }
02257       ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr));
02258    }
02259    destroy_session(s);
02260 
02261 done:
02262    free(ser);
02263    return NULL;
02264 }

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

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

Referenced by action_events().

00844 {
00845    int maskint = strings_to_mask(eventmask);
00846 
00847    ast_mutex_lock(&s->__lock);
00848    if (maskint >= 0)
00849       s->send_events = maskint;
00850    ast_mutex_unlock(&s->__lock);
00851 
00852    return maskint;
00853 }

static int strings_to_mask const char *  string  )  [static]
 

A number returns itself, false returns 0, true returns all flags, other strings return the flags that are set.

Definition at line 359 of file manager.c.

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

Referenced by set_eventmask().

00360 {
00361    const char *p;
00362 
00363    if (ast_strlen_zero(string))
00364       return -1;
00365 
00366    for (p = string; *p; p++)
00367       if (*p < '0' || *p > '9')
00368          break;
00369    if (!p)  /* all digits */
00370       return atoi(string);
00371    if (ast_false(string))
00372       return 0;
00373    if (ast_true(string)) { /* all permissions */
00374       int x, ret = 0;
00375       for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++)
00376          ret |= perms[x].num;
00377       return ret;
00378    }
00379    return get_perm(string);
00380 }

static struct eventqent* unref_event struct eventqent e  )  [static]
 

Definition at line 638 of file manager.c.

References AST_LIST_NEXT, and eventqent::usecount.

Referenced by free_session(), and process_events().

00639 {
00640    ast_atomic_fetchadd_int(&e->usecount, -1);
00641    return AST_LIST_NEXT(e, eq_next);
00642 }


Variable Documentation

int block_sockets [static]
 

Definition at line 113 of file manager.c.

Referenced by session_do().

struct ast_cli_entry cli_manager[] [static]
 

Definition at line 602 of file manager.c.

Referenced by init_manager().

int displayconnects = 1 [static]
 

Definition at line 109 of file manager.c.

Referenced by action_login().

struct manager_action* first_action [static]
 

list of actions registered

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

int manager_debug [static]
 

enable some debugging code in the manager

Definition at line 116 of file manager.c.

Referenced by __manager_event().

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

Referenced by init_manager().

char mandescr_events[] [static]
 

Definition at line 1276 of file manager.c.

Referenced by init_manager().

char mandescr_extensionstate[] [static]
 

Definition at line 1924 of file manager.c.

Referenced by init_manager().

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

Referenced by init_manager().

char mandescr_getvar[] [static]
 

Definition at line 1409 of file manager.c.

Referenced by init_manager().

char mandescr_hangup[] [static]
 

Initial value:

"Description: Hangup a channel\n"
"Variables: \n"
"  Channel: The channel name to be hungup\n"

Definition at line 1343 of file manager.c.

Referenced by init_manager().

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

Referenced by init_manager().

char mandescr_logoff[] [static]
 

Initial value:

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

Definition at line 1298 of file manager.c.

Referenced by init_manager().

char mandescr_mailboxcount[] [static]
 

Definition at line 1893 of file manager.c.

Referenced by init_manager().

char mandescr_mailboxstatus[] [static]
 

Help text for manager command mailboxstatus.

Definition at line 1865 of file manager.c.

Referenced by init_manager().

char mandescr_originate[] [static]
 

Definition at line 1742 of file manager.c.

Referenced by init_manager().

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

Referenced by init_manager().

char mandescr_redirect[] [static]
 

Definition at line 1582 of file manager.c.

Referenced by init_manager().

char mandescr_sendtext[] [static]
 

Definition at line 1541 of file manager.c.

Referenced by init_manager().

char mandescr_setvar[] [static]
 

Definition at line 1367 of file manager.c.

Referenced by init_manager().

char mandescr_timeout[] [static]
 

Definition at line 1959 of file manager.c.

Referenced by init_manager().

char mandescr_updateconfig[] [static]
 

Definition at line 1106 of file manager.c.

Referenced by init_manager().

char mandescr_userevent[] [static]
 

Definition at line 2019 of file manager.c.

Referenced by init_manager().

char mandescr_waitevent[] [static]
 

Manager WAITEVENT.

Definition at line 1152 of file manager.c.

Referenced by init_manager().

int num_sessions [static]
 

Definition at line 114 of file manager.c.

Referenced by __manager_event(), purge_sessions(), and session_do().

struct permalias perms[] [static]
 

helper functions to convert back and forth between string and numeric representation of set of flags

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

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 598 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 593 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 575 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 579 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 583 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 588 of file manager.c.

int timestampevents [static]
 

Definition at line 110 of file manager.c.

Referenced by __manager_event().


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen