/*
 * This is a simple init for shared rootfs guests. This part should be limited
 * to doing mounts and running stage 2 of the init process.
 */
#include <sys/mount.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/reboot.h>

static int run_process(char *filename)
{
	char *new_argv[] = { filename, NULL };
	char *new_env[] = { "TERM=linux", "DISPLAY=192.168.33.1:0",
				"HOME=/virt/home", NULL };

	return execve(filename, new_argv, new_env);
}

static int run_process_sandbox(char *filename)
{
	char *new_argv[] = { filename, "/virt/sandbox.sh", NULL };
	char *new_env[] = { "TERM=linux", "HOME=/virt/home", NULL };

	return execve(filename, new_argv, new_env);
}

static void do_mounts(void)
{
#ifndef CONFIG_GUEST_PRE_INIT
	mount("hostfs", "/host", "9p", MS_RDONLY, "trans=virtio,version=9p2000.L");
#endif
	mount("", "/sys", "sysfs", 0, NULL);
	mount("proc", "/proc", "proc", 0, NULL);
	mount("devtmpfs", "/dev", "devtmpfs", 0, NULL);
	mkdir("/dev/pts", 0755);
	mount("devpts", "/dev/pts", "devpts", 0, NULL);
}

int main(int argc, char *argv[])
{
	pid_t child;
	int status;

	puts("Mounting...");

	do_mounts();

	/* get session leader */
	setsid();

	/* set controlling terminal */
	ioctl(0, TIOCSCTTY, 1);

	child = fork();
	if (child < 0) {
		printf("Fatal: fork() failed with %d\n", child);
		return 0;
	} else if (child == 0) {
		if (access("/virt/sandbox.sh", R_OK) == 0)
			run_process_sandbox("/bin/sh");
		else
			run_process("/bin/sh");
	} else {
		pid_t corpse;

		do {
			corpse = waitpid(-1, &status, 0);
		} while (corpse != child);
	}

	reboot(RB_AUTOBOOT);

	printf("Init failed: %s\n", strerror(errno));

	return 0;
}
