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