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 ----