aboutsummaryrefslogtreecommitdiffstats
path: root/manager.c
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2006-03-25 23:50:09 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2006-03-25 23:50:09 +0000
commit4f4a24ec6ff72908d14402be9e27324148f2c8f1 (patch)
treead20048993b3cb7000c2f24edc0e013205b48924 /manager.c
parent5ba06203e6619dd9871d9a2fa2b7bbc353b54648 (diff)
Add micro-http server and abstract manager interface, make snmp not die
on reload. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@14953 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'manager.c')
-rw-r--r--manager.c106
1 files changed, 78 insertions, 28 deletions
diff --git a/manager.c b/manager.c
index 81c67ff86..47badecac 100644
--- a/manager.c
+++ b/manager.c
@@ -106,7 +106,40 @@ static struct permalias {
{ 0, "none" },
};
-static struct mansession *sessions = NULL;
+static struct mansession {
+ /*! Execution thread */
+ pthread_t t;
+ /*! Thread lock -- don't use in action callbacks, it's already taken care of */
+ ast_mutex_t __lock;
+ /*! socket address */
+ struct sockaddr_in sin;
+ /*! TCP socket */
+ int fd;
+ /*! Whether or not we're busy doing an action */
+ int busy;
+ /*! Whether or not we're "dead" */
+ int dead;
+ /*! Logged in username */
+ char username[80];
+ /*! Authentication challenge */
+ char challenge[10];
+ /*! Authentication status */
+ int authenticated;
+ /*! Authorization for reading */
+ int readperm;
+ /*! Authorization for writing */
+ int writeperm;
+ /*! Buffer */
+ char inbuf[AST_MAX_MANHEADER_LEN];
+ int inlen;
+ int send_events;
+ /* Queued events that we've not had the ability to send yet */
+ struct eventqent *eventq;
+ /* Timeout for ast_carefulwrite() */
+ int writetimeout;
+ struct mansession *next;
+} *sessions = NULL;
+
static struct manager_action *first_action = NULL;
AST_MUTEX_DEFINE_STATIC(actionlock);
@@ -182,6 +215,23 @@ static char *complete_show_mancmd(const char *line, const char *word, int pos, i
return NULL;
}
+void astman_append(struct mansession *s, const char *fmt, ...)
+{
+ char *stuff;
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = vasprintf(&stuff, fmt, ap);
+ va_end(ap);
+ if (res == -1) {
+ ast_log(LOG_ERROR, "Memory allocation failure\n");
+ } else {
+ ast_carefulwrite(s->fd, stuff, strlen(stuff), 100);
+ free(stuff);
+ }
+}
+
static int handle_showmancmd(int fd, int argc, char *argv[])
{
struct manager_action *cur = first_action;
@@ -370,23 +420,23 @@ void astman_send_error(struct mansession *s, struct message *m, char *error)
{
char *id = astman_get_header(m,"ActionID");
- ast_cli(s->fd, "Response: Error\r\n");
+ astman_append(s, "Response: Error\r\n");
if (!ast_strlen_zero(id))
- ast_cli(s->fd, "ActionID: %s\r\n",id);
- ast_cli(s->fd, "Message: %s\r\n\r\n", error);
+ astman_append(s, "ActionID: %s\r\n",id);
+ astman_append(s, "Message: %s\r\n\r\n", error);
}
void astman_send_response(struct mansession *s, struct message *m, char *resp, char *msg)
{
char *id = astman_get_header(m,"ActionID");
- ast_cli(s->fd, "Response: %s\r\n", resp);
+ astman_append(s, "Response: %s\r\n", resp);
if (!ast_strlen_zero(id))
- ast_cli(s->fd, "ActionID: %s\r\n",id);
+ astman_append(s, "ActionID: %s\r\n",id);
if (msg)
- ast_cli(s->fd, "Message: %s\r\n\r\n", msg);
+ astman_append(s, "Message: %s\r\n\r\n", msg);
else
- ast_cli(s->fd, "\r\n");
+ astman_append(s, "\r\n");
}
void astman_send_ack(struct mansession *s, struct message *m, char *msg)
@@ -610,15 +660,15 @@ static int action_listcommands(struct mansession *s, struct message *m)
if (!ast_strlen_zero(id))
snprintf(idText,256,"ActionID: %s\r\n",id);
- ast_cli(s->fd, "Response: Success\r\n%s", idText);
+ astman_append(s, "Response: Success\r\n%s", idText);
ast_mutex_lock(&actionlock);
while (cur) { /* Walk the list of actions */
if ((s->writeperm & cur->authority) == cur->authority)
- ast_cli(s->fd, "%s: %s (Priv: %s)\r\n", cur->action, cur->synopsis, authority_to_str(cur->authority, temp, sizeof(temp)) );
+ astman_append(s, "%s: %s (Priv: %s)\r\n", cur->action, cur->synopsis, authority_to_str(cur->authority, temp, sizeof(temp)) );
cur = cur->next;
}
ast_mutex_unlock(&actionlock);
- ast_cli(s->fd, "\r\n");
+ astman_append(s, "\r\n");
return 0;
}
@@ -758,11 +808,11 @@ static int action_getvar(struct mansession *s, struct message *m)
if (c)
ast_mutex_unlock(&c->lock);
- ast_cli(s->fd, "Response: Success\r\n"
+ astman_append(s, "Response: Success\r\n"
"Variable: %s\r\nValue: %s\r\n", varname, varval);
if (!ast_strlen_zero(id))
- ast_cli(s->fd, "ActionID: %s\r\n",id);
- ast_cli(s->fd, "\r\n");
+ astman_append(s, "ActionID: %s\r\n",id);
+ astman_append(s, "\r\n");
return 0;
}
@@ -803,7 +853,7 @@ static int action_status(struct mansession *s, struct message *m)
if (c->cdr) {
elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
}
- ast_cli(s->fd,
+ astman_append(s,
"Event: Status\r\n"
"Privilege: Call\r\n"
"Channel: %s\r\n"
@@ -826,7 +876,7 @@ static int action_status(struct mansession *s, struct message *m)
ast_state2str(c->_state), c->context,
c->exten, c->priority, (long)elapsed_seconds, bridge, c->uniqueid, idText);
} else {
- ast_cli(s->fd,
+ astman_append(s,
"Event: Status\r\n"
"Privilege: Call\r\n"
"Channel: %s\r\n"
@@ -849,7 +899,7 @@ static int action_status(struct mansession *s, struct message *m)
break;
c = ast_channel_walk_locked(c);
}
- ast_cli(s->fd,
+ astman_append(s,
"Event: StatusComplete\r\n"
"%s"
"\r\n",idText);
@@ -930,12 +980,12 @@ static int action_command(struct mansession *s, struct message *m)
{
char *cmd = astman_get_header(m, "Command");
char *id = astman_get_header(m, "ActionID");
- ast_cli(s->fd, "Response: Follows\r\nPrivilege: Command\r\n");
+ astman_append(s, "Response: Follows\r\nPrivilege: Command\r\n");
if (!ast_strlen_zero(id))
- ast_cli(s->fd, "ActionID: %s\r\n", id);
+ astman_append(s, "ActionID: %s\r\n", id);
/* FIXME: Wedge a ActionID response in here, waiting for later changes */
ast_cli_command(s->fd, cmd);
- ast_cli(s->fd, "--END COMMAND--\r\n\r\n");
+ astman_append(s, "--END COMMAND--\r\n\r\n");
return 0;
}
@@ -1130,7 +1180,7 @@ static int action_mailboxstatus(struct mansession *s, struct message *m)
if (!ast_strlen_zero(id))
snprintf(idText,256,"ActionID: %s\r\n",id);
ret = ast_app_has_voicemail(mailbox, NULL);
- ast_cli(s->fd, "Response: Success\r\n"
+ astman_append(s, "Response: Success\r\n"
"%s"
"Message: Mailbox Status\r\n"
"Mailbox: %s\r\n"
@@ -1163,7 +1213,7 @@ static int action_mailboxcount(struct mansession *s, struct message *m)
if (!ast_strlen_zero(id)) {
snprintf(idText,256,"ActionID: %s\r\n",id);
}
- ast_cli(s->fd, "Response: Success\r\n"
+ astman_append(s, "Response: Success\r\n"
"%s"
"Message: Mailbox Message Count\r\n"
"Mailbox: %s\r\n"
@@ -1204,7 +1254,7 @@ static int action_extensionstate(struct mansession *s, struct message *m)
if (!ast_strlen_zero(id)) {
snprintf(idText,256,"ActionID: %s\r\n",id);
}
- ast_cli(s->fd, "Response: Success\r\n"
+ astman_append(s, "Response: Success\r\n"
"%s"
"Message: Extension Status\r\n"
"Exten: %s\r\n"
@@ -1261,9 +1311,9 @@ static int process_message(struct mansession *s, struct message *m)
astman_send_error(s, m, "Missing action in request");
return 0;
}
- if (!ast_strlen_zero(id)) {
- snprintf(idText,256,"ActionID: %s\r\n",id);
- }
+ if (!ast_strlen_zero(id)) {
+ snprintf(idText,256,"ActionID: %s\r\n",id);
+ }
if (!s->authenticated) {
if (!strcasecmp(action, "Challenge")) {
char *authtype;
@@ -1272,7 +1322,7 @@ static int process_message(struct mansession *s, struct message *m)
if (ast_strlen_zero(s->challenge))
snprintf(s->challenge, sizeof(s->challenge), "%d", rand());
ast_mutex_lock(&s->__lock);
- ast_cli(s->fd, "Response: Success\r\n"
+ astman_append(s, "Response: Success\r\n"
"%s"
"Challenge: %s\r\n\r\n",
idText,s->challenge);
@@ -1396,7 +1446,7 @@ static void *session_do(void *data)
int res;
ast_mutex_lock(&s->__lock);
- ast_cli(s->fd, "Asterisk Call Manager/1.0\r\n");
+ astman_append(s, "Asterisk Call Manager/1.0\r\n");
ast_mutex_unlock(&s->__lock);
memset(&m, 0, sizeof(m));
for (;;) {