Пример #1
0
static int
do_swapon(const char *orig_special, int prio, int canonic) {
	int status;
	const char *special = orig_special;
	int flags = 0;

	if (verbose)
		printf(_("%s on %s\n"), progname, orig_special);

	if (!canonic) {
		special = fsprobe_get_devname_by_spec(orig_special);
		if (!special)
			return cannot_find(orig_special);
	}

	if (swapon_checks(special))
		return -1;

#ifdef SWAP_FLAG_PREFER
	if (prio >= 0) {
		if (prio > SWAP_FLAG_PRIO_MASK)
			prio = SWAP_FLAG_PRIO_MASK;
		flags = SWAP_FLAG_PREFER
			| ((prio & SWAP_FLAG_PRIO_MASK)
			   << SWAP_FLAG_PRIO_SHIFT);
	}
#endif
	status = swapon(special, flags);
	if (status < 0)
		warn(_("%s: swapon failed"), orig_special);

	return status;
}
Пример #2
0
const char *
spec_to_devname(const char *spec)
{
	if (!spec)
		return NULL;
	if (nocanonicalize || is_pseudo_fs(spec))
		return xstrdup(spec);
	return fsprobe_get_devname_by_spec(spec);
}
Пример #3
0
static int
swapon_all(void) {
	FILE *fp;
	struct mntent *fstab;
	int status = 0;

	read_proc_swaps();

	fp = setmntent(_PATH_MNTTAB, "r");
	if (fp == NULL)
		err(2, _("%s: open failed"), _PATH_MNTTAB);

	while ((fstab = getmntent(fp)) != NULL) {
		const char *special;
		int skip = 0, nofail = ifexists;
		int pri = priority, dsc = discard;
		char *opt, *opts;

		if (!streq(fstab->mnt_type, MNTTYPE_SWAP))
			continue;

		opts = strdup(fstab->mnt_opts);

		for (opt = strtok(opts, ","); opt != NULL;
		     opt = strtok(NULL, ",")) {
			if (strncmp(opt, "pri=", 4) == 0)
				pri = atoi(opt+4);
			if (strcmp(opt, "discard") == 0)
				dsc = 1;
			if (strcmp(opt, "noauto") == 0)
				skip = 1;
			if (strcmp(opt, "nofail") == 0)
				nofail = 1;
		}
		free(opts);

		if (skip)
			continue;

		special = fsprobe_get_devname_by_spec(fstab->mnt_fsname);
		if (!special) {
			if (!nofail)
				status |= cannot_find(fstab->mnt_fsname);
			continue;
		}

		if (!is_in_proc_swaps(special) &&
		    (!nofail || !access(special, R_OK)))
			status |= do_swapon(special, pri, dsc, CANONIC);

		free((void *) special);
	}
	fclose(fp);

	return status;
}
Пример #4
0
static int
do_swapoff(const char *orig_special, int quiet, int canonic) {
        const char *special = orig_special;

	if (verbose)
		printf(_("%s on %s\n"), progname, orig_special);

	if (!canonic) {
		special = fsprobe_get_devname_by_spec(orig_special);
		if (!special)
			return cannot_find(orig_special);
	}

	if (swapoff(special) == 0)
		return 0;	/* success */

	if (errno == EPERM)
		errx(EXIT_FAILURE, _("Not superuser."));

	if (!quiet || errno == ENOMEM)
		warn(_("%s: swapoff failed"), orig_special);

	return -1;
}
Пример #5
0
int main(int argc, char **argv, char **envp)
{
	int fd_stdin=-1, fd_stdout=-1;
	pid_t pid;
	int guess = 0;
/*
	char *argv[] = { "/sbin/init", NULL };
	char *envp[] = { "PATH=/bin:/sbin:/usr/bin:/usr/sbin", NULL };
*/
	char *rootdev = NULL;
	
	open_console();

	/* create mountpoints /dev and /proc /rootfs */
	
	mkmountpoint("/dev");
	mkmountpoint("/proc");
	mkmountpoint("/rootfs");

	open_console();
	
	/* make sure /dev is mounted */
	if(mount("devtmpfs", "/dev",
		 "devtmpfs", 0,
		 "")) {
		if(fstdout) {
			if(fstdout) {
				fprintf(fstdout, "INIT: could not mount devtmpfs on /dev: %s\n", strerror(errno));
				fprintf(fstdout, "INIT: waiting 10 seconds ..\n");
				sleep(5);
				sleep(5);
			}
		}	
	}

	open_console();
	
	/* mount /proc */
	if(mount("proc", "/proc",
		 "proc", 0,
		 "")) {
		if(fstdout) {
			fprintf(fstdout, "INIT: could not mount proc on /proc: %s\n", strerror(errno));
			fprintf(fstdout, "INIT: waiting 10 seconds ..\n");
			sleep(5);
			sleep(5);
		}	
	}
	
	rootdev = fsprobe_get_devname_by_spec(ROOTFSLABEL);
	if(!rootdev) {
		if(fstdout) {
			fprintf(fstdout, "INIT: could not find rootdevice\n");
			fprintf(fstdout, "INIT: waiting 10 seconds ..\n");
			sleep(5);
			sleep(5);
			fprintf(fstdout, "INIT: guessing that rootdev is /dev/sda1\n\n");
		}
		rootdev="/dev/sda1";
		guess = 1;
	} else {
		if(fstdout) fprintf(fstdout, "INIT: probed rootdev is %s\n", rootdev);
	}
	sleep(1);

	/* e2fsck -y rootdev */
	/* fork + exec("/e2fsck", "/e2fsck"-y", rootdev) */
	if(!guess) {
		if((pid=fork())==0) {
			execl("/e2fsck", "/e2fsck", "-y", rootdev, NULL);
			exit(0);
		}
		if(pid != -1) wait(NULL);
	}
	
	/* unlink /e2sck to save some memory */
	if(unlink("/e2fsck")) {
		fprintf(fstdout, "INIT: unlink(\"/e2fsck\") failed: %s\n", strerror(errno));
	}
	
	/* mount /rootfs, try ext4, ext3, ext2 */
	if(mount(rootdev, "/rootfs",
		 "ext4", MS_NOATIME,
		 "")) {
		if(mount(rootdev, "/rootfs",
			 "ext3", MS_NOATIME,
			 "")) {
			if(mount(rootdev, "/rootfs",
				 "ext2", MS_NOATIME,
				 "")) {
				if(fstdout) fprintf(fstdout, "INIT: failed to mount %s: %s\n", rootdev, strerror(errno));
				goto forever;
			}
		}
	}
	if(fstdout) fprintf(fstdout, "INIT: %s mounted.\n", rootdev);
	sleep(1);

	if (mount("/dev", "/rootfs/dev", NULL, MS_MOVE, NULL) < 0) {
		if(fstdout)
			fprintf(fstdout, "INIT: failed to mount moving /dev to /rootfs/dev");
		sleep(1);
	}
	if (mount("/proc", "/rootfs/proc", NULL, MS_MOVE, NULL) < 0) {
		if(fstdout)
			fprintf(fstdout, "INIT: failed to mount moving /proc to /rootfs/proc");
		sleep(1);
	}
	if(chdir("/rootfs")) {
		if(fstdout)
			fprintf(fstdout, "INIT: chdir(\"/rootfs\") failed: %s\n", strerror(errno));
		goto forever;
	}
	if (mount("/rootfs", "/", NULL, MS_MOVE, NULL) < 0) {
		if(fstdout)
			fprintf(fstdout, "INIT: failed to mount moving /rootfs to /");
		goto forever;
	}

        /*
	  Now, the init process may still access the old root via its
	  executable, shared libraries, standard input/output/error, and its
	  current root directory. All these references are dropped by the
	  following command:
	  
	  # exec chroot . /sbin/init <dev/console >dev/console 2>&1
	*/
	
	if(chroot(".")) {
		if(fstdout) {
			fprintf(fstdout, "INIT: chroot(\".\") failed: %s\n", strerror(errno));
			sleep(5);
			sleep(5);
		}
	}
	
	fd_stdin = open("/dev/console", O_RDONLY|O_NOCTTY);
	if(fd_stdin == -1) {
		if(fstdout)
			fprintf(fstdout, "INIT: open(\"/dev/console\", O_RDONLY) failed: %s\n", strerror(errno));
	} else {
		if(fd_stdin != 0) {
			dup2(fd_stdin, 0);
			close(fd_stdin);
		}
	}
	fd_stdout = open("/dev/console", O_WRONLY|O_NOCTTY);
	if(fd_stdout == -1) {
		if(fstdout)
			fprintf(fstdout, "INIT: open(\"/dev/console\", O_WRONLY) failed: %s\n", strerror(errno));
	} else { 
		if(fd_stdout != 1) {
			dup2(fd_stdout, 1);
			dup2(fd_stdout, 2);
			close(fd_stdout);
		}
	}
	
	if(fstdout)
		fprintf(fstdout, "INIT: now execing \"/sbin/init\"\n");
	sleep(1);

	if(fstdout) {
		fclose(fstdout);
		fstdout = NULL;
	}
	argv[0] = "/sbin/init";
	execve("/sbin/init", argv,
	       envp);
	
	open_console();

	if(fstdout) {
		fprintf(fstdout, "INIT: execve(\"/sbin/init\") failed: %s\n", strerror(errno));
	}
forever:
	if(fstdout) {
		fprintf(fstdout, "INIT: pid is %u", getpid());
		fprintf(fstdout, "INIT: boot cannot proceed from here.\n");
		fprintf(fstdout, "INIT: turn off the computer.\n");
	}
	while(1) sleep(1000);
	return 2;
}
Пример #6
0
static int
main_swapoff(int argc, char *argv[]) {
	FILE *fp;
	struct mntent *fstab;
	int status = 0;
	int c, i;

	while ((c = getopt_long(argc, argv, "ahvVL:U:",
				 longswapoffopts, NULL)) != -1) {
		switch (c) {
		case 'a':		/* all */
			++all;
			break;
		case 'h':		/* help */
			swapoff_usage(stdout, 0);
			break;
		case 'v':		/* be chatty */
			++verbose;
			break;
		case 'V':		/* version */
			printf(_("%s (%s)\n"), progname, PACKAGE_STRING);
			exit(EXIT_SUCCESS);
		case 'L':
			addl(optarg);
			break;
		case 'U':
			addu(optarg);
			break;
		case 0:
			break;
		case '?':
		default:
			swapoff_usage(stderr, 1);
		}
	}
	argv += optind;

	if (!all && !llct && !ulct && *argv == NULL)
		swapoff_usage(stderr, 2);

	/*
	 * swapoff any explicitly given arguments.
	 * Complain in case the swapoff call fails.
	 */
	for (i = 0; i < llct; i++)
		status |= swapoff_by_label(llist[i], !QUIET);

	for (i = 0; i < ulct; i++)
		status |= swapoff_by_uuid(ulist[i], !QUIET);

	while (*argv != NULL)
		status |= do_swapoff(*argv++, !QUIET, !CANONIC);

	if (all) {
		/*
		 * In case /proc/swaps exists, unswap stuff listed there.
		 * We are quiet but report errors in status.
		 * Errors might mean that /proc/swaps
		 * exists as ordinary file, not in procfs.
		 * do_swapoff() exits immediately on EPERM.
		 */
		read_proc_swaps();
		for(i=0; i<numSwaps; i++)
			status |= do_swapoff(swapFiles[i], QUIET, CANONIC);

		/*
		 * Unswap stuff mentioned in /etc/fstab.
		 * Probably it was unmounted already, so errors are not bad.
		 * Doing swapoff -a twice should not give error messages.
		 */
		fp = setmntent(_PATH_MNTTAB, "r");
		if (fp == NULL)
			err(2, _("%s: open failed"), _PATH_MNTTAB);

		while ((fstab = getmntent(fp)) != NULL) {
			const char *special;

			if (!streq(fstab->mnt_type, MNTTYPE_SWAP))
				continue;

			special = fsprobe_get_devname_by_spec(fstab->mnt_fsname);
			if (!special)
				continue;

			if (!is_in_proc_swaps(special))
				do_swapoff(special, QUIET, CANONIC);
		}
		fclose(fp);
	}

	return status;
}
Пример #7
0
int main(int argc, char **argv, char **envp)
{
	int fd_stdin=-1, fd_stdout=-1;
	pid_t pid;
	int retries = 0;
	int rootmounted = 0;
	char *rootdev = NULL;
	char *rootfstype = "unknown";
	char *rootfslabel = ROOTFSLABEL;
	char *initprg = "/sbin/init";

	conf.mountflags = MS_SYNCHRONOUS;
	
	open_console();

	/* create mountpoints /dev and /proc /rootfs */
	
	mkmountpoint("/dev");
	mkmountpoint("/proc");
	mkmountpoint("/rootfs");

	open_console();
	
	/* make sure /dev is mounted */
	if(mount("devtmpfs", "/dev",
		 "devtmpfs", 0,
		 "")) {
		if(fstdout) {
			if(fstdout) {
				fprintf(fstdout, "INIT: could not mount devtmpfs on /dev: %s\n", strerror(errno));
				fprintf(fstdout, "INIT: waiting 10 seconds ..\n");
				sleep(5);
				sleep(5);
			}
		}	
	}

	open_console();
	
	/* mount /proc */
	if(mount("proc", "/proc",
		 "proc", 0,
		 "")) {
		if(fstdout) {
			fprintf(fstdout, "INIT: could not mount proc on /proc: %s\n", strerror(errno));
			fprintf(fstdout, "INIT: waiting 10 seconds ..\n");
			sleep(5);
			sleep(5);
		}	
	}
	
	/* parse kernel commandline options */
	cmdline.autoresize = 1;
	cmdline_parse();
	
	if(cmdline.init) {
		initprg = cmdline.init;
	}
	
	if(cmdline.async) {
		conf.mountflags ^= MS_SYNCHRONOUS;
	}
	
	if(cmdline.usbreset) {
		usbreset();
		sleep(1);
	}
	
	if(cmdline.rootdelay > 0) {
		if(fstdout) fprintf(fstdout, "INIT: rootdelay, waiting %d seconds\n", cmdline.rootdelay);
		sleep(cmdline.rootdelay);
	}
	
	if(cmdline.rootdev) {
		struct stat statb;
		if(fstdout) fprintf(fstdout, "INIT: rootdev %s given on commandline\n", cmdline.rootdev);
		rootdev = cmdline.rootdev;
		if(stat(rootdev, &statb)) {
			if(fstdout) fprintf(fstdout, "INIT: rootdev %s not found!\n", rootdev);
			rootdev = NULL;
		}
	}
	
	if(!rootdev) {
		if(cmdline.rootfslabel) {
			if(strncmp(cmdline.rootfslabel, "LABEL=", 6)) {
				rootfslabel = malloc(strlen("LABEL=") + strlen(cmdline.rootfslabel) + 1);
				strcpy(rootfslabel, "LABEL=");
				strcat(rootfslabel, cmdline.rootfslabel);
			} else {
				rootfslabel = cmdline.rootfslabel;
			}
		}
		if(fstdout) fprintf(fstdout, "INIT: probing for rootdev labeled '%s'\n", rootfslabel);
		fsprobe_init();
		while( (rootdev = fsprobe_get_devname_by_spec(rootfslabel)) == NULL ) {
			retries++;
			if(retries == 15) usbreset();
			if(retries > 25) break;
			if(fstdout) fprintf(fstdout, "INIT: waiting for rootdevice to be available\n");
			sleep(2);
			fsprobe_init();
		}
	}
	
	if(!rootdev) {
		if(fstdout) {
			fprintf(fstdout, "INIT: could not find rootdevice\n");
			listdevices();
			fprintf(fstdout, "INIT: waiting 10 seconds ..\n");
			sleep(5);
			sleep(5);
			fprintf(fstdout, "INIT: guessing that rootdev is /dev/sda1\n\n");
		}
		rootdev="/dev/sda1";
	} else {
		if(fstdout) fprintf(fstdout, "INIT: using rootdev %s\n", rootdev);
	}
	sleep(1);

	/* if filesystem is of the ext family */
	if((!cmdline.rootfstype) || (!strncmp(cmdline.rootfstype, "ext", 3))) {
		int status = 0;
		int fsckok = 0;
		/* e2fsck -y rootdev */
		/* fork + exec("/e2fsck", "/e2fsck"-y", rootdev) */
		if((pid=fork())==0) {
			execl("/e2fsck", "/e2fsck", "-y", rootdev, NULL);
			exit(0);
		}
		if(pid != -1) {
			wait(&status);
			if(WIFEXITED(status)) {
				fprintf(fstdout, "INIT: e2fsck exited normally with exit code: %d\n", WEXITSTATUS(status));
				if(WEXITSTATUS(status)==0) fsckok=1;
			} else {
				fprintf(fstdout, "INIT: e2fsck exited abnormally\n");
			}
		}
		if(fsckok) {
			if(cmdline.autoresize) {
				sync();
				if((pid=fork())==0) {
					execl("/resize2fs", "/resize2fs", "-f", rootdev, NULL);
					exit(0);
				}
				if(pid != -1) wait(NULL);
				sync();
			}
		}
	}
	
	/* unlink /e2sck and /resize2fs to save some memory */
	if(unlink("/e2fsck")) {
		fprintf(fstdout, "INIT: unlink(\"/e2fsck\") failed: %s\n", strerror(errno));
	}
	if(unlink("/resize2fs")) {
		fprintf(fstdout, "INIT: unlink(\"/resize2fs\") failed: %s\n", strerror(errno));
	}
	
	if(cmdline.rootfstype) {
		/* mount /rootfs, try fstype supplied on kernel commandline */
		if(mount(rootdev, "/rootfs", cmdline.rootfstype, MS_NOATIME|MS_RDONLY|conf.mountflags, "")) {
			if(fstdout) fprintf(fstdout, "INIT: failed to mount (%s) %s: %s\n",
						 cmdline.rootfstype, rootdev, strerror(errno));
		} else {
			rootmounted = 1;
			rootfstype = cmdline.rootfstype;
		}
	}
	if(!rootmounted) {
		/* mount /rootfs, try ext2 */
		if(mount(rootdev, "/rootfs", "ext2", MS_NOATIME|MS_RDONLY|conf.mountflags, "")) {
			if(fstdout) fprintf(fstdout, "INIT: failed to mount (ext2) %s: %s\n", rootdev, strerror(errno));
			goto forever;
		}
		rootfstype = "ext2";
	}
	
	if(fstdout) fprintf(fstdout, "INIT: (%s) %s mounted.\n", rootfstype, rootdev);
	sleep(1);

	if(cmdline.install) {
		if(fstdout) {
			fprintf(fstdout, "INIT: INSTALL INVOKED!\nINSTALL: PROCEEDING IN 5 SECONDS!\n");
			sleep(5);
		}
		
		/* unpack install archive in initramfs root */
		{
			int fd;
			fd = open("/rootfs/install.tar", O_RDONLY);
			if(fd == -1) {
				if(fstdout) fprintf(fstdout, "INSTALL: failed to open '/rootfs/install.tar'\n");
			} else {
				if(fstdout) fprintf(fstdout, "INSTALL: '/rootfs/install.tar' opened ok\n");
				tar_extract(fd);
				close(fd);
			}
		}

		/* Be nice and prepare stdin and stdout for the install program */
		fd_stdin = open("/dev/console", O_RDONLY|O_NOCTTY);
		if(fd_stdin == -1) {
			if(fstdout)
				fprintf(fstdout, "INSTALL: open(\"/dev/console\", O_RDONLY) failed: %s\n", strerror(errno));
		} else {
			if(fd_stdin != 0) {
				dup2(fd_stdin, 0);
				close(fd_stdin);
			}
		}
		fd_stdout = open("/dev/console", O_WRONLY|O_NOCTTY);
		if(fd_stdout == -1) {
			if(fstdout)
				fprintf(fstdout, "INSTALL: open(\"/dev/console\", O_WRONLY) failed: %s\n", strerror(errno));
		} else { 
			if(fd_stdout != 1) {
				dup2(fd_stdout, 1);
				dup2(fd_stdout, 2);
				close(fd_stdout);
			}
		}

		/* exec "/install" */
		{
			char *iv[2];
		iv[0] = "/install";
		iv[1] = NULL;
		if(fstdout)
			fprintf(fstdout, "INSTALL: exec(\"/install\")\n");
		execve(iv[0], iv, envp);
		if(fstdout)
			fprintf(fstdout, "INSTALL: exec(\"/install\") failed\n");
		sleep(10);
		}
	}
	
	if (mount("/dev", "/rootfs/dev", NULL, MS_MOVE, NULL) < 0) {
		if(fstdout)
			fprintf(fstdout, "INIT: failed to mount moving /dev to /rootfs/dev\n");
		sleep(1);
	}
	if (mount("/proc", "/rootfs/proc", NULL, MS_MOVE, NULL) < 0) {
		if(fstdout)
			fprintf(fstdout, "INIT: failed to mount moving /proc to /rootfs/proc\n");
		sleep(1);
	}

	/*
         * mkdir /sbin
 	 * copy /rootfs/sbin/init to /sbin/init
         * mount --bind /rootfs/sbin/init /sbin/init
         */
	if(mkdir("/sbin", 0755)) {
		if(fstdout)
			fprintf(fstdout, "INIT: mkdir(\"/sbin\") failed: %s\n", strerror(errno));
		sleep(1);
	} else {
		int fd, ofd;
		ssize_t siz;
		struct stat statb;
		
		if(stat("/rootfs/sbin/init", &statb)) {
			if(fstdout) fprintf(fstdout, "INIT: stat(\"/rootfs/sbin/init\") failed: %s\n", strerror(errno));
			sleep(1);
			goto noinitcopy;
		}
		siz = statb.st_size;

		if(mount("tmpfs", "/sbin","tmpfs", 0,"")) {
			if(fstdout) fprintf(fstdout, "INIT: mount(\"tmpfs\", \"/sbin\") failed: %s\n", strerror(errno));
		}
		if( (fd = open("/rootfs/sbin/init", O_RDONLY)) == -1) {
			if(fstdout) fprintf(fstdout, "INIT: open(\"/rootfs/sbin/init\", O_RDONLY) failed: %s\n", strerror(errno));
			sleep(1);
			goto noinitcopy;
		}
		if( (ofd = open("/sbin/init", O_WRONLY|O_CREAT|O_TRUNC, 0755)) == -1) {
			if(fstdout) fprintf(fstdout, "INIT: open(\"/sbin/init\", O_WRONLY|O_CREAT|O_TRUNC) failed: %s\n", strerror(errno));
			sleep(1);
			close(fd);
			goto noinitcopy;
		}
		if(data(fd, siz, ofd)) {
			if(fstdout) fprintf(fstdout, "INIT: datacopy of /sbin/init failed: %s\n", strerror(errno));
			sleep(1);
			close(fd);
			close(ofd);
			goto noinitcopy;
		}
		close(fd);
		if(close(ofd)) {
			if(fstdout) fprintf(fstdout, "INIT: close(\"/sbin/init\") failed: %s\n", strerror(errno));
			sleep(1);
			goto noinitcopy;
		}
		if (mount("rootfs", "/", NULL, MS_REMOUNT|MS_NOATIME|MS_RDONLY, NULL) < 0) {
			if(fstdout)
				fprintf(fstdout, "INIT: failed to remount initramfs as read-only\n");
			sleep(1);
		}
		if (mount("tmpfs", "/sbin", NULL, MS_REMOUNT|MS_NOATIME|MS_RDONLY, NULL) < 0) {
			if(fstdout)
				fprintf(fstdout, "INIT: failed to remount \"/sbin\" as read-only\n");
			sleep(1);
		}
		
		if(mount("/sbin/init", "/rootfs/sbin/init", "tmpfs", MS_BIND|MS_RDONLY, NULL)) {
			if(mount("/sbin/init", "/rootfs/sbin/init", "tmpfs", MS_BIND, NULL)) {
				if(fstdout)
					fprintf(fstdout, "INIT: bind mount(\"/sbin/init\", \"/rootfs/sbin/init\") failed: %s\n", strerror(errno));
				sleep(1);
			}
		}
	}
noinitcopy:

	if(chdir("/rootfs")) {
		if(fstdout)
			fprintf(fstdout, "INIT: chdir(\"/rootfs\") failed: %s\n", strerror(errno));
		goto forever;
	}

	if (mount("/rootfs", "/", NULL, MS_MOVE, NULL) < 0) {
		if(fstdout)
			fprintf(fstdout, "INIT: failed to mount moving /rootfs to /\n");
		goto forever;
	}

        /*
	  Now, the init process may still access the old root via its
	  executable, shared libraries, standard input/output/error, and its
	  current root directory. All these references are dropped by the
	  following command:
	  
	  # exec chroot . /sbin/init <dev/console >dev/console 2>&1
	*/
	
	if(chroot(".")) {
		if(fstdout) {
			fprintf(fstdout, "INIT: chroot(\".\") failed: %s\n", strerror(errno));
			sleep(5);
			sleep(5);
		}
	}

	/* check if we need to copy default versions of some config files */
	{
		int remounted=0;
		chk_cfg_file(&remounted, "ssh/ssh_config");
		chk_cfg_file(&remounted, "ssh/sshd_config");
		chk_cfg_file(&remounted, "inetd.conf");
		chk_cfg_file(&remounted, "inittab");
		chk_cfg_file(&remounted, "login.defs");
		chk_cfg_file(&remounted, "limits");
		chk_cfg_file(&remounted, "login.access");
		if(remounted)
			if (mount("rootfs", "/", NULL, MS_REMOUNT|MS_NOATIME|MS_RDONLY|conf.mountflags, NULL) < 0) {
				if(fstdout)
					fprintf(fstdout, "INIT: failed to remount rootfs as read-only\n");
				sleep(1);
			}
	}
		
	fd_stdin = open("/dev/console", O_RDONLY|O_NOCTTY);
	if(fd_stdin == -1) {
		if(fstdout)
			fprintf(fstdout, "INIT: open(\"/dev/console\", O_RDONLY) failed: %s\n", strerror(errno));
	} else {
		if(fd_stdin != 0) {
			dup2(fd_stdin, 0);
			close(fd_stdin);
		}
	}
	fd_stdout = open("/dev/console", O_WRONLY|O_NOCTTY);
	if(fd_stdout == -1) {
		if(fstdout)
			fprintf(fstdout, "INIT: open(\"/dev/console\", O_WRONLY) failed: %s\n", strerror(errno));
	} else { 
		if(fd_stdout != 1) {
			dup2(fd_stdout, 1);
			dup2(fd_stdout, 2);
			close(fd_stdout);
		}
	}

	if(fstdout)
		fprintf(fstdout, "INIT: now execing \"%s\"\n", initprg);
	sleep(1);

	if(fstdout) {
		fclose(fstdout);
		fstdout = NULL;
	}
	argv[0] = initprg;
	execve(initprg, argv, envp);
	
	open_console();

	if(fstdout) {
		fprintf(fstdout, "INIT: execve(\"%s\") failed: %s\n", initprg, strerror(errno));
	}
forever:
	if(fstdout) {
		fprintf(fstdout, "INIT: pid is %u\n", getpid());
		fprintf(fstdout, "INIT: boot cannot proceed from here.\n");
		fprintf(fstdout, "INIT: turn off the computer.\n");
	}
	while(1) sleep(1000);
	return 2;
}