/* vi: set ts=4 :
 *
 * bbsh - busybox shell
 *
 * Copyright 2006 Rob Landley <rob@landley.net>
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */

// A section of code that gets repeatedly or conditionally executed is stored
// as a string and parsed each time it's run.



// Wheee, debugging.

// Terminal control
#define ENABLE_BBSH_TTY        0

// &, fg, bg, jobs.  (ctrl-z with tty.)
#define ENABLE_BBSH_JOBCTL     0

// Flow control (if, while, for, functions { })
#define ENABLE_BBSH_FLOWCTL    0

#define ENABLE_BBSH_ENVVARS    0  // Environment variable support

// Local and synthetic variables, fancy prompts, set, $?, etc.
#define ENABLE_BBSH_LOCALVARS  0

// Pipes and redirects: | > < >> << && || & () ;
#define ENABLE_BBSH_PIPES      0

/* Fun:

  echo `echo hello#comment " woot` and more
*/

#include "busybox.h"

// A single executable, its arguments, and other information we know about it.
#define BBSH_FLAG_EXIT    1
#define BBSH_FLAG_SUSPEND 2
#define BBSH_FLAG_PIPE    4
#define BBSH_FLAG_AND     8
#define BBSH_FLAG_OR      16
#define BBSH_FLAG_AMP     32
#define BBSH_FLAG_SEMI    64
#define BBSH_FLAG_PAREN   128

// What we know about a single process.
struct command {
	struct command *next;
	int flags;		// exit, suspend, && ||
	int pid;		// pid (or exit code)
	int argc;
	char *argv[0];
};

// A collection of processes piped into/waiting on each other.
struct pipeline {
	struct pipeline *next;
	int job_id;
	struct command *cmd;
	char *cmdline;
	int cmdlinelen;
};

static void free_list(void *list, void (*freeit)(void *data))
{
	while(list) {
		void **next = (void **)list;
		void *list_next = *next;
		freeit(list);
		free(list);
		list = list_next;
	}
}

// Parse one word from the command line, appending one or more argv[] entries
// to struct command.  Handles environment variable substitution and
// substrings.  Returns pointer to next used byte, or NULL if it
// hit an ending token.
static char *parse_word(char *start, struct command **cmd)
{
	char *end;

	// Detect end of line (and truncate line at comment)
	if (ENABLE_BBSH_PIPES && strchr("><&|(;", *start)) return 0;

	// Grab next word.  (Add dequote and envvar logic here)
	end = start;
	while (*end && !isspace(*end)) end++;
	(*cmd)->argv[(*cmd)->argc++] = xstrndup(start, end-start);

	// Allocate more space if there's no room for NULL terminator.

	if (!((*cmd)->argc & 7))
			*cmd = xrealloc(*cmd,
					sizeof(struct command) + ((*cmd)->argc+8)*sizeof(char *));
	(*cmd)->argv[(*cmd)->argc] = 0;
	return end;
}

// Parse a line of text into a pipeline.
// Returns a pointer to the next line.

static char *parse_pipeline(char *cmdline, struct pipeline *line)
{
	struct command **cmd = &(line->cmd);
	char *start = line->cmdline = cmdline;

	if (!cmdline) return 0;

	if (ENABLE_BBSH_JOBCTL) line->cmdline = cmdline;

	// Parse command into argv[]
	for (;;) {
		char *end;

		// Skip leading whitespace and detect end of line.
		start = skip_whitespace(start);
		if (!*start || *start=='#') {
			if (ENABLE_BBSH_JOBCTL) line->cmdlinelen = start-cmdline;
			return 0;
		}

		// Allocate next command structure if necessary
		if (!*cmd) *cmd = xzalloc(sizeof(struct command)+8*sizeof(char *));

		// Parse next argument and add the results to argv[]
		end = parse_word(start, cmd);

		// If we hit the end of this command, how did it end?
		if (!end) {
			if (ENABLE_BBSH_PIPES && *start) {
				if (*start==';') {
					start++;
					break;
				}
				// handle | & < > >> << || &&
			}
			break;
		}
		start = end;
	}

	if (ENABLE_BBSH_JOBCTL) line->cmdlinelen = start-cmdline;

	return start;
}

// Execute the commands in a pipeline
static int run_pipeline(struct pipeline *line)
{
	struct command *cmd = line->cmd;
	if (!cmd || !cmd->argc) return 0;

	// Handle local commands.  This is totally fake and plastic.
	if (cmd->argc==2 && !strcmp(cmd->argv[0],"cd"))
		chdir(cmd->argv[1]);
	else if(!strcmp(cmd->argv[0],"exit"))
		exit(cmd->argc>1 ? atoi(cmd->argv[1]) : 0);
	else {
		int status;
		pid_t pid=fork();
		if(!pid) {
			run_applet_by_name(cmd->argv[0],cmd->argc,cmd->argv);
			execvp(cmd->argv[0],cmd->argv);
			printf("No %s",cmd->argv[0]);
			exit(1);
		} else waitpid(pid, &status, 0);
	}

	return 0;
}

static void free_cmd(void *data)
{
	struct command *cmd=(struct command *)data;

	while(cmd->argc) free(cmd->argv[--cmd->argc]);
}


static void handle(char *command)
{
	struct pipeline line;
	char *start = command;

	for (;;) {
		memset(&line,0,sizeof(struct pipeline));
		start = parse_pipeline(start, &line);
		if (!line.cmd) break;

		run_pipeline(&line);
		free_list(line.cmd, free_cmd);
	}
}

int bbsh_main(int argc, char *argv[]);
int bbsh_main(int argc, char *argv[])
{
	char *command=NULL;
	FILE *f;

	getopt32(argc, argv, "c:", &command);

	f = argv[optind] ? xfopen(argv[optind],"r") : NULL;
	if (command) handle(command);
	else {
		unsigned cmdlen=0;
		for (;;) {
			if(!f) putchar('$');
			if(1 > getline(&command, &cmdlen,f ? : stdin)) break;

			handle(command);
		}
		if (ENABLE_FEATURE_CLEAN_UP) free(command);
	}

	return 1;
}
