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 |
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_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 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) |
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 |
static const char * | 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_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 |
static void* accept_thread | ( | void * | ignore | ) | [static] |
Definition at line 2304 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 init_manager(), and reload_config().
02305 { 02306 int as; 02307 struct sockaddr_in sin; 02308 socklen_t sinlen; 02309 struct eventqent *eqe; 02310 struct mansession *s; 02311 struct protoent *p; 02312 int arg = 1; 02313 int flags; 02314 pthread_attr_t attr; 02315 time_t now; 02316 struct pollfd pfds[1]; 02317 02318 pthread_attr_init(&attr); 02319 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02320 02321 for (;;) { 02322 time(&now); 02323 AST_LIST_LOCK(&sessions); 02324 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) { 02325 if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) { 02326 AST_LIST_REMOVE_CURRENT(&sessions, list); 02327 num_sessions--; 02328 if (s->authenticated && (option_verbose > 1) && displayconnects) { 02329 ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' timed out from %s\n", 02330 s->username, ast_inet_ntoa(s->sin.sin_addr)); 02331 } 02332 free_session(s); 02333 break; 02334 } 02335 } 02336 AST_LIST_TRAVERSE_SAFE_END 02337 /* Purge master event queue of old, unused events, but make sure we 02338 always keep at least one in the queue */ 02339 eqe = master_eventq; 02340 while (master_eventq->next && !master_eventq->usecount) { 02341 eqe = master_eventq; 02342 master_eventq = master_eventq->next; 02343 free(eqe); 02344 } 02345 AST_LIST_UNLOCK(&sessions); 02346 02347 sinlen = sizeof(sin); 02348 pfds[0].fd = asock; 02349 pfds[0].events = POLLIN; 02350 /* Wait for something to happen, but timeout every few seconds so 02351 we can ditch any old manager sessions */ 02352 if (poll(pfds, 1, 5000) < 1) 02353 continue; 02354 as = accept(asock, (struct sockaddr *)&sin, &sinlen); 02355 if (as < 0) { 02356 ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno)); 02357 continue; 02358 } 02359 p = getprotobyname("tcp"); 02360 if (p) { 02361 if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { 02362 ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno)); 02363 } 02364 } 02365 if (!(s = ast_calloc(1, sizeof(*s)))) 02366 continue; 02367 02368 memcpy(&s->sin, &sin, sizeof(sin)); 02369 s->writetimeout = 100; 02370 s->waiting_thread = AST_PTHREADT_NULL; 02371 02372 if (!block_sockets) { 02373 /* For safety, make sure socket is non-blocking */ 02374 flags = fcntl(as, F_GETFL); 02375 fcntl(as, F_SETFL, flags | O_NONBLOCK); 02376 } else { 02377 flags = fcntl(as, F_GETFL); 02378 fcntl(as, F_SETFL, flags & ~O_NONBLOCK); 02379 } 02380 ast_mutex_init(&s->__lock); 02381 s->fd = as; 02382 s->send_events = -1; 02383 AST_LIST_LOCK(&sessions); 02384 AST_LIST_INSERT_HEAD(&sessions, s, list); 02385 num_sessions++; 02386 /* Find the last place in the master event queue and hook ourselves 02387 in there */ 02388 s->eventq = master_eventq; 02389 while(s->eventq->next) 02390 s->eventq = s->eventq->next; 02391 ast_atomic_fetchadd_int(&s->eventq->usecount, 1); 02392 AST_LIST_UNLOCK(&sessions); 02393 if (ast_pthread_create_background(&s->t, &attr, session_do, s)) 02394 destroy_session(s); 02395 } 02396 pthread_attr_destroy(&attr); 02397 return NULL; 02398 }
static int action_command | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_command: Manager command "command" - execute CLI command
Definition at line 1690 of file manager.c.
References ast_calloc, ast_cli_command(), ast_free, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), command_blacklist, s, S_OR, and term_strip().
Referenced by init_manager().
01691 { 01692 const char *cmd = astman_get_header(m, "Command"); 01693 const char *id = astman_get_header(m, "ActionID"); 01694 char *buf, *final_buf; 01695 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 01696 int fd = mkstemp(template), i = 0; 01697 off_t l; 01698 01699 for (i = 0; i < sizeof(command_blacklist) / sizeof(command_blacklist[0]); i++) { 01700 if (!strncmp(cmd, command_blacklist[i], strlen(command_blacklist[i]))) { 01701 astman_send_error(s, m, "Command blacklisted"); 01702 return 0; 01703 } 01704 } 01705 01706 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 01707 if (!ast_strlen_zero(id)) 01708 astman_append(s, "ActionID: %s\r\n", id); 01709 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 01710 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 01711 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 01712 01713 /* This has a potential to overflow the stack. Hence, use the heap. */ 01714 buf = ast_calloc(1, l + 1); 01715 final_buf = ast_calloc(1, l + 1); 01716 if (buf) { 01717 lseek(fd, 0, SEEK_SET); 01718 read(fd, buf, l); 01719 buf[l] = '\0'; 01720 if (final_buf) { 01721 term_strip(final_buf, buf, l); 01722 final_buf[l] = '\0'; 01723 } 01724 astman_append(s, "%s", S_OR(final_buf, buf)); 01725 ast_free(buf); 01726 } 01727 close(fd); 01728 unlink(template); 01729 astman_append(s, "--END COMMAND--\r\n\r\n"); 01730 if (final_buf) 01731 ast_free(final_buf); 01732 return 0; 01733 }
static int action_events | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1381 of file manager.c.
References astman_get_header(), astman_send_response(), s, and set_eventmask().
Referenced by init_manager().
01382 { 01383 const char *mask = astman_get_header(m, "EventMask"); 01384 int res; 01385 01386 res = set_eventmask(s, mask); 01387 if (res > 0) 01388 astman_send_response(s, m, "Events On", NULL); 01389 else if (res == 0) 01390 astman_send_response(s, m, "Events Off", NULL); 01391 01392 return 0; 01393 }
static int action_extensionstate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1985 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().
01986 { 01987 const char *exten = astman_get_header(m, "Exten"); 01988 const char *context = astman_get_header(m, "Context"); 01989 const char *id = astman_get_header(m,"ActionID"); 01990 char idText[256] = ""; 01991 char hint[256] = ""; 01992 int status; 01993 if (ast_strlen_zero(exten)) { 01994 astman_send_error(s, m, "Extension not specified"); 01995 return 0; 01996 } 01997 if (ast_strlen_zero(context)) 01998 context = "default"; 01999 status = ast_extension_state(NULL, context, exten); 02000 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 02001 if (!ast_strlen_zero(id)) { 02002 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02003 } 02004 astman_append(s, "Response: Success\r\n" 02005 "%s" 02006 "Message: Extension Status\r\n" 02007 "Exten: %s\r\n" 02008 "Context: %s\r\n" 02009 "Hint: %s\r\n" 02010 "Status: %d\r\n\r\n", 02011 idText,exten, context, hint, status); 02012 return 0; 02013 }
static int action_getconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1110 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().
01111 { 01112 struct ast_config *cfg; 01113 const char *fn = astman_get_header(m, "Filename"); 01114 int catcount = 0; 01115 int lineno = 0; 01116 char *category=NULL; 01117 struct ast_variable *v; 01118 char idText[256] = ""; 01119 const char *id = astman_get_header(m, "ActionID"); 01120 01121 if (!ast_strlen_zero(id)) 01122 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01123 01124 if (ast_strlen_zero(fn)) { 01125 astman_send_error(s, m, "Filename not specified"); 01126 return 0; 01127 } 01128 if (!(cfg = ast_config_load_with_comments(fn))) { 01129 astman_send_error(s, m, "Config file not found"); 01130 return 0; 01131 } 01132 astman_append(s, "Response: Success\r\n%s", idText); 01133 while ((category = ast_category_browse(cfg, category))) { 01134 lineno = 0; 01135 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 01136 for (v = ast_variable_browse(cfg, category); v; v = v->next) 01137 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 01138 catcount++; 01139 } 01140 ast_config_destroy(cfg); 01141 astman_append(s, "\r\n"); 01142 01143 return 0; 01144 }
static int action_getvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1473 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().
01474 { 01475 struct ast_channel *c = NULL; 01476 const char *name = astman_get_header(m, "Channel"); 01477 const char *varname = astman_get_header(m, "Variable"); 01478 const char *id = astman_get_header(m,"ActionID"); 01479 char *varval; 01480 char workspace[1024] = ""; 01481 01482 if (ast_strlen_zero(varname)) { 01483 astman_send_error(s, m, "No variable specified"); 01484 return 0; 01485 } 01486 01487 if (!ast_strlen_zero(name)) { 01488 c = ast_get_channel_by_name_locked(name); 01489 if (!c) { 01490 astman_send_error(s, m, "No such channel"); 01491 return 0; 01492 } 01493 } 01494 01495 if (varname[strlen(varname) - 1] == ')') { 01496 char *copy = ast_strdupa(varname); 01497 01498 ast_func_read(c, copy, workspace, sizeof(workspace)); 01499 varval = workspace; 01500 } else { 01501 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 01502 } 01503 01504 if (c) 01505 ast_channel_unlock(c); 01506 astman_append(s, "Response: Success\r\n" 01507 "Variable: %s\r\nValue: %s\r\n", varname, varval); 01508 if (!ast_strlen_zero(id)) 01509 astman_append(s, "ActionID: %s\r\n",id); 01510 astman_append(s, "\r\n"); 01511 01512 return 0; 01513 }
static int action_hangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1410 of file manager.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, and s.
Referenced by init_manager().
01411 { 01412 struct ast_channel *c = NULL; 01413 const char *name = astman_get_header(m, "Channel"); 01414 if (ast_strlen_zero(name)) { 01415 astman_send_error(s, m, "No channel specified"); 01416 return 0; 01417 } 01418 c = ast_get_channel_by_name_locked(name); 01419 if (!c) { 01420 astman_send_error(s, m, "No such channel"); 01421 return 0; 01422 } 01423 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01424 ast_channel_unlock(c); 01425 astman_send_ack(s, m, "Channel Hungup"); 01426 return 0; 01427 }
static int action_listcommands | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1354 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().
01355 { 01356 struct manager_action *cur; 01357 char idText[256] = ""; 01358 char temp[BUFSIZ]; 01359 const char *id = astman_get_header(m,"ActionID"); 01360 01361 if (!ast_strlen_zero(id)) 01362 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01363 astman_append(s, "Response: Success\r\n%s", idText); 01364 for (cur = first_action; cur; cur = cur->next) { 01365 if ((s->writeperm & cur->authority) == cur->authority) 01366 astman_append(s, "%s: %s (Priv: %s)\r\n", cur->action, cur->synopsis, authority_to_str(cur->authority, temp, sizeof(temp))); 01367 } 01368 astman_append(s, "\r\n"); 01369 01370 return 0; 01371 }
static int action_logoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1399 of file manager.c.
References astman_send_response(), and s.
Referenced by init_manager().
01400 { 01401 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 01402 return -1; 01403 }
static int action_mailboxcount | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1949 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().
01950 { 01951 const char *mailbox = astman_get_header(m, "Mailbox"); 01952 const char *id = astman_get_header(m,"ActionID"); 01953 char idText[256] = ""; 01954 int newmsgs = 0, oldmsgs = 0; 01955 if (ast_strlen_zero(mailbox)) { 01956 astman_send_error(s, m, "Mailbox not specified"); 01957 return 0; 01958 } 01959 ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs); 01960 if (!ast_strlen_zero(id)) { 01961 snprintf(idText, sizeof(idText), "ActionID: %s\r\n",id); 01962 } 01963 astman_append(s, "Response: Success\r\n" 01964 "%s" 01965 "Message: Mailbox Message Count\r\n" 01966 "Mailbox: %s\r\n" 01967 "NewMessages: %d\r\n" 01968 "OldMessages: %d\r\n" 01969 "\r\n", 01970 idText,mailbox, newmsgs, oldmsgs); 01971 return 0; 01972 }
static int action_mailboxstatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1917 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().
01918 { 01919 const char *mailbox = astman_get_header(m, "Mailbox"); 01920 const char *id = astman_get_header(m,"ActionID"); 01921 char idText[256] = ""; 01922 int ret; 01923 if (ast_strlen_zero(mailbox)) { 01924 astman_send_error(s, m, "Mailbox not specified"); 01925 return 0; 01926 } 01927 if (!ast_strlen_zero(id)) 01928 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01929 ret = ast_app_has_voicemail(mailbox, NULL); 01930 astman_append(s, "Response: Success\r\n" 01931 "%s" 01932 "Message: Mailbox Status\r\n" 01933 "Mailbox: %s\r\n" 01934 "Waiting: %d\r\n\r\n", idText, mailbox, ret); 01935 return 0; 01936 }
static int action_originate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1799 of file manager.c.
References app, ast_callerid_parse(), ast_calloc, ast_findlabel_extension(), AST_FORMAT_SLINEAR, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pthread_create, ast_shrink_phone_number(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), context, ast_channel::data, exten, fast_originate(), name, ast_channel::priority, s, ast_channel::tech, and timeout.
Referenced by init_manager().
01800 { 01801 const char *name = astman_get_header(m, "Channel"); 01802 const char *exten = astman_get_header(m, "Exten"); 01803 const char *context = astman_get_header(m, "Context"); 01804 const char *priority = astman_get_header(m, "Priority"); 01805 const char *timeout = astman_get_header(m, "Timeout"); 01806 const char *callerid = astman_get_header(m, "CallerID"); 01807 const char *account = astman_get_header(m, "Account"); 01808 const char *app = astman_get_header(m, "Application"); 01809 const char *appdata = astman_get_header(m, "Data"); 01810 const char *async = astman_get_header(m, "Async"); 01811 const char *id = astman_get_header(m, "ActionID"); 01812 struct ast_variable *vars = astman_get_variables(m); 01813 char *tech, *data; 01814 char *l = NULL, *n = NULL; 01815 int pi = 0; 01816 int res; 01817 int to = 30000; 01818 int reason = 0; 01819 char tmp[256]; 01820 char tmp2[256]; 01821 01822 pthread_t th; 01823 pthread_attr_t attr; 01824 if (!name) { 01825 astman_send_error(s, m, "Channel not specified"); 01826 return 0; 01827 } 01828 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 01829 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 01830 astman_send_error(s, m, "Invalid priority\n"); 01831 return 0; 01832 } 01833 } 01834 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) { 01835 astman_send_error(s, m, "Invalid timeout\n"); 01836 return 0; 01837 } 01838 ast_copy_string(tmp, name, sizeof(tmp)); 01839 tech = tmp; 01840 data = strchr(tmp, '/'); 01841 if (!data) { 01842 astman_send_error(s, m, "Invalid channel\n"); 01843 return 0; 01844 } 01845 *data++ = '\0'; 01846 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 01847 ast_callerid_parse(tmp2, &n, &l); 01848 if (n) { 01849 if (ast_strlen_zero(n)) 01850 n = NULL; 01851 } 01852 if (l) { 01853 ast_shrink_phone_number(l); 01854 if (ast_strlen_zero(l)) 01855 l = NULL; 01856 } 01857 if (ast_true(async)) { 01858 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 01859 if (!fast) { 01860 res = -1; 01861 } else { 01862 if (!ast_strlen_zero(id)) 01863 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s\r\n", id); 01864 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 01865 ast_copy_string(fast->data, data, sizeof(fast->data)); 01866 ast_copy_string(fast->app, app, sizeof(fast->app)); 01867 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 01868 if (l) 01869 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 01870 if (n) 01871 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 01872 fast->vars = vars; 01873 ast_copy_string(fast->context, context, sizeof(fast->context)); 01874 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 01875 ast_copy_string(fast->account, account, sizeof(fast->account)); 01876 fast->timeout = to; 01877 fast->priority = pi; 01878 pthread_attr_init(&attr); 01879 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01880 if (ast_pthread_create(&th, &attr, fast_originate, fast)) { 01881 res = -1; 01882 } else { 01883 res = 0; 01884 } 01885 pthread_attr_destroy(&attr); 01886 } 01887 } else if (!ast_strlen_zero(app)) { 01888 res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 01889 } else { 01890 if (exten && context && pi) 01891 res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 01892 else { 01893 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 01894 return 0; 01895 } 01896 } 01897 if (!res) 01898 astman_send_ack(s, m, "Originate successfully queued"); 01899 else 01900 astman_send_error(s, m, "Originate failed"); 01901 return 0; 01902 }
static int action_ping | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1098 of file manager.c.
References astman_send_response(), and s.
Referenced by init_manager().
01099 { 01100 astman_send_response(s, m, "Pong", NULL); 01101 return 0; 01102 }
static int action_redirect | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_redirect: The redirect manager command
Definition at line 1619 of file manager.c.
References ast_async_goto(), ast_channel_unlock, ast_check_hangup(), ast_findlabel_extension(), ast_get_channel_by_name_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, exten, name, and s.
Referenced by init_manager().
01620 { 01621 const char *name = astman_get_header(m, "Channel"); 01622 const char *name2 = astman_get_header(m, "ExtraChannel"); 01623 const char *exten = astman_get_header(m, "Exten"); 01624 const char *context = astman_get_header(m, "Context"); 01625 const char *priority = astman_get_header(m, "Priority"); 01626 struct ast_channel *chan, *chan2 = NULL; 01627 int pi = 0; 01628 int res; 01629 01630 if (ast_strlen_zero(name)) { 01631 astman_send_error(s, m, "Channel not specified"); 01632 return 0; 01633 } 01634 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 01635 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 01636 astman_send_error(s, m, "Invalid priority\n"); 01637 return 0; 01638 } 01639 } 01640 /* XXX watch out, possible deadlock!!! */ 01641 chan = ast_get_channel_by_name_locked(name); 01642 if (!chan) { 01643 char buf[BUFSIZ]; 01644 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 01645 astman_send_error(s, m, buf); 01646 return 0; 01647 } 01648 if (ast_check_hangup(chan)) { 01649 astman_send_error(s, m, "Redirect failed, channel not up.\n"); 01650 ast_channel_unlock(chan); 01651 return 0; 01652 } 01653 if (!ast_strlen_zero(name2)) 01654 chan2 = ast_get_channel_by_name_locked(name2); 01655 if (chan2 && ast_check_hangup(chan2)) { 01656 astman_send_error(s, m, "Redirect failed, extra channel not up.\n"); 01657 ast_channel_unlock(chan); 01658 ast_channel_unlock(chan2); 01659 return 0; 01660 } 01661 res = ast_async_goto(chan, context, exten, pi); 01662 if (!res) { 01663 if (!ast_strlen_zero(name2)) { 01664 if (chan2) 01665 res = ast_async_goto(chan2, context, exten, pi); 01666 else 01667 res = -1; 01668 if (!res) 01669 astman_send_ack(s, m, "Dual Redirect successful"); 01670 else 01671 astman_send_error(s, m, "Secondary redirect failed"); 01672 } else 01673 astman_send_ack(s, m, "Redirect successful"); 01674 } else 01675 astman_send_error(s, m, "Redirect failed"); 01676 if (chan) 01677 ast_channel_unlock(chan); 01678 if (chan2) 01679 ast_channel_unlock(chan2); 01680 return 0; 01681 }
static int action_setvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1436 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().
01437 { 01438 struct ast_channel *c = NULL; 01439 const char *name = astman_get_header(m, "Channel"); 01440 const char *varname = astman_get_header(m, "Variable"); 01441 const char *varval = astman_get_header(m, "Value"); 01442 01443 if (ast_strlen_zero(varname)) { 01444 astman_send_error(s, m, "No variable specified"); 01445 return 0; 01446 } 01447 01448 if (!ast_strlen_zero(name)) { 01449 c = ast_get_channel_by_name_locked(name); 01450 if (!c) { 01451 astman_send_error(s, m, "No such channel"); 01452 return 0; 01453 } 01454 } 01455 01456 pbx_builtin_setvar_helper(c, varname, S_OR(varval, "")); 01457 01458 if (c) 01459 ast_channel_unlock(c); 01460 01461 astman_send_ack(s, m, "Variable Set"); 01462 01463 return 0; 01464 }
static int action_status | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager "status" command to show channels.
Definition at line 1518 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().
01519 { 01520 const char *id = astman_get_header(m,"ActionID"); 01521 const char *name = astman_get_header(m,"Channel"); 01522 char idText[256] = ""; 01523 struct ast_channel *c; 01524 char bridge[256]; 01525 struct timeval now = ast_tvnow(); 01526 long elapsed_seconds = 0; 01527 int all = ast_strlen_zero(name); /* set if we want all channels */ 01528 01529 if (!ast_strlen_zero(id)) 01530 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01531 if (all) 01532 c = ast_channel_walk_locked(NULL); 01533 else { 01534 c = ast_get_channel_by_name_locked(name); 01535 if (!c) { 01536 astman_send_error(s, m, "No such channel"); 01537 return 0; 01538 } 01539 } 01540 astman_send_ack(s, m, "Channel status will follow"); 01541 /* if we look by name, we break after the first iteration */ 01542 while (c) { 01543 if (c->_bridge) 01544 snprintf(bridge, sizeof(bridge), "Link: %s\r\n", c->_bridge->name); 01545 else 01546 bridge[0] = '\0'; 01547 if (c->pbx) { 01548 if (c->cdr) { 01549 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01550 } 01551 astman_append(s, 01552 "Event: Status\r\n" 01553 "Privilege: Call\r\n" 01554 "Channel: %s\r\n" 01555 "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */ 01556 "CallerIDNum: %s\r\n" 01557 "CallerIDName: %s\r\n" 01558 "Account: %s\r\n" 01559 "State: %s\r\n" 01560 "Context: %s\r\n" 01561 "Extension: %s\r\n" 01562 "Priority: %d\r\n" 01563 "Seconds: %ld\r\n" 01564 "%s" 01565 "Uniqueid: %s\r\n" 01566 "%s" 01567 "\r\n", 01568 c->name, 01569 S_OR(c->cid.cid_num, "<unknown>"), 01570 S_OR(c->cid.cid_num, "<unknown>"), 01571 S_OR(c->cid.cid_name, "<unknown>"), 01572 c->accountcode, 01573 ast_state2str(c->_state), c->context, 01574 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, idText); 01575 } else { 01576 astman_append(s, 01577 "Event: Status\r\n" 01578 "Privilege: Call\r\n" 01579 "Channel: %s\r\n" 01580 "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */ 01581 "CallerIDNum: %s\r\n" 01582 "CallerIDName: %s\r\n" 01583 "Account: %s\r\n" 01584 "State: %s\r\n" 01585 "%s" 01586 "Uniqueid: %s\r\n" 01587 "%s" 01588 "\r\n", 01589 c->name, 01590 S_OR(c->cid.cid_num, "<unknown>"), 01591 S_OR(c->cid.cid_num, "<unknown>"), 01592 S_OR(c->cid.cid_name, "<unknown>"), 01593 c->accountcode, 01594 ast_state2str(c->_state), bridge, c->uniqueid, idText); 01595 } 01596 ast_channel_unlock(c); 01597 if (!all) 01598 break; 01599 c = ast_channel_walk_locked(c); 01600 } 01601 astman_append(s, 01602 "Event: StatusComplete\r\n" 01603 "%s" 01604 "\r\n",idText); 01605 return 0; 01606 }
static int action_timeout | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2022 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, s, and timeout.
Referenced by init_manager().
02023 { 02024 struct ast_channel *c = NULL; 02025 const char *name = astman_get_header(m, "Channel"); 02026 int timeout = atoi(astman_get_header(m, "Timeout")); 02027 if (ast_strlen_zero(name)) { 02028 astman_send_error(s, m, "No channel specified"); 02029 return 0; 02030 } 02031 if (!timeout) { 02032 astman_send_error(s, m, "No timeout specified"); 02033 return 0; 02034 } 02035 c = ast_get_channel_by_name_locked(name); 02036 if (!c) { 02037 astman_send_error(s, m, "No such channel"); 02038 return 0; 02039 } 02040 ast_channel_setwhentohangup(c, timeout); 02041 ast_channel_unlock(c); 02042 astman_send_ack(s, m, "Timeout Set"); 02043 return 0; 02044 }
static int action_updateconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1221 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().
01222 { 01223 struct ast_config *cfg; 01224 const char *sfn = astman_get_header(m, "SrcFilename"); 01225 const char *dfn = astman_get_header(m, "DstFilename"); 01226 int res; 01227 char idText[256] = ""; 01228 const char *id = astman_get_header(m, "ActionID"); 01229 const char *rld = astman_get_header(m, "Reload"); 01230 01231 if (!ast_strlen_zero(id)) 01232 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01233 01234 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { 01235 astman_send_error(s, m, "Filename not specified"); 01236 return 0; 01237 } 01238 if (!(cfg = ast_config_load_with_comments(sfn))) { 01239 astman_send_error(s, m, "Config file not found"); 01240 return 0; 01241 } 01242 handle_updates(s, m, cfg); 01243 res = config_text_file_save(dfn, cfg, "Manager"); 01244 ast_config_destroy(cfg); 01245 if (res) { 01246 astman_send_error(s, m, "Save of config failed"); 01247 return 0; 01248 } 01249 astman_append(s, "Response: Success\r\n%s\r\n", idText); 01250 if (!ast_strlen_zero(rld)) { 01251 if (ast_true(rld)) 01252 rld = NULL; 01253 ast_module_reload(rld); 01254 } 01255 return 0; 01256 }
static int action_userevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2079 of file manager.c.
References astman_get_header(), event, EVENT_FLAG_USER, message::hdrcount, message::headers, and manager_event().
Referenced by init_manager().
02080 { 02081 const char *event = astman_get_header(m, "UserEvent"); 02082 char body[2048] = ""; 02083 int x, bodylen = 0; 02084 for (x = 0; x < m->hdrcount; x++) { 02085 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 02086 ast_copy_string(body + bodylen, m->headers[x], sizeof(body) - bodylen - 3); 02087 bodylen += strlen(m->headers[x]); 02088 ast_copy_string(body + bodylen, "\r\n", 3); 02089 bodylen += 2; 02090 } 02091 } 02092 02093 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body); 02094 return 0; 02095 }
static int action_waitevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1266 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, timeout, and unuse_eventqent().
Referenced by init_manager().
01267 { 01268 const char *timeouts = astman_get_header(m, "Timeout"); 01269 int timeout = -1, max; 01270 int x; 01271 int needexit = 0; 01272 time_t now; 01273 struct eventqent *eqe; 01274 const char *id = astman_get_header(m,"ActionID"); 01275 char idText[256] = ""; 01276 01277 if (!ast_strlen_zero(id)) 01278 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01279 01280 if (!ast_strlen_zero(timeouts)) { 01281 sscanf(timeouts, "%i", &timeout); 01282 } 01283 01284 ast_mutex_lock(&s->__lock); 01285 if (s->waiting_thread != AST_PTHREADT_NULL) { 01286 pthread_kill(s->waiting_thread, SIGURG); 01287 } 01288 if (s->sessiontimeout) { 01289 time(&now); 01290 max = s->sessiontimeout - now - 10; 01291 if (max < 0) 01292 max = 0; 01293 if ((timeout < 0) || (timeout > max)) 01294 timeout = max; 01295 if (!s->send_events) 01296 s->send_events = -1; 01297 /* Once waitevent is called, always queue events from now on */ 01298 } 01299 ast_mutex_unlock(&s->__lock); 01300 s->waiting_thread = pthread_self(); 01301 if (option_debug) 01302 ast_log(LOG_DEBUG, "Starting waiting for an event!\n"); 01303 for (x=0; ((x < timeout) || (timeout < 0)); x++) { 01304 ast_mutex_lock(&s->__lock); 01305 if (s->eventq && s->eventq->next) 01306 needexit = 1; 01307 if (s->waiting_thread != pthread_self()) 01308 needexit = 1; 01309 if (s->needdestroy) 01310 needexit = 1; 01311 ast_mutex_unlock(&s->__lock); 01312 if (needexit) 01313 break; 01314 if (s->fd > 0) { 01315 if (ast_wait_for_input(s->fd, 1000)) 01316 break; 01317 } else { 01318 sleep(1); 01319 } 01320 } 01321 if (option_debug) 01322 ast_log(LOG_DEBUG, "Finished waiting for an event!\n"); 01323 ast_mutex_lock(&s->__lock); 01324 if (s->waiting_thread == pthread_self()) { 01325 astman_send_response(s, m, "Success", "Waiting for Event..."); 01326 /* Only show events if we're the most recent waiter */ 01327 while(s->eventq->next) { 01328 eqe = s->eventq->next; 01329 if (((s->readperm & eqe->category) == eqe->category) && 01330 ((s->send_events & eqe->category) == eqe->category)) { 01331 astman_append(s, "%s", eqe->eventdata); 01332 } 01333 unuse_eventqent(s->eventq); 01334 s->eventq = eqe; 01335 } 01336 astman_append(s, 01337 "Event: WaitEventComplete\r\n" 01338 "%s" 01339 "\r\n", idText); 01340 s->waiting_thread = AST_PTHREADT_NULL; 01341 } else { 01342 ast_log(LOG_DEBUG, "Abandoning event request!\n"); 01343 } 01344 ast_mutex_unlock(&s->__lock); 01345 return 0; 01346 }
static int append_event | ( | const char * | str, | |
int | category | |||
) | [static] |
Definition at line 2400 of file manager.c.
References ast_malloc, master_eventq, eventqent::next, num_sessions, and eventqent::usecount.
Referenced by init_manager(), and manager_event().
02401 { 02402 struct eventqent *tmp, *prev = NULL; 02403 tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 02404 02405 if (!tmp) 02406 return -1; 02407 02408 tmp->next = NULL; 02409 tmp->category = category; 02410 strcpy(tmp->eventdata, str); 02411 02412 if (master_eventq) { 02413 prev = master_eventq; 02414 while (prev->next) 02415 prev = prev->next; 02416 prev->next = tmp; 02417 } else { 02418 master_eventq = tmp; 02419 } 02420 02421 tmp->usecount = num_sessions; 02422 02423 return 0; 02424 }
static struct ast_manager_user* ast_get_manager_by_name_locked | ( | const char * | name | ) | [static] |
Definition at line 467 of file manager.c.
References AST_LIST_TRAVERSE, ast_manager_user::username, and users.
Referenced by handle_showmanager(), and init_manager().
00468 { 00469 struct ast_manager_user *user = NULL; 00470 00471 AST_LIST_TRAVERSE(&users, user, list) 00472 if (!strcasecmp(user->username, name)) 00473 break; 00474 return user; 00475 }
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 854 of file manager.c.
References ast_variable::next.
Referenced by get_perm(), and strings_to_mask().
00855 { 00856 const char *val = bigstr, *next; 00857 00858 do { 00859 if ((next = strchr(val, delim))) { 00860 if (!strncmp(val, smallstr, (next - val))) 00861 return 1; 00862 else 00863 continue; 00864 } else 00865 return !strcmp(smallstr, val); 00866 00867 } while (*(val = (next + 1))); 00868 00869 return 0; 00870 }
static int ast_is_number | ( | const char * | string | ) | [static] |
Definition at line 887 of file manager.c.
Referenced by strings_to_mask().
00888 { 00889 int ret = 1, x = 0; 00890 00891 if (!string) 00892 return 0; 00893 00894 for (x = 0; x < strlen(string); x++) { 00895 if (!(string[x] >= 48 && string[x] <= 57)) { 00896 ret = 0; 00897 break; 00898 } 00899 } 00900 00901 return ret ? atoi(string) : 0; 00902 }
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 2546 of file manager.c.
References ast_malloc, and ast_manager_register_struct().
Referenced by init_manager(), and load_module().
02547 { 02548 struct manager_action *cur; 02549 02550 cur = ast_malloc(sizeof(*cur)); 02551 if (!cur) 02552 return -1; 02553 02554 cur->action = action; 02555 cur->authority = auth; 02556 cur->func = func; 02557 cur->synopsis = synopsis; 02558 cur->description = description; 02559 cur->next = NULL; 02560 02561 ast_manager_register_struct(cur); 02562 02563 return 0; 02564 }
static int ast_manager_register_struct | ( | struct manager_action * | act | ) | [static] |
Definition at line 2502 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().
02503 { 02504 struct manager_action *cur, *prev = NULL; 02505 int ret; 02506 02507 ast_rwlock_wrlock(&actionlock); 02508 cur = first_action; 02509 while (cur) { /* Walk the list of actions */ 02510 ret = strcasecmp(cur->action, act->action); 02511 if (ret == 0) { 02512 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 02513 ast_rwlock_unlock(&actionlock); 02514 return -1; 02515 } else if (ret > 0) { 02516 /* Insert these alphabetically */ 02517 if (prev) { 02518 act->next = prev->next; 02519 prev->next = act; 02520 } else { 02521 act->next = first_action; 02522 first_action = act; 02523 } 02524 break; 02525 } 02526 prev = cur; 02527 cur = cur->next; 02528 } 02529 02530 if (!cur) { 02531 if (prev) 02532 prev->next = act; 02533 else 02534 first_action = act; 02535 act->next = NULL; 02536 } 02537 02538 if (option_verbose > 1) 02539 ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", act->action); 02540 ast_rwlock_unlock(&actionlock); 02541 return 0; 02542 }
int ast_manager_unregister | ( | char * | action | ) |
action | Name of registred Action: |
Definition at line 2473 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().
02474 { 02475 struct manager_action *cur, *prev; 02476 02477 ast_rwlock_wrlock(&actionlock); 02478 cur = prev = first_action; 02479 while (cur) { 02480 if (!strcasecmp(action, cur->action)) { 02481 prev->next = cur->next; 02482 free(cur); 02483 if (option_verbose > 1) 02484 ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action); 02485 ast_rwlock_unlock(&actionlock); 02486 return 0; 02487 } 02488 prev = cur; 02489 cur = cur->next; 02490 } 02491 ast_rwlock_unlock(&actionlock); 02492 return 0; 02493 }
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 477 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_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().
00478 { 00479 va_list ap; 00480 struct ast_dynamic_str *buf; 00481 00482 ast_mutex_lock(&s->__lock); 00483 00484 if (!(buf = ast_dynamic_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) { 00485 ast_mutex_unlock(&s->__lock); 00486 return; 00487 } 00488 00489 va_start(ap, fmt); 00490 ast_dynamic_str_thread_set_va(&buf, 0, &astman_append_buf, fmt, ap); 00491 va_end(ap); 00492 00493 if (s->fd > -1) 00494 ast_carefulwrite(s->fd, buf->str, strlen(buf->str), s->writetimeout); 00495 else { 00496 if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) { 00497 ast_mutex_unlock(&s->__lock); 00498 return; 00499 } 00500 00501 ast_dynamic_str_append(&s->outputstr, 0, "%s", buf->str); 00502 } 00503 00504 ast_mutex_unlock(&s->__lock); 00505 }
const char* astman_get_header | ( | const struct message * | m, | |
char * | var | |||
) |
Get header from mananger transaction
Definition at line 757 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_originate(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_userevent(), action_waitevent(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zapshowchannels(), astman_send_error(), astman_send_response(), authenticate(), change_monitor_action(), do_pause_or_unpause(), handle_updates(), manager_add_queue_member(), manager_dbget(), manager_dbput(), manager_iax2_show_peers(), manager_jabber_send(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queues_status(), manager_remove_queue_member(), manager_sip_show_peer(), manager_sip_show_peers(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
00758 { 00759 char cmp[80]; 00760 int x; 00761 00762 snprintf(cmp, sizeof(cmp), "%s: ", var); 00763 00764 for (x = 0; x < m->hdrcount; x++) { 00765 if (!strncasecmp(cmp, m->headers[x], strlen(cmp))) 00766 return m->headers[x] + strlen(cmp); 00767 } 00768 00769 return ""; 00770 }
struct ast_variable* astman_get_variables | ( | const struct message * | m | ) |
Get a linked list of the Variable: headers
Definition at line 772 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().
00773 { 00774 int varlen, x, y; 00775 struct ast_variable *head = NULL, *cur; 00776 char *var, *val; 00777 00778 char *parse; 00779 AST_DECLARE_APP_ARGS(args, 00780 AST_APP_ARG(vars)[32]; 00781 ); 00782 00783 varlen = strlen("Variable: "); 00784 00785 for (x = 0; x < m->hdrcount; x++) { 00786 if (strncasecmp("Variable: ", m->headers[x], varlen)) 00787 continue; 00788 00789 parse = ast_strdupa(m->headers[x] + varlen); 00790 00791 AST_STANDARD_APP_ARGS(args, parse); 00792 if (args.argc) { 00793 for (y = 0; y < args.argc; y++) { 00794 if (!args.vars[y]) 00795 continue; 00796 var = val = ast_strdupa(args.vars[y]); 00797 strsep(&val, "="); 00798 if (!val || ast_strlen_zero(var)) 00799 continue; 00800 cur = ast_variable_new(var, val); 00801 if (head) { 00802 cur->next = head; 00803 head = cur; 00804 } else 00805 head = cur; 00806 } 00807 } 00808 } 00809 00810 return head; 00811 }
void astman_send_ack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg | |||
) |
Definition at line 844 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_originate(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), action_zapshowchannels(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_park(), manager_parking_status(), manager_pause_queue_member(), manager_play_dtmf(), manager_queues_status(), manager_remove_queue_member(), manager_sip_show_peers(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
00845 { 00846 astman_send_response(s, m, "Success", msg); 00847 }
void astman_send_error | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | error | |||
) |
Definition at line 821 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_originate(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_park(), manager_pause_queue_member(), manager_play_dtmf(), manager_remove_queue_member(), manager_sip_show_peer(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
00822 { 00823 const char *id = astman_get_header(m,"ActionID"); 00824 00825 astman_append(s, "Response: Error\r\n"); 00826 if (!ast_strlen_zero(id)) 00827 astman_append(s, "ActionID: %s\r\n", id); 00828 astman_append(s, "Message: %s\r\n\r\n", error); 00829 }
void astman_send_response | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg | |||
) |
Definition at line 831 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().
00832 { 00833 const char *id = astman_get_header(m,"ActionID"); 00834 00835 astman_append(s, "Response: %s\r\n", resp); 00836 if (!ast_strlen_zero(id)) 00837 astman_append(s, "ActionID: %s\r\n", id); 00838 if (msg) 00839 astman_append(s, "Message: %s\r\n\r\n", msg); 00840 else 00841 astman_append(s, "\r\n"); 00842 }
static int authenticate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 947 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, key(), 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().
00948 { 00949 struct ast_config *cfg; 00950 char *cat; 00951 const char *user = astman_get_header(m, "Username"); 00952 const char *pass = astman_get_header(m, "Secret"); 00953 const char *authtype = astman_get_header(m, "AuthType"); 00954 const char *key = astman_get_header(m, "Key"); 00955 const char *events = astman_get_header(m, "Events"); 00956 00957 cfg = ast_config_load("manager.conf"); 00958 if (!cfg) 00959 return -1; 00960 cat = ast_category_browse(cfg, NULL); 00961 while (cat) { 00962 if (strcasecmp(cat, "general")) { 00963 /* This is a user */ 00964 if (!strcasecmp(cat, user)) { 00965 struct ast_variable *v; 00966 struct ast_ha *ha = NULL; 00967 char *password = NULL; 00968 00969 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 00970 if (!strcasecmp(v->name, "secret")) { 00971 password = v->value; 00972 } else if (!strcasecmp(v->name, "displaysystemname")) { 00973 if (ast_true(v->value)) { 00974 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) { 00975 s->displaysystemname = 1; 00976 } else { 00977 ast_log(LOG_ERROR, "Can't enable displaysystemname in manager.conf - no system name configured in asterisk.conf\n"); 00978 } 00979 } 00980 } else if (!strcasecmp(v->name, "permit") || 00981 !strcasecmp(v->name, "deny")) { 00982 ha = ast_append_ha(v->name, v->value, ha); 00983 } else if (!strcasecmp(v->name, "writetimeout")) { 00984 int val = atoi(v->value); 00985 00986 if (val < 100) 00987 ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", v->value, v->lineno); 00988 else 00989 s->writetimeout = val; 00990 } 00991 00992 } 00993 if (ha && !ast_apply_ha(ha, &(s->sin))) { 00994 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 00995 ast_free_ha(ha); 00996 ast_config_destroy(cfg); 00997 return -1; 00998 } else if (ha) 00999 ast_free_ha(ha); 01000 if (!strcasecmp(authtype, "MD5")) { 01001 if (!ast_strlen_zero(key) && 01002 !ast_strlen_zero(s->challenge) && !ast_strlen_zero(password)) { 01003 int x; 01004 int len = 0; 01005 char md5key[256] = ""; 01006 struct MD5Context md5; 01007 unsigned char digest[16]; 01008 MD5Init(&md5); 01009 MD5Update(&md5, (unsigned char *) s->challenge, strlen(s->challenge)); 01010 MD5Update(&md5, (unsigned char *) password, strlen(password)); 01011 MD5Final(digest, &md5); 01012 for (x=0; x<16; x++) 01013 len += sprintf(md5key + len, "%2.2x", digest[x]); 01014 if (!strcmp(md5key, key)) 01015 break; 01016 else { 01017 ast_config_destroy(cfg); 01018 return -1; 01019 } 01020 } else { 01021 ast_log(LOG_DEBUG, "MD5 authentication is not possible. challenge: '%s'\n", 01022 S_OR(s->challenge, "")); 01023 ast_config_destroy(cfg); 01024 return -1; 01025 } 01026 } else if (password && !strcmp(password, pass)) { 01027 break; 01028 } else { 01029 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01030 ast_config_destroy(cfg); 01031 return -1; 01032 } 01033 } 01034 } 01035 cat = ast_category_browse(cfg, cat); 01036 } 01037 if (cat) { 01038 ast_copy_string(s->username, cat, sizeof(s->username)); 01039 s->readperm = get_perm(ast_variable_retrieve(cfg, cat, "read")); 01040 s->writeperm = get_perm(ast_variable_retrieve(cfg, cat, "write")); 01041 ast_config_destroy(cfg); 01042 if (events) 01043 set_eventmask(s, events); 01044 return 0; 01045 } 01046 ast_config_destroy(cfg); 01047 cfg = ast_config_load("users.conf"); 01048 if (!cfg) 01049 return -1; 01050 cat = ast_category_browse(cfg, NULL); 01051 while (cat) { 01052 struct ast_variable *v; 01053 const char *password = NULL; 01054 int hasmanager = 0; 01055 const char *readperms = NULL; 01056 const char *writeperms = NULL; 01057 01058 if (strcasecmp(cat, user) || !strcasecmp(cat, "general")) { 01059 cat = ast_category_browse(cfg, cat); 01060 continue; 01061 } 01062 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 01063 if (!strcasecmp(v->name, "secret")) 01064 password = v->value; 01065 else if (!strcasecmp(v->name, "hasmanager")) 01066 hasmanager = ast_true(v->value); 01067 else if (!strcasecmp(v->name, "managerread")) 01068 readperms = v->value; 01069 else if (!strcasecmp(v->name, "managerwrite")) 01070 writeperms = v->value; 01071 } 01072 if (!hasmanager) 01073 break; 01074 if (!password || strcmp(password, pass)) { 01075 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01076 ast_config_destroy(cfg); 01077 return -1; 01078 } 01079 ast_copy_string(s->username, cat, sizeof(s->username)); 01080 s->readperm = readperms ? get_perm(readperms) : -1; 01081 s->writeperm = writeperms ? get_perm(writeperms) : -1; 01082 ast_config_destroy(cfg); 01083 if (events) 01084 set_eventmask(s, events); 01085 return 0; 01086 } 01087 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01088 ast_config_destroy(cfg); 01089 return -1; 01090 }
static char* authority_to_str | ( | int | authority, | |
char * | res, | |||
int | reslen | |||
) | [static] |
Convert authority code to string with serveral options.
Definition at line 201 of file manager.c.
References ast_strlen_zero(), and perms.
Referenced by action_listcommands(), handle_showmancmd(), handle_showmancmds(), and manager_event().
00202 { 00203 int running_total = 0, i; 00204 00205 memset(res, 0, reslen); 00206 for (i = 0; i < (sizeof(perms) / sizeof(perms[0])) - 1; i++) { 00207 if (authority & perms[i].num) { 00208 if (*res) { 00209 strncat(res, ",", (reslen > running_total) ? reslen - running_total - 1 : 0); 00210 running_total++; 00211 } 00212 strncat(res, perms[i].label, (reslen > running_total) ? reslen - running_total - 1 : 0); 00213 running_total += strlen(perms[i].label); 00214 } 00215 } 00216 00217 if (ast_strlen_zero(res)) 00218 ast_copy_string(res, "<none>", reslen); 00219 00220 return res; 00221 }
static char* complete_show_mancmd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 223 of file manager.c.
References manager_action::action, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_strdup, first_action, and manager_action::next.
00224 { 00225 struct manager_action *cur; 00226 int which = 0; 00227 char *ret = NULL; 00228 00229 ast_rwlock_rdlock(&actionlock); 00230 for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */ 00231 if (!strncasecmp(word, cur->action, strlen(word)) && ++which > state) { 00232 ret = ast_strdup(cur->action); 00233 break; /* make sure we exit even if ast_strdup() returns NULL */ 00234 } 00235 } 00236 ast_rwlock_unlock(&actionlock); 00237 00238 return ret; 00239 }
static int compress_char | ( | char | c | ) | [static] |
Definition at line 283 of file manager.c.
Referenced by member_hash_fn(), and variable_count_hash_fn().
00284 { 00285 c &= 0x7f; 00286 if (c < 32) 00287 return 0; 00288 else if (c >= 'a' && c <= 'z') 00289 return c - 64; 00290 else if (c > 'z') 00291 return '_'; 00292 else 00293 return c - 32; 00294 }
static void destroy_session | ( | struct mansession * | s | ) | [static] |
Definition at line 748 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().
00749 { 00750 AST_LIST_LOCK(&sessions); 00751 AST_LIST_REMOVE(&sessions, s, list); 00752 num_sessions--; 00753 free_session(s); 00754 AST_LIST_UNLOCK(&sessions); 00755 }
static int do_message | ( | struct mansession * | s | ) | [static] |
Definition at line 2233 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().
02234 { 02235 struct message m = { 0 }; 02236 char header_buf[sizeof(s->inbuf)] = { '\0' }; 02237 int res; 02238 02239 for (;;) { 02240 /* Check if any events are pending and do them if needed */ 02241 if (s->eventq->next) { 02242 if (process_events(s)) 02243 return -1; 02244 } 02245 res = get_input(s, header_buf); 02246 if (res == 0) { 02247 continue; 02248 } else if (res > 0) { 02249 /* Strip trailing \r\n */ 02250 if (strlen(header_buf) < 2) 02251 continue; 02252 header_buf[strlen(header_buf) - 2] = '\0'; 02253 if (ast_strlen_zero(header_buf)) 02254 return process_message(s, &m) ? -1 : 0; 02255 else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) 02256 m.headers[m.hdrcount++] = ast_strdupa(header_buf); 02257 } else { 02258 return res; 02259 } 02260 } 02261 }
static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 1735 of file manager.c.
References fast_originate_helper::account, fast_originate_helper::app, fast_originate_helper::appdata, AST_CHANNEL_NAME, ast_channel_unlock, AST_FORMAT_SLINEAR, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_strlen_zero(), fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, fast_originate_helper::data, EVENT_FLAG_CALL, fast_originate_helper::exten, free, fast_originate_helper::idtext, manager_event(), fast_originate_helper::priority, S_OR, fast_originate_helper::tech, fast_originate_helper::timeout, and fast_originate_helper::vars.
Referenced by action_originate().
01736 { 01737 struct fast_originate_helper *in = data; 01738 int res; 01739 int reason = 0; 01740 struct ast_channel *chan = NULL; 01741 char requested_channel[AST_CHANNEL_NAME]; 01742 01743 if (!ast_strlen_zero(in->app)) { 01744 res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, 01745 S_OR(in->cid_num, NULL), 01746 S_OR(in->cid_name, NULL), 01747 in->vars, in->account, &chan); 01748 } else { 01749 res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 01750 S_OR(in->cid_num, NULL), 01751 S_OR(in->cid_name, NULL), 01752 in->vars, in->account, &chan); 01753 } 01754 01755 if (!chan) 01756 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 01757 /* Tell the manager what happened with the channel */ 01758 manager_event(EVENT_FLAG_CALL, "OriginateResponse", 01759 "%s" 01760 "Response: %s\r\n" 01761 "Channel: %s\r\n" 01762 "Context: %s\r\n" 01763 "Exten: %s\r\n" 01764 "Reason: %d\r\n" 01765 "Uniqueid: %s\r\n" 01766 "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */ 01767 "CallerIDNum: %s\r\n" 01768 "CallerIDName: %s\r\n", 01769 in->idtext, res ? "Failure" : "Success", chan ? chan->name : requested_channel, in->context, in->exten, reason, 01770 chan ? chan->uniqueid : "<null>", 01771 S_OR(in->cid_num, "<unknown>"), 01772 S_OR(in->cid_num, "<unknown>"), 01773 S_OR(in->cid_name, "<unknown>") 01774 ); 01775 01776 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 01777 if (chan) 01778 ast_channel_unlock(chan); 01779 free(in); 01780 return NULL; 01781 }
static void free_session | ( | struct mansession * | s | ) | [static] |
Definition at line 732 of file manager.c.
References ast_mutex_destroy(), free, s, and unuse_eventqent().
Referenced by accept_thread(), and destroy_session().
00733 { 00734 struct eventqent *eqe; 00735 if (s->fd > -1) 00736 close(s->fd); 00737 if (s->outputstr) 00738 free(s->outputstr); 00739 ast_mutex_destroy(&s->__lock); 00740 while (s->eventq) { 00741 eqe = s->eventq; 00742 s->eventq = s->eventq->next; 00743 unuse_eventqent(eqe); 00744 } 00745 free(s); 00746 }
static int get_input | ( | struct mansession * | s, | |
char * | output | |||
) | [static] |
Definition at line 2179 of file manager.c.
References ast_channel::fds, and s.
Referenced by do_message(), and skinny_session().
02180 { 02181 /* output must have at least sizeof(s->inbuf) space */ 02182 int res; 02183 int x; 02184 struct pollfd fds[1]; 02185 for (x = 1; x < s->inlen; x++) { 02186 if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) { 02187 /* Copy output data up to and including \r\n */ 02188 memcpy(output, s->inbuf, x + 1); 02189 /* Add trailing \0 */ 02190 output[x+1] = '\0'; 02191 /* Move remaining data back to the front */ 02192 memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x); 02193 s->inlen -= (x + 1); 02194 return 1; 02195 } 02196 } 02197 if (s->inlen >= sizeof(s->inbuf) - 1) { 02198 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->sin.sin_addr), s->inbuf); 02199 s->inlen = 0; 02200 } 02201 fds[0].fd = s->fd; 02202 fds[0].events = POLLIN; 02203 do { 02204 ast_mutex_lock(&s->__lock); 02205 s->waiting_thread = pthread_self(); 02206 ast_mutex_unlock(&s->__lock); 02207 02208 res = poll(fds, 1, -1); 02209 02210 ast_mutex_lock(&s->__lock); 02211 s->waiting_thread = AST_PTHREADT_NULL; 02212 ast_mutex_unlock(&s->__lock); 02213 if (res < 0) { 02214 if (errno == EINTR) { 02215 return 0; 02216 } 02217 ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno)); 02218 return -1; 02219 } else if (res > 0) { 02220 ast_mutex_lock(&s->__lock); 02221 res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen); 02222 ast_mutex_unlock(&s->__lock); 02223 if (res < 1) 02224 return -1; 02225 break; 02226 } 02227 } while(1); 02228 s->inlen += res; 02229 s->inbuf[s->inlen] = '\0'; 02230 return 0; 02231 }
static int get_perm | ( | const char * | instr | ) | [static] |
Definition at line 872 of file manager.c.
References ast_instring(), and perms.
00873 { 00874 int x = 0, ret = 0; 00875 00876 if (!instr) 00877 return 0; 00878 00879 for (x = 0; x < (sizeof(perms) / sizeof(perms[0])); x++) { 00880 if (ast_instring(instr, perms[x].label, ',')) 00881 ret |= perms[x].num; 00882 } 00883 00884 return ret; 00885 }
static int handle_showmanager | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 529 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.
00530 { 00531 struct ast_manager_user *user = NULL; 00532 00533 if (argc != 4) 00534 return RESULT_SHOWUSAGE; 00535 00536 AST_LIST_LOCK(&users); 00537 00538 if (!(user = ast_get_manager_by_name_locked(argv[3]))) { 00539 ast_cli(fd, "There is no manager called %s\n", argv[3]); 00540 AST_LIST_UNLOCK(&users); 00541 return -1; 00542 } 00543 00544 ast_cli(fd,"\n"); 00545 ast_cli(fd, 00546 " username: %s\n" 00547 " secret: %s\n" 00548 " deny: %s\n" 00549 " permit: %s\n" 00550 " read: %s\n" 00551 " write: %s\n" 00552 "displayconnects: %s\n", 00553 (user->username ? user->username : "(N/A)"), 00554 (user->secret ? "<Set>" : "(N/A)"), 00555 (user->deny ? user->deny : "(N/A)"), 00556 (user->permit ? user->permit : "(N/A)"), 00557 (user->read ? user->read : "(N/A)"), 00558 (user->write ? user->write : "(N/A)"), 00559 (user->displayconnects ? "yes" : "no")); 00560 00561 AST_LIST_UNLOCK(&users); 00562 00563 return RESULT_SUCCESS; 00564 }
static int handle_showmanagers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 567 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.
00568 { 00569 struct ast_manager_user *user = NULL; 00570 int count_amu = 0; 00571 00572 if (argc != 3) 00573 return RESULT_SHOWUSAGE; 00574 00575 AST_LIST_LOCK(&users); 00576 00577 /* If there are no users, print out something along those lines */ 00578 if (AST_LIST_EMPTY(&users)) { 00579 ast_cli(fd, "There are no manager users.\n"); 00580 AST_LIST_UNLOCK(&users); 00581 return RESULT_SUCCESS; 00582 } 00583 00584 ast_cli(fd, "\nusername\n--------\n"); 00585 00586 AST_LIST_TRAVERSE(&users, user, list) { 00587 ast_cli(fd, "%s\n", user->username); 00588 count_amu++; 00589 } 00590 00591 AST_LIST_UNLOCK(&users); 00592 00593 ast_cli(fd,"-------------------\n"); 00594 ast_cli(fd,"%d manager users configured.\n", count_amu); 00595 00596 return RESULT_SUCCESS; 00597 }
static int handle_showmancmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 507 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.
00508 { 00509 struct manager_action *cur; 00510 char authority[80]; 00511 int num; 00512 00513 if (argc != 4) 00514 return RESULT_SHOWUSAGE; 00515 00516 ast_rwlock_rdlock(&actionlock); 00517 for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */ 00518 for (num = 3; num < argc; num++) { 00519 if (!strcasecmp(cur->action, argv[num])) { 00520 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 : ""); 00521 } 00522 } 00523 } 00524 ast_rwlock_unlock(&actionlock); 00525 00526 return RESULT_SUCCESS; 00527 }
static int handle_showmancmds | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command Should change to "manager show commands".
Definition at line 602 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.
00603 { 00604 struct manager_action *cur; 00605 char authority[80]; 00606 char *format = " %-15.15s %-15.15s %-55.55s\n"; 00607 00608 ast_cli(fd, format, "Action", "Privilege", "Synopsis"); 00609 ast_cli(fd, format, "------", "---------", "--------"); 00610 00611 ast_rwlock_rdlock(&actionlock); 00612 for (cur = first_action; cur; cur = cur->next) /* Walk the list of actions */ 00613 ast_cli(fd, format, cur->action, authority_to_str(cur->authority, authority, sizeof(authority) -1), cur->synopsis); 00614 ast_rwlock_unlock(&actionlock); 00615 00616 return RESULT_SUCCESS; 00617 }
static int handle_showmanconn | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command show manager connected.
Definition at line 621 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.
00622 { 00623 struct mansession *s; 00624 char *format = " %-15.15s %-15.15s\n"; 00625 00626 ast_cli(fd, format, "Username", "IP Address"); 00627 00628 AST_LIST_LOCK(&sessions); 00629 AST_LIST_TRAVERSE(&sessions, s, list) 00630 ast_cli(fd, format,s->username, ast_inet_ntoa(s->sin.sin_addr)); 00631 AST_LIST_UNLOCK(&sessions); 00632 00633 return RESULT_SUCCESS; 00634 }
static int handle_showmaneventq | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command show manager connected.
Definition at line 638 of file manager.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_UNLOCK, master_eventq, RESULT_SUCCESS, s, and sessions.
00639 { 00640 struct eventqent *s; 00641 00642 AST_LIST_LOCK(&sessions); 00643 for (s = master_eventq; s; s = s->next) { 00644 ast_cli(fd, "Usecount: %d\n",s->usecount); 00645 ast_cli(fd, "Category: %d\n", s->category); 00646 ast_cli(fd, "Event:\n%s", s->eventdata); 00647 } 00648 AST_LIST_UNLOCK(&sessions); 00649 00650 return RESULT_SUCCESS; 00651 }
static void handle_updates | ( | struct mansession * | s, | |
const struct message * | m, | |||
struct ast_config * | cfg | |||
) | [static] |
Definition at line 1147 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().
01148 { 01149 int x; 01150 char hdr[40]; 01151 const char *action, *cat, *var, *value, *match; 01152 struct ast_category *category; 01153 struct ast_variable *v; 01154 01155 for (x=0;x<100000;x++) { 01156 unsigned int object = 0; 01157 01158 snprintf(hdr, sizeof(hdr), "Action-%06d", x); 01159 action = astman_get_header(m, hdr); 01160 if (ast_strlen_zero(action)) 01161 break; 01162 snprintf(hdr, sizeof(hdr), "Cat-%06d", x); 01163 cat = astman_get_header(m, hdr); 01164 snprintf(hdr, sizeof(hdr), "Var-%06d", x); 01165 var = astman_get_header(m, hdr); 01166 snprintf(hdr, sizeof(hdr), "Value-%06d", x); 01167 value = astman_get_header(m, hdr); 01168 if (!ast_strlen_zero(value) && *value == '>') { 01169 object = 1; 01170 value++; 01171 } 01172 snprintf(hdr, sizeof(hdr), "Match-%06d", x); 01173 match = astman_get_header(m, hdr); 01174 if (!strcasecmp(action, "newcat")) { 01175 if (!ast_strlen_zero(cat)) { 01176 category = ast_category_new(cat); 01177 if (category) { 01178 ast_category_append(cfg, category); 01179 } 01180 } 01181 } else if (!strcasecmp(action, "renamecat")) { 01182 if (!ast_strlen_zero(cat) && !ast_strlen_zero(value)) { 01183 category = ast_category_get(cfg, cat); 01184 if (category) 01185 ast_category_rename(category, value); 01186 } 01187 } else if (!strcasecmp(action, "delcat")) { 01188 if (!ast_strlen_zero(cat)) 01189 ast_category_delete(cfg, (char *) cat); 01190 } else if (!strcasecmp(action, "update")) { 01191 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat))) 01192 ast_variable_update(category, var, value, match, object); 01193 } else if (!strcasecmp(action, "delete")) { 01194 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat))) 01195 ast_variable_delete(category, (char *) var, (char *) match); 01196 } else if (!strcasecmp(action, "append")) { 01197 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && 01198 (category = ast_category_get(cfg, cat)) && 01199 (v = ast_variable_new(var, value))){ 01200 if (object || (match && !strcasecmp(match, "object"))) 01201 v->object = 1; 01202 ast_variable_append(category, v); 01203 } 01204 } 01205 } 01206 }
static char* html_translate | ( | char * | in | ) | [static] |
Definition at line 418 of file manager.c.
References ast_build_string(), ast_malloc, len, and var.
00419 { 00420 int x; 00421 int colons = 0; 00422 int breaks = 0; 00423 size_t len; 00424 int count = 1; 00425 char *tmp, *var, *val, *out; 00426 00427 for (x=0; in[x]; x++) { 00428 if (in[x] == ':') 00429 colons++; 00430 if (in[x] == '\n') 00431 breaks++; 00432 } 00433 len = strlen(in) + colons * 40 + breaks * 40; /* <tr><td></td><td></td></tr>, "<tr><td colspan=\"2\"><hr></td></tr> */ 00434 out = ast_malloc(len); 00435 if (!out) 00436 return 0; 00437 tmp = out; 00438 while (*in) { 00439 var = in; 00440 while (*in && (*in >= 32)) 00441 in++; 00442 if (*in) { 00443 if ((count % 4) == 0){ 00444 ast_build_string(&tmp, &len, "<tr><td colspan=\"2\"><hr></td></tr>\r\n"); 00445 } 00446 count = 0; 00447 while (*in && (*in < 32)) { 00448 *in = '\0'; 00449 in++; 00450 count++; 00451 } 00452 val = strchr(var, ':'); 00453 if (val) { 00454 *val = '\0'; 00455 val++; 00456 if (*val == ' ') 00457 val++; 00458 ast_build_string(&tmp, &len, "<tr><td>%s</td><td>%s</td></tr>\r\n", var, val); 00459 } 00460 } 00461 } 00462 return out; 00463 }
int manager_event | ( | int | category, | |
const char * | event, | |||
const char * | fmt, | |||
... | ||||
) |
manager_event: Send AMI event to client
Definition at line 2427 of file manager.c.
References append_event(), ast_dynamic_str_thread_append(), ast_dynamic_str_thread_append_va, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, authority_to_str(), MANAGER_EVENT_BUF_INITSIZE, num_sessions, s, sessions, and timestampevents.
Referenced by __expire_registry(), __iax2_poke_noanswer(), __login_exec(), action_agent_callback_login(), action_userevent(), add_to_queue(), agent_logoff_maintenance(), aji_log_hook(), ast_change_name(), ast_channel_bridge(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_set_callerid(), ast_setstate(), bridge_exec(), change_hold_state(), conf_run(), expire_register(), fast_originate(), handle_init_event(), handle_response_peerpoke(), handle_response_register(), iax2_ack_registry(), join_queue(), leave_queue(), manager_log(), manager_state_cb(), notify_new_message(), park_call_full(), park_exec(), parse_register_contact(), pbx_extension_helper(), phase_e_handler(), 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().
02428 { 02429 struct mansession *s; 02430 char auth[80]; 02431 va_list ap; 02432 struct timeval now; 02433 struct ast_dynamic_str *buf; 02434 02435 /* Abort if there aren't any manager sessions */ 02436 if (!num_sessions) 02437 return 0; 02438 02439 if (!(buf = ast_dynamic_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) 02440 return -1; 02441 02442 ast_dynamic_str_thread_set(&buf, 0, &manager_event_buf, 02443 "Event: %s\r\nPrivilege: %s\r\n", 02444 event, authority_to_str(category, auth, sizeof(auth))); 02445 02446 if (timestampevents) { 02447 now = ast_tvnow(); 02448 ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, 02449 "Timestamp: %ld.%06lu\r\n", 02450 now.tv_sec, (unsigned long) now.tv_usec); 02451 } 02452 02453 va_start(ap, fmt); 02454 ast_dynamic_str_thread_append_va(&buf, 0, &manager_event_buf, fmt, ap); 02455 va_end(ap); 02456 02457 ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, "\r\n"); 02458 02459 /* Append event to master list and wake up any sleeping sessions */ 02460 AST_LIST_LOCK(&sessions); 02461 append_event(buf->str, category); 02462 AST_LIST_TRAVERSE(&sessions, s, list) { 02463 ast_mutex_lock(&s->__lock); 02464 if (s->waiting_thread != AST_PTHREADT_NULL) 02465 pthread_kill(s->waiting_thread, SIGURG); 02466 ast_mutex_unlock(&s->__lock); 02467 } 02468 AST_LIST_UNLOCK(&sessions); 02469 02470 return 0; 02471 }
static int manager_state_cb | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Definition at line 2495 of file manager.c.
References EVENT_FLAG_CALL, and manager_event().
Referenced by init_manager().
02496 { 02497 /* Notify managers of change */ 02498 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nStatus: %d\r\n", exten, context, state); 02499 return 0; 02500 }
static int process_events | ( | struct mansession * | s | ) | [static] |
Definition at line 2046 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().
02047 { 02048 struct eventqent *eqe; 02049 int ret = 0; 02050 ast_mutex_lock(&s->__lock); 02051 if (!s->eventq) 02052 s->eventq = master_eventq; 02053 while(s->eventq->next) { 02054 eqe = s->eventq->next; 02055 if ((s->authenticated && (s->readperm & eqe->category) == eqe->category) && 02056 ((s->send_events & eqe->category) == eqe->category)) { 02057 if (s->fd > -1) { 02058 if (!ret && ast_carefulwrite(s->fd, eqe->eventdata, strlen(eqe->eventdata), s->writetimeout) < 0) 02059 ret = -1; 02060 } else if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) 02061 ret = -1; 02062 else 02063 ast_dynamic_str_append(&s->outputstr, 0, "%s", eqe->eventdata); 02064 } 02065 unuse_eventqent(s->eventq); 02066 s->eventq = eqe; 02067 } 02068 ast_mutex_unlock(&s->__lock); 02069 return ret; 02070 }
static int process_message | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2097 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().
02098 { 02099 char action[80] = ""; 02100 struct manager_action *tmp; 02101 const char *id = astman_get_header(m,"ActionID"); 02102 char idText[256] = ""; 02103 int ret = 0; 02104 02105 ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action)); 02106 if (option_debug) 02107 ast_log( LOG_DEBUG, "Manager received command '%s'\n", action ); 02108 02109 if (ast_strlen_zero(action)) { 02110 astman_send_error(s, m, "Missing action in request"); 02111 return 0; 02112 } 02113 if (!ast_strlen_zero(id)) { 02114 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02115 } 02116 if (!s->authenticated) { 02117 if (!strcasecmp(action, "Challenge")) { 02118 const char *authtype = astman_get_header(m, "AuthType"); 02119 02120 if (!strcasecmp(authtype, "MD5")) { 02121 if (ast_strlen_zero(s->challenge)) 02122 snprintf(s->challenge, sizeof(s->challenge), "%ld", ast_random()); 02123 astman_append(s, "Response: Success\r\n" 02124 "%s" 02125 "Challenge: %s\r\n\r\n", 02126 idText, s->challenge); 02127 return 0; 02128 } else { 02129 astman_send_error(s, m, "Must specify AuthType"); 02130 return 0; 02131 } 02132 } else if (!strcasecmp(action, "Login")) { 02133 if (authenticate(s, m)) { 02134 sleep(1); 02135 astman_send_error(s, m, "Authentication failed"); 02136 return -1; 02137 } else { 02138 s->authenticated = 1; 02139 if (option_verbose > 1) { 02140 if (displayconnects) { 02141 ast_verbose(VERBOSE_PREFIX_2 "%sManager '%s' logged on from %s\n", 02142 (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr)); 02143 } 02144 } 02145 ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", 02146 (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr)); 02147 astman_send_ack(s, m, "Authentication accepted"); 02148 } 02149 } else if (!strcasecmp(action, "Logoff")) { 02150 astman_send_ack(s, m, "See ya"); 02151 return -1; 02152 } else 02153 astman_send_error(s, m, "Authentication Required"); 02154 } else { 02155 if (!strcasecmp(action, "Login")) 02156 astman_send_ack(s, m, "Already logged in"); 02157 else { 02158 ast_rwlock_rdlock(&actionlock); 02159 for (tmp = first_action; tmp; tmp = tmp->next) { 02160 if (strcasecmp(action, tmp->action)) 02161 continue; 02162 if ((s->writeperm & tmp->authority) == tmp->authority) { 02163 if (tmp->func(s, m)) 02164 ret = -1; 02165 } else 02166 astman_send_error(s, m, "Permission denied"); 02167 break; 02168 } 02169 ast_rwlock_unlock(&actionlock); 02170 if (!tmp) 02171 astman_send_error(s, m, "Invalid/unknown command"); 02172 } 02173 } 02174 if (ret) 02175 return ret; 02176 return process_events(s); 02177 }
static void* session_do | ( | void * | data | ) | [static] |
Definition at line 2263 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().
02264 { 02265 struct mansession *s = data; 02266 int res; 02267 02268 astman_append(s, "Asterisk Call Manager/1.0\r\n"); 02269 for (;;) { 02270 if ((res = do_message(s)) < 0) 02271 break; 02272 } 02273 if (s->authenticated) { 02274 if (option_verbose > 1) { 02275 if (displayconnects) 02276 ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); 02277 } 02278 ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); 02279 } else { 02280 if (option_verbose > 1) { 02281 if (displayconnects) 02282 ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr)); 02283 } 02284 ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr)); 02285 } 02286 02287 /* It is possible under certain circumstances for this session thread 02288 to complete its work and exit *before* the thread that created it 02289 has finished executing the ast_pthread_create_background() function. 02290 If this occurs, some versions of glibc appear to act in a buggy 02291 fashion and attempt to write data into memory that it thinks belongs 02292 to the thread but is in fact not owned by the thread (or may have 02293 been freed completely). 02294 02295 Causing this thread to yield to other threads at least one time 02296 appears to work around this bug. 02297 */ 02298 usleep(1); 02299 02300 destroy_session(s); 02301 return NULL; 02302 }
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 935 of file manager.c.
References ast_mutex_lock(), ast_mutex_unlock(), s, and strings_to_mask().
Referenced by action_events().
00936 { 00937 int maskint = strings_to_mask(eventmask); 00938 00939 ast_mutex_lock(&s->__lock); 00940 if (maskint >= 0) 00941 s->send_events = maskint; 00942 ast_mutex_unlock(&s->__lock); 00943 00944 return maskint; 00945 }
static int strings_to_mask | ( | const char * | string | ) | [static] |
Definition at line 904 of file manager.c.
References ast_false(), ast_instring(), ast_is_number(), ast_strlen_zero(), ast_true(), and perms.
Referenced by set_eventmask().
00905 { 00906 int x, ret = -1; 00907 00908 x = ast_is_number(string); 00909 00910 if (x) 00911 ret = x; 00912 else if (ast_strlen_zero(string)) 00913 ret = -1; 00914 else if (ast_false(string)) 00915 ret = 0; 00916 else if (ast_true(string)) { 00917 ret = 0; 00918 for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) 00919 ret |= perms[x].num; 00920 } else { 00921 ret = 0; 00922 for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) { 00923 if (ast_instring(string, perms[x].label, ',')) 00924 ret |= perms[x].num; 00925 } 00926 } 00927 00928 return ret; 00929 }
static void unuse_eventqent | ( | struct eventqent * | e | ) | [static] |
Definition at line 726 of file manager.c.
References eventqent::next, and eventqent::usecount.
Referenced by action_waitevent(), free_session(), and process_events().
00727 { 00728 if (ast_atomic_dec_and_test(&e->usecount) && e->next) 00729 pthread_kill(t, SIGURG); 00730 }
static int variable_count_cmp_fn | ( | void * | obj, | |
void * | vstr, | |||
int | flags | |||
) | [static] |
Definition at line 308 of file manager.c.
References variable_count::varname.
Referenced by xml_translate().
00309 { 00310 /* Due to the simplicity of struct variable_count, it makes no difference 00311 * if you pass in objects or strings, the same operation applies. This is 00312 * due to the fact that the hash occurs on the first element, which means 00313 * the address of both the struct and the string are exactly the same. */ 00314 struct variable_count *vc = obj; 00315 char *str = vstr; 00316 return !strcmp(vc->varname, str) ? CMP_MATCH : 0; 00317 }
static int variable_count_hash_fn | ( | const void * | vvc, | |
const int | flags | |||
) | [static] |
Definition at line 296 of file manager.c.
References compress_char(), and variable_count::varname.
Referenced by xml_translate().
00297 { 00298 const struct variable_count *vc = vvc; 00299 int res = 0, i; 00300 for (i = 0; i < 5; i++) { 00301 if (vc->varname[i] == '\0') 00302 break; 00303 res += compress_char(vc->varname[i]) << (i * 6); 00304 } 00305 return res; 00306 }
static void xml_copy_escape | ( | char ** | dst, | |
size_t * | maxlen, | |||
const char * | src, | |||
int | lower | |||
) | [static] |
Definition at line 241 of file manager.c.
Referenced by xml_translate().
00242 { 00243 while (*src && (*maxlen > 6)) { 00244 switch (*src) { 00245 case '<': 00246 strcpy(*dst, "<"); 00247 (*dst) += 4; 00248 *maxlen -= 4; 00249 break; 00250 case '>': 00251 strcpy(*dst, ">"); 00252 (*dst) += 4; 00253 *maxlen -= 4; 00254 break; 00255 case '\"': 00256 strcpy(*dst, """); 00257 (*dst) += 6; 00258 *maxlen -= 6; 00259 break; 00260 case '\'': 00261 strcpy(*dst, "'"); 00262 (*dst) += 6; 00263 *maxlen -= 6; 00264 break; 00265 case '&': 00266 strcpy(*dst, "&"); 00267 (*dst) += 5; 00268 *maxlen -= 5; 00269 break; 00270 default: 00271 *(*dst)++ = lower ? tolower(*src) : *src; 00272 (*maxlen)--; 00273 } 00274 src++; 00275 } 00276 }
static char* xml_translate | ( | char * | in, | |
struct ast_variable * | vars | |||
) | [static] |
Definition at line 319 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().
00320 { 00321 struct ast_variable *v; 00322 char *dest = NULL; 00323 char *out, *tmp, *var, *val; 00324 char *objtype = NULL; 00325 int colons = 0; 00326 int breaks = 0; 00327 size_t len; 00328 int count = 1; 00329 int escaped = 0; 00330 int inobj = 0; 00331 int x; 00332 struct variable_count *vc = NULL; 00333 struct ao2_container *vco = NULL; 00334 00335 for (v = vars; v; v = v->next) { 00336 if (!dest && !strcasecmp(v->name, "ajaxdest")) 00337 dest = v->value; 00338 else if (!objtype && !strcasecmp(v->name, "ajaxobjtype")) 00339 objtype = v->value; 00340 } 00341 if (!dest) 00342 dest = "unknown"; 00343 if (!objtype) 00344 objtype = "generic"; 00345 for (x = 0; in[x]; x++) { 00346 if (in[x] == ':') 00347 colons++; 00348 else if (in[x] == '\n') 00349 breaks++; 00350 else if (strchr("&\"<>\'", in[x])) 00351 escaped++; 00352 } 00353 len = (size_t) (strlen(in) + colons * 5 + breaks * (40 + strlen(dest) + strlen(objtype)) + escaped * 10); /* foo="bar", "<response type=\"object\" id=\"dest\"", "&" */ 00354 out = ast_malloc(len); 00355 if (!out) 00356 return 0; 00357 tmp = out; 00358 while (*in) { 00359 var = in; 00360 while (*in && (*in >= 32)) 00361 in++; 00362 if (*in) { 00363 if ((count > 3) && inobj) { 00364 ast_build_string(&tmp, &len, " /></response>\n"); 00365 inobj = 0; 00366 00367 /* Entity is closed, so close out the name cache */ 00368 ao2_ref(vco, -1); 00369 vco = NULL; 00370 } 00371 count = 0; 00372 while (*in && (*in < 32)) { 00373 *in = '\0'; 00374 in++; 00375 count++; 00376 } 00377 val = strchr(var, ':'); 00378 if (val) { 00379 *val = '\0'; 00380 val++; 00381 if (*val == ' ') 00382 val++; 00383 if (!inobj) { 00384 vco = ao2_container_alloc(37, variable_count_hash_fn, variable_count_cmp_fn); 00385 ast_build_string(&tmp, &len, "<response type='object' id='%s'><%s", dest, objtype); 00386 inobj = 1; 00387 } 00388 00389 /* Check if the var has been used already */ 00390 if ((vc = ao2_find(vco, var, 0))) 00391 vc->count++; 00392 else { 00393 /* Create a new entry for this one */ 00394 vc = ao2_alloc(sizeof(*vc), NULL); 00395 vc->varname = var; 00396 vc->count = 1; 00397 ao2_link(vco, vc); 00398 } 00399 00400 ast_build_string(&tmp, &len, " "); 00401 xml_copy_escape(&tmp, &len, var, 1); 00402 if (vc->count > 1) 00403 ast_build_string(&tmp, &len, "-%d", vc->count); 00404 ast_build_string(&tmp, &len, "='"); 00405 xml_copy_escape(&tmp, &len, val, 0); 00406 ast_build_string(&tmp, &len, "'"); 00407 ao2_ref(vc, -1); 00408 } 00409 } 00410 } 00411 if (inobj) 00412 ast_build_string(&tmp, &len, " /></response>\n"); 00413 if (vco) 00414 ao2_ref(vco, -1); 00415 return out; 00416 }
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 }
const char* command_blacklist[] [static] |
Initial value:
{ "module load", "module unload", }
Definition at line 133 of file manager.c.
Referenced by action_command().
int displayconnects = 1 [static] |
Definition at line 100 of file manager.c.
Referenced by accept_thread(), init_manager(), process_message(), and session_do().
struct manager_action* first_action [static] |
Definition at line 197 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_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 109 of file manager.c.
Referenced by accept_thread(), append_event(), handle_showmaneventq(), and process_events().
int num_sessions [static] |
Definition at line 106 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 98 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 104 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(), init_manager(), launch_service(), listener(), local_new(), localsub(), lws2sws(), manager_log(), MD5Update(), misdn_read(), newpvt(), nv_background_detect_exec(), nv_detectfax_exec(), osp_create_provider(), osp_load(), packdate(), parse_moved_contact(), pgsql_log(), phase_d_handler(), phase_e_handler(), play_message_datetime(), prune_gateways(), rebuild_matrix(), register_verify(), rpt(), rpt_do_lstats(), rpt_exec(), rpt_tele_thread(), rxfax_exec(), 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(), txfax_exec(), vmu_tm(), and write_metadata().
int timestampevents [static] |