iinitt.c
150 lines · 3625 bytes
1// Ilkay Alakay <ilkay@astronix.org>. Licensed under The Unlicense
2#include <stdio.h>
3#include <unistd.h>
4#include <sys/mount.h>
5#include <sys/wait.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <stdlib.h>
9#include <signal.h>
10#include <sys/reboot.h>
11#include <string.h>
12
13void start_service(char *path){
14 pid_t pid = fork();
15 if (pid < 0){
16 perror("fork failed");
17 return;
18 }
19 if (pid == 0) {
20 setsid();
21 execl(path, path, NULL);
22 perror("exec failed");
23 exit(1);
24 }
25}
26
27void start_dbus(){
28 pid_t pid = fork();
29 if (pid < 0) {
30 perror("fork failed");
31 return;
32 }
33 if (pid == 0){
34 setsid();
35 execl("/usr/bin/dbus-daemon", "dbus-daemon", "--system", "--nofork", NULL);
36 perror("dbus-daemon failed");
37 exit(1);
38 }
39}
40
41void start_getty(){
42 pid_t pid = fork();
43 if (pid < 0) {
44 perror("fork failed");
45 return;
46 }
47 if (pid == 0){
48 setsid();
49 execl("/sbin/agetty", "agetty", "--noreset", "--noclear",
50 "--issue-file=/etc/issue:/etc/issue.d:/run/issue.d:/usr/lib/issue.d - ${TERM}", NULL);
51 perror("agetty failed");
52 exit(1);
53 }
54}
55
56void do_reboot(){
57 write(1, "iinitt: rebooting...\n", strlen("iinitt: rebooting...\n"));
58 sync();
59 mount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
60 sync();
61 reboot(RB_AUTOBOOT);
62}
63
64void do_poweroff(){
65 write(1, "iinitt: shutting down root...\n", strlen("iinitt: shutting down root...\n"));
66 sync();
67 mount(NULL, "/", NULL, MS_REMOUNT | MS_RDONLY, NULL);
68 sync();
69 reboot(RB_POWER_OFF);
70}
71
72void handle_signal(int sig){
73 if (sig == SIGTERM){
74 do_poweroff();
75 }
76 if (sig == SIGINT){
77 do_reboot();
78 }
79}
80
81int main(){
82 signal(SIGPIPE, SIG_IGN);
83 signal(SIGTERM, handle_signal);
84 signal(SIGINT, handle_signal);
85 reboot(RB_ENABLE_CAD);
86
87 printf("\033[2J\033[H");
88 printf("iinitt v5.4.1: ilkay STARTING...\n");
89 umask(022);
90
91 if (mount(NULL, "/", NULL, MS_REMOUNT, NULL) < 0) {
92 perror("Failed to remount rootfs RW");
93 }
94 mount("proc", "/proc", "proc", 0, "");
95 mount("sysfs", "/sys", "sysfs", 0, "");
96 mount("devtmpfs", "/dev", "devtmpfs", 0, "");
97 mkdir("/run", 0755);
98 mount("tmpfs", "/run", "tmpfs", 0, "");
99 mkdir("/tmp", 1777);
100 mount("tmpfs", "/tmp", "tmpfs", 0, "");
101 mkdir("/run/dbus", 0755);
102 mkdir("/dev/pts", 0755);
103 mount("devpts", "/dev/pts", "devpts", 0, "");
104
105 pid_t udev_pid = fork();
106 if (udev_pid == 0){
107 execl("/sbin/udevd", "udevd", "--daemon", NULL);
108 perror("udevd");
109 exit(1);
110 }
111 sleep(1);
112 if (fork() == 0){
113 execl("/sbin/udevadm", "udevadm", "trigger", "--action=add", NULL);
114 perror("udevadm trigger");
115 exit(1);
116 }
117 wait(NULL);
118
119 if (fork() == 0){
120 execl("/sbin/udevadm", "udevadm", "settle", NULL);
121 perror("udevadm settle");
122 exit(1);
123 }
124 wait(NULL);
125
126 printf("Filesystems, eudev daemon and /run dir mounted/started successfully\n");
127
128 start_dbus();
129 sleep(1);
130
131 start_service("/usr/sbin/NetworkManager");
132 sleep(1);
133 start_service("/usr/libexec/elogind");
134 sleep(1);
135 start_service("/usr/bin/syslog-ng");
136 start_service("/usr/bin/chronyd");
137 start_service("/usr/bin/crond");
138 start_service("/bin/bash");
139
140 while (1){
141 pid_t pid;
142 int status;
143 while ((pid = waitpid(-1, &status, WNOHANG)) > 0){
144 printf("iinitt: process %d exited\n", pid);
145 }
146 sleep(1);
147 }
148
149 return 0;
150}