First commit

This commit is contained in:
PedroEdiaz
2025-10-01 12:41:12 -06:00
commit 5139653429
11 changed files with 319 additions and 0 deletions

15
.clang-format Normal file
View File

@@ -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

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
**.o
poweroff

5
LICENSE Normal file
View File

@@ -0,0 +1,5 @@
Copyright (c) 2025 by PedroEdiaz <ppedroediaz (at) gmail.com>.
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.

12
Makefile Normal file
View File

@@ -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)

49
init.c Normal file
View File

@@ -0,0 +1,49 @@
/* See LICENSE file for copyright and license details. */
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
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;
}

100
libexec/boot.c Normal file
View File

@@ -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]));
}

57
libexec/common.c Normal file
View File

@@ -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:;
}
}

23
libexec/common.h Normal file
View File

@@ -0,0 +1,23 @@
#define NOFLAGS 0b00
#define WAIT 0b01
#define RESPAWN 0b10
#include <unistd.h>
#include <fcntl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/reboot.h>
struct cmd
{
char flags;
char *args[10];
};
void log( const char * );
void runprgs( struct cmd * cmds, int n );

27
libexec/config.h Normal file
View File

@@ -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 } },
};

23
libexec/shut.c Normal file
View File

@@ -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);
}

6
poweroff.c Normal file
View File

@@ -0,0 +1,6 @@
#include <signal.h>
int main(int argc, char *argv[])
{
return kill(1, (argv[0][0] == 'r') ? SIGINT : SIGUSR1);
}