If the remote client is behind a firewall, the RFC931 conversation will
time out.  When this occurred, the daemon would fail to close the socket in
a timely manne.  Worse yet, if the control connection would later time out
(which it almost always does with a web browser on the remote end), the
daemon would hang forever; never timing out and closing down.

Index: src/authenticate.c
===================================================================
RCS file: /cvsroot/wu-ftpd-stable/src/authenticate.c,v
retrieving revision 1.1.1.2
diff -c -r1.1.1.2 authenticate.c
*** src/authenticate.c	1999/02/26 08:08:44	1.1.1.2
--- src/authenticate.c	1999/07/23 15:31:47
***************
*** 38,67 ****
  #include "support/authuser.h"
  #include "authenticate.h"
  
- #if USE_A_RFC931
- #include <signal.h>
- #include <setjmp.h>
- 
- #define RFC931_Timeout 10
- static jmp_buf  timebuf;
- 
- #endif				/* USE_A_RFC931 */
- 
- 
  #define AUTHNAMESIZE 100
  
  char authuser[AUTHNAMESIZE];
  int authenticated;
  
- #if USE_A_RFC931
- static          void
- timout (sig)
-     int             sig;
- {
-     longjmp (timebuf, sig);
- }
- 
- #endif				/* USE_A_RFC931 */
  /*
   * This routine actually returns nothing. It just sets the authenticated global
   * variable.
--- 38,48 ----
***************
*** 90,108 ****
      user = "*";
  
  #if USE_A_RFC931
- 
-  /*
-   * Set up a timer so we won't get stuck while waiting for the server.
-   */
- 
-     signal (SIGALRM, timout);
- 
      if (auth_fd(0, &in, &local, &remote) == -1)
          user = "?";             /* getpeername/getsockname failure */
      else
      {
! 	alarm (RFC931_Timeout);
! 	if (setjmp (timebuf) != 0 || !(user = auth_tcpuser (in, local, remote)))
  	{
              user = "*";         /* remote host doesn't support RFC 931 */
  	}
--- 71,81 ----
      user = "*";
  
  #if USE_A_RFC931
      if (auth_fd(0, &in, &local, &remote) == -1)
          user = "?";             /* getpeername/getsockname failure */
      else
      {
! 	if (!(user = auth_tcpuser (in, local, remote)))
  	{
              user = "*";         /* remote host doesn't support RFC 931 */
  	}
***************
*** 110,116 ****
  	{
              authenticated |= A_RFC931;
          }
- 	alarm (0);
      }
  #endif /* USE_A_RFC931 */
  
--- 83,88 ----
Index: support/authuser.c
===================================================================
RCS file: /cvsroot/wu-ftpd-stable/support/authuser.c,v
retrieving revision 1.2
diff -c -r1.2 authuser.c
*** support/authuser.c	1999/03/04 04:39:22	1.2
--- support/authuser.c	1999/07/23 15:31:47
***************
*** 26,32 ****
--- 26,35 ----
  #include <arpa/inet.h>
  #include <sys/socket.h>
  #include <sys/stat.h>
+ #include <signal.h>
  
+ #define RFC931_Timeout 10
+ 
  extern int errno;
  
  #include "authuser.h"
***************
*** 123,128 ****
--- 126,135 ----
  static char realbuf[SIZ];
  static char *buf;
  
+ static void timout(int sig)
+ {
+ }
+ 
  char *
  #ifdef __STDC__
  auth_tcpuser(register long unsigned int in, register short unsigned int local, register short unsigned int remote)
***************
*** 153,160 ****
--- 160,170 ----
  	sa.sin_family = AF_INET;
  	sa.sin_port = htons(auth_tcpport);
  	sa.sin_addr.s_addr = in;
+ 	signal(SIGALRM, timout);
+ 	alarm(RFC931_Timeout);
  	if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
  		saveerrno = errno;
+ 		alarm(0);
  		(void) close(s);
  		errno = saveerrno;
  		return 0;
***************
*** 166,171 ****
--- 176,182 ----
  	while ((w = write(s, buf, buflen)) < buflen)
  		if (w == -1) {			/* should we worry about 0 as well? */
  			saveerrno = errno;
+ 			alarm(0);
  			(void) close(s);
  			errno = saveerrno;
  			return 0;
***************
*** 181,190 ****
  		if ((buf - realbuf == sizeof(realbuf) - 1) || (ch == '\n'))
  			break;
  	}
  	if (w == -1) {
- 		saveerrno = errno;
- 		(void) close(s);
- 		errno = saveerrno;
  		return 0;
  	}
  	*buf = '\0';
--- 192,202 ----
  		if ((buf - realbuf == sizeof(realbuf) - 1) || (ch == '\n'))
  			break;
  	}
+ 	saveerrno = errno;
+ 	alarm(0);
+ 	(void) close(s);
+ 	errno = saveerrno;
  	if (w == -1) {
  		return 0;
  	}
  	*buf = '\0';
***************
*** 192,210 ****
  /* H* fix: limit scanf of returned identd string. */
  	if (sscanf(realbuf, "%hd,%hd: USERID :%*[^:]:%400s",
  			&rremote, &rlocal, ruser) < 3) {
- 		(void) close(s);
  		errno = EIO;
  		/* makes sense, right? well, not when USERID failed to match
  		   ERROR but there's no good error to return in that case */
  		return 0;
  	}
  	if ((remote != rremote) || (local != rlocal)) {
- 		(void) close(s);
  		errno = EIO;
  		return 0;
  	}
  	/* XXX: we're not going to do any backslash processing */
- 	(void) close(s);
  	return ruser;
  }
  
--- 204,219 ----
