From 60c5f7a1fbd8fa31043ea332b33e1b8ac4dd55c9 Mon Sep 17 00:00:00 2001 From: Mark Spencer Date: Tue, 28 Jan 2003 22:33:41 +0000 Subject: Version 0.3.0 from FTP git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@592 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- manager.c | 191 +++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 132 insertions(+), 59 deletions(-) diff --git a/manager.c b/manager.c index 365fb32b5..c5f57384f 100755 --- a/manager.c +++ b/manager.c @@ -51,29 +51,31 @@ static struct permalias { { -1, "all" }, }; -#define MAX_HEADERS 80 -#define MAX_LEN 256 +static struct mansession *sessions = NULL; +static struct manager_action *first_action = NULL; +static pthread_mutex_t actionlock = AST_MUTEX_INITIALIZER; -static struct mansession { - pthread_t t; - pthread_mutex_t lock; - struct sockaddr_in sin; - int fd; - char username[80]; - int authenticated; - int readperm; - int writeperm; - char inbuf[MAX_LEN]; - int inlen; - - struct mansession *next; -} *sessions = NULL; +static int handle_showmancmds(int fd, int argc, char *argv[]) +{ + struct manager_action *cur = first_action; + ast_pthread_mutex_lock(&actionlock); + while(cur) { /* Walk the list of actions */ + ast_cli(fd, "\t%s %s\r\n",cur->action, cur->synopsis); + cur = cur->next; + } -struct message { - int hdrcount; - char headers[MAX_HEADERS][MAX_LEN]; -}; + ast_pthread_mutex_unlock(&actionlock); + return RESULT_SUCCESS; +} + +static char showmancmds_help[] = +"Usage: show manager commands\n" +" Prints a listing of all the available manager commands.\n"; + +static struct ast_cli_entry show_mancmds_cli = + { { "show", "manager", "commands", NULL }, + handle_showmancmds, "Show manager commands", showmancmds_help }; static void destroy_session(struct mansession *s) { @@ -141,14 +143,18 @@ static int get_perm(char *instr) char *c; int x; int ret = 0; + char *stringp=NULL; + if (!instr) + return 0; strncpy(tmp, instr, sizeof(tmp) - 1); - c = strtok(tmp, ","); + stringp=tmp; + c = strsep(&stringp, ","); while(c) { for (x=0;xlock); + s->blocking = 1; + ast_pthread_mutex_unlock(&s->lock); + ast_cli(s->fd, "Response: Follows\r\n"); + ast_cli_command(s->fd, cmd); + ast_cli(s->fd, "--END COMMAND--\r\n\r\n"); + ast_pthread_mutex_lock(&s->lock); + s->blocking = 0; + ast_pthread_mutex_unlock(&s->lock); + return 0; +} + static int action_originate(struct mansession *s, struct message *m) { char *name = get_header(m, "Channel"); @@ -307,6 +328,7 @@ static int action_originate(struct mansession *s, struct message *m) char *context = get_header(m, "Context"); char *priority = get_header(m, "Priority"); char *timeout = get_header(m, "Timeout"); + char *callerid = get_header(m, "CallerID"); char *tech, *data; int pi = 0; int res; @@ -321,7 +343,7 @@ static int action_originate(struct mansession *s, struct message *m) send_error(s, "Invalid priority\n"); return 0; } - if (strlen(timeout) && (sscanf(priority, "%d", &to) != 1)) { + if (strlen(timeout) && (sscanf(timeout, "%d", &to) != 1)) { send_error(s, "Invalid timeout\n"); return 0; } @@ -334,7 +356,7 @@ static int action_originate(struct mansession *s, struct message *m) } *data = '\0'; data++; - res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 0); + res = ast_pbx_outgoing_exten(tech, AST_FORMAT_SLINEAR, data, to, context, exten, pi, &reason, 0, strlen(callerid) ? callerid : NULL, NULL ); if (!res) send_ack(s, "Originate successfully queued"); else @@ -342,24 +364,13 @@ static int action_originate(struct mansession *s, struct message *m) return 0; } -static struct action { - char *action; - int authority; - int (*func)(struct mansession *s, struct message *m); -} actions[] = { - { "Ping", 0, action_ping }, - { "Logoff", 0, action_logoff }, - { "Hangup", EVENT_FLAG_CALL, action_hangup }, - { "Status", EVENT_FLAG_CALL, action_status }, - { "Redirect", EVENT_FLAG_CALL, action_redirect }, - { "Originate", EVENT_FLAG_CALL, action_originate }, -}; - static int process_message(struct mansession *s, struct message *m) { - int x; char action[80]; + struct manager_action *tmp = first_action; + strncpy(action, get_header(m, "Action"), sizeof(action)); + if (!strlen(action)) { send_error(s, "Missing action in request"); return 0; @@ -374,31 +385,26 @@ static int process_message(struct mansession *s, struct message *m) s->authenticated = 1; if (option_verbose > 1) ast_verbose(VERBOSE_PREFIX_2 "Manager '%s' logged on from %s\n", s->username, inet_ntoa(s->sin.sin_addr)); - ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, inet_ntoa(s->sin.sin_addr)); + ast_log(LOG_EVENT, "Manager '%s' logged on from %s\n", s->username, inet_ntoa(s->sin.sin_addr)); send_ack(s, "Authentication accepted"); } } else send_error(s, "Authentication Required"); } else { - for (x=0;xwriteperm & actions[x].authority) == actions[x].authority) { - if (actions[x].func(s, m)) + while( tmp ) { + if (!strcasecmp(action, tmp->action)) { + if ((s->writeperm & tmp->authority) == tmp->authority) { + if (tmp->func(s, m)) return -1; } else { send_error(s, "Permission denied"); } - break; + return 0; } + tmp = tmp->next; } - if (x >= sizeof(actions) / sizeof(actions[0])) - send_error(s, "Invalid/unknown command"); - } -#if 0 - for (x=0;xhdrcount;x++) { - printf("Header: %s\n", m->headers[x]); + send_error(s, "Invalid/unknown command"); } -#endif return 0; } @@ -509,7 +515,7 @@ static void *accept_thread(void *ignore) if (pthread_create(&t, NULL, session_do, s)) destroy_session(s); } - + return NULL; } int manager_event(int category, char *event, char *fmt, ...) @@ -523,12 +529,14 @@ int manager_event(int category, char *event, char *fmt, ...) while(s) { if ((s->readperm & category) == category) { ast_pthread_mutex_lock(&s->lock); - ast_cli(s->fd, "Event: %s\r\n", event); - va_start(ap, fmt); - vsnprintf(tmp, sizeof(tmp), fmt, ap); - va_end(ap); - write(s->fd, tmp, strlen(tmp)); - ast_cli(s->fd, "\r\n"); + if (!s->blocking) { + ast_cli(s->fd, "Event: %s\r\n", event); + va_start(ap, fmt); + vsnprintf(tmp, sizeof(tmp), fmt, ap); + va_end(ap); + write(s->fd, tmp, strlen(tmp)); + ast_cli(s->fd, "\r\n"); + } ast_pthread_mutex_unlock(&s->lock); } s = s->next; @@ -537,6 +545,59 @@ int manager_event(int category, char *event, char *fmt, ...) return 0; } +int ast_manager_unregister( char *action ) { + struct manager_action *cur = first_action, *prev = first_action; + + ast_pthread_mutex_lock(&actionlock); + while( cur ) { + if (!strcasecmp(action, cur->action)) { + prev->next = cur->next; + free(cur); + if (option_verbose > 1) + ast_verbose(VERBOSE_PREFIX_2 "Manager unregistered action %s\n", action); + ast_pthread_mutex_unlock(&actionlock); + return 0; + } + prev = cur; + cur = cur->next; + } + ast_pthread_mutex_unlock(&actionlock); + return 0; +} + +int ast_manager_register( char *action, int auth, + int (*func)(struct mansession *s, struct message *m), char *synopsis) +{ + struct manager_action *cur = first_action, *prev = NULL; + + ast_pthread_mutex_lock(&actionlock); + while(cur) { /* Walk the list of actions */ + prev = cur; + cur = cur->next; + } + cur = malloc( sizeof(struct manager_action) ); + if( !cur ) { + ast_log(LOG_WARNING, "Manager: out of memory trying to register action\n"); + ast_pthread_mutex_unlock(&actionlock); + return -1; + } + strncpy( cur->action, action, 255 ); + cur->authority = auth; + cur->func = func; + cur->synopsis = synopsis; + cur->next = NULL; + + if( prev ) prev->next = cur; + else first_action = cur; + + if (option_verbose > 1) + ast_verbose(VERBOSE_PREFIX_2 "Manager registered action %s\n", action); + ast_pthread_mutex_unlock(&actionlock); + return 0; +} + +static int registered = 0; + int init_manager(void) { struct ast_config *cfg; @@ -544,7 +605,19 @@ int init_manager(void) int oldportno = portno; static struct sockaddr_in ba; int x = 1; - + if (!registered) { + /* Register default actions */ + ast_manager_register( "Ping", 0, action_ping, "Ping" ); + ast_manager_register( "Logoff", 0, action_logoff, "Logoff Manager" ); + ast_manager_register( "Hangup", EVENT_FLAG_CALL, action_hangup, "Hangup Channel" ); + ast_manager_register( "Status", EVENT_FLAG_CALL, action_status, "Status" ); + ast_manager_register( "Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect" ); + ast_manager_register( "Originate", EVENT_FLAG_CALL, action_originate, "Originate Call" ); + ast_manager_register( "Command", EVENT_FLAG_COMMAND, action_command, "Execute Command" ); + + ast_cli_register(&show_mancmds_cli); + registered = 1; + } portno = DEFAULT_MANAGER_PORT; cfg = ast_load("manager.conf"); if (!cfg) { -- cgit v1.2.3