callback to display queues status in manager More...
Data Structures | |
| 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 | mansession |
| struct | mansession_session |
| struct | permalias |
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) |
| 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) |
| static | AST_LIST_HEAD_STATIC (sessions, mansession_session) |
| static | AST_LIST_HEAD_STATIC (all_events, eventqent) |
| int | ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), const char *synopsis, const char *description) |
| register a new command with manager, including online help. This is the preferred way to register a manager command | |
| void | ast_manager_register_hook (struct manager_custom_hook *hook) |
| Add a custom hook to be called when an event is fired. | |
| static int | ast_manager_register_struct (struct manager_action *act) |
| int | ast_manager_unregister (char *action) |
| 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. | |
| static | AST_RWLIST_HEAD_STATIC (manager_hooks, manager_custom_hook) |
| list of hooks registered | |
| static | AST_RWLIST_HEAD_STATIC (actions, manager_action) |
| list of actions registered | |
| static | AST_RWLIST_HEAD_STATIC (users, ast_manager_user) |
| list of users found in the config file | |
| AST_THREADSTORAGE (manager_event_buf) | |
| AST_THREADSTORAGE (userevent_buf) | |
| AST_THREADSTORAGE (astman_append_buf) | |
| thread local buffer for astman_append | |
| 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 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 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 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 3272 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 }
| 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 3275 of file manager.c.
References mansession_session::__lock, append_event(), ast_atomic_fetchadd_int(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_append_va(), ast_str_set(), ast_str_thread_get(), ast_tvnow(), authority_to_str(), buf, manager_custom_hook::helper, MANAGER_EVENT_BUF_INITSIZE, mansession_session::pending_event, eventqent::seq, ast_str::str, and mansession_session::waiting_thread.
03277 { 03278 struct mansession_session *session; 03279 struct manager_custom_hook *hook; 03280 struct ast_str *auth = ast_str_alloca(80); 03281 const char *cat_str; 03282 va_list ap; 03283 struct timeval now; 03284 struct ast_str *buf; 03285 03286 /* Abort if there are neither any manager sessions nor hooks */ 03287 if (!num_sessions && AST_RWLIST_EMPTY(&manager_hooks)) 03288 return 0; 03289 03290 if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) 03291 return -1; 03292 03293 cat_str = authority_to_str(category, &auth); 03294 ast_str_set(&buf, 0, 03295 "Event: %s\r\nPrivilege: %s\r\n", 03296 event, cat_str); 03297 03298 if (timestampevents) { 03299 now = ast_tvnow(); 03300 ast_str_append(&buf, 0, 03301 "Timestamp: %ld.%06lu\r\n", 03302 (long)now.tv_sec, (unsigned long) now.tv_usec); 03303 } 03304 if (manager_debug) { 03305 static int seq; 03306 ast_str_append(&buf, 0, 03307 "SequenceNumber: %d\r\n", 03308 ast_atomic_fetchadd_int(&seq, 1)); 03309 ast_str_append(&buf, 0, 03310 "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func); 03311 } 03312 03313 va_start(ap, fmt); 03314 ast_str_append_va(&buf, 0, fmt, ap); 03315 va_end(ap); 03316 03317 ast_str_append(&buf, 0, "\r\n"); 03318 03319 append_event(buf->str, category); 03320 03321 /* Wake up any sleeping sessions */ 03322 if (num_sessions) { 03323 AST_LIST_LOCK(&sessions); 03324 AST_LIST_TRAVERSE(&sessions, session, list) { 03325 ast_mutex_lock(&session->__lock); 03326 if (session->waiting_thread != AST_PTHREADT_NULL) 03327 pthread_kill(session->waiting_thread, SIGURG); 03328 else 03329 /* We have an event to process, but the mansession is 03330 * not waiting for it. We still need to indicate that there 03331 * is an event waiting so that get_input processes the pending 03332 * event instead of polling. 03333 */ 03334 session->pending_event = 1; 03335 ast_mutex_unlock(&session->__lock); 03336 } 03337 AST_LIST_UNLOCK(&sessions); 03338 } 03339 03340 if (!AST_RWLIST_EMPTY(&manager_hooks)) { 03341 AST_RWLIST_RDLOCK(&manager_hooks); 03342 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) { 03343 hook->helper(category, event, buf->str); 03344 } 03345 AST_RWLIST_UNLOCK(&manager_hooks); 03346 } 03347 03348 return 0; 03349 }
| static int action_atxfer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2150 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().
02151 { 02152 const char *name = astman_get_header(m, "Channel"); 02153 const char *exten = astman_get_header(m, "Exten"); 02154 const char *context = astman_get_header(m, "Context"); 02155 struct ast_channel *chan = NULL; 02156 struct ast_call_feature *atxfer_feature = NULL; 02157 char *feature_code = NULL; 02158 02159 if (ast_strlen_zero(name)) { 02160 astman_send_error(s, m, "No channel specified"); 02161 return 0; 02162 } 02163 if (ast_strlen_zero(exten)) { 02164 astman_send_error(s, m, "No extension specified"); 02165 return 0; 02166 } 02167 02168 if (!(atxfer_feature = ast_find_call_feature("atxfer"))) { 02169 astman_send_error(s, m, "No attended transfer feature found"); 02170 return 0; 02171 } 02172 02173 if (!(chan = ast_get_channel_by_name_locked(name))) { 02174 astman_send_error(s, m, "Channel specified does not exist"); 02175 return 0; 02176 } 02177 02178 if (!ast_strlen_zero(context)) { 02179 pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context); 02180 } 02181 02182 for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) { 02183 struct ast_frame f = {AST_FRAME_DTMF, *feature_code}; 02184 ast_queue_frame(chan, &f); 02185 } 02186 02187 for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) { 02188 struct ast_frame f = {AST_FRAME_DTMF, *feature_code}; 02189 ast_queue_frame(chan, &f); 02190 } 02191 02192 astman_send_ack(s, m, "Atxfer successfully queued"); 02193 ast_channel_unlock(chan); 02194 02195 return 0; 02196 }
| static int action_challenge | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1737 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().
01738 { 01739 const char *authtype = astman_get_header(m, "AuthType"); 01740 01741 if (!strcasecmp(authtype, "MD5")) { 01742 if (ast_strlen_zero(s->session->challenge)) 01743 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random()); 01744 ast_mutex_lock(&s->session->__lock); 01745 astman_start_ack(s, m); 01746 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge); 01747 ast_mutex_unlock(&s->session->__lock); 01748 } else { 01749 astman_send_error(s, m, "Must specify AuthType"); 01750 } 01751 return 0; 01752 }
| static int action_command | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Manager command "command" - execute CLI command.
Definition at line 2240 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().
02241 { 02242 const char *cmd = astman_get_header(m, "Command"); 02243 const char *id = astman_get_header(m, "ActionID"); 02244 char *buf, *final_buf; 02245 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 02246 int fd; 02247 off_t l; 02248 02249 if (ast_strlen_zero(cmd)) { 02250 astman_send_error(s, m, "No command provided"); 02251 return 0; 02252 } 02253 02254 if (check_blacklist(cmd)) { 02255 astman_send_error(s, m, "Command blacklisted"); 02256 return 0; 02257 } 02258 02259 fd = mkstemp(template); 02260 02261 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 02262 if (!ast_strlen_zero(id)) 02263 astman_append(s, "ActionID: %s\r\n", id); 02264 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 02265 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 02266 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 02267 02268 /* This has a potential to overflow the stack. Hence, use the heap. */ 02269 buf = ast_calloc(1, l + 1); 02270 final_buf = ast_calloc(1, l + 1); 02271 if (buf) { 02272 lseek(fd, 0, SEEK_SET); 02273 if (read(fd, buf, l) < 0) { 02274 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 02275 } 02276 buf[l] = '\0'; 02277 if (final_buf) { 02278 term_strip(final_buf, buf, l); 02279 final_buf[l] = '\0'; 02280 } 02281 astman_append(s, "%s", S_OR(final_buf, buf)); 02282 ast_free(buf); 02283 } 02284 close(fd); 02285 unlink(template); 02286 astman_append(s, "--END COMMAND--\r\n\r\n"); 02287 if (final_buf) 02288 ast_free(final_buf); 02289 return 0; 02290 }
| static int action_coresettings | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show PBX core settings information.
Definition at line 2691 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().
02692 { 02693 const char *actionid = astman_get_header(m, "ActionID"); 02694 char idText[150]; 02695 02696 if (!ast_strlen_zero(actionid)) 02697 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02698 else 02699 idText[0] = '\0'; 02700 02701 astman_append(s, "Response: Success\r\n" 02702 "%s" 02703 "AMIversion: %s\r\n" 02704 "AsteriskVersion: %s\r\n" 02705 "SystemName: %s\r\n" 02706 "CoreMaxCalls: %d\r\n" 02707 "CoreMaxLoadAvg: %f\r\n" 02708 "CoreRunUser: %s\r\n" 02709 "CoreRunGroup: %s\r\n" 02710 "CoreMaxFilehandles: %d\r\n" 02711 "CoreRealTimeEnabled: %s\r\n" 02712 "CoreCDRenabled: %s\r\n" 02713 "CoreHTTPenabled: %s\r\n" 02714 "\r\n", 02715 idText, 02716 AMI_VERSION, 02717 ast_get_version(), 02718 ast_config_AST_SYSTEM_NAME, 02719 option_maxcalls, 02720 option_maxload, 02721 ast_config_AST_RUN_USER, 02722 ast_config_AST_RUN_GROUP, 02723 option_maxfiles, 02724 ast_realtime_enabled() ? "Yes" : "No", 02725 check_cdr_enabled() ? "Yes" : "No", 02726 check_webmanager_enabled() ? "Yes" : "No" 02727 ); 02728 return 0; 02729 }
| 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 2796 of file manager.c.
References ast_channel::_state, 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::priority, S_OR, and ast_cdr::start.
Referenced by __init_manager().
02797 { 02798 const char *actionid = astman_get_header(m, "ActionID"); 02799 char actionidtext[256]; 02800 struct ast_channel *c = NULL; 02801 int numchans = 0; 02802 int duration, durh, durm, durs; 02803 02804 if (!ast_strlen_zero(actionid)) 02805 snprintf(actionidtext, sizeof(actionidtext), "ActionID: %s\r\n", actionid); 02806 else 02807 actionidtext[0] = '\0'; 02808 02809 astman_send_listack(s, m, "Channels will follow", "start"); 02810 02811 while ((c = ast_channel_walk_locked(c)) != NULL) { 02812 struct ast_channel *bc = ast_bridged_channel(c); 02813 char durbuf[10] = ""; 02814 02815 if (c->cdr && !ast_tvzero(c->cdr->start)) { 02816 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 02817 durh = duration / 3600; 02818 durm = (duration % 3600) / 60; 02819 durs = duration % 60; 02820 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 02821 } 02822 02823 astman_append(s, 02824 "Event: CoreShowChannel\r\n" 02825 "Channel: %s\r\n" 02826 "UniqueID: %s\r\n" 02827 "Context: %s\r\n" 02828 "Extension: %s\r\n" 02829 "Priority: %d\r\n" 02830 "ChannelState: %d\r\n" 02831 "ChannelStateDesc: %s\r\n" 02832 "Application: %s\r\n" 02833 "ApplicationData: %s\r\n" 02834 "CallerIDnum: %s\r\n" 02835 "Duration: %s\r\n" 02836 "AccountCode: %s\r\n" 02837 "BridgedChannel: %s\r\n" 02838 "BridgedUniqueID: %s\r\n" 02839 "\r\n", c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, ast_state2str(c->_state), 02840 c->appl ? c->appl : "", c->data ? S_OR(c->data, ""): "", 02841 S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : ""); 02842 ast_channel_unlock(c); 02843 numchans++; 02844 } 02845 02846 astman_append(s, 02847 "Event: CoreShowChannelsComplete\r\n" 02848 "EventList: Complete\r\n" 02849 "ListItems: %d\r\n" 02850 "%s" 02851 "\r\n", numchans, actionidtext); 02852 02853 return 0; 02854 }
| static int action_corestatus | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show PBX core status information.
Definition at line 2737 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().
02738 { 02739 const char *actionid = astman_get_header(m, "ActionID"); 02740 char idText[150]; 02741 char startuptime[150]; 02742 char reloadtime[150]; 02743 struct ast_tm tm; 02744 02745 if (!ast_strlen_zero(actionid)) 02746 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02747 else 02748 idText[0] = '\0'; 02749 02750 ast_localtime(&ast_startuptime, &tm, NULL); 02751 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm); 02752 ast_localtime(&ast_lastreloadtime, &tm, NULL); 02753 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm); 02754 02755 astman_append(s, "Response: Success\r\n" 02756 "%s" 02757 "CoreStartupTime: %s\r\n" 02758 "CoreReloadTime: %s\r\n" 02759 "CoreCurrentCalls: %d\r\n" 02760 "\r\n", 02761 idText, 02762 startuptime, 02763 reloadtime, 02764 ast_active_channels() 02765 ); 02766 return 0; 02767 }
| static int action_createconfig | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1548 of file manager.c.
References ast_config_AST_CONFIG_DIR, AST_FILE_MODE, ast_str_alloca, ast_str_append(), ast_str_set(), astman_get_header(), astman_send_ack(), astman_send_error(), errno, and ast_str::str.
Referenced by __init_manager().
01549 { 01550 int fd; 01551 const char *fn = astman_get_header(m, "Filename"); 01552 struct ast_str *filepath = ast_str_alloca(PATH_MAX); 01553 ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR); 01554 ast_str_append(&filepath, 0, "%s", fn); 01555 01556 if ((fd = open(filepath->str, O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) { 01557 close(fd); 01558 astman_send_ack(s, m, "New configuration file created successfully"); 01559 } else 01560 astman_send_error(s, m, strerror(errno)); 01561 01562 return 0; 01563 }
| static int action_events | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1697 of file manager.c.
References astman_append(), astman_get_header(), and set_eventmask().
Referenced by __init_manager().
01698 { 01699 const char *mask = astman_get_header(m, "EventMask"); 01700 int res; 01701 01702 res = set_eventmask(s, mask); 01703 if (res > 0) 01704 astman_append(s, "Response: Success\r\n" 01705 "Events: On\r\n\r\n"); 01706 else if (res == 0) 01707 astman_append(s, "Response: Success\r\n" 01708 "Events: Off\r\n\r\n"); 01709 return 0; 01710 }
| static int action_extensionstate | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2572 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().
02573 { 02574 const char *exten = astman_get_header(m, "Exten"); 02575 const char *context = astman_get_header(m, "Context"); 02576 char hint[256] = ""; 02577 int status; 02578 if (ast_strlen_zero(exten)) { 02579 astman_send_error(s, m, "Extension not specified"); 02580 return 0; 02581 } 02582 if (ast_strlen_zero(context)) 02583 context = "default"; 02584 status = ast_extension_state(NULL, context, exten); 02585 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 02586 astman_start_ack(s, m); 02587 astman_append(s, "Message: Extension Status\r\n" 02588 "Exten: %s\r\n" 02589 "Context: %s\r\n" 02590 "Hint: %s\r\n" 02591 "Status: %d\r\n\r\n", 02592 exten, context, hint, status); 02593 return 0; 02594 }
| static int action_getconfig | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1152 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, ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by __init_manager().
01153 { 01154 struct ast_config *cfg; 01155 const char *fn = astman_get_header(m, "Filename"); 01156 const char *category = astman_get_header(m, "Category"); 01157 int catcount = 0; 01158 int lineno = 0; 01159 char *cur_category = NULL; 01160 struct ast_variable *v; 01161 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01162 01163 if (ast_strlen_zero(fn)) { 01164 astman_send_error(s, m, "Filename not specified"); 01165 return 0; 01166 } 01167 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 01168 astman_send_error(s, m, "Config file not found"); 01169 return 0; 01170 } 01171 01172 astman_start_ack(s, m); 01173 while ((cur_category = ast_category_browse(cfg, cur_category))) { 01174 if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) { 01175 lineno = 0; 01176 astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category); 01177 for (v = ast_variable_browse(cfg, cur_category); v; v = v->next) 01178 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 01179 catcount++; 01180 } 01181 } 01182 if (!ast_strlen_zero(category) && catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */ 01183 astman_append(s, "No categories found\r\n"); 01184 ast_config_destroy(cfg); 01185 astman_append(s, "\r\n"); 01186 01187 return 0; 01188 }
| static int action_getconfigjson | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1246 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, json_escape(), ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by __init_manager().
01247 { 01248 struct ast_config *cfg; 01249 const char *fn = astman_get_header(m, "Filename"); 01250 char *category = NULL; 01251 struct ast_variable *v; 01252 int comma1 = 0; 01253 char *buf = NULL; 01254 unsigned int buf_len = 0; 01255 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01256 01257 if (ast_strlen_zero(fn)) { 01258 astman_send_error(s, m, "Filename not specified"); 01259 return 0; 01260 } 01261 01262 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 01263 astman_send_error(s, m, "Config file not found"); 01264 return 0; 01265 } 01266 01267 buf_len = 512; 01268 buf = alloca(buf_len); 01269 01270 astman_start_ack(s, m); 01271 astman_append(s, "JSON: {"); 01272 while ((category = ast_category_browse(cfg, category))) { 01273 int comma2 = 0; 01274 if (buf_len < 2 * strlen(category) + 1) { 01275 buf_len *= 2; 01276 buf = alloca(buf_len); 01277 } 01278 json_escape(buf, category); 01279 astman_append(s, "%s\"%s\":[", comma1 ? "," : "", buf); 01280 if (!comma1) 01281 comma1 = 1; 01282 for (v = ast_variable_browse(cfg, category); v; v = v->next) { 01283 if (comma2) 01284 astman_append(s, ","); 01285 if (buf_len < 2 * strlen(v->name) + 1) { 01286 buf_len *= 2; 01287 buf = alloca(buf_len); 01288 } 01289 json_escape(buf, v->name); 01290 astman_append(s, "\"%s", buf); 01291 if (buf_len < 2 * strlen(v->value) + 1) { 01292 buf_len *= 2; 01293 buf = alloca(buf_len); 01294 } 01295 json_escape(buf, v->value); 01296 astman_append(s, "%s\"", buf); 01297 if (!comma2) 01298 comma2 = 1; 01299 } 01300 astman_append(s, "]"); 01301 } 01302 astman_append(s, "}\r\n\r\n"); 01303 01304 ast_config_destroy(cfg); 01305 01306 return 0; 01307 }
| static int action_getvar | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1829 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().
01830 { 01831 struct ast_channel *c = NULL; 01832 const char *name = astman_get_header(m, "Channel"); 01833 const char *varname = astman_get_header(m, "Variable"); 01834 char *varval; 01835 char workspace[1024] = ""; 01836 01837 if (ast_strlen_zero(varname)) { 01838 astman_send_error(s, m, "No variable specified"); 01839 return 0; 01840 } 01841 01842 if (!ast_strlen_zero(name)) { 01843 c = ast_get_channel_by_name_locked(name); 01844 if (!c) { 01845 astman_send_error(s, m, "No such channel"); 01846 return 0; 01847 } 01848 } 01849 01850 if (varname[strlen(varname) - 1] == ')') { 01851 if (!c) { 01852 c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/manager"); 01853 if (c) { 01854 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01855 ast_channel_free(c); 01856 c = NULL; 01857 } else 01858 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n"); 01859 } else 01860 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01861 varval = workspace; 01862 } else { 01863 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 01864 } 01865 01866 if (c) 01867 ast_channel_unlock(c); 01868 astman_start_ack(s, m); 01869 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, varval); 01870 01871 return 0; 01872 }
| static int action_hangup | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1759 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().
01760 { 01761 struct ast_channel *c = NULL; 01762 const char *name = astman_get_header(m, "Channel"); 01763 if (ast_strlen_zero(name)) { 01764 astman_send_error(s, m, "No channel specified"); 01765 return 0; 01766 } 01767 c = ast_get_channel_by_name_locked(name); 01768 if (!c) { 01769 astman_send_error(s, m, "No such channel"); 01770 return 0; 01771 } 01772 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01773 ast_channel_unlock(c); 01774 astman_send_ack(s, m, "Channel Hungup"); 01775 return 0; 01776 }
| static int action_listcategories | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1196 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, and CONFIG_FLAG_WITHCOMMENTS.
Referenced by __init_manager().
01197 { 01198 struct ast_config *cfg; 01199 const char *fn = astman_get_header(m, "Filename"); 01200 char *category = NULL; 01201 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01202 int catcount = 0; 01203 01204 if (ast_strlen_zero(fn)) { 01205 astman_send_error(s, m, "Filename not specified"); 01206 return 0; 01207 } 01208 if (!(cfg = ast_config_load2(fn, "manager", config_flags))) { 01209 astman_send_error(s, m, "Config file not found or file has invalid syntax"); 01210 return 0; 01211 } 01212 astman_start_ack(s, m); 01213 while ((category = ast_category_browse(cfg, category))) { 01214 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 01215 catcount++; 01216 } 01217 if (catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */ 01218 astman_append(s, "Error: no categories found\r\n"); 01219 ast_config_destroy(cfg); 01220 astman_append(s, "\r\n"); 01221 01222 return 0; 01223 }
| static int action_listcommands | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1673 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().
01674 { 01675 struct manager_action *cur; 01676 struct ast_str *temp = ast_str_alloca(BUFSIZ); /* XXX very large ? */ 01677 01678 astman_start_ack(s, m); 01679 AST_RWLIST_TRAVERSE(&actions, cur, list) { 01680 if (s->session->writeperm & cur->authority || cur->authority == 0) 01681 astman_append(s, "%s: %s (Priv: %s)\r\n", 01682 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp)); 01683 } 01684 astman_append(s, "\r\n"); 01685 01686 return 0; 01687 }
| static int action_login | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1722 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().
01723 { 01724 if (authenticate(s, m)) { 01725 sleep(1); 01726 astman_send_error(s, m, "Authentication failed"); 01727 return -1; 01728 } 01729 s->session->authenticated = 1; 01730 if (manager_displayconnects(s->session)) 01731 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)); 01732 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)); 01733 astman_send_ack(s, m, "Authentication accepted"); 01734 return 0; 01735 }
| static int action_logoff | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1716 of file manager.c.
References astman_send_response().
Referenced by __init_manager().
01717 { 01718 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 01719 return -1; 01720 }
| static int action_mailboxcount | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2540 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().
02541 { 02542 const char *mailbox = astman_get_header(m, "Mailbox"); 02543 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;; 02544 02545 if (ast_strlen_zero(mailbox)) { 02546 astman_send_error(s, m, "Mailbox not specified"); 02547 return 0; 02548 } 02549 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs); 02550 astman_start_ack(s, m); 02551 astman_append(s, "Message: Mailbox Message Count\r\n" 02552 "Mailbox: %s\r\n" 02553 "UrgMessages: %d\r\n" 02554 "NewMessages: %d\r\n" 02555 "OldMessages: %d\r\n" 02556 "\r\n", 02557 mailbox, urgentmsgs, newmsgs, oldmsgs); 02558 return 0; 02559 }
| static int action_mailboxstatus | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2511 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().
02512 { 02513 const char *mailbox = astman_get_header(m, "Mailbox"); 02514 int ret; 02515 02516 if (ast_strlen_zero(mailbox)) { 02517 astman_send_error(s, m, "Mailbox not specified"); 02518 return 0; 02519 } 02520 ret = ast_app_has_voicemail(mailbox, NULL); 02521 astman_start_ack(s, m); 02522 astman_append(s, "Message: Mailbox Status\r\n" 02523 "Mailbox: %s\r\n" 02524 "Waiting: %d\r\n\r\n", mailbox, ret); 02525 return 0; 02526 }
| static int action_originate | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2374 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, strcasestr(), fast_originate_helper::tech, fast_originate_helper::timeout, fast_originate_helper::vars, and mansession_session::writeperm.
Referenced by __init_manager().
02375 { 02376 const char *name = astman_get_header(m, "Channel"); 02377 const char *exten = astman_get_header(m, "Exten"); 02378 const char *context = astman_get_header(m, "Context"); 02379 const char *priority = astman_get_header(m, "Priority"); 02380 const char *timeout = astman_get_header(m, "Timeout"); 02381 const char *callerid = astman_get_header(m, "CallerID"); 02382 const char *account = astman_get_header(m, "Account"); 02383 const char *app = astman_get_header(m, "Application"); 02384 const char *appdata = astman_get_header(m, "Data"); 02385 const char *async = astman_get_header(m, "Async"); 02386 const char *id = astman_get_header(m, "ActionID"); 02387 const char *codecs = astman_get_header(m, "Codecs"); 02388 struct ast_variable *vars = astman_get_variables(m); 02389 char *tech, *data; 02390 char *l = NULL, *n = NULL; 02391 int pi = 0; 02392 int res; 02393 int to = 30000; 02394 int reason = 0; 02395 char tmp[256]; 02396 char tmp2[256]; 02397 int format = AST_FORMAT_SLINEAR; 02398 02399 pthread_t th; 02400 if (ast_strlen_zero(name)) { 02401 astman_send_error(s, m, "Channel not specified"); 02402 return 0; 02403 } 02404 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 02405 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 02406 astman_send_error(s, m, "Invalid priority"); 02407 return 0; 02408 } 02409 } 02410 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) { 02411 astman_send_error(s, m, "Invalid timeout"); 02412 return 0; 02413 } 02414 ast_copy_string(tmp, name, sizeof(tmp)); 02415 tech = tmp; 02416 data = strchr(tmp, '/'); 02417 if (!data) { 02418 astman_send_error(s, m, "Invalid channel"); 02419 return 0; 02420 } 02421 *data++ = '\0'; 02422 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 02423 ast_callerid_parse(tmp2, &n, &l); 02424 if (n) { 02425 if (ast_strlen_zero(n)) 02426 n = NULL; 02427 } 02428 if (l) { 02429 ast_shrink_phone_number(l); 02430 if (ast_strlen_zero(l)) 02431 l = NULL; 02432 } 02433 if (!ast_strlen_zero(codecs)) { 02434 format = 0; 02435 ast_parse_allow_disallow(NULL, &format, codecs, 1); 02436 } 02437 if (ast_true(async)) { 02438 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 02439 if (!fast) { 02440 res = -1; 02441 } else { 02442 if (!ast_strlen_zero(id)) 02443 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s", id); 02444 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 02445 ast_copy_string(fast->data, data, sizeof(fast->data)); 02446 ast_copy_string(fast->app, app, sizeof(fast->app)); 02447 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 02448 if (l) 02449 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 02450 if (n) 02451 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 02452 fast->vars = vars; 02453 ast_copy_string(fast->context, context, sizeof(fast->context)); 02454 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 02455 ast_copy_string(fast->account, account, sizeof(fast->account)); 02456 fast->format = format; 02457 fast->timeout = to; 02458 fast->priority = pi; 02459 if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) { 02460 ast_free(fast); 02461 res = -1; 02462 } else { 02463 res = 0; 02464 } 02465 } 02466 } else if (!ast_strlen_zero(app)) { 02467 /* To run the System application (or anything else that goes to shell), you must have the additional System privilege */ 02468 if (!(s->session->writeperm & EVENT_FLAG_SYSTEM) 02469 && ( 02470 strcasestr(app, "system") == 0 || /* System(rm -rf /) 02471 TrySystem(rm -rf /) */ 02472 strcasestr(app, "exec") || /* Exec(System(rm -rf /)) 02473 TryExec(System(rm -rf /)) */ 02474 strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /) 02475 EAGI(/bin/rm,-rf /) */ 02476 strstr(appdata, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */ 02477 strstr(appdata, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */ 02478 )) { 02479 astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have."); 02480 return 0; 02481 } 02482 res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 02483 } else { 02484 if (exten && context && pi) 02485 res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 02486 else { 02487 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 02488 return 0; 02489 } 02490 } 02491 if (!res) 02492 astman_send_ack(s, m, "Originate successfully queued"); 02493 else 02494 astman_send_error(s, m, "Originate failed"); 02495 return 0; 02496 }
| static int action_ping | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1137 of file manager.c.
References astman_append().
Referenced by __init_manager().
01138 { 01139 astman_append(s, "Response: Success\r\n" 01140 "Ping: Pong\r\n" 01141 "\r\n"); 01142 return 0; 01143 }
| static int action_redirect | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
action_redirect: The redirect manager command
Definition at line 2066 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().
02067 { 02068 const char *name = astman_get_header(m, "Channel"); 02069 const char *name2 = astman_get_header(m, "ExtraChannel"); 02070 const char *exten = astman_get_header(m, "Exten"); 02071 const char *context = astman_get_header(m, "Context"); 02072 const char *priority = astman_get_header(m, "Priority"); 02073 struct ast_channel *chan, *chan2 = NULL; 02074 int pi = 0; 02075 int res; 02076 02077 if (ast_strlen_zero(name)) { 02078 astman_send_error(s, m, "Channel not specified"); 02079 return 0; 02080 } 02081 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 02082 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 02083 astman_send_error(s, m, "Invalid priority"); 02084 return 0; 02085 } 02086 } 02087 /* XXX watch out, possible deadlock - we are trying to get two channels!!! */ 02088 chan = ast_get_channel_by_name_locked(name); 02089 if (!chan) { 02090 char buf[256]; 02091 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 02092 astman_send_error(s, m, buf); 02093 return 0; 02094 } 02095 if (ast_check_hangup(chan)) { 02096 astman_send_error(s, m, "Redirect failed, channel not up."); 02097 ast_channel_unlock(chan); 02098 return 0; 02099 } 02100 if (!ast_strlen_zero(name2)) 02101 chan2 = ast_get_channel_by_name_locked(name2); 02102 if (chan2 && ast_check_hangup(chan2)) { 02103 astman_send_error(s, m, "Redirect failed, extra channel not up."); 02104 ast_channel_unlock(chan); 02105 ast_channel_unlock(chan2); 02106 return 0; 02107 } 02108 if (chan->pbx) { 02109 ast_channel_lock(chan); 02110 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 02111 ast_channel_unlock(chan); 02112 } 02113 res = ast_async_goto(chan, context, exten, pi); 02114 if (!res) { 02115 if (!ast_strlen_zero(name2)) { 02116 if (chan2) { 02117 if (chan2->pbx) { 02118 ast_channel_lock(chan2); 02119 ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 02120 ast_channel_unlock(chan2); 02121 } 02122 res = ast_async_goto(chan2, context, exten, pi); 02123 } else { 02124 res = -1; 02125 } 02126 if (!res) 02127 astman_send_ack(s, m, "Dual Redirect successful"); 02128 else 02129 astman_send_error(s, m, "Secondary redirect failed"); 02130 } else 02131 astman_send_ack(s, m, "Redirect successful"); 02132 } else 02133 astman_send_error(s, m, "Redirect failed"); 02134 if (chan) 02135 ast_channel_unlock(chan); 02136 if (chan2) 02137 ast_channel_unlock(chan2); 02138 return 0; 02139 }
| static int action_reload | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Send a reload event.
Definition at line 2776 of file manager.c.
References ast_module_reload(), astman_get_header(), astman_send_ack(), astman_send_error(), and S_OR.
Referenced by __init_manager().
02777 { 02778 const char *module = astman_get_header(m, "Module"); 02779 int res = ast_module_reload(S_OR(module, NULL)); 02780 02781 if (res == 2) 02782 astman_send_ack(s, m, "Module Reloaded"); 02783 else 02784 astman_send_error(s, m, s == 0 ? "No such module" : "Module does not support reload"); 02785 return 0; 02786 }
| static int action_sendtext | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2021 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().
02022 { 02023 struct ast_channel *c = NULL; 02024 const char *name = astman_get_header(m, "Channel"); 02025 const char *textmsg = astman_get_header(m, "Message"); 02026 int res = 0; 02027 02028 if (ast_strlen_zero(name)) { 02029 astman_send_error(s, m, "No channel specified"); 02030 return 0; 02031 } 02032 02033 if (ast_strlen_zero(textmsg)) { 02034 astman_send_error(s, m, "No Message specified"); 02035 return 0; 02036 } 02037 02038 c = ast_get_channel_by_name_locked(name); 02039 if (!c) { 02040 astman_send_error(s, m, "No such channel"); 02041 return 0; 02042 } 02043 02044 res = ast_sendtext(c, textmsg); 02045 ast_channel_unlock(c); 02046 02047 if (res > 0) 02048 astman_send_ack(s, m, "Success"); 02049 else 02050 astman_send_error(s, m, "Failure"); 02051 02052 return res; 02053 }
| static int action_setvar | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1785 of file manager.c.
References ast_channel_unlock, ast_func_write(), ast_get_channel_by_name_locked(), ast_strdupa, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, pbx_builtin_setvar_helper(), and S_OR.
Referenced by __init_manager().
01786 { 01787 struct ast_channel *c = NULL; 01788 const char *name = astman_get_header(m, "Channel"); 01789 const char *varname = astman_get_header(m, "Variable"); 01790 const char *varval = astman_get_header(m, "Value"); 01791 int res = 0; 01792 01793 if (ast_strlen_zero(varname)) { 01794 astman_send_error(s, m, "No variable specified"); 01795 return 0; 01796 } 01797 01798 if (!ast_strlen_zero(name)) { 01799 c = ast_get_channel_by_name_locked(name); 01800 if (!c) { 01801 astman_send_error(s, m, "No such channel"); 01802 return 0; 01803 } 01804 } 01805 if (varname[strlen(varname)-1] == ')') { 01806 char *function = ast_strdupa(varname); 01807 res = ast_func_write(c, function, varval); 01808 } else { 01809 pbx_builtin_setvar_helper(c, varname, S_OR(varval, "")); 01810 } 01811 01812 if (c) 01813 ast_channel_unlock(c); 01814 if (res == 0) { 01815 astman_send_ack(s, m, "Variable Set"); 01816 } else { 01817 astman_send_error(s, m, "Variable not set"); 01818 } 01819 return 0; 01820 }
| static int action_status | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Manager "status" command to show channels.
Definition at line 1886 of file manager.c.
References ast_channel::_bridge, ast_channel::_state, 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_create(), ast_str_reset(), ast_strdupa, ast_strlen_zero(), ast_tvnow(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::cdr, channels, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, name, ast_channel::pbx, pbx_retrieve_variable(), ast_channel::priority, S_OR, ast_cdr::start, ast_str::str, and str.
Referenced by __init_manager().
01887 { 01888 const char *name = astman_get_header(m, "Channel"); 01889 const char *cvariables = astman_get_header(m, "Variables"); 01890 char *variables = ast_strdupa(S_OR(cvariables, "")); 01891 struct ast_channel *c; 01892 char bridge[256]; 01893 struct timeval now = ast_tvnow(); 01894 long elapsed_seconds = 0; 01895 int channels = 0; 01896 int all = ast_strlen_zero(name); /* set if we want all channels */ 01897 const char *id = astman_get_header(m, "ActionID"); 01898 char idText[256]; 01899 AST_DECLARE_APP_ARGS(vars, 01900 AST_APP_ARG(name)[100]; 01901 ); 01902 struct ast_str *str = ast_str_create(1000); 01903 01904 if (!ast_strlen_zero(id)) 01905 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01906 else 01907 idText[0] = '\0'; 01908 01909 if (all) 01910 c = ast_channel_walk_locked(NULL); 01911 else { 01912 c = ast_get_channel_by_name_locked(name); 01913 if (!c) { 01914 astman_send_error(s, m, "No such channel"); 01915 ast_free(str); 01916 return 0; 01917 } 01918 } 01919 astman_send_ack(s, m, "Channel status will follow"); 01920 01921 if (!ast_strlen_zero(cvariables)) { 01922 AST_STANDARD_APP_ARGS(vars, variables); 01923 } 01924 01925 /* if we look by name, we break after the first iteration */ 01926 while (c) { 01927 if (!ast_strlen_zero(cvariables)) { 01928 int i; 01929 ast_str_reset(str); 01930 for (i = 0; i < vars.argc; i++) { 01931 char valbuf[512], *ret = NULL; 01932 01933 if (vars.name[i][strlen(vars.name[i]) - 1] == ')') { 01934 if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) { 01935 valbuf[0] = '\0'; 01936 } 01937 ret = valbuf; 01938 } else { 01939 pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL); 01940 } 01941 01942 ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret); 01943 } 01944 } 01945 01946 channels++; 01947 if (c->_bridge) 01948 snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid); 01949 else 01950 bridge[0] = '\0'; 01951 if (c->pbx) { 01952 if (c->cdr) { 01953 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01954 } 01955 astman_append(s, 01956 "Event: Status\r\n" 01957 "Privilege: Call\r\n" 01958 "Channel: %s\r\n" 01959 "CallerIDNum: %s\r\n" 01960 "CallerIDName: %s\r\n" 01961 "Accountcode: %s\r\n" 01962 "ChannelState: %d\r\n" 01963 "ChannelStateDesc: %s\r\n" 01964 "Context: %s\r\n" 01965 "Extension: %s\r\n" 01966 "Priority: %d\r\n" 01967 "Seconds: %ld\r\n" 01968 "%s" 01969 "Uniqueid: %s\r\n" 01970 "%s" 01971 "%s" 01972 "\r\n", 01973 c->name, 01974 S_OR(c->cid.cid_num, ""), 01975 S_OR(c->cid.cid_name, ""), 01976 c->accountcode, 01977 c->_state, 01978 ast_state2str(c->_state), c->context, 01979 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, str->str, idText); 01980 } else { 01981 astman_append(s, 01982 "Event: Status\r\n" 01983 "Privilege: Call\r\n" 01984 "Channel: %s\r\n" 01985 "CallerIDNum: %s\r\n" 01986 "CallerIDName: %s\r\n" 01987 "Account: %s\r\n" 01988 "State: %s\r\n" 01989 "%s" 01990 "Uniqueid: %s\r\n" 01991 "%s" 01992 "%s" 01993 "\r\n", 01994 c->name, 01995 S_OR(c->cid.cid_num, "<unknown>"), 01996 S_OR(c->cid.cid_name, "<unknown>"), 01997 c->accountcode, 01998 ast_state2str(c->_state), bridge, c->uniqueid, str->str, idText); 01999 } 02000 ast_channel_unlock(c); 02001 if (!all) 02002 break; 02003 c = ast_channel_walk_locked(c); 02004 } 02005 astman_append(s, 02006 "Event: StatusComplete\r\n" 02007 "%s" 02008 "Items: %d\r\n" 02009 "\r\n", idText, channels); 02010 ast_free(str); 02011 return 0; 02012 }
| static int action_timeout | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2603 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().
02604 { 02605 struct ast_channel *c; 02606 const char *name = astman_get_header(m, "Channel"); 02607 double timeout = atof(astman_get_header(m, "Timeout")); 02608 struct timeval when = { timeout, 0 }; 02609 02610 if (ast_strlen_zero(name)) { 02611 astman_send_error(s, m, "No channel specified"); 02612 return 0; 02613 } 02614 if (!timeout || timeout < 0) { 02615 astman_send_error(s, m, "No timeout specified"); 02616 return 0; 02617 } 02618 c = ast_get_channel_by_name_locked(name); 02619 if (!c) { 02620 astman_send_error(s, m, "No such channel"); 02621 return 0; 02622 } 02623 02624 when.tv_usec = (timeout - when.tv_sec) * 1000000.0; 02625 ast_channel_setwhentohangup_tv(c, when); 02626 ast_channel_unlock(c); 02627 astman_send_ack(s, m, "Timeout Set"); 02628 return 0; 02629 }
| static int action_updateconfig | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1467 of file manager.c.
References ast_config_destroy(), ast_config_load2(), ast_include_rename(), ast_module_reload(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_send_ack(), astman_send_error(), CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, config_text_file_save(), 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().
01468 { 01469 struct ast_config *cfg; 01470 const char *sfn = astman_get_header(m, "SrcFilename"); 01471 const char *dfn = astman_get_header(m, "DstFilename"); 01472 int res; 01473 const char *rld = astman_get_header(m, "Reload"); 01474 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01475 enum error_type result; 01476 01477 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { 01478 astman_send_error(s, m, "Filename not specified"); 01479 return 0; 01480 } 01481 if (!(cfg = ast_config_load2(sfn, "manager", config_flags))) { 01482 astman_send_error(s, m, "Config file not found"); 01483 return 0; 01484 } 01485 result = handle_updates(s, m, cfg, dfn); 01486 if (!result) { 01487 ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */ 01488 res = config_text_file_save(dfn, cfg, "Manager"); 01489 ast_config_destroy(cfg); 01490 if (res) { 01491 astman_send_error(s, m, "Save of config failed"); 01492 return 0; 01493 } 01494 astman_send_ack(s, m, NULL); 01495 if (!ast_strlen_zero(rld)) { 01496 if (ast_true(rld)) 01497 rld = NULL; 01498 ast_module_reload(rld); 01499 } 01500 } else { 01501 ast_config_destroy(cfg); 01502 switch(result) { 01503 case UNKNOWN_ACTION: 01504 astman_send_error(s, m, "Unknown action command"); 01505 break; 01506 case UNKNOWN_CATEGORY: 01507 astman_send_error(s, m, "Given category does not exist"); 01508 break; 01509 case UNSPECIFIED_CATEGORY: 01510 astman_send_error(s, m, "Category not specified"); 01511 break; 01512 case UNSPECIFIED_ARGUMENT: 01513 astman_send_error(s, m, "Problem with category, value, or line (if required)"); 01514 break; 01515 case FAILURE_ALLOCATION: 01516 astman_send_error(s, m, "Memory allocation failure, this should not happen"); 01517 break; 01518 case FAILURE_NEWCAT: 01519 astman_send_error(s, m, "Create category did not complete successfully"); 01520 break; 01521 case FAILURE_DELCAT: 01522 astman_send_error(s, m, "Delete category did not complete successfully"); 01523 break; 01524 case FAILURE_EMPTYCAT: 01525 astman_send_error(s, m, "Empty category did not complete successfully"); 01526 break; 01527 case FAILURE_UPDATE: 01528 astman_send_error(s, m, "Update did not complete successfully"); 01529 break; 01530 case FAILURE_DELETE: 01531 astman_send_error(s, m, "Delete did not complete successfully"); 01532 break; 01533 case FAILURE_APPEND: 01534 astman_send_error(s, m, "Append did not complete successfully"); 01535 break; 01536 } 01537 } 01538 return 0; 01539 }
| static int action_userevent | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2666 of file manager.c.
References ast_str_append(), ast_str_reset(), ast_str_thread_get(), astman_get_header(), astman_send_ack(), EVENT_FLAG_USER, message::hdrcount, message::headers, manager_event, and ast_str::str.
Referenced by __init_manager().
02667 { 02668 const char *event = astman_get_header(m, "UserEvent"); 02669 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16); 02670 int x; 02671 02672 ast_str_reset(body); 02673 02674 for (x = 0; x < m->hdrcount; x++) { 02675 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 02676 ast_str_append(&body, 0, "%s\r\n", m->headers[x]); 02677 } 02678 } 02679 02680 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body->str); 02681 astman_send_ack(s, m, "Event Sent"); 02682 return 0; 02683 }
| static int action_waitevent | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1573 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, 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().
01574 { 01575 const char *timeouts = astman_get_header(m, "Timeout"); 01576 int timeout = -1; 01577 int x; 01578 int needexit = 0; 01579 const char *id = astman_get_header(m, "ActionID"); 01580 char idText[256]; 01581 01582 if (!ast_strlen_zero(id)) 01583 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01584 else 01585 idText[0] = '\0'; 01586 01587 if (!ast_strlen_zero(timeouts)) { 01588 sscanf(timeouts, "%30i", &timeout); 01589 if (timeout < -1) 01590 timeout = -1; 01591 /* XXX maybe put an upper bound, or prevent the use of 0 ? */ 01592 } 01593 01594 ast_mutex_lock(&s->session->__lock); 01595 if (s->session->waiting_thread != AST_PTHREADT_NULL) 01596 pthread_kill(s->session->waiting_thread, SIGURG); 01597 01598 if (s->session->managerid) { /* AMI-over-HTTP session */ 01599 /* 01600 * Make sure the timeout is within the expire time of the session, 01601 * as the client will likely abort the request if it does not see 01602 * data coming after some amount of time. 01603 */ 01604 time_t now = time(NULL); 01605 int max = s->session->sessiontimeout - now - 10; 01606 01607 if (max < 0) /* We are already late. Strange but possible. */ 01608 max = 0; 01609 if (timeout < 0 || timeout > max) 01610 timeout = max; 01611 if (!s->session->send_events) /* make sure we record events */ 01612 s->session->send_events = -1; 01613 } 01614 ast_mutex_unlock(&s->session->__lock); 01615 01616 /* XXX should this go inside the lock ? */ 01617 s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */ 01618 ast_debug(1, "Starting waiting for an event!\n"); 01619 01620 for (x = 0; x < timeout || timeout < 0; x++) { 01621 ast_mutex_lock(&s->session->__lock); 01622 if (NEW_EVENT(s)) 01623 needexit = 1; 01624 /* We can have multiple HTTP session point to the same mansession entry. 01625 * The way we deal with it is not very nice: newcomers kick out the previous 01626 * HTTP session. XXX this needs to be improved. 01627 */ 01628 if (s->session->waiting_thread != pthread_self()) 01629 needexit = 1; 01630 if (s->session->needdestroy) 01631 needexit = 1; 01632 ast_mutex_unlock(&s->session->__lock); 01633 if (needexit) 01634 break; 01635 if (s->session->managerid == 0) { /* AMI session */ 01636 if (ast_wait_for_input(s->session->fd, 1000)) 01637 break; 01638 } else { /* HTTP session */ 01639 sleep(1); 01640 } 01641 } 01642 ast_debug(1, "Finished waiting for an event!\n"); 01643 ast_mutex_lock(&s->session->__lock); 01644 if (s->session->waiting_thread == pthread_self()) { 01645 struct eventqent *eqe; 01646 astman_send_response(s, m, "Success", "Waiting for Event completed."); 01647 while ( (eqe = NEW_EVENT(s)) ) { 01648 ref_event(eqe); 01649 if (((s->session->readperm & eqe->category) == eqe->category) && 01650 ((s->session->send_events & eqe->category) == eqe->category)) { 01651 astman_append(s, "%s", eqe->eventdata); 01652 } 01653 s->session->last_ev = unref_event(s->session->last_ev); 01654 } 01655 astman_append(s, 01656 "Event: WaitEventComplete\r\n" 01657 "%s" 01658 "\r\n", idText); 01659 s->session->waiting_thread = AST_PTHREADT_NULL; 01660 } else { 01661 ast_debug(1, "Abandoning event request!\n"); 01662 } 01663 ast_mutex_unlock(&s->session->__lock); 01664 return 0; 01665 }
| static int append_event | ( | const char * | str, | |
| int | category | |||
| ) | [static] |
Definition at line 3248 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::seq, and eventqent::usecount.
Referenced by __init_manager(), and __manager_event().
03249 { 03250 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 03251 static int seq; /* sequence number */ 03252 03253 if (!tmp) 03254 return -1; 03255 03256 /* need to init all fields, because ast_malloc() does not */ 03257 tmp->usecount = 0; 03258 tmp->category = category; 03259 tmp->seq = ast_atomic_fetchadd_int(&seq, 1); 03260 AST_LIST_NEXT(tmp, eq_next) = NULL; 03261 strcpy(tmp->eventdata, str); 03262 03263 AST_LIST_LOCK(&all_events); 03264 AST_LIST_INSERT_TAIL(&all_events, tmp, eq_next); 03265 AST_LIST_UNLOCK(&all_events); 03266 03267 return 0; 03268 }
| 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.
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 }
| static AST_LIST_HEAD_STATIC | ( | sessions | , | |
| mansession_session | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | all_events | , | |
| eventqent | ||||
| ) | [static] |
| 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 3423 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().
03424 { 03425 struct manager_action *cur = NULL; 03426 03427 if (!(cur = ast_calloc(1, sizeof(*cur)))) 03428 return -1; 03429 03430 cur->action = action; 03431 cur->authority = auth; 03432 cur->func = func; 03433 cur->synopsis = synopsis; 03434 cur->description = description; 03435 03436 if (ast_manager_register_struct(cur)) { 03437 ast_free(cur); 03438 return -1; 03439 } 03440 03441 return 0; 03442 }
| 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 3387 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().
03388 { 03389 struct manager_action *cur, *prev = NULL; 03390 struct timespec tv = { 5, }; 03391 03392 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03393 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03394 return -1; 03395 } 03396 AST_RWLIST_TRAVERSE(&actions, cur, list) { 03397 int ret = strcasecmp(cur->action, act->action); 03398 if (ret == 0) { 03399 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 03400 AST_RWLIST_UNLOCK(&actions); 03401 return -1; 03402 } 03403 if (ret > 0) { /* Insert these alphabetically */ 03404 prev = cur; 03405 break; 03406 } 03407 } 03408 03409 if (prev) 03410 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list); 03411 else 03412 AST_RWLIST_INSERT_HEAD(&actions, act, list); 03413 03414 ast_verb(2, "Manager registered action %s\n", act->action); 03415 03416 AST_RWLIST_UNLOCK(&actions); 03417 03418 return 0; 03419 }
| int ast_manager_unregister | ( | char * | action | ) |
Unregister a registered manager command.
| action | Name of registered Action: |
Definition at line 3354 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().
03355 { 03356 struct manager_action *cur; 03357 struct timespec tv = { 5, }; 03358 03359 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03360 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03361 return -1; 03362 } 03363 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) { 03364 if (!strcasecmp(action, cur->action)) { 03365 AST_RWLIST_REMOVE_CURRENT(list); 03366 ast_free(cur); 03367 ast_verb(2, "Manager unregistered action %s\n", action); 03368 break; 03369 } 03370 } 03371 AST_RWLIST_TRAVERSE_SAFE_END; 03372 AST_RWLIST_UNLOCK(&actions); 03373 03374 return 0; 03375 }
| 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 }
| static AST_RWLIST_HEAD_STATIC | ( | manager_hooks | , | |
| manager_custom_hook | ||||
| ) | [static] |
list of hooks registered
| static AST_RWLIST_HEAD_STATIC | ( | actions | , | |
| manager_action | ||||
| ) | [static] |
list of actions registered
| static AST_RWLIST_HEAD_STATIC | ( | users | , | |
| ast_manager_user | ||||
| ) | [static] |
list of users found in the config file
| AST_THREADSTORAGE | ( | manager_event_buf | ) |
| AST_THREADSTORAGE | ( | userevent_buf | ) |
| AST_THREADSTORAGE | ( | astman_append_buf | ) |
thread local buffer for astman_append
| 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_set_va(), ast_str_thread_get(), ast_verbose, ASTMAN_APPEND_BUF_INITSIZE, buf, mansession_session::f, mansession::f, send_string(), mansession::session, and ast_str::str.
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), action_agents(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_ping(), 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_jabber_send(), manager_list_voicemail_users(), manager_modulecheck(), manager_parking_status(), manager_queue_rule_show(), manager_queues_show(), manager_queues_status(), manager_queues_summary(), manager_rpt_local_nodes(), manager_rpt_status(), manager_show_dialplan_helper(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), rpt_manager_do_stats(), rpt_manager_success(), and session_do().
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, buf->str); 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(), action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_atxfer(), action_bridge(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), action_waitevent(), astman_send_response_full(), authenticate(), change_monitor_action(), do_pause_or_unpause(), handle_updates(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_jabber_send(), manager_list_voicemail_users(), manager_modulecheck(), manager_moduleload(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_rule_show(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_rpt_status(), manager_show_dialplan(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), meetmemute(), process_message(), rpt_manager_do_stats(), rpt_manager_success(), start_monitor_action(), and stop_monitor_action().
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_strdupa, ast_strlen_zero(), ast_variable_new(), message::hdrcount, message::headers, parse(), strsep(), 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_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_remove_queue_member(), manager_rpt_status(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sipnotify(), meetmemute(), process_message(), 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_show_registry(), and manager_sip_show_peers().
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(), num, and perms.
Referenced by __manager_event(), action_listcommands(), handle_showmanager(), handle_showmancmd(), and handle_showmancmds().
00390 { 00391 int i; 00392 char *sep = ""; 00393 00394 (*res)->used = 0; 00395 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) { 00396 if (authority & perms[i].num) { 00397 ast_str_append(res, 0, "%s%s", sep, perms[i].label); 00398 sep = ","; 00399 } 00400 } 00401 00402 if ((*res)->used == 0) /* replace empty string with something sensible */ 00403 ast_str_append(res, 0, "<none>"); 00404 00405 return (*res)->str; 00406 }
| static int check_blacklist | ( | const char * | cmd | ) | [static] |
Definition at line 2198 of file manager.c.
References ARRAY_LEN, ast_strdupa, ast_strip(), ast_strlen_zero(), command_blacklist, match(), MAX_BLACKLIST_CMD_LEN, strsep(), and words.
Referenced by action_command().
02199 { 02200 char *cmd_copy, *cur_cmd; 02201 char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, }; 02202 int i; 02203 02204 cmd_copy = ast_strdupa(cmd); 02205 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) { 02206 cur_cmd = ast_strip(cur_cmd); 02207 if (ast_strlen_zero(cur_cmd)) { 02208 i--; 02209 continue; 02210 } 02211 02212 cmd_words[i] = cur_cmd; 02213 } 02214 02215 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) { 02216 int j, match = 1; 02217 02218 for (j = 0; command_blacklist[i].words[j]; j++) { 02219 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) { 02220 match = 0; 02221 break; 02222 } 02223 } 02224 02225 if (match) { 02226 return 1; 02227 } 02228 } 02229 02230 return 0; 02231 }
| 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, 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 3112 of file manager.c.
References AST_MAX_MANHEADERS, ast_strdupa, ast_strlen_zero(), get_input(), message::hdrcount, message::headers, mansession_session::inbuf, process_events(), process_message(), and mansession::session.
Referenced by session_do().
03113 { 03114 struct message m = { 0 }; 03115 char header_buf[sizeof(s->session->inbuf)] = { '\0' }; 03116 int res; 03117 03118 for (;;) { 03119 /* Check if any events are pending and do them if needed */ 03120 if (process_events(s)) 03121 return -1; 03122 res = get_input(s, header_buf); 03123 if (res == 0) { 03124 continue; 03125 } else if (res > 0) { 03126 if (ast_strlen_zero(header_buf)) 03127 return process_message(s, &m) ? -1 : 0; 03128 else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) 03129 m.headers[m.hdrcount++] = ast_strdupa(header_buf); 03130 } else { 03131 return res; 03132 } 03133 } 03134 }
| static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 2311 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, fast_originate_helper::priority, S_OR, fast_originate_helper::tech, fast_originate_helper::timeout, and fast_originate_helper::vars.
Referenced by action_originate().
02312 { 02313 struct fast_originate_helper *in = data; 02314 int res; 02315 int reason = 0; 02316 struct ast_channel *chan = NULL; 02317 char requested_channel[AST_CHANNEL_NAME]; 02318 02319 if (!ast_strlen_zero(in->app)) { 02320 res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1, 02321 S_OR(in->cid_num, NULL), 02322 S_OR(in->cid_name, NULL), 02323 in->vars, in->account, &chan); 02324 } else { 02325 res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 02326 S_OR(in->cid_num, NULL), 02327 S_OR(in->cid_name, NULL), 02328 in->vars, in->account, &chan); 02329 } 02330 02331 if (!chan) 02332 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 02333 /* Tell the manager what happened with the channel */ 02334 manager_event(EVENT_FLAG_CALL, "OriginateResponse", 02335 "%s%s" 02336 "Response: %s\r\n" 02337 "Channel: %s\r\n" 02338 "Context: %s\r\n" 02339 "Exten: %s\r\n" 02340 "Reason: %d\r\n" 02341 "Uniqueid: %s\r\n" 02342 "CallerIDNum: %s\r\n" 02343 "CallerIDName: %s\r\n", 02344 in->idtext, ast_strlen_zero(in->idtext) ? "" : "\r\n", res ? "Failure" : "Success", 02345 chan ? chan->name : requested_channel, in->context, in->exten, reason, 02346 chan ? chan->uniqueid : "<null>", 02347 S_OR(in->cid_num, "<unknown>"), 02348 S_OR(in->cid_name, "<unknown>") 02349 ); 02350 02351 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 02352 if (chan) 02353 ast_channel_unlock(chan); 02354 ast_free(in); 02355 return NULL; 02356 }
| 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::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 3042 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().
03043 { 03044 int res, x; 03045 int maxlen = sizeof(s->session->inbuf) - 1; 03046 char *src = s->session->inbuf; 03047 03048 /* 03049 * Look for \r\n within the buffer. If found, copy to the output 03050 * buffer and return, trimming the \r\n (not used afterwards). 03051 */ 03052 for (x = 0; x < s->session->inlen; x++) { 03053 int cr; /* set if we have \r */ 03054 if (src[x] == '\r' && x+1 < s->session->inlen && src[x+1] == '\n') 03055 cr = 2; /* Found. Update length to include \r\n */ 03056 else if (src[x] == '\n') 03057 cr = 1; /* also accept \n only */ 03058 else 03059 continue; 03060 memmove(output, src, x); /*... but trim \r\n */ 03061 output[x] = '\0'; /* terminate the string */ 03062 x += cr; /* number of bytes used */ 03063 s->session->inlen -= x; /* remaining size */ 03064 memmove(src, src + x, s->session->inlen); /* remove used bytes */ 03065 return 1; 03066 } 03067 if (s->session->inlen >= maxlen) { 03068 /* no crlf found, and buffer full - sorry, too long for us */ 03069 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src); 03070 s->session->inlen = 0; 03071 } 03072 res = 0; 03073 while (res == 0) { 03074 /* XXX do we really need this locking ? */ 03075 ast_mutex_lock(&s->session->__lock); 03076 if (s->session->pending_event) { 03077 s->session->pending_event = 0; 03078 ast_mutex_unlock(&s->session->__lock); 03079 return 0; 03080 } 03081 s->session->waiting_thread = pthread_self(); 03082 ast_mutex_unlock(&s->session->__lock); 03083 03084 res = ast_wait_for_input(s->session->fd, -1); /* return 0 on timeout ? */ 03085 03086 ast_mutex_lock(&s->session->__lock); 03087 s->session->waiting_thread = AST_PTHREADT_NULL; 03088 ast_mutex_unlock(&s->session->__lock); 03089 } 03090 if (res < 0) { 03091 /* If we get a signal from some other thread (typically because 03092 * there are new events queued), return 0 to notify the caller. 03093 */ 03094 if (errno == EINTR || errno == EAGAIN) 03095 return 0; 03096 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno)); 03097 return -1; 03098 } 03099 ast_mutex_lock(&s->session->__lock); 03100 res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f); 03101 if (res < 1) 03102 res = -1; /* error return */ 03103 else { 03104 s->session->inlen += res; 03105 src[s->session->inlen] = '\0'; 03106 res = 0; 03107 } 03108 ast_mutex_unlock(&s->session->__lock); 03109 return res; 03110 }
| 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, 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 debug [on|off]"; 00570 e->usage = "Usage: manager 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 == 2) 00576 ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off"); 00577 else if (a->argc == 3) { 00578 if (!strcasecmp(a->argv[2], "on")) 00579 manager_debug = 1; 00580 else if (!strcasecmp(a->argv[2], "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_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::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, 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 1310 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().
01311 { 01312 int x; 01313 char hdr[40]; 01314 const char *action, *cat, *var, *value, *match, *line; 01315 struct ast_category *category; 01316 struct ast_variable *v; 01317 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 01318 enum error_type result = 0; 01319 01320 for (x = 0; x < 100000; x++) { /* 100000 = the max number of allowed updates + 1 */ 01321 unsigned int object = 0; 01322 01323 snprintf(hdr, sizeof(hdr), "Action-%06d", x); 01324 action = astman_get_header(m, hdr); 01325 if (ast_strlen_zero(action)) /* breaks the for loop if no action header */ 01326 break; /* this could cause problems if actions come in misnumbered */ 01327 01328 snprintf(hdr, sizeof(hdr), "Cat-%06d", x); 01329 cat = astman_get_header(m, hdr); 01330 if (ast_strlen_zero(cat)) { /* every action needs a category */ 01331 result = UNSPECIFIED_CATEGORY; 01332 break; 01333 } 01334 01335 snprintf(hdr, sizeof(hdr), "Var-%06d", x); 01336 var = astman_get_header(m, hdr); 01337 01338 snprintf(hdr, sizeof(hdr), "Value-%06d", x); 01339 value = astman_get_header(m, hdr); 01340 01341 if (!ast_strlen_zero(value) && *value == '>') { 01342 object = 1; 01343 value++; 01344 } 01345 01346 snprintf(hdr, sizeof(hdr), "Match-%06d", x); 01347 match = astman_get_header(m, hdr); 01348 01349 snprintf(hdr, sizeof(hdr), "Line-%06d", x); 01350 line = astman_get_header(m, hdr); 01351 01352 if (!strcasecmp(action, "newcat")) { 01353 if (ast_category_get(cfg,cat)) { /* check to make sure the cat doesn't */ 01354 result = FAILURE_NEWCAT; /* already exist */ 01355 break; 01356 } 01357 if (!(category = ast_category_new(cat, dfn, -1))) { 01358 result = FAILURE_ALLOCATION; 01359 break; 01360 } 01361 if (ast_strlen_zero(match)) { 01362 ast_category_append(cfg, category); 01363 } else 01364 ast_category_insert(cfg, category, match); 01365 } else if (!strcasecmp(action, "renamecat")) { 01366 if (ast_strlen_zero(value)) { 01367 result = UNSPECIFIED_ARGUMENT; 01368 break; 01369 } 01370 if (!(category = ast_category_get(cfg, cat))) { 01371 result = UNKNOWN_CATEGORY; 01372 break; 01373 } 01374 ast_category_rename(category, value); 01375 } else if (!strcasecmp(action, "delcat")) { 01376 if (ast_category_delete(cfg, cat)) { 01377 result = FAILURE_DELCAT; 01378 break; 01379 } 01380 } else if (!strcasecmp(action, "emptycat")) { 01381 if (ast_category_empty(cfg, cat)) { 01382 result = FAILURE_EMPTYCAT; 01383 break; 01384 } 01385 } else if (!strcasecmp(action, "update")) { 01386 if (ast_strlen_zero(var)) { 01387 result = UNSPECIFIED_ARGUMENT; 01388 break; 01389 } 01390 if (!(category = ast_category_get(cfg,cat))) { 01391 result = UNKNOWN_CATEGORY; 01392 break; 01393 } 01394 if (ast_variable_update(category, var, value, match, object)) { 01395 result = FAILURE_UPDATE; 01396 break; 01397 } 01398 } else if (!strcasecmp(action, "delete")) { 01399 if ((ast_strlen_zero(var) && ast_strlen_zero(line))) { 01400 result = UNSPECIFIED_ARGUMENT; 01401 break; 01402 } 01403 if (!(category = ast_category_get(cfg, cat))) { 01404 result = UNKNOWN_CATEGORY; 01405 break; 01406 } 01407 if (ast_variable_delete(category, var, match, line)) { 01408 result = FAILURE_DELETE; 01409 break; 01410 } 01411 } else if (!strcasecmp(action, "append")) { 01412 if (ast_strlen_zero(var)) { 01413 result = UNSPECIFIED_ARGUMENT; 01414 break; 01415 } 01416 if (!(category = ast_category_get(cfg, cat))) { 01417 result = UNKNOWN_CATEGORY; 01418 break; 01419 } 01420 if (!(v = ast_variable_new(var, value, dfn))) { 01421 result = FAILURE_ALLOCATION; 01422 break; 01423 } 01424 if (object || (match && !strcasecmp(match, "object"))) 01425 v->object = 1; 01426 ast_variable_append(category, v); 01427 } else if (!strcasecmp(action, "insert")) { 01428 if (ast_strlen_zero(var) || ast_strlen_zero(line)) { 01429 result = UNSPECIFIED_ARGUMENT; 01430 break; 01431 } 01432 if (!(category = ast_category_get(cfg, cat))) { 01433 result = UNKNOWN_CATEGORY; 01434 break; 01435 } 01436 if (!(v = ast_variable_new(var, value, dfn))) { 01437 result = FAILURE_ALLOCATION; 01438 break; 01439 } 01440 ast_variable_insert(category, v, line); 01441 } 01442 else { 01443 ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action); 01444 result = UNKNOWN_ACTION; 01445 break; 01446 } 01447 } 01448 ast_free(str1); 01449 ast_free(str2); 01450 return result; 01451 }
| 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 1229 of file manager.c.
Referenced by action_getconfigjson().
| static int manager_displayconnects | ( | struct mansession_session * | session | ) | [static] |
Get displayconnects config option.
| s | manager session to get parameter from. |
Definition at line 505 of file manager.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, 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 2866 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().
02867 { 02868 int res; 02869 const char *module = astman_get_header(m, "Module"); 02870 const char *id = astman_get_header(m, "ActionID"); 02871 char idText[256]; 02872 #if !defined(LOW_MEMORY) 02873 const char *version; 02874 #endif 02875 char filename[PATH_MAX]; 02876 char *cut; 02877 02878 ast_copy_string(filename, module, sizeof(filename)); 02879 if ((cut = strchr(filename, '.'))) { 02880 *cut = '\0'; 02881 } else { 02882 cut = filename + strlen(filename); 02883 } 02884 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so"); 02885 ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename); 02886 res = ast_module_check(filename); 02887 if (!res) { 02888 astman_send_error(s, m, "Module not loaded"); 02889 return 0; 02890 } 02891 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c"); 02892 ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename); 02893 #if !defined(LOW_MEMORY) 02894 version = ast_file_version_find(filename); 02895 #endif 02896 02897 if (!ast_strlen_zero(id)) 02898 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02899 else 02900 idText[0] = '\0'; 02901 astman_append(s, "Response: Success\r\n%s", idText); 02902 #if !defined(LOW_MEMORY) 02903 astman_append(s, "Version: %s\r\n\r\n", version ? version : ""); 02904 #endif 02905 return 0; 02906 }
| static int manager_moduleload | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2919 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().
02920 { 02921 int res; 02922 const char *module = astman_get_header(m, "Module"); 02923 const char *loadtype = astman_get_header(m, "LoadType"); 02924 02925 if (!loadtype || strlen(loadtype) == 0) 02926 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02927 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) 02928 astman_send_error(s, m, "Need module name"); 02929 02930 if (!strcasecmp(loadtype, "load")) { 02931 res = ast_load_resource(module); 02932 if (res) 02933 astman_send_error(s, m, "Could not load module."); 02934 else 02935 astman_send_ack(s, m, "Module loaded."); 02936 } else if (!strcasecmp(loadtype, "unload")) { 02937 res = ast_unload_resource(module, AST_FORCE_SOFT); 02938 if (res) 02939 astman_send_error(s, m, "Could not unload module."); 02940 else 02941 astman_send_ack(s, m, "Module unloaded."); 02942 } else if (!strcasecmp(loadtype, "reload")) { 02943 if (module != NULL) { 02944 res = ast_module_reload(module); 02945 if (res == 0) 02946 astman_send_error(s, m, "No such module."); 02947 else if (res == 1) 02948 astman_send_error(s, m, "Module does not support reload action."); 02949 else 02950 astman_send_ack(s, m, "Module reloaded."); 02951 } else { 02952 ast_module_reload(NULL); /* Reload all modules */ 02953 astman_send_ack(s, m, "All modules reloaded"); 02954 } 02955 } else 02956 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02957 return 0; 02958 }
| static int manager_state_cb | ( | char * | context, | |
| char * | exten, | |||
| int | state, | |||
| void * | data | |||
| ) | [static] |
Definition at line 3377 of file manager.c.
References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.
Referenced by __init_manager().
03378 { 03379 /* Notify managers of change */ 03380 char hint[512]; 03381 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten); 03382 03383 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state); 03384 return 0; 03385 }
| 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 2636 of file manager.c.
References mansession_session::__lock, ast_mutex_lock(), ast_mutex_unlock(), mansession_session::authenticated, eventqent::category, 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().
02637 { 02638 int ret = 0; 02639 02640 ast_mutex_lock(&s->session->__lock); 02641 if (s->session->f != NULL) { 02642 struct eventqent *eqe; 02643 02644 while ( (eqe = NEW_EVENT(s)) ) { 02645 ref_event(eqe); 02646 if (!ret && s->session->authenticated && 02647 (s->session->readperm & eqe->category) == eqe->category && 02648 (s->session->send_events & eqe->category) == eqe->category) { 02649 if (send_string(s, eqe->eventdata) < 0) 02650 ret = -1; /* don't send more */ 02651 } 02652 s->session->last_ev = unref_event(s->session->last_ev); 02653 } 02654 } 02655 ast_mutex_unlock(&s->session->__lock); 02656 return ret; 02657 }
| static int process_message | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2973 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().
02974 { 02975 char action[80] = ""; 02976 int ret = 0; 02977 struct manager_action *tmp; 02978 const char *user = astman_get_header(m, "Username"); 02979 02980 ast_copy_string(action, __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY), sizeof(action)); 02981 ast_debug(1, "Manager received command '%s'\n", action); 02982 02983 if (ast_strlen_zero(action)) { 02984 ast_mutex_lock(&s->session->__lock); 02985 astman_send_error(s, m, "Missing action in request"); 02986 ast_mutex_unlock(&s->session->__lock); 02987 return 0; 02988 } 02989 02990 if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) { 02991 ast_mutex_lock(&s->session->__lock); 02992 astman_send_error(s, m, "Permission denied"); 02993 ast_mutex_unlock(&s->session->__lock); 02994 return 0; 02995 } 02996 02997 if (!allowmultiplelogin && !s->session->authenticated && user && 02998 (!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) { 02999 if (check_manager_session_inuse(user)) { 03000 sleep(1); 03001 ast_mutex_lock(&s->session->__lock); 03002 astman_send_error(s, m, "Login Already In Use"); 03003 ast_mutex_unlock(&s->session->__lock); 03004 return -1; 03005 } 03006 } 03007 03008 AST_RWLIST_RDLOCK(&actions); 03009 AST_RWLIST_TRAVERSE(&actions, tmp, list) { 03010 if (strcasecmp(action, tmp->action)) 03011 continue; 03012 if (s->session->writeperm & tmp->authority || tmp->authority == 0) 03013 ret = tmp->func(s, m); 03014 else 03015 astman_send_error(s, m, "Permission denied"); 03016 break; 03017 } 03018 AST_RWLIST_UNLOCK(&actions); 03019 03020 if (!tmp) { 03021 char buf[512]; 03022 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action); 03023 ast_mutex_lock(&s->session->__lock); 03024 astman_send_error(s, m, buf); 03025 ast_mutex_unlock(&s->session->__lock); 03026 } 03027 if (ret) 03028 return ret; 03029 /* Once done with our message, deliver any pending events */ 03030 return process_events(s); 03031 }
| 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 3221 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().
03222 { 03223 struct mansession_session *session; 03224 time_t now = time(NULL); 03225 03226 AST_LIST_LOCK(&sessions); 03227 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, session, list) { 03228 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) { 03229 AST_LIST_REMOVE_CURRENT(list); 03230 ast_atomic_fetchadd_int(&num_sessions, -1); 03231 if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) { 03232 ast_verb(2, "HTTP Manager '%s' timed out from %s\n", 03233 session->username, ast_inet_ntoa(session->sin.sin_addr)); 03234 } 03235 free_session(session); /* XXX outside ? */ 03236 if (--n_max <= 0) 03237 break; 03238 } 03239 } 03240 AST_LIST_TRAVERSE_SAFE_END; 03241 AST_LIST_UNLOCK(&sessions); 03242 }
| 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 3144 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, 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.
03145 { 03146 struct ast_tcptls_session_instance *ser = data; 03147 struct mansession_session *session = ast_calloc(1, sizeof(*session)); 03148 struct mansession s = {.session = NULL, }; 03149 int flags; 03150 int res; 03151 03152 if (session == NULL) 03153 goto done; 03154 03155 session->writetimeout = 100; 03156 session->waiting_thread = AST_PTHREADT_NULL; 03157 03158 flags = fcntl(ser->fd, F_GETFL); 03159 if (!block_sockets) /* make sure socket is non-blocking */ 03160 flags |= O_NONBLOCK; 03161 else 03162 flags &= ~O_NONBLOCK; 03163 fcntl(ser->fd, F_SETFL, flags); 03164 03165 ast_mutex_init(&session->__lock); 03166 session->send_events = -1; 03167 /* Hook to the tail of the event queue */ 03168 session->last_ev = grab_last(); 03169 03170 /* these fields duplicate those in the 'ser' structure */ 03171 session->fd = ser->fd; 03172 session->f = ser->f; 03173 session->sin = ser->remote_address; 03174 s.session = session; 03175 03176 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores); 03177 03178 AST_LIST_LOCK(&sessions); 03179 AST_LIST_INSERT_HEAD(&sessions, session, list); 03180 ast_atomic_fetchadd_int(&num_sessions, 1); 03181 AST_LIST_UNLOCK(&sessions); 03182 03183 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */ 03184 for (;;) { 03185 if ((res = do_message(&s)) < 0) 03186 break; 03187 } 03188 /* session is over, explain why and terminate */ 03189 if (session->authenticated) { 03190 if (manager_displayconnects(session)) 03191 ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 03192 ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 03193 } else { 03194 if (displayconnects) 03195 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr)); 03196 ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(session->sin.sin_addr)); 03197 } 03198 03199 /* It is possible under certain circumstances for this session thread 03200 to complete its work and exit *before* the thread that created it 03201 has finished executing the ast_pthread_create_background() function. 03202 If this occurs, some versions of glibc appear to act in a buggy 03203 fashion and attempt to write data into memory that it thinks belongs 03204 to the thread but is in fact not owned by the thread (or may have 03205 been freed completely). 03206 03207 Causing this thread to yield to other threads at least one time 03208 appears to work around this bug. 03209 */ 03210 usleep(1); 03211 03212 destroy_session(session); 03213 03214 done: 03215 ao2_ref(ser, -1); 03216 ser = NULL; 03217 return NULL; 03218 }
| 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] |
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] |
char mandescr_atxfer[] [static] |
Definition at line 2141 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 2233 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 2685 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 2788 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 2731 of file manager.c.
Referenced by __init_manager().
char mandescr_createconfig[] [static] |
Definition at line 1541 of file manager.c.
Referenced by __init_manager().
char mandescr_events[] [static] |
Definition at line 1689 of file manager.c.
Referenced by __init_manager().
char mandescr_extensionstate[] [static] |
Definition at line 2561 of file manager.c.
Referenced by __init_manager().
char mandescr_getconfig[] [static] |
Definition at line 1145 of file manager.c.
Referenced by __init_manager().
char mandescr_getconfigjson[] [static] |
Definition at line 1239 of file manager.c.
Referenced by __init_manager().
char mandescr_getvar[] [static] |
Definition at line 1822 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 1754 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 1190 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 1667 of file manager.c.
Referenced by __init_manager().
char mandescr_logoff[] [static] |
"Description: Logoff this manager session\n" "Variables: NONE\n"
Definition at line 1712 of file manager.c.
Referenced by __init_manager().
char mandescr_mailboxcount[] [static] |
Definition at line 2528 of file manager.c.
Referenced by __init_manager().
char mandescr_mailboxstatus[] [static] |
Help text for manager command mailboxstatus.
Definition at line 2500 of file manager.c.
Referenced by __init_manager().
char mandescr_modulecheck[] [static] |
Definition at line 2856 of file manager.c.
Referenced by __init_manager().
char mandescr_moduleload[] [static] |
Definition at line 2908 of file manager.c.
Referenced by __init_manager().
char mandescr_originate[] [static] |
Definition at line 2358 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 2055 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 2769 of file manager.c.
Referenced by __init_manager().
char mandescr_sendtext[] [static] |
Definition at line 2014 of file manager.c.
Referenced by __init_manager().
char mandescr_setvar[] [static] |
Definition at line 1778 of file manager.c.
Referenced by __init_manager().
char mandescr_status[] [static] |
Definition at line 1874 of file manager.c.
Referenced by __init_manager().
char mandescr_timeout[] [static] |
Definition at line 2596 of file manager.c.
Referenced by __init_manager().
char mandescr_updateconfig[] [static] |
Definition at line 1453 of file manager.c.
Referenced by __init_manager().
char mandescr_userevent[] [static] |
Definition at line 2659 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] |
int webmanager_enabled = 0 [static] |
1.6.1