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 int | broken_events_action = 0 |
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 965 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 870 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 144 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 1005 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 871 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().
00872 { 00873 int x, l = strlen(var); 00874 const char *result = ""; 00875 00876 for (x = 0; x < m->hdrcount; x++) { 00877 const char *h = m->headers[x]; 00878 if (!strncasecmp(var, h, l) && h[l] == ':' && h[l+1] == ' ') { 00879 const char *value = h + l + 2; 00880 /* found a potential candidate */ 00881 if (mode & GET_HEADER_SKIP_EMPTY && ast_strlen_zero(value)) 00882 continue; /* not interesting */ 00883 if (mode & GET_HEADER_LAST_MATCH) 00884 result = value; /* record the last match so far */ 00885 else 00886 return value; 00887 } 00888 } 00889 00890 return ""; 00891 }
static void __init_astman_append_buf | ( | void | ) | [static] |
thread local buffer for astman_append
Definition at line 961 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 3297 of file manager.c.
References mansession_session::__lock, append_event(), ast_atomic_fetchadd_int(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_append_va(), ast_str_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.
03299 { 03300 struct mansession_session *session; 03301 struct manager_custom_hook *hook; 03302 struct ast_str *auth = ast_str_alloca(80); 03303 const char *cat_str; 03304 va_list ap; 03305 struct timeval now; 03306 struct ast_str *buf; 03307 03308 /* Abort if there are neither any manager sessions nor hooks */ 03309 if (!num_sessions && AST_RWLIST_EMPTY(&manager_hooks)) 03310 return 0; 03311 03312 if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) 03313 return -1; 03314 03315 cat_str = authority_to_str(category, &auth); 03316 ast_str_set(&buf, 0, 03317 "Event: %s\r\nPrivilege: %s\r\n", 03318 event, cat_str); 03319 03320 if (timestampevents) { 03321 now = ast_tvnow(); 03322 ast_str_append(&buf, 0, 03323 "Timestamp: %ld.%06lu\r\n", 03324 (long)now.tv_sec, (unsigned long) now.tv_usec); 03325 } 03326 if (manager_debug) { 03327 static int seq; 03328 ast_str_append(&buf, 0, 03329 "SequenceNumber: %d\r\n", 03330 ast_atomic_fetchadd_int(&seq, 1)); 03331 ast_str_append(&buf, 0, 03332 "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func); 03333 } 03334 03335 va_start(ap, fmt); 03336 ast_str_append_va(&buf, 0, fmt, ap); 03337 va_end(ap); 03338 03339 ast_str_append(&buf, 0, "\r\n"); 03340 03341 append_event(buf->str, category); 03342 03343 /* Wake up any sleeping sessions */ 03344 if (num_sessions) { 03345 AST_LIST_LOCK(&sessions); 03346 AST_LIST_TRAVERSE(&sessions, session, list) { 03347 ast_mutex_lock(&session->__lock); 03348 if (session->waiting_thread != AST_PTHREADT_NULL) 03349 pthread_kill(session->waiting_thread, SIGURG); 03350 else 03351 /* We have an event to process, but the mansession is 03352 * not waiting for it. We still need to indicate that there 03353 * is an event waiting so that get_input processes the pending 03354 * event instead of polling. 03355 */ 03356 session->pending_event = 1; 03357 ast_mutex_unlock(&session->__lock); 03358 } 03359 AST_LIST_UNLOCK(&sessions); 03360 } 03361 03362 if (!AST_RWLIST_EMPTY(&manager_hooks)) { 03363 AST_RWLIST_RDLOCK(&manager_hooks); 03364 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) { 03365 hook->helper(category, event, buf->str); 03366 } 03367 AST_RWLIST_UNLOCK(&manager_hooks); 03368 } 03369 03370 return 0; 03371 }
static int action_atxfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2172 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().
02173 { 02174 const char *name = astman_get_header(m, "Channel"); 02175 const char *exten = astman_get_header(m, "Exten"); 02176 const char *context = astman_get_header(m, "Context"); 02177 struct ast_channel *chan = NULL; 02178 struct ast_call_feature *atxfer_feature = NULL; 02179 char *feature_code = NULL; 02180 02181 if (ast_strlen_zero(name)) { 02182 astman_send_error(s, m, "No channel specified"); 02183 return 0; 02184 } 02185 if (ast_strlen_zero(exten)) { 02186 astman_send_error(s, m, "No extension specified"); 02187 return 0; 02188 } 02189 02190 if (!(atxfer_feature = ast_find_call_feature("atxfer"))) { 02191 astman_send_error(s, m, "No attended transfer feature found"); 02192 return 0; 02193 } 02194 02195 if (!(chan = ast_get_channel_by_name_locked(name))) { 02196 astman_send_error(s, m, "Channel specified does not exist"); 02197 return 0; 02198 } 02199 02200 if (!ast_strlen_zero(context)) { 02201 pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context); 02202 } 02203 02204 for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) { 02205 struct ast_frame f = {AST_FRAME_DTMF, *feature_code}; 02206 ast_queue_frame(chan, &f); 02207 } 02208 02209 for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) { 02210 struct ast_frame f = {AST_FRAME_DTMF, *feature_code}; 02211 ast_queue_frame(chan, &f); 02212 } 02213 02214 astman_send_ack(s, m, "Atxfer successfully queued"); 02215 ast_channel_unlock(chan); 02216 02217 return 0; 02218 }
static int action_challenge | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1759 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().
01760 { 01761 const char *authtype = astman_get_header(m, "AuthType"); 01762 01763 if (!strcasecmp(authtype, "MD5")) { 01764 if (ast_strlen_zero(s->session->challenge)) 01765 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random()); 01766 ast_mutex_lock(&s->session->__lock); 01767 astman_start_ack(s, m); 01768 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge); 01769 ast_mutex_unlock(&s->session->__lock); 01770 } else { 01771 astman_send_error(s, m, "Must specify AuthType"); 01772 } 01773 return 0; 01774 }
static int action_command | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager command "command" - execute CLI command.
Definition at line 2262 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().
02263 { 02264 const char *cmd = astman_get_header(m, "Command"); 02265 const char *id = astman_get_header(m, "ActionID"); 02266 char *buf, *final_buf; 02267 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 02268 int fd; 02269 off_t l; 02270 02271 if (ast_strlen_zero(cmd)) { 02272 astman_send_error(s, m, "No command provided"); 02273 return 0; 02274 } 02275 02276 if (check_blacklist(cmd)) { 02277 astman_send_error(s, m, "Command blacklisted"); 02278 return 0; 02279 } 02280 02281 fd = mkstemp(template); 02282 02283 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 02284 if (!ast_strlen_zero(id)) 02285 astman_append(s, "ActionID: %s\r\n", id); 02286 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 02287 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 02288 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 02289 02290 /* This has a potential to overflow the stack. Hence, use the heap. */ 02291 buf = ast_calloc(1, l + 1); 02292 final_buf = ast_calloc(1, l + 1); 02293 if (buf) { 02294 lseek(fd, 0, SEEK_SET); 02295 if (read(fd, buf, l) < 0) { 02296 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 02297 } 02298 buf[l] = '\0'; 02299 if (final_buf) { 02300 term_strip(final_buf, buf, l); 02301 final_buf[l] = '\0'; 02302 } 02303 astman_append(s, "%s", S_OR(final_buf, buf)); 02304 ast_free(buf); 02305 } 02306 close(fd); 02307 unlink(template); 02308 astman_append(s, "--END COMMAND--\r\n\r\n"); 02309 if (final_buf) 02310 ast_free(final_buf); 02311 return 0; 02312 }
static int action_coresettings | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show PBX core settings information.
Definition at line 2713 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().
02714 { 02715 const char *actionid = astman_get_header(m, "ActionID"); 02716 char idText[150]; 02717 02718 if (!ast_strlen_zero(actionid)) 02719 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02720 else 02721 idText[0] = '\0'; 02722 02723 astman_append(s, "Response: Success\r\n" 02724 "%s" 02725 "AMIversion: %s\r\n" 02726 "AsteriskVersion: %s\r\n" 02727 "SystemName: %s\r\n" 02728 "CoreMaxCalls: %d\r\n" 02729 "CoreMaxLoadAvg: %f\r\n" 02730 "CoreRunUser: %s\r\n" 02731 "CoreRunGroup: %s\r\n" 02732 "CoreMaxFilehandles: %d\r\n" 02733 "CoreRealTimeEnabled: %s\r\n" 02734 "CoreCDRenabled: %s\r\n" 02735 "CoreHTTPenabled: %s\r\n" 02736 "\r\n", 02737 idText, 02738 AMI_VERSION, 02739 ast_get_version(), 02740 ast_config_AST_SYSTEM_NAME, 02741 option_maxcalls, 02742 option_maxload, 02743 ast_config_AST_RUN_USER, 02744 ast_config_AST_RUN_GROUP, 02745 option_maxfiles, 02746 ast_realtime_enabled() ? "Yes" : "No", 02747 check_cdr_enabled() ? "Yes" : "No", 02748 check_webmanager_enabled() ? "Yes" : "No" 02749 ); 02750 return 0; 02751 }
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 2818 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().
02819 { 02820 const char *actionid = astman_get_header(m, "ActionID"); 02821 char actionidtext[256]; 02822 struct ast_channel *c = NULL; 02823 int numchans = 0; 02824 int duration, durh, durm, durs; 02825 02826 if (!ast_strlen_zero(actionid)) 02827 snprintf(actionidtext, sizeof(actionidtext), "ActionID: %s\r\n", actionid); 02828 else 02829 actionidtext[0] = '\0'; 02830 02831 astman_send_listack(s, m, "Channels will follow", "start"); 02832 02833 while ((c = ast_channel_walk_locked(c)) != NULL) { 02834 struct ast_channel *bc = ast_bridged_channel(c); 02835 char durbuf[10] = ""; 02836 02837 if (c->cdr && !ast_tvzero(c->cdr->start)) { 02838 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 02839 durh = duration / 3600; 02840 durm = (duration % 3600) / 60; 02841 durs = duration % 60; 02842 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 02843 } 02844 02845 astman_append(s, 02846 "Event: CoreShowChannel\r\n" 02847 "Channel: %s\r\n" 02848 "UniqueID: %s\r\n" 02849 "Context: %s\r\n" 02850 "Extension: %s\r\n" 02851 "Priority: %d\r\n" 02852 "ChannelState: %d\r\n" 02853 "ChannelStateDesc: %s\r\n" 02854 "Application: %s\r\n" 02855 "ApplicationData: %s\r\n" 02856 "CallerIDnum: %s\r\n" 02857 "Duration: %s\r\n" 02858 "AccountCode: %s\r\n" 02859 "BridgedChannel: %s\r\n" 02860 "BridgedUniqueID: %s\r\n" 02861 "\r\n", c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, ast_state2str(c->_state), 02862 c->appl ? c->appl : "", c->data ? S_OR(c->data, ""): "", 02863 S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : ""); 02864 ast_channel_unlock(c); 02865 numchans++; 02866 } 02867 02868 astman_append(s, 02869 "Event: CoreShowChannelsComplete\r\n" 02870 "EventList: Complete\r\n" 02871 "ListItems: %d\r\n" 02872 "%s" 02873 "\r\n", numchans, actionidtext); 02874 02875 return 0; 02876 }
static int action_corestatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show PBX core status information.
Definition at line 2759 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().
02760 { 02761 const char *actionid = astman_get_header(m, "ActionID"); 02762 char idText[150]; 02763 char startuptime[150]; 02764 char reloadtime[150]; 02765 struct ast_tm tm; 02766 02767 if (!ast_strlen_zero(actionid)) 02768 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02769 else 02770 idText[0] = '\0'; 02771 02772 ast_localtime(&ast_startuptime, &tm, NULL); 02773 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm); 02774 ast_localtime(&ast_lastreloadtime, &tm, NULL); 02775 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm); 02776 02777 astman_append(s, "Response: Success\r\n" 02778 "%s" 02779 "CoreStartupTime: %s\r\n" 02780 "CoreReloadTime: %s\r\n" 02781 "CoreCurrentCalls: %d\r\n" 02782 "\r\n", 02783 idText, 02784 startuptime, 02785 reloadtime, 02786 ast_active_channels() 02787 ); 02788 return 0; 02789 }
static int action_createconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1549 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().
01550 { 01551 int fd; 01552 const char *fn = astman_get_header(m, "Filename"); 01553 struct ast_str *filepath = ast_str_alloca(PATH_MAX); 01554 ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR); 01555 ast_str_append(&filepath, 0, "%s", fn); 01556 01557 if ((fd = open(filepath->str, O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) { 01558 close(fd); 01559 astman_send_ack(s, m, "New configuration file created successfully"); 01560 } else 01561 astman_send_error(s, m, strerror(errno)); 01562 01563 return 0; 01564 }
static int action_events | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1698 of file manager.c.
References ARRAY_LEN, astman_append(), astman_get_header(), astman_send_error(), num, perms, s, and set_eventmask().
Referenced by __init_manager().
01699 { 01700 const char *mask = astman_get_header(m, "EventMask"); 01701 int res, x; 01702 01703 res = set_eventmask(s, mask); 01704 if (broken_events_action) { 01705 /* if this option is set we should not return a response on 01706 * error, or when all events are set */ 01707 01708 if (res > 0) { 01709 for (x = 0; x < ARRAY_LEN(perms); x++) { 01710 if (!strcasecmp(perms[x].label, "all") && res == perms[x].num) { 01711 return 0; 01712 } 01713 } 01714 astman_append(s, "Response: Success\r\n" 01715 "Events: On\r\n\r\n"); 01716 } else if (res == 0) 01717 astman_append(s, "Response: Success\r\n" 01718 "Events: Off\r\n\r\n"); 01719 return 0; 01720 } 01721 01722 if (res > 0) 01723 astman_append(s, "Response: Success\r\n" 01724 "Events: On\r\n\r\n"); 01725 else if (res == 0) 01726 astman_append(s, "Response: Success\r\n" 01727 "Events: Off\r\n\r\n"); 01728 else 01729 astman_send_error(s, m, "Invalid event mask"); 01730 01731 return 0; 01732 }
static int action_extensionstate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2594 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().
02595 { 02596 const char *exten = astman_get_header(m, "Exten"); 02597 const char *context = astman_get_header(m, "Context"); 02598 char hint[256] = ""; 02599 int status; 02600 if (ast_strlen_zero(exten)) { 02601 astman_send_error(s, m, "Extension not specified"); 02602 return 0; 02603 } 02604 if (ast_strlen_zero(context)) 02605 context = "default"; 02606 status = ast_extension_state(NULL, context, exten); 02607 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 02608 astman_start_ack(s, m); 02609 astman_append(s, "Message: Extension Status\r\n" 02610 "Exten: %s\r\n" 02611 "Context: %s\r\n" 02612 "Hint: %s\r\n" 02613 "Status: %d\r\n\r\n", 02614 exten, context, hint, status); 02615 return 0; 02616 }
static int action_getconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1153 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().
01154 { 01155 struct ast_config *cfg; 01156 const char *fn = astman_get_header(m, "Filename"); 01157 const char *category = astman_get_header(m, "Category"); 01158 int catcount = 0; 01159 int lineno = 0; 01160 char *cur_category = NULL; 01161 struct ast_variable *v; 01162 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01163 01164 if (ast_strlen_zero(fn)) { 01165 astman_send_error(s, m, "Filename not specified"); 01166 return 0; 01167 } 01168 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 01169 astman_send_error(s, m, "Config file not found"); 01170 return 0; 01171 } 01172 01173 astman_start_ack(s, m); 01174 while ((cur_category = ast_category_browse(cfg, cur_category))) { 01175 if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) { 01176 lineno = 0; 01177 astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category); 01178 for (v = ast_variable_browse(cfg, cur_category); v; v = v->next) 01179 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 01180 catcount++; 01181 } 01182 } 01183 if (!ast_strlen_zero(category) && catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */ 01184 astman_append(s, "No categories found\r\n"); 01185 ast_config_destroy(cfg); 01186 astman_append(s, "\r\n"); 01187 01188 return 0; 01189 }
static int action_getconfigjson | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1247 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().
01248 { 01249 struct ast_config *cfg; 01250 const char *fn = astman_get_header(m, "Filename"); 01251 char *category = NULL; 01252 struct ast_variable *v; 01253 int comma1 = 0; 01254 char *buf = NULL; 01255 unsigned int buf_len = 0; 01256 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01257 01258 if (ast_strlen_zero(fn)) { 01259 astman_send_error(s, m, "Filename not specified"); 01260 return 0; 01261 } 01262 01263 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 01264 astman_send_error(s, m, "Config file not found"); 01265 return 0; 01266 } 01267 01268 buf_len = 512; 01269 buf = alloca(buf_len); 01270 01271 astman_start_ack(s, m); 01272 astman_append(s, "JSON: {"); 01273 while ((category = ast_category_browse(cfg, category))) { 01274 int comma2 = 0; 01275 if (buf_len < 2 * strlen(category) + 1) { 01276 buf_len *= 2; 01277 buf = alloca(buf_len); 01278 } 01279 json_escape(buf, category); 01280 astman_append(s, "%s\"%s\":[", comma1 ? "," : "", buf); 01281 if (!comma1) 01282 comma1 = 1; 01283 for (v = ast_variable_browse(cfg, category); v; v = v->next) { 01284 if (comma2) 01285 astman_append(s, ","); 01286 if (buf_len < 2 * strlen(v->name) + 1) { 01287 buf_len *= 2; 01288 buf = alloca(buf_len); 01289 } 01290 json_escape(buf, v->name); 01291 astman_append(s, "\"%s", buf); 01292 if (buf_len < 2 * strlen(v->value) + 1) { 01293 buf_len *= 2; 01294 buf = alloca(buf_len); 01295 } 01296 json_escape(buf, v->value); 01297 astman_append(s, "%s\"", buf); 01298 if (!comma2) 01299 comma2 = 1; 01300 } 01301 astman_append(s, "]"); 01302 } 01303 astman_append(s, "}\r\n\r\n"); 01304 01305 ast_config_destroy(cfg); 01306 01307 return 0; 01308 }
static int action_getvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1851 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().
01852 { 01853 struct ast_channel *c = NULL; 01854 const char *name = astman_get_header(m, "Channel"); 01855 const char *varname = astman_get_header(m, "Variable"); 01856 char *varval; 01857 char workspace[1024] = ""; 01858 01859 if (ast_strlen_zero(varname)) { 01860 astman_send_error(s, m, "No variable specified"); 01861 return 0; 01862 } 01863 01864 if (!ast_strlen_zero(name)) { 01865 c = ast_get_channel_by_name_locked(name); 01866 if (!c) { 01867 astman_send_error(s, m, "No such channel"); 01868 return 0; 01869 } 01870 } 01871 01872 if (varname[strlen(varname) - 1] == ')') { 01873 if (!c) { 01874 c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/manager"); 01875 if (c) { 01876 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01877 ast_channel_free(c); 01878 c = NULL; 01879 } else 01880 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n"); 01881 } else 01882 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01883 varval = workspace; 01884 } else { 01885 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 01886 } 01887 01888 if (c) 01889 ast_channel_unlock(c); 01890 astman_start_ack(s, m); 01891 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, varval); 01892 01893 return 0; 01894 }
static int action_hangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1781 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().
01782 { 01783 struct ast_channel *c = NULL; 01784 const char *name = astman_get_header(m, "Channel"); 01785 if (ast_strlen_zero(name)) { 01786 astman_send_error(s, m, "No channel specified"); 01787 return 0; 01788 } 01789 c = ast_get_channel_by_name_locked(name); 01790 if (!c) { 01791 astman_send_error(s, m, "No such channel"); 01792 return 0; 01793 } 01794 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01795 ast_channel_unlock(c); 01796 astman_send_ack(s, m, "Channel Hungup"); 01797 return 0; 01798 }
static int action_listcategories | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1197 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().
01198 { 01199 struct ast_config *cfg; 01200 const char *fn = astman_get_header(m, "Filename"); 01201 char *category = NULL; 01202 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01203 int catcount = 0; 01204 01205 if (ast_strlen_zero(fn)) { 01206 astman_send_error(s, m, "Filename not specified"); 01207 return 0; 01208 } 01209 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 01210 astman_send_error(s, m, "Config file not found or file has invalid syntax"); 01211 return 0; 01212 } 01213 astman_start_ack(s, m); 01214 while ((category = ast_category_browse(cfg, category))) { 01215 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 01216 catcount++; 01217 } 01218 if (catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */ 01219 astman_append(s, "Error: no categories found\r\n"); 01220 ast_config_destroy(cfg); 01221 astman_append(s, "\r\n"); 01222 01223 return 0; 01224 }
static int action_listcommands | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1674 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().
01675 { 01676 struct manager_action *cur; 01677 struct ast_str *temp = ast_str_alloca(BUFSIZ); /* XXX very large ? */ 01678 01679 astman_start_ack(s, m); 01680 AST_RWLIST_TRAVERSE(&actions, cur, list) { 01681 if (s->session->writeperm & cur->authority || cur->authority == 0) 01682 astman_append(s, "%s: %s (Priv: %s)\r\n", 01683 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp)); 01684 } 01685 astman_append(s, "\r\n"); 01686 01687 return 0; 01688 }
static int action_login | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1744 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().
01745 { 01746 if (authenticate(s, m)) { 01747 sleep(1); 01748 astman_send_error(s, m, "Authentication failed"); 01749 return -1; 01750 } 01751 s->session->authenticated = 1; 01752 if (manager_displayconnects(s->session)) 01753 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)); 01754 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)); 01755 astman_send_ack(s, m, "Authentication accepted"); 01756 return 0; 01757 }
static int action_logoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1738 of file manager.c.
References astman_send_response(), and s.
Referenced by __init_manager().
01739 { 01740 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 01741 return -1; 01742 }
static int action_mailboxcount | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2562 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().
02563 { 02564 const char *mailbox = astman_get_header(m, "Mailbox"); 02565 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;; 02566 02567 if (ast_strlen_zero(mailbox)) { 02568 astman_send_error(s, m, "Mailbox not specified"); 02569 return 0; 02570 } 02571 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs); 02572 astman_start_ack(s, m); 02573 astman_append(s, "Message: Mailbox Message Count\r\n" 02574 "Mailbox: %s\r\n" 02575 "UrgMessages: %d\r\n" 02576 "NewMessages: %d\r\n" 02577 "OldMessages: %d\r\n" 02578 "\r\n", 02579 mailbox, urgentmsgs, newmsgs, oldmsgs); 02580 return 0; 02581 }
static int action_mailboxstatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2533 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().
02534 { 02535 const char *mailbox = astman_get_header(m, "Mailbox"); 02536 int ret; 02537 02538 if (ast_strlen_zero(mailbox)) { 02539 astman_send_error(s, m, "Mailbox not specified"); 02540 return 0; 02541 } 02542 ret = ast_app_has_voicemail(mailbox, NULL); 02543 astman_start_ack(s, m); 02544 astman_append(s, "Message: Mailbox Status\r\n" 02545 "Mailbox: %s\r\n" 02546 "Waiting: %d\r\n\r\n", mailbox, ret); 02547 return 0; 02548 }
static int action_originate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2396 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().
02397 { 02398 const char *name = astman_get_header(m, "Channel"); 02399 const char *exten = astman_get_header(m, "Exten"); 02400 const char *context = astman_get_header(m, "Context"); 02401 const char *priority = astman_get_header(m, "Priority"); 02402 const char *timeout = astman_get_header(m, "Timeout"); 02403 const char *callerid = astman_get_header(m, "CallerID"); 02404 const char *account = astman_get_header(m, "Account"); 02405 const char *app = astman_get_header(m, "Application"); 02406 const char *appdata = astman_get_header(m, "Data"); 02407 const char *async = astman_get_header(m, "Async"); 02408 const char *id = astman_get_header(m, "ActionID"); 02409 const char *codecs = astman_get_header(m, "Codecs"); 02410 struct ast_variable *vars = astman_get_variables(m); 02411 char *tech, *data; 02412 char *l = NULL, *n = NULL; 02413 int pi = 0; 02414 int res; 02415 int to = 30000; 02416 int reason = 0; 02417 char tmp[256]; 02418 char tmp2[256]; 02419 int format = AST_FORMAT_SLINEAR; 02420 02421 pthread_t th; 02422 if (ast_strlen_zero(name)) { 02423 astman_send_error(s, m, "Channel not specified"); 02424 return 0; 02425 } 02426 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 02427 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 02428 astman_send_error(s, m, "Invalid priority"); 02429 return 0; 02430 } 02431 } 02432 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) { 02433 astman_send_error(s, m, "Invalid timeout"); 02434 return 0; 02435 } 02436 ast_copy_string(tmp, name, sizeof(tmp)); 02437 tech = tmp; 02438 data = strchr(tmp, '/'); 02439 if (!data) { 02440 astman_send_error(s, m, "Invalid channel"); 02441 return 0; 02442 } 02443 *data++ = '\0'; 02444 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 02445 ast_callerid_parse(tmp2, &n, &l); 02446 if (n) { 02447 if (ast_strlen_zero(n)) 02448 n = NULL; 02449 } 02450 if (l) { 02451 ast_shrink_phone_number(l); 02452 if (ast_strlen_zero(l)) 02453 l = NULL; 02454 } 02455 if (!ast_strlen_zero(codecs)) { 02456 format = 0; 02457 ast_parse_allow_disallow(NULL, &format, codecs, 1); 02458 } 02459 if (ast_true(async)) { 02460 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 02461 if (!fast) { 02462 res = -1; 02463 } else { 02464 if (!ast_strlen_zero(id)) 02465 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s", id); 02466 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 02467 ast_copy_string(fast->data, data, sizeof(fast->data)); 02468 ast_copy_string(fast->app, app, sizeof(fast->app)); 02469 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 02470 if (l) 02471 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 02472 if (n) 02473 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 02474 fast->vars = vars; 02475 ast_copy_string(fast->context, context, sizeof(fast->context)); 02476 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 02477 ast_copy_string(fast->account, account, sizeof(fast->account)); 02478 fast->format = format; 02479 fast->timeout = to; 02480 fast->priority = pi; 02481 if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) { 02482 ast_free(fast); 02483 res = -1; 02484 } else { 02485 res = 0; 02486 } 02487 } 02488 } else if (!ast_strlen_zero(app)) { 02489 /* To run the System application (or anything else that goes to shell), you must have the additional System privilege */ 02490 if (!(s->session->writeperm & EVENT_FLAG_SYSTEM) 02491 && ( 02492 strcasestr(app, "system") == 0 || /* System(rm -rf /) 02493 TrySystem(rm -rf /) */ 02494 strcasestr(app, "exec") || /* Exec(System(rm -rf /)) 02495 TryExec(System(rm -rf /)) */ 02496 strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /) 02497 EAGI(/bin/rm,-rf /) */ 02498 strstr(appdata, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */ 02499 strstr(appdata, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */ 02500 )) { 02501 astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have."); 02502 return 0; 02503 } 02504 res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 02505 } else { 02506 if (exten && context && pi) 02507 res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 02508 else { 02509 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 02510 return 0; 02511 } 02512 } 02513 if (!res) 02514 astman_send_ack(s, m, "Originate successfully queued"); 02515 else 02516 astman_send_error(s, m, "Originate failed"); 02517 return 0; 02518 }
static int action_ping | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1138 of file manager.c.
References astman_append(), and s.
Referenced by __init_manager().
01139 { 01140 astman_append(s, "Response: Success\r\n" 01141 "Ping: Pong\r\n" 01142 "\r\n"); 01143 return 0; 01144 }
static int action_redirect | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_redirect: The redirect manager command
Definition at line 2088 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().
02089 { 02090 const char *name = astman_get_header(m, "Channel"); 02091 const char *name2 = astman_get_header(m, "ExtraChannel"); 02092 const char *exten = astman_get_header(m, "Exten"); 02093 const char *context = astman_get_header(m, "Context"); 02094 const char *priority = astman_get_header(m, "Priority"); 02095 struct ast_channel *chan, *chan2 = NULL; 02096 int pi = 0; 02097 int res; 02098 02099 if (ast_strlen_zero(name)) { 02100 astman_send_error(s, m, "Channel not specified"); 02101 return 0; 02102 } 02103 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 02104 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 02105 astman_send_error(s, m, "Invalid priority"); 02106 return 0; 02107 } 02108 } 02109 /* XXX watch out, possible deadlock - we are trying to get two channels!!! */ 02110 chan = ast_get_channel_by_name_locked(name); 02111 if (!chan) { 02112 char buf[256]; 02113 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 02114 astman_send_error(s, m, buf); 02115 return 0; 02116 } 02117 if (ast_check_hangup(chan)) { 02118 astman_send_error(s, m, "Redirect failed, channel not up."); 02119 ast_channel_unlock(chan); 02120 return 0; 02121 } 02122 if (!ast_strlen_zero(name2)) 02123 chan2 = ast_get_channel_by_name_locked(name2); 02124 if (chan2 && ast_check_hangup(chan2)) { 02125 astman_send_error(s, m, "Redirect failed, extra channel not up."); 02126 ast_channel_unlock(chan); 02127 ast_channel_unlock(chan2); 02128 return 0; 02129 } 02130 if (chan->pbx) { 02131 ast_channel_lock(chan); 02132 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 02133 ast_channel_unlock(chan); 02134 } 02135 res = ast_async_goto(chan, context, exten, pi); 02136 if (!res) { 02137 if (!ast_strlen_zero(name2)) { 02138 if (chan2) { 02139 if (chan2->pbx) { 02140 ast_channel_lock(chan2); 02141 ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 02142 ast_channel_unlock(chan2); 02143 } 02144 res = ast_async_goto(chan2, context, exten, pi); 02145 } else { 02146 res = -1; 02147 } 02148 if (!res) 02149 astman_send_ack(s, m, "Dual Redirect successful"); 02150 else 02151 astman_send_error(s, m, "Secondary redirect failed"); 02152 } else 02153 astman_send_ack(s, m, "Redirect successful"); 02154 } else 02155 astman_send_error(s, m, "Redirect failed"); 02156 if (chan) 02157 ast_channel_unlock(chan); 02158 if (chan2) 02159 ast_channel_unlock(chan2); 02160 return 0; 02161 }
static int action_reload | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Send a reload event.
Definition at line 2798 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().
02799 { 02800 const char *module = astman_get_header(m, "Module"); 02801 int res = ast_module_reload(S_OR(module, NULL)); 02802 02803 if (res == 2) 02804 astman_send_ack(s, m, "Module Reloaded"); 02805 else 02806 astman_send_error(s, m, s == 0 ? "No such module" : "Module does not support reload"); 02807 return 0; 02808 }
static int action_sendtext | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2043 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().
02044 { 02045 struct ast_channel *c = NULL; 02046 const char *name = astman_get_header(m, "Channel"); 02047 const char *textmsg = astman_get_header(m, "Message"); 02048 int res = 0; 02049 02050 if (ast_strlen_zero(name)) { 02051 astman_send_error(s, m, "No channel specified"); 02052 return 0; 02053 } 02054 02055 if (ast_strlen_zero(textmsg)) { 02056 astman_send_error(s, m, "No Message specified"); 02057 return 0; 02058 } 02059 02060 c = ast_get_channel_by_name_locked(name); 02061 if (!c) { 02062 astman_send_error(s, m, "No such channel"); 02063 return 0; 02064 } 02065 02066 res = ast_sendtext(c, textmsg); 02067 ast_channel_unlock(c); 02068 02069 if (res > 0) 02070 astman_send_ack(s, m, "Success"); 02071 else 02072 astman_send_error(s, m, "Failure"); 02073 02074 return res; 02075 }
static int action_setvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1807 of file manager.c.
References ast_channel_unlock, ast_func_write(), ast_get_channel_by_name_locked(), ast_strdupa, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, pbx_builtin_setvar_helper(), s, and S_OR.
Referenced by __init_manager().
01808 { 01809 struct ast_channel *c = NULL; 01810 const char *name = astman_get_header(m, "Channel"); 01811 const char *varname = astman_get_header(m, "Variable"); 01812 const char *varval = astman_get_header(m, "Value"); 01813 int res = 0; 01814 01815 if (ast_strlen_zero(varname)) { 01816 astman_send_error(s, m, "No variable specified"); 01817 return 0; 01818 } 01819 01820 if (!ast_strlen_zero(name)) { 01821 c = ast_get_channel_by_name_locked(name); 01822 if (!c) { 01823 astman_send_error(s, m, "No such channel"); 01824 return 0; 01825 } 01826 } 01827 if (varname[strlen(varname)-1] == ')') { 01828 char *function = ast_strdupa(varname); 01829 res = ast_func_write(c, function, varval); 01830 } else { 01831 pbx_builtin_setvar_helper(c, varname, S_OR(varval, "")); 01832 } 01833 01834 if (c) 01835 ast_channel_unlock(c); 01836 if (res == 0) { 01837 astman_send_ack(s, m, "Variable Set"); 01838 } else { 01839 astman_send_error(s, m, "Variable not set"); 01840 } 01841 return 0; 01842 }
static int action_status | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager "status" command to show channels.
Definition at line 1908 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().
01909 { 01910 const char *name = astman_get_header(m, "Channel"); 01911 const char *cvariables = astman_get_header(m, "Variables"); 01912 char *variables = ast_strdupa(S_OR(cvariables, "")); 01913 struct ast_channel *c; 01914 char bridge[256]; 01915 struct timeval now = ast_tvnow(); 01916 long elapsed_seconds = 0; 01917 int channels = 0; 01918 int all = ast_strlen_zero(name); /* set if we want all channels */ 01919 const char *id = astman_get_header(m, "ActionID"); 01920 char idText[256]; 01921 AST_DECLARE_APP_ARGS(vars, 01922 AST_APP_ARG(name)[100]; 01923 ); 01924 struct ast_str *str = ast_str_create(1000); 01925 01926 if (!ast_strlen_zero(id)) 01927 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01928 else 01929 idText[0] = '\0'; 01930 01931 if (all) 01932 c = ast_channel_walk_locked(NULL); 01933 else { 01934 c = ast_get_channel_by_name_locked(name); 01935 if (!c) { 01936 astman_send_error(s, m, "No such channel"); 01937 ast_free(str); 01938 return 0; 01939 } 01940 } 01941 astman_send_ack(s, m, "Channel status will follow"); 01942 01943 if (!ast_strlen_zero(cvariables)) { 01944 AST_STANDARD_APP_ARGS(vars, variables); 01945 } 01946 01947 /* if we look by name, we break after the first iteration */ 01948 while (c) { 01949 if (!ast_strlen_zero(cvariables)) { 01950 int i; 01951 ast_str_reset(str); 01952 for (i = 0; i < vars.argc; i++) { 01953 char valbuf[512], *ret = NULL; 01954 01955 if (vars.name[i][strlen(vars.name[i]) - 1] == ')') { 01956 if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) { 01957 valbuf[0] = '\0'; 01958 } 01959 ret = valbuf; 01960 } else { 01961 pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL); 01962 } 01963 01964 ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret); 01965 } 01966 } 01967 01968 channels++; 01969 if (c->_bridge) 01970 snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid); 01971 else 01972 bridge[0] = '\0'; 01973 if (c->pbx) { 01974 if (c->cdr) { 01975 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01976 } 01977 astman_append(s, 01978 "Event: Status\r\n" 01979 "Privilege: Call\r\n" 01980 "Channel: %s\r\n" 01981 "CallerIDNum: %s\r\n" 01982 "CallerIDName: %s\r\n" 01983 "Accountcode: %s\r\n" 01984 "ChannelState: %d\r\n" 01985 "ChannelStateDesc: %s\r\n" 01986 "Context: %s\r\n" 01987 "Extension: %s\r\n" 01988 "Priority: %d\r\n" 01989 "Seconds: %ld\r\n" 01990 "%s" 01991 "Uniqueid: %s\r\n" 01992 "%s" 01993 "%s" 01994 "\r\n", 01995 c->name, 01996 S_OR(c->cid.cid_num, ""), 01997 S_OR(c->cid.cid_name, ""), 01998 c->accountcode, 01999 c->_state, 02000 ast_state2str(c->_state), c->context, 02001 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, str->str, idText); 02002 } else { 02003 astman_append(s, 02004 "Event: Status\r\n" 02005 "Privilege: Call\r\n" 02006 "Channel: %s\r\n" 02007 "CallerIDNum: %s\r\n" 02008 "CallerIDName: %s\r\n" 02009 "Account: %s\r\n" 02010 "State: %s\r\n" 02011 "%s" 02012 "Uniqueid: %s\r\n" 02013 "%s" 02014 "%s" 02015 "\r\n", 02016 c->name, 02017 S_OR(c->cid.cid_num, "<unknown>"), 02018 S_OR(c->cid.cid_name, "<unknown>"), 02019 c->accountcode, 02020 ast_state2str(c->_state), bridge, c->uniqueid, str->str, idText); 02021 } 02022 ast_channel_unlock(c); 02023 if (!all) 02024 break; 02025 c = ast_channel_walk_locked(c); 02026 } 02027 astman_append(s, 02028 "Event: StatusComplete\r\n" 02029 "%s" 02030 "Items: %d\r\n" 02031 "\r\n", idText, channels); 02032 ast_free(str); 02033 return 0; 02034 }
static int action_timeout | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2625 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().
02626 { 02627 struct ast_channel *c; 02628 const char *name = astman_get_header(m, "Channel"); 02629 double timeout = atof(astman_get_header(m, "Timeout")); 02630 struct timeval when = { timeout, 0 }; 02631 02632 if (ast_strlen_zero(name)) { 02633 astman_send_error(s, m, "No channel specified"); 02634 return 0; 02635 } 02636 if (!timeout || timeout < 0) { 02637 astman_send_error(s, m, "No timeout specified"); 02638 return 0; 02639 } 02640 c = ast_get_channel_by_name_locked(name); 02641 if (!c) { 02642 astman_send_error(s, m, "No such channel"); 02643 return 0; 02644 } 02645 02646 when.tv_usec = (timeout - when.tv_sec) * 1000000.0; 02647 ast_channel_setwhentohangup_tv(c, when); 02648 ast_channel_unlock(c); 02649 astman_send_ack(s, m, "Timeout Set"); 02650 return 0; 02651 }
static int action_updateconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1468 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().
01469 { 01470 struct ast_config *cfg; 01471 const char *sfn = astman_get_header(m, "SrcFilename"); 01472 const char *dfn = astman_get_header(m, "DstFilename"); 01473 int res; 01474 const char *rld = astman_get_header(m, "Reload"); 01475 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01476 enum error_type result; 01477 01478 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { 01479 astman_send_error(s, m, "Filename not specified"); 01480 return 0; 01481 } 01482 if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) { 01483 astman_send_error(s, m, "Config file not found"); 01484 return 0; 01485 } 01486 result = handle_updates(s, m, cfg, dfn); 01487 if (!result) { 01488 ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */ 01489 res = config_text_file_save(dfn, cfg, "Manager"); 01490 ast_config_destroy(cfg); 01491 if (res) { 01492 astman_send_error(s, m, "Save of config failed"); 01493 return 0; 01494 } 01495 astman_send_ack(s, m, NULL); 01496 if (!ast_strlen_zero(rld)) { 01497 if (ast_true(rld)) 01498 rld = NULL; 01499 ast_module_reload(rld); 01500 } 01501 } else { 01502 ast_config_destroy(cfg); 01503 switch(result) { 01504 case UNKNOWN_ACTION: 01505 astman_send_error(s, m, "Unknown action command"); 01506 break; 01507 case UNKNOWN_CATEGORY: 01508 astman_send_error(s, m, "Given category does not exist"); 01509 break; 01510 case UNSPECIFIED_CATEGORY: 01511 astman_send_error(s, m, "Category not specified"); 01512 break; 01513 case UNSPECIFIED_ARGUMENT: 01514 astman_send_error(s, m, "Problem with category, value, or line (if required)"); 01515 break; 01516 case FAILURE_ALLOCATION: 01517 astman_send_error(s, m, "Memory allocation failure, this should not happen"); 01518 break; 01519 case FAILURE_NEWCAT: 01520 astman_send_error(s, m, "Create category did not complete successfully"); 01521 break; 01522 case FAILURE_DELCAT: 01523 astman_send_error(s, m, "Delete category did not complete successfully"); 01524 break; 01525 case FAILURE_EMPTYCAT: 01526 astman_send_error(s, m, "Empty category did not complete successfully"); 01527 break; 01528 case FAILURE_UPDATE: 01529 astman_send_error(s, m, "Update did not complete successfully"); 01530 break; 01531 case FAILURE_DELETE: 01532 astman_send_error(s, m, "Delete did not complete successfully"); 01533 break; 01534 case FAILURE_APPEND: 01535 astman_send_error(s, m, "Append did not complete successfully"); 01536 break; 01537 } 01538 } 01539 return 0; 01540 }
static int action_userevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2688 of file manager.c.
References ast_str_append(), ast_str_reset(), ast_str_thread_get(), astman_get_header(), astman_send_ack(), EVENT_FLAG_USER, message::hdrcount, message::headers, manager_event, s, ast_str::str, and userevent_buf.
Referenced by __init_manager().
02689 { 02690 const char *event = astman_get_header(m, "UserEvent"); 02691 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16); 02692 int x; 02693 02694 ast_str_reset(body); 02695 02696 for (x = 0; x < m->hdrcount; x++) { 02697 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 02698 ast_str_append(&body, 0, "%s\r\n", m->headers[x]); 02699 } 02700 } 02701 02702 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body->str); 02703 astman_send_ack(s, m, "Event Sent"); 02704 return 0; 02705 }
static int action_waitevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1574 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().
01575 { 01576 const char *timeouts = astman_get_header(m, "Timeout"); 01577 int timeout = -1; 01578 int x; 01579 int needexit = 0; 01580 const char *id = astman_get_header(m, "ActionID"); 01581 char idText[256]; 01582 01583 if (!ast_strlen_zero(id)) 01584 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01585 else 01586 idText[0] = '\0'; 01587 01588 if (!ast_strlen_zero(timeouts)) { 01589 sscanf(timeouts, "%30i", &timeout); 01590 if (timeout < -1) 01591 timeout = -1; 01592 /* XXX maybe put an upper bound, or prevent the use of 0 ? */ 01593 } 01594 01595 ast_mutex_lock(&s->session->__lock); 01596 if (s->session->waiting_thread != AST_PTHREADT_NULL) 01597 pthread_kill(s->session->waiting_thread, SIGURG); 01598 01599 if (s->session->managerid) { /* AMI-over-HTTP session */ 01600 /* 01601 * Make sure the timeout is within the expire time of the session, 01602 * as the client will likely abort the request if it does not see 01603 * data coming after some amount of time. 01604 */ 01605 time_t now = time(NULL); 01606 int max = s->session->sessiontimeout - now - 10; 01607 01608 if (max < 0) /* We are already late. Strange but possible. */ 01609 max = 0; 01610 if (timeout < 0 || timeout > max) 01611 timeout = max; 01612 if (!s->session->send_events) /* make sure we record events */ 01613 s->session->send_events = -1; 01614 } 01615 ast_mutex_unlock(&s->session->__lock); 01616 01617 /* XXX should this go inside the lock ? */ 01618 s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */ 01619 ast_debug(1, "Starting waiting for an event!\n"); 01620 01621 for (x = 0; x < timeout || timeout < 0; x++) { 01622 ast_mutex_lock(&s->session->__lock); 01623 if (NEW_EVENT(s)) 01624 needexit = 1; 01625 /* We can have multiple HTTP session point to the same mansession entry. 01626 * The way we deal with it is not very nice: newcomers kick out the previous 01627 * HTTP session. XXX this needs to be improved. 01628 */ 01629 if (s->session->waiting_thread != pthread_self()) 01630 needexit = 1; 01631 if (s->session->needdestroy) 01632 needexit = 1; 01633 ast_mutex_unlock(&s->session->__lock); 01634 if (needexit) 01635 break; 01636 if (s->session->managerid == 0) { /* AMI session */ 01637 if (ast_wait_for_input(s->session->fd, 1000)) 01638 break; 01639 } else { /* HTTP session */ 01640 sleep(1); 01641 } 01642 } 01643 ast_debug(1, "Finished waiting for an event!\n"); 01644 ast_mutex_lock(&s->session->__lock); 01645 if (s->session->waiting_thread == pthread_self()) { 01646 struct eventqent *eqe; 01647 astman_send_response(s, m, "Success", "Waiting for Event completed."); 01648 while ( (eqe = NEW_EVENT(s)) ) { 01649 ref_event(eqe); 01650 if (((s->session->readperm & eqe->category) == eqe->category) && 01651 ((s->session->send_events & eqe->category) == eqe->category)) { 01652 astman_append(s, "%s", eqe->eventdata); 01653 } 01654 s->session->last_ev = unref_event(s->session->last_ev); 01655 } 01656 astman_append(s, 01657 "Event: WaitEventComplete\r\n" 01658 "%s" 01659 "\r\n", idText); 01660 s->session->waiting_thread = AST_PTHREADT_NULL; 01661 } else { 01662 ast_debug(1, "Abandoning event request!\n"); 01663 } 01664 ast_mutex_unlock(&s->session->__lock); 01665 return 0; 01666 }
static int append_event | ( | const char * | str, | |
int | category | |||
) | [static] |
Definition at line 3270 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().
03271 { 03272 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 03273 static int seq; /* sequence number */ 03274 03275 if (!tmp) 03276 return -1; 03277 03278 /* need to init all fields, because ast_malloc() does not */ 03279 tmp->usecount = 0; 03280 tmp->category = category; 03281 tmp->seq = ast_atomic_fetchadd_int(&seq, 1); 03282 AST_LIST_NEXT(tmp, eq_next) = NULL; 03283 strcpy(tmp->eventdata, str); 03284 03285 AST_LIST_LOCK(&all_events); 03286 AST_LIST_INSERT_TAIL(&all_events, tmp, eq_next); 03287 AST_LIST_UNLOCK(&all_events); 03288 03289 return 0; 03290 }
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 414 of file manager.c.
References eventqent::next.
Referenced by get_perm().
00415 { 00416 const char *val = bigstr, *next; 00417 00418 do { 00419 if ((next = strchr(val, delim))) { 00420 if (!strncmp(val, smallstr, (next - val))) 00421 return 1; 00422 else 00423 continue; 00424 } else 00425 return !strcmp(smallstr, val); 00426 } while (*(val = (next + 1))); 00427 00428 return 0; 00429 }
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 3445 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().
03446 { 03447 struct manager_action *cur = NULL; 03448 03449 if (!(cur = ast_calloc(1, sizeof(*cur)))) 03450 return -1; 03451 03452 cur->action = action; 03453 cur->authority = auth; 03454 cur->func = func; 03455 cur->synopsis = synopsis; 03456 cur->description = description; 03457 03458 if (ast_manager_register_struct(cur)) { 03459 ast_free(cur); 03460 return -1; 03461 } 03462 03463 return 0; 03464 }
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 257 of file manager.c.
References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
00258 { 00259 AST_RWLIST_WRLOCK(&manager_hooks); 00260 AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list); 00261 AST_RWLIST_UNLOCK(&manager_hooks); 00262 return; 00263 }
static int ast_manager_register_struct | ( | struct manager_action * | act | ) | [static] |
Definition at line 3409 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().
03410 { 03411 struct manager_action *cur, *prev = NULL; 03412 struct timespec tv = { 5, }; 03413 03414 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03415 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03416 return -1; 03417 } 03418 AST_RWLIST_TRAVERSE(&actions, cur, list) { 03419 int ret = strcasecmp(cur->action, act->action); 03420 if (ret == 0) { 03421 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 03422 AST_RWLIST_UNLOCK(&actions); 03423 return -1; 03424 } 03425 if (ret > 0) { /* Insert these alphabetically */ 03426 prev = cur; 03427 break; 03428 } 03429 } 03430 03431 if (prev) 03432 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list); 03433 else 03434 AST_RWLIST_INSERT_HEAD(&actions, act, list); 03435 03436 ast_verb(2, "Manager registered action %s\n", act->action); 03437 03438 AST_RWLIST_UNLOCK(&actions); 03439 03440 return 0; 03441 }
int ast_manager_unregister | ( | char * | action | ) |
Unregister a registered manager command.
action | Name of registered Action: |
Definition at line 3376 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().
03377 { 03378 struct manager_action *cur; 03379 struct timespec tv = { 5, }; 03380 03381 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03382 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03383 return -1; 03384 } 03385 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) { 03386 if (!strcasecmp(action, cur->action)) { 03387 AST_RWLIST_REMOVE_CURRENT(list); 03388 ast_free(cur); 03389 ast_verb(2, "Manager unregistered action %s\n", action); 03390 break; 03391 } 03392 } 03393 AST_RWLIST_TRAVERSE_SAFE_END; 03394 AST_RWLIST_UNLOCK(&actions); 03395 03396 return 0; 03397 }
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 266 of file manager.c.
References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
00267 { 00268 AST_RWLIST_WRLOCK(&manager_hooks); 00269 AST_RWLIST_REMOVE(&manager_hooks, hook, list); 00270 AST_RWLIST_UNLOCK(&manager_hooks); 00271 return; 00272 }
void astman_append | ( | struct mansession * | s, | |
const char * | fmt, | |||
... | ||||
) |
utility functions for creating AMI replies
Definition at line 970 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().
00971 { 00972 va_list ap; 00973 struct ast_str *buf; 00974 00975 if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) 00976 return; 00977 00978 va_start(ap, fmt); 00979 ast_str_set_va(&buf, 0, fmt, ap); 00980 va_end(ap); 00981 00982 if (s->f != NULL || s->session->f != NULL) { 00983 send_string(s, buf->str); 00984 } else { 00985 ast_verbose("fd == -1 in astman_append, should not happen\n"); 00986 } 00987 }
const char* astman_get_header | ( | const struct message * | m, | |
char * | var | |||
) |
Get header from mananger transaction.
Definition at line 898 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().
00899 { 00900 return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH); 00901 }
struct ast_variable* astman_get_variables | ( | const struct message * | m | ) |
Get a linked list of the Variable: headers.
Definition at line 904 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().
00905 { 00906 int varlen, x, y; 00907 struct ast_variable *head = NULL, *cur; 00908 00909 AST_DECLARE_APP_ARGS(args, 00910 AST_APP_ARG(vars)[32]; 00911 ); 00912 00913 varlen = strlen("Variable: "); 00914 00915 for (x = 0; x < m->hdrcount; x++) { 00916 char *parse, *var, *val; 00917 00918 if (strncasecmp("Variable: ", m->headers[x], varlen)) 00919 continue; 00920 parse = ast_strdupa(m->headers[x] + varlen); 00921 00922 AST_STANDARD_APP_ARGS(args, parse); 00923 if (!args.argc) 00924 continue; 00925 for (y = 0; y < args.argc; y++) { 00926 if (!args.vars[y]) 00927 continue; 00928 var = val = ast_strdupa(args.vars[y]); 00929 strsep(&val, "="); 00930 if (!val || ast_strlen_zero(var)) 00931 continue; 00932 cur = ast_variable_new(var, val, ""); 00933 cur->next = head; 00934 head = cur; 00935 } 00936 } 00937 00938 return head; 00939 }
void astman_send_ack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg | |||
) |
Send ack in manager transaction.
Definition at line 1033 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(), action_userevent(), 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().
01034 { 01035 astman_send_response_full(s, m, "Success", msg, NULL); 01036 }
void astman_send_error | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | error | |||
) |
Send error in manager transaction.
Definition at line 1028 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_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_modulecheck(), manager_moduleload(), manager_park(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_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().
01029 { 01030 astman_send_response_full(s, m, "Error", error, NULL); 01031 }
void astman_send_listack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg, | |||
char * | listflag | |||
) |
Send ack in manager list transaction.
Definition at line 1043 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().
01044 { 01045 astman_send_response_full(s, m, "Success", msg, listflag); 01046 }
void astman_send_response | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg | |||
) |
Send response in manager transaction.
Definition at line 1023 of file manager.c.
References astman_send_response_full(), and s.
Referenced by action_logoff().
01024 { 01025 astman_send_response_full(s, m, resp, msg, NULL); 01026 }
static void astman_send_response_full | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg, | |||
char * | listflag | |||
) | [static] |
Definition at line 1006 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().
01007 { 01008 const char *id = astman_get_header(m, "ActionID"); 01009 01010 astman_append(s, "Response: %s\r\n", resp); 01011 if (!ast_strlen_zero(id)) 01012 astman_append(s, "ActionID: %s\r\n", id); 01013 if (listflag) 01014 astman_append(s, "Eventlist: %s\r\n", listflag); /* Start, complete, cancelled */ 01015 if (msg == MSG_MOREDATA) 01016 return; 01017 else if (msg) 01018 astman_append(s, "Message: %s\r\n\r\n", msg); 01019 else 01020 astman_append(s, "\r\n"); 01021 }
static void astman_start_ack | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1038 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().
01039 { 01040 astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL); 01041 }
static int authenticate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1072 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().
01073 { 01074 const char *username = astman_get_header(m, "Username"); 01075 const char *password = astman_get_header(m, "Secret"); 01076 int error = -1; 01077 struct ast_manager_user *user = NULL; 01078 01079 if (ast_strlen_zero(username)) /* missing username */ 01080 return -1; 01081 01082 /* locate user in locked state */ 01083 AST_RWLIST_WRLOCK(&users); 01084 01085 if (!(user = get_manager_by_name_locked(username))) { 01086 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01087 } else if (user->ha && !ast_apply_ha(user->ha, &(s->session->sin))) { 01088 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01089 } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) { 01090 const char *key = astman_get_header(m, "Key"); 01091 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) { 01092 int x; 01093 int len = 0; 01094 char md5key[256] = ""; 01095 struct MD5Context md5; 01096 unsigned char digest[16]; 01097 01098 MD5Init(&md5); 01099 MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge)); 01100 MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret)); 01101 MD5Final(digest, &md5); 01102 for (x = 0; x < 16; x++) 01103 len += sprintf(md5key + len, "%2.2x", digest[x]); 01104 if (!strcmp(md5key, key)) 01105 error = 0; 01106 } else { 01107 ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n", 01108 S_OR(s->session->challenge, "")); 01109 } 01110 } else if (password && user->secret && !strcmp(password, user->secret)) 01111 error = 0; 01112 01113 if (error) { 01114 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01115 AST_RWLIST_UNLOCK(&users); 01116 return -1; 01117 } 01118 01119 /* auth complete */ 01120 01121 ast_copy_string(s->session->username, username, sizeof(s->session->username)); 01122 s->session->readperm = user->readperm; 01123 s->session->writeperm = user->writeperm; 01124 s->session->writetimeout = user->writetimeout; 01125 s->session->sessionstart = time(NULL); 01126 set_eventmask(s, astman_get_header(m, "Events")); 01127 01128 AST_RWLIST_UNLOCK(&users); 01129 return 0; 01130 }
static char* authority_to_str | ( | int | authority, | |
struct ast_str ** | res | |||
) | [static] |
Convert authority code to a list of options.
Definition at line 390 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().
00391 { 00392 int i; 00393 char *sep = ""; 00394 00395 (*res)->used = 0; 00396 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) { 00397 if (authority & perms[i].num) { 00398 ast_str_append(res, 0, "%s%s", sep, perms[i].label); 00399 sep = ","; 00400 } 00401 } 00402 00403 if ((*res)->used == 0) /* replace empty string with something sensible */ 00404 ast_str_append(res, 0, "<none>"); 00405 00406 return (*res)->str; 00407 }
static int check_blacklist | ( | const char * | cmd | ) | [static] |
Definition at line 2220 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().
02221 { 02222 char *cmd_copy, *cur_cmd; 02223 char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, }; 02224 int i; 02225 02226 cmd_copy = ast_strdupa(cmd); 02227 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) { 02228 cur_cmd = ast_strip(cur_cmd); 02229 if (ast_strlen_zero(cur_cmd)) { 02230 i--; 02231 continue; 02232 } 02233 02234 cmd_words[i] = cur_cmd; 02235 } 02236 02237 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) { 02238 int j, match = 1; 02239 02240 for (j = 0; command_blacklist[i].words[j]; j++) { 02241 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) { 02242 match = 0; 02243 break; 02244 } 02245 } 02246 02247 if (match) { 02248 return 1; 02249 } 02250 } 02251 02252 return 0; 02253 }
int check_manager_enabled | ( | void | ) |
Check if AMI is enabled.
Definition at line 317 of file manager.c.
Referenced by handle_show_settings().
00318 { 00319 return manager_enabled; 00320 }
static int check_manager_session_inuse | ( | const char * | name | ) | [static] |
Definition at line 473 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().
00474 { 00475 struct mansession_session *session = NULL; 00476 00477 AST_LIST_LOCK(&sessions); 00478 AST_LIST_TRAVERSE(&sessions, session, list) { 00479 if (!strcasecmp(session->username, name)) 00480 break; 00481 } 00482 AST_LIST_UNLOCK(&sessions); 00483 00484 return session ? 1 : 0; 00485 }
int check_webmanager_enabled | ( | void | ) |
Check if AMI/HTTP is enabled.
Definition at line 322 of file manager.c.
Referenced by action_coresettings(), and handle_show_settings().
00323 { 00324 return (webmanager_enabled && manager_enabled); 00325 }
static void destroy_session | ( | struct mansession_session * | session | ) | [static] |
Definition at line 853 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().
00854 { 00855 AST_LIST_LOCK(&sessions); 00856 AST_LIST_REMOVE(&sessions, session, list); 00857 ast_atomic_fetchadd_int(&num_sessions, -1); 00858 free_session(session); 00859 AST_LIST_UNLOCK(&sessions); 00860 }
static int do_message | ( | struct mansession * | s | ) | [static] |
Definition at line 3134 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().
03135 { 03136 struct message m = { 0 }; 03137 char header_buf[sizeof(s->session->inbuf)] = { '\0' }; 03138 int res; 03139 03140 for (;;) { 03141 /* Check if any events are pending and do them if needed */ 03142 if (process_events(s)) 03143 return -1; 03144 res = get_input(s, header_buf); 03145 if (res == 0) { 03146 continue; 03147 } else if (res > 0) { 03148 if (ast_strlen_zero(header_buf)) 03149 return process_message(s, &m) ? -1 : 0; 03150 else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) 03151 m.headers[m.hdrcount++] = ast_strdupa(header_buf); 03152 } else { 03153 return res; 03154 } 03155 } 03156 }
static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 2333 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().
02334 { 02335 struct fast_originate_helper *in = data; 02336 int res; 02337 int reason = 0; 02338 struct ast_channel *chan = NULL; 02339 char requested_channel[AST_CHANNEL_NAME]; 02340 02341 if (!ast_strlen_zero(in->app)) { 02342 res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1, 02343 S_OR(in->cid_num, NULL), 02344 S_OR(in->cid_name, NULL), 02345 in->vars, in->account, &chan); 02346 } else { 02347 res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 02348 S_OR(in->cid_num, NULL), 02349 S_OR(in->cid_name, NULL), 02350 in->vars, in->account, &chan); 02351 } 02352 02353 if (!chan) 02354 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 02355 /* Tell the manager what happened with the channel */ 02356 manager_event(EVENT_FLAG_CALL, "OriginateResponse", 02357 "%s%s" 02358 "Response: %s\r\n" 02359 "Channel: %s\r\n" 02360 "Context: %s\r\n" 02361 "Exten: %s\r\n" 02362 "Reason: %d\r\n" 02363 "Uniqueid: %s\r\n" 02364 "CallerIDNum: %s\r\n" 02365 "CallerIDName: %s\r\n", 02366 in->idtext, ast_strlen_zero(in->idtext) ? "" : "\r\n", res ? "Failure" : "Success", 02367 chan ? chan->name : requested_channel, in->context, in->exten, reason, 02368 chan ? chan->uniqueid : "<null>", 02369 S_OR(in->cid_num, "<unknown>"), 02370 S_OR(in->cid_name, "<unknown>") 02371 ); 02372 02373 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 02374 if (chan) 02375 ast_channel_unlock(chan); 02376 ast_free(in); 02377 return NULL; 02378 }
static void free_session | ( | struct mansession_session * | session | ) | [static] |
Definition at line 835 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().
00836 { 00837 struct eventqent *eqe = session->last_ev; 00838 struct ast_datastore *datastore; 00839 00840 /* Get rid of each of the data stores on the session */ 00841 while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) { 00842 /* Free the data store */ 00843 ast_datastore_free(datastore); 00844 } 00845 00846 if (session->f != NULL) 00847 fclose(session->f); 00848 ast_mutex_destroy(&session->__lock); 00849 ast_free(session); 00850 unref_event(eqe); 00851 }
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 3064 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().
03065 { 03066 int res, x; 03067 int maxlen = sizeof(s->session->inbuf) - 1; 03068 char *src = s->session->inbuf; 03069 03070 /* 03071 * Look for \r\n within the buffer. If found, copy to the output 03072 * buffer and return, trimming the \r\n (not used afterwards). 03073 */ 03074 for (x = 0; x < s->session->inlen; x++) { 03075 int cr; /* set if we have \r */ 03076 if (src[x] == '\r' && x+1 < s->session->inlen && src[x+1] == '\n') 03077 cr = 2; /* Found. Update length to include \r\n */ 03078 else if (src[x] == '\n') 03079 cr = 1; /* also accept \n only */ 03080 else 03081 continue; 03082 memmove(output, src, x); /*... but trim \r\n */ 03083 output[x] = '\0'; /* terminate the string */ 03084 x += cr; /* number of bytes used */ 03085 s->session->inlen -= x; /* remaining size */ 03086 memmove(src, src + x, s->session->inlen); /* remove used bytes */ 03087 return 1; 03088 } 03089 if (s->session->inlen >= maxlen) { 03090 /* no crlf found, and buffer full - sorry, too long for us */ 03091 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src); 03092 s->session->inlen = 0; 03093 } 03094 res = 0; 03095 while (res == 0) { 03096 /* XXX do we really need this locking ? */ 03097 ast_mutex_lock(&s->session->__lock); 03098 if (s->session->pending_event) { 03099 s->session->pending_event = 0; 03100 ast_mutex_unlock(&s->session->__lock); 03101 return 0; 03102 } 03103 s->session->waiting_thread = pthread_self(); 03104 ast_mutex_unlock(&s->session->__lock); 03105 03106 res = ast_wait_for_input(s->session->fd, -1); /* return 0 on timeout ? */ 03107 03108 ast_mutex_lock(&s->session->__lock); 03109 s->session->waiting_thread = AST_PTHREADT_NULL; 03110 ast_mutex_unlock(&s->session->__lock); 03111 } 03112 if (res < 0) { 03113 /* If we get a signal from some other thread (typically because 03114 * there are new events queued), return 0 to notify the caller. 03115 */ 03116 if (errno == EINTR || errno == EAGAIN) 03117 return 0; 03118 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno)); 03119 return -1; 03120 } 03121 ast_mutex_lock(&s->session->__lock); 03122 res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f); 03123 if (res < 1) 03124 res = -1; /* error return */ 03125 else { 03126 s->session->inlen += res; 03127 src[s->session->inlen] = '\0'; 03128 res = 0; 03129 } 03130 ast_mutex_unlock(&s->session->__lock); 03131 return res; 03132 }
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 492 of file manager.c.
References AST_RWLIST_TRAVERSE, ast_manager_user::list, and user.
Referenced by authenticate(), handle_showmanager(), and manager_displayconnects().
00493 { 00494 struct ast_manager_user *user = NULL; 00495 00496 AST_RWLIST_TRAVERSE(&users, user, list) 00497 if (!strcasecmp(user->username, name)) 00498 break; 00499 return user; 00500 }
static int get_perm | ( | const char * | instr | ) | [static] |
Definition at line 431 of file manager.c.
References ARRAY_LEN, ast_instring(), permalias::num, and perms.
Referenced by strings_to_mask().
00432 { 00433 int x = 0, ret = 0; 00434 00435 if (!instr) 00436 return 0; 00437 00438 for (x = 0; x < ARRAY_LEN(perms); x++) { 00439 if (ast_instring(instr, perms[x].label, ',')) 00440 ret |= perms[x].num; 00441 } 00442 00443 return ret; 00444 }
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 331 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().
00332 { 00333 struct eventqent *ret; 00334 00335 AST_LIST_LOCK(&all_events); 00336 ret = AST_LIST_LAST(&all_events); 00337 /* the list is never empty now, but may become so when 00338 * we optimize it in the future, so be prepared. 00339 */ 00340 if (ret) 00341 ast_atomic_fetchadd_int(&ret->usecount, 1); 00342 AST_LIST_UNLOCK(&all_events); 00343 return ret; 00344 }
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 785 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.
00786 { 00787 switch (cmd) { 00788 case CLI_INIT: 00789 e->command = "manager reload"; 00790 e->usage = 00791 "Usage: manager reload\n" 00792 " Reloads the manager configuration.\n"; 00793 return NULL; 00794 case CLI_GENERATE: 00795 return NULL; 00796 } 00797 if (a->argc > 2) 00798 return CLI_SHOWUSAGE; 00799 reload_manager(); 00800 return CLI_SUCCESS; 00801 }
static char* handle_mandebug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 566 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.
00567 { 00568 switch (cmd) { 00569 case CLI_INIT: 00570 e->command = "manager debug [on|off]"; 00571 e->usage = "Usage: manager debug [on|off]\n Show, enable, disable debugging of the manager code.\n"; 00572 return NULL; 00573 case CLI_GENERATE: 00574 return NULL; 00575 } 00576 if (a->argc == 2) 00577 ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off"); 00578 else if (a->argc == 3) { 00579 if (!strcasecmp(a->argv[2], "on")) 00580 manager_debug = 1; 00581 else if (!strcasecmp(a->argv[2], "off")) 00582 manager_debug = 0; 00583 else 00584 return CLI_SHOWUSAGE; 00585 } 00586 return CLI_SUCCESS; 00587 }
static char* handle_showmanager | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 589 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.
00590 { 00591 struct ast_manager_user *user = NULL; 00592 int l, which; 00593 char *ret = NULL; 00594 struct ast_str *rauthority = ast_str_alloca(128); 00595 struct ast_str *wauthority = ast_str_alloca(128); 00596 00597 switch (cmd) { 00598 case CLI_INIT: 00599 e->command = "manager show user"; 00600 e->usage = 00601 " Usage: manager show user <user>\n" 00602 " Display all information related to the manager user specified.\n"; 00603 return NULL; 00604 case CLI_GENERATE: 00605 l = strlen(a->word); 00606 which = 0; 00607 if (a->pos != 3) 00608 return NULL; 00609 AST_RWLIST_RDLOCK(&users); 00610 AST_RWLIST_TRAVERSE(&users, user, list) { 00611 if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) { 00612 ret = ast_strdup(user->username); 00613 break; 00614 } 00615 } 00616 AST_RWLIST_UNLOCK(&users); 00617 return ret; 00618 } 00619 00620 if (a->argc != 4) 00621 return CLI_SHOWUSAGE; 00622 00623 AST_RWLIST_RDLOCK(&users); 00624 00625 if (!(user = get_manager_by_name_locked(a->argv[3]))) { 00626 ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]); 00627 AST_RWLIST_UNLOCK(&users); 00628 return CLI_SUCCESS; 00629 } 00630 00631 ast_cli(a->fd, "\n"); 00632 ast_cli(a->fd, 00633 " username: %s\n" 00634 " secret: %s\n" 00635 " acl: %s\n" 00636 " read perm: %s\n" 00637 " write perm: %s\n" 00638 "displayconnects: %s\n", 00639 (user->username ? user->username : "(N/A)"), 00640 (user->secret ? "<Set>" : "(N/A)"), 00641 (user->ha ? "yes" : "no"), 00642 authority_to_str(user->readperm, &rauthority), 00643 authority_to_str(user->writeperm, &wauthority), 00644 (user->displayconnects ? "yes" : "no")); 00645 00646 AST_RWLIST_UNLOCK(&users); 00647 00648 return CLI_SUCCESS; 00649 }
static char* handle_showmanagers | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 652 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.
00653 { 00654 struct ast_manager_user *user = NULL; 00655 int count_amu = 0; 00656 switch (cmd) { 00657 case CLI_INIT: 00658 e->command = "manager show users"; 00659 e->usage = 00660 "Usage: manager show users\n" 00661 " Prints a listing of all managers that are currently configured on that\n" 00662 " system.\n"; 00663 return NULL; 00664 case CLI_GENERATE: 00665 return NULL; 00666 } 00667 if (a->argc != 3) 00668 return CLI_SHOWUSAGE; 00669 00670 AST_RWLIST_RDLOCK(&users); 00671 00672 /* If there are no users, print out something along those lines */ 00673 if (AST_RWLIST_EMPTY(&users)) { 00674 ast_cli(a->fd, "There are no manager users.\n"); 00675 AST_RWLIST_UNLOCK(&users); 00676 return CLI_SUCCESS; 00677 } 00678 00679 ast_cli(a->fd, "\nusername\n--------\n"); 00680 00681 AST_RWLIST_TRAVERSE(&users, user, list) { 00682 ast_cli(a->fd, "%s\n", user->username); 00683 count_amu++; 00684 } 00685 00686 AST_RWLIST_UNLOCK(&users); 00687 00688 ast_cli(a->fd, "-------------------\n"); 00689 ast_cli(a->fd, "%d manager users configured.\n", count_amu); 00690 00691 return CLI_SUCCESS; 00692 }
static char* handle_showmancmd | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 519 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.
00520 { 00521 struct manager_action *cur; 00522 struct ast_str *authority; 00523 int num, l, which; 00524 char *ret = NULL; 00525 switch (cmd) { 00526 case CLI_INIT: 00527 e->command = "manager show command"; 00528 e->usage = 00529 "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n" 00530 " Shows the detailed description for a specific Asterisk manager interface command.\n"; 00531 return NULL; 00532 case CLI_GENERATE: 00533 l = strlen(a->word); 00534 which = 0; 00535 AST_RWLIST_RDLOCK(&actions); 00536 AST_RWLIST_TRAVERSE(&actions, cur, list) { 00537 if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) { 00538 ret = ast_strdup(cur->action); 00539 break; /* make sure we exit even if ast_strdup() returns NULL */ 00540 } 00541 } 00542 AST_RWLIST_UNLOCK(&actions); 00543 return ret; 00544 } 00545 authority = ast_str_alloca(80); 00546 if (a->argc < 4) { 00547 return CLI_SHOWUSAGE; 00548 } 00549 00550 AST_RWLIST_RDLOCK(&actions); 00551 AST_RWLIST_TRAVERSE(&actions, cur, list) { 00552 for (num = 3; num < a->argc; num++) { 00553 if (!strcasecmp(cur->action, a->argv[num])) { 00554 ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", 00555 cur->action, cur->synopsis, 00556 authority_to_str(cur->authority, &authority), 00557 S_OR(cur->description, "")); 00558 } 00559 } 00560 } 00561 AST_RWLIST_UNLOCK(&actions); 00562 00563 return CLI_SUCCESS; 00564 }
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 696 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.
00697 { 00698 struct manager_action *cur; 00699 struct ast_str *authority; 00700 #define HSMC_FORMAT " %-15.15s %-15.15s %-55.55s\n" 00701 switch (cmd) { 00702 case CLI_INIT: 00703 e->command = "manager show commands"; 00704 e->usage = 00705 "Usage: manager show commands\n" 00706 " Prints a listing of all the available Asterisk manager interface commands.\n"; 00707 return NULL; 00708 case CLI_GENERATE: 00709 return NULL; 00710 } 00711 authority = ast_str_alloca(80); 00712 ast_cli(a->fd, HSMC_FORMAT, "Action", "Privilege", "Synopsis"); 00713 ast_cli(a->fd, HSMC_FORMAT, "------", "---------", "--------"); 00714 00715 AST_RWLIST_RDLOCK(&actions); 00716 AST_RWLIST_TRAVERSE(&actions, cur, list) 00717 ast_cli(a->fd, HSMC_FORMAT, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis); 00718 AST_RWLIST_UNLOCK(&actions); 00719 00720 return CLI_SUCCESS; 00721 }
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 724 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.
00725 { 00726 struct mansession_session *session; 00727 time_t now = time(NULL); 00728 #define HSMCONN_FORMAT1 " %-15.15s %-15.15s %-10.10s %-10.10s %-8.8s %-8.8s %-5.5s %-5.5s\n" 00729 #define HSMCONN_FORMAT2 " %-15.15s %-15.15s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\n" 00730 int count = 0; 00731 switch (cmd) { 00732 case CLI_INIT: 00733 e->command = "manager show connected"; 00734 e->usage = 00735 "Usage: manager show connected\n" 00736 " Prints a listing of the users that are currently connected to the\n" 00737 "Asterisk manager interface.\n"; 00738 return NULL; 00739 case CLI_GENERATE: 00740 return NULL; 00741 } 00742 00743 ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write"); 00744 00745 AST_LIST_LOCK(&sessions); 00746 AST_LIST_TRAVERSE(&sessions, session, list) { 00747 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); 00748 count++; 00749 } 00750 AST_LIST_UNLOCK(&sessions); 00751 00752 ast_cli(a->fd, "%d users connected.\n", count); 00753 00754 return CLI_SUCCESS; 00755 }
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 759 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.
00760 { 00761 struct eventqent *s; 00762 switch (cmd) { 00763 case CLI_INIT: 00764 e->command = "manager show eventq"; 00765 e->usage = 00766 "Usage: manager show eventq\n" 00767 " Prints a listing of all events pending in the Asterisk manger\n" 00768 "event queue.\n"; 00769 return NULL; 00770 case CLI_GENERATE: 00771 return NULL; 00772 } 00773 AST_LIST_LOCK(&all_events); 00774 AST_LIST_TRAVERSE(&all_events, s, eq_next) { 00775 ast_cli(a->fd, "Usecount: %d\n", s->usecount); 00776 ast_cli(a->fd, "Category: %d\n", s->category); 00777 ast_cli(a->fd, "Event:\n%s", s->eventdata); 00778 } 00779 AST_LIST_UNLOCK(&all_events); 00780 00781 return CLI_SUCCESS; 00782 }
static enum error_type handle_updates | ( | struct mansession * | s, | |
const struct message * | m, | |||
struct ast_config * | cfg, | |||
const char * | dfn | |||
) | [static] |
Definition at line 1311 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().
01312 { 01313 int x; 01314 char hdr[40]; 01315 const char *action, *cat, *var, *value, *match, *line; 01316 struct ast_category *category; 01317 struct ast_variable *v; 01318 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 01319 enum error_type result = 0; 01320 01321 for (x = 0; x < 100000; x++) { /* 100000 = the max number of allowed updates + 1 */ 01322 unsigned int object = 0; 01323 01324 snprintf(hdr, sizeof(hdr), "Action-%06d", x); 01325 action = astman_get_header(m, hdr); 01326 if (ast_strlen_zero(action)) /* breaks the for loop if no action header */ 01327 break; /* this could cause problems if actions come in misnumbered */ 01328 01329 snprintf(hdr, sizeof(hdr), "Cat-%06d", x); 01330 cat = astman_get_header(m, hdr); 01331 if (ast_strlen_zero(cat)) { /* every action needs a category */ 01332 result = UNSPECIFIED_CATEGORY; 01333 break; 01334 } 01335 01336 snprintf(hdr, sizeof(hdr), "Var-%06d", x); 01337 var = astman_get_header(m, hdr); 01338 01339 snprintf(hdr, sizeof(hdr), "Value-%06d", x); 01340 value = astman_get_header(m, hdr); 01341 01342 if (!ast_strlen_zero(value) && *value == '>') { 01343 object = 1; 01344 value++; 01345 } 01346 01347 snprintf(hdr, sizeof(hdr), "Match-%06d", x); 01348 match = astman_get_header(m, hdr); 01349 01350 snprintf(hdr, sizeof(hdr), "Line-%06d", x); 01351 line = astman_get_header(m, hdr); 01352 01353 if (!strcasecmp(action, "newcat")) { 01354 if (ast_category_get(cfg,cat)) { /* check to make sure the cat doesn't */ 01355 result = FAILURE_NEWCAT; /* already exist */ 01356 break; 01357 } 01358 if (!(category = ast_category_new(cat, dfn, -1))) { 01359 result = FAILURE_ALLOCATION; 01360 break; 01361 } 01362 if (ast_strlen_zero(match)) { 01363 ast_category_append(cfg, category); 01364 } else 01365 ast_category_insert(cfg, category, match); 01366 } else if (!strcasecmp(action, "renamecat")) { 01367 if (ast_strlen_zero(value)) { 01368 result = UNSPECIFIED_ARGUMENT; 01369 break; 01370 } 01371 if (!(category = ast_category_get(cfg, cat))) { 01372 result = UNKNOWN_CATEGORY; 01373 break; 01374 } 01375 ast_category_rename(category, value); 01376 } else if (!strcasecmp(action, "delcat")) { 01377 if (ast_category_delete(cfg, cat)) { 01378 result = FAILURE_DELCAT; 01379 break; 01380 } 01381 } else if (!strcasecmp(action, "emptycat")) { 01382 if (ast_category_empty(cfg, cat)) { 01383 result = FAILURE_EMPTYCAT; 01384 break; 01385 } 01386 } else if (!strcasecmp(action, "update")) { 01387 if (ast_strlen_zero(var)) { 01388 result = UNSPECIFIED_ARGUMENT; 01389 break; 01390 } 01391 if (!(category = ast_category_get(cfg,cat))) { 01392 result = UNKNOWN_CATEGORY; 01393 break; 01394 } 01395 if (ast_variable_update(category, var, value, match, object)) { 01396 result = FAILURE_UPDATE; 01397 break; 01398 } 01399 } else if (!strcasecmp(action, "delete")) { 01400 if ((ast_strlen_zero(var) && ast_strlen_zero(line))) { 01401 result = UNSPECIFIED_ARGUMENT; 01402 break; 01403 } 01404 if (!(category = ast_category_get(cfg, cat))) { 01405 result = UNKNOWN_CATEGORY; 01406 break; 01407 } 01408 if (ast_variable_delete(category, var, match, line)) { 01409 result = FAILURE_DELETE; 01410 break; 01411 } 01412 } else if (!strcasecmp(action, "append")) { 01413 if (ast_strlen_zero(var)) { 01414 result = UNSPECIFIED_ARGUMENT; 01415 break; 01416 } 01417 if (!(category = ast_category_get(cfg, cat))) { 01418 result = UNKNOWN_CATEGORY; 01419 break; 01420 } 01421 if (!(v = ast_variable_new(var, value, dfn))) { 01422 result = FAILURE_ALLOCATION; 01423 break; 01424 } 01425 if (object || (match && !strcasecmp(match, "object"))) 01426 v->object = 1; 01427 ast_variable_append(category, v); 01428 } else if (!strcasecmp(action, "insert")) { 01429 if (ast_strlen_zero(var) || ast_strlen_zero(line)) { 01430 result = UNSPECIFIED_ARGUMENT; 01431 break; 01432 } 01433 if (!(category = ast_category_get(cfg, cat))) { 01434 result = UNKNOWN_CATEGORY; 01435 break; 01436 } 01437 if (!(v = ast_variable_new(var, value, dfn))) { 01438 result = FAILURE_ALLOCATION; 01439 break; 01440 } 01441 ast_variable_insert(category, v, line); 01442 } 01443 else { 01444 ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action); 01445 result = UNKNOWN_ACTION; 01446 break; 01447 } 01448 } 01449 ast_free(str1); 01450 ast_free(str2); 01451 return result; 01452 }
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 1230 of file manager.c.
Referenced by action_getconfigjson().
01231 { 01232 for (; *in; in++) { 01233 if (*in == '\\' || *in == '\"') 01234 *out++ = '\\'; 01235 *out++ = *in; 01236 } 01237 *out = '\0'; 01238 }
static int manager_displayconnects | ( | struct mansession_session * | session | ) | [static] |
Get displayconnects config option.
s | manager session to get parameter from. |
Definition at line 506 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().
00507 { 00508 struct ast_manager_user *user = NULL; 00509 int ret = 0; 00510 00511 AST_RWLIST_RDLOCK(&users); 00512 if ((user = get_manager_by_name_locked (session->username))) 00513 ret = user->displayconnects; 00514 AST_RWLIST_UNLOCK(&users); 00515 00516 return ret; 00517 }
static int manager_modulecheck | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2888 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().
02889 { 02890 int res; 02891 const char *module = astman_get_header(m, "Module"); 02892 const char *id = astman_get_header(m, "ActionID"); 02893 char idText[256]; 02894 #if !defined(LOW_MEMORY) 02895 const char *version; 02896 #endif 02897 char filename[PATH_MAX]; 02898 char *cut; 02899 02900 ast_copy_string(filename, module, sizeof(filename)); 02901 if ((cut = strchr(filename, '.'))) { 02902 *cut = '\0'; 02903 } else { 02904 cut = filename + strlen(filename); 02905 } 02906 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so"); 02907 ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename); 02908 res = ast_module_check(filename); 02909 if (!res) { 02910 astman_send_error(s, m, "Module not loaded"); 02911 return 0; 02912 } 02913 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c"); 02914 ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename); 02915 #if !defined(LOW_MEMORY) 02916 version = ast_file_version_find(filename); 02917 #endif 02918 02919 if (!ast_strlen_zero(id)) 02920 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02921 else 02922 idText[0] = '\0'; 02923 astman_append(s, "Response: Success\r\n%s", idText); 02924 #if !defined(LOW_MEMORY) 02925 astman_append(s, "Version: %s\r\n\r\n", version ? version : ""); 02926 #endif 02927 return 0; 02928 }
static int manager_moduleload | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2941 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().
02942 { 02943 int res; 02944 const char *module = astman_get_header(m, "Module"); 02945 const char *loadtype = astman_get_header(m, "LoadType"); 02946 02947 if (!loadtype || strlen(loadtype) == 0) 02948 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02949 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) 02950 astman_send_error(s, m, "Need module name"); 02951 02952 if (!strcasecmp(loadtype, "load")) { 02953 res = ast_load_resource(module); 02954 if (res) 02955 astman_send_error(s, m, "Could not load module."); 02956 else 02957 astman_send_ack(s, m, "Module loaded."); 02958 } else if (!strcasecmp(loadtype, "unload")) { 02959 res = ast_unload_resource(module, AST_FORCE_SOFT); 02960 if (res) 02961 astman_send_error(s, m, "Could not unload module."); 02962 else 02963 astman_send_ack(s, m, "Module unloaded."); 02964 } else if (!strcasecmp(loadtype, "reload")) { 02965 if (module != NULL) { 02966 res = ast_module_reload(module); 02967 if (res == 0) 02968 astman_send_error(s, m, "No such module."); 02969 else if (res == 1) 02970 astman_send_error(s, m, "Module does not support reload action."); 02971 else 02972 astman_send_ack(s, m, "Module reloaded."); 02973 } else { 02974 ast_module_reload(NULL); /* Reload all modules */ 02975 astman_send_ack(s, m, "All modules reloaded"); 02976 } 02977 } else 02978 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02979 return 0; 02980 }
static int manager_state_cb | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Definition at line 3399 of file manager.c.
References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.
Referenced by __init_manager().
03400 { 03401 /* Notify managers of change */ 03402 char hint[512]; 03403 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten); 03404 03405 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state); 03406 return 0; 03407 }
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 2658 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().
02659 { 02660 int ret = 0; 02661 02662 ast_mutex_lock(&s->session->__lock); 02663 if (s->session->f != NULL) { 02664 struct eventqent *eqe; 02665 02666 while ( (eqe = NEW_EVENT(s)) ) { 02667 ref_event(eqe); 02668 if (!ret && s->session->authenticated && 02669 (s->session->readperm & eqe->category) == eqe->category && 02670 (s->session->send_events & eqe->category) == eqe->category) { 02671 if (send_string(s, eqe->eventdata) < 0) 02672 ret = -1; /* don't send more */ 02673 } 02674 s->session->last_ev = unref_event(s->session->last_ev); 02675 } 02676 } 02677 ast_mutex_unlock(&s->session->__lock); 02678 return ret; 02679 }
static int process_message | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2995 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().
02996 { 02997 char action[80] = ""; 02998 int ret = 0; 02999 struct manager_action *tmp; 03000 const char *user = astman_get_header(m, "Username"); 03001 03002 ast_copy_string(action, __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY), sizeof(action)); 03003 ast_debug(1, "Manager received command '%s'\n", action); 03004 03005 if (ast_strlen_zero(action)) { 03006 ast_mutex_lock(&s->session->__lock); 03007 astman_send_error(s, m, "Missing action in request"); 03008 ast_mutex_unlock(&s->session->__lock); 03009 return 0; 03010 } 03011 03012 if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) { 03013 ast_mutex_lock(&s->session->__lock); 03014 astman_send_error(s, m, "Permission denied"); 03015 ast_mutex_unlock(&s->session->__lock); 03016 return 0; 03017 } 03018 03019 if (!allowmultiplelogin && !s->session->authenticated && user && 03020 (!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) { 03021 if (check_manager_session_inuse(user)) { 03022 sleep(1); 03023 ast_mutex_lock(&s->session->__lock); 03024 astman_send_error(s, m, "Login Already In Use"); 03025 ast_mutex_unlock(&s->session->__lock); 03026 return -1; 03027 } 03028 } 03029 03030 AST_RWLIST_RDLOCK(&actions); 03031 AST_RWLIST_TRAVERSE(&actions, tmp, list) { 03032 if (strcasecmp(action, tmp->action)) 03033 continue; 03034 if (s->session->writeperm & tmp->authority || tmp->authority == 0) 03035 ret = tmp->func(s, m); 03036 else 03037 astman_send_error(s, m, "Permission denied"); 03038 break; 03039 } 03040 AST_RWLIST_UNLOCK(&actions); 03041 03042 if (!tmp) { 03043 char buf[512]; 03044 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action); 03045 ast_mutex_lock(&s->session->__lock); 03046 astman_send_error(s, m, buf); 03047 ast_mutex_unlock(&s->session->__lock); 03048 } 03049 if (ret) 03050 return ret; 03051 /* Once done with our message, deliver any pending events */ 03052 return process_events(s); 03053 }
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 350 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().
00351 { 00352 struct eventqent *ev; 00353 00354 AST_LIST_LOCK(&all_events); 00355 while ( (ev = AST_LIST_FIRST(&all_events)) && 00356 ev->usecount == 0 && AST_LIST_NEXT(ev, eq_next)) { 00357 AST_LIST_REMOVE_HEAD(&all_events, eq_next); 00358 ast_free(ev); 00359 } 00360 AST_LIST_UNLOCK(&all_events); 00361 }
static void purge_sessions | ( | int | n_max | ) | [static] |
remove at most n_max stale session from the list.
Definition at line 3243 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().
03244 { 03245 struct mansession_session *session; 03246 time_t now = time(NULL); 03247 03248 AST_LIST_LOCK(&sessions); 03249 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, session, list) { 03250 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) { 03251 AST_LIST_REMOVE_CURRENT(list); 03252 ast_atomic_fetchadd_int(&num_sessions, -1); 03253 if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) { 03254 ast_verb(2, "HTTP Manager '%s' timed out from %s\n", 03255 session->username, ast_inet_ntoa(session->sin.sin_addr)); 03256 } 03257 free_session(session); /* XXX outside ? */ 03258 if (--n_max <= 0) 03259 break; 03260 } 03261 } 03262 AST_LIST_TRAVERSE_SAFE_END; 03263 AST_LIST_UNLOCK(&sessions); 03264 }
static void ref_event | ( | struct eventqent * | e | ) | [static] |
Definition at line 827 of file manager.c.
References ast_atomic_fetchadd_int(), and eventqent::usecount.
Referenced by process_events().
00828 { 00829 ast_atomic_fetchadd_int(&e->usecount, 1); 00830 }
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 945 of file manager.c.
References ast_careful_fwrite(), and s.
Referenced by astman_append(), and process_events().
00946 { 00947 if (s->f) { 00948 return ast_careful_fwrite(s->f, s->fd, string, strlen(string), s->session->writetimeout); 00949 } else { 00950 return ast_careful_fwrite(s->session->f, s->session->fd, string, strlen(string), s->session->writetimeout); 00951 } 00952 }
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 3166 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.
03167 { 03168 struct ast_tcptls_session_instance *ser = data; 03169 struct mansession_session *session = ast_calloc(1, sizeof(*session)); 03170 struct mansession s = {.session = NULL, }; 03171 int flags; 03172 int res; 03173 03174 if (session == NULL) 03175 goto done; 03176 03177 session->writetimeout = 100; 03178 session->waiting_thread = AST_PTHREADT_NULL; 03179 03180 flags = fcntl(ser->fd, F_GETFL); 03181 if (!block_sockets) /* make sure socket is non-blocking */ 03182 flags |= O_NONBLOCK; 03183 else 03184 flags &= ~O_NONBLOCK; 03185 fcntl(ser->fd, F_SETFL, flags); 03186 03187 ast_mutex_init(&session->__lock); 03188 session->send_events = -1; 03189 /* Hook to the tail of the event queue */ 03190 session->last_ev = grab_last(); 03191 03192 /* these fields duplicate those in the 'ser' structure */ 03193 session->fd = ser->fd; 03194 session->f = ser->f; 03195 session->sin = ser->remote_address; 03196 s.session = session; 03197 03198 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores); 03199 03200 AST_LIST_LOCK(&sessions); 03201 AST_LIST_INSERT_HEAD(&sessions, session, list); 03202 ast_atomic_fetchadd_int(&num_sessions, 1); 03203 AST_LIST_UNLOCK(&sessions); 03204 03205 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */ 03206 for (;;) { 03207 if ((res = do_message(&s)) < 0) 03208 break; 03209 } 03210 /* session is over, explain why and terminate */ 03211 if (session->authenticated) { 03212 if (manager_displayconnects(session)) 03213 ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 03214 ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 03215 } else { 03216 if (displayconnects) 03217 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr)); 03218 ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(session->sin.sin_addr)); 03219 } 03220 03221 /* It is possible under certain circumstances for this session thread 03222 to complete its work and exit *before* the thread that created it 03223 has finished executing the ast_pthread_create_background() function. 03224 If this occurs, some versions of glibc appear to act in a buggy 03225 fashion and attempt to write data into memory that it thinks belongs 03226 to the thread but is in fact not owned by the thread (or may have 03227 been freed completely). 03228 03229 Causing this thread to yield to other threads at least one time 03230 appears to work around this bug. 03231 */ 03232 usleep(1); 03233 03234 destroy_session(session); 03235 03236 done: 03237 ao2_ref(ser, -1); 03238 ser = NULL; 03239 return NULL; 03240 }
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 1053 of file manager.c.
References ast_mutex_lock(), ast_mutex_unlock(), s, and strings_to_mask().
Referenced by action_events(), and authenticate().
01054 { 01055 int maskint = strings_to_mask(eventmask); 01056 01057 ast_mutex_lock(&s->session->__lock); 01058 if (maskint >= 0) 01059 s->session->send_events = maskint; 01060 ast_mutex_unlock(&s->session->__lock); 01061 01062 return maskint; 01063 }
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 450 of file manager.c.
References ARRAY_LEN, ast_false(), ast_strlen_zero(), ast_true(), get_perm(), num, and perms.
Referenced by set_eventmask().
00451 { 00452 const char *p; 00453 00454 if (ast_strlen_zero(string)) 00455 return -1; 00456 00457 for (p = string; *p; p++) 00458 if (*p < '0' || *p > '9') 00459 break; 00460 if (!*p) /* all digits */ 00461 return atoi(string); 00462 if (ast_false(string)) 00463 return 0; 00464 if (ast_true(string)) { /* all permissions */ 00465 int x, ret = 0; 00466 for (x = 0; x < ARRAY_LEN(perms); x++) 00467 ret |= perms[x].num; 00468 return ret; 00469 } 00470 return get_perm(string); 00471 }
Definition at line 821 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().
00822 { 00823 ast_atomic_fetchadd_int(&e->usecount, -1); 00824 return AST_LIST_NEXT(e, eq_next); 00825 }
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] |
int broken_events_action = 0 [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 1191 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 1133 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 action_events(), 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] |