Index: contrib/lukemftpd/src/ftpcmd.y
===================================================================
--- contrib/lukemftpd/src/ftpcmd.y	(revision 186403)
+++ contrib/lukemftpd/src/ftpcmd.y	(working copy)
@@ -1363,8 +1363,12 @@
 
 /*
  * getline - a hacked up version of fgets to ignore TELNET escape codes.
+ *	`s' is the buffer to read into.
+ *	`n' is the 1 less than the size of the buffer, to allow trailing NUL
+ *	`iop' is the FILE to read from.
+ *	Returns 0 on success, -1 on EOF, -2 if the command was too long.
  */
-char *
+int
 getline(char *s, int n, FILE *iop)
 {
 	int c;
@@ -1379,7 +1383,7 @@
 			if (ftpd_debug)
 				syslog(LOG_DEBUG, "command: %s", s);
 			tmpline[0] = '\0';
-			return(s);
+			return(0);
 		}
 		if (c == 0)
 			tmpline[0] = '\0';
@@ -1418,11 +1422,25 @@
 		    }
 		}
 		*cs++ = c;
-		if (--n <= 0 || c == '\n')
+		if (--n <= 0) {
+			/*
+			 * If command doesn't fit into buffer, discard the
+			 * rest of the command and indicate truncation.
+			 * This prevents the command to be split up into
+			 * multiple commands.
+			 */
+			if (ftpd_debug)
+				syslog(LOG_DEBUG,
+				    "command too long, last char: %d", c);
+			while (c != '\n' && (c = getc(iop)) != EOF)
+				continue;
+			return (-2);
+		}
+		if (c == '\n')
 			break;
 	}
 	if (c == EOF && cs == s)
-		return (NULL);
+		return (-1);
 	*cs++ = '\0';
 	if (ftpd_debug) {
 		if ((curclass.type != CLASS_GUEST &&
@@ -1444,7 +1462,7 @@
 			syslog(LOG_DEBUG, "command: %.*s", len, s);
 		}
 	}
-	return (s);
+	return (0);
 }
 
 void
@@ -1458,15 +1476,20 @@
 void
 ftp_loop(void)
 {
+	int ret;
 
 	while (1) {
 		(void) alarm(curclass.timeout);
-		if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
+		ret = getline(cbuf, sizeof(cbuf)-1, stdin);
+		(void) alarm(0);
+		if (ret == -1) {
 			reply(221, "You could at least say goodbye.");
 			dologout(0);
+		} else if (ret == -2) {
+			reply(500, "Command too long.");
+		} else {
+			ftp_handle_line(cbuf);
 		}
-		(void) alarm(0);
-		ftp_handle_line(cbuf);
 	}
 	/*NOTREACHED*/
 }
Index: contrib/lukemftpd/src/extern.h
===================================================================
--- contrib/lukemftpd/src/extern.h	(revision 186403)
+++ contrib/lukemftpd/src/extern.h	(working copy)
@@ -139,7 +139,7 @@
 void	format_path(char *, const char *);
 int	ftpd_pclose(FILE *);
 FILE   *ftpd_popen(char *[], const char *, int);
-char   *getline(char *, int, FILE *);
+int	getline(char *, int, FILE *);
 void	init_curclass(void);
 void	logxfer(const char *, off_t, const char *, const char *,
 	    const struct timeval *, const char *);
Index: contrib/lukemftpd/src/ftpd.c
===================================================================
--- contrib/lukemftpd/src/ftpd.c	(revision 186403)
+++ contrib/lukemftpd/src/ftpd.c	(working copy)
@@ -1,4 +1,4 @@
-/*	$NetBSD: ftpd.c,v 1.176 2006/05/09 20:18:06 mrg Exp $	*/
+/*	$NetBSD: ftpd.c,v 1.187 2008/09/13 03:30:35 lukem Exp $	*/
 
 /*
  * Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
@@ -2896,6 +2896,7 @@
 handleoobcmd()
 {
 	char *cp;
+	int ret;
 
 	if (!urgflag)
 		return (0);
@@ -2904,9 +2905,14 @@
 	if (!transflag)
 		return (0);
 	cp = tmpline;
-	if (getline(cp, sizeof(tmpline), stdin) == NULL) {
+	ret = getline(cp, sizeof(tmpline)-1, stdin);
+	if (ret == -1) {
 		reply(221, "You could at least say goodbye.");
 		dologout(0);
+	} else if (ret == -2) {
+		/* Ignore truncated command */
+		/* XXX: abort xfer with "500 command too long", & return 1 ? */
+		return 0;
 	}
 		/*
 		 * Manually parse OOB commands, because we can't
