Data Structures | |
struct | actions |
list of actions registered More... | |
struct | all_events |
struct | ast_manager_user |
user descriptor, as read from the config file. More... | |
struct | eventqent |
struct | fast_originate_helper |
helper function for originate More... | |
struct | manager_hooks |
list of hooks registered More... | |
struct | mansession |
struct | mansession_session |
struct | permalias |
struct | sessions |
struct | users |
list of users found in the config file More... | |
Defines | |
#define | ASTMAN_APPEND_BUF_INITSIZE 256 |
initial allocated size for the astman_append_buf | |
#define | 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 void | __init_astman_append_buf (void) |
thread local buffer for astman_append | |
static void | __init_manager_event_buf (void) |
static void | __init_userevent_buf (void) |
int | __manager_event (int category, const char *event, const char *file, int line, const char *func, const char *fmt,...) |
manager_event: Send AMI event to client | |
static int | action_challenge (struct mansession *s, const struct message *m) |
static int | action_command (struct mansession *s, const struct message *m) |
Manager command "command" - execute CLI command. | |
static int | action_coresettings (struct mansession *s, const struct message *m) |
Show PBX core settings information. | |
static int | action_coreshowchannels (struct mansession *s, const struct message *m) |
Manager command "CoreShowChannels" - List currently defined channels and some information about them. | |
static int | action_corestatus (struct mansession *s, const struct message *m) |
Show PBX core status information. | |
static int | action_createconfig (struct mansession *s, const struct message *m) |
static int | action_events (struct mansession *s, const struct message *m) |
static int | action_extensionstate (struct mansession *s, const struct message *m) |
static int | action_getconfig (struct mansession *s, const struct message *m) |
static int | action_getconfigjson (struct mansession *s, const struct message *m) |
static int | action_getvar (struct mansession *s, const struct message *m) |
static int | action_hangup (struct mansession *s, const struct message *m) |
static int | action_listcategories (struct mansession *s, const struct message *m) |
static int | action_listcommands (struct mansession *s, const struct message *m) |
static int | action_login (struct mansession *s, const struct message *m) |
static int | action_logoff (struct mansession *s, const struct message *m) |
static int | action_mailboxcount (struct mansession *s, const struct message *m) |
static int | action_mailboxstatus (struct mansession *s, const struct message *m) |
static int | action_originate (struct mansession *s, const struct message *m) |
static int | action_ping (struct mansession *s, const struct message *m) |
static int | action_redirect (struct mansession *s, const struct message *m) |
action_redirect: The redirect manager command | |
static int | action_reload (struct mansession *s, const struct message *m) |
Send a reload event. | |
static int | action_sendtext (struct mansession *s, const struct message *m) |
static int | action_setvar (struct mansession *s, const struct message *m) |
static int | action_status (struct mansession *s, const struct message *m) |
Manager "status" command to show channels. | |
static int | action_timeout (struct mansession *s, const struct message *m) |
static int | action_updateconfig (struct mansession *s, const struct message *m) |
static int | action_userevent (struct mansession *s, const struct message *m) |
static int | action_waitevent (struct mansession *s, const struct message *m) |
static int | append_event (const char *str, int category) |
static int | ast_instring (const char *bigstr, const char *smallstr, const char delim) |
int | ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), const char *synopsis, const char *description) |
Register a manager command with the manager interface. | |
void | ast_manager_register_hook (struct manager_custom_hook *hook) |
Add a custom hook to be called when an event is fired. | |
static int | ast_manager_register_struct (struct manager_action *act) |
int | ast_manager_unregister (char *action) |
Unregister a registered manager command. | |
void | ast_manager_unregister_hook (struct manager_custom_hook *hook) |
Delete a custom hook to be called when an event is fired. | |
void | astman_append (struct mansession *s, const char *fmt,...) |
const char * | astman_get_header (const struct message *m, char *var) |
Get header from mananger transaction. | |
ast_variable * | astman_get_variables (const struct message *m) |
Get a linked list of the Variable: headers. | |
void | astman_send_ack (struct mansession *s, const struct message *m, char *msg) |
Send ack in manager transaction. | |
void | astman_send_error (struct mansession *s, const struct message *m, char *error) |
Send error in manager transaction. | |
void | astman_send_listack (struct mansession *s, const struct message *m, char *msg, char *listflag) |
Send ack in manager list transaction. | |
void | astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg) |
Send response in manager transaction. | |
static void | astman_send_response_full (struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag) |
static void | astman_start_ack (struct mansession *s, const struct message *m) |
static int | authenticate (struct mansession *s, const struct message *m) |
static char * | authority_to_str (int authority, struct ast_str **res) |
Convert authority code to a list of options. | |
static int | check_blacklist (const char *cmd) |
int | check_manager_enabled () |
Check if AMI is enabled. | |
static int | check_manager_session_inuse (const char *name) |
int | check_webmanager_enabled () |
Check if AMI/HTTP is enabled. | |
static void | destroy_session (struct mansession_session *session) |
static int | do_message (struct mansession *s) |
static void * | fast_originate (void *data) |
static void | free_session (struct mansession_session *session) |
static int | get_input (struct mansession *s, char *output) |
static struct ast_manager_user * | get_manager_by_name_locked (const char *name) |
static int | get_perm (const char *instr) |
static struct eventqent * | grab_last (void) |
static char * | handle_manager_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI command manager reload. | |
static char * | handle_mandebug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_showmanager (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_showmanagers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_showmancmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_showmancmds (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI command manager list commands. | |
static char * | handle_showmanconn (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI command manager list connected. | |
static char * | handle_showmaneventq (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI command manager list eventq. | |
static enum error_type | handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg, const char *dfn) |
static void | json_escape (char *out, const char *in) |
static int | manager_displayconnects (struct mansession_session *session) |
Get displayconnects config option. | |
static int | manager_modulecheck (struct mansession *s, const struct message *m) |
static int | manager_moduleload (struct mansession *s, const struct message *m) |
static int | manager_state_cb (char *context, char *exten, int state, void *data) |
static int | process_events (struct mansession *s) |
static int | process_message (struct mansession *s, const struct message *m) |
static void | purge_events (void) |
static void | purge_sessions (int n_max) |
remove at most n_max stale session from the list. | |
static void | ref_event (struct eventqent *e) |
static int | send_string (struct mansession *s, char *string) |
static void * | session_do (void *data) |
The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ). | |
static int | set_eventmask (struct mansession *s, const char *eventmask) |
Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm. | |
static int | strings_to_mask (const char *string) |
static struct eventqent * | unref_event (struct eventqent *e) |
Variables | |
static int | allowmultiplelogin = 1 |
static struct ast_threadstorage | astman_append_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_astman_append_buf , .custom_init = NULL , } |
static int | block_sockets |
static struct ast_cli_entry | cli_manager [] |
struct { | |
char * words [AST_MAX_CMD_LEN] | |
} | command_blacklist [] |
static int | displayconnects = 1 |
static int | httptimeout = 60 |
static int | manager_debug |
static int | manager_enabled = 0 |
static struct ast_threadstorage | manager_event_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_manager_event_buf , .custom_init = NULL , } |
static char | mandescr_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_timeout [] |
static char | mandescr_updateconfig [] |
static char | mandescr_userevent [] |
static char | mandescr_waitevent [] |
Manager WAITEVENT. | |
static int | num_sessions |
static struct permalias | perms [] |
static int | timestampevents |
static struct ast_threadstorage | userevent_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_userevent_buf , .custom_init = NULL , } |
static int | webmanager_enabled = 0 |
#define ASTMAN_APPEND_BUF_INITSIZE 256 |
initial allocated size for the astman_append_buf
Definition at line 919 of file manager.c.
Referenced by astman_append().
#define MANAGER_EVENT_BUF_INITSIZE 256 |
#define MAX_BLACKLIST_CMD_LEN 2 |
Descriptor for a manager session, either on the AMI socket or over HTTP.
Definition at line 142 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 958 of file manager.c.
Referenced by astman_send_response_full(), and astman_start_ack().
#define NEW_EVENT | ( | m | ) | (AST_LIST_NEXT(m->session->last_ev, eq_next)) |
enum error_type |
Doxygen group
UNKNOWN_ACTION | |
UNKNOWN_CATEGORY | |
UNSPECIFIED_CATEGORY | |
UNSPECIFIED_ARGUMENT | |
FAILURE_ALLOCATION | |
FAILURE_NEWCAT | |
FAILURE_DELCAT | |
FAILURE_EMPTYCAT | |
FAILURE_UPDATE | |
FAILURE_DELETE | |
FAILURE_APPEND |
Definition at line 77 of file manager.c.
00077 { 00078 UNKNOWN_ACTION = 1, 00079 UNKNOWN_CATEGORY, 00080 UNSPECIFIED_CATEGORY, 00081 UNSPECIFIED_ARGUMENT, 00082 FAILURE_ALLOCATION, 00083 FAILURE_NEWCAT, 00084 FAILURE_DELCAT, 00085 FAILURE_EMPTYCAT, 00086 FAILURE_UPDATE, 00087 FAILURE_DELETE, 00088 FAILURE_APPEND 00089 };
static void __init_astman_append_buf | ( | void | ) | [static] |
thread local buffer for astman_append
Definition at line 915 of file manager.c.
static void __init_manager_event_buf | ( | void | ) | [static] |
int __manager_event | ( | int | category, | |
const char * | event, | |||
const char * | file, | |||
int | line, | |||
const char * | func, | |||
const char * | fmt, | |||
... | ||||
) |
manager_event: Send AMI event to client
Definition at line 3067 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, MANAGER_EVENT_BUF_INITSIZE, mansession_session::pending_event, seq, and mansession_session::waiting_thread.
03069 { 03070 struct mansession_session *session; 03071 struct manager_custom_hook *hook; 03072 struct ast_str *auth = ast_str_alloca(80); 03073 const char *cat_str; 03074 va_list ap; 03075 struct timeval now; 03076 struct ast_str *buf; 03077 03078 /* Abort if there aren't any manager sessions */ 03079 if (!num_sessions) 03080 return 0; 03081 03082 if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) 03083 return -1; 03084 03085 cat_str = authority_to_str(category, &auth); 03086 ast_str_set(&buf, 0, 03087 "Event: %s\r\nPrivilege: %s\r\n", 03088 event, cat_str); 03089 03090 if (timestampevents) { 03091 now = ast_tvnow(); 03092 ast_str_append(&buf, 0, 03093 "Timestamp: %ld.%06lu\r\n", 03094 now.tv_sec, (unsigned long) now.tv_usec); 03095 } 03096 if (manager_debug) { 03097 static int seq; 03098 ast_str_append(&buf, 0, 03099 "SequenceNumber: %d\r\n", 03100 ast_atomic_fetchadd_int(&seq, 1)); 03101 ast_str_append(&buf, 0, 03102 "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func); 03103 } 03104 03105 va_start(ap, fmt); 03106 ast_str_append_va(&buf, 0, fmt, ap); 03107 va_end(ap); 03108 03109 ast_str_append(&buf, 0, "\r\n"); 03110 03111 append_event(buf->str, category); 03112 03113 /* Wake up any sleeping sessions */ 03114 AST_LIST_LOCK(&sessions); 03115 AST_LIST_TRAVERSE(&sessions, session, list) { 03116 ast_mutex_lock(&session->__lock); 03117 if (session->waiting_thread != AST_PTHREADT_NULL) 03118 pthread_kill(session->waiting_thread, SIGURG); 03119 else 03120 /* We have an event to process, but the mansession is 03121 * not waiting for it. We still need to indicate that there 03122 * is an event waiting so that get_input processes the pending 03123 * event instead of polling. 03124 */ 03125 session->pending_event = 1; 03126 ast_mutex_unlock(&session->__lock); 03127 } 03128 AST_LIST_UNLOCK(&sessions); 03129 03130 AST_RWLIST_RDLOCK(&manager_hooks); 03131 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) { 03132 hook->helper(category, event, buf->str); 03133 } 03134 AST_RWLIST_UNLOCK(&manager_hooks); 03135 03136 return 0; 03137 }
static int action_challenge | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1647 of file manager.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and s.
Referenced by __init_manager().
01648 { 01649 const char *authtype = astman_get_header(m, "AuthType"); 01650 01651 if (!strcasecmp(authtype, "MD5")) { 01652 if (ast_strlen_zero(s->session->challenge)) 01653 snprintf(s->session->challenge, sizeof(s->session->challenge), "%ld", ast_random()); 01654 ast_mutex_lock(&s->session->__lock); 01655 astman_start_ack(s, m); 01656 astman_append(s, "Challenge: %s\r\n\r\n", s->session->challenge); 01657 ast_mutex_unlock(&s->session->__lock); 01658 } else { 01659 astman_send_error(s, m, "Must specify AuthType"); 01660 } 01661 return 0; 01662 }
static int action_command | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager command "command" - execute CLI command.
Definition at line 2044 of file manager.c.
References ast_calloc, ast_cli_command(), ast_free, ast_log(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), buf, check_blacklist(), errno, LOG_WARNING, s, S_OR, and term_strip().
Referenced by __init_manager().
02045 { 02046 const char *cmd = astman_get_header(m, "Command"); 02047 const char *id = astman_get_header(m, "ActionID"); 02048 char *buf, *final_buf; 02049 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 02050 int fd = mkstemp(template); 02051 off_t l; 02052 02053 if (ast_strlen_zero(cmd)) { 02054 astman_send_error(s, m, "No command provided"); 02055 return 0; 02056 } 02057 02058 if (check_blacklist(cmd)) { 02059 astman_send_error(s, m, "Command blacklisted"); 02060 return 0; 02061 } 02062 02063 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 02064 if (!ast_strlen_zero(id)) 02065 astman_append(s, "ActionID: %s\r\n", id); 02066 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 02067 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 02068 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 02069 02070 /* This has a potential to overflow the stack. Hence, use the heap. */ 02071 buf = ast_calloc(1, l + 1); 02072 final_buf = ast_calloc(1, l + 1); 02073 if (buf) { 02074 lseek(fd, 0, SEEK_SET); 02075 if (read(fd, buf, l) < 0) { 02076 ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno)); 02077 } 02078 buf[l] = '\0'; 02079 if (final_buf) { 02080 term_strip(final_buf, buf, l); 02081 final_buf[l] = '\0'; 02082 } 02083 astman_append(s, "%s", S_OR(final_buf, buf)); 02084 ast_free(buf); 02085 } 02086 close(fd); 02087 unlink(template); 02088 astman_append(s, "--END COMMAND--\r\n\r\n"); 02089 if (final_buf) 02090 ast_free(final_buf); 02091 return 0; 02092 }
static int action_coresettings | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show PBX core settings information.
Definition at line 2487 of file manager.c.
References AMI_VERSION, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SYSTEM_NAME, ast_get_version(), ast_realtime_enabled(), ast_strlen_zero(), astman_append(), astman_get_header(), check_cdr_enabled(), check_webmanager_enabled(), option_maxcalls, option_maxfiles, option_maxload, and s.
Referenced by __init_manager().
02488 { 02489 const char *actionid = astman_get_header(m, "ActionID"); 02490 char idText[150]; 02491 02492 if (!ast_strlen_zero(actionid)) 02493 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02494 else 02495 idText[0] = '\0'; 02496 02497 astman_append(s, "Response: Success\r\n" 02498 "%s" 02499 "AMIversion: %s\r\n" 02500 "AsteriskVersion: %s\r\n" 02501 "SystemName: %s\r\n" 02502 "CoreMaxCalls: %d\r\n" 02503 "CoreMaxLoadAvg: %f\r\n" 02504 "CoreRunUser: %s\r\n" 02505 "CoreRunGroup: %s\r\n" 02506 "CoreMaxFilehandles: %d\r\n" 02507 "CoreRealTimeEnabled: %s\r\n" 02508 "CoreCDRenabled: %s\r\n" 02509 "CoreHTTPenabled: %s\r\n" 02510 "\r\n", 02511 idText, 02512 AMI_VERSION, 02513 ast_get_version(), 02514 ast_config_AST_SYSTEM_NAME, 02515 option_maxcalls, 02516 option_maxload, 02517 ast_config_AST_RUN_USER, 02518 ast_config_AST_RUN_GROUP, 02519 option_maxfiles, 02520 ast_realtime_enabled() ? "Yes" : "No", 02521 check_cdr_enabled() ? "Yes" : "No", 02522 check_webmanager_enabled() ? "Yes" : "No" 02523 ); 02524 return 0; 02525 }
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 2592 of file manager.c.
References ast_channel::_state, ast_channel::accountcode, ast_channel::appl, ast_bridged_channel(), ast_channel_unlock, ast_channel_walk_locked(), ast_state2str(), ast_strlen_zero(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), astman_append(), astman_get_header(), astman_send_listack(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::data, ast_channel::exten, ast_channel::name, ast_channel::priority, s, S_OR, ast_cdr::start, and ast_channel::uniqueid.
Referenced by __init_manager().
02593 { 02594 const char *actionid = astman_get_header(m, "ActionID"); 02595 char actionidtext[256]; 02596 struct ast_channel *c = NULL; 02597 int numchans = 0; 02598 int duration, durh, durm, durs; 02599 02600 if (!ast_strlen_zero(actionid)) 02601 snprintf(actionidtext, sizeof(actionidtext), "ActionID: %s\r\n", actionid); 02602 else 02603 actionidtext[0] = '\0'; 02604 02605 astman_send_listack(s, m, "Channels will follow", "start"); 02606 02607 while ((c = ast_channel_walk_locked(c)) != NULL) { 02608 struct ast_channel *bc = ast_bridged_channel(c); 02609 char durbuf[10] = ""; 02610 02611 if (c->cdr && !ast_tvzero(c->cdr->start)) { 02612 duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000); 02613 durh = duration / 3600; 02614 durm = (duration % 3600) / 60; 02615 durs = duration % 60; 02616 snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs); 02617 } 02618 02619 astman_append(s, 02620 "Channel: %s\r\n" 02621 "UniqueID: %s\r\n" 02622 "Context: %s\r\n" 02623 "Extension: %s\r\n" 02624 "Priority: %d\r\n" 02625 "ChannelState: %d\r\n" 02626 "ChannelStateDesc: %s\r\n" 02627 "Application: %s\r\n" 02628 "ApplicationData: %s\r\n" 02629 "CallerIDnum: %s\r\n" 02630 "Duration: %s\r\n" 02631 "AccountCode: %s\r\n" 02632 "BridgedChannel: %s\r\n" 02633 "BridgedUniqueID: %s\r\n" 02634 "\r\n", c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, ast_state2str(c->_state), 02635 c->appl ? c->appl : "", c->data ? S_OR(c->data, ""): "", 02636 S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : ""); 02637 ast_channel_unlock(c); 02638 numchans++; 02639 } 02640 02641 astman_append(s, 02642 "Event: CoreShowChannelsComplete\r\n" 02643 "EventList: Complete\r\n" 02644 "ListItems: %d\r\n" 02645 "%s" 02646 "\r\n", numchans, actionidtext); 02647 02648 return 0; 02649 }
static int action_corestatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show PBX core status information.
Definition at line 2533 of file manager.c.
References ast_active_channels(), ast_lastreloadtime, ast_localtime(), ast_startuptime, ast_strftime(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by __init_manager().
02534 { 02535 const char *actionid = astman_get_header(m, "ActionID"); 02536 char idText[150]; 02537 char startuptime[150]; 02538 char reloadtime[150]; 02539 struct ast_tm tm; 02540 02541 if (!ast_strlen_zero(actionid)) 02542 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02543 else 02544 idText[0] = '\0'; 02545 02546 ast_localtime(&ast_startuptime, &tm, NULL); 02547 ast_strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm); 02548 ast_localtime(&ast_lastreloadtime, &tm, NULL); 02549 ast_strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm); 02550 02551 astman_append(s, "Response: Success\r\n" 02552 "%s" 02553 "CoreStartupTime: %s\r\n" 02554 "CoreReloadTime: %s\r\n" 02555 "CoreCurrentCalls: %d\r\n" 02556 "\r\n", 02557 idText, 02558 startuptime, 02559 reloadtime, 02560 ast_active_channels() 02561 ); 02562 return 0; 02563 }
static int action_createconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1458 of file manager.c.
References ast_config_AST_CONFIG_DIR, AST_FILE_MODE, ast_str_alloca, ast_str_append(), ast_str_set(), astman_get_header(), astman_send_ack(), astman_send_error(), errno, s, and ast_str::str.
Referenced by __init_manager().
01459 { 01460 int fd; 01461 const char *fn = astman_get_header(m, "Filename"); 01462 struct ast_str *filepath = ast_str_alloca(PATH_MAX); 01463 ast_str_set(&filepath, 0, "%s/", ast_config_AST_CONFIG_DIR); 01464 ast_str_append(&filepath, 0, "%s", fn); 01465 01466 if ((fd = open(filepath->str, O_CREAT | O_EXCL, AST_FILE_MODE)) != -1) { 01467 close(fd); 01468 astman_send_ack(s, m, "New configuration file created successfully"); 01469 } else 01470 astman_send_error(s, m, strerror(errno)); 01471 01472 return 0; 01473 }
static int action_events | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1607 of file manager.c.
References astman_append(), astman_get_header(), s, and set_eventmask().
Referenced by __init_manager().
01608 { 01609 const char *mask = astman_get_header(m, "EventMask"); 01610 int res; 01611 01612 res = set_eventmask(s, mask); 01613 if (res > 0) 01614 astman_append(s, "Response: Success\r\n" 01615 "Events: On\r\n"); 01616 else if (res == 0) 01617 astman_append(s, "Response: Success\r\n" 01618 "Events: Off\r\n"); 01619 return 0; 01620 }
static int action_extensionstate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2372 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, s, and status.
Referenced by __init_manager().
02373 { 02374 const char *exten = astman_get_header(m, "Exten"); 02375 const char *context = astman_get_header(m, "Context"); 02376 char hint[256] = ""; 02377 int status; 02378 if (ast_strlen_zero(exten)) { 02379 astman_send_error(s, m, "Extension not specified"); 02380 return 0; 02381 } 02382 if (ast_strlen_zero(context)) 02383 context = "default"; 02384 status = ast_extension_state(NULL, context, exten); 02385 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 02386 astman_start_ack(s, m); 02387 astman_append(s, "Message: Extension Status\r\n" 02388 "Exten: %s\r\n" 02389 "Context: %s\r\n" 02390 "Hint: %s\r\n" 02391 "Status: %d\r\n\r\n", 02392 exten, context, hint, status); 02393 return 0; 02394 }
static int action_getconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1106 of file manager.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load, 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, s, and ast_variable::value.
Referenced by __init_manager().
01107 { 01108 struct ast_config *cfg; 01109 const char *fn = astman_get_header(m, "Filename"); 01110 const char *category = astman_get_header(m, "Category"); 01111 int catcount = 0; 01112 int lineno = 0; 01113 char *cur_category = NULL; 01114 struct ast_variable *v; 01115 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01116 01117 if (ast_strlen_zero(fn)) { 01118 astman_send_error(s, m, "Filename not specified"); 01119 return 0; 01120 } 01121 if (!(cfg = ast_config_load(fn, config_flags))) { 01122 astman_send_error(s, m, "Config file not found"); 01123 return 0; 01124 } 01125 01126 astman_start_ack(s, m); 01127 while ((cur_category = ast_category_browse(cfg, cur_category))) { 01128 if (ast_strlen_zero(category) || (!ast_strlen_zero(category) && !strcmp(category, cur_category))) { 01129 lineno = 0; 01130 astman_append(s, "Category-%06d: %s\r\n", catcount, cur_category); 01131 for (v = ast_variable_browse(cfg, cur_category); v; v = v->next) 01132 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 01133 catcount++; 01134 } 01135 } 01136 if (!ast_strlen_zero(category) && catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */ 01137 astman_append(s, "No categories found\r\n"); 01138 ast_config_destroy(cfg); 01139 astman_append(s, "\r\n"); 01140 01141 return 0; 01142 }
static int action_getconfigjson | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1200 of file manager.c.
References ast_category_browse(), ast_config_load, 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, s, and ast_variable::value.
Referenced by __init_manager().
01201 { 01202 struct ast_config *cfg; 01203 const char *fn = astman_get_header(m, "Filename"); 01204 char *category = NULL; 01205 struct ast_variable *v; 01206 int comma1 = 0; 01207 char *buf = NULL; 01208 unsigned int buf_len = 0; 01209 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01210 01211 if (ast_strlen_zero(fn)) { 01212 astman_send_error(s, m, "Filename not specified"); 01213 return 0; 01214 } 01215 01216 if (!(cfg = ast_config_load(fn, config_flags))) { 01217 astman_send_error(s, m, "Config file not found"); 01218 return 0; 01219 } 01220 01221 buf_len = 512; 01222 buf = alloca(buf_len); 01223 01224 astman_start_ack(s, m); 01225 astman_append(s, "JSON: {"); 01226 while ((category = ast_category_browse(cfg, category))) { 01227 int comma2 = 0; 01228 if (buf_len < 2 * strlen(category) + 1) { 01229 buf_len *= 2; 01230 buf = alloca(buf_len); 01231 } 01232 json_escape(buf, category); 01233 astman_append(s, "%s\"%s\":[", comma1 ? "," : "", buf); 01234 if (!comma1) 01235 comma1 = 1; 01236 for (v = ast_variable_browse(cfg, category); v; v = v->next) { 01237 if (comma2) 01238 astman_append(s, ","); 01239 if (buf_len < 2 * strlen(v->name) + 1) { 01240 buf_len *= 2; 01241 buf = alloca(buf_len); 01242 } 01243 json_escape(buf, v->name); 01244 astman_append(s, "\"%s", buf); 01245 if (buf_len < 2 * strlen(v->value) + 1) { 01246 buf_len *= 2; 01247 buf = alloca(buf_len); 01248 } 01249 json_escape(buf, v->value); 01250 astman_append(s, "%s\"", buf); 01251 if (!comma2) 01252 comma2 = 1; 01253 } 01254 astman_append(s, "]"); 01255 } 01256 astman_append(s, "}\r\n\r\n"); 01257 01258 ast_config_destroy(cfg); 01259 01260 return 0; 01261 }
static int action_getvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1732 of file manager.c.
References ast_channel_alloc, ast_channel_free(), ast_channel_unlock, ast_func_read(), ast_get_channel_by_name_locked(), ast_log(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), LOG_ERROR, name, pbx_retrieve_variable(), and s.
Referenced by __init_manager().
01733 { 01734 struct ast_channel *c = NULL; 01735 const char *name = astman_get_header(m, "Channel"); 01736 const char *varname = astman_get_header(m, "Variable"); 01737 char *varval; 01738 char workspace[1024] = ""; 01739 01740 if (ast_strlen_zero(varname)) { 01741 astman_send_error(s, m, "No variable specified"); 01742 return 0; 01743 } 01744 01745 if (!ast_strlen_zero(name)) { 01746 c = ast_get_channel_by_name_locked(name); 01747 if (!c) { 01748 astman_send_error(s, m, "No such channel"); 01749 return 0; 01750 } 01751 } 01752 01753 if (varname[strlen(varname) - 1] == ')') { 01754 if (!c) { 01755 c = ast_channel_alloc(0, 0, "", "", "", "", "", 0, "Bogus/manager"); 01756 if (c) { 01757 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01758 ast_channel_free(c); 01759 c = NULL; 01760 } else 01761 ast_log(LOG_ERROR, "Unable to allocate bogus channel for variable substitution. Function results may be blank.\n"); 01762 } else 01763 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01764 varval = workspace; 01765 } else { 01766 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 01767 } 01768 01769 if (c) 01770 ast_channel_unlock(c); 01771 astman_start_ack(s, m); 01772 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, varval); 01773 01774 return 0; 01775 }
static int action_hangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1669 of file manager.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, and s.
Referenced by __init_manager().
01670 { 01671 struct ast_channel *c = NULL; 01672 const char *name = astman_get_header(m, "Channel"); 01673 if (ast_strlen_zero(name)) { 01674 astman_send_error(s, m, "No channel specified"); 01675 return 0; 01676 } 01677 c = ast_get_channel_by_name_locked(name); 01678 if (!c) { 01679 astman_send_error(s, m, "No such channel"); 01680 return 0; 01681 } 01682 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01683 ast_channel_unlock(c); 01684 astman_send_ack(s, m, "Channel Hungup"); 01685 return 0; 01686 }
static int action_listcategories | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1150 of file manager.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), eventqent::category, CONFIG_FLAG_NOCACHE, CONFIG_FLAG_WITHCOMMENTS, and s.
Referenced by __init_manager().
01151 { 01152 struct ast_config *cfg; 01153 const char *fn = astman_get_header(m, "Filename"); 01154 char *category = NULL; 01155 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01156 int catcount = 0; 01157 01158 if (ast_strlen_zero(fn)) { 01159 astman_send_error(s, m, "Filename not specified"); 01160 return 0; 01161 } 01162 if (!(cfg = ast_config_load(fn, config_flags))) { 01163 astman_send_error(s, m, "Config file not found or file has invalid syntax"); 01164 return 0; 01165 } 01166 astman_start_ack(s, m); 01167 while ((category = ast_category_browse(cfg, category))) { 01168 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 01169 catcount++; 01170 } 01171 if (catcount == 0) /* TODO: actually, a config with no categories doesn't even get loaded */ 01172 astman_append(s, "Error: no categories found\r\n"); 01173 ast_config_destroy(cfg); 01174 astman_append(s, "\r\n"); 01175 01176 return 0; 01177 }
static int action_listcommands | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1583 of file manager.c.
References manager_action::action, AST_RWLIST_TRAVERSE, ast_str_alloca, astman_append(), astman_start_ack(), manager_action::authority, authority_to_str(), s, and manager_action::synopsis.
Referenced by __init_manager().
01584 { 01585 struct manager_action *cur; 01586 struct ast_str *temp = ast_str_alloca(BUFSIZ); /* XXX very large ? */ 01587 01588 astman_start_ack(s, m); 01589 AST_RWLIST_TRAVERSE(&actions, cur, list) { 01590 if (s->session->writeperm & cur->authority || cur->authority == 0) 01591 astman_append(s, "%s: %s (Priv: %s)\r\n", 01592 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp)); 01593 } 01594 astman_append(s, "\r\n"); 01595 01596 return 0; 01597 }
static int action_login | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1632 of file manager.c.
References ast_inet_ntoa(), ast_log(), ast_verb, astman_send_ack(), astman_send_error(), authenticate(), LOG_EVENT, manager_displayconnects(), and s.
Referenced by __init_manager().
01633 { 01634 if (authenticate(s, m)) { 01635 sleep(1); 01636 astman_send_error(s, m, "Authentication failed"); 01637 return -1; 01638 } 01639 s->session->authenticated = 1; 01640 if (manager_displayconnects(s->session)) 01641 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)); 01642 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)); 01643 astman_send_ack(s, m, "Authentication accepted"); 01644 return 0; 01645 }
static int action_logoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1626 of file manager.c.
References astman_send_response(), and s.
Referenced by __init_manager().
01627 { 01628 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 01629 return -1; 01630 }
static int action_mailboxcount | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2341 of file manager.c.
References ast_app_inboxcount(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), mailbox, and s.
Referenced by __init_manager().
02342 { 02343 const char *mailbox = astman_get_header(m, "Mailbox"); 02344 int newmsgs = 0, oldmsgs = 0; 02345 02346 if (ast_strlen_zero(mailbox)) { 02347 astman_send_error(s, m, "Mailbox not specified"); 02348 return 0; 02349 } 02350 ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs); 02351 astman_start_ack(s, m); 02352 astman_append(s, "Message: Mailbox Message Count\r\n" 02353 "Mailbox: %s\r\n" 02354 "NewMessages: %d\r\n" 02355 "OldMessages: %d\r\n" 02356 "\r\n", 02357 mailbox, newmsgs, oldmsgs); 02358 return 0; 02359 }
static int action_mailboxstatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2313 of file manager.c.
References ast_app_has_voicemail(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), mailbox, and s.
Referenced by __init_manager().
02314 { 02315 const char *mailbox = astman_get_header(m, "Mailbox"); 02316 int ret; 02317 02318 if (ast_strlen_zero(mailbox)) { 02319 astman_send_error(s, m, "Mailbox not specified"); 02320 return 0; 02321 } 02322 ret = ast_app_has_voicemail(mailbox, NULL); 02323 astman_start_ack(s, m); 02324 astman_append(s, "Message: Mailbox Status\r\n" 02325 "Mailbox: %s\r\n" 02326 "Waiting: %d\r\n\r\n", mailbox, ret); 02327 return 0; 02328 }
static int action_originate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2176 of file manager.c.
References app, ast_callerid_parse(), ast_calloc, ast_copy_string(), ast_findlabel_extension(), AST_FORMAT_SLINEAR, ast_free, ast_parse_allow_disallow(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pthread_create_detached, ast_shrink_phone_number(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), context, ast_channel::data, EVENT_FLAG_SYSTEM, exten, fast_originate(), format, name, ast_channel::priority, s, strcasestr(), and ast_channel::tech.
Referenced by __init_manager().
02177 { 02178 const char *name = astman_get_header(m, "Channel"); 02179 const char *exten = astman_get_header(m, "Exten"); 02180 const char *context = astman_get_header(m, "Context"); 02181 const char *priority = astman_get_header(m, "Priority"); 02182 const char *timeout = astman_get_header(m, "Timeout"); 02183 const char *callerid = astman_get_header(m, "CallerID"); 02184 const char *account = astman_get_header(m, "Account"); 02185 const char *app = astman_get_header(m, "Application"); 02186 const char *appdata = astman_get_header(m, "Data"); 02187 const char *async = astman_get_header(m, "Async"); 02188 const char *id = astman_get_header(m, "ActionID"); 02189 const char *codecs = astman_get_header(m, "Codecs"); 02190 struct ast_variable *vars = astman_get_variables(m); 02191 char *tech, *data; 02192 char *l = NULL, *n = NULL; 02193 int pi = 0; 02194 int res; 02195 int to = 30000; 02196 int reason = 0; 02197 char tmp[256]; 02198 char tmp2[256]; 02199 int format = AST_FORMAT_SLINEAR; 02200 02201 pthread_t th; 02202 if (ast_strlen_zero(name)) { 02203 astman_send_error(s, m, "Channel not specified"); 02204 return 0; 02205 } 02206 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 02207 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 02208 astman_send_error(s, m, "Invalid priority"); 02209 return 0; 02210 } 02211 } 02212 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) { 02213 astman_send_error(s, m, "Invalid timeout"); 02214 return 0; 02215 } 02216 ast_copy_string(tmp, name, sizeof(tmp)); 02217 tech = tmp; 02218 data = strchr(tmp, '/'); 02219 if (!data) { 02220 astman_send_error(s, m, "Invalid channel"); 02221 return 0; 02222 } 02223 *data++ = '\0'; 02224 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 02225 ast_callerid_parse(tmp2, &n, &l); 02226 if (n) { 02227 if (ast_strlen_zero(n)) 02228 n = NULL; 02229 } 02230 if (l) { 02231 ast_shrink_phone_number(l); 02232 if (ast_strlen_zero(l)) 02233 l = NULL; 02234 } 02235 if (!ast_strlen_zero(codecs)) { 02236 format = 0; 02237 ast_parse_allow_disallow(NULL, &format, codecs, 1); 02238 } 02239 if (ast_true(async)) { 02240 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 02241 if (!fast) { 02242 res = -1; 02243 } else { 02244 if (!ast_strlen_zero(id)) 02245 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s", id); 02246 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 02247 ast_copy_string(fast->data, data, sizeof(fast->data)); 02248 ast_copy_string(fast->app, app, sizeof(fast->app)); 02249 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 02250 if (l) 02251 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 02252 if (n) 02253 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 02254 fast->vars = vars; 02255 ast_copy_string(fast->context, context, sizeof(fast->context)); 02256 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 02257 ast_copy_string(fast->account, account, sizeof(fast->account)); 02258 fast->format = format; 02259 fast->timeout = to; 02260 fast->priority = pi; 02261 if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) { 02262 ast_free(fast); 02263 res = -1; 02264 } else { 02265 res = 0; 02266 } 02267 } 02268 } else if (!ast_strlen_zero(app)) { 02269 /* To run the System application (or anything else that goes to shell), you must have the additional System privilege */ 02270 if (!(s->session->writeperm & EVENT_FLAG_SYSTEM) 02271 && ( 02272 strcasestr(app, "system") == 0 || /* System(rm -rf /) 02273 TrySystem(rm -rf /) */ 02274 strcasestr(app, "exec") || /* Exec(System(rm -rf /)) 02275 TryExec(System(rm -rf /)) */ 02276 strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /) 02277 EAGI(/bin/rm,-rf /) */ 02278 strstr(appdata, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */ 02279 strstr(appdata, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */ 02280 )) { 02281 astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have."); 02282 return 0; 02283 } 02284 res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 02285 } else { 02286 if (exten && context && pi) 02287 res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 02288 else { 02289 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 02290 return 0; 02291 } 02292 } 02293 if (!res) 02294 astman_send_ack(s, m, "Originate successfully queued"); 02295 else 02296 astman_send_error(s, m, "Originate failed"); 02297 return 0; 02298 }
static int action_ping | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1091 of file manager.c.
References astman_append(), and s.
Referenced by __init_manager().
01092 { 01093 astman_append(s, "Response: Success\r\n" 01094 "Ping: Pong\r\n" 01095 "\r\n"); 01096 return 0; 01097 }
static int action_redirect | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_redirect: The redirect manager command
Definition at line 1927 of file manager.c.
References ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_findlabel_extension(), AST_FLAG_BRIDGE_HANGUP_DONT, ast_get_channel_by_name_locked(), ast_set_flag, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), buf, chan, context, exten, name, ast_channel::pbx, ast_channel::priority, and s.
Referenced by __init_manager().
01928 { 01929 const char *name = astman_get_header(m, "Channel"); 01930 const char *name2 = astman_get_header(m, "ExtraChannel"); 01931 const char *exten = astman_get_header(m, "Exten"); 01932 const char *context = astman_get_header(m, "Context"); 01933 const char *priority = astman_get_header(m, "Priority"); 01934 struct ast_channel *chan, *chan2 = NULL; 01935 int pi = 0; 01936 int res; 01937 01938 if (ast_strlen_zero(name)) { 01939 astman_send_error(s, m, "Channel not specified"); 01940 return 0; 01941 } 01942 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 01943 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 01944 astman_send_error(s, m, "Invalid priority"); 01945 return 0; 01946 } 01947 } 01948 /* XXX watch out, possible deadlock - we are trying to get two channels!!! */ 01949 chan = ast_get_channel_by_name_locked(name); 01950 if (!chan) { 01951 char buf[256]; 01952 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 01953 astman_send_error(s, m, buf); 01954 return 0; 01955 } 01956 if (ast_check_hangup(chan)) { 01957 astman_send_error(s, m, "Redirect failed, channel not up."); 01958 ast_channel_unlock(chan); 01959 return 0; 01960 } 01961 if (!ast_strlen_zero(name2)) 01962 chan2 = ast_get_channel_by_name_locked(name2); 01963 if (chan2 && ast_check_hangup(chan2)) { 01964 astman_send_error(s, m, "Redirect failed, extra channel not up."); 01965 ast_channel_unlock(chan); 01966 ast_channel_unlock(chan2); 01967 return 0; 01968 } 01969 if (chan->pbx) { 01970 ast_channel_lock(chan); 01971 ast_set_flag(chan, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 01972 ast_channel_unlock(chan); 01973 } 01974 res = ast_async_goto(chan, context, exten, pi); 01975 if (!res) { 01976 if (!ast_strlen_zero(name2)) { 01977 if (chan2) { 01978 if (chan2->pbx) { 01979 ast_channel_lock(chan2); 01980 ast_set_flag(chan2, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */ 01981 ast_channel_unlock(chan2); 01982 } 01983 res = ast_async_goto(chan2, context, exten, pi); 01984 } else { 01985 res = -1; 01986 } 01987 if (!res) 01988 astman_send_ack(s, m, "Dual Redirect successful"); 01989 else 01990 astman_send_error(s, m, "Secondary redirect failed"); 01991 } else 01992 astman_send_ack(s, m, "Redirect successful"); 01993 } else 01994 astman_send_error(s, m, "Redirect failed"); 01995 if (chan) 01996 ast_channel_unlock(chan); 01997 if (chan2) 01998 ast_channel_unlock(chan2); 01999 return 0; 02000 }
static int action_reload | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Send a reload event.
Definition at line 2572 of file manager.c.
References ast_module_reload(), astman_get_header(), astman_send_ack(), astman_send_error(), s, and S_OR.
Referenced by __init_manager().
02573 { 02574 const char *module = astman_get_header(m, "Module"); 02575 int res = ast_module_reload(S_OR(module, NULL)); 02576 02577 if (res == 2) 02578 astman_send_ack(s, m, "Module Reloaded"); 02579 else 02580 astman_send_error(s, m, s == 0 ? "No such module" : "Module does not support reload"); 02581 return 0; 02582 }
static int action_sendtext | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1882 of file manager.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_sendtext(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, and s.
Referenced by __init_manager().
01883 { 01884 struct ast_channel *c = NULL; 01885 const char *name = astman_get_header(m, "Channel"); 01886 const char *textmsg = astman_get_header(m, "Message"); 01887 int res = 0; 01888 01889 if (ast_strlen_zero(name)) { 01890 astman_send_error(s, m, "No channel specified"); 01891 return 0; 01892 } 01893 01894 if (ast_strlen_zero(textmsg)) { 01895 astman_send_error(s, m, "No Message specified"); 01896 return 0; 01897 } 01898 01899 c = ast_get_channel_by_name_locked(name); 01900 if (!c) { 01901 astman_send_error(s, m, "No such channel"); 01902 return 0; 01903 } 01904 01905 res = ast_sendtext(c, textmsg); 01906 ast_channel_unlock(c); 01907 01908 if (res > 0) 01909 astman_send_ack(s, m, "Success"); 01910 else 01911 astman_send_error(s, m, "Failure"); 01912 01913 return res; 01914 }
static int action_setvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1695 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(), s, and S_OR.
Referenced by __init_manager().
01696 { 01697 struct ast_channel *c = NULL; 01698 const char *name = astman_get_header(m, "Channel"); 01699 const char *varname = astman_get_header(m, "Variable"); 01700 const char *varval = astman_get_header(m, "Value"); 01701 01702 if (ast_strlen_zero(varname)) { 01703 astman_send_error(s, m, "No variable specified"); 01704 return 0; 01705 } 01706 01707 if (!ast_strlen_zero(name)) { 01708 c = ast_get_channel_by_name_locked(name); 01709 if (!c) { 01710 astman_send_error(s, m, "No such channel"); 01711 return 0; 01712 } 01713 } 01714 01715 pbx_builtin_setvar_helper(c, varname, S_OR(varval, "")); 01716 01717 if (c) 01718 ast_channel_unlock(c); 01719 01720 astman_send_ack(s, m, "Variable Set"); 01721 01722 return 0; 01723 }
static int action_status | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager "status" command to show channels.
Definition at line 1780 of file manager.c.
References ast_channel::_bridge, ast_channel::_state, ast_channel::accountcode, ast_channel_unlock, ast_channel_walk_locked(), ast_get_channel_by_name_locked(), ast_state2str(), ast_strlen_zero(), ast_tvnow(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, ast_channel::name, name, ast_channel::pbx, ast_channel::priority, s, S_OR, ast_cdr::start, and ast_channel::uniqueid.
Referenced by __init_manager().
01781 { 01782 const char *name = astman_get_header(m, "Channel"); 01783 struct ast_channel *c; 01784 char bridge[256]; 01785 struct timeval now = ast_tvnow(); 01786 long elapsed_seconds = 0; 01787 int channels = 0; 01788 int all = ast_strlen_zero(name); /* set if we want all channels */ 01789 const char *id = astman_get_header(m, "ActionID"); 01790 char idText[256]; 01791 01792 if (!ast_strlen_zero(id)) 01793 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01794 else 01795 idText[0] = '\0'; 01796 01797 if (all) 01798 c = ast_channel_walk_locked(NULL); 01799 else { 01800 c = ast_get_channel_by_name_locked(name); 01801 if (!c) { 01802 astman_send_error(s, m, "No such channel"); 01803 return 0; 01804 } 01805 } 01806 astman_send_ack(s, m, "Channel status will follow"); 01807 01808 /* if we look by name, we break after the first iteration */ 01809 while (c) { 01810 channels++; 01811 if (c->_bridge) 01812 snprintf(bridge, sizeof(bridge), "BridgedChannel: %s\r\nBridgedUniqueid: %s\r\n", c->_bridge->name, c->_bridge->uniqueid); 01813 else 01814 bridge[0] = '\0'; 01815 if (c->pbx) { 01816 if (c->cdr) { 01817 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01818 } 01819 astman_append(s, 01820 "Event: Status\r\n" 01821 "Privilege: Call\r\n" 01822 "Channel: %s\r\n" 01823 "CallerIDNum: %s\r\n" 01824 "CallerIDName: %s\r\n" 01825 "Accountcode: %s\r\n" 01826 "ChannelState: %d\r\n" 01827 "ChannelStateDesc: %s\r\n" 01828 "Context: %s\r\n" 01829 "Extension: %s\r\n" 01830 "Priority: %d\r\n" 01831 "Seconds: %ld\r\n" 01832 "%s" 01833 "Uniqueid: %s\r\n" 01834 "%s" 01835 "\r\n", 01836 c->name, 01837 S_OR(c->cid.cid_num, ""), 01838 S_OR(c->cid.cid_name, ""), 01839 c->accountcode, 01840 c->_state, 01841 ast_state2str(c->_state), c->context, 01842 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, idText); 01843 } else { 01844 astman_append(s, 01845 "Event: Status\r\n" 01846 "Privilege: Call\r\n" 01847 "Channel: %s\r\n" 01848 "CallerIDNum: %s\r\n" 01849 "CallerIDName: %s\r\n" 01850 "Account: %s\r\n" 01851 "State: %s\r\n" 01852 "%s" 01853 "Uniqueid: %s\r\n" 01854 "%s" 01855 "\r\n", 01856 c->name, 01857 S_OR(c->cid.cid_num, "<unknown>"), 01858 S_OR(c->cid.cid_name, "<unknown>"), 01859 c->accountcode, 01860 ast_state2str(c->_state), bridge, c->uniqueid, idText); 01861 } 01862 ast_channel_unlock(c); 01863 if (!all) 01864 break; 01865 c = ast_channel_walk_locked(c); 01866 } 01867 astman_append(s, 01868 "Event: StatusComplete\r\n" 01869 "%s" 01870 "Items: %d\r\n" 01871 "\r\n", idText, channels); 01872 return 0; 01873 }
static int action_timeout | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2403 of file manager.c.
References ast_channel_setwhentohangup(), ast_channel_unlock, ast_get_channel_by_name_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, and s.
Referenced by __init_manager().
02404 { 02405 struct ast_channel *c; 02406 const char *name = astman_get_header(m, "Channel"); 02407 int timeout = atoi(astman_get_header(m, "Timeout")); 02408 02409 if (ast_strlen_zero(name)) { 02410 astman_send_error(s, m, "No channel specified"); 02411 return 0; 02412 } 02413 if (!timeout) { 02414 astman_send_error(s, m, "No timeout specified"); 02415 return 0; 02416 } 02417 c = ast_get_channel_by_name_locked(name); 02418 if (!c) { 02419 astman_send_error(s, m, "No such channel"); 02420 return 0; 02421 } 02422 ast_channel_setwhentohangup(c, timeout); 02423 ast_channel_unlock(c); 02424 astman_send_ack(s, m, "Timeout Set"); 02425 return 0; 02426 }
static int action_updateconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1377 of file manager.c.
References ast_config_destroy(), ast_config_load, 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_DELCAT, FAILURE_DELETE, FAILURE_EMPTYCAT, FAILURE_NEWCAT, FAILURE_UPDATE, handle_updates(), s, UNKNOWN_ACTION, UNKNOWN_CATEGORY, UNSPECIFIED_ARGUMENT, and UNSPECIFIED_CATEGORY.
Referenced by __init_manager().
01378 { 01379 struct ast_config *cfg; 01380 const char *sfn = astman_get_header(m, "SrcFilename"); 01381 const char *dfn = astman_get_header(m, "DstFilename"); 01382 int res; 01383 const char *rld = astman_get_header(m, "Reload"); 01384 struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS | CONFIG_FLAG_NOCACHE }; 01385 enum error_type result; 01386 01387 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { 01388 astman_send_error(s, m, "Filename not specified"); 01389 return 0; 01390 } 01391 if (!(cfg = ast_config_load(sfn, config_flags))) { 01392 astman_send_error(s, m, "Config file not found"); 01393 return 0; 01394 } 01395 result = handle_updates(s, m, cfg, dfn); 01396 if (!result) { 01397 ast_include_rename(cfg, sfn, dfn); /* change the include references from dfn to sfn, so things match up */ 01398 res = config_text_file_save(dfn, cfg, "Manager"); 01399 ast_config_destroy(cfg); 01400 if (res) { 01401 astman_send_error(s, m, "Save of config failed"); 01402 return 0; 01403 } 01404 astman_send_ack(s, m, NULL); 01405 if (!ast_strlen_zero(rld)) { 01406 if (ast_true(rld)) 01407 rld = NULL; 01408 ast_module_reload(rld); 01409 } 01410 } else { 01411 ast_config_destroy(cfg); 01412 switch(result) { 01413 case UNKNOWN_ACTION: 01414 astman_send_error(s, m, "Unknown action command"); 01415 break; 01416 case UNKNOWN_CATEGORY: 01417 astman_send_error(s, m, "Given category does not exist"); 01418 break; 01419 case UNSPECIFIED_CATEGORY: 01420 astman_send_error(s, m, "Category not specified"); 01421 break; 01422 case UNSPECIFIED_ARGUMENT: 01423 astman_send_error(s, m, "Problem with category, value, or line (if required)"); 01424 break; 01425 case FAILURE_ALLOCATION: 01426 astman_send_error(s, m, "Memory allocation failure, this should not happen"); 01427 break; 01428 case FAILURE_NEWCAT: 01429 astman_send_error(s, m, "Create category did not complete successfully"); 01430 break; 01431 case FAILURE_DELCAT: 01432 astman_send_error(s, m, "Delete category did not complete successfully"); 01433 break; 01434 case FAILURE_EMPTYCAT: 01435 astman_send_error(s, m, "Empty category did not complete successfully"); 01436 break; 01437 case FAILURE_UPDATE: 01438 astman_send_error(s, m, "Update did not complete successfully"); 01439 break; 01440 case FAILURE_DELETE: 01441 astman_send_error(s, m, "Delete did not complete successfully"); 01442 break; 01443 case FAILURE_APPEND: 01444 astman_send_error(s, m, "Append did not complete successfully"); 01445 break; 01446 } 01447 } 01448 return 0; 01449 }
static int action_userevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2463 of file manager.c.
References ast_str_append(), ast_str_reset(), ast_str_thread_get(), astman_get_header(), EVENT_FLAG_USER, message::hdrcount, message::headers, manager_event, ast_str::str, and userevent_buf.
Referenced by __init_manager().
02464 { 02465 const char *event = astman_get_header(m, "UserEvent"); 02466 struct ast_str *body = ast_str_thread_get(&userevent_buf, 16); 02467 int x; 02468 02469 ast_str_reset(body); 02470 02471 for (x = 0; x < m->hdrcount; x++) { 02472 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 02473 ast_str_append(&body, 0, "%s\r\n", m->headers[x]); 02474 } 02475 } 02476 02477 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body->str); 02478 return 0; 02479 }
static int action_waitevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1483 of file manager.c.
References ast_debug, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_strlen_zero(), ast_wait_for_input(), astman_get_header(), NEW_EVENT, and s.
Referenced by __init_manager().
01484 { 01485 const char *timeouts = astman_get_header(m, "Timeout"); 01486 int timeout = -1; 01487 int x; 01488 int needexit = 0; 01489 const char *id = astman_get_header(m, "ActionID"); 01490 char idText[256]; 01491 01492 if (!ast_strlen_zero(id)) 01493 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01494 else 01495 idText[0] = '\0'; 01496 01497 if (!ast_strlen_zero(timeouts)) { 01498 sscanf(timeouts, "%i", &timeout); 01499 if (timeout < -1) 01500 timeout = -1; 01501 /* XXX maybe put an upper bound, or prevent the use of 0 ? */ 01502 } 01503 01504 ast_mutex_lock(&s->session->__lock); 01505 if (s->session->waiting_thread != AST_PTHREADT_NULL) 01506 pthread_kill(s->session->waiting_thread, SIGURG); 01507 01508 if (s->session->managerid) { /* AMI-over-HTTP session */ 01509 /* 01510 * Make sure the timeout is within the expire time of the session, 01511 * as the client will likely abort the request if it does not see 01512 * data coming after some amount of time. 01513 */ 01514 time_t now = time(NULL); 01515 int max = s->session->sessiontimeout - now - 10; 01516 01517 if (max < 0) /* We are already late. Strange but possible. */ 01518 max = 0; 01519 if (timeout < 0 || timeout > max) 01520 timeout = max; 01521 if (!s->session->send_events) /* make sure we record events */ 01522 s->session->send_events = -1; 01523 } 01524 ast_mutex_unlock(&s->session->__lock); 01525 01526 /* XXX should this go inside the lock ? */ 01527 s->session->waiting_thread = pthread_self(); /* let new events wake up this thread */ 01528 ast_debug(1, "Starting waiting for an event!\n"); 01529 01530 for (x = 0; x < timeout || timeout < 0; x++) { 01531 ast_mutex_lock(&s->session->__lock); 01532 if (NEW_EVENT(s)) 01533 needexit = 1; 01534 /* We can have multiple HTTP session point to the same mansession entry. 01535 * The way we deal with it is not very nice: newcomers kick out the previous 01536 * HTTP session. XXX this needs to be improved. 01537 */ 01538 if (s->session->waiting_thread != pthread_self()) 01539 needexit = 1; 01540 if (s->session->needdestroy) 01541 needexit = 1; 01542 ast_mutex_unlock(&s->session->__lock); 01543 if (needexit) 01544 break; 01545 if (s->session->managerid == 0) { /* AMI session */ 01546 if (ast_wait_for_input(s->session->fd, 1000)) 01547 break; 01548 } else { /* HTTP session */ 01549 sleep(1); 01550 } 01551 } 01552 ast_debug(1, "Finished waiting for an event!\n"); 01553 ast_mutex_lock(&s->session->__lock); 01554 if (s->session->waiting_thread == pthread_self()) { 01555 struct eventqent *eqe; 01556 astman_send_response(s, m, "Success", "Waiting for Event completed."); 01557 while ( (eqe = NEW_EVENT(s)) ) { 01558 ref_event(eqe); 01559 if (((s->session->readperm & eqe->category) == eqe->category) && 01560 ((s->session->send_events & eqe->category) == eqe->category)) { 01561 astman_append(s, "%s", eqe->eventdata); 01562 } 01563 s->session->last_ev = unref_event(s->session->last_ev); 01564 } 01565 astman_append(s, 01566 "Event: WaitEventComplete\r\n" 01567 "%s" 01568 "\r\n", idText); 01569 s->session->waiting_thread = AST_PTHREADT_NULL; 01570 } else { 01571 ast_debug(1, "Abandoning event request!\n"); 01572 } 01573 ast_mutex_unlock(&s->session->__lock); 01574 return 0; 01575 }
static int append_event | ( | const char * | str, | |
int | category | |||
) | [static] |
Definition at line 3040 of file manager.c.
References ast_atomic_fetchadd_int(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_UNLOCK, ast_malloc, and seq.
Referenced by __init_manager(), and __manager_event().
03041 { 03042 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 03043 static int seq; /* sequence number */ 03044 03045 if (!tmp) 03046 return -1; 03047 03048 /* need to init all fields, because ast_malloc() does not */ 03049 tmp->usecount = 0; 03050 tmp->category = category; 03051 tmp->seq = ast_atomic_fetchadd_int(&seq, 1); 03052 AST_LIST_NEXT(tmp, eq_next) = NULL; 03053 strcpy(tmp->eventdata, str); 03054 03055 AST_LIST_LOCK(&all_events); 03056 AST_LIST_INSERT_TAIL(&all_events, tmp, eq_next); 03057 AST_LIST_UNLOCK(&all_events); 03058 03059 return 0; 03060 }
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 405 of file manager.c.
References eventqent::next.
Referenced by get_perm().
00406 { 00407 const char *val = bigstr, *next; 00408 00409 do { 00410 if ((next = strchr(val, delim))) { 00411 if (!strncmp(val, smallstr, (next - val))) 00412 return 1; 00413 else 00414 continue; 00415 } else 00416 return !strcmp(smallstr, val); 00417 } while (*(val = (next + 1))); 00418 00419 return 0; 00420 }
int ast_manager_register2 | ( | const char * | action, | |
int | authority, | |||
int(*)(struct mansession *s, const struct message *m) | func, | |||
const char * | synopsis, | |||
const char * | description | |||
) |
Register a manager command with the manager interface.
action | Name of the requested Action: | |
authority | Required authority for this command | |
func | Function to call for this command | |
synopsis | Help text (one line, up to 30 chars) for CLI manager show commands | |
description | Help text, several lines |
Definition at line 3211 of file manager.c.
References ast_calloc, ast_free, and ast_manager_register_struct().
Referenced by __init_manager(), ast_features_init(), load_module(), and load_pbx().
03212 { 03213 struct manager_action *cur = NULL; 03214 03215 if (!(cur = ast_calloc(1, sizeof(*cur)))) 03216 return -1; 03217 03218 cur->action = action; 03219 cur->authority = auth; 03220 cur->func = func; 03221 cur->synopsis = synopsis; 03222 cur->description = description; 03223 03224 if (ast_manager_register_struct(cur)) { 03225 ast_free(cur); 03226 return -1; 03227 } 03228 03229 return 0; 03230 }
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 249 of file manager.c.
References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
00250 { 00251 AST_RWLIST_WRLOCK(&manager_hooks); 00252 AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list); 00253 AST_RWLIST_UNLOCK(&manager_hooks); 00254 return; 00255 }
static int ast_manager_register_struct | ( | struct manager_action * | act | ) | [static] |
Definition at line 3175 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().
03176 { 03177 struct manager_action *cur, *prev = NULL; 03178 struct timespec tv = { 5, }; 03179 03180 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03181 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03182 return -1; 03183 } 03184 AST_RWLIST_TRAVERSE(&actions, cur, list) { 03185 int ret = strcasecmp(cur->action, act->action); 03186 if (ret == 0) { 03187 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 03188 AST_RWLIST_UNLOCK(&actions); 03189 return -1; 03190 } 03191 if (ret > 0) { /* Insert these alphabetically */ 03192 prev = cur; 03193 break; 03194 } 03195 } 03196 03197 if (prev) 03198 AST_RWLIST_INSERT_AFTER(&actions, prev, act, list); 03199 else 03200 AST_RWLIST_INSERT_HEAD(&actions, act, list); 03201 03202 ast_verb(2, "Manager registered action %s\n", act->action); 03203 03204 AST_RWLIST_UNLOCK(&actions); 03205 03206 return 0; 03207 }
int ast_manager_unregister | ( | char * | action | ) |
Unregister a registered manager command.
action | Name of registered Action: |
Definition at line 3142 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().
03143 { 03144 struct manager_action *cur; 03145 struct timespec tv = { 5, }; 03146 03147 if (AST_RWLIST_TIMEDWRLOCK(&actions, &tv)) { 03148 ast_log(LOG_ERROR, "Could not obtain lock on manager list\n"); 03149 return -1; 03150 } 03151 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&actions, cur, list) { 03152 if (!strcasecmp(action, cur->action)) { 03153 AST_RWLIST_REMOVE_CURRENT(list); 03154 ast_free(cur); 03155 ast_verb(2, "Manager unregistered action %s\n", action); 03156 break; 03157 } 03158 } 03159 AST_RWLIST_TRAVERSE_SAFE_END 03160 AST_RWLIST_UNLOCK(&actions); 03161 03162 return 0; 03163 }
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 258 of file manager.c.
References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.
00259 { 00260 AST_RWLIST_WRLOCK(&manager_hooks); 00261 AST_RWLIST_REMOVE(&manager_hooks, hook, list); 00262 AST_RWLIST_UNLOCK(&manager_hooks); 00263 return; 00264 }
void astman_append | ( | struct mansession * | s, | |
const char * | fmt, | |||
... | ||||
) |
utility functions for creating AMI replies
Definition at line 924 of file manager.c.
References ast_str_set_va, ast_str_thread_get(), ast_verbose(), astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE, buf, s, and send_string().
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), action_agents(), action_challenge(), action_command(), action_coresettings(), action_coreshowchannels(), action_corestatus(), action_dahdishowchannels(), action_events(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_mailboxcount(), action_mailboxstatus(), action_meetmelist(), action_ping(), action_status(), 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_show_dialplan_helper(), manager_show_registry(), manager_sip_show_peer(), manager_sip_show_peers(), and session_do().
00925 { 00926 va_list ap; 00927 struct ast_str *buf; 00928 00929 if (!(buf = ast_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) 00930 return; 00931 00932 va_start(ap, fmt); 00933 ast_str_set_va(&buf, 0, fmt, ap); 00934 va_end(ap); 00935 00936 if (s->f != NULL || s->session->f != NULL) 00937 send_string(s, buf->str); 00938 else 00939 ast_verbose("fd == -1 in astman_append, should not happen\n"); 00940 }
const char* astman_get_header | ( | const struct message * | m, | |
char * | var | |||
) |
Get header from mananger transaction.
Definition at line 845 of file manager.c.
References message::hdrcount, and message::headers.
Referenced by _sip_show_peer(), _sip_show_peers(), action_add_agi_cmd(), action_agent_logoff(), action_agents(), 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_show_dialplan(), manager_show_registry(), manager_sip_show_peer(), manager_sip_show_peers(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
00846 { 00847 int x, l = strlen(var); 00848 00849 for (x = 0; x < m->hdrcount; x++) { 00850 const char *h = m->headers[x]; 00851 if (!strncasecmp(var, h, l) && h[l] == ':' && h[l+1] == ' ') 00852 return h + l + 2; 00853 } 00854 00855 return ""; 00856 }
struct ast_variable* astman_get_variables | ( | const struct message * | m | ) |
Get a linked list of the Variable: headers.
Definition at line 858 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().
00859 { 00860 int varlen, x, y; 00861 struct ast_variable *head = NULL, *cur; 00862 00863 AST_DECLARE_APP_ARGS(args, 00864 AST_APP_ARG(vars)[32]; 00865 ); 00866 00867 varlen = strlen("Variable: "); 00868 00869 for (x = 0; x < m->hdrcount; x++) { 00870 char *parse, *var, *val; 00871 00872 if (strncasecmp("Variable: ", m->headers[x], varlen)) 00873 continue; 00874 parse = ast_strdupa(m->headers[x] + varlen); 00875 00876 AST_STANDARD_APP_ARGS(args, parse); 00877 if (!args.argc) 00878 continue; 00879 for (y = 0; y < args.argc; y++) { 00880 if (!args.vars[y]) 00881 continue; 00882 var = val = ast_strdupa(args.vars[y]); 00883 strsep(&val, "="); 00884 if (!val || ast_strlen_zero(var)) 00885 continue; 00886 cur = ast_variable_new(var, val, ""); 00887 cur->next = head; 00888 head = cur; 00889 } 00890 } 00891 00892 return head; 00893 }
void astman_send_ack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg | |||
) |
Send ack in manager transaction.
Definition at line 986 of file manager.c.
References astman_send_response_full(), and s.
Referenced by action_add_agi_cmd(), action_agent_logoff(), action_agents(), action_bridge(), action_createconfig(), action_dahdidialoffhook(), action_dahdidndoff(), action_dahdidndon(), action_dahdirestart(), action_dahdishowchannels(), action_hangup(), action_login(), action_originate(), action_redirect(), action_reload(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_iax2_show_peers(), manager_jabber_send(), manager_list_voicemail_users(), manager_moduleload(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queue_log_custom(), manager_queue_member_penalty(), manager_queues_status(), manager_queues_summary(), manager_remove_queue_member(), meetmemute(), start_monitor_action(), and stop_monitor_action().
00987 { 00988 astman_send_response_full(s, m, "Success", msg, NULL); 00989 }
void astman_send_error | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | error | |||
) |
Send error in manager transaction.
Definition at line 981 of file manager.c.
References astman_send_response_full(), and s.
Referenced by _sip_show_peer(), action_add_agi_cmd(), action_agent_logoff(), 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_show_dialplan(), manager_show_dialplan_helper(), manager_sip_show_peer(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
00982 { 00983 astman_send_response_full(s, m, "Error", error, NULL); 00984 }
void astman_send_listack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg, | |||
char * | listflag | |||
) |
Send ack in manager list transaction.
Definition at line 996 of file manager.c.
References astman_send_response_full(), and s.
Referenced by action_coreshowchannels(), action_meetmelist(), manager_dpsendack(), manager_show_registry(), and manager_sip_show_peers().
00997 { 00998 astman_send_response_full(s, m, "Success", msg, listflag); 00999 }
void astman_send_response | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg | |||
) |
Send response in manager transaction.
Definition at line 976 of file manager.c.
References astman_send_response_full(), and s.
Referenced by action_logoff().
00977 { 00978 astman_send_response_full(s, m, resp, msg, NULL); 00979 }
static void astman_send_response_full | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg, | |||
char * | listflag | |||
) | [static] |
Definition at line 959 of file manager.c.
References ast_strlen_zero(), astman_append(), astman_get_header(), MSG_MOREDATA, and s.
Referenced by astman_send_ack(), astman_send_error(), astman_send_listack(), astman_send_response(), and astman_start_ack().
00960 { 00961 const char *id = astman_get_header(m, "ActionID"); 00962 00963 astman_append(s, "Response: %s\r\n", resp); 00964 if (!ast_strlen_zero(id)) 00965 astman_append(s, "ActionID: %s\r\n", id); 00966 if (listflag) 00967 astman_append(s, "Eventlist: %s\r\n", listflag); /* Start, complete, cancelled */ 00968 if (msg == MSG_MOREDATA) 00969 return; 00970 else if (msg) 00971 astman_append(s, "Message: %s\r\n\r\n", msg); 00972 else 00973 astman_append(s, "\r\n"); 00974 }
static void astman_start_ack | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 991 of file manager.c.
References astman_send_response_full(), MSG_MOREDATA, and s.
Referenced by action_challenge(), action_extensionstate(), action_getconfig(), action_getconfigjson(), action_getvar(), action_listcategories(), action_listcommands(), action_mailboxcount(), and action_mailboxstatus().
00992 { 00993 astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL); 00994 }
static int authenticate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1025 of file manager.c.
References ast_apply_ha(), ast_copy_string(), ast_debug, ast_inet_ntoa(), ast_log(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), astman_get_header(), get_manager_by_name_locked(), len(), LOG_NOTICE, md5(), MD5Final(), MD5Init(), MD5Update(), s, S_OR, set_eventmask(), and user.
Referenced by action_login(), authenticate_reply(), and registry_rerequest().
01026 { 01027 const char *username = astman_get_header(m, "Username"); 01028 const char *password = astman_get_header(m, "Secret"); 01029 int error = -1; 01030 struct ast_manager_user *user = NULL; 01031 01032 if (ast_strlen_zero(username)) /* missing username */ 01033 return -1; 01034 01035 /* locate user in locked state */ 01036 AST_RWLIST_WRLOCK(&users); 01037 01038 if (!(user = get_manager_by_name_locked(username))) { 01039 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01040 } else if (user->ha && !ast_apply_ha(user->ha, &(s->session->sin))) { 01041 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01042 } else if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) { 01043 const char *key = astman_get_header(m, "Key"); 01044 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->session->challenge) && user->secret) { 01045 int x; 01046 int len = 0; 01047 char md5key[256] = ""; 01048 struct MD5Context md5; 01049 unsigned char digest[16]; 01050 01051 MD5Init(&md5); 01052 MD5Update(&md5, (unsigned char *) s->session->challenge, strlen(s->session->challenge)); 01053 MD5Update(&md5, (unsigned char *) user->secret, strlen(user->secret)); 01054 MD5Final(digest, &md5); 01055 for (x = 0; x < 16; x++) 01056 len += sprintf(md5key + len, "%2.2x", digest[x]); 01057 if (!strcmp(md5key, key)) 01058 error = 0; 01059 } else { 01060 ast_debug(1, "MD5 authentication is not possible. challenge: '%s'\n", 01061 S_OR(s->session->challenge, "")); 01062 } 01063 } else if (password && user->secret && !strcmp(password, user->secret)) 01064 error = 0; 01065 01066 if (error) { 01067 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->session->sin.sin_addr), username); 01068 AST_RWLIST_UNLOCK(&users); 01069 return -1; 01070 } 01071 01072 /* auth complete */ 01073 01074 ast_copy_string(s->session->username, username, sizeof(s->session->username)); 01075 s->session->readperm = user->readperm; 01076 s->session->writeperm = user->writeperm; 01077 s->session->writetimeout = user->writetimeout; 01078 s->session->sessionstart = time(NULL); 01079 set_eventmask(s, astman_get_header(m, "Events")); 01080 01081 AST_RWLIST_UNLOCK(&users); 01082 return 0; 01083 }
static char* authority_to_str | ( | int | authority, | |
struct ast_str ** | res | |||
) | [static] |
Convert authority code to a list of options.
Definition at line 381 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().
00382 { 00383 int i; 00384 char *sep = ""; 00385 00386 (*res)->used = 0; 00387 for (i = 0; i < ARRAY_LEN(perms) - 1; i++) { 00388 if (authority & perms[i].num) { 00389 ast_str_append(res, 0, "%s%s", sep, perms[i].label); 00390 sep = ","; 00391 } 00392 } 00393 00394 if ((*res)->used == 0) /* replace empty string with something sensible */ 00395 ast_str_append(res, 0, "<none>"); 00396 00397 return (*res)->str; 00398 }
static int check_blacklist | ( | const char * | cmd | ) | [static] |
Definition at line 2002 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().
02003 { 02004 char *cmd_copy, *cur_cmd; 02005 char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, }; 02006 int i; 02007 02008 cmd_copy = ast_strdupa(cmd); 02009 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) { 02010 cur_cmd = ast_strip(cur_cmd); 02011 if (ast_strlen_zero(cur_cmd)) { 02012 i--; 02013 continue; 02014 } 02015 02016 cmd_words[i] = cur_cmd; 02017 } 02018 02019 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) { 02020 int j, match = 1; 02021 02022 for (j = 0; command_blacklist[i].words[j]; j++) { 02023 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) { 02024 match = 0; 02025 break; 02026 } 02027 } 02028 02029 if (match) { 02030 return 1; 02031 } 02032 } 02033 02034 return 0; 02035 }
int check_manager_enabled | ( | void | ) |
Check if AMI is enabled.
Definition at line 309 of file manager.c.
Referenced by handle_show_settings().
00310 { 00311 return manager_enabled; 00312 }
static int check_manager_session_inuse | ( | const char * | name | ) | [static] |
Definition at line 464 of file manager.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, mansession_session::list, and mansession_session::username.
Referenced by process_message().
00465 { 00466 struct mansession_session *session = NULL; 00467 00468 AST_LIST_LOCK(&sessions); 00469 AST_LIST_TRAVERSE(&sessions, session, list) { 00470 if (!strcasecmp(session->username, name)) 00471 break; 00472 } 00473 AST_LIST_UNLOCK(&sessions); 00474 00475 return session ? 1 : 0; 00476 }
int check_webmanager_enabled | ( | void | ) |
Check if AMI/HTTP is enabled.
Definition at line 314 of file manager.c.
Referenced by action_coresettings(), and handle_show_settings().
00315 { 00316 return (webmanager_enabled && manager_enabled); 00317 }
static void destroy_session | ( | struct mansession_session * | session | ) | [static] |
Definition at line 836 of file manager.c.
References ast_atomic_fetchadd_int(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, and free_session().
Referenced by accept_thread(), and skinny_session().
00837 { 00838 AST_LIST_LOCK(&sessions); 00839 AST_LIST_REMOVE(&sessions, session, list); 00840 ast_atomic_fetchadd_int(&num_sessions, -1); 00841 free_session(session); 00842 AST_LIST_UNLOCK(&sessions); 00843 }
static int do_message | ( | struct mansession * | s | ) | [static] |
Definition at line 2907 of file manager.c.
References AST_MAX_MANHEADERS, ast_strdupa, ast_strlen_zero(), get_input(), message::hdrcount, message::headers, process_events(), process_message(), and s.
Referenced by session_do().
02908 { 02909 struct message m = { 0 }; 02910 char header_buf[sizeof(s->session->inbuf)] = { '\0' }; 02911 int res; 02912 02913 for (;;) { 02914 /* Check if any events are pending and do them if needed */ 02915 if (process_events(s)) 02916 return -1; 02917 res = get_input(s, header_buf); 02918 if (res == 0) { 02919 continue; 02920 } else if (res > 0) { 02921 if (ast_strlen_zero(header_buf)) 02922 return process_message(s, &m) ? -1 : 0; 02923 else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) 02924 m.headers[m.hdrcount++] = ast_strdupa(header_buf); 02925 } else { 02926 return res; 02927 } 02928 } 02929 }
static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 2113 of file manager.c.
References fast_originate_helper::account, fast_originate_helper::app, fast_originate_helper::appdata, AST_CHANNEL_NAME, ast_channel_unlock, ast_free, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_strlen_zero(), chan, fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, fast_originate_helper::data, EVENT_FLAG_CALL, fast_originate_helper::exten, fast_originate_helper::format, fast_originate_helper::idtext, manager_event, ast_channel::name, fast_originate_helper::priority, S_OR, fast_originate_helper::tech, fast_originate_helper::timeout, ast_channel::uniqueid, and fast_originate_helper::vars.
Referenced by action_originate().
02114 { 02115 struct fast_originate_helper *in = data; 02116 int res; 02117 int reason = 0; 02118 struct ast_channel *chan = NULL; 02119 char requested_channel[AST_CHANNEL_NAME]; 02120 02121 if (!ast_strlen_zero(in->app)) { 02122 res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1, 02123 S_OR(in->cid_num, NULL), 02124 S_OR(in->cid_name, NULL), 02125 in->vars, in->account, &chan); 02126 } else { 02127 res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 02128 S_OR(in->cid_num, NULL), 02129 S_OR(in->cid_name, NULL), 02130 in->vars, in->account, &chan); 02131 } 02132 02133 if (!chan) 02134 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 02135 /* Tell the manager what happened with the channel */ 02136 manager_event(EVENT_FLAG_CALL, "OriginateResponse", 02137 "%s%s" 02138 "Response: %s\r\n" 02139 "Channel: %s\r\n" 02140 "Context: %s\r\n" 02141 "Exten: %s\r\n" 02142 "Reason: %d\r\n" 02143 "Uniqueid: %s\r\n" 02144 "CallerIDNum: %s\r\n" 02145 "CallerIDName: %s\r\n", 02146 in->idtext, ast_strlen_zero(in->idtext) ? "" : "\r\n", res ? "Failure" : "Success", 02147 chan ? chan->name : requested_channel, in->context, in->exten, reason, 02148 chan ? chan->uniqueid : "<null>", 02149 S_OR(in->cid_num, "<unknown>"), 02150 S_OR(in->cid_name, "<unknown>") 02151 ); 02152 02153 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 02154 if (chan) 02155 ast_channel_unlock(chan); 02156 ast_free(in); 02157 return NULL; 02158 }
static void free_session | ( | struct mansession_session * | session | ) | [static] |
Definition at line 826 of file manager.c.
References mansession_session::__lock, ast_free, ast_mutex_destroy(), mansession_session::f, mansession_session::last_ev, and unref_event().
Referenced by destroy_session(), and purge_sessions().
00827 { 00828 struct eventqent *eqe = session->last_ev; 00829 if (session->f != NULL) 00830 fclose(session->f); 00831 ast_mutex_destroy(&session->__lock); 00832 ast_free(session); 00833 unref_event(eqe); 00834 }
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 2837 of file manager.c.
References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_wait_for_input(), errno, LOG_WARNING, and s.
Referenced by do_message(), and skinny_session().
02838 { 02839 int res, x; 02840 int maxlen = sizeof(s->session->inbuf) - 1; 02841 char *src = s->session->inbuf; 02842 02843 /* 02844 * Look for \r\n within the buffer. If found, copy to the output 02845 * buffer and return, trimming the \r\n (not used afterwards). 02846 */ 02847 for (x = 0; x < s->session->inlen; x++) { 02848 int cr; /* set if we have \r */ 02849 if (src[x] == '\r' && x+1 < s->session->inlen && src[x+1] == '\n') 02850 cr = 2; /* Found. Update length to include \r\n */ 02851 else if (src[x] == '\n') 02852 cr = 1; /* also accept \n only */ 02853 else 02854 continue; 02855 memmove(output, src, x); /*... but trim \r\n */ 02856 output[x] = '\0'; /* terminate the string */ 02857 x += cr; /* number of bytes used */ 02858 s->session->inlen -= x; /* remaining size */ 02859 memmove(src, src + x, s->session->inlen); /* remove used bytes */ 02860 return 1; 02861 } 02862 if (s->session->inlen >= maxlen) { 02863 /* no crlf found, and buffer full - sorry, too long for us */ 02864 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->session->sin.sin_addr), src); 02865 s->session->inlen = 0; 02866 } 02867 res = 0; 02868 while (res == 0) { 02869 /* XXX do we really need this locking ? */ 02870 ast_mutex_lock(&s->session->__lock); 02871 if (s->session->pending_event) { 02872 s->session->pending_event = 0; 02873 ast_mutex_unlock(&s->session->__lock); 02874 return 0; 02875 } 02876 s->session->waiting_thread = pthread_self(); 02877 ast_mutex_unlock(&s->session->__lock); 02878 02879 res = ast_wait_for_input(s->session->fd, -1); /* return 0 on timeout ? */ 02880 02881 ast_mutex_lock(&s->session->__lock); 02882 s->session->waiting_thread = AST_PTHREADT_NULL; 02883 ast_mutex_unlock(&s->session->__lock); 02884 } 02885 if (res < 0) { 02886 /* If we get a signal from some other thread (typically because 02887 * there are new events queued), return 0 to notify the caller. 02888 */ 02889 if (errno == EINTR || errno == EAGAIN) 02890 return 0; 02891 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno)); 02892 return -1; 02893 } 02894 ast_mutex_lock(&s->session->__lock); 02895 res = fread(src + s->session->inlen, 1, maxlen - s->session->inlen, s->session->f); 02896 if (res < 1) 02897 res = -1; /* error return */ 02898 else { 02899 s->session->inlen += res; 02900 src[s->session->inlen] = '\0'; 02901 res = 0; 02902 } 02903 ast_mutex_unlock(&s->session->__lock); 02904 return res; 02905 }
static struct ast_manager_user* get_manager_by_name_locked | ( | const char * | name | ) | [static] |
lookup an entry in the list of registered users. must be called with the list lock held.
Definition at line 483 of file manager.c.
References AST_RWLIST_TRAVERSE, ast_manager_user::list, and user.
Referenced by authenticate(), handle_showmanager(), and manager_displayconnects().
00484 { 00485 struct ast_manager_user *user = NULL; 00486 00487 AST_RWLIST_TRAVERSE(&users, user, list) 00488 if (!strcasecmp(user->username, name)) 00489 break; 00490 return user; 00491 }
static int get_perm | ( | const char * | instr | ) | [static] |
Definition at line 422 of file manager.c.
References ARRAY_LEN, ast_instring(), permalias::num, and perms.
Referenced by strings_to_mask().
00423 { 00424 int x = 0, ret = 0; 00425 00426 if (!instr) 00427 return 0; 00428 00429 for (x = 0; x < ARRAY_LEN(perms); x++) { 00430 if (ast_instring(instr, perms[x].label, ',')) 00431 ret |= perms[x].num; 00432 } 00433 00434 return ret; 00435 }
static struct eventqent* grab_last | ( | void | ) | [static] |
Grab a reference to the last event, update usecount as needed. Can handle a NULL pointer.
Definition at line 323 of file manager.c.
References ast_atomic_fetchadd_int(), AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_UNLOCK, and eventqent::usecount.
Referenced by session_do().
00324 { 00325 struct eventqent *ret; 00326 00327 AST_LIST_LOCK(&all_events); 00328 ret = AST_LIST_LAST(&all_events); 00329 /* the list is never empty now, but may become so when 00330 * we optimize it in the future, so be prepared. 00331 */ 00332 if (ret) 00333 ast_atomic_fetchadd_int(&ret->usecount, 1); 00334 AST_LIST_UNLOCK(&all_events); 00335 return ret; 00336 }
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 776 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.
00777 { 00778 switch (cmd) { 00779 case CLI_INIT: 00780 e->command = "manager reload"; 00781 e->usage = 00782 "Usage: manager reload\n" 00783 " Reloads the manager configuration.\n"; 00784 return NULL; 00785 case CLI_GENERATE: 00786 return NULL; 00787 } 00788 if (a->argc > 2) 00789 return CLI_SHOWUSAGE; 00790 reload_manager(); 00791 return CLI_SUCCESS; 00792 }
static char* handle_mandebug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 557 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.
00558 { 00559 switch (cmd) { 00560 case CLI_INIT: 00561 e->command = "manager debug [on|off]"; 00562 e->usage = "Usage: manager debug [on|off]\n Show, enable, disable debugging of the manager code.\n"; 00563 return NULL; 00564 case CLI_GENERATE: 00565 return NULL; 00566 } 00567 if (a->argc == 2) 00568 ast_cli(a->fd, "manager debug is %s\n", manager_debug? "on" : "off"); 00569 else if (a->argc == 3) { 00570 if (!strcasecmp(a->argv[2], "on")) 00571 manager_debug = 1; 00572 else if (!strcasecmp(a->argv[2], "off")) 00573 manager_debug = 0; 00574 else 00575 return CLI_SHOWUSAGE; 00576 } 00577 return CLI_SUCCESS; 00578 }
static char* handle_showmanager | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 580 of file manager.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_manager_by_name_locked(), ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, user, and ast_cli_args::word.
00581 { 00582 struct ast_manager_user *user = NULL; 00583 int l, which; 00584 char *ret = NULL; 00585 struct ast_str *rauthority = ast_str_alloca(128); 00586 struct ast_str *wauthority = ast_str_alloca(128); 00587 00588 switch (cmd) { 00589 case CLI_INIT: 00590 e->command = "manager show user"; 00591 e->usage = 00592 " Usage: manager show user <user>\n" 00593 " Display all information related to the manager user specified.\n"; 00594 return NULL; 00595 case CLI_GENERATE: 00596 l = strlen(a->word); 00597 which = 0; 00598 if (a->pos != 3) 00599 return NULL; 00600 AST_RWLIST_RDLOCK(&users); 00601 AST_RWLIST_TRAVERSE(&users, user, list) { 00602 if ( !strncasecmp(a->word, user->username, l) && ++which > a->n ) { 00603 ret = ast_strdup(user->username); 00604 break; 00605 } 00606 } 00607 AST_RWLIST_UNLOCK(&users); 00608 return ret; 00609 } 00610 00611 if (a->argc != 4) 00612 return CLI_SHOWUSAGE; 00613 00614 AST_RWLIST_RDLOCK(&users); 00615 00616 if (!(user = get_manager_by_name_locked(a->argv[3]))) { 00617 ast_cli(a->fd, "There is no manager called %s\n", a->argv[3]); 00618 AST_RWLIST_UNLOCK(&users); 00619 return CLI_SUCCESS; 00620 } 00621 00622 ast_cli(a->fd, "\n"); 00623 ast_cli(a->fd, 00624 " username: %s\n" 00625 " secret: %s\n" 00626 " acl: %s\n" 00627 " read perm: %s\n" 00628 " write perm: %s\n" 00629 "displayconnects: %s\n", 00630 (user->username ? user->username : "(N/A)"), 00631 (user->secret ? "<Set>" : "(N/A)"), 00632 (user->ha ? "yes" : "no"), 00633 authority_to_str(user->readperm, &rauthority), 00634 authority_to_str(user->writeperm, &wauthority), 00635 (user->displayconnects ? "yes" : "no")); 00636 00637 AST_RWLIST_UNLOCK(&users); 00638 00639 return CLI_SUCCESS; 00640 }
static char* handle_showmanagers | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 643 of file manager.c.
References ast_cli_args::argc, ast_cli(), AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_manager_user::list, ast_cli_entry::usage, and user.
00644 { 00645 struct ast_manager_user *user = NULL; 00646 int count_amu = 0; 00647 switch (cmd) { 00648 case CLI_INIT: 00649 e->command = "manager show users"; 00650 e->usage = 00651 "Usage: manager show users\n" 00652 " Prints a listing of all managers that are currently configured on that\n" 00653 " system.\n"; 00654 return NULL; 00655 case CLI_GENERATE: 00656 return NULL; 00657 } 00658 if (a->argc != 3) 00659 return CLI_SHOWUSAGE; 00660 00661 AST_RWLIST_RDLOCK(&users); 00662 00663 /* If there are no users, print out something along those lines */ 00664 if (AST_RWLIST_EMPTY(&users)) { 00665 ast_cli(a->fd, "There are no manager users.\n"); 00666 AST_RWLIST_UNLOCK(&users); 00667 return CLI_SUCCESS; 00668 } 00669 00670 ast_cli(a->fd, "\nusername\n--------\n"); 00671 00672 AST_RWLIST_TRAVERSE(&users, user, list) { 00673 ast_cli(a->fd, "%s\n", user->username); 00674 count_amu++; 00675 } 00676 00677 AST_RWLIST_UNLOCK(&users); 00678 00679 ast_cli(a->fd, "-------------------\n"); 00680 ast_cli(a->fd, "%d manager users configured.\n", count_amu); 00681 00682 return CLI_SUCCESS; 00683 }
static char* handle_showmancmd | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 510 of file manager.c.
References manager_action::action, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_strdup, manager_action::authority, authority_to_str(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, manager_action::description, ast_cli_args::fd, ast_cli_args::n, num, S_OR, manager_action::synopsis, ast_cli_entry::usage, and ast_cli_args::word.
00511 { 00512 struct manager_action *cur; 00513 struct ast_str *authority; 00514 int num, l, which; 00515 char *ret = NULL; 00516 switch (cmd) { 00517 case CLI_INIT: 00518 e->command = "manager show command"; 00519 e->usage = 00520 "Usage: manager show command <actionname> [<actionname> [<actionname> [...]]]\n" 00521 " Shows the detailed description for a specific Asterisk manager interface command.\n"; 00522 return NULL; 00523 case CLI_GENERATE: 00524 l = strlen(a->word); 00525 which = 0; 00526 AST_RWLIST_RDLOCK(&actions); 00527 AST_RWLIST_TRAVERSE(&actions, cur, list) { 00528 if (!strncasecmp(a->word, cur->action, l) && ++which > a->n) { 00529 ret = ast_strdup(cur->action); 00530 break; /* make sure we exit even if ast_strdup() returns NULL */ 00531 } 00532 } 00533 AST_RWLIST_UNLOCK(&actions); 00534 return ret; 00535 } 00536 authority = ast_str_alloca(80); 00537 if (a->argc < 4) { 00538 return CLI_SHOWUSAGE; 00539 } 00540 00541 AST_RWLIST_RDLOCK(&actions); 00542 AST_RWLIST_TRAVERSE(&actions, cur, list) { 00543 for (num = 3; num < a->argc; num++) { 00544 if (!strcasecmp(cur->action, a->argv[num])) { 00545 ast_cli(a->fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", 00546 cur->action, cur->synopsis, 00547 authority_to_str(cur->authority, &authority), 00548 S_OR(cur->description, "")); 00549 } 00550 } 00551 } 00552 AST_RWLIST_UNLOCK(&actions); 00553 00554 return CLI_SUCCESS; 00555 }
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 687 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.
00688 { 00689 struct manager_action *cur; 00690 struct ast_str *authority; 00691 #define HSMC_FORMAT " %-15.15s %-15.15s %-55.55s\n" 00692 switch (cmd) { 00693 case CLI_INIT: 00694 e->command = "manager show commands"; 00695 e->usage = 00696 "Usage: manager show commands\n" 00697 " Prints a listing of all the available Asterisk manager interface commands.\n"; 00698 return NULL; 00699 case CLI_GENERATE: 00700 return NULL; 00701 } 00702 authority = ast_str_alloca(80); 00703 ast_cli(a->fd, HSMC_FORMAT, "Action", "Privilege", "Synopsis"); 00704 ast_cli(a->fd, HSMC_FORMAT, "------", "---------", "--------"); 00705 00706 AST_RWLIST_RDLOCK(&actions); 00707 AST_RWLIST_TRAVERSE(&actions, cur, list) 00708 ast_cli(a->fd, HSMC_FORMAT, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis); 00709 AST_RWLIST_UNLOCK(&actions); 00710 00711 return CLI_SUCCESS; 00712 }
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 715 of file manager.c.
References ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, mansession_session::fd, ast_cli_args::fd, HSMCONN_FORMAT1, HSMCONN_FORMAT2, mansession_session::inuse, mansession_session::list, mansession_session::readperm, mansession_session::sessionstart, mansession_session::sin, ast_cli_entry::usage, mansession_session::username, and mansession_session::writeperm.
00716 { 00717 struct mansession_session *session; 00718 time_t now = time(NULL); 00719 #define HSMCONN_FORMAT1 " %-15.15s %-15.15s %-10.10s %-10.10s %-8.8s %-8.8s %-5.5s %-5.5s\n" 00720 #define HSMCONN_FORMAT2 " %-15.15s %-15.15s %-10d %-10d %-8d %-8d %-5.5d %-5.5d\n" 00721 int count = 0; 00722 switch (cmd) { 00723 case CLI_INIT: 00724 e->command = "manager show connected"; 00725 e->usage = 00726 "Usage: manager show connected\n" 00727 " Prints a listing of the users that are currently connected to the\n" 00728 "Asterisk manager interface.\n"; 00729 return NULL; 00730 case CLI_GENERATE: 00731 return NULL; 00732 } 00733 00734 ast_cli(a->fd, HSMCONN_FORMAT1, "Username", "IP Address", "Start", "Elapsed", "FileDes", "HttpCnt", "Read", "Write"); 00735 00736 AST_LIST_LOCK(&sessions); 00737 AST_LIST_TRAVERSE(&sessions, session, list) { 00738 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); 00739 count++; 00740 } 00741 AST_LIST_UNLOCK(&sessions); 00742 00743 ast_cli(a->fd, "%d users connected.\n", count); 00744 00745 return CLI_SUCCESS; 00746 }
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 750 of file manager.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, eventqent::eq_next, ast_cli_args::fd, s, and ast_cli_entry::usage.
00751 { 00752 struct eventqent *s; 00753 switch (cmd) { 00754 case CLI_INIT: 00755 e->command = "manager show eventq"; 00756 e->usage = 00757 "Usage: manager show eventq\n" 00758 " Prints a listing of all events pending in the Asterisk manger\n" 00759 "event queue.\n"; 00760 return NULL; 00761 case CLI_GENERATE: 00762 return NULL; 00763 } 00764 AST_LIST_LOCK(&all_events); 00765 AST_LIST_TRAVERSE(&all_events, s, eq_next) { 00766 ast_cli(a->fd, "Usecount: %d\n", s->usecount); 00767 ast_cli(a->fd, "Category: %d\n", s->category); 00768 ast_cli(a->fd, "Event:\n%s", s->eventdata); 00769 } 00770 AST_LIST_UNLOCK(&all_events); 00771 00772 return CLI_SUCCESS; 00773 }
static enum error_type handle_updates | ( | struct mansession * | s, | |
const struct message * | m, | |||
struct ast_config * | cfg, | |||
const char * | dfn | |||
) | [static] |
Definition at line 1264 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_log(), 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().
01265 { 01266 int x; 01267 char hdr[40]; 01268 const char *action, *cat, *var, *value, *match, *line; 01269 struct ast_category *category; 01270 struct ast_variable *v; 01271 01272 for (x = 0; x < 100000; x++) { /* 100000 = the max number of allowed updates + 1 */ 01273 unsigned int object = 0; 01274 01275 snprintf(hdr, sizeof(hdr), "Action-%06d", x); 01276 action = astman_get_header(m, hdr); 01277 if (ast_strlen_zero(action)) /* breaks the for loop if no action header */ 01278 break; /* this could cause problems if actions come in misnumbered */ 01279 01280 snprintf(hdr, sizeof(hdr), "Cat-%06d", x); 01281 cat = astman_get_header(m, hdr); 01282 if (ast_strlen_zero(cat)) /* every action needs a category */ 01283 return UNSPECIFIED_CATEGORY; 01284 01285 snprintf(hdr, sizeof(hdr), "Var-%06d", x); 01286 var = astman_get_header(m, hdr); 01287 01288 snprintf(hdr, sizeof(hdr), "Value-%06d", x); 01289 value = astman_get_header(m, hdr); 01290 if (!ast_strlen_zero(value) && *value == '>') { 01291 object = 1; 01292 value++; 01293 } 01294 01295 snprintf(hdr, sizeof(hdr), "Match-%06d", x); 01296 match = astman_get_header(m, hdr); 01297 01298 snprintf(hdr, sizeof(hdr), "Line-%06d", x); 01299 line = astman_get_header(m, hdr); 01300 01301 if (!strcasecmp(action, "newcat")) { 01302 if (ast_category_get(cfg,cat)) /* check to make sure the cat doesn't */ 01303 return FAILURE_NEWCAT; /* already exist */ 01304 if (!(category = ast_category_new(cat, dfn, -1))) 01305 return FAILURE_ALLOCATION; 01306 if (ast_strlen_zero(match)) { 01307 ast_category_append(cfg, category); 01308 } else 01309 ast_category_insert(cfg, category, match); 01310 } else if (!strcasecmp(action, "renamecat")) { 01311 if (ast_strlen_zero(value)) 01312 return UNSPECIFIED_ARGUMENT; 01313 if (!(category = ast_category_get(cfg, cat))) 01314 return UNKNOWN_CATEGORY; 01315 ast_category_rename(category, value); 01316 } else if (!strcasecmp(action, "delcat")) { 01317 if (ast_category_delete(cfg, cat)) 01318 return FAILURE_DELCAT; 01319 } else if (!strcasecmp(action, "emptycat")) { 01320 if (ast_category_empty(cfg, cat)) 01321 return FAILURE_EMPTYCAT; 01322 } else if (!strcasecmp(action, "update")) { 01323 if (ast_strlen_zero(var)) 01324 return UNSPECIFIED_ARGUMENT; 01325 if (!(category = ast_category_get(cfg,cat))) 01326 return UNKNOWN_CATEGORY; 01327 if (ast_variable_update(category, var, value, match, object)) 01328 return FAILURE_UPDATE; 01329 } else if (!strcasecmp(action, "delete")) { 01330 if ((ast_strlen_zero(var) && ast_strlen_zero(line))) 01331 return UNSPECIFIED_ARGUMENT; 01332 if (!(category = ast_category_get(cfg, cat))) 01333 return UNKNOWN_CATEGORY; 01334 if (ast_variable_delete(category, var, match, line)) 01335 return FAILURE_DELETE; 01336 } else if (!strcasecmp(action, "append")) { 01337 if (ast_strlen_zero(var)) 01338 return UNSPECIFIED_ARGUMENT; 01339 if (!(category = ast_category_get(cfg, cat))) 01340 return UNKNOWN_CATEGORY; 01341 if (!(v = ast_variable_new(var, value, dfn))) 01342 return FAILURE_ALLOCATION; 01343 if (object || (match && !strcasecmp(match, "object"))) 01344 v->object = 1; 01345 ast_variable_append(category, v); 01346 } else if (!strcasecmp(action, "insert")) { 01347 if (ast_strlen_zero(var) || ast_strlen_zero(line)) 01348 return UNSPECIFIED_ARGUMENT; 01349 if (!(category = ast_category_get(cfg, cat))) 01350 return UNKNOWN_CATEGORY; 01351 if (!(v = ast_variable_new(var, value, dfn))) 01352 return FAILURE_ALLOCATION; 01353 ast_variable_insert(category, v, line); 01354 } 01355 else { 01356 ast_log(LOG_WARNING, "Action-%06d: %s not handled\n", x, action); 01357 return UNKNOWN_ACTION; 01358 } 01359 } 01360 return 0; 01361 }
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 1183 of file manager.c.
Referenced by action_getconfigjson().
01184 { 01185 for (; *in; in++) { 01186 if (*in == '\\' || *in == '\"') 01187 *out++ = '\\'; 01188 *out++ = *in; 01189 } 01190 *out = '\0'; 01191 }
static int manager_displayconnects | ( | struct mansession_session * | session | ) | [static] |
Get displayconnects config option.
s | manager session to get parameter from. |
Definition at line 497 of file manager.c.
References AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, get_manager_by_name_locked(), user, and mansession_session::username.
Referenced by action_login(), purge_sessions(), and session_do().
00498 { 00499 struct ast_manager_user *user = NULL; 00500 int ret = 0; 00501 00502 AST_RWLIST_RDLOCK(&users); 00503 if ((user = get_manager_by_name_locked (session->username))) 00504 ret = user->displayconnects; 00505 AST_RWLIST_UNLOCK(&users); 00506 00507 return ret; 00508 }
static int manager_modulecheck | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2661 of file manager.c.
References ast_copy_string(), ast_file_version_find(), ast_log(), ast_module_check(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), LOG_DEBUG, s, and version.
Referenced by __init_manager().
02662 { 02663 int res; 02664 const char *module = astman_get_header(m, "Module"); 02665 const char *id = astman_get_header(m, "ActionID"); 02666 char idText[256]; 02667 #if !defined(LOW_MEMORY) 02668 const char *version; 02669 #endif 02670 char filename[PATH_MAX]; 02671 char *cut; 02672 02673 ast_copy_string(filename, module, sizeof(filename)); 02674 if ((cut = strchr(filename, '.'))) { 02675 *cut = '\0'; 02676 } else { 02677 cut = filename + strlen(filename); 02678 } 02679 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".so"); 02680 ast_log(LOG_DEBUG, "**** ModuleCheck .so file %s\n", filename); 02681 res = ast_module_check(filename); 02682 if (!res) { 02683 astman_send_error(s, m, "Module not loaded"); 02684 return 0; 02685 } 02686 snprintf(cut, (sizeof(filename) - strlen(filename)) - 1, ".c"); 02687 ast_log(LOG_DEBUG, "**** ModuleCheck .c file %s\n", filename); 02688 #if !defined(LOW_MEMORY) 02689 version = ast_file_version_find(filename); 02690 #endif 02691 02692 if (!ast_strlen_zero(id)) 02693 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02694 else 02695 idText[0] = '\0'; 02696 astman_append(s, "Response: Success\r\n%s", idText); 02697 #if !defined(LOW_MEMORY) 02698 astman_append(s, "Version: %s\r\n\r\n", version ? version : ""); 02699 #endif 02700 return 0; 02701 }
static int manager_moduleload | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2714 of file manager.c.
References AST_FORCE_SOFT, ast_load_resource(), ast_module_reload(), ast_unload_resource(), astman_get_header(), astman_send_ack(), astman_send_error(), and s.
Referenced by __init_manager().
02715 { 02716 int res; 02717 const char *module = astman_get_header(m, "Module"); 02718 const char *loadtype = astman_get_header(m, "LoadType"); 02719 02720 if (!loadtype || strlen(loadtype) == 0) 02721 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02722 if ((!module || strlen(module) == 0) && strcasecmp(loadtype, "reload") != 0) 02723 astman_send_error(s, m, "Need module name"); 02724 02725 if (!strcasecmp(loadtype, "load")) { 02726 res = ast_load_resource(module); 02727 if (res) 02728 astman_send_error(s, m, "Could not load module."); 02729 else 02730 astman_send_ack(s, m, "Module loaded."); 02731 } else if (!strcasecmp(loadtype, "unload")) { 02732 res = ast_unload_resource(module, AST_FORCE_SOFT); 02733 if (res) 02734 astman_send_error(s, m, "Could not unload module."); 02735 else 02736 astman_send_ack(s, m, "Module unloaded."); 02737 } else if (!strcasecmp(loadtype, "reload")) { 02738 if (module != NULL) { 02739 res = ast_module_reload(module); 02740 if (res == 0) 02741 astman_send_error(s, m, "No such module."); 02742 else if (res == 1) 02743 astman_send_error(s, m, "Module does not support reload action."); 02744 else 02745 astman_send_ack(s, m, "Module reloaded."); 02746 } else { 02747 ast_module_reload(NULL); /* Reload all modules */ 02748 astman_send_ack(s, m, "All modules reloaded"); 02749 } 02750 } else 02751 astman_send_error(s, m, "Incomplete ModuleLoad action."); 02752 return 0; 02753 }
static int manager_state_cb | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Definition at line 3165 of file manager.c.
References ast_get_hint(), EVENT_FLAG_CALL, and manager_event.
Referenced by __init_manager().
03166 { 03167 /* Notify managers of change */ 03168 char hint[512]; 03169 ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, context, exten); 03170 03171 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nHint: %s\r\nStatus: %d\r\n", exten, context, hint, state); 03172 return 0; 03173 }
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 2433 of file manager.c.
References ast_mutex_lock(), ast_mutex_unlock(), NEW_EVENT, ref_event(), s, send_string(), and unref_event().
Referenced by do_message(), and process_message().
02434 { 02435 int ret = 0; 02436 02437 ast_mutex_lock(&s->session->__lock); 02438 if (s->session->f != NULL) { 02439 struct eventqent *eqe; 02440 02441 while ( (eqe = NEW_EVENT(s)) ) { 02442 ref_event(eqe); 02443 if (!ret && s->session->authenticated && 02444 (s->session->readperm & eqe->category) == eqe->category && 02445 (s->session->send_events & eqe->category) == eqe->category) { 02446 if (send_string(s, eqe->eventdata) < 0) 02447 ret = -1; /* don't send more */ 02448 } 02449 s->session->last_ev = unref_event(s->session->last_ev); 02450 } 02451 } 02452 ast_mutex_unlock(&s->session->__lock); 02453 return ret; 02454 }
static int process_message | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2768 of file manager.c.
References manager_action::action, ast_copy_string(), ast_debug, ast_mutex_lock(), ast_mutex_unlock(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), astman_get_header(), astman_send_error(), manager_action::authority, buf, check_manager_session_inuse(), manager_action::func, process_events(), and s.
Referenced by do_message().
02769 { 02770 char action[80] = ""; 02771 int ret = 0; 02772 struct manager_action *tmp; 02773 const char *user = astman_get_header(m, "Username"); 02774 02775 ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action)); 02776 ast_debug(1, "Manager received command '%s'\n", action); 02777 02778 if (ast_strlen_zero(action)) { 02779 ast_mutex_lock(&s->session->__lock); 02780 astman_send_error(s, m, "Missing action in request"); 02781 ast_mutex_unlock(&s->session->__lock); 02782 return 0; 02783 } 02784 02785 if (!s->session->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) { 02786 ast_mutex_lock(&s->session->__lock); 02787 astman_send_error(s, m, "Permission denied"); 02788 ast_mutex_unlock(&s->session->__lock); 02789 return 0; 02790 } 02791 02792 if (!allowmultiplelogin && !s->session->authenticated && user && 02793 (!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) { 02794 if (check_manager_session_inuse(user)) { 02795 sleep(1); 02796 ast_mutex_lock(&s->session->__lock); 02797 astman_send_error(s, m, "Login Already In Use"); 02798 ast_mutex_unlock(&s->session->__lock); 02799 return -1; 02800 } 02801 } 02802 02803 AST_RWLIST_RDLOCK(&actions); 02804 AST_RWLIST_TRAVERSE(&actions, tmp, list) { 02805 if (strcasecmp(action, tmp->action)) 02806 continue; 02807 if (s->session->writeperm & tmp->authority || tmp->authority == 0) 02808 ret = tmp->func(s, m); 02809 else 02810 astman_send_error(s, m, "Permission denied"); 02811 break; 02812 } 02813 AST_RWLIST_UNLOCK(&actions); 02814 02815 if (!tmp) { 02816 char buf[512]; 02817 snprintf(buf, sizeof(buf), "Invalid/unknown command: %s. Use Action: ListCommands to show available commands.", action); 02818 ast_mutex_lock(&s->session->__lock); 02819 astman_send_error(s, m, buf); 02820 ast_mutex_unlock(&s->session->__lock); 02821 } 02822 if (ret) 02823 return ret; 02824 /* Once done with our message, deliver any pending events */ 02825 return process_events(s); 02826 }
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 342 of file manager.c.
References ast_free, AST_LIST_FIRST, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, eventqent::eq_next, and eventqent::usecount.
Referenced by purge_old_stuff().
00343 { 00344 struct eventqent *ev; 00345 00346 AST_LIST_LOCK(&all_events); 00347 while ( (ev = AST_LIST_FIRST(&all_events)) && 00348 ev->usecount == 0 && AST_LIST_NEXT(ev, eq_next)) { 00349 AST_LIST_REMOVE_HEAD(&all_events, eq_next); 00350 ast_free(ev); 00351 } 00352 AST_LIST_UNLOCK(&all_events); 00353 }
static void purge_sessions | ( | int | n_max | ) | [static] |
remove at most n_max stale session from the list.
Definition at line 3013 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().
03014 { 03015 struct mansession_session *session; 03016 time_t now = time(NULL); 03017 03018 AST_LIST_LOCK(&sessions); 03019 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, session, list) { 03020 if (session->sessiontimeout && (now > session->sessiontimeout) && !session->inuse) { 03021 AST_LIST_REMOVE_CURRENT(list); 03022 ast_atomic_fetchadd_int(&num_sessions, -1); 03023 if (session->authenticated && (VERBOSITY_ATLEAST(2)) && manager_displayconnects(session)) { 03024 ast_verb(2, "HTTP Manager '%s' timed out from %s\n", 03025 session->username, ast_inet_ntoa(session->sin.sin_addr)); 03026 } 03027 free_session(session); /* XXX outside ? */ 03028 if (--n_max <= 0) 03029 break; 03030 } 03031 } 03032 AST_LIST_TRAVERSE_SAFE_END; 03033 AST_LIST_UNLOCK(&sessions); 03034 }
static void ref_event | ( | struct eventqent * | e | ) | [static] |
Definition at line 818 of file manager.c.
References ast_atomic_fetchadd_int(), and eventqent::usecount.
Referenced by process_events().
00819 { 00820 ast_atomic_fetchadd_int(&e->usecount, 1); 00821 }
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 899 of file manager.c.
References ast_careful_fwrite(), and s.
Referenced by astman_append(), and process_events().
00900 { 00901 if (s->f) { 00902 return ast_careful_fwrite(s->f, s->fd, string, strlen(string), s->session->writetimeout); 00903 } else { 00904 return ast_careful_fwrite(s->session->f, s->session->fd, string, strlen(string), s->session->writetimeout); 00905 } 00906 }
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 2939 of file manager.c.
References AMI_VERSION, ast_atomic_fetchadd_int(), ast_calloc, ast_inet_ntoa(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), AST_PTHREADT_NULL, ast_verb, astman_append(), do_message(), ast_tcptls_session_instance::f, ast_tcptls_session_instance::fd, ast_channel::flags, grab_last(), LOG_EVENT, manager_displayconnects(), ast_tcptls_session_instance::requestor, and s.
02940 { 02941 struct ast_tcptls_session_instance *ser = data; 02942 struct mansession_session *session = ast_calloc(1, sizeof(*session)); 02943 struct mansession s = {.session = NULL, }; 02944 int flags; 02945 int res; 02946 02947 if (session == NULL) 02948 goto done; 02949 02950 session->writetimeout = 100; 02951 session->waiting_thread = AST_PTHREADT_NULL; 02952 02953 flags = fcntl(ser->fd, F_GETFL); 02954 if (!block_sockets) /* make sure socket is non-blocking */ 02955 flags |= O_NONBLOCK; 02956 else 02957 flags &= ~O_NONBLOCK; 02958 fcntl(ser->fd, F_SETFL, flags); 02959 02960 ast_mutex_init(&session->__lock); 02961 session->send_events = -1; 02962 /* these fields duplicate those in the 'ser' structure */ 02963 session->fd = ser->fd; 02964 session->f = ser->f; 02965 session->sin = ser->requestor; 02966 02967 AST_LIST_LOCK(&sessions); 02968 AST_LIST_INSERT_HEAD(&sessions, session, list); 02969 ast_atomic_fetchadd_int(&num_sessions, 1); 02970 AST_LIST_UNLOCK(&sessions); 02971 /* Hook to the tail of the event queue */ 02972 session->last_ev = grab_last(); 02973 session->f = ser->f; 02974 s.session = session; 02975 astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION); /* welcome prompt */ 02976 for (;;) { 02977 if ((res = do_message(&s)) < 0) 02978 break; 02979 } 02980 /* session is over, explain why and terminate */ 02981 if (session->authenticated) { 02982 if (manager_displayconnects(session)) 02983 ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 02984 ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr)); 02985 } else { 02986 if (displayconnects) 02987 ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr)); 02988 ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(session->sin.sin_addr)); 02989 } 02990 02991 /* It is possible under certain circumstances for this session thread 02992 to complete its work and exit *before* the thread that created it 02993 has finished executing the ast_pthread_create_background() function. 02994 If this occurs, some versions of glibc appear to act in a buggy 02995 fashion and attempt to write data into memory that it thinks belongs 02996 to the thread but is in fact not owned by the thread (or may have 02997 been freed completely). 02998 02999 Causing this thread to yield to other threads at least one time 03000 appears to work around this bug. 03001 */ 03002 usleep(1); 03003 03004 destroy_session(session); 03005 03006 done: 03007 ao2_ref(ser, -1); 03008 ser = NULL; 03009 return NULL; 03010 }
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 1006 of file manager.c.
References ast_mutex_lock(), ast_mutex_unlock(), s, and strings_to_mask().
Referenced by action_events(), and authenticate().
01007 { 01008 int maskint = strings_to_mask(eventmask); 01009 01010 ast_mutex_lock(&s->session->__lock); 01011 if (maskint >= 0) 01012 s->session->send_events = maskint; 01013 ast_mutex_unlock(&s->session->__lock); 01014 01015 return maskint; 01016 }
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 441 of file manager.c.
References ARRAY_LEN, ast_false(), ast_strlen_zero(), ast_true(), get_perm(), num, and perms.
Referenced by set_eventmask().
00442 { 00443 const char *p; 00444 00445 if (ast_strlen_zero(string)) 00446 return -1; 00447 00448 for (p = string; *p; p++) 00449 if (*p < '0' || *p > '9') 00450 break; 00451 if (!p) /* all digits */ 00452 return atoi(string); 00453 if (ast_false(string)) 00454 return 0; 00455 if (ast_true(string)) { /* all permissions */ 00456 int x, ret = 0; 00457 for (x = 0; x < ARRAY_LEN(perms); x++) 00458 ret |= perms[x].num; 00459 return ret; 00460 } 00461 return get_perm(string); 00462 }
Definition at line 812 of file manager.c.
References ast_atomic_fetchadd_int(), AST_LIST_NEXT, eventqent::eq_next, and eventqent::usecount.
Referenced by free_session(), and process_events().
00813 { 00814 ast_atomic_fetchadd_int(&e->usecount, -1); 00815 return AST_LIST_NEXT(e, eq_next); 00816 }
int allowmultiplelogin = 1 [static] |
struct ast_threadstorage astman_append_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_astman_append_buf , .custom_init = NULL , } [static] |
int block_sockets [static] |
struct ast_cli_entry cli_manager[] [static] |
struct { ... } command_blacklist[] [static] |
Referenced by check_blacklist().
int displayconnects = 1 [static] |
int httptimeout = 60 [static] |
int manager_debug [static] |
int manager_enabled = 0 [static] |
struct ast_threadstorage manager_event_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_manager_event_buf , .custom_init = NULL , } [static] |
char mandescr_command[] [static] |
char mandescr_coresettings[] [static] |
char mandescr_coreshowchannels[] [static] |
char mandescr_corestatus[] [static] |
char mandescr_createconfig[] [static] |
char mandescr_events[] [static] |
char mandescr_extensionstate[] [static] |
char mandescr_getconfig[] [static] |
char mandescr_getconfigjson[] [static] |
char mandescr_getvar[] [static] |
char mandescr_hangup[] [static] |
char mandescr_listcategories[] [static] |
Initial value:
"Description: A 'ListCategories' action will dump the categories in\n" "a given file.\n" "Variables:\n" " Filename: Configuration filename (e.g. foo.conf)\n"
Definition at line 1144 of file manager.c.
Referenced by __init_manager().
char mandescr_listcommands[] [static] |
char mandescr_logoff[] [static] |
char mandescr_mailboxcount[] [static] |
char mandescr_mailboxstatus[] [static] |
char mandescr_modulecheck[] [static] |
char mandescr_moduleload[] [static] |
char mandescr_originate[] [static] |
char mandescr_ping[] [static] |
Initial value:
"Description: A 'Ping' action will ellicit a 'Pong' response. Used to keep the\n" " manager connection open.\n" "Variables: NONE\n"
Definition at line 1086 of file manager.c.
Referenced by __init_manager().
char mandescr_redirect[] [static] |
char mandescr_reload[] [static] |
char mandescr_sendtext[] [static] |
char mandescr_setvar[] [static] |
char mandescr_timeout[] [static] |
char mandescr_updateconfig[] [static] |
char mandescr_userevent[] [static] |
char mandescr_waitevent[] [static] |
int num_sessions [static] |
helper functions to convert back and forth between string and numeric representation of set of flags
Referenced by authority_to_str(), get_perm(), and strings_to_mask().
int timestampevents [static] |
struct ast_threadstorage userevent_buf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_userevent_buf , .custom_init = NULL , } [static] |
int webmanager_enabled = 0 [static] |