[Asterisk-cvs] asterisk manager.c,1.38,1.39

markster at lists.digium.com markster at lists.digium.com
Mon Mar 1 16:22:14 CST 2004


Update of /usr/cvsroot/asterisk
In directory mongoose.digium.com:/tmp/cvs-serv12657

Modified Files:
	manager.c 
Log Message:
Allow semi-blocking fd's on manager (bug #1100)


Index: manager.c
===================================================================
RCS file: /usr/cvsroot/asterisk/manager.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- manager.c	7 Feb 2004 07:13:33 -0000	1.38
+++ manager.c	1 Mar 2004 21:12:32 -0000	1.39
@@ -43,6 +43,7 @@
 static int asock = -1;
 static pthread_t t;
 static ast_mutex_t sessionlock = AST_MUTEX_INITIALIZER;
+static int block_sockets = 0;
 
 static struct permalias {
 	int num;
@@ -62,6 +63,37 @@
 static struct manager_action *first_action = NULL;
 static ast_mutex_t actionlock = AST_MUTEX_INITIALIZER;
 
+
+
+
+int ast_carefulwrite(int fd, char *s, int len, int timeoutms) 
+{
+	/* Try to write string, but wait no more than ms milliseconds
+	   before timing out */
+	int res=0;
+	struct timeval tv;
+	fd_set fds;
+	while(len) {
+		res = write(fd, s, len);
+		if ((res < 0) && (errno != EAGAIN)) {
+			return -1;
+		}
+		if (res < 0) res = 0;
+		len -= res;
+		s += res;
+		tv.tv_sec = timeoutms / 1000;
+		tv.tv_usec = timeoutms % 1000;
+		FD_ZERO(&fds);
+		FD_SET(fd, &fds);
+		/* Wait until writable again */
+		res = select(fd + 1, NULL, &fds, NULL, &tv);
+		if (res < 1)
+			return -1;
+	}
+	return res;
+}
+
+
 static int handle_showmancmds(int fd, int argc, char *argv[])
 {
 	struct manager_action *cur = first_action;
@@ -207,7 +239,9 @@
 	char *pass = astman_get_header(m, "Secret");
 	char *authtype = astman_get_header(m, "AuthType");
 	char *key = astman_get_header(m, "Key");
-
+	char *events = astman_get_header(m, "Events");
+	int send_events = events ? ast_true(events) : 1;
+	
 	cfg = ast_load("manager.conf");
 	if (!cfg)
 		return -1;
@@ -272,6 +306,7 @@
 		s->readperm = get_perm(ast_variable_retrieve(cfg, cat, "read"));
 		s->writeperm = get_perm(ast_variable_retrieve(cfg, cat, "write"));
 		ast_destroy(cfg);
+		s->send_events=send_events;
 		return 0;
 	}
 	ast_log(LOG_NOTICE, "%s tried to authenticate with non-existant user '%s'\n", inet_ntoa(s->sin.sin_addr), user);
@@ -285,6 +320,35 @@
 	return 0;
 }
 
+
+static int events_on_off(struct mansession *s,int onoff) {
+	ast_mutex_lock(&s->lock);
+	s->send_events = onoff ? 1 : 0;
+	ast_mutex_unlock(&s->lock);
+	return s->send_events;
+}
+
+
+static int action_events(struct mansession *s, struct message *m)
+{
+	char *mask = astman_get_header(m, "EventMask");
+	char reply[25];
+	int res;
+	int true=0;
+	
+	/* ast_true might wanna learn to include 'on' as a true stmt  */
+	if(!strcasecmp(mask,"on"))
+		true = 1;
+	else 
+		true = ast_true(mask);
+	
+	res = events_on_off(s,true);
+	sprintf(reply,"Events are now %s",res ? "on" : "off");
+	astman_send_response(s, m,reply, NULL);
+	return 0;
+}
+
+
 static int action_logoff(struct mansession *s, struct message *m)
 {
 	astman_send_response(s, m, "Goodbye", "Thanks for all the fish.");
@@ -753,11 +817,15 @@
 		} 
 		memset(s, 0, sizeof(struct mansession));
 		memcpy(&s->sin, &sin, sizeof(sin));
-		/* For safety, make sure socket is non-blocking */
-		flags = fcntl(as, F_GETFL);
-		fcntl(as, F_SETFL, flags | O_NONBLOCK);
+
+		if(! block_sockets) {
+			/* For safety, make sure socket is non-blocking */
+			flags = fcntl(as, F_GETFL);
+			fcntl(as, F_SETFL, flags | O_NONBLOCK);
+		}
 		ast_mutex_init(&s->lock);
 		s->fd = as;
+		s->send_events = 1;
 		ast_mutex_lock(&sessionlock);
 		s->next = sessions;
 		sessions = s;
@@ -778,14 +846,16 @@
 	ast_mutex_lock(&sessionlock);
 	s = sessions;
 	while(s) {
-		if ((s->readperm & category) == category) {
+		if (((s->readperm & category) == category) && s->send_events) {
 			ast_mutex_lock(&s->lock);
 			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_carefulwrite(s->fd,tmp,strlen(tmp),100);
+				/*write(s->fd, tmp, strlen(tmp));*/
 				ast_cli(s->fd, "\r\n");
 			}
 			ast_mutex_unlock(&s->lock);
@@ -871,6 +941,7 @@
 	if (!registered) {
 		/* Register default actions */
 		ast_manager_register( "Ping", 0, action_ping, "Ping" );
+		ast_manager_register( "Events", 0, action_events, "Contol Event Flow" );
 		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" );
@@ -898,6 +969,11 @@
 	if (val)
 		enabled = ast_true(val);
 
+	val = ast_variable_retrieve(cfg, "general", "block-sockets");
+	if(val)
+		block_sockets = ast_true(val);
+	
+
 	if ((val = ast_variable_retrieve(cfg, "general", "portno"))) {
 		if (sscanf(val, "%d", &portno) != 1) {
 			ast_log(LOG_WARNING, "Invalid port number '%s'\n", val);
@@ -915,7 +991,7 @@
 			memset(&ba.sin_addr, 0, sizeof(ba.sin_addr));
 		}
 	}
-
+	
 	if ((asock > -1) && ((portno != oldportno) || !enabled)) {
 #if 0
 		/* Can't be done yet */




More information about the svn-commits mailing list