#include <sys/mount.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <alloca.h>
#include <limits.h>
#include <ctype.h>
#include <termios.h>

#include "kinit.h"
#include "ipconfig.h"
#include "run-init.h"
#include "resume.h"

const char *progname = "kinit";
int mnt_procfs;
int mnt_sysfs;

#ifdef DEBUG
void dump_args(int argc, char *argv[])
{
	int i;

	printf("  argc == %d\n", argc);

	for (i = 0; i < argc; i++) {
		printf("  argv[%d]: \"%s\"\n", i, argv[i]);
	}

	if (argv[argc] != NULL) {
		printf("  argv[%d]: \"%s\" (SHOULD BE NULL)\n",
			argc, argv[argc]);
	}
}
#endif /* DEBUG */


static int do_ipconfig(int argc, char *argv[])
{
	int i, a = 0;
	char **args = alloca((argc + 3) * sizeof(char *));

	if (!args)
		return -1;

	args[a++] = (char *)"IP-Config";
	args[a++] = (char *)"-i";
	args[a++] = (char *)"Linux kinit";

	dprintf("Running ipconfig\n");

	for (i = 1; i < argc; i++) {
		if (strncmp(argv[i], "ip=", 3) == 0 ||
		    strncmp(argv[i], "nfsaddrs=", 9) == 0) {
			args[a++] = argv[i];
		}
	}

	if (a > 1) {
		args[a] = NULL;
		dump_args(a, args);
		return ipconfig_main(a, args);
	}

	return 0;
}

static int split_cmdline(int cmdcmax, char *cmdv[], char *argv0,
			 char *cmdlines[], char *args[])
{
	int was_space;
	char c, *p;
	int vmax = cmdcmax;
	int v = 1;
	int space;

	if (cmdv)
		cmdv[0] = argv0;

	/* First, add the parsable command lines */

	while (*cmdlines) {
		p = *cmdlines++;
		was_space = 1;
		while (v < vmax) {
			c = *p;
			space = isspace(c);
			if ((space || !c) && !was_space) {
				if (cmdv)
					*p = '\0';
				v++;
			} else if (was_space) {
				if (cmdv)
					cmdv[v] = p;
			}

			if (!c)
				break;

			was_space = space;
			p++;
		}
	}

	/* Second, add the explicit command line arguments */

	while (*args && v < vmax) {
		if (cmdv)
			cmdv[v] = *args;
		v++;
		args++;
	}

	if (cmdv)
		cmdv[v] = NULL;

	return v;
}

static int mount_sys_fs(const char *check, const char *fsname,
			const char *fstype)
{
	struct stat st;

	if (stat(check, &st) == 0) {
		return 0;
	}

	mkdir(fsname, 0555);

	if (mount("none", fsname, fstype, 0, NULL) == -1) {
		fprintf(stderr, "%s: could not mount %s as %s\n",
			progname, fsname, fstype);
		return -1;
	}

	return 1;
}

static void check_path(const char *path)
{
	struct stat st;

	if (stat(path, &st) == -1) {
		if (errno != ENOENT) {
			perror("stat");
			exit(1);
		}
		if (mkdir(path, 0755) == -1) {
			perror("mkdir");
			exit(1);
		}
	} else if (!S_ISDIR(st.st_mode)) {
		fprintf(stderr, "%s: '%s' not a directory\n", progname, path);
		exit(1);
	}
}

static const char *find_init(const char *root, const char *user)
{
	const char *init_paths[] = {
		"/sbin/init", "/bin/init", "/etc/init", "/bin/sh", NULL
	};
	const char **p;
	const char *path;

	if (chdir(root)) {
		perror("chdir");
		exit(1);
	}

	if (user)
		dprintf("Checking for init: %s\n", user);

	if (user && user[0] == '/' && !access(user+1, X_OK)) {
		path = user;
	} else {
		for (p = init_paths; *p; p++) {
			dprintf("Checking for init: %s\n", *p);
			if (!access(*p+1, X_OK))
				break;
		}
		path = *p;
	}
	chdir("/");
	return path;
}

/* This is the argc and argv we pass to init */
const char *init_path;
int init_argc;
char **init_argv;

extern ssize_t readfile(const char *, char **);

int main(int argc, char *argv[])
{
	char **cmdv, **args;
	char *cmdlines[3];
	int i;
	const char *errmsg;
	int ret = 0;
	int cmdc;
	int fd;
	struct timeval now;

	gettimeofday(&now, NULL);
	srand48(now.tv_usec ^ (now.tv_sec << 24));

	/* Default parameters for anything init-like we execute */
	init_argc = argc;
	init_argv = alloca((argc+1)*sizeof(char *));
	memcpy(init_argv, argv, (argc+1)*sizeof(char *));

	if ((fd = open("/dev/console", O_RDWR)) != -1) {
		dup2(fd, STDIN_FILENO);
		dup2(fd, STDOUT_FILENO);
		dup2(fd, STDERR_FILENO);

		if (fd > STDERR_FILENO) {
			close(fd);
		}
	}

	mnt_procfs = mount_sys_fs("/proc/cmdline", "/proc", "proc") >= 0;
	if (!mnt_procfs) {
		ret = 1;
		goto bail;
	}

	mnt_sysfs = mount_sys_fs("/sys/bus", "/sys", "sysfs") >= 0;
	if (!mnt_sysfs) {
		ret = 1;
		goto bail;
	}

	/* Construct the effective kernel command line.  The
	   effective kernel command line consists of /arch.cmd, if
	   it exists, /proc/cmdline, plus any arguments after an --
	   argument on the proper command line, in that order. */

	ret = readfile("/arch.cmd", &cmdlines[0]);
	if (ret < 0)
		cmdlines[0] = "";

	ret = readfile("/proc/cmdline", &cmdlines[1]);
	if (ret < 0) {
		fprintf(stderr, "%s: cannot read /proc/cmdline\n", progname);
		ret = 1;
		goto bail;
	}

	cmdlines[2] = NULL;

	/* Find an -- argument, and if so append to the command line */
	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "--")) {
			i++;
			break;
		}
	}
	args = &argv[i];	/* Points either to first argument past -- or
				   to the final NULL */

	/* Count the number of arguments */
	cmdc = split_cmdline(INT_MAX, NULL, argv[0], cmdlines, args);

	/* Actually generate the cmdline array */
	cmdv = (char **)alloca((cmdc+1)*sizeof(char *));
	if (split_cmdline(cmdc, cmdv, argv[0], cmdlines, args) != cmdc) {
		ret = 1;
		goto bail;
	}

	/* Debugging... */
	dump_args(cmdc, cmdv);

	/* Resume from suspend-to-disk, if appropriate */
	/* If successful, does not return */
	do_resume(cmdc, cmdv);

	/* Initialize networking, if applicable */
	do_ipconfig(cmdc, cmdv);

	check_path("/root");
	do_mounts(cmdc, cmdv);

	if (mnt_procfs) {
		umount2("/proc", 0);
		mnt_procfs = 0;
	}

	if (mnt_sysfs) {
		umount2("/sys", 0);
		mnt_sysfs = 0;
	}

	init_path = find_init("/root", get_arg(cmdc, cmdv, "init="));
	if (!init_path) {
		fprintf(stderr, "%s: init not found!\n", progname);
		ret = 2;
		goto bail;
	}

	init_argv[0] = strrchr(init_path, '/') + 1;

	errmsg = run_init("/root", "/dev/console", init_path, init_argv);

	/* If run_init returned, something went bad */
	fprintf(stderr, "%s: %s: %s\n", progname, errmsg, strerror(errno));
	ret = 2;
	goto bail;

bail:
	if (mnt_procfs)
		umount2("/proc", 0);

	if (mnt_sysfs)
		umount2("/sys", 0);

	/*
	 * If we get here, something bad probably happened, and the kernel
	 * will most likely panic.  Drain console output so the user can
	 * figure out what happened.
	 */
	tcdrain(2);
	tcdrain(1);

	return ret;
}
