From 815e90447064e287ad181c1231636e7f1b44f76c Mon Sep 17 00:00:00 2001
From: Eric Andersen
Date: Tue, 6 Jun 2000 16:15:23 +0000
Subject: Fixed a bunch of stuff: 	* Fixed segfault caused by "touch -c" 
 * Fixed segfault caused by "rm -f" 	* Fixed segfault caused by "ln -s -s"
 and similar abuses. 	* Fixed segfault caused by "cp -a -a" and similar
 abuses. 	* Implemented "rm -- <foo>" updated docs accordingly.  -Erik

---
 Changelog               |  5 +++++
 Makefile                |  2 +-
 TODO                    |  6 ------
 coreutils/ln.c          | 37 +++++++++++++++++++----------------
 coreutils/rm.c          | 37 +++++++++++++++++++----------------
 cp_mv.c                 | 51 +++++++++++++++++++++++++++----------------------
 docs/busybox.pod        |  5 +++--
 ln.c                    | 37 +++++++++++++++++++----------------
 mkfs_minix.c            |  2 +-
 rm.c                    | 37 +++++++++++++++++++----------------
 util-linux/mkfs_minix.c |  2 +-
 11 files changed, 123 insertions(+), 98 deletions(-)

diff --git a/Changelog b/Changelog
index 57b936e..637f983 100644
--- a/Changelog
+++ b/Changelog
@@ -50,6 +50,11 @@
 	* Fixed all fatalError() calls lacking a "\n", thanks to Pavel Roskin.
 	* Fixed a segfault in yes when no args were given -- Pavel Roskin.
 	* Simplified freeramdisk and added argument checking -- Pavel Roskin. 
+	* Fixed segfault caused by "touch -c"
+	* Fixed segfault caused by "rm -f"
+	* Fixed segfault caused by "ln -s -s" and similar abuses.
+	* Fixed segfault caused by "cp -a -a" and similar abuses.
+	* Implemented "rm -- <foo>"
 	* "which" rewritten to use stat(). Fixes to improve its compatability
 	    with traditional implementations -- Pavel Roskin.
 	* More doc updates
diff --git a/Makefile b/Makefile
index 386d8c3..1395b52 100644
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,7 @@ export VERSION
 # Set the following to `true' to make a debuggable build.
 # Leave this set to `false' for production use.
 # eg: `make DODEBUG=true tests'
-DODEBUG = false
+DODEBUG = true
 
 # If you want a static binary, turn this on.
 DOSTATIC = false
diff --git a/TODO b/TODO
index 4778436..70706dc 100644
--- a/TODO
+++ b/TODO
@@ -26,12 +26,6 @@ Bugs that need fixing before the 0.44 release goes out the door:
 	chmod -R
 	chown -R
 	chgrp -R
-	cp -a -a
-	ln -s -s
-	rm -f
-	rm -f -
-	rm -- -
-	touch -c
   - I believe that swaponoff may also be also broken (check it).
   - It used to be that BusyBox tar would happily overwrite existing files on
       an extraction.  However, as of 0.42, BusyBox tar simply dies as soon as an 
diff --git a/coreutils/ln.c b/coreutils/ln.c
index 29ff938..d4fa473 100644
--- a/coreutils/ln.c
+++ b/coreutils/ln.c
@@ -59,25 +59,30 @@ extern int ln_main(int argc, char **argv)
 	argv++;
 
 	/* Parse any options */
-	while (**argv == '-') {
-		while (*++(*argv))
-			switch (**argv) {
-			case 's':
-				symlinkFlag = TRUE;
-				break;
-			case 'f':
-				removeoldFlag = TRUE;
-				break;
-			case 'n':
-				followLinks = FALSE;
-				break;
-			default:
-				usage(ln_usage);
-			}
-		argc--;
+	while (--argc >= 0 && *argv && **argv) {
+		while (**argv == '-') {
+			while (*++(*argv))
+				switch (**argv) {
+					case 's':
+						symlinkFlag = TRUE;
+						break;
+					case 'f':
+						removeoldFlag = TRUE;
+						break;
+					case 'n':
+						followLinks = FALSE;
+						break;
+					default:
+						usage(ln_usage);
+				}
+		}
 		argv++;
 	}
 
+	if (argc < 1) {
+		fatalError("ln: missing file argument\n");
+	}
+
 	linkName = argv[argc - 1];
 
 	if (strlen(linkName) > BUFSIZ) {
diff --git a/coreutils/rm.c b/coreutils/rm.c
index c62d68a..5901c5d 100644
--- a/coreutils/rm.c
+++ b/coreutils/rm.c
@@ -31,7 +31,8 @@
 
 static const char *rm_usage = "rm [OPTION]... FILE...\n"
 #ifndef BB_FEATURE_TRIVIAL_HELP
-	"\nRemove (unlink) the FILE(s).\n\n"
+	"\nRemove (unlink) the FILE(s).  You may use '--' to\n"
+	"indicate that all following arguments are non-options.\n\n"
 	"Options:\n"
 	"\t-f\t\tremove existing destinations, never prompt\n"
 	"\t-r or -R\tremove the contents of directories recursively\n"
@@ -64,29 +65,33 @@ static int dirAction(const char *fileName, struct stat *statbuf, void* junk)
 
 extern int rm_main(int argc, char **argv)
 {
+	int stopIt=FALSE;
 	struct stat statbuf;
 
 	if (argc < 2) {
 		usage(rm_usage);
 	}
-	argc--;
 	argv++;
 
 	/* Parse any options */
-	while (**argv == '-') {
-		while (*++(*argv))
-			switch (**argv) {
-			case 'R':
-			case 'r':
-				recursiveFlag = TRUE;
-				break;
-			case 'f':
-				forceFlag = TRUE;
-				break;
-			default:
-				usage(rm_usage);
-			}
-		argc--;
+	while (--argc >= 0 && *argv && **argv && stopIt==FALSE) {
+		while (**argv == '-') {
+			while (*++(*argv))
+				switch (**argv) {
+					case 'R':
+					case 'r':
+						recursiveFlag = TRUE;
+						break;
+					case 'f':
+						forceFlag = TRUE;
+						break;
+					case '-':
+						stopIt = TRUE;
+						break;
+					default:
+						usage(rm_usage);
+				}
+		}
 		argv++;
 	}
 
diff --git a/cp_mv.c b/cp_mv.c
index ac1e71b..4445e77 100644
--- a/cp_mv.c
+++ b/cp_mv.c
@@ -203,37 +203,42 @@ extern int cp_mv_main(int argc, char **argv)
 	if (dz_i == is_cp) {
 		recursiveFlag = preserveFlag = forceFlag = FALSE;
 		followLinks = TRUE;
-		while (**argv == '-') {
-			while (*++(*argv)) {
-				switch (**argv) {
-				case 'a':
-					followLinks = FALSE;
-					preserveFlag = TRUE;
-					recursiveFlag = TRUE;
-					break;
-				case 'd':
-					followLinks = FALSE;
-					break;
-				case 'p':
-					preserveFlag = TRUE;
-					break;
-				case 'R':
-					recursiveFlag = TRUE;
-					break;
-				case 'f':
-					forceFlag = TRUE;
-					break;
-				default:
-					usage(cp_mv_usage[is_cp]);
+		while (--argc >= 0 && *argv && **argv) {
+			while (**argv == '-') {
+				while (*++(*argv)) {
+					switch (**argv) {
+					case 'a':
+						followLinks = FALSE;
+						preserveFlag = TRUE;
+						recursiveFlag = TRUE;
+						break;
+					case 'd':
+						followLinks = FALSE;
+						break;
+					case 'p':
+						preserveFlag = TRUE;
+						break;
+					case 'R':
+						recursiveFlag = TRUE;
+						break;
+					case 'f':
+						forceFlag = TRUE;
+						break;
+					default:
+						usage(cp_mv_usage[is_cp]);
+					}
 				}
 			}
-			argc--;
 			argv++;
 		}
+		if (argc < 1) {
+			fatalError("cp: missing file argument\n");
+		}
 	} else {					/* (dz_i == is_mv) */
 		recursiveFlag = preserveFlag = TRUE;
 		followLinks = FALSE;
 	}
+	
 
 	if (strlen(argv[argc - 1]) > BUFSIZ) {
 		fprintf(stderr, name_too_long, "cp");
diff --git a/docs/busybox.pod b/docs/busybox.pod
index 2728851..7b76e7e 100644
--- a/docs/busybox.pod
+++ b/docs/busybox.pod
@@ -1327,7 +1327,8 @@ Instructs the kernel to reboot the system.
 
 Usage: rm [OPTION]... FILE...
 
-Remove (unlink) the FILE(s).
+Remove (unlink) the FILE(s).  You may use '--' to 
+indicate that all following arguments are non-options.
 
 Options:
 
@@ -1946,4 +1947,4 @@ Enrique Zanardi <ezanardi@ull.es>
 
 =cut
 
-# $Id: busybox.pod,v 1.34 2000/06/05 17:23:06 andersen Exp $
+# $Id: busybox.pod,v 1.35 2000/06/06 16:15:23 andersen Exp $
diff --git a/ln.c b/ln.c
index 29ff938..d4fa473 100644
--- a/ln.c
+++ b/ln.c
@@ -59,25 +59,30 @@ extern int ln_main(int argc, char **argv)
 	argv++;
 
 	/* Parse any options */
-	while (**argv == '-') {
-		while (*++(*argv))
-			switch (**argv) {
-			case 's':
-				symlinkFlag = TRUE;
-				break;
-			case 'f':
-				removeoldFlag = TRUE;
-				break;
-			case 'n':
-				followLinks = FALSE;
-				break;
-			default:
-				usage(ln_usage);
-			}
-		argc--;
+	while (--argc >= 0 && *argv && **argv) {
+		while (**argv == '-') {
+			while (*++(*argv))
+				switch (**argv) {
+					case 's':
+						symlinkFlag = TRUE;
+						break;
+					case 'f':
+						removeoldFlag = TRUE;
+						break;
+					case 'n':
+						followLinks = FALSE;
+						break;
+					default:
+						usage(ln_usage);
+				}
+		}
 		argv++;
 	}
 
+	if (argc < 1) {
+		fatalError("ln: missing file argument\n");
+	}
+
 	linkName = argv[argc - 1];
 
 	if (strlen(linkName) > BUFSIZ) {
diff --git a/mkfs_minix.c b/mkfs_minix.c
index c6f057a..ef37c38 100644
--- a/mkfs_minix.c
+++ b/mkfs_minix.c
@@ -188,7 +188,7 @@ static volatile void show_usage()
 	fprintf(stderr,
 			"\t-n [14|30]\tSpecify the maximum length of filenames\n");
 	fprintf(stderr,
-			"\t-i\t\tSpecify the number of inodes for the filesystem\n");
+			"\t-i INODES\tSpecify the number of inodes for the filesystem\n");
 	fprintf(stderr,
 			"\t-l FILENAME\tRead the bad blocks list from FILENAME\n");
 	fprintf(stderr, "\t-v\t\tMake a Minix version 2 filesystem\n\n");
diff --git a/rm.c b/rm.c
index c62d68a..5901c5d 100644
--- a/rm.c
+++ b/rm.c
@@ -31,7 +31,8 @@
 
 static const char *rm_usage = "rm [OPTION]... FILE...\n"
 #ifndef BB_FEATURE_TRIVIAL_HELP
-	"\nRemove (unlink) the FILE(s).\n\n"
+	"\nRemove (unlink) the FILE(s).  You may use '--' to\n"
+	"indicate that all following arguments are non-options.\n\n"
 	"Options:\n"
 	"\t-f\t\tremove existing destinations, never prompt\n"
 	"\t-r or -R\tremove the contents of directories recursively\n"
@@ -64,29 +65,33 @@ static int dirAction(const char *fileName, struct stat *statbuf, void* junk)
 
 extern int rm_main(int argc, char **argv)
 {
+	int stopIt=FALSE;
 	struct stat statbuf;
 
 	if (argc < 2) {
 		usage(rm_usage);
 	}
-	argc--;
 	argv++;
 
 	/* Parse any options */
-	while (**argv == '-') {
-		while (*++(*argv))
-			switch (**argv) {
-			case 'R':
-			case 'r':
-				recursiveFlag = TRUE;
-				break;
-			case 'f':
-				forceFlag = TRUE;
-				break;
-			default:
-				usage(rm_usage);
-			}
-		argc--;
+	while (--argc >= 0 && *argv && **argv && stopIt==FALSE) {
+		while (**argv == '-') {
+			while (*++(*argv))
+				switch (**argv) {
+					case 'R':
+					case 'r':
+						recursiveFlag = TRUE;
+						break;
+					case 'f':
+						forceFlag = TRUE;
+						break;
+					case '-':
+						stopIt = TRUE;
+						break;
+					default:
+						usage(rm_usage);
+				}
+		}
 		argv++;
 	}
 
diff --git a/util-linux/mkfs_minix.c b/util-linux/mkfs_minix.c
index c6f057a..ef37c38 100644
--- a/util-linux/mkfs_minix.c
+++ b/util-linux/mkfs_minix.c
@@ -188,7 +188,7 @@ static volatile void show_usage()
 	fprintf(stderr,
 			"\t-n [14|30]\tSpecify the maximum length of filenames\n");
 	fprintf(stderr,
-			"\t-i\t\tSpecify the number of inodes for the filesystem\n");
+			"\t-i INODES\tSpecify the number of inodes for the filesystem\n");
 	fprintf(stderr,
 			"\t-l FILENAME\tRead the bad blocks list from FILENAME\n");
 	fprintf(stderr, "\t-v\t\tMake a Minix version 2 filesystem\n\n");
-- 
cgit v1.1