updated on Thu Jan 19 20:01:47 UTC 2012
[aur-mirror.git] / finit-arc / finit-arc.c
blob08ad5257650032ef7be6ee7b743cf4c5a24aa1e4
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <sys/mount.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include <signal.h>
9 #include <unistd.h>
10 #include <sys/reboot.h>
11 #include <sys/wait.h>
12 #include <linux/fs.h>
13 #include <utmp.h>
15 #include "helpers.h"
18 /* From sysvinit */
19 /* Set a signal handler. */
20 #define SETSIG(sa, sig, fun, flags) \
21 do { \
22 sa.sa_handler = fun; \
23 sa.sa_flags = flags; \
24 sigemptyset(&sa.sa_mask); \
25 sigaction(sig, &sa, NULL); \
26 } while (0)
30 #define INIT_MAGIC 0x03091969
31 #define INIT_CMD_RUNLVL 1
33 struct init_request {
34 int magic; /* Magic number */
35 int cmd; /* What kind of request */
36 int runlevel; /* Runlevel to change to */
37 int sleeptime; /* Time between TERM and KILL */
38 char data[368];
42 #define touch(x) mknod((x), S_IFREG|0644, 0)
43 #define chardev(x,m,maj,min) mknod((x), S_IFCHR|(m), makedev((maj),(min)))
44 #define blkdev(x,m,maj,min) mknod((x), S_IFBLK|(m), makedev((maj),(min)))
46 #define _d(x...) do { if (debug) { printf(x); printf("\n"); } } while (0)
48 #define LINE_SIZE 1024
49 #define CMD_SIZE 256
50 #define PARAMETER_SIZE 32
51 #define KEYMAP_SIZE 8
53 void shutdown(int);
54 void signal_handler(int);
55 void chld_handler(int);
56 int getparam(char line[], char parola[], int prefisso, int suffisso);
57 static int debug = 0;
60 /* Standard reboot/shutdown utilities talk to init using /dev/initctl.
61 * We should check if the fifo was recreated and reopen it.
63 static void listen_initctl()
65 if (!fork()) {
66 int ctl;
67 fd_set fds;
68 struct init_request request;
70 mkfifo("/dev/initctl", 0600);
71 ctl = open("/dev/initctl", O_RDONLY);
73 while (1) {
74 FD_ZERO(&fds);
75 FD_SET(ctl, &fds);
76 if (select(ctl + 1, &fds, NULL, NULL, NULL) <= 0)
77 continue;
79 read(ctl, &request, sizeof(request));
81 if (request.magic != INIT_MAGIC)
82 continue;
84 if (request.cmd == INIT_CMD_RUNLVL) {
85 switch (request.runlevel) {
86 case '0':
87 shutdown(SIGUSR2);
88 break;
89 case '6':
90 shutdown(SIGUSR1);
99 int main()
101 int i;
102 FILE *f;
103 char line[LINE_SIZE];
104 char LET[LINE_SIZE];
105 int SUMDEV = 0;
106 struct sigaction sa, act;
107 sigset_t nmask, nmask2;
108 char hostname[PARAMETER_SIZE];
109 char timezone[PARAMETER_SIZE];
110 char modules[PARAMETER_SIZE];
111 char *module;
112 char keymap[KEYMAP_SIZE] = "us";
113 char hardwareclock[PARAMETER_SIZE] = "localtime";
114 char cmd[CMD_SIZE];
116 //RUNLEVEL
117 struct utmp entry;
120 chdir("/");
121 umask(022);
124 * Signal management
126 for (i = 1; i < NSIG; i++)
127 SETSIG(sa, i, SIG_IGN, SA_RESTART);
129 SETSIG(sa, SIGINT, shutdown, 0);
130 SETSIG(sa, SIGPWR, SIG_IGN, 0);
131 SETSIG(sa, SIGUSR1, shutdown, 0);
132 SETSIG(sa, SIGUSR2, shutdown, 0);
133 SETSIG(sa, SIGTERM, SIG_IGN, 0);
134 SETSIG(sa, SIGALRM, SIG_IGN, 0);
135 SETSIG(sa, SIGHUP, SIG_IGN, 0);
136 SETSIG(sa, SIGCONT, SIG_IGN, SA_RESTART);
137 SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
139 /* Block sigchild while forking */
140 sigemptyset(&nmask);
141 sigaddset(&nmask, SIGCHLD);
142 sigprocmask(SIG_BLOCK, &nmask, NULL);
144 reboot(RB_DISABLE_CAD);
146 mount("none", "/proc", "proc", 0, NULL);
149 * Parse kernel parameters
151 if ((f = fopen("/proc/cmdline", "r")) != NULL) {
152 fgets(line, LINE_SIZE, f);
153 if ((strstr(line, "finit_debug"))) {
154 debug = 1;
156 if (strstr(line, "quiet")) {
157 close(0);
158 //close(1);
159 close(2);
161 fclose(f);
164 // puts("finit-arc " VERSION " (built " __DATE__ " " __TIME__ " by " WHOAMI ")");
166 puts("Finit-ARC - beta 0.2");
167 setsid();
169 mount("none", "/dev", "ramfs", 0, NULL);
170 mount("none", "/sys", "sysfs", 0, NULL);
171 mount("/mnt", "/", NULL, MS_MOVE, NULL);
173 //mount("none", "/dev", "tmpfs", 0, "mode=0755");
174 chardev("/dev/null", 0666, 1, 3);
175 chmod("/dev/null", 0666);
178 /* Create basic device nodes. */
179 if ((f = fopen("/etc/fstab", "r")) != NULL) {
180 *line = 0;
182 while (!feof(f)) {
183 fgets(line, LINE_SIZE, f);
185 if (getparam(line,"/dev/sd",0,0) == 0 )
187 SUMDEV = 0;
188 *LET = 0;
190 strcpy(LET,"/dev/sd");
191 strncat(LET,line,2);
193 if ((LET[7] == 'b'))
194 SUMDEV = 16;
195 if ((LET[7] == 'c'))
196 SUMDEV = 32;
197 if ((LET[7] == 'd'))
198 SUMDEV = 64;
200 blkdev(LET, 0660, 8, ((atoi(&LET[8]))+SUMDEV));
201 //printf("%s, 0660, 8, %d\n",LET,((atoi(&LET[8]))+SUMDEV));
203 if (getparam(line,"/dev/mmcblk0p",0,0) == 0 )
205 strcpy(LET,"/dev/mmcblk0p");
206 strncat(LET,line,1);
208 blkdev(LET, 0660, 179, ((atoi(&LET[13]))));
209 //printf("%s, 0660, 179, %d\n",LET,((atoi(&LET[13]))));
212 fclose(f);
218 * Parse configuration file
220 if ((f = fopen("/etc/rc.conf", "r")) != NULL) {
221 while (!feof(f)) {
222 fgets(line, LINE_SIZE, f);
224 if (getparam(line,"HARDWARECLOCK",2,1) == 0 ) {
225 *hardwareclock = 0;
226 strcpy(hardwareclock,line);
227 continue;
229 if (getparam(line,"KEYMAP",2,1) == 0 ) {
230 *keymap = 0;
231 strcpy(keymap,line);
232 continue;
234 if (getparam(line,"HOSTNAME",2,1) == 0 ) {
235 *hostname = 0;
236 strcpy(hostname,line);
237 continue;
239 if (getparam(line,"TIMEZONE",2,1) == 0 ) {
240 *timezone = 0;
241 strcpy(timezone,line);
242 continue;
244 if (getparam(line,"MODULES",2,1) == 0 ) {
245 *modules = 0;
246 strcpy(modules,line);
248 if((strlen(modules)) > 0)
250 if ((strstr(modules," ")) )
252 module = strtok(modules, " ");
253 while (module != NULL)
255 strcpy(cmd,"/sbin/modprobe ");
256 if (!(strstr(module,"!")))
258 strcat(cmd,module);
259 system(cmd);
261 module = strtok(NULL, " ");
263 } else {
264 if (!(strstr(modules,"!")))
266 strcpy(cmd,"/sbin/modprobe ");
267 strcat(cmd,modules);
268 system(cmd);
272 continue;
275 fclose(f);
280 * Set hwclock for fscheck
282 strcpy(cmd, "/sbin/hwclock --hctosys --");
283 if(((strcmp(hardwareclock,"UTC")) == 0))
284 strcpy(hardwareclock,"utc");
285 strcat(cmd,hardwareclock);
286 system(cmd);
287 //strcpy(SETCLOCK,cmd);
292 * Make standard devices
294 chardev("/dev/console", 0666, 5, 1);
295 chardev("/dev/urandom", 0666, 1, 9);
296 chardev("/dev/ptmx", 0666, 5, 2);
297 chardev("/dev/mem", 0640, 1, 1);
298 blkdev("/dev/loop0", 0600, 7, 0);
299 chardev("/dev/tty", 0666, 5, 0);
300 chardev("/dev/tty0", 0660, 4, 0);
301 chardev("/dev/tty1", 0660, 4, 1);
302 chardev("/dev/tty2", 0660, 4, 2);
303 chardev("/dev/tty3", 0660, 4, 3);
304 mkdir("/dev/vc", 0755);
305 chardev("/dev/vc/0", 0660, 4, 0);
306 chardev("/dev/vc/1", 0660, 4, 1);
307 chardev("/dev/vc/2", 0660, 4, 2);
308 chardev("/dev/vc/3", 0660, 4, 3);
309 mkdir("/dev/input", 0755);
310 chardev("/dev/input/mice", 0660, 13, 63);
311 chardev("/dev/input/event0", 0660, 13, 64);
316 system("/bin/mount -n -o remount,ro /");
319 * Filesystem check
321 system("/sbin/fsck -A -T -C -a");
325 * Remount root filesystems
327 mkdir("/dev/shm", 0755);
328 mkdir("/dev/pts", 0755);
329 system("/bin/mount -n -o remount,rw /");
330 umask(0);
334 * Mount local partitions
336 unlink("/etc/mtab");
337 //system("/bin/grep -e '/proc ' -e '/sys ' -e '/dev ' /proc/mounts >> /etc/mtab");
338 system("mount -a");
339 umask(0022);
343 * Set global path var
345 setenv("PATH","/bin:/usr/bin:/sbin:/usr/sbin:/usr/bin/perlbin/site:/usr/bin/perlbin/vendor:/usr/bin/perlbin/core",1);
349 * Time adjustments
351 if ((fd = open("/etc/adjtime", O_CREAT|O_WRONLY|O_TRUNC, 0644)) >= 0) {
352 write(fd, "0.0 0 0.0\n", 10);
353 close(fd);
355 if((strcmp(hardwareclock,"localtime")) == 0)
357 strcpy(cmd, "/bin/cp /usr/share/zoneinfo/");
358 strcpy(cmd, timezone);
359 build_cmd(cmd, " /etc/localtime", CMD_SIZE);
360 puts(cmd);
361 system(cmd);
363 system("/sbin/hwclock --adjust");
364 strcpy(cmd,SETCLOCK);
365 strcat(cmd, " &");
366 system(cmd);
371 * Network stuff
373 system("/sbin/ifconfig lo 127.0.0.1 up &");
376 /* RUNLEVEL */
377 memset(&entry, 0, sizeof(struct utmp));
378 entry.ut_type = RUN_LVL;
379 entry.ut_pid = '0' + 5;
380 setutent();
381 pututline(&entry);
382 endutent();
386 * Set random seed
388 copyfile("/var/lib/random-seed", "/dev/urandom", 0);
389 unlink("/var/lib/random-seed");
390 umask(077);
391 copyfile("/dev/urandom", "/var/lib/random-seed", 4096);
392 umask(0);
397 * Set hostname
399 sethostname(hostname, strlen(hostname));
403 * Set Keymap
405 strcpy(cmd, "/bin/loadkeys ");
406 strcat(cmd, keymap);
407 strcat(cmd, " &>/dev/null &");
408 system(cmd);
412 * Start getty terminal
414 system("/sbin/agetty -8 38400 vc/1 linux &");
415 system("/sbin/agetty -8 38400 vc/2 linux &");
419 * Leftover files
421 mount("none", "/var/lock", "tmpfs", 0, "mode=1777");
422 mount("none", "/tmp", "tmpfs", 0, "mode=1777,size=128m");
423 touch("/var/run/utmp");
424 chown("/var/run/utmp", 0, getgroup("utmp"));
425 chmod("/var/run/utmp", 0664);
429 * Misc setup
431 mkdir("/tmp/.X11-unix", 01777);
432 mkdir("/tmp/.ICE-unix", 01777);
433 umask(022);
436 if (!fork()) {
437 /* child process */
438 vhangup();
440 close(2);
441 close(1);
442 close(0);
444 if (open("/dev/tty1", O_RDWR) != 0)
445 exit(1);
447 sigemptyset(&act.sa_mask);
448 act.sa_handler = SIG_DFL;
450 sigemptyset(&nmask2);
451 sigaddset(&nmask2, SIGCHLD);
452 sigprocmask(SIG_UNBLOCK, &nmask2, NULL);
454 for (i = 1; i < NSIG; i++)
455 sigaction(i, &sa, NULL);
457 dup2(0, 0);
458 dup2(0, 1);
459 dup2(0, 2);
462 /* Listen initctl */
463 listen_initctl();
466 /* Prevents bash from running loadkeys */
467 unsetenv("TERM");
470 /* ConsoleKit needs this */
471 setenv("DISPLAY", ":0.0", 1);
474 /* Get action from /etc/finittab*/
475 if ((f = fopen("/etc/finittab", "r")) != NULL) {
476 while (!feof(f)) {
477 fgets(line, LINE_SIZE, f);
479 if (getparam(line,"level:",0,0) == 0 )
481 strcat(line," &");
482 system(line);
484 continue;
489 exit(0);
493 /* parent process */
494 system("/usr/sbin/start-services.sh &>/dev/null &");
497 while (1) {
498 sigemptyset(&nmask);
499 pselect(0, NULL, NULL, NULL, NULL, &nmask);
505 * Shut down on INT USR1 USR2
507 void shutdown(int sig)
510 system("/usr/sbin/stop-services.sh > /dev/null");
511 touch("/tmp/shutdown");
513 kill(-1, SIGTERM);
515 write(1, "\033[?25l\033[30;40m", 14);
516 sleep(2);
518 system("/usr/sbin/alsactl store > /dev/null 2>&1");
519 system("/sbin/hwclock --systohc --localtime");
521 kill(-1, SIGKILL);
523 sync();
524 sync();
525 system("/bin/umount -a;/bin/mount -n -o remount,ro /");
526 //system("/sbin/unionctl.static / --remove / > /dev/null 2>&1");
528 if (sig == SIGINT || sig == SIGUSR1)
529 reboot(RB_AUTOBOOT);
531 reboot(RB_POWER_OFF);
536 * SIGCHLD: one of our children has died
538 void chld_handler(int sig)
540 int status;
542 while (waitpid(-1, &status, WNOHANG) != 0) {
543 if (errno == ECHILD)
544 break;
548 int getparam(char line[], char parola[], int prefisso, int suffisso)
550 int present = 1;
551 if ((strstr(line,parola)) && ((strncmp(parola,line,(strlen(parola)))) == 0))
553 strncpy(line,&line[(strlen(parola))+prefisso],(strlen(line)));
554 line[((strlen(line))-(suffisso+1))]='\0';
555 present = 0;
558 return(present);