Subject: ftpd ASCII mode fix, (#157)
Index:	etc/ftpd/ftpd.c 2.11BSD

Description:
	In ASCII mode the <cr> characters were not being inserted when
	a 'ls' command was done.

	Anonymous requests were not being logged because the 'openlog'
	call did not specify the no delay option to immediately
	create the logging connection before the chroot was done.

	The dotted quad was printed twice - 1.2.3.4 (1.2.3.4) instead
	of checking to see if the name had been resolved and only
	printing the name.

Repeat-By:
	Observation.  Between Unix systems the first bug is not a
	problem because of the way \r and \n are handled.  Using a
	VMS+Multinet system ftp'ing to a 2.11BSD system (thanks for spotting
	the problem and supplying the fix Terry) would demonstrate the
	bug.

	If anonymous FTP sessions do not cause information to be logged
	into /usr/adm/daemonlog then the second bug is present.

Fix:
	Apply the following update.  Then recompile and install ftpd.

	The openlog call is moved up towards the beginning of the
	program and the no delay (LOG_NDELAY) flag is now used.
============================cut here============================
*** /usr/src/etc/ftpd/ftpd.c.old	Thu Nov 11 20:46:02 1993
--- /usr/src/etc/ftpd/ftpd.c	Wed Nov 17 19:30:03 1993
***************
*** 15,29 ****
   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   */
  
! #ifndef lint
  char copyright[] =
  "@(#) Copyright (c) 1985, 1988 Regents of the University of California.\n\
   All rights reserved.\n";
- #endif /* not lint */
  
! #ifndef lint
! static char sccsid[] = "@(#)ftpd.c	based on 5.28	(Berkeley) 4/20/89";
! #endif /* not lint */
  
  /*
   * FTP server.
--- 15,27 ----
   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   */
  
! #if	!defined(lint) && defined(DOSCCS)
  char copyright[] =
  "@(#) Copyright (c) 1985, 1988 Regents of the University of California.\n\
   All rights reserved.\n";
  
! static char sccsid[] = "@(#)ftpd.c	5.28.1	(2.11BSD) 11/17/93";
! #endif
  
  /*
   * FTP server.
***************
*** 143,148 ****
--- 141,151 ----
  	int addrlen, on = 1;
  	char *cp;
  
+ 	/*
+ 	 * LOG_NDELAY sets up the logging connection immediately,
+ 	 * necessary for anonymous ftp's that chroot and can't do it later.
+ 	 */
+ 	openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_DAEMON);
  	addrlen = sizeof (his_addr);
  	if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) {
  		syslog(LOG_ERR, "getpeername (%s): %m",argv[0]);
***************
*** 155,165 ****
  	}
  	data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1);
  	debug = 0;
- #ifdef LOG_DAEMON
- 	openlog("ftpd", LOG_PID, LOG_DAEMON);
- #else
- 	openlog("ftpd", LOG_PID);
- #endif
  #ifdef SETPROCTITLE
  	/*
  	 *  Save start and extent of argv for setproctitle.
--- 158,163 ----
***************
*** 932,938 ****
  	lreply(211, "%s FTP server status:", hostname, version);
  	printf("     %s\r\n", version);
  	printf("     Connected to %s", remotehost);
! 	if (isdigit(remotehost[0]))
  		printf(" (%s)", inet_ntoa(his_addr.sin_addr));
  	printf("\r\n");
  	if (logged_in) {
--- 930,936 ----
  	lreply(211, "%s FTP server status:", hostname, version);
  	printf("     %s\r\n", version);
  	printf("     Connected to %s", remotehost);
! 	if (!isdigit(remotehost[0]))
  		printf(" (%s)", inet_ntoa(his_addr.sin_addr));
  	printf("\r\n");
  	if (logged_in) {
***************
*** 1350,1356 ****
  					return;
  				transflag++;
  			}
! 			fprintf(dout, "%s\n", dirname);
  			byte_count += strlen(dirname) + 1;
  			continue;
  		} else if ((st.st_mode&S_IFMT) != S_IFDIR)
--- 1348,1355 ----
  					return;
  				transflag++;
  			}
! 			fprintf(dout, "%s%s\n", dirname,
! 				type == TYPE_A ? "\r" : "");
  			byte_count += strlen(dirname) + 1;
  			continue;
  		} else if ((st.st_mode&S_IFMT) != S_IFDIR)
***************
*** 1384,1392 ****
  					transflag++;
  				}
  				if (nbuf[0] == '.' && nbuf[1] == '/')
! 					fprintf(dout, "%s\n", &nbuf[2]);
  				else
! 					fprintf(dout, "%s\n", nbuf);
  				byte_count += strlen(nbuf) + 1;
  			}
  		}
--- 1383,1393 ----
  					transflag++;
  				}
  				if (nbuf[0] == '.' && nbuf[1] == '/')
! 					fprintf(dout, "%s%s\n", &nbuf[2],
! 						type == TYPE_A ? "\r" : "");
  				else
! 					fprintf(dout, "%s%s\n", nbuf,
! 						type == TYPE_A ? "\r" : "");
  				byte_count += strlen(nbuf) + 1;
  			}
  		}
