BusyBox shell (lash) can now be used as a standalone shell when
BB_FEATURE_STANDALONE_SHELL is defined (i.e. BusyBox can now completely replace
sash).  Also fixed it so shell builtins now respect pipes and redirects.
 -Erik
diff --git a/Changelog b/Changelog
index db2dc44..87a0bd8 100644
--- a/Changelog
+++ b/Changelog
@@ -30,6 +30,10 @@
 	* zcat now works (wasn't working since option parsing was broken)
 	* Renamed "mnc" to the more correct "nc".
 	* Makefile intelligence updates
+	* BusyBox sh (lash) internals now behave wrt pipes and redirects. 
+	* BusyBox sh (lash) now supports being used as a standalone shell.  When
+	    BB_FEATURE_STANDALONE_SHELL is defined, all the busybox commands may
+	    be invoked as shell internals.
 	* More doc updates
 
 
diff --git a/applets/busybox.c b/applets/busybox.c
index 85b42df..07caa34 100644
--- a/applets/busybox.c
+++ b/applets/busybox.c
@@ -30,7 +30,7 @@
 void *__libc_stack_end;
 #endif
 
-static const struct Applet applets[] = {
+const struct BB_applet applets[] = {
 
 #ifdef BB_BASENAME
 	{"basename", basename_main, _BB_DIR_USR_BIN},
@@ -350,7 +350,7 @@
 {
 	char				*s;
 	char				*name;
-	const struct Applet	*a		= applets;
+	const struct BB_applet	*a		= applets;
 
 	for (s = name = argv[0]; *s != '\0';) {
 		if (*s++ == '/')
@@ -384,7 +384,7 @@
 	argv++;
 
 	if (been_there_done_that == 1 || argc < 1) {
-		const struct Applet *a = applets;
+		const struct BB_applet *a = applets;
 
 		fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n",
 				BB_VER, BB_BT);
diff --git a/busybox.c b/busybox.c
index 85b42df..07caa34 100644
--- a/busybox.c
+++ b/busybox.c
@@ -30,7 +30,7 @@
 void *__libc_stack_end;
 #endif
 
-static const struct Applet applets[] = {
+const struct BB_applet applets[] = {
 
 #ifdef BB_BASENAME
 	{"basename", basename_main, _BB_DIR_USR_BIN},
@@ -350,7 +350,7 @@
 {
 	char				*s;
 	char				*name;
-	const struct Applet	*a		= applets;
+	const struct BB_applet	*a		= applets;
 
 	for (s = name = argv[0]; *s != '\0';) {
 		if (*s++ == '/')
@@ -384,7 +384,7 @@
 	argv++;
 
 	if (been_there_done_that == 1 || argc < 1) {
-		const struct Applet *a = applets;
+		const struct BB_applet *a = applets;
 
 		fprintf(stderr, "BusyBox v%s (%s) multi-call binary -- GPL2\n\n",
 				BB_VER, BB_BT);
diff --git a/busybox.def.h b/busybox.def.h
index 5652b45..296c7f9 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -201,6 +201,11 @@
 // Enable command line editing in the shell
 //#define BB_FEATURE_SH_COMMAND_EDITING
 //
+//Allow the shell to invoke all the compiled in BusyBox commands as if they
+//were shell builtins.  Nice for staticly linking an emergency rescue shell
+//amoung other thing.
+#ifdef BB_FEATURE_STANDALONE_SHELL
+//
 // Enable tab completion in the shell (not yet 
 // working very well -- so don't turn this on)
 //#define BB_FEATURE_SH_TAB_COMPLETION
diff --git a/internal.h b/internal.h
index a953ce2..92b0255 100644
--- a/internal.h
+++ b/internal.h
@@ -90,11 +90,13 @@
 	_BB_DIR_USR_SBIN
 };
 
-struct Applet {
+struct BB_applet {
 	const	char*	name;
 	int	(*main)(int argc, char** argv);
 	enum	Location	location;
 };
+/* From busybox.c */
+extern const struct BB_applet applets[];
 
 extern int basename_main(int argc, char **argv);
 extern int busybox_main(int argc, char** argv);
diff --git a/lash.c b/lash.c
index e446ad1..05dab92 100644
--- a/lash.c
+++ b/lash.c
@@ -721,6 +721,7 @@
 	return 0;
 }
 
+
 static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
 {
 	struct job *job;
@@ -728,14 +729,10 @@
 	int nextin, nextout;
 	int pipefds[2];				/* pipefd[0] is for reading */
 	struct builtInCommand *x;
+#ifdef BB_FEATURE_STANDALONE_SHELL
+	const struct BB_applet *a = applets;
+#endif
 
-	/* handle built-ins here -- we don't fork() so we can't background
-	   these very easily */
-	for (x = bltins; x->cmd; x++) {
-		if (!strcmp(newJob.progs[0].argv[0], x->cmd)) {
-			return (x->function(&newJob, jobList));
-		}
-	}
 
 	nextin = 0, nextout = 1;
 	for (i = 0; i < newJob.numProgs; i++) {
@@ -762,6 +759,25 @@
 			/* explicit redirections override pipes */
 			setupRedirections(newJob.progs + i);
 
+			/* Match any built-ins here */
+			for (x = bltins; x->cmd; x++) {
+				if (!strcmp(newJob.progs[i].argv[0], x->cmd)) {
+					exit (x->function(&newJob, jobList));
+				}
+			}
+#ifdef BB_FEATURE_STANDALONE_SHELL
+			/* Handle busybox internals here */
+			while (a->name != 0) {
+				if (strcmp(newJob.progs[i].argv[0], a->name) == 0) {
+					int argc;
+					char** argv=newJob.progs[i].argv;
+					for(argc=0;*argv!=NULL, argv++, argc++);
+					exit((*(a->main)) (argc, newJob.progs[i].argv));
+				}
+				a++;
+			}
+#endif
+
 			execvp(newJob.progs[i].argv[0], newJob.progs[i].argv);
 			fatalError("sh: %s: %s\n", newJob.progs[i].argv[0],
 					   strerror(errno));
diff --git a/sh.c b/sh.c
index e446ad1..05dab92 100644
--- a/sh.c
+++ b/sh.c
@@ -721,6 +721,7 @@
 	return 0;
 }
 
+
 static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
 {
 	struct job *job;
@@ -728,14 +729,10 @@
 	int nextin, nextout;
 	int pipefds[2];				/* pipefd[0] is for reading */
 	struct builtInCommand *x;
+#ifdef BB_FEATURE_STANDALONE_SHELL
+	const struct BB_applet *a = applets;
+#endif
 
-	/* handle built-ins here -- we don't fork() so we can't background
-	   these very easily */
-	for (x = bltins; x->cmd; x++) {
-		if (!strcmp(newJob.progs[0].argv[0], x->cmd)) {
-			return (x->function(&newJob, jobList));
-		}
-	}
 
 	nextin = 0, nextout = 1;
 	for (i = 0; i < newJob.numProgs; i++) {
@@ -762,6 +759,25 @@
 			/* explicit redirections override pipes */
 			setupRedirections(newJob.progs + i);
 
+			/* Match any built-ins here */
+			for (x = bltins; x->cmd; x++) {
+				if (!strcmp(newJob.progs[i].argv[0], x->cmd)) {
+					exit (x->function(&newJob, jobList));
+				}
+			}
+#ifdef BB_FEATURE_STANDALONE_SHELL
+			/* Handle busybox internals here */
+			while (a->name != 0) {
+				if (strcmp(newJob.progs[i].argv[0], a->name) == 0) {
+					int argc;
+					char** argv=newJob.progs[i].argv;
+					for(argc=0;*argv!=NULL, argv++, argc++);
+					exit((*(a->main)) (argc, newJob.progs[i].argv));
+				}
+				a++;
+			}
+#endif
+
 			execvp(newJob.progs[i].argv[0], newJob.progs[i].argv);
 			fatalError("sh: %s: %s\n", newJob.progs[i].argv[0],
 					   strerror(errno));
diff --git a/shell/lash.c b/shell/lash.c
index e446ad1..05dab92 100644
--- a/shell/lash.c
+++ b/shell/lash.c
@@ -721,6 +721,7 @@
 	return 0;
 }
 
+
 static int runCommand(struct job newJob, struct jobSet *jobList, int inBg)
 {
 	struct job *job;
@@ -728,14 +729,10 @@
 	int nextin, nextout;
 	int pipefds[2];				/* pipefd[0] is for reading */
 	struct builtInCommand *x;
+#ifdef BB_FEATURE_STANDALONE_SHELL
+	const struct BB_applet *a = applets;
+#endif
 
-	/* handle built-ins here -- we don't fork() so we can't background
-	   these very easily */
-	for (x = bltins; x->cmd; x++) {
-		if (!strcmp(newJob.progs[0].argv[0], x->cmd)) {
-			return (x->function(&newJob, jobList));
-		}
-	}
 
 	nextin = 0, nextout = 1;
 	for (i = 0; i < newJob.numProgs; i++) {
@@ -762,6 +759,25 @@
 			/* explicit redirections override pipes */
 			setupRedirections(newJob.progs + i);
 
+			/* Match any built-ins here */
+			for (x = bltins; x->cmd; x++) {
+				if (!strcmp(newJob.progs[i].argv[0], x->cmd)) {
+					exit (x->function(&newJob, jobList));
+				}
+			}
+#ifdef BB_FEATURE_STANDALONE_SHELL
+			/* Handle busybox internals here */
+			while (a->name != 0) {
+				if (strcmp(newJob.progs[i].argv[0], a->name) == 0) {
+					int argc;
+					char** argv=newJob.progs[i].argv;
+					for(argc=0;*argv!=NULL, argv++, argc++);
+					exit((*(a->main)) (argc, newJob.progs[i].argv));
+				}
+				a++;
+			}
+#endif
+
 			execvp(newJob.progs[i].argv[0], newJob.progs[i].argv);
 			fatalError("sh: %s: %s\n", newJob.progs[i].argv[0],
 					   strerror(errno));