callback to display queues status in manager More...
Data Structures | |
| struct | actions |
| list of actions registered More... | |
| struct | all_events |
| struct | ast_manager_user |
| user descriptor, as read from the config file. More... | |
| struct | eventqent |
| struct | fast_originate_helper |
| helper function for originate More... | |
| struct | manager_hooks |
| list of hooks registered More... | |
| struct | mansession |
| struct | mansession_session |
| struct | permalias |
| struct | sessions |
| struct | users |
| list of users found in the config file More... | |
Defines | |
| #define | ASTMAN_APPEND_BUF_INITSIZE 256 |
| initial allocated size for the astman_append_buf | |
| #define | GET_HEADER_FIRST_MATCH 0 |
| #define | GET_HEADER_LAST_MATCH 1 |
| #define | GET_HEADER_SKIP_EMPTY 2 |
| #define | MANAGER_EVENT_BUF_INITSIZE 256 |
| #define | MAX_BLACKLIST_CMD_LEN 2 |
| Descriptor for a manager session, either on the AMI socket or over HTTP. | |
| #define | MSG_MOREDATA ((char *)astman_send_response) |
| send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field. | |
| #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 new command with manager, including online help. This is the preferred way to register a manager command | |
| void | ast_manager_register_hook (struct manager_custom_hook *hook) |
| Add a custom hook to be called when an event is fired. | |
| static int | ast_manager_register_struct (struct manager_action *act) |
| int | ast_manager_unregister (char *action) |
| Unregister a registered manager command. | |
| void | ast_manager_unregister_hook (struct manager_custom_hook *hook) |
| Delete a custom hook to be called when an event is fired. | |
| void | astman_append (struct mansession *s, const char *fmt,...) |
| const char * | astman_get_header (const struct message *m, char *var) |
| Get header from mananger transaction. | |
| struct ast_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 () |
| Event list management functions. We assume that the event list always has at least one element, and the delete code will not remove the last entry even if the. | |
| static int | check_manager_session_inuse (const char *name) |
| int | check_webmanager_enabled () |
| Check if AMI/HTTP is enabled. | |
| static void | destroy_session (struct mansession_session *session) |
| static int | do_message (struct mansession *s) |
| static void * | fast_originate (void *data) |
| static void | free_session (struct mansession_session *session) |
| static int | get_input (struct mansession *s, char *output) |
| static struct ast_manager_user * | get_manager_by_name_locked (const char *name) |
| static int | get_perm (const char *instr) |
| static struct eventqent * | grab_last (void) |
| static char * | handle_manager_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command manager reload. | |
| static char * | handle_mandebug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_showmanager (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_showmanagers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_showmancmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_showmancmds (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command manager list commands. | |
| static char * | handle_showmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command manager list connected. | |
| static char * | handle_showmaneventq (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| CLI command manager list eventq. | |
| static enum error_type | handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn) |
| static void | json_escape (char *out, const char *in) |
| static int | manager_displayconnects (struct mansession_session *session) |
| Get displayconnects config option. | |
| static int | manager_modulecheck (struct mansession *s, const struct message *m) |
| static int | manager_moduleload (struct mansession *s, const struct message *m) |
| static int | manager_state_cb (char *context, char *exten, int state, void *data) |
| static int | process_events (struct mansession *s) |
| static int | process_message (struct mansession *s, const struct message *m) |
| static void | purge_events (void) |
| static void | purge_sessions (int n_max) |
| remove at most n_max stale session from the list. | |
| static void | ref_event (struct eventqent *e) |
| static int | send_string (struct mansession *s, char *string) |
| static void * | session_do (void *data) |
| The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ). | |
| static int | set_eventmask (struct mansession *s, const char *eventmask) |
| Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm. | |
| static int | strings_to_mask (const char *string) |
| static struct eventqent * | unref_event (struct eventqent *e) |
Variables | |
| static int | allowmultiplelogin = 1 |
| static struct ast_threadstorage | astman_append_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_astman_append_buf , .custom_init = NULL , } |
| static int | block_sockets |
| static struct ast_cli_entry | cli_manager [] |
| struct { | |
| char * words [AST_MAX_CMD_LEN] | |
| } | command_blacklist [] |
| static int | displayconnects = 1 |
| static int | httptimeout = 60 |
| static int | manager_debug |
| static int | manager_enabled = 0 |
| static struct ast_threadstorage | manager_event_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_manager_event_buf , .custom_init = NULL , } |
| static char | mandescr_atxfer [] |
| static char | mandescr_command [] |
| static char | mandescr_coresettings [] |
| static char | mandescr_coreshowchannels [] |
| static char | mandescr_corestatus [] |
| static char | mandescr_createconfig [] |
| static char | mandescr_events [] |
| static char | mandescr_extensionstate [] |
| static char | mandescr_getconfig [] |
| static char | mandescr_getconfigjson [] |
| static char | mandescr_getvar [] |
| static char | mandescr_hangup [] |
| static char | mandescr_listcategories [] |
| static char | mandescr_listcommands [] |
| static char | mandescr_logoff [] |
| static char | mandescr_mailboxcount [] |
| static char | mandescr_mailboxstatus [] |
| Help text for manager command mailboxstatus. | |
| static char | mandescr_modulecheck [] |
| static char | mandescr_moduleload [] |
| static char | mandescr_originate [] |
| static char | mandescr_ping [] |
| Manager PING. | |
| static char | mandescr_redirect [] |
| static char | mandescr_reload [] |
| static char | mandescr_sendtext [] |
| static char | mandescr_setvar [] |
| static char | mandescr_status [] |
| static char | mandescr_timeout [] |
| static char | mandescr_updateconfig [] |
| static char | mandescr_userevent [] |
| static char | mandescr_waitevent [] |
| Manager WAITEVENT. | |
| static int | num_sessions |
| static struct permalias | perms [] |
| static int | timestampevents |
| static struct ast_threadstorage | userevent_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_userevent_buf , .custom_init = NULL , } |
| static int | webmanager_enabled = 0 |
callback to display queues status in manager
callback to display list of locally configured nodes
| #define ASTMAN_APPEND_BUF_INITSIZE 256 |
initial allocated size for the astman_append_buf
Definition at line 964 of file manager.c.
Referenced by astman_append().
| #define GET_HEADER_FIRST_MATCH 0 |
Definition at line 867 of file manager.c.
Referenced by astman_get_header().
| #define GET_HEADER_LAST_MATCH 1 |
Definition at line 868 of file manager.c.
Referenced by __astman_get_header().
| #define GET_HEADER_SKIP_EMPTY 2 |
Definition at line 869 of file manager.c.
Referenced by __astman_get_header(), and process_message().
| #define MANAGER_EVENT_BUF_INITSIZE 256 |
Definition at line 3297 of file manager.c.
Referenced by __manager_event().
| #define MAX_BLACKLIST_CMD_LEN 2 |
Descriptor for a manager session, either on the AMI socket or over HTTP.
Definition at line 143 of file manager.c.
Referenced by check_blacklist().
| #define MSG_MOREDATA ((char *)astman_send_response) |
send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field.
Use the explicit constant MSG_MOREDATA to remove the empty line. XXX MSG_MOREDATA should go to a header file.
Definition at line 1004 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)) |
Definition at line 224 of file manager.c.
Referenced by action_waitevent(), and process_events().
| 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 870 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().
00871 { 00872 int x, l = strlen(var); 00873 const char *result = ""; 00874 00875 for (x = 0; x < m->hdrcount; x++) { 00876 const char *h = m->headers[x]; 00877 if (!strncasecmp(var, h, l) && h[l] == ':' && h[l+1] == ' ') { 00878 const char *value = h + l + 2; 00879 /* found a potential candidate */ 00880 if (mode & GET_HEADER_SKIP_EMPTY && ast_strlen_zero(value)) 00881 continue; /* not interesting */ 00882 if (mode & GET_HEADER_LAST_MATCH) 00883 result = value; /* record the last match so far */ 00884 else 00885 return value; 00886 } 00887 } 00888 00889 return ""; 00890 }
| static void __init_astman_append_buf | ( | void | ) | [static] |
thread local buffer for astman_append
| static void __init_manager_event_buf | ( | void | ) | [static] |
| static void __init_userevent_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 3300 of file manager.c.
References mansession_session::__lock, append_event(), ast_atomic_fetchadd_int(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_append_va(), ast_str_buffer(), ast_str_set(), ast_str_thread_get(), ast_tvnow(), authority_to_str(), buf, manager_custom_hook::helper, manager_event_buf, MANAGER_EVENT_BUF_INITSIZE, mansession_session::pending_event, eventqent::seq, and mansession_session::waiting_thread.
03302 { 03303 struct mansession_session *session; 03304 struct manager_custom_hook *hook; 03305 struct ast_str *auth = ast_str_alloca(80); 03306 const char *cat_str; 03307 va_list ap; 03308 struct timeval now; 03309 struct ast_str *buf; 03310 03311 /* Abort if there are neither any manager sessions nor hooks */ 03312 if (!num_sessions && AST_RWLIST_EMPTY(&manager_hooks)) 03313 return 0; 03314 03315 if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) 03316 return -1; 03317 03318 cat_str = authority_to_str(category, &auth); 03319 ast_str_set(&buf, 0, 03320 "Event: %s\r\nPrivilege: %s\r\n", 03321 event, cat_str); 03322 03323 if (timestampevents) { 03324 now = ast_tvnow(); 03325 ast_str_append(&buf, 0, 03326 "Timestamp: %ld.%06lu\r\n", 03327 (long)now.tv_sec, (unsigned long) now.tv_usec); 03328 } 03329 if (manager_debug) { 03330 static int seq; 03331 ast_str_append(&buf, 0, 03332 "SequenceNumber: %d\r\n", 03333 ast_atomic_fetchadd_int(&seq, 1)); 03334 ast_str_append(&buf, 0, 03335 "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func); 03336 } 03337 03338 va_start(ap, fmt); 03339 ast_str_append_va(&buf, 0, fmt, ap); 03340 va_end(ap); 03341 03342 ast_str_append(&buf, 0, "\r\n"); 03343 03344 append_event(ast_str_buffer(buf), category); 03345 03346 if (num_sessions) { 03347 /* Wake up any sleeping sessions */ 03348 AST_LIST_LOCK(&sessions); 03349 AST_LIST_TRAVERSE(&sessions, session, list) { 03350 ast_mutex_lock(&session->__lock); 03351 if (session->waiting_thread != AST_PTHREADT_NULL) 03352 pthread_kill(session->waiting_thread, SIGURG); 03353 else 03354 /* We have an event to process, but the mansession is 03355 * not waiting for it. We still need to indicate that there 03356 * is an event waiting so that get_input processes the pending 03357 * event instead of polling. 03358 */ 03359 session->pending_event = 1; 03360 ast_mutex_unlock(&session->__lock); 03361 } 03362 AST_LIST_UNLOCK(&sessions); 03363 } 03364 03365 if (!AST_RWLIST_EMPTY(&manager_hooks)) { 03366 AST_RWLIST_RDLOCK(&manager_hooks); 03367 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) { 03368 hook->helper(category, event, ast_str_buffer(buf)); 03369 } 03370 AST_RWLIST_UNLOCK(&manager_hooks); 03371 } 03372 03373 return 0; 03374 }
| static int action_atxfer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2168 of file manager.c.
References ast_channel_unlock, ast_find_call_feature(), AST_FRAME_DTMF, ast_get_channel_by_name_locked(), ast_queue_frame(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), chan, context, ast_call_feature::exten, exten, name, and pbx_builtin_setvar_helper().
Referenced by __init_manager().
02169 { 02170 const char *name = astman_get_header(m, "Channel"); 02171 const char *exten = astman_get_header(m, "Exten"); 02172 const char *context = astman_get_header(m, "Context"); 02173 struct ast_channel *chan = NULL; 02174 struct ast_call_feature *atxfer_feature = NULL; 02175 char *feature_code = NULL; 02176 02177 if (ast_strlen_zero(name)) { 02178 astman_send_error(s, m, "No channel specified"); 02179 return 0; 02180 } 02181 if (ast_strlen_zero(exten)) { 02182 astman_send_error(s, m, "No extension specified"); 02183 return 0; 02184 } 02185 02186 if (!(atxfer_feature = ast_find_call_feature("atxfer"))) { 02187 astman_send_error(s, m, "No attended transfer feature found"); 02188 return 0; 02189 } 02190 02191 if (!(chan = ast_get_channel_by_name_locked(name))) { 02192 astman_send_error(s, m, "Channel specified does not exist"); 02193 return 0; 02194 } 02195 02196 if (!ast_strlen_zero(context)) { 02197 pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context); 02198 } 02199 02200 for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) { 02201 struct ast_frame f = {AST_FRAME_DTMF, *feature_code}; 02202 ast_queue_frame(chan, &f); 02203 } 02204 02205 for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) { 02206 struct ast_frame f = {AST_FRAME_DTMF, *feature_code}; 02207 ast_queue_frame(chan, &f); 02208 } 02209 02210 astman_send_ack(s, m, "Atxfer successfully queued"); 02211 ast_channel_unlock(chan); 02212 02213 return 0; 02214 }
| static int action_challenge | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1755 of file manager.c.
References mansession_session::__lock, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), mansession_session::challenge, and mansession::session.
Referenced by __init_manager().
01756 { 01757 const char *authtype = astman_get_header(m, "AuthType"); 01758 01759 if (!strcasecmp(authtype, "MD5")) { 01760 if (ast_strlen_zero(s->session->challenge)) 01761 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random()); 01762 ast_mutex_lock(&s->session->__lock); 01763 astman_start_ack(s, m); 01764 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge); 01765 ast_mutex_unlock(&s->session->__lock); 01766 } else { 01767 astman_send_error(s, m, "Must specify AuthType"); 01768 } 01769 return 0; 01770 }
| static int action_command | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Manager command "command" - execute CLI command.
Definition at line 2258 of file manager.c.
References ast_calloc, ast_cli_command, ast_free, ast_log(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), buf, check_blacklist(), errno, LOG_WARNING, S_OR, and term_strip().
Referenced by __init_manager().
02259 { 02260 const char *cmd = astman_get_header(m, "Command"); 02261 const char *id = astman_get_header(m, "ActionID"); 02262 char *buf, *final_buf; 02263 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 02264 int fd; 02265 off_t l; 02266 02267 if (ast_strlen_zero(cmd)) { 02268 astman_send_error(s, m, "No command provided"); 02269 return 0; 02270 } 02271 02272 if (check_blacklist(cmd)) { 02273 astman_send_error(s, m, "Command blacklisted"); 02274 return 0; 02275 } 02276 02277 fd = mkstemp(template); 02278 02279 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 02280 if (!ast_strlen_zero(id)) 02281 astman_append(s, "ActionID: %s\r\n", id); 02282 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 02283 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 02284 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 02285 02286 /* This has a potential to overflow the stack. Hence, use the heap. */ 02287 buf = ast_calloc(1, l + 1); 02288 final_buf = ast_calloc(1, l + 1); 02289 if (buf) { 02290 lseek(fd, 0, SEEK_SET); 02291 if (read(fd, buf, l) < 0) { 02292 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 02293 } 02294 buf[l] = '\0'; 02295 if (final_buf) { 02296 term_strip(final_buf, buf, l); 02297 final_buf[l] = '\0'; 02298 } 02299 astman_append(s, "%s", S_OR(final_buf, buf)); 02300 ast_free(buf); 02301 } 02302 close(fd); 02303 unlink(template); 02304 astman_append(s, "--END COMMAND--\r\n\r\n"); 02305 if (final_buf) 02306 ast_free(final_buf); 02307 return 0; 02308 }
| static int action_coresettings | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show PBX core settings information.
Definition at line 2709 of file manager.c.
References AMI_VERSION, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SYSTEM_NAME, ast_get_version(), ast_realtime_enabled(), ast_strlen_zero(), astman_append(), astman_get_header(), check_cdr_enabled(), check_webmanager_enabled(), option_maxcalls, option_maxfiles, and option_maxload.
Referenced by __init_manager().
02710 { 02711 const char *actionid = astman_get_header(m, "ActionID"); 02712 char idText[150]; 02713 02714 if (!ast_strlen_zero(actionid)) 02715 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02716 else 02717 idText[0] = '\0'; 02718 02719 astman_append(s, "Response: Success\r\n" 02720 "%s" 02721 "AMIversion: %s\r\n" 02722 "AsteriskVersion: %s\r\n" 02723 "SystemName: %s\r\n" 02724 "CoreMaxCalls: %d\r\n" 02725 "CoreMaxLoadAvg: %f\r\n" 02726 "CoreRunUser: %s\r\n" 02727 "CoreRunGroup: %s\r\n" 02728 "CoreMaxFilehandles: %d\r\n" 02729 "CoreRealTimeEnabled: %s\r\n" 02730 "CoreCDRenabled: %s\r\n" 02731 "CoreHTTPenabled: %s\r\n" 02732 "\r\n", 02733 idText, 02734 AMI_VERSION, 02735 ast_get_version(), 02736 ast_config_AST_SYSTEM_NAME, 02737 option_maxcalls, 02738 option_maxload, 02739 ast_config_AST_RUN_USER, 02740 ast_config_AST_RUN_GROUP, 02741 option_maxfiles, 02742 ast_realtime_enabled() ? "Yes" : "No", 02743 check_cdr_enabled() ? "Yes" : "No", 02744 check_webmanager_enabled() ? "Yes" : "No" 02745 ); 02746 return 0; 02747 }
| 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 2814 of file manager.c.
References ast_channel::_state, ast_channel::accountcode, ast_channel::appl, ast_bridged_channel(), ast_channel_unlock, ast_channel_walk_locked(), ast_state2str(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), astman_append(), astman_get_header(), astman_send_listack(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::data, ast_channel::exten, ast_channel::name, ast_channel::priority, S_OR, ast_cdr::start, and ast_channel::uniqueid.
Referenced by __init_manager().
02815 { 02816 const char *actionid = astman_get_header(m, "ActionID"); 02817 char idText[256]; 02818 struct ast_channel *c = NULL; 02819 int numchans = 0; 02820 int duration, durh, durm, durs; 02821 02822 if (!ast_strlen_zero(actionid)) 02823 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02824 else 02825 idText[0] = '\0'; 02826 02827 astman_send_listack(s, m, "Channels will follow", "start"); 02828 02829 while ((c = ast_channel_walk_locked(c)) != NULL) { 02830 struct ast_channel *bc = ast_bridged_channel(c); 02831 char durbuf[10] = ""; 02832 02833 if (c->cdr && !ast_tvzero(c->cdr->start)) { 02834 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 02835 durh = duration / 3600; 02836 durm = (duration % 3600) / 60; 02837 durs = duration % 60; 02838 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 02839 } 02840 02841 astman_append(s, 02842 "Event: CoreShowChannel\r\n" 02843 "%s" 02844 "Channel: %s\r\n" 02845 "UniqueID: %s\r\n" 02846 "Context: %s\r\n" 02847 "Extension: %s\r\n" 02848 "Priority: %d\r\n" 02849 "ChannelState: %d\r\n" 02850 "ChannelStateDesc: %s\r\n" 02851 "Application: %s\r\n" 02852 "ApplicationData: %s\r\n" 02853 "CallerIDnum: %s\r\n" 02854 "Duration: %s\r\n" 02855 "AccountCode: %s\r\n" 02856 "BridgedChannel: %s\r\n" 02857 "BridgedUniqueID: %s\r\n" 02858 "\r\n", idText, c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, 02859 ast_state2str(c->_state), c->appl ? c->appl : "", c->data ? S_OR(c->data, "") : "", 02860 S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : ""); 02861 ast_channel_unlock(c); 02862 numchans++; 02863 } 02864 02865 astman_append(s, 02866 "Event: CoreShowChannelsComplete\r\n" 02867 "EventList: Complete\r\n" 02868 "ListItems: %d\r\n" 02869 "%s" 02870 "\r\n", numchans, idText); 02871 02872 return 0; 02873 }
| static int action_corestatus | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show PBX core status information.
Definition at line 2755 of file manager.c.
References ast_active_channels(), ast_lastreloadtime, ast_localtime(), ast_startuptime, ast_strftime(), ast_strlen_zero(), astman_append(), and astman_get_header().
Referenced by __init_manager().
02756 { 02757 const char *actionid = astman_get_header(m, "ActionID"); 02758 char idText[150]; 02759 char startuptime[150]; 02760 char reloadtime[150]; 02761 struct ast_tm tm; 02762 02763 if (!ast_strlen_zero(actionid)) 02764 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02765 else 02766 idText[0] = '\0'; 02767 02768 ast_localtime(&ast_startuptime, &tm, NULL); 02769 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm); 02770 ast_localtime(&ast_lastreloadtime, &tm, NULL); 02771 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm); 02772 02773 astman_append(s, "Response: Success\r\n" 02774 "%s" 02775 "CoreStartupTime: %s\r\n" 02776 "CoreReloadTime: %s\r\n" 02777 "CoreCurrentCalls: %d\r\n" 02778 "\r\n", 02779 idText, 02780 startuptime, 02781 reloadtime, 02782 ast_active_channels() 02783 ); 02784 return 0; 02785 }
| static int action_createconfig | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1565 of file manager.c.
References ast_config_AST_CONFIG_DIR, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), astman_get_header(), astman_send_ack(), astman_send_error(), and errno.
Referenced by __init_manager().
01566 { 01567 int fd; 01568 const char *fn = astman_get_header(m, "Filename"); 01569 struct ast_str *filepath = ast_str_alloca(PATH_MAX); 01570 ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR); 01571 ast_str_append(&filepath, 0, "%s", fn); 01572 01573 if ((fd = open(ast_str_buffer(filepath), O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) { 01574 close(fd); 01575 astman_send_ack(s, m, "New configuration file created successfully"); 01576 } else { 01577 astman_send_error(s, m, strerror(errno)); 01578 } 01579 01580 return 0; 01581 }
| static int action_events | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1715 of file manager.c.
References astman_append(), astman_get_header(), and set_eventmask().
Referenced by __init_manager().
01716 { 01717 const char *mask = astman_get_header(m, "EventMask"); 01718 int res; 01719 01720 res = set_eventmask(s, mask); 01721 if (res > 0) 01722 astman_append(s, "Response: Success\r\n" 01723 "Events: On\r\n\r\n"); 01724 else if (res == 0) 01725 astman_append(s, "Response: Success\r\n" 01726 "Events: Off\r\n\r\n"); 01727 return 0; 01728 }
| static int action_extensionstate | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2590 of file manager.c.
References ast_extension_state(), ast_get_hint(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), context, exten, and status.
Referenced by __init_manager().
02591 { 02592 const char *exten = astman_get_header(m, "Exten"); 02593 const char *context = astman_get_header(m, "Context"); 02594 char hint[256] = ""; 02595 int status; 02596 if (ast_strlen_zero(exten)) { 02597 astman_send_error(s, m, "Extension not specified"); 02598 return 0; 02599 } 02600 if (ast_strlen_zero(context)) 02601 context = "default"; 02602 status = ast_extension_state(NULL, context, exten); 02603 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 02604 astman_start_ack(s, m); 02605 astman_append(s, "Message: Extension Status\r\n" 02606 "Exten: %s\r\n" 02607 "Context: %s\r\n" 02608 "Hint: %s\r\n" 02609 "Status: %d\r\n\r\n", 02610 exten, context, hint, status); 02611 return 0; 02612 }
| static int action_getconfig | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1156 of file manager.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), ast_variable_browse(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by __init_manager().
01157 { 01158 struct ast_config *cfg; 01159 const char *fn = astman_get_header(m, "Filename"); 01160 const char *category = astman_get_header(m, "Category"); 01161 int catcount = 0; 01162 int lineno = 0; 01163 char *cur_category = NULL; 01164 struct ast_variable *v; 01165 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01166 01167 if (ast_strlen_zero(fn)) { 01168 astman_send_error(s, m, "Filename not specified"); 01169 return 0; 01170 } 01171 cfg = ast_config_load2(fn, "manager", config_flags); 01172 if (cfg == CONFIG_STATUS_FILEMISSING) { 01173 astman_send_error(s, m, "Config file not found"); 01174 return 0; 01175 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 01176 astman_send_error(s, m, "Config file has invalid format"); 01177 return 0; 01178 } 01179 01180 astman_start_ack(s, m); 01181 while ((cur_category = ast_category_browse(cfg, cur_category))) { 01182 if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) { 01183 lineno = 0; 01184 astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category); 01185 for (v = ast_variable_browse(cfg, cur_category); v; v = v->next) 01186 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 01187 catcount++; 01188 } 01189 } 01190 if (!ast_strlen_zero(category) && catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */ 01191 astman_append(s, "No categories found\r\n"); 01192 ast_config_destroy(cfg); 01193 astman_append(s, "\r\n"); 01194 01195 return 0; 01196 }
| static int action_getconfigjson | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1257 of file manager.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), ast_variable_browse(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), buf, eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, json_escape(), ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by __init_manager().
01258 { 01259 struct ast_config *cfg; 01260 const char *fn = astman_get_header(m, "Filename"); 01261 char *category = NULL; 01262 struct ast_variable *v; 01263 int comma1 = 0; 01264 char *buf = NULL; 01265 unsigned int buf_len = 0; 01266 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01267 01268 if (ast_strlen_zero(fn)) { 01269 astman_send_error(s, m, "Filename not specified"); 01270 return 0; 01271 } 01272 01273 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 01274 astman_send_error(s, m, "Config file not found"); 01275 return 0; 01276 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 01277 astman_send_error(s, m, "Config file has invalid format"); 01278 return 0; 01279 } 01280 01281 buf_len = 512; 01282 buf = alloca(buf_len); 01283 01284 astman_start_ack(s, m); 01285 astman_append(s, "JSON: {"); 01286 while ((category = ast_category_browse(cfg, category))) { 01287 int comma2 = 0; 01288 if (buf_len < 2 * strlen(category) + 1) { 01289 buf_len *= 2; 01290 buf = alloca(buf_len); 01291 } 01292 json_escape(buf, category); 01293 astman_append(s, "%s\"%s\":[", comma1 ? "," : "", buf); 01294 if (!comma1) 01295 comma1 = 1; 01296 for (v = ast_variable_browse(cfg, category); v; v = v->next) { 01297 if (comma2) 01298 astman_append(s, ","); 01299 if (buf_len < 2 * strlen(v->name) + 1) { 01300 buf_len *= 2; 01301 buf = alloca(buf_len); 01302 } 01303 json_escape(buf, v->name); 01304 astman_append(s, "\"%s", buf); 01305 if (buf_len < 2 * strlen(v->value) + 1) { 01306 buf_len *= 2; 01307 buf = alloca(buf_len); 01308 } 01309 json_escape(buf, v->value); 01310 astman_append(s, "%s\"", buf); 01311 if (!comma2) 01312 comma2 = 1; 01313 } 01314 astman_append(s, "]"); 01315 } 01316 astman_append(s, "}\r\n\r\n"); 01317 01318 ast_config_destroy(cfg); 01319 01320 return 0; 01321 }
| static int action_getvar | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1847 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, and pbx_retrieve_variable().
Referenced by __init_manager().
01848 { 01849 struct ast_channel *c = NULL; 01850 const char *name = astman_get_header(m, "Channel"); 01851 const char *varname = astman_get_header(m, "Variable"); 01852 char *varval; 01853 char workspace[1024] = ""; 01854 01855 if (ast_strlen_zero(varname)) { 01856 astman_send_error(s, m, "No variable specified"); 01857 return 0; 01858 } 01859 01860 if (!ast_strlen_zero(name)) { 01861 c = ast_get_channel_by_name_locked(name); 01862 if (!c) { 01863 astman_send_error(s, m, "No such channel"); 01864 return 0; 01865 } 01866 } 01867 01868 if (varname[strlen(varname) - 1] == ')') { 01869 if (!c) { 01870 c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/manager"); 01871 if (c) { 01872 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01873 ast_channel_free(c); 01874 c = NULL; 01875 } else 01876 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n"); 01877 } else 01878 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01879 varval = workspace; 01880 } else { 01881 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 01882 } 01883 01884 if (c) 01885 ast_channel_unlock(c); 01886 astman_start_ack(s, m); 01887 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, varval); 01888 01889 return 0; 01890 }
| static int action_hangup | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1777 of file manager.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and name.
Referenced by __init_manager().
01778 { 01779 struct ast_channel *c = NULL; 01780 const char *name = astman_get_header(m, "Channel"); 01781 if (ast_strlen_zero(name)) { 01782 astman_send_error(s, m, "No channel specified"); 01783 return 0; 01784 } 01785 c = ast_get_channel_by_name_locked(name); 01786 if (!c) { 01787 astman_send_error(s, m, "No such channel"); 01788 return 0; 01789 } 01790 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01791 ast_channel_unlock(c); 01792 astman_send_ack(s, m, "Channel Hungup"); 01793 return 0; 01794 }
| static int action_listcategories | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1204 of file manager.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, and CONFIG_STATUS_FILEINVALID.
Referenced by __init_manager().
01205 { 01206 struct ast_config *cfg; 01207 const char *fn = astman_get_header(m, "Filename"); 01208 char *category = NULL; 01209 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01210 int catcount = 0; 01211 01212 if (ast_strlen_zero(fn)) { 01213 astman_send_error(s, m, "Filename not specified"); 01214 return 0; 01215 } 01216 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 01217 astman_send_error(s, m, "Config file not found"); 01218 return 0; 01219 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 01220 astman_send_error(s, m, "Config file has invalid format"); 01221 return 0; 01222 } 01223 astman_start_ack(s, m); 01224 while ((category = ast_category_browse(cfg, category))) { 01225 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 01226 catcount++; 01227 } 01228 if (catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */ 01229 astman_append(s, "Error: no categories found\r\n"); 01230 ast_config_destroy(cfg); 01231 astman_append(s, "\r\n"); 01232 01233 return 0; 01234 }
| static int action_listcommands | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1691 of file manager.c.
References manager_action::action, AST_RWLIST_TRAVERSE, ast_str_alloca, astman_append(), astman_start_ack(), manager_action::authority, authority_to_str(), mansession::session, manager_action::synopsis, and mansession_session::writeperm.
Referenced by __init_manager().
01692 { 01693 struct manager_action *cur; 01694 struct ast_str *temp = ast_str_alloca(BUFSIZ); /* XXX very large ? */ 01695 01696 astman_start_ack(s, m); 01697 AST_RWLIST_TRAVERSE(&actions, cur, list) { 01698 if (s->session->writeperm & cur->authority || cur->authority == 0) 01699 astman_append(s, "%s: %s (Priv: %s)\r\n", 01700 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp)); 01701 } 01702 astman_append(s, "\r\n"); 01703 01704 return 0; 01705 }
| static int action_login | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1740 of file manager.c.
References ast_inet_ntoa(), ast_log(), ast_verb, astman_send_ack(), astman_send_error(), authenticate(), mansession_session::authenticated, LOG_EVENT, manager_displayconnects(), mansession_session::managerid, mansession::session, mansession_session::sin, and mansession_session::username.
Referenced by __init_manager().
01741 { 01742 if (authenticate(s, m)) { 01743 sleep(1); 01744 astman_send_error(s, m, "Authentication failed"); 01745 return -1; 01746 } 01747 s->session->authenticated = 1; 01748 if (manager_displayconnects(s->session)) 01749 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)); 01750 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)); 01751 astman_send_ack(s, m, "Authentication accepted"); 01752 return 0; 01753 }
| static int action_logoff | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1734 of file manager.c.
References astman_send_response().
Referenced by __init_manager().
01735 { 01736 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 01737 return -1; 01738 }
| static int action_mailboxcount | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2558 of file manager.c.
References ast_app_inboxcount2(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and mailbox.
Referenced by __init_manager().
02559 { 02560 const char *mailbox = astman_get_header(m, "Mailbox"); 02561 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;; 02562 02563 if (ast_strlen_zero(mailbox)) { 02564 astman_send_error(s, m, "Mailbox not specified"); 02565 return 0; 02566 } 02567 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs); 02568 astman_start_ack(s, m); 02569 astman_append(s, "Message: Mailbox Message Count\r\n" 02570 "Mailbox: %s\r\n" 02571 "UrgMessages: %d\r\n" 02572 "NewMessages: %d\r\n" 02573 "OldMessages: %d\r\n" 02574 "\r\n", 02575 mailbox, urgentmsgs, newmsgs, oldmsgs); 02576 return 0; 02577 }
| static int action_mailboxstatus | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2529 of file manager.c.
References ast_app_has_voicemail(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and mailbox.
Referenced by __init_manager().
02530 { 02531 const char *mailbox = astman_get_header(m, "Mailbox"); 02532 int ret; 02533 02534 if (ast_strlen_zero(mailbox)) { 02535 astman_send_error(s, m, "Mailbox not specified"); 02536 return 0; 02537 } 02538 ret = ast_app_has_voicemail(mailbox, NULL); 02539 astman_start_ack(s, m); 02540 astman_append(s, "Message: Mailbox Status\r\n" 02541 "Mailbox: %s\r\n" 02542 "Waiting: %d\r\n\r\n", mailbox, ret); 02543 return 0; 02544 }
| static int action_originate | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2392 of file manager.c.
References fast_originate_helper::account, fast_originate_helper::app, app, fast_originate_helper::appdata, ast_callerid_parse(), ast_calloc, ast_copy_string(), ast_findlabel_extension(), AST_FORMAT_SLINEAR, ast_free, ast_parse_allow_disallow(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pthread_create_detached, ast_shrink_phone_number(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, context, fast_originate_helper::data, ast_frame::data, EVENT_FLAG_SYSTEM, fast_originate_helper::exten, exten, fast_originate(), fast_originate_helper::format, format, fast_originate_helper::idtext, name, fast_originate_helper::priority, mansession::session, fast_originate_helper::tech, fast_originate_helper::timeout, fast_originate_helper::vars, and mansession_session::writeperm.
Referenced by __init_manager().
02393 { 02394 const char *name = astman_get_header(m, "Channel"); 02395 const char *exten = astman_get_header(m, "Exten"); 02396 const char *context = astman_get_header(m, "Context"); 02397 const char *priority = astman_get_header(m, "Priority"); 02398 const char *timeout = astman_get_header(m, "Timeout"); 02399 const char *callerid = astman_get_header(m, "CallerID"); 02400 const char *account = astman_get_header(m, "Account"); 02401 const char *app = astman_get_header(m, "Application"); 02402 const char *appdata = astman_get_header(m, "Data"); 02403 const char *async = astman_get_header(m, "Async"); 02404 const char *id = astman_get_header(m, "ActionID"); 02405 const char *codecs = astman_get_header(m, "Codecs"); 02406 struct ast_variable *vars = astman_get_variables(m); 02407 char *tech, *data; 02408 char *l = NULL, *n = NULL; 02409 int pi = 0; 02410 int res; 02411 int to = 30000; 02412 int reason = 0; 02413 char tmp[256]; 02414 char tmp2[256]; 02415 int format = AST_FORMAT_SLINEAR; 02416 02417 pthread_t th; 02418 if (ast_strlen_zero(name)) { 02419 astman_send_error(s, m, "Channel not specified"); 02420 return 0; 02421 } 02422 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 02423 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 02424 astman_send_error(s, m, "Invalid priority"); 02425 return 0; 02426 } 02427 } 02428 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) { 02429 astman_send_error(s, m, "Invalid timeout"); 02430 return 0; 02431 } 02432 ast_copy_string(tmp, name, sizeof(tmp)); 02433 tech = tmp; 02434 data = strchr(tmp, '/'); 02435 if (!data) { 02436 astman_send_error(s, m, "Invalid channel"); 02437 return 0; 02438 } 02439 *data++ = '\0'; 02440 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 02441 ast_callerid_parse(tmp2, &n, &l); 02442 if (n) { 02443 if (ast_strlen_zero(n)) 02444 n = NULL; 02445 } 02446 if (l) { 02447 ast_shrink_phone_number(l); 02448 if (ast_strlen_zero(l)) 02449 l = NULL; 02450 } 02451 if (!ast_strlen_zero(codecs)) { 02452 format = 0; 02453 ast_parse_allow_disallow(NULL, &format, codecs, 1); 02454 } 02455 if (ast_true(async)) { 02456 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 02457 if (!fast) { 02458 res = -1; 02459 } else { 02460 if (!ast_strlen_zero(id)) 02461 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s", id); 02462 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 02463 ast_copy_string(fast->data, data, sizeof(fast->data)); 02464 ast_copy_string(fast->app, app, sizeof(fast->app)); 02465 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 02466 if (l) 02467 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 02468 if (n) 02469 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 02470 fast->vars = vars; 02471 ast_copy_string(fast->context, context, sizeof(fast->context)); 02472 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 02473 ast_copy_string(fast->account, account, sizeof(fast->account)); 02474 fast->format = format; 02475 fast->timeout = to; 02476 fast->priority = pi; 02477 if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) { 02478 ast_free(fast); 02479 res = -1; 02480 } else { 02481 res = 0; 02482 } 02483 } 02484 } else if (!ast_strlen_zero(app)) { 02485 /* To run the System application (or anything else that goes to shell), you must have the additional System privilege */ 02486 if (!(s->session->writeperm & EVENT_FLAG_SYSTEM) 02487 && ( 02488 strcasestr(app, "system") == 0 || /* System(rm -rf /) 02489 TrySystem(rm -rf /) */ 02490 strcasestr(app, "exec") || /* Exec(System(rm -rf /)) 02491 TryExec(System(rm -rf /)) */ 02492 strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /) 02493 EAGI(/bin/rm,-rf /) */ 02494 strstr(appdata, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */ 02495 strstr(appdata, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */ 02496 )) { 02497 astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have."); 02498 return 0; 02499 } 02500 res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 02501 } else { 02502 if (exten && context && pi) 02503 res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 02504 else { 02505 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 02506 return 0; 02507 } 02508 } 02509 if (!res) 02510 astman_send_ack(s, m, "Originate successfully queued"); 02511 else 02512 astman_send_error(s, m, "Originate failed"); 02513 return 0; 02514 }
| static int action_ping | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1137 of file manager.c.
References ast_strlen_zero(), astman_append(), and astman_get_header().
Referenced by __init_manager().
01138 { 01139 const char *actionid = astman_get_header(m, "ActionID"); 01140 01141 astman_append(s, "Response: Success\r\n"); 01142 if (!ast_strlen_zero(actionid)){ 01143 astman_append(s, "ActionID: %s\r\n", actionid); 01144 } 01145 astman_append(s, "Ping: Pong\r\n\r\n"); 01146 return 0; 01147 }
| static int action_redirect | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
action_redirect: The redirect manager command
Definition at line 2084 of file manager.c.
References ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_findlabel_extension(), AST_FLAG_BRIDGE_HANGUP_DONT, ast_get_channel_by_name_locked(), ast_set_flag, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), buf, chan, context, exten, name, ast_channel::pbx, and ast_channel::priority.
Referenced by __init_manager().
02085 { 02086 const char *name = astman_get_header(m, "Channel"); 02087 const char *name2 = astman_get_header(m, "ExtraChannel"); 02088 const char *exten = astman_get_header(m, "Exten"); 02089 const char *context = astman_get_header(m, "Context"); 02090 const char *priority = astman_get_header(m, "Priority"); 02091 struct ast_channel *chan, *chan2 = NULL; 02092 int pi = 0; 02093 int res; 02094 02095 if (ast_strlen_zero(name)) { 02096 astman_send_error(s, m, "Channel not specified"); 02097 return 0; 02098 } 02099 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 02100 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 02101 astman_send_error(s, m, "Invalid priority"); 02102 return 0; 02103 } 02104 } 02105 /* XXX watch out, possible deadlock - we are trying to get two channels!!! */ 02106 chan = ast_get_channel_by_name_locked(name); 02107 if (!chan) { 02108 char buf[256]; 02109 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 02110 astman_send_error(s, m, buf); 02111 return 0; 02112 } 02113 if (ast_check_hangup(chan)) { 02114 astman_send_error(s, m, "Redirect failed, channel not up."); 02115 ast_channel_unlock(chan); 02116 return 0; 02117 } 02118 if (!ast_strlen_zero(name2)) 02119 chan2 = ast_get_channel_by_name_locked(name2); 02120 if (chan2 && ast_check_hangup(chan2)) { 02121 astman_send_error(s, m, "Redirect failed, extra channel not up."); 02122 ast_channel_unlock(chan); 02123 ast_channel_unlock(chan2); 02124 return 0; 02125 } 02126 if (chan->pbx) { 02127 ast_channel_lock(chan); 02128 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 02129 ast_channel_unlock(chan); 02130 } 02131 res = ast_async_goto(chan, context, exten, pi); 02132 if (!res) { 02133 if (!ast_strlen_zero(name2)) { 02134 if (chan2) { 02135 if (chan2->pbx) { 02136 ast_channel_lock(chan2); 02137 ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 02138 ast_channel_unlock(chan2); 02139 } 02140 res = ast_async_goto(chan2, context, exten, pi); 02141 } else { 02142 res = -1; 02143 } 02144 if (!res) 02145 astman_send_ack(s, m, "Dual Redirect successful"); 02146 else 02147 astman_send_error(s, m, "Secondary redirect failed"); 02148 } else 02149 astman_send_ack(s, m, "Redirect successful"); 02150 } else 02151 astman_send_error(s, m, "Redirect failed"); 02152 if (chan) 02153 ast_channel_unlock(chan); 02154 if (chan2) 02155 ast_channel_unlock(chan2); 02156 return 0; 02157 }
| static int action_reload | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Send a reload event.
Definition at line 2794 of file manager.c.
References ast_module_reload(), astman_get_header(), astman_send_ack(), astman_send_error(), and S_OR.
Referenced by __init_manager().
02795 { 02796 const char *module = astman_get_header(m, "Module"); 02797 int res = ast_module_reload(S_OR(module, NULL)); 02798 02799 if (res == 2) 02800 astman_send_ack(s, m, "Module Reloaded"); 02801 else 02802 astman_send_error(s, m, s == 0 ? "No such module" : "Module does not support reload"); 02803 return 0; 02804 }
| static int action_sendtext | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2039 of file manager.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_sendtext(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and name.
Referenced by __init_manager().
02040 { 02041 struct ast_channel *c = NULL; 02042 const char *name = astman_get_header(m, "Channel"); 02043 const char *textmsg = astman_get_header(m, "Message"); 02044 int res = 0; 02045 02046 if (ast_strlen_zero(name)) { 02047 astman_send_error(s, m, "No channel specified"); 02048 return 0; 02049 } 02050 02051 if (ast_strlen_zero(textmsg)) { 02052 astman_send_error(s, m, "No Message specified"); 02053 return 0; 02054 } 02055 02056 c = ast_get_channel_by_name_locked(name); 02057 if (!c) { 02058 astman_send_error(s, m, "No such channel"); 02059 return 0; 02060 } 02061 02062 res = ast_sendtext(c, textmsg); 02063 ast_channel_unlock(c); 02064 02065 if (res > 0) 02066 astman_send_ack(s, m, "Success"); 02067 else 02068 astman_send_error(s, m, "Failure"); 02069 02070 return res; 02071 }
| static int action_setvar | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1803 of file manager.c.
References ast_channel_unlock, ast_func_write(), ast_get_channel_by_name_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, pbx_builtin_setvar_helper(), and S_OR.
Referenced by __init_manager().
01804 { 01805 struct ast_channel *c = NULL; 01806 const char *name = astman_get_header(m, "Channel"); 01807 const char *varname = astman_get_header(m, "Variable"); 01808 const char *varval = astman_get_header(m, "Value"); 01809 int res = 0; 01810 01811 if (ast_strlen_zero(varname)) { 01812 astman_send_error(s, m, "No variable specified"); 01813 return 0; 01814 } 01815 01816 if (!ast_strlen_zero(name)) { 01817 c = ast_get_channel_by_name_locked(name); 01818 if (!c) { 01819 astman_send_error(s, m, "No such channel"); 01820 return 0; 01821 } 01822 } 01823 if (varname[strlen(varname)-1] == ')') { 01824 char *function = ast_strdupa(varname); 01825 res = ast_func_write(c, function, varval); 01826 } else { 01827 pbx_builtin_setvar_helper(c, varname, S_OR(varval, "")); 01828 } 01829 01830 if (c) 01831 ast_channel_unlock(c); 01832 if (res == 0) { 01833 astman_send_ack(s, m, "Variable Set"); 01834 } else { 01835 astman_send_error(s, m, "Variable not set"); 01836 } 01837 return 0; 01838 }
| static int action_status | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Manager "status" command to show channels.
Definition at line 1904 of file manager.c.
References ast_channel::_bridge, ast_channel::_state, ast_channel::accountcode, AST_APP_ARG, ast_channel_unlock, ast_channel_walk_locked(), AST_DECLARE_APP_ARGS, ast_free, ast_func_read(), ast_get_channel_by_name_locked(), AST_STANDARD_APP_ARGS, ast_state2str(), ast_str_append(), ast_str_buffer(), ast_str_create(), ast_str_reset(), ast_strlen_zero(), ast_tvnow(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::bridge, ast_channel::cdr, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, ast_channel::name, name, ast_channel::pbx, pbx_retrieve_variable(), ast_channel::priority, S_OR, ast_cdr::start, str, and ast_channel::uniqueid.
Referenced by __init_manager().
01905 { 01906 const char *name = astman_get_header(m, "Channel"); 01907 const char *cvariables = astman_get_header(m, "Variables"); 01908 char *variables = ast_strdupa(S_OR(cvariables, "")); 01909 struct ast_channel *c; 01910 char bridge[256]; 01911 struct timeval now = ast_tvnow(); 01912 long elapsed_seconds = 0; 01913 int channels = 0; 01914 int all = ast_strlen_zero(name); /* set if we want all channels */ 01915 const char *id = astman_get_header(m, "ActionID"); 01916 char idText[256]; 01917 AST_DECLARE_APP_ARGS(vars, 01918 AST_APP_ARG(name)[100]; 01919 ); 01920 struct ast_str *str = ast_str_create(1000); 01921 01922 if (!ast_strlen_zero(id)) 01923 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01924 else 01925 idText[0] = '\0'; 01926 01927 if (all) 01928 c = ast_channel_walk_locked(NULL); 01929 else { 01930 c = ast_get_channel_by_name_locked(name); 01931 if (!c) { 01932 astman_send_error(s, m, "No such channel"); 01933 ast_free(str); 01934 return 0; 01935 } 01936 } 01937 astman_send_ack(s, m, "Channel status will follow"); 01938 01939 if (!ast_strlen_zero(cvariables)) { 01940 AST_STANDARD_APP_ARGS(vars, variables); 01941 } 01942 01943 /* if we look by name, we break after the first iteration */ 01944 while (c) { 01945 if (!ast_strlen_zero(cvariables)) { 01946 int i; 01947 ast_str_reset(str); 01948 for (i = 0; i < vars.argc; i++) { 01949 char valbuf[512], *ret = NULL; 01950 01951 if (vars.name[i][strlen(vars.name[i]) - 1] == ')') { 01952 if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) { 01953 valbuf[0] = '\0'; 01954 } 01955 ret = valbuf; 01956 } else { 01957 pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL); 01958 } 01959 01960 ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret); 01961 } 01962 } 01963 01964 channels++; 01965 if (c->_bridge) 01966 snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid); 01967 else 01968 bridge[0] = '\0'; 01969 if (c->pbx) { 01970 if (c->cdr) { 01971 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01972 } 01973 astman_append(s, 01974 "Event: Status\r\n" 01975 "Privilege: Call\r\n" 01976 "Channel: %s\r\n" 01977 "CallerIDNum: %s\r\n" 01978 "CallerIDName: %s\r\n" 01979 "Accountcode: %s\r\n" 01980 "ChannelState: %d\r\n" 01981 "ChannelStateDesc: %s\r\n" 01982 "Context: %s\r\n" 01983 "Extension: %s\r\n" 01984 "Priority: %d\r\n" 01985 "Seconds: %ld\r\n" 01986 "%s" 01987 "Uniqueid: %s\r\n" 01988 "%s" 01989 "%s" 01990 "\r\n", 01991 c->name, 01992 S_OR(c->cid.cid_num, ""), 01993 S_OR(c->cid.cid_name, ""), 01994 c->accountcode, 01995 c->_state, 01996 ast_state2str(c->_state), c->context, 01997 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, ast_str_buffer(str), idText); 01998 } else { 01999 astman_append(s, 02000 "Event: Status\r\n" 02001 "Privilege: Call\r\n" 02002 "Channel: %s\r\n" 02003 "CallerIDNum: %s\r\n" 02004 "CallerIDName: %s\r\n" 02005 "Account: %s\r\n" 02006 "State: %s\r\n" 02007 "%s" 02008 "Uniqueid: %s\r\n" 02009 "%s" 02010 "%s" 02011 "\r\n", 02012 c->name, 02013 S_OR(c->cid.cid_num, "<unknown>"), 02014 S_OR(c->cid.cid_name, "<unknown>"), 02015 c->accountcode, 02016 ast_state2str(c->_state), bridge, c->uniqueid, ast_str_buffer(str), idText); 02017 } 02018 ast_channel_unlock(c); 02019 if (!all) 02020 break; 02021 c = ast_channel_walk_locked(c); 02022 } 02023 astman_append(s, 02024 "Event: StatusComplete\r\n" 02025 "%s" 02026 "Items: %d\r\n" 02027 "\r\n", idText, channels); 02028 ast_free(str); 02029 return 0; 02030 }
| static int action_timeout | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2621 of file manager.c.
References ast_channel_setwhentohangup_tv(), ast_channel_unlock, ast_get_channel_by_name_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and name.
Referenced by __init_manager().
02622 { 02623 struct ast_channel *c; 02624 const char *name = astman_get_header(m, "Channel"); 02625 double timeout = atof(astman_get_header(m, "Timeout")); 02626 struct timeval when = { timeout, 0 }; 02627 02628 if (ast_strlen_zero(name)) { 02629 astman_send_error(s, m, "No channel specified"); 02630 return 0; 02631 } 02632 if (!timeout || timeout < 0) { 02633 astman_send_error(s, m, "No timeout specified"); 02634 return 0; 02635 } 02636 c = ast_get_channel_by_name_locked(name); 02637 if (!c) { 02638 astman_send_error(s, m, "No such channel"); 02639 return 0; 02640 } 02641 02642 when.tv_usec = (timeout - when.tv_sec) * 1000000.0; 02643 ast_channel_setwhentohangup_tv(c, when); 02644 ast_channel_unlock(c); 02645 astman_send_ack(s, m, "Timeout Set"); 02646 return 0; 02647 }
| static int action_updateconfig | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1481 of file manager.c.
References ast_config_destroy(), ast_config_load2(), ast_config_text_file_save(), ast_include_rename(), ast_module_reload(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_send_ack(), astman_send_error(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, CONFIG_STATUS_FILEINVALID, FAILURE_ALLOCATION, FAILURE_APPEND, FAILURE_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, handle_updates(), UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, and UNSPECIFIED_CATEGORY.
Referenced by __init_manager().
01482 { 01483 struct ast_config *cfg; 01484 const char *sfn = astman_get_header(m, "SrcFilename"); 01485 const char *dfn = astman_get_header(m, "DstFilename"); 01486 int res; 01487 const char *rld = astman_get_header(m, "Reload"); 01488 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01489 enum error_type result; 01490 01491 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { 01492 astman_send_error(s, m, "Filename not specified"); 01493 return 0; 01494 } 01495 if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) { 01496 astman_send_error(s, m, "Config file not found"); 01497 return 0; 01498 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 01499 astman_send_error(s, m, "Config file has invalid format"); 01500 return 0; 01501 } 01502 result = handle_updates(s, m, cfg, dfn); 01503 if (!result) { 01504 ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */ 01505 res = ast_config_text_file_save(dfn, cfg, "Manager"); 01506 ast_config_destroy(cfg); 01507 if (res) { 01508 astman_send_error(s, m, "Save of config failed"); 01509 return 0; 01510 } 01511 astman_send_ack(s, m, NULL); 01512 if (!ast_strlen_zero(rld)) { 01513 if (ast_true(rld)) 01514 rld = NULL; 01515 ast_module_reload(rld); 01516 } 01517 } else { 01518 ast_config_destroy(cfg); 01519 switch(result) { 01520 case UNKNOWN_ACTION: 01521 astman_send_error(s, m, "Unknown action command"); 01522 break; 01523 case UNKNOWN_CATEGORY: 01524 astman_send_error(s, m, "Given category does not exist"); 01525 break; 01526 case UNSPECIFIED_CATEGORY: 01527 astman_send_error(s, m, "Category not specified"); 01528 break; 01529 case UNSPECIFIED_ARGUMENT: 01530 astman_send_error(s, m, "Problem with category, value, or line (if required)"); 01531 break; 01532 case FAILURE_ALLOCATION: 01533 astman_send_error(s, m, "Memory allocation failure, this should not happen"); 01534 break; 01535 case FAILURE_NEWCAT: 01536 astman_send_error(s, m, "Create category did not complete successfully"); 01537 break; 01538 case FAILURE_DELCAT: 01539 astman_send_error(s, m, "Delete category did not complete successfully"); 01540 break; 01541 case FAILURE_EMPTYCAT: 01542 astman_send_error(s, m, "Empty category did not complete successfully"); 01543 break; 01544 case FAILURE_UPDATE: 01545 astman_send_error(s, m, "Update did not complete successfully"); 01546 break; 01547 case FAILURE_DELETE: 01548 astman_send_error(s, m, "Delete did not complete successfully"); 01549 break; 01550 case FAILURE_APPEND: 01551 astman_send_error(s, m, "Append did not complete successfully"); 01552 break; 01553 } 01554 } 01555 return 0; 01556 }
| static int action_userevent | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2684 of file manager.c.
References ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_thread_get(), astman_get_header(), astman_send_ack(), EVENT_FLAG_USER, message::hdrcount, message::headers, manager_event, and userevent_buf.
Referenced by __init_manager().
02685 { 02686 const char *event = astman_get_header(m, "UserEvent"); 02687 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16); 02688 int x; 02689 02690 ast_str_reset(body); 02691 02692 for (x = 0; x < m->hdrcount; x++) { 02693 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 02694 ast_str_append(&body, 0, "%s\r\n", m->headers[x]); 02695 } 02696 } 02697 02698 astman_send_ack(s, m, "Event Sent"); 02699 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, ast_str_buffer(body)); 02700 return 0; 02701 }
| static int action_waitevent | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1591 of file manager.c.
References mansession_session::__lock, ast_debug, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_strlen_zero(), ast_wait_for_input(), astman_append(), astman_get_header(), astman_send_response(), eventqent::category, eventqent::eventdata, mansession_session::fd, mansession_session::last_ev, mansession_session::managerid, mansession_session::needdestroy, NEW_EVENT, mansession_session::readperm, ref_event(), mansession_session::send_events, mansession::session, mansession_session::sessiontimeout, unref_event(), and mansession_session::waiting_thread.
Referenced by __init_manager().
01592 { 01593 const char *timeouts = astman_get_header(m, "Timeout"); 01594 int timeout = -1; 01595 int x; 01596 int needexit = 0; 01597 const char *id = astman_get_header(m, "ActionID"); 01598 char idText[256]; 01599 01600 if (!ast_strlen_zero(id)) 01601 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01602 else 01603 idText[0] = '\0'; 01604 01605 if (!ast_strlen_zero(timeouts)) { 01606 sscanf(timeouts, "%30i", &timeout); 01607 if (timeout < -1) 01608 timeout = -1; 01609 /* XXX maybe put an upper bound, or prevent the use of 0 ? */ 01610 } 01611 01612 ast_mutex_lock(&s->session->__lock); 01613 if (s->session->waiting_thread != AST_PTHREADT_NULL) 01614 pthread_kill(s->session->waiting_thread, SIGURG); 01615 01616 if (s->session->managerid) { /* AMI-over-HTTP session */ 01617 /* 01618 * Make sure the timeout is within the expire time of the session, 01619 * as the client will likely abort the request if it does not see 01620 * data coming after some amount of time. 01621 */ 01622 time_t now = time(NULL); 01623 int max = s->session->sessiontimeout - now - 10; 01624 01625 if (max < 0) /* We are already late. Strange but possible. */ 01626 max = 0; 01627 if (timeout < 0 || timeout > max) 01628 timeout = max; 01629 if (!s->session->send_events) /* make sure we record events */ 01630 s->session->send_events = -1; 01631 } 01632 ast_mutex_unlock(&s->session->__lock); 01633 01634 /* XXX should this go inside the lock ? */ 01635 s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */ 01636 ast_debug(1, "Starting waiting for an event!\n"); 01637 01638 for (x = 0; x < timeout || timeout < 0; x++) { 01639 ast_mutex_lock(&s->session->__lock); 01640 if (NEW_EVENT(s)) 01641 needexit = 1; 01642 /* We can have multiple HTTP session point to the same mansession entry. 01643 * The way we deal with it is not very nice: newcomers kick out the previous 01644 * HTTP session. XXX this needs to be improved. 01645 */ 01646 if (s->session->waiting_thread != pthread_self()) 01647 needexit = 1; 01648 if (s->session->needdestroy) 01649 needexit = 1; 01650 ast_mutex_unlock(&s->session->__lock); 01651 if (needexit) 01652 break; 01653 if (s->session->managerid == 0) { /* AMI session */ 01654 if (ast_wait_for_input(s->session->fd, 1000)) 01655 break; 01656 } else { /* HTTP session */ 01657 sleep(1); 01658 } 01659 } 01660 ast_debug(1, "Finished waiting for an event!\n"); 01661 ast_mutex_lock(&s->session->__lock); 01662 if (s->session->waiting_thread == pthread_self()) { 01663 struct eventqent *eqe; 01664 astman_send_response(s, m, "Success", "Waiting for Event completed."); 01665 while ( (eqe = NEW_EVENT(s)) ) { 01666 ref_event(eqe); 01667 if (((s->session->readperm & eqe->category) == eqe->category) && 01668 ((s->session->send_events & eqe->category) == eqe->category)) { 01669 astman_append(s, "%s", eqe->eventdata); 01670 } 01671 s->session->last_ev = unref_event(s->session->last_ev); 01672 } 01673 astman_append(s, 01674 "Event: WaitEventComplete\r\n" 01675 "%s" 01676 "\r\n", idText); 01677 s->session->waiting_thread = AST_PTHREADT_NULL; 01678 } else { 01679 ast_debug(1, "Abandoning event request!\n"); 01680 } 01681 ast_mutex_unlock(&s->session->__lock); 01682 return 0; 01683 }
| static int append_event | ( | const char * | str, | |
| int | category | |||
| ) | [static] |
Definition at line 3273 of file manager.c.
References ast_atomic_fetchadd_int(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_UNLOCK, ast_malloc, eventqent::category, eventqent::eventdata, eventqent::seq, and eventqent::usecount.
Referenced by __init_manager(), and __manager_event().
03274 { 03275 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 03276 static int seq; /* sequence number */ 03277 03278 if (!tmp) 03279 return -1; 03280 03281 /* need to init all fields, because ast_malloc() does not */ 03282 tmp->usecount = 0; 03283 tmp->category = category; 03284 tmp->seq = ast_atomic_fetchadd_int(&seq, 1); 03285 AST_LIST_NEXT(tmp, eq_next) = NULL; 03286 strcpy(tmp->eventdata, str); 03287 03288 AST_LIST_LOCK(&all_events); 03289 AST_LIST_INSERT_TAIL(&all_events, tmp, eq_next); 03290 AST_LIST_UNLOCK(&all_events); 03291 03292 return 0; 03293 }
| static int ast_instring | ( | const char * | bigstr, | |
| const char * | smallstr, | |||
| const char | delim | |||
| ) | [static] |
Tells you if smallstr exists inside bigstr which is delim by delim and uses no buf or stringsep ast_instring("this|that|more","this",'|') == 1;
feel free to move this to app.c -anthm
Definition at line 413 of file manager.c.
References eventqent::next.
Referenced by get_perm().
00414 { 00415 const char *val = bigstr, *next; 00416 00417 do { 00418 if ((next = strchr(val, delim))) { 00419 if (!strncmp(val, smallstr, (next - val))) 00420 return 1; 00421 else 00422 continue; 00423 } else 00424 return !strcmp(smallstr, val); 00425 } while (*(val = (next + 1))); 00426 00427 return 0; 00428 }
| int ast_manager_register2 | ( | const char * | action, | |
| int | auth, | |||
| int(*)(struct mansession *s, const struct message *m) | func, | |||
| const char * | synopsis, | |||
| const char * | description | |||
| ) |
register a new command with manager, including online help. This is the preferred way to register a manager command
Register a manager command with the manager interface.
Definition at line 3448 of file manager.c.
References manager_action::action, ast_calloc, ast_free, ast_manager_register_struct(), manager_action::authority, manager_action::description, manager_action::func, and manager_action::synopsis.
Referenced by __init_manager(), ast_features_init(), load_module(), and load_pbx().
03449 { 03450 struct manager_action *cur = NULL; 03451 03452 if (!(cur = ast_calloc(1, sizeof(*cur)))) 03453 return -1; 03454 03455 cur->action = action; 03456 cur->authority = auth; 03457 cur->func = func; 03458 cur->synopsis = synopsis; 03459 cur->description = description; 03460 03461 if (ast_manager_register_struct(cur)) { 03462 ast_free(cur); 03463 return -1; 03464 } 03465 03466 return 0; 03467 }
| void ast_manager_register_hook | ( | struct manager_custom_hook * | hook | ) |
Add a custom hook to be called when an event is fired.
Add a custom hook to be called when an event is fired
| hook | struct manager_custom_hook object to add |
Definition at line 256 of file manager.c.
References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
00257 { 00258 AST_RWLIST_WRLOCK(&manager_hooks); 00259 AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list); 00260 AST_RWLIST_UNLOCK(&manager_hooks); 00261 return; 00262 }
| static int ast_manager_register_struct | ( | struct manager_action * | act | ) | [static] |
Definition at line 3412 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().
03413 { 03414 struct manager_action *cur, *prev = NULL; 03415 struct timespec tv = { 5, }; 03416 03417 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03418 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03419 return -1; 03420 } 03421 AST_RWLIST_TRAVERSE(&actions, cur, list) { 03422 int ret = strcasecmp(cur->action, act->action); 03423 if (ret == 0) { 03424 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 03425 AST_RWLIST_UNLOCK(&actions); 03426 return -1; 03427 } 03428 if (ret > 0) { /* Insert these alphabetically */ 03429 prev = cur; 03430 break; 03431 } 03432 } 03433 03434 if (prev) 03435 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list); 03436 else 03437 AST_RWLIST_INSERT_HEAD(&actions, act, list); 03438 03439 ast_verb(2, "Manager registered action %s\n", act->action); 03440 03441 AST_RWLIST_UNLOCK(&actions); 03442 03443 return 0; 03444 }
| int ast_manager_unregister | ( | char * | action | ) |
Unregister a registered manager command.
| action | Name of registered Action: |
Definition at line 3379 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().
03380 { 03381 struct manager_action *cur; 03382 struct timespec tv = { 5, }; 03383 03384 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03385 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03386 return -1; 03387 } 03388 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) { 03389 if (!strcasecmp(action, cur->action)) { 03390 AST_RWLIST_REMOVE_CURRENT(list); 03391 ast_free(cur); 03392 ast_verb(2, "Manager unregistered action %s\n", action); 03393 break; 03394 } 03395 } 03396 AST_RWLIST_TRAVERSE_SAFE_END; 03397 AST_RWLIST_UNLOCK(&actions); 03398 03399 return 0; 03400 }
| void ast_manager_unregister_hook | ( | struct manager_custom_hook * | hook | ) |
Delete a custom hook to be called when an event is fired.
Delete a custom hook to be called when an event is fired
| hook | struct manager_custom_hook object to delete |
Definition at line 265 of file manager.c.
References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
00266 { 00267 AST_RWLIST_WRLOCK(&manager_hooks); 00268 AST_RWLIST_REMOVE(&manager_hooks, hook, list); 00269 AST_RWLIST_UNLOCK(&manager_hooks); 00270 return; 00271 }
| void astman_append | ( | struct mansession * | s, | |
| const char * | fmt, | |||
| ... | ||||
| ) |
utility functions for creating AMI replies
Definition at line 969 of file manager.c.
References ast_str_buffer(), ast_str_set_va(), ast_str_thread_get(), ast_verbose, astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE, buf, mansession_session::f, mansession::f, send_string(), and mansession::session.
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), _skinny_show_device(), _skinny_show_devices(), _skinny_show_line(), _skinny_show_lines(), action_agents(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_ping(), action_status(), action_waitevent(), ast_cli_netstats(), astman_send_response_full(), do_print(), manager_dbget(), manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_registry(), manager_jabber_send(), manager_list_voicemail_users(), manager_modulecheck(), manager_parking_status(), manager_queue_rule_show(), manager_queues_show(), manager_queues_status(), manager_queues_summary(), manager_rpt_local_nodes(), manager_rpt_status(), manager_show_dialplan_helper(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_skinny_show_device(), manager_skinny_show_devices(), manager_skinny_show_line(), manager_skinny_show_lines(), rpt_manager_do_stats(), rpt_manager_success(), and session_do().
00970 { 00971 va_list ap; 00972 struct ast_str *buf; 00973 00974 if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) 00975 return; 00976 00977 va_start(ap, fmt); 00978 ast_str_set_va(&buf, 0, fmt, ap); 00979 va_end(ap); 00980 00981 if (s->f != NULL || s->session->f != NULL) { 00982 send_string(s, ast_str_buffer(buf)); 00983 } else { 00984 ast_verbose("fd == -1 in astman_append, should not happen\n"); 00985 } 00986 }
| const char* astman_get_header | ( | const struct message * | m, | |
| char * | var | |||
| ) |
Get header from mananger transaction.
Definition at line 897 of file manager.c.
References __astman_get_header(), and GET_HEADER_FIRST_MATCH.
Referenced by _sip_show_peer(), _sip_show_peers(), _skinny_show_devices(), _skinny_show_lines(), action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_atxfer(), action_bridge(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), action_ping(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), action_waitevent(), astman_send_response_full(), authenticate(), change_monitor_action(), do_pause_or_unpause(), handle_updates(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), manager_jabber_send(), manager_list_voicemail_users(), manager_modulecheck(), manager_moduleload(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_reload(), manager_queue_reset(), manager_queue_rule_show(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_rpt_status(), manager_show_dialplan(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), manager_skinny_show_device(), manager_skinny_show_devices(), manager_skinny_show_line(), manager_skinny_show_lines(), meetmemute(), process_message(), rpt_manager_do_stats(), rpt_manager_success(), start_monitor_action(), and stop_monitor_action().
00898 { 00899 return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH); 00900 }
| struct ast_variable* astman_get_variables | ( | const struct message * | m | ) | [read] |
Get a linked list of the Variable: headers.
Definition at line 903 of file manager.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strlen_zero(), ast_variable_new(), message::hdrcount, message::headers, parse(), and var.
Referenced by action_originate(), and manager_sipnotify().
00904 { 00905 int varlen, x, y; 00906 struct ast_variable *head = NULL, *cur; 00907 00908 AST_DECLARE_APP_ARGS(args, 00909 AST_APP_ARG(vars)[32]; 00910 ); 00911 00912 varlen = strlen("Variable: "); 00913 00914 for (x = 0; x < m->hdrcount; x++) { 00915 char *parse, *var, *val; 00916 00917 if (strncasecmp("Variable: ", m->headers[x], varlen)) 00918 continue; 00919 parse = ast_strdupa(m->headers[x] + varlen); 00920 00921 AST_STANDARD_APP_ARGS(args, parse); 00922 if (!args.argc) 00923 continue; 00924 for (y = 0; y < args.argc; y++) { 00925 if (!args.vars[y]) 00926 continue; 00927 var = val = ast_strdupa(args.vars[y]); 00928 strsep(&val, "="); 00929 if (!val || ast_strlen_zero(var)) 00930 continue; 00931 cur = ast_variable_new(var, val, ""); 00932 cur->next = head; 00933 head = cur; 00934 } 00935 } 00936 00937 return head; 00938 }
| void astman_send_ack | ( | struct mansession * | s, | |
| const struct message * | m, | |||
| char * | msg | |||
| ) |
Send ack in manager transaction.
Definition at line 1032 of file manager.c.
References astman_send_response_full().
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_queue_reload(), manager_queue_reset(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_sipnotify(), meetmemute(), start_monitor_action(), and stop_monitor_action().
01033 { 01034 astman_send_response_full(s, m, "Success", msg, NULL); 01035 }
| void astman_send_error | ( | struct mansession * | s, | |
| const struct message * | m, | |||
| char * | error | |||
| ) |
Send error in manager transaction.
Definition at line 1027 of file manager.c.
References astman_send_response_full().
Referenced by _sip_qualify_peer(), _sip_show_peer(), action_add_agi_cmd(), action_agent_logoff(), action_atxfer(), action_bridge(), action_challenge(), action_command(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_modulecheck(), manager_moduleload(), manager_park(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_reload(), manager_queue_reset(), manager_remove_queue_member(), manager_rpt_status(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sipnotify(), manager_skinny_show_device(), manager_skinny_show_line(), meetmemute(), process_message(), rpt_manager_do_stats(), start_monitor_action(), and stop_monitor_action().
01028 { 01029 astman_send_response_full(s, m, "Error", error, NULL); 01030 }
| void astman_send_listack | ( | struct mansession * | s, | |
| const struct message * | m, | |||
| char * | msg, | |||
| char * | listflag | |||
| ) |
Send ack in manager list transaction.
Definition at line 1042 of file manager.c.
References astman_send_response_full().
Referenced by action_coreshowchannels(), action_meetmelist(), manager_dpsendack(), manager_iax2_show_registry(), manager_show_registry(), manager_sip_show_peers(), manager_skinny_show_devices(), and manager_skinny_show_lines().
01043 { 01044 astman_send_response_full(s, m, "Success", msg, listflag); 01045 }
| void astman_send_response | ( | struct mansession * | s, | |
| const struct message * | m, | |||
| char * | resp, | |||
| char * | msg | |||
| ) |
Send response in manager transaction.
Definition at line 1022 of file manager.c.
References astman_send_response_full().
Referenced by action_logoff(), and action_waitevent().
01023 { 01024 astman_send_response_full(s, m, resp, msg, NULL); 01025 }
| static void astman_send_response_full | ( | struct mansession * | s, | |
| const struct message * | m, | |||
| char * | resp, | |||
| char * | msg, | |||
| char * | listflag | |||
| ) | [static] |
Definition at line 1005 of file manager.c.
References ast_strlen_zero(), astman_append(), astman_get_header(), and MSG_MOREDATA.
Referenced by astman_send_ack(), astman_send_error(), astman_send_listack(), astman_send_response(), and astman_start_ack().
01006 { 01007 const char *id = astman_get_header(m, "ActionID"); 01008 01009 astman_append(s, "Response: %s\r\n", resp); 01010 if (!ast_strlen_zero(id)) 01011 astman_append(s, "ActionID: %s\r\n", id); 01012 if (listflag) 01013 astman_append(s, "Eventlist: %s\r\n", listflag); /* Start, complete, cancelled */ 01014 if (msg == MSG_MOREDATA) 01015 return; 01016 else if (msg) 01017 astman_append(s, "Message: %s\r\n\r\n", msg); 01018 else 01019 astman_append(s, "\r\n"); 01020 }
| static void astman_start_ack | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1037 of file manager.c.
References astman_send_response_full(), and MSG_MOREDATA.
Referenced by action_challenge(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_mailboxcount(), and action_mailboxstatus().
01038 { 01039 astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL); 01040 }
| static int authenticate | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1071 of file manager.c.
References ast_apply_ha(), ast_copy_string(), ast_debug, ast_inet_ntoa(), ast_log(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), astman_get_header(), mansession_session::challenge, get_manager_by_name_locked(), ast_manager_user::ha, len(), LOG_NOTICE, MD5Final(), MD5Init(), MD5Update(), ast_manager_user::readperm, mansession_session::readperm, S_OR, ast_manager_user::secret, mansession::session, mansession_session::sessionstart, set_eventmask(), mansession_session::sin, mansession_session::username, ast_manager_user::writeperm, mansession_session::writeperm, ast_manager_user::writetimeout, and mansession_session::writetimeout.
Referenced by action_login().
01072 { 01073 const char *username = astman_get_header(m, "Username"); 01074 const char *password = astman_get_header(m, "Secret"); 01075 int error = -1; 01076 struct ast_manager_user *user = NULL; 01077 01078 if (ast_strlen_zero(username)) /* missing username */ 01079 return -1; 01080 01081 /* locate user in locked state */ 01082 AST_RWLIST_WRLOCK(&users); 01083 01084 if (!(user = get_manager_by_name_locked(username))) { 01085 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01086 } else if (user->ha && !ast_apply_ha(user->ha, &(s->session->sin))) { 01087 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01088 } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) { 01089 const char *key = astman_get_header(m, "Key"); 01090 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) { 01091 int x; 01092 int len = 0; 01093 char md5key[256] = ""; 01094 struct MD5Context md5; 01095 unsigned char digest[16]; 01096 01097 MD5Init(&md5); 01098 MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge)); 01099 MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret)); 01100 MD5Final(digest, &md5); 01101 for (x = 0; x < 16; x++) 01102 len += sprintf(md5key + len, "%2.2x", digest[x]); 01103 if (!strcmp(md5key, key)) 01104 error = 0; 01105 } else { 01106 ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n", 01107 S_OR(s->session->challenge, "")); 01108 } 01109 } else if (password && user->secret && !strcmp(password, user->secret)) 01110 error = 0; 01111 01112 if (error) { 01113 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01114 AST_RWLIST_UNLOCK(&users); 01115 return -1; 01116 } 01117 01118 /* auth complete */ 01119 01120 ast_copy_string(s->session->username, username, sizeof(s->session->username)); 01121 s->session->readperm = user->readperm; 01122 s->session->writeperm = user->writeperm; 01123 s->session->writetimeout = user->writetimeout; 01124 s->session->sessionstart = time(NULL); 01125 set_eventmask(s, astman_get_header(m, "Events")); 01126 01127 AST_RWLIST_UNLOCK(&users); 01128 return 0; 01129 }
| static char* authority_to_str | ( | int | authority, | |
| struct ast_str ** | res | |||
| ) | [static] |
Convert authority code to a list of options.
Definition at line 389 of file manager.c.
References ARRAY_LEN, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_strlen(), num, and perms.
Referenced by __manager_event(), action_listcommands(), handle_showmanager(), handle_showmancmd(), and handle_showmancmds().
00390 { 00391 int i; 00392 char *sep = ""; 00393 00394 ast_str_reset(*res); 00395 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) { 00396 if (authority & perms[i].num) { 00397 ast_str_append(res, 0, "%s%s", sep, perms[i].label); 00398 sep = ","; 00399 } 00400 } 00401 00402 if (ast_str_strlen(*res) == 0) /* replace empty string with something sensible */ 00403 ast_str_append(res, 0, "<none>"); 00404 00405 return ast_str_buffer(*res); 00406 }
| static int check_blacklist | ( | const char * | cmd | ) | [static] |
Definition at line 2216 of file manager.c.
References ARRAY_LEN, ast_strip(), ast_strlen_zero(), command_blacklist, match(), MAX_BLACKLIST_CMD_LEN, and words.
Referenced by action_command().
02217 { 02218 char *cmd_copy, *cur_cmd; 02219 char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, }; 02220 int i; 02221 02222 cmd_copy = ast_strdupa(cmd); 02223 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) { 02224 cur_cmd = ast_strip(cur_cmd); 02225 if (ast_strlen_zero(cur_cmd)) { 02226 i--; 02227 continue; 02228 } 02229 02230 cmd_words[i] = cur_cmd; 02231 } 02232 02233 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) { 02234 int j, match = 1; 02235 02236 for (j = 0; command_blacklist[i].words[j]; j++) { 02237 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) { 02238 match = 0; 02239 break; 02240 } 02241 } 02242 02243 if (match) { 02244 return 1; 02245 } 02246 } 02247 02248 return 0; 02249 }
| int check_manager_enabled | ( | void | ) |
Event list management functions. We assume that the event list always has at least one element, and the delete code will not remove the last entry even if the.
Check if AMI is enabled.
Definition at line 316 of file manager.c.
Referenced by handle_show_settings().
00317 { 00318 return manager_enabled; 00319 }
| static int check_manager_session_inuse | ( | const char * | name | ) | [static] |
Definition at line 472 of file manager.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, mansession_session::list, and mansession_session::username.
Referenced by process_message().
00473 { 00474 struct mansession_session *session = NULL; 00475 00476 AST_LIST_LOCK(&sessions); 00477 AST_LIST_TRAVERSE(&sessions, session, list) { 00478 if (!strcasecmp(session->username, name)) 00479 break; 00480 } 00481 AST_LIST_UNLOCK(&sessions); 00482 00483 return session ? 1 : 0; 00484 }
| int check_webmanager_enabled | ( | void | ) |
Check if AMI/HTTP is enabled.
Definition at line 321 of file manager.c.
Referenced by action_coresettings(), and handle_show_settings().
00322 { 00323 return (webmanager_enabled && manager_enabled); 00324 }
| static void destroy_session | ( | struct mansession_session * | session | ) | [static] |
Definition at line 852 of file manager.c.
References ast_atomic_fetchadd_int(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, and free_session().
Referenced by generic_http_callback(), and session_do().
00853 { 00854 AST_LIST_LOCK(&sessions); 00855 AST_LIST_REMOVE(&sessions, session, list); 00856 ast_atomic_fetchadd_int(&num_sessions, -1); 00857 free_session(session); 00858 AST_LIST_UNLOCK(&sessions); 00859 }
| static int do_message | ( | struct mansession * | s | ) | [static] |
Definition at line 3137 of file manager.c.
References AST_MAX_MANHEADERS, ast_strlen_zero(), get_input(), message::hdrcount, message::headers, mansession_session::inbuf, process_events(), process_message(), and mansession::session.
Referenced by session_do().
03138 { 03139 struct message m = { 0 }; 03140 char header_buf[sizeof(s->session->inbuf)] = { '\0' }; 03141 int res; 03142 03143 for (;;) { 03144 /* Check if any events are pending and do them if needed */ 03145 if (process_events(s)) 03146 return -1; 03147 res = get_input(s, header_buf); 03148 if (res == 0) { 03149 continue; 03150 } else if (res > 0) { 03151 if (ast_strlen_zero(header_buf)) 03152 return process_message(s, &m) ? -1 : 0; 03153 else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) 03154 m.headers[m.hdrcount++] = ast_strdupa(header_buf); 03155 } else { 03156 return res; 03157 } 03158 } 03159 }
| static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 2329 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().
02330 { 02331 struct fast_originate_helper *in = data; 02332 int res; 02333 int reason = 0; 02334 struct ast_channel *chan = NULL; 02335 char requested_channel[AST_CHANNEL_NAME]; 02336 02337 if (!ast_strlen_zero(in->app)) { 02338 res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1, 02339 S_OR(in->cid_num, NULL), 02340 S_OR(in->cid_name, NULL), 02341 in->vars, in->account, &chan); 02342 } else { 02343 res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 02344 S_OR(in->cid_num, NULL), 02345 S_OR(in->cid_name, NULL), 02346 in->vars, in->account, &chan); 02347 } 02348 02349 if (!chan) 02350 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 02351 /* Tell the manager what happened with the channel */ 02352 manager_event(EVENT_FLAG_CALL, "OriginateResponse", 02353 "%s%s" 02354 "Response: %s\r\n" 02355 "Channel: %s\r\n" 02356 "Context: %s\r\n" 02357 "Exten: %s\r\n" 02358 "Reason: %d\r\n" 02359 "Uniqueid: %s\r\n" 02360 "CallerIDNum: %s\r\n" 02361 "CallerIDName: %s\r\n", 02362 in->idtext, ast_strlen_zero(in->idtext) ? "" : "\r\n", res ? "Failure" : "Success", 02363 chan ? chan->name : requested_channel, in->context, in->exten, reason, 02364 chan ? chan->uniqueid : "<null>", 02365 S_OR(in->cid_num, "<unknown>"), 02366 S_OR(in->cid_name, "<unknown>") 02367 ); 02368 02369 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 02370 if (chan) 02371 ast_channel_unlock(chan); 02372 ast_free(in); 02373 return NULL; 02374 }
| static void free_session | ( | struct mansession_session * | session | ) | [static] |
Definition at line 834 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().
00835 { 00836 struct eventqent *eqe = session->last_ev; 00837 struct ast_datastore *datastore; 00838 00839 /* Get rid of each of the data stores on the session */ 00840 while ((datastore = AST_LIST_REMOVE_HEAD(&session->datastores, entry))) { 00841 /* Free the data store */ 00842 ast_datastore_free(datastore); 00843 } 00844 00845 if (session->f != NULL) 00846 fclose(session->f); 00847 ast_mutex_destroy(&session->__lock); 00848 ast_free(session); 00849 unref_event(eqe); 00850 }
| 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 3067 of file manager.c.
References mansession_session::__lock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_wait_for_input(), errno, mansession_session::f, mansession_session::fd, mansession_session::inbuf, mansession_session::inlen, LOG_WARNING, mansession_session::pending_event, mansession::session, mansession_session::sin, ast_frame::src, and mansession_session::waiting_thread.
Referenced by do_message().
03068 { 03069 int res, x; 03070 int maxlen = sizeof(s->session->inbuf) - 1; 03071 char *src = s->session->inbuf; 03072 03073 /* 03074 * Look for \r\n within the buffer. If found, copy to the output 03075 * buffer and return, trimming the \r\n (not used afterwards). 03076 */ 03077 for (x = 0; x < s->session->inlen; x++) { 03078 int cr; /* set if we have \r */ 03079 if (src[x] == '\r' && x+1 < s->session->inlen && src[x+1] == '\n') 03080 cr = 2; /* Found. Update length to include \r\n */ 03081 else if (src[x] == '\n') 03082 cr = 1; /* also accept \n only */ 03083 else 03084 continue; 03085 memmove(output, src, x); /*... but trim \r\n */ 03086 output[x] = '\0'; /* terminate the string */ 03087 x += cr; /* number of bytes used */ 03088 s->session->inlen -= x; /* remaining size */ 03089 memmove(src, src + x, s->session->inlen); /* remove used bytes */ 03090 return 1; 03091 } 03092 if (s->session->inlen >= maxlen) { 03093 /* no crlf found, and buffer full - sorry, too long for us */ 03094 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src); 03095 s->session->inlen = 0; 03096 } 03097 res = 0; 03098 while (res == 0) { 03099 /* XXX do we really need this locking ? */ 03100 ast_mutex_lock(&s->session->__lock); 03101 if (s->session->pending_event) { 03102 s->session->pending_event = 0; 03103 ast_mutex_unlock(&s->session->__lock); 03104 return 0; 03105 } 03106 s->session->waiting_thread = pthread_self(); 03107 ast_mutex_unlock(&s->session->__lock); 03108 03109 res = ast_wait_for_input(s->session->fd, -1); /* return 0 on timeout ? */ 03110 03111 ast_mutex_lock(&s->session->__lock); 03112 s->session->waiting_thread = AST_PTHREADT_NULL; 03113 ast_mutex_unlock(&s->session->__lock); 03114 } 03115 if (res < 0) { 03116 /* If we get a signal from some other thread (typically because 03117 * there are new events queued), return 0 to notify the caller. 03118 */ 03119 if (errno == EINTR || errno == EAGAIN) 03120 return 0; 03121 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno)); 03122 return -1; 03123 } 03124 ast_mutex_lock(&s->session->__lock); 03125 res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f); 03126 if (res < 1) 03127 res = -1; /* error return */ 03128 else { 03129 s->session->inlen += res; 03130 src[s->session->inlen] = '\0'; 03131 res = 0; 03132 } 03133 ast_mutex_unlock(&s->session->__lock); 03134 return res; 03135 }
| static struct ast_manager_user* get_manager_by_name_locked | ( | const char * | name | ) | [static, read] |
lookup an entry in the list of registered users. must be called with the list lock held.
Definition at line 491 of file manager.c.
References AST_RWLIST_TRAVERSE, ast_manager_user::list, and ast_manager_user::username.
Referenced by __init_manager(), authenticate(), handle_showmanager(), and manager_displayconnects().
00492 { 00493 struct ast_manager_user *user = NULL; 00494 00495 AST_RWLIST_TRAVERSE(&users, user, list) 00496 if (!strcasecmp(user->username, name)) 00497 break; 00498 return user; 00499 }
| static int get_perm | ( | const char * | instr | ) | [static] |
Definition at line 430 of file manager.c.
References ARRAY_LEN, ast_instring(), num, and perms.
Referenced by __init_manager(), and strings_to_mask().
| static struct eventqent* grab_last | ( | void | ) | [static, read] |
Grab a reference to the last event, update usecount as needed. Can handle a NULL pointer.
Definition at line 330 of file manager.c.
References ast_atomic_fetchadd_int(), AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_UNLOCK, and eventqent::usecount.
Referenced by generic_http_callback(), and session_do().
00331 { 00332 struct eventqent *ret; 00333 00334 AST_LIST_LOCK(&all_events); 00335 ret = AST_LIST_LAST(&all_events); 00336 /* the list is never empty now, but may become so when 00337 * we optimize it in the future, so be prepared. 00338 */ 00339 if (ret) 00340 ast_atomic_fetchadd_int(&ret->usecount, 1); 00341 AST_LIST_UNLOCK(&all_events); 00342 return ret; 00343 }
| static char* handle_manager_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
CLI command manager reload.
Definition at line 784 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.
00785 { 00786 switch (cmd) { 00787 case CLI_INIT: 00788 e->command = "manager reload"; 00789 e->usage = 00790 "Usage: manager reload\n" 00791 " Reloads the manager configuration.\n"; 00792 return NULL; 00793 case CLI_GENERATE: 00794 return NULL; 00795 } 00796 if (a->argc > 2) 00797 return CLI_SHOWUSAGE; 00798 reload_manager(); 00799 return CLI_SUCCESS; 00800 }
| static char* handle_mandebug | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 565 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.
00566 { 00567 switch (cmd) { 00568 case CLI_INIT: 00569 e->command = "manager set debug [on|off]"; 00570 e->usage = "Usage: manager set debug [on|off]\n Show, enable, disable debugging of the manager code.\n"; 00571 return NULL; 00572 case CLI_GENERATE: 00573 return NULL; 00574 } 00575 if (a->argc == 3) 00576 ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off"); 00577 else if (a->argc == 4) { 00578 if (!strcasecmp(a->argv[3], "on")) 00579 manager_debug = 1; 00580 else if (!strcasecmp(a->argv[3], "off")) 00581 manager_debug = 0; 00582 else 00583 return CLI_SHOWUSAGE; 00584 } 00585 return CLI_SUCCESS; 00586 }
| static char* handle_showmanager | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 588 of file manager.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_manager_user::displayconnects, ast_cli_args::fd, get_manager_by_name_locked(), ast_manager_user::ha, ast_cli_args::n, ast_cli_args::pos, ast_manager_user::readperm, ast_manager_user::secret, ast_cli_entry::usage, ast_manager_user::username, ast_cli_args::word, and ast_manager_user::writeperm.
00589 { 00590 struct ast_manager_user *user = NULL; 00591 int l, which; 00592 char *ret = NULL; 00593 struct ast_str *rauthority = ast_str_alloca(128); 00594 struct ast_str *wauthority = ast_str_alloca(128); 00595 00596 switch (cmd) { 00597 case CLI_INIT: 00598 e->command = "manager show user"; 00599 e->usage = 00600 " Usage: manager show user <user>\n" 00601 " Display all information related to the manager user specified.\n"; 00602 return NULL; 00603 case CLI_GENERATE: 00604 l = strlen(a->word); 00605 which = 0; 00606 if (a->pos != 3) 00607 return NULL; 00608 AST_RWLIST_RDLOCK(&users); 00609 AST_RWLIST_TRAVERSE(&users, user, list) { 00610 if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) { 00611 ret = ast_strdup(user->username); 00612 break; 00613 } 00614 } 00615 AST_RWLIST_UNLOCK(&users); 00616 return ret; 00617 } 00618 00619 if (a->argc != 4) 00620 return CLI_SHOWUSAGE; 00621 00622 AST_RWLIST_RDLOCK(&users); 00623 00624 if (!(user = get_manager_by_name_locked(a->argv[3]))) { 00625 ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]); 00626 AST_RWLIST_UNLOCK(&users); 00627 return CLI_SUCCESS; 00628 } 00629 00630 ast_cli(a->fd, "\n"); 00631 ast_cli(a->fd, 00632 " username: %s\n" 00633 " secret: %s\n" 00634 " acl: %s\n" 00635 " read perm: %s\n" 00636 " write perm: %s\n" 00637 "displayconnects: %s\n", 00638 (user->username ? user->username : "(N/A)"), 00639 (user->secret ? "<Set>" : "(N/A)"), 00640 (user->ha ? "yes" : "no"), 00641 authority_to_str(user->readperm, &rauthority), 00642 authority_to_str(user->writeperm, &wauthority), 00643 (user->displayconnects ? "yes" : "no")); 00644 00645 AST_RWLIST_UNLOCK(&users); 00646 00647 return CLI_SUCCESS; 00648 }
| static char* handle_showmanagers | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 651 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 ast_manager_user::username.
00652 { 00653 struct ast_manager_user *user = NULL; 00654 int count_amu = 0; 00655 switch (cmd) { 00656 case CLI_INIT: 00657 e->command = "manager show users"; 00658 e->usage = 00659 "Usage: manager show users\n" 00660 " Prints a listing of all managers that are currently configured on that\n" 00661 " system.\n"; 00662 return NULL; 00663 case CLI_GENERATE: 00664 return NULL; 00665 } 00666 if (a->argc != 3) 00667 return CLI_SHOWUSAGE; 00668 00669 AST_RWLIST_RDLOCK(&users); 00670 00671 /* If there are no users, print out something along those lines */ 00672 if (AST_RWLIST_EMPTY(&users)) { 00673 ast_cli(a->fd, "There are no manager users.\n"); 00674 AST_RWLIST_UNLOCK(&users); 00675 return CLI_SUCCESS; 00676 } 00677 00678 ast_cli(a->fd, "\nusername\n--------\n"); 00679 00680 AST_RWLIST_TRAVERSE(&users, user, list) { 00681 ast_cli(a->fd, "%s\n", user->username); 00682 count_amu++; 00683 } 00684 00685 AST_RWLIST_UNLOCK(&users); 00686 00687 ast_cli(a->fd, "-------------------\n"); 00688 ast_cli(a->fd, "%d manager users configured.\n", count_amu); 00689 00690 return CLI_SUCCESS; 00691 }
| static char* handle_showmancmd | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 518 of file manager.c.
References manager_action::action, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, manager_action::authority, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, manager_action::description, ast_cli_args::fd, ast_cli_args::n, num, S_OR, manager_action::synopsis, ast_cli_entry::usage, and ast_cli_args::word.
00519 { 00520 struct manager_action *cur; 00521 struct ast_str *authority; 00522 int num, l, which; 00523 char *ret = NULL; 00524 switch (cmd) { 00525 case CLI_INIT: 00526 e->command = "manager show command"; 00527 e->usage = 00528 "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n" 00529 " Shows the detailed description for a specific Asterisk manager interface command.\n"; 00530 return NULL; 00531 case CLI_GENERATE: 00532 l = strlen(a->word); 00533 which = 0; 00534 AST_RWLIST_RDLOCK(&actions); 00535 AST_RWLIST_TRAVERSE(&actions, cur, list) { 00536 if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) { 00537 ret = ast_strdup(cur->action); 00538 break; /* make sure we exit even if ast_strdup() returns NULL */ 00539 } 00540 } 00541 AST_RWLIST_UNLOCK(&actions); 00542 return ret; 00543 } 00544 authority = ast_str_alloca(80); 00545 if (a->argc < 4) { 00546 return CLI_SHOWUSAGE; 00547 } 00548 00549 AST_RWLIST_RDLOCK(&actions); 00550 AST_RWLIST_TRAVERSE(&actions, cur, list) { 00551 for (num = 3; num < a->argc; num++) { 00552 if (!strcasecmp(cur->action, a->argv[num])) { 00553 ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", 00554 cur->action, cur->synopsis, 00555 authority_to_str(cur->authority, &authority), 00556 S_OR(cur->description, "")); 00557 } 00558 } 00559 } 00560 AST_RWLIST_UNLOCK(&actions); 00561 00562 return CLI_SUCCESS; 00563 }
| 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 695 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.
00696 { 00697 struct manager_action *cur; 00698 struct ast_str *authority; 00699 #define HSMC_FORMAT " %-15.15s %-15.15s %-55.55s\n" 00700 switch (cmd) { 00701 case CLI_INIT: 00702 e->command = "manager show commands"; 00703 e->usage = 00704 "Usage: manager show commands\n" 00705 " Prints a listing of all the available Asterisk manager interface commands.\n"; 00706 return NULL; 00707 case CLI_GENERATE: 00708 return NULL; 00709 } 00710 authority = ast_str_alloca(80); 00711 ast_cli(a->fd, HSMC_FORMAT, "Action", "Privilege", "Synopsis"); 00712 ast_cli(a->fd, HSMC_FORMAT, "------", "---------", "--------"); 00713 00714 AST_RWLIST_RDLOCK(&actions); 00715 AST_RWLIST_TRAVERSE(&actions, cur, list) 00716 ast_cli(a->fd, HSMC_FORMAT, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis); 00717 AST_RWLIST_UNLOCK(&actions); 00718 00719 return CLI_SUCCESS; 00720 }
| 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 723 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.
00724 { 00725 struct mansession_session *session; 00726 time_t now = time(NULL); 00727 #define HSMCONN_FORMAT1 " %-15.15s %-15.15s %-10.10s %-10.10s %-8.8s %-8.8s %-5.5s %-5.5s\n" 00728 #define HSMCONN_FORMAT2 " %-15.15s %-15.15s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\n" 00729 int count = 0; 00730 switch (cmd) { 00731 case CLI_INIT: 00732 e->command = "manager show connected"; 00733 e->usage = 00734 "Usage: manager show connected\n" 00735 " Prints a listing of the users that are currently connected to the\n" 00736 "Asterisk manager interface.\n"; 00737 return NULL; 00738 case CLI_GENERATE: 00739 return NULL; 00740 } 00741 00742 ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write"); 00743 00744 AST_LIST_LOCK(&sessions); 00745 AST_LIST_TRAVERSE(&sessions, session, list) { 00746 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); 00747 count++; 00748 } 00749 AST_LIST_UNLOCK(&sessions); 00750 00751 ast_cli(a->fd, "%d users connected.\n", count); 00752 00753 return CLI_SUCCESS; 00754 }
| 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 758 of file manager.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, eventqent::category, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, eventqent::eventdata, ast_cli_args::fd, s, ast_cli_entry::usage, and eventqent::usecount.
00759 { 00760 struct eventqent *s; 00761 switch (cmd) { 00762 case CLI_INIT: 00763 e->command = "manager show eventq"; 00764 e->usage = 00765 "Usage: manager show eventq\n" 00766 " Prints a listing of all events pending in the Asterisk manger\n" 00767 "event queue.\n"; 00768 return NULL; 00769 case CLI_GENERATE: 00770 return NULL; 00771 } 00772 AST_LIST_LOCK(&all_events); 00773 AST_LIST_TRAVERSE(&all_events, s, eq_next) { 00774 ast_cli(a->fd, "Usecount: %d\n", s->usecount); 00775 ast_cli(a->fd, "Category: %d\n", s->category); 00776 ast_cli(a->fd, "Event:\n%s", s->eventdata); 00777 } 00778 AST_LIST_UNLOCK(&all_events); 00779 00780 return CLI_SUCCESS; 00781 }
| static enum error_type handle_updates | ( | struct mansession * | s, | |
| const struct message * | m, | |||
| struct ast_config * | cfg, | |||
| const char * | dfn | |||
| ) | [static] |
Definition at line 1324 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().
01325 { 01326 int x; 01327 char hdr[40]; 01328 const char *action, *cat, *var, *value, *match, *line; 01329 struct ast_category *category; 01330 struct ast_variable *v; 01331 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 01332 enum error_type result = 0; 01333 01334 for (x = 0; x < 100000; x++) { /* 100000 = the max number of allowed updates + 1 */ 01335 unsigned int object = 0; 01336 01337 snprintf(hdr, sizeof(hdr), "Action-%06d", x); 01338 action = astman_get_header(m, hdr); 01339 if (ast_strlen_zero(action)) /* breaks the for loop if no action header */ 01340 break; /* this could cause problems if actions come in misnumbered */ 01341 01342 snprintf(hdr, sizeof(hdr), "Cat-%06d", x); 01343 cat = astman_get_header(m, hdr); 01344 if (ast_strlen_zero(cat)) { /* every action needs a category */ 01345 result = UNSPECIFIED_CATEGORY; 01346 break; 01347 } 01348 01349 snprintf(hdr, sizeof(hdr), "Var-%06d", x); 01350 var = astman_get_header(m, hdr); 01351 01352 snprintf(hdr, sizeof(hdr), "Value-%06d", x); 01353 value = astman_get_header(m, hdr); 01354 01355 if (!ast_strlen_zero(value) && *value == '>') { 01356 object = 1; 01357 value++; 01358 } 01359 01360 snprintf(hdr, sizeof(hdr), "Match-%06d", x); 01361 match = astman_get_header(m, hdr); 01362 01363 snprintf(hdr, sizeof(hdr), "Line-%06d", x); 01364 line = astman_get_header(m, hdr); 01365 01366 if (!strcasecmp(action, "newcat")) { 01367 if (ast_category_get(cfg,cat)) { /* check to make sure the cat doesn't */ 01368 result = FAILURE_NEWCAT; /* already exist */ 01369 break; 01370 } 01371 if (!(category = ast_category_new(cat, dfn, -1))) { 01372 result = FAILURE_ALLOCATION; 01373 break; 01374 } 01375 if (ast_strlen_zero(match)) { 01376 ast_category_append(cfg, category); 01377 } else 01378 ast_category_insert(cfg, category, match); 01379 } else if (!strcasecmp(action, "renamecat")) { 01380 if (ast_strlen_zero(value)) { 01381 result = UNSPECIFIED_ARGUMENT; 01382 break; 01383 } 01384 if (!(category = ast_category_get(cfg, cat))) { 01385 result = UNKNOWN_CATEGORY; 01386 break; 01387 } 01388 ast_category_rename(category, value); 01389 } else if (!strcasecmp(action, "delcat")) { 01390 if (ast_category_delete(cfg, cat)) { 01391 result = FAILURE_DELCAT; 01392 break; 01393 } 01394 } else if (!strcasecmp(action, "emptycat")) { 01395 if (ast_category_empty(cfg, cat)) { 01396 result = FAILURE_EMPTYCAT; 01397 break; 01398 } 01399 } else if (!strcasecmp(action, "update")) { 01400 if (ast_strlen_zero(var)) { 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_update(category, var, value, match, object)) { 01409 result = FAILURE_UPDATE; 01410 break; 01411 } 01412 } else if (!strcasecmp(action, "delete")) { 01413 if ((ast_strlen_zero(var) && ast_strlen_zero(line))) { 01414 result = UNSPECIFIED_ARGUMENT; 01415 break; 01416 } 01417 if (!(category = ast_category_get(cfg, cat))) { 01418 result = UNKNOWN_CATEGORY; 01419 break; 01420 } 01421 if (ast_variable_delete(category, var, match, line)) { 01422 result = FAILURE_DELETE; 01423 break; 01424 } 01425 } else if (!strcasecmp(action, "append")) { 01426 if (ast_strlen_zero(var)) { 01427 result = UNSPECIFIED_ARGUMENT; 01428 break; 01429 } 01430 if (!(category = ast_category_get(cfg, cat))) { 01431 result = UNKNOWN_CATEGORY; 01432 break; 01433 } 01434 if (!(v = ast_variable_new(var, value, dfn))) { 01435 result = FAILURE_ALLOCATION; 01436 break; 01437 } 01438 if (object || (match && !strcasecmp(match, "object"))) 01439 v->object = 1; 01440 ast_variable_append(category, v); 01441 } else if (!strcasecmp(action, "insert")) { 01442 if (ast_strlen_zero(var) || ast_strlen_zero(line)) { 01443 result = UNSPECIFIED_ARGUMENT; 01444 break; 01445 } 01446 if (!(category = ast_category_get(cfg, cat))) { 01447 result = UNKNOWN_CATEGORY; 01448 break; 01449 } 01450 if (!(v = ast_variable_new(var, value, dfn))) { 01451 result = FAILURE_ALLOCATION; 01452 break; 01453 } 01454 ast_variable_insert(category, v, line); 01455 } 01456 else { 01457 ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action); 01458 result = UNKNOWN_ACTION; 01459 break; 01460 } 01461 } 01462 ast_free(str1); 01463 ast_free(str2); 01464 return result; 01465 }
| 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 1240 of file manager.c.
Referenced by action_getconfigjson().
| static int manager_displayconnects | ( | struct mansession_session * | session | ) | [static] |
Get displayconnects config option.
| session | manager session to get parameter from. |
Definition at line 505 of file manager.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_manager_user::displayconnects, get_manager_by_name_locked(), and mansession_session::username.
Referenced by action_login(), generic_http_callback(), purge_sessions(), and session_do().
00506 { 00507 struct ast_manager_user *user = NULL; 00508 int ret = 0; 00509 00510 AST_RWLIST_RDLOCK(&users); 00511 if ((user = get_manager_by_name_locked (session->username))) 00512 ret = user->displayconnects; 00513 AST_RWLIST_UNLOCK(&users); 00514 00515 return ret; 00516 }
| static int manager_modulecheck | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2885 of file manager.c.
References ast_copy_string(), ast_file_version_find(), ast_log(), ast_module_check(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), LOG_DEBUG, and version.
Referenced by __init_manager().
02886 { 02887 int res; 02888 const char *module = astman_get_header(m, "Module"); 02889 const char *id = astman_get_header(m, "ActionID"); 02890 char idText[256]; 02891 #if !defined(LOW_MEMORY) 02892 const char *version; 02893 #endif 02894 char filename[PATH_MAX]; 02895 char *cut; 02896 02897 ast_copy_string(filename, module, sizeof(filename)); 02898 if ((cut = strchr(filename, '.'))) { 02899 *cut = '\0'; 02900 } else { 02901 cut = filename + strlen(filename); 02902 } 02903 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so"); 02904 ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename); 02905 res = ast_module_check(filename); 02906 if (!res) { 02907 astman_send_error(s, m, "Module not loaded"); 02908 return 0; 02909 } 02910 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c"); 02911 ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename); 02912 #if !defined(LOW_MEMORY) 02913 version = ast_file_version_find(filename); 02914 #endif 02915 02916 if (!ast_strlen_zero(id)) 02917 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02918 else 02919 idText[0] = '\0'; 02920 astman_append(s, "Response: Success\r\n%s", idText); 02921 #if !defined(LOW_MEMORY) 02922 astman_append(s, "Version: %s\r\n\r\n", version ? version : ""); 02923 #endif 02924 return 0; 02925 }
| static int manager_moduleload | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2938 of file manager.c.
References AST_FORCE_SOFT, ast_load_resource(), ast_module_reload(), ast_unload_resource(), astman_get_header(), astman_send_ack(), and astman_send_error().
Referenced by __init_manager().
02939 { 02940 int res; 02941 const char *module = astman_get_header(m, "Module"); 02942 const char *loadtype = astman_get_header(m, "LoadType"); 02943 02944 if (!loadtype || strlen(loadtype) == 0) 02945 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02946 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) 02947 astman_send_error(s, m, "Need module name"); 02948 02949 if (!strcasecmp(loadtype, "load")) { 02950 res = ast_load_resource(module); 02951 if (res) 02952 astman_send_error(s, m, "Could not load module."); 02953 else 02954 astman_send_ack(s, m, "Module loaded."); 02955 } else if (!strcasecmp(loadtype, "unload")) { 02956 res = ast_unload_resource(module, AST_FORCE_SOFT); 02957 if (res) 02958 astman_send_error(s, m, "Could not unload module."); 02959 else 02960 astman_send_ack(s, m, "Module unloaded."); 02961 } else if (!strcasecmp(loadtype, "reload")) { 02962 if (module != NULL) { 02963 res = ast_module_reload(module); 02964 if (res == 0) 02965 astman_send_error(s, m, "No such module."); 02966 else if (res == 1) 02967 astman_send_error(s, m, "Module does not support reload action."); 02968 else 02969 astman_send_ack(s, m, "Module reloaded."); 02970 } else { 02971 ast_module_reload(NULL); /* Reload all modules */ 02972 astman_send_ack(s, m, "All modules reloaded"); 02973 } 02974 } else 02975 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02976 return 0; 02977 }
| static int manager_state_cb | ( | char * | context, | |
| char * | exten, | |||
| int | state, | |||
| void * | data | |||
| ) | [static] |
Definition at line 3402 of file manager.c.
References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.
Referenced by __init_manager().
03403 { 03404 /* Notify managers of change */ 03405 char hint[512]; 03406 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten); 03407 03408 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state); 03409 return 0; 03410 }
| 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 2654 of file manager.c.
References mansession_session::__lock, ast_mutex_lock(), ast_mutex_unlock(), mansession_session::authenticated, eventqent::category, eventqent::eventdata, mansession_session::f, mansession_session::last_ev, NEW_EVENT, mansession_session::readperm, ref_event(), mansession_session::send_events, send_string(), mansession::session, and unref_event().
Referenced by do_message(), and process_message().
02655 { 02656 int ret = 0; 02657 02658 ast_mutex_lock(&s->session->__lock); 02659 if (s->session->f != NULL) { 02660 struct eventqent *eqe; 02661 02662 while ( (eqe = NEW_EVENT(s)) ) { 02663 ref_event(eqe); 02664 if (!ret && s->session->authenticated && 02665 (s->session->readperm & eqe->category) == eqe->category && 02666 (s->session->send_events & eqe->category) == eqe->category) { 02667 if (send_string(s, eqe->eventdata) < 0) 02668 ret = -1; /* don't send more */ 02669 } 02670 s->session->last_ev = unref_event(s->session->last_ev); 02671 } 02672 } 02673 ast_mutex_unlock(&s->session->__lock); 02674 return ret; 02675 }
| static int process_message | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2992 of file manager.c.
References __astman_get_header(), mansession_session::__lock, manager_action::action, ast_copy_string(), ast_debug, ast_mutex_lock(), ast_mutex_unlock(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), astman_get_header(), astman_send_error(), mansession_session::authenticated, manager_action::authority, buf, check_manager_session_inuse(), manager_action::func, GET_HEADER_SKIP_EMPTY, process_events(), mansession::session, and mansession_session::writeperm.
Referenced by do_message(), and generic_http_callback().
02993 { 02994 char action[80] = ""; 02995 int ret = 0; 02996 struct manager_action *tmp; 02997 const char *user = astman_get_header(m, "Username"); 02998 02999 ast_copy_string(action, __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY), sizeof(action)); 03000 ast_debug(1, "Manager received command '%s'\n", action); 03001 03002 if (ast_strlen_zero(action)) { 03003 ast_mutex_lock(&s->session->__lock); 03004 astman_send_error(s, m, "Missing action in request"); 03005 ast_mutex_unlock(&s->session->__lock); 03006 return 0; 03007 } 03008 03009 if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) { 03010 ast_mutex_lock(&s->session->__lock); 03011 astman_send_error(s, m, "Permission denied"); 03012 ast_mutex_unlock(&s->session->__lock); 03013 return 0; 03014 } 03015 03016 if (!allowmultiplelogin && !s->session->authenticated && user && 03017 (!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) { 03018 if (check_manager_session_inuse(user)) { 03019 sleep(1); 03020 ast_mutex_lock(&s->session->__lock); 03021 astman_send_error(s, m, "Login Already In Use"); 03022 ast_mutex_unlock(&s->session->__lock); 03023 return -1; 03024 } 03025 } 03026 03027 AST_RWLIST_RDLOCK(&actions); 03028 AST_RWLIST_TRAVERSE(&actions, tmp, list) { 03029 if (strcasecmp(action, tmp->action)) 03030 continue; 03031 if (s->session->writeperm & tmp->authority || tmp->authority == 0) 03032 ret = tmp->func(s, m); 03033 else 03034 astman_send_error(s, m, "Permission denied"); 03035 break; 03036 } 03037 AST_RWLIST_UNLOCK(&actions); 03038 03039 if (!tmp) { 03040 char buf[512]; 03041 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action); 03042 ast_mutex_lock(&s->session->__lock); 03043 astman_send_error(s, m, buf); 03044 ast_mutex_unlock(&s->session->__lock); 03045 } 03046 if (ret) 03047 return ret; 03048 /* Once done with our message, deliver any pending events unless the 03049 requester doesn't want them as part of this response. 03050 */ 03051 if (ast_strlen_zero(astman_get_header(m, "SuppressEvents"))) { 03052 return process_events(s); 03053 } else { 03054 return ret; 03055 } 03056 }
| static void purge_events | ( | void | ) | [static] |
Purge unused events. Remove elements from the head as long as their usecount is 0 and there is a next element.
Definition at line 349 of file manager.c.
References ast_free, AST_LIST_FIRST, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and eventqent::usecount.
Referenced by purge_old_stuff().
00350 { 00351 struct eventqent *ev; 00352 00353 AST_LIST_LOCK(&all_events); 00354 while ( (ev = AST_LIST_FIRST(&all_events)) && 00355 ev->usecount == 0 && AST_LIST_NEXT(ev, eq_next)) { 00356 AST_LIST_REMOVE_HEAD(&all_events, eq_next); 00357 ast_free(ev); 00358 } 00359 AST_LIST_UNLOCK(&all_events); 00360 }
| static void purge_sessions | ( | int | n_max | ) | [static] |
remove at most n_max stale session from the list.
Definition at line 3246 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().
03247 { 03248 struct mansession_session *session; 03249 time_t now = time(NULL); 03250 03251 AST_LIST_LOCK(&sessions); 03252 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, session, list) { 03253 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) { 03254 AST_LIST_REMOVE_CURRENT(list); 03255 ast_atomic_fetchadd_int(&num_sessions, -1); 03256 if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) { 03257 ast_verb(2, "HTTP Manager '%s' timed out from %s\n", 03258 session->username, ast_inet_ntoa(session->sin.sin_addr)); 03259 } 03260 free_session(session); /* XXX outside ? */ 03261 if (--n_max <= 0) 03262 break; 03263 } 03264 } 03265 AST_LIST_TRAVERSE_SAFE_END; 03266 AST_LIST_UNLOCK(&sessions); 03267 }
| static void ref_event | ( | struct eventqent * | e | ) | [static] |
Definition at line 826 of file manager.c.
References ast_atomic_fetchadd_int(), and eventqent::usecount.
Referenced by action_waitevent(), and process_events().
00827 { 00828 ast_atomic_fetchadd_int(&e->usecount, 1); 00829 }
| 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 944 of file manager.c.
References ast_careful_fwrite(), mansession_session::f, mansession::f, mansession_session::fd, mansession::fd, mansession::session, and mansession_session::writetimeout.
Referenced by astman_append(), and process_events().
00945 { 00946 if (s->f) { 00947 return ast_careful_fwrite(s->f, s->fd, string, strlen(string), s->session->writetimeout); 00948 } else { 00949 return ast_careful_fwrite(s->session->f, s->session->fd, string, strlen(string), s->session->writetimeout); 00950 } 00951 }
| 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 3169 of file manager.c.
References mansession_session::__lock, AMI_VERSION, ao2_ref, ast_atomic_fetchadd_int(), ast_calloc, ast_inet_ntoa(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), AST_PTHREADT_NULL, ast_verb, astman_append(), mansession_session::authenticated, mansession_session::datastores, destroy_session(), do_message(), ast_tcptls_session_instance::f, mansession_session::f, mansession_session::fd, ast_tcptls_session_instance::fd, ast_frame::flags, grab_last(), mansession_session::last_ev, LOG_EVENT, manager_displayconnects(), ast_tcptls_session_instance::remote_address, s, mansession_session::send_events, mansession::session, mansession_session::sin, mansession_session::username, mansession_session::waiting_thread, and mansession_session::writetimeout.
03170 { 03171 struct ast_tcptls_session_instance *ser = data; 03172 struct mansession_session *session = ast_calloc(1, sizeof(*session)); 03173 struct mansession s = {.session = NULL, }; 03174 int flags; 03175 int res; 03176 03177 if (session == NULL) 03178 goto done; 03179 03180 session->writetimeout = 100; 03181 session->waiting_thread = AST_PTHREADT_NULL; 03182 03183 flags = fcntl(ser->fd, F_GETFL); 03184 if (!block_sockets) /* make sure socket is non-blocking */ 03185 flags |= O_NONBLOCK; 03186 else 03187 flags &= ~O_NONBLOCK; 03188 fcntl(ser->fd, F_SETFL, flags); 03189 03190 ast_mutex_init(&session->__lock); 03191 session->send_events = -1; 03192 /* Hook to the tail of the event queue */ 03193 session->last_ev = grab_last(); 03194 03195 /* these fields duplicate those in the 'ser' structure */ 03196 session->fd = ser->fd; 03197 session->f = ser->f; 03198 session->sin = ser->remote_address; 03199 s.session = session; 03200 03201 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores); 03202 03203 AST_LIST_LOCK(&sessions); 03204 AST_LIST_INSERT_HEAD(&sessions, session, list); 03205 ast_atomic_fetchadd_int(&num_sessions, 1); 03206 AST_LIST_UNLOCK(&sessions); 03207 03208 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */ 03209 for (;;) { 03210 if ((res = do_message(&s)) < 0) 03211 break; 03212 } 03213 /* session is over, explain why and terminate */ 03214 if (session->authenticated) { 03215 if (manager_displayconnects(session)) 03216 ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 03217 ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 03218 } else { 03219 if (displayconnects) 03220 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr)); 03221 ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(session->sin.sin_addr)); 03222 } 03223 03224 /* It is possible under certain circumstances for this session thread 03225 to complete its work and exit *before* the thread that created it 03226 has finished executing the ast_pthread_create_background() function. 03227 If this occurs, some versions of glibc appear to act in a buggy 03228 fashion and attempt to write data into memory that it thinks belongs 03229 to the thread but is in fact not owned by the thread (or may have 03230 been freed completely). 03231 03232 Causing this thread to yield to other threads at least one time 03233 appears to work around this bug. 03234 */ 03235 usleep(1); 03236 03237 destroy_session(session); 03238 03239 done: 03240 ao2_ref(ser, -1); 03241 ser = NULL; 03242 return NULL; 03243 }
| 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 1052 of file manager.c.
References mansession_session::__lock, ast_mutex_lock(), ast_mutex_unlock(), mansession_session::send_events, mansession::session, and strings_to_mask().
Referenced by action_events(), and authenticate().
01053 { 01054 int maskint = strings_to_mask(eventmask); 01055 01056 ast_mutex_lock(&s->session->__lock); 01057 if (maskint >= 0) 01058 s->session->send_events = maskint; 01059 ast_mutex_unlock(&s->session->__lock); 01060 01061 return maskint; 01062 }
| static int strings_to_mask | ( | const char * | string | ) | [static] |
A number returns itself, false returns 0, true returns all flags, other strings return the flags that are set.
Definition at line 449 of file manager.c.
References ARRAY_LEN, ast_false(), ast_strlen_zero(), ast_true(), get_perm(), num, and perms.
Referenced by set_eventmask().
00450 { 00451 const char *p; 00452 00453 if (ast_strlen_zero(string)) 00454 return -1; 00455 00456 for (p = string; *p; p++) 00457 if (*p < '0' || *p > '9') 00458 break; 00459 if (!*p) /* all digits */ 00460 return atoi(string); 00461 if (ast_false(string)) 00462 return 0; 00463 if (ast_true(string)) { /* all permissions */ 00464 int x, ret = 0; 00465 for (x = 0; x < ARRAY_LEN(perms); x++) 00466 ret |= perms[x].num; 00467 return ret; 00468 } 00469 return get_perm(string); 00470 }
Definition at line 820 of file manager.c.
References ast_atomic_fetchadd_int(), AST_LIST_NEXT, and eventqent::usecount.
Referenced by action_waitevent(), free_session(), and process_events().
00821 { 00822 ast_atomic_fetchadd_int(&e->usecount, -1); 00823 return AST_LIST_NEXT(e, eq_next); 00824 }
int allowmultiplelogin = 1 [static] |
struct ast_threadstorage astman_append_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_astman_append_buf , .custom_init = NULL , } [static] |
Definition at line 960 of file manager.c.
Referenced by astman_append().
int block_sockets [static] |
struct ast_cli_entry cli_manager[] [static] |
Definition at line 803 of file manager.c.
Referenced by __init_manager().
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] |
Definition at line 3296 of file manager.c.
Referenced by __manager_event().
char mandescr_atxfer[] [static] |
Definition at line 2159 of file manager.c.
Referenced by __init_manager().
char mandescr_command[] [static] |
"Description: Run a CLI command.\n" "Variables: (Names marked with * are required)\n" " *Command: Asterisk CLI command to run\n" " ActionID: Optional Action id for message matching.\n"
Definition at line 2251 of file manager.c.
Referenced by __init_manager().
char mandescr_coresettings[] [static] |
"Description: Query for Core PBX settings.\n" "Variables: (Names marked with * are optional)\n" " *ActionID: ActionID of this transaction\n"
Definition at line 2703 of file manager.c.
Referenced by __init_manager().
char mandescr_coreshowchannels[] [static] |
"Description: List currently defined channels and some information\n" " about them.\n" "Variables:\n" " ActionID: Optional Action id for message matching.\n"
Definition at line 2806 of file manager.c.
Referenced by __init_manager().
char mandescr_corestatus[] [static] |
"Description: Query for Core PBX status.\n" "Variables: (Names marked with * are optional)\n" " *ActionID: ActionID of this transaction\n"
Definition at line 2749 of file manager.c.
Referenced by __init_manager().
char mandescr_createconfig[] [static] |
Definition at line 1558 of file manager.c.
Referenced by __init_manager().
char mandescr_events[] [static] |
Definition at line 1707 of file manager.c.
Referenced by __init_manager().
char mandescr_extensionstate[] [static] |
Definition at line 2579 of file manager.c.
Referenced by __init_manager().
char mandescr_getconfig[] [static] |
Definition at line 1149 of file manager.c.
Referenced by __init_manager().
char mandescr_getconfigjson[] [static] |
Definition at line 1250 of file manager.c.
Referenced by __init_manager().
char mandescr_getvar[] [static] |
Definition at line 1840 of file manager.c.
Referenced by __init_manager().
char mandescr_hangup[] [static] |
"Description: Hangup a channel\n" "Variables: \n" " Channel: The channel name to be hungup\n"
Definition at line 1772 of file manager.c.
Referenced by __init_manager().
char mandescr_listcategories[] [static] |
"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 1198 of file manager.c.
Referenced by __init_manager().
char mandescr_listcommands[] [static] |
"Description: Returns the action name and synopsis for every\n" " action that is available to the user\n" "Variables: NONE\n"
Definition at line 1685 of file manager.c.
Referenced by __init_manager().
char mandescr_logoff[] [static] |
"Description: Logoff this manager session\n" "Variables: NONE\n"
Definition at line 1730 of file manager.c.
Referenced by __init_manager().
char mandescr_mailboxcount[] [static] |
Definition at line 2546 of file manager.c.
Referenced by __init_manager().
char mandescr_mailboxstatus[] [static] |
Help text for manager command mailboxstatus.
Definition at line 2518 of file manager.c.
Referenced by __init_manager().
char mandescr_modulecheck[] [static] |
Definition at line 2875 of file manager.c.
Referenced by __init_manager().
char mandescr_moduleload[] [static] |
Definition at line 2927 of file manager.c.
Referenced by __init_manager().
char mandescr_originate[] [static] |
Definition at line 2376 of file manager.c.
Referenced by __init_manager().
char mandescr_ping[] [static] |
"Description: A 'Ping' action will ellicit a 'Pong' response. Used to keep the\n" " manager connection open.\n" "Variables: NONE\n"
Manager PING.
Definition at line 1132 of file manager.c.
Referenced by __init_manager().
char mandescr_redirect[] [static] |
Definition at line 2073 of file manager.c.
Referenced by __init_manager().
char mandescr_reload[] [static] |
"Description: Send a reload event.\n" "Variables: (Names marked with * are optional)\n" " *ActionID: ActionID of this transaction\n" " *Module: Name of the module to reload\n"
Definition at line 2787 of file manager.c.
Referenced by __init_manager().
char mandescr_sendtext[] [static] |
Definition at line 2032 of file manager.c.
Referenced by __init_manager().
char mandescr_setvar[] [static] |
Definition at line 1796 of file manager.c.
Referenced by __init_manager().
char mandescr_status[] [static] |
Definition at line 1892 of file manager.c.
Referenced by __init_manager().
char mandescr_timeout[] [static] |
Definition at line 2614 of file manager.c.
Referenced by __init_manager().
char mandescr_updateconfig[] [static] |
Definition at line 1467 of file manager.c.
Referenced by __init_manager().
char mandescr_userevent[] [static] |
Definition at line 2677 of file manager.c.
Referenced by __init_manager().
char mandescr_waitevent[] [static] |
int num_sessions [static] |
helper functions to convert back and forth between string and numeric representation of set of flags
Referenced by authority_to_str(), get_perm(), and strings_to_mask().
int timestampevents [static] |
struct ast_threadstorage userevent_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_userevent_buf , .custom_init = NULL , } [static] |
Definition at line 961 of file manager.c.
Referenced by action_userevent().
int webmanager_enabled = 0 [static] |
1.6.2