[asterisk-commits] rizzo: trunk r45572 - /trunk/main/manager.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Oct 18 09:52:14 MST 2006


Author: rizzo
Date: Wed Oct 18 11:52:13 2006
New Revision: 45572

URL: http://svn.digium.com/view/asterisk?rev=45572&view=rev
Log:
more comment and formatting fixes, small simplifications
to functions get_input() and session_do()


Modified:
    trunk/main/manager.c

Modified: trunk/main/manager.c
URL: http://svn.digium.com/view/asterisk/trunk/main/manager.c?rev=45572&r1=45571&r2=45572&view=diff
==============================================================================
--- trunk/main/manager.c (original)
+++ trunk/main/manager.c Wed Oct 18 11:52:13 2006
@@ -1517,7 +1517,7 @@
 			return 0;
 		}
 	}
-	/* XXX watch out, possible deadlock!!! */
+	/* XXX watch out, possible deadlock - we are trying to get two channels!!! */
 	chan = ast_get_channel_by_name_locked(name);
 	if (!chan) {
 		char buf[BUFSIZ];
@@ -1555,7 +1555,7 @@
 "	*Command: Asterisk CLI command to run\n"
 "	ActionID: Optional Action id for message matching.\n";
 
-/*! \brief  action_command: Manager command "command" - execute CLI command */
+/*! \brief  Manager command "command" - execute CLI command */
 static int action_command(struct mansession *s, struct message *m)
 {
 	char *cmd = astman_get_header(m, "Command");
@@ -1569,6 +1569,7 @@
 	return 0;
 }
 
+/* helper function for originate */
 static void *fast_originate(void *data)
 {
 	struct fast_originate_helper *in = data;
@@ -1749,6 +1750,7 @@
 {
 	char *mailbox = astman_get_header(m, "Mailbox");
 	int ret;
+
 	if (ast_strlen_zero(mailbox)) {
 		astman_send_error(s, m, "Mailbox not specified");
 		return 0;
@@ -1776,19 +1778,19 @@
 {
 	char *mailbox = astman_get_header(m, "Mailbox");
 	int newmsgs = 0, oldmsgs = 0;
+
 	if (ast_strlen_zero(mailbox)) {
 		astman_send_error(s, m, "Mailbox not specified");
 		return 0;
 	}
 	ast_app_inboxcount(mailbox, &newmsgs, &oldmsgs);
 	astman_start_ack(s, m);
-	astman_append(s,
-				   "Message: Mailbox Message Count\r\n"
-				   "Mailbox: %s\r\n"
-		 		   "NewMessages: %d\r\n"
-				   "OldMessages: %d\r\n" 
-				   "\r\n",
-				   mailbox, newmsgs, oldmsgs);
+	astman_append(s,   "Message: Mailbox Message Count\r\n"
+			   "Mailbox: %s\r\n"
+			   "NewMessages: %d\r\n"
+			   "OldMessages: %d\r\n" 
+			   "\r\n",
+			   mailbox, newmsgs, oldmsgs);
 	return 0;
 }
 
@@ -1836,9 +1838,10 @@
 
 static int action_timeout(struct mansession *s, struct message *m)
 {
-	struct ast_channel *c = NULL;
+	struct ast_channel *c;
 	char *name = astman_get_header(m, "Channel");
 	int timeout = atoi(astman_get_header(m, "Timeout"));
+
 	if (ast_strlen_zero(name)) {
 		astman_send_error(s, m, "No channel specified");
 		return 0;
@@ -1908,7 +1911,7 @@
 }
 
 /*
- * Process the message, performing desired action.
+ * Process an AMI message, performing desired action.
  * Return 0 on success, -1 on error that require the session to be destroyed.
  */
 static int process_message(struct mansession *s, struct message *m)
@@ -1945,31 +1948,36 @@
 	return process_events(s);
 }
 
+/*
+ * Read one full line (including crlf) from the manager socket.
+ */
 static int get_input(struct mansession *s, char *output)
 {
 	/* output must have at least sizeof(s->inbuf) space */
-	int res;
-	int x;
 	struct pollfd fds[1];
-	for (x = 1; x < s->inlen; x++) {
-		if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) {
-			/* Copy output data up to and including \r\n */
-			memcpy(output, s->inbuf, x + 1);
-			/* Add trailing \0 */
-			output[x+1] = '\0';
-			/* Move remaining data back to the front */
-			memmove(s->inbuf, s->inbuf + x + 1, s->inlen - x);
-			s->inlen -= (x + 1);
-			return 1;
-		}
-	} 
+	char *crlf;
+
 	if (s->inlen >= sizeof(s->inbuf) - 1) {
 		ast_log(LOG_WARNING, "Dumping long line with no return from %s: %s\n", ast_inet_ntoa(s->sin.sin_addr), s->inbuf);
 		s->inlen = 0;
 	}
+	s->inbuf[s->inlen] = '\0';	/* terminate, just in case */
+	crlf = strstr(s->inbuf, "\r\n");
+	if (crlf) {
+		/* Copy output data up to and including \r\n */
+		int x = crlf - s->inbuf + 2;
+		memcpy(output, s->inbuf, x);
+		output[x] = '\0'; /* Add trailing \0 */
+		/* Move remaining data back to the front */
+		memmove(s->inbuf, s->inbuf + x, s->inlen - x);
+		s->inlen -= x;
+		return 1;
+	} 
 	fds[0].fd = s->fd;
 	fds[0].events = POLLIN;
-	do {
+	for (;;) {
+		int res;
+		/* XXX do we really need this locking ? */
 		ast_mutex_lock(&s->__lock);
 		s->waiting_thread = pthread_self();
 		ast_mutex_unlock(&s->__lock);
@@ -1979,56 +1987,63 @@
 		ast_mutex_lock(&s->__lock);
 		s->waiting_thread = AST_PTHREADT_NULL;
 		ast_mutex_unlock(&s->__lock);
+
+		if (res == 0)	/* timeout ? */
+			continue;
 		if (res < 0) {
-			if (errno == EINTR) {
+			if (errno == EINTR)
 				return 0;
-			}
-			ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));
+			ast_log(LOG_WARNING, "poll() returned error: %s\n", strerror(errno));
 	 		return -1;
-		} else if (res > 0) {
-			ast_mutex_lock(&s->__lock);
-			res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen);
-			ast_mutex_unlock(&s->__lock);
-			if (res < 1)
-				return -1;
-			break;
-		}
-	} while(1);
-	s->inlen += res;
-	s->inbuf[s->inlen] = '\0';
-	return 0;
-}
-
+		}
+		ast_mutex_lock(&s->__lock);
+		res = read(s->fd, s->inbuf + s->inlen, sizeof(s->inbuf) - 1 - s->inlen);
+		if (res < 1)
+			res = -1;	/* error return */
+		else {
+			s->inlen += res;
+			s->inbuf[s->inlen] = '\0';
+			res = 0;
+		}
+		ast_mutex_unlock(&s->__lock);
+		return res;
+	}
+}
+
+/*! \brief The body of the individual manager session.
+ */
 static void *session_do(void *data)
 {
 	struct mansession *s = data;
-	struct message m;
-	int res;
+	struct message m;	/* XXX watch out, this is 20k of memory! */
 	
 	ast_mutex_lock(&s->__lock);
-	astman_append(s, "Asterisk Call Manager/1.0\r\n");
+	astman_append(s, "Asterisk Call Manager/1.0\r\n");	/* welcome prompt */
 	ast_mutex_unlock(&s->__lock);
 	memset(&m, 0, sizeof(m));
 	for (;;) {
-		res = get_input(s, m.headers[m.hdrcount]);
-		if (res > 0) {
-			/* Strip trailing \r\n */
-			if (strlen(m.headers[m.hdrcount]) < 2)
+		char *buf = m.headers[m.hdrcount];
+		int res = get_input(s, buf);
+		if (res < 0)	/* error */
+			break;
+		if (res > 0) {	/* got one line */
+			res = strlen(buf);
+			if (res < 2)
 				continue;
-			m.headers[m.hdrcount][strlen(m.headers[m.hdrcount]) - 2] = '\0';
-			if (ast_strlen_zero(m.headers[m.hdrcount])) {
+			/* Strip trailing \r\n (which must be there) */
+			buf[res - 2] = '\0';
+			if (ast_strlen_zero(buf)) {	/* empty line, terminator */
 				if (process_message(s, &m))
 					break;
 				memset(&m, 0, sizeof(m));
 			} else if (m.hdrcount < AST_MAX_MANHEADERS - 1)
 				m.hdrcount++;
-		} else if (res < 0) {
-			break;
 		} else if (s->eventq->next) {
 			if (process_events(s))
 				break;
 		}
 	}
+	/* session is over, explain why and terminate */
 	if (s->authenticated) {
 		if (option_verbose > 1) {
 			if (displayconnects) 



More information about the asterisk-commits mailing list