Data Structures | |
struct | ast_manager_user |
struct | eventqent |
struct | fast_originate_helper |
struct | mansession |
struct | permalias |
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) |
struct 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 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 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. | |
struct 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 2215 of file manager.c.
References mansession::__lock, 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(), mansession::authenticated, destroy_session(), mansession::eventq, pollfd::events, mansession::fd, pollfd::fd, ast_channel::flags, free, free_session(), mansession::inuse, LOG_NOTICE, LOG_WARNING, eventqent::next, option_verbose, poll(), POLLIN, s, mansession::send_events, session_do(), mansession::sessiontimeout, mansession::sin, mansession::t, eventqent::usecount, mansession::username, VERBOSE_PREFIX_2, mansession::waiting_thread, and mansession::writetimeout.
Referenced by init_manager(), and reload_config().
02216 { 02217 int as; 02218 struct sockaddr_in sin; 02219 socklen_t sinlen; 02220 struct eventqent *eqe; 02221 struct mansession *s; 02222 struct protoent *p; 02223 int arg = 1; 02224 int flags; 02225 pthread_attr_t attr; 02226 time_t now; 02227 struct pollfd pfds[1]; 02228 02229 pthread_attr_init(&attr); 02230 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02231 02232 for (;;) { 02233 time(&now); 02234 AST_LIST_LOCK(&sessions); 02235 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) { 02236 if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) { 02237 AST_LIST_REMOVE_CURRENT(&sessions, list); 02238 if (s->authenticated && (option_verbose > 1) && displayconnects) { 02239 ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' timed out from %s\n", 02240 s->username, ast_inet_ntoa(s->sin.sin_addr)); 02241 } 02242 free_session(s); 02243 break; 02244 } 02245 } 02246 AST_LIST_TRAVERSE_SAFE_END 02247 /* Purge master event queue of old, unused events, but make sure we 02248 always keep at least one in the queue */ 02249 eqe = master_eventq; 02250 while (master_eventq->next && !master_eventq->usecount) { 02251 eqe = master_eventq; 02252 master_eventq = master_eventq->next; 02253 free(eqe); 02254 } 02255 AST_LIST_UNLOCK(&sessions); 02256 if (s) 02257 ast_atomic_fetchadd_int(&num_sessions, -1); 02258 02259 sinlen = sizeof(sin); 02260 pfds[0].fd = asock; 02261 pfds[0].events = POLLIN; 02262 /* Wait for something to happen, but timeout every few seconds so 02263 we can ditch any old manager sessions */ 02264 if (poll(pfds, 1, 5000) < 1) 02265 continue; 02266 as = accept(asock, (struct sockaddr *)&sin, &sinlen); 02267 if (as < 0) { 02268 ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno)); 02269 continue; 02270 } 02271 p = getprotobyname("tcp"); 02272 if (p) { 02273 if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { 02274 ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno)); 02275 } 02276 } 02277 if (!(s = ast_calloc(1, sizeof(*s)))) 02278 continue; 02279 02280 ast_atomic_fetchadd_int(&num_sessions, 1); 02281 02282 memcpy(&s->sin, &sin, sizeof(sin)); 02283 s->writetimeout = 100; 02284 s->waiting_thread = AST_PTHREADT_NULL; 02285 02286 if (!block_sockets) { 02287 /* For safety, make sure socket is non-blocking */ 02288 flags = fcntl(as, F_GETFL); 02289 fcntl(as, F_SETFL, flags | O_NONBLOCK); 02290 } else { 02291 flags = fcntl(as, F_GETFL); 02292 fcntl(as, F_SETFL, flags & ~O_NONBLOCK); 02293 } 02294 ast_mutex_init(&s->__lock); 02295 s->fd = as; 02296 s->send_events = -1; 02297 AST_LIST_LOCK(&sessions); 02298 AST_LIST_INSERT_HEAD(&sessions, s, list); 02299 /* Find the last place in the master event queue and hook ourselves 02300 in there */ 02301 s->eventq = master_eventq; 02302 while(s->eventq->next) 02303 s->eventq = s->eventq->next; 02304 AST_LIST_UNLOCK(&sessions); 02305 ast_atomic_fetchadd_int(&s->eventq->usecount, 1); 02306 if (ast_pthread_create_background(&s->t, &attr, session_do, s)) 02307 destroy_session(s); 02308 } 02309 pthread_attr_destroy(&attr); 02310 return NULL; 02311 }
static int action_command | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_command: Manager command "command" - execute CLI command
Definition at line 1618 of file manager.c.
References ast_calloc, ast_cli_command(), ast_free, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), mansession::fd, S_OR, and term_strip().
Referenced by init_manager().
01619 { 01620 const char *cmd = astman_get_header(m, "Command"); 01621 const char *id = astman_get_header(m, "ActionID"); 01622 char *buf, *final_buf; 01623 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 01624 int fd = mkstemp(template), i = 0; 01625 off_t l; 01626 01627 for (i = 0; i < sizeof(command_blacklist) / sizeof(command_blacklist[0]); i++) { 01628 if (!strncmp(cmd, command_blacklist[i], strlen(command_blacklist[i]))) { 01629 astman_send_error(s, m, "Command blacklisted"); 01630 return 0; 01631 } 01632 } 01633 01634 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 01635 if (!ast_strlen_zero(id)) 01636 astman_append(s, "ActionID: %s\r\n", id); 01637 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 01638 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 01639 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 01640 01641 /* This has a potential to overflow the stack. Hence, use the heap. */ 01642 buf = ast_calloc(1, l + 1); 01643 final_buf = ast_calloc(1, l + 1); 01644 if (buf) { 01645 lseek(fd, 0, SEEK_SET); 01646 read(fd, buf, l); 01647 buf[l] = '\0'; 01648 if (final_buf) { 01649 term_strip(final_buf, buf, l); 01650 final_buf[l] = '\0'; 01651 } 01652 astman_append(s, S_OR(final_buf, buf)); 01653 ast_free(buf); 01654 } 01655 close(fd); 01656 unlink(template); 01657 astman_append(s, "--END COMMAND--\r\n\r\n"); 01658 if (final_buf) 01659 ast_free(final_buf); 01660 return 0; 01661 }
static int action_events | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1309 of file manager.c.
References astman_get_header(), astman_send_response(), and set_eventmask().
Referenced by init_manager().
01310 { 01311 const char *mask = astman_get_header(m, "EventMask"); 01312 int res; 01313 01314 res = set_eventmask(s, mask); 01315 if (res > 0) 01316 astman_send_response(s, m, "Events On", NULL); 01317 else if (res == 0) 01318 astman_send_response(s, m, "Events Off", NULL); 01319 01320 return 0; 01321 }
static int action_extensionstate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1913 of file manager.c.
References ast_extension_state(), ast_get_hint(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), context, and exten.
Referenced by init_manager().
01914 { 01915 const char *exten = astman_get_header(m, "Exten"); 01916 const char *context = astman_get_header(m, "Context"); 01917 const char *id = astman_get_header(m,"ActionID"); 01918 char idText[256] = ""; 01919 char hint[256] = ""; 01920 int status; 01921 if (ast_strlen_zero(exten)) { 01922 astman_send_error(s, m, "Extension not specified"); 01923 return 0; 01924 } 01925 if (ast_strlen_zero(context)) 01926 context = "default"; 01927 status = ast_extension_state(NULL, context, exten); 01928 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 01929 if (!ast_strlen_zero(id)) { 01930 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01931 } 01932 astman_append(s, "Response: Success\r\n" 01933 "%s" 01934 "Message: Extension Status\r\n" 01935 "Exten: %s\r\n" 01936 "Context: %s\r\n" 01937 "Hint: %s\r\n" 01938 "Status: %d\r\n\r\n", 01939 idText,exten, context, hint, status); 01940 return 0; 01941 }
static int action_getconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1038 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, and ast_variable::value.
Referenced by init_manager().
01039 { 01040 struct ast_config *cfg; 01041 const char *fn = astman_get_header(m, "Filename"); 01042 int catcount = 0; 01043 int lineno = 0; 01044 char *category=NULL; 01045 struct ast_variable *v; 01046 char idText[256] = ""; 01047 const char *id = astman_get_header(m, "ActionID"); 01048 01049 if (!ast_strlen_zero(id)) 01050 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01051 01052 if (ast_strlen_zero(fn)) { 01053 astman_send_error(s, m, "Filename not specified"); 01054 return 0; 01055 } 01056 if (!(cfg = ast_config_load_with_comments(fn))) { 01057 astman_send_error(s, m, "Config file not found"); 01058 return 0; 01059 } 01060 astman_append(s, "Response: Success\r\n%s", idText); 01061 while ((category = ast_category_browse(cfg, category))) { 01062 lineno = 0; 01063 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 01064 for (v = ast_variable_browse(cfg, category); v; v = v->next) 01065 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 01066 catcount++; 01067 } 01068 ast_config_destroy(cfg); 01069 astman_append(s, "\r\n"); 01070 01071 return 0; 01072 }
static int action_getvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1401 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, and pbx_retrieve_variable().
Referenced by init_manager().
01402 { 01403 struct ast_channel *c = NULL; 01404 const char *name = astman_get_header(m, "Channel"); 01405 const char *varname = astman_get_header(m, "Variable"); 01406 const char *id = astman_get_header(m,"ActionID"); 01407 char *varval; 01408 char workspace[1024] = ""; 01409 01410 if (ast_strlen_zero(varname)) { 01411 astman_send_error(s, m, "No variable specified"); 01412 return 0; 01413 } 01414 01415 if (!ast_strlen_zero(name)) { 01416 c = ast_get_channel_by_name_locked(name); 01417 if (!c) { 01418 astman_send_error(s, m, "No such channel"); 01419 return 0; 01420 } 01421 } 01422 01423 if (varname[strlen(varname) - 1] == ')') { 01424 char *copy = ast_strdupa(varname); 01425 01426 ast_func_read(c, copy, workspace, sizeof(workspace)); 01427 varval = workspace; 01428 } else { 01429 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 01430 } 01431 01432 if (c) 01433 ast_channel_unlock(c); 01434 astman_append(s, "Response: Success\r\n" 01435 "Variable: %s\r\nValue: %s\r\n", varname, varval); 01436 if (!ast_strlen_zero(id)) 01437 astman_append(s, "ActionID: %s\r\n",id); 01438 astman_append(s, "\r\n"); 01439 01440 return 0; 01441 }
static int action_hangup | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1338 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(), and name.
Referenced by init_manager().
01339 { 01340 struct ast_channel *c = NULL; 01341 const char *name = astman_get_header(m, "Channel"); 01342 if (ast_strlen_zero(name)) { 01343 astman_send_error(s, m, "No channel specified"); 01344 return 0; 01345 } 01346 c = ast_get_channel_by_name_locked(name); 01347 if (!c) { 01348 astman_send_error(s, m, "No such channel"); 01349 return 0; 01350 } 01351 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01352 ast_channel_unlock(c); 01353 astman_send_ack(s, m, "Channel Hungup"); 01354 return 0; 01355 }
static int action_listcommands | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1282 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, manager_action::synopsis, and mansession::writeperm.
Referenced by init_manager().
01283 { 01284 struct manager_action *cur; 01285 char idText[256] = ""; 01286 char temp[BUFSIZ]; 01287 const char *id = astman_get_header(m,"ActionID"); 01288 01289 if (!ast_strlen_zero(id)) 01290 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01291 astman_append(s, "Response: Success\r\n%s", idText); 01292 for (cur = first_action; cur; cur = cur->next) { 01293 if ((s->writeperm & cur->authority) == cur->authority) 01294 astman_append(s, "%s: %s (Priv: %s)\r\n", cur->action, cur->synopsis, authority_to_str(cur->authority, temp, sizeof(temp))); 01295 } 01296 astman_append(s, "\r\n"); 01297 01298 return 0; 01299 }
static int action_logoff | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1327 of file manager.c.
References astman_send_response().
Referenced by init_manager().
01328 { 01329 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 01330 return -1; 01331 }
static int action_mailboxcount | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1877 of file manager.c.
References ast_app_inboxcount(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), and mailbox.
Referenced by init_manager().
01878 { 01879 const char *mailbox = astman_get_header(m, "Mailbox"); 01880 const char *id = astman_get_header(m,"ActionID"); 01881 char idText[256] = ""; 01882 int newmsgs = 0, oldmsgs = 0; 01883 if (ast_strlen_zero(mailbox)) { 01884 astman_send_error(s, m, "Mailbox not specified"); 01885 return 0; 01886 } 01887 ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs); 01888 if (!ast_strlen_zero(id)) { 01889 snprintf(idText, sizeof(idText), "ActionID: %s\r\n",id); 01890 } 01891 astman_append(s, "Response: Success\r\n" 01892 "%s" 01893 "Message: Mailbox Message Count\r\n" 01894 "Mailbox: %s\r\n" 01895 "NewMessages: %d\r\n" 01896 "OldMessages: %d\r\n" 01897 "\r\n", 01898 idText,mailbox, newmsgs, oldmsgs); 01899 return 0; 01900 }
static int action_mailboxstatus | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1845 of file manager.c.
References ast_app_has_voicemail(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), and mailbox.
Referenced by init_manager().
01846 { 01847 const char *mailbox = astman_get_header(m, "Mailbox"); 01848 const char *id = astman_get_header(m,"ActionID"); 01849 char idText[256] = ""; 01850 int ret; 01851 if (ast_strlen_zero(mailbox)) { 01852 astman_send_error(s, m, "Mailbox not specified"); 01853 return 0; 01854 } 01855 if (!ast_strlen_zero(id)) 01856 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01857 ret = ast_app_has_voicemail(mailbox, NULL); 01858 astman_append(s, "Response: Success\r\n" 01859 "%s" 01860 "Message: Mailbox Status\r\n" 01861 "Mailbox: %s\r\n" 01862 "Waiting: %d\r\n\r\n", idText, mailbox, ret); 01863 return 0; 01864 }
static int action_originate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1727 of file manager.c.
References fast_originate_helper::account, fast_originate_helper::app, app, fast_originate_helper::appdata, 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(), fast_originate_helper::cid_name, fast_originate_helper::cid_num, fast_originate_helper::context, context, fast_originate_helper::data, ast_channel::data, fast_originate_helper::exten, exten, fast_originate(), fast_originate_helper::idtext, name, fast_originate_helper::priority, ast_channel::priority, fast_originate_helper::tech, ast_channel::tech, fast_originate_helper::timeout, and fast_originate_helper::vars.
Referenced by init_manager().
01728 { 01729 const char *name = astman_get_header(m, "Channel"); 01730 const char *exten = astman_get_header(m, "Exten"); 01731 const char *context = astman_get_header(m, "Context"); 01732 const char *priority = astman_get_header(m, "Priority"); 01733 const char *timeout = astman_get_header(m, "Timeout"); 01734 const char *callerid = astman_get_header(m, "CallerID"); 01735 const char *account = astman_get_header(m, "Account"); 01736 const char *app = astman_get_header(m, "Application"); 01737 const char *appdata = astman_get_header(m, "Data"); 01738 const char *async = astman_get_header(m, "Async"); 01739 const char *id = astman_get_header(m, "ActionID"); 01740 struct ast_variable *vars = astman_get_variables(m); 01741 char *tech, *data; 01742 char *l = NULL, *n = NULL; 01743 int pi = 0; 01744 int res; 01745 int to = 30000; 01746 int reason = 0; 01747 char tmp[256]; 01748 char tmp2[256]; 01749 01750 pthread_t th; 01751 pthread_attr_t attr; 01752 if (!name) { 01753 astman_send_error(s, m, "Channel not specified"); 01754 return 0; 01755 } 01756 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 01757 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 01758 astman_send_error(s, m, "Invalid priority\n"); 01759 return 0; 01760 } 01761 } 01762 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) { 01763 astman_send_error(s, m, "Invalid timeout\n"); 01764 return 0; 01765 } 01766 ast_copy_string(tmp, name, sizeof(tmp)); 01767 tech = tmp; 01768 data = strchr(tmp, '/'); 01769 if (!data) { 01770 astman_send_error(s, m, "Invalid channel\n"); 01771 return 0; 01772 } 01773 *data++ = '\0'; 01774 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 01775 ast_callerid_parse(tmp2, &n, &l); 01776 if (n) { 01777 if (ast_strlen_zero(n)) 01778 n = NULL; 01779 } 01780 if (l) { 01781 ast_shrink_phone_number(l); 01782 if (ast_strlen_zero(l)) 01783 l = NULL; 01784 } 01785 if (ast_true(async)) { 01786 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 01787 if (!fast) { 01788 res = -1; 01789 } else { 01790 if (!ast_strlen_zero(id)) 01791 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s\r\n", id); 01792 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 01793 ast_copy_string(fast->data, data, sizeof(fast->data)); 01794 ast_copy_string(fast->app, app, sizeof(fast->app)); 01795 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 01796 if (l) 01797 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 01798 if (n) 01799 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 01800 fast->vars = vars; 01801 ast_copy_string(fast->context, context, sizeof(fast->context)); 01802 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 01803 ast_copy_string(fast->account, account, sizeof(fast->account)); 01804 fast->timeout = to; 01805 fast->priority = pi; 01806 pthread_attr_init(&attr); 01807 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01808 if (ast_pthread_create(&th, &attr, fast_originate, fast)) { 01809 res = -1; 01810 } else { 01811 res = 0; 01812 } 01813 pthread_attr_destroy(&attr); 01814 } 01815 } else if (!ast_strlen_zero(app)) { 01816 res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 01817 } else { 01818 if (exten && context && pi) 01819 res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 01820 else { 01821 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 01822 return 0; 01823 } 01824 } 01825 if (!res) 01826 astman_send_ack(s, m, "Originate successfully queued"); 01827 else 01828 astman_send_error(s, m, "Originate failed"); 01829 return 0; 01830 }
static int action_ping | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1026 of file manager.c.
References astman_send_response().
Referenced by init_manager().
01027 { 01028 astman_send_response(s, m, "Pong", NULL); 01029 return 0; 01030 }
static int action_redirect | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
action_redirect: The redirect manager command
Definition at line 1547 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, and name.
Referenced by init_manager().
01548 { 01549 const char *name = astman_get_header(m, "Channel"); 01550 const char *name2 = astman_get_header(m, "ExtraChannel"); 01551 const char *exten = astman_get_header(m, "Exten"); 01552 const char *context = astman_get_header(m, "Context"); 01553 const char *priority = astman_get_header(m, "Priority"); 01554 struct ast_channel *chan, *chan2 = NULL; 01555 int pi = 0; 01556 int res; 01557 01558 if (ast_strlen_zero(name)) { 01559 astman_send_error(s, m, "Channel not specified"); 01560 return 0; 01561 } 01562 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 01563 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 01564 astman_send_error(s, m, "Invalid priority\n"); 01565 return 0; 01566 } 01567 } 01568 /* XXX watch out, possible deadlock!!! */ 01569 chan = ast_get_channel_by_name_locked(name); 01570 if (!chan) { 01571 char buf[BUFSIZ]; 01572 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 01573 astman_send_error(s, m, buf); 01574 return 0; 01575 } 01576 if (ast_check_hangup(chan)) { 01577 astman_send_error(s, m, "Redirect failed, channel not up.\n"); 01578 ast_channel_unlock(chan); 01579 return 0; 01580 } 01581 if (!ast_strlen_zero(name2)) 01582 chan2 = ast_get_channel_by_name_locked(name2); 01583 if (chan2 && ast_check_hangup(chan2)) { 01584 astman_send_error(s, m, "Redirect failed, extra channel not up.\n"); 01585 ast_channel_unlock(chan); 01586 ast_channel_unlock(chan2); 01587 return 0; 01588 } 01589 res = ast_async_goto(chan, context, exten, pi); 01590 if (!res) { 01591 if (!ast_strlen_zero(name2)) { 01592 if (chan2) 01593 res = ast_async_goto(chan2, context, exten, pi); 01594 else 01595 res = -1; 01596 if (!res) 01597 astman_send_ack(s, m, "Dual Redirect successful"); 01598 else 01599 astman_send_error(s, m, "Secondary redirect failed"); 01600 } else 01601 astman_send_ack(s, m, "Redirect successful"); 01602 } else 01603 astman_send_error(s, m, "Redirect failed"); 01604 if (chan) 01605 ast_channel_unlock(chan); 01606 if (chan2) 01607 ast_channel_unlock(chan2); 01608 return 0; 01609 }
static int action_setvar | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1364 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(), and S_OR.
Referenced by init_manager().
01365 { 01366 struct ast_channel *c = NULL; 01367 const char *name = astman_get_header(m, "Channel"); 01368 const char *varname = astman_get_header(m, "Variable"); 01369 const char *varval = astman_get_header(m, "Value"); 01370 01371 if (ast_strlen_zero(varname)) { 01372 astman_send_error(s, m, "No variable specified"); 01373 return 0; 01374 } 01375 01376 if (!ast_strlen_zero(name)) { 01377 c = ast_get_channel_by_name_locked(name); 01378 if (!c) { 01379 astman_send_error(s, m, "No such channel"); 01380 return 0; 01381 } 01382 } 01383 01384 pbx_builtin_setvar_helper(c, varname, S_OR(varval, "")); 01385 01386 if (c) 01387 ast_channel_unlock(c); 01388 01389 astman_send_ack(s, m, "Variable Set"); 01390 01391 return 0; 01392 }
static int action_status | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Manager "status" command to show channels.
Definition at line 1446 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_OR, and ast_cdr::start.
Referenced by init_manager().
01447 { 01448 const char *id = astman_get_header(m,"ActionID"); 01449 const char *name = astman_get_header(m,"Channel"); 01450 char idText[256] = ""; 01451 struct ast_channel *c; 01452 char bridge[256]; 01453 struct timeval now = ast_tvnow(); 01454 long elapsed_seconds = 0; 01455 int all = ast_strlen_zero(name); /* set if we want all channels */ 01456 01457 if (!ast_strlen_zero(id)) 01458 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01459 if (all) 01460 c = ast_channel_walk_locked(NULL); 01461 else { 01462 c = ast_get_channel_by_name_locked(name); 01463 if (!c) { 01464 astman_send_error(s, m, "No such channel"); 01465 return 0; 01466 } 01467 } 01468 astman_send_ack(s, m, "Channel status will follow"); 01469 /* if we look by name, we break after the first iteration */ 01470 while (c) { 01471 if (c->_bridge) 01472 snprintf(bridge, sizeof(bridge), "Link: %s\r\n", c->_bridge->name); 01473 else 01474 bridge[0] = '\0'; 01475 if (c->pbx) { 01476 if (c->cdr) { 01477 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01478 } 01479 astman_append(s, 01480 "Event: Status\r\n" 01481 "Privilege: Call\r\n" 01482 "Channel: %s\r\n" 01483 "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */ 01484 "CallerIDNum: %s\r\n" 01485 "CallerIDName: %s\r\n" 01486 "Account: %s\r\n" 01487 "State: %s\r\n" 01488 "Context: %s\r\n" 01489 "Extension: %s\r\n" 01490 "Priority: %d\r\n" 01491 "Seconds: %ld\r\n" 01492 "%s" 01493 "Uniqueid: %s\r\n" 01494 "%s" 01495 "\r\n", 01496 c->name, 01497 S_OR(c->cid.cid_num, "<unknown>"), 01498 S_OR(c->cid.cid_num, "<unknown>"), 01499 S_OR(c->cid.cid_name, "<unknown>"), 01500 c->accountcode, 01501 ast_state2str(c->_state), c->context, 01502 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, idText); 01503 } else { 01504 astman_append(s, 01505 "Event: Status\r\n" 01506 "Privilege: Call\r\n" 01507 "Channel: %s\r\n" 01508 "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */ 01509 "CallerIDNum: %s\r\n" 01510 "CallerIDName: %s\r\n" 01511 "Account: %s\r\n" 01512 "State: %s\r\n" 01513 "%s" 01514 "Uniqueid: %s\r\n" 01515 "%s" 01516 "\r\n", 01517 c->name, 01518 S_OR(c->cid.cid_num, "<unknown>"), 01519 S_OR(c->cid.cid_num, "<unknown>"), 01520 S_OR(c->cid.cid_name, "<unknown>"), 01521 c->accountcode, 01522 ast_state2str(c->_state), bridge, c->uniqueid, idText); 01523 } 01524 ast_channel_unlock(c); 01525 if (!all) 01526 break; 01527 c = ast_channel_walk_locked(c); 01528 } 01529 astman_append(s, 01530 "Event: StatusComplete\r\n" 01531 "%s" 01532 "\r\n",idText); 01533 return 0; 01534 }
static int action_timeout | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1950 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(), and name.
Referenced by init_manager().
01951 { 01952 struct ast_channel *c = NULL; 01953 const char *name = astman_get_header(m, "Channel"); 01954 int timeout = atoi(astman_get_header(m, "Timeout")); 01955 if (ast_strlen_zero(name)) { 01956 astman_send_error(s, m, "No channel specified"); 01957 return 0; 01958 } 01959 if (!timeout) { 01960 astman_send_error(s, m, "No timeout specified"); 01961 return 0; 01962 } 01963 c = ast_get_channel_by_name_locked(name); 01964 if (!c) { 01965 astman_send_error(s, m, "No such channel"); 01966 return 0; 01967 } 01968 ast_channel_setwhentohangup(c, timeout); 01969 ast_channel_unlock(c); 01970 astman_send_ack(s, m, "Timeout Set"); 01971 return 0; 01972 }
static int action_updateconfig | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1149 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(), and handle_updates().
Referenced by init_manager().
01150 { 01151 struct ast_config *cfg; 01152 const char *sfn = astman_get_header(m, "SrcFilename"); 01153 const char *dfn = astman_get_header(m, "DstFilename"); 01154 int res; 01155 char idText[256] = ""; 01156 const char *id = astman_get_header(m, "ActionID"); 01157 const char *rld = astman_get_header(m, "Reload"); 01158 01159 if (!ast_strlen_zero(id)) 01160 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01161 01162 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { 01163 astman_send_error(s, m, "Filename not specified"); 01164 return 0; 01165 } 01166 if (!(cfg = ast_config_load_with_comments(sfn))) { 01167 astman_send_error(s, m, "Config file not found"); 01168 return 0; 01169 } 01170 handle_updates(s, m, cfg); 01171 res = config_text_file_save(dfn, cfg, "Manager"); 01172 ast_config_destroy(cfg); 01173 if (res) { 01174 astman_send_error(s, m, "Save of config failed"); 01175 return 0; 01176 } 01177 astman_append(s, "Response: Success\r\n%s\r\n", idText); 01178 if (!ast_strlen_zero(rld)) { 01179 if (ast_true(rld)) 01180 rld = NULL; 01181 ast_module_reload(rld); 01182 } 01183 return 0; 01184 }
static int action_userevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2004 of file manager.c.
References astman_get_header(), event, EVENT_FLAG_USER, message::hdrcount, message::headers, and manager_event().
Referenced by init_manager().
02005 { 02006 const char *event = astman_get_header(m, "UserEvent"); 02007 char body[2048] = ""; 02008 int x, bodylen = 0; 02009 for (x = 0; x < m->hdrcount; x++) { 02010 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 02011 ast_copy_string(body + bodylen, m->headers[x], sizeof(body) - bodylen - 3); 02012 bodylen += strlen(m->headers[x]); 02013 ast_copy_string(body + bodylen, "\r\n", 3); 02014 bodylen += 2; 02015 } 02016 } 02017 02018 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body); 02019 return 0; 02020 }
static int action_waitevent | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 1194 of file manager.c.
References mansession::__lock, 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, mansession::eventq, mansession::fd, LOG_DEBUG, mansession::needdestroy, eventqent::next, option_debug, mansession::readperm, mansession::send_events, mansession::sessiontimeout, unuse_eventqent(), and mansession::waiting_thread.
Referenced by init_manager().
01195 { 01196 const char *timeouts = astman_get_header(m, "Timeout"); 01197 int timeout = -1, max; 01198 int x; 01199 int needexit = 0; 01200 time_t now; 01201 struct eventqent *eqe; 01202 const char *id = astman_get_header(m,"ActionID"); 01203 char idText[256] = ""; 01204 01205 if (!ast_strlen_zero(id)) 01206 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01207 01208 if (!ast_strlen_zero(timeouts)) { 01209 sscanf(timeouts, "%i", &timeout); 01210 } 01211 01212 ast_mutex_lock(&s->__lock); 01213 if (s->waiting_thread != AST_PTHREADT_NULL) { 01214 pthread_kill(s->waiting_thread, SIGURG); 01215 } 01216 if (s->sessiontimeout) { 01217 time(&now); 01218 max = s->sessiontimeout - now - 10; 01219 if (max < 0) 01220 max = 0; 01221 if ((timeout < 0) || (timeout > max)) 01222 timeout = max; 01223 if (!s->send_events) 01224 s->send_events = -1; 01225 /* Once waitevent is called, always queue events from now on */ 01226 } 01227 ast_mutex_unlock(&s->__lock); 01228 s->waiting_thread = pthread_self(); 01229 if (option_debug) 01230 ast_log(LOG_DEBUG, "Starting waiting for an event!\n"); 01231 for (x=0; ((x < timeout) || (timeout < 0)); x++) { 01232 ast_mutex_lock(&s->__lock); 01233 if (s->eventq && s->eventq->next) 01234 needexit = 1; 01235 if (s->waiting_thread != pthread_self()) 01236 needexit = 1; 01237 if (s->needdestroy) 01238 needexit = 1; 01239 ast_mutex_unlock(&s->__lock); 01240 if (needexit) 01241 break; 01242 if (s->fd > 0) { 01243 if (ast_wait_for_input(s->fd, 1000)) 01244 break; 01245 } else { 01246 sleep(1); 01247 } 01248 } 01249 if (option_debug) 01250 ast_log(LOG_DEBUG, "Finished waiting for an event!\n"); 01251 ast_mutex_lock(&s->__lock); 01252 if (s->waiting_thread == pthread_self()) { 01253 astman_send_response(s, m, "Success", "Waiting for Event..."); 01254 /* Only show events if we're the most recent waiter */ 01255 while(s->eventq->next) { 01256 eqe = s->eventq->next; 01257 if (((s->readperm & eqe->category) == eqe->category) && 01258 ((s->send_events & eqe->category) == eqe->category)) { 01259 astman_append(s, "%s", eqe->eventdata); 01260 } 01261 unuse_eventqent(s->eventq); 01262 s->eventq = eqe; 01263 } 01264 astman_append(s, 01265 "Event: WaitEventComplete\r\n" 01266 "%s" 01267 "\r\n", idText); 01268 s->waiting_thread = AST_PTHREADT_NULL; 01269 } else { 01270 ast_log(LOG_DEBUG, "Abandoning event request!\n"); 01271 } 01272 ast_mutex_unlock(&s->__lock); 01273 return 0; 01274 }
static int append_event | ( | const char * | str, | |
int | category | |||
) | [static] |
Definition at line 2313 of file manager.c.
References ast_malloc, eventqent::category, eventqent::eventdata, eventqent::next, and eventqent::usecount.
Referenced by init_manager(), and manager_event().
02314 { 02315 struct eventqent *tmp, *prev = NULL; 02316 tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 02317 02318 if (!tmp) 02319 return -1; 02320 02321 tmp->next = NULL; 02322 tmp->category = category; 02323 strcpy(tmp->eventdata, str); 02324 02325 if (master_eventq) { 02326 prev = master_eventq; 02327 while (prev->next) 02328 prev = prev->next; 02329 prev->next = tmp; 02330 } else { 02331 master_eventq = tmp; 02332 } 02333 02334 tmp->usecount = num_sessions; 02335 02336 return 0; 02337 }
static struct ast_manager_user* ast_get_manager_by_name_locked | ( | const char * | name | ) | [static, read] |
Definition at line 401 of file manager.c.
References AST_LIST_TRAVERSE, and ast_manager_user::username.
Referenced by handle_showmanager(), and init_manager().
00402 { 00403 struct ast_manager_user *user = NULL; 00404 00405 AST_LIST_TRAVERSE(&users, user, list) 00406 if (!strcasecmp(user->username, name)) 00407 break; 00408 return user; 00409 }
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 789 of file manager.c.
References ast_variable::next.
Referenced by get_perm(), and strings_to_mask().
00790 { 00791 const char *val = bigstr, *next; 00792 00793 do { 00794 if ((next = strchr(val, delim))) { 00795 if (!strncmp(val, smallstr, (next - val))) 00796 return 1; 00797 else 00798 continue; 00799 } else 00800 return !strcmp(smallstr, val); 00801 00802 } while (*(val = (next + 1))); 00803 00804 return 0; 00805 }
static int ast_is_number | ( | const char * | string | ) | [static] |
Definition at line 822 of file manager.c.
Referenced by strings_to_mask().
00823 { 00824 int ret = 1, x = 0; 00825 00826 if (!string) 00827 return 0; 00828 00829 for (x = 0; x < strlen(string); x++) { 00830 if (!(string[x] >= 48 && string[x] <= 57)) { 00831 ret = 0; 00832 break; 00833 } 00834 } 00835 00836 return ret ? atoi(string) : 0; 00837 }
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
Register a manager command with the manager interface
action | Name of the requested Action: | |
authority | Required authority for this command | |
func | Function to call for this command | |
synopsis | Help text (one line, up to 30 chars) for CLI manager show commands | |
description | Help text, several lines |
Definition at line 2459 of file manager.c.
Referenced by init_manager(), and load_module().
02460 { 02461 struct manager_action *cur; 02462 02463 cur = ast_malloc(sizeof(*cur)); 02464 if (!cur) 02465 return -1; 02466 02467 cur->action = action; 02468 cur->authority = auth; 02469 cur->func = func; 02470 cur->synopsis = synopsis; 02471 cur->description = description; 02472 cur->next = NULL; 02473 02474 ast_manager_register_struct(cur); 02475 02476 return 0; 02477 }
static int ast_manager_register_struct | ( | struct manager_action * | act | ) | [static] |
Definition at line 2415 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().
02416 { 02417 struct manager_action *cur, *prev = NULL; 02418 int ret; 02419 02420 ast_rwlock_wrlock(&actionlock); 02421 cur = first_action; 02422 while (cur) { /* Walk the list of actions */ 02423 ret = strcasecmp(cur->action, act->action); 02424 if (ret == 0) { 02425 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 02426 ast_rwlock_unlock(&actionlock); 02427 return -1; 02428 } else if (ret > 0) { 02429 /* Insert these alphabetically */ 02430 if (prev) { 02431 act->next = prev->next; 02432 prev->next = act; 02433 } else { 02434 act->next = first_action; 02435 first_action = act; 02436 } 02437 break; 02438 } 02439 prev = cur; 02440 cur = cur->next; 02441 } 02442 02443 if (!cur) { 02444 if (prev) 02445 prev->next = act; 02446 else 02447 first_action = act; 02448 act->next = NULL; 02449 } 02450 02451 if (option_verbose > 1) 02452 ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", act->action); 02453 ast_rwlock_unlock(&actionlock); 02454 return 0; 02455 }
int ast_manager_unregister | ( | char * | action | ) |
Unregister a registred manager command
action | Name of registred Action: |
Definition at line 2386 of file manager.c.
Referenced by __unload_module(), and unload_module().
02387 { 02388 struct manager_action *cur, *prev; 02389 02390 ast_rwlock_wrlock(&actionlock); 02391 cur = prev = first_action; 02392 while (cur) { 02393 if (!strcasecmp(action, cur->action)) { 02394 prev->next = cur->next; 02395 free(cur); 02396 if (option_verbose > 1) 02397 ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action); 02398 ast_rwlock_unlock(&actionlock); 02399 return 0; 02400 } 02401 prev = cur; 02402 cur = cur->next; 02403 } 02404 ast_rwlock_unlock(&actionlock); 02405 return 0; 02406 }
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 411 of file manager.c.
References mansession::__lock, ast_calloc, ast_carefulwrite(), ast_dynamic_str_thread_set_va, ast_mutex_lock(), ast_mutex_unlock(), ASTMAN_APPEND_BUF_INITSIZE, mansession::fd, mansession::outputstr, and mansession::writetimeout.
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().
00412 { 00413 va_list ap; 00414 struct ast_dynamic_str *buf; 00415 00416 ast_mutex_lock(&s->__lock); 00417 00418 if (!(buf = ast_dynamic_str_thread_get(&astman_append_buf, ASTMAN_APPEND_BUF_INITSIZE))) { 00419 ast_mutex_unlock(&s->__lock); 00420 return; 00421 } 00422 00423 va_start(ap, fmt); 00424 ast_dynamic_str_thread_set_va(&buf, 0, &astman_append_buf, fmt, ap); 00425 va_end(ap); 00426 00427 if (s->fd > -1) 00428 ast_carefulwrite(s->fd, buf->str, strlen(buf->str), s->writetimeout); 00429 else { 00430 if (!s->outputstr && !(s->outputstr = ast_calloc(1, sizeof(*s->outputstr)))) { 00431 ast_mutex_unlock(&s->__lock); 00432 return; 00433 } 00434 00435 ast_dynamic_str_append(&s->outputstr, 0, "%s", buf->str); 00436 } 00437 00438 ast_mutex_unlock(&s->__lock); 00439 }
const char* astman_get_header | ( | const struct message * | m, | |
char * | var | |||
) |
Get header from mananger transaction
Definition at line 692 of file manager.c.
Referenced by _sip_show_peer(), _sip_show_peers(), action_agent_callback_login(), action_agent_logoff(), action_agents(), action_command(), 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().
00693 { 00694 char cmp[80]; 00695 int x; 00696 00697 snprintf(cmp, sizeof(cmp), "%s: ", var); 00698 00699 for (x = 0; x < m->hdrcount; x++) { 00700 if (!strncasecmp(cmp, m->headers[x], strlen(cmp))) 00701 return m->headers[x] + strlen(cmp); 00702 } 00703 00704 return ""; 00705 }
struct ast_variable* astman_get_variables | ( | const struct message * | m | ) | [read] |
Get a linked list of the Variable: headers
Definition at line 707 of file manager.c.
Referenced by action_originate().
00708 { 00709 int varlen, x, y; 00710 struct ast_variable *head = NULL, *cur; 00711 char *var, *val; 00712 00713 char *parse; 00714 AST_DECLARE_APP_ARGS(args, 00715 AST_APP_ARG(vars)[32]; 00716 ); 00717 00718 varlen = strlen("Variable: "); 00719 00720 for (x = 0; x < m->hdrcount; x++) { 00721 if (strncasecmp("Variable: ", m->headers[x], varlen)) 00722 continue; 00723 00724 parse = ast_strdupa(m->headers[x] + varlen); 00725 00726 AST_STANDARD_APP_ARGS(args, parse); 00727 if (args.argc) { 00728 for (y = 0; y < args.argc; y++) { 00729 if (!args.vars[y]) 00730 continue; 00731 var = val = ast_strdupa(args.vars[y]); 00732 strsep(&val, "="); 00733 if (!val || ast_strlen_zero(var)) 00734 continue; 00735 cur = ast_variable_new(var, val); 00736 if (head) { 00737 cur->next = head; 00738 head = cur; 00739 } else 00740 head = cur; 00741 } 00742 } 00743 } 00744 00745 return head; 00746 }
void astman_send_ack | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | msg | |||
) |
Definition at line 779 of file manager.c.
Referenced by action_agent_callback_login(), action_agent_logoff(), action_agents(), 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().
00780 { 00781 astman_send_response(s, m, "Success", msg); 00782 }
void astman_send_error | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | error | |||
) |
Definition at line 756 of file manager.c.
Referenced by _sip_show_peer(), action_agent_callback_login(), action_agent_logoff(), action_command(), action_extensionstate(), action_getconfig(), action_getvar(), action_hangup(), action_mailboxcount(), action_mailboxstatus(), action_originate(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_zapdialoffhook(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), change_monitor_action(), do_pause_or_unpause(), manager_add_queue_member(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_park(), manager_pause_queue_member(), manager_play_dtmf(), manager_remove_queue_member(), manager_sip_show_peer(), meetmemute(), process_message(), start_monitor_action(), and stop_monitor_action().
00757 { 00758 const char *id = astman_get_header(m,"ActionID"); 00759 00760 astman_append(s, "Response: Error\r\n"); 00761 if (!ast_strlen_zero(id)) 00762 astman_append(s, "ActionID: %s\r\n", id); 00763 astman_append(s, "Message: %s\r\n\r\n", error); 00764 }
void astman_send_response | ( | struct mansession * | s, | |
const struct message * | m, | |||
char * | resp, | |||
char * | msg | |||
) |
Definition at line 766 of file manager.c.
Referenced by action_events(), action_logoff(), action_ping(), action_waitevent(), and astman_send_ack().
00767 { 00768 const char *id = astman_get_header(m,"ActionID"); 00769 00770 astman_append(s, "Response: %s\r\n", resp); 00771 if (!ast_strlen_zero(id)) 00772 astman_append(s, "ActionID: %s\r\n", id); 00773 if (msg) 00774 astman_append(s, "Message: %s\r\n\r\n", msg); 00775 else 00776 astman_append(s, "\r\n"); 00777 }
static int authenticate | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 882 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(), ast_variable_retrieve(), astman_get_header(), mansession::challenge, mansession::displaysystemname, events, get_perm(), key(), len, ast_variable::lineno, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MD5Final(), MD5Init(), MD5Update(), ast_variable::name, ast_variable::next, password, mansession::readperm, S_OR, set_eventmask(), mansession::sin, mansession::username, ast_variable::value, mansession::writeperm, and mansession::writetimeout.
Referenced by authenticate_reply(), handle_response_invite(), process_message(), and registry_rerequest().
00883 { 00884 struct ast_config *cfg; 00885 char *cat; 00886 const char *user = astman_get_header(m, "Username"); 00887 const char *pass = astman_get_header(m, "Secret"); 00888 const char *authtype = astman_get_header(m, "AuthType"); 00889 const char *key = astman_get_header(m, "Key"); 00890 const char *events = astman_get_header(m, "Events"); 00891 00892 cfg = ast_config_load("manager.conf"); 00893 if (!cfg) 00894 return -1; 00895 cat = ast_category_browse(cfg, NULL); 00896 while (cat) { 00897 if (strcasecmp(cat, "general")) { 00898 /* This is a user */ 00899 if (!strcasecmp(cat, user)) { 00900 struct ast_variable *v; 00901 struct ast_ha *ha = NULL; 00902 char *password = NULL; 00903 00904 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 00905 if (!strcasecmp(v->name, "secret")) { 00906 password = v->value; 00907 } else if (!strcasecmp(v->name, "displaysystemname")) { 00908 if (ast_true(v->value)) { 00909 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) { 00910 s->displaysystemname = 1; 00911 } else { 00912 ast_log(LOG_ERROR, "Can't enable displaysystemname in manager.conf - no system name configured in asterisk.conf\n"); 00913 } 00914 } 00915 } else if (!strcasecmp(v->name, "permit") || 00916 !strcasecmp(v->name, "deny")) { 00917 ha = ast_append_ha(v->name, v->value, ha); 00918 } else if (!strcasecmp(v->name, "writetimeout")) { 00919 int val = atoi(v->value); 00920 00921 if (val < 100) 00922 ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", v->value, v->lineno); 00923 else 00924 s->writetimeout = val; 00925 } 00926 00927 } 00928 if (ha && !ast_apply_ha(ha, &(s->sin))) { 00929 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 00930 ast_free_ha(ha); 00931 ast_config_destroy(cfg); 00932 return -1; 00933 } else if (ha) 00934 ast_free_ha(ha); 00935 if (!strcasecmp(authtype, "MD5")) { 00936 if (!ast_strlen_zero(key) && 00937 !ast_strlen_zero(s->challenge) && !ast_strlen_zero(password)) { 00938 int x; 00939 int len = 0; 00940 char md5key[256] = ""; 00941 struct MD5Context md5; 00942 unsigned char digest[16]; 00943 MD5Init(&md5); 00944 MD5Update(&md5, (unsigned char *) s->challenge, strlen(s->challenge)); 00945 MD5Update(&md5, (unsigned char *) password, strlen(password)); 00946 MD5Final(digest, &md5); 00947 for (x=0; x<16; x++) 00948 len += sprintf(md5key + len, "%2.2x", digest[x]); 00949 if (!strcmp(md5key, key)) 00950 break; 00951 else { 00952 ast_config_destroy(cfg); 00953 return -1; 00954 } 00955 } else { 00956 ast_log(LOG_DEBUG, "MD5 authentication is not possible. challenge: '%s'\n", 00957 S_OR(s->challenge, "")); 00958 ast_config_destroy(cfg); 00959 return -1; 00960 } 00961 } else if (password && !strcmp(password, pass)) { 00962 break; 00963 } else { 00964 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 00965 ast_config_destroy(cfg); 00966 return -1; 00967 } 00968 } 00969 } 00970 cat = ast_category_browse(cfg, cat); 00971 } 00972 if (cat) { 00973 ast_copy_string(s->username, cat, sizeof(s->username)); 00974 s->readperm = get_perm(ast_variable_retrieve(cfg, cat, "read")); 00975 s->writeperm = get_perm(ast_variable_retrieve(cfg, cat, "write")); 00976 ast_config_destroy(cfg); 00977 if (events) 00978 set_eventmask(s, events); 00979 return 0; 00980 } 00981 ast_config_destroy(cfg); 00982 cfg = ast_config_load("users.conf"); 00983 if (!cfg) 00984 return -1; 00985 cat = ast_category_browse(cfg, NULL); 00986 while (cat) { 00987 struct ast_variable *v; 00988 const char *password = NULL; 00989 int hasmanager = 0; 00990 if (strcasecmp(cat, user) || !strcasecmp(cat, "general")) { 00991 cat = ast_category_browse(cfg, cat); 00992 continue; 00993 } 00994 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 00995 if (!strcasecmp(v->name, "secret")) 00996 password = v->value; 00997 else if (!strcasecmp(v->name, "hasmanager")) 00998 hasmanager = ast_true(v->value); 00999 } 01000 if (!hasmanager) 01001 break; 01002 if (!password || strcmp(password, pass)) { 01003 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01004 ast_config_destroy(cfg); 01005 return -1; 01006 } 01007 ast_copy_string(s->username, cat, sizeof(s->username)); 01008 s->readperm = -1; 01009 s->writeperm = -1; 01010 ast_config_destroy(cfg); 01011 if (events) 01012 set_eventmask(s, events); 01013 return 0; 01014 } 01015 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 01016 ast_config_destroy(cfg); 01017 return -1; 01018 }
static char* authority_to_str | ( | int | authority, | |
char * | res, | |||
int | reslen | |||
) | [static] |
Convert authority code to string with serveral options.
Definition at line 200 of file manager.c.
References ast_strlen_zero(), and perms.
Referenced by action_listcommands(), handle_showmancmd(), handle_showmancmds(), and manager_event().
00201 { 00202 int running_total = 0, i; 00203 00204 memset(res, 0, reslen); 00205 for (i = 0; i < (sizeof(perms) / sizeof(perms[0])) - 1; i++) { 00206 if (authority & perms[i].num) { 00207 if (*res) { 00208 strncat(res, ",", (reslen > running_total) ? reslen - running_total : 0); 00209 running_total++; 00210 } 00211 strncat(res, perms[i].label, (reslen > running_total) ? reslen - running_total : 0); 00212 running_total += strlen(perms[i].label); 00213 } 00214 } 00215 00216 if (ast_strlen_zero(res)) 00217 ast_copy_string(res, "<none>", reslen); 00218 00219 return res; 00220 }
static char* complete_show_mancmd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 222 of file manager.c.
References manager_action::action, ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_strdup, first_action, and manager_action::next.
00223 { 00224 struct manager_action *cur; 00225 int which = 0; 00226 char *ret = NULL; 00227 00228 ast_rwlock_rdlock(&actionlock); 00229 for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */ 00230 if (!strncasecmp(word, cur->action, strlen(word)) && ++which > state) { 00231 ret = ast_strdup(cur->action); 00232 break; /* make sure we exit even if ast_strdup() returns NULL */ 00233 } 00234 } 00235 ast_rwlock_unlock(&actionlock); 00236 00237 return ret; 00238 }
static void destroy_session | ( | struct mansession * | s | ) | [static] |
Definition at line 682 of file manager.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, and free_session().
Referenced by accept_thread(), generic_http_callback(), session_do(), and skinny_session().
00683 { 00684 AST_LIST_LOCK(&sessions); 00685 AST_LIST_REMOVE(&sessions, s, list); 00686 AST_LIST_UNLOCK(&sessions); 00687 00688 ast_atomic_fetchadd_int(&num_sessions, -1); 00689 free_session(s); 00690 }
static int do_message | ( | struct mansession * | s | ) | [static] |
Definition at line 2158 of file manager.c.
References AST_MAX_MANHEADERS, ast_strdupa, ast_strlen_zero(), mansession::eventq, get_input(), message::hdrcount, message::headers, mansession::inbuf, eventqent::next, process_events(), and process_message().
Referenced by session_do().
02159 { 02160 struct message m = { 0 }; 02161 char header_buf[sizeof(s->inbuf)] = { '\0' }; 02162 int res; 02163 02164 for (;;) { 02165 /* Check if any events are pending and do them if needed */ 02166 if (s->eventq->next) { 02167 if (process_events(s)) 02168 return -1; 02169 } 02170 res = get_input(s, header_buf); 02171 if (res == 0) { 02172 continue; 02173 } else if (res > 0) { 02174 /* Strip trailing \r\n */ 02175 if (strlen(header_buf) < 2) 02176 continue; 02177 header_buf[strlen(header_buf) - 2] = '\0'; 02178 if (ast_strlen_zero(header_buf)) 02179 return process_message(s, &m) ? -1 : 0; 02180 else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) 02181 m.headers[m.hdrcount++] = ast_strdupa(header_buf); 02182 } else { 02183 return res; 02184 } 02185 } 02186 }
static void* fast_originate | ( | void * | data | ) | [static] |
Definition at line 1663 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().
01664 { 01665 struct fast_originate_helper *in = data; 01666 int res; 01667 int reason = 0; 01668 struct ast_channel *chan = NULL; 01669 char requested_channel[AST_CHANNEL_NAME]; 01670 01671 if (!ast_strlen_zero(in->app)) { 01672 res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, 01673 S_OR(in->cid_num, NULL), 01674 S_OR(in->cid_name, NULL), 01675 in->vars, in->account, &chan); 01676 } else { 01677 res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 01678 S_OR(in->cid_num, NULL), 01679 S_OR(in->cid_name, NULL), 01680 in->vars, in->account, &chan); 01681 } 01682 01683 if (!chan) 01684 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 01685 /* Tell the manager what happened with the channel */ 01686 manager_event(EVENT_FLAG_CALL, "OriginateResponse", 01687 "%s" 01688 "Response: %s\r\n" 01689 "Channel: %s\r\n" 01690 "Context: %s\r\n" 01691 "Exten: %s\r\n" 01692 "Reason: %d\r\n" 01693 "Uniqueid: %s\r\n" 01694 "CallerID: %s\r\n" /* This parameter is deprecated and will be removed post-1.4 */ 01695 "CallerIDNum: %s\r\n" 01696 "CallerIDName: %s\r\n", 01697 in->idtext, res ? "Failure" : "Success", chan ? chan->name : requested_channel, in->context, in->exten, reason, 01698 chan ? chan->uniqueid : "<null>", 01699 S_OR(in->cid_num, "<unknown>"), 01700 S_OR(in->cid_num, "<unknown>"), 01701 S_OR(in->cid_name, "<unknown>") 01702 ); 01703 01704 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 01705 if (chan) 01706 ast_channel_unlock(chan); 01707 free(in); 01708 return NULL; 01709 }
static void free_session | ( | struct mansession * | s | ) | [static] |
Definition at line 666 of file manager.c.
References mansession::__lock, ast_mutex_destroy(), mansession::eventq, mansession::fd, free, eventqent::next, mansession::outputstr, and unuse_eventqent().
Referenced by accept_thread(), and destroy_session().
00667 { 00668 struct eventqent *eqe; 00669 if (s->fd > -1) 00670 close(s->fd); 00671 if (s->outputstr) 00672 free(s->outputstr); 00673 ast_mutex_destroy(&s->__lock); 00674 while (s->eventq) { 00675 eqe = s->eventq; 00676 s->eventq = s->eventq->next; 00677 unuse_eventqent(eqe); 00678 } 00679 free(s); 00680 }
static int get_input | ( | struct mansession * | s, | |
char * | output | |||
) | [static] |
Definition at line 2104 of file manager.c.
References mansession::__lock, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, pollfd::events, mansession::fd, pollfd::fd, ast_channel::fds, mansession::inbuf, mansession::inlen, LOG_WARNING, poll(), POLLIN, mansession::sin, and mansession::waiting_thread.
Referenced by do_message(), and skinny_session().
02105 { 02106 /* output must have at least sizeof(s->inbuf) space */ 02107 int res; 02108 int x; 02109 struct pollfd fds[1]; 02110 for (x = 1; x < s->inlen; x++) { 02111 if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) { 02112 /* Copy output data up to and including \r\n */ 02113 memcpy(output, s->inbuf, x + 1); 02114 /* Add trailing \0 */ 02115 output[x+1] = '\0'; 02116 /* Move remaining data back to the front */ 02117 memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x); 02118 s->inlen -= (x + 1); 02119 return 1; 02120 } 02121 } 02122 if (s->inlen >= sizeof(s->inbuf) - 1) { 02123 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->sin.sin_addr), s->inbuf); 02124 s->inlen = 0; 02125 } 02126 fds[0].fd = s->fd; 02127 fds[0].events = POLLIN; 02128 do { 02129 ast_mutex_lock(&s->__lock); 02130 s->waiting_thread = pthread_self(); 02131 ast_mutex_unlock(&s->__lock); 02132 02133 res = poll(fds, 1, -1); 02134 02135 ast_mutex_lock(&s->__lock); 02136 s->waiting_thread = AST_PTHREADT_NULL; 02137 ast_mutex_unlock(&s->__lock); 02138 if (res < 0) { 02139 if (errno == EINTR) { 02140 return 0; 02141 } 02142 ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno)); 02143 return -1; 02144 } else if (res > 0) { 02145 ast_mutex_lock(&s->__lock); 02146 res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen); 02147 ast_mutex_unlock(&s->__lock); 02148 if (res < 1) 02149 return -1; 02150 break; 02151 } 02152 } while(1); 02153 s->inlen += res; 02154 s->inbuf[s->inlen] = '\0'; 02155 return 0; 02156 }
static int get_perm | ( | const char * | instr | ) | [static] |
Definition at line 807 of file manager.c.
References ast_instring(), and perms.
Referenced by authenticate().
00808 { 00809 int x = 0, ret = 0; 00810 00811 if (!instr) 00812 return 0; 00813 00814 for (x = 0; x < (sizeof(perms) / sizeof(perms[0])); x++) { 00815 if (ast_instring(instr, perms[x].label, ',')) 00816 ret |= perms[x].num; 00817 } 00818 00819 return ret; 00820 }
static int handle_showmanager | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 463 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, and ast_manager_user::write.
00464 { 00465 struct ast_manager_user *user = NULL; 00466 00467 if (argc != 4) 00468 return RESULT_SHOWUSAGE; 00469 00470 AST_LIST_LOCK(&users); 00471 00472 if (!(user = ast_get_manager_by_name_locked(argv[3]))) { 00473 ast_cli(fd, "There is no manager called %s\n", argv[3]); 00474 AST_LIST_UNLOCK(&users); 00475 return -1; 00476 } 00477 00478 ast_cli(fd,"\n"); 00479 ast_cli(fd, 00480 " username: %s\n" 00481 " secret: %s\n" 00482 " deny: %s\n" 00483 " permit: %s\n" 00484 " read: %s\n" 00485 " write: %s\n" 00486 "displayconnects: %s\n", 00487 (user->username ? user->username : "(N/A)"), 00488 (user->secret ? "<Set>" : "(N/A)"), 00489 (user->deny ? user->deny : "(N/A)"), 00490 (user->permit ? user->permit : "(N/A)"), 00491 (user->read ? user->read : "(N/A)"), 00492 (user->write ? user->write : "(N/A)"), 00493 (user->displayconnects ? "yes" : "no")); 00494 00495 AST_LIST_UNLOCK(&users); 00496 00497 return RESULT_SUCCESS; 00498 }
static int handle_showmanagers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 501 of file manager.c.
References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_manager_user::username.
00502 { 00503 struct ast_manager_user *user = NULL; 00504 int count_amu = 0; 00505 00506 if (argc != 3) 00507 return RESULT_SHOWUSAGE; 00508 00509 AST_LIST_LOCK(&users); 00510 00511 /* If there are no users, print out something along those lines */ 00512 if (AST_LIST_EMPTY(&users)) { 00513 ast_cli(fd, "There are no manager users.\n"); 00514 AST_LIST_UNLOCK(&users); 00515 return RESULT_SUCCESS; 00516 } 00517 00518 ast_cli(fd, "\nusername\n--------\n"); 00519 00520 AST_LIST_TRAVERSE(&users, user, list) { 00521 ast_cli(fd, "%s\n", user->username); 00522 count_amu++; 00523 } 00524 00525 AST_LIST_UNLOCK(&users); 00526 00527 ast_cli(fd,"-------------------\n"); 00528 ast_cli(fd,"%d manager users configured.\n", count_amu); 00529 00530 return RESULT_SUCCESS; 00531 }
static int handle_showmancmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 441 of file manager.c.
References manager_action::action, ast_cli(), ast_rwlock_rdlock(), ast_rwlock_unlock(), manager_action::authority, authority_to_str(), manager_action::description, first_action, manager_action::next, RESULT_SHOWUSAGE, RESULT_SUCCESS, and manager_action::synopsis.
00442 { 00443 struct manager_action *cur; 00444 char authority[80]; 00445 int num; 00446 00447 if (argc != 4) 00448 return RESULT_SHOWUSAGE; 00449 00450 ast_rwlock_rdlock(&actionlock); 00451 for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */ 00452 for (num = 3; num < argc; num++) { 00453 if (!strcasecmp(cur->action, argv[num])) { 00454 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 : ""); 00455 } 00456 } 00457 } 00458 ast_rwlock_unlock(&actionlock); 00459 00460 return RESULT_SUCCESS; 00461 }
static int handle_showmancmds | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command Should change to "manager show commands".
Definition at line 536 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.
00537 { 00538 struct manager_action *cur; 00539 char authority[80]; 00540 char *format = " %-15.15s %-15.15s %-55.55s\n"; 00541 00542 ast_cli(fd, format, "Action", "Privilege", "Synopsis"); 00543 ast_cli(fd, format, "------", "---------", "--------"); 00544 00545 ast_rwlock_rdlock(&actionlock); 00546 for (cur = first_action; cur; cur = cur->next) /* Walk the list of actions */ 00547 ast_cli(fd, format, cur->action, authority_to_str(cur->authority, authority, sizeof(authority) -1), cur->synopsis); 00548 ast_rwlock_unlock(&actionlock); 00549 00550 return RESULT_SUCCESS; 00551 }
static int handle_showmanconn | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command show manager connected.
Definition at line 555 of file manager.c.
References ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, format, RESULT_SUCCESS, s, mansession::sin, and mansession::username.
00556 { 00557 struct mansession *s; 00558 char *format = " %-15.15s %-15.15s\n"; 00559 00560 ast_cli(fd, format, "Username", "IP Address"); 00561 00562 AST_LIST_LOCK(&sessions); 00563 AST_LIST_TRAVERSE(&sessions, s, list) 00564 ast_cli(fd, format,s->username, ast_inet_ntoa(s->sin.sin_addr)); 00565 AST_LIST_UNLOCK(&sessions); 00566 00567 return RESULT_SUCCESS; 00568 }
static int handle_showmaneventq | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
CLI command show manager connected.
Definition at line 572 of file manager.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_UNLOCK, eventqent::category, eventqent::eventdata, eventqent::next, RESULT_SUCCESS, s, and eventqent::usecount.
00573 { 00574 struct eventqent *s; 00575 00576 AST_LIST_LOCK(&sessions); 00577 for (s = master_eventq; s; s = s->next) { 00578 ast_cli(fd, "Usecount: %d\n",s->usecount); 00579 ast_cli(fd, "Category: %d\n", s->category); 00580 ast_cli(fd, "Event:\n%s", s->eventdata); 00581 } 00582 AST_LIST_UNLOCK(&sessions); 00583 00584 return RESULT_SUCCESS; 00585 }
static void handle_updates | ( | struct mansession * | s, | |
const struct message * | m, | |||
struct ast_config * | cfg | |||
) | [static] |
Definition at line 1075 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().
01076 { 01077 int x; 01078 char hdr[40]; 01079 const char *action, *cat, *var, *value, *match; 01080 struct ast_category *category; 01081 struct ast_variable *v; 01082 01083 for (x=0;x<100000;x++) { 01084 unsigned int object = 0; 01085 01086 snprintf(hdr, sizeof(hdr), "Action-%06d", x); 01087 action = astman_get_header(m, hdr); 01088 if (ast_strlen_zero(action)) 01089 break; 01090 snprintf(hdr, sizeof(hdr), "Cat-%06d", x); 01091 cat = astman_get_header(m, hdr); 01092 snprintf(hdr, sizeof(hdr), "Var-%06d", x); 01093 var = astman_get_header(m, hdr); 01094 snprintf(hdr, sizeof(hdr), "Value-%06d", x); 01095 value = astman_get_header(m, hdr); 01096 if (!ast_strlen_zero(value) && *value == '>') { 01097 object = 1; 01098 value++; 01099 } 01100 snprintf(hdr, sizeof(hdr), "Match-%06d", x); 01101 match = astman_get_header(m, hdr); 01102 if (!strcasecmp(action, "newcat")) { 01103 if (!ast_strlen_zero(cat)) { 01104 category = ast_category_new(cat); 01105 if (category) { 01106 ast_category_append(cfg, category); 01107 } 01108 } 01109 } else if (!strcasecmp(action, "renamecat")) { 01110 if (!ast_strlen_zero(cat) && !ast_strlen_zero(value)) { 01111 category = ast_category_get(cfg, cat); 01112 if (category) 01113 ast_category_rename(category, value); 01114 } 01115 } else if (!strcasecmp(action, "delcat")) { 01116 if (!ast_strlen_zero(cat)) 01117 ast_category_delete(cfg, (char *) cat); 01118 } else if (!strcasecmp(action, "update")) { 01119 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat))) 01120 ast_variable_update(category, var, value, match, object); 01121 } else if (!strcasecmp(action, "delete")) { 01122 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat))) 01123 ast_variable_delete(category, (char *) var, (char *) match); 01124 } else if (!strcasecmp(action, "append")) { 01125 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && 01126 (category = ast_category_get(cfg, cat)) && 01127 (v = ast_variable_new(var, value))){ 01128 if (object || (match && !strcasecmp(match, "object"))) 01129 v->object = 1; 01130 ast_variable_append(category, v); 01131 } 01132 } 01133 } 01134 }
static char* html_translate | ( | char * | in | ) | [static] |
Definition at line 352 of file manager.c.
References ast_build_string(), ast_malloc, len, and var.
Referenced by generic_http_callback().
00353 { 00354 int x; 00355 int colons = 0; 00356 int breaks = 0; 00357 size_t len; 00358 int count = 1; 00359 char *tmp, *var, *val, *out; 00360 00361 for (x=0; in[x]; x++) { 00362 if (in[x] == ':') 00363 colons++; 00364 if (in[x] == '\n') 00365 breaks++; 00366 } 00367 len = strlen(in) + colons * 40 + breaks * 40; /* <tr><td></td><td></td></tr>, "<tr><td colspan=\"2\"><hr></td></tr> */ 00368 out = ast_malloc(len); 00369 if (!out) 00370 return 0; 00371 tmp = out; 00372 while (*in) { 00373 var = in; 00374 while (*in && (*in >= 32)) 00375 in++; 00376 if (*in) { 00377 if ((count % 4) == 0){ 00378 ast_build_string(&tmp, &len, "<tr><td colspan=\"2\"><hr></td></tr>\r\n"); 00379 } 00380 count = 0; 00381 while (*in && (*in < 32)) { 00382 *in = '\0'; 00383 in++; 00384 count++; 00385 } 00386 val = strchr(var, ':'); 00387 if (val) { 00388 *val = '\0'; 00389 val++; 00390 if (*val == ' ') 00391 val++; 00392 ast_build_string(&tmp, &len, "<tr><td>%s</td><td>%s</td></tr>\r\n", var, val); 00393 } 00394 } 00395 } 00396 return out; 00397 }
int manager_event | ( | int | category, | |
const char * | event, | |||
const char * | fmt, | |||
... | ||||
) |
manager_event: Send AMI event to client
Definition at line 2340 of file manager.c.
References mansession::__lock, 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, s, and mansession::waiting_thread.
Referenced by __expire_registry(), __iax2_poke_noanswer(), __login_exec(), action_agent_callback_login(), action_userevent(), add_to_queue(), agent_logoff_maintenance(), aji_log_hook(), ast_change_name(), ast_channel_alloc(), ast_channel_bridge(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_park_call(), ast_set_callerid(), ast_setstate(), change_hold_state(), changethread(), 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_exec(), parse_register_contact(), pbx_extension_helper(), post_manager_event(), quit_handler(), realtime_exec(), record_abandoned(), register_verify(), reload_config(), 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().
02341 { 02342 struct mansession *s; 02343 char auth[80]; 02344 va_list ap; 02345 struct timeval now; 02346 struct ast_dynamic_str *buf; 02347 02348 /* Abort if there aren't any manager sessions */ 02349 if (!num_sessions) 02350 return 0; 02351 02352 if (!(buf = ast_dynamic_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) 02353 return -1; 02354 02355 ast_dynamic_str_thread_set(&buf, 0, &manager_event_buf, 02356 "Event: %s\r\nPrivilege: %s\r\n", 02357 event, authority_to_str(category, auth, sizeof(auth))); 02358 02359 if (timestampevents) { 02360 now = ast_tvnow(); 02361 ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, 02362 "Timestamp: %ld.%06lu\r\n", 02363 now.tv_sec, (unsigned long) now.tv_usec); 02364 } 02365 02366 va_start(ap, fmt); 02367 ast_dynamic_str_thread_append_va(&buf, 0, &manager_event_buf, fmt, ap); 02368 va_end(ap); 02369 02370 ast_dynamic_str_thread_append(&buf, 0, &manager_event_buf, "\r\n"); 02371 02372 /* Append event to master list and wake up any sleeping sessions */ 02373 AST_LIST_LOCK(&sessions); 02374 append_event(buf->str, category); 02375 AST_LIST_TRAVERSE(&sessions, s, list) { 02376 ast_mutex_lock(&s->__lock); 02377 if (s->waiting_thread != AST_PTHREADT_NULL) 02378 pthread_kill(s->waiting_thread, SIGURG); 02379 ast_mutex_unlock(&s->__lock); 02380 } 02381 AST_LIST_UNLOCK(&sessions); 02382 02383 return 0; 02384 }
static int manager_state_cb | ( | char * | context, | |
char * | exten, | |||
int | state, | |||
void * | data | |||
) | [static] |
Definition at line 2408 of file manager.c.
References EVENT_FLAG_CALL, and manager_event().
Referenced by init_manager().
02409 { 02410 /* Notify managers of change */ 02411 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nStatus: %d\r\n", exten, context, state); 02412 return 0; 02413 }
static int process_events | ( | struct mansession * | s | ) | [static] |
Definition at line 1974 of file manager.c.
References mansession::__lock, ast_carefulwrite(), ast_mutex_lock(), ast_mutex_unlock(), mansession::authenticated, eventqent::category, eventqent::eventdata, mansession::eventq, mansession::fd, eventqent::next, mansession::readperm, mansession::send_events, unuse_eventqent(), and mansession::writetimeout.
Referenced by do_message(), and process_message().
01975 { 01976 struct eventqent *eqe; 01977 int ret = 0; 01978 ast_mutex_lock(&s->__lock); 01979 if (s->fd > -1) { 01980 if (!s->eventq) 01981 s->eventq = master_eventq; 01982 while(s->eventq->next) { 01983 eqe = s->eventq->next; 01984 if ((s->authenticated && (s->readperm & eqe->category) == eqe->category) && 01985 ((s->send_events & eqe->category) == eqe->category)) { 01986 if (!ret && ast_carefulwrite(s->fd, eqe->eventdata, strlen(eqe->eventdata), s->writetimeout) < 0) 01987 ret = -1; 01988 } 01989 unuse_eventqent(s->eventq); 01990 s->eventq = eqe; 01991 } 01992 } 01993 ast_mutex_unlock(&s->__lock); 01994 return ret; 01995 }
static int process_message | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 2022 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(), mansession::authenticated, manager_action::authority, mansession::challenge, first_action, manager_action::func, LOG_DEBUG, LOG_EVENT, manager_action::next, option_debug, option_verbose, process_events(), mansession::sessiontimeout, mansession::sin, mansession::username, VERBOSE_PREFIX_2, and mansession::writeperm.
Referenced by do_message(), and generic_http_callback().
02023 { 02024 char action[80] = ""; 02025 struct manager_action *tmp; 02026 const char *id = astman_get_header(m,"ActionID"); 02027 char idText[256] = ""; 02028 int ret = 0; 02029 02030 ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action)); 02031 if (option_debug) 02032 ast_log( LOG_DEBUG, "Manager received command '%s'\n", action ); 02033 02034 if (ast_strlen_zero(action)) { 02035 astman_send_error(s, m, "Missing action in request"); 02036 return 0; 02037 } 02038 if (!ast_strlen_zero(id)) { 02039 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02040 } 02041 if (!s->authenticated) { 02042 if (!strcasecmp(action, "Challenge")) { 02043 const char *authtype = astman_get_header(m, "AuthType"); 02044 02045 if (!strcasecmp(authtype, "MD5")) { 02046 if (ast_strlen_zero(s->challenge)) 02047 snprintf(s->challenge, sizeof(s->challenge), "%ld", ast_random()); 02048 astman_append(s, "Response: Success\r\n" 02049 "%s" 02050 "Challenge: %s\r\n\r\n", 02051 idText, s->challenge); 02052 return 0; 02053 } else { 02054 astman_send_error(s, m, "Must specify AuthType"); 02055 return 0; 02056 } 02057 } else if (!strcasecmp(action, "Login")) { 02058 if (authenticate(s, m)) { 02059 sleep(1); 02060 astman_send_error(s, m, "Authentication failed"); 02061 return -1; 02062 } else { 02063 s->authenticated = 1; 02064 if (option_verbose > 1) { 02065 if (displayconnects) { 02066 ast_verbose(VERBOSE_PREFIX_2 "%sManager '%s' logged on from %s\n", 02067 (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr)); 02068 } 02069 } 02070 ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", 02071 (s->sessiontimeout ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr)); 02072 astman_send_ack(s, m, "Authentication accepted"); 02073 } 02074 } else if (!strcasecmp(action, "Logoff")) { 02075 astman_send_ack(s, m, "See ya"); 02076 return -1; 02077 } else 02078 astman_send_error(s, m, "Authentication Required"); 02079 } else { 02080 if (!strcasecmp(action, "Login")) 02081 astman_send_ack(s, m, "Already logged in"); 02082 else { 02083 ast_rwlock_rdlock(&actionlock); 02084 for (tmp = first_action; tmp; tmp = tmp->next) { 02085 if (strcasecmp(action, tmp->action)) 02086 continue; 02087 if ((s->writeperm & tmp->authority) == tmp->authority) { 02088 if (tmp->func(s, m)) 02089 ret = -1; 02090 } else 02091 astman_send_error(s, m, "Permission denied"); 02092 break; 02093 } 02094 ast_rwlock_unlock(&actionlock); 02095 if (!tmp) 02096 astman_send_error(s, m, "Invalid/unknown command"); 02097 } 02098 } 02099 if (ret) 02100 return ret; 02101 return process_events(s); 02102 }
static void* session_do | ( | void * | data | ) | [static] |
Definition at line 2188 of file manager.c.
References ast_inet_ntoa(), ast_log(), ast_verbose(), astman_append(), mansession::authenticated, destroy_session(), do_message(), LOG_EVENT, option_verbose, s, mansession::sin, mansession::username, and VERBOSE_PREFIX_2.
Referenced by accept_thread().
02189 { 02190 struct mansession *s = data; 02191 int res; 02192 02193 astman_append(s, "Asterisk Call Manager/1.0\r\n"); 02194 for (;;) { 02195 if ((res = do_message(s)) < 0) 02196 break; 02197 } 02198 if (s->authenticated) { 02199 if (option_verbose > 1) { 02200 if (displayconnects) 02201 ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); 02202 } 02203 ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); 02204 } else { 02205 if (option_verbose > 1) { 02206 if (displayconnects) 02207 ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr)); 02208 } 02209 ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr)); 02210 } 02211 destroy_session(s); 02212 return NULL; 02213 }
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 870 of file manager.c.
References mansession::__lock, ast_mutex_lock(), ast_mutex_unlock(), mansession::send_events, and strings_to_mask().
Referenced by action_events(), and authenticate().
00871 { 00872 int maskint = strings_to_mask(eventmask); 00873 00874 ast_mutex_lock(&s->__lock); 00875 if (maskint >= 0) 00876 s->send_events = maskint; 00877 ast_mutex_unlock(&s->__lock); 00878 00879 return maskint; 00880 }
static int strings_to_mask | ( | const char * | string | ) | [static] |
Definition at line 839 of file manager.c.
References ast_false(), ast_instring(), ast_is_number(), ast_strlen_zero(), ast_true(), and perms.
Referenced by set_eventmask().
00840 { 00841 int x, ret = -1; 00842 00843 x = ast_is_number(string); 00844 00845 if (x) 00846 ret = x; 00847 else if (ast_strlen_zero(string)) 00848 ret = -1; 00849 else if (ast_false(string)) 00850 ret = 0; 00851 else if (ast_true(string)) { 00852 ret = 0; 00853 for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) 00854 ret |= perms[x].num; 00855 } else { 00856 ret = 0; 00857 for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) { 00858 if (ast_instring(string, perms[x].label, ',')) 00859 ret |= perms[x].num; 00860 } 00861 } 00862 00863 return ret; 00864 }
static void unuse_eventqent | ( | struct eventqent * | e | ) | [static] |
Definition at line 660 of file manager.c.
References eventqent::next, and eventqent::usecount.
Referenced by action_waitevent(), free_session(), and process_events().
00661 { 00662 if (ast_atomic_dec_and_test(&e->usecount) && e->next) 00663 pthread_kill(t, SIGURG); 00664 }
static void xml_copy_escape | ( | char ** | dst, | |
size_t * | maxlen, | |||
const char * | src, | |||
int | lower | |||
) | [static] |
Definition at line 240 of file manager.c.
Referenced by xml_translate().
00241 { 00242 while (*src && (*maxlen > 6)) { 00243 switch (*src) { 00244 case '<': 00245 strcpy(*dst, "<"); 00246 (*dst) += 4; 00247 *maxlen -= 4; 00248 break; 00249 case '>': 00250 strcpy(*dst, ">"); 00251 (*dst) += 4; 00252 *maxlen -= 4; 00253 break; 00254 case '\"': 00255 strcpy(*dst, """); 00256 (*dst) += 6; 00257 *maxlen -= 6; 00258 break; 00259 case '\'': 00260 strcpy(*dst, "'"); 00261 (*dst) += 6; 00262 *maxlen -= 6; 00263 break; 00264 case '&': 00265 strcpy(*dst, "&"); 00266 (*dst) += 5; 00267 *maxlen -= 5; 00268 break; 00269 default: 00270 *(*dst)++ = lower ? tolower(*src) : *src; 00271 (*maxlen)--; 00272 } 00273 src++; 00274 } 00275 }
static char* xml_translate | ( | char * | in, | |
struct ast_variable * | vars | |||
) | [static] |
Definition at line 277 of file manager.c.
References ast_build_string(), ast_malloc, len, ast_variable::name, ast_variable::next, ast_variable::value, var, and xml_copy_escape().
Referenced by generic_http_callback().
00278 { 00279 struct ast_variable *v; 00280 char *dest = NULL; 00281 char *out, *tmp, *var, *val; 00282 char *objtype = NULL; 00283 int colons = 0; 00284 int breaks = 0; 00285 size_t len; 00286 int count = 1; 00287 int escaped = 0; 00288 int inobj = 0; 00289 int x; 00290 00291 for (v = vars; v; v = v->next) { 00292 if (!dest && !strcasecmp(v->name, "ajaxdest")) 00293 dest = v->value; 00294 else if (!objtype && !strcasecmp(v->name, "ajaxobjtype")) 00295 objtype = v->value; 00296 } 00297 if (!dest) 00298 dest = "unknown"; 00299 if (!objtype) 00300 objtype = "generic"; 00301 for (x = 0; in[x]; x++) { 00302 if (in[x] == ':') 00303 colons++; 00304 else if (in[x] == '\n') 00305 breaks++; 00306 else if (strchr("&\"<>", in[x])) 00307 escaped++; 00308 } 00309 len = (size_t) (strlen(in) + colons * 5 + breaks * (40 + strlen(dest) + strlen(objtype)) + escaped * 10); /* foo="bar", "<response type=\"object\" id=\"dest\"", "&" */ 00310 out = ast_malloc(len); 00311 if (!out) 00312 return 0; 00313 tmp = out; 00314 while (*in) { 00315 var = in; 00316 while (*in && (*in >= 32)) 00317 in++; 00318 if (*in) { 00319 if ((count > 3) && inobj) { 00320 ast_build_string(&tmp, &len, " /></response>\n"); 00321 inobj = 0; 00322 } 00323 count = 0; 00324 while (*in && (*in < 32)) { 00325 *in = '\0'; 00326 in++; 00327 count++; 00328 } 00329 val = strchr(var, ':'); 00330 if (val) { 00331 *val = '\0'; 00332 val++; 00333 if (*val == ' ') 00334 val++; 00335 if (!inobj) { 00336 ast_build_string(&tmp, &len, "<response type='object' id='%s'><%s", dest, objtype); 00337 inobj = 1; 00338 } 00339 ast_build_string(&tmp, &len, " "); 00340 xml_copy_escape(&tmp, &len, var, 1); 00341 ast_build_string(&tmp, &len, "='"); 00342 xml_copy_escape(&tmp, &len, val, 0); 00343 ast_build_string(&tmp, &len, "'"); 00344 } 00345 } 00346 } 00347 if (inobj) 00348 ast_build_string(&tmp, &len, " /></response>\n"); 00349 return out; 00350 }
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] |
int displayconnects = 1 [static] |
struct manager_action* first_action [static] |
Definition at line 196 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 |
int num_sessions [static] |
Referenced by authority_to_str(), get_perm(), and strings_to_mask().
int portno = DEFAULT_MANAGER_PORT [static] |
Definition at line 97 of file manager.c.
Referenced by ast_netsock_bind(), create_addr(), 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 103 of file manager.c.
Referenced by __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_build_path(), ast_verbose(), background_detect_exec(), build_mapping(), byteReverse(), callerid_genmsg(), callerid_getcarrier(), cb_events(), cdr_get_tv(), check_switch_expr(), check_user_full(), cli_prompt(), config_text_file_save(), destroy(), do_monitor(), does_peer_need_mwi(), dump_cmd_queues(), expr2_token_subst(), gen_match_to_pattern(), gen_tone(), gen_tones(), get_date(), get_trans_id(), handle_bchan(), handle_enbloc_call_message(), handle_hd_hf(), handle_offhook_message(), handle_save_dialplan(), handle_soft_key_event_message(), handle_stimulus_message(), iax2_datetime(), iax2_process_thread(), iax2_show_threads(), iax_template_parse(), launch_service(), listener(), local_new(), localsub(), lws2sws(), manager_log(), MD5Update(), osp_create_provider(), osp_load(), packdate(), parse_moved_contact(), pgsql_log(), play_message_datetime(), prune_gateways(), rebuild_matrix(), register_verify(), send_request(), SHA1ProcessMessageBlock(), socket_read(), sqlite_log(), statechange_queue(), strip_quotes(), tdd_getcarrier(), time1(), time2(), transmit_notify_request_with_callerid(), transmit_notify_with_mwi(), transmit_state_notify(), vmu_tm(), and write_metadata().
int timestampevents [static] |