Subject: slightly ugly patch

From: Darrell Fuhriman <[email-masked]>
Date: Wed, 11 Oct 1995 00:31:26 -0700 (PDT)

This is a rather ugly patch for a problem we are having on our SunOS
machines (2.4.2-b5, but it's been present on all of them)).  If a client
goes away without closing the connection,(i.e. they hang up their modem)
the daemon never dies. 

So, this fixes the problem, just not elegantly.  I've worried that there 
might be a performance hit, but it doesn't seem to have made a 
significant difference.  We've been running this for a couple weeks with 
no problems.

it does create a file 'teleport.c' which should be renamed to something 
else, if that makes you happy.

So, anyway, here it is.

*** wu-ftpd-2.4.2-beta-5/src/ftpd.c	Mon Oct  2 13:42:47 1995
--- wu-ftpd-2.4.2-beta-5.dist/src/ftpd.c	Tue Jul 11 04:09:24 1995
***************
*** 35,41 ****
  #endif /* not lint */
  
  #ifndef lint
! static char sccsid[] = "@(#)$Id: ftpd.c,v 1.3 1995/10/02 20:42:45 darrell Exp $ based on ftpd.c  5.40 (Berkeley) 7/2/91";
  #endif /* not lint */
  
  /* FTP server. */
--- 35,41 ----
  #endif /* not lint */
  
  #ifndef lint
! static char sccsid[] = "@(#)$Id: ftpd.c,v 1.11 1995/07/11 11:08:49 sob Exp sob $ based on ftpd.c  5.40 (Berkeley) 7/2/91";
  #endif /* not lint */
  
  /* FTP server. */
***************
*** 209,215 ****
  int nameserved = 0;
  extern char authuser[];
  extern int authenticated;
- static void TPtoolong();
  
  /* File transfer logging */
  int xferlog = 0;
--- 209,214 ----
***************
*** 973,994 ****
      guest = 0;
  }
  
- static void
- TPtoolong()
- {
-     time_t now;
- 
-     reply(421,
-       "Timeout (%d seconds): closing control connection.", timeout);
-     (void) time(&now);
-     if (logging) {
-         syslog(LOG_INFO,
-             "User %s timed out after %d seconds at %.24s",
-             (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
-     }
-     dologout(1);
- }
- 
  int
  validate_eaddr(char *eaddr)
  {
--- 972,977 ----
***************
*** 1847,1853 ****
  
      file_size = size;
      byte_count = 0;
-     (void) signal(SIGALRM, TPtoolong);
      if (size != (off_t) - 1)
          (void) sprintf(sizebuf, " (%ld bytes)", size);
      else
--- 1830,1835 ----
***************
*** 1856,1864 ****
          struct sockaddr_in from;
          int s,
            fromlen = sizeof(from);
! 	alarm(timeout);
          s = accept(pdata, (struct sockaddr *) &from, &fromlen);
- 	alarm(0);
          if (s < 0) {
              reply(425, "Can't open data connection.");
              (void) close(pdata);
--- 1838,1845 ----
          struct sockaddr_in from;
          int s,
            fromlen = sizeof(from);
! 
          s = accept(pdata, (struct sockaddr *) &from, &fromlen);
          if (s < 0) {
              reply(425, "Can't open data connection.");
              (void) close(pdata);
***************
*** 1917,1933 ****
   * NB: Form isn't handled. */
  send_data(FILE *instr, FILE *outstr, off_t blksize)
  {
- 
      register int c,
        cnt;
      register char *buf;
      int netfd,
        filefd;
  
-     (void) signal(SIGALRM, TPtoolong);
- 
      transflag++;
- 
      if (setjmp(urgcatch)) {
          transflag = 0;
          return;
--- 1898,1910 ----
***************
*** 1935,1953 ****
      switch (type) {
  
      case TYPE_A:
-         alarm(timeout);
          while ((c = getc(instr)) != EOF) {
              byte_count++;
              if (c == '\n') {
                  if (ferror(outstr))
                      goto data_err;
                  (void) putc('\r', outstr);
- 		alarm(timeout);
              }
              (void) putc(c, outstr);
! 	}
          fflush(outstr);
- 	alarm(0);
          transflag = 0;
          if (ferror(instr))
              goto file_err;
--- 1912,1927 ----
      switch (type) {
  
      case TYPE_A:
          while ((c = getc(instr)) != EOF) {
              byte_count++;
              if (c == '\n') {
                  if (ferror(outstr))
                      goto data_err;
                  (void) putc('\r', outstr);
              }
              (void) putc(c, outstr);
!         }
          fflush(outstr);
          transflag = 0;
          if (ferror(instr))
              goto file_err;
***************
*** 1976,1982 ****
  	}
  #else
          while ((cnt = read(filefd, buf, (u_int) blksize)) > 0 &&
!                TPwrite(netfd, buf, cnt) == cnt)
              byte_count += cnt;
  #endif
          transflag = 0;
--- 1950,1956 ----
  	}
  #else
          while ((cnt = read(filefd, buf, (u_int) blksize)) > 0 &&
!                write(netfd, buf, cnt) == cnt)
              byte_count += cnt;
  #endif
          transflag = 0;
***************
*** 1996,2008 ****
  
    data_err:
      transflag = 0;
-     alarm(0);
      perror_reply(426, "Data connection");
      return;
  
    file_err:
      transflag = 0;
-     alarm(0);
      perror_reply(551, "Error on input file");
  }
  
--- 1970,1980 ----
***************
*** 2017,2026 ****
        bare_lfs = 0;
      char buf[BUFSIZ];
  
-     (void) signal(SIGALRM, TPtoolong);
- 
      transflag++;
- 
      if (setjmp(urgcatch)) {
          transflag = 0;
          return (-1);
--- 1989,1995 ----
***************
*** 2029,2035 ****
  
      case TYPE_I:
      case TYPE_L:
!         while ((cnt = TPread(fileno(instr), buf, sizeof buf)) > 0) {
              if (write(fileno(outstr), buf, cnt) != cnt)
                  goto file_err;
              byte_count += cnt;
--- 1998,2004 ----
  
      case TYPE_I:
      case TYPE_L:
!         while ((cnt = read(fileno(instr), buf, sizeof buf)) > 0) {
              if (write(fileno(outstr), buf, cnt) != cnt)
                  goto file_err;
              byte_count += cnt;
***************
*** 2045,2063 ****
          return (-1);
  
      case TYPE_A:
- 	alarm(timeout);
          while ((c = getc(instr)) != EOF) {
              byte_count++;
!             if (c == '\n') {
                  bare_lfs++;
- 	        alarm(timeout);
- 	     }
              while (c == '\r') {
                  if (ferror(outstr))
                      goto data_err;
                  if ((c = getc(instr)) != '\n') {
                      (void) putc('\r', outstr);
- 		    alarm(timeout);
                      if (c == '\0' || c == EOF)
                          goto contin2;
                  }
--- 2014,2028 ----
          return (-1);
  
      case TYPE_A:
          while ((c = getc(instr)) != EOF) {
              byte_count++;
!             if (c == '\n')
                  bare_lfs++;
              while (c == '\r') {
                  if (ferror(outstr))
                      goto data_err;
                  if ((c = getc(instr)) != '\n') {
                      (void) putc('\r', outstr);
                      if (c == '\0' || c == EOF)
                          goto contin2;
                  }
***************
*** 2066,2072 ****
            contin2:;
          }
          fflush(outstr);
- 	alarm(0);
          if (ferror(instr))
              goto data_err;
          if (ferror(outstr))
--- 2031,2036 ----
***************
*** 2085,2097 ****
  
    data_err:
      transflag = 0;
-     alarm(0);
      perror_reply(426, "Data Connection");
      return (-1);
  
    file_err:
      transflag = 0;
-     alarm(0);
      perror_reply(452, "Error writing file");
      return (-1);
  }
--- 2049,2059 ----
*** wu-ftpd-2.4.2-beta-5/src/teleport.c	Thu Sep 28 17:10:32 1995
--- wu-ftpd-2.4.2-beta-5.dist/src/teleport.c	Wed Oct 11 00:10:09 1995
***************
*** 1,28 ****
- #include <sys/types.h>
- #include <sys/uio.h>
- 
- extern int timeout;
- 
- int TPwrite(fd, buf, nbyte)
-      int fd;
-      char *buf;
-      int nbyte;
- {
-   int cnt;
-   alarm(timeout);
-   cnt = write(fd, buf, nbyte);
-   alarm(0);
-   return cnt;
- }
- 
- int TPread(fd, buf, nbyte)
-      int fd;
-      char *buf;
-      int nbyte;
- {
-   int cnt;
-   alarm(timeout);
-   cnt = read(fd, buf, nbyte);
-   alarm(0);
-   return cnt;
- }
--- 0 ----

---

From: Vidiot <[email-masked]>
Date: Thu, 26 Oct 1995 10:19:24 -0500 (CDT)

<
<
<This is a rather ugly patch for a problem we are having on our SunOS
<machines (2.4.2-b5, but it's been present on all of them)).  If a client
<goes away without closing the connection,(i.e. they hang up their modem)
<the daemon never dies. 
<
<So, this fixes the problem, just not elegantly.  I've worried that there 
<might be a performance hit, but it doesn't seem to have made a 
<significant difference.  We've been running this for a couple weeks with 
<no problems.

The ftpd.c patches were in the beta 6 release.

<it does create a file 'teleport.c' which should be renamed to something 
<else, if that makes you happy.

There isn't a teleport.c in the beta 6 release, though the stuff you had
could be incorporated elsewhere.

In any event, the patches do not work for me (SunOS 4.1.3_U1).  I have
to constantly kill anonymous ftp processes that are hanging around.

I have the following inetd.conf startup line:

	in.ftpd -l -a -T1200

Any clues, hints, etc?

MB
-- 
System Administrator - FT/MS - Madison WI. <URL:http://www.ftms.com/>
e-mail: [email-masked]
phone: (608) 273-8262  fax: (608) 273-8719  voice-mail: (800) 426-6488 ext 6293
Visit - <URL:http://www.cdsnet.net/vidiot/>  (Your link to Star Trek and UPN)

---

From: Darrell Fuhriman <[email-masked]>
Date: Thu, 26 Oct 1995 14:59:00 -0700 (PDT)

> The ftpd.c patches were in the beta 6 release.

I didn't see them, and they certainly aren't in the beta 7 release.  I'd 
suggest re-applying them.

---

From: Vidiot <[email-masked]>
Date: Thu, 26 Oct 1995 22:56:01 -0500 (CDT)

<
<> The ftpd.c patches were in the beta 6 release.
<
<I didn't see them, and they certainly aren't in the beta 7 release.  I'd 
<suggest re-applying them.

I went back at looked at the patch file.  Not only is it an ugly patch,
but it is backwards.  The diff file was created to REMOVE the patches from
the source, not add them.

MB