Several fixes.
 -Erik
diff --git a/applets/busybox.c b/applets/busybox.c
index 7582647..ee745e7 100644
--- a/applets/busybox.c
+++ b/applets/busybox.c
@@ -4,10 +4,6 @@
 #include <string.h>
 #include <errno.h>
 
-#ifndef BB_INIT
-#undef BB_FEATURE_LINUXRC
-#endif
-
 static int been_there_done_that = 0;
 
 /* It has been alledged that doing such things can
diff --git a/applets/busybox.mkll b/applets/busybox.mkll
index fa1bff2..90f28e8 100755
--- a/applets/busybox.mkll
+++ b/applets/busybox.mkll
@@ -4,7 +4,8 @@
 DF="busybox.def.h"
 MF="busybox.c"
 
-LIST="$(sed -n '/^#define/{s/^#define BB_FEATURE_.*//g;s/^#define //p;}' $DF)"
+#LIST="$(sed -n '/^#define/{s/^#define BB_FEATURE_.*//g;s/^#define //p;}' $DF)"
+LIST="$(cpp $DF -dM | sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*\<BB_\(.*\)\>/\1/gp;' | sort)"
 
 for def in ${LIST}; do
 	i=`sed -n '/^#ifdef \<'$def'\>.*/,/^#endif/{ s/.*\"\(.*\)\".*\(_BB_DIR_[A-Z_]*\).*$/\2\/\1/gp; }' $MF`
diff --git a/applets/busybox.sh b/applets/busybox.sh
index 304ac87..c4e241f 100755
--- a/applets/busybox.sh
+++ b/applets/busybox.sh
@@ -1,3 +1,10 @@
 #!/bin/sh
-sed -n -e 's/^#define.*BB_FEATURE.*$//g;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;' \
-    -e '/^#define/{s/.*bb_//;s/$/.o/p;}' busybox.def.h
+
+# I added in the extra "ls" so only source files that
+# actually exist will show up in the compile list.
+ls -1 ` \
+    cpp busybox.def.h -dM | \
+    sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*\<BB_\(.*\)\>/\1.c/gp;' \
+    | tr [:upper:] [:lower:] | sort
+` 2>/dev/null | sed -e 's/\.c$/\.o/g'
+
diff --git a/busybox.c b/busybox.c
index 7582647..ee745e7 100644
--- a/busybox.c
+++ b/busybox.c
@@ -4,10 +4,6 @@
 #include <string.h>
 #include <errno.h>
 
-#ifndef BB_INIT
-#undef BB_FEATURE_LINUXRC
-#endif
-
 static int been_there_done_that = 0;
 
 /* It has been alledged that doing such things can
diff --git a/busybox.def.h b/busybox.def.h
index d78a0ef..cfafc29 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -40,6 +40,7 @@
 // Don't bother turning BB_INSMOD on.  It doesn't work.
 //#define BB_INSMOD
 #define BB_KILL
+#define BB_KILLALL
 #define BB_KLOGD
 //#define BB_LENGTH
 #define BB_LN
@@ -198,11 +199,23 @@
 #define BB_MTAB
 #endif
 //
-#ifdef BB_FEATURE_FULL_REGULAR_EXPRESSIONS
+#if defined BB_FEATURE_FULL_REGULAR_EXPRESSIONS && (defined BB_SED || defined BB_GREP )
 #define BB_REGEXP
 #endif
 //
-#ifdef BB_FEATURE_SH_COMMAND_EDITING
+#if defined BB_FEATURE_SH_COMMAND_EDITING && defined BB_SH
 #define BB_CMDEDIT
 #endif
 //
+#ifdef BB_KILLALL
+#ifndef BB_KILL
+#define BB_KILL
+#endif
+#endif
+//
+#ifdef BB_FEATURE_LINUXRC
+#ifndef BB_INIT
+#define BB_INIT
+#endif
+#endif
+//
diff --git a/busybox.mkll b/busybox.mkll
index fa1bff2..90f28e8 100755
--- a/busybox.mkll
+++ b/busybox.mkll
@@ -4,7 +4,8 @@
 DF="busybox.def.h"
 MF="busybox.c"
 
-LIST="$(sed -n '/^#define/{s/^#define BB_FEATURE_.*//g;s/^#define //p;}' $DF)"
+#LIST="$(sed -n '/^#define/{s/^#define BB_FEATURE_.*//g;s/^#define //p;}' $DF)"
+LIST="$(cpp $DF -dM | sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*\<BB_\(.*\)\>/\1/gp;' | sort)"
 
 for def in ${LIST}; do
 	i=`sed -n '/^#ifdef \<'$def'\>.*/,/^#endif/{ s/.*\"\(.*\)\".*\(_BB_DIR_[A-Z_]*\).*$/\2\/\1/gp; }' $MF`
diff --git a/busybox.sh b/busybox.sh
index 304ac87..c4e241f 100755
--- a/busybox.sh
+++ b/busybox.sh
@@ -1,3 +1,10 @@
 #!/bin/sh
-sed -n -e 's/^#define.*BB_FEATURE.*$//g;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;' \
-    -e '/^#define/{s/.*bb_//;s/$/.o/p;}' busybox.def.h
+
+# I added in the extra "ls" so only source files that
+# actually exist will show up in the compile list.
+ls -1 ` \
+    cpp busybox.def.h -dM | \
+    sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*\<BB_\(.*\)\>/\1.c/gp;' \
+    | tr [:upper:] [:lower:] | sort
+` 2>/dev/null | sed -e 's/\.c$/\.o/g'
+
diff --git a/cmdedit.c b/cmdedit.c
index d1604f1..314e8cd 100644
--- a/cmdedit.c
+++ b/cmdedit.c
@@ -47,6 +47,8 @@
 
 #define ESC	27
 #define DEL	127
+#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
+#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
 
 static struct history *his_front = NULL;	/* First element in command line list */
 static struct history *his_end = NULL;	/* Last element in command line list */
@@ -104,7 +106,7 @@
 	xioctl(fileno(stdin), TCSETA, (void *) &old_term);
 }
 
-void gotaSignal(int sig)
+void prepareToDie(int sig)
 {
     cmdedit_reset_term();
     fprintf(stdout, "\n");
@@ -175,6 +177,40 @@
     }
 }
 
+char **username_completion_matches( char* matchBuf)
+{
+    fprintf(stderr, "\nin username_completion_matches\n");
+    return ( (char**) NULL);
+}
+char **command_completion_matches( char* matchBuf)
+{
+    fprintf(stderr, "\nin command_completion_matches\n");
+    return ( (char**) NULL);
+}
+char **directory_completion_matches( char* matchBuf)
+{
+    fprintf(stderr, "\nin directory_completion_matches\n");
+    return ( (char**) NULL);
+}
+
+/*
+ * This function is used to grab a character buffer
+ * from the input file descriptor and allows you to
+ * a string with full command editing (sortof like
+ * a mini readline).
+ *
+ * The following standard commands are not implemented:
+ * ESC-b -- Move back one word
+ * ESC-f -- Move forward one word
+ * ESC-d -- Delete back one word
+ * ESC-h -- Delete forward one word
+ * CTL-t -- Transpose two characters
+ *
+ * Furthermore, the "vi" command editing keys are not implemented.
+ *
+ * TODO: implement TAB command completion. :)
+ *
+ */
 extern int cmdedit_read_input(int inputFd, int outputFd,
 			    char command[BUFSIZ])
 {
@@ -185,6 +221,8 @@
     int cursor = 0;
     int break_out = 0;
     int ret = 0;
+    int lastWasTab = FALSE;
+    char **matches = (char **)NULL;
     char c = 0;
     struct history *hp = his_end;
 
@@ -209,90 +247,233 @@
 
 	if ((ret = read(inputFd, &c, 1)) < 1)
 	    return ret;
-
+	
 	switch (c) {
-	case 1:		/* Control-A Beginning of line */
+	case 1:		
+	    /* Control-a -- Beginning of line */
 	    input_home(outputFd, &cursor);
-	    break;
-	case 5:		/* Control-E EOL */
+	case 5:		
+	    /* Control-e -- End of line */
 	    input_end(outputFd, &cursor, len);
 	    break;
-	case 4:		/* Control-D */
+	case 2:
+	    /* Control-b -- Move back one character */
+	    if (cursor > 0) {
+		xwrite(outputFd, "\033[D", 3);
+		cursor--;
+	    }
+	    break;
+	case 6:	
+	    /* Control-f -- Move forward one character */
+	    if (cursor < len) {
+		xwrite(outputFd, "\033[C", 3);
+		cursor++;
+	    }
+	    break;
+	case 4:
+	    /* Control-d -- Delete one character */
 	    if (cursor != len) {
 		input_delete(outputFd, cursor);
 		len--;
+	    } else if (len == 0) {
+		prepareToDie(0);
+		exit(0);
 	    }
 	    break;
-	case '\b':		/* Backspace */
+	case 14:
+	    /* Control-n -- Get next command */
+	    if (hp && hp->n && hp->n->s) {	
+		free( hp->s);
+		hp->s = strdup(parsenextc);
+		hp = hp->n;
+		goto hop;
+	    }
+	    break;
+	case 16:
+	    /* Control-p -- Get previous command */
+	    if (hp && hp->p) {	
+		free( hp->s);
+		hp->s = strdup(parsenextc);
+		hp = hp->p;
+		goto hop;
+	    }
+	    break;
+	case '\t':
+	    {
+	    /* Do TAB completion */
+		int in_command_position=0, ti=len-1;
+
+		if (lastWasTab == FALSE) {
+		    char *tmp;
+		    char *matchBuf;
+
+		    if (matches) {
+			free(matches);
+			matches = (char **)NULL;
+		    }
+
+		    matchBuf = (char *) calloc(BUFSIZ, sizeof(char));
+
+		    /* Make a local copy of the string -- up 
+		     * to the the position of the cursor */
+		    strcpy( matchBuf, parsenextc); 
+		    matchBuf[cursor+1] = '\0';
+
+		    /* skip leading white space */
+		    tmp = matchBuf;
+		    while (*tmp && isspace(*tmp)) {
+			(tmp)++;
+			ti++;
+		    }
+
+		    /* Determine if this is a command word or not */
+		    //while ((ti > -1) && (whitespace (matchBuf[ti]))) {
+//printf("\nti=%d\n", ti);
+		//	ti--;
+		 //   }
+printf("\nti=%d\n", ti);
+
+		    if (ti < 0) {
+			  in_command_position++;
+		    } else if (member(matchBuf[ti], ";|&{(`")) {
+			int this_char, prev_char;
+			in_command_position++;
+			/* Handle the two character tokens `>&', `<&', and `>|'.
+			 We are not in a command position after one of these. */
+			this_char = matchBuf[ti];
+			prev_char = matchBuf[ti - 1];
+
+			if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
+				(this_char == '|' && prev_char == '>')) {
+			    in_command_position = 0;
+			} 
+			/* For now, do not bother with catching quoted
+			 * expressions and marking them as not in command
+			 * positions.  Some other day.  Or not.
+			 */
+			//else if (char_is_quoted (matchBuf, ti)) {
+			//    in_command_position = 0;
+			//}
+		    }
+printf("\nin_command_position=%d\n", in_command_position);
+		    /* If the word starts in `~', and there is no slash in the word, 
+		     * then try completing this word as a username. */
+		    if (*matchBuf == '~' && !strchr (matchBuf, '/'))
+			matches = username_completion_matches(matchBuf);
+
+		    /* If this word is in a command position, then complete over possible 
+		     * command names, including aliases, built-ins, and executables. */
+		    if (!matches && in_command_position) {
+			matches = command_completion_matches(matchBuf);
+
+		    /* If we are attempting command completion and nothing matches, 
+		     * then try and match directories as a last resort... */
+		    if (!matches)
+			matches = directory_completion_matches(matchBuf);
+		    }
+		} else {
+		    printf("\nprinting match list\n");
+		}
+		/* Rewrite the whole line (for debugging) */
+		for (; cursor > 0; cursor--)	
+		    xwrite(outputFd, "\b", 1);
+		len = strlen(parsenextc);
+		xwrite(outputFd, parsenextc, len);
+		cursor = len;
+		break;
+	    }
+	case '\b':		
 	case DEL:
+	    /* Backspace */
 	    input_backspace(outputFd, &cursor, &len);
 	    break;
-	case '\n':		/* Enter */
+	case '\n':		
+	    /* Enter */
 	    *(parsenextc + len++ + 1) = c;
 	    xwrite(outputFd, &c, 1);
 	    break_out = 1;
 	    break;
-	case ESC:		/* escape sequence follows */
+	case ESC:		{
+	    /* escape sequence follows */
 	    if ((ret = read(inputFd, &c, 1)) < 1)
 		return ret;
 
 	    if (c == '[') {	/* 91 */
 		if ((ret = read(inputFd, &c, 1)) < 1)
 		    return ret;
-
+		
 		switch (c) {
 		case 'A':
-		    if (hp && hp->p) {	/* Up */
+		    /* Up Arrow -- Get previous command */
+		    if (hp && hp->p) {	
+			free( hp->s);
+			hp->s = strdup(parsenextc);
 			hp = hp->p;
 			goto hop;
 		    }
 		    break;
 		case 'B':
-		    if (hp && hp->n && hp->n->s) {	/* Down */
+		    /* Down Arrow -- Get next command */
+		    if (hp && hp->n && hp->n->s) {	
+			free( hp->s);
+			hp->s = strdup(parsenextc);
 			hp = hp->n;
 			goto hop;
 		    }
 		    break;
 
-		  hop:		/* hop */
+		    /* This is where we rewrite the line 
+		     * using the selected history item */
+		  hop:		
 		    len = strlen(parsenextc);
 
-		    for (; cursor > 0; cursor--)	/* return to begining of line */
+		    /* return to begining of line */
+		    for (; cursor > 0; cursor--)	
 			xwrite(outputFd, "\b", 1);
+		    xwrite(outputFd, parsenextc, len);
 
-		    for (j = 0; j < len; j++)	/* erase old command */
+		    /* erase old command */
+		    for (j = 0; j < len; j++)	
 			xwrite(outputFd, " ", 1);
 
-		    for (j = len; j > 0; j--)	/* return to begining of line */
+		    /* return to begining of line */
+		    for (j = len; j > 0; j--)	
 			xwrite(outputFd, "\b", 1);
 
-		    strcpy(parsenextc, hp->s);	/* write new command */
+		    memset(parsenextc, 0, BUFSIZ);
+		    /* write new command */
+		    strcpy(parsenextc, hp->s);	
 		    len = strlen(hp->s);
 		    xwrite(outputFd, parsenextc, len);
 		    cursor = len;
 		    break;
-		case 'C':	/* Right */
+		case 'C':	
+		    /* Right Arrow -- Move forward one character */
 		    if (cursor < len) {
 			xwrite(outputFd, "\033[C", 3);
 			cursor++;
 		    }
 		    break;
-		case 'D':	/* Left */
+		case 'D':	
+		    /* Left Arrow -- Move back one character */
 		    if (cursor > 0) {
 			xwrite(outputFd, "\033[D", 3);
 			cursor--;
 		    }
 		    break;
-		case '3':	/* Delete */
+		case '3':	
+		    /* Delete */
 		    if (cursor != len) {
 			input_delete(outputFd, cursor);
 			len--;
 		    }
 		    break;
-		case '1':	/* Home (Ctrl-A) */
+		case '1':	
+		    /* Home (Ctrl-A) */
 		    input_home(outputFd, &cursor);
 		    break;
-		case '4':	/* End (Ctrl-E) */
+		case '4':	
+		    /* End (Ctrl-E) */
 		    input_end(outputFd, &cursor, len);
 		    break;
 		}
@@ -300,20 +481,24 @@
 		    if ((ret = read(inputFd, &c, 1)) < 1)
 			return ret;	/* read 126 (~) */
 	    }
-	    if (c == 'O') {	/* 79 */
+	    if (c == 'O') {	
+		/* 79 */
 		if ((ret = read(inputFd, &c, 1)) < 1)
 		    return ret;
 		switch (c) {
-		case 'H':	/* Home (xterm) */
+		case 'H':	
+		    /* Home (xterm) */
 		    input_home(outputFd, &cursor);
 		    break;
-		case 'F':	/* End (xterm) */
+		case 'F':	
+		    /* End (xterm) */
 		    input_end(outputFd, &cursor, len);
 		    break;
 		}
 	    }
 	    c = 0;
 	    break;
+	}
 
 	default:		/* If it's regular input, do the normal thing */
 
@@ -343,6 +528,10 @@
 	    xwrite(outputFd, &c, 1);
 	    break;
 	}
+	if (c=='\t')
+	    lastWasTab = TRUE;
+	else
+	    lastWasTab = FALSE;
 
 	if (break_out)		/* Enter is the command terminator, no more input. */
 	    break;
@@ -353,32 +542,33 @@
     reset_term = 0;
 
 
-    if (*(parsenextc)) {	/* Handle command history log */
+    /* Handle command history log */
+    if (*(parsenextc)) {	
 
 	struct history *h = his_end;
 
-	if (!h) {		/* No previous history */
+	if (!h) {		
+	    /* No previous history */
 	    h = his_front = malloc(sizeof(struct history));
 	    h->n = malloc(sizeof(struct history));
 	    h->p = NULL;
 	    h->s = strdup(parsenextc);
-
 	    h->n->p = h;
 	    h->n->n = NULL;
 	    h->n->s = NULL;
 	    his_end = h->n;
 	    history_counter++;
-	} else {		/* Add a new history command */
-
+	} else {		
+	    /* Add a new history command */
 	    h->n = malloc(sizeof(struct history));
-
 	    h->n->p = h;
 	    h->n->n = NULL;
 	    h->n->s = NULL;
 	    h->s = strdup(parsenextc);
 	    his_end = h->n;
 
-	    if (history_counter >= MAX_HISTORY) {	/* After max history, remove the last known command */
+	    /* After max history, remove the oldest command */
+	    if (history_counter >= MAX_HISTORY) {	
 
 		struct history *p = his_front->n;
 
@@ -398,8 +588,8 @@
 extern void cmdedit_init(void)
 {
     atexit(cmdedit_reset_term);
-    signal(SIGINT, gotaSignal);
-    signal(SIGQUIT, gotaSignal);
-    signal(SIGTERM, gotaSignal);
+    signal(SIGINT, prepareToDie);
+    signal(SIGQUIT, prepareToDie);
+    signal(SIGTERM, prepareToDie);
 }
 #endif				/* BB_FEATURE_SH_COMMAND_EDITING */
diff --git a/kill.c b/kill.c
index 8a99e0f..10343a1 100644
--- a/kill.c
+++ b/kill.c
@@ -36,11 +36,12 @@
 	"Send a signal (default is SIGTERM) to the specified process(es).\n\n"
 	"Options:\n" "\t-l\tList all signal names and numbers.\n\n";
 
+#ifdef BB_KILLALL
 static const char *killall_usage =
 	"killall [-signal] process-name [process-name ...]\n\n"
 	"Send a signal (default is SIGTERM) to the specified process(es).\n\n"
 	"Options:\n" "\t-l\tList all signal names and numbers.\n\n";
-
+#endif
 
 #define KILL	0
 #define KILLALL	1
@@ -132,10 +133,15 @@
 	int whichApp, sig = SIGTERM;
 	const char *appUsage;
 
+#ifdef BB_KILLALL
 	/* Figure out what we are trying to do here */
 	whichApp = (strcmp(*argv, "killall") == 0)? 
 		KILLALL : KILL; 
 	appUsage = (whichApp == KILLALL)?  killall_usage : kill_usage;
+#else
+	whichApp = KILL;
+	appUsage = kill_usage;
+#endif
 
 	argc--;
 	argv++;
@@ -213,7 +219,9 @@
 				fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
 			argv++;
 		}
-	} else {
+	} 
+#ifdef BB_KILLALL
+	else {
 		/* Looks like they want to do a killall.  Do that */
 		while (--argc >= 0) {
 			int pid;
@@ -225,6 +233,7 @@
 			argv++;
 		}
 	}
+#endif
 
 	exit(TRUE);
 
diff --git a/lash.c b/lash.c
index e143cfe..0681596 100644
--- a/lash.c
+++ b/lash.c
@@ -98,7 +98,7 @@
 static int shell_help(struct job *cmd, struct jobSet *junk);
 static int shell_jobs(struct job *dummy, struct jobSet *jobList);
 static int shell_pwd(struct job *dummy, struct jobSet *junk);
-static int shell_set(struct job *cmd, struct jobSet *junk);
+static int shell_export(struct job *cmd, struct jobSet *junk);
 static int shell_source(struct job *cmd, struct jobSet *jobList);
 static int shell_unset(struct job *cmd, struct jobSet *junk);
 
@@ -120,7 +120,7 @@
 	{"fg", "Bring job into the foreground", "fg [%%job]", shell_fg_bg},
 	{"jobs", "Lists the active jobs", "jobs", shell_jobs},
 	{"pwd", "Print current directory", "pwd", shell_pwd},
-	{"set", "Set environment variable", "set [VAR=value]", shell_set},
+	{"export", "Set environment variable", "export [VAR=value]", shell_export},
 	{"unset", "Unset environment variable", "unset VAR", shell_unset},
 	
 		{".", "Source-in and run commands in a file", ". filename",
@@ -182,7 +182,7 @@
 static int shell_fg_bg(struct job *cmd, struct jobSet *jobList)
 {
 	int i, jobNum;
-	struct job *job;
+	struct job *job=NULL;
 
 	if (!jobList->head) {
 		if (!cmd->progs[0].argv[1] || cmd->progs[0].argv[2]) {
@@ -268,8 +268,8 @@
 	return TRUE;
 }
 
-/* built-in 'set VAR=value' handler */
-static int shell_set(struct job *cmd, struct jobSet *junk)
+/* built-in 'export VAR=value' handler */
+static int shell_export(struct job *cmd, struct jobSet *junk)
 {
 	int res;
 
@@ -278,7 +278,7 @@
 	}
 	res = putenv(cmd->progs[0].argv[1]);
 	if (res)
-		fprintf(stdout, "set: %s\n", strerror(errno));
+		fprintf(stdout, "export: %s\n", strerror(errno));
 	return (res);
 }
 
diff --git a/procps/kill.c b/procps/kill.c
index 8a99e0f..10343a1 100644
--- a/procps/kill.c
+++ b/procps/kill.c
@@ -36,11 +36,12 @@
 	"Send a signal (default is SIGTERM) to the specified process(es).\n\n"
 	"Options:\n" "\t-l\tList all signal names and numbers.\n\n";
 
+#ifdef BB_KILLALL
 static const char *killall_usage =
 	"killall [-signal] process-name [process-name ...]\n\n"
 	"Send a signal (default is SIGTERM) to the specified process(es).\n\n"
 	"Options:\n" "\t-l\tList all signal names and numbers.\n\n";
-
+#endif
 
 #define KILL	0
 #define KILLALL	1
@@ -132,10 +133,15 @@
 	int whichApp, sig = SIGTERM;
 	const char *appUsage;
 
+#ifdef BB_KILLALL
 	/* Figure out what we are trying to do here */
 	whichApp = (strcmp(*argv, "killall") == 0)? 
 		KILLALL : KILL; 
 	appUsage = (whichApp == KILLALL)?  killall_usage : kill_usage;
+#else
+	whichApp = KILL;
+	appUsage = kill_usage;
+#endif
 
 	argc--;
 	argv++;
@@ -213,7 +219,9 @@
 				fatalError( "Could not kill pid '%d': %s\n", pid, strerror(errno));
 			argv++;
 		}
-	} else {
+	} 
+#ifdef BB_KILLALL
+	else {
 		/* Looks like they want to do a killall.  Do that */
 		while (--argc >= 0) {
 			int pid;
@@ -225,6 +233,7 @@
 			argv++;
 		}
 	}
+#endif
 
 	exit(TRUE);
 
diff --git a/sh.c b/sh.c
index e143cfe..0681596 100644
--- a/sh.c
+++ b/sh.c
@@ -98,7 +98,7 @@
 static int shell_help(struct job *cmd, struct jobSet *junk);
 static int shell_jobs(struct job *dummy, struct jobSet *jobList);
 static int shell_pwd(struct job *dummy, struct jobSet *junk);
-static int shell_set(struct job *cmd, struct jobSet *junk);
+static int shell_export(struct job *cmd, struct jobSet *junk);
 static int shell_source(struct job *cmd, struct jobSet *jobList);
 static int shell_unset(struct job *cmd, struct jobSet *junk);
 
@@ -120,7 +120,7 @@
 	{"fg", "Bring job into the foreground", "fg [%%job]", shell_fg_bg},
 	{"jobs", "Lists the active jobs", "jobs", shell_jobs},
 	{"pwd", "Print current directory", "pwd", shell_pwd},
-	{"set", "Set environment variable", "set [VAR=value]", shell_set},
+	{"export", "Set environment variable", "export [VAR=value]", shell_export},
 	{"unset", "Unset environment variable", "unset VAR", shell_unset},
 	
 		{".", "Source-in and run commands in a file", ". filename",
@@ -182,7 +182,7 @@
 static int shell_fg_bg(struct job *cmd, struct jobSet *jobList)
 {
 	int i, jobNum;
-	struct job *job;
+	struct job *job=NULL;
 
 	if (!jobList->head) {
 		if (!cmd->progs[0].argv[1] || cmd->progs[0].argv[2]) {
@@ -268,8 +268,8 @@
 	return TRUE;
 }
 
-/* built-in 'set VAR=value' handler */
-static int shell_set(struct job *cmd, struct jobSet *junk)
+/* built-in 'export VAR=value' handler */
+static int shell_export(struct job *cmd, struct jobSet *junk)
 {
 	int res;
 
@@ -278,7 +278,7 @@
 	}
 	res = putenv(cmd->progs[0].argv[1]);
 	if (res)
-		fprintf(stdout, "set: %s\n", strerror(errno));
+		fprintf(stdout, "export: %s\n", strerror(errno));
 	return (res);
 }
 
diff --git a/shell/cmdedit.c b/shell/cmdedit.c
index d1604f1..314e8cd 100644
--- a/shell/cmdedit.c
+++ b/shell/cmdedit.c
@@ -47,6 +47,8 @@
 
 #define ESC	27
 #define DEL	127
+#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
+#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
 
 static struct history *his_front = NULL;	/* First element in command line list */
 static struct history *his_end = NULL;	/* Last element in command line list */
@@ -104,7 +106,7 @@
 	xioctl(fileno(stdin), TCSETA, (void *) &old_term);
 }
 
-void gotaSignal(int sig)
+void prepareToDie(int sig)
 {
     cmdedit_reset_term();
     fprintf(stdout, "\n");
@@ -175,6 +177,40 @@
     }
 }
 
+char **username_completion_matches( char* matchBuf)
+{
+    fprintf(stderr, "\nin username_completion_matches\n");
+    return ( (char**) NULL);
+}
+char **command_completion_matches( char* matchBuf)
+{
+    fprintf(stderr, "\nin command_completion_matches\n");
+    return ( (char**) NULL);
+}
+char **directory_completion_matches( char* matchBuf)
+{
+    fprintf(stderr, "\nin directory_completion_matches\n");
+    return ( (char**) NULL);
+}
+
+/*
+ * This function is used to grab a character buffer
+ * from the input file descriptor and allows you to
+ * a string with full command editing (sortof like
+ * a mini readline).
+ *
+ * The following standard commands are not implemented:
+ * ESC-b -- Move back one word
+ * ESC-f -- Move forward one word
+ * ESC-d -- Delete back one word
+ * ESC-h -- Delete forward one word
+ * CTL-t -- Transpose two characters
+ *
+ * Furthermore, the "vi" command editing keys are not implemented.
+ *
+ * TODO: implement TAB command completion. :)
+ *
+ */
 extern int cmdedit_read_input(int inputFd, int outputFd,
 			    char command[BUFSIZ])
 {
@@ -185,6 +221,8 @@
     int cursor = 0;
     int break_out = 0;
     int ret = 0;
+    int lastWasTab = FALSE;
+    char **matches = (char **)NULL;
     char c = 0;
     struct history *hp = his_end;
 
@@ -209,90 +247,233 @@
 
 	if ((ret = read(inputFd, &c, 1)) < 1)
 	    return ret;
-
+	
 	switch (c) {
-	case 1:		/* Control-A Beginning of line */
+	case 1:		
+	    /* Control-a -- Beginning of line */
 	    input_home(outputFd, &cursor);
-	    break;
-	case 5:		/* Control-E EOL */
+	case 5:		
+	    /* Control-e -- End of line */
 	    input_end(outputFd, &cursor, len);
 	    break;
-	case 4:		/* Control-D */
+	case 2:
+	    /* Control-b -- Move back one character */
+	    if (cursor > 0) {
+		xwrite(outputFd, "\033[D", 3);
+		cursor--;
+	    }
+	    break;
+	case 6:	
+	    /* Control-f -- Move forward one character */
+	    if (cursor < len) {
+		xwrite(outputFd, "\033[C", 3);
+		cursor++;
+	    }
+	    break;
+	case 4:
+	    /* Control-d -- Delete one character */
 	    if (cursor != len) {
 		input_delete(outputFd, cursor);
 		len--;
+	    } else if (len == 0) {
+		prepareToDie(0);
+		exit(0);
 	    }
 	    break;
-	case '\b':		/* Backspace */
+	case 14:
+	    /* Control-n -- Get next command */
+	    if (hp && hp->n && hp->n->s) {	
+		free( hp->s);
+		hp->s = strdup(parsenextc);
+		hp = hp->n;
+		goto hop;
+	    }
+	    break;
+	case 16:
+	    /* Control-p -- Get previous command */
+	    if (hp && hp->p) {	
+		free( hp->s);
+		hp->s = strdup(parsenextc);
+		hp = hp->p;
+		goto hop;
+	    }
+	    break;
+	case '\t':
+	    {
+	    /* Do TAB completion */
+		int in_command_position=0, ti=len-1;
+
+		if (lastWasTab == FALSE) {
+		    char *tmp;
+		    char *matchBuf;
+
+		    if (matches) {
+			free(matches);
+			matches = (char **)NULL;
+		    }
+
+		    matchBuf = (char *) calloc(BUFSIZ, sizeof(char));
+
+		    /* Make a local copy of the string -- up 
+		     * to the the position of the cursor */
+		    strcpy( matchBuf, parsenextc); 
+		    matchBuf[cursor+1] = '\0';
+
+		    /* skip leading white space */
+		    tmp = matchBuf;
+		    while (*tmp && isspace(*tmp)) {
+			(tmp)++;
+			ti++;
+		    }
+
+		    /* Determine if this is a command word or not */
+		    //while ((ti > -1) && (whitespace (matchBuf[ti]))) {
+//printf("\nti=%d\n", ti);
+		//	ti--;
+		 //   }
+printf("\nti=%d\n", ti);
+
+		    if (ti < 0) {
+			  in_command_position++;
+		    } else if (member(matchBuf[ti], ";|&{(`")) {
+			int this_char, prev_char;
+			in_command_position++;
+			/* Handle the two character tokens `>&', `<&', and `>|'.
+			 We are not in a command position after one of these. */
+			this_char = matchBuf[ti];
+			prev_char = matchBuf[ti - 1];
+
+			if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) ||
+				(this_char == '|' && prev_char == '>')) {
+			    in_command_position = 0;
+			} 
+			/* For now, do not bother with catching quoted
+			 * expressions and marking them as not in command
+			 * positions.  Some other day.  Or not.
+			 */
+			//else if (char_is_quoted (matchBuf, ti)) {
+			//    in_command_position = 0;
+			//}
+		    }
+printf("\nin_command_position=%d\n", in_command_position);
+		    /* If the word starts in `~', and there is no slash in the word, 
+		     * then try completing this word as a username. */
+		    if (*matchBuf == '~' && !strchr (matchBuf, '/'))
+			matches = username_completion_matches(matchBuf);
+
+		    /* If this word is in a command position, then complete over possible 
+		     * command names, including aliases, built-ins, and executables. */
+		    if (!matches && in_command_position) {
+			matches = command_completion_matches(matchBuf);
+
+		    /* If we are attempting command completion and nothing matches, 
+		     * then try and match directories as a last resort... */
+		    if (!matches)
+			matches = directory_completion_matches(matchBuf);
+		    }
+		} else {
+		    printf("\nprinting match list\n");
+		}
+		/* Rewrite the whole line (for debugging) */
+		for (; cursor > 0; cursor--)	
+		    xwrite(outputFd, "\b", 1);
+		len = strlen(parsenextc);
+		xwrite(outputFd, parsenextc, len);
+		cursor = len;
+		break;
+	    }
+	case '\b':		
 	case DEL:
+	    /* Backspace */
 	    input_backspace(outputFd, &cursor, &len);
 	    break;
-	case '\n':		/* Enter */
+	case '\n':		
+	    /* Enter */
 	    *(parsenextc + len++ + 1) = c;
 	    xwrite(outputFd, &c, 1);
 	    break_out = 1;
 	    break;
-	case ESC:		/* escape sequence follows */
+	case ESC:		{
+	    /* escape sequence follows */
 	    if ((ret = read(inputFd, &c, 1)) < 1)
 		return ret;
 
 	    if (c == '[') {	/* 91 */
 		if ((ret = read(inputFd, &c, 1)) < 1)
 		    return ret;
-
+		
 		switch (c) {
 		case 'A':
-		    if (hp && hp->p) {	/* Up */
+		    /* Up Arrow -- Get previous command */
+		    if (hp && hp->p) {	
+			free( hp->s);
+			hp->s = strdup(parsenextc);
 			hp = hp->p;
 			goto hop;
 		    }
 		    break;
 		case 'B':
-		    if (hp && hp->n && hp->n->s) {	/* Down */
+		    /* Down Arrow -- Get next command */
+		    if (hp && hp->n && hp->n->s) {	
+			free( hp->s);
+			hp->s = strdup(parsenextc);
 			hp = hp->n;
 			goto hop;
 		    }
 		    break;
 
-		  hop:		/* hop */
+		    /* This is where we rewrite the line 
+		     * using the selected history item */
+		  hop:		
 		    len = strlen(parsenextc);
 
-		    for (; cursor > 0; cursor--)	/* return to begining of line */
+		    /* return to begining of line */
+		    for (; cursor > 0; cursor--)	
 			xwrite(outputFd, "\b", 1);
+		    xwrite(outputFd, parsenextc, len);
 
-		    for (j = 0; j < len; j++)	/* erase old command */
+		    /* erase old command */
+		    for (j = 0; j < len; j++)	
 			xwrite(outputFd, " ", 1);
 
-		    for (j = len; j > 0; j--)	/* return to begining of line */
+		    /* return to begining of line */
+		    for (j = len; j > 0; j--)	
 			xwrite(outputFd, "\b", 1);
 
-		    strcpy(parsenextc, hp->s);	/* write new command */
+		    memset(parsenextc, 0, BUFSIZ);
+		    /* write new command */
+		    strcpy(parsenextc, hp->s);	
 		    len = strlen(hp->s);
 		    xwrite(outputFd, parsenextc, len);
 		    cursor = len;
 		    break;
-		case 'C':	/* Right */
+		case 'C':	
+		    /* Right Arrow -- Move forward one character */
 		    if (cursor < len) {
 			xwrite(outputFd, "\033[C", 3);
 			cursor++;
 		    }
 		    break;
-		case 'D':	/* Left */
+		case 'D':	
+		    /* Left Arrow -- Move back one character */
 		    if (cursor > 0) {
 			xwrite(outputFd, "\033[D", 3);
 			cursor--;
 		    }
 		    break;
-		case '3':	/* Delete */
+		case '3':	
+		    /* Delete */
 		    if (cursor != len) {
 			input_delete(outputFd, cursor);
 			len--;
 		    }
 		    break;
-		case '1':	/* Home (Ctrl-A) */
+		case '1':	
+		    /* Home (Ctrl-A) */
 		    input_home(outputFd, &cursor);
 		    break;
-		case '4':	/* End (Ctrl-E) */
+		case '4':	
+		    /* End (Ctrl-E) */
 		    input_end(outputFd, &cursor, len);
 		    break;
 		}
@@ -300,20 +481,24 @@
 		    if ((ret = read(inputFd, &c, 1)) < 1)
 			return ret;	/* read 126 (~) */
 	    }
-	    if (c == 'O') {	/* 79 */
+	    if (c == 'O') {	
+		/* 79 */
 		if ((ret = read(inputFd, &c, 1)) < 1)
 		    return ret;
 		switch (c) {
-		case 'H':	/* Home (xterm) */
+		case 'H':	
+		    /* Home (xterm) */
 		    input_home(outputFd, &cursor);
 		    break;
-		case 'F':	/* End (xterm) */
+		case 'F':	
+		    /* End (xterm) */
 		    input_end(outputFd, &cursor, len);
 		    break;
 		}
 	    }
 	    c = 0;
 	    break;
+	}
 
 	default:		/* If it's regular input, do the normal thing */
 
@@ -343,6 +528,10 @@
 	    xwrite(outputFd, &c, 1);
 	    break;
 	}
+	if (c=='\t')
+	    lastWasTab = TRUE;
+	else
+	    lastWasTab = FALSE;
 
 	if (break_out)		/* Enter is the command terminator, no more input. */
 	    break;
@@ -353,32 +542,33 @@
     reset_term = 0;
 
 
-    if (*(parsenextc)) {	/* Handle command history log */
+    /* Handle command history log */
+    if (*(parsenextc)) {	
 
 	struct history *h = his_end;
 
-	if (!h) {		/* No previous history */
+	if (!h) {		
+	    /* No previous history */
 	    h = his_front = malloc(sizeof(struct history));
 	    h->n = malloc(sizeof(struct history));
 	    h->p = NULL;
 	    h->s = strdup(parsenextc);
-
 	    h->n->p = h;
 	    h->n->n = NULL;
 	    h->n->s = NULL;
 	    his_end = h->n;
 	    history_counter++;
-	} else {		/* Add a new history command */
-
+	} else {		
+	    /* Add a new history command */
 	    h->n = malloc(sizeof(struct history));
-
 	    h->n->p = h;
 	    h->n->n = NULL;
 	    h->n->s = NULL;
 	    h->s = strdup(parsenextc);
 	    his_end = h->n;
 
-	    if (history_counter >= MAX_HISTORY) {	/* After max history, remove the last known command */
+	    /* After max history, remove the oldest command */
+	    if (history_counter >= MAX_HISTORY) {	
 
 		struct history *p = his_front->n;
 
@@ -398,8 +588,8 @@
 extern void cmdedit_init(void)
 {
     atexit(cmdedit_reset_term);
-    signal(SIGINT, gotaSignal);
-    signal(SIGQUIT, gotaSignal);
-    signal(SIGTERM, gotaSignal);
+    signal(SIGINT, prepareToDie);
+    signal(SIGQUIT, prepareToDie);
+    signal(SIGTERM, prepareToDie);
 }
 #endif				/* BB_FEATURE_SH_COMMAND_EDITING */
diff --git a/shell/lash.c b/shell/lash.c
index e143cfe..0681596 100644
--- a/shell/lash.c
+++ b/shell/lash.c
@@ -98,7 +98,7 @@
 static int shell_help(struct job *cmd, struct jobSet *junk);
 static int shell_jobs(struct job *dummy, struct jobSet *jobList);
 static int shell_pwd(struct job *dummy, struct jobSet *junk);
-static int shell_set(struct job *cmd, struct jobSet *junk);
+static int shell_export(struct job *cmd, struct jobSet *junk);
 static int shell_source(struct job *cmd, struct jobSet *jobList);
 static int shell_unset(struct job *cmd, struct jobSet *junk);
 
@@ -120,7 +120,7 @@
 	{"fg", "Bring job into the foreground", "fg [%%job]", shell_fg_bg},
 	{"jobs", "Lists the active jobs", "jobs", shell_jobs},
 	{"pwd", "Print current directory", "pwd", shell_pwd},
-	{"set", "Set environment variable", "set [VAR=value]", shell_set},
+	{"export", "Set environment variable", "export [VAR=value]", shell_export},
 	{"unset", "Unset environment variable", "unset VAR", shell_unset},
 	
 		{".", "Source-in and run commands in a file", ". filename",
@@ -182,7 +182,7 @@
 static int shell_fg_bg(struct job *cmd, struct jobSet *jobList)
 {
 	int i, jobNum;
-	struct job *job;
+	struct job *job=NULL;
 
 	if (!jobList->head) {
 		if (!cmd->progs[0].argv[1] || cmd->progs[0].argv[2]) {
@@ -268,8 +268,8 @@
 	return TRUE;
 }
 
-/* built-in 'set VAR=value' handler */
-static int shell_set(struct job *cmd, struct jobSet *junk)
+/* built-in 'export VAR=value' handler */
+static int shell_export(struct job *cmd, struct jobSet *junk)
 {
 	int res;
 
@@ -278,7 +278,7 @@
 	}
 	res = putenv(cmd->progs[0].argv[1]);
 	if (res)
-		fprintf(stdout, "set: %s\n", strerror(errno));
+		fprintf(stdout, "export: %s\n", strerror(errno));
 	return (res);
 }
 
diff --git a/utility.c b/utility.c
index 4b26a1b..c274bfa 100644
--- a/utility.c
+++ b/utility.c
@@ -1247,8 +1247,7 @@
 #endif							/* BB_INIT BB_SYSLOGD */
 
 
-#if defined BB_FEATURE_LINUXRC && ( defined BB_HALT || defined BB_REBOOT || defined BB_POWEROFF )
-
+#if defined BB_KILLALL || ( defined BB_FEATURE_LINUXRC && ( defined BB_HALT || defined BB_REBOOT || defined BB_POWEROFF ))
 #ifdef BB_FEATURE_USE_DEVPS_PATCH
 #include <linux/devps.h>
 #endif
@@ -1363,7 +1362,7 @@
 	return 0;
 }
 #endif							/* BB_FEATURE_USE_DEVPS_PATCH */
-#endif							/* BB_INIT || BB_HALT || BB_REBOOT || BB_POWEROFF */
+#endif							/* BB_KILLALL || ( BB_FEATURE_LINUXRC && ( BB_HALT || BB_REBOOT || BB_POWEROFF )) */
 
 #if defined BB_GUNZIP \
  || defined BB_GZIP   \