Thu Apr 28 2011 16:57:19

Asterisk developer's documentation


AMI functions

callback to display queues status in manager More...

Data Structures

struct  actions
 list of actions registered More...
struct  all_events
struct  ast_manager_user
 user descriptor, as read from the config file. More...
struct  eventqent
struct  fast_originate_helper
 helper function for originate More...
struct  manager_hooks
 list of hooks registered More...
struct  mansession
struct  mansession_session
struct  permalias
struct  sessions
struct  users
 list of users found in the config file More...

Defines

#define ASTMAN_APPEND_BUF_INITSIZE   256
 initial allocated size for the astman_append_buf
#define GET_HEADER_FIRST_MATCH   0
#define GET_HEADER_LAST_MATCH   1
#define GET_HEADER_SKIP_EMPTY   2
#define MANAGER_EVENT_BUF_INITSIZE   256
#define MAX_BLACKLIST_CMD_LEN   2
 Descriptor for a manager session, either on the AMI socket or over HTTP.
#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.

Enumerations

enum  error_type {
  UNKNOWN_ACTION = 1, UNKNOWN_CATEGORY, UNSPECIFIED_CATEGORY, UNSPECIFIED_ARGUMENT,
  FAILURE_ALLOCATION, FAILURE_NEWCAT, FAILURE_DELCAT, FAILURE_EMPTYCAT,
  FAILURE_UPDATE, FAILURE_DELETE, FAILURE_APPEND
}

Functions

static const char * __astman_get_header (const struct message *m, char *var, int mode)
static void __fini_actions (void)
static void __fini_all_events (void)
static void __fini_manager_hooks (void)
static void __fini_users (void)
static void __init_actions (void)
static void __init_all_events (void)
static void __init_manager_hooks (void)
static void __init_users (void)
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_atxfer (struct mansession *s, const struct message *m)
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_coresettings (struct mansession *s, const struct message *m)
 Show PBX core settings information.
static int action_coreshowchannels (struct mansession *s, const struct message *m)
 Manager command "CoreShowChannels" - List currently defined channels and some information about them.
static int action_corestatus (struct mansession *s, const struct message *m)
 Show PBX core status information.
static int action_createconfig (struct mansession *s, const struct message *m)
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_getconfigjson (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_listcategories (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_reload (struct mansession *s, const struct message *m)
 Send a reload event.
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 struct eventqentadvance_event (struct eventqent *e)
static int append_event (const char *str, int category)
static int ast_instring (const char *bigstr, const char *smallstr, const char delim)
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)
 Unregister a registered manager command.
void ast_manager_unregister_hook (struct manager_custom_hook *hook)
 Delete a custom hook to be called when an event is fired.
 AST_THREADSTORAGE_CUSTOM_SCOPE (astman_append_buf, NULL, ast_free_ptr, static)
 thread local buffer for astman_append
 AST_THREADSTORAGE_CUSTOM_SCOPE (userevent_buf, NULL, ast_free_ptr, static)
 AST_THREADSTORAGE_CUSTOM_SCOPE (manager_event_buf, NULL, ast_free_ptr, static)
void astman_append (struct mansession *s, const char *fmt,...)
const char * astman_get_header (const struct message *m, char *var)
 Get header from mananger transaction.
struct ast_variableastman_get_variables (const struct message *m)
 Get a linked list of the Variable: headers.
void astman_send_ack (struct mansession *s, const struct message *m, char *msg)
 Send ack in manager transaction.
void astman_send_error (struct mansession *s, const struct message *m, char *error)
 Send error in manager transaction.
void astman_send_listack (struct mansession *s, const struct message *m, char *msg, char *listflag)
 Send ack in manager list transaction.
void astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg)
 Send response in manager transaction.
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 int check_blacklist (const char *cmd)
int check_manager_enabled ()
 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 check_manager_session_inuse (const char *name)
int check_webmanager_enabled ()
 Check if AMI/HTTP is enabled.
static void destroy_session (struct mansession_session *session)
static int do_message (struct mansession *s)
static void * fast_originate (void *data)
static void free_session (struct mansession_session *session)
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)
static char * handle_manager_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager reload.
static char * handle_mandebug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showmanager (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showmanagers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showmancmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_showmancmds (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list commands.
static char * handle_showmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list connected.
static char * handle_showmaneventq (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command manager list eventq.
static enum error_type handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn)
static void json_escape (char *out, const char *in)
static int manager_displayconnects (struct mansession_session *session)
 Get displayconnects config option.
static int manager_modulecheck (struct mansession *s, const struct message *m)
static int manager_moduleload (struct mansession *s, const struct message *m)
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 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)

Variables

static struct actions actions
static struct all_events all_events
static int allowmultiplelogin = 1
static int authlimit
static int authtimeout
static int block_sockets
static int broken_events_action
static struct ast_cli_entry cli_manager []
struct {
   char *   words [AST_MAX_CMD_LEN]
command_blacklist []
static const int DEFAULT_AUTHLIMIT = 50
static const int DEFAULT_AUTHTIMEOUT = 30
static const int DEFAULT_BLOCKSOCKETS = 0
static const int DEFAULT_BROKENEVENTSACTION = 0
static const int DEFAULT_DISPLAYCONNECTS = 1
static const int DEFAULT_ENABLED = 0
static const int DEFAULT_HTTPTIMEOUT = 60
static const int DEFAULT_TIMESTAMPEVENTS = 0
static const int DEFAULT_WEBENABLED = 0
static int displayconnects
static int httptimeout
static int manager_debug
static int manager_enabled = 0
static struct manager_hooks manager_hooks
static char mandescr_atxfer [] = " ActionID: Optional Action id for message matching.\n"
static char mandescr_command [] = " ActionID: Optional Action id for message matching.\n"
static char mandescr_coresettings [] = " *ActionID: ActionID of this transaction\n"
static char mandescr_coreshowchannels [] = " ActionID: Optional Action id for message matching.\n"
static char mandescr_corestatus [] = " *ActionID: ActionID of this transaction\n"
static char mandescr_createconfig [] = " Filename: The configuration filename to create (e.g. foo.conf)\n"
static char mandescr_events [] = " 'system,call,log' to select which flags events should have to be sent.\n"
static char mandescr_extensionstate [] = "The response will include the hint for the extension and the status.\n"
static char mandescr_getconfig [] = " Category: Category in configuration file\n"
static char mandescr_getconfigjson [] = " Filename: Configuration filename (e.g. foo.conf)\n"
static char mandescr_getvar [] = " ActionID: Optional Action id for message matching.\n"
static char mandescr_hangup [] = " Channel: The channel name to be hungup\n"
static char mandescr_listcategories [] = " Filename: Configuration filename (e.g. foo.conf)\n"
static char mandescr_listcommands [] = "Variables: NONE\n"
static char mandescr_logoff [] = "Variables: NONE\n"
static char mandescr_mailboxcount [] = "\n"
static char mandescr_mailboxstatus [] = "\n"
 Help text for manager command mailboxstatus.
static char mandescr_modulecheck [] = "For success returns, the module revision number is included.\n"
static char mandescr_moduleload [] = " If no module is specified for a reload loadtype, all modules are reloaded"
static char mandescr_originate [] = " Async: Set to 'true' for fast origination\n"
static char mandescr_ping [] = "Variables: NONE\n"
 Manager PING.
static char mandescr_redirect [] = " ActionID: Optional Action id for message matching.\n"
static char mandescr_reload [] = " *Module: Name of the module to reload\n"
static char mandescr_sendtext [] = " ActionID: Optional Action id for message matching.\n"
static char mandescr_setvar [] = " *Value: Value\n"
static char mandescr_status [] = "value for the specified channel variables.\n"
static char mandescr_timeout [] = "Acknowledges set time with 'Timeout Set' message\n"
static char mandescr_updateconfig [] = " Line-XXXXXX: Line in category to operate on (used with delete and insert actions)\n"
static char mandescr_userevent [] = " HeaderN: ContentN\n"
static char mandescr_waitevent [] = " Timeout: Maximum time (in seconds) to wait for events, -1 means forever.\n"
 Manager WAITEVENT.
static int num_sessions
static struct permalias perms []
static struct sessions sessions
static int timestampevents
static int unauth_sessions = 0
static struct users users
static int webmanager_enabled = 0

Detailed Description

callback to display queues status in manager

callback to display list of locally configured nodes


Define Documentation

#define ASTMAN_APPEND_BUF_INITSIZE   256

initial allocated size for the astman_append_buf

Definition at line 991 of file manager.c.

Referenced by astman_append().

#define GET_HEADER_FIRST_MATCH   0

Definition at line 894 of file manager.c.

Referenced by astman_get_header().

#define GET_HEADER_LAST_MATCH   1

Definition at line 895 of file manager.c.

Referenced by __astman_get_header().

#define GET_HEADER_SKIP_EMPTY   2

Definition at line 896 of file manager.c.

Referenced by __astman_get_header(), and process_message().

#define MANAGER_EVENT_BUF_INITSIZE   256

Definition at line 3407 of file manager.c.

Referenced by __manager_event().

#define MAX_BLACKLIST_CMD_LEN   2

Descriptor for a manager session, either on the AMI socket or over HTTP.

Note:
AMI session have managerid == 0; the entry is created upon a connect, and destroyed with the socket. HTTP sessions have managerid != 0, the value is used as a search key to lookup sessions (using the mansession_id cookie).

Definition at line 158 of file manager.c.

Referenced by check_blacklist().

#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.

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

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

Definition at line 1031 of file manager.c.

Referenced by astman_send_response_full(), and astman_start_ack().


Enumeration Type Documentation

enum error_type

Doxygen group

Enumerator:
UNKNOWN_ACTION 
UNKNOWN_CATEGORY 
UNSPECIFIED_CATEGORY 
UNSPECIFIED_ARGUMENT 
FAILURE_ALLOCATION 
FAILURE_NEWCAT 
FAILURE_DELCAT 
FAILURE_EMPTYCAT 
FAILURE_UPDATE 
FAILURE_DELETE 
FAILURE_APPEND 

Definition at line 78 of file manager.c.


Function Documentation

static const char* __astman_get_header ( const struct message m,
char *  var,
int  mode 
) [static]

Definition at line 897 of file manager.c.

References ast_strlen_zero(), GET_HEADER_LAST_MATCH, GET_HEADER_SKIP_EMPTY, message::hdrcount, and message::headers.

Referenced by astman_get_header(), and process_message().

{
   int x, l = strlen(var);
   const char *result = "";

   for (x = 0; x < m->hdrcount; x++) {
      const char *h = m->headers[x];
      if (!strncasecmp(var, h, l) && h[l] == ':' && h[l+1] == ' ') {
         const char *value = h + l + 2;
         /* found a potential candidate */
         if (mode & GET_HEADER_SKIP_EMPTY && ast_strlen_zero(value))
            continue;   /* not interesting */
         if (mode & GET_HEADER_LAST_MATCH)
            result = value;   /* record the last match so far */
         else
            return value;
      }
   }

   return "";
}
static void __fini_actions ( void  ) [static]

Definition at line 263 of file manager.c.

{
static void __fini_all_events ( void  ) [static]

Definition at line 121 of file manager.c.

{
static void __fini_manager_hooks ( void  ) [static]

Definition at line 266 of file manager.c.

{
static void __fini_users ( void  ) [static]

Definition at line 260 of file manager.c.

{
static void __init_actions ( void  ) [static]

Definition at line 263 of file manager.c.

{
static void __init_all_events ( void  ) [static]

Definition at line 121 of file manager.c.

{
static void __init_manager_hooks ( void  ) [static]

Definition at line 266 of file manager.c.

{
static void __init_users ( void  ) [static]

Definition at line 260 of file manager.c.

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

References mansession_session::__lock, append_event(), ast_atomic_fetchadd_int(), 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(), ast_str_buffer(), ast_str_set(), ast_str_thread_get(), ast_tvnow(), authority_to_str(), buf, manager_custom_hook::helper, MANAGER_EVENT_BUF_INITSIZE, mansession_session::pending_event, eventqent::seq, and mansession_session::waiting_thread.

{
   struct mansession_session *session;
   struct manager_custom_hook *hook;
   struct ast_str *auth = ast_str_alloca(80);
   const char *cat_str;
   va_list ap;
   struct timeval now;
   struct ast_str *buf;

   /* Abort if there are neither any manager sessions nor hooks */
   if (!num_sessions && AST_RWLIST_EMPTY(&manager_hooks))
      return 0;

   if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE)))
      return -1;

   cat_str = authority_to_str(category, &auth);
   ast_str_set(&buf, 0,
         "Event: %s\r\nPrivilege: %s\r\n",
          event, cat_str);

   if (timestampevents) {
      now = ast_tvnow();
      ast_str_append(&buf, 0,
            "Timestamp: %ld.%06lu\r\n",
             (long)now.tv_sec, (unsigned long) now.tv_usec);
   }
   if (manager_debug) {
      static int seq;
      ast_str_append(&buf, 0,
            "SequenceNumber: %d\r\n",
             ast_atomic_fetchadd_int(&seq, 1));
      ast_str_append(&buf, 0,
            "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func);
   }

   va_start(ap, fmt);
   ast_str_append_va(&buf, 0, fmt, ap);
   va_end(ap);

   ast_str_append(&buf, 0, "\r\n");

   append_event(ast_str_buffer(buf), category);

   if (num_sessions) {
      /* Wake up any sleeping sessions */
      AST_LIST_LOCK(&sessions);
      AST_LIST_TRAVERSE(&sessions, session, list) {
         ast_mutex_lock(&session->__lock);
         if (session->waiting_thread != AST_PTHREADT_NULL)
            pthread_kill(session->waiting_thread, SIGURG);
         else
            /* We have an event to process, but the mansession is
             * not waiting for it. We still need to indicate that there
             * is an event waiting so that get_input processes the pending
             * event instead of polling.
             */
            session->pending_event = 1;
         ast_mutex_unlock(&session->__lock);
      }
      AST_LIST_UNLOCK(&sessions);
   }

   if (!AST_RWLIST_EMPTY(&manager_hooks)) {
      AST_RWLIST_RDLOCK(&manager_hooks);
      AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
         hook->helper(category, event, ast_str_buffer(buf));
      }
      AST_RWLIST_UNLOCK(&manager_hooks);
   }

   return 0;
}
static int action_atxfer ( struct mansession s,
const struct message m 
) [static]

Definition at line 2221 of file manager.c.

References ast_channel_unlock, ast_find_call_feature(), AST_FRAME_DTMF, ast_get_channel_by_name_locked(), ast_queue_frame(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), chan, context, ast_call_feature::exten, exten, name, and pbx_builtin_setvar_helper().

Referenced by __init_manager().

{
   const char *name = astman_get_header(m, "Channel");
   const char *exten = astman_get_header(m, "Exten");
   const char *context = astman_get_header(m, "Context");
   struct ast_channel *chan = NULL;
   struct ast_call_feature *atxfer_feature = NULL;
   char *feature_code = NULL;

   if (ast_strlen_zero(name)) { 
      astman_send_error(s, m, "No channel specified");
      return 0;
   }
   if (ast_strlen_zero(exten)) {
      astman_send_error(s, m, "No extension specified");
      return 0;
   }

   if (!(atxfer_feature = ast_find_call_feature("atxfer"))) {
      astman_send_error(s, m, "No attended transfer feature found");
      return 0;
   }

   if (!(chan = ast_get_channel_by_name_locked(name))) {
      astman_send_error(s, m, "Channel specified does not exist");
      return 0;
   }

   if (!ast_strlen_zero(context)) {
      pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context);
   }

   for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) {
      struct ast_frame f = {AST_FRAME_DTMF, *feature_code};
      ast_queue_frame(chan, &f);
   }

   for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) {
      struct ast_frame f = {AST_FRAME_DTMF, *feature_code};
      ast_queue_frame(chan, &f);
   }

   astman_send_ack(s, m, "Atxfer successfully queued");
   ast_channel_unlock(chan);

   return 0;
}
static int action_challenge ( struct mansession s,
const struct message m 
) [static]

Definition at line 1807 of file manager.c.

References mansession_session::__lock, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), mansession_session::challenge, and mansession::session.

Referenced by __init_manager().

{
   const char *authtype = astman_get_header(m, "AuthType");

   if (!strcasecmp(authtype, "MD5")) {
      if (ast_strlen_zero(s->session->challenge))
         snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random());
      ast_mutex_lock(&s->session->__lock);
      astman_start_ack(s, m);
      astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge);
      ast_mutex_unlock(&s->session->__lock);
   } else {
      astman_send_error(s, m, "Must specify AuthType");
   }
   return 0;
}
static int action_command ( struct mansession s,
const struct message m 
) [static]

Manager command "command" - execute CLI command.

Definition at line 2311 of file manager.c.

References ast_calloc, ast_cli_command, ast_free, ast_log(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), buf, check_blacklist(), errno, LOG_WARNING, S_OR, and term_strip().

Referenced by __init_manager().

{
   const char *cmd = astman_get_header(m, "Command");
   const char *id = astman_get_header(m, "ActionID");
   char *buf, *final_buf;
   char template[] = "/tmp/ast-ami-XXXXXX";  /* template for temporary file */
   int fd;
   off_t l;

   if (ast_strlen_zero(cmd)) {
      astman_send_error(s, m, "No command provided");
      return 0;
   }

   if (check_blacklist(cmd)) {
      astman_send_error(s, m, "Command blacklisted");
      return 0;
   }

   fd = mkstemp(template);

   astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
   if (!ast_strlen_zero(id))
      astman_append(s, "ActionID: %s\r\n", id);
   /* FIXME: Wedge a ActionID response in here, waiting for later changes */
   ast_cli_command(fd, cmd);  /* XXX need to change this to use a FILE * */
   l = lseek(fd, 0, SEEK_END);   /* how many chars available */

   /* This has a potential to overflow the stack.  Hence, use the heap. */
   buf = ast_calloc(1, l + 1);
   final_buf = ast_calloc(1, l + 1);
   if (buf) {
      lseek(fd, 0, SEEK_SET);
      if (read(fd, buf, l) < 0) {
         ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
      }
      buf[l] = '\0';
      if (final_buf) {
         term_strip(final_buf, buf, l);
         final_buf[l] = '\0';
      }
      astman_append(s, "%s", S_OR(final_buf, buf));
      ast_free(buf);
   }
   close(fd);
   unlink(template);
   astman_append(s, "--END COMMAND--\r\n\r\n");
   if (final_buf)
      ast_free(final_buf);
   return 0;
}
static int action_coresettings ( struct mansession s,
const struct message m 
) [static]

Show PBX core settings information.

Definition at line 2772 of file manager.c.

References AMI_VERSION, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SYSTEM_NAME, ast_get_version(), ast_realtime_enabled(), ast_strlen_zero(), astman_append(), astman_get_header(), check_cdr_enabled(), check_webmanager_enabled(), option_maxcalls, option_maxfiles, and option_maxload.

Referenced by __init_manager().

{
   const char *actionid = astman_get_header(m, "ActionID");
   char idText[150];

   if (!ast_strlen_zero(actionid))
      snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
   else
      idText[0] = '\0';

   astman_append(s, "Response: Success\r\n"
         "%s"
         "AMIversion: %s\r\n"
         "AsteriskVersion: %s\r\n"
         "SystemName: %s\r\n"
         "CoreMaxCalls: %d\r\n"
         "CoreMaxLoadAvg: %f\r\n"
         "CoreRunUser: %s\r\n"
         "CoreRunGroup: %s\r\n"
         "CoreMaxFilehandles: %d\r\n" 
         "CoreRealTimeEnabled: %s\r\n"
         "CoreCDRenabled: %s\r\n"
         "CoreHTTPenabled: %s\r\n"
         "\r\n",
         idText,
         AMI_VERSION,
         ast_get_version(), 
         ast_config_AST_SYSTEM_NAME,
         option_maxcalls,
         option_maxload,
         ast_config_AST_RUN_USER,
         ast_config_AST_RUN_GROUP,
         option_maxfiles,
         ast_realtime_enabled() ? "Yes" : "No",
         check_cdr_enabled() ? "Yes" : "No",
         check_webmanager_enabled() ? "Yes" : "No"
         );
   return 0;
}
static int action_coreshowchannels ( struct mansession s,
const struct message m 
) [static]

Manager command "CoreShowChannels" - List currently defined channels and some information about them.

Definition at line 2877 of file manager.c.

References ast_channel::_state, ast_channel::accountcode, ast_channel::appl, ast_bridged_channel(), ast_channel_unlock, ast_channel_walk_locked(), ast_state2str(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), astman_append(), astman_get_header(), astman_send_listack(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::data, ast_channel::exten, ast_channel::name, ast_channel::priority, S_OR, ast_cdr::start, and ast_channel::uniqueid.

Referenced by __init_manager().

{
   const char *actionid = astman_get_header(m, "ActionID");
   char idText[256];
   struct ast_channel *c = NULL;
   int numchans = 0;
   int duration, durh, durm, durs;

   if (!ast_strlen_zero(actionid))
      snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
   else
      idText[0] = '\0';

   astman_send_listack(s, m, "Channels will follow", "start"); 

   while ((c = ast_channel_walk_locked(c)) != NULL) {
      struct ast_channel *bc = ast_bridged_channel(c);
      char durbuf[10] = "";

      if (c->cdr && !ast_tvzero(c->cdr->start)) {
         duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
         durh = duration / 3600;
         durm = (duration % 3600) / 60;
         durs = duration % 60;
         snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
      }

      astman_append(s,
         "Event: CoreShowChannel\r\n"
         "%s"
         "Channel: %s\r\n"
         "UniqueID: %s\r\n"
         "Context: %s\r\n"
         "Extension: %s\r\n"
         "Priority: %d\r\n"
         "ChannelState: %d\r\n"
         "ChannelStateDesc: %s\r\n"
         "Application: %s\r\n"
         "ApplicationData: %s\r\n"
         "CallerIDnum: %s\r\n"
         "Duration: %s\r\n"
         "AccountCode: %s\r\n"
         "BridgedChannel: %s\r\n"
         "BridgedUniqueID: %s\r\n"
         "\r\n", idText, c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state,
         ast_state2str(c->_state), c->appl ? c->appl : "", c->data ? S_OR(c->data, "") : "",
         S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : "");
      ast_channel_unlock(c);
      numchans++;
   }

   astman_append(s,
      "Event: CoreShowChannelsComplete\r\n"
      "EventList: Complete\r\n"
      "ListItems: %d\r\n"
      "%s"
      "\r\n", numchans, idText);

   return 0;
}
static int action_corestatus ( struct mansession s,
const struct message m 
) [static]

Show PBX core status information.

Definition at line 2818 of file manager.c.

References ast_active_channels(), ast_lastreloadtime, ast_localtime(), ast_startuptime, ast_strftime(), ast_strlen_zero(), astman_append(), and astman_get_header().

Referenced by __init_manager().

{
   const char *actionid = astman_get_header(m, "ActionID");
   char idText[150];
   char startuptime[150];
   char reloadtime[150];
   struct ast_tm tm;

   if (!ast_strlen_zero(actionid))
      snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid);
   else
      idText[0] = '\0';

   ast_localtime(&ast_startuptime, &tm, NULL);
   ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm);
   ast_localtime(&ast_lastreloadtime, &tm, NULL);
   ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm);

   astman_append(s, "Response: Success\r\n"
         "%s"
         "CoreStartupTime: %s\r\n"
         "CoreReloadTime: %s\r\n"
         "CoreCurrentCalls: %d\r\n"
         "\r\n",
         idText,
         startuptime,
         reloadtime,
         ast_active_channels()
         );
   return 0;
}
static int action_createconfig ( struct mansession s,
const struct message m 
) [static]

Definition at line 1592 of file manager.c.

References ast_config_AST_CONFIG_DIR, AST_FILE_MODE, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), astman_get_header(), astman_send_ack(), astman_send_error(), and errno.

Referenced by __init_manager().

{
   int fd;
   const char *fn = astman_get_header(m, "Filename");
   struct ast_str *filepath = ast_str_alloca(PATH_MAX);
   ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR);
   ast_str_append(&filepath, 0, "%s", fn);

   if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) {
      close(fd);
      astman_send_ack(s, m, "New configuration file created successfully");
   } else {
      astman_send_error(s, m, strerror(errno));
   }

   return 0;
}
static int action_events ( struct mansession s,
const struct message m 
) [static]

Definition at line 1742 of file manager.c.

References ARRAY_LEN, astman_append(), astman_get_header(), astman_send_error(), permalias::num, perms, and set_eventmask().

Referenced by __init_manager().

{
   const char *mask = astman_get_header(m, "EventMask");
   int res, x;

   res = set_eventmask(s, mask);
   if (broken_events_action) {
      /* if this option is set we should not return a response on
       * error, or when all events are set */

      if (res > 0) {
         for (x = 0; x < ARRAY_LEN(perms); x++) {
            if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) {
               return 0;
            }
         }
         astman_append(s, "Response: Success\r\n"
                "Events: On\r\n\r\n");
      } else if (res == 0)
         astman_append(s, "Response: Success\r\n"
                "Events: Off\r\n\r\n");
      return 0;
   }

   if (res > 0)
      astman_append(s, "Response: Success\r\n"
             "Events: On\r\n\r\n");
   else if (res == 0)
      astman_append(s, "Response: Success\r\n"
             "Events: Off\r\n\r\n");
   else
      astman_send_error(s, m, "Invalid event mask");

   return 0;
}
static int action_extensionstate ( struct mansession s,
const struct message m 
) [static]

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

Referenced by __init_manager().

{
   const char *exten = astman_get_header(m, "Exten");
   const char *context = astman_get_header(m, "Context");
   char hint[256] = "";
   int status;
   if (ast_strlen_zero(exten)) {
      astman_send_error(s, m, "Extension not specified");
      return 0;
   }
   if (ast_strlen_zero(context))
      context = "default";
   status = ast_extension_state(NULL, context, exten);
   ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
   astman_start_ack(s, m);
   astman_append(s,   "Message: Extension Status\r\n"
            "Exten: %s\r\n"
            "Context: %s\r\n"
            "Hint: %s\r\n"
            "Status: %d\r\n\r\n",
            exten, context, hint, status);
   return 0;
}
static int action_getconfig ( struct mansession s,
const struct message m 
) [static]

Definition at line 1183 of file manager.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), ast_variable_browse(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by __init_manager().

{
   struct ast_config *cfg;
   const char *fn = astman_get_header(m, "Filename");
   const char *category = astman_get_header(m, "Category");
   int catcount = 0;
   int lineno = 0;
   char *cur_category = NULL;
   struct ast_variable *v;
   struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };

   if (ast_strlen_zero(fn)) {
      astman_send_error(s, m, "Filename not specified");
      return 0;
   }
   cfg = ast_config_load2(fn, "manager", config_flags);
   if (cfg == CONFIG_STATUS_FILEMISSING) {
      astman_send_error(s, m, "Config file not found");
      return 0;
   } else if (cfg == CONFIG_STATUS_FILEINVALID) {
      astman_send_error(s, m, "Config file has invalid format");
      return 0;
   }

   astman_start_ack(s, m);
   while ((cur_category = ast_category_browse(cfg, cur_category))) {
      if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) {
         lineno = 0;
         astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category);
         for (v = ast_variable_browse(cfg, cur_category); v; v = v->next)
            astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value);
         catcount++;
      }
   }
   if (!ast_strlen_zero(category) && catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */
      astman_append(s, "No categories found\r\n");
   ast_config_destroy(cfg);
   astman_append(s, "\r\n");

   return 0;
}
static int action_getconfigjson ( struct mansession s,
const struct message m 
) [static]

Definition at line 1284 of file manager.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), ast_variable_browse(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), buf, eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, json_escape(), ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by __init_manager().

{
   struct ast_config *cfg;
   const char *fn = astman_get_header(m, "Filename");
   char *category = NULL;
   struct ast_variable *v;
   int comma1 = 0;
   char *buf = NULL;
   unsigned int buf_len = 0;
   struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };

   if (ast_strlen_zero(fn)) {
      astman_send_error(s, m, "Filename not specified");
      return 0;
   }

   if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
      astman_send_error(s, m, "Config file not found");
      return 0;
   } else if (cfg == CONFIG_STATUS_FILEINVALID) {
      astman_send_error(s, m, "Config file has invalid format");
      return 0;
   }

   buf_len = 512;
   buf = alloca(buf_len);

   astman_start_ack(s, m);
   astman_append(s, "JSON: {");
   while ((category = ast_category_browse(cfg, category))) {
      int comma2 = 0;
      if (buf_len < 2 * strlen(category) + 1) {
         buf_len *= 2;
         buf = alloca(buf_len);
      }
      json_escape(buf, category);
      astman_append(s, "%s\"%s\":[", comma1 ? "," : "", buf);
      if (!comma1)
         comma1 = 1;
      for (v = ast_variable_browse(cfg, category); v; v = v->next) {
         if (comma2)
            astman_append(s, ",");
         if (buf_len < 2 * strlen(v->name) + 1) {
            buf_len *= 2;
            buf = alloca(buf_len);
         }
         json_escape(buf, v->name);
         astman_append(s, "\"%s", buf);
         if (buf_len < 2 * strlen(v->value) + 1) {
            buf_len *= 2;
            buf = alloca(buf_len);
         }
         json_escape(buf, v->value);
         astman_append(s, "%s\"", buf);
         if (!comma2)
            comma2 = 1;
      }
      astman_append(s, "]");
   }
   astman_append(s, "}\r\n\r\n");

   ast_config_destroy(cfg);

   return 0;
}
static int action_getvar ( struct mansession s,
const struct message m 
) [static]

Definition at line 1899 of file manager.c.

References ast_channel_alloc(), ast_channel_free(), ast_channel_unlock, ast_func_read(), ast_get_channel_by_name_locked(), ast_log(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), LOG_ERROR, name, pbx_retrieve_variable(), and S_OR.

Referenced by __init_manager().

{
   struct ast_channel *c = NULL;
   const char *name = astman_get_header(m, "Channel");
   const char *varname = astman_get_header(m, "Variable");
   char *varval;
   char workspace[1024] = "";

   if (ast_strlen_zero(varname)) {
      astman_send_error(s, m, "No variable specified");
      return 0;
   }

   if (!ast_strlen_zero(name)) {
      c = ast_get_channel_by_name_locked(name);
      if (!c) {
         astman_send_error(s, m, "No such channel");
         return 0;
      }
   }

   if (varname[strlen(varname) - 1] == ')') {
      if (!c) {
         c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/manager");
         if (c) {
            ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
            ast_channel_free(c);
            c = NULL;
         } else
            ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution.  Function results may be blank.\n");
      } else
         ast_func_read(c, (char *) varname, workspace, sizeof(workspace));
      varval = workspace;
   } else {
      pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL);
   }

   if (c)
      ast_channel_unlock(c);
   astman_start_ack(s, m);
   astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, S_OR(varval, ""));

   return 0;
}
static int action_hangup ( struct mansession s,
const struct message m 
) [static]

Definition at line 1829 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(), and name.

Referenced by __init_manager().

{
   struct ast_channel *c = NULL;
   const char *name = astman_get_header(m, "Channel");
   if (ast_strlen_zero(name)) {
      astman_send_error(s, m, "No channel specified");
      return 0;
   }
   c = ast_get_channel_by_name_locked(name);
   if (!c) {
      astman_send_error(s, m, "No such channel");
      return 0;
   }
   ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
   ast_channel_unlock(c);
   astman_send_ack(s, m, "Channel Hungup");
   return 0;
}
static int action_listcategories ( struct mansession s,
const struct message m 
) [static]

Definition at line 1231 of file manager.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, and CONFIG_STATUS_FILEINVALID.

Referenced by __init_manager().

{
   struct ast_config *cfg;
   const char *fn = astman_get_header(m, "Filename");
   char *category = NULL;
   struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
   int catcount = 0;

   if (ast_strlen_zero(fn)) {
      astman_send_error(s, m, "Filename not specified");
      return 0;
   }
   if (!(cfg = ast_config_load2(fn, "manager", config_flags))) {
      astman_send_error(s, m, "Config file not found");
      return 0;
   } else if (cfg == CONFIG_STATUS_FILEINVALID) {
      astman_send_error(s, m, "Config file has invalid format");
      return 0;
   }
   astman_start_ack(s, m);
   while ((category = ast_category_browse(cfg, category))) {
      astman_append(s, "Category-%06d: %s\r\n", catcount, category);
      catcount++;
   }
   if (catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */
      astman_append(s, "Error: no categories found\r\n");
   ast_config_destroy(cfg);
   astman_append(s, "\r\n");

   return 0;
}
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 1718 of file manager.c.

References manager_action::action, AST_RWLIST_TRAVERSE, ast_str_alloca, astman_append(), astman_start_ack(), manager_action::authority, authority_to_str(), mansession::session, manager_action::synopsis, and mansession_session::writeperm.

Referenced by __init_manager().

{
   struct manager_action *cur;
   struct ast_str *temp = ast_str_alloca(BUFSIZ); /* XXX very large ? */

   astman_start_ack(s, m);
   AST_RWLIST_TRAVERSE(&actions, cur, list) {
      if (s->session->writeperm & cur->authority || cur->authority == 0)
         astman_append(s, "%s: %s (Priv: %s)\r\n",
            cur->action, cur->synopsis, authority_to_str(cur->authority, &temp));
   }
   astman_append(s, "\r\n");

   return 0;
}
static int action_login ( struct mansession s,
const struct message m 
) [static]
static int action_logoff ( struct mansession s,
const struct message m 
) [static]

Definition at line 1782 of file manager.c.

References astman_send_response().

Referenced by __init_manager().

{
   astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
   return -1;
}
static int action_mailboxcount ( struct mansession s,
const struct message m 
) [static]

Definition at line 2622 of file manager.c.

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

Referenced by __init_manager().

{
   const char *mailbox = astman_get_header(m, "Mailbox");
   int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;;

   if (ast_strlen_zero(mailbox)) {
      astman_send_error(s, m, "Mailbox not specified");
      return 0;
   }
   ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs);
   astman_start_ack(s, m);
   astman_append(s,   "Message: Mailbox Message Count\r\n"
            "Mailbox: %s\r\n"
            "UrgMessages: %d\r\n"
            "NewMessages: %d\r\n"
            "OldMessages: %d\r\n"
            "\r\n",
            mailbox, urgentmsgs, newmsgs, oldmsgs);
   return 0;
}
static int action_mailboxstatus ( struct mansession s,
const struct message m 
) [static]

Definition at line 2593 of file manager.c.

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

Referenced by __init_manager().

{
   const char *mailbox = astman_get_header(m, "Mailbox");
   int ret;

   if (ast_strlen_zero(mailbox)) {
      astman_send_error(s, m, "Mailbox not specified");
      return 0;
   }
   ret = ast_app_has_voicemail(mailbox, NULL);
   astman_start_ack(s, m);
   astman_append(s, "Message: Mailbox Status\r\n"
          "Mailbox: %s\r\n"
          "Waiting: %d\r\n\r\n", mailbox, ret);
   return 0;
}
static int action_originate ( struct mansession s,
const struct message m 
) [static]

Definition at line 2446 of file manager.c.

References fast_originate_helper::account, fast_originate_helper::app, app, fast_originate_helper::appdata, ast_callerid_parse(), ast_calloc, ast_copy_string(), ast_findlabel_extension(), AST_FORMAT_SLINEAR, ast_free, ast_parse_allow_disallow(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pthread_create_detached, ast_shrink_phone_number(), ast_strlen_zero(), ast_true(), ast_variables_destroy(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, context, fast_originate_helper::data, ast_frame::data, EVENT_FLAG_SYSTEM, fast_originate_helper::exten, exten, fast_originate(), fast_originate_helper::format, format, fast_originate_helper::idtext, name, fast_originate_helper::priority, mansession::session, strcasestr(), fast_originate_helper::tech, fast_originate_helper::timeout, fast_originate_helper::vars, and mansession_session::writeperm.

Referenced by __init_manager().

{
   const char *name = astman_get_header(m, "Channel");
   const char *exten = astman_get_header(m, "Exten");
   const char *context = astman_get_header(m, "Context");
   const char *priority = astman_get_header(m, "Priority");
   const char *timeout = astman_get_header(m, "Timeout");
   const char *callerid = astman_get_header(m, "CallerID");
   const char *account = astman_get_header(m, "Account");
   const char *app = astman_get_header(m, "Application");
   const char *appdata = astman_get_header(m, "Data");
   const char *async = astman_get_header(m, "Async");
   const char *id = astman_get_header(m, "ActionID");
   const char *codecs = astman_get_header(m, "Codecs");
   struct ast_variable *vars;
   char *tech, *data;
   char *l = NULL, *n = NULL;
   int pi = 0;
   int res;
   int to = 30000;
   int reason = 0;
   char tmp[256];
   char tmp2[256];
   int format = AST_FORMAT_SLINEAR;

   pthread_t th;
   if (ast_strlen_zero(name)) {
      astman_send_error(s, m, "Channel not specified");
      return 0;
   }
   if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
      if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
         astman_send_error(s, m, "Invalid priority");
         return 0;
      }
   }
   if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
      astman_send_error(s, m, "Invalid timeout");
      return 0;
   }
   ast_copy_string(tmp, name, sizeof(tmp));
   tech = tmp;
   data = strchr(tmp, '/');
   if (!data) {
      astman_send_error(s, m, "Invalid channel");
      return 0;
   }
   *data++ = '\0';
   ast_copy_string(tmp2, callerid, sizeof(tmp2));
   ast_callerid_parse(tmp2, &n, &l);
   if (n) {
      if (ast_strlen_zero(n))
         n = NULL;
   }
   if (l) {
      ast_shrink_phone_number(l);
      if (ast_strlen_zero(l))
         l = NULL;
   }
   if (!ast_strlen_zero(codecs)) {
      format = 0;
      ast_parse_allow_disallow(NULL, &format, codecs, 1);
   }
   if (!ast_strlen_zero(app)) {
      /* To run the System application (or anything else that goes to
       * shell), you must have the additional System privilege */
      if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
         && (
            strcasestr(app, "system") ||      /* System(rm -rf /)
                                                 TrySystem(rm -rf /)       */
            strcasestr(app, "exec") ||        /* Exec(System(rm -rf /))
                                                 TryExec(System(rm -rf /)) */
            strcasestr(app, "agi") ||         /* AGI(/bin/rm,-rf /)
                                                 EAGI(/bin/rm,-rf /)       */
            strstr(appdata, "SHELL") ||       /* NoOp(${SHELL(rm -rf /)})  */
            strstr(appdata, "EVAL")           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
            )) {
         astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have.");
         return 0;
      }
   }

   /* Allocate requested channel variables */
   vars = astman_get_variables(m);

   if (ast_true(async)) {
      struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast));
      if (!fast) {
         res = -1;
      } else {
         if (!ast_strlen_zero(id))
            snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s", id);
         ast_copy_string(fast->tech, tech, sizeof(fast->tech));
            ast_copy_string(fast->data, data, sizeof(fast->data));
         ast_copy_string(fast->app, app, sizeof(fast->app));
         ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata));
         if (l)
            ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num));
         if (n)
            ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name));
         fast->vars = vars;
         ast_copy_string(fast->context, context, sizeof(fast->context));
         ast_copy_string(fast->exten, exten, sizeof(fast->exten));
         ast_copy_string(fast->account, account, sizeof(fast->account));
         fast->format = format;
         fast->timeout = to;
         fast->priority = pi;
         if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) {
            ast_free(fast);
            res = -1;
         } else {
            res = 0;
         }
      }
   } else if (!ast_strlen_zero(app)) {
      res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
   } else {
      if (exten && context && pi)
         res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL);
      else {
         astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
         if (vars) {
            ast_variables_destroy(vars);
         }
         return 0;
      }
   }
   if (!res)
      astman_send_ack(s, m, "Originate successfully queued");
   else
      astman_send_error(s, m, "Originate failed");
   return 0;
}
static int action_ping ( struct mansession s,
const struct message m 
) [static]

Definition at line 1164 of file manager.c.

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

Referenced by __init_manager().

{
   const char *actionid = astman_get_header(m, "ActionID");

   astman_append(s, "Response: Success\r\n");
   if (!ast_strlen_zero(actionid)){
      astman_append(s, "ActionID: %s\r\n", actionid);
   }
   astman_append(s, "Ping: Pong\r\n\r\n");
   return 0;
}
static int action_redirect ( struct mansession s,
const struct message m 
) [static]

action_redirect: The redirect manager command

Definition at line 2137 of file manager.c.

References ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_findlabel_extension(), AST_FLAG_BRIDGE_HANGUP_DONT, ast_get_channel_by_name_locked(), ast_set_flag, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), buf, chan, context, exten, name, ast_channel::pbx, and ast_channel::priority.

Referenced by __init_manager().

{
   const char *name = astman_get_header(m, "Channel");
   const char *name2 = astman_get_header(m, "ExtraChannel");
   const char *exten = astman_get_header(m, "Exten");
   const char *context = astman_get_header(m, "Context");
   const char *priority = astman_get_header(m, "Priority");
   struct ast_channel *chan, *chan2 = NULL;
   int pi = 0;
   int res;

   if (ast_strlen_zero(name)) {
      astman_send_error(s, m, "Channel not specified");
      return 0;
   }
   if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
      if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
         astman_send_error(s, m, "Invalid priority");
         return 0;
      }
   }
   /* XXX watch out, possible deadlock - we are trying to get two channels!!! */
   chan = ast_get_channel_by_name_locked(name);
   if (!chan) {
      char buf[256];
      snprintf(buf, sizeof(buf), "Channel does not exist: %s", name);
      astman_send_error(s, m, buf);
      return 0;
   }
   if (ast_check_hangup(chan)) {
      astman_send_error(s, m, "Redirect failed, channel not up.");
      ast_channel_unlock(chan);
      return 0;
   }
   if (!ast_strlen_zero(name2))
      chan2 = ast_get_channel_by_name_locked(name2);
   if (chan2 && ast_check_hangup(chan2)) {
      astman_send_error(s, m, "Redirect failed, extra channel not up.");
      ast_channel_unlock(chan);
      ast_channel_unlock(chan2);
      return 0;
   }
   if (chan->pbx) {
      ast_channel_lock(chan);
      ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
      ast_channel_unlock(chan);
   }
   res = ast_async_goto(chan, context, exten, pi);
   if (!res) {
      if (!ast_strlen_zero(name2)) {
         if (chan2) {
            if (chan2->pbx) {
               ast_channel_lock(chan2);
               ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
               ast_channel_unlock(chan2);
            }
            res = ast_async_goto(chan2, context, exten, pi);
         } else {
            res = -1;
         }
         if (!res)
            astman_send_ack(s, m, "Dual Redirect successful");
         else
            astman_send_error(s, m, "Secondary redirect failed");
      } else
         astman_send_ack(s, m, "Redirect successful");
   } else
      astman_send_error(s, m, "Redirect failed");
   if (chan)
      ast_channel_unlock(chan);
   if (chan2)
      ast_channel_unlock(chan2);
   return 0;
}
static int action_reload ( struct mansession s,
const struct message m 
) [static]

Send a reload event.

Definition at line 2857 of file manager.c.

References ast_module_reload(), astman_get_header(), astman_send_ack(), astman_send_error(), and S_OR.

Referenced by __init_manager().

{
   const char *module = astman_get_header(m, "Module");
   int res = ast_module_reload(S_OR(module, NULL));

   if (res == 2)
      astman_send_ack(s, m, "Module Reloaded");
   else
      astman_send_error(s, m, s == 0 ? "No such module" : "Module does not support reload");
   return 0;
}
static int action_sendtext ( struct mansession s,
const struct message m 
) [static]

Definition at line 2091 of file manager.c.

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

Referenced by __init_manager().

{
   struct ast_channel *c = NULL;
   const char *name = astman_get_header(m, "Channel");
   const char *textmsg = astman_get_header(m, "Message");
   int res = 0;

   if (ast_strlen_zero(name)) {
      astman_send_error(s, m, "No channel specified");
      return 0;
   }

   if (ast_strlen_zero(textmsg)) {
      astman_send_error(s, m, "No Message specified");
      return 0;
   }

   c = ast_get_channel_by_name_locked(name);
   if (!c) {
      astman_send_error(s, m, "No such channel");
      return 0;
   }

   res = ast_sendtext(c, textmsg);
   ast_channel_unlock(c);

   if (res >= 0) {
      astman_send_ack(s, m, "Success");
   } else {
      astman_send_error(s, m, "Failure");
   }

   return res;
}
static int action_setvar ( struct mansession s,
const struct message m 
) [static]

Definition at line 1855 of file manager.c.

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

Referenced by __init_manager().

{
   struct ast_channel *c = NULL;
   const char *name = astman_get_header(m, "Channel");
   const char *varname = astman_get_header(m, "Variable");
   const char *varval = astman_get_header(m, "Value");
   int res = 0;
   
   if (ast_strlen_zero(varname)) {
      astman_send_error(s, m, "No variable specified");
      return 0;
   }

   if (!ast_strlen_zero(name)) {
      c = ast_get_channel_by_name_locked(name);
      if (!c) {
         astman_send_error(s, m, "No such channel");
         return 0;
      }
   }
   if (varname[strlen(varname)-1] == ')') {
      char *function = ast_strdupa(varname);
      res = ast_func_write(c, function, varval);
   } else {
      pbx_builtin_setvar_helper(c, varname, S_OR(varval, ""));
   }

   if (c)
      ast_channel_unlock(c);
   if (res == 0) {
      astman_send_ack(s, m, "Variable Set"); 
   } else {
      astman_send_error(s, m, "Variable not set");
   }
   return 0;
}
static int action_status ( struct mansession s,
const struct message m 
) [static]

Manager "status" command to show channels.

Definition at line 1956 of file manager.c.

References ast_channel::_bridge, ast_channel::_state, ast_channel::accountcode, AST_APP_ARG, ast_channel_unlock, ast_channel_walk_locked(), AST_DECLARE_APP_ARGS, ast_free, ast_func_read(), ast_get_channel_by_name_locked(), AST_STANDARD_APP_ARGS, ast_state2str(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_strdupa, ast_strlen_zero(), ast_tvnow(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::bridge, ast_channel::cdr, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, ast_channel::name, name, ast_channel::pbx, pbx_retrieve_variable(), ast_channel::priority, S_OR, ast_cdr::start, str, and ast_channel::uniqueid.

Referenced by __init_manager().

{
   const char *name = astman_get_header(m, "Channel");
   const char *cvariables = astman_get_header(m, "Variables");
   char *variables = ast_strdupa(S_OR(cvariables, ""));
   struct ast_channel *c;
   char bridge[256];
   struct timeval now = ast_tvnow();
   long elapsed_seconds = 0;
   int channels = 0;
   int all = ast_strlen_zero(name); /* set if we want all channels */
   const char *id = astman_get_header(m, "ActionID");
   char idText[256];
   AST_DECLARE_APP_ARGS(vars,
      AST_APP_ARG(name)[100];
   );
   struct ast_str *str = ast_str_create(1000);

   if (!ast_strlen_zero(id))
      snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
   else
      idText[0] = '\0';

   if (all)
      c = ast_channel_walk_locked(NULL);
   else {
      c = ast_get_channel_by_name_locked(name);
      if (!c) {
         astman_send_error(s, m, "No such channel");
         ast_free(str);
         return 0;
      }
   }
   astman_send_ack(s, m, "Channel status will follow");

   if (!ast_strlen_zero(cvariables)) {
      AST_STANDARD_APP_ARGS(vars, variables);
   }

   /* if we look by name, we break after the first iteration */
   while (c) {
      if (!ast_strlen_zero(cvariables)) {
         int i;
         ast_str_reset(str);
         for (i = 0; i < vars.argc; i++) {
            char valbuf[512], *ret = NULL;

            if (vars.name[i][strlen(vars.name[i]) - 1] == ')') {
               if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) {
                  valbuf[0] = '\0';
               }
               ret = valbuf;
            } else {
               pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL);
            }

            ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret);
         }
      }

      channels++;
      if (c->_bridge)
         snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid);
      else
         bridge[0] = '\0';
      if (c->pbx) {
         if (c->cdr) {
            elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
         }
         astman_append(s,
         "Event: Status\r\n"
         "Privilege: Call\r\n"
         "Channel: %s\r\n"
         "CallerIDNum: %s\r\n"
         "CallerIDName: %s\r\n"
         "Accountcode: %s\r\n"
         "ChannelState: %d\r\n"
         "ChannelStateDesc: %s\r\n"
         "Context: %s\r\n"
         "Extension: %s\r\n"
         "Priority: %d\r\n"
         "Seconds: %ld\r\n"
         "%s"
         "Uniqueid: %s\r\n"
         "%s"
         "%s"
         "\r\n",
         c->name,
         S_OR(c->cid.cid_num, ""),
         S_OR(c->cid.cid_name, ""),
         c->accountcode,
         c->_state,
         ast_state2str(c->_state), c->context,
         c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, ast_str_buffer(str), idText);
      } else {
         astman_append(s,
         "Event: Status\r\n"
         "Privilege: Call\r\n"
         "Channel: %s\r\n"
         "CallerIDNum: %s\r\n"
         "CallerIDName: %s\r\n"
         "Account: %s\r\n"
         "State: %s\r\n"
         "%s"
         "Uniqueid: %s\r\n"
         "%s"
         "%s"
         "\r\n",
         c->name,
         S_OR(c->cid.cid_num, "<unknown>"),
         S_OR(c->cid.cid_name, "<unknown>"),
         c->accountcode,
         ast_state2str(c->_state), bridge, c->uniqueid, ast_str_buffer(str), idText);
      }
      ast_channel_unlock(c);
      if (!all)
         break;
      c = ast_channel_walk_locked(c);
   }
   astman_append(s,
   "Event: StatusComplete\r\n"
   "%s"
   "Items: %d\r\n"
   "\r\n", idText, channels);
   ast_free(str);
   return 0;
}
static int action_timeout ( struct mansession s,
const struct message m 
) [static]

Definition at line 2685 of file manager.c.

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

Referenced by __init_manager().

{
   struct ast_channel *c;
   const char *name = astman_get_header(m, "Channel");
   double timeout = atof(astman_get_header(m, "Timeout"));
   struct timeval when = { timeout, 0 };

   if (ast_strlen_zero(name)) {
      astman_send_error(s, m, "No channel specified");
      return 0;
   }
   if (!timeout || timeout < 0) {
      astman_send_error(s, m, "No timeout specified");
      return 0;
   }
   c = ast_get_channel_by_name_locked(name);
   if (!c) {
      astman_send_error(s, m, "No such channel");
      return 0;
   }

   when.tv_usec = (timeout - when.tv_sec) * 1000000.0;
   ast_channel_setwhentohangup_tv(c, when);
   ast_channel_unlock(c);
   astman_send_ack(s, m, "Timeout Set");
   return 0;
}
static int action_updateconfig ( struct mansession s,
const struct message m 
) [static]

Definition at line 1508 of file manager.c.

References ast_config_destroy(), ast_config_load2(), ast_config_text_file_save(), ast_include_rename(), ast_module_reload(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_send_ack(), astman_send_error(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, FAILURE_ALLOCATION, FAILURE_APPEND, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, handle_updates(), UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, and UNSPECIFIED_CATEGORY.

Referenced by __init_manager().

{
   struct ast_config *cfg;
   const char *sfn = astman_get_header(m, "SrcFilename");
   const char *dfn = astman_get_header(m, "DstFilename");
   int res;
   const char *rld = astman_get_header(m, "Reload");
   struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE };
   enum error_type result;

   if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) {
      astman_send_error(s, m, "Filename not specified");
      return 0;
   }
   if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) {
      astman_send_error(s, m, "Config file not found");
      return 0;
   } else if (cfg == CONFIG_STATUS_FILEINVALID) {
      astman_send_error(s, m, "Config file has invalid format");
      return 0;
   }
   result = handle_updates(s, m, cfg, dfn);
   if (!result) {
      ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */
      res = ast_config_text_file_save(dfn, cfg, "Manager");
      ast_config_destroy(cfg);
      if (res) {
         astman_send_error(s, m, "Save of config failed");
         return 0;
      }
      astman_send_ack(s, m, NULL);
      if (!ast_strlen_zero(rld)) {
         if (ast_true(rld))
            rld = NULL;
         ast_module_reload(rld);
      }
   } else {
      ast_config_destroy(cfg);
      switch(result) {
      case UNKNOWN_ACTION:
         astman_send_error(s, m, "Unknown action command");
         break;
      case UNKNOWN_CATEGORY:
         astman_send_error(s, m, "Given category does not exist");
         break;
      case UNSPECIFIED_CATEGORY:
         astman_send_error(s, m, "Category not specified");
         break;
      case UNSPECIFIED_ARGUMENT:
         astman_send_error(s, m, "Problem with category, value, or line (if required)");
         break;
      case FAILURE_ALLOCATION:
         astman_send_error(s, m, "Memory allocation failure, this should not happen");
         break;
      case FAILURE_NEWCAT:
         astman_send_error(s, m, "Create category did not complete successfully");
         break;
      case FAILURE_DELCAT:
         astman_send_error(s, m, "Delete category did not complete successfully");
         break;
      case FAILURE_EMPTYCAT:
         astman_send_error(s, m, "Empty category did not complete successfully");
         break;
      case FAILURE_UPDATE:
         astman_send_error(s, m, "Update did not complete successfully");
         break;
      case FAILURE_DELETE:
         astman_send_error(s, m, "Delete did not complete successfully");
         break;
      case FAILURE_APPEND:
         astman_send_error(s, m, "Append did not complete successfully");
         break;
      }
   }
   return 0;
}
static int action_userevent ( struct mansession s,
const struct message m 
) [static]

Definition at line 2747 of file manager.c.

References ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), astman_get_header(), astman_send_ack(), EVENT_FLAG_USER, message::hdrcount, message::headers, and manager_event.

Referenced by __init_manager().

{
   const char *event = astman_get_header(m, "UserEvent");
   struct ast_str *body = ast_str_thread_get(&userevent_buf, 16);
   int x;

   ast_str_reset(body);

   for (x = 0; x < m->hdrcount; x++) {
      if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) {
         ast_str_append(&body, 0, "%s\r\n", m->headers[x]);
      }
   }

   astman_send_ack(s, m, "Event Sent");   
   manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body));
   return 0;
}
static int action_waitevent ( struct mansession s,
const struct message m 
) [static]

Definition at line 1618 of file manager.c.

References mansession_session::__lock, advance_event(), ast_debug, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_RWLIST_NEXT, ast_strlen_zero(), ast_wait_for_input(), astman_append(), astman_get_header(), astman_send_response(), eventqent::category, mansession_session::fd, mansession_session::last_ev, mansession_session::managerid, mansession_session::needdestroy, mansession_session::readperm, mansession_session::send_events, mansession::session, mansession_session::sessiontimeout, and mansession_session::waiting_thread.

Referenced by __init_manager().

{
   const char *timeouts = astman_get_header(m, "Timeout");
   int timeout = -1;
   int x;
   int needexit = 0;
   const char *id = astman_get_header(m, "ActionID");
   char idText[256];

   if (!ast_strlen_zero(id))
      snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
   else
      idText[0] = '\0';

   if (!ast_strlen_zero(timeouts)) {
      sscanf(timeouts, "%30i", &timeout);
      if (timeout < -1)
         timeout = -1;
      /* XXX maybe put an upper bound, or prevent the use of 0 ? */
   }

   ast_mutex_lock(&s->session->__lock);
   if (s->session->waiting_thread != AST_PTHREADT_NULL)
      pthread_kill(s->session->waiting_thread, SIGURG);

   if (s->session->managerid) { /* AMI-over-HTTP session */
      /*
       * Make sure the timeout is within the expire time of the session,
       * as the client will likely abort the request if it does not see
       * data coming after some amount of time.
       */
      time_t now = time(NULL);
      int max = s->session->sessiontimeout - now - 10;

      if (max < 0)   /* We are already late. Strange but possible. */
         max = 0;
      if (timeout < 0 || timeout > max)
         timeout = max;
      if (!s->session->send_events) /* make sure we record events */
         s->session->send_events = -1;
   }
   ast_mutex_unlock(&s->session->__lock);

   /* XXX should this go inside the lock ? */
   s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */
   ast_debug(1, "Starting waiting for an event!\n");

   for (x = 0; x < timeout || timeout < 0; x++) {
      ast_mutex_lock(&s->session->__lock);
      if (AST_RWLIST_NEXT(s->session->last_ev, eq_next)) {
         needexit = 1;
      }
      /* We can have multiple HTTP session point to the same mansession entry.
       * The way we deal with it is not very nice: newcomers kick out the previous
       * HTTP session. XXX this needs to be improved.
       */
      if (s->session->waiting_thread != pthread_self())
         needexit = 1;
      if (s->session->needdestroy)
         needexit = 1;
      ast_mutex_unlock(&s->session->__lock);
      if (needexit)
         break;
      if (s->session->managerid == 0) {   /* AMI session */
         if (ast_wait_for_input(s->session->fd, 1000))
            break;
      } else { /* HTTP session */
         sleep(1);
      }
   }
   ast_debug(1, "Finished waiting for an event!\n");
   ast_mutex_lock(&s->session->__lock);
   if (s->session->waiting_thread == pthread_self()) {
      struct eventqent *eqe = s->session->last_ev;
      astman_send_response(s, m, "Success", "Waiting for Event completed.");
      while ((eqe = advance_event(eqe))) {
         if (((s->session->readperm & eqe->category) == eqe->category) &&
             ((s->session->send_events & eqe->category) == eqe->category)) {
            astman_append(s, "%s", eqe->eventdata);
         }
         s->session->last_ev = eqe;
      }
      astman_append(s,
         "Event: WaitEventComplete\r\n"
         "%s"
         "\r\n", idText);
      s->session->waiting_thread = AST_PTHREADT_NULL;
   } else {
      ast_debug(1, "Abandoning event request!\n");
   }
   ast_mutex_unlock(&s->session->__lock);
   return 0;
}
static struct eventqent* advance_event ( struct eventqent e) [static, read]
static int append_event ( const char *  str,
int  category 
) [static]

Definition at line 3382 of file manager.c.

References ast_atomic_fetchadd_int(), ast_malloc, AST_RWLIST_INSERT_TAIL, AST_RWLIST_NEXT, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_tvnow(), eventqent::category, eventqent::seq, eventqent::tv, and eventqent::usecount.

Referenced by __init_manager(), and __manager_event().

{
   struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str));
   static int seq;   /* sequence number */

   if (!tmp)
      return -1;

   /* need to init all fields, because ast_malloc() does not */
   tmp->usecount = 0;
   tmp->category = category;
   tmp->seq = ast_atomic_fetchadd_int(&seq, 1);
   tmp->tv = ast_tvnow();
   AST_RWLIST_NEXT(tmp, eq_next) = NULL;
   strcpy(tmp->eventdata, str);

   AST_RWLIST_WRLOCK(&all_events);
   AST_RWLIST_INSERT_TAIL(&all_events, tmp, eq_next);
   AST_RWLIST_UNLOCK(&all_events);

   return 0;
}
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 442 of file manager.c.

Referenced by get_perm().

{
   const char *val = bigstr, *next;

   do {
      if ((next = strchr(val, delim))) {
         if (!strncmp(val, smallstr, (next - val)))
            return 1;
         else
            continue;
      } else
         return !strcmp(smallstr, val);
   } while (*(val = (next + 1)));

   return 0;
}
int ast_manager_register2 ( const char *  action,
int  auth,
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

Register a manager command with the manager interface.

Definition at line 3558 of file manager.c.

References manager_action::action, ast_calloc, ast_free, ast_manager_register_struct(), manager_action::authority, description, manager_action::description, manager_action::func, synopsis, and manager_action::synopsis.

Referenced by __init_manager(), ast_features_init(), load_module(), and load_pbx().

{
   struct manager_action *cur = NULL;

   if (!(cur = ast_calloc(1, sizeof(*cur))))
      return -1;

   cur->action = action;
   cur->authority = auth;
   cur->func = func;
   cur->synopsis = synopsis;
   cur->description = description;

   if (ast_manager_register_struct(cur)) {
      ast_free(cur);
      return -1;
   }

   return 0;
}
void ast_manager_register_hook ( struct manager_custom_hook hook)

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

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

Parameters:
hookstruct manager_custom_hook object to add

Definition at line 269 of file manager.c.

References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

static int ast_manager_register_struct ( struct manager_action act) [static]

Definition at line 3522 of file manager.c.

References manager_action::action, ast_log(), AST_RWLIST_INSERT_AFTER, AST_RWLIST_INSERT_HEAD, AST_RWLIST_TIMEDWRLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_verb, LOG_ERROR, LOG_WARNING, and eventqent::tv.

Referenced by ast_manager_register2().

{
   struct manager_action *cur, *prev = NULL;
   struct timespec tv = { 5, };

   if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) {
      ast_log(LOG_ERROR, "Could not obtain lock on manager list\n");
      return -1;
   }
   AST_RWLIST_TRAVERSE(&actions, cur, list) {
      int ret = strcasecmp(cur->action, act->action);
      if (ret == 0) {
         ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action);
         AST_RWLIST_UNLOCK(&actions);
         return -1;
      }
      if (ret > 0) { /* Insert these alphabetically */
         prev = cur;
         break;
      }
   }

   if (prev)
      AST_RWLIST_INSERT_AFTER(&actions, prev, act, list);
   else
      AST_RWLIST_INSERT_HEAD(&actions, act, list);

   ast_verb(2, "Manager registered action %s\n", act->action);

   AST_RWLIST_UNLOCK(&actions);

   return 0;
}
int ast_manager_unregister ( char *  action)

Unregister a registered manager command.

Parameters:
actionName of registered Action:

Definition at line 3489 of file manager.c.

References manager_action::action, ast_free, ast_log(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TIMEDWRLOCK, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, ast_verb, LOG_ERROR, and eventqent::tv.

Referenced by __unload_module(), and unload_module().

{
   struct manager_action *cur;
   struct timespec tv = { 5, };

   if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) {
      ast_log(LOG_ERROR, "Could not obtain lock on manager list\n");
      return -1;
   }
   AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) {
      if (!strcasecmp(action, cur->action)) {
         AST_RWLIST_REMOVE_CURRENT(list);
         ast_free(cur);
         ast_verb(2, "Manager unregistered action %s\n", action);
         break;
      }
   }
   AST_RWLIST_TRAVERSE_SAFE_END;
   AST_RWLIST_UNLOCK(&actions);

   return 0;
}
void ast_manager_unregister_hook ( struct manager_custom_hook hook)

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

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

Parameters:
hookstruct manager_custom_hook object to delete

Definition at line 278 of file manager.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

AST_THREADSTORAGE_CUSTOM_SCOPE ( astman_append_buf  ,
NULL  ,
ast_free_ptr  ,
static   
)

thread local buffer for astman_append

Note:
This can not be defined within the astman_append() function because it declares a couple of functions that get used to initialize the thread local storage key.
AST_THREADSTORAGE_CUSTOM_SCOPE ( userevent_buf  ,
NULL  ,
ast_free_ptr  ,
static   
)
AST_THREADSTORAGE_CUSTOM_SCOPE ( manager_event_buf  ,
NULL  ,
ast_free_ptr  ,
static   
)
void astman_append ( struct mansession s,
const char *  fmt,
  ... 
)

utility functions for creating AMI replies

Definition at line 996 of file manager.c.

References ast_str_buffer(), ast_str_set_va(), ast_str_thread_get(), ast_verbose(), ASTMAN_APPEND_BUF_INITSIZE, buf, mansession_session::f, mansession::f, send_string(), and mansession::session.

Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), _skinny_show_device(), _skinny_show_devices(), _skinny_show_line(), _skinny_show_lines(), action_agents(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_ping(), action_status(), action_waitevent(), ast_cli_netstats(), astman_send_response_full(), do_print(), manager_dbget(), manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_registry(), manager_jabber_send(), manager_list_voicemail_users(), manager_modulecheck(), manager_parking_status(), manager_queue_rule_show(), manager_queues_show(), manager_queues_status(), manager_queues_summary(), manager_rpt_local_nodes(), manager_rpt_status(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_skinny_show_device(), manager_skinny_show_devices(), manager_skinny_show_line(), manager_skinny_show_lines(), rpt_manager_do_stats(), rpt_manager_success(), and session_do().

{
   va_list ap;
   struct ast_str *buf;

   if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE)))
      return;

   va_start(ap, fmt);
   ast_str_set_va(&buf, 0, fmt, ap);
   va_end(ap);

   if (s->f != NULL || s->session->f != NULL) {
      send_string(s, ast_str_buffer(buf));
   } else {
      ast_verbose("fd == -1 in astman_append, should not happen\n");
   }
}
const char* astman_get_header ( const struct message m,
char *  var 
)

Get header from mananger transaction.

Definition at line 924 of file manager.c.

References __astman_get_header(), and GET_HEADER_FIRST_MATCH.

Referenced by _sip_show_peer(), _sip_show_peers(), _skinny_show_devices(), _skinny_show_lines(), action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_atxfer(), action_bridge(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), action_ping(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), action_waitevent(), astman_send_response_full(), authenticate(), change_monitor_action(), do_pause_or_unpause(), handle_updates(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), manager_jabber_send(), manager_list_voicemail_users(), manager_modulecheck(), manager_moduleload(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_reload(), manager_queue_reset(), manager_queue_rule_show(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_rpt_status(), manager_show_dialplan(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), manager_skinny_show_device(), manager_skinny_show_devices(), manager_skinny_show_line(), manager_skinny_show_lines(), meetmemute(), process_message(), rpt_manager_do_stats(), rpt_manager_success(), start_monitor_action(), and stop_monitor_action().

struct ast_variable* astman_get_variables ( const struct message m) [read]

Get a linked list of the Variable: headers.

Definition at line 930 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(), val, and var.

Referenced by action_originate(), and manager_sipnotify().

{
   int varlen, x, y;
   struct ast_variable *head = NULL, *cur;

   AST_DECLARE_APP_ARGS(args,
      AST_APP_ARG(vars)[32];
   );

   varlen = strlen("Variable: ");

   for (x = 0; x < m->hdrcount; x++) {
      char *parse, *var, *val;

      if (strncasecmp("Variable: ", m->headers[x], varlen))
         continue;
      parse = ast_strdupa(m->headers[x] + varlen);

      AST_STANDARD_APP_ARGS(args, parse);
      if (!args.argc)
         continue;
      for (y = 0; y < args.argc; y++) {
         if (!args.vars[y])
            continue;
         var = val = ast_strdupa(args.vars[y]);
         strsep(&val, "=");
         if (!val || ast_strlen_zero(var))
            continue;
         cur = ast_variable_new(var, val, "");
         cur->next = head;
         head = cur;
      }
   }

   return head;
}
void astman_send_error ( struct mansession s,
const struct message m,
char *  error 
)

Send error in manager transaction.

Definition at line 1054 of file manager.c.

References astman_send_response_full().

Referenced by _sip_qualify_peer(), _sip_show_peer(), action_add_agi_cmd(), action_agent_logoff(), action_atxfer(), action_bridge(), action_challenge(), action_command(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_modulecheck(), manager_moduleload(), manager_park(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_reload(), manager_queue_reset(), manager_remove_queue_member(), manager_rpt_status(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sipnotify(), manager_skinny_show_device(), manager_skinny_show_line(), meetmemute(), process_message(), rpt_manager_do_stats(), start_monitor_action(), and stop_monitor_action().

{
   astman_send_response_full(s, m, "Error", error, NULL);
}
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 
)

Send response in manager transaction.

Definition at line 1049 of file manager.c.

References astman_send_response_full().

Referenced by action_logoff(), and action_waitevent().

{
   astman_send_response_full(s, m, resp, msg, NULL);
}
static void astman_send_response_full ( struct mansession s,
const struct message m,
char *  resp,
char *  msg,
char *  listflag 
) [static]

Definition at line 1032 of file manager.c.

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

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

{
   const char *id = astman_get_header(m, "ActionID");

   astman_append(s, "Response: %s\r\n", resp);
   if (!ast_strlen_zero(id))
      astman_append(s, "ActionID: %s\r\n", id);
   if (listflag)
      astman_append(s, "EventList: %s\r\n", listflag);   /* Start, complete, cancelled */
   if (msg == MSG_MOREDATA)
      return;
   else if (msg)
      astman_append(s, "Message: %s\r\n\r\n", msg);
   else
      astman_append(s, "\r\n");
}
static void astman_start_ack ( struct mansession s,
const struct message m 
) [static]
static int authenticate ( struct mansession s,
const struct message m 
) [static]

Definition at line 1098 of file manager.c.

References ast_apply_ha(), ast_copy_string(), ast_debug, ast_inet_ntoa(), ast_log(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), astman_get_header(), mansession_session::challenge, get_manager_by_name_locked(), ast_manager_user::ha, len(), LOG_NOTICE, MD5Final(), MD5Init(), MD5Update(), ast_manager_user::readperm, mansession_session::readperm, S_OR, ast_manager_user::secret, mansession::session, mansession_session::sessionstart, set_eventmask(), mansession_session::sin, mansession_session::username, ast_manager_user::writeperm, mansession_session::writeperm, ast_manager_user::writetimeout, and mansession_session::writetimeout.

Referenced by action_login().

{
   const char *username = astman_get_header(m, "Username");
   const char *password = astman_get_header(m, "Secret");
   int error = -1;
   struct ast_manager_user *user = NULL;

   if (ast_strlen_zero(username))   /* missing username */
      return -1;

   /* locate user in locked state */
   AST_RWLIST_WRLOCK(&users);

   if (!(user = get_manager_by_name_locked(username))) {
      ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
   } else if (user->ha && !ast_apply_ha(user->ha, &(s->session->sin))) {
      ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
   } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) {
      const char *key = astman_get_header(m, "Key");
      if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) {
         int x;
         int len = 0;
         char md5key[256] = "";
         struct MD5Context md5;
         unsigned char digest[16];

         MD5Init(&md5);
         MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge));
         MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret));
         MD5Final(digest, &md5);
         for (x = 0; x < 16; x++)
            len += sprintf(md5key + len, "%2.2x", digest[x]);
         if (!strcmp(md5key, key))
            error = 0;
      } else {
         ast_debug(1, "MD5 authentication is not possible.  challenge: '%s'\n", 
            S_OR(s->session->challenge, ""));
      }
   } else if (password && user->secret && !strcmp(password, user->secret))
      error = 0;

   if (error) {
      ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username);
      AST_RWLIST_UNLOCK(&users);
      return -1;
   }

   /* auth complete */
   
   ast_copy_string(s->session->username, username, sizeof(s->session->username));
   s->session->readperm = user->readperm;
   s->session->writeperm = user->writeperm;
   s->session->writetimeout = user->writetimeout;
   s->session->sessionstart = time(NULL);
   set_eventmask(s, astman_get_header(m, "Events"));
   
   AST_RWLIST_UNLOCK(&users);
   return 0;
}
static char* authority_to_str ( int  authority,
struct ast_str **  res 
) [static]

Convert authority code to a list of options.

Definition at line 418 of file manager.c.

References ARRAY_LEN, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_strlen(), num, and perms.

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

{
   int i;
   char *sep = "";

   ast_str_reset(*res);
   for (i = 0; i < ARRAY_LEN(perms) - 1; i++) {
      if (authority & perms[i].num) {
         ast_str_append(res, 0, "%s%s", sep, perms[i].label);
         sep = ",";
      }
   }

   if (ast_str_strlen(*res) == 0)   /* replace empty string with something sensible */
      ast_str_append(res, 0, "<none>");

   return ast_str_buffer(*res);
}
static int check_blacklist ( const char *  cmd) [static]

Definition at line 2269 of file manager.c.

References ARRAY_LEN, ast_strdupa, ast_strip(), ast_strlen_zero(), command_blacklist, match(), MAX_BLACKLIST_CMD_LEN, strsep(), and words.

Referenced by action_command().

{
   char *cmd_copy, *cur_cmd;
   char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, };
   int i;

   cmd_copy = ast_strdupa(cmd);
   for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) {
      cur_cmd = ast_strip(cur_cmd);
      if (ast_strlen_zero(cur_cmd)) {
         i--;
         continue;
      }

      cmd_words[i] = cur_cmd;
   }

   for (i = 0; i < ARRAY_LEN(command_blacklist); i++) {
      int j, match = 1;

      for (j = 0; command_blacklist[i].words[j]; j++) {
         if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) {
            match = 0;
            break;
         }
      }

      if (match) {
         return 1;
      }
   }

   return 0;
}
int check_manager_enabled ( 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.

Check if AMI is enabled.

Definition at line 329 of file manager.c.

References manager_enabled.

Referenced by handle_show_settings().

{
   return manager_enabled;
}
static int check_manager_session_inuse ( const char *  name) [static]

Definition at line 501 of file manager.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, mansession_session::list, and mansession_session::username.

Referenced by process_message().

{
   struct mansession_session *session = NULL;

   AST_LIST_LOCK(&sessions);
   AST_LIST_TRAVERSE(&sessions, session, list) {
      if (!strcasecmp(session->username, name)) 
         break;
   }
   AST_LIST_UNLOCK(&sessions);

   return session ? 1 : 0;
}
int check_webmanager_enabled ( void  )

Check if AMI/HTTP is enabled.

Definition at line 334 of file manager.c.

Referenced by action_coresettings(), and handle_show_settings().

static void destroy_session ( struct mansession_session session) [static]
static int do_message ( struct mansession s) [static]

Definition at line 3216 of file manager.c.

References ast_inet_ntoa(), ast_log(), AST_MAX_MANHEADERS, ast_strdupa, ast_strlen_zero(), mansession_session::authenticated, mansession_session::authstart, errno, get_input(), message::hdrcount, message::headers, mansession_session::inbuf, LOG_ERROR, LOG_EVENT, process_events(), process_message(), mansession::session, and mansession_session::sin.

Referenced by session_do().

{
   struct message m = { 0 };
   char header_buf[sizeof(s->session->inbuf)] = { '\0' };
   int res;
   time_t now;

   for (;;) {
      /* Check if any events are pending and do them if needed */
      if (process_events(s))
         return -1;
      res = get_input(s, header_buf);
      if (res == 0) {
         if (!s->session->authenticated) {
            if(time(&now) == -1) {
               ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
               return -1;
            }

            if (now - s->session->authstart > authtimeout) {
               ast_log(LOG_EVENT, "Client from %s, failed to authenticate in %d seconds\n", ast_inet_ntoa(s->session->sin.sin_addr), authtimeout);
               return -1;
            }
         }
         continue;
      } else if (res > 0) {
         if (ast_strlen_zero(header_buf))
            return process_message(s, &m) ? -1 : 0;
         else if (m.hdrcount < (AST_MAX_MANHEADERS - 1))
            m.headers[m.hdrcount++] = ast_strdupa(header_buf);
      } else {
         return res;
      }
   }
}
static void* fast_originate ( void *  data) [static]

Definition at line 2382 of file manager.c.

References fast_originate_helper::account, fast_originate_helper::app, fast_originate_helper::appdata, AST_CHANNEL_NAME, ast_channel_unlock, ast_free, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_strlen_zero(), chan, fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, fast_originate_helper::data, ast_frame::data, EVENT_FLAG_CALL, fast_originate_helper::exten, fast_originate_helper::format, fast_originate_helper::idtext, manager_event, ast_channel::name, fast_originate_helper::priority, S_OR, fast_originate_helper::tech, fast_originate_helper::timeout, ast_channel::uniqueid, and fast_originate_helper::vars.

Referenced by action_originate().

{
   struct fast_originate_helper *in = data;
   int res;
   int reason = 0;
   struct ast_channel *chan = NULL;
   char requested_channel[AST_CHANNEL_NAME];

   if (!ast_strlen_zero(in->app)) {
      res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1,
         S_OR(in->cid_num, NULL),
         S_OR(in->cid_name, NULL),
         in->vars, in->account, &chan);
   } else {
      res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1,
         S_OR(in->cid_num, NULL),
         S_OR(in->cid_name, NULL),
         in->vars, in->account, &chan);
   }

   if (!chan)
      snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data);   
   /* Tell the manager what happened with the channel */
   manager_event(EVENT_FLAG_CALL, "OriginateResponse",
      "%s%s"
      "Response: %s\r\n"
      "Channel: %s\r\n"
      "Context: %s\r\n"
      "Exten: %s\r\n"
      "Reason: %d\r\n"
      "Uniqueid: %s\r\n"
      "CallerIDNum: %s\r\n"
      "CallerIDName: %s\r\n",
      in->idtext, ast_strlen_zero(in->idtext) ? "" : "\r\n", res ? "Failure" : "Success", 
      chan ? chan->name : requested_channel, in->context, in->exten, reason, 
      chan ? chan->uniqueid : "<null>",
      S_OR(in->cid_num, "<unknown>"),
      S_OR(in->cid_name, "<unknown>")
      );

   /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */
   if (chan)
      ast_channel_unlock(chan);
   ast_free(in);
   return NULL;
}
static void free_session ( struct mansession_session session) [static]

Definition at line 859 of file manager.c.

References mansession_session::__lock, ast_atomic_fetchadd_int(), ast_datastore_free(), ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_destroy(), mansession_session::datastores, ast_datastore::entry, mansession_session::f, mansession_session::last_ev, and eventqent::usecount.

Referenced by destroy_session(), and purge_sessions().

{
   struct eventqent *eqe = session->last_ev;
   struct ast_datastore *datastore;

   /* Get rid of each of the data stores on the session */
   while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) {
      /* Free the data store */
      ast_datastore_free(datastore);
   }

   if (session->f != NULL)
      fclose(session->f);
   ast_mutex_destroy(&session->__lock);
   ast_free(session);
   if (eqe) {
      ast_atomic_fetchadd_int(&eqe->usecount, -1);
   }
}
static int get_input ( struct mansession s,
char *  output 
) [static]

Read one full line (including crlf) from the manager socket.

Note:
 * \r\n is the only valid terminator for the line.
 * (Note that, later, '\0' will be considered as the end-of-line marker,
 * so everything between the '\0' and the '\r\n' will not be used).
 * Also note that we assume output to have at least "maxlen" space.
 * 

Definition at line 3130 of file manager.c.

References mansession_session::__lock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_wait_for_input(), mansession_session::authenticated, mansession_session::authstart, errno, mansession_session::f, mansession_session::fd, mansession_session::inbuf, mansession_session::inlen, LOG_ERROR, LOG_WARNING, mansession_session::pending_event, mansession::session, mansession_session::sin, ast_frame::src, and mansession_session::waiting_thread.

Referenced by do_message().

{
   int res, x;
   int maxlen = sizeof(s->session->inbuf) - 1;
   char *src = s->session->inbuf;
   int timeout = -1;
   time_t now;

   /*
    * Look for \r\n within the buffer. If found, copy to the output
    * buffer and return, trimming the \r\n (not used afterwards).
    */
   for (x = 0; x < s->session->inlen; x++) {
      int cr;  /* set if we have \r */
      if (src[x] == '\r' && x+1 < s->session->inlen && src[x+1] == '\n')
         cr = 2;  /* Found. Update length to include \r\n */
      else if (src[x] == '\n')
         cr = 1;  /* also accept \n only */
      else
         continue;
      memmove(output, src, x);   /*... but trim \r\n */
      output[x] = '\0';    /* terminate the string */
      x += cr;       /* number of bytes used */
      s->session->inlen -= x;       /* remaining size */
      memmove(src, src + x, s->session->inlen); /* remove used bytes */
      return 1;
   }
   if (s->session->inlen >= maxlen) {
      /* no crlf found, and buffer full - sorry, too long for us */
      ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src);
      s->session->inlen = 0;
   }
   res = 0;
   while (res == 0) {
      /* calculate a timeout if we are not authenticated */
      if (!s->session->authenticated) {
         if(time(&now) == -1) {
            ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
            return -1;
         }

         timeout = (authtimeout - (now - s->session->authstart)) * 1000;
         if (timeout < 0) {
            /* we have timed out */
            return 0;
         }
      }

      /* XXX do we really need this locking ? */
      ast_mutex_lock(&s->session->__lock);
      if (s->session->pending_event) {
         s->session->pending_event = 0;
         ast_mutex_unlock(&s->session->__lock);
         return 0;
      }
      s->session->waiting_thread = pthread_self();
      ast_mutex_unlock(&s->session->__lock);

      res = ast_wait_for_input(s->session->fd, timeout);

      ast_mutex_lock(&s->session->__lock);
      s->session->waiting_thread = AST_PTHREADT_NULL;
      ast_mutex_unlock(&s->session->__lock);
   }
   if (res < 0) {
      /* If we get a signal from some other thread (typically because
       * there are new events queued), return 0 to notify the caller.
       */
      if (errno == EINTR || errno == EAGAIN)
         return 0;
      ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
      return -1;
   }
   ast_mutex_lock(&s->session->__lock);
   res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f);
   if (res < 1)
      res = -1;   /* error return */
   else {
      s->session->inlen += res;
      src[s->session->inlen] = '\0';
      res = 0;
   }
   ast_mutex_unlock(&s->session->__lock);
   return res;
}
static struct ast_manager_user* get_manager_by_name_locked ( const char *  name) [static, read]

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

Definition at line 520 of file manager.c.

References AST_RWLIST_TRAVERSE, user, and ast_manager_user::username.

Referenced by __init_manager(), authenticate(), handle_showmanager(), and manager_displayconnects().

{
   struct ast_manager_user *user = NULL;

   AST_RWLIST_TRAVERSE(&users, user, list)
      if (!strcasecmp(user->username, name))
         break;
   return user;
}
static int get_perm ( const char *  instr) [static]

Definition at line 459 of file manager.c.

References ARRAY_LEN, ast_instring(), num, and perms.

Referenced by __init_manager(), and strings_to_mask().

{
   int x = 0, ret = 0;

   if (!instr)
      return 0;

   for (x = 0; x < ARRAY_LEN(perms); x++) {
      if (ast_instring(instr, perms[x].label, ','))
         ret |= perms[x].num;
   }

   return ret;
}
static struct eventqent* grab_last ( void  ) [static, read]

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

Definition at line 343 of file manager.c.

References ast_atomic_fetchadd_int(), AST_RWLIST_LAST, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and eventqent::usecount.

Referenced by generic_http_callback(), and session_do().

{
   struct eventqent *ret;

   AST_RWLIST_RDLOCK(&all_events);
   ret = AST_RWLIST_LAST(&all_events);
   /* the list is never empty now, but may become so when
    * we optimize it in the future, so be prepared.
    */
   if (ret) {
      ast_atomic_fetchadd_int(&ret->usecount, 1);
   }
   AST_RWLIST_UNLOCK(&all_events);
   return ret;
}
static char* handle_manager_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI command manager reload.

Definition at line 813 of file manager.c.

References ast_cli_args::argc, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, reload_manager(), and ast_cli_entry::usage.

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "manager reload";
      e->usage =
         "Usage: manager reload\n"
         "       Reloads the manager configuration.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }
   if (a->argc > 2)
      return CLI_SHOWUSAGE;
   reload_manager();
   return CLI_SUCCESS;
}
static char* handle_mandebug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 594 of file manager.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

{
   switch (cmd) {
   case CLI_INIT:
      e->command = "manager set debug [on|off]";
      e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;   
   }
   if (a->argc == 3)
      ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off");
   else if (a->argc == 4) {
      if (!strcasecmp(a->argv[3], "on"))
         manager_debug = 1;
      else if (!strcasecmp(a->argv[3], "off"))
         manager_debug = 0;
      else
         return CLI_SHOWUSAGE;
   }
   return CLI_SUCCESS;
}
static char* handle_showmanager ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 617 of file manager.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_manager_user::displayconnects, ast_cli_args::fd, get_manager_by_name_locked(), ast_manager_user::ha, ast_cli_args::n, ast_cli_args::pos, ast_manager_user::readperm, ast_manager_user::secret, ast_cli_entry::usage, ast_manager_user::username, ast_cli_args::word, and ast_manager_user::writeperm.

{
   struct ast_manager_user *user = NULL;
   int l, which;
   char *ret = NULL;
   struct ast_str *rauthority = ast_str_alloca(128);
   struct ast_str *wauthority = ast_str_alloca(128);

   switch (cmd) {
   case CLI_INIT:
      e->command = "manager show user";
      e->usage = 
         " Usage: manager show user <user>\n"
         "        Display all information related to the manager user specified.\n";
      return NULL;
   case CLI_GENERATE:
      l = strlen(a->word);
      which = 0;
      if (a->pos != 3)
         return NULL;
      AST_RWLIST_RDLOCK(&users);
      AST_RWLIST_TRAVERSE(&users, user, list) {
         if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) {
            ret = ast_strdup(user->username);
            break;
         }
      }
      AST_RWLIST_UNLOCK(&users);
      return ret;
   }

   if (a->argc != 4)
      return CLI_SHOWUSAGE;

   AST_RWLIST_RDLOCK(&users);

   if (!(user = get_manager_by_name_locked(a->argv[3]))) {
      ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]);
      AST_RWLIST_UNLOCK(&users);
      return CLI_SUCCESS;
   }

   ast_cli(a->fd, "\n");
   ast_cli(a->fd,
      "       username: %s\n"
      "         secret: %s\n"
      "            acl: %s\n"
      "      read perm: %s\n"
      "     write perm: %s\n"
      "displayconnects: %s\n",
      (user->username ? user->username : "(N/A)"),
      (user->secret ? "<Set>" : "(N/A)"),
      (user->ha ? "yes" : "no"),
      authority_to_str(user->readperm, &rauthority),
      authority_to_str(user->writeperm, &wauthority),
      (user->displayconnects ? "yes" : "no"));

   AST_RWLIST_UNLOCK(&users);

   return CLI_SUCCESS;
}
static char* handle_showmanagers ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 680 of file manager.c.

References ast_cli_args::argc, ast_cli(), AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_entry::usage, and ast_manager_user::username.

{
   struct ast_manager_user *user = NULL;
   int count_amu = 0;
   switch (cmd) {
   case CLI_INIT:
      e->command = "manager show users";
      e->usage = 
         "Usage: manager show users\n"
         "       Prints a listing of all managers that are currently configured on that\n"
         " system.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }
   if (a->argc != 3)
      return CLI_SHOWUSAGE;

   AST_RWLIST_RDLOCK(&users);

   /* If there are no users, print out something along those lines */
   if (AST_RWLIST_EMPTY(&users)) {
      ast_cli(a->fd, "There are no manager users.\n");
      AST_RWLIST_UNLOCK(&users);
      return CLI_SUCCESS;
   }

   ast_cli(a->fd, "\nusername\n--------\n");

   AST_RWLIST_TRAVERSE(&users, user, list) {
      ast_cli(a->fd, "%s\n", user->username);
      count_amu++;
   }

   AST_RWLIST_UNLOCK(&users);

   ast_cli(a->fd, "-------------------\n");
   ast_cli(a->fd, "%d manager users configured.\n", count_amu);

   return CLI_SUCCESS;
}
static char* handle_showmancmd ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 547 of file manager.c.

References manager_action::action, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, manager_action::authority, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, manager_action::description, ast_cli_args::fd, ast_cli_args::n, num, S_OR, manager_action::synopsis, ast_cli_entry::usage, and ast_cli_args::word.

{
   struct manager_action *cur;
   struct ast_str *authority;
   int num, l, which;
   char *ret = NULL;
   switch (cmd) {
   case CLI_INIT:
      e->command = "manager show command";
      e->usage = 
         "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n"
         "  Shows the detailed description for a specific Asterisk manager interface command.\n";
      return NULL;
   case CLI_GENERATE:
      l = strlen(a->word);
      which = 0;
      AST_RWLIST_RDLOCK(&actions);
      AST_RWLIST_TRAVERSE(&actions, cur, list) {
         if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) {
            ret = ast_strdup(cur->action);
            break;   /* make sure we exit even if ast_strdup() returns NULL */
         }
      }
      AST_RWLIST_UNLOCK(&actions);
      return ret;
   }
   authority = ast_str_alloca(80);
   if (a->argc < 4) {
      return CLI_SHOWUSAGE;
   }

   AST_RWLIST_RDLOCK(&actions);
   AST_RWLIST_TRAVERSE(&actions, cur, list) {
      for (num = 3; num < a->argc; num++) {
         if (!strcasecmp(cur->action, a->argv[num])) {
            ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n",
               cur->action, cur->synopsis,
               authority_to_str(cur->authority, &authority),
               S_OR(cur->description, ""));
         }
      }
   }
   AST_RWLIST_UNLOCK(&actions);

   return CLI_SUCCESS;
}
static char* handle_showmancmds ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI command manager list commands.

Definition at line 724 of file manager.c.

References manager_action::action, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, manager_action::authority, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HSMC_FORMAT, manager_action::synopsis, and ast_cli_entry::usage.

{
   struct manager_action *cur;
   struct ast_str *authority;
#define HSMC_FORMAT "  %-15.15s  %-15.15s  %-55.55s\n"
   switch (cmd) {
   case CLI_INIT:
      e->command = "manager show commands";
      e->usage = 
         "Usage: manager show commands\n"
         "  Prints a listing of all the available Asterisk manager interface commands.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;   
   }  
   authority = ast_str_alloca(80);
   ast_cli(a->fd, HSMC_FORMAT, "Action", "Privilege", "Synopsis");
   ast_cli(a->fd, HSMC_FORMAT, "------", "---------", "--------");

   AST_RWLIST_RDLOCK(&actions);
   AST_RWLIST_TRAVERSE(&actions, cur, list)
      ast_cli(a->fd, HSMC_FORMAT, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis);
   AST_RWLIST_UNLOCK(&actions);

   return CLI_SUCCESS;
}
static char* handle_showmanconn ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI command manager list connected.

Definition at line 752 of file manager.c.

References ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, mansession_session::fd, ast_cli_args::fd, HSMCONN_FORMAT1, HSMCONN_FORMAT2, mansession_session::inuse, mansession_session::list, mansession_session::readperm, mansession_session::sessionstart, mansession_session::sin, ast_cli_entry::usage, mansession_session::username, and mansession_session::writeperm.

{
   struct mansession_session *session;
   time_t now = time(NULL);
#define HSMCONN_FORMAT1 "  %-15.15s  %-15.15s  %-10.10s  %-10.10s  %-8.8s  %-8.8s  %-5.5s  %-5.5s\n"
#define HSMCONN_FORMAT2 "  %-15.15s  %-15.15s  %-10d  %-10d  %-8d  %-8d  %-5.5d  %-5.5d\n"
   int count = 0;
   switch (cmd) {
   case CLI_INIT:
      e->command = "manager show connected";
      e->usage = 
         "Usage: manager show connected\n"
         "  Prints a listing of the users that are currently connected to the\n"
         "Asterisk manager interface.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;   
   }

   ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write");

   AST_LIST_LOCK(&sessions);
   AST_LIST_TRAVERSE(&sessions, session, list) {
      ast_cli(a->fd, HSMCONN_FORMAT2, session->username, ast_inet_ntoa(session->sin.sin_addr), (int)(session->sessionstart), (int)(now - session->sessionstart), session->fd, session->inuse, session->readperm, session->writeperm);
      count++;
   }
   AST_LIST_UNLOCK(&sessions);

   ast_cli(a->fd, "%d users connected.\n", count);

   return CLI_SUCCESS;
}
static char* handle_showmaneventq ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI command manager list eventq.

Definition at line 787 of file manager.c.

References ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, eventqent::category, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, s, ast_cli_entry::usage, and eventqent::usecount.

{
   struct eventqent *s;
   switch (cmd) {
   case CLI_INIT:
      e->command = "manager show eventq";
      e->usage = 
         "Usage: manager show eventq\n"
         "  Prints a listing of all events pending in the Asterisk manger\n"
         "event queue.\n";
      return NULL;
   case CLI_GENERATE:
      return NULL;
   }
   AST_RWLIST_RDLOCK(&all_events);
   AST_RWLIST_TRAVERSE(&all_events, s, eq_next) {
      ast_cli(a->fd, "Usecount: %d\n", s->usecount);
      ast_cli(a->fd, "Category: %d\n", s->category);
      ast_cli(a->fd, "Event:\n%s", s->eventdata);
   }
   AST_RWLIST_UNLOCK(&all_events);

   return CLI_SUCCESS;
}
static enum error_type handle_updates ( struct mansession s,
const struct message m,
struct ast_config cfg,
const char *  dfn 
) [static]

Definition at line 1351 of file manager.c.

References ast_category_append(), ast_category_delete(), ast_category_empty(), ast_category_get(), ast_category_insert(), ast_category_new(), ast_category_rename(), ast_free, ast_log(), ast_str_create(), ast_strlen_zero(), ast_variable_append(), ast_variable_delete(), ast_variable_insert(), ast_variable_new(), ast_variable_update(), astman_get_header(), eventqent::category, FAILURE_ALLOCATION, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, LOG_WARNING, match(), ast_variable::object, UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, UNSPECIFIED_CATEGORY, and var.

Referenced by action_updateconfig().

{
   int x;
   char hdr[40];
   const char *action, *cat, *var, *value, *match, *line;
   struct ast_category *category;
   struct ast_variable *v;
   struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16);
   enum error_type result = 0;

   for (x = 0; x < 100000; x++) {   /* 100000 = the max number of allowed updates + 1 */
      unsigned int object = 0;

      snprintf(hdr, sizeof(hdr), "Action-%06d", x);
      action = astman_get_header(m, hdr);
      if (ast_strlen_zero(action))     /* breaks the for loop if no action header */
         break;                        /* this could cause problems if actions come in misnumbered */

      snprintf(hdr, sizeof(hdr), "Cat-%06d", x);
      cat = astman_get_header(m, hdr);
      if (ast_strlen_zero(cat)) {      /* every action needs a category */
         result =  UNSPECIFIED_CATEGORY;
         break;
      }

      snprintf(hdr, sizeof(hdr), "Var-%06d", x);
      var = astman_get_header(m, hdr);

      snprintf(hdr, sizeof(hdr), "Value-%06d", x);
      value = astman_get_header(m, hdr);

      if (!ast_strlen_zero(value) && *value == '>') {
         object = 1;
         value++;
      }
   
      snprintf(hdr, sizeof(hdr), "Match-%06d", x);
      match = astman_get_header(m, hdr);

      snprintf(hdr, sizeof(hdr), "Line-%06d", x);
      line = astman_get_header(m, hdr);

      if (!strcasecmp(action, "newcat")) {
         if (ast_category_get(cfg,cat)) { /* check to make sure the cat doesn't */
            result = FAILURE_NEWCAT;   /* already exist */
            break;
         }
         if (!(category = ast_category_new(cat, dfn, -1))) {
            result = FAILURE_ALLOCATION;
            break;
         }
         if (ast_strlen_zero(match)) {
            ast_category_append(cfg, category);
         } else
            ast_category_insert(cfg, category, match);
      } else if (!strcasecmp(action, "renamecat")) {
         if (ast_strlen_zero(value)) {
            result = UNSPECIFIED_ARGUMENT;
            break;
         }
         if (!(category = ast_category_get(cfg, cat))) {
            result = UNKNOWN_CATEGORY;
            break;
         }
         ast_category_rename(category, value);
      } else if (!strcasecmp(action, "delcat")) {
         if (ast_category_delete(cfg, cat)) {
            result = FAILURE_DELCAT;
            break;
         }
      } else if (!strcasecmp(action, "emptycat")) {
         if (ast_category_empty(cfg, cat)) {
            result = FAILURE_EMPTYCAT;
            break;
         }
      } else if (!strcasecmp(action, "update")) {
         if (ast_strlen_zero(var)) {
            result = UNSPECIFIED_ARGUMENT;
            break;
         }
         if (!(category = ast_category_get(cfg,cat))) {
            result = UNKNOWN_CATEGORY;
            break;
         }
         if (ast_variable_update(category, var, value, match, object)) {
            result = FAILURE_UPDATE;
            break;
         }
      } else if (!strcasecmp(action, "delete")) {
         if ((ast_strlen_zero(var) && ast_strlen_zero(line))) {
            result = UNSPECIFIED_ARGUMENT;
            break;
         }
         if (!(category = ast_category_get(cfg, cat))) {
            result = UNKNOWN_CATEGORY;
            break;
         }
         if (ast_variable_delete(category, var, match, line)) {
            result = FAILURE_DELETE;
            break;
         }
      } else if (!strcasecmp(action, "append")) {
         if (ast_strlen_zero(var)) {
            result = UNSPECIFIED_ARGUMENT;
            break;
         }
         if (!(category = ast_category_get(cfg, cat))) {
            result = UNKNOWN_CATEGORY; 
            break;
         }
         if (!(v = ast_variable_new(var, value, dfn))) {
            result = FAILURE_ALLOCATION;
            break;
         }
         if (object || (match && !strcasecmp(match, "object")))
            v->object = 1;
         ast_variable_append(category, v);
      } else if (!strcasecmp(action, "insert")) {
         if (ast_strlen_zero(var) || ast_strlen_zero(line)) {
            result = UNSPECIFIED_ARGUMENT;
            break;
         }
         if (!(category = ast_category_get(cfg, cat))) {
            result = UNKNOWN_CATEGORY;
            break;
         }
         if (!(v = ast_variable_new(var, value, dfn))) {
            result = FAILURE_ALLOCATION;
            break;
         }
         ast_variable_insert(category, v, line);
      }
      else {
         ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action);
         result = UNKNOWN_ACTION;
         break;
      }
   }
   ast_free(str1);
   ast_free(str2);
   return result;
}
static void json_escape ( char *  out,
const char *  in 
) [static]

The amount of space in out must be at least ( 2 * strlen(in) + 1 )

Definition at line 1267 of file manager.c.

Referenced by action_getconfigjson().

{
   for (; *in; in++) {
      if (*in == '\\' || *in == '\"')
         *out++ = '\\';
      *out++ = *in;
   }
   *out = '\0';
}
static int manager_displayconnects ( struct mansession_session session) [static]

Get displayconnects config option.

Parameters:
sessionmanager session to get parameter from.
Returns:
displayconnects config option value.

Definition at line 534 of file manager.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_manager_user::displayconnects, get_manager_by_name_locked(), and mansession_session::username.

Referenced by action_login(), generic_http_callback(), purge_sessions(), and session_do().

{
   struct ast_manager_user *user = NULL;
   int ret = 0;

   AST_RWLIST_RDLOCK(&users);
   if ((user = get_manager_by_name_locked (session->username)))
      ret = user->displayconnects;
   AST_RWLIST_UNLOCK(&users);
   
   return ret;
}
static int manager_modulecheck ( struct mansession s,
const struct message m 
) [static]

Definition at line 2948 of file manager.c.

References ast_copy_string(), ast_file_version_find(), ast_log(), ast_module_check(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), LOG_DEBUG, and version.

Referenced by __init_manager().

{
   int res;
   const char *module = astman_get_header(m, "Module");
   const char *id = astman_get_header(m, "ActionID");
   char idText[256];
#if !defined(LOW_MEMORY)
   const char *version;
#endif
   char filename[PATH_MAX];
   char *cut;

   ast_copy_string(filename, module, sizeof(filename));
   if ((cut = strchr(filename, '.'))) {
      *cut = '\0';
   } else {
      cut = filename + strlen(filename);
   }
   snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so");
   ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename);
   res = ast_module_check(filename);
   if (!res) {
      astman_send_error(s, m, "Module not loaded");
      return 0;
   }
   snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c");
   ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename);
#if !defined(LOW_MEMORY)
   version = ast_file_version_find(filename);
#endif

   if (!ast_strlen_zero(id))
      snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
   else
      idText[0] = '\0';
   astman_append(s, "Response: Success\r\n%s", idText);
#if !defined(LOW_MEMORY)
   astman_append(s, "Version: %s\r\n\r\n", version ? version : "");
#endif
   return 0;
}
static int manager_moduleload ( struct mansession s,
const struct message m 
) [static]

Definition at line 3001 of file manager.c.

References AST_FORCE_SOFT, ast_load_resource(), ast_module_reload(), ast_unload_resource(), astman_get_header(), astman_send_ack(), and astman_send_error().

Referenced by __init_manager().

{
   int res;
   const char *module = astman_get_header(m, "Module");
   const char *loadtype = astman_get_header(m, "LoadType");

   if (!loadtype || strlen(loadtype) == 0)
      astman_send_error(s, m, "Incomplete ModuleLoad action.");
   if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0)
      astman_send_error(s, m, "Need module name");

   if (!strcasecmp(loadtype, "load")) {
      res = ast_load_resource(module);
      if (res)
         astman_send_error(s, m, "Could not load module.");
      else
         astman_send_ack(s, m, "Module loaded.");
   } else if (!strcasecmp(loadtype, "unload")) {
      res = ast_unload_resource(module, AST_FORCE_SOFT);
      if (res)
         astman_send_error(s, m, "Could not unload module.");
      else
         astman_send_ack(s, m, "Module unloaded.");
   } else if (!strcasecmp(loadtype, "reload")) {
      if (module != NULL) {
         res = ast_module_reload(module);
         if (res == 0)
            astman_send_error(s, m, "No such module.");
         else if (res == 1)
            astman_send_error(s, m, "Module does not support reload action.");
         else
            astman_send_ack(s, m, "Module reloaded.");
      } else {
         ast_module_reload(NULL);   /* Reload all modules */
         astman_send_ack(s, m, "All modules reloaded");
      }
   } else 
      astman_send_error(s, m, "Incomplete ModuleLoad action.");
   return 0;
}
static int manager_state_cb ( char *  context,
char *  exten,
int  state,
void *  data 
) [static]

Definition at line 3512 of file manager.c.

References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.

Referenced by __init_manager().

{
   /* Notify managers of change */
   char hint[512];
   ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten);

   manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state);
   return 0;
}
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 2718 of file manager.c.

References mansession_session::__lock, advance_event(), ast_mutex_lock(), ast_mutex_unlock(), mansession_session::authenticated, eventqent::category, mansession_session::f, mansession_session::last_ev, mansession_session::readperm, mansession_session::send_events, send_string(), and mansession::session.

Referenced by do_message(), and process_message().

{
   int ret = 0;

   ast_mutex_lock(&s->session->__lock);
   if (s->session->f != NULL) {
      struct eventqent *eqe = s->session->last_ev;

      while ((eqe = advance_event(eqe))) {
         if (!ret && s->session->authenticated &&
             (s->session->readperm & eqe->category) == eqe->category &&
             (s->session->send_events & eqe->category) == eqe->category) {
            if (send_string(s, eqe->eventdata) < 0)
               ret = -1;   /* don't send more */
         }
         s->session->last_ev = eqe;
      }
   }
   ast_mutex_unlock(&s->session->__lock);
   return ret;
}
static int process_message ( struct mansession s,
const struct message m 
) [static]

Definition at line 3055 of file manager.c.

References __astman_get_header(), mansession_session::__lock, manager_action::action, ast_copy_string(), ast_debug, ast_mutex_lock(), ast_mutex_unlock(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), astman_get_header(), astman_send_error(), mansession_session::authenticated, manager_action::authority, buf, check_manager_session_inuse(), manager_action::func, GET_HEADER_SKIP_EMPTY, process_events(), mansession::session, and mansession_session::writeperm.

Referenced by do_message(), and generic_http_callback().

{
   char action[80] = "";
   int ret = 0;
   struct manager_action *tmp;
   const char *user = astman_get_header(m, "Username");

   ast_copy_string(action, __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY), sizeof(action));
   ast_debug(1, "Manager received command '%s'\n", action);

   if (ast_strlen_zero(action)) {
      ast_mutex_lock(&s->session->__lock);
      astman_send_error(s, m, "Missing action in request");
      ast_mutex_unlock(&s->session->__lock);
      return 0;
   }

   if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) {
      ast_mutex_lock(&s->session->__lock);
      astman_send_error(s, m, "Permission denied");
      ast_mutex_unlock(&s->session->__lock);
      return 0;
   }

   if (!allowmultiplelogin && !s->session->authenticated && user &&
      (!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) {
      if (check_manager_session_inuse(user)) {
         sleep(1);
         ast_mutex_lock(&s->session->__lock);
         astman_send_error(s, m, "Login Already In Use");
         ast_mutex_unlock(&s->session->__lock);
         return -1;
      }
   }

   AST_RWLIST_RDLOCK(&actions);
   AST_RWLIST_TRAVERSE(&actions, tmp, list) {
      if (strcasecmp(action, tmp->action))
         continue;
      if (s->session->writeperm & tmp->authority || tmp->authority == 0)
         ret = tmp->func(s, m);
      else
         astman_send_error(s, m, "Permission denied");
      break;
   }
   AST_RWLIST_UNLOCK(&actions);

   if (!tmp) {
      char buf[512];
      snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action);
      ast_mutex_lock(&s->session->__lock);
      astman_send_error(s, m, buf);
      ast_mutex_unlock(&s->session->__lock);
   }
   if (ret)
      return ret;
   /* Once done with our message, deliver any pending events unless the
      requester doesn't want them as part of this response.
   */
   if (ast_strlen_zero(astman_get_header(m, "SuppressEvents"))) {
      return process_events(s);
   } else {
      return ret;
   }
}
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 363 of file manager.c.

References ast_free, AST_RWLIST_FIRST, AST_RWLIST_NEXT, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_REMOVE_HEAD, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_tvdiff_sec(), ast_tvnow(), eventqent::tv, and eventqent::usecount.

Referenced by purge_old_stuff().

{
   struct eventqent *ev;
   struct timeval now = ast_tvnow();

   AST_RWLIST_WRLOCK(&all_events);
   while ( (ev = AST_RWLIST_FIRST(&all_events)) &&
       ev->usecount == 0 && AST_RWLIST_NEXT(ev, eq_next)) {
      AST_RWLIST_REMOVE_HEAD(&all_events, eq_next);
      ast_free(ev);
   }

   AST_RWLIST_TRAVERSE_SAFE_BEGIN(&all_events, ev, eq_next) {
      /* Never release the last event */
      if (!AST_RWLIST_NEXT(ev, eq_next)) {
         break;
      }

      /* 2.5 times whatever the HTTP timeout is (maximum 2.5 hours) is the maximum time that we will definitely cache an event */
      if (ev->usecount == 0 && ast_tvdiff_sec(now, ev->tv) > (httptimeout > 3600 ? 3600 : httptimeout) * 2.5) {
         AST_RWLIST_REMOVE_CURRENT(eq_next);
         ast_free(ev);
      }
   }
   AST_RWLIST_TRAVERSE_SAFE_END;
   AST_RWLIST_UNLOCK(&all_events);
}
static void purge_sessions ( int  n_max) [static]
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 971 of file manager.c.

References ast_careful_fwrite(), mansession_session::f, mansession::f, mansession_session::fd, mansession::fd, mansession::session, and mansession_session::writetimeout.

Referenced by astman_append(), and process_events().

{
   if (s->f) {
      return ast_careful_fwrite(s->f, s->fd, string, strlen(string), s->session->writetimeout);
   } else {
      return ast_careful_fwrite(s->session->f, s->session->fd, string, strlen(string), s->session->writetimeout);
   }
}
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 3260 of file manager.c.

References mansession_session::__lock, AMI_VERSION, ao2_ref, ast_atomic_fetchadd_int(), ast_calloc, ast_inet_ntoa(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), AST_PTHREADT_NULL, ast_verb, astman_append(), mansession_session::authenticated, mansession_session::authstart, ast_frame::data, mansession_session::datastores, destroy_session(), do_message(), errno, mansession_session::f, ast_tcptls_session_instance::f, mansession_session::fd, ast_tcptls_session_instance::fd, ast_frame::flags, grab_last(), mansession_session::last_ev, LOG_ERROR, LOG_EVENT, LOG_WARNING, manager_displayconnects(), ast_tcptls_session_instance::remote_address, s, mansession_session::send_events, mansession::session, mansession_session::sin, mansession_session::username, mansession_session::waiting_thread, and mansession_session::writetimeout.

{
   struct ast_tcptls_session_instance *ser = data;
   struct mansession_session *session = NULL;
   struct mansession s = {.session = NULL, };
   int flags;
   int res;
   struct protoent *p;

   if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) {
      fclose(ser->f);
      ast_atomic_fetchadd_int(&unauth_sessions, -1);
      goto done;
   }

   if ((session = ast_calloc(1, sizeof(*session))) == NULL) {
      fclose(ser->f);
      ast_atomic_fetchadd_int(&unauth_sessions, -1);
      goto done;
   }

   /* here we set TCP_NODELAY on the socket to disable Nagle's algorithm.
    * This is necessary to prevent delays (caused by buffering) as we
    * write to the socket in bits and peices. */
   p = getprotobyname("tcp");
   if (p) {
      int arg = 1;
      if( setsockopt(ser->fd, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
         ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\nSome manager actions may be slow to respond.\n", strerror(errno));
      }
   } else {
      ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY, getprotobyname(\"tcp\") failed\nSome manager actions may be slow to respond.\n");
   }

   session->writetimeout = 100;
   session->waiting_thread = AST_PTHREADT_NULL;

   flags = fcntl(ser->fd, F_GETFL);
   if (!block_sockets) /* make sure socket is non-blocking */
      flags |= O_NONBLOCK;
   else
      flags &= ~O_NONBLOCK;
   fcntl(ser->fd, F_SETFL, flags);

   ast_mutex_init(&session->__lock);
   session->send_events = -1;
   /* Hook to the tail of the event queue */
   session->last_ev = grab_last();

   /* these fields duplicate those in the 'ser' structure */
   session->fd = ser->fd;
   session->f = ser->f;
   session->sin = ser->remote_address;
   s.session = session;

   AST_LIST_HEAD_INIT_NOLOCK(&session->datastores);

   AST_LIST_LOCK(&sessions);
   AST_LIST_INSERT_HEAD(&sessions, session, list);
   ast_atomic_fetchadd_int(&num_sessions, 1);
   AST_LIST_UNLOCK(&sessions);

   if(time(&session->authstart) == -1) {
      ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
      ast_atomic_fetchadd_int(&unauth_sessions, -1);
      destroy_session(session);
      goto done;
   }

   astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION);   /* welcome prompt */
   for (;;) {
      if ((res = do_message(&s)) < 0)
         break;
   }
   /* session is over, explain why and terminate */
   if (session->authenticated) {
         if (manager_displayconnects(session))
         ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
      ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
   } else {
      ast_atomic_fetchadd_int(&unauth_sessions, -1);
         if (displayconnects)
         ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr));
      ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(session->sin.sin_addr));
   }

   destroy_session(session);

done:
   ao2_ref(ser, -1);
   ser = NULL;
   return NULL;
}
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 1079 of file manager.c.

References mansession_session::__lock, ast_mutex_lock(), ast_mutex_unlock(), mansession_session::send_events, mansession::session, and strings_to_mask().

Referenced by action_events(), and authenticate().

{
   int maskint = strings_to_mask(eventmask);

   ast_mutex_lock(&s->session->__lock);
   if (maskint >= 0)
      s->session->send_events = maskint;
   ast_mutex_unlock(&s->session->__lock);

   return maskint;
}
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 478 of file manager.c.

References ARRAY_LEN, ast_false(), ast_strlen_zero(), ast_true(), get_perm(), num, and perms.

Referenced by set_eventmask().

{
   const char *p;

   if (ast_strlen_zero(string))
      return -1;

   for (p = string; *p; p++)
      if (*p < '0' || *p > '9')
         break;
   if (!*p) /* all digits */
      return atoi(string);
   if (ast_false(string))
      return 0;
   if (ast_true(string)) { /* all permissions */
      int x, ret = 0;
      for (x = 0; x < ARRAY_LEN(perms); x++)
         ret |= perms[x].num;
      return ret;
   }
   return get_perm(string);
}

Variable Documentation

struct actions actions [static]
struct all_events all_events [static]
int allowmultiplelogin = 1 [static]

Definition at line 134 of file manager.c.

int authlimit [static]

Definition at line 141 of file manager.c.

int authtimeout [static]

Definition at line 140 of file manager.c.

int block_sockets [static]

Definition at line 143 of file manager.c.

int broken_events_action [static]

Definition at line 137 of file manager.c.

struct ast_cli_entry cli_manager[] [static]

Definition at line 832 of file manager.c.

Referenced by __init_manager().

struct { ... } command_blacklist[] [static]

Referenced by check_blacklist().

const int DEFAULT_AUTHLIMIT = 50 [static]

Default setting for authlimit

Definition at line 131 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_AUTHTIMEOUT = 30 [static]

Default setting for authtimeout

Definition at line 130 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_BLOCKSOCKETS = 0 [static]

Default setting for block-sockets

Definition at line 125 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_BROKENEVENTSACTION = 0 [static]

Default setting for brokeneventsaction

Definition at line 129 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_DISPLAYCONNECTS = 1 [static]

Default setting for displaying manager connections

Definition at line 126 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_ENABLED = 0 [static]

Default setting for manager to be enabled

Definition at line 123 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_HTTPTIMEOUT = 60 [static]

Default manager http timeout

Definition at line 128 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_TIMESTAMPEVENTS = 0 [static]

Default setting for timestampevents

Definition at line 127 of file manager.c.

Referenced by __init_manager().

const int DEFAULT_WEBENABLED = 0 [static]

Default setting for the web interface to be enabled

Definition at line 124 of file manager.c.

Referenced by __init_manager().

int displayconnects [static]

Definition at line 133 of file manager.c.

Referenced by __init_manager().

int httptimeout [static]

Definition at line 136 of file manager.c.

int manager_debug [static]

enable some debugging code in the manager

Definition at line 147 of file manager.c.

int manager_enabled = 0 [static]

Definition at line 138 of file manager.c.

Referenced by check_manager_enabled().

struct manager_hooks manager_hooks [static]
char mandescr_atxfer[] = " ActionID: Optional Action id for message matching.\n" [static]

Definition at line 2212 of file manager.c.

Referenced by __init_manager().

char mandescr_command[] = " ActionID: Optional Action id for message matching.\n" [static]

Definition at line 2304 of file manager.c.

Referenced by __init_manager().

char mandescr_coresettings[] = " *ActionID: ActionID of this transaction\n" [static]

Definition at line 2766 of file manager.c.

Referenced by __init_manager().

char mandescr_coreshowchannels[] = " ActionID: Optional Action id for message matching.\n" [static]

Definition at line 2869 of file manager.c.

Referenced by __init_manager().

char mandescr_corestatus[] = " *ActionID: ActionID of this transaction\n" [static]

Definition at line 2812 of file manager.c.

Referenced by __init_manager().

char mandescr_createconfig[] = " Filename: The configuration filename to create (e.g. foo.conf)\n" [static]

Definition at line 1585 of file manager.c.

Referenced by __init_manager().

char mandescr_events[] = " 'system,call,log' to select which flags events should have to be sent.\n" [static]

Definition at line 1734 of file manager.c.

Referenced by __init_manager().

char mandescr_extensionstate[] = "The response will include the hint for the extension and the status.\n" [static]

Definition at line 2643 of file manager.c.

Referenced by __init_manager().

char mandescr_getconfig[] = " Category: Category in configuration file\n" [static]

Definition at line 1176 of file manager.c.

Referenced by __init_manager().

char mandescr_getconfigjson[] = " Filename: Configuration filename (e.g. foo.conf)\n" [static]

Definition at line 1277 of file manager.c.

Referenced by __init_manager().

char mandescr_getvar[] = " ActionID: Optional Action id for message matching.\n" [static]

Definition at line 1892 of file manager.c.

Referenced by __init_manager().

char mandescr_hangup[] = " Channel: The channel name to be hungup\n" [static]

Definition at line 1824 of file manager.c.

Referenced by __init_manager().

char mandescr_listcategories[] = " Filename: Configuration filename (e.g. foo.conf)\n" [static]

Definition at line 1225 of file manager.c.

Referenced by __init_manager().

char mandescr_listcommands[] = "Variables: NONE\n" [static]

Definition at line 1712 of file manager.c.

Referenced by __init_manager().

char mandescr_logoff[] = "Variables: NONE\n" [static]

Definition at line 1778 of file manager.c.

Referenced by __init_manager().

char mandescr_mailboxcount[] = "\n" [static]

Definition at line 2610 of file manager.c.

Referenced by __init_manager().

char mandescr_mailboxstatus[] = "\n" [static]

Help text for manager command mailboxstatus.

Definition at line 2582 of file manager.c.

Referenced by __init_manager().

char mandescr_modulecheck[] = "For success returns, the module revision number is included.\n" [static]

Definition at line 2938 of file manager.c.

Referenced by __init_manager().

char mandescr_moduleload[] = " If no module is specified for a reload loadtype, all modules are reloaded" [static]

Definition at line 2990 of file manager.c.

Referenced by __init_manager().

char mandescr_originate[] = " Async: Set to 'true' for fast origination\n" [static]

Definition at line 2429 of file manager.c.

Referenced by __init_manager().

char mandescr_ping[] = "Variables: NONE\n" [static]

Manager PING.

Definition at line 1159 of file manager.c.

Referenced by __init_manager().

char mandescr_redirect[] = " ActionID: Optional Action id for message matching.\n" [static]

Definition at line 2126 of file manager.c.

Referenced by __init_manager().

char mandescr_reload[] = " *Module: Name of the module to reload\n" [static]

Definition at line 2850 of file manager.c.

Referenced by __init_manager().

char mandescr_sendtext[] = " ActionID: Optional Action id for message matching.\n" [static]

Definition at line 2084 of file manager.c.

Referenced by __init_manager().

char mandescr_setvar[] = " *Value: Value\n" [static]

Definition at line 1848 of file manager.c.

Referenced by __init_manager().

char mandescr_status[] = "value for the specified channel variables.\n" [static]

Definition at line 1944 of file manager.c.

Referenced by __init_manager().

char mandescr_timeout[] = "Acknowledges set time with 'Timeout Set' message\n" [static]

Definition at line 2678 of file manager.c.

Referenced by __init_manager().

char mandescr_updateconfig[] = " Line-XXXXXX: Line in category to operate on (used with delete and insert actions)\n" [static]

Definition at line 1494 of file manager.c.

Referenced by __init_manager().

char mandescr_userevent[] = " HeaderN: ContentN\n" [static]

Definition at line 2740 of file manager.c.

Referenced by __init_manager().

char mandescr_waitevent[] = " Timeout: Maximum time (in seconds) to wait for events, -1 means forever.\n" [static]

Manager WAITEVENT.

Definition at line 1611 of file manager.c.

Referenced by __init_manager().

int num_sessions [static]

Definition at line 144 of file manager.c.

struct sessions sessions [static]
int timestampevents [static]

Definition at line 135 of file manager.c.

int unauth_sessions = 0 [static]

Definition at line 145 of file manager.c.

struct users users [static]
int webmanager_enabled = 0 [static]

Definition at line 139 of file manager.c.

char* words[AST_MAX_CMD_LEN] [inherited]

Definition at line 160 of file manager.c.