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 3262 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 3265 of file manager.c.
References mansession_session::__lock, append_event(), ast_atomic_fetchadd_int(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_append_va(), ast_str_set(), ast_str_thread_get(), ast_tvnow(), authority_to_str(), buf, manager_custom_hook::helper, MANAGER_EVENT_BUF_INITSIZE, mansession_session::pending_event, eventqent::seq, ast_str::str, and mansession_session::waiting_thread.
03267 { 03268 struct mansession_session *session; 03269 struct manager_custom_hook *hook; 03270 struct ast_str *auth = ast_str_alloca(80); 03271 const char *cat_str; 03272 va_list ap; 03273 struct timeval now; 03274 struct ast_str *buf; 03275 03276 /* Abort if there aren't any manager sessions */ 03277 if (!num_sessions) 03278 return 0; 03279 03280 if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) 03281 return -1; 03282 03283 cat_str = authority_to_str(category, &auth); 03284 ast_str_set(&buf, 0, 03285 "Event: %s\r\nPrivilege: %s\r\n", 03286 event, cat_str); 03287 03288 if (timestampevents) { 03289 now = ast_tvnow(); 03290 ast_str_append(&buf, 0, 03291 "Timestamp: %ld.%06lu\r\n", 03292 (long)now.tv_sec, (unsigned long) now.tv_usec); 03293 } 03294 if (manager_debug) { 03295 static int seq; 03296 ast_str_append(&buf, 0, 03297 "SequenceNumber: %d\r\n", 03298 ast_atomic_fetchadd_int(&seq, 1)); 03299 ast_str_append(&buf, 0, 03300 "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func); 03301 } 03302 03303 va_start(ap, fmt); 03304 ast_str_append_va(&buf, 0, fmt, ap); 03305 va_end(ap); 03306 03307 ast_str_append(&buf, 0, "\r\n"); 03308 03309 append_event(buf->str, category); 03310 03311 /* Wake up any sleeping sessions */ 03312 AST_LIST_LOCK(&sessions); 03313 AST_LIST_TRAVERSE(&sessions, session, list) { 03314 ast_mutex_lock(&session->__lock); 03315 if (session->waiting_thread != AST_PTHREADT_NULL) 03316 pthread_kill(session->waiting_thread, SIGURG); 03317 else 03318 /* We have an event to process, but the mansession is 03319 * not waiting for it. We still need to indicate that there 03320 * is an event waiting so that get_input processes the pending 03321 * event instead of polling. 03322 */ 03323 session->pending_event = 1; 03324 ast_mutex_unlock(&session->__lock); 03325 } 03326 AST_LIST_UNLOCK(&sessions); 03327 03328 AST_RWLIST_RDLOCK(&manager_hooks); 03329 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) { 03330 hook->helper(category, event, buf->str); 03331 } 03332 AST_RWLIST_UNLOCK(&manager_hooks); 03333 03334 return 0; 03335 }
| static int action_atxfer | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2143 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().
02144 { 02145 const char *name = astman_get_header(m, "Channel"); 02146 const char *exten = astman_get_header(m, "Exten"); 02147 const char *context = astman_get_header(m, "Context"); 02148 struct ast_channel *chan = NULL; 02149 struct ast_call_feature *atxfer_feature = NULL; 02150 char *feature_code = NULL; 02151 02152 if (ast_strlen_zero(name)) { 02153 astman_send_error(s, m, "No channel specified"); 02154 return 0; 02155 } 02156 if (ast_strlen_zero(exten)) { 02157 astman_send_error(s, m, "No extension specified"); 02158 return 0; 02159 } 02160 02161 if (!(atxfer_feature = ast_find_call_feature("atxfer"))) { 02162 astman_send_error(s, m, "No attended transfer feature found"); 02163 return 0; 02164 } 02165 02166 if (!(chan = ast_get_channel_by_name_locked(name))) { 02167 astman_send_error(s, m, "Channel specified does not exist"); 02168 return 0; 02169 } 02170 02171 if (!ast_strlen_zero(context)) { 02172 pbx_builtin_setvar_helper(chan, "TRANSFER_CONTEXT", context); 02173 } 02174 02175 for (feature_code = atxfer_feature->exten; feature_code && *feature_code; ++feature_code) { 02176 struct ast_frame f = {AST_FRAME_DTMF, *feature_code}; 02177 ast_queue_frame(chan, &f); 02178 } 02179 02180 for (feature_code = (char *)exten; feature_code && *feature_code; ++feature_code) { 02181 struct ast_frame f = {AST_FRAME_DTMF, *feature_code}; 02182 ast_queue_frame(chan, &f); 02183 } 02184 02185 astman_send_ack(s, m, "Atxfer successfully queued"); 02186 ast_channel_unlock(chan); 02187 02188 return 0; 02189 }
| 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 2233 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().
02234 { 02235 const char *cmd = astman_get_header(m, "Command"); 02236 const char *id = astman_get_header(m, "ActionID"); 02237 char *buf, *final_buf; 02238 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 02239 int fd = mkstemp(template); 02240 off_t l; 02241 02242 if (ast_strlen_zero(cmd)) { 02243 astman_send_error(s, m, "No command provided"); 02244 return 0; 02245 } 02246 02247 if (check_blacklist(cmd)) { 02248 astman_send_error(s, m, "Command blacklisted"); 02249 return 0; 02250 } 02251 02252 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 02253 if (!ast_strlen_zero(id)) 02254 astman_append(s, "ActionID: %s\r\n", id); 02255 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 02256 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 02257 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 02258 02259 /* This has a potential to overflow the stack. Hence, use the heap. */ 02260 buf = ast_calloc(1, l + 1); 02261 final_buf = ast_calloc(1, l + 1); 02262 if (buf) { 02263 lseek(fd, 0, SEEK_SET); 02264 if (read(fd, buf, l) < 0) { 02265 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 02266 } 02267 buf[l] = '\0'; 02268 if (final_buf) { 02269 term_strip(final_buf, buf, l); 02270 final_buf[l] = '\0'; 02271 } 02272 astman_append(s, "%s", S_OR(final_buf, buf)); 02273 ast_free(buf); 02274 } 02275 close(fd); 02276 unlink(template); 02277 astman_append(s, "--END COMMAND--\r\n\r\n"); 02278 if (final_buf) 02279 ast_free(final_buf); 02280 return 0; 02281 }
| static int action_coresettings | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show PBX core settings information.
Definition at line 2681 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().
02682 { 02683 const char *actionid = astman_get_header(m, "ActionID"); 02684 char idText[150]; 02685 02686 if (!ast_strlen_zero(actionid)) 02687 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02688 else 02689 idText[0] = '\0'; 02690 02691 astman_append(s, "Response: Success\r\n" 02692 "%s" 02693 "AMIversion: %s\r\n" 02694 "AsteriskVersion: %s\r\n" 02695 "SystemName: %s\r\n" 02696 "CoreMaxCalls: %d\r\n" 02697 "CoreMaxLoadAvg: %f\r\n" 02698 "CoreRunUser: %s\r\n" 02699 "CoreRunGroup: %s\r\n" 02700 "CoreMaxFilehandles: %d\r\n" 02701 "CoreRealTimeEnabled: %s\r\n" 02702 "CoreCDRenabled: %s\r\n" 02703 "CoreHTTPenabled: %s\r\n" 02704 "\r\n", 02705 idText, 02706 AMI_VERSION, 02707 ast_get_version(), 02708 ast_config_AST_SYSTEM_NAME, 02709 option_maxcalls, 02710 option_maxload, 02711 ast_config_AST_RUN_USER, 02712 ast_config_AST_RUN_GROUP, 02713 option_maxfiles, 02714 ast_realtime_enabled() ? "Yes" : "No", 02715 check_cdr_enabled() ? "Yes" : "No", 02716 check_webmanager_enabled() ? "Yes" : "No" 02717 ); 02718 return 0; 02719 }
| 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 2786 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().
02787 { 02788 const char *actionid = astman_get_header(m, "ActionID"); 02789 char actionidtext[256]; 02790 struct ast_channel *c = NULL; 02791 int numchans = 0; 02792 int duration, durh, durm, durs; 02793 02794 if (!ast_strlen_zero(actionid)) 02795 snprintf(actionidtext, sizeof(actionidtext), "ActionID: %s\r\n", actionid); 02796 else 02797 actionidtext[0] = '\0'; 02798 02799 astman_send_listack(s, m, "Channels will follow", "start"); 02800 02801 while ((c = ast_channel_walk_locked(c)) != NULL) { 02802 struct ast_channel *bc = ast_bridged_channel(c); 02803 char durbuf[10] = ""; 02804 02805 if (c->cdr && !ast_tvzero(c->cdr->start)) { 02806 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 02807 durh = duration / 3600; 02808 durm = (duration % 3600) / 60; 02809 durs = duration % 60; 02810 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 02811 } 02812 02813 astman_append(s, 02814 "Event: CoreShowChannel\r\n" 02815 "Channel: %s\r\n" 02816 "UniqueID: %s\r\n" 02817 "Context: %s\r\n" 02818 "Extension: %s\r\n" 02819 "Priority: %d\r\n" 02820 "ChannelState: %d\r\n" 02821 "ChannelStateDesc: %s\r\n" 02822 "Application: %s\r\n" 02823 "ApplicationData: %s\r\n" 02824 "CallerIDnum: %s\r\n" 02825 "Duration: %s\r\n" 02826 "AccountCode: %s\r\n" 02827 "BridgedChannel: %s\r\n" 02828 "BridgedUniqueID: %s\r\n" 02829 "\r\n", c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, ast_state2str(c->_state), 02830 c->appl ? c->appl : "", c->data ? S_OR(c->data, ""): "", 02831 S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : ""); 02832 ast_channel_unlock(c); 02833 numchans++; 02834 } 02835 02836 astman_append(s, 02837 "Event: CoreShowChannelsComplete\r\n" 02838 "EventList: Complete\r\n" 02839 "ListItems: %d\r\n" 02840 "%s" 02841 "\r\n", numchans, actionidtext); 02842 02843 return 0; 02844 }
| static int action_corestatus | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show PBX core status information.
Definition at line 2727 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().
02728 { 02729 const char *actionid = astman_get_header(m, "ActionID"); 02730 char idText[150]; 02731 char startuptime[150]; 02732 char reloadtime[150]; 02733 struct ast_tm tm; 02734 02735 if (!ast_strlen_zero(actionid)) 02736 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02737 else 02738 idText[0] = '\0'; 02739 02740 ast_localtime(&ast_startuptime, &tm, NULL); 02741 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm); 02742 ast_localtime(&ast_lastreloadtime, &tm, NULL); 02743 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm); 02744 02745 astman_append(s, "Response: Success\r\n" 02746 "%s" 02747 "CoreStartupTime: %s\r\n" 02748 "CoreReloadTime: %s\r\n" 02749 "CoreCurrentCalls: %d\r\n" 02750 "\r\n", 02751 idText, 02752 startuptime, 02753 reloadtime, 02754 ast_active_channels() 02755 ); 02756 return 0; 02757 }
| 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"); 01706 else if (res == 0) 01707 astman_append(s, "Response: Success\r\n" 01708 "Events: Off\r\n"); 01709 return 0; 01710 }
| static int action_extensionstate | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2563 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().
02564 { 02565 const char *exten = astman_get_header(m, "Exten"); 02566 const char *context = astman_get_header(m, "Context"); 02567 char hint[256] = ""; 02568 int status; 02569 if (ast_strlen_zero(exten)) { 02570 astman_send_error(s, m, "Extension not specified"); 02571 return 0; 02572 } 02573 if (ast_strlen_zero(context)) 02574 context = "default"; 02575 status = ast_extension_state(NULL, context, exten); 02576 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 02577 astman_start_ack(s, m); 02578 astman_append(s, "Message: Extension Status\r\n" 02579 "Exten: %s\r\n" 02580 "Context: %s\r\n" 02581 "Hint: %s\r\n" 02582 "Status: %d\r\n\r\n", 02583 exten, context, hint, status); 02584 return 0; 02585 }
| 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 1822 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().
01823 { 01824 struct ast_channel *c = NULL; 01825 const char *name = astman_get_header(m, "Channel"); 01826 const char *varname = astman_get_header(m, "Variable"); 01827 char *varval; 01828 char workspace[1024] = ""; 01829 01830 if (ast_strlen_zero(varname)) { 01831 astman_send_error(s, m, "No variable specified"); 01832 return 0; 01833 } 01834 01835 if (!ast_strlen_zero(name)) { 01836 c = ast_get_channel_by_name_locked(name); 01837 if (!c) { 01838 astman_send_error(s, m, "No such channel"); 01839 return 0; 01840 } 01841 } 01842 01843 if (varname[strlen(varname) - 1] == ')') { 01844 if (!c) { 01845 c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/manager"); 01846 if (c) { 01847 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01848 ast_channel_free(c); 01849 c = NULL; 01850 } else 01851 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n"); 01852 } else 01853 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01854 varval = workspace; 01855 } else { 01856 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 01857 } 01858 01859 if (c) 01860 ast_channel_unlock(c); 01861 astman_start_ack(s, m); 01862 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, varval); 01863 01864 return 0; 01865 }
| 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 2531 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().
02532 { 02533 const char *mailbox = astman_get_header(m, "Mailbox"); 02534 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;; 02535 02536 if (ast_strlen_zero(mailbox)) { 02537 astman_send_error(s, m, "Mailbox not specified"); 02538 return 0; 02539 } 02540 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs); 02541 astman_start_ack(s, m); 02542 astman_append(s, "Message: Mailbox Message Count\r\n" 02543 "Mailbox: %s\r\n" 02544 "UrgMessages: %d\r\n" 02545 "NewMessages: %d\r\n" 02546 "OldMessages: %d\r\n" 02547 "\r\n", 02548 mailbox, urgentmsgs, newmsgs, oldmsgs); 02549 return 0; 02550 }
| static int action_mailboxstatus | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2502 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().
02503 { 02504 const char *mailbox = astman_get_header(m, "Mailbox"); 02505 int ret; 02506 02507 if (ast_strlen_zero(mailbox)) { 02508 astman_send_error(s, m, "Mailbox not specified"); 02509 return 0; 02510 } 02511 ret = ast_app_has_voicemail(mailbox, NULL); 02512 astman_start_ack(s, m); 02513 astman_append(s, "Message: Mailbox Status\r\n" 02514 "Mailbox: %s\r\n" 02515 "Waiting: %d\r\n\r\n", mailbox, ret); 02516 return 0; 02517 }
| static int action_originate | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2365 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().
02366 { 02367 const char *name = astman_get_header(m, "Channel"); 02368 const char *exten = astman_get_header(m, "Exten"); 02369 const char *context = astman_get_header(m, "Context"); 02370 const char *priority = astman_get_header(m, "Priority"); 02371 const char *timeout = astman_get_header(m, "Timeout"); 02372 const char *callerid = astman_get_header(m, "CallerID"); 02373 const char *account = astman_get_header(m, "Account"); 02374 const char *app = astman_get_header(m, "Application"); 02375 const char *appdata = astman_get_header(m, "Data"); 02376 const char *async = astman_get_header(m, "Async"); 02377 const char *id = astman_get_header(m, "ActionID"); 02378 const char *codecs = astman_get_header(m, "Codecs"); 02379 struct ast_variable *vars = astman_get_variables(m); 02380 char *tech, *data; 02381 char *l = NULL, *n = NULL; 02382 int pi = 0; 02383 int res; 02384 int to = 30000; 02385 int reason = 0; 02386 char tmp[256]; 02387 char tmp2[256]; 02388 int format = AST_FORMAT_SLINEAR; 02389 02390 pthread_t th; 02391 if (ast_strlen_zero(name)) { 02392 astman_send_error(s, m, "Channel not specified"); 02393 return 0; 02394 } 02395 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 02396 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 02397 astman_send_error(s, m, "Invalid priority"); 02398 return 0; 02399 } 02400 } 02401 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) { 02402 astman_send_error(s, m, "Invalid timeout"); 02403 return 0; 02404 } 02405 ast_copy_string(tmp, name, sizeof(tmp)); 02406 tech = tmp; 02407 data = strchr(tmp, '/'); 02408 if (!data) { 02409 astman_send_error(s, m, "Invalid channel"); 02410 return 0; 02411 } 02412 *data++ = '\0'; 02413 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 02414 ast_callerid_parse(tmp2, &n, &l); 02415 if (n) { 02416 if (ast_strlen_zero(n)) 02417 n = NULL; 02418 } 02419 if (l) { 02420 ast_shrink_phone_number(l); 02421 if (ast_strlen_zero(l)) 02422 l = NULL; 02423 } 02424 if (!ast_strlen_zero(codecs)) { 02425 format = 0; 02426 ast_parse_allow_disallow(NULL, &format, codecs, 1); 02427 } 02428 if (ast_true(async)) { 02429 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 02430 if (!fast) { 02431 res = -1; 02432 } else { 02433 if (!ast_strlen_zero(id)) 02434 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s", id); 02435 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 02436 ast_copy_string(fast->data, data, sizeof(fast->data)); 02437 ast_copy_string(fast->app, app, sizeof(fast->app)); 02438 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 02439 if (l) 02440 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 02441 if (n) 02442 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 02443 fast->vars = vars; 02444 ast_copy_string(fast->context, context, sizeof(fast->context)); 02445 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 02446 ast_copy_string(fast->account, account, sizeof(fast->account)); 02447 fast->format = format; 02448 fast->timeout = to; 02449 fast->priority = pi; 02450 if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) { 02451 ast_free(fast); 02452 res = -1; 02453 } else { 02454 res = 0; 02455 } 02456 } 02457 } else if (!ast_strlen_zero(app)) { 02458 /* To run the System application (or anything else that goes to shell), you must have the additional System privilege */ 02459 if (!(s->session->writeperm & EVENT_FLAG_SYSTEM) 02460 && ( 02461 strcasestr(app, "system") == 0 || /* System(rm -rf /) 02462 TrySystem(rm -rf /) */ 02463 strcasestr(app, "exec") || /* Exec(System(rm -rf /)) 02464 TryExec(System(rm -rf /)) */ 02465 strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /) 02466 EAGI(/bin/rm,-rf /) */ 02467 strstr(appdata, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */ 02468 strstr(appdata, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */ 02469 )) { 02470 astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have."); 02471 return 0; 02472 } 02473 res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 02474 } else { 02475 if (exten && context && pi) 02476 res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 02477 else { 02478 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 02479 return 0; 02480 } 02481 } 02482 if (!res) 02483 astman_send_ack(s, m, "Originate successfully queued"); 02484 else 02485 astman_send_error(s, m, "Originate failed"); 02486 return 0; 02487 }
| 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 2059 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().
02060 { 02061 const char *name = astman_get_header(m, "Channel"); 02062 const char *name2 = astman_get_header(m, "ExtraChannel"); 02063 const char *exten = astman_get_header(m, "Exten"); 02064 const char *context = astman_get_header(m, "Context"); 02065 const char *priority = astman_get_header(m, "Priority"); 02066 struct ast_channel *chan, *chan2 = NULL; 02067 int pi = 0; 02068 int res; 02069 02070 if (ast_strlen_zero(name)) { 02071 astman_send_error(s, m, "Channel not specified"); 02072 return 0; 02073 } 02074 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 02075 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 02076 astman_send_error(s, m, "Invalid priority"); 02077 return 0; 02078 } 02079 } 02080 /* XXX watch out, possible deadlock - we are trying to get two channels!!! */ 02081 chan = ast_get_channel_by_name_locked(name); 02082 if (!chan) { 02083 char buf[256]; 02084 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 02085 astman_send_error(s, m, buf); 02086 return 0; 02087 } 02088 if (ast_check_hangup(chan)) { 02089 astman_send_error(s, m, "Redirect failed, channel not up."); 02090 ast_channel_unlock(chan); 02091 return 0; 02092 } 02093 if (!ast_strlen_zero(name2)) 02094 chan2 = ast_get_channel_by_name_locked(name2); 02095 if (chan2 && ast_check_hangup(chan2)) { 02096 astman_send_error(s, m, "Redirect failed, extra channel not up."); 02097 ast_channel_unlock(chan); 02098 ast_channel_unlock(chan2); 02099 return 0; 02100 } 02101 if (chan->pbx) { 02102 ast_channel_lock(chan); 02103 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 02104 ast_channel_unlock(chan); 02105 } 02106 res = ast_async_goto(chan, context, exten, pi); 02107 if (!res) { 02108 if (!ast_strlen_zero(name2)) { 02109 if (chan2) { 02110 if (chan2->pbx) { 02111 ast_channel_lock(chan2); 02112 ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 02113 ast_channel_unlock(chan2); 02114 } 02115 res = ast_async_goto(chan2, context, exten, pi); 02116 } else { 02117 res = -1; 02118 } 02119 if (!res) 02120 astman_send_ack(s, m, "Dual Redirect successful"); 02121 else 02122 astman_send_error(s, m, "Secondary redirect failed"); 02123 } else 02124 astman_send_ack(s, m, "Redirect successful"); 02125 } else 02126 astman_send_error(s, m, "Redirect failed"); 02127 if (chan) 02128 ast_channel_unlock(chan); 02129 if (chan2) 02130 ast_channel_unlock(chan2); 02131 return 0; 02132 }
| static int action_reload | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Send a reload event.
Definition at line 2766 of file manager.c.
References ast_module_reload(), astman_get_header(), astman_send_ack(), astman_send_error(), and S_OR.
Referenced by __init_manager().
02767 { 02768 const char *module = astman_get_header(m, "Module"); 02769 int res = ast_module_reload(S_OR(module, NULL)); 02770 02771 if (res == 2) 02772 astman_send_ack(s, m, "Module Reloaded"); 02773 else 02774 astman_send_error(s, m, s == 0 ? "No such module" : "Module does not support reload"); 02775 return 0; 02776 }
| static int action_sendtext | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2014 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().
02015 { 02016 struct ast_channel *c = NULL; 02017 const char *name = astman_get_header(m, "Channel"); 02018 const char *textmsg = astman_get_header(m, "Message"); 02019 int res = 0; 02020 02021 if (ast_strlen_zero(name)) { 02022 astman_send_error(s, m, "No channel specified"); 02023 return 0; 02024 } 02025 02026 if (ast_strlen_zero(textmsg)) { 02027 astman_send_error(s, m, "No Message specified"); 02028 return 0; 02029 } 02030 02031 c = ast_get_channel_by_name_locked(name); 02032 if (!c) { 02033 astman_send_error(s, m, "No such channel"); 02034 return 0; 02035 } 02036 02037 res = ast_sendtext(c, textmsg); 02038 ast_channel_unlock(c); 02039 02040 if (res > 0) 02041 astman_send_ack(s, m, "Success"); 02042 else 02043 astman_send_error(s, m, "Failure"); 02044 02045 return res; 02046 }
| 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_get_channel_by_name_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, pbx_builtin_setvar_helper(), and S_OR.
Referenced by __init_manager().
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 01792 if (ast_strlen_zero(varname)) { 01793 astman_send_error(s, m, "No variable specified"); 01794 return 0; 01795 } 01796 01797 if (!ast_strlen_zero(name)) { 01798 c = ast_get_channel_by_name_locked(name); 01799 if (!c) { 01800 astman_send_error(s, m, "No such channel"); 01801 return 0; 01802 } 01803 } 01804 01805 pbx_builtin_setvar_helper(c, varname, S_OR(varval, "")); 01806 01807 if (c) 01808 ast_channel_unlock(c); 01809 01810 astman_send_ack(s, m, "Variable Set"); 01811 01812 return 0; 01813 }
| static int action_status | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Manager "status" command to show channels.
Definition at line 1879 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().
01880 { 01881 const char *name = astman_get_header(m, "Channel"); 01882 const char *cvariables = astman_get_header(m, "Variables"); 01883 char *variables = ast_strdupa(S_OR(cvariables, "")); 01884 struct ast_channel *c; 01885 char bridge[256]; 01886 struct timeval now = ast_tvnow(); 01887 long elapsed_seconds = 0; 01888 int channels = 0; 01889 int all = ast_strlen_zero(name); /* set if we want all channels */ 01890 const char *id = astman_get_header(m, "ActionID"); 01891 char idText[256]; 01892 AST_DECLARE_APP_ARGS(vars, 01893 AST_APP_ARG(name)[100]; 01894 ); 01895 struct ast_str *str = ast_str_create(1000); 01896 01897 if (!ast_strlen_zero(id)) 01898 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01899 else 01900 idText[0] = '\0'; 01901 01902 if (all) 01903 c = ast_channel_walk_locked(NULL); 01904 else { 01905 c = ast_get_channel_by_name_locked(name); 01906 if (!c) { 01907 astman_send_error(s, m, "No such channel"); 01908 ast_free(str); 01909 return 0; 01910 } 01911 } 01912 astman_send_ack(s, m, "Channel status will follow"); 01913 01914 if (!ast_strlen_zero(cvariables)) { 01915 AST_STANDARD_APP_ARGS(vars, variables); 01916 } 01917 01918 /* if we look by name, we break after the first iteration */ 01919 while (c) { 01920 if (!ast_strlen_zero(cvariables)) { 01921 int i; 01922 ast_str_reset(str); 01923 for (i = 0; i < vars.argc; i++) { 01924 char valbuf[512], *ret = NULL; 01925 01926 if (vars.name[i][strlen(vars.name[i]) - 1] == ')') { 01927 if (ast_func_read(c, vars.name[i], valbuf, sizeof(valbuf)) < 0) { 01928 valbuf[0] = '\0'; 01929 } 01930 ret = valbuf; 01931 } else { 01932 pbx_retrieve_variable(c, vars.name[i], &ret, valbuf, sizeof(valbuf), NULL); 01933 } 01934 01935 ast_str_append(&str, 0, "Variable: %s=%s\r\n", vars.name[i], ret); 01936 } 01937 } 01938 01939 channels++; 01940 if (c->_bridge) 01941 snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid); 01942 else 01943 bridge[0] = '\0'; 01944 if (c->pbx) { 01945 if (c->cdr) { 01946 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01947 } 01948 astman_append(s, 01949 "Event: Status\r\n" 01950 "Privilege: Call\r\n" 01951 "Channel: %s\r\n" 01952 "CallerIDNum: %s\r\n" 01953 "CallerIDName: %s\r\n" 01954 "Accountcode: %s\r\n" 01955 "ChannelState: %d\r\n" 01956 "ChannelStateDesc: %s\r\n" 01957 "Context: %s\r\n" 01958 "Extension: %s\r\n" 01959 "Priority: %d\r\n" 01960 "Seconds: %ld\r\n" 01961 "%s" 01962 "Uniqueid: %s\r\n" 01963 "%s" 01964 "%s" 01965 "\r\n", 01966 c->name, 01967 S_OR(c->cid.cid_num, ""), 01968 S_OR(c->cid.cid_name, ""), 01969 c->accountcode, 01970 c->_state, 01971 ast_state2str(c->_state), c->context, 01972 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, str->str, idText); 01973 } else { 01974 astman_append(s, 01975 "Event: Status\r\n" 01976 "Privilege: Call\r\n" 01977 "Channel: %s\r\n" 01978 "CallerIDNum: %s\r\n" 01979 "CallerIDName: %s\r\n" 01980 "Account: %s\r\n" 01981 "State: %s\r\n" 01982 "%s" 01983 "Uniqueid: %s\r\n" 01984 "%s" 01985 "%s" 01986 "\r\n", 01987 c->name, 01988 S_OR(c->cid.cid_num, "<unknown>"), 01989 S_OR(c->cid.cid_name, "<unknown>"), 01990 c->accountcode, 01991 ast_state2str(c->_state), bridge, c->uniqueid, str->str, idText); 01992 } 01993 ast_channel_unlock(c); 01994 if (!all) 01995 break; 01996 c = ast_channel_walk_locked(c); 01997 } 01998 astman_append(s, 01999 "Event: StatusComplete\r\n" 02000 "%s" 02001 "Items: %d\r\n" 02002 "\r\n", idText, channels); 02003 ast_free(str); 02004 return 0; 02005 }
| static int action_timeout | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2594 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().
02595 { 02596 struct ast_channel *c; 02597 const char *name = astman_get_header(m, "Channel"); 02598 double timeout = atof(astman_get_header(m, "Timeout")); 02599 struct timeval when = { timeout, 0 }; 02600 02601 if (ast_strlen_zero(name)) { 02602 astman_send_error(s, m, "No channel specified"); 02603 return 0; 02604 } 02605 if (!timeout || timeout < 0) { 02606 astman_send_error(s, m, "No timeout specified"); 02607 return 0; 02608 } 02609 c = ast_get_channel_by_name_locked(name); 02610 if (!c) { 02611 astman_send_error(s, m, "No such channel"); 02612 return 0; 02613 } 02614 02615 when.tv_usec = (timeout - when.tv_sec) * 1000000.0; 02616 ast_channel_setwhentohangup_tv(c, when); 02617 ast_channel_unlock(c); 02618 astman_send_ack(s, m, "Timeout Set"); 02619 return 0; 02620 }
| 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 2657 of file manager.c.
References ast_str_append(), ast_str_reset(), ast_str_thread_get(), astman_get_header(), EVENT_FLAG_USER, message::hdrcount, message::headers, manager_event, and ast_str::str.
Referenced by __init_manager().
02658 { 02659 const char *event = astman_get_header(m, "UserEvent"); 02660 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16); 02661 int x; 02662 02663 ast_str_reset(body); 02664 02665 for (x = 0; x < m->hdrcount; x++) { 02666 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 02667 ast_str_append(&body, 0, "%s\r\n", m->headers[x]); 02668 } 02669 } 02670 02671 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body->str); 02672 return 0; 02673 }
| 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 3238 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().
03239 { 03240 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 03241 static int seq; /* sequence number */ 03242 03243 if (!tmp) 03244 return -1; 03245 03246 /* need to init all fields, because ast_malloc() does not */ 03247 tmp->usecount = 0; 03248 tmp->category = category; 03249 tmp->seq = ast_atomic_fetchadd_int(&seq, 1); 03250 AST_LIST_NEXT(tmp, eq_next) = NULL; 03251 strcpy(tmp->eventdata, str); 03252 03253 AST_LIST_LOCK(&all_events); 03254 AST_LIST_INSERT_TAIL(&all_events, tmp, eq_next); 03255 AST_LIST_UNLOCK(&all_events); 03256 03257 return 0; 03258 }
| 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 3409 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().
03410 { 03411 struct manager_action *cur = NULL; 03412 03413 if (!(cur = ast_calloc(1, sizeof(*cur)))) 03414 return -1; 03415 03416 cur->action = action; 03417 cur->authority = auth; 03418 cur->func = func; 03419 cur->synopsis = synopsis; 03420 cur->description = description; 03421 03422 if (ast_manager_register_struct(cur)) { 03423 ast_free(cur); 03424 return -1; 03425 } 03426 03427 return 0; 03428 }
| 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 3373 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().
03374 { 03375 struct manager_action *cur, *prev = NULL; 03376 struct timespec tv = { 5, }; 03377 03378 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03379 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03380 return -1; 03381 } 03382 AST_RWLIST_TRAVERSE(&actions, cur, list) { 03383 int ret = strcasecmp(cur->action, act->action); 03384 if (ret == 0) { 03385 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 03386 AST_RWLIST_UNLOCK(&actions); 03387 return -1; 03388 } 03389 if (ret > 0) { /* Insert these alphabetically */ 03390 prev = cur; 03391 break; 03392 } 03393 } 03394 03395 if (prev) 03396 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list); 03397 else 03398 AST_RWLIST_INSERT_HEAD(&actions, act, list); 03399 03400 ast_verb(2, "Manager registered action %s\n", act->action); 03401 03402 AST_RWLIST_UNLOCK(&actions); 03403 03404 return 0; 03405 }
| int ast_manager_unregister | ( | char * | action | ) |
Unregister a registered manager command.
| action | Name of registered Action: |
Definition at line 3340 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().
03341 { 03342 struct manager_action *cur; 03343 struct timespec tv = { 5, }; 03344 03345 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03346 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03347 return -1; 03348 } 03349 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) { 03350 if (!strcasecmp(action, cur->action)) { 03351 AST_RWLIST_REMOVE_CURRENT(list); 03352 ast_free(cur); 03353 ast_verb(2, "Manager unregistered action %s\n", action); 03354 break; 03355 } 03356 } 03357 AST_RWLIST_TRAVERSE_SAFE_END; 03358 AST_RWLIST_UNLOCK(&actions); 03359 03360 return 0; 03361 }
| 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(), 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 2191 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().
02192 { 02193 char *cmd_copy, *cur_cmd; 02194 char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, }; 02195 int i; 02196 02197 cmd_copy = ast_strdupa(cmd); 02198 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) { 02199 cur_cmd = ast_strip(cur_cmd); 02200 if (ast_strlen_zero(cur_cmd)) { 02201 i--; 02202 continue; 02203 } 02204 02205 cmd_words[i] = cur_cmd; 02206 } 02207 02208 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) { 02209 int j, match = 1; 02210 02211 for (j = 0; command_blacklist[i].words[j]; j++) { 02212 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) { 02213 match = 0; 02214 break; 02215 } 02216 } 02217 02218 if (match) { 02219 return 1; 02220 } 02221 } 02222 02223 return 0; 02224 }
| 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 3102 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().
03103 { 03104 struct message m = { 0 }; 03105 char header_buf[sizeof(s->session->inbuf)] = { '\0' }; 03106 int res; 03107 03108 for (;;) { 03109 /* Check if any events are pending and do them if needed */ 03110 if (process_events(s)) 03111 return -1; 03112 res = get_input(s, header_buf); 03113 if (res == 0) { 03114 continue; 03115 } else if (res > 0) { 03116 if (ast_strlen_zero(header_buf)) 03117 return process_message(s, &m) ? -1 : 0; 03118 else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) 03119 m.headers[m.hdrcount++] = ast_strdupa(header_buf); 03120 } else { 03121 return res; 03122 } 03123 } 03124 }
| static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 2302 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().
02303 { 02304 struct fast_originate_helper *in = data; 02305 int res; 02306 int reason = 0; 02307 struct ast_channel *chan = NULL; 02308 char requested_channel[AST_CHANNEL_NAME]; 02309 02310 if (!ast_strlen_zero(in->app)) { 02311 res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1, 02312 S_OR(in->cid_num, NULL), 02313 S_OR(in->cid_name, NULL), 02314 in->vars, in->account, &chan); 02315 } else { 02316 res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 02317 S_OR(in->cid_num, NULL), 02318 S_OR(in->cid_name, NULL), 02319 in->vars, in->account, &chan); 02320 } 02321 02322 if (!chan) 02323 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 02324 /* Tell the manager what happened with the channel */ 02325 manager_event(EVENT_FLAG_CALL, "OriginateResponse", 02326 "%s%s" 02327 "Response: %s\r\n" 02328 "Channel: %s\r\n" 02329 "Context: %s\r\n" 02330 "Exten: %s\r\n" 02331 "Reason: %d\r\n" 02332 "Uniqueid: %s\r\n" 02333 "CallerIDNum: %s\r\n" 02334 "CallerIDName: %s\r\n", 02335 in->idtext, ast_strlen_zero(in->idtext) ? "" : "\r\n", res ? "Failure" : "Success", 02336 chan ? chan->name : requested_channel, in->context, in->exten, reason, 02337 chan ? chan->uniqueid : "<null>", 02338 S_OR(in->cid_num, "<unknown>"), 02339 S_OR(in->cid_name, "<unknown>") 02340 ); 02341 02342 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 02343 if (chan) 02344 ast_channel_unlock(chan); 02345 ast_free(in); 02346 return NULL; 02347 }
| 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 3032 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().
03033 { 03034 int res, x; 03035 int maxlen = sizeof(s->session->inbuf) - 1; 03036 char *src = s->session->inbuf; 03037 03038 /* 03039 * Look for \r\n within the buffer. If found, copy to the output 03040 * buffer and return, trimming the \r\n (not used afterwards). 03041 */ 03042 for (x = 0; x < s->session->inlen; x++) { 03043 int cr; /* set if we have \r */ 03044 if (src[x] == '\r' && x+1 < s->session->inlen && src[x+1] == '\n') 03045 cr = 2; /* Found. Update length to include \r\n */ 03046 else if (src[x] == '\n') 03047 cr = 1; /* also accept \n only */ 03048 else 03049 continue; 03050 memmove(output, src, x); /*... but trim \r\n */ 03051 output[x] = '\0'; /* terminate the string */ 03052 x += cr; /* number of bytes used */ 03053 s->session->inlen -= x; /* remaining size */ 03054 memmove(src, src + x, s->session->inlen); /* remove used bytes */ 03055 return 1; 03056 } 03057 if (s->session->inlen >= maxlen) { 03058 /* no crlf found, and buffer full - sorry, too long for us */ 03059 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src); 03060 s->session->inlen = 0; 03061 } 03062 res = 0; 03063 while (res == 0) { 03064 /* XXX do we really need this locking ? */ 03065 ast_mutex_lock(&s->session->__lock); 03066 if (s->session->pending_event) { 03067 s->session->pending_event = 0; 03068 ast_mutex_unlock(&s->session->__lock); 03069 return 0; 03070 } 03071 s->session->waiting_thread = pthread_self(); 03072 ast_mutex_unlock(&s->session->__lock); 03073 03074 res = ast_wait_for_input(s->session->fd, -1); /* return 0 on timeout ? */ 03075 03076 ast_mutex_lock(&s->session->__lock); 03077 s->session->waiting_thread = AST_PTHREADT_NULL; 03078 ast_mutex_unlock(&s->session->__lock); 03079 } 03080 if (res < 0) { 03081 /* If we get a signal from some other thread (typically because 03082 * there are new events queued), return 0 to notify the caller. 03083 */ 03084 if (errno == EINTR || errno == EAGAIN) 03085 return 0; 03086 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno)); 03087 return -1; 03088 } 03089 ast_mutex_lock(&s->session->__lock); 03090 res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f); 03091 if (res < 1) 03092 res = -1; /* error return */ 03093 else { 03094 s->session->inlen += res; 03095 src[s->session->inlen] = '\0'; 03096 res = 0; 03097 } 03098 ast_mutex_unlock(&s->session->__lock); 03099 return res; 03100 }
| 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 2856 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().
02857 { 02858 int res; 02859 const char *module = astman_get_header(m, "Module"); 02860 const char *id = astman_get_header(m, "ActionID"); 02861 char idText[256]; 02862 #if !defined(LOW_MEMORY) 02863 const char *version; 02864 #endif 02865 char filename[PATH_MAX]; 02866 char *cut; 02867 02868 ast_copy_string(filename, module, sizeof(filename)); 02869 if ((cut = strchr(filename, '.'))) { 02870 *cut = '\0'; 02871 } else { 02872 cut = filename + strlen(filename); 02873 } 02874 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so"); 02875 ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename); 02876 res = ast_module_check(filename); 02877 if (!res) { 02878 astman_send_error(s, m, "Module not loaded"); 02879 return 0; 02880 } 02881 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c"); 02882 ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename); 02883 #if !defined(LOW_MEMORY) 02884 version = ast_file_version_find(filename); 02885 #endif 02886 02887 if (!ast_strlen_zero(id)) 02888 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02889 else 02890 idText[0] = '\0'; 02891 astman_append(s, "Response: Success\r\n%s", idText); 02892 #if !defined(LOW_MEMORY) 02893 astman_append(s, "Version: %s\r\n\r\n", version ? version : ""); 02894 #endif 02895 return 0; 02896 }
| static int manager_moduleload | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2909 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().
02910 { 02911 int res; 02912 const char *module = astman_get_header(m, "Module"); 02913 const char *loadtype = astman_get_header(m, "LoadType"); 02914 02915 if (!loadtype || strlen(loadtype) == 0) 02916 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02917 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) 02918 astman_send_error(s, m, "Need module name"); 02919 02920 if (!strcasecmp(loadtype, "load")) { 02921 res = ast_load_resource(module); 02922 if (res) 02923 astman_send_error(s, m, "Could not load module."); 02924 else 02925 astman_send_ack(s, m, "Module loaded."); 02926 } else if (!strcasecmp(loadtype, "unload")) { 02927 res = ast_unload_resource(module, AST_FORCE_SOFT); 02928 if (res) 02929 astman_send_error(s, m, "Could not unload module."); 02930 else 02931 astman_send_ack(s, m, "Module unloaded."); 02932 } else if (!strcasecmp(loadtype, "reload")) { 02933 if (module != NULL) { 02934 res = ast_module_reload(module); 02935 if (res == 0) 02936 astman_send_error(s, m, "No such module."); 02937 else if (res == 1) 02938 astman_send_error(s, m, "Module does not support reload action."); 02939 else 02940 astman_send_ack(s, m, "Module reloaded."); 02941 } else { 02942 ast_module_reload(NULL); /* Reload all modules */ 02943 astman_send_ack(s, m, "All modules reloaded"); 02944 } 02945 } else 02946 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02947 return 0; 02948 }
| static int manager_state_cb | ( | char * | context, | |
| char * | exten, | |||
| int | state, | |||
| void * | data | |||
| ) | [static] |
Definition at line 3363 of file manager.c.
References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.
Referenced by __init_manager().
03364 { 03365 /* Notify managers of change */ 03366 char hint[512]; 03367 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten); 03368 03369 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state); 03370 return 0; 03371 }
| 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 2627 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().
02628 { 02629 int ret = 0; 02630 02631 ast_mutex_lock(&s->session->__lock); 02632 if (s->session->f != NULL) { 02633 struct eventqent *eqe; 02634 02635 while ( (eqe = NEW_EVENT(s)) ) { 02636 ref_event(eqe); 02637 if (!ret && s->session->authenticated && 02638 (s->session->readperm & eqe->category) == eqe->category && 02639 (s->session->send_events & eqe->category) == eqe->category) { 02640 if (send_string(s, eqe->eventdata) < 0) 02641 ret = -1; /* don't send more */ 02642 } 02643 s->session->last_ev = unref_event(s->session->last_ev); 02644 } 02645 } 02646 ast_mutex_unlock(&s->session->__lock); 02647 return ret; 02648 }
| static int process_message | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2963 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().
02964 { 02965 char action[80] = ""; 02966 int ret = 0; 02967 struct manager_action *tmp; 02968 const char *user = astman_get_header(m, "Username"); 02969 02970 ast_copy_string(action, __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY), sizeof(action)); 02971 ast_debug(1, "Manager received command '%s'\n", action); 02972 02973 if (ast_strlen_zero(action)) { 02974 ast_mutex_lock(&s->session->__lock); 02975 astman_send_error(s, m, "Missing action in request"); 02976 ast_mutex_unlock(&s->session->__lock); 02977 return 0; 02978 } 02979 02980 if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) { 02981 ast_mutex_lock(&s->session->__lock); 02982 astman_send_error(s, m, "Permission denied"); 02983 ast_mutex_unlock(&s->session->__lock); 02984 return 0; 02985 } 02986 02987 if (!allowmultiplelogin && !s->session->authenticated && user && 02988 (!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) { 02989 if (check_manager_session_inuse(user)) { 02990 sleep(1); 02991 ast_mutex_lock(&s->session->__lock); 02992 astman_send_error(s, m, "Login Already In Use"); 02993 ast_mutex_unlock(&s->session->__lock); 02994 return -1; 02995 } 02996 } 02997 02998 AST_RWLIST_RDLOCK(&actions); 02999 AST_RWLIST_TRAVERSE(&actions, tmp, list) { 03000 if (strcasecmp(action, tmp->action)) 03001 continue; 03002 if (s->session->writeperm & tmp->authority || tmp->authority == 0) 03003 ret = tmp->func(s, m); 03004 else 03005 astman_send_error(s, m, "Permission denied"); 03006 break; 03007 } 03008 AST_RWLIST_UNLOCK(&actions); 03009 03010 if (!tmp) { 03011 char buf[512]; 03012 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action); 03013 ast_mutex_lock(&s->session->__lock); 03014 astman_send_error(s, m, buf); 03015 ast_mutex_unlock(&s->session->__lock); 03016 } 03017 if (ret) 03018 return ret; 03019 /* Once done with our message, deliver any pending events */ 03020 return process_events(s); 03021 }
| 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 3211 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().
03212 { 03213 struct mansession_session *session; 03214 time_t now = time(NULL); 03215 03216 AST_LIST_LOCK(&sessions); 03217 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, session, list) { 03218 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) { 03219 AST_LIST_REMOVE_CURRENT(list); 03220 ast_atomic_fetchadd_int(&num_sessions, -1); 03221 if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) { 03222 ast_verb(2, "HTTP Manager '%s' timed out from %s\n", 03223 session->username, ast_inet_ntoa(session->sin.sin_addr)); 03224 } 03225 free_session(session); /* XXX outside ? */ 03226 if (--n_max <= 0) 03227 break; 03228 } 03229 } 03230 AST_LIST_TRAVERSE_SAFE_END; 03231 AST_LIST_UNLOCK(&sessions); 03232 }
| 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 3134 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.
03135 { 03136 struct ast_tcptls_session_instance *ser = data; 03137 struct mansession_session *session = ast_calloc(1, sizeof(*session)); 03138 struct mansession s = {.session = NULL, }; 03139 int flags; 03140 int res; 03141 03142 if (session == NULL) 03143 goto done; 03144 03145 session->writetimeout = 100; 03146 session->waiting_thread = AST_PTHREADT_NULL; 03147 03148 flags = fcntl(ser->fd, F_GETFL); 03149 if (!block_sockets) /* make sure socket is non-blocking */ 03150 flags |= O_NONBLOCK; 03151 else 03152 flags &= ~O_NONBLOCK; 03153 fcntl(ser->fd, F_SETFL, flags); 03154 03155 ast_mutex_init(&session->__lock); 03156 session->send_events = -1; 03157 /* Hook to the tail of the event queue */ 03158 session->last_ev = grab_last(); 03159 03160 /* these fields duplicate those in the 'ser' structure */ 03161 session->fd = ser->fd; 03162 session->f = ser->f; 03163 session->sin = ser->remote_address; 03164 s.session = session; 03165 03166 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores); 03167 03168 AST_LIST_LOCK(&sessions); 03169 AST_LIST_INSERT_HEAD(&sessions, session, list); 03170 ast_atomic_fetchadd_int(&num_sessions, 1); 03171 AST_LIST_UNLOCK(&sessions); 03172 03173 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */ 03174 for (;;) { 03175 if ((res = do_message(&s)) < 0) 03176 break; 03177 } 03178 /* session is over, explain why and terminate */ 03179 if (session->authenticated) { 03180 if (manager_displayconnects(session)) 03181 ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 03182 ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 03183 } else { 03184 if (displayconnects) 03185 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr)); 03186 ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(session->sin.sin_addr)); 03187 } 03188 03189 /* It is possible under certain circumstances for this session thread 03190 to complete its work and exit *before* the thread that created it 03191 has finished executing the ast_pthread_create_background() function. 03192 If this occurs, some versions of glibc appear to act in a buggy 03193 fashion and attempt to write data into memory that it thinks belongs 03194 to the thread but is in fact not owned by the thread (or may have 03195 been freed completely). 03196 03197 Causing this thread to yield to other threads at least one time 03198 appears to work around this bug. 03199 */ 03200 usleep(1); 03201 03202 destroy_session(session); 03203 03204 done: 03205 ao2_ref(ser, -1); 03206 ser = NULL; 03207 return NULL; 03208 }
| 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 2134 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 2226 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 2675 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 2778 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 2721 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 2552 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 1815 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 2519 of file manager.c.
Referenced by __init_manager().
char mandescr_mailboxstatus[] [static] |
Help text for manager command mailboxstatus.
Definition at line 2491 of file manager.c.
Referenced by __init_manager().
char mandescr_modulecheck[] [static] |
Definition at line 2846 of file manager.c.
Referenced by __init_manager().
char mandescr_moduleload[] [static] |
Definition at line 2898 of file manager.c.
Referenced by __init_manager().
char mandescr_originate[] [static] |
Definition at line 2349 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 2048 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 2759 of file manager.c.
Referenced by __init_manager().
char mandescr_sendtext[] [static] |
Definition at line 2007 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 1867 of file manager.c.
Referenced by __init_manager().
char mandescr_timeout[] [static] |
Definition at line 2587 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 2650 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