/* * Copyright (C) 2000-2007 Proxmox Server Solutions GmbH. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include void exec_init (char *argv[], char *envp[]) { execve ("/sbin/init.org", argv, envp); execve ("/etc/init", argv, envp); execve ("/bin/init", argv, envp); exit (-1); // not reached } static int terminate = 0; void sigterm_handler (int signum) { terminate = 1; } int main (int argc, char *argv[], char *envp[]) { int pid; pid = getpid(); if (pid == 1) { if (mkfifo ("/var/log/init.fifo", 0644) != 0) { if (errno != EEXIST) { // perror ("unable to create fifo"); exec_init (argv, envp); // start without log } } char *envp[] = {"HOME=/", "TERM=linux", "CONSOLE=/var/log/init.fifo", NULL}; pid = fork (); if (pid > 0) { exec_init (argv, envp); } if (pid == 0) { // child struct sigaction act; int fd; int fifo; int len; char buf[4096]; char *txt; char txtbuf[4096]; sigemptyset(&act.sa_mask); act.sa_handler = sigterm_handler; act.sa_flags = SA_RESETHAND; sigaction(SIGTERM, &act, NULL); if ((fd = open("/var/log/init.log", O_CREAT|O_WRONLY|O_TRUNC, 0644)) == -1) { // perror ("unable to open '/var/log/init.log'"); exit (-1); } if ((fifo = open("/var/log/init.fifo", O_RDONLY)) == -1) { sprintf (txtbuf, "ERROR: unable to open fifo: %s\n", strerror(errno)); write (fd, txtbuf, strlen (txtbuf)); exit (-1); } while (1) { len = read (fifo, buf, 4096); if (terminate) { // got signal if (len > 0) { write (fd, buf, len); } break; } if (len == -1) { if (errno == EAGAIN || errno == EINTR) { continue; } sprintf (txtbuf, "ERROR: unable to read fifo: %s\n", strerror(errno)); write (fd, txtbuf, strlen (txtbuf)); break; } if (len == 0) { // EOF - try later sleep (1); continue; } write (fd, buf, len); } // terminated - just write a CR txt = "\n"; write (fd, txt, strlen (txt)); close (fifo); close (fd); } } else { // controll call (/sbin/telinit) exec_init (argv, envp); } exit (0); }