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

manager.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <pthread.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 <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>

Go to the source code of this file.

Data Structures

struct  permalias

Functions

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_register (char *action, int auth, int(*func)(struct mansession *s, struct message *m), char *synopsis)
int init_manager (void)
int reload_manager (void)


Function Documentation

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

Definition at line 66 of file manager.c.

References s.

Referenced by manager_event().

00067 {
00068    /* Try to write string, but wait no more than ms milliseconds
00069       before timing out */
00070    int res=0;
00071    struct timeval tv;
00072    fd_set fds;
00073    while(len) {
00074       res = write(fd, s, len);
00075       if ((res < 0) && (errno != EAGAIN)) {
00076          return -1;
00077       }
00078       if (res < 0) res = 0;
00079       len -= res;
00080       s += res;
00081       tv.tv_sec = timeoutms / 1000;
00082       tv.tv_usec = timeoutms % 1000;
00083       FD_ZERO(&fds);
00084       FD_SET(fd, &fds);
00085       /* Wait until writable again */
00086       res = select(fd + 1, NULL, &fds, NULL, &tv);
00087       if (res < 1)
00088          return -1;
00089    }
00090    return res;
00091 }

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

Definition at line 899 of file manager.c.

References ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), LOG_WARNING, malloc, option_verbose, and VERBOSE_PREFIX_2.

Referenced by init_manager().

00901 {
00902    struct manager_action *cur = first_action, *prev = NULL;
00903 
00904    ast_mutex_lock(&actionlock);
00905    while(cur) { /* Walk the list of actions */
00906       if (!strcasecmp(cur->action, action)) {
00907          ast_log(LOG_WARNING, "Manager: Action '%s' already registered\n", action);
00908          ast_mutex_unlock(&actionlock);
00909          return -1;
00910       }
00911       prev = cur; 
00912       cur = cur->next;
00913    }
00914    cur = malloc( sizeof(struct manager_action) );
00915    if( !cur ) {
00916       ast_log(LOG_WARNING, "Manager: out of memory trying to register action\n");
00917       ast_mutex_unlock(&actionlock);
00918       return -1;
00919    }
00920    strncpy( cur->action, action, 255 );
00921    cur->authority = auth;
00922    cur->func = func;
00923    cur->synopsis = synopsis;
00924    cur->next = NULL;
00925 
00926    if( prev ) prev->next = cur;
00927    else first_action = cur;
00928 
00929    if (option_verbose > 1) 
00930       ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", action);
00931    ast_mutex_unlock(&actionlock);
00932    return 0;
00933 }

int ast_manager_unregister char *  action  ) 
 

Definition at line 872 of file manager.c.

References ast_mutex_lock, ast_mutex_unlock, ast_verbose(), free, option_verbose, and VERBOSE_PREFIX_2.

00872                                            {
00873    struct manager_action *cur = first_action, *prev = first_action;
00874 
00875    ast_mutex_lock(&actionlock);
00876    while( cur ) {       
00877       if (!strcasecmp(action, cur->action)) {
00878          prev->next = cur->next;
00879          free(cur);
00880          if (option_verbose > 1) 
00881             ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action);
00882          ast_mutex_unlock(&actionlock);
00883          return 0;
00884       }
00885       prev = cur;
00886       cur = cur->next;
00887    }
00888    ast_mutex_unlock(&actionlock);
00889    return 0;
00890 }

char* astman_get_header struct message m,
char *  var
 

Definition at line 167 of file manager.c.

References message::hdrcount, and message::headers.

Referenced by astman_send_error(), and astman_send_response().

00168 {
00169    char cmp[80];
00170    int x;
00171    snprintf(cmp, sizeof(cmp), "%s: ", var);
00172    for (x=0;x<m->hdrcount;x++)
00173       if (!strncasecmp(cmp, m->headers[x], strlen(cmp)))
00174          return m->headers[x] + strlen(cmp);
00175    return "";
00176 }

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

Definition at line 203 of file manager.c.

References astman_send_response(), and s.

00204 {
00205    astman_send_response(s, m, "Success", msg);
00206 }

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

Definition at line 178 of file manager.c.

References ast_cli(), ast_mutex_lock, ast_mutex_unlock, astman_get_header(), and s.

00179 {
00180    char *id = astman_get_header(m,"ActionID");
00181    ast_mutex_lock(&s->lock);
00182    ast_cli(s->fd, "Response: Error\r\n");
00183    if (id && strlen(id))
00184       ast_cli(s->fd, "ActionID: %s\r\n",id);
00185    ast_cli(s->fd, "Message: %s\r\n\r\n", error);
00186    ast_mutex_unlock(&s->lock);
00187 }

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

Definition at line 189 of file manager.c.

References ast_cli(), ast_mutex_lock, ast_mutex_unlock, astman_get_header(), and s.

Referenced by astman_send_ack().

00190 {
00191    char *id = astman_get_header(m,"ActionID");
00192    ast_mutex_lock(&s->lock);
00193    ast_cli(s->fd, "Response: %s\r\n", resp);
00194    if (id && strlen(id))
00195       ast_cli(s->fd, "ActionID: %s\r\n",id);
00196    if (msg)
00197       ast_cli(s->fd, "Message: %s\r\n\r\n", msg);
00198    else
00199       ast_cli(s->fd, "\r\n");
00200    ast_mutex_unlock(&s->lock);
00201 }

int init_manager void   ) 
 

Definition at line 937 of file manager.c.

References ast_cli_register(), ast_destroy(), ast_extension_state_add(), ast_load(), ast_log(), ast_manager_register(), 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().

00938 {
00939    struct ast_config *cfg;
00940    char *val;
00941    int oldportno = portno;
00942    static struct sockaddr_in ba;
00943    int x = 1;
00944    if (!registered) {
00945       /* Register default actions */
00946       ast_manager_register( "Ping", 0, action_ping, "Ping" );
00947       ast_manager_register( "Events", 0, action_events, "Contol Event Flow" );
00948       ast_manager_register( "Logoff", 0, action_logoff, "Logoff Manager" );
00949       ast_manager_register( "Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel" );
00950       ast_manager_register( "Status", EVENT_FLAG_CALL, action_status, "Status" );
00951       ast_manager_register( "Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect" );
00952       ast_manager_register( "Originate", EVENT_FLAG_CALL, action_originate, "Originate Call" );
00953       ast_manager_register( "MailboxStatus", EVENT_FLAG_CALL, action_mailboxstatus, "Check Mailbox" );
00954       ast_manager_register( "Command", EVENT_FLAG_COMMAND, action_command, "Execute Command" );
00955       ast_manager_register( "ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status" );
00956       ast_manager_register( "AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout" );
00957       ast_manager_register( "MailboxCount", EVENT_FLAG_CALL, action_mailboxcount, "Check Mailbox Message Count" );
00958 
00959       ast_cli_register(&show_mancmds_cli);
00960       ast_cli_register(&show_manconn_cli);
00961       ast_extension_state_add(NULL, NULL, manager_state_cb, NULL);
00962       registered = 1;
00963    }
00964    portno = DEFAULT_MANAGER_PORT;
00965    cfg = ast_load("manager.conf");
00966    if (!cfg) {
00967       ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf.  Call management disabled.\n");
00968       return 0;
00969    }
00970    memset(&ba, 0, sizeof(ba));
00971    val = ast_variable_retrieve(cfg, "general", "enabled");
00972    if (val)
00973       enabled = ast_true(val);
00974 
00975    val = ast_variable_retrieve(cfg, "general", "block-sockets");
00976    if(val)
00977       block_sockets = ast_true(val);
00978 
00979    if ((val = ast_variable_retrieve(cfg, "general", "port"))) {
00980       if (sscanf(val, "%d", &portno) != 1) {
00981          ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
00982          portno = DEFAULT_MANAGER_PORT;
00983       }
00984    } else if ((val = ast_variable_retrieve(cfg, "general", "portno"))) {
00985       if (sscanf(val, "%d", &portno) != 1) {
00986          ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
00987          portno = DEFAULT_MANAGER_PORT;
00988       }
00989       ast_log(LOG_NOTICE, "Use of portno in manager.conf deprecated.  Please use 'port=%s' instead.\n", val);
00990    }
00991    
00992    ba.sin_family = AF_INET;
00993    ba.sin_port = htons(portno);
00994    memset(&ba.sin_addr, 0, sizeof(ba.sin_addr));
00995    
00996    if ((val = ast_variable_retrieve(cfg, "general", "bindaddr"))) {
00997       if (!inet_aton(val, &ba.sin_addr)) { 
00998          ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val);
00999          memset(&ba.sin_addr, 0, sizeof(ba.sin_addr));
01000       }
01001    }
01002    
01003    if ((asock > -1) && ((portno != oldportno) || !enabled)) {
01004 #if 0
01005       /* Can't be done yet */
01006       close(asock);
01007       asock = -1;
01008 #else
01009       ast_log(LOG_WARNING, "Unable to change management port / enabled\n");
01010 #endif
01011    }
01012    ast_destroy(cfg);
01013    
01014    /* If not enabled, do nothing */
01015    if (!enabled) {
01016       return 0;
01017    }
01018    if (asock < 0) {
01019       asock = socket(AF_INET, SOCK_STREAM, 0);
01020       if (asock < 0) {
01021          ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
01022          return -1;
01023       }
01024       setsockopt(asock, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
01025       if (bind(asock, (struct sockaddr *)&ba, sizeof(ba))) {
01026          ast_log(LOG_WARNING, "Unable to bind socket: %s\n", strerror(errno));
01027          close(asock);
01028          asock = -1;
01029          return -1;
01030       }
01031       if (listen(asock, 2)) {
01032          ast_log(LOG_WARNING, "Unable to listen on socket: %s\n", strerror(errno));
01033          close(asock);
01034          asock = -1;
01035          return -1;
01036       }
01037       if (option_verbose)
01038          ast_verbose("Asterisk Management interface listening on port %d\n", portno);
01039       pthread_create(&t, NULL, accept_thread, NULL);
01040    }
01041    return 0;
01042 }

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

Definition at line 845 of file manager.c.

References ast_carefulwrite(), ast_cli(), ast_mutex_lock, ast_mutex_unlock, and s.

00846 {
00847    struct mansession *s;
00848    char tmp[4096];
00849    va_list ap;
00850 
00851    ast_mutex_lock(&sessionlock);
00852    s = sessions;
00853    while(s) {
00854       if (((s->readperm & category) == category) && s->send_events) {
00855          ast_mutex_lock(&s->lock);
00856          if (!s->blocking) {
00857             ast_cli(s->fd, "Event: %s\r\n", event);
00858             va_start(ap, fmt);
00859             vsnprintf(tmp, sizeof(tmp), fmt, ap);
00860             va_end(ap);
00861             ast_carefulwrite(s->fd,tmp,strlen(tmp),100);
00862             ast_cli(s->fd, "\r\n");
00863          }
00864          ast_mutex_unlock(&s->lock);
00865       }
00866       s = s->next;
00867    }
00868    ast_mutex_unlock(&sessionlock);
00869    return 0;
00870 }

int reload_manager void   ) 
 

Definition at line 1044 of file manager.c.

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

Referenced by ast_module_reload().

01045 {
01046    manager_event(EVENT_FLAG_SYSTEM, "Reload", "Message: Reload Requested\r\n");
01047    return init_manager();
01048 }


Generated on Sun Apr 18 23:34:07 2004 for Asterisk by doxygen 1.3.6-20040222