From 51396534298d6156fa41e5d992e42f315fcb51c8 Mon Sep 17 00:00:00 2001 From: PedroEdiaz Date: Wed, 1 Oct 2025 12:41:12 -0600 Subject: [PATCH] First commit --- .clang-format | 15 +++++++ .gitignore | 2 + LICENSE | 5 +++ Makefile | 12 ++++++ init.c | 49 +++++++++++++++++++++++ libexec/boot.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++ libexec/common.c | 57 +++++++++++++++++++++++++++ libexec/common.h | 23 +++++++++++ libexec/config.h | 27 +++++++++++++ libexec/shut.c | 23 +++++++++++ poweroff.c | 6 +++ 11 files changed, 319 insertions(+) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 init.c create mode 100644 libexec/boot.c create mode 100644 libexec/common.c create mode 100644 libexec/common.h create mode 100644 libexec/config.h create mode 100644 libexec/shut.c create mode 100644 poweroff.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..816917a --- /dev/null +++ b/.clang-format @@ -0,0 +1,15 @@ +# Tabs +UseTab: ForContinuationAndIndentation #ForIndentation +# Sized +TabWidth: 8 +IndentWidth: 8 +ContinuationIndentWidth: 8 + +# Column Limit +ColumnLimit: 80 + +# Functions +AllowAllArgumentsOnNextLine: false + +# Allman +BreakBeforeBraces: Allman diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1c2b822 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +**.o +poweroff diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fb0ec10 --- /dev/null +++ b/LICENSE @@ -0,0 +1,5 @@ +Copyright (c) 2025 by PedroEdiaz . + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2adb57e --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +OBJ = init.o libexec/boot.o libexec/shut.o libexec/common.o +BIN = init + +all: $(BIN) poweroff + +$(BIN): $(OBJ) + $(CC) $(LDFLAGS) -o $@ $(OBJ) $(LDLIBS) + +fmt: + clang-format -i *.c libexec/*.c +clean: + rm -f $(BIN) $(OBJ) diff --git a/init.c b/init.c new file mode 100644 index 0000000..f7a36bf --- /dev/null +++ b/init.c @@ -0,0 +1,49 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include + +void boot(void); +void shut(char); + +int main(void) +{ + int sig; + sigset_t set; + size_t i; + + if (getpid() != 1) + return 1; + + chdir("/"); + + sigfillset(&set); + sigprocmask(SIG_BLOCK, &set, NULL); + + nice(15); + boot(); + +restart: + while (1) + { + sigwait(&set, &sig); + + switch (sig) + { + case SIGUSR1: + shut('p'); + goto restart; + case SIGCHLD: + case SIGALRM: + while (waitpid(-1, NULL, WNOHANG) > 0) + ; + goto restart; + case SIGINT: + shut('r'); + goto restart; + } + } + + /* not reachable */ + return 0; +} diff --git a/libexec/boot.c b/libexec/boot.c new file mode 100644 index 0000000..232ced7 --- /dev/null +++ b/libexec/boot.c @@ -0,0 +1,100 @@ +#include "config.h" +void boot(void) +{ + log("Mounting pseudo filesystem..."); + { + mount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV, + NULL); + mount("sys", "/sys", "sysfs", MS_NOSUID | MS_NOEXEC | MS_NODEV, + NULL); + mount("cache", "/var/cache", "tmpfs", + MS_NOSUID | MS_NOEXEC | MS_NODEV, "mode=0777"); + mount("tmp", "/tmp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV, + "mode=0777"); + mount("run", "/run", "tmpfs", MS_NOSUID | MS_NODEV, + "mode=0777"); + mount("dev", "/dev", "devtmpfs", MS_NOSUID, "mode=0755"); + + mkdir("/dev/pts", 0755); + mkdir("/dev/shm", 0755); + mount("devpts", "/dev/pts", "devpts", MS_NOSUID | MS_NOEXEC, + "mode=0620,gid=5"); + mount("shm", "/dev/shm", "tmpfs", MS_NOSUID | MS_NODEV, + "mode=1777"); + + symlink("/proc/self/fd", "/dev/fd"); + symlink("fd/0", "/dev/stdin"); + symlink("fd/1", "/dev/stdout"); + symlink("fd/2", "/dev/stderr"); + + mkdir("/run/lock", 0755); + } + + log("Set up loopback..."); + { + int fd, i; + struct sockaddr_in *addr; + struct ifreq iface; + const char *ifname = "lo"; + + fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); + + iface.ifr_addr.sa_family = AF_INET; + for (i = 0; iface.ifr_name[i] = ifname[i]; ++i) + ; + + addr = (struct sockaddr_in *)&iface.ifr_addr; + + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = 0x0100007f; + ioctl(fd, SIOCSIFADDR, &iface); + + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = 0x0000ff; + ioctl(fd, SIOCSIFNETMASK, &iface); + + iface.ifr_flags |= (IFF_UP | IFF_RUNNING | IFF_LOOPBACK); + ioctl(fd, SIOCSIFFLAGS, &iface); + + close(fd); + } + + log("Setting hostname..."); + { + char buf[64]; + long result; + int input, output; + +#warning callback if HOSTNAME doesnot exists + input = open(HOSTFILE, O_RDONLY); + output = open("/proc/sys/kernel/hostname", O_WRONLY); + + while (result = read(input, buf, sizeof(buf))) + write(output, buf, result); + + close(input); + close(output); + } + log("Seeding urandom..."); + { + char buf[64]; + long result; + int input, output; + + output = open("/dev/urandom", O_WRONLY); + +#warning callback if input doesnot exists + if (input = open(SEEDFILE, O_RDONLY)) + ; + { + while (result = read(input, buf, sizeof(buf))) + write(output, buf, result); + } + + close(input); + close(output); + } + + log("Running programs..."); + runprgs((void *)boot_cmd, sizeof(boot_cmd) / sizeof(boot_cmd[0])); +} diff --git a/libexec/common.c b/libexec/common.c new file mode 100644 index 0000000..11e89c6 --- /dev/null +++ b/libexec/common.c @@ -0,0 +1,57 @@ +#include "config.h" + +int len(const char *msg) +{ + char *p; + for (p = (char *)msg; *p; ++p) + ; + return p - msg; +} + +void log(const char *msg) +{ + write(1, "=> ", 4); + write(1, msg, len(msg)); + write(1, "\n", 1); +} + +void runprgs(struct cmd *cmds, int n) +{ + int tty, i; + tty = open(LOGTO, O_WRONLY); + close(1); + close(2); + dup2(tty, 1); + dup2(tty, 2); + + for (i = 0; i < n; i++) + { + int pid; + + if (cmds[i].flags == RESPAWN) + { + if (fork()) + goto end; + } + + loop: + pid = fork(); + + if (!pid) + { + execve(cmds[i].args[0], cmds[i].args, NULL); + exit(1); + } + + switch (cmds[i].flags) + { + case RESPAWN: + waitpid(pid, NULL, 0); + sleep(1); + goto loop; + case WAIT: + wait4(pid, NULL, 0, NULL); + } + end:; + } +} diff --git a/libexec/common.h b/libexec/common.h new file mode 100644 index 0000000..eab1810 --- /dev/null +++ b/libexec/common.h @@ -0,0 +1,23 @@ +#define NOFLAGS 0b00 +#define WAIT 0b01 +#define RESPAWN 0b10 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct cmd +{ + char flags; + char *args[10]; +}; + +void log( const char * ); + +void runprgs( struct cmd * cmds, int n ); diff --git a/libexec/config.h b/libexec/config.h new file mode 100644 index 0000000..9074fbb --- /dev/null +++ b/libexec/config.h @@ -0,0 +1,27 @@ +#include "common.h" + +#define LOGTO "/dev/tty3" +#define SEEDFILE "/var/lib/init/seed" +#define HOSTFILE "/etc/hostname" + +static const +struct cmd boot_cmd[] = +{ + { WAIT, { "/bin/mount", "-a", NULL } }, + { WAIT, { "/bin/mount", "-o", "rw,remount", "/", NULL } }, + { NOFLAGS, { "/bin/smdev", "-s", NULL } }, +#if 0 + { NOFLAGS, { "/bin/alsactl", "restore", NULL } }, +#endif + { RESPAWN, { "/bin/agetty", "tty1", "38400", "linux", NULL } }, + { RESPAWN, { "/bin/agetty", "tty2", "38400", "linux", NULL } }, + { RESPAWN, { "/bin/nldev", NULL } }, + { RESPAWN, { "/bin/wsupp", "wlan0", NULL } }, +}; + +static const +struct cmd shut_cmd[] = +{ + { WAIT, { "/sbin/killall5", "9", NULL } }, + { WAIT, { "/sbin/umount", "-a", NULL } }, +}; diff --git a/libexec/shut.c b/libexec/shut.c new file mode 100644 index 0000000..4e02ce0 --- /dev/null +++ b/libexec/shut.c @@ -0,0 +1,23 @@ +#include "config.h" + +void shut(char c) +{ + log("Saving seed..."); + { + char buf[512]; + int input, output; + + input = open("/dev/urandom", O_RDONLY); + output = open(SEEDFILE, O_WRONLY); + + write(output, buf, read(input, buf, sizeof(buf))); + + close(input); + close(output); + } + + log("Running programs..."); + runprgs((void *)shut_cmd, sizeof(shut_cmd) / sizeof(shut_cmd[0])); + + reboot((c == 'r') ? RB_AUTOBOOT : RB_POWER_OFF); +} diff --git a/poweroff.c b/poweroff.c new file mode 100644 index 0000000..a314ef2 --- /dev/null +++ b/poweroff.c @@ -0,0 +1,6 @@ +#include + +int main(int argc, char *argv[]) +{ + return kill(1, (argv[0][0] == 'r') ? SIGINT : SIGUSR1); +}