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. | |
#define | NEW_EVENT(m) (AST_LIST_NEXT(m->session->last_ev, eq_next)) |
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 | __init_astman_append_buf (void) |
thread local buffer for astman_append | |
static void | __init_manager_event_buf (void) |
static void | __init_userevent_buf (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 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 manager command with the manager interface. | |
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. | |
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. | |
ast_variable * | astman_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 () |
Check if AMI is enabled. | |
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_user * | get_manager_by_name_locked (const char *name) |
static int | get_perm (const char *instr) |
static struct eventqent * | grab_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 void | ref_event (struct eventqent *e) |
static int | send_string (struct mansession *s, char *string) |
static void * | session_do (void *data) |
The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ). | |
static int | set_eventmask (struct mansession *s, const char *eventmask) |
Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm. | |
static int | strings_to_mask (const char *string) |
static struct eventqent * | unref_event (struct eventqent *e) |
Variables | |
static int | allowmultiplelogin = 1 |
static struct ast_threadstorage | astman_append_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_astman_append_buf , .custom_init = NULL , } |
static int | block_sockets |
static struct ast_cli_entry | cli_manager [] |
struct { | |
char * words [AST_MAX_CMD_LEN] | |
} | command_blacklist [] |
static int | displayconnects = 1 |
static int | httptimeout = 60 |
static int | manager_debug |
static int | manager_enabled = 0 |
static struct ast_threadstorage | manager_event_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_manager_event_buf , .custom_init = NULL , } |
static char | mandescr_atxfer [] |
static char | mandescr_command [] |
static char | mandescr_coresettings [] |
static char | mandescr_coreshowchannels [] |
static char | mandescr_corestatus [] |
static char | mandescr_createconfig [] |
static char | mandescr_events [] |
static char | mandescr_extensionstate [] |
static char | mandescr_getconfig [] |
static char | mandescr_getconfigjson [] |
static char | mandescr_getvar [] |
static char | mandescr_hangup [] |
static char | mandescr_listcategories [] |
static char | mandescr_listcommands [] |
static char | mandescr_logoff [] |
static char | mandescr_mailboxcount [] |
static char | mandescr_mailboxstatus [] |
Help text for manager command mailboxstatus. | |
static char | mandescr_modulecheck [] |
static char | mandescr_moduleload [] |
static char | mandescr_originate [] |
static char | mandescr_ping [] |
Manager PING. | |
static char | mandescr_redirect [] |
static char | mandescr_reload [] |
static char | mandescr_sendtext [] |
static char | mandescr_setvar [] |
static char | mandescr_status [] |
static char | mandescr_timeout [] |
static char | mandescr_updateconfig [] |
static char | mandescr_userevent [] |
static char | mandescr_waitevent [] |
Manager WAITEVENT. | |
static int | num_sessions |
static struct permalias | perms [] |
static int | timestampevents |
static struct ast_threadstorage | userevent_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_userevent_buf , .custom_init = NULL , } |
static int | webmanager_enabled = 0 |
#define ASTMAN_APPEND_BUF_INITSIZE 256 |
initial allocated size for the astman_append_buf
Definition at line 963 of file manager.c.
Referenced by astman_append().
#define GET_HEADER_FIRST_MATCH 0 |
#define GET_HEADER_LAST_MATCH 1 |
#define GET_HEADER_SKIP_EMPTY 2 |
Definition at line 868 of file manager.c.
Referenced by __astman_get_header(), and process_message().
#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.
Definition at line 143 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.
Use the explicit constant MSG_MOREDATA to remove the empty line. XXX MSG_MOREDATA should go to a header file.
Definition at line 1003 of file manager.c.
Referenced by astman_send_response_full(), and astman_start_ack().
#define NEW_EVENT | ( | m | ) | (AST_LIST_NEXT(m->session->last_ev, eq_next)) |
enum error_type |
Doxygen group
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.
00078 { 00079 UNKNOWN_ACTION = 1, 00080 UNKNOWN_CATEGORY, 00081 UNSPECIFIED_CATEGORY, 00082 UNSPECIFIED_ARGUMENT, 00083 FAILURE_ALLOCATION, 00084 FAILURE_NEWCAT, 00085 FAILURE_DELCAT, 00086 FAILURE_EMPTYCAT, 00087 FAILURE_UPDATE, 00088 FAILURE_DELETE, 00089 FAILURE_APPEND 00090 };
static const char* __astman_get_header | ( | const struct message * | m, | |
char * | var, | |||
int | mode | |||
) | [static] |
Definition at line 869 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().
00870 { 00871 int x, l = strlen(var); 00872 const char *result = ""; 00873 00874 for (x = 0; x < m->hdrcount; x++) { 00875 const char *h = m->headers[x]; 00876 if (!strncasecmp(var, h, l) && h[l] == ':' && h[l+1] == ' ') { 00877 const char *value = h + l + 2; 00878 /* found a potential candidate */ 00879 if (mode & GET_HEADER_SKIP_EMPTY && ast_strlen_zero(value)) 00880 continue; /* not interesting */ 00881 if (mode & GET_HEADER_LAST_MATCH) 00882 result = value; /* record the last match so far */ 00883 else 00884 return value; 00885 } 00886 } 00887 00888 return ""; 00889 }
static void __init_astman_append_buf | ( | void | ) | [static] |
thread local buffer for astman_append
Definition at line 959 of file manager.c.
static void __init_manager_event_buf | ( | void | ) | [static] |
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 3263 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_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_append_va(), ast_str_set(), ast_str_thread_get(), ast_tvnow(), authority_to_str(), buf, manager_custom_hook::helper, manager_event_buf, MANAGER_EVENT_BUF_INITSIZE, mansession_session::pending_event, seq, and mansession_session::waiting_thread.
03265 { 03266 struct mansession_session *session; 03267 struct manager_custom_hook *hook; 03268 struct ast_str *auth = ast_str_alloca(80); 03269 const char *cat_str; 03270 va_list ap; 03271 struct timeval now; 03272 struct ast_str *buf; 03273 03274 /* Abort if there aren't any manager sessions */ 03275 if (!num_sessions) 03276 return 0; 03277 03278 if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) 03279 return -1; 03280 03281 cat_str = authority_to_str(category, &auth); 03282 ast_str_set(&buf, 0, 03283 "Event: %s\r\nPrivilege: %s\r\n", 03284 event, cat_str); 03285 03286 if (timestampevents) { 03287 now = ast_tvnow(); 03288 ast_str_append(&buf, 0, 03289 "Timestamp: %ld.%06lu\r\n", 03290 (long)now.tv_sec, (unsigned long) now.tv_usec); 03291 } 03292 if (manager_debug) { 03293 static int seq; 03294 ast_str_append(&buf, 0, 03295 "SequenceNumber: %d\r\n", 03296 ast_atomic_fetchadd_int(&seq, 1)); 03297 ast_str_append(&buf, 0, 03298 "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func); 03299 } 03300 03301 va_start(ap, fmt); 03302 ast_str_append_va(&buf, 0, fmt, ap); 03303 va_end(ap); 03304 03305 ast_str_append(&buf, 0, "\r\n"); 03306 03307 append_event(buf->str, category); 03308 03309 /* Wake up any sleeping sessions */ 03310 AST_LIST_LOCK(&sessions); 03311 AST_LIST_TRAVERSE(&sessions, session, list) { 03312 ast_mutex_lock(&session->__lock); 03313 if (session->waiting_thread != AST_PTHREADT_NULL) 03314 pthread_kill(session->waiting_thread, SIGURG); 03315 else 03316 /* We have an event to process, but the mansession is 03317 * not waiting for it. We still need to indicate that there 03318 * is an event waiting so that get_input processes the pending 03319 * event instead of polling. 03320 */ 03321 session->pending_event = 1; 03322 ast_mutex_unlock(&session->__lock); 03323 } 03324 AST_LIST_UNLOCK(&sessions); 03325 03326 AST_RWLIST_RDLOCK(&manager_hooks); 03327 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) { 03328 hook->helper(category, event, buf->str); 03329 } 03330 AST_RWLIST_UNLOCK(&manager_hooks); 03331 03332 return 0; 03333 }
static int action_atxfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2141 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, f, name, pbx_builtin_setvar_helper(), and s.
Referenced by __init_manager().
02142 { 02143 const char *name = astman_get_header(m, "Channel"); 02144 const char *exten = astman_get_header(m, "Exten"); 02145 const char *context = astman_get_header(m, "Context"); 02146 struct ast_channel *chan = NULL; 02147 struct ast_call_feature *atxfer_feature = NULL; 02148 char *feature_code = NULL; 02149 02150 if (ast_strlen_zero(name)) { 02151 astman_send_error(s, m, "No channel specified"); 02152 return 0; 02153 } 02154 if (ast_strlen_zero(exten)) { 02155 astman_send_error(s, m, "No extension specified"); 02156 return 0; 02157 } 02158 02159 if (!(atxfer_feature = ast_find_call_feature("atxfer"))) { 02160 astman_send_error(s, m, "No attended transfer feature found"); 02161 return 0; 02162 } 02163 02164 if (!(chan = ast_get_channel_by_name_locked(name))) { 02165 astman_send_error(s, m, "Channel specified does not exist"); 02166 return 0; 02167 } 02168 02169 if (!ast_strlen_zero(context)) { 02170 pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context); 02171 } 02172 02173 for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) { 02174 struct ast_frame f = {AST_FRAME_DTMF, *feature_code}; 02175 ast_queue_frame(chan, &f); 02176 } 02177 02178 for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) { 02179 struct ast_frame f = {AST_FRAME_DTMF, *feature_code}; 02180 ast_queue_frame(chan, &f); 02181 } 02182 02183 astman_send_ack(s, m, "Atxfer successfully queued"); 02184 ast_channel_unlock(chan); 02185 02186 return 0; 02187 }
static int action_challenge | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1736 of file manager.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and s.
Referenced by __init_manager().
01737 { 01738 const char *authtype = astman_get_header(m, "AuthType"); 01739 01740 if (!strcasecmp(authtype, "MD5")) { 01741 if (ast_strlen_zero(s->session->challenge)) 01742 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random()); 01743 ast_mutex_lock(&s->session->__lock); 01744 astman_start_ack(s, m); 01745 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge); 01746 ast_mutex_unlock(&s->session->__lock); 01747 } else { 01748 astman_send_error(s, m, "Must specify AuthType"); 01749 } 01750 return 0; 01751 }
static int action_command | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager command "command" - execute CLI command.
Definition at line 2231 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, S_OR, and term_strip().
Referenced by __init_manager().
02232 { 02233 const char *cmd = astman_get_header(m, "Command"); 02234 const char *id = astman_get_header(m, "ActionID"); 02235 char *buf, *final_buf; 02236 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 02237 int fd = mkstemp(template); 02238 off_t l; 02239 02240 if (ast_strlen_zero(cmd)) { 02241 astman_send_error(s, m, "No command provided"); 02242 return 0; 02243 } 02244 02245 if (check_blacklist(cmd)) { 02246 astman_send_error(s, m, "Command blacklisted"); 02247 return 0; 02248 } 02249 02250 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 02251 if (!ast_strlen_zero(id)) 02252 astman_append(s, "ActionID: %s\r\n", id); 02253 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 02254 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 02255 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 02256 02257 /* This has a potential to overflow the stack. Hence, use the heap. */ 02258 buf = ast_calloc(1, l + 1); 02259 final_buf = ast_calloc(1, l + 1); 02260 if (buf) { 02261 lseek(fd, 0, SEEK_SET); 02262 if (read(fd, buf, l) < 0) { 02263 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 02264 } 02265 buf[l] = '\0'; 02266 if (final_buf) { 02267 term_strip(final_buf, buf, l); 02268 final_buf[l] = '\0'; 02269 } 02270 astman_append(s, "%s", S_OR(final_buf, buf)); 02271 ast_free(buf); 02272 } 02273 close(fd); 02274 unlink(template); 02275 astman_append(s, "--END COMMAND--\r\n\r\n"); 02276 if (final_buf) 02277 ast_free(final_buf); 02278 return 0; 02279 }
static int action_coresettings | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show PBX core settings information.
Definition at line 2679 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, option_maxload, and s.
Referenced by __init_manager().
02680 { 02681 const char *actionid = astman_get_header(m, "ActionID"); 02682 char idText[150]; 02683 02684 if (!ast_strlen_zero(actionid)) 02685 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02686 else 02687 idText[0] = '\0'; 02688 02689 astman_append(s, "Response: Success\r\n" 02690 "%s" 02691 "AMIversion: %s\r\n" 02692 "AsteriskVersion: %s\r\n" 02693 "SystemName: %s\r\n" 02694 "CoreMaxCalls: %d\r\n" 02695 "CoreMaxLoadAvg: %f\r\n" 02696 "CoreRunUser: %s\r\n" 02697 "CoreRunGroup: %s\r\n" 02698 "CoreMaxFilehandles: %d\r\n" 02699 "CoreRealTimeEnabled: %s\r\n" 02700 "CoreCDRenabled: %s\r\n" 02701 "CoreHTTPenabled: %s\r\n" 02702 "\r\n", 02703 idText, 02704 AMI_VERSION, 02705 ast_get_version(), 02706 ast_config_AST_SYSTEM_NAME, 02707 option_maxcalls, 02708 option_maxload, 02709 ast_config_AST_RUN_USER, 02710 ast_config_AST_RUN_GROUP, 02711 option_maxfiles, 02712 ast_realtime_enabled() ? "Yes" : "No", 02713 check_cdr_enabled() ? "Yes" : "No", 02714 check_webmanager_enabled() ? "Yes" : "No" 02715 ); 02716 return 0; 02717 }
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 2784 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, S_OR, ast_cdr::start, and ast_channel::uniqueid.
Referenced by __init_manager().
02785 { 02786 const char *actionid = astman_get_header(m, "ActionID"); 02787 char actionidtext[256]; 02788 struct ast_channel *c = NULL; 02789 int numchans = 0; 02790 int duration, durh, durm, durs; 02791 02792 if (!ast_strlen_zero(actionid)) 02793 snprintf(actionidtext, sizeof(actionidtext), "ActionID: %s\r\n", actionid); 02794 else 02795 actionidtext[0] = '\0'; 02796 02797 astman_send_listack(s, m, "Channels will follow", "start"); 02798 02799 while ((c = ast_channel_walk_locked(c)) != NULL) { 02800 struct ast_channel *bc = ast_bridged_channel(c); 02801 char durbuf[10] = ""; 02802 02803 if (c->cdr && !ast_tvzero(c->cdr->start)) { 02804 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 02805 durh = duration / 3600; 02806 durm = (duration % 3600) / 60; 02807 durs = duration % 60; 02808 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 02809 } 02810 02811 astman_append(s, 02812 "Event: CoreShowChannel\r\n" 02813 "Channel: %s\r\n" 02814 "UniqueID: %s\r\n" 02815 "Context: %s\r\n" 02816 "Extension: %s\r\n" 02817 "Priority: %d\r\n" 02818 "ChannelState: %d\r\n" 02819 "ChannelStateDesc: %s\r\n" 02820 "Application: %s\r\n" 02821 "ApplicationData: %s\r\n" 02822 "CallerIDnum: %s\r\n" 02823 "Duration: %s\r\n" 02824 "AccountCode: %s\r\n" 02825 "BridgedChannel: %s\r\n" 02826 "BridgedUniqueID: %s\r\n" 02827 "\r\n", c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, ast_state2str(c->_state), 02828 c->appl ? c->appl : "", c->data ? S_OR(c->data, ""): "", 02829 S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : ""); 02830 ast_channel_unlock(c); 02831 numchans++; 02832 } 02833 02834 astman_append(s, 02835 "Event: CoreShowChannelsComplete\r\n" 02836 "EventList: Complete\r\n" 02837 "ListItems: %d\r\n" 02838 "%s" 02839 "\r\n", numchans, actionidtext); 02840 02841 return 0; 02842 }
static int action_corestatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show PBX core status information.
Definition at line 2725 of file manager.c.
References ast_active_channels(), ast_lastreloadtime, ast_localtime(), ast_startuptime, ast_strftime(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by __init_manager().
02726 { 02727 const char *actionid = astman_get_header(m, "ActionID"); 02728 char idText[150]; 02729 char startuptime[150]; 02730 char reloadtime[150]; 02731 struct ast_tm tm; 02732 02733 if (!ast_strlen_zero(actionid)) 02734 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02735 else 02736 idText[0] = '\0'; 02737 02738 ast_localtime(&ast_startuptime, &tm, NULL); 02739 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm); 02740 ast_localtime(&ast_lastreloadtime, &tm, NULL); 02741 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm); 02742 02743 astman_append(s, "Response: Success\r\n" 02744 "%s" 02745 "CoreStartupTime: %s\r\n" 02746 "CoreReloadTime: %s\r\n" 02747 "CoreCurrentCalls: %d\r\n" 02748 "\r\n", 02749 idText, 02750 startuptime, 02751 reloadtime, 02752 ast_active_channels() 02753 ); 02754 return 0; 02755 }
static int action_createconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1547 of file manager.c.
References ast_config_AST_CONFIG_DIR, AST_FILE_MODE, ast_str_alloca, ast_str_append(), ast_str_set(), astman_get_header(), astman_send_ack(), astman_send_error(), errno, s, and ast_str::str.
Referenced by __init_manager().
01548 { 01549 int fd; 01550 const char *fn = astman_get_header(m, "Filename"); 01551 struct ast_str *filepath = ast_str_alloca(PATH_MAX); 01552 ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR); 01553 ast_str_append(&filepath, 0, "%s", fn); 01554 01555 if ((fd = open(filepath->str, O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) { 01556 close(fd); 01557 astman_send_ack(s, m, "New configuration file created successfully"); 01558 } else 01559 astman_send_error(s, m, strerror(errno)); 01560 01561 return 0; 01562 }
static int action_events | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1696 of file manager.c.
References astman_append(), astman_get_header(), s, and set_eventmask().
Referenced by __init_manager().
01697 { 01698 const char *mask = astman_get_header(m, "EventMask"); 01699 int res; 01700 01701 res = set_eventmask(s, mask); 01702 if (res > 0) 01703 astman_append(s, "Response: Success\r\n" 01704 "Events: On\r\n"); 01705 else if (res == 0) 01706 astman_append(s, "Response: Success\r\n" 01707 "Events: Off\r\n"); 01708 return 0; 01709 }
static int action_extensionstate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2561 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(), s, and status.
Referenced by __init_manager().
02562 { 02563 const char *exten = astman_get_header(m, "Exten"); 02564 const char *context = astman_get_header(m, "Context"); 02565 char hint[256] = ""; 02566 int status; 02567 if (ast_strlen_zero(exten)) { 02568 astman_send_error(s, m, "Extension not specified"); 02569 return 0; 02570 } 02571 if (ast_strlen_zero(context)) 02572 context = "default"; 02573 status = ast_extension_state(NULL, context, exten); 02574 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 02575 astman_start_ack(s, m); 02576 astman_append(s, "Message: Extension Status\r\n" 02577 "Exten: %s\r\n" 02578 "Context: %s\r\n" 02579 "Hint: %s\r\n" 02580 "Status: %d\r\n\r\n", 02581 exten, context, hint, status); 02582 return 0; 02583 }
static int action_getconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1151 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_flags, ast_variable::name, ast_variable::next, s, and ast_variable::value.
Referenced by __init_manager().
01152 { 01153 struct ast_config *cfg; 01154 const char *fn = astman_get_header(m, "Filename"); 01155 const char *category = astman_get_header(m, "Category"); 01156 int catcount = 0; 01157 int lineno = 0; 01158 char *cur_category = NULL; 01159 struct ast_variable *v; 01160 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01161 01162 if (ast_strlen_zero(fn)) { 01163 astman_send_error(s, m, "Filename not specified"); 01164 return 0; 01165 } 01166 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 01167 astman_send_error(s, m, "Config file not found"); 01168 return 0; 01169 } 01170 01171 astman_start_ack(s, m); 01172 while ((cur_category = ast_category_browse(cfg, cur_category))) { 01173 if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) { 01174 lineno = 0; 01175 astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category); 01176 for (v = ast_variable_browse(cfg, cur_category); v; v = v->next) 01177 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 01178 catcount++; 01179 } 01180 } 01181 if (!ast_strlen_zero(category) && catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */ 01182 astman_append(s, "No categories found\r\n"); 01183 ast_config_destroy(cfg); 01184 astman_append(s, "\r\n"); 01185 01186 return 0; 01187 }
static int action_getconfigjson | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1245 of file manager.c.
References ast_category_browse(), 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_flags, json_escape(), ast_variable::name, ast_variable::next, s, and ast_variable::value.
Referenced by __init_manager().
01246 { 01247 struct ast_config *cfg; 01248 const char *fn = astman_get_header(m, "Filename"); 01249 char *category = NULL; 01250 struct ast_variable *v; 01251 int comma1 = 0; 01252 char *buf = NULL; 01253 unsigned int buf_len = 0; 01254 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01255 01256 if (ast_strlen_zero(fn)) { 01257 astman_send_error(s, m, "Filename not specified"); 01258 return 0; 01259 } 01260 01261 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 01262 astman_send_error(s, m, "Config file not found"); 01263 return 0; 01264 } 01265 01266 buf_len = 512; 01267 buf = alloca(buf_len); 01268 01269 astman_start_ack(s, m); 01270 astman_append(s, "JSON: {"); 01271 while ((category = ast_category_browse(cfg, category))) { 01272 int comma2 = 0; 01273 if (buf_len < 2 * strlen(category) + 1) { 01274 buf_len *= 2; 01275 buf = alloca(buf_len); 01276 } 01277 json_escape(buf, category); 01278 astman_append(s, "%s\"%s\":[", comma1 ? "," : "", buf); 01279 if (!comma1) 01280 comma1 = 1; 01281 for (v = ast_variable_browse(cfg, category); v; v = v->next) { 01282 if (comma2) 01283 astman_append(s, ","); 01284 if (buf_len < 2 * strlen(v->name) + 1) { 01285 buf_len *= 2; 01286 buf = alloca(buf_len); 01287 } 01288 json_escape(buf, v->name); 01289 astman_append(s, "\"%s", buf); 01290 if (buf_len < 2 * strlen(v->value) + 1) { 01291 buf_len *= 2; 01292 buf = alloca(buf_len); 01293 } 01294 json_escape(buf, v->value); 01295 astman_append(s, "%s\"", buf); 01296 if (!comma2) 01297 comma2 = 1; 01298 } 01299 astman_append(s, "]"); 01300 } 01301 astman_append(s, "}\r\n\r\n"); 01302 01303 ast_config_destroy(cfg); 01304 01305 return 0; 01306 }
static int action_getvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1821 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.
Referenced by __init_manager().
01822 { 01823 struct ast_channel *c = NULL; 01824 const char *name = astman_get_header(m, "Channel"); 01825 const char *varname = astman_get_header(m, "Variable"); 01826 char *varval; 01827 char workspace[1024] = ""; 01828 01829 if (ast_strlen_zero(varname)) { 01830 astman_send_error(s, m, "No variable specified"); 01831 return 0; 01832 } 01833 01834 if (!ast_strlen_zero(name)) { 01835 c = ast_get_channel_by_name_locked(name); 01836 if (!c) { 01837 astman_send_error(s, m, "No such channel"); 01838 return 0; 01839 } 01840 } 01841 01842 if (varname[strlen(varname) - 1] == ')') { 01843 if (!c) { 01844 c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/manager"); 01845 if (c) { 01846 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01847 ast_channel_free(c); 01848 } else 01849 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n"); 01850 } else 01851 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01852 varval = workspace; 01853 } else { 01854 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 01855 } 01856 01857 if (c) 01858 ast_channel_unlock(c); 01859 astman_start_ack(s, m); 01860 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, varval); 01861 01862 return 0; 01863 }
static int action_hangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1758 of file manager.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, and s.
Referenced by __init_manager().
01759 { 01760 struct ast_channel *c = NULL; 01761 const char *name = astman_get_header(m, "Channel"); 01762 if (ast_strlen_zero(name)) { 01763 astman_send_error(s, m, "No channel specified"); 01764 return 0; 01765 } 01766 c = ast_get_channel_by_name_locked(name); 01767 if (!c) { 01768 astman_send_error(s, m, "No such channel"); 01769 return 0; 01770 } 01771 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01772 ast_channel_unlock(c); 01773 astman_send_ack(s, m, "Channel Hungup"); 01774 return 0; 01775 }
static int action_listcategories | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1195 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, config_flags, and s.
Referenced by __init_manager().
01196 { 01197 struct ast_config *cfg; 01198 const char *fn = astman_get_header(m, "Filename"); 01199 char *category = NULL; 01200 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01201 int catcount = 0; 01202 01203 if (ast_strlen_zero(fn)) { 01204 astman_send_error(s, m, "Filename not specified"); 01205 return 0; 01206 } 01207 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 01208 astman_send_error(s, m, "Config file not found or file has invalid syntax"); 01209 return 0; 01210 } 01211 astman_start_ack(s, m); 01212 while ((category = ast_category_browse(cfg, category))) { 01213 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 01214 catcount++; 01215 } 01216 if (catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */ 01217 astman_append(s, "Error: no categories found\r\n"); 01218 ast_config_destroy(cfg); 01219 astman_append(s, "\r\n"); 01220 01221 return 0; 01222 }
static int action_listcommands | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1672 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(), s, and manager_action::synopsis.
Referenced by __init_manager().
01673 { 01674 struct manager_action *cur; 01675 struct ast_str *temp = ast_str_alloca(BUFSIZ); /* XXX very large ? */ 01676 01677 astman_start_ack(s, m); 01678 AST_RWLIST_TRAVERSE(&actions, cur, list) { 01679 if (s->session->writeperm & cur->authority || cur->authority == 0) 01680 astman_append(s, "%s: %s (Priv: %s)\r\n", 01681 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp)); 01682 } 01683 astman_append(s, "\r\n"); 01684 01685 return 0; 01686 }
static int action_login | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1721 of file manager.c.
References ast_inet_ntoa(), ast_log(), ast_verb, astman_send_ack(), astman_send_error(), authenticate(), LOG_EVENT, manager_displayconnects(), and s.
Referenced by __init_manager().
01722 { 01723 if (authenticate(s, m)) { 01724 sleep(1); 01725 astman_send_error(s, m, "Authentication failed"); 01726 return -1; 01727 } 01728 s->session->authenticated = 1; 01729 if (manager_displayconnects(s->session)) 01730 ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_inet_ntoa(s->session->sin.sin_addr)); 01731 ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_inet_ntoa(s->session->sin.sin_addr)); 01732 astman_send_ack(s, m, "Authentication accepted"); 01733 return 0; 01734 }
static int action_logoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1715 of file manager.c.
References astman_send_response(), and s.
Referenced by __init_manager().
01716 { 01717 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 01718 return -1; 01719 }
static int action_mailboxcount | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2529 of file manager.c.
References ast_app_inboxcount2(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), mailbox, and s.
Referenced by __init_manager().
02530 { 02531 const char *mailbox = astman_get_header(m, "Mailbox"); 02532 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;; 02533 02534 if (ast_strlen_zero(mailbox)) { 02535 astman_send_error(s, m, "Mailbox not specified"); 02536 return 0; 02537 } 02538 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs); 02539 astman_start_ack(s, m); 02540 astman_append(s, "Message: Mailbox Message Count\r\n" 02541 "Mailbox: %s\r\n" 02542 "UrgMessages: %d\r\n" 02543 "NewMessages: %d\r\n" 02544 "OldMessages: %d\r\n" 02545 "\r\n", 02546 mailbox, urgentmsgs, newmsgs, oldmsgs); 02547 return 0; 02548 }
static int action_mailboxstatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2500 of file manager.c.
References ast_app_has_voicemail(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), mailbox, and s.
Referenced by __init_manager().
02501 { 02502 const char *mailbox = astman_get_header(m, "Mailbox"); 02503 int ret; 02504 02505 if (ast_strlen_zero(mailbox)) { 02506 astman_send_error(s, m, "Mailbox not specified"); 02507 return 0; 02508 } 02509 ret = ast_app_has_voicemail(mailbox, NULL); 02510 astman_start_ack(s, m); 02511 astman_append(s, "Message: Mailbox Status\r\n" 02512 "Mailbox: %s\r\n" 02513 "Waiting: %d\r\n\r\n", mailbox, ret); 02514 return 0; 02515 }
static int action_originate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2363 of file manager.c.
References app, 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(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), ast_frame::data, EVENT_FLAG_SYSTEM, fast_originate(), format, s, and strcasestr().
Referenced by __init_manager().
02364 { 02365 const char *name = astman_get_header(m, "Channel"); 02366 const char *exten = astman_get_header(m, "Exten"); 02367 const char *context = astman_get_header(m, "Context"); 02368 const char *priority = astman_get_header(m, "Priority"); 02369 const char *timeout = astman_get_header(m, "Timeout"); 02370 const char *callerid = astman_get_header(m, "CallerID"); 02371 const char *account = astman_get_header(m, "Account"); 02372 const char *app = astman_get_header(m, "Application"); 02373 const char *appdata = astman_get_header(m, "Data"); 02374 const char *async = astman_get_header(m, "Async"); 02375 const char *id = astman_get_header(m, "ActionID"); 02376 const char *codecs = astman_get_header(m, "Codecs"); 02377 struct ast_variable *vars = astman_get_variables(m); 02378 char *tech, *data; 02379 char *l = NULL, *n = NULL; 02380 int pi = 0; 02381 int res; 02382 int to = 30000; 02383 int reason = 0; 02384 char tmp[256]; 02385 char tmp2[256]; 02386 int format = AST_FORMAT_SLINEAR; 02387 02388 pthread_t th; 02389 if (ast_strlen_zero(name)) { 02390 astman_send_error(s, m, "Channel not specified"); 02391 return 0; 02392 } 02393 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 02394 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 02395 astman_send_error(s, m, "Invalid priority"); 02396 return 0; 02397 } 02398 } 02399 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) { 02400 astman_send_error(s, m, "Invalid timeout"); 02401 return 0; 02402 } 02403 ast_copy_string(tmp, name, sizeof(tmp)); 02404 tech = tmp; 02405 data = strchr(tmp, '/'); 02406 if (!data) { 02407 astman_send_error(s, m, "Invalid channel"); 02408 return 0; 02409 } 02410 *data++ = '\0'; 02411 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 02412 ast_callerid_parse(tmp2, &n, &l); 02413 if (n) { 02414 if (ast_strlen_zero(n)) 02415 n = NULL; 02416 } 02417 if (l) { 02418 ast_shrink_phone_number(l); 02419 if (ast_strlen_zero(l)) 02420 l = NULL; 02421 } 02422 if (!ast_strlen_zero(codecs)) { 02423 format = 0; 02424 ast_parse_allow_disallow(NULL, &format, codecs, 1); 02425 } 02426 if (ast_true(async)) { 02427 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 02428 if (!fast) { 02429 res = -1; 02430 } else { 02431 if (!ast_strlen_zero(id)) 02432 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s", id); 02433 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 02434 ast_copy_string(fast->data, data, sizeof(fast->data)); 02435 ast_copy_string(fast->app, app, sizeof(fast->app)); 02436 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 02437 if (l) 02438 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 02439 if (n) 02440 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 02441 fast->vars = vars; 02442 ast_copy_string(fast->context, context, sizeof(fast->context)); 02443 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 02444 ast_copy_string(fast->account, account, sizeof(fast->account)); 02445 fast->format = format; 02446 fast->timeout = to; 02447 fast->priority = pi; 02448 if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) { 02449 ast_free(fast); 02450 res = -1; 02451 } else { 02452 res = 0; 02453 } 02454 } 02455 } else if (!ast_strlen_zero(app)) { 02456 /* To run the System application (or anything else that goes to shell), you must have the additional System privilege */ 02457 if (!(s->session->writeperm & EVENT_FLAG_SYSTEM) 02458 && ( 02459 strcasestr(app, "system") == 0 || /* System(rm -rf /) 02460 TrySystem(rm -rf /) */ 02461 strcasestr(app, "exec") || /* Exec(System(rm -rf /)) 02462 TryExec(System(rm -rf /)) */ 02463 strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /) 02464 EAGI(/bin/rm,-rf /) */ 02465 strstr(appdata, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */ 02466 strstr(appdata, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */ 02467 )) { 02468 astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have."); 02469 return 0; 02470 } 02471 res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 02472 } else { 02473 if (exten && context && pi) 02474 res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 02475 else { 02476 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 02477 return 0; 02478 } 02479 } 02480 if (!res) 02481 astman_send_ack(s, m, "Originate successfully queued"); 02482 else 02483 astman_send_error(s, m, "Originate failed"); 02484 return 0; 02485 }
static int action_ping | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1136 of file manager.c.
References astman_append(), and s.
Referenced by __init_manager().
01137 { 01138 astman_append(s, "Response: Success\r\n" 01139 "Ping: Pong\r\n" 01140 "\r\n"); 01141 return 0; 01142 }
static int action_redirect | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_redirect: The redirect manager command
Definition at line 2057 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, ast_channel::priority, and s.
Referenced by __init_manager().
02058 { 02059 const char *name = astman_get_header(m, "Channel"); 02060 const char *name2 = astman_get_header(m, "ExtraChannel"); 02061 const char *exten = astman_get_header(m, "Exten"); 02062 const char *context = astman_get_header(m, "Context"); 02063 const char *priority = astman_get_header(m, "Priority"); 02064 struct ast_channel *chan, *chan2 = NULL; 02065 int pi = 0; 02066 int res; 02067 02068 if (ast_strlen_zero(name)) { 02069 astman_send_error(s, m, "Channel not specified"); 02070 return 0; 02071 } 02072 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 02073 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 02074 astman_send_error(s, m, "Invalid priority"); 02075 return 0; 02076 } 02077 } 02078 /* XXX watch out, possible deadlock - we are trying to get two channels!!! */ 02079 chan = ast_get_channel_by_name_locked(name); 02080 if (!chan) { 02081 char buf[256]; 02082 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 02083 astman_send_error(s, m, buf); 02084 return 0; 02085 } 02086 if (ast_check_hangup(chan)) { 02087 astman_send_error(s, m, "Redirect failed, channel not up."); 02088 ast_channel_unlock(chan); 02089 return 0; 02090 } 02091 if (!ast_strlen_zero(name2)) 02092 chan2 = ast_get_channel_by_name_locked(name2); 02093 if (chan2 && ast_check_hangup(chan2)) { 02094 astman_send_error(s, m, "Redirect failed, extra channel not up."); 02095 ast_channel_unlock(chan); 02096 ast_channel_unlock(chan2); 02097 return 0; 02098 } 02099 if (chan->pbx) { 02100 ast_channel_lock(chan); 02101 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 02102 ast_channel_unlock(chan); 02103 } 02104 res = ast_async_goto(chan, context, exten, pi); 02105 if (!res) { 02106 if (!ast_strlen_zero(name2)) { 02107 if (chan2) { 02108 if (chan2->pbx) { 02109 ast_channel_lock(chan2); 02110 ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 02111 ast_channel_unlock(chan2); 02112 } 02113 res = ast_async_goto(chan2, context, exten, pi); 02114 } else { 02115 res = -1; 02116 } 02117 if (!res) 02118 astman_send_ack(s, m, "Dual Redirect successful"); 02119 else 02120 astman_send_error(s, m, "Secondary redirect failed"); 02121 } else 02122 astman_send_ack(s, m, "Redirect successful"); 02123 } else 02124 astman_send_error(s, m, "Redirect failed"); 02125 if (chan) 02126 ast_channel_unlock(chan); 02127 if (chan2) 02128 ast_channel_unlock(chan2); 02129 return 0; 02130 }
static int action_reload | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Send a reload event.
Definition at line 2764 of file manager.c.
References ast_module_reload(), astman_get_header(), astman_send_ack(), astman_send_error(), s, and S_OR.
Referenced by __init_manager().
02765 { 02766 const char *module = astman_get_header(m, "Module"); 02767 int res = ast_module_reload(S_OR(module, NULL)); 02768 02769 if (res == 2) 02770 astman_send_ack(s, m, "Module Reloaded"); 02771 else 02772 astman_send_error(s, m, s == 0 ? "No such module" : "Module does not support reload"); 02773 return 0; 02774 }
static int action_sendtext | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2012 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(), name, and s.
Referenced by __init_manager().
02013 { 02014 struct ast_channel *c = NULL; 02015 const char *name = astman_get_header(m, "Channel"); 02016 const char *textmsg = astman_get_header(m, "Message"); 02017 int res = 0; 02018 02019 if (ast_strlen_zero(name)) { 02020 astman_send_error(s, m, "No channel specified"); 02021 return 0; 02022 } 02023 02024 if (ast_strlen_zero(textmsg)) { 02025 astman_send_error(s, m, "No Message specified"); 02026 return 0; 02027 } 02028 02029 c = ast_get_channel_by_name_locked(name); 02030 if (!c) { 02031 astman_send_error(s, m, "No such channel"); 02032 return 0; 02033 } 02034 02035 res = ast_sendtext(c, textmsg); 02036 ast_channel_unlock(c); 02037 02038 if (res > 0) 02039 astman_send_ack(s, m, "Success"); 02040 else 02041 astman_send_error(s, m, "Failure"); 02042 02043 return res; 02044 }
static int action_setvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1784 of file manager.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, pbx_builtin_setvar_helper(), s, and S_OR.
Referenced by __init_manager().
01785 { 01786 struct ast_channel *c = NULL; 01787 const char *name = astman_get_header(m, "Channel"); 01788 const char *varname = astman_get_header(m, "Variable"); 01789 const char *varval = astman_get_header(m, "Value"); 01790 01791 if (ast_strlen_zero(varname)) { 01792 astman_send_error(s, m, "No variable specified"); 01793 return 0; 01794 } 01795 01796 if (!ast_strlen_zero(name)) { 01797 c = ast_get_channel_by_name_locked(name); 01798 if (!c) { 01799 astman_send_error(s, m, "No such channel"); 01800 return 0; 01801 } 01802 } 01803 01804 pbx_builtin_setvar_helper(c, varname, S_OR(varval, "")); 01805 01806 if (c) 01807 ast_channel_unlock(c); 01808 01809 astman_send_ack(s, m, "Variable Set"); 01810 01811 return 0; 01812 }
static int action_status | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager "status" command to show channels.
Definition at line 1877 of file manager.c.
References AST_APP_ARG, ast_channel_walk_locked(), AST_DECLARE_APP_ARGS, ast_free, ast_func_read(), ast_get_channel_by_name_locked(), AST_STANDARD_APP_ARGS, ast_str_append(), ast_str_create(), ast_str_reset(), ast_strdupa, ast_strlen_zero(), ast_tvnow(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::name, name, pbx_retrieve_variable(), s, S_OR, and str.
Referenced by __init_manager().
01878 { 01879 const char *name = astman_get_header(m, "Channel"); 01880 const char *cvariables = astman_get_header(m, "Variables"); 01881 char *variables = ast_strdupa(S_OR(cvariables, "")); 01882 struct ast_channel *c; 01883 char bridge[256]; 01884 struct timeval now = ast_tvnow(); 01885 long elapsed_seconds = 0; 01886 int channels = 0; 01887 int all = ast_strlen_zero(name); /* set if we want all channels */ 01888 const char *id = astman_get_header(m, "ActionID"); 01889 char idText[256]; 01890 AST_DECLARE_APP_ARGS(vars, 01891 AST_APP_ARG(name)[100]; 01892 ); 01893 struct ast_str *str = ast_str_create(1000); 01894 01895 if (!ast_strlen_zero(id)) 01896 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01897 else 01898 idText[0] = '\0'; 01899 01900 if (all) 01901 c = ast_channel_walk_locked(NULL); 01902 else { 01903 c = ast_get_channel_by_name_locked(name); 01904 if (!c) { 01905 astman_send_error(s, m, "No such channel"); 01906 ast_free(str); 01907 return 0; 01908 } 01909 } 01910 astman_send_ack(s, m, "Channel status will follow"); 01911 01912 if (!ast_strlen_zero(cvariables)) { 01913 AST_STANDARD_APP_ARGS(vars, variables); 01914 } 01915 01916 /* if we look by name, we break after the first iteration */ 01917 while (c) { 01918 if (!ast_strlen_zero(cvariables)) { 01919 int i; 01920 ast_str_reset(str); 01921 for (i = 0; i < vars.argc; i++) { 01922 char valbuf[512], *ret = NULL; 01923 01924 if (vars.name[i][strlen(vars.name[i]) - 1] == ')') { 01925 if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) { 01926 valbuf[0] = '\0'; 01927 } 01928 ret = valbuf; 01929 } else { 01930 pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL); 01931 } 01932 01933 ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret); 01934 } 01935 } 01936 01937 channels++; 01938 if (c->_bridge) 01939 snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid); 01940 else 01941 bridge[0] = '\0'; 01942 if (c->pbx) { 01943 if (c->cdr) { 01944 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01945 } 01946 astman_append(s, 01947 "Event: Status\r\n" 01948 "Privilege: Call\r\n" 01949 "Channel: %s\r\n" 01950 "CallerIDNum: %s\r\n" 01951 "CallerIDName: %s\r\n" 01952 "Accountcode: %s\r\n" 01953 "ChannelState: %d\r\n" 01954 "ChannelStateDesc: %s\r\n" 01955 "Context: %s\r\n" 01956 "Extension: %s\r\n" 01957 "Priority: %d\r\n" 01958 "Seconds: %ld\r\n" 01959 "%s" 01960 "Uniqueid: %s\r\n" 01961 "%s" 01962 "%s" 01963 "\r\n", 01964 c->name, 01965 S_OR(c->cid.cid_num, ""), 01966 S_OR(c->cid.cid_name, ""), 01967 c->accountcode, 01968 c->_state, 01969 ast_state2str(c->_state), c->context, 01970 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, str->str, idText); 01971 } else { 01972 astman_append(s, 01973 "Event: Status\r\n" 01974 "Privilege: Call\r\n" 01975 "Channel: %s\r\n" 01976 "CallerIDNum: %s\r\n" 01977 "CallerIDName: %s\r\n" 01978 "Account: %s\r\n" 01979 "State: %s\r\n" 01980 "%s" 01981 "Uniqueid: %s\r\n" 01982 "%s" 01983 "%s" 01984 "\r\n", 01985 c->name, 01986 S_OR(c->cid.cid_num, "<unknown>"), 01987 S_OR(c->cid.cid_name, "<unknown>"), 01988 c->accountcode, 01989 ast_state2str(c->_state), bridge, c->uniqueid, str->str, idText); 01990 } 01991 ast_channel_unlock(c); 01992 if (!all) 01993 break; 01994 c = ast_channel_walk_locked(c); 01995 } 01996 astman_append(s, 01997 "Event: StatusComplete\r\n" 01998 "%s" 01999 "Items: %d\r\n" 02000 "\r\n", idText, channels); 02001 ast_free(str); 02002 return 0; 02003 }
static int action_timeout | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2592 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 s.
Referenced by __init_manager().
02593 { 02594 struct ast_channel *c; 02595 const char *name = astman_get_header(m, "Channel"); 02596 double timeout = atof(astman_get_header(m, "Timeout")); 02597 struct timeval when = { timeout, 0 }; 02598 02599 if (ast_strlen_zero(name)) { 02600 astman_send_error(s, m, "No channel specified"); 02601 return 0; 02602 } 02603 if (!timeout || timeout < 0) { 02604 astman_send_error(s, m, "No timeout specified"); 02605 return 0; 02606 } 02607 c = ast_get_channel_by_name_locked(name); 02608 if (!c) { 02609 astman_send_error(s, m, "No such channel"); 02610 return 0; 02611 } 02612 02613 when.tv_usec = (timeout - when.tv_sec) * 1000000.0; 02614 ast_channel_setwhentohangup_tv(c, when); 02615 ast_channel_unlock(c); 02616 astman_send_ack(s, m, "Timeout Set"); 02617 return 0; 02618 }
static int action_updateconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1466 of file manager.c.
References ast_config_destroy(), ast_config_load2(), 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_flags, config_text_file_save(), FAILURE_ALLOCATION, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, handle_updates(), s, UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, and UNSPECIFIED_CATEGORY.
Referenced by __init_manager().
01467 { 01468 struct ast_config *cfg; 01469 const char *sfn = astman_get_header(m, "SrcFilename"); 01470 const char *dfn = astman_get_header(m, "DstFilename"); 01471 int res; 01472 const char *rld = astman_get_header(m, "Reload"); 01473 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01474 enum error_type result; 01475 01476 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { 01477 astman_send_error(s, m, "Filename not specified"); 01478 return 0; 01479 } 01480 if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) { 01481 astman_send_error(s, m, "Config file not found"); 01482 return 0; 01483 } 01484 result = handle_updates(s, m, cfg, dfn); 01485 if (!result) { 01486 ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */ 01487 res = config_text_file_save(dfn, cfg, "Manager"); 01488 ast_config_destroy(cfg); 01489 if (res) { 01490 astman_send_error(s, m, "Save of config failed"); 01491 return 0; 01492 } 01493 astman_send_ack(s, m, NULL); 01494 if (!ast_strlen_zero(rld)) { 01495 if (ast_true(rld)) 01496 rld = NULL; 01497 ast_module_reload(rld); 01498 } 01499 } else { 01500 ast_config_destroy(cfg); 01501 switch(result) { 01502 case UNKNOWN_ACTION: 01503 astman_send_error(s, m, "Unknown action command"); 01504 break; 01505 case UNKNOWN_CATEGORY: 01506 astman_send_error(s, m, "Given category does not exist"); 01507 break; 01508 case UNSPECIFIED_CATEGORY: 01509 astman_send_error(s, m, "Category not specified"); 01510 break; 01511 case UNSPECIFIED_ARGUMENT: 01512 astman_send_error(s, m, "Problem with category, value, or line (if required)"); 01513 break; 01514 case FAILURE_ALLOCATION: 01515 astman_send_error(s, m, "Memory allocation failure, this should not happen"); 01516 break; 01517 case FAILURE_NEWCAT: 01518 astman_send_error(s, m, "Create category did not complete successfully"); 01519 break; 01520 case FAILURE_DELCAT: 01521 astman_send_error(s, m, "Delete category did not complete successfully"); 01522 break; 01523 case FAILURE_EMPTYCAT: 01524 astman_send_error(s, m, "Empty category did not complete successfully"); 01525 break; 01526 case FAILURE_UPDATE: 01527 astman_send_error(s, m, "Update did not complete successfully"); 01528 break; 01529 case FAILURE_DELETE: 01530 astman_send_error(s, m, "Delete did not complete successfully"); 01531 break; 01532 case FAILURE_APPEND: 01533 astman_send_error(s, m, "Append did not complete successfully"); 01534 break; 01535 } 01536 } 01537 return 0; 01538 }
static int action_userevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2655 of file manager.c.
References ast_str_append(), ast_str_reset(), ast_str_thread_get(), astman_get_header(), EVENT_FLAG_USER, message::hdrcount, message::headers, manager_event, ast_str::str, and userevent_buf.
Referenced by __init_manager().
02656 { 02657 const char *event = astman_get_header(m, "UserEvent"); 02658 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16); 02659 int x; 02660 02661 ast_str_reset(body); 02662 02663 for (x = 0; x < m->hdrcount; x++) { 02664 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 02665 ast_str_append(&body, 0, "%s\r\n", m->headers[x]); 02666 } 02667 } 02668 02669 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body->str); 02670 return 0; 02671 }
static int action_waitevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1572 of file manager.c.
References ast_debug, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_strlen_zero(), ast_wait_for_input(), astman_get_header(), NEW_EVENT, and s.
Referenced by __init_manager().
01573 { 01574 const char *timeouts = astman_get_header(m, "Timeout"); 01575 int timeout = -1; 01576 int x; 01577 int needexit = 0; 01578 const char *id = astman_get_header(m, "ActionID"); 01579 char idText[256]; 01580 01581 if (!ast_strlen_zero(id)) 01582 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01583 else 01584 idText[0] = '\0'; 01585 01586 if (!ast_strlen_zero(timeouts)) { 01587 sscanf(timeouts, "%i", &timeout); 01588 if (timeout < -1) 01589 timeout = -1; 01590 /* XXX maybe put an upper bound, or prevent the use of 0 ? */ 01591 } 01592 01593 ast_mutex_lock(&s->session->__lock); 01594 if (s->session->waiting_thread != AST_PTHREADT_NULL) 01595 pthread_kill(s->session->waiting_thread, SIGURG); 01596 01597 if (s->session->managerid) { /* AMI-over-HTTP session */ 01598 /* 01599 * Make sure the timeout is within the expire time of the session, 01600 * as the client will likely abort the request if it does not see 01601 * data coming after some amount of time. 01602 */ 01603 time_t now = time(NULL); 01604 int max = s->session->sessiontimeout - now - 10; 01605 01606 if (max < 0) /* We are already late. Strange but possible. */ 01607 max = 0; 01608 if (timeout < 0 || timeout > max) 01609 timeout = max; 01610 if (!s->session->send_events) /* make sure we record events */ 01611 s->session->send_events = -1; 01612 } 01613 ast_mutex_unlock(&s->session->__lock); 01614 01615 /* XXX should this go inside the lock ? */ 01616 s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */ 01617 ast_debug(1, "Starting waiting for an event!\n"); 01618 01619 for (x = 0; x < timeout || timeout < 0; x++) { 01620 ast_mutex_lock(&s->session->__lock); 01621 if (NEW_EVENT(s)) 01622 needexit = 1; 01623 /* We can have multiple HTTP session point to the same mansession entry. 01624 * The way we deal with it is not very nice: newcomers kick out the previous 01625 * HTTP session. XXX this needs to be improved. 01626 */ 01627 if (s->session->waiting_thread != pthread_self()) 01628 needexit = 1; 01629 if (s->session->needdestroy) 01630 needexit = 1; 01631 ast_mutex_unlock(&s->session->__lock); 01632 if (needexit) 01633 break; 01634 if (s->session->managerid == 0) { /* AMI session */ 01635 if (ast_wait_for_input(s->session->fd, 1000)) 01636 break; 01637 } else { /* HTTP session */ 01638 sleep(1); 01639 } 01640 } 01641 ast_debug(1, "Finished waiting for an event!\n"); 01642 ast_mutex_lock(&s->session->__lock); 01643 if (s->session->waiting_thread == pthread_self()) { 01644 struct eventqent *eqe; 01645 astman_send_response(s, m, "Success", "Waiting for Event completed."); 01646 while ( (eqe = NEW_EVENT(s)) ) { 01647 ref_event(eqe); 01648 if (((s->session->readperm & eqe->category) == eqe->category) && 01649 ((s->session->send_events & eqe->category) == eqe->category)) { 01650 astman_append(s, "%s", eqe->eventdata); 01651 } 01652 s->session->last_ev = unref_event(s->session->last_ev); 01653 } 01654 astman_append(s, 01655 "Event: WaitEventComplete\r\n" 01656 "%s" 01657 "\r\n", idText); 01658 s->session->waiting_thread = AST_PTHREADT_NULL; 01659 } else { 01660 ast_debug(1, "Abandoning event request!\n"); 01661 } 01662 ast_mutex_unlock(&s->session->__lock); 01663 return 0; 01664 }
static int append_event | ( | const char * | str, | |
int | category | |||
) | [static] |
Definition at line 3236 of file manager.c.
References ast_atomic_fetchadd_int(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_UNLOCK, ast_malloc, and seq.
Referenced by __init_manager(), and __manager_event().
03237 { 03238 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 03239 static int seq; /* sequence number */ 03240 03241 if (!tmp) 03242 return -1; 03243 03244 /* need to init all fields, because ast_malloc() does not */ 03245 tmp->usecount = 0; 03246 tmp->category = category; 03247 tmp->seq = ast_atomic_fetchadd_int(&seq, 1); 03248 AST_LIST_NEXT(tmp, eq_next) = NULL; 03249 strcpy(tmp->eventdata, str); 03250 03251 AST_LIST_LOCK(&all_events); 03252 AST_LIST_INSERT_TAIL(&all_events, tmp, eq_next); 03253 AST_LIST_UNLOCK(&all_events); 03254 03255 return 0; 03256 }
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 413 of file manager.c.
References eventqent::next.
Referenced by get_perm().
00414 { 00415 const char *val = bigstr, *next; 00416 00417 do { 00418 if ((next = strchr(val, delim))) { 00419 if (!strncmp(val, smallstr, (next - val))) 00420 return 1; 00421 else 00422 continue; 00423 } else 00424 return !strcmp(smallstr, val); 00425 } while (*(val = (next + 1))); 00426 00427 return 0; 00428 }
int ast_manager_register2 | ( | const char * | action, | |
int | authority, | |||
int(*)(struct mansession *s, const struct message *m) | func, | |||
const char * | synopsis, | |||
const char * | description | |||
) |
Register a manager command with the manager interface.
action | Name of the requested Action: | |
authority | Required authority for this command | |
func | Function to call for this command | |
synopsis | Help text (one line, up to 30 chars) for CLI manager show commands | |
description | Help text, several lines |
Definition at line 3407 of file manager.c.
References ast_calloc, ast_free, and ast_manager_register_struct().
Referenced by __init_manager(), ast_features_init(), load_module(), and load_pbx().
03408 { 03409 struct manager_action *cur = NULL; 03410 03411 if (!(cur = ast_calloc(1, sizeof(*cur)))) 03412 return -1; 03413 03414 cur->action = action; 03415 cur->authority = auth; 03416 cur->func = func; 03417 cur->synopsis = synopsis; 03418 cur->description = description; 03419 03420 if (ast_manager_register_struct(cur)) { 03421 ast_free(cur); 03422 return -1; 03423 } 03424 03425 return 0; 03426 }
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
hook | struct manager_custom_hook object to add |
Definition at line 256 of file manager.c.
References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
00257 { 00258 AST_RWLIST_WRLOCK(&manager_hooks); 00259 AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list); 00260 AST_RWLIST_UNLOCK(&manager_hooks); 00261 return; 00262 }
static int ast_manager_register_struct | ( | struct manager_action * | act | ) | [static] |
Definition at line 3371 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 tv.
Referenced by ast_manager_register2().
03372 { 03373 struct manager_action *cur, *prev = NULL; 03374 struct timespec tv = { 5, }; 03375 03376 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03377 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03378 return -1; 03379 } 03380 AST_RWLIST_TRAVERSE(&actions, cur, list) { 03381 int ret = strcasecmp(cur->action, act->action); 03382 if (ret == 0) { 03383 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 03384 AST_RWLIST_UNLOCK(&actions); 03385 return -1; 03386 } 03387 if (ret > 0) { /* Insert these alphabetically */ 03388 prev = cur; 03389 break; 03390 } 03391 } 03392 03393 if (prev) 03394 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list); 03395 else 03396 AST_RWLIST_INSERT_HEAD(&actions, act, list); 03397 03398 ast_verb(2, "Manager registered action %s\n", act->action); 03399 03400 AST_RWLIST_UNLOCK(&actions); 03401 03402 return 0; 03403 }
int ast_manager_unregister | ( | char * | action | ) |
Unregister a registered manager command.
action | Name of registered Action: |
Definition at line 3338 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 tv.
Referenced by __unload_module(), and unload_module().
03339 { 03340 struct manager_action *cur; 03341 struct timespec tv = { 5, }; 03342 03343 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03344 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03345 return -1; 03346 } 03347 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) { 03348 if (!strcasecmp(action, cur->action)) { 03349 AST_RWLIST_REMOVE_CURRENT(list); 03350 ast_free(cur); 03351 ast_verb(2, "Manager unregistered action %s\n", action); 03352 break; 03353 } 03354 } 03355 AST_RWLIST_TRAVERSE_SAFE_END; 03356 AST_RWLIST_UNLOCK(&actions); 03357 03358 return 0; 03359 }
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
hook | struct manager_custom_hook object to delete |
Definition at line 265 of file manager.c.
References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
00266 { 00267 AST_RWLIST_WRLOCK(&manager_hooks); 00268 AST_RWLIST_REMOVE(&manager_hooks, hook, list); 00269 AST_RWLIST_UNLOCK(&manager_hooks); 00270 return; 00271 }
void astman_append | ( | struct mansession * | s, | |
const char * | fmt, | |||
... | ||||
) |
utility functions for creating AMI replies
Definition at line 968 of file manager.c.
References ast_str_set_va(), ast_str_thread_get(), ast_verbose, astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE, buf, s, and send_string().
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), 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(), ast_cli_netstats(), astman_send_response_full(), do_print(), manager_dbget(), manager_iax2_show_netstats(), manager_iax2_show_peer_list(), 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_helper(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), rpt_manager_do_stats(), rpt_manager_success(), and session_do().
00969 { 00970 va_list ap; 00971 struct ast_str *buf; 00972 00973 if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) 00974 return; 00975 00976 va_start(ap, fmt); 00977 ast_str_set_va(&buf, 0, fmt, ap); 00978 va_end(ap); 00979 00980 if (s->f != NULL || s->session->f != NULL) { 00981 send_string(s, buf->str); 00982 } else { 00983 ast_verbose("fd == -1 in astman_append, should not happen\n"); 00984 } 00985 }
const char* astman_get_header | ( | const struct message * | m, | |
char * | var | |||
) |
Get header from mananger transaction.
Definition at line 896 of file manager.c.
References __astman_get_header(), and GET_HEADER_FIRST_MATCH.
Referenced by _sip_show_peer(), _sip_show_peers(), 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_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_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_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(), meetmemute(), process_message(), rpt_manager_do_stats(), rpt_manager_success(), start_monitor_action(), and stop_monitor_action().
00897 { 00898 return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH); 00899 }
struct ast_variable* astman_get_variables | ( | const struct message * | m | ) |
Get a linked list of the Variable: headers.
Definition at line 902 of file manager.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_variable_new(), message::hdrcount, message::headers, parse(), strsep(), and var.
Referenced by action_originate(), and manager_sipnotify().
00903 { 00904 int varlen, x, y; 00905 struct ast_variable *head = NULL, *cur; 00906 00907 AST_DECLARE_APP_ARGS(args, 00908 AST_APP_ARG(vars)[32]; 00909 ); 00910 00911 varlen = strlen("Variable: "); 00912 00913 for (x = 0; x < m->hdrcount; x++) { 00914 char *parse, *var, *val; 00915 00916 if (strncasecmp("Variable: ", m->headers[x], varlen)) 00917 continue; 00918 parse = ast_strdupa(m->headers[x] + varlen); 00919 00920 AST_STANDARD_APP_ARGS(args, parse); 00921 if (!args.argc) 00922 continue; 00923 for (y = 0; y < args.argc; y++) { 00924 if (!args.vars[y]) 00925 continue; 00926 var = val = ast_strdupa(args.vars[y]); 00927 strsep(&val, "="); 00928 if (!val || ast_strlen_zero(var)) 00929 continue; 00930 cur = ast_variable_new(var, val, ""); 00931 cur->next = head; 00932 head = cur; 00933 } 00934 } 00935 00936 return head; 00937 }
void astman_send_ack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg | |||
) |
Send ack in manager transaction.
Definition at line 1031 of file manager.c.
References astman_send_response_full(), and s.
Referenced by action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_atxfer(), action_bridge(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_dahdishowchannels(), action_hangup(), action_login(), 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_iax2_show_peers(), manager_jabber_send(), manager_list_voicemail_users(), manager_moduleload(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_sipnotify(), meetmemute(), start_monitor_action(), and stop_monitor_action().
01032 { 01033 astman_send_response_full(s, m, "Success", msg, NULL); 01034 }
void astman_send_error | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | error | |||
) |
Send error in manager transaction.
Definition at line 1026 of file manager.c.
References astman_send_response_full(), and s.
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_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_remove_queue_member(), manager_rpt_status(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sipnotify(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
01027 { 01028 astman_send_response_full(s, m, "Error", error, NULL); 01029 }
void astman_send_listack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg, | |||
char * | listflag | |||
) |
Send ack in manager list transaction.
Definition at line 1041 of file manager.c.
References astman_send_response_full(), and s.
Referenced by action_coreshowchannels(), action_meetmelist(), manager_dpsendack(), manager_show_registry(), and manager_sip_show_peers().
01042 { 01043 astman_send_response_full(s, m, "Success", msg, listflag); 01044 }
void astman_send_response | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg | |||
) |
Send response in manager transaction.
Definition at line 1021 of file manager.c.
References astman_send_response_full(), and s.
Referenced by action_logoff().
01022 { 01023 astman_send_response_full(s, m, resp, msg, NULL); 01024 }
static void astman_send_response_full | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg, | |||
char * | listflag | |||
) | [static] |
Definition at line 1004 of file manager.c.
References ast_strlen_zero(), astman_append(), astman_get_header(), MSG_MOREDATA, and s.
Referenced by astman_send_ack(), astman_send_error(), astman_send_listack(), astman_send_response(), and astman_start_ack().
01005 { 01006 const char *id = astman_get_header(m, "ActionID"); 01007 01008 astman_append(s, "Response: %s\r\n", resp); 01009 if (!ast_strlen_zero(id)) 01010 astman_append(s, "ActionID: %s\r\n", id); 01011 if (listflag) 01012 astman_append(s, "Eventlist: %s\r\n", listflag); /* Start, complete, cancelled */ 01013 if (msg == MSG_MOREDATA) 01014 return; 01015 else if (msg) 01016 astman_append(s, "Message: %s\r\n\r\n", msg); 01017 else 01018 astman_append(s, "\r\n"); 01019 }
static void astman_start_ack | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1036 of file manager.c.
References astman_send_response_full(), MSG_MOREDATA, and s.
Referenced by action_challenge(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_mailboxcount(), and action_mailboxstatus().
01037 { 01038 astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL); 01039 }
static int authenticate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1070 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(), get_manager_by_name_locked(), len(), LOG_NOTICE, md5(), MD5Final(), MD5Init(), MD5Update(), s, S_OR, set_eventmask(), and user.
Referenced by action_login(), authenticate_reply(), and registry_rerequest().
01071 { 01072 const char *username = astman_get_header(m, "Username"); 01073 const char *password = astman_get_header(m, "Secret"); 01074 int error = -1; 01075 struct ast_manager_user *user = NULL; 01076 01077 if (ast_strlen_zero(username)) /* missing username */ 01078 return -1; 01079 01080 /* locate user in locked state */ 01081 AST_RWLIST_WRLOCK(&users); 01082 01083 if (!(user = get_manager_by_name_locked(username))) { 01084 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01085 } else if (user->ha && !ast_apply_ha(user->ha, &(s->session->sin))) { 01086 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01087 } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) { 01088 const char *key = astman_get_header(m, "Key"); 01089 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) { 01090 int x; 01091 int len = 0; 01092 char md5key[256] = ""; 01093 struct MD5Context md5; 01094 unsigned char digest[16]; 01095 01096 MD5Init(&md5); 01097 MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge)); 01098 MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret)); 01099 MD5Final(digest, &md5); 01100 for (x = 0; x < 16; x++) 01101 len += sprintf(md5key + len, "%2.2x", digest[x]); 01102 if (!strcmp(md5key, key)) 01103 error = 0; 01104 } else { 01105 ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n", 01106 S_OR(s->session->challenge, "")); 01107 } 01108 } else if (password && user->secret && !strcmp(password, user->secret)) 01109 error = 0; 01110 01111 if (error) { 01112 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01113 AST_RWLIST_UNLOCK(&users); 01114 return -1; 01115 } 01116 01117 /* auth complete */ 01118 01119 ast_copy_string(s->session->username, username, sizeof(s->session->username)); 01120 s->session->readperm = user->readperm; 01121 s->session->writeperm = user->writeperm; 01122 s->session->writetimeout = user->writetimeout; 01123 s->session->sessionstart = time(NULL); 01124 set_eventmask(s, astman_get_header(m, "Events")); 01125 01126 AST_RWLIST_UNLOCK(&users); 01127 return 0; 01128 }
static char* authority_to_str | ( | int | authority, | |
struct ast_str ** | res | |||
) | [static] |
Convert authority code to a list of options.
Definition at line 389 of file manager.c.
References ARRAY_LEN, ast_str_append(), num, and perms.
Referenced by __manager_event(), action_listcommands(), handle_showmanager(), handle_showmancmd(), and handle_showmancmds().
00390 { 00391 int i; 00392 char *sep = ""; 00393 00394 (*res)->used = 0; 00395 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) { 00396 if (authority & perms[i].num) { 00397 ast_str_append(res, 0, "%s%s", sep, perms[i].label); 00398 sep = ","; 00399 } 00400 } 00401 00402 if ((*res)->used == 0) /* replace empty string with something sensible */ 00403 ast_str_append(res, 0, "<none>"); 00404 00405 return (*res)->str; 00406 }
static int check_blacklist | ( | const char * | cmd | ) | [static] |
Definition at line 2189 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().
02190 { 02191 char *cmd_copy, *cur_cmd; 02192 char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, }; 02193 int i; 02194 02195 cmd_copy = ast_strdupa(cmd); 02196 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) { 02197 cur_cmd = ast_strip(cur_cmd); 02198 if (ast_strlen_zero(cur_cmd)) { 02199 i--; 02200 continue; 02201 } 02202 02203 cmd_words[i] = cur_cmd; 02204 } 02205 02206 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) { 02207 int j, match = 1; 02208 02209 for (j = 0; command_blacklist[i].words[j]; j++) { 02210 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) { 02211 match = 0; 02212 break; 02213 } 02214 } 02215 02216 if (match) { 02217 return 1; 02218 } 02219 } 02220 02221 return 0; 02222 }
int check_manager_enabled | ( | void | ) |
Check if AMI is enabled.
Definition at line 316 of file manager.c.
Referenced by handle_show_settings().
00317 { 00318 return manager_enabled; 00319 }
static int check_manager_session_inuse | ( | const char * | name | ) | [static] |
Definition at line 472 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().
00473 { 00474 struct mansession_session *session = NULL; 00475 00476 AST_LIST_LOCK(&sessions); 00477 AST_LIST_TRAVERSE(&sessions, session, list) { 00478 if (!strcasecmp(session->username, name)) 00479 break; 00480 } 00481 AST_LIST_UNLOCK(&sessions); 00482 00483 return session ? 1 : 0; 00484 }
int check_webmanager_enabled | ( | void | ) |
Check if AMI/HTTP is enabled.
Definition at line 321 of file manager.c.
Referenced by action_coresettings(), and handle_show_settings().
00322 { 00323 return (webmanager_enabled && manager_enabled); 00324 }
static void destroy_session | ( | struct mansession_session * | session | ) | [static] |
Definition at line 851 of file manager.c.
References ast_atomic_fetchadd_int(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, and free_session().
Referenced by accept_thread(), and skinny_session().
00852 { 00853 AST_LIST_LOCK(&sessions); 00854 AST_LIST_REMOVE(&sessions, session, list); 00855 ast_atomic_fetchadd_int(&num_sessions, -1); 00856 free_session(session); 00857 AST_LIST_UNLOCK(&sessions); 00858 }
static int do_message | ( | struct mansession * | s | ) | [static] |
Definition at line 3100 of file manager.c.
References AST_MAX_MANHEADERS, ast_strdupa, ast_strlen_zero(), get_input(), message::hdrcount, message::headers, process_events(), process_message(), and s.
Referenced by session_do().
03101 { 03102 struct message m = { 0 }; 03103 char header_buf[sizeof(s->session->inbuf)] = { '\0' }; 03104 int res; 03105 03106 for (;;) { 03107 /* Check if any events are pending and do them if needed */ 03108 if (process_events(s)) 03109 return -1; 03110 res = get_input(s, header_buf); 03111 if (res == 0) { 03112 continue; 03113 } else if (res > 0) { 03114 if (ast_strlen_zero(header_buf)) 03115 return process_message(s, &m) ? -1 : 0; 03116 else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) 03117 m.headers[m.hdrcount++] = ast_strdupa(header_buf); 03118 } else { 03119 return res; 03120 } 03121 } 03122 }
static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 2300 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, 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().
02301 { 02302 struct fast_originate_helper *in = data; 02303 int res; 02304 int reason = 0; 02305 struct ast_channel *chan = NULL; 02306 char requested_channel[AST_CHANNEL_NAME]; 02307 02308 if (!ast_strlen_zero(in->app)) { 02309 res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1, 02310 S_OR(in->cid_num, NULL), 02311 S_OR(in->cid_name, NULL), 02312 in->vars, in->account, &chan); 02313 } else { 02314 res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 02315 S_OR(in->cid_num, NULL), 02316 S_OR(in->cid_name, NULL), 02317 in->vars, in->account, &chan); 02318 } 02319 02320 if (!chan) 02321 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 02322 /* Tell the manager what happened with the channel */ 02323 manager_event(EVENT_FLAG_CALL, "OriginateResponse", 02324 "%s%s" 02325 "Response: %s\r\n" 02326 "Channel: %s\r\n" 02327 "Context: %s\r\n" 02328 "Exten: %s\r\n" 02329 "Reason: %d\r\n" 02330 "Uniqueid: %s\r\n" 02331 "CallerIDNum: %s\r\n" 02332 "CallerIDName: %s\r\n", 02333 in->idtext, ast_strlen_zero(in->idtext) ? "" : "\r\n", res ? "Failure" : "Success", 02334 chan ? chan->name : requested_channel, in->context, in->exten, reason, 02335 chan ? chan->uniqueid : "<null>", 02336 S_OR(in->cid_num, "<unknown>"), 02337 S_OR(in->cid_name, "<unknown>") 02338 ); 02339 02340 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 02341 if (chan) 02342 ast_channel_unlock(chan); 02343 ast_free(in); 02344 return NULL; 02345 }
static void free_session | ( | struct mansession_session * | session | ) | [static] |
Definition at line 833 of file manager.c.
References mansession_session::__lock, 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 unref_event().
Referenced by destroy_session(), and purge_sessions().
00834 { 00835 struct eventqent *eqe = session->last_ev; 00836 struct ast_datastore *datastore; 00837 00838 /* Get rid of each of the data stores on the session */ 00839 while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) { 00840 /* Free the data store */ 00841 ast_datastore_free(datastore); 00842 } 00843 00844 if (session->f != NULL) 00845 fclose(session->f); 00846 ast_mutex_destroy(&session->__lock); 00847 ast_free(session); 00848 unref_event(eqe); 00849 }
static int get_input | ( | struct mansession * | s, | |
char * | output | |||
) | [static] |
Read one full line (including crlf) from the manager socket.
* \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 3030 of file manager.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_wait_for_input(), errno, LOG_WARNING, s, and ast_frame::src.
Referenced by do_message(), and skinny_session().
03031 { 03032 int res, x; 03033 int maxlen = sizeof(s->session->inbuf) - 1; 03034 char *src = s->session->inbuf; 03035 03036 /* 03037 * Look for \r\n within the buffer. If found, copy to the output 03038 * buffer and return, trimming the \r\n (not used afterwards). 03039 */ 03040 for (x = 0; x < s->session->inlen; x++) { 03041 int cr; /* set if we have \r */ 03042 if (src[x] == '\r' && x+1 < s->session->inlen && src[x+1] == '\n') 03043 cr = 2; /* Found. Update length to include \r\n */ 03044 else if (src[x] == '\n') 03045 cr = 1; /* also accept \n only */ 03046 else 03047 continue; 03048 memmove(output, src, x); /*... but trim \r\n */ 03049 output[x] = '\0'; /* terminate the string */ 03050 x += cr; /* number of bytes used */ 03051 s->session->inlen -= x; /* remaining size */ 03052 memmove(src, src + x, s->session->inlen); /* remove used bytes */ 03053 return 1; 03054 } 03055 if (s->session->inlen >= maxlen) { 03056 /* no crlf found, and buffer full - sorry, too long for us */ 03057 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src); 03058 s->session->inlen = 0; 03059 } 03060 res = 0; 03061 while (res == 0) { 03062 /* XXX do we really need this locking ? */ 03063 ast_mutex_lock(&s->session->__lock); 03064 if (s->session->pending_event) { 03065 s->session->pending_event = 0; 03066 ast_mutex_unlock(&s->session->__lock); 03067 return 0; 03068 } 03069 s->session->waiting_thread = pthread_self(); 03070 ast_mutex_unlock(&s->session->__lock); 03071 03072 res = ast_wait_for_input(s->session->fd, -1); /* return 0 on timeout ? */ 03073 03074 ast_mutex_lock(&s->session->__lock); 03075 s->session->waiting_thread = AST_PTHREADT_NULL; 03076 ast_mutex_unlock(&s->session->__lock); 03077 } 03078 if (res < 0) { 03079 /* If we get a signal from some other thread (typically because 03080 * there are new events queued), return 0 to notify the caller. 03081 */ 03082 if (errno == EINTR || errno == EAGAIN) 03083 return 0; 03084 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno)); 03085 return -1; 03086 } 03087 ast_mutex_lock(&s->session->__lock); 03088 res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f); 03089 if (res < 1) 03090 res = -1; /* error return */ 03091 else { 03092 s->session->inlen += res; 03093 src[s->session->inlen] = '\0'; 03094 res = 0; 03095 } 03096 ast_mutex_unlock(&s->session->__lock); 03097 return res; 03098 }
static struct ast_manager_user* get_manager_by_name_locked | ( | const char * | name | ) | [static] |
lookup an entry in the list of registered users. must be called with the list lock held.
Definition at line 491 of file manager.c.
References AST_RWLIST_TRAVERSE, ast_manager_user::list, and user.
Referenced by authenticate(), handle_showmanager(), and manager_displayconnects().
00492 { 00493 struct ast_manager_user *user = NULL; 00494 00495 AST_RWLIST_TRAVERSE(&users, user, list) 00496 if (!strcasecmp(user->username, name)) 00497 break; 00498 return user; 00499 }
static int get_perm | ( | const char * | instr | ) | [static] |
Definition at line 430 of file manager.c.
References ARRAY_LEN, ast_instring(), permalias::num, and perms.
Referenced by strings_to_mask().
00431 { 00432 int x = 0, ret = 0; 00433 00434 if (!instr) 00435 return 0; 00436 00437 for (x = 0; x < ARRAY_LEN(perms); x++) { 00438 if (ast_instring(instr, perms[x].label, ',')) 00439 ret |= perms[x].num; 00440 } 00441 00442 return ret; 00443 }
static struct eventqent* grab_last | ( | void | ) | [static] |
Grab a reference to the last event, update usecount as needed. Can handle a NULL pointer.
Definition at line 330 of file manager.c.
References ast_atomic_fetchadd_int(), AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_UNLOCK, and eventqent::usecount.
Referenced by session_do().
00331 { 00332 struct eventqent *ret; 00333 00334 AST_LIST_LOCK(&all_events); 00335 ret = AST_LIST_LAST(&all_events); 00336 /* the list is never empty now, but may become so when 00337 * we optimize it in the future, so be prepared. 00338 */ 00339 if (ret) 00340 ast_atomic_fetchadd_int(&ret->usecount, 1); 00341 AST_LIST_UNLOCK(&all_events); 00342 return ret; 00343 }
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 783 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.
00784 { 00785 switch (cmd) { 00786 case CLI_INIT: 00787 e->command = "manager reload"; 00788 e->usage = 00789 "Usage: manager reload\n" 00790 " Reloads the manager configuration.\n"; 00791 return NULL; 00792 case CLI_GENERATE: 00793 return NULL; 00794 } 00795 if (a->argc > 2) 00796 return CLI_SHOWUSAGE; 00797 reload_manager(); 00798 return CLI_SUCCESS; 00799 }
static char* handle_mandebug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 564 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.
00565 { 00566 switch (cmd) { 00567 case CLI_INIT: 00568 e->command = "manager debug [on|off]"; 00569 e->usage = "Usage: manager debug [on|off]\n Show, enable, disable debugging of the manager code.\n"; 00570 return NULL; 00571 case CLI_GENERATE: 00572 return NULL; 00573 } 00574 if (a->argc == 2) 00575 ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off"); 00576 else if (a->argc == 3) { 00577 if (!strcasecmp(a->argv[2], "on")) 00578 manager_debug = 1; 00579 else if (!strcasecmp(a->argv[2], "off")) 00580 manager_debug = 0; 00581 else 00582 return CLI_SHOWUSAGE; 00583 } 00584 return CLI_SUCCESS; 00585 }
static char* handle_showmanager | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 587 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_cli_args::fd, get_manager_by_name_locked(), ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, user, and ast_cli_args::word.
00588 { 00589 struct ast_manager_user *user = NULL; 00590 int l, which; 00591 char *ret = NULL; 00592 struct ast_str *rauthority = ast_str_alloca(128); 00593 struct ast_str *wauthority = ast_str_alloca(128); 00594 00595 switch (cmd) { 00596 case CLI_INIT: 00597 e->command = "manager show user"; 00598 e->usage = 00599 " Usage: manager show user <user>\n" 00600 " Display all information related to the manager user specified.\n"; 00601 return NULL; 00602 case CLI_GENERATE: 00603 l = strlen(a->word); 00604 which = 0; 00605 if (a->pos != 3) 00606 return NULL; 00607 AST_RWLIST_RDLOCK(&users); 00608 AST_RWLIST_TRAVERSE(&users, user, list) { 00609 if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) { 00610 ret = ast_strdup(user->username); 00611 break; 00612 } 00613 } 00614 AST_RWLIST_UNLOCK(&users); 00615 return ret; 00616 } 00617 00618 if (a->argc != 4) 00619 return CLI_SHOWUSAGE; 00620 00621 AST_RWLIST_RDLOCK(&users); 00622 00623 if (!(user = get_manager_by_name_locked(a->argv[3]))) { 00624 ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]); 00625 AST_RWLIST_UNLOCK(&users); 00626 return CLI_SUCCESS; 00627 } 00628 00629 ast_cli(a->fd, "\n"); 00630 ast_cli(a->fd, 00631 " username: %s\n" 00632 " secret: %s\n" 00633 " acl: %s\n" 00634 " read perm: %s\n" 00635 " write perm: %s\n" 00636 "displayconnects: %s\n", 00637 (user->username ? user->username : "(N/A)"), 00638 (user->secret ? "<Set>" : "(N/A)"), 00639 (user->ha ? "yes" : "no"), 00640 authority_to_str(user->readperm, &rauthority), 00641 authority_to_str(user->writeperm, &wauthority), 00642 (user->displayconnects ? "yes" : "no")); 00643 00644 AST_RWLIST_UNLOCK(&users); 00645 00646 return CLI_SUCCESS; 00647 }
static char* handle_showmanagers | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 650 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_manager_user::list, ast_cli_entry::usage, and user.
00651 { 00652 struct ast_manager_user *user = NULL; 00653 int count_amu = 0; 00654 switch (cmd) { 00655 case CLI_INIT: 00656 e->command = "manager show users"; 00657 e->usage = 00658 "Usage: manager show users\n" 00659 " Prints a listing of all managers that are currently configured on that\n" 00660 " system.\n"; 00661 return NULL; 00662 case CLI_GENERATE: 00663 return NULL; 00664 } 00665 if (a->argc != 3) 00666 return CLI_SHOWUSAGE; 00667 00668 AST_RWLIST_RDLOCK(&users); 00669 00670 /* If there are no users, print out something along those lines */ 00671 if (AST_RWLIST_EMPTY(&users)) { 00672 ast_cli(a->fd, "There are no manager users.\n"); 00673 AST_RWLIST_UNLOCK(&users); 00674 return CLI_SUCCESS; 00675 } 00676 00677 ast_cli(a->fd, "\nusername\n--------\n"); 00678 00679 AST_RWLIST_TRAVERSE(&users, user, list) { 00680 ast_cli(a->fd, "%s\n", user->username); 00681 count_amu++; 00682 } 00683 00684 AST_RWLIST_UNLOCK(&users); 00685 00686 ast_cli(a->fd, "-------------------\n"); 00687 ast_cli(a->fd, "%d manager users configured.\n", count_amu); 00688 00689 return CLI_SUCCESS; 00690 }
static char* handle_showmancmd | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 518 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, 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.
00519 { 00520 struct manager_action *cur; 00521 struct ast_str *authority; 00522 int num, l, which; 00523 char *ret = NULL; 00524 switch (cmd) { 00525 case CLI_INIT: 00526 e->command = "manager show command"; 00527 e->usage = 00528 "Usage: manager show command <actionname>\n" 00529 " Shows the detailed description for a specific Asterisk manager interface command.\n"; 00530 return NULL; 00531 case CLI_GENERATE: 00532 l = strlen(a->word); 00533 which = 0; 00534 AST_RWLIST_RDLOCK(&actions); 00535 AST_RWLIST_TRAVERSE(&actions, cur, list) { 00536 if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) { 00537 ret = ast_strdup(cur->action); 00538 break; /* make sure we exit even if ast_strdup() returns NULL */ 00539 } 00540 } 00541 AST_RWLIST_UNLOCK(&actions); 00542 return ret; 00543 } 00544 authority = ast_str_alloca(80); 00545 if (a->argc != 4) 00546 return CLI_SHOWUSAGE; 00547 00548 AST_RWLIST_RDLOCK(&actions); 00549 AST_RWLIST_TRAVERSE(&actions, cur, list) { 00550 for (num = 3; num < a->argc; num++) { 00551 if (!strcasecmp(cur->action, a->argv[num])) { 00552 ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", 00553 cur->action, cur->synopsis, 00554 authority_to_str(cur->authority, &authority), 00555 S_OR(cur->description, "")); 00556 } 00557 } 00558 } 00559 AST_RWLIST_UNLOCK(&actions); 00560 00561 return CLI_SUCCESS; 00562 }
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 694 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.
00695 { 00696 struct manager_action *cur; 00697 struct ast_str *authority; 00698 #define HSMC_FORMAT " %-15.15s %-15.15s %-55.55s\n" 00699 switch (cmd) { 00700 case CLI_INIT: 00701 e->command = "manager show commands"; 00702 e->usage = 00703 "Usage: manager show commands\n" 00704 " Prints a listing of all the available Asterisk manager interface commands.\n"; 00705 return NULL; 00706 case CLI_GENERATE: 00707 return NULL; 00708 } 00709 authority = ast_str_alloca(80); 00710 ast_cli(a->fd, HSMC_FORMAT, "Action", "Privilege", "Synopsis"); 00711 ast_cli(a->fd, HSMC_FORMAT, "------", "---------", "--------"); 00712 00713 AST_RWLIST_RDLOCK(&actions); 00714 AST_RWLIST_TRAVERSE(&actions, cur, list) 00715 ast_cli(a->fd, HSMC_FORMAT, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis); 00716 AST_RWLIST_UNLOCK(&actions); 00717 00718 return CLI_SUCCESS; 00719 }
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 722 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.
00723 { 00724 struct mansession_session *session; 00725 time_t now = time(NULL); 00726 #define HSMCONN_FORMAT1 " %-15.15s %-15.15s %-10.10s %-10.10s %-8.8s %-8.8s %-5.5s %-5.5s\n" 00727 #define HSMCONN_FORMAT2 " %-15.15s %-15.15s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\n" 00728 int count = 0; 00729 switch (cmd) { 00730 case CLI_INIT: 00731 e->command = "manager show connected"; 00732 e->usage = 00733 "Usage: manager show connected\n" 00734 " Prints a listing of the users that are currently connected to the\n" 00735 "Asterisk manager interface.\n"; 00736 return NULL; 00737 case CLI_GENERATE: 00738 return NULL; 00739 } 00740 00741 ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write"); 00742 00743 AST_LIST_LOCK(&sessions); 00744 AST_LIST_TRAVERSE(&sessions, session, list) { 00745 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); 00746 count++; 00747 } 00748 AST_LIST_UNLOCK(&sessions); 00749 00750 ast_cli(a->fd, "%d users connected.\n", count); 00751 00752 return CLI_SUCCESS; 00753 }
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 757 of file manager.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, eventqent::eq_next, ast_cli_args::fd, s, and ast_cli_entry::usage.
00758 { 00759 struct eventqent *s; 00760 switch (cmd) { 00761 case CLI_INIT: 00762 e->command = "manager show eventq"; 00763 e->usage = 00764 "Usage: manager show eventq\n" 00765 " Prints a listing of all events pending in the Asterisk manger\n" 00766 "event queue.\n"; 00767 return NULL; 00768 case CLI_GENERATE: 00769 return NULL; 00770 } 00771 AST_LIST_LOCK(&all_events); 00772 AST_LIST_TRAVERSE(&all_events, s, eq_next) { 00773 ast_cli(a->fd, "Usecount: %d\n", s->usecount); 00774 ast_cli(a->fd, "Category: %d\n", s->category); 00775 ast_cli(a->fd, "Event:\n%s", s->eventdata); 00776 } 00777 AST_LIST_UNLOCK(&all_events); 00778 00779 return CLI_SUCCESS; 00780 }
static enum error_type handle_updates | ( | struct mansession * | s, | |
const struct message * | m, | |||
struct ast_config * | cfg, | |||
const char * | dfn | |||
) | [static] |
Definition at line 1309 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().
01310 { 01311 int x; 01312 char hdr[40]; 01313 const char *action, *cat, *var, *value, *match, *line; 01314 struct ast_category *category; 01315 struct ast_variable *v; 01316 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 01317 enum error_type result = 0; 01318 01319 for (x = 0; x < 100000; x++) { /* 100000 = the max number of allowed updates + 1 */ 01320 unsigned int object = 0; 01321 01322 snprintf(hdr, sizeof(hdr), "Action-%06d", x); 01323 action = astman_get_header(m, hdr); 01324 if (ast_strlen_zero(action)) /* breaks the for loop if no action header */ 01325 break; /* this could cause problems if actions come in misnumbered */ 01326 01327 snprintf(hdr, sizeof(hdr), "Cat-%06d", x); 01328 cat = astman_get_header(m, hdr); 01329 if (ast_strlen_zero(cat)) { /* every action needs a category */ 01330 result = UNSPECIFIED_CATEGORY; 01331 break; 01332 } 01333 01334 snprintf(hdr, sizeof(hdr), "Var-%06d", x); 01335 var = astman_get_header(m, hdr); 01336 01337 snprintf(hdr, sizeof(hdr), "Value-%06d", x); 01338 value = astman_get_header(m, hdr); 01339 01340 if (!ast_strlen_zero(value) && *value == '>') { 01341 object = 1; 01342 value++; 01343 } 01344 01345 snprintf(hdr, sizeof(hdr), "Match-%06d", x); 01346 match = astman_get_header(m, hdr); 01347 01348 snprintf(hdr, sizeof(hdr), "Line-%06d", x); 01349 line = astman_get_header(m, hdr); 01350 01351 if (!strcasecmp(action, "newcat")) { 01352 if (ast_category_get(cfg,cat)) { /* check to make sure the cat doesn't */ 01353 result = FAILURE_NEWCAT; /* already exist */ 01354 break; 01355 } 01356 if (!(category = ast_category_new(cat, dfn, -1))) { 01357 result = FAILURE_ALLOCATION; 01358 break; 01359 } 01360 if (ast_strlen_zero(match)) { 01361 ast_category_append(cfg, category); 01362 } else 01363 ast_category_insert(cfg, category, match); 01364 } else if (!strcasecmp(action, "renamecat")) { 01365 if (ast_strlen_zero(value)) { 01366 result = UNSPECIFIED_ARGUMENT; 01367 break; 01368 } 01369 if (!(category = ast_category_get(cfg, cat))) { 01370 result = UNKNOWN_CATEGORY; 01371 break; 01372 } 01373 ast_category_rename(category, value); 01374 } else if (!strcasecmp(action, "delcat")) { 01375 if (ast_category_delete(cfg, cat)) { 01376 result = FAILURE_DELCAT; 01377 break; 01378 } 01379 } else if (!strcasecmp(action, "emptycat")) { 01380 if (ast_category_empty(cfg, cat)) { 01381 result = FAILURE_EMPTYCAT; 01382 break; 01383 } 01384 } else if (!strcasecmp(action, "update")) { 01385 if (ast_strlen_zero(var)) { 01386 result = UNSPECIFIED_ARGUMENT; 01387 break; 01388 } 01389 if (!(category = ast_category_get(cfg,cat))) { 01390 result = UNKNOWN_CATEGORY; 01391 break; 01392 } 01393 if (ast_variable_update(category, var, value, match, object)) { 01394 result = FAILURE_UPDATE; 01395 break; 01396 } 01397 } else if (!strcasecmp(action, "delete")) { 01398 if ((ast_strlen_zero(var) && ast_strlen_zero(line))) { 01399 result = UNSPECIFIED_ARGUMENT; 01400 break; 01401 } 01402 if (!(category = ast_category_get(cfg, cat))) { 01403 result = UNKNOWN_CATEGORY; 01404 break; 01405 } 01406 if (ast_variable_delete(category, var, match, line)) { 01407 result = FAILURE_DELETE; 01408 break; 01409 } 01410 } else if (!strcasecmp(action, "append")) { 01411 if (ast_strlen_zero(var)) { 01412 result = UNSPECIFIED_ARGUMENT; 01413 break; 01414 } 01415 if (!(category = ast_category_get(cfg, cat))) { 01416 result = UNKNOWN_CATEGORY; 01417 break; 01418 } 01419 if (!(v = ast_variable_new(var, value, dfn))) { 01420 result = FAILURE_ALLOCATION; 01421 break; 01422 } 01423 if (object || (match && !strcasecmp(match, "object"))) 01424 v->object = 1; 01425 ast_variable_append(category, v); 01426 } else if (!strcasecmp(action, "insert")) { 01427 if (ast_strlen_zero(var) || ast_strlen_zero(line)) { 01428 result = UNSPECIFIED_ARGUMENT; 01429 break; 01430 } 01431 if (!(category = ast_category_get(cfg, cat))) { 01432 result = UNKNOWN_CATEGORY; 01433 break; 01434 } 01435 if (!(v = ast_variable_new(var, value, dfn))) { 01436 result = FAILURE_ALLOCATION; 01437 break; 01438 } 01439 ast_variable_insert(category, v, line); 01440 } 01441 else { 01442 ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action); 01443 result = UNKNOWN_ACTION; 01444 break; 01445 } 01446 } 01447 ast_free(str1); 01448 ast_free(str2); 01449 return result; 01450 }
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 1228 of file manager.c.
Referenced by action_getconfigjson().
01229 { 01230 for (; *in; in++) { 01231 if (*in == '\\' || *in == '\"') 01232 *out++ = '\\'; 01233 *out++ = *in; 01234 } 01235 *out = '\0'; 01236 }
static int manager_displayconnects | ( | struct mansession_session * | session | ) | [static] |
Get displayconnects config option.
s | manager session to get parameter from. |
Definition at line 505 of file manager.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, get_manager_by_name_locked(), user, and mansession_session::username.
Referenced by action_login(), purge_sessions(), and session_do().
00506 { 00507 struct ast_manager_user *user = NULL; 00508 int ret = 0; 00509 00510 AST_RWLIST_RDLOCK(&users); 00511 if ((user = get_manager_by_name_locked (session->username))) 00512 ret = user->displayconnects; 00513 AST_RWLIST_UNLOCK(&users); 00514 00515 return ret; 00516 }
static int manager_modulecheck | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2854 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, s, and version.
Referenced by __init_manager().
02855 { 02856 int res; 02857 const char *module = astman_get_header(m, "Module"); 02858 const char *id = astman_get_header(m, "ActionID"); 02859 char idText[256]; 02860 #if !defined(LOW_MEMORY) 02861 const char *version; 02862 #endif 02863 char filename[PATH_MAX]; 02864 char *cut; 02865 02866 ast_copy_string(filename, module, sizeof(filename)); 02867 if ((cut = strchr(filename, '.'))) { 02868 *cut = '\0'; 02869 } else { 02870 cut = filename + strlen(filename); 02871 } 02872 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so"); 02873 ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename); 02874 res = ast_module_check(filename); 02875 if (!res) { 02876 astman_send_error(s, m, "Module not loaded"); 02877 return 0; 02878 } 02879 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c"); 02880 ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename); 02881 #if !defined(LOW_MEMORY) 02882 version = ast_file_version_find(filename); 02883 #endif 02884 02885 if (!ast_strlen_zero(id)) 02886 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02887 else 02888 idText[0] = '\0'; 02889 astman_append(s, "Response: Success\r\n%s", idText); 02890 #if !defined(LOW_MEMORY) 02891 astman_append(s, "Version: %s\r\n\r\n", version ? version : ""); 02892 #endif 02893 return 0; 02894 }
static int manager_moduleload | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2907 of file manager.c.
References AST_FORCE_SOFT, ast_load_resource(), ast_module_reload(), ast_unload_resource(), astman_get_header(), astman_send_ack(), astman_send_error(), and s.
Referenced by __init_manager().
02908 { 02909 int res; 02910 const char *module = astman_get_header(m, "Module"); 02911 const char *loadtype = astman_get_header(m, "LoadType"); 02912 02913 if (!loadtype || strlen(loadtype) == 0) 02914 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02915 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) 02916 astman_send_error(s, m, "Need module name"); 02917 02918 if (!strcasecmp(loadtype, "load")) { 02919 res = ast_load_resource(module); 02920 if (res) 02921 astman_send_error(s, m, "Could not load module."); 02922 else 02923 astman_send_ack(s, m, "Module loaded."); 02924 } else if (!strcasecmp(loadtype, "unload")) { 02925 res = ast_unload_resource(module, AST_FORCE_SOFT); 02926 if (res) 02927 astman_send_error(s, m, "Could not unload module."); 02928 else 02929 astman_send_ack(s, m, "Module unloaded."); 02930 } else if (!strcasecmp(loadtype, "reload")) { 02931 if (module != NULL) { 02932 res = ast_module_reload(module); 02933 if (res == 0) 02934 astman_send_error(s, m, "No such module."); 02935 else if (res == 1) 02936 astman_send_error(s, m, "Module does not support reload action."); 02937 else 02938 astman_send_ack(s, m, "Module reloaded."); 02939 } else { 02940 ast_module_reload(NULL); /* Reload all modules */ 02941 astman_send_ack(s, m, "All modules reloaded"); 02942 } 02943 } else 02944 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02945 return 0; 02946 }
static int manager_state_cb | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Definition at line 3361 of file manager.c.
References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.
Referenced by __init_manager().
03362 { 03363 /* Notify managers of change */ 03364 char hint[512]; 03365 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten); 03366 03367 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state); 03368 return 0; 03369 }
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 2625 of file manager.c.
References ast_mutex_lock(), ast_mutex_unlock(), NEW_EVENT, ref_event(), s, send_string(), and unref_event().
Referenced by do_message(), and process_message().
02626 { 02627 int ret = 0; 02628 02629 ast_mutex_lock(&s->session->__lock); 02630 if (s->session->f != NULL) { 02631 struct eventqent *eqe; 02632 02633 while ( (eqe = NEW_EVENT(s)) ) { 02634 ref_event(eqe); 02635 if (!ret && s->session->authenticated && 02636 (s->session->readperm & eqe->category) == eqe->category && 02637 (s->session->send_events & eqe->category) == eqe->category) { 02638 if (send_string(s, eqe->eventdata) < 0) 02639 ret = -1; /* don't send more */ 02640 } 02641 s->session->last_ev = unref_event(s->session->last_ev); 02642 } 02643 } 02644 ast_mutex_unlock(&s->session->__lock); 02645 return ret; 02646 }
static int process_message | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2961 of file manager.c.
References __astman_get_header(), 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(), manager_action::authority, buf, check_manager_session_inuse(), manager_action::func, GET_HEADER_SKIP_EMPTY, process_events(), and s.
Referenced by do_message().
02962 { 02963 char action[80] = ""; 02964 int ret = 0; 02965 struct manager_action *tmp; 02966 const char *user = astman_get_header(m, "Username"); 02967 02968 ast_copy_string(action, __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY), sizeof(action)); 02969 ast_debug(1, "Manager received command '%s'\n", action); 02970 02971 if (ast_strlen_zero(action)) { 02972 ast_mutex_lock(&s->session->__lock); 02973 astman_send_error(s, m, "Missing action in request"); 02974 ast_mutex_unlock(&s->session->__lock); 02975 return 0; 02976 } 02977 02978 if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) { 02979 ast_mutex_lock(&s->session->__lock); 02980 astman_send_error(s, m, "Permission denied"); 02981 ast_mutex_unlock(&s->session->__lock); 02982 return 0; 02983 } 02984 02985 if (!allowmultiplelogin && !s->session->authenticated && user && 02986 (!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) { 02987 if (check_manager_session_inuse(user)) { 02988 sleep(1); 02989 ast_mutex_lock(&s->session->__lock); 02990 astman_send_error(s, m, "Login Already In Use"); 02991 ast_mutex_unlock(&s->session->__lock); 02992 return -1; 02993 } 02994 } 02995 02996 AST_RWLIST_RDLOCK(&actions); 02997 AST_RWLIST_TRAVERSE(&actions, tmp, list) { 02998 if (strcasecmp(action, tmp->action)) 02999 continue; 03000 if (s->session->writeperm & tmp->authority || tmp->authority == 0) 03001 ret = tmp->func(s, m); 03002 else 03003 astman_send_error(s, m, "Permission denied"); 03004 break; 03005 } 03006 AST_RWLIST_UNLOCK(&actions); 03007 03008 if (!tmp) { 03009 char buf[512]; 03010 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action); 03011 ast_mutex_lock(&s->session->__lock); 03012 astman_send_error(s, m, buf); 03013 ast_mutex_unlock(&s->session->__lock); 03014 } 03015 if (ret) 03016 return ret; 03017 /* Once done with our message, deliver any pending events */ 03018 return process_events(s); 03019 }
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 349 of file manager.c.
References ast_free, AST_LIST_FIRST, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, eventqent::eq_next, and eventqent::usecount.
Referenced by purge_old_stuff().
00350 { 00351 struct eventqent *ev; 00352 00353 AST_LIST_LOCK(&all_events); 00354 while ( (ev = AST_LIST_FIRST(&all_events)) && 00355 ev->usecount == 0 && AST_LIST_NEXT(ev, eq_next)) { 00356 AST_LIST_REMOVE_HEAD(&all_events, eq_next); 00357 ast_free(ev); 00358 } 00359 AST_LIST_UNLOCK(&all_events); 00360 }
static void purge_sessions | ( | int | n_max | ) | [static] |
remove at most n_max stale session from the list.
Definition at line 3209 of file manager.c.
References ast_atomic_fetchadd_int(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verb, mansession_session::authenticated, free_session(), mansession_session::inuse, manager_displayconnects(), mansession_session::sessiontimeout, mansession_session::sin, mansession_session::username, and VERBOSITY_ATLEAST.
Referenced by purge_old_stuff().
03210 { 03211 struct mansession_session *session; 03212 time_t now = time(NULL); 03213 03214 AST_LIST_LOCK(&sessions); 03215 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, session, list) { 03216 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) { 03217 AST_LIST_REMOVE_CURRENT(list); 03218 ast_atomic_fetchadd_int(&num_sessions, -1); 03219 if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) { 03220 ast_verb(2, "HTTP Manager '%s' timed out from %s\n", 03221 session->username, ast_inet_ntoa(session->sin.sin_addr)); 03222 } 03223 free_session(session); /* XXX outside ? */ 03224 if (--n_max <= 0) 03225 break; 03226 } 03227 } 03228 AST_LIST_TRAVERSE_SAFE_END; 03229 AST_LIST_UNLOCK(&sessions); 03230 }
static void ref_event | ( | struct eventqent * | e | ) | [static] |
Definition at line 825 of file manager.c.
References ast_atomic_fetchadd_int(), and eventqent::usecount.
Referenced by process_events().
00826 { 00827 ast_atomic_fetchadd_int(&e->usecount, 1); 00828 }
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 943 of file manager.c.
References ast_careful_fwrite(), and s.
Referenced by astman_append(), and process_events().
00944 { 00945 if (s->f) { 00946 return ast_careful_fwrite(s->f, s->fd, string, strlen(string), s->session->writetimeout); 00947 } else { 00948 return ast_careful_fwrite(s->session->f, s->session->fd, string, strlen(string), s->session->writetimeout); 00949 } 00950 }
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 3132 of file manager.c.
References AMI_VERSION, 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(), do_message(), ast_tcptls_session_instance::f, ast_tcptls_session_instance::fd, ast_frame::flags, grab_last(), LOG_EVENT, manager_displayconnects(), ast_tcptls_session_instance::remote_address, and s.
03133 { 03134 struct ast_tcptls_session_instance *ser = data; 03135 struct mansession_session *session = ast_calloc(1, sizeof(*session)); 03136 struct mansession s = {.session = NULL, }; 03137 int flags; 03138 int res; 03139 03140 if (session == NULL) 03141 goto done; 03142 03143 session->writetimeout = 100; 03144 session->waiting_thread = AST_PTHREADT_NULL; 03145 03146 flags = fcntl(ser->fd, F_GETFL); 03147 if (!block_sockets) /* make sure socket is non-blocking */ 03148 flags |= O_NONBLOCK; 03149 else 03150 flags &= ~O_NONBLOCK; 03151 fcntl(ser->fd, F_SETFL, flags); 03152 03153 ast_mutex_init(&session->__lock); 03154 session->send_events = -1; 03155 /* Hook to the tail of the event queue */ 03156 session->last_ev = grab_last(); 03157 03158 /* these fields duplicate those in the 'ser' structure */ 03159 session->fd = ser->fd; 03160 session->f = ser->f; 03161 session->sin = ser->remote_address; 03162 s.session = session; 03163 03164 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores); 03165 03166 AST_LIST_LOCK(&sessions); 03167 AST_LIST_INSERT_HEAD(&sessions, session, list); 03168 ast_atomic_fetchadd_int(&num_sessions, 1); 03169 AST_LIST_UNLOCK(&sessions); 03170 03171 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */ 03172 for (;;) { 03173 if ((res = do_message(&s)) < 0) 03174 break; 03175 } 03176 /* session is over, explain why and terminate */ 03177 if (session->authenticated) { 03178 if (manager_displayconnects(session)) 03179 ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 03180 ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 03181 } else { 03182 if (displayconnects) 03183 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr)); 03184 ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(session->sin.sin_addr)); 03185 } 03186 03187 /* It is possible under certain circumstances for this session thread 03188 to complete its work and exit *before* the thread that created it 03189 has finished executing the ast_pthread_create_background() function. 03190 If this occurs, some versions of glibc appear to act in a buggy 03191 fashion and attempt to write data into memory that it thinks belongs 03192 to the thread but is in fact not owned by the thread (or may have 03193 been freed completely). 03194 03195 Causing this thread to yield to other threads at least one time 03196 appears to work around this bug. 03197 */ 03198 usleep(1); 03199 03200 destroy_session(session); 03201 03202 done: 03203 ao2_ref(ser, -1); 03204 ser = NULL; 03205 return NULL; 03206 }
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 1051 of file manager.c.
References ast_mutex_lock(), ast_mutex_unlock(), s, and strings_to_mask().
Referenced by action_events(), and authenticate().
01052 { 01053 int maskint = strings_to_mask(eventmask); 01054 01055 ast_mutex_lock(&s->session->__lock); 01056 if (maskint >= 0) 01057 s->session->send_events = maskint; 01058 ast_mutex_unlock(&s->session->__lock); 01059 01060 return maskint; 01061 }
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 449 of file manager.c.
References ARRAY_LEN, ast_false(), ast_strlen_zero(), ast_true(), get_perm(), num, and perms.
Referenced by set_eventmask().
00450 { 00451 const char *p; 00452 00453 if (ast_strlen_zero(string)) 00454 return -1; 00455 00456 for (p = string; *p; p++) 00457 if (*p < '0' || *p > '9') 00458 break; 00459 if (!p) /* all digits */ 00460 return atoi(string); 00461 if (ast_false(string)) 00462 return 0; 00463 if (ast_true(string)) { /* all permissions */ 00464 int x, ret = 0; 00465 for (x = 0; x < ARRAY_LEN(perms); x++) 00466 ret |= perms[x].num; 00467 return ret; 00468 } 00469 return get_perm(string); 00470 }
Definition at line 819 of file manager.c.
References ast_atomic_fetchadd_int(), AST_LIST_NEXT, eventqent::eq_next, and eventqent::usecount.
Referenced by free_session(), and process_events().
00820 { 00821 ast_atomic_fetchadd_int(&e->usecount, -1); 00822 return AST_LIST_NEXT(e, eq_next); 00823 }
int allowmultiplelogin = 1 [static] |
struct ast_threadstorage astman_append_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_astman_append_buf , .custom_init = NULL , } [static] |
int block_sockets [static] |
struct ast_cli_entry cli_manager[] [static] |
struct { ... } command_blacklist[] [static] |
Referenced by check_blacklist().
int displayconnects = 1 [static] |
int httptimeout = 60 [static] |
int manager_debug [static] |
int manager_enabled = 0 [static] |
struct ast_threadstorage manager_event_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_manager_event_buf , .custom_init = NULL , } [static] |
char mandescr_atxfer[] [static] |
char mandescr_command[] [static] |
char mandescr_coresettings[] [static] |
char mandescr_coreshowchannels[] [static] |
char mandescr_corestatus[] [static] |
char mandescr_createconfig[] [static] |
char mandescr_events[] [static] |
char mandescr_extensionstate[] [static] |
char mandescr_getconfig[] [static] |
char mandescr_getconfigjson[] [static] |
char mandescr_getvar[] [static] |
char mandescr_hangup[] [static] |
char mandescr_listcategories[] [static] |
Initial value:
"Description: A 'ListCategories' action will dump the categories in\n" "a given file.\n" "Variables:\n" " Filename: Configuration filename (e.g. foo.conf)\n"
Definition at line 1189 of file manager.c.
Referenced by __init_manager().
char mandescr_listcommands[] [static] |
char mandescr_logoff[] [static] |
char mandescr_mailboxcount[] [static] |
char mandescr_mailboxstatus[] [static] |
char mandescr_modulecheck[] [static] |
char mandescr_moduleload[] [static] |
char mandescr_originate[] [static] |
char mandescr_ping[] [static] |
Initial value:
"Description: A 'Ping' action will ellicit a 'Pong' response. Used to keep the\n" " manager connection open.\n" "Variables: NONE\n"
Definition at line 1131 of file manager.c.
Referenced by __init_manager().
char mandescr_redirect[] [static] |
char mandescr_reload[] [static] |
char mandescr_sendtext[] [static] |
char mandescr_setvar[] [static] |
char mandescr_status[] [static] |
char mandescr_timeout[] [static] |
char mandescr_updateconfig[] [static] |
char mandescr_userevent[] [static] |
char mandescr_waitevent[] [static] |
int num_sessions [static] |
helper functions to convert back and forth between string and numeric representation of set of flags
Referenced by authority_to_str(), get_perm(), and strings_to_mask().
int timestampevents [static] |
struct ast_threadstorage userevent_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_userevent_buf , .custom_init = NULL , } [static] |
int webmanager_enabled = 0 [static] |