#include <sys/types.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
int run(const char *path, ...) {
va_list ap;
char **argv;
int argvMax, argvIdx;
pid_t pid;
int pidstat;
pid = fork();
if (pid == ((pid_t) -1)) {
return(-1);
}
if (pid != 0) {
waitpid(pid, &pidstat, 0);
return(pidstat);
}
argvMax = 32;
argv = malloc(sizeof(*argv) * argvMax);
va_start(ap, path);
for (argvIdx = 0; argvIdx < argvMax; argvIdx++) {
argv[argvIdx] = va_arg(ap, char *);
if (argv[argvIdx] == NULL) {
break;
}
}
va_end(ap);
execv(path, argv);
exit(EXIT_FAILURE);
}
int main(int argc, char **argv) {
int mount_ret;
/*
* Load kernel modules (drivers)
*/
mkdir("/sys", 0755);
mount("sysfs", "/sys", "sysfs", 0, NULL);
run("/bin/init-modules", "init-modules", NULL);
umount("/sys");
rmdir("/sys");
/*
* Mount root filesystem
*/
mkdir("/dev", 0755);
mount("devtmpfs", "/dev", "devtmpfs", 0, NULL);
mkdir("/new-root", 0755);
mount_ret = mount("/dev/vda2", "/new-root", "ext4", 0, NULL);
if (mount_ret != 0) {
mount_ret = mount("/dev/sda2", "/new-root", "ext4", 0, NULL);
}
if (mount_ret != 0) {
mount_ret = mount("/dev/hda2", "/new-root", "ext4", 0, NULL);
}
umount("/dev");
rmdir("/dev");
if (mount_ret == 0) {
mkdir("/new-root/initramfs", 0755);
mkdir("/new-root/bin", 0755);
mkdir("/new-root/lib", 0755);
symlink("../initramfs/bin/appfsd", "/new-root/bin/appfsd");
symlink("../initramfs/bin/init", "/new-root/bin/init");
symlink("../initramfs/bin/init-modules", "/new-root/bin/init-modules");
symlink("../initramfs/bin/init-networking", "/new-root/bin/init-networking");
symlink("../initramfs/bin/appfs-cache", "/new-root/bin/appfs-cache");
symlink("../initramfs/bin/tclkit", "/new-root/bin/tclkit");
symlink("../initramfs/lib/modules", "/new-root/lib/modules");
chdir("/new-root");
mount("/", "/new-root/initramfs", "bind", MS_BIND, NULL);
chroot("/new-root");
chdir("/");
}
/*
* Mount needed filesystems
*/
mkdir("/dev", 0755);
mount("devtmpfs", "/dev", "devtmpfs", 0, NULL);
mkdir("/tmp", 0755);
mount("tmpfs", "/tmp", "tmpfs", 0, NULL);
mkdir("/proc", 0755);
mount("proc", "/proc", "proc", 0, NULL);
mkdir("/sys", 0755);
mount("sysfs", "/sys", "sysfs", 0, NULL);
/*
* Setup networking
*/
run("/bin/init-networking", "init-networking", NULL);
mkdir("/etc", 0755);
mkdir("/bin", 0755);
mkdir("/lib", 0755);
mkdir("/opt", 0755);
mkdir("/opt/appfs", 0755);
mkdir("/var", 0755);
mkdir("/var/cache", 0755);
mkdir("/var/cache/appfs", 0755);
run("/bin/appfsd", "appfsd", "/var/cache/appfs", "/opt/appfs", NULL);
symlink(".", "/usr");
symlink("lib", "/lib64");
symlink("/proc/self/mounts", "/etc/mtab");
symlink("/opt/appfs/core.appfs.rkeene.org/bash/platform/latest/bin/bash", "/bin/bash");
symlink("/opt/appfs/core.appfs.rkeene.org/coreutils/platform/latest/bin/env", "/bin/env");
symlink("/bin/bash", "/bin/sh");
setenv("PATH", "/bin:/opt/appfs/core.appfs.rkeene.org/coreutils/platform/latest/bin", 1);
run("/bin/appfs-cache", "appfs-cache", "install", "-lib", "core.appfs.rkeene.org", "glibc", NULL);
run("/bin/appfs-cache", "appfs-cache", "install", "core.appfs.rkeene.org", "coreutils", NULL);
run("/bin/appfs-cache", "appfs-cache", "install", "core.appfs.rkeene.org", "procps-ng", NULL);
setenv("PATH", "/bin", 1);
run("/bin/sh", "sh", NULL);
sync();
return(0);
}