#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"

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

#ifdef INI_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


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

	if (!args)
		return -1;

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

	DEBUG(("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)
		DEBUG(("Checking for init: %s\n", user));

	if (user && user[0] == '/' && !access(user+1, X_OK)) {
		path = user;
	} else {
		for (p = init_paths; *p; p++) {
			DEBUG(("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;
}
