- millert@cvs.openbsd.org 2001/03/03 21:19:41
     [ssh-keyscan.c]
     Dynamically allocate read_wait and its copies.  Since maxfd is
     based on resource limits it is often (usually?) larger than FD_SETSIZE.
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
index fe03c14..ab46e9e 100644
--- a/ssh-keyscan.c
+++ b/ssh-keyscan.c
@@ -8,7 +8,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keyscan.c,v 1.18 2001/03/03 06:53:12 deraadt Exp $");
+RCSID("$OpenBSD: ssh-keyscan.c,v 1.19 2001/03/03 21:19:41 millert Exp $");
 
 #if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H)
 #include <sys/queue.h>
@@ -45,7 +45,8 @@
 #else
 char *__progname;
 #endif
-fd_set read_wait;
+fd_set *read_wait;
+size_t read_wait_size;
 int ncon;
 
 /*
@@ -361,7 +362,7 @@
 	gettimeofday(&fdcon[s].c_tv, NULL);
 	fdcon[s].c_tv.tv_sec += timeout;
 	TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link);
-	FD_SET(s, &read_wait);
+	FD_SET(s, read_wait);
 	ncon++;
 	return (s);
 }
@@ -378,7 +379,7 @@
 		xfree(fdcon[s].c_data);
 	fdcon[s].c_status = CS_UNUSED;
 	TAILQ_REMOVE(&tq, &fdcon[s], c_link);
-	FD_CLR(s, &read_wait);
+	FD_CLR(s, read_wait);
 	ncon--;
 }
 
@@ -481,7 +482,7 @@
 void
 conloop(void)
 {
-	fd_set r, e;
+	fd_set *r, *e;
 	struct timeval seltime, now;
 	int i;
 	con *c;
@@ -501,18 +502,24 @@
 	} else
 		seltime.tv_sec = seltime.tv_usec = 0;
 
-	r = e = read_wait;
-	while (select(maxfd, &r, NULL, &e, &seltime) == -1 &&
+	r = xmalloc(read_wait_size);
+	memcpy(r, read_wait, read_wait_size);
+	e = xmalloc(read_wait_size);
+	memcpy(e, read_wait, read_wait_size);
+
+	while (select(maxfd, r, NULL, e, &seltime) == -1 &&
 	    (errno == EAGAIN || errno == EINTR))
 		;
 
 	for (i = 0; i < maxfd; i++) {
-		if (FD_ISSET(i, &e)) {
+		if (FD_ISSET(i, e)) {
 			error("%s: exception!", fdcon[i].c_name);
 			confree(i);
-		} else if (FD_ISSET(i, &r))
+		} else if (FD_ISSET(i, r))
 			conread(i);
 	}
+	xfree(r);
+	xfree(e);
 
 	c = tq.tqh_first;
 	while (c && (c->c_tv.tv_sec < now.tv_sec ||
@@ -612,6 +619,10 @@
 	fdcon = xmalloc(maxfd * sizeof(con));
 	memset(fdcon, 0, maxfd * sizeof(con));
 
+	read_wait_size = howmany(maxfd, NFDBITS) * sizeof(fd_mask);
+	read_wait = xmalloc(read_wait_size);
+	memset(read_wait, 0, read_wait_size);
+
 	do {
 		while (ncon < MAXCON) {
 			char *name;