Data Structures | |
struct | ast_manager_user |
struct | eventqent |
struct | fast_originate_helper |
struct | mansession |
struct | permalias |
struct | variable_count |
Defines | |
#define | ASTMAN_APPEND_BUF_INITSIZE 256 |
#define | MANAGER_EVENT_BUF_INITSIZE 256 |
#define | MAX_BLACKLIST_CMD_LEN 2 |
Functions | |
static void * | accept_thread (void *ignore) |
static int | action_atxfer (struct mansession *s, const struct message *m) |
static int | action_command (struct mansession *s, const struct message *m) |
action_command: 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_corestatus (struct mansession *s, const struct message *m) |
Show PBX core status information. | |
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_getvar (struct mansession *s, const struct message *m) |
static int | action_hangup (struct mansession *s, const struct message *m) |
static int | action_listcommands (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_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 struct ast_manager_user * | ast_get_manager_by_name_locked (const char *name) |
static int | ast_instring (const char *bigstr, const char *smallstr, char delim) |
static int | ast_is_number (const char *string) |
static | AST_LIST_HEAD_STATIC (users, ast_manager_user) |
static | AST_LIST_HEAD_STATIC (sessions, mansession) |
int | ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), const char *synopsis, const char *description) |
register a new command with manager, including online help. This is the preferred way to register a manager command | |
static int | ast_manager_register_struct (struct manager_action *act) |
int | ast_manager_unregister (char *action) |
AST_RWLOCK_DEFINE_STATIC (actionlock) | |
AST_THREADSTORAGE (astman_append_buf, astman_append_buf_init) | |
AST_THREADSTORAGE (manager_event_buf, manager_event_buf_init) | |
void | astman_append (struct mansession *s, const char *fmt,...) |
const char * | astman_get_header (const struct message *m, char *var) |
ast_variable * | astman_get_variables (const struct message *m) |
void | astman_send_ack (struct mansession *s, const struct message *m, char *msg) |
void | astman_send_error (struct mansession *s, const struct message *m, char *error) |
void | astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg) |
static int | authenticate (struct mansession *s, const struct message *m) |
static char * | authority_to_str (int authority, char *res, int reslen) |
Convert authority code to string with serveral options. | |
static int | check_blacklist (const char *cmd) |
int | check_manager_enabled () |
Check if AMI is enabled. | |
int | check_webmanager_enabled () |
Check if AMI/HTTP is enabled. | |
static char * | complete_show_mancmd (const char *line, const char *word, int pos, int state) |
static int | compress_char (char c) |
static void | destroy_session (struct mansession *s) |
static int | do_message (struct mansession *s) |
static void * | fast_originate (void *data) |
static void | free_session (struct mansession *s) |
static int | get_input (struct mansession *s, char *output) |
static int | get_perm (const char *instr) |
static int | handle_showmanager (int fd, int argc, char *argv[]) |
static int | handle_showmanagers (int fd, int argc, char *argv[]) |
static int | handle_showmancmd (int fd, int argc, char *argv[]) |
static int | handle_showmancmds (int fd, int argc, char *argv[]) |
CLI command Should change to "manager show commands". | |
static int | handle_showmanconn (int fd, int argc, char *argv[]) |
CLI command show manager connected. | |
static int | handle_showmaneventq (int fd, int argc, char *argv[]) |
CLI command show manager eventq. | |
static void | handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg) |
static char * | html_translate (char *in) |
int | manager_event (int category, const char *event, const char *fmt,...) |
manager_event: Send AMI event to client | |
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 * | session_do (void *data) |
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 void | unuse_eventqent (struct eventqent *e) |
static int | variable_count_cmp_fn (void *obj, void *vstr, int flags) |
static int | variable_count_hash_fn (const void *vvc, const int flags) |
static void | xml_copy_escape (char **dst, size_t *maxlen, const char *src, int lower) |
static char * | xml_translate (char *in, struct ast_variable *vars) |
Variables | |
static int | asock = -1 |
static int | block_sockets |
static struct ast_cli_entry | cli_manager [] |
static struct ast_cli_entry | cli_show_manager_command_deprecated |
static struct ast_cli_entry | cli_show_manager_commands_deprecated |
static struct ast_cli_entry | cli_show_manager_connected_deprecated |
static struct ast_cli_entry | cli_show_manager_eventq_deprecated |
struct { | |
char * words [AST_MAX_CMD_LEN] | |
} | command_blacklist [] |
static int | displayconnects = 1 |
static struct manager_action * | first_action |
static int | httptimeout = 60 |
static int | manager_enabled = 0 |
static char | mandescr_atxfer [] |
static char | mandescr_command [] |
static char | mandescr_coresettings [] |
static char | mandescr_corestatus [] |
static char | mandescr_events [] |
static char | mandescr_extensionstate [] |
static char | mandescr_getconfig [] |
static char | mandescr_getvar [] |
static char | mandescr_hangup [] |
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_originate [] |
static char | mandescr_ping [] |
Manager PING. | |
static char | mandescr_redirect [] |
static char | mandescr_setvar [] |
static char | mandescr_timeout [] |
static char | mandescr_updateconfig [] |
static char | mandescr_userevent [] |
static char | mandescr_waitevent [] |
Manager WAITEVENT. | |
eventqent * | master_eventq = NULL |
static int | num_sessions |
static struct permalias | perms [] |
static int | portno = DEFAULT_MANAGER_PORT |
static char | showmanager_help [] |
static char | showmanagers_help [] |
static char | showmancmd_help [] |
static char | showmancmds_help [] |
static char | showmanconn_help [] |
static char | showmaneventq_help [] |
static pthread_t | t |
static int | timestampevents |
static int | webmanager_enabled = 0 |
#define ASTMAN_APPEND_BUF_INITSIZE 256 |
#define MANAGER_EVENT_BUF_INITSIZE 256 |
#define MAX_BLACKLIST_CMD_LEN 2 |
static void* accept_thread | ( | void * | ignore | ) | [static] |
Definition at line 2491 of file manager.c.
References asock, ast_calloc, ast_inet_ntoa(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), ast_pthread_create_background, AST_PTHREADT_NULL, ast_verbose(), block_sockets, destroy_session(), displayconnects, errno, pollfd::events, pollfd::fd, ast_channel::flags, free, free_session(), LOG_WARNING, master_eventq, eventqent::next, num_sessions, option_verbose, poll(), POLLIN, s, session_do(), sessions, eventqent::usecount, and VERBOSE_PREFIX_2.
Referenced by reload_config().
02492 { 02493 int as; 02494 struct sockaddr_in sin; 02495 socklen_t sinlen; 02496 struct eventqent *eqe; 02497 struct mansession *s; 02498 struct protoent *p; 02499 int arg = 1; 02500 int flags; 02501 pthread_attr_t attr; 02502 time_t now; 02503 struct pollfd pfds[1]; 02504 02505 pthread_attr_init(&attr); 02506 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02507 02508 for (;;) { 02509 time(&now); 02510 AST_LIST_LOCK(&sessions); 02511 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) { 02512 if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) { 02513 AST_LIST_REMOVE_CURRENT(&sessions, list); 02514 num_sessions--; 02515 if (s->authenticated && (option_verbose > 1) && displayconnects) { 02516 ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' timed out from %s\n", 02517 s->username, ast_inet_ntoa(s->sin.sin_addr)); 02518 } 02519 free_session(s); 02520 break; 02521 } 02522 } 02523 AST_LIST_TRAVERSE_SAFE_END 02524 /* Purge master event queue of old, unused events, but make sure we 02525 always keep at least one in the queue */ 02526 eqe = master_eventq; 02527 while (master_eventq->next && !master_eventq->usecount) { 02528 eqe = master_eventq; 02529 master_eventq = master_eventq->next; 02530 free(eqe); 02531 } 02532 AST_LIST_UNLOCK(&sessions); 02533 02534 sinlen = sizeof(sin); 02535 pfds[0].fd = asock; 02536 pfds[0].events = POLLIN; 02537 /* Wait for something to happen, but timeout every few seconds so 02538 we can ditch any old manager sessions */ 02539 if (poll(pfds, 1, 5000) < 1) 02540 continue; 02541 as = accept(asock, (struct sockaddr *)&sin, &sinlen); 02542 if (as < 0) { 02543 ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno)); 02544 continue; 02545 } 02546 p = getprotobyname("tcp"); 02547 if (p) { 02548 if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { 02549 ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno)); 02550 } 02551 } 02552 if (!(s = ast_calloc(1, sizeof(*s)))) 02553 continue; 02554 02555 memcpy(&s->sin, &sin, sizeof(sin)); 02556 s->writetimeout = 100; 02557 s->waiting_thread = AST_PTHREADT_NULL; 02558 02559 if (!block_sockets) { 02560 /* For safety, make sure socket is non-blocking */ 02561 flags = fcntl(as, F_GETFL); 02562 fcntl(as, F_SETFL, flags | O_NONBLOCK); 02563 } else { 02564 flags = fcntl(as, F_GETFL); 02565 fcntl(as, F_SETFL, flags & ~O_NONBLOCK); 02566 } 02567 ast_mutex_init(&s->__lock); 02568 s->fd = as; 02569 s->send_events = -1; 02570 AST_LIST_LOCK(&sessions); 02571 AST_LIST_INSERT_HEAD(&sessions, s, list); 02572 num_sessions++; 02573 /* Find the last place in the master event queue and hook ourselves 02574 in there */ 02575 s->eventq = master_eventq; 02576 while(s->eventq->next) 02577 s->eventq = s->eventq->next; 02578 ast_atomic_fetchadd_int(&s->eventq->usecount, 1); 02579 AST_LIST_UNLOCK(&sessions); 02580 if (ast_pthread_create_background(&s->t, &attr, session_do, s)) 02581 destroy_session(s); 02582 } 02583 pthread_attr_destroy(&attr); 02584 return NULL; 02585 }
static int action_atxfer | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1747 of file manager.c.
References asprintf, ast_channel_unlock, AST_CONTROL_ATXFERCMD, ast_get_channel_by_name_locked(), ast_queue_control_data(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), cleanup(), context, exten, free, len, name, and s.
Referenced by init_manager().
01748 { 01749 struct ast_channel *c; 01750 const char *name = astman_get_header(m, "Channel"); 01751 const char *exten = astman_get_header(m, "Exten"); 01752 const char *context = astman_get_header(m, "Context"); 01753 char *xferto; 01754 int len; 01755 01756 if (ast_strlen_zero(name)) { 01757 astman_send_error(s, m, "No channel specified"); 01758 return 0; 01759 } 01760 if (ast_strlen_zero(exten)) { 01761 astman_send_error(s, m, "No exten specified"); 01762 return 0; 01763 } 01764 c = ast_get_channel_by_name_locked(name); 01765 if (!c) { 01766 astman_send_error(s, m, "No such channel"); 01767 return 0; 01768 } 01769 len = asprintf(&xferto, "%s@%s", exten, context); 01770 if (len < 0) { 01771 astman_send_error(s, m, "Out of memory!"); 01772 goto cleanup; 01773 } 01774 ast_queue_control_data(c, AST_CONTROL_ATXFERCMD, xferto, len+1); 01775 free(xferto); 01776 astman_send_ack(s, m, "Attended transfer started"); 01777 cleanup: 01778 ast_channel_unlock(c); 01779 return 0; 01780 }
static int action_command | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_command: Manager command "command" - execute CLI command
Definition at line 1789 of file manager.c.
References ast_calloc, ast_cli_command(), ast_free, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), check_blacklist(), s, S_OR, and term_strip().
Referenced by init_manager().
01790 { 01791 const char *cmd = astman_get_header(m, "Command"); 01792 const char *id = astman_get_header(m, "ActionID"); 01793 char *buf, *final_buf; 01794 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 01795 int fd = mkstemp(template); 01796 off_t l; 01797 01798 if (ast_strlen_zero(cmd)) { 01799 astman_send_error(s, m, "No command provided"); 01800 return 0; 01801 } 01802 01803 if (check_blacklist(cmd)) { 01804 astman_send_error(s, m, "Command blacklisted"); 01805 return 0; 01806 } 01807 01808 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 01809 if (!ast_strlen_zero(id)) 01810 astman_append(s, "ActionID: %s\r\n", id); 01811 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 01812 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 01813 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 01814 01815 /* This has a potential to overflow the stack. Hence, use the heap. */ 01816 buf = ast_calloc(1, l + 1); 01817 final_buf = ast_calloc(1, l + 1); 01818 if (buf) { 01819 lseek(fd, 0, SEEK_SET); 01820 read(fd, buf, l); 01821 buf[l] = '\0'; 01822 if (final_buf) { 01823 term_strip(final_buf, buf, l); 01824 final_buf[l] = '\0'; 01825 } 01826 astman_append(s, "%s", S_OR(final_buf, buf)); 01827 ast_free(buf); 01828 } 01829 close(fd); 01830 unlink(template); 01831 astman_append(s, "--END COMMAND--\r\n\r\n"); 01832 if (final_buf) 01833 ast_free(final_buf); 01834 return 0; 01835 }
static int action_coresettings | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show PBX core settings information.
Definition at line 2205 of file manager.c.
References AMI_VERSION, ast_config_AST_RUN_GROUP, ast_config_AST_RUN_USER, ast_config_AST_SYSTEM_NAME, ast_realtime_enabled(), ast_strlen_zero(), ASTERISK_VERSION, astman_append(), astman_get_header(), check_cdr_enabled(), check_webmanager_enabled(), option_maxcalls, option_maxfiles, option_maxload, and s.
Referenced by init_manager().
02206 { 02207 const char *actionid = astman_get_header(m, "ActionID"); 02208 char idText[150] = ""; 02209 02210 if (!ast_strlen_zero(actionid)) 02211 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02212 02213 astman_append(s, "Response: Success\r\n" 02214 "%s" 02215 "AMIversion: %s\r\n" 02216 "AsteriskVersion: %s\r\n" 02217 "SystemName: %s\r\n" 02218 "CoreMaxCalls: %d\r\n" 02219 "CoreMaxLoadAvg: %f\r\n" 02220 "CoreRunUser: %s\r\n" 02221 "CoreRunGroup: %s\r\n" 02222 "CoreMaxFilehandles: %d\r\n" 02223 "CoreRealTimeEnabled: %s\r\n" 02224 "CoreCDRenabled: %s\r\n" 02225 "CoreHTTPenabled: %s\r\n" 02226 "\r\n", 02227 idText, 02228 AMI_VERSION, 02229 ASTERISK_VERSION, 02230 ast_config_AST_SYSTEM_NAME, 02231 option_maxcalls, 02232 option_maxload, 02233 ast_config_AST_RUN_USER, 02234 ast_config_AST_RUN_GROUP, 02235 option_maxfiles, 02236 ast_realtime_enabled() ? "Yes" : "No", 02237 check_cdr_enabled() ? "Yes" : "No", 02238 check_webmanager_enabled() ? "Yes" : "No" 02239 ); 02240 return 0; 02241 }
static int action_corestatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Show PBX core status information.
Definition at line 2249 of file manager.c.
References ast_active_channels(), ast_lastreloadtime, ast_localtime(), ast_startuptime, ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by init_manager().
02250 { 02251 const char *actionid = astman_get_header(m, "ActionID"); 02252 char idText[150]; 02253 char startuptime[150]; 02254 char reloadtime[150]; 02255 struct tm tm; 02256 02257 if (!ast_strlen_zero(actionid)) 02258 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", actionid); 02259 02260 ast_localtime(&ast_startuptime, &tm, NULL); 02261 strftime(startuptime, sizeof(startuptime), "%H:%M:%S", &tm); 02262 ast_localtime(&ast_lastreloadtime, &tm, NULL); 02263 strftime(reloadtime, sizeof(reloadtime), "%H:%M:%S", &tm); 02264 02265 astman_append(s, "Response: Success\r\n" 02266 "%s" 02267 "CoreStartupTime: %s\r\n" 02268 "CoreReloadTime: %s\r\n" 02269 "CoreCurrentCalls: %d\r\n" 02270 "\r\n", 02271 idText, 02272 startuptime, 02273 reloadtime, 02274 ast_active_channels() 02275 ); 02276 return 0; 02277 }
static int action_events | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1402 of file manager.c.
References astman_get_header(), astman_send_response(), s, and set_eventmask().
Referenced by init_manager().
01403 { 01404 const char *mask = astman_get_header(m, "EventMask"); 01405 int res; 01406 01407 res = set_eventmask(s, mask); 01408 if (res > 0) 01409 astman_send_response(s, m, "Events On", NULL); 01410 else if (res == 0) 01411 astman_send_response(s, m, "Events Off", NULL); 01412 01413 return 0; 01414 }
static int action_extensionstate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2087 of file manager.c.
References ast_extension_state(), ast_get_hint(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), context, exten, and s.
Referenced by init_manager().
02088 { 02089 const char *exten = astman_get_header(m, "Exten"); 02090 const char *context = astman_get_header(m, "Context"); 02091 const char *id = astman_get_header(m,"ActionID"); 02092 char idText[256] = ""; 02093 char hint[256] = ""; 02094 int status; 02095 if (ast_strlen_zero(exten)) { 02096 astman_send_error(s, m, "Extension not specified"); 02097 return 0; 02098 } 02099 if (ast_strlen_zero(context)) 02100 context = "default"; 02101 status = ast_extension_state(NULL, context, exten); 02102 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 02103 if (!ast_strlen_zero(id)) { 02104 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02105 } 02106 astman_append(s, "Response: Success\r\n" 02107 "%s" 02108 "Message: Extension Status\r\n" 02109 "Exten: %s\r\n" 02110 "Context: %s\r\n" 02111 "Hint: %s\r\n" 02112 "Status: %d\r\n\r\n", 02113 idText,exten, context, hint, status); 02114 return 0; 02115 }
static int action_getconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1131 of file manager.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load_with_comments(), ast_strlen_zero(), ast_variable_browse(), astman_append(), astman_get_header(), astman_send_error(), lineno, ast_variable::name, ast_variable::next, s, and ast_variable::value.
Referenced by init_manager().
01132 { 01133 struct ast_config *cfg; 01134 const char *fn = astman_get_header(m, "Filename"); 01135 int catcount = 0; 01136 int lineno = 0; 01137 char *category=NULL; 01138 struct ast_variable *v; 01139 char idText[256] = ""; 01140 const char *id = astman_get_header(m, "ActionID"); 01141 01142 if (!ast_strlen_zero(id)) 01143 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01144 01145 if (ast_strlen_zero(fn)) { 01146 astman_send_error(s, m, "Filename not specified"); 01147 return 0; 01148 } 01149 if (!(cfg = ast_config_load_with_comments(fn))) { 01150 astman_send_error(s, m, "Config file not found"); 01151 return 0; 01152 } 01153 astman_append(s, "Response: Success\r\n%s", idText); 01154 while ((category = ast_category_browse(cfg, category))) { 01155 lineno = 0; 01156 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 01157 for (v = ast_variable_browse(cfg, category); v; v = v->next) 01158 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 01159 catcount++; 01160 } 01161 ast_config_destroy(cfg); 01162 astman_append(s, "\r\n"); 01163 01164 return 0; 01165 }
static int action_getvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1494 of file manager.c.
References ast_channel_unlock, ast_func_read(), ast_get_channel_by_name_locked(), ast_strdupa, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), copy(), name, pbx_retrieve_variable(), and s.
Referenced by init_manager().
01495 { 01496 struct ast_channel *c = NULL; 01497 const char *name = astman_get_header(m, "Channel"); 01498 const char *varname = astman_get_header(m, "Variable"); 01499 const char *id = astman_get_header(m,"ActionID"); 01500 char *varval; 01501 char workspace[1024] = ""; 01502 01503 if (ast_strlen_zero(varname)) { 01504 astman_send_error(s, m, "No variable specified"); 01505 return 0; 01506 } 01507 01508 if (!ast_strlen_zero(name)) { 01509 c = ast_get_channel_by_name_locked(name); 01510 if (!c) { 01511 astman_send_error(s, m, "No such channel"); 01512 return 0; 01513 } 01514 } 01515 01516 if (varname[strlen(varname) - 1] == ')') { 01517 char *copy = ast_strdupa(varname); 01518 01519 ast_func_read(c, copy, workspace, sizeof(workspace)); 01520 varval = workspace; 01521 } else { 01522 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 01523 } 01524 01525 if (c) 01526 ast_channel_unlock(c); 01527 astman_append(s, "Response: Success\r\n" 01528 "Variable: %s\r\nValue: %s\r\n", varname, varval); 01529 if (!ast_strlen_zero(id)) 01530 astman_append(s, "ActionID: %s\r\n",id); 01531 astman_append(s, "\r\n"); 01532 01533 return 0; 01534 }
static int action_hangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1431 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().
01432 { 01433 struct ast_channel *c = NULL; 01434 const char *name = astman_get_header(m, "Channel"); 01435 if (ast_strlen_zero(name)) { 01436 astman_send_error(s, m, "No channel specified"); 01437 return 0; 01438 } 01439 c = ast_get_channel_by_name_locked(name); 01440 if (!c) { 01441 astman_send_error(s, m, "No such channel"); 01442 return 0; 01443 } 01444 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01445 ast_channel_unlock(c); 01446 astman_send_ack(s, m, "Channel Hungup"); 01447 return 0; 01448 }
static int action_listcommands | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1375 of file manager.c.
References manager_action::action, ast_strlen_zero(), astman_append(), astman_get_header(), manager_action::authority, authority_to_str(), first_action, manager_action::next, s, and manager_action::synopsis.
Referenced by init_manager().
01376 { 01377 struct manager_action *cur; 01378 char idText[256] = ""; 01379 char temp[BUFSIZ]; 01380 const char *id = astman_get_header(m,"ActionID"); 01381 01382 if (!ast_strlen_zero(id)) 01383 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01384 astman_append(s, "Response: Success\r\n%s", idText); 01385 for (cur = first_action; cur; cur = cur->next) { 01386 if ((s->writeperm & cur->authority) == cur->authority) 01387 astman_append(s, "%s: %s (Priv: %s)\r\n", cur->action, cur->synopsis, authority_to_str(cur->authority, temp, sizeof(temp))); 01388 } 01389 astman_append(s, "\r\n"); 01390 01391 return 0; 01392 }
static int action_logoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1420 of file manager.c.
References astman_send_response(), and s.
Referenced by init_manager().
01421 { 01422 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 01423 return -1; 01424 }
static int action_mailboxcount | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2051 of file manager.c.
References ast_app_inboxcount(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), mailbox, and s.
Referenced by init_manager().
02052 { 02053 const char *mailbox = astman_get_header(m, "Mailbox"); 02054 const char *id = astman_get_header(m,"ActionID"); 02055 char idText[256] = ""; 02056 int newmsgs = 0, oldmsgs = 0; 02057 if (ast_strlen_zero(mailbox)) { 02058 astman_send_error(s, m, "Mailbox not specified"); 02059 return 0; 02060 } 02061 ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs); 02062 if (!ast_strlen_zero(id)) { 02063 snprintf(idText, sizeof(idText), "ActionID: %s\r\n",id); 02064 } 02065 astman_append(s, "Response: Success\r\n" 02066 "%s" 02067 "Message: Mailbox Message Count\r\n" 02068 "Mailbox: %s\r\n" 02069 "NewMessages: %d\r\n" 02070 "OldMessages: %d\r\n" 02071 "\r\n", 02072 idText,mailbox, newmsgs, oldmsgs); 02073 return 0; 02074 }
static int action_mailboxstatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2019 of file manager.c.
References ast_app_has_voicemail(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), mailbox, and s.
Referenced by init_manager().
02020 { 02021 const char *mailbox = astman_get_header(m, "Mailbox"); 02022 const char *id = astman_get_header(m,"ActionID"); 02023 char idText[256] = ""; 02024 int ret; 02025 if (ast_strlen_zero(mailbox)) { 02026 astman_send_error(s, m, "Mailbox not specified"); 02027 return 0; 02028 } 02029 if (!ast_strlen_zero(id)) 02030 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02031 ret = ast_app_has_voicemail(mailbox, NULL); 02032 astman_append(s, "Response: Success\r\n" 02033 "%s" 02034 "Message: Mailbox Status\r\n" 02035 "Mailbox: %s\r\n" 02036 "Waiting: %d\r\n\r\n", idText, mailbox, ret); 02037 return 0; 02038 }
static int action_originate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1901 of file manager.c.
References app, ast_callerid_parse(), ast_calloc, ast_findlabel_extension(), AST_FORMAT_SLINEAR, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pthread_create, 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, exten, fast_originate(), name, ast_channel::priority, s, and ast_channel::tech.
Referenced by init_manager().
01902 { 01903 const char *name = astman_get_header(m, "Channel"); 01904 const char *exten = astman_get_header(m, "Exten"); 01905 const char *context = astman_get_header(m, "Context"); 01906 const char *priority = astman_get_header(m, "Priority"); 01907 const char *timeout = astman_get_header(m, "Timeout"); 01908 const char *callerid = astman_get_header(m, "CallerID"); 01909 const char *account = astman_get_header(m, "Account"); 01910 const char *app = astman_get_header(m, "Application"); 01911 const char *appdata = astman_get_header(m, "Data"); 01912 const char *async = astman_get_header(m, "Async"); 01913 const char *id = astman_get_header(m, "ActionID"); 01914 struct ast_variable *vars = astman_get_variables(m); 01915 char *tech, *data; 01916 char *l = NULL, *n = NULL; 01917 int pi = 0; 01918 int res; 01919 int to = 30000; 01920 int reason = 0; 01921 char tmp[256]; 01922 char tmp2[256]; 01923 01924 pthread_t th; 01925 pthread_attr_t attr; 01926 if (!name) { 01927 astman_send_error(s, m, "Channel not specified"); 01928 return 0; 01929 } 01930 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 01931 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 01932 astman_send_error(s, m, "Invalid priority\n"); 01933 return 0; 01934 } 01935 } 01936 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) { 01937 astman_send_error(s, m, "Invalid timeout\n"); 01938 return 0; 01939 } 01940 ast_copy_string(tmp, name, sizeof(tmp)); 01941 tech = tmp; 01942 data = strchr(tmp, '/'); 01943 if (!data) { 01944 astman_send_error(s, m, "Invalid channel\n"); 01945 return 0; 01946 } 01947 *data++ = '\0'; 01948 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 01949 ast_callerid_parse(tmp2, &n, &l); 01950 if (n) { 01951 if (ast_strlen_zero(n)) 01952 n = NULL; 01953 } 01954 if (l) { 01955 ast_shrink_phone_number(l); 01956 if (ast_strlen_zero(l)) 01957 l = NULL; 01958 } 01959 if (ast_true(async)) { 01960 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 01961 if (!fast) { 01962 res = -1; 01963 } else { 01964 if (!ast_strlen_zero(id)) 01965 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s\r\n", id); 01966 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 01967 ast_copy_string(fast->data, data, sizeof(fast->data)); 01968 ast_copy_string(fast->app, app, sizeof(fast->app)); 01969 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 01970 if (l) 01971 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 01972 if (n) 01973 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 01974 fast->vars = vars; 01975 ast_copy_string(fast->context, context, sizeof(fast->context)); 01976 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 01977 ast_copy_string(fast->account, account, sizeof(fast->account)); 01978 fast->timeout = to; 01979 fast->priority = pi; 01980 pthread_attr_init(&attr); 01981 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01982 if (ast_pthread_create(&th, &attr, fast_originate, fast)) { 01983 res = -1; 01984 } else { 01985 res = 0; 01986 } 01987 pthread_attr_destroy(&attr); 01988 } 01989 } else if (!ast_strlen_zero(app)) { 01990 res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 01991 } else { 01992 if (exten && context && pi) 01993 res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 01994 else { 01995 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 01996 return 0; 01997 } 01998 } 01999 if (!res) 02000 astman_send_ack(s, m, "Originate successfully queued"); 02001 else 02002 astman_send_error(s, m, "Originate failed"); 02003 return 0; 02004 }
static int action_ping | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1119 of file manager.c.
References astman_send_response(), and s.
Referenced by init_manager().
01120 { 01121 astman_send_response(s, m, "Pong", NULL); 01122 return 0; 01123 }
static int action_redirect | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_redirect: The redirect manager command
Definition at line 1640 of file manager.c.
References ast_async_goto(), ast_channel_unlock, ast_check_hangup(), ast_findlabel_extension(), ast_get_channel_by_name_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, exten, name, and s.
Referenced by init_manager().
01641 { 01642 const char *name = astman_get_header(m, "Channel"); 01643 const char *name2 = astman_get_header(m, "ExtraChannel"); 01644 const char *exten = astman_get_header(m, "Exten"); 01645 const char *context = astman_get_header(m, "Context"); 01646 const char *priority = astman_get_header(m, "Priority"); 01647 struct ast_channel *chan, *chan2 = NULL; 01648 int pi = 0; 01649 int res; 01650 01651 if (ast_strlen_zero(name)) { 01652 astman_send_error(s, m, "Channel not specified"); 01653 return 0; 01654 } 01655 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 01656 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 01657 astman_send_error(s, m, "Invalid priority\n"); 01658 return 0; 01659 } 01660 } 01661 /* XXX watch out, possible deadlock!!! */ 01662 chan = ast_get_channel_by_name_locked(name); 01663 if (!chan) { 01664 char buf[BUFSIZ]; 01665 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 01666 astman_send_error(s, m, buf); 01667 return 0; 01668 } 01669 if (ast_check_hangup(chan)) { 01670 astman_send_error(s, m, "Redirect failed, channel not up.\n"); 01671 ast_channel_unlock(chan); 01672 return 0; 01673 } 01674 if (!ast_strlen_zero(name2)) 01675 chan2 = ast_get_channel_by_name_locked(name2); 01676 if (chan2 && ast_check_hangup(chan2)) { 01677 astman_send_error(s, m, "Redirect failed, extra channel not up.\n"); 01678 ast_channel_unlock(chan); 01679 ast_channel_unlock(chan2); 01680 return 0; 01681 } 01682 res = ast_async_goto(chan, context, exten, pi); 01683 if (!res) { 01684 if (!ast_strlen_zero(name2)) { 01685 if (chan2) 01686 res = ast_async_goto(chan2, context, exten, pi); 01687 else 01688 res = -1; 01689 if (!res) 01690 astman_send_ack(s, m, "Dual Redirect successful"); 01691 else 01692 astman_send_error(s, m, "Secondary redirect failed"); 01693 } else 01694 astman_send_ack(s, m, "Redirect successful"); 01695 } else 01696 astman_send_error(s, m, "Redirect failed"); 01697 if (chan) 01698 ast_channel_unlock(chan); 01699 if (chan2) 01700 ast_channel_unlock(chan2); 01701 return 0; 01702 }
static int action_setvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1457 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().
01458 { 01459 struct ast_channel *c = NULL; 01460 const char *name = astman_get_header(m, "Channel"); 01461 const char *varname = astman_get_header(m, "Variable"); 01462 const char *varval = astman_get_header(m, "Value"); 01463 01464 if (ast_strlen_zero(varname)) { 01465 astman_send_error(s, m, "No variable specified"); 01466 return 0; 01467 } 01468 01469 if (!ast_strlen_zero(name)) { 01470 c = ast_get_channel_by_name_locked(name); 01471 if (!c) { 01472 astman_send_error(s, m, "No such channel"); 01473 return 0; 01474 } 01475 } 01476 01477 pbx_builtin_setvar_helper(c, varname, S_OR(varval, "")); 01478 01479 if (c) 01480 ast_channel_unlock(c); 01481 01482 astman_send_ack(s, m, "Variable Set"); 01483 01484 return 0; 01485 }
static int action_status | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager "status" command to show channels.
Definition at line 1539 of file manager.c.
References ast_channel::_bridge, ast_channel::_state, ast_channel_unlock, ast_channel_walk_locked(), ast_get_channel_by_name_locked(), ast_state2str(), ast_strlen_zero(), 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, name, ast_channel::pbx, ast_channel::priority, s, S_OR, and ast_cdr::start.
Referenced by init_manager().
01540 { 01541 const char *id = astman_get_header(m,"ActionID"); 01542 const char *name = astman_get_header(m,"Channel"); 01543 char idText[256] = ""; 01544 struct ast_channel *c; 01545 char bridge[256]; 01546 struct timeval now = ast_tvnow(); 01547 long elapsed_seconds = 0; 01548 int all = ast_strlen_zero(name); /* set if we want all channels */ 01549 01550 if (!ast_strlen_zero(id)) 01551 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01552 if (all) 01553 c = ast_channel_walk_locked(NULL); 01554 else { 01555 c = ast_get_channel_by_name_locked(name); 01556 if (!c) { 01557 astman_send_error(s, m, "No such channel"); 01558 return 0; 01559 } 01560 } 01561 astman_send_ack(s, m, "Channel status will follow"); 01562 /* if we look by name, we break after the first iteration */ 01563 while (c) { 01564 if (c->_bridge) 01565 snprintf(bridge, sizeof(bridge), "Link: %s\r\n", c->_bridge->name); 01566 else 01567 bridge[0] = '\0'; 01568 if (c->pbx) { 01569 if (c->cdr) { 01570 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01571 } 01572 astman_append(s, 01573 "Event: Status\r\n" 01574 "Privilege: Call\r\n" 01575 "Channel: %s\r\n" 01576 "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */ 01577 "CallerIDNum: %s\r\n" 01578 "CallerIDName: %s\r\n" 01579 "Account: %s\r\n" 01580 "State: %s\r\n" 01581 "Context: %s\r\n" 01582 "Extension: %s\r\n" 01583 "Priority: %d\r\n" 01584 "Seconds: %ld\r\n" 01585 "%s" 01586 "Uniqueid: %s\r\n" 01587 "%s" 01588 "\r\n", 01589 c->name, 01590 S_OR(c->cid.cid_num, "<unknown>"), 01591 S_OR(c->cid.cid_num, "<unknown>"), 01592 S_OR(c->cid.cid_name, "<unknown>"), 01593 c->accountcode, 01594 ast_state2str(c->_state), c->context, 01595 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, idText); 01596 } else { 01597 astman_append(s, 01598 "Event: Status\r\n" 01599 "Privilege: Call\r\n" 01600 "Channel: %s\r\n" 01601 "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */ 01602 "CallerIDNum: %s\r\n" 01603 "CallerIDName: %s\r\n" 01604 "Account: %s\r\n" 01605 "State: %s\r\n" 01606 "%s" 01607 "Uniqueid: %s\r\n" 01608 "%s" 01609 "\r\n", 01610 c->name, 01611 S_OR(c->cid.cid_num, "<unknown>"), 01612 S_OR(c->cid.cid_num, "<unknown>"), 01613 S_OR(c->cid.cid_name, "<unknown>"), 01614 c->accountcode, 01615 ast_state2str(c->_state), bridge, c->uniqueid, idText); 01616 } 01617 ast_channel_unlock(c); 01618 if (!all) 01619 break; 01620 c = ast_channel_walk_locked(c); 01621 } 01622 astman_append(s, 01623 "Event: StatusComplete\r\n" 01624 "%s" 01625 "\r\n",idText); 01626 return 0; 01627 }
static int action_timeout | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2124 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().
02125 { 02126 struct ast_channel *c = NULL; 02127 const char *name = astman_get_header(m, "Channel"); 02128 int timeout = atoi(astman_get_header(m, "Timeout")); 02129 if (ast_strlen_zero(name)) { 02130 astman_send_error(s, m, "No channel specified"); 02131 return 0; 02132 } 02133 if (!timeout) { 02134 astman_send_error(s, m, "No timeout specified"); 02135 return 0; 02136 } 02137 c = ast_get_channel_by_name_locked(name); 02138 if (!c) { 02139 astman_send_error(s, m, "No such channel"); 02140 return 0; 02141 } 02142 ast_channel_setwhentohangup(c, timeout); 02143 ast_channel_unlock(c); 02144 astman_send_ack(s, m, "Timeout Set"); 02145 return 0; 02146 }
static int action_updateconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1242 of file manager.c.
References ast_config_destroy(), ast_config_load_with_comments(), ast_module_reload(), ast_strlen_zero(), ast_true(), astman_append(), astman_get_header(), astman_send_error(), config_text_file_save(), handle_updates(), and s.
Referenced by init_manager().
01243 { 01244 struct ast_config *cfg; 01245 const char *sfn = astman_get_header(m, "SrcFilename"); 01246 const char *dfn = astman_get_header(m, "DstFilename"); 01247 int res; 01248 char idText[256] = ""; 01249 const char *id = astman_get_header(m, "ActionID"); 01250 const char *rld = astman_get_header(m, "Reload"); 01251 01252 if (!ast_strlen_zero(id)) 01253 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01254 01255 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { 01256 astman_send_error(s, m, "Filename not specified"); 01257 return 0; 01258 } 01259 if (!(cfg = ast_config_load_with_comments(sfn))) { 01260 astman_send_error(s, m, "Config file not found"); 01261 return 0; 01262 } 01263 handle_updates(s, m, cfg); 01264 res = config_text_file_save(dfn, cfg, "Manager"); 01265 ast_config_destroy(cfg); 01266 if (res) { 01267 astman_send_error(s, m, "Save of config failed"); 01268 return 0; 01269 } 01270 astman_append(s, "Response: Success\r\n%s\r\n", idText); 01271 if (!ast_strlen_zero(rld)) { 01272 if (ast_true(rld)) 01273 rld = NULL; 01274 ast_module_reload(rld); 01275 } 01276 return 0; 01277 }
static int action_userevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2181 of file manager.c.
References astman_get_header(), event, EVENT_FLAG_USER, message::hdrcount, message::headers, and manager_event().
Referenced by init_manager().
02182 { 02183 const char *event = astman_get_header(m, "UserEvent"); 02184 char body[2048] = ""; 02185 int x, bodylen = 0; 02186 for (x = 0; x < m->hdrcount; x++) { 02187 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 02188 ast_copy_string(body + bodylen, m->headers[x], sizeof(body) - bodylen - 3); 02189 bodylen += strlen(m->headers[x]); 02190 ast_copy_string(body + bodylen, "\r\n", 3); 02191 bodylen += 2; 02192 } 02193 } 02194 02195 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body); 02196 return 0; 02197 }
static int action_waitevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1287 of file manager.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_strlen_zero(), ast_wait_for_input(), astman_append(), astman_get_header(), astman_send_response(), eventqent::category, eventqent::eventdata, LOG_DEBUG, option_debug, s, and unuse_eventqent().
Referenced by init_manager().
01288 { 01289 const char *timeouts = astman_get_header(m, "Timeout"); 01290 int timeout = -1, max; 01291 int x; 01292 int needexit = 0; 01293 time_t now; 01294 struct eventqent *eqe; 01295 const char *id = astman_get_header(m,"ActionID"); 01296 char idText[256] = ""; 01297 01298 if (!ast_strlen_zero(id)) 01299 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01300 01301 if (!ast_strlen_zero(timeouts)) { 01302 sscanf(timeouts, "%i", &timeout); 01303 } 01304 01305 ast_mutex_lock(&s->__lock); 01306 if (s->waiting_thread != AST_PTHREADT_NULL) { 01307 pthread_kill(s->waiting_thread, SIGURG); 01308 } 01309 if (s->sessiontimeout) { 01310 time(&now); 01311 max = s->sessiontimeout - now - 10; 01312 if (max < 0) 01313 max = 0; 01314 if ((timeout < 0) || (timeout > max)) 01315 timeout = max; 01316 if (!s->send_events) 01317 s->send_events = -1; 01318 /* Once waitevent is called, always queue events from now on */ 01319 } 01320 ast_mutex_unlock(&s->__lock); 01321 s->waiting_thread = pthread_self(); 01322 if (option_debug) 01323 ast_log(LOG_DEBUG, "Starting waiting for an event!\n"); 01324 for (x=0; ((x < timeout) || (timeout < 0)); x++) { 01325 ast_mutex_lock(&s->__lock); 01326 if (s->eventq && s->eventq->next) 01327 needexit = 1; 01328 if (s->waiting_thread != pthread_self()) 01329 needexit = 1; 01330 if (s->needdestroy) 01331 needexit = 1; 01332 ast_mutex_unlock(&s->__lock); 01333 if (needexit) 01334 break; 01335 if (s->fd > 0) { 01336 if (ast_wait_for_input(s->fd, 1000)) 01337 break; 01338 } else { 01339 sleep(1); 01340 } 01341 } 01342 if (option_debug) 01343 ast_log(LOG_DEBUG, "Finished waiting for an event!\n"); 01344 ast_mutex_lock(&s->__lock); 01345 if (s->waiting_thread == pthread_self()) { 01346 astman_send_response(s, m, "Success", "Waiting for Event..."); 01347 /* Only show events if we're the most recent waiter */ 01348 while(s->eventq->next) { 01349 eqe = s->eventq->next; 01350 if (((s->readperm & eqe->category) == eqe->category) && 01351 ((s->send_events & eqe->category) == eqe->category)) { 01352 astman_append(s, "%s", eqe->eventdata); 01353 } 01354 unuse_eventqent(s->eventq); 01355 s->eventq = eqe; 01356 } 01357 astman_append(s, 01358 "Event: WaitEventComplete\r\n" 01359 "%s" 01360 "\r\n", idText); 01361 s->waiting_thread = AST_PTHREADT_NULL; 01362 } else { 01363 ast_log(LOG_DEBUG, "Abandoning event request!\n"); 01364 } 01365 ast_mutex_unlock(&s->__lock); 01366 return 0; 01367 }
static int append_event | ( | const char * | str, | |
int | category | |||
) | [static] |
Definition at line 2587 of file manager.c.
References ast_malloc, master_eventq, eventqent::next, num_sessions, and eventqent::usecount.
Referenced by init_manager(), and manager_event().
02588 { 02589 struct eventqent *tmp, *prev = NULL; 02590 tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 02591 02592 if (!tmp) 02593 return -1; 02594 02595 tmp->next = NULL; 02596 tmp->category = category; 02597 strcpy(tmp->eventdata, str); 02598 02599 if (master_eventq) { 02600 prev = master_eventq; 02601 while (prev->next) 02602 prev = prev->next; 02603 prev->next = tmp; 02604 } else { 02605 master_eventq = tmp; 02606 } 02607 02608 tmp->usecount = num_sessions; 02609 02610 return 0; 02611 }
static struct ast_manager_user* ast_get_manager_by_name_locked | ( | const char * | name | ) | [static] |
Definition at line 484 of file manager.c.
References AST_LIST_TRAVERSE, ast_manager_user::username, and users.
Referenced by handle_showmanager(), and init_manager().
00485 { 00486 struct ast_manager_user *user = NULL; 00487 00488 AST_LIST_TRAVERSE(&users, user, list) 00489 if (!strcasecmp(user->username, name)) 00490 break; 00491 return user; 00492 }
static int ast_instring | ( | const char * | bigstr, | |
const char * | smallstr, | |||
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 875 of file manager.c.
References ast_variable::next.
Referenced by get_perm(), and strings_to_mask().
00876 { 00877 const char *val = bigstr, *next; 00878 00879 do { 00880 if ((next = strchr(val, delim))) { 00881 if (!strncmp(val, smallstr, (next - val))) 00882 return 1; 00883 else 00884 continue; 00885 } else 00886 return !strcmp(smallstr, val); 00887 00888 } while (*(val = (next + 1))); 00889 00890 return 0; 00891 }
static int ast_is_number | ( | const char * | string | ) | [static] |
Definition at line 908 of file manager.c.
Referenced by strings_to_mask().
00909 { 00910 int ret = 1, x = 0; 00911 00912 if (!string) 00913 return 0; 00914 00915 for (x = 0; x < strlen(string); x++) { 00916 if (!(string[x] >= 48 && string[x] <= 57)) { 00917 ret = 0; 00918 break; 00919 } 00920 } 00921 00922 return ret ? atoi(string) : 0; 00923 }
static AST_LIST_HEAD_STATIC | ( | users | , | |
ast_manager_user | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | sessions | , | |
mansession | ||||
) | [static] |
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 new command with manager, including online help. This is the preferred way to register a manager command
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 2740 of file manager.c.
References ast_malloc, and ast_manager_register_struct().
Referenced by init_manager(), and load_module().
02741 { 02742 struct manager_action *cur; 02743 02744 cur = ast_malloc(sizeof(*cur)); 02745 if (!cur) 02746 return -1; 02747 02748 cur->action = action; 02749 cur->authority = auth; 02750 cur->func = func; 02751 cur->synopsis = synopsis; 02752 cur->description = description; 02753 cur->next = NULL; 02754 02755 ast_manager_register_struct(cur); 02756 02757 return 0; 02758 }
static int ast_manager_register_struct | ( | struct manager_action * | act | ) | [static] |
Definition at line 2696 of file manager.c.
References manager_action::action, ast_log(), ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_verbose(), first_action, LOG_WARNING, manager_action::next, option_verbose, and VERBOSE_PREFIX_2.
Referenced by ast_manager_register2().
02697 { 02698 struct manager_action *cur, *prev = NULL; 02699 int ret; 02700 02701 ast_rwlock_wrlock(&actionlock); 02702 cur = first_action; 02703 while (cur) { /* Walk the list of actions */ 02704 ret = strcasecmp(cur->action, act->action); 02705 if (ret == 0) { 02706 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 02707 ast_rwlock_unlock(&actionlock); 02708 return -1; 02709 } else if (ret > 0) { 02710 /* Insert these alphabetically */ 02711 if (prev) { 02712 act->next = prev->next; 02713 prev->next = act; 02714 } else { 02715 act->next = first_action; 02716 first_action = act; 02717 } 02718 break; 02719 } 02720 prev = cur; 02721 cur = cur->next; 02722 } 02723 02724 if (!cur) { 02725 if (prev) 02726 prev->next = act; 02727 else 02728 first_action = act; 02729 act->next = NULL; 02730 } 02731 02732 if (option_verbose > 1) 02733 ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", act->action); 02734 ast_rwlock_unlock(&actionlock); 02735 return 0; 02736 }
int ast_manager_unregister | ( | char * | action | ) |
action | Name of registred Action: |
Definition at line 2667 of file manager.c.
References manager_action::action, ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_verbose(), first_action, free, manager_action::next, option_verbose, and VERBOSE_PREFIX_2.
Referenced by __unload_module(), and unload_module().
02668 { 02669 struct manager_action *cur, *prev; 02670 02671 ast_rwlock_wrlock(&actionlock); 02672 cur = prev = first_action; 02673 while (cur) { 02674 if (!strcasecmp(action, cur->action)) { 02675 prev->next = cur->next; 02676 free(cur); 02677 if (option_verbose > 1) 02678 ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action); 02679 ast_rwlock_unlock(&actionlock); 02680 return 0; 02681 } 02682 prev = cur; 02683 cur = cur->next; 02684 } 02685 ast_rwlock_unlock(&actionlock); 02686 return 0; 02687 }
AST_RWLOCK_DEFINE_STATIC | ( | actionlock | ) |
AST_THREADSTORAGE | ( | astman_append_buf | , | |
astman_append_buf_init | ||||
) |
AST_THREADSTORAGE | ( | manager_event_buf | , | |
manager_event_buf_init | ||||
) |
void astman_append | ( | struct mansession * | s, | |
const char * | fmt, | |||
... | ||||
) |
Definition at line 494 of file manager.c.
References ast_calloc, ast_carefulwrite(), ast_dynamic_str_thread_set_va, ast_mutex_lock(), ast_mutex_unlock(), ASTMAN_APPEND_BUF_INITSIZE, and s.
Referenced by __iax2_show_peers(), __queues_show(), _sip_show_peer(), _sip_show_peers(), action_agents(), action_command(), action_coresettings(), action_corestatus(), action_extensionstate(), action_getconfig(), action_getvar(), action_listcommands(), action_mailboxcount(), action_mailboxstatus(), action_status(), action_updateconfig(), action_waitevent(), action_zapshowchannels(), ast_cli_netstats(), astman_send_error(), astman_send_response(), manager_dbget(), manager_iax2_show_netstats(), manager_iax2_show_peers(), manager_jabber_send(), manager_parking_status(), manager_queues_show(), manager_queues_status(), manager_sip_show_peer(), manager_sip_show_peers(), process_message(), and session_do().
00495 { 00496 va_list ap; 00497 struct ast_dynamic_str *buf; 00498 00499 ast_mutex_lock(&s->__lock); 00500 00501 if (!(buf = ast_dynamic_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) { 00502 ast_mutex_unlock(&s->__lock); 00503 return; 00504 } 00505 00506 va_start(ap, fmt); 00507 ast_dynamic_str_thread_set_va(&buf, 0, &astman_append_buf, fmt, ap); 00508 va_end(ap); 00509 00510 if (s->fd > -1) 00511 ast_carefulwrite(s->fd, buf->str, strlen(buf->str), s->writetimeout); 00512 else { 00513 if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) { 00514 ast_mutex_unlock(&s->__lock); 00515 return; 00516 } 00517 00518 ast_dynamic_str_append(&s->outputstr, 0, "%s", buf->str); 00519 } 00520 00521 ast_mutex_unlock(&s->__lock); 00522 }
const char* astman_get_header | ( | const struct message * | m, | |
char * | var | |||
) |
Get header from mananger transaction
Definition at line 778 of file manager.c.
References message::hdrcount, and message::headers.
Referenced by _sip_show_peer(), _sip_show_peers(), action_agent_callback_login(), action_agent_logoff(), action_agents(), action_atxfer(), action_command(), action_coresettings(), action_corestatus(), action_events(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_listcommands(), action_mailboxcount(), action_mailboxstatus(), action_originate(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), action_waitevent(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zapshowchannels(), astman_send_error(), astman_send_response(), authenticate(), change_monitor_action(), do_pause_or_unpause(), handle_updates(), manager_add_queue_member(), manager_dbget(), manager_dbput(), manager_iax2_show_peers(), manager_jabber_send(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queues_status(), manager_remove_queue_member(), manager_sip_show_peer(), manager_sip_show_peers(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
00779 { 00780 char cmp[80]; 00781 int x; 00782 00783 snprintf(cmp, sizeof(cmp), "%s: ", var); 00784 00785 for (x = 0; x < m->hdrcount; x++) { 00786 if (!strncasecmp(cmp, m->headers[x], strlen(cmp))) 00787 return m->headers[x] + strlen(cmp); 00788 } 00789 00790 return ""; 00791 }
struct ast_variable* astman_get_variables | ( | const struct message * | m | ) |
Get a linked list of the Variable: headers
Definition at line 793 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().
00794 { 00795 int varlen, x, y; 00796 struct ast_variable *head = NULL, *cur; 00797 char *var, *val; 00798 00799 char *parse; 00800 AST_DECLARE_APP_ARGS(args, 00801 AST_APP_ARG(vars)[32]; 00802 ); 00803 00804 varlen = strlen("Variable: "); 00805 00806 for (x = 0; x < m->hdrcount; x++) { 00807 if (strncasecmp("Variable: ", m->headers[x], varlen)) 00808 continue; 00809 00810 parse = ast_strdupa(m->headers[x] + varlen); 00811 00812 AST_STANDARD_APP_ARGS(args, parse); 00813 if (args.argc) { 00814 for (y = 0; y < args.argc; y++) { 00815 if (!args.vars[y]) 00816 continue; 00817 var = val = ast_strdupa(args.vars[y]); 00818 strsep(&val, "="); 00819 if (!val || ast_strlen_zero(var)) 00820 continue; 00821 cur = ast_variable_new(var, val); 00822 if (head) { 00823 cur->next = head; 00824 head = cur; 00825 } else 00826 head = cur; 00827 } 00828 } 00829 } 00830 00831 return head; 00832 }
void astman_send_ack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg | |||
) |
Definition at line 865 of file manager.c.
References astman_send_response(), and s.
Referenced by action_agent_callback_login(), action_agent_logoff(), action_agents(), action_atxfer(), action_hangup(), action_originate(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), action_zapshowchannels(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queues_status(), manager_remove_queue_member(), manager_sip_show_peers(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
00866 { 00867 astman_send_response(s, m, "Success", msg); 00868 }
void astman_send_error | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | error | |||
) |
Definition at line 842 of file manager.c.
References ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by _sip_show_peer(), action_agent_callback_login(), action_agent_logoff(), action_atxfer(), action_command(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_mailboxcount(), action_mailboxstatus(), action_originate(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_park(), manager_pause_queue_member(), manager_play_dtmf(), manager_remove_queue_member(), manager_sip_show_peer(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
00843 { 00844 const char *id = astman_get_header(m,"ActionID"); 00845 00846 astman_append(s, "Response: Error\r\n"); 00847 if (!ast_strlen_zero(id)) 00848 astman_append(s, "ActionID: %s\r\n", id); 00849 astman_append(s, "Message: %s\r\n\r\n", error); 00850 }
void astman_send_response | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg | |||
) |
Definition at line 852 of file manager.c.
References ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by action_events(), action_logoff(), action_ping(), action_waitevent(), and astman_send_ack().
00853 { 00854 const char *id = astman_get_header(m,"ActionID"); 00855 00856 astman_append(s, "Response: %s\r\n", resp); 00857 if (!ast_strlen_zero(id)) 00858 astman_append(s, "ActionID: %s\r\n", id); 00859 if (msg) 00860 astman_append(s, "Message: %s\r\n\r\n", msg); 00861 else 00862 astman_append(s, "\r\n"); 00863 }
static int authenticate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 968 of file manager.c.
References ast_append_ha(), ast_apply_ha(), ast_category_browse(), ast_config_AST_SYSTEM_NAME, ast_config_destroy(), ast_config_load(), ast_free_ha(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_true(), ast_variable_browse(), astman_get_header(), events, len, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), ast_variable::name, ast_variable::next, password, s, S_OR, and ast_variable::value.
Referenced by authenticate_reply(), handle_response_invite(), process_message(), and registry_rerequest().
00969 { 00970 struct ast_config *cfg; 00971 char *cat; 00972 const char *user = astman_get_header(m, "Username"); 00973 const char *pass = astman_get_header(m, "Secret"); 00974 const char *authtype = astman_get_header(m, "AuthType"); 00975 const char *key = astman_get_header(m, "Key"); 00976 const char *events = astman_get_header(m, "Events"); 00977 00978 cfg = ast_config_load("manager.conf"); 00979 if (!cfg) 00980 return -1; 00981 cat = ast_category_browse(cfg, NULL); 00982 while (cat) { 00983 if (strcasecmp(cat, "general")) { 00984 /* This is a user */ 00985 if (!strcasecmp(cat, user)) { 00986 struct ast_variable *v; 00987 struct ast_ha *ha = NULL; 00988 char *password = NULL; 00989 00990 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 00991 if (!strcasecmp(v->name, "secret")) { 00992 password = v->value; 00993 } else if (!strcasecmp(v->name, "displaysystemname")) { 00994 if (ast_true(v->value)) { 00995 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) { 00996 s->displaysystemname = 1; 00997 } else { 00998 ast_log(LOG_ERROR, "Can't enable displaysystemname in manager.conf - no system name configured in asterisk.conf\n"); 00999 } 01000 } 01001 } else if (!strcasecmp(v->name, "permit") || 01002 !strcasecmp(v->name, "deny")) { 01003 ha = ast_append_ha(v->name, v->value, ha); 01004 } else if (!strcasecmp(v->name, "writetimeout")) { 01005 int val = atoi(v->value); 01006 01007 if (val < 100) 01008 ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", v->value, v->lineno); 01009 else 01010 s->writetimeout = val; 01011 } 01012 01013 } 01014 if (ha && !ast_apply_ha(ha, &(s->sin))) { 01015 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01016 ast_free_ha(ha); 01017 ast_config_destroy(cfg); 01018 return -1; 01019 } else if (ha) 01020 ast_free_ha(ha); 01021 if (!strcasecmp(authtype, "MD5")) { 01022 if (!ast_strlen_zero(key) && 01023 !ast_strlen_zero(s->challenge) && !ast_strlen_zero(password)) { 01024 int x; 01025 int len = 0; 01026 char md5key[256] = ""; 01027 struct MD5Context md5; 01028 unsigned char digest[16]; 01029 MD5Init(&md5); 01030 MD5Update(&md5, (unsigned char *) s->challenge, strlen(s->challenge)); 01031 MD5Update(&md5, (unsigned char *) password, strlen(password)); 01032 MD5Final(digest, &md5); 01033 for (x=0; x<16; x++) 01034 len += sprintf(md5key + len, "%2.2x", digest[x]); 01035 if (!strcmp(md5key, key)) 01036 break; 01037 else { 01038 ast_config_destroy(cfg); 01039 return -1; 01040 } 01041 } else { 01042 ast_log(LOG_DEBUG, "MD5 authentication is not possible. challenge: '%s'\n", 01043 S_OR(s->challenge, "")); 01044 ast_config_destroy(cfg); 01045 return -1; 01046 } 01047 } else if (password && !strcmp(password, pass)) { 01048 break; 01049 } else { 01050 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01051 ast_config_destroy(cfg); 01052 return -1; 01053 } 01054 } 01055 } 01056 cat = ast_category_browse(cfg, cat); 01057 } 01058 if (cat) { 01059 ast_copy_string(s->username, cat, sizeof(s->username)); 01060 s->readperm = get_perm(ast_variable_retrieve(cfg, cat, "read")); 01061 s->writeperm = get_perm(ast_variable_retrieve(cfg, cat, "write")); 01062 ast_config_destroy(cfg); 01063 if (events) 01064 set_eventmask(s, events); 01065 return 0; 01066 } 01067 ast_config_destroy(cfg); 01068 cfg = ast_config_load("users.conf"); 01069 if (!cfg) 01070 return -1; 01071 cat = ast_category_browse(cfg, NULL); 01072 while (cat) { 01073 struct ast_variable *v; 01074 const char *password = NULL; 01075 int hasmanager = 0; 01076 const char *readperms = NULL; 01077 const char *writeperms = NULL; 01078 01079 if (strcasecmp(cat, user) || !strcasecmp(cat, "general")) { 01080 cat = ast_category_browse(cfg, cat); 01081 continue; 01082 } 01083 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 01084 if (!strcasecmp(v->name, "secret")) 01085 password = v->value; 01086 else if (!strcasecmp(v->name, "hasmanager")) 01087 hasmanager = ast_true(v->value); 01088 else if (!strcasecmp(v->name, "managerread")) 01089 readperms = v->value; 01090 else if (!strcasecmp(v->name, "managerwrite")) 01091 writeperms = v->value; 01092 } 01093 if (!hasmanager) 01094 break; 01095 if (!password || strcmp(password, pass)) { 01096 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01097 ast_config_destroy(cfg); 01098 return -1; 01099 } 01100 ast_copy_string(s->username, cat, sizeof(s->username)); 01101 s->readperm = readperms ? get_perm(readperms) : -1; 01102 s->writeperm = writeperms ? get_perm(writeperms) : -1; 01103 ast_config_destroy(cfg); 01104 if (events) 01105 set_eventmask(s, events); 01106 return 0; 01107 } 01108 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01109 ast_config_destroy(cfg); 01110 return -1; 01111 }
static char* authority_to_str | ( | int | authority, | |
char * | res, | |||
int | reslen | |||
) | [static] |
Convert authority code to string with serveral options.
Definition at line 218 of file manager.c.
References ast_strlen_zero(), and perms.
Referenced by action_listcommands(), handle_showmancmd(), handle_showmancmds(), and manager_event().
00219 { 00220 int running_total = 0, i; 00221 00222 memset(res, 0, reslen); 00223 for (i = 0; i < (sizeof(perms) / sizeof(perms[0])) - 1; i++) { 00224 if (authority & perms[i].num) { 00225 if (*res) { 00226 strncat(res, ",", (reslen > running_total) ? reslen - running_total - 1 : 0); 00227 running_total++; 00228 } 00229 strncat(res, perms[i].label, (reslen > running_total) ? reslen - running_total - 1 : 0); 00230 running_total += strlen(perms[i].label); 00231 } 00232 } 00233 00234 if (ast_strlen_zero(res)) 00235 ast_copy_string(res, "<none>", reslen); 00236 00237 return res; 00238 }
static int check_blacklist | ( | const char * | cmd | ) | [static] |
Definition at line 1704 of file manager.c.
References ARRAY_LEN, ast_strdupa, ast_strlen_zero(), command_blacklist, match(), MAX_BLACKLIST_CMD_LEN, strsep(), and words.
Referenced by action_command().
01705 { 01706 char *cmd_copy, *cur_cmd; 01707 char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, }; 01708 int i; 01709 01710 cmd_copy = ast_strdupa(cmd); 01711 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) { 01712 cur_cmd = ast_strip(cur_cmd); 01713 if (ast_strlen_zero(cur_cmd)) { 01714 i--; 01715 continue; 01716 } 01717 01718 cmd_words[i] = cur_cmd; 01719 } 01720 01721 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) { 01722 int j, match = 1; 01723 01724 for (j = 0; command_blacklist[i].words[j]; j++) { 01725 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) { 01726 match = 0; 01727 break; 01728 } 01729 } 01730 01731 if (match) { 01732 return 1; 01733 } 01734 } 01735 01736 return 0; 01737 }
int check_manager_enabled | ( | void | ) |
Check if AMI is enabled.
Definition at line 207 of file manager.c.
Referenced by handle_show_settings().
00208 { 00209 return manager_enabled; 00210 }
int check_webmanager_enabled | ( | void | ) |
Check if AMI/HTTP is enabled.
Definition at line 212 of file manager.c.
Referenced by action_coresettings(), and handle_show_settings().
00213 { 00214 return (webmanager_enabled && manager_enabled); 00215 }
static char* complete_show_mancmd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 240 of file manager.c.
References manager_action::action, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_strdup, first_action, and manager_action::next.
00241 { 00242 struct manager_action *cur; 00243 int which = 0; 00244 char *ret = NULL; 00245 00246 ast_rwlock_rdlock(&actionlock); 00247 for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */ 00248 if (!strncasecmp(word, cur->action, strlen(word)) && ++which > state) { 00249 ret = ast_strdup(cur->action); 00250 break; /* make sure we exit even if ast_strdup() returns NULL */ 00251 } 00252 } 00253 ast_rwlock_unlock(&actionlock); 00254 00255 return ret; 00256 }
static int compress_char | ( | char | c | ) | [static] |
Definition at line 300 of file manager.c.
Referenced by member_hash_fn(), and variable_count_hash_fn().
00301 { 00302 c &= 0x7f; 00303 if (c < 32) 00304 return 0; 00305 else if (c >= 'a' && c <= 'z') 00306 return c - 64; 00307 else if (c > 'z') 00308 return '_'; 00309 else 00310 return c - 32; 00311 }
static void destroy_session | ( | struct mansession * | s | ) | [static] |
Definition at line 769 of file manager.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, free_session(), s, and sessions.
Referenced by accept_thread(), and skinny_session().
00770 { 00771 AST_LIST_LOCK(&sessions); 00772 AST_LIST_REMOVE(&sessions, s, list); 00773 num_sessions--; 00774 free_session(s); 00775 AST_LIST_UNLOCK(&sessions); 00776 }
static int do_message | ( | struct mansession * | s | ) | [static] |
Definition at line 2420 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().
02421 { 02422 struct message m = { 0 }; 02423 char header_buf[sizeof(s->inbuf)] = { '\0' }; 02424 int res; 02425 02426 for (;;) { 02427 /* Check if any events are pending and do them if needed */ 02428 if (s->eventq->next) { 02429 if (process_events(s)) 02430 return -1; 02431 } 02432 res = get_input(s, header_buf); 02433 if (res == 0) { 02434 continue; 02435 } else if (res > 0) { 02436 /* Strip trailing \r\n */ 02437 if (strlen(header_buf) < 2) 02438 continue; 02439 header_buf[strlen(header_buf) - 2] = '\0'; 02440 if (ast_strlen_zero(header_buf)) 02441 return process_message(s, &m) ? -1 : 0; 02442 else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) 02443 m.headers[m.hdrcount++] = ast_strdupa(header_buf); 02444 } else { 02445 return res; 02446 } 02447 } 02448 }
static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 1837 of file manager.c.
References fast_originate_helper::account, fast_originate_helper::app, fast_originate_helper::appdata, AST_CHANNEL_NAME, ast_channel_unlock, AST_FORMAT_SLINEAR, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_strlen_zero(), 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, free, fast_originate_helper::idtext, manager_event(), fast_originate_helper::priority, S_OR, fast_originate_helper::tech, fast_originate_helper::timeout, and fast_originate_helper::vars.
Referenced by action_originate().
01838 { 01839 struct fast_originate_helper *in = data; 01840 int res; 01841 int reason = 0; 01842 struct ast_channel *chan = NULL; 01843 char requested_channel[AST_CHANNEL_NAME]; 01844 01845 if (!ast_strlen_zero(in->app)) { 01846 res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, 01847 S_OR(in->cid_num, NULL), 01848 S_OR(in->cid_name, NULL), 01849 in->vars, in->account, &chan); 01850 } else { 01851 res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 01852 S_OR(in->cid_num, NULL), 01853 S_OR(in->cid_name, NULL), 01854 in->vars, in->account, &chan); 01855 } 01856 01857 if (!chan) 01858 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 01859 /* Tell the manager what happened with the channel */ 01860 manager_event(EVENT_FLAG_CALL, "OriginateResponse", 01861 "%s" 01862 "Response: %s\r\n" 01863 "Channel: %s\r\n" 01864 "Context: %s\r\n" 01865 "Exten: %s\r\n" 01866 "Reason: %d\r\n" 01867 "Uniqueid: %s\r\n" 01868 "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */ 01869 "CallerIDNum: %s\r\n" 01870 "CallerIDName: %s\r\n", 01871 in->idtext, res ? "Failure" : "Success", chan ? chan->name : requested_channel, in->context, in->exten, reason, 01872 chan ? chan->uniqueid : "<null>", 01873 S_OR(in->cid_num, "<unknown>"), 01874 S_OR(in->cid_num, "<unknown>"), 01875 S_OR(in->cid_name, "<unknown>") 01876 ); 01877 01878 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 01879 if (chan) 01880 ast_channel_unlock(chan); 01881 free(in); 01882 return NULL; 01883 }
static void free_session | ( | struct mansession * | s | ) | [static] |
Definition at line 753 of file manager.c.
References ast_mutex_destroy(), free, s, and unuse_eventqent().
Referenced by accept_thread(), and destroy_session().
00754 { 00755 struct eventqent *eqe; 00756 if (s->fd > -1) 00757 close(s->fd); 00758 if (s->outputstr) 00759 free(s->outputstr); 00760 ast_mutex_destroy(&s->__lock); 00761 while (s->eventq) { 00762 eqe = s->eventq; 00763 s->eventq = s->eventq->next; 00764 unuse_eventqent(eqe); 00765 } 00766 free(s); 00767 }
static int get_input | ( | struct mansession * | s, | |
char * | output | |||
) | [static] |
Definition at line 2361 of file manager.c.
References ast_channel::fds, and s.
Referenced by do_message(), and skinny_session().
02362 { 02363 /* output must have at least sizeof(s->inbuf) space */ 02364 int res; 02365 int x; 02366 struct pollfd fds[1]; 02367 for (x = 1; x < s->inlen; x++) { 02368 if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) { 02369 /* Copy output data up to and including \r\n */ 02370 memcpy(output, s->inbuf, x + 1); 02371 /* Add trailing \0 */ 02372 output[x+1] = '\0'; 02373 /* Move remaining data back to the front */ 02374 memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x); 02375 s->inlen -= (x + 1); 02376 return 1; 02377 } 02378 } 02379 if (s->inlen >= sizeof(s->inbuf) - 1) { 02380 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->sin.sin_addr), s->inbuf); 02381 s->inlen = 0; 02382 } 02383 fds[0].fd = s->fd; 02384 fds[0].events = POLLIN; 02385 do { 02386 ast_mutex_lock(&s->__lock); 02387 if (s->pending_event) { 02388 s->pending_event = 0; 02389 ast_mutex_unlock(&s->__lock); 02390 return 0; 02391 } 02392 s->waiting_thread = pthread_self(); 02393 ast_mutex_unlock(&s->__lock); 02394 02395 res = poll(fds, 1, -1); 02396 02397 ast_mutex_lock(&s->__lock); 02398 s->waiting_thread = AST_PTHREADT_NULL; 02399 ast_mutex_unlock(&s->__lock); 02400 if (res < 0) { 02401 if (errno == EINTR || errno == EAGAIN) { 02402 return 0; 02403 } 02404 ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno)); 02405 return -1; 02406 } else if (res > 0) { 02407 ast_mutex_lock(&s->__lock); 02408 res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen); 02409 ast_mutex_unlock(&s->__lock); 02410 if (res < 1) 02411 return -1; 02412 break; 02413 } 02414 } while(1); 02415 s->inlen += res; 02416 s->inbuf[s->inlen] = '\0'; 02417 return 0; 02418 }
static int get_perm | ( | const char * | instr | ) | [static] |
Definition at line 893 of file manager.c.
References ast_instring(), and perms.
00894 { 00895 int x = 0, ret = 0; 00896 00897 if (!instr) 00898 return 0; 00899 00900 for (x = 0; x < (sizeof(perms) / sizeof(perms[0])); x++) { 00901 if (ast_instring(instr, perms[x].label, ',')) 00902 ret |= perms[x].num; 00903 } 00904 00905 return ret; 00906 }
static int handle_showmanager | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 546 of file manager.c.
References ast_cli(), ast_get_manager_by_name_locked(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_manager_user::deny, ast_manager_user::displayconnects, ast_manager_user::permit, ast_manager_user::read, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_manager_user::secret, ast_manager_user::username, users, and ast_manager_user::write.
00547 { 00548 struct ast_manager_user *user = NULL; 00549 00550 if (argc != 4) 00551 return RESULT_SHOWUSAGE; 00552 00553 AST_LIST_LOCK(&users); 00554 00555 if (!(user = ast_get_manager_by_name_locked(argv[3]))) { 00556 ast_cli(fd, "There is no manager called %s\n", argv[3]); 00557 AST_LIST_UNLOCK(&users); 00558 return -1; 00559 } 00560 00561 ast_cli(fd,"\n"); 00562 ast_cli(fd, 00563 " username: %s\n" 00564 " secret: %s\n" 00565 " deny: %s\n" 00566 " permit: %s\n" 00567 " read: %s\n" 00568 " write: %s\n" 00569 "displayconnects: %s\n", 00570 (user->username ? user->username : "(N/A)"), 00571 (user->secret ? "<Set>" : "(N/A)"), 00572 (user->deny ? user->deny : "(N/A)"), 00573 (user->permit ? user->permit : "(N/A)"), 00574 (user->read ? user->read : "(N/A)"), 00575 (user->write ? user->write : "(N/A)"), 00576 (user->displayconnects ? "yes" : "no")); 00577 00578 AST_LIST_UNLOCK(&users); 00579 00580 return RESULT_SUCCESS; 00581 }
static int handle_showmanagers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 584 of file manager.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_manager_user::username, and users.
00585 { 00586 struct ast_manager_user *user = NULL; 00587 int count_amu = 0; 00588 00589 if (argc != 3) 00590 return RESULT_SHOWUSAGE; 00591 00592 AST_LIST_LOCK(&users); 00593 00594 /* If there are no users, print out something along those lines */ 00595 if (AST_LIST_EMPTY(&users)) { 00596 ast_cli(fd, "There are no manager users.\n"); 00597 AST_LIST_UNLOCK(&users); 00598 return RESULT_SUCCESS; 00599 } 00600 00601 ast_cli(fd, "\nusername\n--------\n"); 00602 00603 AST_LIST_TRAVERSE(&users, user, list) { 00604 ast_cli(fd, "%s\n", user->username); 00605 count_amu++; 00606 } 00607 00608 AST_LIST_UNLOCK(&users); 00609 00610 ast_cli(fd,"-------------------\n"); 00611 ast_cli(fd,"%d manager users configured.\n", count_amu); 00612 00613 return RESULT_SUCCESS; 00614 }
static int handle_showmancmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 524 of file manager.c.
References manager_action::action, ast_cli(), ast_rwlock_rdlock(), manager_action::authority, authority_to_str(), manager_action::description, first_action, manager_action::next, RESULT_SHOWUSAGE, and manager_action::synopsis.
00525 { 00526 struct manager_action *cur; 00527 char authority[80]; 00528 int num; 00529 00530 if (argc != 4) 00531 return RESULT_SHOWUSAGE; 00532 00533 ast_rwlock_rdlock(&actionlock); 00534 for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */ 00535 for (num = 3; num < argc; num++) { 00536 if (!strcasecmp(cur->action, argv[num])) { 00537 ast_cli(fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", cur->action, cur->synopsis, authority_to_str(cur->authority, authority, sizeof(authority) -1), cur->description ? cur->description : ""); 00538 } 00539 } 00540 } 00541 ast_rwlock_unlock(&actionlock); 00542 00543 return RESULT_SUCCESS; 00544 }
static int handle_showmancmds | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command Should change to "manager show commands".
Definition at line 619 of file manager.c.
References manager_action::action, ast_cli(), ast_rwlock_rdlock(), ast_rwlock_unlock(), manager_action::authority, authority_to_str(), first_action, format, manager_action::next, RESULT_SUCCESS, and manager_action::synopsis.
00620 { 00621 struct manager_action *cur; 00622 char authority[80]; 00623 char *format = " %-15.15s %-15.15s %-55.55s\n"; 00624 00625 ast_cli(fd, format, "Action", "Privilege", "Synopsis"); 00626 ast_cli(fd, format, "------", "---------", "--------"); 00627 00628 ast_rwlock_rdlock(&actionlock); 00629 for (cur = first_action; cur; cur = cur->next) /* Walk the list of actions */ 00630 ast_cli(fd, format, cur->action, authority_to_str(cur->authority, authority, sizeof(authority) -1), cur->synopsis); 00631 ast_rwlock_unlock(&actionlock); 00632 00633 return RESULT_SUCCESS; 00634 }
static int handle_showmanconn | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command show manager connected.
Definition at line 638 of file manager.c.
References ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, format, RESULT_SUCCESS, s, and sessions.
00639 { 00640 struct mansession *s; 00641 char wtout[32]; 00642 char *format = " %-15.15s %-15.15s %-15.15s\n"; 00643 00644 ast_cli(fd, format, "Username", "IP Address", "Timeout"); 00645 00646 AST_LIST_LOCK(&sessions); 00647 AST_LIST_TRAVERSE(&sessions, s, list) { 00648 memset(wtout, 0, sizeof(wtout)); 00649 snprintf(wtout, sizeof(wtout)-1, "%d", s->writetimeout); 00650 ast_cli(fd, format,s->username, ast_inet_ntoa(s->sin.sin_addr), wtout); 00651 } 00652 AST_LIST_UNLOCK(&sessions); 00653 00654 return RESULT_SUCCESS; 00655 }
static int handle_showmaneventq | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command show manager eventq.
Definition at line 659 of file manager.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_UNLOCK, master_eventq, RESULT_SUCCESS, s, and sessions.
00660 { 00661 struct eventqent *s; 00662 00663 AST_LIST_LOCK(&sessions); 00664 for (s = master_eventq; s; s = s->next) { 00665 ast_cli(fd, "Usecount: %d\n",s->usecount); 00666 ast_cli(fd, "Category: %d\n", s->category); 00667 ast_cli(fd, "Event:\n%s", s->eventdata); 00668 } 00669 AST_LIST_UNLOCK(&sessions); 00670 00671 return RESULT_SUCCESS; 00672 }
static void handle_updates | ( | struct mansession * | s, | |
const struct message * | m, | |||
struct ast_config * | cfg | |||
) | [static] |
Definition at line 1168 of file manager.c.
References ast_category_append(), ast_category_delete(), ast_category_get(), ast_category_new(), ast_category_rename(), ast_strlen_zero(), ast_variable_append(), ast_variable_delete(), ast_variable_new(), ast_variable_update(), astman_get_header(), match(), ast_variable::object, ast_variable::value, and var.
Referenced by action_updateconfig().
01169 { 01170 int x; 01171 char hdr[40]; 01172 const char *action, *cat, *var, *value, *match; 01173 struct ast_category *category; 01174 struct ast_variable *v; 01175 01176 for (x=0;x<100000;x++) { 01177 unsigned int object = 0; 01178 01179 snprintf(hdr, sizeof(hdr), "Action-%06d", x); 01180 action = astman_get_header(m, hdr); 01181 if (ast_strlen_zero(action)) 01182 break; 01183 snprintf(hdr, sizeof(hdr), "Cat-%06d", x); 01184 cat = astman_get_header(m, hdr); 01185 snprintf(hdr, sizeof(hdr), "Var-%06d", x); 01186 var = astman_get_header(m, hdr); 01187 snprintf(hdr, sizeof(hdr), "Value-%06d", x); 01188 value = astman_get_header(m, hdr); 01189 if (!ast_strlen_zero(value) && *value == '>') { 01190 object = 1; 01191 value++; 01192 } 01193 snprintf(hdr, sizeof(hdr), "Match-%06d", x); 01194 match = astman_get_header(m, hdr); 01195 if (!strcasecmp(action, "newcat")) { 01196 if (!ast_strlen_zero(cat)) { 01197 category = ast_category_new(cat); 01198 if (category) { 01199 ast_category_append(cfg, category); 01200 } 01201 } 01202 } else if (!strcasecmp(action, "renamecat")) { 01203 if (!ast_strlen_zero(cat) && !ast_strlen_zero(value)) { 01204 category = ast_category_get(cfg, cat); 01205 if (category) 01206 ast_category_rename(category, value); 01207 } 01208 } else if (!strcasecmp(action, "delcat")) { 01209 if (!ast_strlen_zero(cat)) 01210 ast_category_delete(cfg, (char *) cat); 01211 } else if (!strcasecmp(action, "update")) { 01212 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat))) 01213 ast_variable_update(category, var, value, match, object); 01214 } else if (!strcasecmp(action, "delete")) { 01215 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat))) 01216 ast_variable_delete(category, (char *) var, (char *) match); 01217 } else if (!strcasecmp(action, "append")) { 01218 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && 01219 (category = ast_category_get(cfg, cat)) && 01220 (v = ast_variable_new(var, value))){ 01221 if (object || (match && !strcasecmp(match, "object"))) 01222 v->object = 1; 01223 ast_variable_append(category, v); 01224 } 01225 } 01226 } 01227 }
static char* html_translate | ( | char * | in | ) | [static] |
Definition at line 435 of file manager.c.
References ast_build_string(), ast_malloc, len, and var.
00436 { 00437 int x; 00438 int colons = 0; 00439 int breaks = 0; 00440 size_t len; 00441 int count = 1; 00442 char *tmp, *var, *val, *out; 00443 00444 for (x=0; in[x]; x++) { 00445 if (in[x] == ':') 00446 colons++; 00447 if (in[x] == '\n') 00448 breaks++; 00449 } 00450 len = strlen(in) + colons * 40 + breaks * 40; /* <tr><td></td><td></td></tr>, "<tr><td colspan=\"2\"><hr></td></tr> */ 00451 out = ast_malloc(len); 00452 if (!out) 00453 return 0; 00454 tmp = out; 00455 while (*in) { 00456 var = in; 00457 while (*in && (*in >= 32)) 00458 in++; 00459 if (*in) { 00460 if ((count % 4) == 0){ 00461 ast_build_string(&tmp, &len, "<tr><td colspan=\"2\"><hr></td></tr>\r\n"); 00462 } 00463 count = 0; 00464 while (*in && (*in < 32)) { 00465 *in = '\0'; 00466 in++; 00467 count++; 00468 } 00469 val = strchr(var, ':'); 00470 if (val) { 00471 *val = '\0'; 00472 val++; 00473 if (*val == ' ') 00474 val++; 00475 ast_build_string(&tmp, &len, "<tr><td>%s</td><td>%s</td></tr>\r\n", var, val); 00476 } 00477 } 00478 } 00479 return out; 00480 }
int manager_event | ( | int | category, | |
const char * | event, | |||
const char * | fmt, | |||
... | ||||
) |
manager_event: Send AMI event to client
Definition at line 2614 of file manager.c.
References append_event(), ast_dynamic_str_thread_append(), ast_dynamic_str_thread_append_va, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, authority_to_str(), MANAGER_EVENT_BUF_INITSIZE, num_sessions, s, sessions, and timestampevents.
Referenced by __expire_registry(), __iax2_poke_noanswer(), __login_exec(), action_agent_callback_login(), action_userevent(), add_to_queue(), agent_logoff_maintenance(), aji_log_hook(), ast_change_name(), ast_channel_bridge(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_set_callerid(), ast_setstate(), change_hold_state(), conf_run(), expire_register(), fast_originate(), handle_init_event(), handle_response_peerpoke(), handle_response_register(), iax2_ack_registry(), join_queue(), leave_queue(), manager_log(), manager_state_cb(), notify_new_message(), park_call_full(), park_exec(), parse_register_contact(), pbx_extension_helper(), post_manager_event(), quit_handler(), realtime_exec(), record_abandoned(), register_verify(), reload_logger(), reload_manager(), remove_from_queue(), ring_entry(), senddialevent(), set_member_paused(), sip_poke_noanswer(), sip_reg_timeout(), socket_process(), ss_thread(), try_calling(), update_registry(), update_status(), userevent_exec(), vm_execmain(), and zt_handle_event().
02615 { 02616 struct mansession *s; 02617 char auth[80]; 02618 va_list ap; 02619 struct timeval now; 02620 struct ast_dynamic_str *buf; 02621 02622 /* Abort if there aren't any manager sessions */ 02623 if (!num_sessions) 02624 return 0; 02625 02626 if (!(buf = ast_dynamic_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) 02627 return -1; 02628 02629 ast_dynamic_str_thread_set(&buf, 0, &manager_event_buf, 02630 "Event: %s\r\nPrivilege: %s\r\n", 02631 event, authority_to_str(category, auth, sizeof(auth))); 02632 02633 if (timestampevents) { 02634 now = ast_tvnow(); 02635 ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, 02636 "Timestamp: %ld.%06lu\r\n", 02637 now.tv_sec, (unsigned long) now.tv_usec); 02638 } 02639 02640 va_start(ap, fmt); 02641 ast_dynamic_str_thread_append_va(&buf, 0, &manager_event_buf, fmt, ap); 02642 va_end(ap); 02643 02644 ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, "\r\n"); 02645 02646 /* Append event to master list and wake up any sleeping sessions */ 02647 AST_LIST_LOCK(&sessions); 02648 append_event(buf->str, category); 02649 AST_LIST_TRAVERSE(&sessions, s, list) { 02650 ast_mutex_lock(&s->__lock); 02651 if (s->waiting_thread != AST_PTHREADT_NULL) 02652 pthread_kill(s->waiting_thread, SIGURG); 02653 else 02654 /* We have an event to process, but the mansession is 02655 * not waiting for it. We still need to indicate that there 02656 * is an event waiting so that get_input processes the pending 02657 * event instead of polling. 02658 */ 02659 s->pending_event = 1; 02660 ast_mutex_unlock(&s->__lock); 02661 } 02662 AST_LIST_UNLOCK(&sessions); 02663 02664 return 0; 02665 }
static int manager_state_cb | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Definition at line 2689 of file manager.c.
References EVENT_FLAG_CALL, and manager_event().
Referenced by init_manager().
02690 { 02691 /* Notify managers of change */ 02692 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nStatus: %d\r\n", exten, context, state); 02693 return 0; 02694 }
static int process_events | ( | struct mansession * | s | ) | [static] |
Definition at line 2148 of file manager.c.
References ast_calloc, ast_carefulwrite(), ast_mutex_lock(), ast_mutex_unlock(), eventqent::category, eventqent::eventdata, master_eventq, s, and unuse_eventqent().
Referenced by do_message().
02149 { 02150 struct eventqent *eqe; 02151 int ret = 0; 02152 ast_mutex_lock(&s->__lock); 02153 if (!s->eventq) 02154 s->eventq = master_eventq; 02155 while(s->eventq->next) { 02156 eqe = s->eventq->next; 02157 if ((s->authenticated && (s->readperm & eqe->category) == eqe->category) && 02158 ((s->send_events & eqe->category) == eqe->category)) { 02159 if (s->fd > -1) { 02160 if (!ret && ast_carefulwrite(s->fd, eqe->eventdata, strlen(eqe->eventdata), s->writetimeout) < 0) 02161 ret = -1; 02162 } else if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) 02163 ret = -1; 02164 else 02165 ast_dynamic_str_append(&s->outputstr, 0, "%s", eqe->eventdata); 02166 } 02167 unuse_eventqent(s->eventq); 02168 s->eventq = eqe; 02169 } 02170 ast_mutex_unlock(&s->__lock); 02171 return ret; 02172 }
static int process_message | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2279 of file manager.c.
References manager_action::action, ast_inet_ntoa(), ast_log(), ast_random(), ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_strlen_zero(), ast_verbose(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), authenticate(), manager_action::authority, displayconnects, first_action, manager_action::func, LOG_DEBUG, LOG_EVENT, manager_action::next, option_debug, option_verbose, s, and VERBOSE_PREFIX_2.
Referenced by do_message().
02280 { 02281 char action[80] = ""; 02282 struct manager_action *tmp; 02283 const char *id = astman_get_header(m,"ActionID"); 02284 char idText[256] = ""; 02285 int ret = 0; 02286 02287 ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action)); 02288 if (option_debug) 02289 ast_log( LOG_DEBUG, "Manager received command '%s'\n", action ); 02290 02291 if (ast_strlen_zero(action)) { 02292 astman_send_error(s, m, "Missing action in request"); 02293 return 0; 02294 } 02295 if (!ast_strlen_zero(id)) { 02296 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02297 } 02298 if (!s->authenticated) { 02299 if (!strcasecmp(action, "Challenge")) { 02300 const char *authtype = astman_get_header(m, "AuthType"); 02301 02302 if (!strcasecmp(authtype, "MD5")) { 02303 if (ast_strlen_zero(s->challenge)) 02304 snprintf(s->challenge, sizeof(s->challenge), "%ld", ast_random()); 02305 astman_append(s, "Response: Success\r\n" 02306 "%s" 02307 "Challenge: %s\r\n\r\n", 02308 idText, s->challenge); 02309 return 0; 02310 } else { 02311 astman_send_error(s, m, "Must specify AuthType"); 02312 return 0; 02313 } 02314 } else if (!strcasecmp(action, "Login")) { 02315 if (authenticate(s, m)) { 02316 sleep(1); 02317 astman_send_error(s, m, "Authentication failed"); 02318 return -1; 02319 } else { 02320 s->authenticated = 1; 02321 if (option_verbose > 1) { 02322 if (displayconnects) { 02323 ast_verbose(VERBOSE_PREFIX_2 "%sManager '%s' logged on from %s\n", 02324 (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr)); 02325 } 02326 } 02327 ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", 02328 (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr)); 02329 astman_send_ack(s, m, "Authentication accepted"); 02330 } 02331 } else if (!strcasecmp(action, "Logoff")) { 02332 astman_send_ack(s, m, "See ya"); 02333 return -1; 02334 } else 02335 astman_send_error(s, m, "Authentication Required"); 02336 } else { 02337 if (!strcasecmp(action, "Login")) 02338 astman_send_ack(s, m, "Already logged in"); 02339 else { 02340 ast_rwlock_rdlock(&actionlock); 02341 for (tmp = first_action; tmp; tmp = tmp->next) { 02342 if (strcasecmp(action, tmp->action)) 02343 continue; 02344 if ((s->writeperm & tmp->authority) == tmp->authority) { 02345 if (tmp->func(s, m)) 02346 ret = -1; 02347 } else 02348 astman_send_error(s, m, "Permission denied"); 02349 break; 02350 } 02351 ast_rwlock_unlock(&actionlock); 02352 if (!tmp) 02353 astman_send_error(s, m, "Invalid/unknown command"); 02354 } 02355 } 02356 if (ret) 02357 return ret; 02358 return process_events(s); 02359 }
static void* session_do | ( | void * | data | ) | [static] |
Definition at line 2450 of file manager.c.
References ast_inet_ntoa(), ast_log(), ast_verbose(), astman_append(), displayconnects, do_message(), LOG_EVENT, option_verbose, s, and VERBOSE_PREFIX_2.
Referenced by accept_thread().
02451 { 02452 struct mansession *s = data; 02453 int res; 02454 02455 astman_append(s, "Asterisk Call Manager/1.0\r\n"); 02456 for (;;) { 02457 if ((res = do_message(s)) < 0) 02458 break; 02459 } 02460 if (s->authenticated) { 02461 if (option_verbose > 1) { 02462 if (displayconnects) 02463 ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); 02464 } 02465 ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); 02466 } else { 02467 if (option_verbose > 1) { 02468 if (displayconnects) 02469 ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr)); 02470 } 02471 ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr)); 02472 } 02473 02474 /* It is possible under certain circumstances for this session thread 02475 to complete its work and exit *before* the thread that created it 02476 has finished executing the ast_pthread_create_background() function. 02477 If this occurs, some versions of glibc appear to act in a buggy 02478 fashion and attempt to write data into memory that it thinks belongs 02479 to the thread but is in fact not owned by the thread (or may have 02480 been freed completely). 02481 02482 Causing this thread to yield to other threads at least one time 02483 appears to work around this bug. 02484 */ 02485 usleep(1); 02486 02487 destroy_session(s); 02488 return NULL; 02489 }
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 956 of file manager.c.
References ast_mutex_lock(), ast_mutex_unlock(), s, and strings_to_mask().
Referenced by action_events().
00957 { 00958 int maskint = strings_to_mask(eventmask); 00959 00960 ast_mutex_lock(&s->__lock); 00961 if (maskint >= 0) 00962 s->send_events = maskint; 00963 ast_mutex_unlock(&s->__lock); 00964 00965 return maskint; 00966 }
static int strings_to_mask | ( | const char * | string | ) | [static] |
Definition at line 925 of file manager.c.
References ast_false(), ast_instring(), ast_is_number(), ast_strlen_zero(), ast_true(), and perms.
Referenced by set_eventmask().
00926 { 00927 int x, ret = -1; 00928 00929 x = ast_is_number(string); 00930 00931 if (x) 00932 ret = x; 00933 else if (ast_strlen_zero(string)) 00934 ret = -1; 00935 else if (ast_false(string)) 00936 ret = 0; 00937 else if (ast_true(string)) { 00938 ret = 0; 00939 for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) 00940 ret |= perms[x].num; 00941 } else { 00942 ret = 0; 00943 for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) { 00944 if (ast_instring(string, perms[x].label, ',')) 00945 ret |= perms[x].num; 00946 } 00947 } 00948 00949 return ret; 00950 }
static void unuse_eventqent | ( | struct eventqent * | e | ) | [static] |
Definition at line 747 of file manager.c.
References eventqent::next, and eventqent::usecount.
Referenced by action_waitevent(), free_session(), and process_events().
00748 { 00749 if (ast_atomic_dec_and_test(&e->usecount) && e->next) 00750 pthread_kill(t, SIGURG); 00751 }
static int variable_count_cmp_fn | ( | void * | obj, | |
void * | vstr, | |||
int | flags | |||
) | [static] |
Definition at line 325 of file manager.c.
References variable_count::varname.
Referenced by xml_translate().
00326 { 00327 /* Due to the simplicity of struct variable_count, it makes no difference 00328 * if you pass in objects or strings, the same operation applies. This is 00329 * due to the fact that the hash occurs on the first element, which means 00330 * the address of both the struct and the string are exactly the same. */ 00331 struct variable_count *vc = obj; 00332 char *str = vstr; 00333 return !strcmp(vc->varname, str) ? CMP_MATCH : 0; 00334 }
static int variable_count_hash_fn | ( | const void * | vvc, | |
const int | flags | |||
) | [static] |
Definition at line 313 of file manager.c.
References compress_char(), and variable_count::varname.
Referenced by xml_translate().
00314 { 00315 const struct variable_count *vc = vvc; 00316 int res = 0, i; 00317 for (i = 0; i < 5; i++) { 00318 if (vc->varname[i] == '\0') 00319 break; 00320 res += compress_char(vc->varname[i]) << (i * 6); 00321 } 00322 return res; 00323 }
static void xml_copy_escape | ( | char ** | dst, | |
size_t * | maxlen, | |||
const char * | src, | |||
int | lower | |||
) | [static] |
Definition at line 258 of file manager.c.
Referenced by xml_translate().
00259 { 00260 while (*src && (*maxlen > 6)) { 00261 switch (*src) { 00262 case '<': 00263 strcpy(*dst, "<"); 00264 (*dst) += 4; 00265 *maxlen -= 4; 00266 break; 00267 case '>': 00268 strcpy(*dst, ">"); 00269 (*dst) += 4; 00270 *maxlen -= 4; 00271 break; 00272 case '\"': 00273 strcpy(*dst, """); 00274 (*dst) += 6; 00275 *maxlen -= 6; 00276 break; 00277 case '\'': 00278 strcpy(*dst, "'"); 00279 (*dst) += 6; 00280 *maxlen -= 6; 00281 break; 00282 case '&': 00283 strcpy(*dst, "&"); 00284 (*dst) += 5; 00285 *maxlen -= 5; 00286 break; 00287 default: 00288 *(*dst)++ = lower ? tolower(*src) : *src; 00289 (*maxlen)--; 00290 } 00291 src++; 00292 } 00293 }
static char* xml_translate | ( | char * | in, | |
struct ast_variable * | vars | |||
) | [static] |
Definition at line 336 of file manager.c.
References ao2_alloc(), ao2_container_alloc(), ao2_find(), ao2_ref(), ast_build_string(), ast_malloc, variable_count::count, len, ast_variable::name, ast_variable::next, ast_variable::value, var, variable_count_cmp_fn(), variable_count_hash_fn(), and xml_copy_escape().
00337 { 00338 struct ast_variable *v; 00339 char *dest = NULL; 00340 char *out, *tmp, *var, *val; 00341 char *objtype = NULL; 00342 int colons = 0; 00343 int breaks = 0; 00344 size_t len; 00345 int count = 1; 00346 int escaped = 0; 00347 int inobj = 0; 00348 int x; 00349 struct variable_count *vc = NULL; 00350 struct ao2_container *vco = NULL; 00351 00352 for (v = vars; v; v = v->next) { 00353 if (!dest && !strcasecmp(v->name, "ajaxdest")) 00354 dest = v->value; 00355 else if (!objtype && !strcasecmp(v->name, "ajaxobjtype")) 00356 objtype = v->value; 00357 } 00358 if (!dest) 00359 dest = "unknown"; 00360 if (!objtype) 00361 objtype = "generic"; 00362 for (x = 0; in[x]; x++) { 00363 if (in[x] == ':') 00364 colons++; 00365 else if (in[x] == '\n') 00366 breaks++; 00367 else if (strchr("&\"<>\'", in[x])) 00368 escaped++; 00369 } 00370 len = (size_t) (strlen(in) + colons * 5 + breaks * (40 + strlen(dest) + strlen(objtype)) + escaped * 10); /* foo="bar", "<response type=\"object\" id=\"dest\"", "&" */ 00371 out = ast_malloc(len); 00372 if (!out) 00373 return 0; 00374 tmp = out; 00375 while (*in) { 00376 var = in; 00377 while (*in && (*in >= 32)) 00378 in++; 00379 if (*in) { 00380 if ((count > 3) && inobj) { 00381 ast_build_string(&tmp, &len, " /></response>\n"); 00382 inobj = 0; 00383 00384 /* Entity is closed, so close out the name cache */ 00385 ao2_ref(vco, -1); 00386 vco = NULL; 00387 } 00388 count = 0; 00389 while (*in && (*in < 32)) { 00390 *in = '\0'; 00391 in++; 00392 count++; 00393 } 00394 val = strchr(var, ':'); 00395 if (val) { 00396 *val = '\0'; 00397 val++; 00398 if (*val == ' ') 00399 val++; 00400 if (!inobj) { 00401 vco = ao2_container_alloc(37, variable_count_hash_fn, variable_count_cmp_fn); 00402 ast_build_string(&tmp, &len, "<response type='object' id='%s'><%s", dest, objtype); 00403 inobj = 1; 00404 } 00405 00406 /* Check if the var has been used already */ 00407 if ((vc = ao2_find(vco, var, 0))) 00408 vc->count++; 00409 else { 00410 /* Create a new entry for this one */ 00411 vc = ao2_alloc(sizeof(*vc), NULL); 00412 vc->varname = var; 00413 vc->count = 1; 00414 ao2_link(vco, vc); 00415 } 00416 00417 ast_build_string(&tmp, &len, " "); 00418 xml_copy_escape(&tmp, &len, var, 1); 00419 if (vc->count > 1) 00420 ast_build_string(&tmp, &len, "-%d", vc->count); 00421 ast_build_string(&tmp, &len, "='"); 00422 xml_copy_escape(&tmp, &len, val, 0); 00423 ast_build_string(&tmp, &len, "'"); 00424 ao2_ref(vc, -1); 00425 } 00426 } 00427 } 00428 if (inobj) 00429 ast_build_string(&tmp, &len, " /></response>\n"); 00430 if (vco) 00431 ao2_ref(vco, -1); 00432 return out; 00433 }
int asock = -1 [static] |
int block_sockets [static] |
struct ast_cli_entry cli_manager[] [static] |
struct ast_cli_entry cli_show_manager_command_deprecated [static] |
Initial value:
{ { "show", "manager", "command", NULL }, handle_showmancmd, NULL, NULL, complete_show_mancmd }
struct ast_cli_entry cli_show_manager_commands_deprecated [static] |
Initial value:
{ { "show", "manager", "commands", NULL }, handle_showmancmds, NULL, NULL }
struct ast_cli_entry cli_show_manager_connected_deprecated [static] |
Initial value:
{ { "show", "manager", "connected", NULL }, handle_showmanconn, NULL, NULL }
struct ast_cli_entry cli_show_manager_eventq_deprecated [static] |
Initial value:
{ { "show", "manager", "eventq", NULL }, handle_showmaneventq, NULL, NULL }
struct { ... } command_blacklist[] [static] |
Referenced by check_blacklist().
int displayconnects = 1 [static] |
Definition at line 103 of file manager.c.
Referenced by accept_thread(), init_manager(), process_message(), and session_do().
struct manager_action* first_action [static] |
Definition at line 204 of file manager.c.
Referenced by action_listcommands(), ast_manager_register_struct(), ast_manager_unregister(), complete_show_mancmd(), handle_showmancmd(), handle_showmancmds(), and process_message().
int httptimeout = 60 [static] |
int manager_enabled = 0 [static] |
char mandescr_atxfer[] [static] |
char mandescr_command[] [static] |
char mandescr_coresettings[] [static] |
char mandescr_corestatus[] [static] |
char mandescr_events[] [static] |
char mandescr_extensionstate[] [static] |
char mandescr_getconfig[] [static] |
char mandescr_getvar[] [static] |
char mandescr_hangup[] [static] |
char mandescr_listcommands[] [static] |
char mandescr_logoff[] [static] |
char mandescr_mailboxcount[] [static] |
char mandescr_mailboxstatus[] [static] |
char mandescr_originate[] [static] |
char mandescr_ping[] [static] |
char mandescr_redirect[] [static] |
char mandescr_setvar[] [static] |
char mandescr_timeout[] [static] |
char mandescr_updateconfig[] [static] |
char mandescr_userevent[] [static] |
char mandescr_waitevent[] [static] |
struct eventqent* master_eventq = NULL |
Definition at line 112 of file manager.c.
Referenced by accept_thread(), append_event(), handle_showmaneventq(), and process_events().
int num_sessions [static] |
Definition at line 109 of file manager.c.
Referenced by accept_thread(), append_event(), and manager_event().
Referenced by authority_to_str(), get_perm(), and strings_to_mask().
int portno = DEFAULT_MANAGER_PORT [static] |
Definition at line 101 of file manager.c.
Referenced by ast_netsock_bind(), create_addr(), init_manager(), process_sdp(), and set_config().
char showmanager_help[] [static] |
char showmanagers_help[] [static] |
char showmancmd_help[] [static] |
char showmancmds_help[] [static] |
char showmanconn_help[] [static] |
char showmaneventq_help[] [static] |
pthread_t t [static] |
Definition at line 107 of file manager.c.
Referenced by __ast_register_translator(), __schedule_action(), acf_odbc_write(), add_sdp(), add_t38_sdp(), append_date(), ast_channel_bridge(), ast_check_timing(), ast_do_masquerade(), ast_get_time_t(), ast_httpd_helper_thread(), ast_log(), ast_pbx_start(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_de(), ast_translator_activate(), ast_translator_build_path(), ast_translator_deactivate(), ast_unregister_translator(), ast_verbose(), background_detect_exec(), build_mapping(), byteReverse(), calc_cost(), calc_txstamp(), callerid_genmsg(), callerid_getcarrier(), cdr_get_tv(), check_switch_expr(), check_user_full(), cli_prompt(), config_text_file_save(), destroy(), do_monitor(), does_peer_need_mwi(), dump_cmd_queues(), expr2_token_subst(), gen_match_to_pattern(), gen_tone(), gen_tones(), get_date(), get_trans_id(), handle_bchan(), handle_enbloc_call_message(), handle_hd_hf(), handle_offhook_message(), handle_save_dialplan(), handle_soft_key_event_message(), handle_stimulus_message(), iax2_datetime(), iax2_process_thread(), iax2_show_threads(), iax_template_parse(), launch_service(), listener(), local_new(), localsub(), lws2sws(), manager_log(), MD5Update(), misdn_read(), newpvt(), osp_create_provider(), osp_load(), packdate(), parse_moved_contact(), pgsql_log(), play_message_datetime(), prune_gateways(), rebuild_matrix(), register_verify(), rpt(), rpt_do_lstats(), rpt_exec(), rpt_tele_thread(), send_request(), SHA1ProcessMessageBlock(), sms_readfile(), socket_read(), sqlite_log(), strip_quotes(), tdd_getcarrier(), time2sub(), transmit_notify_request_with_callerid(), transmit_notify_with_mwi(), transmit_state_notify(), vmu_tm(), and write_metadata().
int timestampevents [static] |
int webmanager_enabled = 0 [static] |