--- Makefile
+++ Makefile	1994/03/27 23:38:44
@@ -0,0 +1,23 @@
+# If you do not have the shadow-3.3.1 package installed do:
+# - remove "-DSHADOW_PWD" in this Makefile
+# - remove "-lshadow" in this Makefile
+
+CFLAGS = -O2 -fomit-frame-pointer -m486 \
+	-include /usr/include/bsd/bsd.h -I/usr/include/bsd \
+	-include ftphack.h -DSETPROCTITLE -I../ftp -DSHADOW_PWD
+YACC = bison -y
+LDFLAGS = -s -v
+LDLIBS = -lbsd -lshadow
+
+ftpd: ftpd.o ftpcmd.o glob.o logwtmp.o popen.o vers.o
+
+glob.o: ../ftp/glob.c
+	$(CC) $(CFLAGS) -c ../ftp/glob.c -o glob.o
+
+install: ftpd
+	install -m755 ftpd /usr/sbin/in.ftpd
+	install -m644 ftpd.8 /usr/man/man8
+
+clean:
+	rm -f *.o ftpd
+
--- ftpcmd.y
+++ ftpcmd.y	1994/03/27 23:38:44
@@ -54,6 +54,7 @@
 #include <setjmp.h>
 #include <syslog.h>
 #include <time.h>
+#include <stdio.h>
 #include <pwd.h>
 #include <unistd.h>
 #include <stdio.h>
@@ -221,14 +222,14 @@
 	|	STOR check_login SP pathname CRLF
 		= {
 			if ($2 && $4 != NULL)
-				store((char *) $4, "w", 0);
+				_store((char *) $4, "w", 0);
 			if ($4 != NULL)
 				free((char *) $4);
 		}
 	|	APPE check_login SP pathname CRLF
 		= {
 			if ($2 && $4 != NULL)
-				store((char *) $4, "a", 0);
+				_store((char *) $4, "a", 0);
 			if ($4 != NULL)
 				free((char *) $4);
 		}
@@ -270,7 +271,7 @@
 	|	DELE check_login SP pathname CRLF
 		= {
 			if ($2 && $4 != NULL)
-				delete((char *) $4);
+				_delete((char *) $4);
 			if ($4 != NULL)
 				free((char *) $4);
 		}
@@ -418,7 +419,7 @@
 	|	STOU check_login SP pathname CRLF
 		= {
 			if ($2 && $4 != NULL)
-				store((char *) $4, "w", 1);
+				_store((char *) $4, "w", 1);
 			if ($4 != NULL)
 				free((char *) $4);
 		}
@@ -876,7 +877,7 @@
 			}
 			(void) alarm(0);
 #ifdef SETPROCTITLE
-			if (strncasecmp(cbuf, "PASS", 4) != NULL)
+			if (strncasecmp(cbuf, "PASS", 4) != 0)
 				setproctitle("%s: %s", proctitle, cbuf);
 #endif /* SETPROCTITLE */
 			if ((cp = index(cbuf, '\r'))) {
--- ftpd.c
+++ ftpd.c	1994/03/27 23:41:29
@@ -52,7 +52,6 @@
 #include <sys/wait.h>
 
 #include <netinet/in.h>
-#include <netinet/in_systm.h>
 #include <netinet/ip.h>
 
 #define	FTP_NAMES
@@ -60,10 +59,15 @@
 #include <arpa/inet.h>
 #include <arpa/telnet.h>
 
+#include <stdio.h>
+#include <grp.h>
 #include <signal.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <time.h>
+#ifdef	SHADOW_PWD
+#include <shadow.h>
+#endif
 #include <pwd.h>
 #include <setjmp.h>
 #include <netdb.h>
@@ -71,7 +75,6 @@
 #include <syslog.h>
 #include <varargs.h>
 #include <unistd.h>
-#include <stdio.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
@@ -83,7 +86,6 @@
  * Commonly used to disallow uucp.
  */
 extern	int errno;
-extern	char *crypt();
 extern	char version[];
 extern	char *home;		/* pointer to home directory for glob */
 extern	FILE *ftpd_popen(), *fopen(), *freopen();
@@ -308,6 +310,12 @@
 	static struct passwd save;
 	register struct passwd *p;
 	char *sgetsave();
+#ifdef	SHADOW_PWD
+	struct spwd *sp;
+
+	if ((sp = getspnam(name)) == NULL)
+		return NULL;
+#endif
 
 	if ((p = getpwnam(name)) == NULL)
 		return (p);
@@ -320,7 +328,11 @@
 	}
 	save = *p;
 	save.pw_name = sgetsave(p->pw_name);
+#ifdef	SHADOW_PWD
+	save.pw_passwd = sgetsave(sp->sp_pwdp);
+#else
 	save.pw_passwd = sgetsave(p->pw_passwd);
+#endif
 	save.pw_gecos = sgetsave(p->pw_gecos);
 	save.pw_dir = sgetsave(p->pw_dir);
 	save.pw_shell = sgetsave(p->pw_shell);
@@ -449,7 +461,11 @@
 			salt = "xx";
 		else
 			salt = pw->pw_passwd;
+#ifdef		SHADOW_PWD
+		xpasswd = pw_encrypt(passwd, salt);
+#else
 		xpasswd = crypt(passwd, salt);
+#endif
 		/* The strcmp does not catch null passwords! */
 		if (pw == NULL || *pw->pw_passwd == '\0' ||
 		    strcmp(xpasswd, pw->pw_passwd)) {
@@ -582,7 +598,7 @@
 	(*closefunc)(fin);
 }
 
-store(name, mode, unique)
+_store(name, mode, unique)
 	char *name, *mode;
 	int unique;
 {
@@ -810,9 +826,18 @@
 		}
 		netfd = fileno(outstr);
 		filefd = fileno(instr);
-		while ((cnt = read(filefd, buf, (u_int)blksize)) > 0 &&
-		    write(netfd, buf, cnt) == cnt)
+		while ((cnt = read(filefd, buf, (u_int)blksize)) > 0) {
+			int offset = 0, sent;
+
+			while (cnt > 0) {
+				sent = write(netfd, buf+offset, cnt);
+				if (sent <= 0) break;
+				offset += sent;
+				cnt -= sent;
+			}
 			byte_count += cnt;
+			if (cnt) break;
+		}
 		transflag = 0;
 		(void)free(buf);
 		if (cnt != 0) {
@@ -1067,7 +1092,7 @@
 	reply(500, "'%s': command not understood.", cbuf);
 }
 
-delete(name)
+_delete(name)
 	char *name;
 {
 	struct stat st;
--- ftphack.h
+++ ftphack.h	1994/03/27 23:38:44
@@ -0,0 +1,2 @@
+extern struct tab cmdtab[];
+extern struct tab sitetab[];
--- popen.c
+++ popen.c	1994/03/27 23:38:44
@@ -87,6 +87,7 @@
 	/* glob each piece */
 	gargv[0] = argv[0];
 	for (gargc = argc = 1; argv[argc]; argc++) {
+		argv[argc] = strdup(argv[argc]);
 		if (!(pop = ftpglob(argv[argc]))) {	/* globbing failed */
 			vv[0] = argv[argc];
 			vv[1] = NULL;