Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

manager.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <sys/poll.h>
#include <asterisk/channel.h>
#include <asterisk/file.h>
#include <asterisk/manager.h>
#include <asterisk/config.h>
#include <asterisk/lock.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/cli.h>
#include <asterisk/app.h>
#include <asterisk/pbx.h>
#include <asterisk/md5.h>
#include <asterisk/acl.h>
#include <asterisk/utils.h>

Go to the source code of this file.

Data Structures

struct  fast_originate_helper
struct  permalias

Functions

 AST_MUTEX_DEFINE_STATIC (sessionlock)
 AST_MUTEX_DEFINE_STATIC (actionlock)
int ast_carefulwrite (int fd, char *s, int len, int timeoutms)
char * astman_get_header (struct message *m, char *var)
void astman_send_error (struct mansession *s, struct message *m, char *error)
void astman_send_response (struct mansession *s, struct message *m, char *resp, char *msg)
void astman_send_ack (struct mansession *s, struct message *m, char *msg)
int manager_event (int category, char *event, char *fmt,...)
int ast_manager_unregister (char *action)
int ast_manager_register2 (char *action, int auth, int(*func)(struct mansession *s, struct message *m), char *synopsis, char *description)
int init_manager (void)
int reload_manager (void)


Function Documentation

int ast_carefulwrite int  fd,
char *  s,
int  len,
int  timeoutms
 

Definition at line 85 of file manager.c.

References pollfd::events, pollfd::fd, poll(), and POLLOUT.

Referenced by ast_cli(), and manager_event().

00086 {
00087    /* Try to write string, but wait no more than ms milliseconds
00088       before timing out */
00089    int res=0;
00090    struct pollfd fds[1];
00091    while(len) {
00092       res = write(fd, s, len);
00093       if ((res < 0) && (errno != EAGAIN)) {
00094          return -1;
00095       }
00096       if (res < 0) res = 0;
00097       len -= res;
00098       s += res;
00099       fds[0].fd = fd;
00100       fds[0].events = POLLOUT;
00101       /* Wait until writable again */
00102       res = poll(fds, 1, timeoutms);
00103       if (res < 1)
00104          return -1;
00105    }
00106    return res;
00107 }

int ast_manager_register2 char *  action,
int  auth,
int(*)(struct mansession *s, struct message *m)  func,
char *  synopsis,
char *  description
 

Definition at line 1420 of file manager.c.

References manager_action::action, ast_log(), ast_mutex_unlock, manager_action::authority, manager_action::description, manager_action::func, LOG_WARNING, malloc, manager_action::next, and manager_action::synopsis.

Referenced by init_manager().

01421 {
01422    struct manager_action *cur;
01423 
01424    cur = malloc(sizeof(struct manager_action));
01425    if (!cur) {
01426       ast_log(LOG_WARNING, "Manager: out of memory trying to register action\n");
01427       ast_mutex_unlock(&actionlock);
01428       return -1;
01429    }
01430    cur->action = action;
01431    cur->authority = auth;
01432    cur->func = func;
01433    cur->synopsis = synopsis;
01434    cur->description = description;
01435    cur->next = NULL;
01436 
01437    ast_manager_register_struct(cur);
01438 
01439    return 0;
01440 }

int ast_manager_unregister char *  action  ) 
 

Definition at line 1352 of file manager.c.

References manager_action::action, ast_mutex_lock, ast_mutex_unlock, ast_verbose(), free, manager_action::next, option_verbose, and VERBOSE_PREFIX_2.

01352                                            {
01353    struct manager_action *cur = first_action, *prev = first_action;
01354 
01355    ast_mutex_lock(&actionlock);
01356    while( cur ) {       
01357       if (!strcasecmp(action, cur->action)) {
01358          prev->next = cur->next;
01359          free(cur);
01360          if (option_verbose > 1) 
01361             ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action);
01362          ast_mutex_unlock(&actionlock);
01363          return 0;
01364       }
01365       prev = cur;
01366       cur = cur->next;
01367    }
01368    ast_mutex_unlock(&actionlock);
01369    return 0;
01370 }

AST_MUTEX_DEFINE_STATIC actionlock   ) 
 

AST_MUTEX_DEFINE_STATIC sessionlock   ) 
 

char* astman_get_header struct message m,
char *  var
 

Definition at line 256 of file manager.c.

References message::headers.

Referenced by astman_send_error(), and astman_send_response().

00257 {
00258    char cmp[80];
00259    int x;
00260    snprintf(cmp, sizeof(cmp), "%s: ", var);
00261    for (x=0;x<m->hdrcount;x++)
00262       if (!strncasecmp(cmp, m->headers[x], strlen(cmp)))
00263          return m->headers[x] + strlen(cmp);
00264    return "";
00265 }

void astman_send_ack struct mansession s,
struct message m,
char *  msg
 

Definition at line 292 of file manager.c.

References astman_send_response().

00293 {
00294    astman_send_response(s, m, "Success", msg);
00295 }

void astman_send_error struct mansession s,
struct message m,
char *  error
 

Definition at line 267 of file manager.c.

References ast_cli(), ast_mutex_lock, ast_mutex_unlock, astman_get_header(), mansession::fd, and mansession::lock.

00268 {
00269    char *id = astman_get_header(m,"ActionID");
00270    ast_mutex_lock(&s->lock);
00271    ast_cli(s->fd, "Response: Error\r\n");
00272    if (id && !ast_strlen_zero(id))
00273       ast_cli(s->fd, "ActionID: %s\r\n",id);
00274    ast_cli(s->fd, "Message: %s\r\n\r\n", error);
00275    ast_mutex_unlock(&s->lock);
00276 }

void astman_send_response struct mansession s,
struct message m,
char *  resp,
char *  msg
 

Definition at line 278 of file manager.c.

References ast_cli(), ast_mutex_lock, ast_mutex_unlock, astman_get_header(), mansession::fd, and mansession::lock.

Referenced by astman_send_ack().

00279 {
00280    char *id = astman_get_header(m,"ActionID");
00281    ast_mutex_lock(&s->lock);
00282    ast_cli(s->fd, "Response: %s\r\n", resp);
00283    if (id && !ast_strlen_zero(id))
00284       ast_cli(s->fd, "ActionID: %s\r\n",id);
00285    if (msg)
00286       ast_cli(s->fd, "Message: %s\r\n\r\n", msg);
00287    else
00288       ast_cli(s->fd, "\r\n");
00289    ast_mutex_unlock(&s->lock);
00290 }

int init_manager void   ) 
 

Definition at line 1444 of file manager.c.

References ast_cli_register(), ast_destroy(), ast_extension_state_add(), ast_load(), ast_log(), ast_manager_register, ast_manager_register2(), ast_pthread_create(), ast_true(), ast_variable_retrieve(), ast_verbose(), DEFAULT_MANAGER_PORT, EVENT_FLAG_CALL, EVENT_FLAG_COMMAND, LOG_NOTICE, LOG_WARNING, and option_verbose.

Referenced by main(), and reload_manager().

01445 {
01446    struct ast_config *cfg;
01447    char *val;
01448    int oldportno = portno;
01449    static struct sockaddr_in ba;
01450    int x = 1;
01451    if (!registered) {
01452       /* Register default actions */
01453       ast_manager_register2("Ping", 0, action_ping, "Ping", mandescr_ping);
01454       ast_manager_register2("Events", 0, action_events, "Contol Event Flow", mandescr_events);
01455       ast_manager_register2("Logoff", 0, action_logoff, "Logoff Manager", mandescr_logoff);
01456       ast_manager_register2("Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel", mandescr_hangup);
01457       ast_manager_register( "Status", EVENT_FLAG_CALL, action_status, "Status" );
01458       ast_manager_register2( "Setvar", EVENT_FLAG_CALL, action_setvar, "Set Channel Variable", mandescr_setvar );
01459       ast_manager_register2( "Getvar", EVENT_FLAG_CALL, action_getvar, "Gets a Channel Variable", mandescr_getvar );
01460       ast_manager_register( "Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect" );
01461       ast_manager_register2("Originate", EVENT_FLAG_CALL, action_originate, "Originate Call", mandescr_originate);
01462       ast_manager_register2( "Command", EVENT_FLAG_COMMAND, action_command, "Execute Command", mandescr_command );
01463       ast_manager_register2( "ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status", mandescr_extensionstate );
01464       ast_manager_register2( "AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout );
01465       ast_manager_register2( "MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox", mandescr_mailboxstatus );
01466       ast_manager_register2( "MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count", mandescr_mailboxcount );
01467       ast_manager_register2("ListCommands", 0, action_listcommands, "List available manager commands", mandescr_listcommands);
01468 
01469       ast_cli_register(&show_mancmd_cli);
01470       ast_cli_register(&show_mancmds_cli);
01471       ast_cli_register(&show_manconn_cli);
01472       ast_extension_state_add(NULL, NULL, manager_state_cb, NULL);
01473       registered = 1;
01474    }
01475    portno = DEFAULT_MANAGER_PORT;
01476    cfg = ast_load("manager.conf");
01477    if (!cfg) {
01478       ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf.  Call management disabled.\n");
01479       return 0;
01480    }
01481    memset(&ba, 0, sizeof(ba));
01482    val = ast_variable_retrieve(cfg, "general", "enabled");
01483    if (val)
01484       enabled = ast_true(val);
01485 
01486    val = ast_variable_retrieve(cfg, "general", "block-sockets");
01487    if(val)
01488       block_sockets = ast_true(val);
01489 
01490    if ((val = ast_variable_retrieve(cfg, "general", "port"))) {
01491       if (sscanf(val, "%d", &portno) != 1) {
01492          ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
01493          portno = DEFAULT_MANAGER_PORT;
01494       }
01495    } else if ((val = ast_variable_retrieve(cfg, "general", "portno"))) {
01496       if (sscanf(val, "%d", &portno) != 1) {
01497          ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
01498          portno = DEFAULT_MANAGER_PORT;
01499       }
01500       ast_log(LOG_NOTICE, "Use of portno in manager.conf deprecated.  Please use 'port=%s' instead.\n", val);
01501    }
01502    
01503    ba.sin_family = AF_INET;
01504    ba.sin_port = htons(portno);
01505    memset(&ba.sin_addr, 0, sizeof(ba.sin_addr));
01506    
01507    if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) {
01508       if (!inet_aton(val, &ba.sin_addr)) { 
01509          ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val);
01510          memset(&ba.sin_addr, 0, sizeof(ba.sin_addr));
01511       }
01512    }
01513    
01514    if ((asock > -1) && ((portno != oldportno) || !enabled)) {
01515 #if 0
01516       /* Can't be done yet */
01517       close(asock);
01518       asock = -1;
01519 #else
01520       ast_log(LOG_WARNING, "Unable to change management port / enabled\n");
01521 #endif
01522    }
01523    ast_destroy(cfg);
01524    
01525    /* If not enabled, do nothing */
01526    if (!enabled) {
01527       return 0;
01528    }
01529    if (asock < 0) {
01530       asock = socket(AF_INET, SOCK_STREAM, 0);
01531       if (asock < 0) {
01532          ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
01533          return -1;
01534       }
01535       setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
01536       if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) {
01537          ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno));
01538          close(asock);
01539          asock = -1;
01540          return -1;
01541       }
01542       if (listen(asock, 2)) {
01543          ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno));
01544          close(asock);
01545          asock = -1;
01546          return -1;
01547       }
01548       if (option_verbose)
01549          ast_verbose("Asterisk Management interface listening on port %d\n", portno);
01550       ast_pthread_create(&t, NULL, accept_thread, NULL);
01551    }
01552    return 0;
01553 }

int manager_event int  category,
char *  event,
char *  fmt,
  ...
 

Definition at line 1325 of file manager.c.

References ast_carefulwrite(), ast_cli(), ast_mutex_lock, ast_mutex_unlock, mansession::blocking, mansession::fd, mansession::lock, mansession::next, mansession::readperm, and mansession::send_events.

Referenced by ast_change_name(), ast_channel_bridge(), ast_do_masquerade(), ast_hangup(), ast_request(), ast_set_callerid(), ast_setstate(), and reload_manager().

01326 {
01327    struct mansession *s;
01328    char tmp[4096];
01329    va_list ap;
01330 
01331    ast_mutex_lock(&sessionlock);
01332    s = sessions;
01333    while(s) {
01334       if (((s->readperm & category) == category) && ((s->send_events & category) == category) ) {
01335          ast_mutex_lock(&s->lock);
01336          if (!s->blocking) {
01337             ast_cli(s->fd, "Event: %s\r\n", event);
01338             va_start(ap, fmt);
01339             vsnprintf(tmp, sizeof(tmp), fmt, ap);
01340             va_end(ap);
01341             ast_carefulwrite(s->fd,tmp,strlen(tmp),100);
01342             ast_cli(s->fd, "\r\n");
01343          }
01344          ast_mutex_unlock(&s->lock);
01345       }
01346       s = s->next;
01347    }
01348    ast_mutex_unlock(&sessionlock);
01349    return 0;
01350 }

int reload_manager void   ) 
 

Definition at line 1555 of file manager.c.

References EVENT_FLAG_SYSTEM, init_manager(), and manager_event().

Referenced by ast_module_reload(), and main().

01556 {
01557    manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n");
01558    return init_manager();
01559 }


Generated on Wed Aug 10 11:36:34 2005 for Asterisk by  doxygen 1.4.4