From a68a69b3fab1f2f35be22940f6151db90a8b8cc4 Mon Sep 17 00:00:00 2001 From: Nick Shipp Date: Wed, 18 Jan 2017 05:17:11 -0500 Subject: Major nshp rewrite --- sinit.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 114 insertions(+), 5 deletions(-) (limited to 'sinit.c') diff --git a/sinit.c b/sinit.c index 93f9925..6e3c5d8 100644 --- a/sinit.c +++ b/sinit.c @@ -1,18 +1,27 @@ /* See LICENSE file for copyright and license details. */ +#include #include #include +#include +#include +#include +#include +#include #include #include #include #include +#include #define LEN(x) (sizeof (x) / sizeof *(x)) static void sigpoweroff(void); static void sigreap(void); static void sigreboot(void); -static void spawn(char *const []); +static void spawn(int (*)(), char *const []); +static void spawn_as(uid_t, gid_t, char *const [], char *const []); +static void mounts(void); static struct { int sig; @@ -35,10 +44,24 @@ main(void) if (getpid() != 1) return 1; + +#ifdef PERF + spawn(NULL, perf); +#endif + chdir("/"); + sethostname(HOSTNAME, sizeof(HOSTNAME)-1); + mounts(); sigfillset(&set); sigprocmask(SIG_BLOCK, &set, NULL); - spawn(rcinitcmd); + ioctl(STDIN_FILENO, TIOCNOTTY, 0); + + for (i=0;i < LEN(init_procs);i++) { + spawn(init_procs[i].dep, init_procs[i].argv); + } + for (i=0;i < LEN(user_procs);i++) { + spawn_as(uid, gid, user_env, user_procs[i]); + } while (1) { sigwait(&set, &sig); for (i = 0; i < LEN(sigmap); i++) { @@ -52,10 +75,26 @@ main(void) return 0; } +static void +kill_wait(void) +{ + int i; + + for (i=0;i < 4 && kill(-1, i>=3 ? SIGKILL:SIGTERM) == 0;i++) { + /* printf("killall %d\n", i); */ + sleep(1); + } +} + static void sigpoweroff(void) { - spawn(rcpoweroffcmd); + sigprocmask(SIG_BLOCK, &set, NULL); + kill_wait(); + sync(); + reboot(RB_POWER_OFF); + /* only reachable on error */ + perror("poweroff"); } static void @@ -68,16 +107,31 @@ sigreap(void) static void sigreboot(void) { - spawn(rcrebootcmd); + sigprocmask(SIG_BLOCK, &set, NULL); + kill_wait(); + sync(); + reboot(RB_AUTOBOOT); + /* only reachable on error */ + perror("reboot"); } static void -spawn(char *const argv[]) +spawn(int (*dep)(), char *const argv[]) + { + struct timespec delay = { + .tv_nsec = 1000, + .tv_sec = 0, + }; + switch (fork()) { case 0: sigprocmask(SIG_UNBLOCK, &set, NULL); setsid(); + if (dep != NULL) { + while (!dep()) nanosleep(&delay, NULL); + } + /* printf("spawn: %s\n", argv[0]); */ execvp(argv[0], argv); perror("execvp"); _exit(1); @@ -85,3 +139,58 @@ spawn(char *const argv[]) perror("fork"); } } + +static void +spawn_as(uid_t uid, gid_t gid, char *const env[], char *const argv[]) +{ + /* printf("spawn_as %d,%d: %s\n", uid, gid, argv[0]); */ + switch (fork()) { + case 0: + chdir("/home/nick"); + sigprocmask(SIG_UNBLOCK, &set, NULL); + setsid(); + ioctl(STDIN_FILENO, TIOCSCTTY, 0); + setgid(gid); + setgroups(LEN(groups), groups); + setuid(uid); + execve(argv[0], argv, env); + perror("execve"); + _exit(1); + case -1: + perror("fork"); + } +} + +static void +mounts(void) +{ + int i; + mkdir("/dev/pts", 0755); + mkdir("/dev/shm", 0755); + for (i=0;i < LEN(static_mounts);i++) { + if (mount(static_mounts[i].source, + static_mounts[i].target, + static_mounts[i].type, + static_mounts[i].flags, + static_mounts[i].data) != 0) + { + warn("mount %s", static_mounts[i].target); + } + + } +} + +int +wpa_started(void) +{ + return ! access("/var/run/wpa_supplicant/wlan0", O_RDONLY); +} + +int +udev_settled(void) +{ + struct stat info; + if (stat("/dev/input/event4", &info)) + return 0; + return info.st_gid == 97; /* input group */ +} -- cgit v1.2.3-54-g00ecf