![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
AMI functions
Data Structures | |
| struct | ast_manager_user |
| user descriptor, as read from the config file. More... | |
| struct | eventqent |
| struct | fast_originate_helper |
| struct | mansession |
| struct | permalias |
Defines | |
| #define | ASTMAN_APPEND_BUF_INITSIZE 256 |
| #define | MANAGER_EVENT_BUF_INITSIZE 256 |
| #define | MSG_MOREDATA ((char *)astman_send_response) |
| send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field. | |
| #define | NEW_EVENT(m) (AST_LIST_NEXT(m->last_ev, eq_next)) |
Functions | |
| int | __manager_event (int category, const char *event, const char *file, int line, const char *func, const char *fmt,...) |
| manager_event: Send AMI event to client | |
| static int | action_challenge (struct mansession *s, const struct message *m) |
| static int | action_command (struct mansession *s, const struct message *m) |
| 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_login (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_sendtext (struct mansession *s, const struct message *m) |
| 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 int | ast_instring (const char *bigstr, const char *smallstr, const char delim) |
| static | AST_LIST_HEAD_STATIC (users, ast_manager_user) |
| list of users found in the config file | |
| static | AST_LIST_HEAD_STATIC (sessions, mansession) |
| static | AST_LIST_HEAD_STATIC (all_events, eventqent) |
| 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 | |
| void | ast_manager_register_hook (struct manager_custom_hook *hook) |
| Add a custom hook to be called when an event is fired. | |
| static int | ast_manager_register_struct (struct manager_action *act) |
| int | ast_manager_unregister (char *action) |
| void | ast_manager_unregister_hook (struct manager_custom_hook *hook) |
| Delete a custom hook to be called when an event is fired. | |
| static | AST_RWLIST_HEAD_STATIC (manager_hooks, manager_custom_hook) |
| AST_RWLOCK_DEFINE_STATIC (actionlock) | |
| AST_THREADSTORAGE (manager_event_buf) | |
| AST_THREADSTORAGE (astman_append_buf) | |
| 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_listack (struct mansession *s, const struct message *m, char *msg, char *listflag) |
| void | astman_send_response (struct mansession *s, const struct message *m, char *resp, char *msg) |
| static void | astman_send_response_full (struct mansession *s, const struct message *m, char *resp, char *msg, char *listflag) |
| static void | astman_start_ack (struct mansession *s, const struct message *m) |
| static int | authenticate (struct mansession *s, const struct message *m) |
| static char * | authority_to_str (int authority, struct ast_str **res) |
| Convert authority code to a list of 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 struct ast_manager_user * | get_manager_by_name_locked (const char *name) |
| static int | get_perm (const char *instr) |
| static struct eventqent * | grab_last (void) |
| Event list management functions. We assume that the event list always has at least one element, and the delete code will not remove the last entry even if the. | |
| static int | handle_mandebug (int fd, int argc, char *argv[]) |
| 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 manager list commands. | |
| static int | handle_showmanconn (int fd, int argc, char *argv[]) |
| CLI command manager list connected. | |
| static int | handle_showmaneventq (int fd, int argc, char *argv[]) |
| CLI command manager list eventq. | |
| static void | handle_updates (struct mansession *s, const struct message *m, struct ast_config *cfg) |
| 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 | purge_events (void) |
| static void | purge_sessions (int n_max) |
| remove at most n_max stale session from the list. | |
| static void | ref_event (struct eventqent *e) |
| static int | send_string (struct mansession *s, char *string) |
| static void * | session_do (void *data) |
| The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ). | |
| 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 struct eventqent * | unref_event (struct eventqent *e) |
Variables | |
| static int | block_sockets |
| static struct ast_cli_entry | cli_manager [] |
| static int | displayconnects = 1 |
| static struct manager_action * | first_action |
| list of actions registered | |
| static int | httptimeout = 60 |
| static int | manager_debug |
| 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_sendtext [] |
| static char | mandescr_setvar [] |
| static char | mandescr_timeout [] |
| static char | mandescr_updateconfig [] |
| static char | mandescr_userevent [] |
| static char | mandescr_waitevent [] |
| Manager WAITEVENT. | |
| static int | num_sessions |
| static struct permalias | perms [] |
| 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 int | timestampevents |
|
|
Definition at line 756 of file manager.c. Referenced by astman_append(). |
|
|
Definition at line 2318 of file manager.c. Referenced by __manager_event(). |
|
|
send a response with an optional message, and terminate it with an empty line. m is used only to grab the 'ActionID' field. Use the explicit constant MSG_MOREDATA to remove the empty line. XXX MSG_MOREDATA should go to a header file. Definition at line 795 of file manager.c. Referenced by astman_send_response_full(), and astman_start_ack(). |
|
|
Definition at line 151 of file manager.c. Referenced by action_waitevent(), and process_events(). |
|
||||||||||||||||||||||||||||||||
|
manager_event: Send AMI event to client
Definition at line 2321 of file manager.c. References append_event(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_RWLIST_EMPTY, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_alloca, ast_str_append(), ast_str_append_va, authority_to_str(), manager_custom_hook::helper, manager_debug, MANAGER_EVENT_BUF_INITSIZE, num_sessions, s, seq, sessions, ast_str::str, and timestampevents. 02323 { 02324 struct mansession *s; 02325 struct manager_custom_hook *hook; 02326 struct ast_str *auth = ast_str_alloca(80); 02327 const char *cat_str; 02328 va_list ap; 02329 struct timeval now; 02330 struct ast_str *buf; 02331 02332 /* Abort if there aren't any manager sessions */ 02333 if (!num_sessions) 02334 return 0; 02335 02336 if (!(buf = ast_str_thread_get(&manager_event_buf, MANAGER_EVENT_BUF_INITSIZE))) 02337 return -1; 02338 02339 cat_str = authority_to_str(category, &auth); 02340 ast_str_set(&buf, 0, 02341 "Event: %s\r\nPrivilege: %s\r\n", 02342 event, cat_str); 02343 02344 if (timestampevents) { 02345 now = ast_tvnow(); 02346 ast_str_append(&buf, 0, 02347 "Timestamp: %ld.%06lu\r\n", 02348 now.tv_sec, (unsigned long) now.tv_usec); 02349 } 02350 if (manager_debug) { 02351 static int seq; 02352 ast_str_append(&buf, 0, 02353 "SequenceNumber: %d\r\n", 02354 ast_atomic_fetchadd_int(&seq, 1)); 02355 ast_str_append(&buf, 0, 02356 "File: %s\r\nLine: %d\r\nFunc: %s\r\n", file, line, func); 02357 } 02358 02359 va_start(ap, fmt); 02360 ast_str_append_va(&buf, 0, fmt, ap); 02361 va_end(ap); 02362 02363 ast_str_append(&buf, 0, "\r\n"); 02364 02365 append_event(buf->str, category); 02366 02367 /* Wake up any sleeping sessions */ 02368 AST_LIST_LOCK(&sessions); 02369 AST_LIST_TRAVERSE(&sessions, s, list) { 02370 ast_mutex_lock(&s->__lock); 02371 if (s->waiting_thread != AST_PTHREADT_NULL) 02372 pthread_kill(s->waiting_thread, SIGURG); 02373 ast_mutex_unlock(&s->__lock); 02374 } 02375 AST_LIST_UNLOCK(&sessions); 02376 02377 AST_RWLIST_RDLOCK(&manager_hooks); 02378 if (!AST_RWLIST_EMPTY(&manager_hooks)) { 02379 AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) { 02380 hook->helper(category, event, buf->str); 02381 } 02382 } 02383 AST_RWLIST_UNLOCK(&manager_hooks); 02384 02385 return 0; 02386 }
|
|
||||||||||||
|
Definition at line 1326 of file manager.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), and s. Referenced by init_manager(). 01327 { 01328 const char *authtype = astman_get_header(m, "AuthType"); 01329 01330 if (!strcasecmp(authtype, "MD5")) { 01331 if (ast_strlen_zero(s->challenge)) 01332 snprintf(s->challenge, sizeof(s->challenge), "%ld", ast_random()); 01333 ast_mutex_lock(&s->__lock); 01334 astman_start_ack(s, m); 01335 astman_append(s, "Challenge: %s\r\n\r\n", s->challenge); 01336 ast_mutex_unlock(&s->__lock); 01337 } else { 01338 astman_send_error(s, m, "Must specify AuthType"); 01339 } 01340 return 0; 01341 }
|
|
||||||||||||
|
Manager command "command" - execute CLI command.
Definition at line 1653 of file manager.c. References ast_cli_command(), ast_strlen_zero(), astman_append(), astman_get_header(), and s. Referenced by init_manager(). 01654 { 01655 const char *cmd = astman_get_header(m, "Command"); 01656 const char *id = astman_get_header(m, "ActionID"); 01657 char *buf; 01658 char template[] = "/tmp/ast-ami-XXXXXX"; /* template for temporary file */ 01659 int fd = mkstemp(template); 01660 off_t l; 01661 01662 astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n"); 01663 if (!ast_strlen_zero(id)) 01664 astman_append(s, "ActionID: %s\r\n", id); 01665 /* FIXME: Wedge a ActionID response in here, waiting for later changes */ 01666 ast_cli_command(fd, cmd); /* XXX need to change this to use a FILE * */ 01667 l = lseek(fd, 0, SEEK_END); /* how many chars available */ 01668 buf = alloca(l+1); 01669 lseek(fd, 0, SEEK_SET); 01670 read(fd, buf, l); 01671 buf[l] = '\0'; 01672 close(fd); 01673 unlink(template); 01674 astman_append(s, buf); 01675 astman_append(s, "--END COMMAND--\r\n\r\n"); 01676 return 0; 01677 }
|
|
||||||||||||
|
Definition at line 1284 of file manager.c. References astman_get_header(), astman_send_response(), s, and set_eventmask(). Referenced by init_manager(). 01285 { 01286 const char *mask = astman_get_header(m, "EventMask"); 01287 int res; 01288 01289 res = set_eventmask(s, mask); 01290 if (res > 0) 01291 astman_send_response(s, m, "Events On", NULL); 01292 else if (res == 0) 01293 astman_send_response(s, m, "Events Off", NULL); 01294 01295 return 0; 01296 }
|
|
||||||||||||
|
Definition at line 1935 of file manager.c. References ast_extension_state(), ast_get_hint(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), context, exten, and s. Referenced by init_manager(). 01936 { 01937 const char *exten = astman_get_header(m, "Exten"); 01938 const char *context = astman_get_header(m, "Context"); 01939 char hint[256] = ""; 01940 int status; 01941 if (ast_strlen_zero(exten)) { 01942 astman_send_error(s, m, "Extension not specified"); 01943 return 0; 01944 } 01945 if (ast_strlen_zero(context)) 01946 context = "default"; 01947 status = ast_extension_state(NULL, context, exten); 01948 ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten); 01949 astman_start_ack(s, m); 01950 astman_append(s, "Message: Extension Status\r\n" 01951 "Exten: %s\r\n" 01952 "Context: %s\r\n" 01953 "Hint: %s\r\n" 01954 "Status: %d\r\n\r\n", 01955 exten, context, hint, status); 01956 return 0; 01957 }
|
|
||||||||||||
|
Definition at line 1019 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(), astman_start_ack(), lineno, ast_variable::name, ast_variable::next, s, and ast_variable::value. Referenced by init_manager(). 01020 { 01021 struct ast_config *cfg; 01022 const char *fn = astman_get_header(m, "Filename"); 01023 int catcount = 0; 01024 int lineno = 0; 01025 char *category=NULL; 01026 struct ast_variable *v; 01027 01028 if (ast_strlen_zero(fn)) { 01029 astman_send_error(s, m, "Filename not specified"); 01030 return 0; 01031 } 01032 if (!(cfg = ast_config_load_with_comments(fn))) { 01033 astman_send_error(s, m, "Config file not found"); 01034 return 0; 01035 } 01036 astman_start_ack(s, m); 01037 while ((category = ast_category_browse(cfg, category))) { 01038 lineno = 0; 01039 astman_append(s, "Category-%06d: %s\r\n", catcount, category); 01040 for (v = ast_variable_browse(cfg, category); v; v = v->next) 01041 astman_append(s, "Line-%06d-%06d: %s=%s\r\n", catcount, lineno++, v->name, v->value); 01042 catcount++; 01043 } 01044 ast_config_destroy(cfg); 01045 astman_append(s, "\r\n"); 01046 01047 return 0; 01048 }
|
|
||||||||||||
|
Definition at line 1416 of file manager.c. References ast_channel_unlock, ast_func_read(), ast_get_channel_by_name_locked(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), name, pbx_retrieve_variable(), and s. Referenced by init_manager(). 01417 { 01418 struct ast_channel *c = NULL; 01419 const char *name = astman_get_header(m, "Channel"); 01420 const char *varname = astman_get_header(m, "Variable"); 01421 char *varval; 01422 char workspace[1024]; 01423 01424 if (ast_strlen_zero(varname)) { 01425 astman_send_error(s, m, "No variable specified"); 01426 return 0; 01427 } 01428 01429 if (!ast_strlen_zero(name)) { 01430 c = ast_get_channel_by_name_locked(name); 01431 if (!c) { 01432 astman_send_error(s, m, "No such channel"); 01433 return 0; 01434 } 01435 } 01436 01437 if (varname[strlen(varname) - 1] == ')') { 01438 ast_func_read(c, (char *) varname, workspace, sizeof(workspace)); 01439 } else { 01440 pbx_retrieve_variable(c, varname, &varval, workspace, sizeof(workspace), NULL); 01441 } 01442 01443 if (c) 01444 ast_channel_unlock(c); 01445 astman_start_ack(s, m); 01446 astman_append(s, "Variable: %s\r\nValue: %s\r\n\r\n", varname, varval); 01447 01448 return 0; 01449 }
|
|
||||||||||||
|
Definition at line 1348 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(). 01349 { 01350 struct ast_channel *c = NULL; 01351 const char *name = astman_get_header(m, "Channel"); 01352 if (ast_strlen_zero(name)) { 01353 astman_send_error(s, m, "No channel specified"); 01354 return 0; 01355 } 01356 c = ast_get_channel_by_name_locked(name); 01357 if (!c) { 01358 astman_send_error(s, m, "No such channel"); 01359 return 0; 01360 } 01361 ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT); 01362 ast_channel_unlock(c); 01363 astman_send_ack(s, m, "Channel Hungup"); 01364 return 0; 01365 }
|
|
||||||||||||
|
Definition at line 1260 of file manager.c. References manager_action::action, ast_str_alloca, astman_append(), astman_start_ack(), manager_action::authority, authority_to_str(), first_action, manager_action::next, s, and manager_action::synopsis. Referenced by init_manager(). 01261 { 01262 struct manager_action *cur; 01263 struct ast_str *temp = ast_str_alloca(BUFSIZ); /* XXX very large ? */ 01264 01265 astman_start_ack(s, m); 01266 for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */ 01267 if ((s->writeperm & cur->authority) == cur->authority) 01268 astman_append(s, "%s: %s (Priv: %s)\r\n", 01269 cur->action, cur->synopsis, authority_to_str(cur->authority, &temp)); 01270 } 01271 astman_append(s, "\r\n"); 01272 01273 return 0; 01274 }
|
|
||||||||||||
|
Definition at line 1308 of file manager.c. References ast_inet_ntoa(), ast_log(), ast_verbose(), astman_send_ack(), astman_send_error(), authenticate(), displayconnects, LOG_EVENT, option_verbose, s, and VERBOSE_PREFIX_2. Referenced by init_manager(). 01309 { 01310 if (authenticate(s, m)) { 01311 sleep(1); 01312 astman_send_error(s, m, "Authentication failed"); 01313 return -1; 01314 } 01315 s->authenticated = 1; 01316 if (option_verbose > 1) { 01317 if (displayconnects) { 01318 ast_verbose(VERBOSE_PREFIX_2 "%sManager '%s' logged on from %s\n", (s->managerid ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr)); 01319 } 01320 } 01321 ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", (s->managerid ? "HTTP " : ""), s->username, ast_inet_ntoa(s->sin.sin_addr)); 01322 astman_send_ack(s, m, "Authentication accepted"); 01323 return 0; 01324 }
|
|
||||||||||||
|
Definition at line 1302 of file manager.c. References astman_send_response(), and s. Referenced by init_manager(). 01303 { 01304 astman_send_response(s, m, "Goodbye", "Thanks for all the fish."); 01305 return -1; 01306 }
|
|
||||||||||||
|
Definition at line 1904 of file manager.c. References ast_app_inboxcount(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), mailbox, and s. Referenced by init_manager(). 01905 { 01906 const char *mailbox = astman_get_header(m, "Mailbox"); 01907 int newmsgs = 0, oldmsgs = 0; 01908 01909 if (ast_strlen_zero(mailbox)) { 01910 astman_send_error(s, m, "Mailbox not specified"); 01911 return 0; 01912 } 01913 ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs); 01914 astman_start_ack(s, m); 01915 astman_append(s, "Message: Mailbox Message Count\r\n" 01916 "Mailbox: %s\r\n" 01917 "NewMessages: %d\r\n" 01918 "OldMessages: %d\r\n" 01919 "\r\n", 01920 mailbox, newmsgs, oldmsgs); 01921 return 0; 01922 }
|
|
||||||||||||
|
Definition at line 1876 of file manager.c. References ast_app_has_voicemail(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), astman_start_ack(), mailbox, and s. Referenced by init_manager(). 01877 { 01878 const char *mailbox = astman_get_header(m, "Mailbox"); 01879 int ret; 01880 01881 if (ast_strlen_zero(mailbox)) { 01882 astman_send_error(s, m, "Mailbox not specified"); 01883 return 0; 01884 } 01885 ret = ast_app_has_voicemail(mailbox, NULL); 01886 astman_start_ack(s, m); 01887 astman_append(s, "Message: Mailbox Status\r\n" 01888 "Mailbox: %s\r\n" 01889 "Waiting: %d\r\n\r\n", mailbox, ret); 01890 return 0; 01891 }
|
|
||||||||||||
|
Definition at line 1758 of file manager.c. References app, ast_callerid_parse(), ast_calloc, ast_findlabel_extension(), AST_FORMAT_SLINEAR, ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pthread_create, ast_shrink_phone_number(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), context, ast_channel::data, exten, fast_originate(), name, ast_channel::priority, s, and ast_channel::tech. Referenced by init_manager(). 01759 { 01760 const char *name = astman_get_header(m, "Channel"); 01761 const char *exten = astman_get_header(m, "Exten"); 01762 const char *context = astman_get_header(m, "Context"); 01763 const char *priority = astman_get_header(m, "Priority"); 01764 const char *timeout = astman_get_header(m, "Timeout"); 01765 const char *callerid = astman_get_header(m, "CallerID"); 01766 const char *account = astman_get_header(m, "Account"); 01767 const char *app = astman_get_header(m, "Application"); 01768 const char *appdata = astman_get_header(m, "Data"); 01769 const char *async = astman_get_header(m, "Async"); 01770 const char *id = astman_get_header(m, "ActionID"); 01771 struct ast_variable *vars = astman_get_variables(m); 01772 char *tech, *data; 01773 char *l = NULL, *n = NULL; 01774 int pi = 0; 01775 int res; 01776 int to = 30000; 01777 int reason = 0; 01778 char tmp[256]; 01779 char tmp2[256]; 01780 01781 pthread_t th; 01782 pthread_attr_t attr; 01783 if (!name) { 01784 astman_send_error(s, m, "Channel not specified"); 01785 return 0; 01786 } 01787 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 01788 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 01789 astman_send_error(s, m, "Invalid priority\n"); 01790 return 0; 01791 } 01792 } 01793 if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%d", &to) != 1)) { 01794 astman_send_error(s, m, "Invalid timeout\n"); 01795 return 0; 01796 } 01797 ast_copy_string(tmp, name, sizeof(tmp)); 01798 tech = tmp; 01799 data = strchr(tmp, '/'); 01800 if (!data) { 01801 astman_send_error(s, m, "Invalid channel\n"); 01802 return 0; 01803 } 01804 *data++ = '\0'; 01805 ast_copy_string(tmp2, callerid, sizeof(tmp2)); 01806 ast_callerid_parse(tmp2, &n, &l); 01807 if (n) { 01808 if (ast_strlen_zero(n)) 01809 n = NULL; 01810 } 01811 if (l) { 01812 ast_shrink_phone_number(l); 01813 if (ast_strlen_zero(l)) 01814 l = NULL; 01815 } 01816 if (ast_true(async)) { 01817 struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast)); 01818 if (!fast) { 01819 res = -1; 01820 } else { 01821 if (!ast_strlen_zero(id)) 01822 snprintf(fast->idtext, sizeof(fast->idtext), "ActionID: %s\r\n", id); 01823 ast_copy_string(fast->tech, tech, sizeof(fast->tech)); 01824 ast_copy_string(fast->data, data, sizeof(fast->data)); 01825 ast_copy_string(fast->app, app, sizeof(fast->app)); 01826 ast_copy_string(fast->appdata, appdata, sizeof(fast->appdata)); 01827 if (l) 01828 ast_copy_string(fast->cid_num, l, sizeof(fast->cid_num)); 01829 if (n) 01830 ast_copy_string(fast->cid_name, n, sizeof(fast->cid_name)); 01831 fast->vars = vars; 01832 ast_copy_string(fast->context, context, sizeof(fast->context)); 01833 ast_copy_string(fast->exten, exten, sizeof(fast->exten)); 01834 ast_copy_string(fast->account, account, sizeof(fast->account)); 01835 fast->timeout = to; 01836 fast->priority = pi; 01837 pthread_attr_init(&attr); 01838 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01839 if (ast_pthread_create(&th, &attr, fast_originate, fast)) { 01840 res = -1; 01841 } else { 01842 res = 0; 01843 } 01844 pthread_attr_destroy(&attr); 01845 } 01846 } else if (!ast_strlen_zero(app)) { 01847 res = ast_pbx_outgoing_app(tech, AST_FORMAT_SLINEAR, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL); 01848 } else { 01849 if (exten && context && pi) 01850 res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL); 01851 else { 01852 astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'"); 01853 return 0; 01854 } 01855 } 01856 if (!res) 01857 astman_send_ack(s, m, "Originate successfully queued"); 01858 else 01859 astman_send_error(s, m, "Originate failed"); 01860 return 0; 01861 }
|
|
||||||||||||
|
Definition at line 1007 of file manager.c. References astman_send_response(), and s. Referenced by init_manager(). 01008 { 01009 astman_send_response(s, m, "Pong", NULL); 01010 return 0; 01011 }
|
|
||||||||||||
|
action_redirect: The redirect manager command
Definition at line 1593 of file manager.c. References ast_async_goto(), ast_channel_unlock, ast_findlabel_extension(), ast_get_channel_by_name_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), context, exten, name, ast_channel::priority, and s. Referenced by init_manager(). 01594 { 01595 const char *name = astman_get_header(m, "Channel"); 01596 const char *name2 = astman_get_header(m, "ExtraChannel"); 01597 const char *exten = astman_get_header(m, "Exten"); 01598 const char *context = astman_get_header(m, "Context"); 01599 const char *priority = astman_get_header(m, "Priority"); 01600 struct ast_channel *chan, *chan2 = NULL; 01601 int pi = 0; 01602 int res; 01603 01604 if (ast_strlen_zero(name)) { 01605 astman_send_error(s, m, "Channel not specified"); 01606 return 0; 01607 } 01608 if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) { 01609 if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) { 01610 astman_send_error(s, m, "Invalid priority\n"); 01611 return 0; 01612 } 01613 } 01614 /* XXX watch out, possible deadlock - we are trying to get two channels!!! */ 01615 chan = ast_get_channel_by_name_locked(name); 01616 if (!chan) { 01617 char buf[BUFSIZ]; 01618 snprintf(buf, sizeof(buf), "Channel does not exist: %s", name); 01619 astman_send_error(s, m, buf); 01620 return 0; 01621 } 01622 if (!ast_strlen_zero(name2)) 01623 chan2 = ast_get_channel_by_name_locked(name2); 01624 res = ast_async_goto(chan, context, exten, pi); 01625 if (!res) { 01626 if (!ast_strlen_zero(name2)) { 01627 if (chan2) 01628 res = ast_async_goto(chan2, context, exten, pi); 01629 else 01630 res = -1; 01631 if (!res) 01632 astman_send_ack(s, m, "Dual Redirect successful"); 01633 else 01634 astman_send_error(s, m, "Secondary redirect failed"); 01635 } else 01636 astman_send_ack(s, m, "Redirect successful"); 01637 } else 01638 astman_send_error(s, m, "Redirect failed"); 01639 if (chan) 01640 ast_channel_unlock(chan); 01641 if (chan2) 01642 ast_channel_unlock(chan2); 01643 return 0; 01644 }
|
|
||||||||||||
|
Definition at line 1548 of file manager.c. References ast_get_channel_by_name_locked(), ast_mutex_unlock(), ast_sendtext(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::lock, name, and s. Referenced by init_manager(). 01549 { 01550 struct ast_channel *c = NULL; 01551 const char *name = astman_get_header(m, "Channel"); 01552 const char *textmsg = astman_get_header(m, "Message"); 01553 int res = 0; 01554 01555 if (ast_strlen_zero(name)) { 01556 astman_send_error(s, m, "No channel specified"); 01557 return 0; 01558 } 01559 01560 if (ast_strlen_zero(textmsg)) { 01561 astman_send_error(s, m, "No Message specified"); 01562 return 0; 01563 } 01564 01565 c = ast_get_channel_by_name_locked(name); 01566 if (!c) { 01567 astman_send_error(s, m, "No such channel"); 01568 return 0; 01569 } 01570 01571 res = ast_sendtext(c, textmsg); 01572 ast_mutex_unlock(&c->lock); 01573 01574 if (res > 0) 01575 astman_send_ack(s, m, "Success"); 01576 else 01577 astman_send_error(s, m, "Failure"); 01578 01579 return res; 01580 }
|
|
||||||||||||
|
Definition at line 1374 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. Referenced by init_manager(). 01375 { 01376 struct ast_channel *c = NULL; 01377 const char *name = astman_get_header(m, "Channel"); 01378 const char *varname = astman_get_header(m, "Variable"); 01379 const char *varval = astman_get_header(m, "Value"); 01380 01381 if (ast_strlen_zero(varname)) { 01382 astman_send_error(s, m, "No variable specified"); 01383 return 0; 01384 } 01385 01386 if (ast_strlen_zero(varval)) { 01387 astman_send_error(s, m, "No value specified"); 01388 return 0; 01389 } 01390 01391 if (!ast_strlen_zero(name)) { 01392 c = ast_get_channel_by_name_locked(name); 01393 if (!c) { 01394 astman_send_error(s, m, "No such channel"); 01395 return 0; 01396 } 01397 } 01398 01399 pbx_builtin_setvar_helper(c, varname, varval); 01400 01401 if (c) 01402 ast_channel_unlock(c); 01403 01404 astman_send_ack(s, m, "Variable Set"); 01405 01406 return 0; 01407 }
|
|
||||||||||||
|
Manager "status" command to show channels.
Definition at line 1454 of file manager.c. References ast_channel::_bridge, ast_channel::_state, ast_channel_unlock, ast_channel_walk_locked(), ast_get_channel_by_name_locked(), ast_state2str(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_ack(), astman_send_error(), ast_channel::cdr, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, name, ast_channel::pbx, ast_channel::priority, s, S_OR, and ast_cdr::start. Referenced by init_manager(). 01455 { 01456 const char *name = astman_get_header(m,"Channel"); 01457 struct ast_channel *c; 01458 char bridge[256]; 01459 struct timeval now = ast_tvnow(); 01460 long elapsed_seconds = 0; 01461 int all = ast_strlen_zero(name); /* set if we want all channels */ 01462 const char *id = astman_get_header(m,"ActionID"); 01463 char idText[256] = ""; 01464 01465 if (!ast_strlen_zero(id)) 01466 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01467 01468 astman_send_ack(s, m, "Channel status will follow"); 01469 if (all) 01470 c = ast_channel_walk_locked(NULL); 01471 else { 01472 c = ast_get_channel_by_name_locked(name); 01473 if (!c) { 01474 astman_send_error(s, m, "No such channel"); 01475 return 0; 01476 } 01477 } 01478 /* if we look by name, we break after the first iteration */ 01479 while (c) { 01480 if (c->_bridge) 01481 snprintf(bridge, sizeof(bridge), "Link: %s\r\n", c->_bridge->name); 01482 else 01483 bridge[0] = '\0'; 01484 if (c->pbx) { 01485 if (c->cdr) { 01486 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec; 01487 } 01488 astman_append(s, 01489 "Event: Status\r\n" 01490 "Privilege: Call\r\n" 01491 "Channel: %s\r\n" 01492 "CallerIDNum: %s\r\n" 01493 "CallerIDName: %s\r\n" 01494 "Account: %s\r\n" 01495 "State: %s\r\n" 01496 "Context: %s\r\n" 01497 "Extension: %s\r\n" 01498 "Priority: %d\r\n" 01499 "Seconds: %ld\r\n" 01500 "%s" 01501 "Uniqueid: %s\r\n" 01502 "%s" 01503 "\r\n", 01504 c->name, 01505 S_OR(c->cid.cid_num, "<unknown>"), 01506 S_OR(c->cid.cid_name, "<unknown>"), 01507 c->accountcode, 01508 ast_state2str(c->_state), c->context, 01509 c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, idText); 01510 } else { 01511 astman_append(s, 01512 "Event: Status\r\n" 01513 "Privilege: Call\r\n" 01514 "Channel: %s\r\n" 01515 "CallerIDNum: %s\r\n" 01516 "CallerIDName: %s\r\n" 01517 "Account: %s\r\n" 01518 "State: %s\r\n" 01519 "%s" 01520 "Uniqueid: %s\r\n" 01521 "%s" 01522 "\r\n", 01523 c->name, 01524 S_OR(c->cid.cid_num, "<unknown>"), 01525 S_OR(c->cid.cid_name, "<unknown>"), 01526 c->accountcode, 01527 ast_state2str(c->_state), bridge, c->uniqueid, idText); 01528 } 01529 ast_channel_unlock(c); 01530 if (!all) 01531 break; 01532 c = ast_channel_walk_locked(c); 01533 } 01534 astman_append(s, 01535 "Event: StatusComplete\r\n" 01536 "%s" 01537 "\r\n",idText); 01538 return 0; 01539 }
|
|
||||||||||||
|
Definition at line 1966 of file manager.c. References ast_channel_setwhentohangup(), ast_channel_unlock, ast_get_channel_by_name_locked(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, and s. Referenced by init_manager(). 01967 { 01968 struct ast_channel *c; 01969 const char *name = astman_get_header(m, "Channel"); 01970 int timeout = atoi(astman_get_header(m, "Timeout")); 01971 01972 if (ast_strlen_zero(name)) { 01973 astman_send_error(s, m, "No channel specified"); 01974 return 0; 01975 } 01976 if (!timeout) { 01977 astman_send_error(s, m, "No timeout specified"); 01978 return 0; 01979 } 01980 c = ast_get_channel_by_name_locked(name); 01981 if (!c) { 01982 astman_send_error(s, m, "No such channel"); 01983 return 0; 01984 } 01985 ast_channel_setwhentohangup(c, timeout); 01986 ast_channel_unlock(c); 01987 astman_send_ack(s, m, "Timeout Set"); 01988 return 0; 01989 }
|
|
||||||||||||
|
Definition at line 1119 of file manager.c. References ast_config_destroy(), ast_config_load_with_comments(), ast_module_reload(), ast_strlen_zero(), ast_true(), astman_get_header(), astman_send_ack(), astman_send_error(), config_text_file_save(), handle_updates(), and s. Referenced by init_manager(). 01120 { 01121 struct ast_config *cfg; 01122 const char *sfn = astman_get_header(m, "SrcFilename"); 01123 const char *dfn = astman_get_header(m, "DstFilename"); 01124 int res; 01125 const char *rld = astman_get_header(m, "Reload"); 01126 01127 if (ast_strlen_zero(sfn) || ast_strlen_zero(dfn)) { 01128 astman_send_error(s, m, "Filename not specified"); 01129 return 0; 01130 } 01131 if (!(cfg = ast_config_load_with_comments(sfn))) { 01132 astman_send_error(s, m, "Config file not found"); 01133 return 0; 01134 } 01135 handle_updates(s, m, cfg); 01136 res = config_text_file_save(dfn, cfg, "Manager"); 01137 ast_config_destroy(cfg); 01138 if (res) { 01139 astman_send_error(s, m, "Save of config failed"); 01140 return 0; 01141 } 01142 astman_send_ack(s, m, NULL); 01143 if (!ast_strlen_zero(rld)) { 01144 if (ast_true(rld)) 01145 rld = NULL; 01146 ast_module_reload(rld); 01147 } 01148 return 0; 01149 }
|
|
||||||||||||
|
Definition at line 2026 of file manager.c. References astman_get_header(), event, message::hdrcount, and message::headers. Referenced by init_manager(). 02027 { 02028 const char *event = astman_get_header(m, "UserEvent"); 02029 char body[2048] = ""; 02030 int x, bodylen = 0; 02031 for (x = 0; x < m->hdrcount; x++) { 02032 if (strncasecmp("UserEvent:", m->headers[x], strlen("UserEvent:"))) { 02033 ast_copy_string(body + bodylen, m->headers[x], sizeof(body) - bodylen - 3); 02034 bodylen += strlen(m->headers[x]); 02035 ast_copy_string(body + bodylen, "\r\n", 3); 02036 bodylen += 2; 02037 } 02038 } 02039 02040 manager_event(EVENT_FLAG_USER, "UserEvent", "UserEvent: %s\r\n%s", event, body); 02041 return 0; 02042 }
|
|
||||||||||||
|
Definition at line 1159 of file manager.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_strlen_zero(), ast_wait_for_input(), astman_get_header(), LOG_DEBUG, NEW_EVENT, option_debug, and s. Referenced by init_manager(). 01160 { 01161 const char *timeouts = astman_get_header(m, "Timeout"); 01162 int timeout = -1; 01163 int x; 01164 int needexit = 0; 01165 const char *id = astman_get_header(m,"ActionID"); 01166 char idText[256] = ""; 01167 01168 if (!ast_strlen_zero(id)) 01169 snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id); 01170 01171 if (!ast_strlen_zero(timeouts)) { 01172 sscanf(timeouts, "%i", &timeout); 01173 if (timeout < -1) 01174 timeout = -1; 01175 /* XXX maybe put an upper bound, or prevent the use of 0 ? */ 01176 } 01177 01178 ast_mutex_lock(&s->__lock); 01179 if (s->waiting_thread != AST_PTHREADT_NULL) 01180 pthread_kill(s->waiting_thread, SIGURG); 01181 01182 if (s->managerid) { /* AMI-over-HTTP session */ 01183 /* 01184 * Make sure the timeout is within the expire time of the session, 01185 * as the client will likely abort the request if it does not see 01186 * data coming after some amount of time. 01187 */ 01188 time_t now = time(NULL); 01189 int max = s->sessiontimeout - now - 10; 01190 01191 if (max < 0) /* We are already late. Strange but possible. */ 01192 max = 0; 01193 if (timeout < 0 || timeout > max) 01194 timeout = max; 01195 if (!s->send_events) /* make sure we record events */ 01196 s->send_events = -1; 01197 } 01198 ast_mutex_unlock(&s->__lock); 01199 01200 /* XXX should this go inside the lock ? */ 01201 s->waiting_thread = pthread_self(); /* let new events wake up this thread */ 01202 if (option_debug) 01203 ast_log(LOG_DEBUG, "Starting waiting for an event!\n"); 01204 01205 for (x=0; x < timeout || timeout < 0; x++) { 01206 ast_mutex_lock(&s->__lock); 01207 if (NEW_EVENT(s)) 01208 needexit = 1; 01209 /* We can have multiple HTTP session point to the same mansession entry. 01210 * The way we deal with it is not very nice: newcomers kick out the previous 01211 * HTTP session. XXX this needs to be improved. 01212 */ 01213 if (s->waiting_thread != pthread_self()) 01214 needexit = 1; 01215 if (s->needdestroy) 01216 needexit = 1; 01217 ast_mutex_unlock(&s->__lock); 01218 if (needexit) 01219 break; 01220 if (s->managerid == 0) { /* AMI session */ 01221 if (ast_wait_for_input(s->fd, 1000)) 01222 break; 01223 } else { /* HTTP session */ 01224 sleep(1); 01225 } 01226 } 01227 if (option_debug) 01228 ast_log(LOG_DEBUG, "Finished waiting for an event!\n"); 01229 ast_mutex_lock(&s->__lock); 01230 if (s->waiting_thread == pthread_self()) { 01231 struct eventqent *eqe; 01232 astman_send_response(s, m, "Success", "Waiting for Event completed."); 01233 while ( (eqe = NEW_EVENT(s)) ) { 01234 ref_event(eqe); 01235 if (((s->readperm & eqe->category) == eqe->category) && 01236 ((s->send_events & eqe->category) == eqe->category)) { 01237 astman_append(s, "%s", eqe->eventdata); 01238 } 01239 s->last_ev = unref_event(s->last_ev); 01240 } 01241 astman_append(s, 01242 "Event: WaitEventComplete\r\n" 01243 "%s" 01244 "\r\n", idText); 01245 s->waiting_thread = AST_PTHREADT_NULL; 01246 } else { 01247 if (option_debug) 01248 ast_log(LOG_DEBUG, "Abandoning event request!\n"); 01249 } 01250 ast_mutex_unlock(&s->__lock); 01251 return 0; 01252 }
|
|
||||||||||||
|
Definition at line 2294 of file manager.c. References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_UNLOCK, ast_malloc, and seq. Referenced by __manager_event(), and init_manager(). 02295 { 02296 struct eventqent *tmp = ast_malloc(sizeof(*tmp) + strlen(str)); 02297 static int seq; /* sequence number */ 02298 02299 if (!tmp) 02300 return -1; 02301 02302 /* need to init all fields, because ast_malloc() does not */ 02303 tmp->usecount = 0; 02304 tmp->category = category; 02305 tmp->seq = ast_atomic_fetchadd_int(&seq, 1); 02306 AST_LIST_NEXT(tmp, eq_next) = NULL; 02307 strcpy(tmp->eventdata, str); 02308 02309 AST_LIST_LOCK(&all_events); 02310 AST_LIST_INSERT_TAIL(&all_events, tmp, eq_next); 02311 AST_LIST_UNLOCK(&all_events); 02312 02313 return 0; 02314 }
|
|
||||||||||||||||
|
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 323 of file manager.c. Referenced by get_perm(). 00324 { 00325 const char *val = bigstr, *next; 00326 00327 do { 00328 if ((next = strchr(val, delim))) { 00329 if (!strncmp(val, smallstr, (next - val))) 00330 return 1; 00331 else 00332 continue; 00333 } else 00334 return !strcmp(smallstr, val); 00335 } while (*(val = (next + 1))); 00336 00337 return 0; 00338 }
|
|
||||||||||||
|
list of users found in the config file
|
|
||||||||||||
|
|
|
||||||||||||
|
|
|
||||||||||||||||||||||||
|
register a new command with manager, including online help. This is the preferred way to register a manager command
Definition at line 2449 of file manager.c. References ast_malloc, and ast_manager_register_struct(). Referenced by init_manager(), load_module(), and sip_cli_and_manager_commands_register(). 02450 { 02451 struct manager_action *cur; 02452 02453 cur = ast_malloc(sizeof(*cur)); 02454 if (!cur) 02455 return -1; 02456 02457 cur->action = action; 02458 cur->authority = auth; 02459 cur->func = func; 02460 cur->synopsis = synopsis; 02461 cur->description = description; 02462 cur->next = NULL; 02463 02464 ast_manager_register_struct(cur); 02465 02466 return 0; 02467 }
|
|
|
Add a custom hook to be called when an event is fired.
Definition at line 182 of file manager.c. References AST_RWLIST_INSERT_TAIL, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK. 00183 { 00184 AST_RWLIST_WRLOCK(&manager_hooks); 00185 AST_RWLIST_INSERT_TAIL(&manager_hooks, hook, list); 00186 AST_RWLIST_UNLOCK(&manager_hooks); 00187 return; 00188 }
|
|
|
Definition at line 2419 of file manager.c. References manager_action::action, ast_log(), ast_rwlock_unlock(), ast_rwlock_wrlock(), first_action, LOG_WARNING, and manager_action::next. Referenced by ast_manager_register2(). 02420 { 02421 struct manager_action *cur, *prev = NULL; 02422 int ret; 02423 02424 ast_rwlock_wrlock(&actionlock); 02425 for (cur = first_action; cur; prev = cur, cur = cur->next) { 02426 ret = strcasecmp(cur->action, act->action); 02427 if (ret == 0) { 02428 ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", act->action); 02429 ast_rwlock_unlock(&actionlock); 02430 return -1; 02431 } 02432 if (ret > 0) /* Insert these alphabetically */ 02433 break; 02434 } 02435 if (prev) 02436 prev->next = act; 02437 else 02438 first_action = act; 02439 act->next = cur; 02440 02441 if (option_verbose > 1) 02442 ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", act->action); 02443 ast_rwlock_unlock(&actionlock); 02444 return 0; 02445 }
|
|
|
Definition at line 2391 of file manager.c. References ast_rwlock_wrlock(), ast_verbose(), first_action, free, manager_action::next, and option_verbose. Referenced by __unload_module(), sip_cli_and_manager_commands_unregister(), and unload_module(). 02392 { 02393 struct manager_action *cur, *prev; 02394 02395 ast_rwlock_wrlock(&actionlock); 02396 for (cur = first_action, prev = NULL; cur; prev = cur, cur = cur->next) { 02397 if (!strcasecmp(action, cur->action)) { 02398 if (prev) 02399 prev->next = cur->next; 02400 else 02401 first_action = cur->next; 02402 free(cur); 02403 if (option_verbose > 1) 02404 ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action); 02405 break; 02406 } 02407 } 02408 ast_rwlock_unlock(&actionlock); 02409 return 0; 02410 }
|
|
|
Delete a custom hook to be called when an event is fired.
Definition at line 191 of file manager.c. References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK. 00192 { 00193 AST_RWLIST_WRLOCK(&manager_hooks); 00194 AST_RWLIST_REMOVE(&manager_hooks, hook, list); 00195 AST_RWLIST_UNLOCK(&manager_hooks); 00196 return; 00197 }
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||
|
||||||||||||
|
|
Get a linked list of the Variable: headers Definition at line 685 of file manager.c. References AST_APP_ARG, AST_DECLARE_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_variable_new(), message::hdrcount, message::headers, parse(), strsep(), and var. Referenced by action_originate(). 00686 { 00687 int varlen, x, y; 00688 struct ast_variable *head = NULL, *cur; 00689 00690 AST_DECLARE_APP_ARGS(args, 00691 AST_APP_ARG(vars)[32]; 00692 ); 00693 00694 varlen = strlen("Variable: "); 00695 00696 for (x = 0; x < m->hdrcount; x++) { 00697 char *parse, *var, *val; 00698 00699 if (strncasecmp("Variable: ", m->headers[x], varlen)) 00700 continue; 00701 parse = ast_strdupa(m->headers[x] + varlen); 00702 00703 AST_STANDARD_APP_ARGS(args, parse); 00704 if (!args.argc) 00705 continue; 00706 for (y = 0; y < args.argc; y++) { 00707 if (!args.vars[y]) 00708 continue; 00709 var = val = ast_strdupa(args.vars[y]); 00710 strsep(&val, "="); 00711 if (!val || ast_strlen_zero(var)) 00712 continue; 00713 cur = ast_variable_new(var, val); 00714 cur->next = head; 00715 head = cur; 00716 } 00717 } 00718 00719 return head; 00720 }
|
|
||||||||||||||||
|
Definition at line 823 of file manager.c. References astman_send_response_full(), and s. Referenced by action_agent_logoff(), action_agents(), action_hangup(), action_login(), action_originate(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), action_transfer(), action_transferhangup(), action_updateconfig(), action_zapdndoff(), action_zapdndon(), action_zaprestart(), action_zapshowchannels(), change_monitor_action(), do_pause_or_unpause(), manager_dbdel(), manager_dbdeltree(), manager_dbget(), manager_dbput(), manager_jabber_send(), manager_park(), manager_parking_status(), manager_sip_show_devices(), start_monitor_action(), and stop_monitor_action(). 00824 { 00825 astman_send_response_full(s, m, "Success", msg, NULL); 00826 }
|
|
||||||||||||||||
|
||||||||||||||||||||
|
Definition at line 833 of file manager.c. References astman_send_response_full(), and s. Referenced by manager_dpsendack(), and manager_sip_show_peers(). 00834 { 00835 astman_send_response_full(s, m, "Success", msg, listflag); 00836 }
|
|
||||||||||||||||||||
|
Definition at line 813 of file manager.c. References astman_send_response_full(), and s. Referenced by action_events(), action_logoff(), and action_ping(). 00814 { 00815 astman_send_response_full(s, m, resp, msg, NULL); 00816 }
|
|
||||||||||||||||||||||||
|
Definition at line 796 of file manager.c. References ast_strlen_zero(), astman_append(), astman_get_header(), MSG_MOREDATA, and s. Referenced by astman_send_ack(), astman_send_error(), astman_send_listack(), astman_send_response(), and astman_start_ack(). 00797 { 00798 const char *id = astman_get_header(m,"ActionID"); 00799 00800 astman_append(s, "Response: %s\r\n", resp); 00801 if (!ast_strlen_zero(id)) 00802 astman_append(s, "ActionID: %s\r\n", id); 00803 if (listflag) 00804 astman_append(s, "Eventlist: %s\r\n", listflag); /* Start, complete, cancelled */ 00805 if (msg == MSG_MOREDATA) 00806 return; 00807 else if (msg) 00808 astman_append(s, "Message: %s\r\n\r\n", msg); 00809 else 00810 astman_append(s, "\r\n"); 00811 }
|
|
||||||||||||
|
Definition at line 828 of file manager.c. References astman_send_response_full(), MSG_MOREDATA, and s. Referenced by action_challenge(), action_extensionstate(), action_getconfig(), action_getvar(), action_listcommands(), action_mailboxcount(), and action_mailboxstatus(). 00829 { 00830 astman_send_response_full(s, m, "Success", MSG_MOREDATA, NULL); 00831 }
|
|
||||||||||||
|
Definition at line 862 of file manager.c. References ast_append_ha(), ast_category_browse(), ast_config_load(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_variable_browse(), astman_get_header(), error(), get_perm(), ast_variable::lineno, LOG_WARNING, ast_variable::name, ast_variable::next, s, and ast_variable::value. Referenced by action_login(), authenticate_reply(), and registry_rerequest(). 00863 { 00864 const char *user = astman_get_header(m, "Username"); 00865 int error = -1; 00866 struct ast_ha *ha = NULL; 00867 char *password = NULL; 00868 int readperm = 0, writeperm = 0; 00869 00870 if (ast_strlen_zero(user)) /* missing username */ 00871 return -1; 00872 00873 { 00874 /* 00875 * XXX there should be no need to scan the config file again here, 00876 * suffices to call get_manager_by_name_locked() to fetch 00877 * the user's entry. 00878 */ 00879 struct ast_config *cfg = ast_config_load("manager.conf"); 00880 char *cat = NULL; 00881 struct ast_variable *v; 00882 00883 if (!cfg) 00884 return -1; 00885 while ( (cat = ast_category_browse(cfg, cat)) ) { 00886 /* "general" is not a valid user */ 00887 if (strcasecmp(cat, user) || !strcasecmp(cat, "general")) 00888 continue; 00889 /* collect parameters for the user's entry */ 00890 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 00891 if (!strcasecmp(v->name, "secret")) 00892 password = ast_strdupa(v->value); 00893 else if (!strcasecmp(v->name, "read")) 00894 readperm = get_perm(v->value); 00895 else if (!strcasecmp(v->name, "write")) 00896 writeperm = get_perm(v->value); 00897 else if (!strcasecmp(v->name, "permit") || 00898 !strcasecmp(v->name, "deny")) { 00899 ha = ast_append_ha(v->name, v->value, ha, NULL); 00900 } else if (!strcasecmp(v->name, "writetimeout")) { 00901 int val = atoi(v->value); 00902 00903 if (val < 100) 00904 ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", v->value, v->lineno); 00905 else 00906 s->writetimeout = val; 00907 } 00908 } 00909 break; 00910 } 00911 00912 ast_config_destroy(cfg); 00913 if (!cat) { 00914 /* Didn't find the user in manager.conf, check users.conf */ 00915 int hasmanager = 0; 00916 cfg = ast_config_load("users.conf"); 00917 if (!cfg) 00918 return -1; 00919 while ( (cat = ast_category_browse(cfg, cat)) ) { 00920 if (!strcasecmp(cat, user) && strcasecmp(cat, "general")) 00921 break; 00922 } 00923 if (!cat) { 00924 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 00925 ast_config_destroy(cfg); 00926 return -1; 00927 } 00928 /* collect parameters for the user's entry from users.conf */ 00929 for (v = ast_variable_browse(cfg, cat); v; v = v->next) { 00930 if (!strcasecmp(v->name, "secret")) 00931 password = ast_strdupa(v->value); 00932 else if (!strcasecmp(v->name, "read")) 00933 readperm = get_perm(v->value); 00934 else if (!strcasecmp(v->name, "write")) 00935 writeperm = get_perm(v->value); 00936 else if (!strcasecmp(v->name, "permit") || 00937 !strcasecmp(v->name, "deny")) { 00938 ha = ast_append_ha(v->name, v->value, ha, NULL); 00939 } else if (!strcasecmp(v->name, "writetimeout")) { 00940 int val = atoi(v->value); 00941 00942 if (val < 100) 00943 ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", v->value, v->lineno); 00944 else 00945 s->writetimeout = val; 00946 } else if (!strcasecmp(v->name, "hasmanager")) { 00947 hasmanager = ast_true(v->value); 00948 } 00949 } 00950 ast_config_destroy(cfg); 00951 if (!hasmanager) { 00952 ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 00953 return -1; 00954 } 00955 } 00956 00957 } 00958 00959 if (ha) { 00960 int good = ast_apply_ha(ha, &(s->sin)); 00961 ast_free_ha(ha); 00962 if (!good) { 00963 ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 00964 return -1; 00965 } 00966 } 00967 if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) { 00968 const char *key = astman_get_header(m, "Key"); 00969 if (!ast_strlen_zero(key) && !ast_strlen_zero(s->challenge)) { 00970 int x; 00971 int len = 0; 00972 char md5key[256] = ""; 00973 struct MD5Context md5; 00974 unsigned char digest[16]; 00975 00976 MD5Init(&md5); 00977 MD5Update(&md5, (unsigned char *) s->challenge, strlen(s->challenge)); 00978 MD5Update(&md5, (unsigned char *) password, strlen(password)); 00979 MD5Final(digest, &md5); 00980 for (x=0; x<16; x++) 00981 len += sprintf(md5key + len, "%2.2x", digest[x]); 00982 if (!strcmp(md5key, key)) 00983 error = 0; 00984 } 00985 } else if (password) { 00986 const char *pass = astman_get_header(m, "Secret"); 00987 if (!strcmp(password, pass)) 00988 error = 0; 00989 } 00990 if (error) { 00991 ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); 00992 return -1; 00993 } 00994 ast_copy_string(s->username, user, sizeof(s->username)); 00995 s->readperm = readperm; 00996 s->writeperm = writeperm; 00997 set_eventmask(s, astman_get_header(m, "Events")); 00998 return 0; 00999 }
|
|
||||||||||||
|
Convert authority code to a list of options.
Definition at line 299 of file manager.c. References ast_str_append(), and perms. Referenced by __manager_event(), action_listcommands(), handle_showmancmd(), and handle_showmancmds(). 00300 { 00301 int i; 00302 char *sep = ""; 00303 00304 (*res)->used = 0; 00305 for (i = 0; i < (sizeof(perms) / sizeof(perms[0])) - 1; i++) { 00306 if (authority & perms[i].num) { 00307 ast_str_append(res, 0, "%s%s", sep, perms[i].label); 00308 sep = ","; 00309 } 00310 } 00311 00312 if ((*res)->used == 0) /* replace empty string with something sensible */ 00313 ast_str_append(res, 0, "<none>"); 00314 00315 return (*res)->str; 00316 }
|
|
||||||||||||||||||||
|
Definition at line 382 of file manager.c. References manager_action::action, ast_rwlock_rdlock(), ast_strdup, first_action, and manager_action::next. 00383 { 00384 struct manager_action *cur; 00385 int l = strlen(word), which = 0; 00386 char *ret = NULL; 00387 00388 ast_rwlock_rdlock(&actionlock); 00389 for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */ 00390 if (!strncasecmp(word, cur->action, l) && ++which > state) { 00391 ret = ast_strdup(cur->action); 00392 break; /* make sure we exit even if ast_strdup() returns NULL */ 00393 } 00394 } 00395 ast_rwlock_unlock(&actionlock); 00396 00397 return ret; 00398 }
|
|
|
Definition at line 662 of file manager.c. References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, free_session(), s, and sessions. Referenced by accept_thread(). 00663 { 00664 AST_LIST_LOCK(&sessions); 00665 AST_LIST_REMOVE(&sessions, s, list); 00666 AST_LIST_UNLOCK(&sessions); 00667 00668 ast_atomic_fetchadd_int(&num_sessions, -1); 00669 free_session(s); 00670 }
|
|
|
Definition at line 2174 of file manager.c. References AST_MAX_MANHEADERS, ast_strdupa, ast_strlen_zero(), get_input(), message::hdrcount, message::headers, process_events(), process_message(), and s. Referenced by session_do(). 02175 { 02176 struct message m = { 0 }; 02177 char header_buf[sizeof(s->inbuf)] = { '\0' }; 02178 int res; 02179 02180 for (;;) { 02181 /* Check if any events are pending and do them if needed */ 02182 if (process_events(s)) 02183 return -1; 02184 res = get_input(s, header_buf); 02185 if (res == 0) { 02186 continue; 02187 } else if (res > 0) { 02188 if (ast_strlen_zero(header_buf)) 02189 return process_message(s, &m) ? -1 : 0; 02190 else if (m.hdrcount < (AST_MAX_MANHEADERS - 1)) 02191 m.headers[m.hdrcount++] = ast_strdupa(header_buf); 02192 } else { 02193 return res; 02194 } 02195 } 02196 }
|
|
|
Definition at line 1696 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(). 01697 { 01698 struct fast_originate_helper *in = data; 01699 int res; 01700 int reason = 0; 01701 struct ast_channel *chan = NULL; 01702 char requested_channel[AST_CHANNEL_NAME]; 01703 01704 if (!ast_strlen_zero(in->app)) { 01705 res = ast_pbx_outgoing_app(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->app, in->appdata, &reason, 1, 01706 S_OR(in->cid_num, NULL), 01707 S_OR(in->cid_name, NULL), 01708 in->vars, in->account, &chan); 01709 } else { 01710 res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, 01711 S_OR(in->cid_num, NULL), 01712 S_OR(in->cid_name, NULL), 01713 in->vars, in->account, &chan); 01714 } 01715 01716 if (!chan) 01717 snprintf(requested_channel, AST_CHANNEL_NAME, "%s/%s", in->tech, in->data); 01718 /* Tell the manager what happened with the channel */ 01719 manager_event(EVENT_FLAG_CALL, "OriginateResponse", 01720 "%s" 01721 "Response: %s\r\n" 01722 "Channel: %s\r\n" 01723 "Context: %s\r\n" 01724 "Exten: %s\r\n" 01725 "Reason: %d\r\n" 01726 "Uniqueid: %s\r\n" 01727 "CallerIDNum: %s\r\n" 01728 "CallerIDName: %s\r\n", 01729 in->idtext, res ? "Failure" : "Success", chan ? chan->name : requested_channel, in->context, in->exten, reason, 01730 chan ? chan->uniqueid : "<null>", 01731 S_OR(in->cid_num, "<unknown>"), 01732 S_OR(in->cid_name, "<unknown>") 01733 ); 01734 01735 /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ 01736 if (chan) 01737 ast_channel_unlock(chan); 01738 free(in); 01739 return NULL; 01740 }
|
|
|
Definition at line 652 of file manager.c. References ast_mutex_destroy(), free, s, and unref_event(). Referenced by destroy_session(), and purge_sessions(). 00653 { 00654 struct eventqent *eqe = s->last_ev; 00655 if (s->f != NULL) 00656 fclose(s->f); 00657 ast_mutex_destroy(&s->__lock); 00658 free(s); 00659 unref_event(eqe); 00660 }
|
|
||||||||||||
|
Read one full line (including crlf) from the manager socket. Definition at line 2109 of file manager.c. References s. Referenced by do_message(), and skinny_session(). 02110 { 02111 int res, x; 02112 int maxlen = sizeof(s->inbuf) - 1; 02113 char *src = s->inbuf; 02114 02115 /* 02116 * Look for \r\n within the buffer. If found, copy to the output 02117 * buffer and return, trimming the \r\n (not used afterwards). 02118 */ 02119 for (x = 0; x < s->inlen; x++) { 02120 int cr; /* set if we have \r */ 02121 if (src[x] == '\r' && x+1 < s->inlen && src[x+1] == '\n') 02122 cr = 2; /* Found. Update length to include \r\n */ 02123 else if (src[x] == '\n') 02124 cr = 1; /* also accept \n only */ 02125 else 02126 continue; 02127 memmove(output, src, x); /*... but trim \r\n */ 02128 output[x] = '\0'; /* terminate the string */ 02129 x += cr; /* number of bytes used */ 02130 s->inlen -= x; /* remaining size */ 02131 memmove(src, src + x, s->inlen); /* remove used bytes */ 02132 return 1; 02133 } 02134 if (s->inlen >= maxlen) { 02135 /* no crlf found, and buffer full - sorry, too long for us */ 02136 ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->sin.sin_addr), src); 02137 s->inlen = 0; 02138 } 02139 res = 0; 02140 while (res == 0) { 02141 /* XXX do we really need this locking ? */ 02142 ast_mutex_lock(&s->__lock); 02143 s->waiting_thread = pthread_self(); 02144 ast_mutex_unlock(&s->__lock); 02145 02146 res = ast_wait_for_input(s->fd, -1); /* return 0 on timeout ? */ 02147 02148 ast_mutex_lock(&s->__lock); 02149 s->waiting_thread = AST_PTHREADT_NULL; 02150 ast_mutex_unlock(&s->__lock); 02151 } 02152 if (res < 0) { 02153 /* If we get a signal from some other thread (typically because 02154 * there are new events queued), return 0 to notify the caller. 02155 */ 02156 if (errno == EINTR) 02157 return 0; 02158 ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno)); 02159 return -1; 02160 } 02161 ast_mutex_lock(&s->__lock); 02162 res = fread(src + s->inlen, 1, maxlen - s->inlen, s->f); 02163 if (res < 1) 02164 res = -1; /* error return */ 02165 else { 02166 s->inlen += res; 02167 src[s->inlen] = '\0'; 02168 res = 0; 02169 } 02170 ast_mutex_unlock(&s->__lock); 02171 return res; 02172 }
|
|
|
lookup an entry in the list of registered users. must be called with the list lock held. Definition at line 404 of file manager.c. References AST_LIST_TRAVERSE, and ast_manager_user::username. Referenced by handle_showmanager(). 00405 { 00406 struct ast_manager_user *user = NULL; 00407 00408 AST_LIST_TRAVERSE(&users, user, list) 00409 if (!strcasecmp(user->username, name)) 00410 break; 00411 return user; 00412 }
|
|
|
Definition at line 340 of file manager.c. References ast_instring(), and perms. Referenced by authenticate(). 00341 { 00342 int x = 0, ret = 0; 00343 00344 if (!instr) 00345 return 0; 00346 00347 for (x = 0; x < (sizeof(perms) / sizeof(perms[0])); x++) { 00348 if (ast_instring(instr, perms[x].label, ',')) 00349 ret |= perms[x].num; 00350 } 00351 00352 return ret; 00353 }
|
|
|
Event list management functions. We assume that the event list always has at least one element, and the delete code will not remove the last entry even if the. Grab a reference to the last event, update usecount as needed. Can handle a NULL pointer. Definition at line 246 of file manager.c. References AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_UNLOCK, and eventqent::usecount. Referenced by session_do(). 00247 { 00248 struct eventqent *ret; 00249 00250 AST_LIST_LOCK(&all_events); 00251 ret = AST_LIST_LAST(&all_events); 00252 /* the list is never empty now, but may become so when 00253 * we optimize it in the future, so be prepared. 00254 */ 00255 if (ret) 00256 ast_atomic_fetchadd_int(&ret->usecount, 1); 00257 AST_LIST_UNLOCK(&all_events); 00258 return ret; 00259 }
|
|
||||||||||||||||
|
Definition at line 438 of file manager.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 00439 { 00440 if (argc == 2) 00441 ast_cli(fd, "manager debug is %s\n", manager_debug? "on" : "off"); 00442 else if (argc == 3) { 00443 if (!strcasecmp(argv[2], "on")) 00444 manager_debug = 1; 00445 else if (!strcasecmp(argv[2], "off")) 00446 manager_debug = 0; 00447 else 00448 return RESULT_SHOWUSAGE; 00449 } 00450 return RESULT_SUCCESS; 00451 }
|
|
||||||||||||||||
|
Definition at line 453 of file manager.c. References ast_cli(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_manager_user::deny, ast_manager_user::displayconnects, get_manager_by_name_locked(), 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. 00454 { 00455 struct ast_manager_user *user = NULL; 00456 00457 if (argc != 4) 00458 return RESULT_SHOWUSAGE; 00459 00460 AST_LIST_LOCK(&users); 00461 00462 if (!(user = get_manager_by_name_locked(argv[3]))) { 00463 ast_cli(fd, "There is no manager called %s\n", argv[3]); 00464 AST_LIST_UNLOCK(&users); 00465 return -1; 00466 } 00467 00468 ast_cli(fd,"\n"); 00469 ast_cli(fd, 00470 " username: %s\n" 00471 " secret: %s\n" 00472 " deny: %s\n" 00473 " permit: %s\n" 00474 " read: %s\n" 00475 " write: %s\n" 00476 "displayconnects: %s\n", 00477 (user->username ? user->username : "(N/A)"), 00478 (user->secret ? user->secret : "(N/A)"), 00479 (user->deny ? user->deny : "(N/A)"), 00480 (user->permit ? user->permit : "(N/A)"), 00481 (user->read ? user->read : "(N/A)"), 00482 (user->write ? user->write : "(N/A)"), 00483 (user->displayconnects ? "yes" : "no")); 00484 00485 AST_LIST_UNLOCK(&users); 00486 00487 return RESULT_SUCCESS; 00488 }
|
|
||||||||||||||||
|
Definition at line 491 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. 00492 { 00493 struct ast_manager_user *user = NULL; 00494 int count_amu = 0; 00495 00496 if (argc != 3) 00497 return RESULT_SHOWUSAGE; 00498 00499 AST_LIST_LOCK(&users); 00500 00501 /* If there are no users, print out something along those lines */ 00502 if (AST_LIST_EMPTY(&users)) { 00503 ast_cli(fd, "There are no manager users.\n"); 00504 AST_LIST_UNLOCK(&users); 00505 return RESULT_SUCCESS; 00506 } 00507 00508 ast_cli(fd, "\nusername\n--------\n"); 00509 00510 AST_LIST_TRAVERSE(&users, user, list) { 00511 ast_cli(fd, "%s\n", user->username); 00512 count_amu++; 00513 } 00514 00515 AST_LIST_UNLOCK(&users); 00516 00517 ast_cli(fd,"-------------------\n"); 00518 ast_cli(fd,"%d manager users configured.\n", count_amu); 00519 00520 return RESULT_SUCCESS; 00521 }
|
|
||||||||||||||||
|
Definition at line 415 of file manager.c. References manager_action::action, ast_cli(), ast_str_alloca, manager_action::authority, authority_to_str(), manager_action::description, first_action, manager_action::next, RESULT_SHOWUSAGE, S_OR, and manager_action::synopsis. 00416 { 00417 struct manager_action *cur; 00418 struct ast_str *authority = ast_str_alloca(80); 00419 int num; 00420 00421 if (argc != 4) 00422 return RESULT_SHOWUSAGE; 00423 00424 for (cur = first_action; cur; cur = cur->next) { /* Walk the list of actions */ 00425 for (num = 3; num < argc; num++) { 00426 if (!strcasecmp(cur->action, argv[num])) { 00427 ast_cli(fd, "Action: %s\nSynopsis: %s\nPrivilege: %s\n%s\n", 00428 cur->action, cur->synopsis, 00429 authority_to_str(cur->authority, &authority), 00430 S_OR(cur->description, "") ); 00431 } 00432 } 00433 } 00434 00435 return RESULT_SUCCESS; 00436 }
|
|
||||||||||||||||
|
CLI command manager list commands.
Definition at line 525 of file manager.c. References manager_action::action, ast_cli(), ast_rwlock_rdlock(), ast_rwlock_unlock(), ast_str_alloca, manager_action::authority, authority_to_str(), first_action, format, manager_action::next, RESULT_SUCCESS, and manager_action::synopsis. 00526 { 00527 struct manager_action *cur; 00528 struct ast_str *authority = ast_str_alloca(80); 00529 char *format = " %-15.15s %-15.15s %-55.55s\n"; 00530 00531 ast_cli(fd, format, "Action", "Privilege", "Synopsis"); 00532 ast_cli(fd, format, "------", "---------", "--------"); 00533 00534 ast_rwlock_rdlock(&actionlock); 00535 for (cur = first_action; cur; cur = cur->next) /* Walk the list of actions */ 00536 ast_cli(fd, format, cur->action, authority_to_str(cur->authority, &authority), cur->synopsis); 00537 ast_rwlock_unlock(&actionlock); 00538 00539 return RESULT_SUCCESS; 00540 }
|
|
||||||||||||||||
|
CLI command manager list connected.
Definition at line 543 of file manager.c. References ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, format, RESULT_SUCCESS, s, and sessions. 00544 { 00545 struct mansession *s; 00546 char *format = " %-15.15s %-15.15s\n"; 00547 00548 ast_cli(fd, format, "Username", "IP Address"); 00549 00550 AST_LIST_LOCK(&sessions); 00551 AST_LIST_TRAVERSE(&sessions, s, list) 00552 ast_cli(fd, format,s->username, ast_inet_ntoa(s->sin.sin_addr)); 00553 AST_LIST_UNLOCK(&sessions); 00554 00555 return RESULT_SUCCESS; 00556 }
|
|
||||||||||||||||
|
CLI command manager list eventq.
Definition at line 560 of file manager.c. References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, RESULT_SUCCESS, and s. 00561 { 00562 struct eventqent *s; 00563 00564 AST_LIST_LOCK(&all_events); 00565 AST_LIST_TRAVERSE(&all_events, s, eq_next) { 00566 ast_cli(fd, "Usecount: %d\n",s->usecount); 00567 ast_cli(fd, "Category: %d\n", s->category); 00568 ast_cli(fd, "Event:\n%s", s->eventdata); 00569 } 00570 AST_LIST_UNLOCK(&all_events); 00571 00572 return RESULT_SUCCESS; 00573 }
|
|
||||||||||||||||
|
Definition at line 1051 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(). 01052 { 01053 int x; 01054 char hdr[40]; 01055 const char *action, *cat, *var, *value, *match; 01056 struct ast_category *category; 01057 struct ast_variable *v; 01058 01059 for (x=0;x<100000;x++) { 01060 snprintf(hdr, sizeof(hdr), "Action-%06d", x); 01061 action = astman_get_header(m, hdr); 01062 if (ast_strlen_zero(action)) 01063 break; 01064 snprintf(hdr, sizeof(hdr), "Cat-%06d", x); 01065 cat = astman_get_header(m, hdr); 01066 snprintf(hdr, sizeof(hdr), "Var-%06d", x); 01067 var = astman_get_header(m, hdr); 01068 snprintf(hdr, sizeof(hdr), "Value-%06d", x); 01069 value = astman_get_header(m, hdr); 01070 snprintf(hdr, sizeof(hdr), "Match-%06d", x); 01071 match = astman_get_header(m, hdr); 01072 if (!strcasecmp(action, "newcat")) { 01073 if (!ast_strlen_zero(cat)) { 01074 category = ast_category_new(cat); 01075 if (category) { 01076 ast_category_append(cfg, category); 01077 } 01078 } 01079 } else if (!strcasecmp(action, "renamecat")) { 01080 if (!ast_strlen_zero(cat) && !ast_strlen_zero(value)) { 01081 category = ast_category_get(cfg, cat); 01082 if (category) 01083 ast_category_rename(category, value); 01084 } 01085 } else if (!strcasecmp(action, "delcat")) { 01086 if (!ast_strlen_zero(cat)) 01087 ast_category_delete(cfg, cat); 01088 } else if (!strcasecmp(action, "update")) { 01089 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat))) 01090 ast_variable_update(category, var, value, match); 01091 } else if (!strcasecmp(action, "delete")) { 01092 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && (category = ast_category_get(cfg, cat))) 01093 ast_variable_delete(category, var, match); 01094 } else if (!strcasecmp(action, "append")) { 01095 if (!ast_strlen_zero(cat) && !ast_strlen_zero(var) && 01096 (category = ast_category_get(cfg, cat)) && 01097 (v = ast_variable_new(var, value))){ 01098 if (match && !strcasecmp(match, "object")) 01099 v->object = 1; 01100 ast_variable_append(category, v); 01101 } 01102 } 01103 } 01104 }
|
|
||||||||||||||||||||
|
Definition at line 2412 of file manager.c. References EVENT_FLAG_CALL, and manager_event. Referenced by init_manager(). 02413 { 02414 /* Notify managers of change */ 02415 manager_event(EVENT_FLAG_CALL, "ExtensionStatus", "Exten: %s\r\nContext: %s\r\nStatus: %d\r\n", exten, context, state); 02416 return 0; 02417 }
|
|
|
Send any applicable events to the client listening on this socket. Wait only for a finite time on each event, and drop all events whether they are successfully sent or not. Definition at line 1996 of file manager.c. References ast_mutex_lock(), ast_mutex_unlock(), NEW_EVENT, ref_event(), s, send_string(), and unref_event(). Referenced by do_message(). 01997 { 01998 int ret = 0; 01999 02000 ast_mutex_lock(&s->__lock); 02001 if (s->f != NULL) { 02002 struct eventqent *eqe; 02003 02004 while ( (eqe = NEW_EVENT(s)) ) { 02005 ref_event(eqe); 02006 if (!ret && s->authenticated && 02007 (s->readperm & eqe->category) == eqe->category && 02008 (s->send_events & eqe->category) == eqe->category) { 02009 if (send_string(s, eqe->eventdata) < 0) 02010 ret = -1; /* don't send more */ 02011 } 02012 s->last_ev = unref_event(s->last_ev); 02013 } 02014 } 02015 ast_mutex_unlock(&s->__lock); 02016 return ret; 02017 }
|
|
||||||||||||
|
Definition at line 2057 of file manager.c. References manager_action::action, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rwlock_rdlock(), ast_strlen_zero(), astman_get_header(), astman_send_error(), manager_action::authority, first_action, manager_action::func, LOG_DEBUG, manager_action::next, option_debug, and s. Referenced by do_message(). 02058 { 02059 char action[80] = ""; 02060 int ret = 0; 02061 struct manager_action *tmp; 02062 02063 ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action)); 02064 if (option_debug) 02065 ast_log(LOG_DEBUG, "Manager received command '%s'\n", action); 02066 02067 if (ast_strlen_zero(action)) { 02068 astman_send_error(s, m, "Missing action in request"); 02069 return 0; 02070 } 02071 02072 if (!s->authenticated && strcasecmp(action, "Login") && strcasecmp(action, "Logoff") && strcasecmp(action, "Challenge")) { 02073 ast_mutex_lock(&s->__lock); 02074 astman_send_error(s, m, "Permission denied"); 02075 ast_mutex_unlock(&s->__lock); 02076 return 0; 02077 } 02078 ast_rwlock_rdlock(&actionlock); 02079 for (tmp = first_action ; tmp; tmp = tmp->next) { 02080 if (strcasecmp(action, tmp->action)) 02081 continue; 02082 if ((s->writeperm & tmp->authority) == tmp->authority) { 02083 if (tmp->func(s, m)) { /* error */ 02084 return -1; 02085 } 02086 } else 02087 astman_send_error(s, m, "Permission denied"); 02088 break; 02089 } 02090 ast_rwlock_unlock(&actionlock); 02091 if (!tmp) { 02092 ast_mutex_lock(&s->__lock); 02093 astman_send_error(s, m, "Invalid/unknown command. Use Action: ListCommands to show available commands."); 02094 ast_mutex_unlock(&s->__lock); 02095 } 02096 if (ret) 02097 return ret; 02098 /* Once done with our message, deliver any pending events */ 02099 return process_events(s); 02100 }
|
|
|
Purge unused events. Remove elements from the head as long as their usecount is 0 and there is a next element. Definition at line 265 of file manager.c. References AST_LIST_FIRST, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free, and eventqent::usecount. Referenced by purge_old_stuff(). 00266 { 00267 struct eventqent *ev; 00268 00269 AST_LIST_LOCK(&all_events); 00270 while ( (ev = AST_LIST_FIRST(&all_events)) && 00271 ev->usecount == 0 && AST_LIST_NEXT(ev, eq_next)) { 00272 AST_LIST_REMOVE_HEAD(&all_events, eq_next); 00273 free(ev); 00274 } 00275 AST_LIST_UNLOCK(&all_events); 00276 }
|
|
|
remove at most n_max stale session from the list.
Definition at line 2267 of file manager.c. References ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_verbose(), free_session(), num_sessions, option_verbose, s, and sessions. Referenced by purge_old_stuff(). 02268 { 02269 struct mansession *s; 02270 time_t now = time(NULL); 02271 02272 AST_LIST_LOCK(&sessions); 02273 AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) { 02274 if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) { 02275 AST_LIST_REMOVE_CURRENT(&sessions, list); 02276 ast_atomic_fetchadd_int(&num_sessions, -1); 02277 if (s->authenticated && (option_verbose > 1) && displayconnects) { 02278 ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' timed out from %s\n", 02279 s->username, ast_inet_ntoa(s->sin.sin_addr)); 02280 } 02281 free_session(s); /* XXX outside ? */ 02282 if (--n_max <= 0) 02283 break; 02284 } 02285 } 02286 AST_LIST_TRAVERSE_SAFE_END 02287 AST_LIST_UNLOCK(&sessions); 02288 }
|
|
|
Definition at line 644 of file manager.c. References eventqent::usecount. Referenced by process_events(). 00645 { 00646 ast_atomic_fetchadd_int(&e->usecount, 1); 00647 }
|
|
||||||||||||
|
helper function to send a string to the socket. Return -1 on error (e.g. buffer full). Definition at line 726 of file manager.c. References pollfd::fd, len, poll(), POLLOUT, and s. Referenced by astman_append(), and process_events(). 00727 { 00728 int len = strlen(string); /* residual length */ 00729 char *src = string; 00730 struct timeval start = ast_tvnow(); 00731 int n = 0; 00732 00733 for (;;) { 00734 int elapsed; 00735 struct pollfd fd; 00736 n = fwrite(src, 1, len, s->f); /* try to write the string, non blocking */ 00737 if (n == len /* ok */ || n < 0 /* error */) 00738 break; 00739 len -= n; /* skip already written data */ 00740 src += n; 00741 fd.fd = s->fd; 00742 fd.events = POLLOUT; 00743 n = -1; /* error marker */ 00744 elapsed = ast_tvdiff_ms(ast_tvnow(), start); 00745 if (elapsed > s->writetimeout) 00746 break; 00747 if (poll(&fd, 1, s->writetimeout - elapsed) < 1) 00748 break; 00749 } 00750 fflush(s->f); 00751 return n < 0 ? -1 : 0; 00752 }
|
|
|
The body of the individual manager session. Call get_input() to read one line at a time (or be woken up on new events), collect the lines in a message until found an empty line, and execute the request. In any case, deliver events asynchronously through process_events() (called from here if no line is available, or at the end of process_message(). ).
Definition at line 2206 of file manager.c. References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_mutex_init(), AST_PTHREADT_NULL, astman_append(), block_sockets, do_message(), server_instance::f, server_instance::fd, grab_last(), num_sessions, server_instance::requestor, s, and sessions. 02207 { 02208 struct server_instance *ser = data; 02209 struct mansession *s = ast_calloc(1, sizeof(*s)); 02210 int flags; 02211 int res; 02212 02213 if (s == NULL) 02214 goto done; 02215 02216 s->writetimeout = 100; 02217 s->waiting_thread = AST_PTHREADT_NULL; 02218 02219 flags = fcntl(ser->fd, F_GETFL); 02220 if (!block_sockets) /* make sure socket is non-blocking */ 02221 flags |= O_NONBLOCK; 02222 else 02223 flags &= ~O_NONBLOCK; 02224 fcntl(ser->fd, F_SETFL, flags); 02225 02226 ast_mutex_init(&s->__lock); 02227 s->send_events = -1; 02228 /* these fields duplicate those in the 'ser' structure */ 02229 s->fd = ser->fd; 02230 s->f = ser->f; 02231 s->sin = ser->requestor; 02232 02233 ast_atomic_fetchadd_int(&num_sessions, 1); 02234 AST_LIST_LOCK(&sessions); 02235 AST_LIST_INSERT_HEAD(&sessions, s, list); 02236 AST_LIST_UNLOCK(&sessions); 02237 /* Hook to the tail of the event queue */ 02238 s->last_ev = grab_last(); 02239 s->f = ser->f; 02240 astman_append(s, "Asterisk Call Manager/1.0\r\n"); /* welcome prompt */ 02241 for (;;) { 02242 if ((res = do_message(s)) < 0) 02243 break; 02244 } 02245 /* session is over, explain why and terminate */ 02246 if (s->authenticated) { 02247 if (option_verbose > 1) { 02248 if (displayconnects) 02249 ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); 02250 } 02251 ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr)); 02252 } else { 02253 if (option_verbose > 1) { 02254 if (displayconnects) 02255 ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr)); 02256 } 02257 ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(s->sin.sin_addr)); 02258 } 02259 destroy_session(s); 02260 02261 done: 02262 free(ser); 02263 return NULL; 02264 }
|
|
||||||||||||
|
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 843 of file manager.c. References ast_mutex_lock(), ast_mutex_unlock(), s, and strings_to_mask(). Referenced by action_events(). 00844 { 00845 int maskint = strings_to_mask(eventmask); 00846 00847 ast_mutex_lock(&s->__lock); 00848 if (maskint >= 0) 00849 s->send_events = maskint; 00850 ast_mutex_unlock(&s->__lock); 00851 00852 return maskint; 00853 }
|
|
|
A number returns itself, false returns 0, true returns all flags, other strings return the flags that are set. Definition at line 359 of file manager.c. References ast_false(), ast_strlen_zero(), ast_true(), and perms. Referenced by set_eventmask(). 00360 { 00361 const char *p; 00362 00363 if (ast_strlen_zero(string)) 00364 return -1; 00365 00366 for (p = string; *p; p++) 00367 if (*p < '0' || *p > '9') 00368 break; 00369 if (!p) /* all digits */ 00370 return atoi(string); 00371 if (ast_false(string)) 00372 return 0; 00373 if (ast_true(string)) { /* all permissions */ 00374 int x, ret = 0; 00375 for (x=0; x<sizeof(perms) / sizeof(perms[0]); x++) 00376 ret |= perms[x].num; 00377 return ret; 00378 } 00379 return get_perm(string); 00380 }
|
|
|
Definition at line 638 of file manager.c. References AST_LIST_NEXT, and eventqent::usecount. Referenced by free_session(), and process_events(). 00639 { 00640 ast_atomic_fetchadd_int(&e->usecount, -1); 00641 return AST_LIST_NEXT(e, eq_next); 00642 }
|
|
|
Definition at line 113 of file manager.c. Referenced by session_do(). |
|
|
Definition at line 602 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 109 of file manager.c. Referenced by action_login(). |
|
|
list of actions registered
Definition at line 176 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(). |
|
|
|
|
|
enable some debugging code in the manager Definition at line 116 of file manager.c. Referenced by __manager_event(). |
|
|
Initial value: "Description: Run a CLI command.\n" "Variables: (Names marked with * are required)\n" " *Command: Asterisk CLI command to run\n" " ActionID: Optional Action id for message matching.\n" Definition at line 1646 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 1276 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 1924 of file manager.c. Referenced by init_manager(). |
|
|
Initial value: "Description: A 'GetConfig' action will dump the contents of a configuration\n" "file by category and contents.\n" "Variables:\n" " Filename: Configuration filename (e.g. foo.conf)\n" Definition at line 1013 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 1409 of file manager.c. Referenced by init_manager(). |
|
|
Initial value: "Description: Hangup a channel\n" "Variables: \n" " Channel: The channel name to be hungup\n" Definition at line 1343 of file manager.c. Referenced by init_manager(). |
|
|
Initial value: "Description: Returns the action name and synopsis for every\n" " action that is available to the user\n" "Variables: NONE\n" Definition at line 1254 of file manager.c. Referenced by init_manager(). |
|
|
Initial value: "Description: Logoff this manager session\n" "Variables: NONE\n" Definition at line 1298 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 1893 of file manager.c. Referenced by init_manager(). |
|
|
Help text for manager command mailboxstatus.
Definition at line 1865 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 1742 of file manager.c. Referenced by init_manager(). |
|
|
Initial value: "Description: A 'Ping' action will ellicit a 'Pong' response. Used to keep the\n" " manager connection open.\n" "Variables: NONE\n"
Definition at line 1002 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 1582 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 1541 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 1367 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 1959 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 1106 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 2019 of file manager.c. Referenced by init_manager(). |
|
|
Manager WAITEVENT.
Definition at line 1152 of file manager.c. Referenced by init_manager(). |
|
|
Definition at line 114 of file manager.c. Referenced by __manager_event(), purge_sessions(), and session_do(). |
|
|
helper functions to convert back and forth between string and numeric representation of set of flags Referenced by authority_to_str(), get_perm(), and strings_to_mask(). |
|
|
Initial value: " Usage: manager show user <user>\n" " Display all information related to the manager user specified.\n" |
|
|
Initial value: "Usage: manager show users\n" " Prints a listing of all managers that are currently configured on that\n" " system.\n" |
|
|
Initial value: "Usage: manager show command <actionname>\n" " Shows the detailed description for a specific Asterisk manager interface command.\n" |
|
|
Initial value: "Usage: manager show commands\n" " Prints a listing of all the available Asterisk manager interface commands.\n" |
|
|
Initial value: "Usage: manager show connected\n" " Prints a listing of the users that are currently connected to the\n" "Asterisk manager interface.\n" |
|
|
Initial value: "Usage: manager show eventq\n" " Prints a listing of all events pending in the Asterisk manger\n" "event queue.\n" |
|
|
Definition at line 110 of file manager.c. Referenced by __manager_event(). |