/* 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;
	end = skip_non_whitespace(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_and_exit(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;
}
