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_command (struct mansession *s, const struct message *m) |
action_command: Manager command "command" - execute CLI command | |
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_message (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) |
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 connected. | |
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, char *cid_num, char *cid_name) |
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 int | enabled |
static struct manager_action * | first_action |
static int | httptimeout = 60 |
static char | mandescr_command [] |
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_message [] |
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 |
#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 2448 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().
02449 { 02450 int as; 02451 struct sockaddr_in sin; 02452 socklen_t sinlen; 02453 struct eventqent *eqe; 02454 struct mansession *s; 02455 struct protoent *p; 02456 int arg = 1; 02457 int flags; 02458 pthread_attr_t attr; 02459 time_t now; 02460 struct pollfd pfds[1]; 02461 02462 pthread_attr_init(&attr); 02463 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02464 02465 for (;;) { 02466 time(&now); 02467 AST_LIST_LOCK(&sessions); 02468 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) { 02469 if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) { 02470 AST_LIST_REMOVE_CURRENT(&sessions, list); 02471 num_sessions--; 02472 if (s->authenticated && (option_verbose > 1) && displayconnects) { 02473 ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' timed out from %s\n", 02474 s->username, ast_inet_ntoa(s->sin.sin_addr)); 02475 } 02476 free_session(s); 02477 break; 02478 } 02479 } 02480 AST_LIST_TRAVERSE_SAFE_END 02481 /* Purge master event queue of old, unused events, but make sure we 02482 always keep at least one in the queue */ 02483 eqe = master_eventq; 02484 while (master_eventq->next && !master_eventq->usecount) { 02485 eqe = master_eventq; 02486 master_eventq = master_eventq->next; 02487 free(eqe); 02488 } 02489 AST_LIST_UNLOCK(&sessions); 02490 02491 sinlen = sizeof(sin); 02492 pfds[0].fd = asock; 02493 pfds[0].events = POLLIN; 02494 /* Wait for something to happen, but timeout every few seconds so 02495 we can ditch any old manager sessions */ 02496 if (poll(pfds, 1, 5000) < 1) 02497 continue; 02498 as = accept(asock, (struct sockaddr *)&sin, &sinlen); 02499 if (as < 0) { 02500 ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno)); 02501 continue; 02502 } 02503 p = getprotobyname("tcp"); 02504 if (p) { 02505 if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { 02506 ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno)); 02507 } 02508 } 02509 if (!(s = ast_calloc(1, sizeof(*s)))) 02510 continue; 02511 02512 memcpy(&s->sin, &sin, sizeof(sin)); 02513 s->writetimeout = 100; 02514 s->waiting_thread = AST_PTHREADT_NULL; 02515 02516 if (!block_sockets) { 02517 /* For safety, make sure socket is non-blocking */ 02518 flags = fcntl(as, F_GETFL); 02519 fcntl(as, F_SETFL, flags | O_NONBLOCK); 02520 } else { 02521 flags = fcntl(as, F_GETFL); 02522 fcntl(as, F_SETFL, flags & ~O_NONBLOCK); 02523 } 02524 ast_mutex_init(&s->__lock); 02525 s->fd = as; 02526 s->send_events = -1; 02527 AST_LIST_LOCK(&sessions); 02528 AST_LIST_INSERT_HEAD(&sessions, s, list); 02529 num_sessions++; 02530 /* Find the last place in the master event queue and hook ourselves 02531 in there */ 02532 s->eventq = master_eventq; 02533 while(s->eventq->next) 02534 s->eventq = s->eventq->next; 02535 ast_atomic_fetchadd_int(&s->eventq->usecount, 1); 02536 AST_LIST_UNLOCK(&sessions); 02537 if (ast_pthread_create_background(&s->t, &attr, session_do, s)) 02538 destroy_session(s); 02539 } 02540 pthread_attr_destroy(&attr); 02541 return NULL; 02542 }
static int action_command | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_command: Manager command "command" - execute CLI command
Definition at line 1806 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().
01807 { 01808 const char *cmd = astman_get_header(m, "Command"); 01809 const char *id = astman_get_header(m, "ActionID"); 01810 char *buf, *final_buf; 01811 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 01812 int fd = mkstemp(template); 01813 off_t l; 01814 01815 if (ast_strlen_zero(cmd)) { 01816 astman_send_error(s, m, "No command provided"); 01817 return 0; 01818 } 01819 01820 if (check_blacklist(cmd)) { 01821 astman_send_error(s, m, "Command blacklisted"); 01822 return 0; 01823 } 01824 01825 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 01826 if (!ast_strlen_zero(id)) 01827 astman_append(s, "ActionID: %s\r\n", id); 01828 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 01829 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 01830 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 01831 01832 /* This has a potential to overflow the stack. Hence, use the heap. */ 01833 buf = ast_calloc(1, l + 1); 01834 final_buf = ast_calloc(1, l + 1); 01835 if (buf) { 01836 lseek(fd, 0, SEEK_SET); 01837 read(fd, buf, l); 01838 buf[l] = '\0'; 01839 if (final_buf) { 01840 term_strip(final_buf, buf, l); 01841 final_buf[l] = '\0'; 01842 } 01843 astman_append(s, "%s", S_OR(final_buf, buf)); 01844 ast_free(buf); 01845 } 01846 close(fd); 01847 unlink(template); 01848 astman_append(s, "--END COMMAND--\r\n\r\n"); 01849 if (final_buf) 01850 ast_free(final_buf); 01851 return 0; 01852 }
static int action_events | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1391 of file manager.c.
References astman_get_header(), astman_send_response(), s, and set_eventmask().
Referenced by init_manager().
01392 { 01393 const char *mask = astman_get_header(m, "EventMask"); 01394 int res; 01395 01396 res = set_eventmask(s, mask); 01397 if (res > 0) 01398 astman_send_response(s, m, "Events On", NULL); 01399 else if (res == 0) 01400 astman_send_response(s, m, "Events Off", NULL); 01401 01402 return 0; 01403 }
static int action_extensionstate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2124 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().
02125 { 02126 const char *exten = astman_get_header(m, "Exten"); 02127 const char *context = astman_get_header(m, "Context"); 02128 const char *id = astman_get_header(m,"ActionID"); 02129 char idText[256] = ""; 02130 char hint[256] = ""; 02131 int status; 02132 if (ast_strlen_zero(exten)) { 02133 astman_send_error(s, m, "Extension not specified"); 02134 return 0; 02135 } 02136 if (ast_strlen_zero(context)) 02137 context = "default"; 02138 status = ast_extension_state(NULL, context, exten); 02139 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 02140 if (!ast_strlen_zero(id)) { 02141 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02142 } 02143 astman_append(s, "Response: Success\r\n" 02144 "%s" 02145 "Message: Extension Status\r\n" 02146 "Exten: %s\r\n" 02147 "Context: %s\r\n" 02148 "Hint: %s\r\n" 02149 "Status: %d\r\n\r\n", 02150 idText,exten, context, hint, status); 02151 return 0; 02152 }
static int action_getconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1120 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().
01121 { 01122 struct ast_config *cfg; 01123 const char *fn = astman_get_header(m, "Filename"); 01124 int catcount = 0; 01125 int lineno = 0; 01126 char *category=NULL; 01127 struct ast_variable *v; 01128 char idText[256] = ""; 01129 const char *id = astman_get_header(m, "ActionID"); 01130 01131 if (!ast_strlen_zero(id)) 01132 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01133 01134 if (ast_strlen_zero(fn)) { 01135 astman_send_error(s, m, "Filename not specified"); 01136 return 0; 01137 } 01138 if (!(cfg = ast_config_load_with_comments(fn))) { 01139 astman_send_error(s, m, "Config file not found"); 01140 return 0; 01141 } 01142 astman_append(s, "Response: Success\r\n%s", idText); 01143 while ((category = ast_category_browse(cfg, category))) { 01144 lineno = 0; 01145 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 01146 for (v = ast_variable_browse(cfg, category); v; v = v->next) 01147 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 01148 catcount++; 01149 } 01150 ast_config_destroy(cfg); 01151 astman_append(s, "\r\n"); 01152 01153 return 0; 01154 }
static int action_getvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1535 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().
01536 { 01537 struct ast_channel *c = NULL; 01538 const char *name = astman_get_header(m, "Channel"); 01539 const char *varname = astman_get_header(m, "Variable"); 01540 const char *id = astman_get_header(m,"ActionID"); 01541 char *varval; 01542 char workspace[1024] = ""; 01543 01544 if (ast_strlen_zero(varname)) { 01545 astman_send_error(s, m, "No variable specified"); 01546 return 0; 01547 } 01548 01549 if (!ast_strlen_zero(name)) { 01550 c = ast_get_channel_by_name_locked(name); 01551 if (!c) { 01552 astman_send_error(s, m, "No such channel"); 01553 return 0; 01554 } 01555 } 01556 01557 if (varname[strlen(varname) - 1] == ')') { 01558 char *copy = ast_strdupa(varname); 01559 01560 ast_func_read(c, copy, workspace, sizeof(workspace)); 01561 varval = workspace; 01562 } else { 01563 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 01564 } 01565 01566 if (c) 01567 ast_channel_unlock(c); 01568 astman_append(s, "Response: Success\r\n" 01569 "Variable: %s\r\nValue: %s\r\n", varname, varval); 01570 if (!ast_strlen_zero(id)) 01571 astman_append(s, "ActionID: %s\r\n",id); 01572 astman_append(s, "\r\n"); 01573 01574 return 0; 01575 }
static int action_hangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1420 of file manager.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_get_channel_by_uniqueid_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().
01421 { 01422 struct ast_channel *c = NULL; 01423 const char *name = astman_get_header(m, "Channel"); 01424 const char *uniqueid = astman_get_header(m, "Uniqueid"); 01425 01426 if (ast_strlen_zero(name) && ast_strlen_zero(uniqueid)) { 01427 astman_send_error(s, m, "No channel or uniqueid specified"); 01428 return 0; 01429 } 01430 01431 if (!ast_strlen_zero(uniqueid)) { 01432 c = ast_get_channel_by_uniqueid_locked(uniqueid); 01433 } else { 01434 if (!ast_strlen_zero(name)) 01435 c = ast_get_channel_by_name_locked(name); 01436 } 01437 01438 if (!c) { 01439 astman_send_error(s, m, "No such channel"); 01440 return 0; 01441 } 01442 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01443 ast_channel_unlock(c); 01444 astman_send_ack(s, m, "Channel Hungup"); 01445 return 0; 01446 }
static int action_listcommands | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1364 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().
01365 { 01366 struct manager_action *cur; 01367 char idText[256] = ""; 01368 char temp[BUFSIZ]; 01369 const char *id = astman_get_header(m,"ActionID"); 01370 01371 if (!ast_strlen_zero(id)) 01372 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01373 astman_append(s, "Response: Success\r\n%s", idText); 01374 for (cur = first_action; cur; cur = cur->next) { 01375 if ((s->writeperm & cur->authority) == cur->authority) 01376 astman_append(s, "%s: %s (Priv: %s)\r\n", cur->action, cur->synopsis, authority_to_str(cur->authority, temp, sizeof(temp))); 01377 } 01378 astman_append(s, "\r\n"); 01379 01380 return 0; 01381 }
static int action_logoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1409 of file manager.c.
References astman_send_response(), and s.
Referenced by init_manager().
01410 { 01411 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 01412 return -1; 01413 }
static int action_mailboxcount | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2088 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().
02089 { 02090 const char *mailbox = astman_get_header(m, "Mailbox"); 02091 const char *id = astman_get_header(m,"ActionID"); 02092 char idText[256] = ""; 02093 int newmsgs = 0, oldmsgs = 0; 02094 if (ast_strlen_zero(mailbox)) { 02095 astman_send_error(s, m, "Mailbox not specified"); 02096 return 0; 02097 } 02098 ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs); 02099 if (!ast_strlen_zero(id)) { 02100 snprintf(idText, sizeof(idText), "ActionID: %s\r\n",id); 02101 } 02102 astman_append(s, "Response: Success\r\n" 02103 "%s" 02104 "Message: Mailbox Message Count\r\n" 02105 "Mailbox: %s\r\n" 02106 "NewMessages: %d\r\n" 02107 "OldMessages: %d\r\n" 02108 "\r\n", 02109 idText,mailbox, newmsgs, oldmsgs); 02110 return 0; 02111 }
static int action_mailboxstatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2056 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().
02057 { 02058 const char *mailbox = astman_get_header(m, "Mailbox"); 02059 const char *id = astman_get_header(m,"ActionID"); 02060 char idText[256] = ""; 02061 int ret; 02062 if (ast_strlen_zero(mailbox)) { 02063 astman_send_error(s, m, "Mailbox not specified"); 02064 return 0; 02065 } 02066 if (!ast_strlen_zero(id)) 02067 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02068 ret = ast_app_has_voicemail(mailbox, NULL); 02069 astman_append(s, "Response: Success\r\n" 02070 "%s" 02071 "Message: Mailbox Status\r\n" 02072 "Mailbox: %s\r\n" 02073 "Waiting: %d\r\n\r\n", idText, mailbox, ret); 02074 return 0; 02075 }
static int action_message | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1455 of file manager.c.
References ast_send_message(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::data, name, s, and ast_channel::tech.
Referenced by init_manager().
01456 { 01457 const char *name = astman_get_header(m, "Channel"); 01458 const char *from = astman_get_header(m, "From"); 01459 const char *message = astman_get_header(m, "Message"); 01460 const char *pdu = astman_get_header(m, "PDU"); 01461 char tmp[256]; 01462 char *tech, *data; 01463 int res; 01464 if (ast_strlen_zero(name) || (ast_strlen_zero(message) && ast_strlen_zero(pdu))) { 01465 astman_send_error(s, m, "No channel or message/PDU specified"); 01466 return 0; 01467 } 01468 ast_copy_string(tmp, name, sizeof(tmp)); 01469 tech = tmp; 01470 data = strchr(tmp, '/'); 01471 if (!data) { 01472 astman_send_error(s, m, "Invalid channel\n"); 01473 return 0; 01474 } 01475 *data = '\0'; 01476 data++; 01477 if (ast_strlen_zero(pdu)) { 01478 res = ast_send_message(tech, (char *)data, (char *)name, (char *)from, (char *)message, 0); 01479 } else { 01480 res = ast_send_message(tech, (char *)data, (char *)name, (char *)from, (char *)pdu, 1); 01481 } 01482 01483 if (res) { 01484 astman_send_error(s, m, "Error sending message"); 01485 return 0; 01486 } 01487 astman_send_ack(s, m, "Message sent"); 01488 return 0; 01489 }
static int action_originate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1918 of file manager.c.
References app, ast_alloc_uniqueid(), ast_callerid_parse(), ast_calloc, ast_cli(), ast_findlabel_extension(), AST_FORMAT_SLINEAR, ast_pbx_outgoing_app_uniqueid(), ast_pbx_outgoing_exten_uniqueid(), ast_pthread_create, ast_shrink_phone_number(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_get_variables(), astman_send_error(), context, ast_channel::data, exten, fast_originate(), name, ast_channel::priority, s, and ast_channel::tech.
Referenced by init_manager().
01919 { 01920 const char *name = astman_get_header(m, "Channel"); 01921 const char *exten = astman_get_header(m, "Exten"); 01922 const char *context = astman_get_header(m, "Context"); 01923 const char *priority = astman_get_header(m, "Priority"); 01924 const char *timeout = astman_get_header(m, "Timeout"); 01925 const char *callerid = astman_get_header(m, "CallerID"); 01926 const char *account = astman_get_header(m, "Account"); 01927 const char *app = astman_get_header(m, "Application"); 01928 const char *appdata = astman_get_header(m, "Data"); 01929 const char *async = astman_get_header(m, "Async"); 01930 const char *id = astman_get_header(m, "ActionID"); 01931 const char *callingpres = astman_get_header(m, "CallingPres"); 01932 struct ast_variable *vars = astman_get_variables(m); 01933 char *tech, *data; 01934 char *l = NULL, *n = NULL; 01935 int pi = 0; 01936 int res; 01937 int to = 30000; 01938 int reason = 0; 01939 char tmp[256]; 01940 char tmp2[256]; 01941 char *uniqueid; 01942 int cpresi = 0; 01943 char idText[256] = ""; 01944 01945 pthread_t th; 01946 pthread_attr_t attr; 01947 if (!name) { 01948 astman_send_error(s, m, "Channel not specified"); 01949 return 0; 01950 } 01951 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 01952 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 01953 astman_send_error(s, m, "Invalid priority\n"); 01954 return 0; 01955 } 01956 } 01957 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) { 01958 astman_send_error(s, m, "Invalid timeout\n"); 01959 return 0; 01960 } 01961 if (!ast_strlen_zero(callingpres) && (sscanf(callingpres, "%d", &cpresi) != 1)) { 01962 astman_send_error(s, m, "Invalid CallingPres\n"); 01963 return 0; 01964 } 01965 ast_copy_string(tmp, name, sizeof(tmp)); 01966 tech = tmp; 01967 data = strchr(tmp, '/'); 01968 if (!data) { 01969 astman_send_error(s, m, "Invalid channel\n"); 01970 return 0; 01971 } 01972 *data++ = '\0'; 01973 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 01974 ast_callerid_parse(tmp2, &n, &l); 01975 if (n) { 01976 if (ast_strlen_zero(n)) 01977 n = NULL; 01978 } 01979 if (l) { 01980 ast_shrink_phone_number(l); 01981 if (ast_strlen_zero(l)) 01982 l = NULL; 01983 } 01984 uniqueid = ast_alloc_uniqueid(); 01985 if (ast_true(async)) { 01986 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 01987 if (!fast) { 01988 res = -1; 01989 } else { 01990 if (!ast_strlen_zero(id)) 01991 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s\r\n", id); 01992 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 01993 ast_copy_string(fast->data, data, sizeof(fast->data)); 01994 ast_copy_string(fast->app, app, sizeof(fast->app)); 01995 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 01996 if (l) 01997 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 01998 if (n) 01999 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 02000 fast->vars = vars; 02001 ast_copy_string(fast->context, context, sizeof(fast->context)); 02002 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 02003 ast_copy_string(fast->account, account, sizeof(fast->account)); 02004 ast_copy_string(fast->uniqueid, uniqueid, sizeof(fast->uniqueid)); 02005 fast->timeout = to; 02006 fast->priority = pi; 02007 fast->callingpres = cpresi; 02008 pthread_attr_init(&attr); 02009 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02010 if (ast_pthread_create(&th, &attr, fast_originate, fast)) { 02011 res = -1; 02012 } else { 02013 res = 0; 02014 } 02015 pthread_attr_destroy(&attr); 02016 } 02017 } else if (!ast_strlen_zero(app)) { 02018 res = ast_pbx_outgoing_app_uniqueid(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, cpresi, l, n, vars, account, NULL, uniqueid); 02019 } else { 02020 if (exten && context && pi) 02021 res = ast_pbx_outgoing_exten_uniqueid(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, cpresi, l, n, vars, account, NULL, uniqueid); 02022 else { 02023 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 02024 return 0; 02025 } 02026 } 02027 if (!res) { 02028 if (id && !ast_strlen_zero(id)) { 02029 snprintf(idText,256,"ActionID: %s\r\n",id); 02030 } 02031 ast_cli(s->fd, "Response: Success\r\n" 02032 "%s" 02033 "Message: Originate successfully queued\r\n" 02034 "Uniqueid: %s\r\n" 02035 "\r\n", 02036 idText, uniqueid); 02037 } else { 02038 astman_send_error(s, m, "Originate failed"); 02039 } 02040 return 0; 02041 }
static int action_ping | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1108 of file manager.c.
References astman_send_response(), and s.
Referenced by init_manager().
01109 { 01110 astman_send_response(s, m, "Pong", NULL); 01111 return 0; 01112 }
static int action_redirect | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_redirect: The redirect manager command
Definition at line 1681 of file manager.c.
References ast_async_goto(), ast_channel_unlock, ast_check_hangup(), ast_findlabel_extension(), ast_get_channel_by_name_locked(), ast_get_channel_by_uniqueid_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, exten, name, and s.
Referenced by init_manager().
01682 { 01683 const char *name = astman_get_header(m, "Channel"); 01684 const char *name2 = astman_get_header(m, "ExtraChannel"); 01685 const char *exten = astman_get_header(m, "Exten"); 01686 const char *context = astman_get_header(m, "Context"); 01687 const char *priority = astman_get_header(m, "Priority"); 01688 const char *uniqueid = astman_get_header(m, "Uniqueid"); 01689 const char *uniqueid2 = astman_get_header(m, "ExtraUniqueid"); 01690 const char *exten2 = astman_get_header(m, "ExtraExten"); 01691 const char *context2 = astman_get_header(m, "ExtraContext"); 01692 const char *priority2 = astman_get_header(m, "ExtraPriority"); 01693 struct ast_channel *chan, *chan2 = NULL; 01694 int pi = 0; 01695 int pi2 = 0; 01696 int res; 01697 01698 if (ast_strlen_zero(name) && ast_strlen_zero(uniqueid)) { 01699 astman_send_error(s, m, "Channel or Uniqueid not specified"); 01700 return 0; 01701 } 01702 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 01703 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 01704 astman_send_error(s, m, "Invalid priority\n"); 01705 return 0; 01706 } 01707 } 01708 if (!ast_strlen_zero(priority2) && (sscanf(priority2, "%d", &pi2) != 1)) { 01709 if ((pi = ast_findlabel_extension(NULL, context2, exten2, priority2, NULL)) < 1) { 01710 astman_send_error(s, m, "Invalid extra priority\n"); 01711 return 0; 01712 } 01713 } 01714 /* XXX watch out, possible deadlock!!! */ 01715 if (!ast_strlen_zero(uniqueid)) { 01716 chan = ast_get_channel_by_uniqueid_locked(uniqueid); 01717 } else { 01718 chan = ast_get_channel_by_name_locked(name); 01719 } 01720 if (!chan) { 01721 char buf[BUFSIZ]; 01722 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 01723 astman_send_error(s, m, buf); 01724 return 0; 01725 } 01726 if (ast_check_hangup(chan)) { 01727 astman_send_error(s, m, "Redirect failed, channel not up.\n"); 01728 ast_channel_unlock(chan); 01729 return 0; 01730 } 01731 if (!ast_strlen_zero(uniqueid2)) { 01732 chan2 = ast_get_channel_by_uniqueid_locked(uniqueid2); 01733 } else if (!ast_strlen_zero(name2)) { 01734 chan2 = ast_get_channel_by_name_locked(name2); 01735 } 01736 if (chan2 && ast_check_hangup(chan2)) { 01737 astman_send_error(s, m, "Redirect failed, extra channel not up.\n"); 01738 ast_channel_unlock(chan); 01739 ast_channel_unlock(chan2); 01740 return 0; 01741 } 01742 res = ast_async_goto(chan, context, exten, pi); 01743 if (!res) { 01744 if ((!ast_strlen_zero(name2)) || (!ast_strlen_zero(uniqueid2))){ 01745 if (chan2) 01746 res = ast_async_goto(chan2, context2, exten2, pi2); 01747 else 01748 res = -1; 01749 if (!res) 01750 astman_send_ack(s, m, "Dual Redirect successful"); 01751 else 01752 astman_send_error(s, m, "Secondary redirect failed"); 01753 } else 01754 astman_send_ack(s, m, "Redirect successful"); 01755 } else 01756 astman_send_error(s, m, "Redirect failed"); 01757 if (chan) 01758 ast_channel_unlock(chan); 01759 if (chan2) 01760 ast_channel_unlock(chan2); 01761 return 0; 01762 }
static int action_setvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1498 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().
01499 { 01500 struct ast_channel *c = NULL; 01501 const char *name = astman_get_header(m, "Channel"); 01502 const char *varname = astman_get_header(m, "Variable"); 01503 const char *varval = astman_get_header(m, "Value"); 01504 01505 if (ast_strlen_zero(varname)) { 01506 astman_send_error(s, m, "No variable specified"); 01507 return 0; 01508 } 01509 01510 if (!ast_strlen_zero(name)) { 01511 c = ast_get_channel_by_name_locked(name); 01512 if (!c) { 01513 astman_send_error(s, m, "No such channel"); 01514 return 0; 01515 } 01516 } 01517 01518 pbx_builtin_setvar_helper(c, varname, S_OR(varval, "")); 01519 01520 if (c) 01521 ast_channel_unlock(c); 01522 01523 astman_send_ack(s, m, "Variable Set"); 01524 01525 return 0; 01526 }
static int action_status | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager "status" command to show channels.
Definition at line 1580 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().
01581 { 01582 const char *id = astman_get_header(m,"ActionID"); 01583 const char *name = astman_get_header(m,"Channel"); 01584 char idText[256] = ""; 01585 struct ast_channel *c; 01586 char bridge[256]; 01587 struct timeval now = ast_tvnow(); 01588 long elapsed_seconds = 0; 01589 int all = ast_strlen_zero(name); /* set if we want all channels */ 01590 01591 if (!ast_strlen_zero(id)) 01592 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01593 if (all) 01594 c = ast_channel_walk_locked(NULL); 01595 else { 01596 c = ast_get_channel_by_name_locked(name); 01597 if (!c) { 01598 astman_send_error(s, m, "No such channel"); 01599 return 0; 01600 } 01601 } 01602 astman_send_ack(s, m, "Channel status will follow"); 01603 /* if we look by name, we break after the first iteration */ 01604 while (c) { 01605 if (c->_bridge) 01606 snprintf(bridge, sizeof(bridge), "Link: %s\r\n", c->_bridge->name); 01607 else 01608 bridge[0] = '\0'; 01609 if (c->pbx) { 01610 if (c->cdr) { 01611 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01612 } 01613 astman_append(s, 01614 "Event: Status\r\n" 01615 "Privilege: Call\r\n" 01616 "Channel: %s\r\n" 01617 "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */ 01618 "CallerIDNum: %s\r\n" 01619 "CallerIDName: %s\r\n" 01620 "Account: %s\r\n" 01621 "State: %s\r\n" 01622 "Context: %s\r\n" 01623 "Extension: %s\r\n" 01624 "Priority: %d\r\n" 01625 "Seconds: %ld\r\n" 01626 "%s" 01627 "Uniqueid: %s\r\n" 01628 "%s" 01629 "\r\n", 01630 c->name, 01631 S_OR(c->cid.cid_num, "<unknown>"), 01632 S_OR(c->cid.cid_num, "<unknown>"), 01633 S_OR(c->cid.cid_name, "<unknown>"), 01634 c->accountcode, 01635 ast_state2str(c->_state), c->context, 01636 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, idText); 01637 } else { 01638 astman_append(s, 01639 "Event: Status\r\n" 01640 "Privilege: Call\r\n" 01641 "Channel: %s\r\n" 01642 "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */ 01643 "CallerIDNum: %s\r\n" 01644 "CallerIDName: %s\r\n" 01645 "Account: %s\r\n" 01646 "State: %s\r\n" 01647 "%s" 01648 "Uniqueid: %s\r\n" 01649 "%s" 01650 "\r\n", 01651 c->name, 01652 S_OR(c->cid.cid_num, "<unknown>"), 01653 S_OR(c->cid.cid_num, "<unknown>"), 01654 S_OR(c->cid.cid_name, "<unknown>"), 01655 c->accountcode, 01656 ast_state2str(c->_state), bridge, c->uniqueid, idText); 01657 } 01658 ast_channel_unlock(c); 01659 if (!all) 01660 break; 01661 c = ast_channel_walk_locked(c); 01662 } 01663 astman_append(s, 01664 "Event: StatusComplete\r\n" 01665 "%s" 01666 "\r\n",idText); 01667 return 0; 01668 }
static int action_timeout | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2161 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().
02162 { 02163 struct ast_channel *c = NULL; 02164 const char *name = astman_get_header(m, "Channel"); 02165 int timeout = atoi(astman_get_header(m, "Timeout")); 02166 if (ast_strlen_zero(name)) { 02167 astman_send_error(s, m, "No channel specified"); 02168 return 0; 02169 } 02170 if (!timeout) { 02171 astman_send_error(s, m, "No timeout specified"); 02172 return 0; 02173 } 02174 c = ast_get_channel_by_name_locked(name); 02175 if (!c) { 02176 astman_send_error(s, m, "No such channel"); 02177 return 0; 02178 } 02179 ast_channel_setwhentohangup(c, timeout); 02180 ast_channel_unlock(c); 02181 astman_send_ack(s, m, "Timeout Set"); 02182 return 0; 02183 }
static int action_updateconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1231 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().
01232 { 01233 struct ast_config *cfg; 01234 const char *sfn = astman_get_header(m, "SrcFilename"); 01235 const char *dfn = astman_get_header(m, "DstFilename"); 01236 int res; 01237 char idText[256] = ""; 01238 const char *id = astman_get_header(m, "ActionID"); 01239 const char *rld = astman_get_header(m, "Reload"); 01240 01241 if (!ast_strlen_zero(id)) 01242 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01243 01244 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { 01245 astman_send_error(s, m, "Filename not specified"); 01246 return 0; 01247 } 01248 if (!(cfg = ast_config_load_with_comments(sfn))) { 01249 astman_send_error(s, m, "Config file not found"); 01250 return 0; 01251 } 01252 handle_updates(s, m, cfg); 01253 res = config_text_file_save(dfn, cfg, "Manager"); 01254 ast_config_destroy(cfg); 01255 if (res) { 01256 astman_send_error(s, m, "Save of config failed"); 01257 return 0; 01258 } 01259 astman_append(s, "Response: Success\r\n%s\r\n", idText); 01260 if (!ast_strlen_zero(rld)) { 01261 if (ast_true(rld)) 01262 rld = NULL; 01263 ast_module_reload(rld); 01264 } 01265 return 0; 01266 }
static int action_userevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2218 of file manager.c.
References astman_get_header(), event, EVENT_FLAG_USER, message::hdrcount, message::headers, and manager_event().
Referenced by init_manager().
02219 { 02220 const char *event = astman_get_header(m, "UserEvent"); 02221 char body[2048] = ""; 02222 int x, bodylen = 0; 02223 for (x = 0; x < m->hdrcount; x++) { 02224 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 02225 ast_copy_string(body + bodylen, m->headers[x], sizeof(body) - bodylen - 3); 02226 bodylen += strlen(m->headers[x]); 02227 ast_copy_string(body + bodylen, "\r\n", 3); 02228 bodylen += 2; 02229 } 02230 } 02231 02232 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body); 02233 return 0; 02234 }
static int action_waitevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1276 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().
01277 { 01278 const char *timeouts = astman_get_header(m, "Timeout"); 01279 int timeout = -1, max; 01280 int x; 01281 int needexit = 0; 01282 time_t now; 01283 struct eventqent *eqe; 01284 const char *id = astman_get_header(m,"ActionID"); 01285 char idText[256] = ""; 01286 01287 if (!ast_strlen_zero(id)) 01288 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01289 01290 if (!ast_strlen_zero(timeouts)) { 01291 sscanf(timeouts, "%i", &timeout); 01292 } 01293 01294 ast_mutex_lock(&s->__lock); 01295 if (s->waiting_thread != AST_PTHREADT_NULL) { 01296 pthread_kill(s->waiting_thread, SIGURG); 01297 } 01298 if (s->sessiontimeout) { 01299 time(&now); 01300 max = s->sessiontimeout - now - 10; 01301 if (max < 0) 01302 max = 0; 01303 if ((timeout < 0) || (timeout > max)) 01304 timeout = max; 01305 if (!s->send_events) 01306 s->send_events = -1; 01307 /* Once waitevent is called, always queue events from now on */ 01308 } 01309 ast_mutex_unlock(&s->__lock); 01310 s->waiting_thread = pthread_self(); 01311 if (option_debug) 01312 ast_log(LOG_DEBUG, "Starting waiting for an event!\n"); 01313 for (x=0; ((x < timeout) || (timeout < 0)); x++) { 01314 ast_mutex_lock(&s->__lock); 01315 if (s->eventq && s->eventq->next) 01316 needexit = 1; 01317 if (s->waiting_thread != pthread_self()) 01318 needexit = 1; 01319 if (s->needdestroy) 01320 needexit = 1; 01321 ast_mutex_unlock(&s->__lock); 01322 if (needexit) 01323 break; 01324 if (s->fd > 0) { 01325 if (ast_wait_for_input(s->fd, 1000)) 01326 break; 01327 } else { 01328 sleep(1); 01329 } 01330 } 01331 if (option_debug) 01332 ast_log(LOG_DEBUG, "Finished waiting for an event!\n"); 01333 ast_mutex_lock(&s->__lock); 01334 if (s->waiting_thread == pthread_self()) { 01335 astman_send_response(s, m, "Success", "Waiting for Event..."); 01336 /* Only show events if we're the most recent waiter */ 01337 while(s->eventq->next) { 01338 eqe = s->eventq->next; 01339 if (((s->readperm & eqe->category) == eqe->category) && 01340 ((s->send_events & eqe->category) == eqe->category)) { 01341 astman_append(s, "%s", eqe->eventdata); 01342 } 01343 unuse_eventqent(s->eventq); 01344 s->eventq = eqe; 01345 } 01346 astman_append(s, 01347 "Event: WaitEventComplete\r\n" 01348 "%s" 01349 "\r\n", idText); 01350 s->waiting_thread = AST_PTHREADT_NULL; 01351 } else { 01352 ast_log(LOG_DEBUG, "Abandoning event request!\n"); 01353 } 01354 ast_mutex_unlock(&s->__lock); 01355 return 0; 01356 }
static int append_event | ( | const char * | str, | |
int | category | |||
) | [static] |
Definition at line 2544 of file manager.c.
References ast_malloc, master_eventq, eventqent::next, num_sessions, and eventqent::usecount.
Referenced by init_manager(), and manager_event().
02545 { 02546 struct eventqent *tmp, *prev = NULL; 02547 tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 02548 02549 if (!tmp) 02550 return -1; 02551 02552 tmp->next = NULL; 02553 tmp->category = category; 02554 strcpy(tmp->eventdata, str); 02555 02556 if (master_eventq) { 02557 prev = master_eventq; 02558 while (prev->next) 02559 prev = prev->next; 02560 prev->next = tmp; 02561 } else { 02562 master_eventq = tmp; 02563 } 02564 02565 tmp->usecount = num_sessions; 02566 02567 return 0; 02568 }
static struct ast_manager_user* ast_get_manager_by_name_locked | ( | const char * | name | ) | [static] |
Definition at line 477 of file manager.c.
References AST_LIST_TRAVERSE, ast_manager_user::username, and users.
Referenced by handle_showmanager(), and init_manager().
00478 { 00479 struct ast_manager_user *user = NULL; 00480 00481 AST_LIST_TRAVERSE(&users, user, list) 00482 if (!strcasecmp(user->username, name)) 00483 break; 00484 return user; 00485 }
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 864 of file manager.c.
References ast_variable::next.
Referenced by get_perm(), and strings_to_mask().
00865 { 00866 const char *val = bigstr, *next; 00867 00868 do { 00869 if ((next = strchr(val, delim))) { 00870 if (!strncmp(val, smallstr, (next - val))) 00871 return 1; 00872 else 00873 continue; 00874 } else 00875 return !strcmp(smallstr, val); 00876 00877 } while (*(val = (next + 1))); 00878 00879 return 0; 00880 }
static int ast_is_number | ( | const char * | string | ) | [static] |
Definition at line 897 of file manager.c.
Referenced by strings_to_mask().
00898 { 00899 int ret = 1, x = 0; 00900 00901 if (!string) 00902 return 0; 00903 00904 for (x = 0; x < strlen(string); x++) { 00905 if (!(string[x] >= 48 && string[x] <= 57)) { 00906 ret = 0; 00907 break; 00908 } 00909 } 00910 00911 return ret ? atoi(string) : 0; 00912 }
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 2699 of file manager.c.
References ast_malloc, and ast_manager_register_struct().
Referenced by init_manager(), and load_module().
02700 { 02701 struct manager_action *cur; 02702 02703 cur = ast_malloc(sizeof(*cur)); 02704 if (!cur) 02705 return -1; 02706 02707 cur->action = action; 02708 cur->authority = auth; 02709 cur->func = func; 02710 cur->synopsis = synopsis; 02711 cur->description = description; 02712 cur->next = NULL; 02713 02714 ast_manager_register_struct(cur); 02715 02716 return 0; 02717 }
static int ast_manager_register_struct | ( | struct manager_action * | act | ) | [static] |
Definition at line 2655 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().
02656 { 02657 struct manager_action *cur, *prev = NULL; 02658 int ret; 02659 02660 ast_rwlock_wrlock(&actionlock); 02661 cur = first_action; 02662 while (cur) { /* Walk the list of actions */ 02663 ret = strcasecmp(cur->action, act->action); 02664 if (ret == 0) { 02665 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 02666 ast_rwlock_unlock(&actionlock); 02667 return -1; 02668 } else if (ret > 0) { 02669 /* Insert these alphabetically */ 02670 if (prev) { 02671 act->next = prev->next; 02672 prev->next = act; 02673 } else { 02674 act->next = first_action; 02675 first_action = act; 02676 } 02677 break; 02678 } 02679 prev = cur; 02680 cur = cur->next; 02681 } 02682 02683 if (!cur) { 02684 if (prev) 02685 prev->next = act; 02686 else 02687 first_action = act; 02688 act->next = NULL; 02689 } 02690 02691 if (option_verbose > 1) 02692 ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", act->action); 02693 ast_rwlock_unlock(&actionlock); 02694 return 0; 02695 }
int ast_manager_unregister | ( | char * | action | ) |
action | Name of registred Action: |
Definition at line 2624 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().
02625 { 02626 struct manager_action *cur, *prev; 02627 02628 ast_rwlock_wrlock(&actionlock); 02629 cur = prev = first_action; 02630 while (cur) { 02631 if (!strcasecmp(action, cur->action)) { 02632 prev->next = cur->next; 02633 free(cur); 02634 if (option_verbose > 1) 02635 ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action); 02636 ast_rwlock_unlock(&actionlock); 02637 return 0; 02638 } 02639 prev = cur; 02640 cur = cur->next; 02641 } 02642 ast_rwlock_unlock(&actionlock); 02643 return 0; 02644 }
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 487 of file manager.c.
References ast_calloc, ast_carefulwrite(), ast_dynamic_str_thread_set_va, ast_mutex_lock(), ast_mutex_unlock(), ASTMAN_APPEND_BUF_INITSIZE, and s.
Referenced by __iax2_show_peers(), __queues_show(), _sip_show_peer(), _sip_show_peers(), action_agents(), action_command(), action_devstate(), action_extensionstate(), action_getconfig(), action_getvar(), action_listcommands(), action_mailboxcount(), action_mailboxstatus(), action_status(), action_updateconfig(), action_waitevent(), action_zapshowchannels(), ast_cli_netstats(), astman_send_error(), astman_send_response(), manager_dbget(), manager_iax2_show_netstats(), manager_iax2_show_peers(), manager_jabber_send(), manager_parking_status(), manager_queues_show(), manager_queues_status(), manager_sip_show_peer(), manager_sip_show_peers(), process_message(), and session_do().
00488 { 00489 va_list ap; 00490 struct ast_dynamic_str *buf; 00491 00492 ast_mutex_lock(&s->__lock); 00493 00494 if (!(buf = ast_dynamic_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) { 00495 ast_mutex_unlock(&s->__lock); 00496 return; 00497 } 00498 00499 va_start(ap, fmt); 00500 ast_dynamic_str_thread_set_va(&buf, 0, &astman_append_buf, fmt, ap); 00501 va_end(ap); 00502 00503 if (s->fd > -1) 00504 ast_carefulwrite(s->fd, buf->str, strlen(buf->str), s->writetimeout); 00505 else { 00506 if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) { 00507 ast_mutex_unlock(&s->__lock); 00508 return; 00509 } 00510 00511 ast_dynamic_str_append(&s->outputstr, 0, "%s", buf->str); 00512 } 00513 00514 ast_mutex_unlock(&s->__lock); 00515 }
const char* astman_get_header | ( | const struct message * | m, | |
char * | var | |||
) |
Get header from mananger transaction
Definition at line 767 of file manager.c.
References message::hdrcount, and message::headers.
Referenced by _sip_show_peer(), _sip_show_peers(), action_agent_callback_login(), action_agent_logoff(), action_agents(), action_bridge(), action_command(), action_devstate(), action_events(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_listcommands(), action_mailboxcount(), action_mailboxstatus(), action_message(), action_originate(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), action_waitevent(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zapshowchannels(), astman_send_error(), astman_send_response(), authenticate(), change_monitor_action(), do_pause_or_unpause(), handle_updates(), manager_add_queue_member(), manager_dbdel(), 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().
00768 { 00769 char cmp[80]; 00770 int x; 00771 00772 snprintf(cmp, sizeof(cmp), "%s: ", var); 00773 00774 for (x = 0; x < m->hdrcount; x++) { 00775 if (!strncasecmp(cmp, m->headers[x], strlen(cmp))) 00776 return m->headers[x] + strlen(cmp); 00777 } 00778 00779 return ""; 00780 }
struct ast_variable* astman_get_variables | ( | const struct message * | m | ) |
Get a linked list of the Variable: headers
Definition at line 782 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().
00783 { 00784 int varlen, x, y; 00785 struct ast_variable *head = NULL, *cur; 00786 char *var, *val; 00787 00788 char *parse; 00789 AST_DECLARE_APP_ARGS(args, 00790 AST_APP_ARG(vars)[32]; 00791 ); 00792 00793 varlen = strlen("Variable: "); 00794 00795 for (x = 0; x < m->hdrcount; x++) { 00796 if (strncasecmp("Variable: ", m->headers[x], varlen)) 00797 continue; 00798 00799 parse = ast_strdupa(m->headers[x] + varlen); 00800 00801 AST_STANDARD_APP_ARGS(args, parse); 00802 if (args.argc) { 00803 for (y = 0; y < args.argc; y++) { 00804 if (!args.vars[y]) 00805 continue; 00806 var = val = ast_strdupa(args.vars[y]); 00807 strsep(&val, "="); 00808 if (!val || ast_strlen_zero(var)) 00809 continue; 00810 cur = ast_variable_new(var, val); 00811 if (head) { 00812 cur->next = head; 00813 head = cur; 00814 } else 00815 head = cur; 00816 } 00817 } 00818 } 00819 00820 return head; 00821 }
void astman_send_ack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg | |||
) |
Definition at line 854 of file manager.c.
References astman_send_response(), and s.
Referenced by action_agent_callback_login(), action_agent_logoff(), action_agents(), action_bridge(), action_hangup(), action_message(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), action_zapshowchannels(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbdel(), 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().
00855 { 00856 astman_send_response(s, m, "Success", msg); 00857 }
void astman_send_error | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | error | |||
) |
Definition at line 831 of file manager.c.
References ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by _sip_show_peer(), action_agent_callback_login(), action_agent_logoff(), action_bridge(), action_command(), action_devstate(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_mailboxcount(), action_mailboxstatus(), action_message(), action_originate(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbdel(), 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().
00832 { 00833 const char *id = astman_get_header(m,"ActionID"); 00834 00835 astman_append(s, "Response: Error\r\n"); 00836 if (!ast_strlen_zero(id)) 00837 astman_append(s, "ActionID: %s\r\n", id); 00838 astman_append(s, "Message: %s\r\n\r\n", error); 00839 }
void astman_send_response | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg | |||
) |
Definition at line 841 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().
00842 { 00843 const char *id = astman_get_header(m,"ActionID"); 00844 00845 astman_append(s, "Response: %s\r\n", resp); 00846 if (!ast_strlen_zero(id)) 00847 astman_append(s, "ActionID: %s\r\n", id); 00848 if (msg) 00849 astman_append(s, "Message: %s\r\n\r\n", msg); 00850 else 00851 astman_append(s, "\r\n"); 00852 }
static int authenticate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 957 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().
00958 { 00959 struct ast_config *cfg; 00960 char *cat; 00961 const char *user = astman_get_header(m, "Username"); 00962 const char *pass = astman_get_header(m, "Secret"); 00963 const char *authtype = astman_get_header(m, "AuthType"); 00964 const char *key = astman_get_header(m, "Key"); 00965 const char *events = astman_get_header(m, "Events"); 00966 00967 cfg = ast_config_load("manager.conf"); 00968 if (!cfg) 00969 return -1; 00970 cat = ast_category_browse(cfg, NULL); 00971 while (cat) { 00972 if (strcasecmp(cat, "general")) { 00973 /* This is a user */ 00974 if (!strcasecmp(cat, user)) { 00975 struct ast_variable *v; 00976 struct ast_ha *ha = NULL; 00977 char *password = NULL; 00978 00979 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 00980 if (!strcasecmp(v->name, "secret")) { 00981 password = v->value; 00982 } else if (!strcasecmp(v->name, "displaysystemname")) { 00983 if (ast_true(v->value)) { 00984 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) { 00985 s->displaysystemname = 1; 00986 } else { 00987 ast_log(LOG_ERROR, "Can't enable displaysystemname in manager.conf - no system name configured in asterisk.conf\n"); 00988 } 00989 } 00990 } else if (!strcasecmp(v->name, "permit") || 00991 !strcasecmp(v->name, "deny")) { 00992 ha = ast_append_ha(v->name, v->value, ha); 00993 } else if (!strcasecmp(v->name, "writetimeout")) { 00994 int val = atoi(v->value); 00995 00996 if (val < 100) 00997 ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", v->value, v->lineno); 00998 else 00999 s->writetimeout = val; 01000 } 01001 01002 } 01003 if (ha && !ast_apply_ha(ha, &(s->sin))) { 01004 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01005 ast_free_ha(ha); 01006 ast_config_destroy(cfg); 01007 return -1; 01008 } else if (ha) 01009 ast_free_ha(ha); 01010 if (!strcasecmp(authtype, "MD5")) { 01011 if (!ast_strlen_zero(key) && 01012 !ast_strlen_zero(s->challenge) && !ast_strlen_zero(password)) { 01013 int x; 01014 int len = 0; 01015 char md5key[256] = ""; 01016 struct MD5Context md5; 01017 unsigned char digest[16]; 01018 MD5Init(&md5); 01019 MD5Update(&md5, (unsigned char *) s->challenge, strlen(s->challenge)); 01020 MD5Update(&md5, (unsigned char *) password, strlen(password)); 01021 MD5Final(digest, &md5); 01022 for (x=0; x<16; x++) 01023 len += sprintf(md5key + len, "%2.2x", digest[x]); 01024 if (!strcmp(md5key, key)) 01025 break; 01026 else { 01027 ast_config_destroy(cfg); 01028 return -1; 01029 } 01030 } else { 01031 ast_log(LOG_DEBUG, "MD5 authentication is not possible. challenge: '%s'\n", 01032 S_OR(s->challenge, "")); 01033 ast_config_destroy(cfg); 01034 return -1; 01035 } 01036 } else if (password && !strcmp(password, pass)) { 01037 break; 01038 } else { 01039 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01040 ast_config_destroy(cfg); 01041 return -1; 01042 } 01043 } 01044 } 01045 cat = ast_category_browse(cfg, cat); 01046 } 01047 if (cat) { 01048 ast_copy_string(s->username, cat, sizeof(s->username)); 01049 s->readperm = get_perm(ast_variable_retrieve(cfg, cat, "read")); 01050 s->writeperm = get_perm(ast_variable_retrieve(cfg, cat, "write")); 01051 ast_config_destroy(cfg); 01052 if (events) 01053 set_eventmask(s, events); 01054 return 0; 01055 } 01056 ast_config_destroy(cfg); 01057 cfg = ast_config_load("users.conf"); 01058 if (!cfg) 01059 return -1; 01060 cat = ast_category_browse(cfg, NULL); 01061 while (cat) { 01062 struct ast_variable *v; 01063 const char *password = NULL; 01064 int hasmanager = 0; 01065 const char *readperms = NULL; 01066 const char *writeperms = NULL; 01067 01068 if (strcasecmp(cat, user) || !strcasecmp(cat, "general")) { 01069 cat = ast_category_browse(cfg, cat); 01070 continue; 01071 } 01072 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 01073 if (!strcasecmp(v->name, "secret")) 01074 password = v->value; 01075 else if (!strcasecmp(v->name, "hasmanager")) 01076 hasmanager = ast_true(v->value); 01077 else if (!strcasecmp(v->name, "managerread")) 01078 readperms = v->value; 01079 else if (!strcasecmp(v->name, "managerwrite")) 01080 writeperms = v->value; 01081 } 01082 if (!hasmanager) 01083 break; 01084 if (!password || strcmp(password, pass)) { 01085 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01086 ast_config_destroy(cfg); 01087 return -1; 01088 } 01089 ast_copy_string(s->username, cat, sizeof(s->username)); 01090 s->readperm = readperms ? get_perm(readperms) : -1; 01091 s->writeperm = writeperms ? get_perm(writeperms) : -1; 01092 ast_config_destroy(cfg); 01093 if (events) 01094 set_eventmask(s, events); 01095 return 0; 01096 } 01097 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01098 ast_config_destroy(cfg); 01099 return -1; 01100 }
static char* authority_to_str | ( | int | authority, | |
char * | res, | |||
int | reslen | |||
) | [static] |
Convert authority code to string with serveral options.
Definition at line 211 of file manager.c.
References ast_strlen_zero(), and perms.
Referenced by action_listcommands(), handle_showmancmd(), handle_showmancmds(), and manager_event().
00212 { 00213 int running_total = 0, i; 00214 00215 memset(res, 0, reslen); 00216 for (i = 0; i < (sizeof(perms) / sizeof(perms[0])) - 1; i++) { 00217 if (authority & perms[i].num) { 00218 if (*res) { 00219 strncat(res, ",", (reslen > running_total) ? reslen - running_total - 1 : 0); 00220 running_total++; 00221 } 00222 strncat(res, perms[i].label, (reslen > running_total) ? reslen - running_total - 1 : 0); 00223 running_total += strlen(perms[i].label); 00224 } 00225 } 00226 00227 if (ast_strlen_zero(res)) 00228 ast_copy_string(res, "<none>", reslen); 00229 00230 return res; 00231 }
static int check_blacklist | ( | const char * | cmd | ) | [static] |
Definition at line 1764 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().
01765 { 01766 char *cmd_copy, *cur_cmd; 01767 char *cmd_words[MAX_BLACKLIST_CMD_LEN] = { NULL, }; 01768 int i; 01769 01770 cmd_copy = ast_strdupa(cmd); 01771 for (i = 0; i < MAX_BLACKLIST_CMD_LEN && (cur_cmd = strsep(&cmd_copy, " ")); i++) { 01772 cur_cmd = ast_strip(cur_cmd); 01773 if (ast_strlen_zero(cur_cmd)) { 01774 i--; 01775 continue; 01776 } 01777 01778 cmd_words[i] = cur_cmd; 01779 } 01780 01781 for (i = 0; i < ARRAY_LEN(command_blacklist); i++) { 01782 int j, match = 1; 01783 01784 for (j = 0; command_blacklist[i].words[j]; j++) { 01785 if (ast_strlen_zero(cmd_words[j]) || strcasecmp(cmd_words[j], command_blacklist[i].words[j])) { 01786 match = 0; 01787 break; 01788 } 01789 } 01790 01791 if (match) { 01792 return 1; 01793 } 01794 } 01795 01796 return 0; 01797 }
static char* complete_show_mancmd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 233 of file manager.c.
References manager_action::action, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_strdup, first_action, and manager_action::next.
00234 { 00235 struct manager_action *cur; 00236 int which = 0; 00237 char *ret = NULL; 00238 00239 ast_rwlock_rdlock(&actionlock); 00240 for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */ 00241 if (!strncasecmp(word, cur->action, strlen(word)) && ++which > state) { 00242 ret = ast_strdup(cur->action); 00243 break; /* make sure we exit even if ast_strdup() returns NULL */ 00244 } 00245 } 00246 ast_rwlock_unlock(&actionlock); 00247 00248 return ret; 00249 }
static int compress_char | ( | char | c | ) | [static] |
Definition at line 293 of file manager.c.
Referenced by member_hash_fn(), and variable_count_hash_fn().
00294 { 00295 c &= 0x7f; 00296 if (c < 32) 00297 return 0; 00298 else if (c >= 'a' && c <= 'z') 00299 return c - 64; 00300 else if (c > 'z') 00301 return '_'; 00302 else 00303 return c - 32; 00304 }
static void destroy_session | ( | struct mansession * | s | ) | [static] |
Definition at line 758 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().
00759 { 00760 AST_LIST_LOCK(&sessions); 00761 AST_LIST_REMOVE(&sessions, s, list); 00762 num_sessions--; 00763 free_session(s); 00764 AST_LIST_UNLOCK(&sessions); 00765 }
static int do_message | ( | struct mansession * | s | ) | [static] |
Definition at line 2377 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().
02378 { 02379 struct message m = { 0 }; 02380 char header_buf[sizeof(s->inbuf)] = { '\0' }; 02381 int res; 02382 02383 for (;;) { 02384 /* Check if any events are pending and do them if needed */ 02385 if (s->eventq->next) { 02386 if (process_events(s)) 02387 return -1; 02388 } 02389 res = get_input(s, header_buf); 02390 if (res == 0) { 02391 continue; 02392 } else if (res > 0) { 02393 /* Strip trailing \r\n */ 02394 if (strlen(header_buf) < 2) 02395 continue; 02396 header_buf[strlen(header_buf) - 2] = '\0'; 02397 if (ast_strlen_zero(header_buf)) 02398 return process_message(s, &m) ? -1 : 0; 02399 else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) 02400 m.headers[m.hdrcount++] = ast_strdupa(header_buf); 02401 } else { 02402 return res; 02403 } 02404 } 02405 }
static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 1854 of file manager.c.
References fast_originate_helper::account, fast_originate_helper::app, fast_originate_helper::appdata, AST_CHANNEL_NAME, ast_channel_unlock, AST_FORMAT_SLINEAR, ast_pbx_outgoing_app_uniqueid(), ast_pbx_outgoing_exten_uniqueid(), ast_strlen_zero(), fast_originate_helper::callingpres, fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, fast_originate_helper::data, EVENT_FLAG_CALL, fast_originate_helper::exten, free, fast_originate_helper::idtext, manager_event(), fast_originate_helper::priority, S_OR, fast_originate_helper::tech, fast_originate_helper::timeout, fast_originate_helper::uniqueid, and fast_originate_helper::vars.
Referenced by action_originate().
01855 { 01856 struct fast_originate_helper *in = data; 01857 int res; 01858 int reason = 0; 01859 struct ast_channel *chan = NULL; 01860 char requested_channel[AST_CHANNEL_NAME]; 01861 01862 if (!ast_strlen_zero(in->app)) { 01863 res = ast_pbx_outgoing_app_uniqueid(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, in->callingpres, 01864 S_OR(in->cid_num, NULL), 01865 S_OR(in->cid_name, NULL), 01866 in->vars, in->account, &chan, in->uniqueid); 01867 } else { 01868 res = ast_pbx_outgoing_exten_uniqueid(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, in->callingpres, 01869 S_OR(in->cid_num, NULL), 01870 S_OR(in->cid_name, NULL), 01871 in->vars, in->account, &chan, in->uniqueid); 01872 } 01873 01874 if (!chan) 01875 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 01876 /* Tell the manager what happened with the channel */ 01877 manager_event(EVENT_FLAG_CALL, "OriginateResponse", 01878 "%s" 01879 "Response: %s\r\n" 01880 "Channel: %s\r\n" 01881 "Context: %s\r\n" 01882 "Exten: %s\r\n" 01883 "Reason: %d\r\n" 01884 "Uniqueid: %s\r\n" 01885 "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */ 01886 "CallerIDNum: %s\r\n" 01887 "CallerIDName: %s\r\n", 01888 in->idtext, res ? "Failure" : "Success", chan ? chan->name : requested_channel, in->context, in->exten, reason, 01889 chan ? chan->uniqueid : "<null>", 01890 S_OR(in->cid_num, "<unknown>"), 01891 S_OR(in->cid_num, "<unknown>"), 01892 S_OR(in->cid_name, "<unknown>") 01893 ); 01894 01895 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 01896 if (chan) 01897 ast_channel_unlock(chan); 01898 free(in); 01899 return NULL; 01900 }
static void free_session | ( | struct mansession * | s | ) | [static] |
Definition at line 742 of file manager.c.
References ast_mutex_destroy(), free, s, and unuse_eventqent().
Referenced by accept_thread(), and destroy_session().
00743 { 00744 struct eventqent *eqe; 00745 if (s->fd > -1) 00746 close(s->fd); 00747 if (s->outputstr) 00748 free(s->outputstr); 00749 ast_mutex_destroy(&s->__lock); 00750 while (s->eventq) { 00751 eqe = s->eventq; 00752 s->eventq = s->eventq->next; 00753 unuse_eventqent(eqe); 00754 } 00755 free(s); 00756 }
static int get_input | ( | struct mansession * | s, | |
char * | output | |||
) | [static] |
Definition at line 2318 of file manager.c.
References ast_channel::fds, and s.
Referenced by do_message(), and skinny_session().
02319 { 02320 /* output must have at least sizeof(s->inbuf) space */ 02321 int res; 02322 int x; 02323 struct pollfd fds[1]; 02324 for (x = 1; x < s->inlen; x++) { 02325 if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) { 02326 /* Copy output data up to and including \r\n */ 02327 memcpy(output, s->inbuf, x + 1); 02328 /* Add trailing \0 */ 02329 output[x+1] = '\0'; 02330 /* Move remaining data back to the front */ 02331 memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x); 02332 s->inlen -= (x + 1); 02333 return 1; 02334 } 02335 } 02336 if (s->inlen >= sizeof(s->inbuf) - 1) { 02337 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->sin.sin_addr), s->inbuf); 02338 s->inlen = 0; 02339 } 02340 fds[0].fd = s->fd; 02341 fds[0].events = POLLIN; 02342 do { 02343 ast_mutex_lock(&s->__lock); 02344 if (s->pending_event) { 02345 s->pending_event = 0; 02346 ast_mutex_unlock(&s->__lock); 02347 return 0; 02348 } 02349 s->waiting_thread = pthread_self(); 02350 ast_mutex_unlock(&s->__lock); 02351 02352 res = poll(fds, 1, -1); 02353 02354 ast_mutex_lock(&s->__lock); 02355 s->waiting_thread = AST_PTHREADT_NULL; 02356 ast_mutex_unlock(&s->__lock); 02357 if (res < 0) { 02358 if (errno == EINTR || errno == EAGAIN) { 02359 return 0; 02360 } 02361 ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno)); 02362 return -1; 02363 } else if (res > 0) { 02364 ast_mutex_lock(&s->__lock); 02365 res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen); 02366 ast_mutex_unlock(&s->__lock); 02367 if (res < 1) 02368 return -1; 02369 break; 02370 } 02371 } while(1); 02372 s->inlen += res; 02373 s->inbuf[s->inlen] = '\0'; 02374 return 0; 02375 }
static int get_perm | ( | const char * | instr | ) | [static] |
Definition at line 882 of file manager.c.
References ast_instring(), and perms.
00883 { 00884 int x = 0, ret = 0; 00885 00886 if (!instr) 00887 return 0; 00888 00889 for (x = 0; x < (sizeof(perms) / sizeof(perms[0])); x++) { 00890 if (ast_instring(instr, perms[x].label, ',')) 00891 ret |= perms[x].num; 00892 } 00893 00894 return ret; 00895 }
static int handle_showmanager | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 539 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.
00540 { 00541 struct ast_manager_user *user = NULL; 00542 00543 if (argc != 4) 00544 return RESULT_SHOWUSAGE; 00545 00546 AST_LIST_LOCK(&users); 00547 00548 if (!(user = ast_get_manager_by_name_locked(argv[3]))) { 00549 ast_cli(fd, "There is no manager called %s\n", argv[3]); 00550 AST_LIST_UNLOCK(&users); 00551 return -1; 00552 } 00553 00554 ast_cli(fd,"\n"); 00555 ast_cli(fd, 00556 " username: %s\n" 00557 " secret: %s\n" 00558 " deny: %s\n" 00559 " permit: %s\n" 00560 " read: %s\n" 00561 " write: %s\n" 00562 "displayconnects: %s\n", 00563 (user->username ? user->username : "(N/A)"), 00564 (user->secret ? "<Set>" : "(N/A)"), 00565 (user->deny ? user->deny : "(N/A)"), 00566 (user->permit ? user->permit : "(N/A)"), 00567 (user->read ? user->read : "(N/A)"), 00568 (user->write ? user->write : "(N/A)"), 00569 (user->displayconnects ? "yes" : "no")); 00570 00571 AST_LIST_UNLOCK(&users); 00572 00573 return RESULT_SUCCESS; 00574 }
static int handle_showmanagers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 577 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.
00578 { 00579 struct ast_manager_user *user = NULL; 00580 int count_amu = 0; 00581 00582 if (argc != 3) 00583 return RESULT_SHOWUSAGE; 00584 00585 AST_LIST_LOCK(&users); 00586 00587 /* If there are no users, print out something along those lines */ 00588 if (AST_LIST_EMPTY(&users)) { 00589 ast_cli(fd, "There are no manager users.\n"); 00590 AST_LIST_UNLOCK(&users); 00591 return RESULT_SUCCESS; 00592 } 00593 00594 ast_cli(fd, "\nusername\n--------\n"); 00595 00596 AST_LIST_TRAVERSE(&users, user, list) { 00597 ast_cli(fd, "%s\n", user->username); 00598 count_amu++; 00599 } 00600 00601 AST_LIST_UNLOCK(&users); 00602 00603 ast_cli(fd,"-------------------\n"); 00604 ast_cli(fd,"%d manager users configured.\n", count_amu); 00605 00606 return RESULT_SUCCESS; 00607 }
static int handle_showmancmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 517 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.
00518 { 00519 struct manager_action *cur; 00520 char authority[80]; 00521 int num; 00522 00523 if (argc != 4) 00524 return RESULT_SHOWUSAGE; 00525 00526 ast_rwlock_rdlock(&actionlock); 00527 for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */ 00528 for (num = 3; num < argc; num++) { 00529 if (!strcasecmp(cur->action, argv[num])) { 00530 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 : ""); 00531 } 00532 } 00533 } 00534 ast_rwlock_unlock(&actionlock); 00535 00536 return RESULT_SUCCESS; 00537 }
static int handle_showmancmds | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command Should change to "manager show commands".
Definition at line 612 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.
00613 { 00614 struct manager_action *cur; 00615 char authority[80]; 00616 char *format = " %-15.15s %-15.15s %-55.55s\n"; 00617 00618 ast_cli(fd, format, "Action", "Privilege", "Synopsis"); 00619 ast_cli(fd, format, "------", "---------", "--------"); 00620 00621 ast_rwlock_rdlock(&actionlock); 00622 for (cur = first_action; cur; cur = cur->next) /* Walk the list of actions */ 00623 ast_cli(fd, format, cur->action, authority_to_str(cur->authority, authority, sizeof(authority) -1), cur->synopsis); 00624 ast_rwlock_unlock(&actionlock); 00625 00626 return RESULT_SUCCESS; 00627 }
static int handle_showmanconn | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command show manager connected.
Definition at line 631 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.
00632 { 00633 struct mansession *s; 00634 char *format = " %-15.15s %-15.15s\n"; 00635 00636 ast_cli(fd, format, "Username", "IP Address"); 00637 00638 AST_LIST_LOCK(&sessions); 00639 AST_LIST_TRAVERSE(&sessions, s, list) 00640 ast_cli(fd, format,s->username, ast_inet_ntoa(s->sin.sin_addr)); 00641 AST_LIST_UNLOCK(&sessions); 00642 00643 return RESULT_SUCCESS; 00644 }
static int handle_showmaneventq | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command show manager connected.
Definition at line 648 of file manager.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_UNLOCK, master_eventq, RESULT_SUCCESS, s, and sessions.
00649 { 00650 struct eventqent *s; 00651 00652 AST_LIST_LOCK(&sessions); 00653 for (s = master_eventq; s; s = s->next) { 00654 ast_cli(fd, "Usecount: %d\n",s->usecount); 00655 ast_cli(fd, "Category: %d\n", s->category); 00656 ast_cli(fd, "Event:\n%s", s->eventdata); 00657 } 00658 AST_LIST_UNLOCK(&sessions); 00659 00660 return RESULT_SUCCESS; 00661 }
static void handle_updates | ( | struct mansession * | s, | |
const struct message * | m, | |||
struct ast_config * | cfg | |||
) | [static] |
Definition at line 1157 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().
01158 { 01159 int x; 01160 char hdr[40]; 01161 const char *action, *cat, *var, *value, *match; 01162 struct ast_category *category; 01163 struct ast_variable *v; 01164 01165 for (x=0;x<100000;x++) { 01166 unsigned int object = 0; 01167 01168 snprintf(hdr, sizeof(hdr), "Action-%06d", x); 01169 action = astman_get_header(m, hdr); 01170 if (ast_strlen_zero(action)) 01171 break; 01172 snprintf(hdr, sizeof(hdr), "Cat-%06d", x); 01173 cat = astman_get_header(m, hdr); 01174 snprintf(hdr, sizeof(hdr), "Var-%06d", x); 01175 var = astman_get_header(m, hdr); 01176 snprintf(hdr, sizeof(hdr), "Value-%06d", x); 01177 value = astman_get_header(m, hdr); 01178 if (!ast_strlen_zero(value) && *value == '>') { 01179 object = 1; 01180 value++; 01181 } 01182 snprintf(hdr, sizeof(hdr), "Match-%06d", x); 01183 match = astman_get_header(m, hdr); 01184 if (!strcasecmp(action, "newcat")) { 01185 if (!ast_strlen_zero(cat)) { 01186 category = ast_category_new(cat); 01187 if (category) { 01188 ast_category_append(cfg, category); 01189 } 01190 } 01191 } else if (!strcasecmp(action, "renamecat")) { 01192 if (!ast_strlen_zero(cat) && !ast_strlen_zero(value)) { 01193 category = ast_category_get(cfg, cat); 01194 if (category) 01195 ast_category_rename(category, value); 01196 } 01197 } else if (!strcasecmp(action, "delcat")) { 01198 if (!ast_strlen_zero(cat)) 01199 ast_category_delete(cfg, (char *) cat); 01200 } else if (!strcasecmp(action, "update")) { 01201 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat))) 01202 ast_variable_update(category, var, value, match, object); 01203 } else if (!strcasecmp(action, "delete")) { 01204 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat))) 01205 ast_variable_delete(category, (char *) var, (char *) match); 01206 } else if (!strcasecmp(action, "append")) { 01207 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && 01208 (category = ast_category_get(cfg, cat)) && 01209 (v = ast_variable_new(var, value))){ 01210 if (object || (match && !strcasecmp(match, "object"))) 01211 v->object = 1; 01212 ast_variable_append(category, v); 01213 } 01214 } 01215 } 01216 }
static char* html_translate | ( | char * | in | ) | [static] |
Definition at line 428 of file manager.c.
References ast_build_string(), ast_malloc, len, and var.
00429 { 00430 int x; 00431 int colons = 0; 00432 int breaks = 0; 00433 size_t len; 00434 int count = 1; 00435 char *tmp, *var, *val, *out; 00436 00437 for (x=0; in[x]; x++) { 00438 if (in[x] == ':') 00439 colons++; 00440 if (in[x] == '\n') 00441 breaks++; 00442 } 00443 len = strlen(in) + colons * 40 + breaks * 40; /* <tr><td></td><td></td></tr>, "<tr><td colspan=\"2\"><hr></td></tr> */ 00444 out = ast_malloc(len); 00445 if (!out) 00446 return 0; 00447 tmp = out; 00448 while (*in) { 00449 var = in; 00450 while (*in && (*in >= 32)) 00451 in++; 00452 if (*in) { 00453 if ((count % 4) == 0){ 00454 ast_build_string(&tmp, &len, "<tr><td colspan=\"2\"><hr></td></tr>\r\n"); 00455 } 00456 count = 0; 00457 while (*in && (*in < 32)) { 00458 *in = '\0'; 00459 in++; 00460 count++; 00461 } 00462 val = strchr(var, ':'); 00463 if (val) { 00464 *val = '\0'; 00465 val++; 00466 if (*val == ' ') 00467 val++; 00468 ast_build_string(&tmp, &len, "<tr><td>%s</td><td>%s</td></tr>\r\n", var, val); 00469 } 00470 } 00471 } 00472 return out; 00473 }
int manager_event | ( | int | category, | |
const char * | event, | |||
const char * | fmt, | |||
... | ||||
) |
manager_event: Send AMI event to client
Definition at line 2571 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_autoanswer_login(), ast_change_name(), ast_channel_bridge(), ast_do_masquerade(), ast_hangup(), ast_hold_call(), ast_log(), ast_monitor_stop(), ast_set_callerid(), ast_setstate_and_callerid(), autoanswer_exec(), bridge_exec(), change_hold_state(), conf_run(), do_autoanswer_thread(), expire_register(), fast_originate(), handle_init_event(), handle_response_peerpoke(), handle_response_register(), iax2_ack_registry(), join_queue(), leave_queue(), manager_log(), manager_state_cb(), notify_new_message(), park_call_full(), park_exec(), parse_register_contact(), pbx_extension_helper(), post_manager_event(), quit_handler(), realtime_exec(), record_abandoned(), register_verify(), reload_logger(), reload_manager(), remove_from_queue(), ring_entry(), senddialevent(), set_member_paused(), sip_poke_noanswer(), sip_reg_timeout(), socket_process(), ss_thread(), try_calling(), update_registry(), update_status(), userevent_exec(), vm_execmain(), and zt_handle_event().
02572 { 02573 struct mansession *s; 02574 char auth[80]; 02575 va_list ap; 02576 struct timeval now; 02577 struct ast_dynamic_str *buf; 02578 02579 /* Abort if there aren't any manager sessions */ 02580 if (!num_sessions) 02581 return 0; 02582 02583 if (!(buf = ast_dynamic_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) 02584 return -1; 02585 02586 ast_dynamic_str_thread_set(&buf, 0, &manager_event_buf, 02587 "Event: %s\r\nPrivilege: %s\r\n", 02588 event, authority_to_str(category, auth, sizeof(auth))); 02589 02590 if (timestampevents) { 02591 now = ast_tvnow(); 02592 ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, 02593 "Timestamp: %ld.%06lu\r\n", 02594 now.tv_sec, (unsigned long) now.tv_usec); 02595 } 02596 02597 va_start(ap, fmt); 02598 ast_dynamic_str_thread_append_va(&buf, 0, &manager_event_buf, fmt, ap); 02599 va_end(ap); 02600 02601 ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, "\r\n"); 02602 02603 /* Append event to master list and wake up any sleeping sessions */ 02604 AST_LIST_LOCK(&sessions); 02605 append_event(buf->str, category); 02606 AST_LIST_TRAVERSE(&sessions, s, list) { 02607 ast_mutex_lock(&s->__lock); 02608 if (s->waiting_thread != AST_PTHREADT_NULL) 02609 pthread_kill(s->waiting_thread, SIGURG); 02610 else 02611 /* We have an event to process, but the mansession is 02612 * not waiting for it. We still need to indicate that there 02613 * is an event waiting so that get_input processes the pending 02614 * event instead of polling. 02615 */ 02616 s->pending_event = 1; 02617 ast_mutex_unlock(&s->__lock); 02618 } 02619 AST_LIST_UNLOCK(&sessions); 02620 02621 return 0; 02622 }
static int manager_state_cb | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data, | |||
char * | cid_num, | |||
char * | cid_name | |||
) | [static] |
Definition at line 2646 of file manager.c.
References ast_get_hint(), EVENT_FLAG_EXTENSIONSTATUS, and manager_event().
Referenced by init_manager().
02647 { 02648 char hint[256] = ""; 02649 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 02650 /* Notify managers of change */ 02651 manager_event(EVENT_FLAG_EXTENSIONSTATUS, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nStatus: %d\r\nCallerID: \"%s\" <%s>\r\nHint: %s\r\n", exten, context, state, cid_num, cid_name, hint); 02652 return 0; 02653 }
static int process_events | ( | struct mansession * | s | ) | [static] |
Definition at line 2185 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().
02186 { 02187 struct eventqent *eqe; 02188 int ret = 0; 02189 ast_mutex_lock(&s->__lock); 02190 if (!s->eventq) 02191 s->eventq = master_eventq; 02192 while(s->eventq->next) { 02193 eqe = s->eventq->next; 02194 if ((s->authenticated && (s->readperm & eqe->category) == eqe->category) && 02195 ((s->send_events & eqe->category) == eqe->category)) { 02196 if (s->fd > -1) { 02197 if (!ret && ast_carefulwrite(s->fd, eqe->eventdata, strlen(eqe->eventdata), s->writetimeout) < 0) 02198 ret = -1; 02199 } else if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) 02200 ret = -1; 02201 else 02202 ast_dynamic_str_append(&s->outputstr, 0, "%s", eqe->eventdata); 02203 } 02204 unuse_eventqent(s->eventq); 02205 s->eventq = eqe; 02206 } 02207 ast_mutex_unlock(&s->__lock); 02208 return ret; 02209 }
static int process_message | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2236 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().
02237 { 02238 char action[80] = ""; 02239 struct manager_action *tmp; 02240 const char *id = astman_get_header(m,"ActionID"); 02241 char idText[256] = ""; 02242 int ret = 0; 02243 02244 ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action)); 02245 if (option_debug) 02246 ast_log( LOG_DEBUG, "Manager received command '%s'\n", action ); 02247 02248 if (ast_strlen_zero(action)) { 02249 astman_send_error(s, m, "Missing action in request"); 02250 return 0; 02251 } 02252 if (!ast_strlen_zero(id)) { 02253 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02254 } 02255 if (!s->authenticated) { 02256 if (!strcasecmp(action, "Challenge")) { 02257 const char *authtype = astman_get_header(m, "AuthType"); 02258 02259 if (!strcasecmp(authtype, "MD5")) { 02260 if (ast_strlen_zero(s->challenge)) 02261 snprintf(s->challenge, sizeof(s->challenge), "%ld", ast_random()); 02262 astman_append(s, "Response: Success\r\n" 02263 "%s" 02264 "Challenge: %s\r\n\r\n", 02265 idText, s->challenge); 02266 return 0; 02267 } else { 02268 astman_send_error(s, m, "Must specify AuthType"); 02269 return 0; 02270 } 02271 } else if (!strcasecmp(action, "Login")) { 02272 if (authenticate(s, m)) { 02273 sleep(1); 02274 astman_send_error(s, m, "Authentication failed"); 02275 return -1; 02276 } else { 02277 s->authenticated = 1; 02278 if (option_verbose > 1) { 02279 if (displayconnects) { 02280 ast_verbose(VERBOSE_PREFIX_2 "%sManager '%s' logged on from %s\n", 02281 (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr)); 02282 } 02283 } 02284 ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", 02285 (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr)); 02286 astman_send_ack(s, m, "Authentication accepted"); 02287 } 02288 } else if (!strcasecmp(action, "Logoff")) { 02289 astman_send_ack(s, m, "See ya"); 02290 return -1; 02291 } else 02292 astman_send_error(s, m, "Authentication Required"); 02293 } else { 02294 if (!strcasecmp(action, "Login")) 02295 astman_send_ack(s, m, "Already logged in"); 02296 else { 02297 ast_rwlock_rdlock(&actionlock); 02298 for (tmp = first_action; tmp; tmp = tmp->next) { 02299 if (strcasecmp(action, tmp->action)) 02300 continue; 02301 if ((s->writeperm & tmp->authority) == tmp->authority) { 02302 if (tmp->func(s, m)) 02303 ret = -1; 02304 } else 02305 astman_send_error(s, m, "Permission denied"); 02306 break; 02307 } 02308 ast_rwlock_unlock(&actionlock); 02309 if (!tmp) 02310 astman_send_error(s, m, "Invalid/unknown command"); 02311 } 02312 } 02313 if (ret) 02314 return ret; 02315 return process_events(s); 02316 }
static void* session_do | ( | void * | data | ) | [static] |
Definition at line 2407 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().
02408 { 02409 struct mansession *s = data; 02410 int res; 02411 02412 astman_append(s, "Asterisk Call Manager/1.0\r\n"); 02413 for (;;) { 02414 if ((res = do_message(s)) < 0) 02415 break; 02416 } 02417 if (s->authenticated) { 02418 if (option_verbose > 1) { 02419 if (displayconnects) 02420 ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); 02421 } 02422 ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); 02423 } else { 02424 if (option_verbose > 1) { 02425 if (displayconnects) 02426 ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr)); 02427 } 02428 ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr)); 02429 } 02430 02431 /* It is possible under certain circumstances for this session thread 02432 to complete its work and exit *before* the thread that created it 02433 has finished executing the ast_pthread_create_background() function. 02434 If this occurs, some versions of glibc appear to act in a buggy 02435 fashion and attempt to write data into memory that it thinks belongs 02436 to the thread but is in fact not owned by the thread (or may have 02437 been freed completely). 02438 02439 Causing this thread to yield to other threads at least one time 02440 appears to work around this bug. 02441 */ 02442 usleep(1); 02443 02444 destroy_session(s); 02445 return NULL; 02446 }
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 945 of file manager.c.
References ast_mutex_lock(), ast_mutex_unlock(), s, and strings_to_mask().
Referenced by action_events().
00946 { 00947 int maskint = strings_to_mask(eventmask); 00948 00949 ast_mutex_lock(&s->__lock); 00950 if (maskint >= 0) 00951 s->send_events = maskint; 00952 ast_mutex_unlock(&s->__lock); 00953 00954 return maskint; 00955 }
static int strings_to_mask | ( | const char * | string | ) | [static] |
Definition at line 914 of file manager.c.
References ast_false(), ast_instring(), ast_is_number(), ast_strlen_zero(), ast_true(), and perms.
Referenced by set_eventmask().
00915 { 00916 int x, ret = -1; 00917 00918 x = ast_is_number(string); 00919 00920 if (x) 00921 ret = x; 00922 else if (ast_strlen_zero(string)) 00923 ret = -1; 00924 else if (ast_false(string)) 00925 ret = 0; 00926 else if (ast_true(string)) { 00927 ret = 0; 00928 for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) 00929 ret |= perms[x].num; 00930 } else { 00931 ret = 0; 00932 for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) { 00933 if (ast_instring(string, perms[x].label, ',')) 00934 ret |= perms[x].num; 00935 } 00936 } 00937 00938 return ret; 00939 }
static void unuse_eventqent | ( | struct eventqent * | e | ) | [static] |
Definition at line 736 of file manager.c.
References eventqent::next, and eventqent::usecount.
Referenced by action_waitevent(), free_session(), and process_events().
00737 { 00738 if (ast_atomic_dec_and_test(&e->usecount) && e->next) 00739 pthread_kill(t, SIGURG); 00740 }
static int variable_count_cmp_fn | ( | void * | obj, | |
void * | vstr, | |||
int | flags | |||
) | [static] |
Definition at line 318 of file manager.c.
References variable_count::varname.
Referenced by xml_translate().
00319 { 00320 /* Due to the simplicity of struct variable_count, it makes no difference 00321 * if you pass in objects or strings, the same operation applies. This is 00322 * due to the fact that the hash occurs on the first element, which means 00323 * the address of both the struct and the string are exactly the same. */ 00324 struct variable_count *vc = obj; 00325 char *str = vstr; 00326 return !strcmp(vc->varname, str) ? CMP_MATCH : 0; 00327 }
static int variable_count_hash_fn | ( | const void * | vvc, | |
const int | flags | |||
) | [static] |
Definition at line 306 of file manager.c.
References compress_char(), and variable_count::varname.
Referenced by xml_translate().
00307 { 00308 const struct variable_count *vc = vvc; 00309 int res = 0, i; 00310 for (i = 0; i < 5; i++) { 00311 if (vc->varname[i] == '\0') 00312 break; 00313 res += compress_char(vc->varname[i]) << (i * 6); 00314 } 00315 return res; 00316 }
static void xml_copy_escape | ( | char ** | dst, | |
size_t * | maxlen, | |||
const char * | src, | |||
int | lower | |||
) | [static] |
Definition at line 251 of file manager.c.
Referenced by xml_translate().
00252 { 00253 while (*src && (*maxlen > 6)) { 00254 switch (*src) { 00255 case '<': 00256 strcpy(*dst, "<"); 00257 (*dst) += 4; 00258 *maxlen -= 4; 00259 break; 00260 case '>': 00261 strcpy(*dst, ">"); 00262 (*dst) += 4; 00263 *maxlen -= 4; 00264 break; 00265 case '\"': 00266 strcpy(*dst, """); 00267 (*dst) += 6; 00268 *maxlen -= 6; 00269 break; 00270 case '\'': 00271 strcpy(*dst, "'"); 00272 (*dst) += 6; 00273 *maxlen -= 6; 00274 break; 00275 case '&': 00276 strcpy(*dst, "&"); 00277 (*dst) += 5; 00278 *maxlen -= 5; 00279 break; 00280 default: 00281 *(*dst)++ = lower ? tolower(*src) : *src; 00282 (*maxlen)--; 00283 } 00284 src++; 00285 } 00286 }
static char* xml_translate | ( | char * | in, | |
struct ast_variable * | vars | |||
) | [static] |
Definition at line 329 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().
00330 { 00331 struct ast_variable *v; 00332 char *dest = NULL; 00333 char *out, *tmp, *var, *val; 00334 char *objtype = NULL; 00335 int colons = 0; 00336 int breaks = 0; 00337 size_t len; 00338 int count = 1; 00339 int escaped = 0; 00340 int inobj = 0; 00341 int x; 00342 struct variable_count *vc = NULL; 00343 struct ao2_container *vco = NULL; 00344 00345 for (v = vars; v; v = v->next) { 00346 if (!dest && !strcasecmp(v->name, "ajaxdest")) 00347 dest = v->value; 00348 else if (!objtype && !strcasecmp(v->name, "ajaxobjtype")) 00349 objtype = v->value; 00350 } 00351 if (!dest) 00352 dest = "unknown"; 00353 if (!objtype) 00354 objtype = "generic"; 00355 for (x = 0; in[x]; x++) { 00356 if (in[x] == ':') 00357 colons++; 00358 else if (in[x] == '\n') 00359 breaks++; 00360 else if (strchr("&\"<>\'", in[x])) 00361 escaped++; 00362 } 00363 len = (size_t) (strlen(in) + colons * 5 + breaks * (40 + strlen(dest) + strlen(objtype)) + escaped * 10); /* foo="bar", "<response type=\"object\" id=\"dest\"", "&" */ 00364 out = ast_malloc(len); 00365 if (!out) 00366 return 0; 00367 tmp = out; 00368 while (*in) { 00369 var = in; 00370 while (*in && (*in >= 32)) 00371 in++; 00372 if (*in) { 00373 if ((count > 3) && inobj) { 00374 ast_build_string(&tmp, &len, " /></response>\n"); 00375 inobj = 0; 00376 00377 /* Entity is closed, so close out the name cache */ 00378 ao2_ref(vco, -1); 00379 vco = NULL; 00380 } 00381 count = 0; 00382 while (*in && (*in < 32)) { 00383 *in = '\0'; 00384 in++; 00385 count++; 00386 } 00387 val = strchr(var, ':'); 00388 if (val) { 00389 *val = '\0'; 00390 val++; 00391 if (*val == ' ') 00392 val++; 00393 if (!inobj) { 00394 vco = ao2_container_alloc(37, variable_count_hash_fn, variable_count_cmp_fn); 00395 ast_build_string(&tmp, &len, "<response type='object' id='%s'><%s", dest, objtype); 00396 inobj = 1; 00397 } 00398 00399 /* Check if the var has been used already */ 00400 if ((vc = ao2_find(vco, var, 0))) 00401 vc->count++; 00402 else { 00403 /* Create a new entry for this one */ 00404 vc = ao2_alloc(sizeof(*vc), NULL); 00405 vc->varname = var; 00406 vc->count = 1; 00407 ao2_link(vco, vc); 00408 } 00409 00410 ast_build_string(&tmp, &len, " "); 00411 xml_copy_escape(&tmp, &len, var, 1); 00412 if (vc->count > 1) 00413 ast_build_string(&tmp, &len, "-%d", vc->count); 00414 ast_build_string(&tmp, &len, "='"); 00415 xml_copy_escape(&tmp, &len, val, 0); 00416 ast_build_string(&tmp, &len, "'"); 00417 ao2_ref(vc, -1); 00418 } 00419 } 00420 } 00421 if (inobj) 00422 ast_build_string(&tmp, &len, " /></response>\n"); 00423 if (vco) 00424 ao2_ref(vco, -1); 00425 return out; 00426 }
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 105 of file manager.c.
Referenced by accept_thread(), init_manager(), process_message(), and session_do().
struct manager_action* first_action [static] |
Definition at line 207 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] |
char mandescr_command[] [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_message[] [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 114 of file manager.c.
Referenced by accept_thread(), append_event(), handle_showmaneventq(), and process_events().
int num_sessions [static] |
Definition at line 111 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 103 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 109 of file manager.c.
Referenced by __ast_register_translator(), __schedule_action(), acf_odbc_write(), add_sdp(), add_t38_sdp(), append_date(), ast_channel_bridge(), ast_check_timing(), ast_do_masquerade(), ast_get_time_t(), ast_httpd_helper_thread(), ast_log(), ast_pbx_start(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_de(), ast_translator_activate(), ast_translator_build_path(), ast_translator_deactivate(), ast_unregister_translator(), ast_verbose(), background_detect_exec(), build_mapping(), byteReverse(), calc_cost(), calc_txstamp(), callerid_genmsg(), callerid_getcarrier(), cdr_get_tv(), check_switch_expr(), check_user_full(), cli_prompt(), config_text_file_save(), destroy(), do_monitor(), does_peer_need_mwi(), dump_cmd_queues(), expr2_token_subst(), gen_match_to_pattern(), gen_tone(), gen_tones(), get_date(), get_trans_id(), handle_bchan(), handle_enbloc_call_message(), handle_hd_hf(), handle_offhook_message(), handle_save_dialplan(), handle_soft_key_event_message(), handle_stimulus_message(), iax2_datetime(), iax2_process_thread(), iax2_show_threads(), iax_template_parse(), launch_service(), listener(), local_new(), localsub(), lws2sws(), manager_log(), MD5Update(), misdn_read(), newpvt(), osp_create_provider(), osp_load(), packdate(), parse_moved_contact(), pgsql_log(), play_message_datetime(), prune_gateways(), rebuild_matrix(), register_verify(), rpt(), rpt_do_lstats(), rpt_exec(), rpt_tele_thread(), send_request(), SHA1ProcessMessageBlock(), sms_readfile(), socket_read(), sqlite_log(), strip_quotes(), tdd_getcarrier(), time2sub(), transmit_notify_request_with_callerid(), transmit_notify_with_mwi(), transmit_state_notify(), vmu_tm(), and write_metadata().
int timestampevents [static] |