First commit
This commit is contained in:
11 files changed
+319
No files matched your search
@@ -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
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
**.o
|
||||||
|
poweroff
|
||||||
@@ -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.
|
||||||
@@ -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)
|
||||||
@@ -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
@@ -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]));
|
||||||
|
}
|
||||||
@@ -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:;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 );
|
||||||
@@ -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 } },
|
||||||
|
};
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
return kill(1, (argv[0][0] == 'r') ? SIGINT : SIGUSR1);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user