- markus@cvs.openbsd.org 2001/05/28 23:14:49
     [channels.c channels.h nchan.c]
     undo broken channel fix and try a different one. there
     should be still some select errors...
diff --git a/ChangeLog b/ChangeLog
index 3de936f..f0ffd3f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -65,6 +65,10 @@
    - markus@cvs.openbsd.org 2001/05/28 22:51:11
      [cipher.c cipher.h]                       
      simpler 3des for ssh1                     
+   - markus@cvs.openbsd.org 2001/05/28 23:14:49            
+     [channels.c channels.h nchan.c]                       
+     undo broken channel fix and try a different one. there
+     should be still some select errors...                 
 
 20010528
  - (tim) [conifgure.in] add setvbuf test needed for sftp-int.c
@@ -5495,4 +5499,4 @@
  - Wrote replacements for strlcpy and mkdtemp
  - Released 1.0pre1
 
-$Id: ChangeLog,v 1.1242 2001/06/05 20:50:16 mouring Exp $
+$Id: ChangeLog,v 1.1243 2001/06/05 20:52:50 mouring Exp $
diff --git a/channels.c b/channels.c
index d654056..3eccb84 100644
--- a/channels.c
+++ b/channels.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.117 2001/05/19 19:57:09 stevesk Exp $");
+RCSID("$OpenBSD: channels.c,v 1.118 2001/05/28 23:14:49 markus Exp $");
 
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
@@ -280,6 +280,9 @@
 void
 channel_close_fds(Channel *c)
 {
+	debug3("channel_close_fds: channel %d: r %d w %d e %d",
+	    c->self, c->rfd, c->wfd, c->efd);
+
 	if (c->sock != -1) {
 		close(c->sock);
 		c->sock = -1;
@@ -304,9 +307,17 @@
 channel_free(Channel *c)
 {
 	char *s;
+	int i, n;
+
+	for (n = 0, i = 0; i < channels_alloc; i++)
+		if (channels[i])
+			n++;
+
+	debug("channel_free: channel %d: (%s) nchannels: %d", c->self,
+	    c->remote_name ? c->remote_name : "???", n);
 
 	s = channel_open_message();
-	debug("channel_free: channel %d: status: %s", c->self, s);
+	debug3("channel_free: status: %s", c->self, s);
 	xfree(s);
 
 	if (c->dettach_user != NULL) {
@@ -893,7 +904,7 @@
 	char buf[16*1024];
 	int len;
 
-	if (c->istate == CHAN_INPUT_OPEN &&
+	if (c->rfd != -1 &&
 	    FD_ISSET(c->rfd, readset)) {
 		len = read(c->rfd, buf, sizeof(buf));
 		if (len < 0 && (errno == EINTR || errno == EAGAIN))
@@ -932,8 +943,7 @@
 	int len;
 
 	/* Send buffered output data to the socket. */
-	if ((c->ostate == CHAN_OUTPUT_OPEN ||
-	    c->ostate == CHAN_OUTPUT_WAIT_DRAIN) &&
+	if (c->wfd != -1 &&
 	    FD_ISSET(c->wfd, writeset) &&
 	    buffer_len(&c->output) > 0) {
 		len = write(c->wfd, buffer_ptr(&c->output),
@@ -1164,9 +1174,8 @@
 		c = channels[i];
 		if (c == NULL)
 			continue;
-		if (ftab[c->type] == NULL)
-			continue;
-		(*ftab[c->type])(c, readset, writeset);
+		if (ftab[c->type] != NULL)
+			(*ftab[c->type])(c, readset, writeset);
 		if (chan_is_dead(c)) {
 			/*
 			 * we have to remove the fd's from the select mask
@@ -1715,6 +1724,7 @@
 		case SSH_CHANNEL_AUTH_SOCKET:
 		case SSH_CHANNEL_DYNAMIC:
 		case SSH_CHANNEL_CONNECTING:
+		case SSH_CHANNEL_ZOMBIE:
 			continue;
 		case SSH_CHANNEL_LARVAL:
 			if (!compat20)
@@ -1757,6 +1767,7 @@
 		case SSH_CHANNEL_RPORT_LISTENER:
 		case SSH_CHANNEL_OPENING:
 		case SSH_CHANNEL_CONNECTING:
+		case SSH_CHANNEL_ZOMBIE:
 			continue;
 		case SSH_CHANNEL_LARVAL:
 		case SSH_CHANNEL_AUTH_SOCKET:
@@ -1804,6 +1815,7 @@
 		case SSH_CHANNEL_RPORT_LISTENER:
 		case SSH_CHANNEL_CLOSED:
 		case SSH_CHANNEL_AUTH_SOCKET:
+		case SSH_CHANNEL_ZOMBIE:
 			continue;
 		case SSH_CHANNEL_LARVAL:
 		case SSH_CHANNEL_OPENING:
diff --git a/channels.h b/channels.h
index 6739b22..55d3185 100644
--- a/channels.h
+++ b/channels.h
@@ -32,7 +32,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-/* RCSID("$OpenBSD: channels.h,v 1.32 2001/05/04 23:47:33 markus Exp $"); */
+/* RCSID("$OpenBSD: channels.h,v 1.33 2001/05/28 23:14:49 markus Exp $"); */
 
 #ifndef CHANNELS_H
 #define CHANNELS_H
@@ -53,7 +53,8 @@
 #define SSH_CHANNEL_RPORT_LISTENER	11	/* Listening to a R-style port  */
 #define SSH_CHANNEL_CONNECTING		12
 #define SSH_CHANNEL_DYNAMIC		13
-#define SSH_CHANNEL_MAX_TYPE		14
+#define SSH_CHANNEL_ZOMBIE		14	/* Almost dead. */
+#define SSH_CHANNEL_MAX_TYPE		15
 
 #define SSH_CHANNEL_PATH_LEN		30
 
diff --git a/nchan.c b/nchan.c
index 38d860b..957c456 100644
--- a/nchan.c
+++ b/nchan.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: nchan.c,v 1.25 2001/05/16 22:09:21 markus Exp $");
+RCSID("$OpenBSD: nchan.c,v 1.26 2001/05/28 23:14:49 markus Exp $");
 
 #include "ssh1.h"
 #include "ssh2.h"
@@ -394,14 +394,16 @@
 void
 chan_mark_dead(Channel *c)
 {
-	c->flags |= CHAN_DEAD;
+	c->type = SSH_CHANNEL_ZOMBIE;
 }
 
 int
 chan_is_dead(Channel *c)
 {
-	if (c->flags & CHAN_DEAD)
+	if (c->type == SSH_CHANNEL_ZOMBIE) {
+		debug("channel %d: zombie", c->self);
 		return 1;
+	}
 	if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
 		return 0;
 	if (!compat20) {
@@ -484,6 +486,7 @@
 		if (close(c->wfd) < 0)
 			log("channel %d: chan_shutdown_write: close() failed for fd%d: %.100s",
 			    c->self, c->wfd, strerror(errno));
+		c->wfd = -1;
 	}
 }
 static void
@@ -506,5 +509,6 @@
 		if (close(c->rfd) < 0)
 			log("channel %d: chan_shutdown_read: close() failed for fd%d: %.100s",
 			    c->self, c->rfd, strerror(errno));
+		c->rfd = -1;
 	}
 }