/* vi: set sw=4 ts=4: */
/*
 * lash -- the BusyBox Lame-Ass SHell
 *
 * Copyright (C) 2000 by Lineo, inc.
 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
 *
 * Based in part on ladsh.c by Michael K. Johnson and Erik W. Troan, which is
 * under the following liberal license: "We have placed this source code in the
 * public domain. Use it in any project, free or commercial."
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */


#define BB_FEATURE_SH_BACKTICKS



#include "internal.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <glob.h>
#include <signal.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <unistd.h>
#ifdef BB_FEATURE_SH_COMMAND_EDITING
#include "cmdedit.h"
#endif

#define bb_need_full_version
#define BB_DECLARE_EXTERN
#include "messages.c"

#define MAX_READ	128	/* size of input buffer for `read' builtin */
#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"


enum redirectionType { REDIRECT_INPUT, REDIRECT_OVERWRITE,
	REDIRECT_APPEND
};

struct jobSet {
	struct job *head;			/* head of list of running jobs */
	struct job *fg;				/* current foreground job */
};

struct redirectionSpecifier {
	enum redirectionType type;	/* type of redirection */
	int fd;						/* file descriptor being redirected */
	char *filename;				/* file to redirect fd to */
};

struct childProgram {
	pid_t pid;					/* 0 if exited */
	char **argv;				/* program name and arguments */
	int numRedirections;		/* elements in redirection array */
	struct redirectionSpecifier *redirections;	/* I/O redirections */
	glob_t globResult;			/* result of parameter globbing */
	int freeGlob;				/* should we globfree(&globResult)? */
	int isStopped;				/* is the program currently running? */
};

struct job {
	int jobId;					/* job number */
	int numProgs;				/* total number of programs in job */
	int runningProgs;			/* number of programs running */
	char *text;					/* name of job */
	char *cmdBuf;				/* buffer various argv's point into */
	pid_t pgrp;					/* process group ID for the job */
	struct childProgram *progs;	/* array of programs in job */
	struct job *next;			/* to track background commands */
	int stoppedProgs;			/* number of programs alive, but stopped */
};

struct builtInCommand {
	char *cmd;					/* name */
	char *descr;				/* description */
	char *usage;				/* usage */
	int (*function) (struct job *, struct jobSet * jobList);	/* function ptr */
};

/* function prototypes for builtins */
static int builtin_cd(struct job *cmd, struct jobSet *junk);
static int builtin_env(struct job *dummy, struct jobSet *junk);
static int builtin_exit(struct job *cmd, struct jobSet *junk);
static int builtin_fg_bg(struct job *cmd, struct jobSet *jobList);
static int builtin_help(struct job *cmd, struct jobSet *junk);
static int builtin_jobs(struct job *dummy, struct jobSet *jobList);
static int builtin_pwd(struct job *dummy, struct jobSet *junk);
static int builtin_export(struct job *cmd, struct jobSet *junk);
static int builtin_source(struct job *cmd, struct jobSet *jobList);
static int builtin_unset(struct job *cmd, struct jobSet *junk);
static int builtin_read(struct job *cmd, struct jobSet *junk);


/* function prototypes for shell stuff */
static void checkJobs(struct jobSet *jobList);
static int getCommand(FILE * source, char *command);
static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobList, int *isBg);
static int setupRedirections(struct childProgram *prog);
static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int outPipe[2]);
static int busy_loop(FILE * input);


/* Table of built-in functions (these are non-forking builtins, meaning they
 * can change global variables in the parent shell process but they will not
 * work with pipes and redirects; 'unset foo | whatever' will not work) */
static struct builtInCommand bltins[] = {
	{"bg", "Resume a job in the background", "bg [%%job]", builtin_fg_bg},
	{"cd", "Change working directory", "cd [dir]", builtin_cd},
	{"exit", "Exit from shell()", "exit", builtin_exit},
	{"fg", "Bring job into the foreground", "fg [%%job]", builtin_fg_bg},
	{"jobs", "Lists the active jobs", "jobs", builtin_jobs},
	{"export", "Set environment variable", "export [VAR=value]", builtin_export},
	{"unset", "Unset environment variable", "unset VAR", builtin_unset},
	{"read", "Input environment variable", "read [VAR]", builtin_read},
	{NULL, NULL, NULL, NULL}
};

/* Table of forking built-in functions (things that fork cannot change global
 * variables in the parent process, such as the current working directory) */
static struct builtInCommand bltins_forking[] = {
	{"env", "Print all environment variables", "env", builtin_env},
	{"pwd", "Print current directory", "pwd", builtin_pwd},
	{".", "Source-in and run commands in a file", ". filename", builtin_source},
	{"help", "List shell built-in commands", "help", builtin_help},
	{NULL, NULL, NULL, NULL}
};

static char *prompt = "# ";
static char *cwd = NULL;
static char *local_pending_command = NULL;

#ifdef BB_FEATURE_SH_COMMAND_EDITING
void win_changed(int junk)
{
	struct winsize win = { 0, 0, 0, 0 };
	ioctl(0, TIOCGWINSZ, &win);
	if (win.ws_col > 0) {
		cmdedit_setwidth( win.ws_col - 1);
	}
}
#endif


/* built-in 'cd <path>' handler */
static int builtin_cd(struct job *cmd, struct jobSet *junk)
{
	char *newdir;

	if (!cmd->progs[0].argv[1] == 1)
		newdir = getenv("HOME");
	else
		newdir = cmd->progs[0].argv[1];
	if (chdir(newdir)) {
		printf("cd: %s: %s\n", newdir, strerror(errno));
		return FALSE;
	}
	getcwd(cwd, sizeof(cwd));

	return TRUE;
}

/* built-in 'env' handler */
static int builtin_env(struct job *dummy, struct jobSet *junk)
{
	char **e;

	for (e = environ; *e; e++) {
		fprintf(stdout, "%s\n", *e);
	}
	return (0);
}

/* built-in 'exit' handler */
static int builtin_exit(struct job *cmd, struct jobSet *junk)
{
	if (!cmd->progs[0].argv[1] == 1)
		exit TRUE;

	return(atoi(cmd->progs[0].argv[1]));
}

/* built-in 'fg' and 'bg' handler */
static int builtin_fg_bg(struct job *cmd, struct jobSet *jobList)
{
	int i, jobNum;
	struct job *job=NULL;

	if (!jobList->head) {
		if (!cmd->progs[0].argv[1] || cmd->progs[0].argv[2]) {
			errorMsg("%s: exactly one argument is expected\n",
					cmd->progs[0].argv[0]);
			return FALSE;
		}
		if (sscanf(cmd->progs[0].argv[1], "%%%d", &jobNum) != 1) {
			errorMsg("%s: bad argument '%s'\n",
					cmd->progs[0].argv[0], cmd->progs[0].argv[1]);
			return FALSE;
			for (job = jobList->head; job; job = job->next) {
				if (job->jobId == jobNum) {
					break;
				}
			}
		}
	} else {
		job = jobList->head;
	}

	if (!job) {
		errorMsg("%s: unknown job %d\n",
				cmd->progs[0].argv[0], jobNum);
		return FALSE;
	}

	if (*cmd->progs[0].argv[0] == 'f') {
		/* Make this job the foreground job */
		/* suppress messages when run from /linuxrc mag@sysgo.de */
		if (tcsetpgrp(0, job->pgrp) && errno != ENOTTY)
			perror("tcsetpgrp"); 
		jobList->fg = job;
	}

	/* Restart the processes in the job */
	for (i = 0; i < job->numProgs; i++)
		job->progs[i].isStopped = 0;

	kill(-job->pgrp, SIGCONT);

	job->stoppedProgs = 0;

	return TRUE;
}

/* built-in 'help' handler */
static int builtin_help(struct job *dummy, struct jobSet *junk)
{
	struct builtInCommand *x;

	fprintf(stdout, "\nBuilt-in commands:\n");
	fprintf(stdout, "-------------------\n");
	for (x = bltins; x->cmd; x++) {
		fprintf(stdout, "%s\t%s\n", x->cmd, x->descr);
	}
	for (x = bltins_forking; x->cmd; x++) {
		fprintf(stdout, "%s\t%s\n", x->cmd, x->descr);
	}
	fprintf(stdout, "\n\n");
	return TRUE;
}

/* built-in 'jobs' handler */
static int builtin_jobs(struct job *dummy, struct jobSet *jobList)
{
	struct job *job;
	char *statusString;

	for (job = jobList->head; job; job = job->next) {
		if (job->runningProgs == job->stoppedProgs)
			statusString = "Stopped";
		else
			statusString = "Running";

		printf(JOB_STATUS_FORMAT, job->jobId, statusString, job->text);
	}
	return TRUE;
}


/* built-in 'pwd' handler */
static int builtin_pwd(struct job *dummy, struct jobSet *junk)
{
	getcwd(cwd, sizeof(cwd));
	fprintf(stdout, "%s\n", cwd);
	return TRUE;
}

/* built-in 'export VAR=value' handler */
static int builtin_export(struct job *cmd, struct jobSet *junk)
{
	int res;

	if (!cmd->progs[0].argv[1] == 1) {
		return (builtin_env(cmd, junk));
	}
	res = putenv(cmd->progs[0].argv[1]);
	if (res)
		fprintf(stdout, "export: %s\n", strerror(errno));
	return (res);
}

/* built-in 'read VAR' handler */
static int builtin_read(struct job *cmd, struct jobSet *junk)
{
	int res = 0, len, newlen;
	char *s;
	char string[MAX_READ];

	if (cmd->progs[0].argv[1]) {
		/* argument (VAR) given: put "VAR=" into buffer */
		strcpy(string, cmd->progs[0].argv[1]);
		len = strlen(string);
		string[len++] = '=';
		string[len]   = '\0';
		fgets(&string[len], sizeof(string) - len, stdin);	/* read string */
		newlen = strlen(string);
		if(newlen > len)
			string[--newlen] = '\0';	/* chomp trailing newline */
		/*
		** string should now contain "VAR=<value>"
		** copy it (putenv() won't do that, so we must make sure
		** the string resides in a static buffer!)
		*/
		res = -1;
		if((s = strdup(string)))
			res = putenv(s);
		if (res)
			fprintf(stdout, "read: %s\n", strerror(errno));
	}
	else
		fgets(string, sizeof(string), stdin);

	return (res);
}

/* Built-in '.' handler (read-in and execute commands from file) */
static int builtin_source(struct job *cmd, struct jobSet *junk)
{
	FILE *input;
	int status;

	if (!cmd->progs[0].argv[1] == 1)
		return FALSE;

	input = fopen(cmd->progs[0].argv[1], "r");
	if (!input) {
		fprintf(stdout, "Couldn't open file '%s'\n",
				cmd->progs[0].argv[1]);
		return FALSE;
	}

	/* Now run the file */
	status = busy_loop(input);
	return (status);
}

/* built-in 'unset VAR' handler */
static int builtin_unset(struct job *cmd, struct jobSet *junk)
{
	if (!cmd->progs[0].argv[1] == 1) {
		fprintf(stdout, "unset: parameter required.\n");
		return FALSE;
	}
	unsetenv(cmd->progs[0].argv[1]);
	return TRUE;
}

/* free up all memory from a job */
static void freeJob(struct job *cmd)
{
	int i;

	for (i = 0; i < cmd->numProgs; i++) {
		free(cmd->progs[i].argv);
		if (cmd->progs[i].redirections)
			free(cmd->progs[i].redirections);
		if (cmd->progs[i].freeGlob)
			globfree(&cmd->progs[i].globResult);
	}
	free(cmd->progs);
	if (cmd->text)
		free(cmd->text);
	free(cmd->cmdBuf);
	memset(cmd, 0, sizeof(struct job));
}

/* remove a job from the jobList */
static void removeJob(struct jobSet *jobList, struct job *job)
{
	struct job *prevJob;

	freeJob(job);
	if (job == jobList->head) {
		jobList->head = job->next;
	} else {
		prevJob = jobList->head;
		while (prevJob->next != job)
			prevJob = prevJob->next;
		prevJob->next = job->next;
	}

	free(job);
}

/* Checks to see if any background processes have exited -- if they 
   have, figure out why and see if a job has completed */
static void checkJobs(struct jobSet *jobList)
{
	struct job *job;
	pid_t childpid;
	int status;
	int progNum = 0;

	while ((childpid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
		for (job = jobList->head; job; job = job->next) {
			progNum = 0;
			while (progNum < job->numProgs &&
				   job->progs[progNum].pid != childpid) progNum++;
			if (progNum < job->numProgs)
				break;
		}

		/* This happens on backticked commands */
		if(job==NULL)
			return;

		if (WIFEXITED(status) || WIFSIGNALED(status)) {
			/* child exited */
			job->runningProgs--;
			job->progs[progNum].pid = 0;

			if (!job->runningProgs) {
				printf(JOB_STATUS_FORMAT, job->jobId, "Done", job->text);
				removeJob(jobList, job);
			}
		} else {
			/* child stopped */
			job->stoppedProgs++;
			job->progs[progNum].isStopped = 1;

			if (job->stoppedProgs == job->numProgs) {
				printf(JOB_STATUS_FORMAT, job->jobId, "Stopped",
					   job->text);
			}
		}
	}

	if (childpid == -1 && errno != ECHILD)
		perror("waitpid");
}

static int getCommand(FILE * source, char *command)
{
	if (source == NULL) {
		if (local_pending_command) {
			/* a command specified (-c option): return it & mark it done */
			strcpy(command, local_pending_command);
			free(local_pending_command);
			local_pending_command = NULL;
			return 0;
		}
		return 1;
	}

	if (source == stdin) {
#ifdef BB_FEATURE_SH_COMMAND_EDITING
		int len;
		char *promptStr;
		len=fprintf(stdout, "%s %s", cwd, prompt);
		fflush(stdout);
		promptStr=(char*)xmalloc(sizeof(char)*(len+1));
		sprintf(promptStr, "%s %s", cwd, prompt);
		cmdedit_read_input(promptStr, command);
		free( promptStr);
		return 0;
#else
		fprintf(stdout, "%s %s", cwd, prompt);
		fflush(stdout);
#endif
	}

	if (!fgets(command, BUFSIZ - 2, source)) {
		if (source == stdin)
			printf("\n");
		return 1;
	}

	/* remove trailing newline */
	command[strlen(command) - 1] = '\0';

	return 0;
}

static void globLastArgument(struct childProgram *prog, int *argcPtr,
							 int *argcAllocedPtr)
{
	int argc = *argcPtr;
	int argcAlloced = *argcAllocedPtr;
	int rc;
	int flags;
	int i;
	char *src, *dst, *var;

	if (argc > 1) {				/* cmd->globResult is already initialized */
		flags = GLOB_APPEND;
		i = prog->globResult.gl_pathc;
	} else {
		prog->freeGlob = 1;
		flags = 0;
		i = 0;
	}
	/* do shell variable substitution */
	if(*prog->argv[argc - 1] == '$' && (var = getenv(prog->argv[argc - 1] + 1)))
		prog->argv[argc - 1] = var;

	rc = glob(prog->argv[argc - 1], flags, NULL, &prog->globResult);
	if (rc == GLOB_NOSPACE) {
		errorMsg("out of space during glob operation\n");
		return;
	} else if (rc == GLOB_NOMATCH ||
			   (!rc && (prog->globResult.gl_pathc - i) == 1 &&
				!strcmp(prog->argv[argc - 1],
						prog->globResult.gl_pathv[i]))) {
		/* we need to remove whatever \ quoting is still present */
		src = dst = prog->argv[argc - 1];
		while (*src) {
			if (*src != '\\')
				*dst++ = *src;
			src++;
		}
		*dst = '\0';
	} else if (!rc) {
		argcAlloced += (prog->globResult.gl_pathc - i);
		prog->argv =
			realloc(prog->argv, argcAlloced * sizeof(*prog->argv));
		memcpy(prog->argv + (argc - 1), prog->globResult.gl_pathv + i,
			   sizeof(*(prog->argv)) * (prog->globResult.gl_pathc - i));
		argc += (prog->globResult.gl_pathc - i - 1);
	}

	*argcAllocedPtr = argcAlloced;
	*argcPtr = argc;
}

/* Return cmd->numProgs as 0 if no command is present (e.g. an empty
   line). If a valid command is found, commandPtr is set to point to
   the beginning of the next command (if the original command had more 
   then one job associated with it) or NULL if no more commands are 
   present. */
static int parseCommand(char **commandPtr, struct job *job, struct jobSet *jobList, int *isBg)
{
	char *command;
	char *returnCommand = NULL;
	char *src, *buf, *chptr;
	int argc = 0;
	int done = 0;
	int argvAlloced;
	int i;
	char quote = '\0';
	int count;
	struct childProgram *prog;

	/* skip leading white space */
	while (**commandPtr && isspace(**commandPtr))
		(*commandPtr)++;

	/* this handles empty lines or leading '#' characters */
	if (!**commandPtr || (**commandPtr == '#')) {
		job->numProgs=0;
		return 0;
	}

	*isBg = 0;
	job->numProgs = 1;
	job->progs = xmalloc(sizeof(*job->progs));

	/* We set the argv elements to point inside of this string. The 
	   memory is freed by freeJob(). Allocate twice the original
	   length in case we need to quote every single character.

	   Getting clean memory relieves us of the task of NULL 
	   terminating things and makes the rest of this look a bit 
	   cleaner (though it is, admittedly, a tad less efficient) */
	job->cmdBuf = command = calloc(1, 2*strlen(*commandPtr) + 1);
	job->text = NULL;

	prog = job->progs;
	prog->numRedirections = 0;
	prog->redirections = NULL;
	prog->freeGlob = 0;
	prog->isStopped = 0;

	argvAlloced = 5;
	prog->argv = xmalloc(sizeof(*prog->argv) * argvAlloced);
	prog->argv[0] = job->cmdBuf;

	buf = command;
	src = *commandPtr;
	while (*src && !done) {
		if (quote == *src) {
			quote = '\0';
		} else if (quote) {
			if (*src == '\\') {
				src++;
				if (!*src) {
					errorMsg("character expected after \\\n");
					freeJob(job);
					return 1;
				}

				/* in shell, "\'" should yield \' */
				if (*src != quote)
					*buf++ = '\\';
			} else if (*src == '*' || *src == '?' || *src == '[' ||
					   *src == ']') *buf++ = '\\';
			*buf++ = *src;
		} else if (isspace(*src)) {
			if (*prog->argv[argc]) {
				buf++, argc++;
				/* +1 here leaves room for the NULL which ends argv */
				if ((argc + 1) == argvAlloced) {
					argvAlloced += 5;
					prog->argv = realloc(prog->argv,
										 sizeof(*prog->argv) *
										 argvAlloced);
				}
				globLastArgument(prog, &argc, &argvAlloced);
				prog->argv[argc] = buf;
			}
		} else
			switch (*src) {
			case '"':
			case '\'':
				quote = *src;
				break;

			case '#':			/* comment */
				done = 1;
				break;

			case '>':			/* redirections */
			case '<':
				i = prog->numRedirections++;
				prog->redirections = realloc(prog->redirections,
											 sizeof(*prog->redirections) *
											 (i + 1));

				prog->redirections[i].fd = -1;
				if (buf != prog->argv[argc]) {
					/* the stuff before this character may be the file number 
					   being redirected */
					prog->redirections[i].fd =
						strtol(prog->argv[argc], &chptr, 10);

					if (*chptr && *prog->argv[argc]) {
						buf++, argc++;
						globLastArgument(prog, &argc, &argvAlloced);
						prog->argv[argc] = buf;
					}
				}

				if (prog->redirections[i].fd == -1) {
					if (*src == '>')
						prog->redirections[i].fd = 1;
					else
						prog->redirections[i].fd = 0;
				}

				if (*src++ == '>') {
					if (*src == '>')
						prog->redirections[i].type =
							REDIRECT_APPEND, src++;
					else
						prog->redirections[i].type = REDIRECT_OVERWRITE;
				} else {
					prog->redirections[i].type = REDIRECT_INPUT;
				}

				/* This isn't POSIX sh compliant. Oh well. */
				chptr = src;
				while (isspace(*chptr))
					chptr++;

				if (!*chptr) {
					errorMsg("file name expected after %c\n", *src);
					freeJob(job);
					job->numProgs=0;
					return 1;
				}

				prog->redirections[i].filename = buf;
				while (*chptr && !isspace(*chptr))
					*buf++ = *chptr++;

				src = chptr - 1;	/* we src++ later */
				prog->argv[argc] = ++buf;
				break;

			case '|':			/* pipe */
				/* finish this command */
				if (*prog->argv[argc])
					argc++;
				if (!argc) {
					errorMsg("empty command in pipe\n");
					freeJob(job);
					job->numProgs=0;
					return 1;
				}
				prog->argv[argc] = NULL;

				/* and start the next */
				job->numProgs++;
				job->progs = realloc(job->progs,
									 sizeof(*job->progs) * job->numProgs);
				prog = job->progs + (job->numProgs - 1);
				prog->numRedirections = 0;
				prog->redirections = NULL;
				prog->freeGlob = 0;
				argc = 0;

				argvAlloced = 5;
				prog->argv = xmalloc(sizeof(*prog->argv) * argvAlloced);
				prog->argv[0] = ++buf;

				src++;
				while (*src && isspace(*src))
					src++;

				if (!*src) {
					errorMsg("empty command in pipe\n");
					freeJob(job);
					job->numProgs=0;
					return 1;
				}
				src--;			/* we'll ++ it at the end of the loop */

				break;

			case '&':			/* background */
				*isBg = 1;
			case ';':			/* multiple commands */
				done = 1;
				returnCommand = *commandPtr + (src - *commandPtr) + 1;
				break;

			case '\\':
				src++;
				if (!*src) {
					errorMsg("character expected after \\\n");
					freeJob(job);
					return 1;
				}
				if (*src == '*' || *src == '[' || *src == ']'
					|| *src == '?') *buf++ = '\\';
				/* fallthrough */
#ifdef BB_FEATURE_SH_BACKTICKS
			case '`':
				/* Exec a backtick-ed command */
				{
					char* charptr1=NULL, *charptr2;
					char* ptr=NULL;
					struct job *newJob;
					struct jobSet njobList = { NULL, NULL };
					int pipefd[2];
					int size;

					ptr=strchr(++src, '`');
					if (ptr==NULL) {
						fprintf(stderr, "Unmatched '`' in command\n");
						freeJob(job);
						return 1;
					}

					/* Make a copy of any stuff left over in the command 
					 * line after the second backtick */
					charptr2 = xmalloc(strlen(ptr)+1);
					memcpy(charptr2, ptr+1, strlen(ptr));

					/* Make some space to hold just the backticked command */
					charptr1 = xmalloc(1+ptr-src);
					snprintf(charptr1, 1+ptr-src, src);
					newJob = xmalloc(sizeof(struct job));
					/* Now parse and run the backticked command */
					if (!parseCommand(&charptr1, newJob, &njobList, isBg) 
							&& newJob->numProgs) {
						pipe(pipefd);
						runCommand(newJob, &njobList, 0, pipefd);
					}
					checkJobs(jobList);
					free(charptr1);

					/* Copy the output from the backtick-ed command into the
					 * command line, making extra room as needed  */
					--src;
					charptr1 = xmalloc(BUFSIZ);
					while ( (size=fullRead(pipefd[0], charptr1, BUFSIZ-1)) >0) {
						int newSize=src - *commandPtr + size + 1 + strlen(charptr2);
						if (newSize > BUFSIZ) {
							*commandPtr=realloc(*commandPtr, src - *commandPtr + 
									size + 1 + strlen(charptr2));
						}
						memcpy(src, charptr1, size); 
						src+=size;
					}
					free(charptr1);
					close(pipefd[0]);
					if (*(src-1)=='\n')
						--src;

					/* Now paste into the *commandPtr all the stuff 
					 * leftover after the second backtick */
					memcpy(src, charptr2, strlen(charptr2));
					fprintf(stderr,"*commandPtr='%s'\n", *commandPtr);
					free(charptr2);


					/* Now recursively call parseCommand to deal with the new
					 * and improved version of the command line with the backtick
					 * results expanded in place... */
					return(parseCommand(commandPtr, job, jobList, isBg));
				}
				break;
#endif // BB_FEATURE_SH_BACKTICKS
			default:
				*buf++ = *src;
			}

		src++;
	}

	if (*prog->argv[argc]) {
		argc++;
		globLastArgument(prog, &argc, &argvAlloced);
	}
	if (!argc) {
		freeJob(job);
		return 0;
	}
	prog->argv[argc] = NULL;

	if (!returnCommand) {
		job->text = xmalloc(strlen(*commandPtr) + 1);
		strcpy(job->text, *commandPtr);
	} else {
		/* This leaves any trailing spaces, which is a bit sloppy */
		count = returnCommand - *commandPtr;
		job->text = xmalloc(count + 1);
		strncpy(job->text, *commandPtr, count);
		job->text[count] = '\0';
	}

	*commandPtr = returnCommand;

	return 0;
}


static int runCommand(struct job *newJob, struct jobSet *jobList, int inBg, int outPipe[2])
{
	struct job *job;
	int nextin=0, nextout, stdoutfd=fileno(stdout);
	int i;
	int pipefds[2];				/* pipefd[0] is for reading */
	struct builtInCommand *x;
#ifdef BB_FEATURE_SH_STANDALONE_SHELL
	const struct BB_applet *a = applets;
#endif

	for (i = 0; i < newJob->numProgs; i++) {
		if ((i + 1) < newJob->numProgs) {
			pipe(pipefds);
			nextout = pipefds[1];
		} else {
			nextout = stdoutfd;
		}

		/* Check if the command matches any non-forking builtins */
		for (x = bltins; x->cmd; x++) {
			if (!strcmp(newJob->progs[i].argv[0], x->cmd)) {
				return (x->function(newJob, jobList));
			}
		}

		if (!(newJob->progs[i].pid = fork())) {
			signal(SIGTTOU, SIG_DFL);

			if (outPipe[1]!=-1) {
				close(outPipe[0]);
				nextout = stdoutfd = outPipe[1];
				dup2(nextout, 1);
				dup2(nextout, 2);
				close(nextout);
			}

			//dup2(nextin, 0);
			//close(nextin);
			
			/* explicit redirections override pipes */
			setupRedirections(newJob->progs + i);

			/* Check if the command matches any of the other builtins */
			for (x = bltins_forking; x->cmd; x++) {
				if (!strcmp(newJob->progs[i].argv[0], x->cmd)) {
					exit (x->function(newJob, jobList));
				}
			}
#ifdef BB_FEATURE_SH_STANDALONE_SHELL
			/* Check if the command matches any busybox internal commands here */
			/* TODO: Add matching on commands with paths appended (i.e. 'cat' 
			 * currently works, but '/bin/cat' doesn't ) */
			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("%s: %s\n", newJob->progs[i].argv[0],
					   strerror(errno));
		}
		if (outPipe[1]!=-1) { 
			close(outPipe[1]);
		}

		/* put our child in the process group whose leader is the
		   first process in this pipe */
		setpgid(newJob->progs[i].pid, newJob->progs[0].pid);

		if (nextin != 0)
			close(nextin);
		if (nextout != stdoutfd)
			close(nextout);

		/* If there isn't another process, nextin is garbage 
		   but it doesn't matter */
		nextin = pipefds[0];
	}

	newJob->pgrp = newJob->progs[0].pid;

	/* find the ID for the job to use */
	newJob->jobId = 1;
	for (job = jobList->head; job; job = job->next)
		if (job->jobId >= newJob->jobId)
			newJob->jobId = job->jobId + 1;

	/* add the job to the list of running jobs */
	if (!jobList->head) {
		job = jobList->head = xmalloc(sizeof(*job));
	} else {
		for (job = jobList->head; job->next; job = job->next);
		job->next = xmalloc(sizeof(*job));
		job = job->next;
	}

	*job = *newJob;
	job->next = NULL;
	job->runningProgs = job->numProgs;
	job->stoppedProgs = 0;

	if (inBg) {
		/* we don't wait for background jobs to return -- append it 
		   to the list of backgrounded jobs and leave it alone */
		printf("[%d] %d\n", job->jobId,
			   newJob->progs[newJob->numProgs - 1].pid);
	} else {
		jobList->fg = job;

		/* move the new process group into the foreground */
		/* suppress messages when run from /linuxrc mag@sysgo.de */
		if (tcsetpgrp(0, newJob->pgrp) && errno != ENOTTY)
			perror("tcsetpgrp");
	}

	return 0;
}

static int setupRedirections(struct childProgram *prog)
{
	int i;
	int openfd;
	int mode = O_RDONLY;
	struct redirectionSpecifier *redir = prog->redirections;

	for (i = 0; i < prog->numRedirections; i++, redir++) {
		switch (redir->type) {
		case REDIRECT_INPUT:
			mode = O_RDONLY;
			break;
		case REDIRECT_OVERWRITE:
			mode = O_RDWR | O_CREAT | O_TRUNC;
			break;
		case REDIRECT_APPEND:
			mode = O_RDWR | O_CREAT | O_APPEND;
			break;
		}

		openfd = open(redir->filename, mode, 0666);
		if (openfd < 0) {
			/* this could get lost if stderr has been redirected, but
			   bash and ash both lose it as well (though zsh doesn't!) */
			errorMsg("error opening %s: %s\n", redir->filename,
					strerror(errno));
			return 1;
		}

		if (openfd != redir->fd) {
			dup2(openfd, redir->fd);
			close(openfd);
		}
	}

	return 0;
}


static int busy_loop(FILE * input)
{
	char *command;
	char *nextCommand = NULL;
	struct jobSet jobList = { NULL, NULL };
	struct job newJob;
	pid_t  parent_pgrp;
	int i;
	int status;
	int inBg;

	/* save current owner of TTY so we can restore it on exit */
	parent_pgrp = tcgetpgrp(0);

	command = (char *) calloc(BUFSIZ, sizeof(char));

	/* don't pay any attention to this signal; it just confuses 
	   things and isn't really meant for shells anyway */
	signal(SIGTTOU, SIG_IGN);

	while (1) {
		if (!jobList.fg) {
			/* no job is in the foreground */

			/* see if any background processes have exited */
			checkJobs(&jobList);

			if (!nextCommand) {
				if (getCommand(input, command))
					break;
				nextCommand = command;
			}

			if (!parseCommand(&nextCommand, &newJob, &jobList, &inBg) &&
				newJob.numProgs) {
				int pipefds[2] = {-1,-1};
				runCommand(&newJob, &jobList, inBg, pipefds);
			} else {
				nextCommand=NULL;
				free(command);
				command = (char *) calloc(BUFSIZ, sizeof(char));
			}
		} else {
			/* a job is running in the foreground; wait for it */
			i = 0;
			while (!jobList.fg->progs[i].pid ||
				   jobList.fg->progs[i].isStopped) i++;

			waitpid(jobList.fg->progs[i].pid, &status, WUNTRACED);

			if (WIFEXITED(status) || WIFSIGNALED(status)) {
				/* the child exited */
				jobList.fg->runningProgs--;
				jobList.fg->progs[i].pid = 0;

				if (!jobList.fg->runningProgs) {
					/* child exited */

					removeJob(&jobList, jobList.fg);
					jobList.fg = NULL;
				}
			} else {
				/* the child was stopped */
				jobList.fg->stoppedProgs++;
				jobList.fg->progs[i].isStopped = 1;

				if (jobList.fg->stoppedProgs == jobList.fg->runningProgs) {
					printf("\n" JOB_STATUS_FORMAT, jobList.fg->jobId,
						   "Stopped", jobList.fg->text);
					jobList.fg = NULL;
				}
			}

			if (!jobList.fg) {
				/* move the shell to the foreground */
				/* suppress messages when run from /linuxrc mag@sysgo.de */
				if (tcsetpgrp(0, getpid()) && errno != ENOTTY)
					perror("tcsetpgrp"); 
			}
		}
	}
	free(command);

	/* return controlling TTY back to parent process group before exiting */
	if (tcsetpgrp(0, parent_pgrp))
		perror("tcsetpgrp");

	/* return exit status if called with "-c" */
	if (input == NULL && WIFEXITED(status))
		return WEXITSTATUS(status);
	
	return 0;
}


int shell_main(int argc, char **argv)
{
	FILE *input = stdin;

	/* initialize the cwd */
	cwd = (char *) calloc(BUFSIZ, sizeof(char));
	if (cwd == 0) {
		fatalError("out of memory\n");
	}
	getcwd(cwd, sizeof(char)*BUFSIZ);

#ifdef BB_FEATURE_SH_COMMAND_EDITING
	cmdedit_init();
	signal(SIGWINCH, win_changed);
	win_changed(0);
#endif

	//if (argv[0] && argv[0][0] == '-') {
	//      builtin_source("/etc/profile");
	//}

	if (argc < 2) {
		fprintf(stdout, "\n\n%s Built-in shell\n", full_version);
		fprintf(stdout, "Enter 'help' for a list of built-in commands.\n\n");
	} else {
		if (argv[1][0]=='-' && argv[1][1]=='c') {
			int i;
			local_pending_command = (char *) calloc(BUFSIZ, sizeof(char));
			if (local_pending_command == 0) {
				fatalError("out of memory\n");
			}
			for(i=2; i<argc; i++)
			{
				if (strlen(local_pending_command) + strlen(argv[i]) >= BUFSIZ) {
					local_pending_command = realloc(local_pending_command, 
							strlen(local_pending_command) + strlen(argv[i]));
					if (local_pending_command==NULL) 
					  fatalError("commands for -c option too long\n");
				}
				strcat(local_pending_command, argv[i]);
				if ( (i + 1) < argc)
				  strcat(local_pending_command, " ");
			}
			input = NULL;
			  
		}
		else if (argv[1][0]=='-') {
			usage(shell_usage);
		}
		else {
			input = fopen(argv[1], "r");
			if (!input) {
				fatalError("Couldn't open file '%s': %s\n", argv[1],
						   strerror(errno));
			}
		}
	}

	return (busy_loop(input));
}
