Stuff
diff --git a/Changelog b/Changelog
index 1dd93c3..750768b 100644
--- a/Changelog
+++ b/Changelog
@@ -5,6 +5,17 @@
 	    better job of finding the real consol device rather than using
 	    /dev/console which doesn't support job control. Patch also
 	    thanks to Eric Delaunay.
+	* more started to read from stdin after the last file was finished, and 
+	    options were not parsed correctly (fix thanks to Eric Delaunay).
+	* rm wouldn't remove a symlink unless the symlink was valid.  This was
+	    a side effect of the busybox 0.32 recursiveAction() fix.  Things 
+	    should now work correctly.
+	* grep wouldn't grep stdin.  Now it does.
+	* sed wouldn't sed stdin.  Now it does.
+	* sed was appending a \n to the end of lines with replacements.
+	    Now it doesn't do that.
+	* ls -l now bypasses libc6 nss when displaying user/group names.
+	    Now uses my_getpwuid and my_getgrgid.
 
 0.33
 	* Fixed a bug where init could hang instead of rebooting.
diff --git a/Makefile b/Makefile
index 13d349d..14c2f41 100644
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@
 
 # Comment out the following to make a debuggable build
 # Leave this off for production use.
-DODEBUG=false
+DODEBUG=true
 # If you want a static binary, turn this on.  I can't think
 # of many situations where anybody would ever want it static, 
 # but...
diff --git a/archival/tar.c b/archival/tar.c
index cd255f8..9ad41be 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -35,6 +35,16 @@
 #include <signal.h>
 #include <time.h>
 
+/* Note that tar.c expects TRUE and FALSE to be defined
+ * exactly the opposite of how they are used everywhere else.
+ * Some time this should be integrated a bit better, but this
+ * does the job for now.
+ */
+#undef FALSE
+#undef TRUE
+#define FALSE ((int) 0)
+#define TRUE  ((int) 1)
+
 
 static const char tar_usage[] =
     "tar -[cxtvOf] [tarFileName] [FILE] ...\n"
@@ -169,10 +179,9 @@
     /* 
      * Parse the options.
      */
-    options = *argv++;
-    argc--;
-
     if (**argv == '-') {
+	options = (*argv++) + 1;
+	argc--;
 	for (; *options; options++) {
 	    switch (*options) {
 	    case 'f':
diff --git a/busybox.def.h b/busybox.def.h
index 59c1df1..26fd8f8 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -54,7 +54,7 @@
 #define BB_SYNC
 #define BB_TAR
 #define BB_TOUCH
-//#define BB_TRUE_FALSE  // Supplied by ash
+//#define BB_TRUE_FALSE
 #define BB_UMOUNT
 #define BB_UPDATE
 #define BB_UNAME
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 4eb486f..f09cbbc 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -40,7 +40,7 @@
  * 1. requires lstat (BSD) - how do you do it without?
  */
 
-//#define FEATURE_USERNAME	/* show username/groupnames (libc6 uses NSS) */
+#define FEATURE_USERNAME	/* show username/groupnames (bypasses libc6 NSS) */
 #define FEATURE_TIMESTAMPS	/* show file timestamps */
 #define FEATURE_AUTOWIDTH	/* calculate terminal & column widths */
 #define FEATURE_FILETYPECHAR	/* enable -p and -F */
@@ -64,10 +64,6 @@
 #include <dirent.h>
 #include <errno.h>
 #include <stdio.h>
-#ifdef FEATURE_USERNAME
-#include <pwd.h>
-#include <grp.h>
-#endif
 #ifdef FEATURE_TIMESTAMPS
 #include <time.h>
 #endif
@@ -83,27 +79,6 @@
 #define MINOR(dev) ((dev)&0xff)
 #endif
 
-#define MODE1  "rwxrwxrwx"
-#define MODE0  "---------"
-#define SMODE1 "..s..s..t"
-#define SMODE0 "..S..S..T"
-
-/* The 9 mode bits to test */
-
-static const mode_t MBIT[] = {
-  S_IRUSR, S_IWUSR, S_IXUSR,
-  S_IRGRP, S_IWGRP, S_IXGRP,
-  S_IROTH, S_IWOTH, S_IXOTH
-};
-
-/* The special bits. If set, display SMODE0/1 instead of MODE0/1 */
-
-static const mode_t SBIT[] = {
-  0, 0, S_ISUID,
-  0, 0, S_ISGID,
-  0, 0, S_ISVTX
-};
-
 #define FMT_AUTO	0
 #define FMT_LONG	1	/* one record per line, extended info */
 #define FMT_SINGLE	2	/* one record per line */
@@ -216,45 +191,35 @@
 	
 	if (display_fmt == FMT_LONG) {
 		mode_t mode = info->st_mode; 
-		int i;
-		
-		scratch[0] = TYPECHAR(mode);
-		for (i=0; i<9; i++)
-			if (mode & SBIT[i])
-				scratch[i+1] = (mode & MBIT[i])
-						? SMODE1[i]
-						: SMODE0[i];
-			else
-				scratch[i+1] = (mode & MBIT[i])
-						? MODE1[i]
-						: MODE0[i];
 		newline();
-		wr(scratch, 10);
+		wr(modeString(mode), 10);
 		column=10;
-		writenum((long)info->st_nlink,(short)4);
+		writenum((long)info->st_nlink,(short)5);
 		fputs(" ", stdout);
 #ifdef FEATURE_USERNAME
 		if (!(opts & DISP_NUMERIC)) {
-			struct passwd *pw = getpwuid(info->st_uid);
-			if (pw)
-				fputs(pw->pw_name, stdout);
+			scratch[8]='\0';
+			my_getpwuid( scratch, info->st_uid);
+			if (*scratch)
+				fputs(scratch, stdout);
 			else
 				writenum((long)info->st_uid,(short)0);
 		} else
 #endif
 		writenum((long)info->st_uid,(short)0);
-		tab(24);
+		tab(16);
 #ifdef FEATURE_USERNAME
 		if (!(opts & DISP_NUMERIC)) {
-			struct group *gr = getgrgid(info->st_gid);
-			if (gr)
-				fputs(gr->gr_name, stdout);
+			scratch[8]='\0';
+			my_getgrgid( scratch, info->st_gid);
+			if (*scratch)
+				fputs(scratch, stdout);
 			else
 				writenum((long)info->st_gid,(short)0);
 		} else
 #endif
 		writenum((long)info->st_gid,(short)0);
-		tab(33);
+		tab(17);
 		if (S_ISBLK(mode) || S_ISCHR(mode)) {
 			writenum((long)MAJOR(info->st_rdev),(short)3);
 			fputs(", ", stdout);
diff --git a/coreutils/rm.c b/coreutils/rm.c
index f49ada5..077e792 100644
--- a/coreutils/rm.c
+++ b/coreutils/rm.c
@@ -84,7 +84,7 @@
 
     while (argc-- > 0) {
 	srcName = *(argv++);
-	if (recursiveAction( srcName, recursiveFlag, TRUE, TRUE, 
+	if (recursiveAction( srcName, recursiveFlag, FALSE, TRUE, 
 			       fileAction, dirAction) == FALSE) {
 	    exit( FALSE);
 	}
diff --git a/editors/sed.c b/editors/sed.c
index f0a6a3b..34756e0 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -45,9 +45,23 @@
 #else
 "This version of sed matches strings (not full regexps).\n";
 #endif
+    
 
+static void do_sed(FILE *fp, char *needle, char *newNeedle, int ignoreCase, int printFlag, int quietFlag)
+{
+    int foundOne=FALSE;
+    char haystack[1024];
 
-
+    while (fgets (haystack, 1023, fp)) {
+	foundOne = replace_match(haystack, needle, newNeedle, ignoreCase);
+	if (foundOne==TRUE && printFlag==TRUE) {
+	    fprintf(stdout, haystack);
+	}
+	if (quietFlag==FALSE) {
+	    fprintf(stdout, haystack);
+	}
+    }
+}
 
 extern int sed_main (int argc, char **argv)
 {
@@ -56,11 +70,9 @@
     char *name;
     char *cp;
     int ignoreCase=FALSE;
-    int foundOne=FALSE;
     int printFlag=FALSE;
     int quietFlag=FALSE;
     int stopNow;
-    char *haystack;
 
     argc--;
     argv++;
@@ -73,24 +85,23 @@
 	cp = *argv++;
 	stopNow=FALSE;
 
-	while (*++cp && stopNow==FALSE)
+	while (*++cp && stopNow==FALSE) {
 	    switch (*cp) {
 	    case 'n':
 		quietFlag = TRUE;
 		break;
 	    case 'e':
 		if (*(cp+1)==0 && --argc < 0) {
-		    fprintf(stderr, "A\n");
 		    usage( sed_usage);
 		}
-		cp = *argv++;
+		if ( *++cp != 's')
+		    cp = *argv++;
 		while( *cp ) {
 		    if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') {
 			char* pos=needle=cp+2;
 			for(;;) {
 			    pos = strchr(pos, '/');
 			    if (pos==NULL) {
-				fprintf(stderr, "B\n");
 				usage( sed_usage);
 			    }
 			    if (*(pos-1) == '\\') {
@@ -104,7 +115,6 @@
 			for(;;) {
 			    pos = strchr(pos, '/');
 			    if (pos==NULL) {
-				fprintf(stderr, "C\n");
 				usage( sed_usage);
 			    }
 			    if (*(pos-1) == '\\') {
@@ -116,7 +126,6 @@
 			*pos=0;
 			if (pos+2 != 0) {
 			    while (*++pos) {
-				fprintf(stderr, "pos='%s'\n", pos);
 				switch (*pos) {
 				    case 'i':
 					ignoreCase=TRUE;
@@ -134,42 +143,35 @@
 		    }
 		    cp++;
 		}
-		fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle);
+		//fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle);
 		stopNow=TRUE;
 		break;
 
 	    default:
-		fprintf(stderr, "D\n");
 		usage(sed_usage);
 	    }
+	}
     }
 
-    while (argc-- > 0) {
-	name = *argv++;
+    if (argc==0) {
+	do_sed( stdin, needle, newNeedle, ignoreCase, printFlag, quietFlag);
+    } else {
+	while (argc-- > 0) {
+	    name = *argv++;
 
-	fp = fopen (name, "r");
-	if (fp == NULL) {
-	    perror (name);
-	    continue;
+	    fp = fopen (name, "r");
+	    if (fp == NULL) {
+		perror (name);
+		continue;
+	    }
+
+	    do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag);
+
+	    if (ferror (fp))
+		perror (name);
+
+	    fclose (fp);
 	}
-
-	haystack = (char*)malloc( 1024);
-	while (fgets (haystack, 1023, fp)) {
-
-	    foundOne = replace_match(haystack, needle, newNeedle, ignoreCase);
-	    if (foundOne==TRUE && printFlag==TRUE)
-		    fputs (haystack, stdout);
-	    if (quietFlag==FALSE)
-		fputs (haystack, stdout);
-	    /* Avoid any mem leaks */
-	    free(haystack);
-	    haystack = (char*)malloc( BUF_SIZE);
-	}
-
-	if (ferror (fp))
-	    perror (name);
-
-	fclose (fp);
     }
     exit( TRUE);
 }
diff --git a/findutils/grep.c b/findutils/grep.c
index 50a2961..8dcff05 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -40,45 +40,46 @@
 #if defined BB_REGEXP
 "This version of grep matches full regexps.\n";
 #else
-"This version of grep matches strings (not full regexps).\n";
+"This version of grep matches strings (not regexps).\n";
 #endif
 
-int tellName=TRUE;
-int ignoreCase=FALSE;
-int tellLine=FALSE;
 
-static do_grep(char* needle, char* haystack )
+static void do_grep(FILE *fp, char* needle, char *fileName, int tellName, int ignoreCase, int tellLine)
 {
-	line = 0;
+    char *cp;
+    long line = 0;
+    char haystack[BUF_SIZE];
 
-	while (fgets (haystack, sizeof (haystack), fp)) {
-	    line++;
-	    cp = &haystack[strlen (haystack) - 1];
+    while (fgets (haystack, sizeof (haystack), fp)) {
+	line++;
+	cp = &haystack[strlen (haystack) - 1];
 
-	    if (*cp != '\n')
-		fprintf (stderr, "%s: Line too long\n", name);
+	if (*cp != '\n')
+	    fprintf (stderr, "%s: Line too long\n", fileName);
 
-	    if (find_match(haystack, needle, ignoreCase) == TRUE) {
-		if (tellName==TRUE)
-		    printf ("%s: ", name);
+	if (find_match(haystack, needle, ignoreCase) == TRUE) {
+	    if (tellName==TRUE)
+		printf ("%s:", fileName);
 
-		if (tellLine==TRUE)
-		    printf ("%ld: ", line);
+	    if (tellLine==TRUE)
+		printf ("%ld:", line);
 
-		fputs (haystack, stdout);
-	    }
+	    fputs (haystack, stdout);
 	}
+    }
 }
 
 
 extern int grep_main (int argc, char **argv)
 {
     FILE *fp;
-    char *needle;
-    char *name;
     char *cp;
-    long line;
-    char haystack[BUF_SIZE];
+    char *needle;
+    char *fileName;
+    int tellName=FALSE;
+    int ignoreCase=FALSE;
+    int tellLine=FALSE;
+
 
     ignoreCase = FALSE;
     tellLine = FALSE;
@@ -100,7 +101,7 @@
 		break;
 
 	    case 'h':
-		tellName = FALSE;
+		tellName = TRUE;
 		break;
 
 	    case 'n':
@@ -115,28 +116,24 @@
     needle = *argv++;
     argc--;
 
+    if (argc==0) {
+	do_grep( stdin, needle, "stdin", FALSE, ignoreCase, tellLine);
+    } else {
+	while (argc-- > 0) {
+	    fileName = *argv++;
 
-    while (argc-- > 0) {
+	    fp = fopen (fileName, "r");
+	    if (fp == NULL) {
+		perror (fileName);
+		continue;
+	    }
 
-	if (argc==0) {
-	    file = stdin;
+	    do_grep( fp, needle, fileName, tellName, ignoreCase, tellLine);
+
+	    if (ferror (fp))
+		perror (fileName);
+	    fclose (fp);
 	}
-	else
-	    file = fopen(*argv, "r");
-
-
-	name = *argv++;
-
-	fp = fopen (name, "r");
-	if (fp == NULL) {
-	    perror (name);
-	    continue;
-	}
-
-	if (ferror (fp))
-	    perror (name);
-
-	fclose (fp);
     }
     exit( TRUE);
 }
diff --git a/grep.c b/grep.c
index 50a2961..8dcff05 100644
--- a/grep.c
+++ b/grep.c
@@ -40,45 +40,46 @@
 #if defined BB_REGEXP
 "This version of grep matches full regexps.\n";
 #else
-"This version of grep matches strings (not full regexps).\n";
+"This version of grep matches strings (not regexps).\n";
 #endif
 
-int tellName=TRUE;
-int ignoreCase=FALSE;
-int tellLine=FALSE;
 
-static do_grep(char* needle, char* haystack )
+static void do_grep(FILE *fp, char* needle, char *fileName, int tellName, int ignoreCase, int tellLine)
 {
-	line = 0;
+    char *cp;
+    long line = 0;
+    char haystack[BUF_SIZE];
 
-	while (fgets (haystack, sizeof (haystack), fp)) {
-	    line++;
-	    cp = &haystack[strlen (haystack) - 1];
+    while (fgets (haystack, sizeof (haystack), fp)) {
+	line++;
+	cp = &haystack[strlen (haystack) - 1];
 
-	    if (*cp != '\n')
-		fprintf (stderr, "%s: Line too long\n", name);
+	if (*cp != '\n')
+	    fprintf (stderr, "%s: Line too long\n", fileName);
 
-	    if (find_match(haystack, needle, ignoreCase) == TRUE) {
-		if (tellName==TRUE)
-		    printf ("%s: ", name);
+	if (find_match(haystack, needle, ignoreCase) == TRUE) {
+	    if (tellName==TRUE)
+		printf ("%s:", fileName);
 
-		if (tellLine==TRUE)
-		    printf ("%ld: ", line);
+	    if (tellLine==TRUE)
+		printf ("%ld:", line);
 
-		fputs (haystack, stdout);
-	    }
+	    fputs (haystack, stdout);
 	}
+    }
 }
 
 
 extern int grep_main (int argc, char **argv)
 {
     FILE *fp;
-    char *needle;
-    char *name;
     char *cp;
-    long line;
-    char haystack[BUF_SIZE];
+    char *needle;
+    char *fileName;
+    int tellName=FALSE;
+    int ignoreCase=FALSE;
+    int tellLine=FALSE;
+
 
     ignoreCase = FALSE;
     tellLine = FALSE;
@@ -100,7 +101,7 @@
 		break;
 
 	    case 'h':
-		tellName = FALSE;
+		tellName = TRUE;
 		break;
 
 	    case 'n':
@@ -115,28 +116,24 @@
     needle = *argv++;
     argc--;
 
+    if (argc==0) {
+	do_grep( stdin, needle, "stdin", FALSE, ignoreCase, tellLine);
+    } else {
+	while (argc-- > 0) {
+	    fileName = *argv++;
 
-    while (argc-- > 0) {
+	    fp = fopen (fileName, "r");
+	    if (fp == NULL) {
+		perror (fileName);
+		continue;
+	    }
 
-	if (argc==0) {
-	    file = stdin;
+	    do_grep( fp, needle, fileName, tellName, ignoreCase, tellLine);
+
+	    if (ferror (fp))
+		perror (fileName);
+	    fclose (fp);
 	}
-	else
-	    file = fopen(*argv, "r");
-
-
-	name = *argv++;
-
-	fp = fopen (name, "r");
-	if (fp == NULL) {
-	    perror (name);
-	    continue;
-	}
-
-	if (ferror (fp))
-	    perror (name);
-
-	fclose (fp);
     }
     exit( TRUE);
 }
diff --git a/ls.c b/ls.c
index 4eb486f..f09cbbc 100644
--- a/ls.c
+++ b/ls.c
@@ -40,7 +40,7 @@
  * 1. requires lstat (BSD) - how do you do it without?
  */
 
-//#define FEATURE_USERNAME	/* show username/groupnames (libc6 uses NSS) */
+#define FEATURE_USERNAME	/* show username/groupnames (bypasses libc6 NSS) */
 #define FEATURE_TIMESTAMPS	/* show file timestamps */
 #define FEATURE_AUTOWIDTH	/* calculate terminal & column widths */
 #define FEATURE_FILETYPECHAR	/* enable -p and -F */
@@ -64,10 +64,6 @@
 #include <dirent.h>
 #include <errno.h>
 #include <stdio.h>
-#ifdef FEATURE_USERNAME
-#include <pwd.h>
-#include <grp.h>
-#endif
 #ifdef FEATURE_TIMESTAMPS
 #include <time.h>
 #endif
@@ -83,27 +79,6 @@
 #define MINOR(dev) ((dev)&0xff)
 #endif
 
-#define MODE1  "rwxrwxrwx"
-#define MODE0  "---------"
-#define SMODE1 "..s..s..t"
-#define SMODE0 "..S..S..T"
-
-/* The 9 mode bits to test */
-
-static const mode_t MBIT[] = {
-  S_IRUSR, S_IWUSR, S_IXUSR,
-  S_IRGRP, S_IWGRP, S_IXGRP,
-  S_IROTH, S_IWOTH, S_IXOTH
-};
-
-/* The special bits. If set, display SMODE0/1 instead of MODE0/1 */
-
-static const mode_t SBIT[] = {
-  0, 0, S_ISUID,
-  0, 0, S_ISGID,
-  0, 0, S_ISVTX
-};
-
 #define FMT_AUTO	0
 #define FMT_LONG	1	/* one record per line, extended info */
 #define FMT_SINGLE	2	/* one record per line */
@@ -216,45 +191,35 @@
 	
 	if (display_fmt == FMT_LONG) {
 		mode_t mode = info->st_mode; 
-		int i;
-		
-		scratch[0] = TYPECHAR(mode);
-		for (i=0; i<9; i++)
-			if (mode & SBIT[i])
-				scratch[i+1] = (mode & MBIT[i])
-						? SMODE1[i]
-						: SMODE0[i];
-			else
-				scratch[i+1] = (mode & MBIT[i])
-						? MODE1[i]
-						: MODE0[i];
 		newline();
-		wr(scratch, 10);
+		wr(modeString(mode), 10);
 		column=10;
-		writenum((long)info->st_nlink,(short)4);
+		writenum((long)info->st_nlink,(short)5);
 		fputs(" ", stdout);
 #ifdef FEATURE_USERNAME
 		if (!(opts & DISP_NUMERIC)) {
-			struct passwd *pw = getpwuid(info->st_uid);
-			if (pw)
-				fputs(pw->pw_name, stdout);
+			scratch[8]='\0';
+			my_getpwuid( scratch, info->st_uid);
+			if (*scratch)
+				fputs(scratch, stdout);
 			else
 				writenum((long)info->st_uid,(short)0);
 		} else
 #endif
 		writenum((long)info->st_uid,(short)0);
-		tab(24);
+		tab(16);
 #ifdef FEATURE_USERNAME
 		if (!(opts & DISP_NUMERIC)) {
-			struct group *gr = getgrgid(info->st_gid);
-			if (gr)
-				fputs(gr->gr_name, stdout);
+			scratch[8]='\0';
+			my_getgrgid( scratch, info->st_gid);
+			if (*scratch)
+				fputs(scratch, stdout);
 			else
 				writenum((long)info->st_gid,(short)0);
 		} else
 #endif
 		writenum((long)info->st_gid,(short)0);
-		tab(33);
+		tab(17);
 		if (S_ISBLK(mode) || S_ISCHR(mode)) {
 			writenum((long)MAJOR(info->st_rdev),(short)3);
 			fputs(", ", stdout);
diff --git a/more.c b/more.c
index ea5e225..4693161 100644
--- a/more.c
+++ b/more.c
@@ -25,7 +25,9 @@
 
 
 /* Turning this off makes things a bit smaller (and less pretty) */
-#define BB_MORE_TERM
+#define BB_FEATURE_USE_TERMIOS
+/* Turning this off makes things a bit smaller (and less pretty) */
+#define BB_FEATURE_AUTOWIDTH
 
 
 
@@ -33,18 +35,16 @@
 #include <stdio.h>
 #include <fcntl.h>
 #include <signal.h>
-
+#include <sys/ioctl.h>
 
 static const char more_usage[] = "[file ...]";
 
-
 /* ED: sparc termios is broken: revert back to old termio handling. */
-#ifdef BB_MORE_TERM
+#ifdef BB_FEATURE_USE_TERMIOS
 
 #if #cpu(sparc)
 #      define USE_OLD_TERMIO
 #      include <termio.h>
-#      include <sys/ioctl.h>
 #      define termios termio
 #      define stty(fd,argp) ioctl(fd,TCSETAF,argp)
 #else
@@ -57,16 +57,35 @@
 
     void gotsig(int sig) { 
 	    stty(fileno(cin), &initial_settings);
+	    fprintf(stdout, "\n");
 	    exit( TRUE);
     }
 #endif
 
+
+
+#define TERMINAL_WIDTH	79	/* not 80 in case terminal has linefold bug */
+#define TERMINAL_HEIGHT	24
+
+
+#if defined BB_FEATURE_AUTOWIDTH && ! defined USE_OLD_TERMIO
+static int terminal_width = 0, terminal_height = 0;
+#else
+#define terminal_width	TERMINAL_WIDTH
+#define terminal_height	TERMINAL_HEIGHT
+#endif
+
+
+
 extern int more_main(int argc, char **argv)
 {
     int c, lines=0, input=0;
     int next_page=0;
     struct stat st;	
     FILE *file;
+#ifdef BB_FEATURE_AUTOWIDTH
+    struct winsize win;
+#endif
 
     argc--;
     argv++;
@@ -87,7 +106,7 @@
 	}
 	fstat(fileno(file), &st);
 
-#ifdef BB_MORE_TERM
+#ifdef BB_FEATURE_USE_TERMIOS
 	cin = fopen("/dev/tty", "r");
 	if (!cin)
 	    cin = fopen("/dev/console", "r");
@@ -100,12 +119,19 @@
 	new_settings.c_lflag &= ~ICANON;
 	new_settings.c_lflag &= ~ECHO;
 	stty(fileno(cin), &new_settings);
-	
+
+#ifdef BB_FEATURE_AUTOWIDTH	
+	ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
+	if (win.ws_row > 4) 
+	    terminal_height = win.ws_row - 2;
+	if (win.ws_col > 0) 
+	    terminal_width = win.ws_col - 1;
+#endif
+
 	(void) signal(SIGINT, gotsig);
 	(void) signal(SIGQUIT, gotsig);
 	(void) signal(SIGTERM, gotsig);
 
-
 #endif
 	while ((c = getc(file)) != EOF) {
 	    if ( next_page ) {
@@ -119,7 +145,7 @@
 			st.st_size);
 		}
 		len += fprintf(stdout, "%s",
-#ifdef BB_MORE_TERM
+#ifdef BB_FEATURE_USE_TERMIOS
 			""
 #else
 			"\n"
@@ -129,24 +155,31 @@
 		fflush(stdout);
 		input = getc( cin);
 
-#ifdef BB_MORE_TERM
+#ifdef BB_FEATURE_USE_TERMIOS
 		/* Erase the "More" message */
-		while(len-- > 0)
+		while(--len >= 0)
 		    putc('\b', stdout);
-		while(len++ < 79)
+		while(++len <= terminal_width)
 		    putc(' ', stdout);
-		while(len-- > 0)
+		while(--len >= 0)
 		    putc('\b', stdout);
 		fflush(stdout);
 #endif
 
 	    }
-	    if (input=='q')
-		goto end;
-	    if (input=='\n' &&  c == '\n' )
-		next_page = 1;
-	    if ( c == ' ' && ++lines == 24 )
-		next_page = 1;
+	    if (c == '\n' ) {
+		switch(input) {
+		    case 'q':
+			goto end;
+		    case '\n':
+			/* increment by just one line if we are at 
+			 * the end of this line*/
+			next_page = 1;
+			break;
+		}
+		if ( ++lines == terminal_height )
+		    next_page = 1;
+	    }
 	    putc(c, stdout);
 	}
 	fclose(file);
@@ -155,7 +188,7 @@
 	argv++;
     } while (--argc > 0);
 end:
-#ifdef BB_MORE_TERM
+#ifdef BB_FEATURE_USE_TERMIOS
     gotsig(0);
 #endif	
     exit(TRUE);
diff --git a/procps/ps.c b/procps/ps.c
index d8a4233..55439da 100644
--- a/procps/ps.c
+++ b/procps/ps.c
@@ -74,7 +74,7 @@
     );
     else fprintf(stderr, "Internal error!\n");
 
-    /* For busybox, ignoring effecting, saved, etc */
+    /* For busybox, ignoring effective, saved, etc */
     tmp = strstr (S,"Uid:");
     if(tmp) sscanf (tmp,
         "Uid:\t%d", &P->ruid);
diff --git a/ps.c b/ps.c
index d8a4233..55439da 100644
--- a/ps.c
+++ b/ps.c
@@ -74,7 +74,7 @@
     );
     else fprintf(stderr, "Internal error!\n");
 
-    /* For busybox, ignoring effecting, saved, etc */
+    /* For busybox, ignoring effective, saved, etc */
     tmp = strstr (S,"Uid:");
     if(tmp) sscanf (tmp,
         "Uid:\t%d", &P->ruid);
diff --git a/regexp.c b/regexp.c
index 164f880..5500b1d 100644
--- a/regexp.c
+++ b/regexp.c
@@ -50,7 +50,6 @@
 	} while (regexec(re, s, FALSE, ignoreCase) == TRUE);
 	 /* copy stuff from after the match */
 	while ( (*d++ = *s++) ) {}
-	d[-1] = '\n';
 	d[0] = '\0';
 	strcpy(haystack, buf);
     }
diff --git a/rm.c b/rm.c
index f49ada5..077e792 100644
--- a/rm.c
+++ b/rm.c
@@ -84,7 +84,7 @@
 
     while (argc-- > 0) {
 	srcName = *(argv++);
-	if (recursiveAction( srcName, recursiveFlag, TRUE, TRUE, 
+	if (recursiveAction( srcName, recursiveFlag, FALSE, TRUE, 
 			       fileAction, dirAction) == FALSE) {
 	    exit( FALSE);
 	}
diff --git a/sed.c b/sed.c
index f0a6a3b..34756e0 100644
--- a/sed.c
+++ b/sed.c
@@ -45,9 +45,23 @@
 #else
 "This version of sed matches strings (not full regexps).\n";
 #endif
+    
 
+static void do_sed(FILE *fp, char *needle, char *newNeedle, int ignoreCase, int printFlag, int quietFlag)
+{
+    int foundOne=FALSE;
+    char haystack[1024];
 
-
+    while (fgets (haystack, 1023, fp)) {
+	foundOne = replace_match(haystack, needle, newNeedle, ignoreCase);
+	if (foundOne==TRUE && printFlag==TRUE) {
+	    fprintf(stdout, haystack);
+	}
+	if (quietFlag==FALSE) {
+	    fprintf(stdout, haystack);
+	}
+    }
+}
 
 extern int sed_main (int argc, char **argv)
 {
@@ -56,11 +70,9 @@
     char *name;
     char *cp;
     int ignoreCase=FALSE;
-    int foundOne=FALSE;
     int printFlag=FALSE;
     int quietFlag=FALSE;
     int stopNow;
-    char *haystack;
 
     argc--;
     argv++;
@@ -73,24 +85,23 @@
 	cp = *argv++;
 	stopNow=FALSE;
 
-	while (*++cp && stopNow==FALSE)
+	while (*++cp && stopNow==FALSE) {
 	    switch (*cp) {
 	    case 'n':
 		quietFlag = TRUE;
 		break;
 	    case 'e':
 		if (*(cp+1)==0 && --argc < 0) {
-		    fprintf(stderr, "A\n");
 		    usage( sed_usage);
 		}
-		cp = *argv++;
+		if ( *++cp != 's')
+		    cp = *argv++;
 		while( *cp ) {
 		    if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') {
 			char* pos=needle=cp+2;
 			for(;;) {
 			    pos = strchr(pos, '/');
 			    if (pos==NULL) {
-				fprintf(stderr, "B\n");
 				usage( sed_usage);
 			    }
 			    if (*(pos-1) == '\\') {
@@ -104,7 +115,6 @@
 			for(;;) {
 			    pos = strchr(pos, '/');
 			    if (pos==NULL) {
-				fprintf(stderr, "C\n");
 				usage( sed_usage);
 			    }
 			    if (*(pos-1) == '\\') {
@@ -116,7 +126,6 @@
 			*pos=0;
 			if (pos+2 != 0) {
 			    while (*++pos) {
-				fprintf(stderr, "pos='%s'\n", pos);
 				switch (*pos) {
 				    case 'i':
 					ignoreCase=TRUE;
@@ -134,42 +143,35 @@
 		    }
 		    cp++;
 		}
-		fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle);
+		//fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle);
 		stopNow=TRUE;
 		break;
 
 	    default:
-		fprintf(stderr, "D\n");
 		usage(sed_usage);
 	    }
+	}
     }
 
-    while (argc-- > 0) {
-	name = *argv++;
+    if (argc==0) {
+	do_sed( stdin, needle, newNeedle, ignoreCase, printFlag, quietFlag);
+    } else {
+	while (argc-- > 0) {
+	    name = *argv++;
 
-	fp = fopen (name, "r");
-	if (fp == NULL) {
-	    perror (name);
-	    continue;
+	    fp = fopen (name, "r");
+	    if (fp == NULL) {
+		perror (name);
+		continue;
+	    }
+
+	    do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag);
+
+	    if (ferror (fp))
+		perror (name);
+
+	    fclose (fp);
 	}
-
-	haystack = (char*)malloc( 1024);
-	while (fgets (haystack, 1023, fp)) {
-
-	    foundOne = replace_match(haystack, needle, newNeedle, ignoreCase);
-	    if (foundOne==TRUE && printFlag==TRUE)
-		    fputs (haystack, stdout);
-	    if (quietFlag==FALSE)
-		fputs (haystack, stdout);
-	    /* Avoid any mem leaks */
-	    free(haystack);
-	    haystack = (char*)malloc( BUF_SIZE);
-	}
-
-	if (ferror (fp))
-	    perror (name);
-
-	fclose (fp);
     }
     exit( TRUE);
 }
diff --git a/tar.c b/tar.c
index cd255f8..9ad41be 100644
--- a/tar.c
+++ b/tar.c
@@ -35,6 +35,16 @@
 #include <signal.h>
 #include <time.h>
 
+/* Note that tar.c expects TRUE and FALSE to be defined
+ * exactly the opposite of how they are used everywhere else.
+ * Some time this should be integrated a bit better, but this
+ * does the job for now.
+ */
+#undef FALSE
+#undef TRUE
+#define FALSE ((int) 0)
+#define TRUE  ((int) 1)
+
 
 static const char tar_usage[] =
     "tar -[cxtvOf] [tarFileName] [FILE] ...\n"
@@ -169,10 +179,9 @@
     /* 
      * Parse the options.
      */
-    options = *argv++;
-    argc--;
-
     if (**argv == '-') {
+	options = (*argv++) + 1;
+	argc--;
 	for (; *options; options++) {
 	    switch (*options) {
 	    case 'f':
diff --git a/util-linux/more.c b/util-linux/more.c
index ea5e225..4693161 100644
--- a/util-linux/more.c
+++ b/util-linux/more.c
@@ -25,7 +25,9 @@
 
 
 /* Turning this off makes things a bit smaller (and less pretty) */
-#define BB_MORE_TERM
+#define BB_FEATURE_USE_TERMIOS
+/* Turning this off makes things a bit smaller (and less pretty) */
+#define BB_FEATURE_AUTOWIDTH
 
 
 
@@ -33,18 +35,16 @@
 #include <stdio.h>
 #include <fcntl.h>
 #include <signal.h>
-
+#include <sys/ioctl.h>
 
 static const char more_usage[] = "[file ...]";
 
-
 /* ED: sparc termios is broken: revert back to old termio handling. */
-#ifdef BB_MORE_TERM
+#ifdef BB_FEATURE_USE_TERMIOS
 
 #if #cpu(sparc)
 #      define USE_OLD_TERMIO
 #      include <termio.h>
-#      include <sys/ioctl.h>
 #      define termios termio
 #      define stty(fd,argp) ioctl(fd,TCSETAF,argp)
 #else
@@ -57,16 +57,35 @@
 
     void gotsig(int sig) { 
 	    stty(fileno(cin), &initial_settings);
+	    fprintf(stdout, "\n");
 	    exit( TRUE);
     }
 #endif
 
+
+
+#define TERMINAL_WIDTH	79	/* not 80 in case terminal has linefold bug */
+#define TERMINAL_HEIGHT	24
+
+
+#if defined BB_FEATURE_AUTOWIDTH && ! defined USE_OLD_TERMIO
+static int terminal_width = 0, terminal_height = 0;
+#else
+#define terminal_width	TERMINAL_WIDTH
+#define terminal_height	TERMINAL_HEIGHT
+#endif
+
+
+
 extern int more_main(int argc, char **argv)
 {
     int c, lines=0, input=0;
     int next_page=0;
     struct stat st;	
     FILE *file;
+#ifdef BB_FEATURE_AUTOWIDTH
+    struct winsize win;
+#endif
 
     argc--;
     argv++;
@@ -87,7 +106,7 @@
 	}
 	fstat(fileno(file), &st);
 
-#ifdef BB_MORE_TERM
+#ifdef BB_FEATURE_USE_TERMIOS
 	cin = fopen("/dev/tty", "r");
 	if (!cin)
 	    cin = fopen("/dev/console", "r");
@@ -100,12 +119,19 @@
 	new_settings.c_lflag &= ~ICANON;
 	new_settings.c_lflag &= ~ECHO;
 	stty(fileno(cin), &new_settings);
-	
+
+#ifdef BB_FEATURE_AUTOWIDTH	
+	ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
+	if (win.ws_row > 4) 
+	    terminal_height = win.ws_row - 2;
+	if (win.ws_col > 0) 
+	    terminal_width = win.ws_col - 1;
+#endif
+
 	(void) signal(SIGINT, gotsig);
 	(void) signal(SIGQUIT, gotsig);
 	(void) signal(SIGTERM, gotsig);
 
-
 #endif
 	while ((c = getc(file)) != EOF) {
 	    if ( next_page ) {
@@ -119,7 +145,7 @@
 			st.st_size);
 		}
 		len += fprintf(stdout, "%s",
-#ifdef BB_MORE_TERM
+#ifdef BB_FEATURE_USE_TERMIOS
 			""
 #else
 			"\n"
@@ -129,24 +155,31 @@
 		fflush(stdout);
 		input = getc( cin);
 
-#ifdef BB_MORE_TERM
+#ifdef BB_FEATURE_USE_TERMIOS
 		/* Erase the "More" message */
-		while(len-- > 0)
+		while(--len >= 0)
 		    putc('\b', stdout);
-		while(len++ < 79)
+		while(++len <= terminal_width)
 		    putc(' ', stdout);
-		while(len-- > 0)
+		while(--len >= 0)
 		    putc('\b', stdout);
 		fflush(stdout);
 #endif
 
 	    }
-	    if (input=='q')
-		goto end;
-	    if (input=='\n' &&  c == '\n' )
-		next_page = 1;
-	    if ( c == ' ' && ++lines == 24 )
-		next_page = 1;
+	    if (c == '\n' ) {
+		switch(input) {
+		    case 'q':
+			goto end;
+		    case '\n':
+			/* increment by just one line if we are at 
+			 * the end of this line*/
+			next_page = 1;
+			break;
+		}
+		if ( ++lines == terminal_height )
+		    next_page = 1;
+	    }
 	    putc(c, stdout);
 	}
 	fclose(file);
@@ -155,7 +188,7 @@
 	argv++;
     } while (--argc > 0);
 end:
-#ifdef BB_MORE_TERM
+#ifdef BB_FEATURE_USE_TERMIOS
     gotsig(0);
 #endif	
     exit(TRUE);
diff --git a/utility.c b/utility.c
index 97c597e..59ac361 100644
--- a/utility.c
+++ b/utility.c
@@ -415,8 +415,12 @@
 	return (FALSE);
     }
 
-    if ( (followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) )
-	return (TRUE);
+    if ( (followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) ) {
+	if (fileAction == NULL)
+	    return (TRUE);
+	else
+	    return (fileAction(fileName, &statbuf));
+    }
 
     if (recurse == FALSE) {
 	if (S_ISDIR(statbuf.st_mode)) {