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 3265 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 3268 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.
03270 { 03271 struct mansession_session *session; 03272 struct manager_custom_hook *hook; 03273 struct ast_str *auth = ast_str_alloca(80); 03274 const char *cat_str; 03275 va_list ap; 03276 struct timeval now; 03277 struct ast_str *buf; 03278 03279 /* Abort if there aren't any manager sessions */ 03280 if (!num_sessions) 03281 return 0; 03282 03283 if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) 03284 return -1; 03285 03286 cat_str = authority_to_str(category, &auth); 03287 ast_str_set(&buf, 0, 03288 "Event: %s\r\nPrivilege: %s\r\n", 03289 event, cat_str); 03290 03291 if (timestampevents) { 03292 now = ast_tvnow(); 03293 ast_str_append(&buf, 0, 03294 "Timestamp: %ld.%06lu\r\n", 03295 (long)now.tv_sec, (unsigned long) now.tv_usec); 03296 } 03297 if (manager_debug) { 03298 static int seq; 03299 ast_str_append(&buf, 0, 03300 "SequenceNumber: %d\r\n", 03301 ast_atomic_fetchadd_int(&seq, 1)); 03302 ast_str_append(&buf, 0, 03303 "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func); 03304 } 03305 03306 va_start(ap, fmt); 03307 ast_str_append_va(&buf, 0, fmt, ap); 03308 va_end(ap); 03309 03310 ast_str_append(&buf, 0, "\r\n"); 03311 03312 append_event(buf->str, category); 03313 03314 /* Wake up any sleeping sessions */ 03315 AST_LIST_LOCK(&sessions); 03316 AST_LIST_TRAVERSE(&sessions, session, list) { 03317 ast_mutex_lock(&session->__lock); 03318 if (session->waiting_thread != AST_PTHREADT_NULL) 03319 pthread_kill(session->waiting_thread, SIGURG); 03320 else 03321 /* We have an event to process, but the mansession is 03322 * not waiting for it. We still need to indicate that there 03323 * is an event waiting so that get_input processes the pending 03324 * event instead of polling. 03325 */ 03326 session->pending_event = 1; 03327 ast_mutex_unlock(&session->__lock); 03328 } 03329 AST_LIST_UNLOCK(&sessions); 03330 03331 AST_RWLIST_RDLOCK(&manager_hooks); 03332 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) { 03333 hook->helper(category, event, buf->str); 03334 } 03335 AST_RWLIST_UNLOCK(&manager_hooks); 03336 03337 return 0; 03338 }
| 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; 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 fd = mkstemp(template); 02253 02254 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 02255 if (!ast_strlen_zero(id)) 02256 astman_append(s, "ActionID: %s\r\n", id); 02257 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 02258 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 02259 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 02260 02261 /* This has a potential to overflow the stack. Hence, use the heap. */ 02262 buf = ast_calloc(1, l + 1); 02263 final_buf = ast_calloc(1, l + 1); 02264 if (buf) { 02265 lseek(fd, 0, SEEK_SET); 02266 if (read(fd, buf, l) < 0) { 02267 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 02268 } 02269 buf[l] = '\0'; 02270 if (final_buf) { 02271 term_strip(final_buf, buf, l); 02272 final_buf[l] = '\0'; 02273 } 02274 astman_append(s, "%s", S_OR(final_buf, buf)); 02275 ast_free(buf); 02276 } 02277 close(fd); 02278 unlink(template); 02279 astman_append(s, "--END COMMAND--\r\n\r\n"); 02280 if (final_buf) 02281 ast_free(final_buf); 02282 return 0; 02283 }
| static int action_coresettings | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show PBX core settings information.
Definition at line 2684 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().
02685 { 02686 const char *actionid = astman_get_header(m, "ActionID"); 02687 char idText[150]; 02688 02689 if (!ast_strlen_zero(actionid)) 02690 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02691 else 02692 idText[0] = '\0'; 02693 02694 astman_append(s, "Response: Success\r\n" 02695 "%s" 02696 "AMIversion: %s\r\n" 02697 "AsteriskVersion: %s\r\n" 02698 "SystemName: %s\r\n" 02699 "CoreMaxCalls: %d\r\n" 02700 "CoreMaxLoadAvg: %f\r\n" 02701 "CoreRunUser: %s\r\n" 02702 "CoreRunGroup: %s\r\n" 02703 "CoreMaxFilehandles: %d\r\n" 02704 "CoreRealTimeEnabled: %s\r\n" 02705 "CoreCDRenabled: %s\r\n" 02706 "CoreHTTPenabled: %s\r\n" 02707 "\r\n", 02708 idText, 02709 AMI_VERSION, 02710 ast_get_version(), 02711 ast_config_AST_SYSTEM_NAME, 02712 option_maxcalls, 02713 option_maxload, 02714 ast_config_AST_RUN_USER, 02715 ast_config_AST_RUN_GROUP, 02716 option_maxfiles, 02717 ast_realtime_enabled() ? "Yes" : "No", 02718 check_cdr_enabled() ? "Yes" : "No", 02719 check_webmanager_enabled() ? "Yes" : "No" 02720 ); 02721 return 0; 02722 }
| 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 2789 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().
02790 { 02791 const char *actionid = astman_get_header(m, "ActionID"); 02792 char actionidtext[256]; 02793 struct ast_channel *c = NULL; 02794 int numchans = 0; 02795 int duration, durh, durm, durs; 02796 02797 if (!ast_strlen_zero(actionid)) 02798 snprintf(actionidtext, sizeof(actionidtext), "ActionID: %s\r\n", actionid); 02799 else 02800 actionidtext[0] = '\0'; 02801 02802 astman_send_listack(s, m, "Channels will follow", "start"); 02803 02804 while ((c = ast_channel_walk_locked(c)) != NULL) { 02805 struct ast_channel *bc = ast_bridged_channel(c); 02806 char durbuf[10] = ""; 02807 02808 if (c->cdr && !ast_tvzero(c->cdr->start)) { 02809 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 02810 durh = duration / 3600; 02811 durm = (duration % 3600) / 60; 02812 durs = duration % 60; 02813 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 02814 } 02815 02816 astman_append(s, 02817 "Event: CoreShowChannel\r\n" 02818 "Channel: %s\r\n" 02819 "UniqueID: %s\r\n" 02820 "Context: %s\r\n" 02821 "Extension: %s\r\n" 02822 "Priority: %d\r\n" 02823 "ChannelState: %d\r\n" 02824 "ChannelStateDesc: %s\r\n" 02825 "Application: %s\r\n" 02826 "ApplicationData: %s\r\n" 02827 "CallerIDnum: %s\r\n" 02828 "Duration: %s\r\n" 02829 "AccountCode: %s\r\n" 02830 "BridgedChannel: %s\r\n" 02831 "BridgedUniqueID: %s\r\n" 02832 "\r\n", c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, ast_state2str(c->_state), 02833 c->appl ? c->appl : "", c->data ? S_OR(c->data, ""): "", 02834 S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : ""); 02835 ast_channel_unlock(c); 02836 numchans++; 02837 } 02838 02839 astman_append(s, 02840 "Event: CoreShowChannelsComplete\r\n" 02841 "EventList: Complete\r\n" 02842 "ListItems: %d\r\n" 02843 "%s" 02844 "\r\n", numchans, actionidtext); 02845 02846 return 0; 02847 }
| static int action_corestatus | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Show PBX core status information.
Definition at line 2730 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().
02731 { 02732 const char *actionid = astman_get_header(m, "ActionID"); 02733 char idText[150]; 02734 char startuptime[150]; 02735 char reloadtime[150]; 02736 struct ast_tm tm; 02737 02738 if (!ast_strlen_zero(actionid)) 02739 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02740 else 02741 idText[0] = '\0'; 02742 02743 ast_localtime(&ast_startuptime, &tm, NULL); 02744 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm); 02745 ast_localtime(&ast_lastreloadtime, &tm, NULL); 02746 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm); 02747 02748 astman_append(s, "Response: Success\r\n" 02749 "%s" 02750 "CoreStartupTime: %s\r\n" 02751 "CoreReloadTime: %s\r\n" 02752 "CoreCurrentCalls: %d\r\n" 02753 "\r\n", 02754 idText, 02755 startuptime, 02756 reloadtime, 02757 ast_active_channels() 02758 ); 02759 return 0; 02760 }
| static int action_createconfig | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1548 of file manager.c.
References ast_config_AST_CONFIG_DIR, AST_FILE_MODE, ast_str_alloca, ast_str_append(), ast_str_set(), astman_get_header(), astman_send_ack(), astman_send_error(), errno, and ast_str::str.
Referenced by __init_manager().
01549 { 01550 int fd; 01551 const char *fn = astman_get_header(m, "Filename"); 01552 struct ast_str *filepath = ast_str_alloca(PATH_MAX); 01553 ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR); 01554 ast_str_append(&filepath, 0, "%s", fn); 01555 01556 if ((fd = open(filepath->str, O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) { 01557 close(fd); 01558 astman_send_ack(s, m, "New configuration file created successfully"); 01559 } else 01560 astman_send_error(s, m, strerror(errno)); 01561 01562 return 0; 01563 }
| static int action_events | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1697 of file manager.c.
References astman_append(), astman_get_header(), and set_eventmask().
Referenced by __init_manager().
01698 { 01699 const char *mask = astman_get_header(m, "EventMask"); 01700 int res; 01701 01702 res = set_eventmask(s, mask); 01703 if (res > 0) 01704 astman_append(s, "Response: Success\r\n" 01705 "Events: On\r\n\r\n"); 01706 else if (res == 0) 01707 astman_append(s, "Response: Success\r\n" 01708 "Events: Off\r\n\r\n"); 01709 return 0; 01710 }
| static int action_extensionstate | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2565 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().
02566 { 02567 const char *exten = astman_get_header(m, "Exten"); 02568 const char *context = astman_get_header(m, "Context"); 02569 char hint[256] = ""; 02570 int status; 02571 if (ast_strlen_zero(exten)) { 02572 astman_send_error(s, m, "Extension not specified"); 02573 return 0; 02574 } 02575 if (ast_strlen_zero(context)) 02576 context = "default"; 02577 status = ast_extension_state(NULL, context, exten); 02578 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 02579 astman_start_ack(s, m); 02580 astman_append(s, "Message: Extension Status\r\n" 02581 "Exten: %s\r\n" 02582 "Context: %s\r\n" 02583 "Hint: %s\r\n" 02584 "Status: %d\r\n\r\n", 02585 exten, context, hint, status); 02586 return 0; 02587 }
| 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 2533 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().
02534 { 02535 const char *mailbox = astman_get_header(m, "Mailbox"); 02536 int newmsgs = 0, oldmsgs = 0, urgentmsgs = 0;; 02537 02538 if (ast_strlen_zero(mailbox)) { 02539 astman_send_error(s, m, "Mailbox not specified"); 02540 return 0; 02541 } 02542 ast_app_inboxcount2(mailbox, &urgentmsgs, &newmsgs, &oldmsgs); 02543 astman_start_ack(s, m); 02544 astman_append(s, "Message: Mailbox Message Count\r\n" 02545 "Mailbox: %s\r\n" 02546 "UrgMessages: %d\r\n" 02547 "NewMessages: %d\r\n" 02548 "OldMessages: %d\r\n" 02549 "\r\n", 02550 mailbox, urgentmsgs, newmsgs, oldmsgs); 02551 return 0; 02552 }
| static int action_mailboxstatus | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2504 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().
02505 { 02506 const char *mailbox = astman_get_header(m, "Mailbox"); 02507 int ret; 02508 02509 if (ast_strlen_zero(mailbox)) { 02510 astman_send_error(s, m, "Mailbox not specified"); 02511 return 0; 02512 } 02513 ret = ast_app_has_voicemail(mailbox, NULL); 02514 astman_start_ack(s, m); 02515 astman_append(s, "Message: Mailbox Status\r\n" 02516 "Mailbox: %s\r\n" 02517 "Waiting: %d\r\n\r\n", mailbox, ret); 02518 return 0; 02519 }
| static int action_originate | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2367 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().
02368 { 02369 const char *name = astman_get_header(m, "Channel"); 02370 const char *exten = astman_get_header(m, "Exten"); 02371 const char *context = astman_get_header(m, "Context"); 02372 const char *priority = astman_get_header(m, "Priority"); 02373 const char *timeout = astman_get_header(m, "Timeout"); 02374 const char *callerid = astman_get_header(m, "CallerID"); 02375 const char *account = astman_get_header(m, "Account"); 02376 const char *app = astman_get_header(m, "Application"); 02377 const char *appdata = astman_get_header(m, "Data"); 02378 const char *async = astman_get_header(m, "Async"); 02379 const char *id = astman_get_header(m, "ActionID"); 02380 const char *codecs = astman_get_header(m, "Codecs"); 02381 struct ast_variable *vars = astman_get_variables(m); 02382 char *tech, *data; 02383 char *l = NULL, *n = NULL; 02384 int pi = 0; 02385 int res; 02386 int to = 30000; 02387 int reason = 0; 02388 char tmp[256]; 02389 char tmp2[256]; 02390 int format = AST_FORMAT_SLINEAR; 02391 02392 pthread_t th; 02393 if (ast_strlen_zero(name)) { 02394 astman_send_error(s, m, "Channel not specified"); 02395 return 0; 02396 } 02397 if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) { 02398 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 02399 astman_send_error(s, m, "Invalid priority"); 02400 return 0; 02401 } 02402 } 02403 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) { 02404 astman_send_error(s, m, "Invalid timeout"); 02405 return 0; 02406 } 02407 ast_copy_string(tmp, name, sizeof(tmp)); 02408 tech = tmp; 02409 data = strchr(tmp, '/'); 02410 if (!data) { 02411 astman_send_error(s, m, "Invalid channel"); 02412 return 0; 02413 } 02414 *data++ = '\0'; 02415 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 02416 ast_callerid_parse(tmp2, &n, &l); 02417 if (n) { 02418 if (ast_strlen_zero(n)) 02419 n = NULL; 02420 } 02421 if (l) { 02422 ast_shrink_phone_number(l); 02423 if (ast_strlen_zero(l)) 02424 l = NULL; 02425 } 02426 if (!ast_strlen_zero(codecs)) { 02427 format = 0; 02428 ast_parse_allow_disallow(NULL, &format, codecs, 1); 02429 } 02430 if (ast_true(async)) { 02431 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 02432 if (!fast) { 02433 res = -1; 02434 } else { 02435 if (!ast_strlen_zero(id)) 02436 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s", id); 02437 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 02438 ast_copy_string(fast->data, data, sizeof(fast->data)); 02439 ast_copy_string(fast->app, app, sizeof(fast->app)); 02440 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 02441 if (l) 02442 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 02443 if (n) 02444 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 02445 fast->vars = vars; 02446 ast_copy_string(fast->context, context, sizeof(fast->context)); 02447 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 02448 ast_copy_string(fast->account, account, sizeof(fast->account)); 02449 fast->format = format; 02450 fast->timeout = to; 02451 fast->priority = pi; 02452 if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) { 02453 ast_free(fast); 02454 res = -1; 02455 } else { 02456 res = 0; 02457 } 02458 } 02459 } else if (!ast_strlen_zero(app)) { 02460 /* To run the System application (or anything else that goes to shell), you must have the additional System privilege */ 02461 if (!(s->session->writeperm & EVENT_FLAG_SYSTEM) 02462 && ( 02463 strcasestr(app, "system") == 0 || /* System(rm -rf /) 02464 TrySystem(rm -rf /) */ 02465 strcasestr(app, "exec") || /* Exec(System(rm -rf /)) 02466 TryExec(System(rm -rf /)) */ 02467 strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /) 02468 EAGI(/bin/rm,-rf /) */ 02469 strstr(appdata, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */ 02470 strstr(appdata, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */ 02471 )) { 02472 astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have."); 02473 return 0; 02474 } 02475 res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 02476 } else { 02477 if (exten && context && pi) 02478 res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 02479 else { 02480 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 02481 return 0; 02482 } 02483 } 02484 if (!res) 02485 astman_send_ack(s, m, "Originate successfully queued"); 02486 else 02487 astman_send_error(s, m, "Originate failed"); 02488 return 0; 02489 }
| 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 2769 of file manager.c.
References ast_module_reload(), astman_get_header(), astman_send_ack(), astman_send_error(), and S_OR.
Referenced by __init_manager().
02770 { 02771 const char *module = astman_get_header(m, "Module"); 02772 int res = ast_module_reload(S_OR(module, NULL)); 02773 02774 if (res == 2) 02775 astman_send_ack(s, m, "Module Reloaded"); 02776 else 02777 astman_send_error(s, m, s == 0 ? "No such module" : "Module does not support reload"); 02778 return 0; 02779 }
| 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 2596 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().
02597 { 02598 struct ast_channel *c; 02599 const char *name = astman_get_header(m, "Channel"); 02600 double timeout = atof(astman_get_header(m, "Timeout")); 02601 struct timeval when = { timeout, 0 }; 02602 02603 if (ast_strlen_zero(name)) { 02604 astman_send_error(s, m, "No channel specified"); 02605 return 0; 02606 } 02607 if (!timeout || timeout < 0) { 02608 astman_send_error(s, m, "No timeout specified"); 02609 return 0; 02610 } 02611 c = ast_get_channel_by_name_locked(name); 02612 if (!c) { 02613 astman_send_error(s, m, "No such channel"); 02614 return 0; 02615 } 02616 02617 when.tv_usec = (timeout - when.tv_sec) * 1000000.0; 02618 ast_channel_setwhentohangup_tv(c, when); 02619 ast_channel_unlock(c); 02620 astman_send_ack(s, m, "Timeout Set"); 02621 return 0; 02622 }
| 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 2659 of file manager.c.
References ast_str_append(), ast_str_reset(), ast_str_thread_get(), astman_get_header(), astman_send_ack(), EVENT_FLAG_USER, message::hdrcount, message::headers, manager_event, and ast_str::str.
Referenced by __init_manager().
02660 { 02661 const char *event = astman_get_header(m, "UserEvent"); 02662 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16); 02663 int x; 02664 02665 ast_str_reset(body); 02666 02667 for (x = 0; x < m->hdrcount; x++) { 02668 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 02669 ast_str_append(&body, 0, "%s\r\n", m->headers[x]); 02670 } 02671 } 02672 02673 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body->str); 02674 astman_send_ack(s, m, "Event Sent"); 02675 return 0; 02676 }
| 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 3241 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().
03242 { 03243 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 03244 static int seq; /* sequence number */ 03245 03246 if (!tmp) 03247 return -1; 03248 03249 /* need to init all fields, because ast_malloc() does not */ 03250 tmp->usecount = 0; 03251 tmp->category = category; 03252 tmp->seq = ast_atomic_fetchadd_int(&seq, 1); 03253 AST_LIST_NEXT(tmp, eq_next) = NULL; 03254 strcpy(tmp->eventdata, str); 03255 03256 AST_LIST_LOCK(&all_events); 03257 AST_LIST_INSERT_TAIL(&all_events, tmp, eq_next); 03258 AST_LIST_UNLOCK(&all_events); 03259 03260 return 0; 03261 }
| 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 3412 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().
03413 { 03414 struct manager_action *cur = NULL; 03415 03416 if (!(cur = ast_calloc(1, sizeof(*cur)))) 03417 return -1; 03418 03419 cur->action = action; 03420 cur->authority = auth; 03421 cur->func = func; 03422 cur->synopsis = synopsis; 03423 cur->description = description; 03424 03425 if (ast_manager_register_struct(cur)) { 03426 ast_free(cur); 03427 return -1; 03428 } 03429 03430 return 0; 03431 }
| 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 3376 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().
03377 { 03378 struct manager_action *cur, *prev = NULL; 03379 struct timespec tv = { 5, }; 03380 03381 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03382 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03383 return -1; 03384 } 03385 AST_RWLIST_TRAVERSE(&actions, cur, list) { 03386 int ret = strcasecmp(cur->action, act->action); 03387 if (ret == 0) { 03388 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 03389 AST_RWLIST_UNLOCK(&actions); 03390 return -1; 03391 } 03392 if (ret > 0) { /* Insert these alphabetically */ 03393 prev = cur; 03394 break; 03395 } 03396 } 03397 03398 if (prev) 03399 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list); 03400 else 03401 AST_RWLIST_INSERT_HEAD(&actions, act, list); 03402 03403 ast_verb(2, "Manager registered action %s\n", act->action); 03404 03405 AST_RWLIST_UNLOCK(&actions); 03406 03407 return 0; 03408 }
| int ast_manager_unregister | ( | char * | action | ) |
Unregister a registered manager command.
| action | Name of registered Action: |
Definition at line 3343 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().
03344 { 03345 struct manager_action *cur; 03346 struct timespec tv = { 5, }; 03347 03348 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03349 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03350 return -1; 03351 } 03352 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) { 03353 if (!strcasecmp(action, cur->action)) { 03354 AST_RWLIST_REMOVE_CURRENT(list); 03355 ast_free(cur); 03356 ast_verb(2, "Manager unregistered action %s\n", action); 03357 break; 03358 } 03359 } 03360 AST_RWLIST_TRAVERSE_SAFE_END; 03361 AST_RWLIST_UNLOCK(&actions); 03362 03363 return 0; 03364 }
| void ast_manager_unregister_hook | ( | struct manager_custom_hook * | hook | ) |
Delete a custom hook to be called when an event is fired.
Delete a custom hook to be called when an event is fired
| hook | struct manager_custom_hook object to delete |
Definition at line 265 of file manager.c.
References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
00266 { 00267 AST_RWLIST_WRLOCK(&manager_hooks); 00268 AST_RWLIST_REMOVE(&manager_hooks, hook, list); 00269 AST_RWLIST_UNLOCK(&manager_hooks); 00270 return; 00271 }
| static AST_RWLIST_HEAD_STATIC | ( | manager_hooks | , | |
| manager_custom_hook | ||||
| ) | [static] |
list of hooks registered
| static AST_RWLIST_HEAD_STATIC | ( | actions | , | |
| manager_action | ||||
| ) | [static] |
list of actions registered
| static AST_RWLIST_HEAD_STATIC | ( | users | , | |
| ast_manager_user | ||||
| ) | [static] |
list of users found in the config file
| AST_THREADSTORAGE | ( | manager_event_buf | ) |
| AST_THREADSTORAGE | ( | userevent_buf | ) |
| AST_THREADSTORAGE | ( | astman_append_buf | ) |
thread local buffer for astman_append
| void astman_append | ( | struct mansession * | s, | |
| const char * | fmt, | |||
| ... | ||||
| ) |
utility functions for creating AMI replies
Definition at line 969 of file manager.c.
References ast_str_set_va(), ast_str_thread_get(), ast_verbose, ASTMAN_APPEND_BUF_INITSIZE, buf, mansession_session::f, mansession::f, send_string(), mansession::session, and ast_str::str.
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), action_agents(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_ping(), action_status(), action_waitevent(), ast_cli_netstats(), astman_send_response_full(), do_print(), manager_dbget(), manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_jabber_send(), manager_list_voicemail_users(), manager_modulecheck(), manager_parking_status(), manager_queue_rule_show(), manager_queues_show(), manager_queues_status(), manager_queues_summary(), manager_rpt_local_nodes(), manager_rpt_status(), manager_show_dialplan_helper(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), rpt_manager_do_stats(), rpt_manager_success(), and session_do().
00970 { 00971 va_list ap; 00972 struct ast_str *buf; 00973 00974 if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) 00975 return; 00976 00977 va_start(ap, fmt); 00978 ast_str_set_va(&buf, 0, fmt, ap); 00979 va_end(ap); 00980 00981 if (s->f != NULL || s->session->f != NULL) { 00982 send_string(s, buf->str); 00983 } else { 00984 ast_verbose("fd == -1 in astman_append, should not happen\n"); 00985 } 00986 }
| const char* astman_get_header | ( | const struct message * | m, | |
| char * | var | |||
| ) |
Get header from mananger transaction.
Definition at line 897 of file manager.c.
References __astman_get_header(), and GET_HEADER_FIRST_MATCH.
Referenced by _sip_show_peer(), _sip_show_peers(), action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_atxfer(), action_bridge(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), action_waitevent(), astman_send_response_full(), authenticate(), change_monitor_action(), do_pause_or_unpause(), handle_updates(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_jabber_send(), manager_list_voicemail_users(), manager_modulecheck(), manager_moduleload(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queue_rule_show(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_rpt_status(), manager_show_dialplan(), manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), meetmemute(), process_message(), rpt_manager_do_stats(), rpt_manager_success(), start_monitor_action(), and stop_monitor_action().
00898 { 00899 return __astman_get_header(m, var, GET_HEADER_FIRST_MATCH); 00900 }
| struct ast_variable* astman_get_variables | ( | const struct message * | m | ) | [read] |
Get a linked list of the Variable: headers.
Definition at line 903 of file manager.c.
References AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_variable_new(), message::hdrcount, message::headers, parse(), strsep(), and var.
Referenced by action_originate(), and manager_sipnotify().
00904 { 00905 int varlen, x, y; 00906 struct ast_variable *head = NULL, *cur; 00907 00908 AST_DECLARE_APP_ARGS(args, 00909 AST_APP_ARG(vars)[32]; 00910 ); 00911 00912 varlen = strlen("Variable: "); 00913 00914 for (x = 0; x < m->hdrcount; x++) { 00915 char *parse, *var, *val; 00916 00917 if (strncasecmp("Variable: ", m->headers[x], varlen)) 00918 continue; 00919 parse = ast_strdupa(m->headers[x] + varlen); 00920 00921 AST_STANDARD_APP_ARGS(args, parse); 00922 if (!args.argc) 00923 continue; 00924 for (y = 0; y < args.argc; y++) { 00925 if (!args.vars[y]) 00926 continue; 00927 var = val = ast_strdupa(args.vars[y]); 00928 strsep(&val, "="); 00929 if (!val || ast_strlen_zero(var)) 00930 continue; 00931 cur = ast_variable_new(var, val, ""); 00932 cur->next = head; 00933 head = cur; 00934 } 00935 } 00936 00937 return head; 00938 }
| void astman_send_ack | ( | struct mansession * | s, | |
| const struct message * | m, | |||
| char * | msg | |||
| ) |
Send ack in manager transaction.
Definition at line 1032 of file manager.c.
References astman_send_response_full().
Referenced by action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_atxfer(), action_bridge(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_dahdishowchannels(), action_hangup(), action_login(), action_originate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_iax2_show_peers(), manager_jabber_send(), manager_list_voicemail_users(), manager_moduleload(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), manager_sipnotify(), meetmemute(), start_monitor_action(), and stop_monitor_action().
01033 { 01034 astman_send_response_full(s, m, "Success", msg, NULL); 01035 }
| void astman_send_error | ( | struct mansession * | s, | |
| const struct message * | m, | |||
| char * | error | |||
| ) |
Send error in manager transaction.
Definition at line 1027 of file manager.c.
References astman_send_response_full().
Referenced by _sip_qualify_peer(), _sip_show_peer(), action_add_agi_cmd(), action_agent_logoff(), action_atxfer(), action_bridge(), action_challenge(), action_command(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_hangup(), action_listcategories(), action_login(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_originate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_modulecheck(), manager_moduleload(), manager_park(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_remove_queue_member(), manager_rpt_status(), manager_show_dialplan(), manager_show_dialplan_helper(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sipnotify(), meetmemute(), process_message(), rpt_manager_do_stats(), start_monitor_action(), and stop_monitor_action().
01028 { 01029 astman_send_response_full(s, m, "Error", error, NULL); 01030 }
| void astman_send_listack | ( | struct mansession * | s, | |
| const struct message * | m, | |||
| char * | msg, | |||
| char * | listflag | |||
| ) |
Send ack in manager list transaction.
Definition at line 1042 of file manager.c.
References astman_send_response_full().
Referenced by action_coreshowchannels(), action_meetmelist(), manager_dpsendack(), manager_show_registry(), and manager_sip_show_peers().
01043 { 01044 astman_send_response_full(s, m, "Success", msg, listflag); 01045 }
| void astman_send_response | ( | struct mansession * | s, | |
| const struct message * | m, | |||
| char * | resp, | |||
| char * | msg | |||
| ) |
Send response in manager transaction.
Definition at line 1022 of file manager.c.
References astman_send_response_full().
Referenced by action_logoff(), and action_waitevent().
01023 { 01024 astman_send_response_full(s, m, resp, msg, NULL); 01025 }
| static void astman_send_response_full | ( | struct mansession * | s, | |
| const struct message * | m, | |||
| char * | resp, | |||
| char * | msg, | |||
| char * | listflag | |||
| ) | [static] |
Definition at line 1005 of file manager.c.
References ast_strlen_zero(), astman_append(), astman_get_header(), and MSG_MOREDATA.
Referenced by astman_send_ack(), astman_send_error(), astman_send_listack(), astman_send_response(), and astman_start_ack().
01006 { 01007 const char *id = astman_get_header(m, "ActionID"); 01008 01009 astman_append(s, "Response: %s\r\n", resp); 01010 if (!ast_strlen_zero(id)) 01011 astman_append(s, "ActionID: %s\r\n", id); 01012 if (listflag) 01013 astman_append(s, "Eventlist: %s\r\n", listflag); /* Start, complete, cancelled */ 01014 if (msg == MSG_MOREDATA) 01015 return; 01016 else if (msg) 01017 astman_append(s, "Message: %s\r\n\r\n", msg); 01018 else 01019 astman_append(s, "\r\n"); 01020 }
| static void astman_start_ack | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1037 of file manager.c.
References astman_send_response_full(), and MSG_MOREDATA.
Referenced by action_challenge(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_mailboxcount(), and action_mailboxstatus().
01038 { 01039 astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL); 01040 }
| static int authenticate | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1071 of file manager.c.
References ast_apply_ha(), ast_copy_string(), ast_debug, ast_inet_ntoa(), ast_log(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), astman_get_header(), mansession_session::challenge, get_manager_by_name_locked(), ast_manager_user::ha, len(), LOG_NOTICE, MD5Final(), MD5Init(), MD5Update(), ast_manager_user::readperm, mansession_session::readperm, S_OR, ast_manager_user::secret, mansession::session, mansession_session::sessionstart, set_eventmask(), mansession_session::sin, mansession_session::username, ast_manager_user::writeperm, mansession_session::writeperm, ast_manager_user::writetimeout, and mansession_session::writetimeout.
Referenced by action_login().
01072 { 01073 const char *username = astman_get_header(m, "Username"); 01074 const char *password = astman_get_header(m, "Secret"); 01075 int error = -1; 01076 struct ast_manager_user *user = NULL; 01077 01078 if (ast_strlen_zero(username)) /* missing username */ 01079 return -1; 01080 01081 /* locate user in locked state */ 01082 AST_RWLIST_WRLOCK(&users); 01083 01084 if (!(user = get_manager_by_name_locked(username))) { 01085 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01086 } else if (user->ha && !ast_apply_ha(user->ha, &(s->session->sin))) { 01087 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01088 } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) { 01089 const char *key = astman_get_header(m, "Key"); 01090 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) { 01091 int x; 01092 int len = 0; 01093 char md5key[256] = ""; 01094 struct MD5Context md5; 01095 unsigned char digest[16]; 01096 01097 MD5Init(&md5); 01098 MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge)); 01099 MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret)); 01100 MD5Final(digest, &md5); 01101 for (x = 0; x < 16; x++) 01102 len += sprintf(md5key + len, "%2.2x", digest[x]); 01103 if (!strcmp(md5key, key)) 01104 error = 0; 01105 } else { 01106 ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n", 01107 S_OR(s->session->challenge, "")); 01108 } 01109 } else if (password && user->secret && !strcmp(password, user->secret)) 01110 error = 0; 01111 01112 if (error) { 01113 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01114 AST_RWLIST_UNLOCK(&users); 01115 return -1; 01116 } 01117 01118 /* auth complete */ 01119 01120 ast_copy_string(s->session->username, username, sizeof(s->session->username)); 01121 s->session->readperm = user->readperm; 01122 s->session->writeperm = user->writeperm; 01123 s->session->writetimeout = user->writetimeout; 01124 s->session->sessionstart = time(NULL); 01125 set_eventmask(s, astman_get_header(m, "Events")); 01126 01127 AST_RWLIST_UNLOCK(&users); 01128 return 0; 01129 }
| static char* authority_to_str | ( | int | authority, | |
| struct ast_str ** | res | |||
| ) | [static] |
Convert authority code to a list of options.
Definition at line 389 of file manager.c.
References ARRAY_LEN, ast_str_append(), num, and perms.
Referenced by __manager_event(), action_listcommands(), handle_showmanager(), handle_showmancmd(), and handle_showmancmds().
00390 { 00391 int i; 00392 char *sep = ""; 00393 00394 (*res)->used = 0; 00395 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) { 00396 if (authority & perms[i].num) { 00397 ast_str_append(res, 0, "%s%s", sep, perms[i].label); 00398 sep = ","; 00399 } 00400 } 00401 00402 if ((*res)->used == 0) /* replace empty string with something sensible */ 00403 ast_str_append(res, 0, "<none>"); 00404 00405 return (*res)->str; 00406 }
| static int check_blacklist | ( | const char * | cmd | ) | [static] |
Definition at line 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 3105 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().
03106 { 03107 struct message m = { 0 }; 03108 char header_buf[sizeof(s->session->inbuf)] = { '\0' }; 03109 int res; 03110 03111 for (;;) { 03112 /* Check if any events are pending and do them if needed */ 03113 if (process_events(s)) 03114 return -1; 03115 res = get_input(s, header_buf); 03116 if (res == 0) { 03117 continue; 03118 } else if (res > 0) { 03119 if (ast_strlen_zero(header_buf)) 03120 return process_message(s, &m) ? -1 : 0; 03121 else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) 03122 m.headers[m.hdrcount++] = ast_strdupa(header_buf); 03123 } else { 03124 return res; 03125 } 03126 } 03127 }
| static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 2304 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().
02305 { 02306 struct fast_originate_helper *in = data; 02307 int res; 02308 int reason = 0; 02309 struct ast_channel *chan = NULL; 02310 char requested_channel[AST_CHANNEL_NAME]; 02311 02312 if (!ast_strlen_zero(in->app)) { 02313 res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1, 02314 S_OR(in->cid_num, NULL), 02315 S_OR(in->cid_name, NULL), 02316 in->vars, in->account, &chan); 02317 } else { 02318 res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 02319 S_OR(in->cid_num, NULL), 02320 S_OR(in->cid_name, NULL), 02321 in->vars, in->account, &chan); 02322 } 02323 02324 if (!chan) 02325 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 02326 /* Tell the manager what happened with the channel */ 02327 manager_event(EVENT_FLAG_CALL, "OriginateResponse", 02328 "%s%s" 02329 "Response: %s\r\n" 02330 "Channel: %s\r\n" 02331 "Context: %s\r\n" 02332 "Exten: %s\r\n" 02333 "Reason: %d\r\n" 02334 "Uniqueid: %s\r\n" 02335 "CallerIDNum: %s\r\n" 02336 "CallerIDName: %s\r\n", 02337 in->idtext, ast_strlen_zero(in->idtext) ? "" : "\r\n", res ? "Failure" : "Success", 02338 chan ? chan->name : requested_channel, in->context, in->exten, reason, 02339 chan ? chan->uniqueid : "<null>", 02340 S_OR(in->cid_num, "<unknown>"), 02341 S_OR(in->cid_name, "<unknown>") 02342 ); 02343 02344 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 02345 if (chan) 02346 ast_channel_unlock(chan); 02347 ast_free(in); 02348 return NULL; 02349 }
| 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 3035 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().
03036 { 03037 int res, x; 03038 int maxlen = sizeof(s->session->inbuf) - 1; 03039 char *src = s->session->inbuf; 03040 03041 /* 03042 * Look for \r\n within the buffer. If found, copy to the output 03043 * buffer and return, trimming the \r\n (not used afterwards). 03044 */ 03045 for (x = 0; x < s->session->inlen; x++) { 03046 int cr; /* set if we have \r */ 03047 if (src[x] == '\r' && x+1 < s->session->inlen && src[x+1] == '\n') 03048 cr = 2; /* Found. Update length to include \r\n */ 03049 else if (src[x] == '\n') 03050 cr = 1; /* also accept \n only */ 03051 else 03052 continue; 03053 memmove(output, src, x); /*... but trim \r\n */ 03054 output[x] = '\0'; /* terminate the string */ 03055 x += cr; /* number of bytes used */ 03056 s->session->inlen -= x; /* remaining size */ 03057 memmove(src, src + x, s->session->inlen); /* remove used bytes */ 03058 return 1; 03059 } 03060 if (s->session->inlen >= maxlen) { 03061 /* no crlf found, and buffer full - sorry, too long for us */ 03062 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src); 03063 s->session->inlen = 0; 03064 } 03065 res = 0; 03066 while (res == 0) { 03067 /* XXX do we really need this locking ? */ 03068 ast_mutex_lock(&s->session->__lock); 03069 if (s->session->pending_event) { 03070 s->session->pending_event = 0; 03071 ast_mutex_unlock(&s->session->__lock); 03072 return 0; 03073 } 03074 s->session->waiting_thread = pthread_self(); 03075 ast_mutex_unlock(&s->session->__lock); 03076 03077 res = ast_wait_for_input(s->session->fd, -1); /* return 0 on timeout ? */ 03078 03079 ast_mutex_lock(&s->session->__lock); 03080 s->session->waiting_thread = AST_PTHREADT_NULL; 03081 ast_mutex_unlock(&s->session->__lock); 03082 } 03083 if (res < 0) { 03084 /* If we get a signal from some other thread (typically because 03085 * there are new events queued), return 0 to notify the caller. 03086 */ 03087 if (errno == EINTR || errno == EAGAIN) 03088 return 0; 03089 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno)); 03090 return -1; 03091 } 03092 ast_mutex_lock(&s->session->__lock); 03093 res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f); 03094 if (res < 1) 03095 res = -1; /* error return */ 03096 else { 03097 s->session->inlen += res; 03098 src[s->session->inlen] = '\0'; 03099 res = 0; 03100 } 03101 ast_mutex_unlock(&s->session->__lock); 03102 return res; 03103 }
| 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 2859 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().
02860 { 02861 int res; 02862 const char *module = astman_get_header(m, "Module"); 02863 const char *id = astman_get_header(m, "ActionID"); 02864 char idText[256]; 02865 #if !defined(LOW_MEMORY) 02866 const char *version; 02867 #endif 02868 char filename[PATH_MAX]; 02869 char *cut; 02870 02871 ast_copy_string(filename, module, sizeof(filename)); 02872 if ((cut = strchr(filename, '.'))) { 02873 *cut = '\0'; 02874 } else { 02875 cut = filename + strlen(filename); 02876 } 02877 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so"); 02878 ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename); 02879 res = ast_module_check(filename); 02880 if (!res) { 02881 astman_send_error(s, m, "Module not loaded"); 02882 return 0; 02883 } 02884 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c"); 02885 ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename); 02886 #if !defined(LOW_MEMORY) 02887 version = ast_file_version_find(filename); 02888 #endif 02889 02890 if (!ast_strlen_zero(id)) 02891 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02892 else 02893 idText[0] = '\0'; 02894 astman_append(s, "Response: Success\r\n%s", idText); 02895 #if !defined(LOW_MEMORY) 02896 astman_append(s, "Version: %s\r\n\r\n", version ? version : ""); 02897 #endif 02898 return 0; 02899 }
| static int manager_moduleload | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2912 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().
02913 { 02914 int res; 02915 const char *module = astman_get_header(m, "Module"); 02916 const char *loadtype = astman_get_header(m, "LoadType"); 02917 02918 if (!loadtype || strlen(loadtype) == 0) 02919 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02920 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) 02921 astman_send_error(s, m, "Need module name"); 02922 02923 if (!strcasecmp(loadtype, "load")) { 02924 res = ast_load_resource(module); 02925 if (res) 02926 astman_send_error(s, m, "Could not load module."); 02927 else 02928 astman_send_ack(s, m, "Module loaded."); 02929 } else if (!strcasecmp(loadtype, "unload")) { 02930 res = ast_unload_resource(module, AST_FORCE_SOFT); 02931 if (res) 02932 astman_send_error(s, m, "Could not unload module."); 02933 else 02934 astman_send_ack(s, m, "Module unloaded."); 02935 } else if (!strcasecmp(loadtype, "reload")) { 02936 if (module != NULL) { 02937 res = ast_module_reload(module); 02938 if (res == 0) 02939 astman_send_error(s, m, "No such module."); 02940 else if (res == 1) 02941 astman_send_error(s, m, "Module does not support reload action."); 02942 else 02943 astman_send_ack(s, m, "Module reloaded."); 02944 } else { 02945 ast_module_reload(NULL); /* Reload all modules */ 02946 astman_send_ack(s, m, "All modules reloaded"); 02947 } 02948 } else 02949 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02950 return 0; 02951 }
| static int manager_state_cb | ( | char * | context, | |
| char * | exten, | |||
| int | state, | |||
| void * | data | |||
| ) | [static] |
Definition at line 3366 of file manager.c.
References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.
Referenced by __init_manager().
03367 { 03368 /* Notify managers of change */ 03369 char hint[512]; 03370 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten); 03371 03372 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state); 03373 return 0; 03374 }
| 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 2629 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().
02630 { 02631 int ret = 0; 02632 02633 ast_mutex_lock(&s->session->__lock); 02634 if (s->session->f != NULL) { 02635 struct eventqent *eqe; 02636 02637 while ( (eqe = NEW_EVENT(s)) ) { 02638 ref_event(eqe); 02639 if (!ret && s->session->authenticated && 02640 (s->session->readperm & eqe->category) == eqe->category && 02641 (s->session->send_events & eqe->category) == eqe->category) { 02642 if (send_string(s, eqe->eventdata) < 0) 02643 ret = -1; /* don't send more */ 02644 } 02645 s->session->last_ev = unref_event(s->session->last_ev); 02646 } 02647 } 02648 ast_mutex_unlock(&s->session->__lock); 02649 return ret; 02650 }
| static int process_message | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2966 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().
02967 { 02968 char action[80] = ""; 02969 int ret = 0; 02970 struct manager_action *tmp; 02971 const char *user = astman_get_header(m, "Username"); 02972 02973 ast_copy_string(action, __astman_get_header(m, "Action", GET_HEADER_SKIP_EMPTY), sizeof(action)); 02974 ast_debug(1, "Manager received command '%s'\n", action); 02975 02976 if (ast_strlen_zero(action)) { 02977 ast_mutex_lock(&s->session->__lock); 02978 astman_send_error(s, m, "Missing action in request"); 02979 ast_mutex_unlock(&s->session->__lock); 02980 return 0; 02981 } 02982 02983 if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) { 02984 ast_mutex_lock(&s->session->__lock); 02985 astman_send_error(s, m, "Permission denied"); 02986 ast_mutex_unlock(&s->session->__lock); 02987 return 0; 02988 } 02989 02990 if (!allowmultiplelogin && !s->session->authenticated && user && 02991 (!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) { 02992 if (check_manager_session_inuse(user)) { 02993 sleep(1); 02994 ast_mutex_lock(&s->session->__lock); 02995 astman_send_error(s, m, "Login Already In Use"); 02996 ast_mutex_unlock(&s->session->__lock); 02997 return -1; 02998 } 02999 } 03000 03001 AST_RWLIST_RDLOCK(&actions); 03002 AST_RWLIST_TRAVERSE(&actions, tmp, list) { 03003 if (strcasecmp(action, tmp->action)) 03004 continue; 03005 if (s->session->writeperm & tmp->authority || tmp->authority == 0) 03006 ret = tmp->func(s, m); 03007 else 03008 astman_send_error(s, m, "Permission denied"); 03009 break; 03010 } 03011 AST_RWLIST_UNLOCK(&actions); 03012 03013 if (!tmp) { 03014 char buf[512]; 03015 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action); 03016 ast_mutex_lock(&s->session->__lock); 03017 astman_send_error(s, m, buf); 03018 ast_mutex_unlock(&s->session->__lock); 03019 } 03020 if (ret) 03021 return ret; 03022 /* Once done with our message, deliver any pending events */ 03023 return process_events(s); 03024 }
| 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 3214 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().
03215 { 03216 struct mansession_session *session; 03217 time_t now = time(NULL); 03218 03219 AST_LIST_LOCK(&sessions); 03220 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, session, list) { 03221 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) { 03222 AST_LIST_REMOVE_CURRENT(list); 03223 ast_atomic_fetchadd_int(&num_sessions, -1); 03224 if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) { 03225 ast_verb(2, "HTTP Manager '%s' timed out from %s\n", 03226 session->username, ast_inet_ntoa(session->sin.sin_addr)); 03227 } 03228 free_session(session); /* XXX outside ? */ 03229 if (--n_max <= 0) 03230 break; 03231 } 03232 } 03233 AST_LIST_TRAVERSE_SAFE_END; 03234 AST_LIST_UNLOCK(&sessions); 03235 }
| 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 3137 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.
03138 { 03139 struct ast_tcptls_session_instance *ser = data; 03140 struct mansession_session *session = ast_calloc(1, sizeof(*session)); 03141 struct mansession s = {.session = NULL, }; 03142 int flags; 03143 int res; 03144 03145 if (session == NULL) 03146 goto done; 03147 03148 session->writetimeout = 100; 03149 session->waiting_thread = AST_PTHREADT_NULL; 03150 03151 flags = fcntl(ser->fd, F_GETFL); 03152 if (!block_sockets) /* make sure socket is non-blocking */ 03153 flags |= O_NONBLOCK; 03154 else 03155 flags &= ~O_NONBLOCK; 03156 fcntl(ser->fd, F_SETFL, flags); 03157 03158 ast_mutex_init(&session->__lock); 03159 session->send_events = -1; 03160 /* Hook to the tail of the event queue */ 03161 session->last_ev = grab_last(); 03162 03163 /* these fields duplicate those in the 'ser' structure */ 03164 session->fd = ser->fd; 03165 session->f = ser->f; 03166 session->sin = ser->remote_address; 03167 s.session = session; 03168 03169 AST_LIST_HEAD_INIT_NOLOCK(&session->datastores); 03170 03171 AST_LIST_LOCK(&sessions); 03172 AST_LIST_INSERT_HEAD(&sessions, session, list); 03173 ast_atomic_fetchadd_int(&num_sessions, 1); 03174 AST_LIST_UNLOCK(&sessions); 03175 03176 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */ 03177 for (;;) { 03178 if ((res = do_message(&s)) < 0) 03179 break; 03180 } 03181 /* session is over, explain why and terminate */ 03182 if (session->authenticated) { 03183 if (manager_displayconnects(session)) 03184 ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 03185 ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 03186 } else { 03187 if (displayconnects) 03188 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr)); 03189 ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(session->sin.sin_addr)); 03190 } 03191 03192 /* It is possible under certain circumstances for this session thread 03193 to complete its work and exit *before* the thread that created it 03194 has finished executing the ast_pthread_create_background() function. 03195 If this occurs, some versions of glibc appear to act in a buggy 03196 fashion and attempt to write data into memory that it thinks belongs 03197 to the thread but is in fact not owned by the thread (or may have 03198 been freed completely). 03199 03200 Causing this thread to yield to other threads at least one time 03201 appears to work around this bug. 03202 */ 03203 usleep(1); 03204 03205 destroy_session(session); 03206 03207 done: 03208 ao2_ref(ser, -1); 03209 ser = NULL; 03210 return NULL; 03211 }
| 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 2678 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 2781 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 2724 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 2554 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 2521 of file manager.c.
Referenced by __init_manager().
char mandescr_mailboxstatus[] [static] |
Help text for manager command mailboxstatus.
Definition at line 2493 of file manager.c.
Referenced by __init_manager().
char mandescr_modulecheck[] [static] |
Definition at line 2849 of file manager.c.
Referenced by __init_manager().
char mandescr_moduleload[] [static] |
Definition at line 2901 of file manager.c.
Referenced by __init_manager().
char mandescr_originate[] [static] |
Definition at line 2351 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 2762 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 2589 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 2652 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