Data Structures | |
| struct | ast_manager_user |
| struct | eventqent |
| struct | fast_originate_helper |
| struct | mansession |
| struct | permalias |
| struct | variable_count |
Defines | |
| #define | ASTMAN_APPEND_BUF_INITSIZE 256 |
| #define | MANAGER_EVENT_BUF_INITSIZE 256 |
| #define | MAX_BLACKLIST_CMD_LEN 2 |
Functions | |
| static void * | accept_thread (void *ignore) |
| static int | action_command (struct mansession *s, const struct message *m) |
| action_command: Manager command "command" - execute CLI command | |
| static int | action_events (struct mansession *s, const struct message *m) |
| static int | action_extensionstate (struct mansession *s, const struct message *m) |
| static int | action_getconfig (struct mansession *s, const struct message *m) |
| static int | action_getvar (struct mansession *s, const struct message *m) |
| static int | action_hangup (struct mansession *s, const struct message *m) |
| static int | action_listcommands (struct mansession *s, const struct message *m) |
| static int | action_logoff (struct mansession *s, const struct message *m) |
| static int | action_mailboxcount (struct mansession *s, const struct message *m) |
| static int | action_mailboxstatus (struct mansession *s, const struct message *m) |
| static int | action_originate (struct mansession *s, const struct message *m) |
| static int | action_ping (struct mansession *s, const struct message *m) |
| static int | action_redirect (struct mansession *s, const struct message *m) |
| action_redirect: The redirect manager command | |
| static int | action_setvar (struct mansession *s, const struct message *m) |
| static int | action_status (struct mansession *s, const struct message *m) |
| Manager "status" command to show channels. | |
| static int | action_timeout (struct mansession *s, const struct message *m) |
| static int | action_updateconfig (struct mansession *s, const struct message *m) |
| static int | action_userevent (struct mansession *s, const struct message *m) |
| static int | action_waitevent (struct mansession *s, const struct message *m) |
| static int | append_event (const char *str, int category) |
| static struct ast_manager_user * | ast_get_manager_by_name_locked (const char *name) |
| static int | ast_instring (const char *bigstr, const char *smallstr, char delim) |
| static int | ast_is_number (const char *string) |
| static | AST_LIST_HEAD_STATIC (users, ast_manager_user) |
| static | AST_LIST_HEAD_STATIC (sessions, mansession) |
| int | ast_manager_register2 (const char *action, int auth, int(*func)(struct mansession *s, const struct message *m), const char *synopsis, const char *description) |
| register a new command with manager, including online help. This is the preferred way to register a manager command | |
| static int | ast_manager_register_struct (struct manager_action *act) |
| int | ast_manager_unregister (char *action) |
| AST_RWLOCK_DEFINE_STATIC (actionlock) | |
| AST_THREADSTORAGE (astman_append_buf, astman_append_buf_init) | |
| AST_THREADSTORAGE (manager_event_buf, manager_event_buf_init) | |
| void | astman_append (struct mansession *s, const char *fmt,...) |
| const char * | astman_get_header (const struct message *m, char *var) |
| ast_variable * | astman_get_variables (const struct message *m) |
| void | astman_send_ack (struct mansession *s, const struct message *m, char *msg) |
| void | astman_send_error (struct mansession *s, const struct message *m, char *error) |
| void | astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg) |
| static int | authenticate (struct mansession *s, const struct message *m) |
| static char * | authority_to_str (int authority, char *res, int reslen) |
| Convert authority code to string with serveral options. | |
| static int | check_blacklist (const char *cmd) |
| static char * | complete_show_mancmd (const char *line, const char *word, int pos, int state) |
| static int | compress_char (char c) |
| static void | destroy_session (struct mansession *s) |
| static int | do_message (struct mansession *s) |
| static void * | fast_originate (void *data) |
| static void | free_session (struct mansession *s) |
| static int | get_input (struct mansession *s, char *output) |
| static int | get_perm (const char *instr) |
| static int | handle_showmanager (int fd, int argc, char *argv[]) |
| static int | handle_showmanagers (int fd, int argc, char *argv[]) |
| static int | handle_showmancmd (int fd, int argc, char *argv[]) |
| static int | handle_showmancmds (int fd, int argc, char *argv[]) |
| CLI command Should change to "manager show commands". | |
| static int | handle_showmanconn (int fd, int argc, char *argv[]) |
| CLI command show manager connected. | |
| static int | handle_showmaneventq (int fd, int argc, char *argv[]) |
| CLI command show manager connected. | |
| static void | handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg) |
| static char * | html_translate (char *in) |
| int | manager_event (int category, const char *event, const char *fmt,...) |
| manager_event: Send AMI event to client | |
| static int | manager_state_cb (char *context, char *exten, int state, void *data) |
| static int | process_events (struct mansession *s) |
| static int | process_message (struct mansession *s, const struct message *m) |
| static void * | session_do (void *data) |
| static int | set_eventmask (struct mansession *s, const char *eventmask) |
| Rather than braindead on,off this now can also accept a specific int mask value or a ',' delim list of mask strings (the same as manager.conf) -anthm. | |
| static int | strings_to_mask (const char *string) |
| static void | unuse_eventqent (struct eventqent *e) |
| static int | variable_count_cmp_fn (void *obj, void *vstr, int flags) |
| static int | variable_count_hash_fn (const void *vvc, const int flags) |
| static void | xml_copy_escape (char **dst, size_t *maxlen, const char *src, int lower) |
| static char * | xml_translate (char *in, struct ast_variable *vars) |
Variables | |
| static int | asock = -1 |
| static int | block_sockets |
| static struct ast_cli_entry | cli_manager [] |
| static struct ast_cli_entry | cli_show_manager_command_deprecated |
| static struct ast_cli_entry | cli_show_manager_commands_deprecated |
| static struct ast_cli_entry | cli_show_manager_connected_deprecated |
| static struct ast_cli_entry | cli_show_manager_eventq_deprecated |
| struct { | |
| char * words [AST_MAX_CMD_LEN] | |
| } | command_blacklist [] |
| static int | displayconnects = 1 |
| static int | enabled |
| static struct manager_action * | first_action |
| static int | httptimeout = 60 |
| static char | mandescr_command [] |
| static char | mandescr_events [] |
| static char | mandescr_extensionstate [] |
| static char | mandescr_getconfig [] |
| static char | mandescr_getvar [] |
| static char | mandescr_hangup [] |
| static char | mandescr_listcommands [] |
| static char | mandescr_logoff [] |
| static char | mandescr_mailboxcount [] |
| static char | mandescr_mailboxstatus [] |
| Help text for manager command mailboxstatus. | |
| static char | mandescr_originate [] |
| static char | mandescr_ping [] |
| Manager PING. | |
| static char | mandescr_redirect [] |
| static char | mandescr_setvar [] |
| static char | mandescr_timeout [] |
| static char | mandescr_updateconfig [] |
| static char | mandescr_userevent [] |
| static char | mandescr_waitevent [] |
| Manager WAITEVENT. | |
| eventqent * | master_eventq = NULL |
| static int | num_sessions |
| static struct permalias | perms [] |
| static int | portno = DEFAULT_MANAGER_PORT |
| static char | showmanager_help [] |
| static char | showmanagers_help [] |
| static char | showmancmd_help [] |
| static char | showmancmds_help [] |
| static char | showmanconn_help [] |
| static char | showmaneventq_help [] |
| static pthread_t | t |
| static int | timestampevents |
| #define ASTMAN_APPEND_BUF_INITSIZE 256 |
| #define MANAGER_EVENT_BUF_INITSIZE 256 |
| #define MAX_BLACKLIST_CMD_LEN 2 |
| static void* accept_thread | ( | void * | ignore | ) | [static] |
Definition at line 2360 of file manager.c.
References asock, ast_calloc, ast_inet_ntoa(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), ast_pthread_create_background, AST_PTHREADT_NULL, ast_verbose(), block_sockets, destroy_session(), displayconnects, errno, pollfd::events, pollfd::fd, ast_channel::flags, free, free_session(), LOG_WARNING, master_eventq, eventqent::next, num_sessions, option_verbose, poll(), POLLIN, s, session_do(), sessions, eventqent::usecount, and VERBOSE_PREFIX_2.
Referenced by reload_config().
02361 { 02362 int as; 02363 struct sockaddr_in sin; 02364 socklen_t sinlen; 02365 struct eventqent *eqe; 02366 struct mansession *s; 02367 struct protoent *p; 02368 int arg = 1; 02369 int flags; 02370 pthread_attr_t attr; 02371 time_t now; 02372 struct pollfd pfds[1]; 02373 02374 pthread_attr_init(&attr); 02375 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02376 02377 for (;;) { 02378 time(&now); 02379 AST_LIST_LOCK(&sessions); 02380 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) { 02381 if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) { 02382 AST_LIST_REMOVE_CURRENT(&sessions, list); 02383 num_sessions--; 02384 if (s->authenticated && (option_verbose > 1) && displayconnects) { 02385 ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' timed out from %s\n", 02386 s->username, ast_inet_ntoa(s->sin.sin_addr)); 02387 } 02388 free_session(s); 02389 break; 02390 } 02391 } 02392 AST_LIST_TRAVERSE_SAFE_END 02393 /* Purge master event queue of old, unused events, but make sure we 02394 always keep at least one in the queue */ 02395 eqe = master_eventq; 02396 while (master_eventq->next && !master_eventq->usecount) { 02397 eqe = master_eventq; 02398 master_eventq = master_eventq->next; 02399 free(eqe); 02400 } 02401 AST_LIST_UNLOCK(&sessions); 02402 02403 sinlen = sizeof(sin); 02404 pfds[0].fd = asock; 02405 pfds[0].events = POLLIN; 02406 /* Wait for something to happen, but timeout every few seconds so 02407 we can ditch any old manager sessions */ 02408 if (poll(pfds, 1, 5000) < 1) 02409 continue; 02410 as = accept(asock, (struct sockaddr *)&sin, &sinlen); 02411 if (as < 0) { 02412 ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno)); 02413 continue; 02414 } 02415 p = getprotobyname("tcp"); 02416 if (p) { 02417 if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { 02418 ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno)); 02419 } 02420 } 02421 if (!(s = ast_calloc(1, sizeof(*s)))) 02422 continue; 02423 02424 memcpy(&s->sin, &sin, sizeof(sin)); 02425 s->writetimeout = 100; 02426 s->waiting_thread = AST_PTHREADT_NULL; 02427 02428 if (!block_sockets) { 02429 /* For safety, make sure socket is non-blocking */ 02430 flags = fcntl(as, F_GETFL); 02431 fcntl(as, F_SETFL, flags | O_NONBLOCK); 02432 } else { 02433 flags = fcntl(as, F_GETFL); 02434 fcntl(as, F_SETFL, flags & ~O_NONBLOCK); 02435 } 02436 ast_mutex_init(&s->__lock); 02437 s->fd = as; 02438 s->send_events = -1; 02439 AST_LIST_LOCK(&sessions); 02440 AST_LIST_INSERT_HEAD(&sessions, s, list); 02441 num_sessions++; 02442 /* Find the last place in the master event queue and hook ourselves 02443 in there */ 02444 s->eventq = master_eventq; 02445 while(s->eventq->next) 02446 s->eventq = s->eventq->next; 02447 ast_atomic_fetchadd_int(&s->eventq->usecount, 1); 02448 AST_LIST_UNLOCK(&sessions); 02449 if (ast_pthread_create_background(&s->t, &attr, session_do, s)) 02450 destroy_session(s); 02451 } 02452 pthread_attr_destroy(&attr); 02453 return NULL; 02454 }
| static int action_command | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
action_command: Manager command "command" - execute CLI command
Definition at line 1730 of file manager.c.
References ast_calloc, ast_cli_command(), ast_free, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), check_blacklist(), s, S_OR, and term_strip().
Referenced by init_manager().
01731 { 01732 const char *cmd = astman_get_header(m, "Command"); 01733 const char *id = astman_get_header(m, "ActionID"); 01734 char *buf, *final_buf; 01735 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 01736 int fd = mkstemp(template); 01737 off_t l; 01738 01739 if (ast_strlen_zero(cmd)) { 01740 astman_send_error(s, m, "No command provided"); 01741 return 0; 01742 } 01743 01744 if (check_blacklist(cmd)) { 01745 astman_send_error(s, m, "Command blacklisted"); 01746 return 0; 01747 } 01748 01749 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 01750 if (!ast_strlen_zero(id)) 01751 astman_append(s, "ActionID: %s\r\n", id); 01752 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 01753 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 01754 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 01755 01756 /* This has a potential to overflow the stack. Hence, use the heap. */ 01757 buf = ast_calloc(1, l + 1); 01758 final_buf = ast_calloc(1, l + 1); 01759 if (buf) { 01760 lseek(fd, 0, SEEK_SET); 01761 read(fd, buf, l); 01762 buf[l] = '\0'; 01763 if (final_buf) { 01764 term_strip(final_buf, buf, l); 01765 final_buf[l] = '\0'; 01766 } 01767 astman_append(s, "%s", S_OR(final_buf, buf)); 01768 ast_free(buf); 01769 } 01770 close(fd); 01771 unlink(template); 01772 astman_append(s, "--END COMMAND--\r\n\r\n"); 01773 if (final_buf) 01774 ast_free(final_buf); 01775 return 0; 01776 }
| static int action_events | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1386 of file manager.c.
References astman_get_header(), astman_send_response(), s, and set_eventmask().
Referenced by init_manager().
01387 { 01388 const char *mask = astman_get_header(m, "EventMask"); 01389 int res; 01390 01391 res = set_eventmask(s, mask); 01392 if (res > 0) 01393 astman_send_response(s, m, "Events On", NULL); 01394 else if (res == 0) 01395 astman_send_response(s, m, "Events Off", NULL); 01396 01397 return 0; 01398 }
| static int action_extensionstate | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2036 of file manager.c.
References ast_extension_state(), ast_get_hint(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), context, exten, and s.
Referenced by init_manager().
02037 { 02038 const char *exten = astman_get_header(m, "Exten"); 02039 const char *context = astman_get_header(m, "Context"); 02040 const char *id = astman_get_header(m,"ActionID"); 02041 char idText[256] = ""; 02042 char hint[256] = ""; 02043 int status; 02044 if (ast_strlen_zero(exten)) { 02045 astman_send_error(s, m, "Extension not specified"); 02046 return 0; 02047 } 02048 if (ast_strlen_zero(context)) 02049 context = "default"; 02050 status = ast_extension_state(NULL, context, exten); 02051 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 02052 if (!ast_strlen_zero(id)) { 02053 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 02054 } 02055 astman_append(s, "Response: Success\r\n" 02056 "%s" 02057 "Message: Extension Status\r\n" 02058 "Exten: %s\r\n" 02059 "Context: %s\r\n" 02060 "Hint: %s\r\n" 02061 "Status: %d\r\n\r\n", 02062 idText,exten, context, hint, status); 02063 return 0; 02064 }
| static int action_getconfig | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1115 of file manager.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load_with_comments(), ast_strlen_zero(), ast_variable_browse(), astman_append(), astman_get_header(), astman_send_error(), lineno, ast_variable::name, ast_variable::next, s, and ast_variable::value.
Referenced by init_manager().
01116 { 01117 struct ast_config *cfg; 01118 const char *fn = astman_get_header(m, "Filename"); 01119 int catcount = 0; 01120 int lineno = 0; 01121 char *category=NULL; 01122 struct ast_variable *v; 01123 char idText[256] = ""; 01124 const char *id = astman_get_header(m, "ActionID"); 01125 01126 if (!ast_strlen_zero(id)) 01127 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01128 01129 if (ast_strlen_zero(fn)) { 01130 astman_send_error(s, m, "Filename not specified"); 01131 return 0; 01132 } 01133 if (!(cfg = ast_config_load_with_comments(fn))) { 01134 astman_send_error(s, m, "Config file not found"); 01135 return 0; 01136 } 01137 astman_append(s, "Response: Success\r\n%s", idText); 01138 while ((category = ast_category_browse(cfg, category))) { 01139 lineno = 0; 01140 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 01141 for (v = ast_variable_browse(cfg, category); v; v = v->next) 01142 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 01143 catcount++; 01144 } 01145 ast_config_destroy(cfg); 01146 astman_append(s, "\r\n"); 01147 01148 return 0; 01149 }
| static int action_getvar | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1478 of file manager.c.
References ast_channel_unlock, ast_func_read(), ast_get_channel_by_name_locked(), ast_strdupa, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), copy(), name, pbx_retrieve_variable(), and s.
Referenced by init_manager().
01479 { 01480 struct ast_channel *c = NULL; 01481 const char *name = astman_get_header(m, "Channel"); 01482 const char *varname = astman_get_header(m, "Variable"); 01483 const char *id = astman_get_header(m,"ActionID"); 01484 char *varval; 01485 char workspace[1024] = ""; 01486 01487 if (ast_strlen_zero(varname)) { 01488 astman_send_error(s, m, "No variable specified"); 01489 return 0; 01490 } 01491 01492 if (!ast_strlen_zero(name)) { 01493 c = ast_get_channel_by_name_locked(name); 01494 if (!c) { 01495 astman_send_error(s, m, "No such channel"); 01496 return 0; 01497 } 01498 } 01499 01500 if (varname[strlen(varname) - 1] == ')') { 01501 char *copy = ast_strdupa(varname); 01502 01503 ast_func_read(c, copy, workspace, sizeof(workspace)); 01504 varval = workspace; 01505 } else { 01506 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 01507 } 01508 01509 if (c) 01510 ast_channel_unlock(c); 01511 astman_append(s, "Response: Success\r\n" 01512 "Variable: %s\r\nValue: %s\r\n", varname, varval); 01513 if (!ast_strlen_zero(id)) 01514 astman_append(s, "ActionID: %s\r\n",id); 01515 astman_append(s, "\r\n"); 01516 01517 return 0; 01518 }
| static int action_hangup | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1415 of file manager.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, and s.
Referenced by init_manager().
01416 { 01417 struct ast_channel *c = NULL; 01418 const char *name = astman_get_header(m, "Channel"); 01419 if (ast_strlen_zero(name)) { 01420 astman_send_error(s, m, "No channel specified"); 01421 return 0; 01422 } 01423 c = ast_get_channel_by_name_locked(name); 01424 if (!c) { 01425 astman_send_error(s, m, "No such channel"); 01426 return 0; 01427 } 01428 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01429 ast_channel_unlock(c); 01430 astman_send_ack(s, m, "Channel Hungup"); 01431 return 0; 01432 }
| static int action_listcommands | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1359 of file manager.c.
References manager_action::action, ast_strlen_zero(), astman_append(), astman_get_header(), manager_action::authority, authority_to_str(), first_action, manager_action::next, s, and manager_action::synopsis.
Referenced by init_manager().
01360 { 01361 struct manager_action *cur; 01362 char idText[256] = ""; 01363 char temp[BUFSIZ]; 01364 const char *id = astman_get_header(m,"ActionID"); 01365 01366 if (!ast_strlen_zero(id)) 01367 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01368 astman_append(s, "Response: Success\r\n%s", idText); 01369 for (cur = first_action; cur; cur = cur->next) { 01370 if ((s->writeperm & cur->authority) == cur->authority) 01371 astman_append(s, "%s: %s (Priv: %s)\r\n", cur->action, cur->synopsis, authority_to_str(cur->authority, temp, sizeof(temp))); 01372 } 01373 astman_append(s, "\r\n"); 01374 01375 return 0; 01376 }
| static int action_logoff | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1404 of file manager.c.
References astman_send_response(), and s.
Referenced by init_manager().
01405 { 01406 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 01407 return -1; 01408 }
| static int action_mailboxcount | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 2000 of file manager.c.
References ast_app_inboxcount(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), mailbox, and s.
Referenced by init_manager().
02001 { 02002 const char *mailbox = astman_get_header(m, "Mailbox"); 02003 const char *id = astman_get_header(m,"ActionID"); 02004 char idText[256] = ""; 02005 int newmsgs = 0, oldmsgs = 0; 02006 if (ast_strlen_zero(mailbox)) { 02007 astman_send_error(s, m, "Mailbox not specified"); 02008 return 0; 02009 } 02010 ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs); 02011 if (!ast_strlen_zero(id)) { 02012 snprintf(idText, sizeof(idText), "ActionID: %s\r\n",id); 02013 } 02014 astman_append(s, "Response: Success\r\n" 02015 "%s" 02016 "Message: Mailbox Message Count\r\n" 02017 "Mailbox: %s\r\n" 02018 "NewMessages: %d\r\n" 02019 "OldMessages: %d\r\n" 02020 "\r\n", 02021 idText,mailbox, newmsgs, oldmsgs); 02022 return 0; 02023 }
| static int action_mailboxstatus | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1968 of file manager.c.
References ast_app_has_voicemail(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), mailbox, and s.
Referenced by init_manager().
01969 { 01970 const char *mailbox = astman_get_header(m, "Mailbox"); 01971 const char *id = astman_get_header(m,"ActionID"); 01972 char idText[256] = ""; 01973 int ret; 01974 if (ast_strlen_zero(mailbox)) { 01975 astman_send_error(s, m, "Mailbox not specified"); 01976 return 0; 01977 } 01978 if (!ast_strlen_zero(id)) 01979 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01980 ret = ast_app_has_voicemail(mailbox, NULL); 01981 astman_append(s, "Response: Success\r\n" 01982 "%s" 01983 "Message: Mailbox Status\r\n" 01984 "Mailbox: %s\r\n" 01985 "Waiting: %d\r\n\r\n", idText, mailbox, ret); 01986 return 0; 01987 }
| static int action_originate | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 1842 of file manager.c.
References app, ast_callerid_parse(), ast_calloc, ast_findlabel_extension(), AST_FORMAT_SLINEAR, ast_free, ast_parse_allow_disallow(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pthread_create, ast_shrink_phone_number(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), context, ast_channel::data, exten, fast_originate(), format, name, ast_channel::priority, s, and ast_channel::tech.
Referenced by init_manager().
01843 { 01844 const char *name = astman_get_header(m, "Channel"); 01845 const char *exten = astman_get_header(m, "Exten"); 01846 const char *context = astman_get_header(m, "Context"); 01847 const char *priority = astman_get_header(m, "Priority"); 01848 const char *timeout = astman_get_header(m, "Timeout"); 01849 const char *callerid = astman_get_header(m, "CallerID"); 01850 const char *account = astman_get_header(m, "Account"); 01851 const char *app = astman_get_header(m, "Application"); 01852 const char *appdata = astman_get_header(m, "Data"); 01853 const char *async = astman_get_header(m, "Async"); 01854 const char *id = astman_get_header(m, "ActionID"); 01855 const char *codecs = astman_get_header(m, "Codecs"); 01856 struct ast_variable *vars = astman_get_variables(m); 01857 char *tech, *data; 01858 char *l = NULL, *n = NULL; 01859 int pi = 0; 01860 int res; 01861 int to = 30000; 01862 int reason = 0; 01863 char tmp[256]; 01864 char tmp2[256]; 01865 int format = AST_FORMAT_SLINEAR; 01866 01867 pthread_t th; 01868 pthread_attr_t attr; 01869 if (!name) { 01870 astman_send_error(s, m, "Channel not specified"); 01871 return 0; 01872 } 01873 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 01874 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 01875 astman_send_error(s, m, "Invalid priority"); 01876 return 0; 01877 } 01878 } 01879 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) { 01880 astman_send_error(s, m, "Invalid timeout"); 01881 return 0; 01882 } 01883 ast_copy_string(tmp, name, sizeof(tmp)); 01884 tech = tmp; 01885 data = strchr(tmp, '/'); 01886 if (!data) { 01887 astman_send_error(s, m, "Invalid channel"); 01888 return 0; 01889 } 01890 *data++ = '\0'; 01891 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 01892 ast_callerid_parse(tmp2, &n, &l); 01893 if (n) { 01894 if (ast_strlen_zero(n)) 01895 n = NULL; 01896 } 01897 if (l) { 01898 ast_shrink_phone_number(l); 01899 if (ast_strlen_zero(l)) 01900 l = NULL; 01901 } 01902 if (!ast_strlen_zero(codecs)) { 01903 format = 0; 01904 ast_parse_allow_disallow(NULL, &format, codecs, 1); 01905 } 01906 if (ast_true(async)) { 01907 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 01908 if (!fast) { 01909 res = -1; 01910 } else { 01911 if (!ast_strlen_zero(id)) 01912 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s\r\n", id); 01913 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 01914 ast_copy_string(fast->data, data, sizeof(fast->data)); 01915 ast_copy_string(fast->app, app, sizeof(fast->app)); 01916 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 01917 if (l) 01918 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 01919 if (n) 01920 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 01921 fast->vars = vars; 01922 ast_copy_string(fast->context, context, sizeof(fast->context)); 01923 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 01924 ast_copy_string(fast->account, account, sizeof(fast->account)); 01925 fast->format = format; 01926 fast->timeout = to; 01927 fast->priority = pi; 01928 pthread_attr_init(&attr); 01929 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01930 if (ast_pthread_create(&th, &attr, fast_originate, fast)) { 01931 ast_free(fast); 01932 res = -1; 01933 } else { 01934 res = 0; 01935 } 01936 pthread_attr_destroy(&attr); 01937 } 01938 } else if (!ast_strlen_zero(app)) { 01939 res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 01940 } else { 01941 if (exten && context && pi) 01942 res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 01943 else { 01944 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 01945 return 0; 01946 } 01947 } 01948 if (!res) 01949 astman_send_ack(s, m, "Originate successfully queued"); 01950 else 01951 astman_send_error<