]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
simpleinit: remove this deprecated set of utils
authorKarel Zak <kzak@redhat.com>
Wed, 8 Jun 2011 11:20:37 +0000 (13:20 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 8 Jun 2011 11:20:37 +0000 (13:20 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
15 files changed:
Makefile.am
configure.ac
simpleinit/.gitignore [deleted file]
simpleinit/Makefile.am [deleted file]
simpleinit/fastboot.8 [deleted file]
simpleinit/fasthalt.8 [deleted file]
simpleinit/halt.8 [deleted file]
simpleinit/initctl.8 [deleted file]
simpleinit/initctl.c [deleted file]
simpleinit/reboot.8 [deleted file]
simpleinit/shutdown.8 [deleted file]
simpleinit/shutdown.c [deleted file]
simpleinit/simpleinit.8 [deleted file]
simpleinit/simpleinit.c [deleted file]
simpleinit/simpleinit.h [deleted file]

index 5e20294739e4db686cb167aac2f8e09dd015e61f..a0271b71961c8b202eb2d84c4aa0123f07ea75c0 100644 (file)
@@ -45,10 +45,6 @@ if BUILD_PARTX
 SUBDIRS += partx
 endif
 
-if BUILD_INIT
-SUBDIRS += simpleinit
-endif
-
 if BUILD_MOUNT
 SUBDIRS += mount
 endif
@@ -96,7 +92,7 @@ checkconfig:
 
 
 ENABLE_ALL = --enable-static-programs \
- --enable-elvtune --enable-init --enable-kill --enable-last \
+ --enable-elvtune --enable-kill --enable-last \
  --enable-mesg --enable-partx --enable-raw --enable-rdev --enable-reset \
  --enable-login-utils --enable-write --enable-arch --enable-mount
 
index ba048d146414d6cd5ec7d361fbb6b094bbf95249..12a45e619e7808d0958bce85cbc198ccfc092f23 100644 (file)
@@ -968,14 +968,6 @@ AC_ARG_ENABLE([elvtune],
 )
 AM_CONDITIONAL(BUILD_ELVTUNE, test "x$enable_elvtune" = xyes)
 
-
-AC_ARG_ENABLE([init],
-  AS_HELP_STRING([--enable-init], [build simpleinit, shutdown, initctl]),
-  [], enable_init=no
-)
-AM_CONDITIONAL(BUILD_INIT, test "x$enable_init" = xyes)
-
-
 AC_ARG_ENABLE([kill],
   AS_HELP_STRING([--enable-kill], [build kill]),
   [], enable_kill=no
@@ -1223,7 +1215,6 @@ fsck/Makefile
 getopt/Makefile
 hwclock/Makefile
 include/Makefile
-simpleinit/Makefile
 lib/Makefile
 login-utils/Makefile
 Makefile
diff --git a/simpleinit/.gitignore b/simpleinit/.gitignore
deleted file mode 100644 (file)
index f99b58a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-initctl
-shutdown
-simpleinit
diff --git a/simpleinit/Makefile.am b/simpleinit/Makefile.am
deleted file mode 100644 (file)
index f1e4996..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-include $(top_srcdir)/config/include-Makefile.am
-
-sbin_PROGRAMS = simpleinit shutdown initctl
-dist_man_MANS = fastboot.8 fasthalt.8 halt.8 reboot.8 simpleinit.8 shutdown.8 \
-       initctl.8
-
-simpleinit_SOURCES = simpleinit.c simpleinit.h
-initctl_SOURCES = initctl.c simpleinit.h
-
-if NEED_LIBCRYPT
-simpleinit_LDADD = -lcrypt
-endif
-
-install-exec-hook::
-       cd $(DESTDIR)$(sbindir) && ln -sf shutdown reboot
-       cd $(DESTDIR)$(sbindir) && ln -sf shutdown fastboot
-       cd $(DESTDIR)$(sbindir) && ln -sf shutdown halt
-       cd $(DESTDIR)$(sbindir) && ln -sf shutdown fasthalt
-       cd $(DESTDIR)$(sbindir) && ln -sf initctl need
-       cd $(DESTDIR)$(sbindir) && ln -sf initctl display-services
-       cd $(DESTDIR)$(sbindir) && ln -sf initctl provide
-
-install-data-hook:
-       cd $(DESTDIR)$(mandir)/man8 && ln -sf initctl.8 need.8
-       cd $(DESTDIR)$(mandir)/man8 && ln -sf initctl.8 display-services.8
-       cd $(DESTDIR)$(mandir)/man8 && ln -sf initctl.8 provide.8
-
diff --git a/simpleinit/fastboot.8 b/simpleinit/fastboot.8
deleted file mode 100644 (file)
index 386d971..0000000
+++ /dev/null
@@ -1 +0,0 @@
-.so man8/shutdown.8
diff --git a/simpleinit/fasthalt.8 b/simpleinit/fasthalt.8
deleted file mode 100644 (file)
index 386d971..0000000
+++ /dev/null
@@ -1 +0,0 @@
-.so man8/shutdown.8
diff --git a/simpleinit/halt.8 b/simpleinit/halt.8
deleted file mode 100644 (file)
index 386d971..0000000
+++ /dev/null
@@ -1 +0,0 @@
-.so man8/shutdown.8
diff --git a/simpleinit/initctl.8 b/simpleinit/initctl.8
deleted file mode 100644 (file)
index 7e92dea..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-.\" Copyright (C) 2000-2001  Richard Gooch
-.\"
-.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-.\"
-.\" Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
-.\" The postal address is:
-.\"   Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
-.\"
-.\"    initctl.8               Richard Gooch   21-FEB-2001
-.\"
-.TH INITCTL 8 "21 Feb 2001" "Util-Linux Package"
-.SH NAME
-initctl \- utility to control simpleinit(8)
-.SH SYNOPSIS
-.B need
-.RB [ \-r ]
-.I service
-.br
-.B display-services
-.br
-.B provide
-.I service
-.SH OVERVIEW
-The \fBinitctl\fP programme is designed to help improve the
-robustness, scalability and readability of system boot scripts. It is
-now possible to write a modularised set of boot scripts without the
-complex and fragile numbered symlink scheme used in SysV-style boot
-scripts. Each script can simply declare, using \fBneed\fP(8), what
-must run before them.
-.SH DESCRIPTION for need
-The \fBneed\fP programme is a utility that tells \fBsimpleinit\fP(8)
-to start a \fIservice\fP (usually a script in \fI/sbin/init.d\fP) and
-will wait for the service to become available. If the service is
-already available, it will not be started again.
-
-The \fB-r\fP option is used to tell \fBsimpleinit\fP(8) to "roll back"
-(stop) services up to (but not including) \fIservice\fP. If
-\fIservice\fP is not specified, all services are stopped. The \fB-r\fP
-option thus allows the system to be partially or wholly shut down in
-an orderly fashion. The \fBshutdown\fP(8) programme still needs to be
-run.
-
-.SH DESCRIPTION for display-services
-When invoked as \fBdisplay-services\fP it will write the list of
-currently available services and the list of failed services to the
-standard output.
-
-.SH DESCRIPTION for provide
-When invoked as \fBprovide\fP it tells \fBsimpleinit\fP(8) that the
-parent (calling) process will be providing a service with name
-\fIservice\fP. If the calling process exits successfully (status 0)
-the service is deemed to be available. Only one instance of
-\fIservice\fP may be started, so alternate providers will block and
-may fail.
-
-Using \fBprovide\fP it is possible to have multiple potential
-providers for the same (generic) service (e.g. \fBsendmail\fP and
-\fBqmail\fP both provide a \fBmta\fP service), where only one actually
-provides the service. This may be used by service startup scripts
-which check for configuration files.
-.SH EXIT CODE
-The exit code from \fBneed\fP is 0 if the service was successfully
-started, 1 if the service failed badly, and 2 if the service is
-unavailable (i.e. disabled in configuration files). These exit codes
-reflect the exit codes from the service startup scripts.
-
-The exit code from \fBneed -r\fP is 0 if the service was successfully
-stopped, 1 if the service could not be stopped, and 2 if the service
-was not available to start with. The service shutdown scripts may only
-return 0 (for success) or 1 (for failure).
-
-The exit code from \fBprovide\fP is 0 if the service may be provided,
-1 if it may not, and 2 if the parent process is not a child of
-init. It may block waiting for another provider which is initialising
-the service.
-.SH SIGNALS
-\fBinitctl\fP(8) uses \fBSIGUSR1\fP, \fBSIGUSR2\fP and \fBSIGPOLL\fP
-for communication with \fBsimpleinit\fP(8). Don't send these signals
-to it.
-.SH FILES
-.PD 0
-.TP 20
-.BI /dev/initctl
-This is the control FIFO, created by \fBsimpleinit\fP(8), which
-\fBinitctl\fP(8) writes commands to.
-.SH SEE ALSO
-.BR simpleinit (8),
-.BR init (8)
-.PP
-A more complete discussion of the new boot script system, based on
-\fBneed\fP(8), is available from:
-http://www.atnf.csiro.au/~rgooch/linux/boot-scripts/
-.SH AUTHOR
-Richard Gooch (rgooch@atnf.csiro.au)
-
-.SH AVAILABILITY
-The initctl command is part of the util-linux package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/simpleinit/initctl.c b/simpleinit/initctl.c
deleted file mode 100644 (file)
index 3b38b49..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/*  initctl.c
-
-    Source file for  initctl  (init(8) control tool).
-
-    Copyright (C) 2000  Richard Gooch
-
-    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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-    Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
-    The postal address is:
-      Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
-*/
-
-/*
-    This tool will send control messages to init(8). For example, it may
-    request init(8) to start a service and will wait for that service to be
-    available. If the service is already available, init(8) will not start it
-    again.
-    This tool may also be used to inspect the list of currently available
-    services.
-
-
-    Written by      Richard Gooch   28-FEB-2000
-
-    Updated by      Richard Gooch   11-OCT-2000: Added provide support.
-
-    Last updated by Richard Gooch   6-NOV-2000: Renamed to initctl.c
-
-
-*/
-#include <unistd.h>
-#include <stdio.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include "simpleinit.h"
-
-
-static void signal_handler (int sig);
-
-
-static int caught_signal = 0;
-
-
-int main (int argc, char **argv)
-{
-    int fd, nbytes;
-    struct sigaction sa;
-    sigset_t ss;
-    char *ptr;
-    long *buffer;
-    struct command_struct *command;
-
-    buffer = calloc(COMMAND_SIZE / sizeof (long) + 1, sizeof(long));
-    if (!buffer) {
-           fprintf (stderr, "Unable allocate buffer for command\n");
-           exit(1);
-    }
-    command = (struct command_struct *) buffer;
-
-    sigemptyset (&ss);
-    sigaddset (&ss, SIG_PRESENT);
-    sigaddset (&ss, SIG_NOT_PRESENT);
-    sigaddset (&ss, SIG_FAILED);
-    sigprocmask (SIG_BLOCK, &ss, NULL);
-    sigemptyset (&sa.sa_mask);
-    sa.sa_flags = 0;
-    sa.sa_handler = signal_handler;
-    sigaction (SIG_PRESENT, &sa, NULL);
-    sigaction (SIG_NOT_PRESENT, &sa, NULL);
-    sigaction (SIG_FAILED, &sa, NULL);
-    command->pid = getpid ();
-    command->ppid = getppid ();
-    if ( ( ptr = strrchr (argv[0], '/') ) == NULL ) ptr = argv[0];
-    else ++ptr;
-    /*  First generate command number by looking at invocation name  */
-    if (strcmp (ptr, "display-services") == 0)
-       command->command = COMMAND_DUMP_LIST;
-    else if (strcmp (ptr, "need") == 0) command->command = COMMAND_NEED;
-    else if (strcmp (ptr, "provide") == 0) command->command = COMMAND_PROVIDE;
-    else command->command = COMMAND_TEST;
-    /*  Now check for switches  */
-    if ( (argc > 1) && (argv[1][0] == '-') )
-    {
-       switch (argv[1][1])
-       {
-         case 'n':
-           command->command = COMMAND_NEED;
-           break;
-         case 'r':
-           command->command = COMMAND_ROLLBACK;
-           break;
-         case 'd':
-           command->command = COMMAND_DUMP_LIST;
-           break;
-         case 'p':
-           command->command = COMMAND_PROVIDE;
-           break;
-         default:
-           fprintf (stderr, "Illegal switch: \"%s\"\n", argv[1]);
-           exit (1);
-           /*break;*/
-       }
-       --argc;
-       ++argv;
-    }
-    switch (command->command)
-    {
-      case COMMAND_NEED:
-      case COMMAND_PROVIDE:
-       if (argc < 2)
-       {
-           fprintf (stderr, "Usage:\tneed|provide programme\n");
-           exit (1);
-       }
-       /*  Fall through  */
-      case COMMAND_ROLLBACK:
-       if (argc > 1) strcpy (command->name, argv[1]);
-       else command->name[0] = '\0';
-       break;
-      case COMMAND_DUMP_LIST:
-       if (tmpnam (command->name) == NULL)
-       {
-           fprintf (stderr, "Unable to create a unique filename\t%s\n",
-                    ERRSTRING);
-           exit (1);
-       }
-       if (mkfifo (command->name, S_IRUSR) != 0)
-       {
-           fprintf (stderr, "Unable to create FIFO: \"%s\"\t%s\n",
-                    command->name, ERRSTRING);
-           exit (1);
-       }
-       break;
-    }
-    if ( ( fd = open ("/dev/initctl", O_WRONLY, 0) ) < 0 )
-    {
-       fprintf (stderr, "Error opening\t%s\n", ERRSTRING);
-       exit (1);
-    }
-    if (write (fd, buffer, COMMAND_SIZE) < COMMAND_SIZE)
-    {
-       fprintf (stderr, "Error writing\t%s\n", ERRSTRING);
-       exit (1);
-    }
-    close (fd);
-    if (command->command != COMMAND_DUMP_LIST)
-    {
-       sigemptyset (&ss);
-       while (caught_signal == 0) sigsuspend (&ss);
-       switch (command->command)
-       {
-         case COMMAND_PROVIDE:
-           switch (caught_signal)
-           {
-             case SIG_PRESENT:
-               return 1;
-             case SIG_NOT_PRESENT:
-               return 0;
-             case SIG_NOT_CHILD:
-               fprintf (stderr, "Error\n");
-               return 2;
-             default:
-               return 3;
-           }
-           break;
-         default:
-           switch (caught_signal)
-           {
-             case SIG_PRESENT:
-               return 0;
-             case SIG_NOT_PRESENT:
-               return 2;
-             case SIG_FAILED:
-               return 1;
-             default:
-               return 3;
-           }
-           break;
-       }
-       return 3;
-    }
-    /*  Read back the data and display it  */
-    if ( ( fd = open (command->name, O_RDONLY, 0) ) < 0 )
-    {
-       fprintf (stderr, "Error opening:\"%s\"\t%s\n",
-                command->name, ERRSTRING);
-       exit (1);
-    }
-    unlink (command->name);
-    fflush (stdout);
-    while ( ( nbytes = read (fd, buffer, COMMAND_SIZE) ) > 0 )
-       write (1, buffer, nbytes);
-    close (fd);
-    return (0);
-}   /*  End Function main  */
-
-static void signal_handler (int sig)
-{
-    caught_signal = sig;
-}   /*  End Function signal_handler  */
diff --git a/simpleinit/reboot.8 b/simpleinit/reboot.8
deleted file mode 100644 (file)
index 386d971..0000000
+++ /dev/null
@@ -1 +0,0 @@
-.so man8/shutdown.8
diff --git a/simpleinit/shutdown.8 b/simpleinit/shutdown.8
deleted file mode 100644 (file)
index 371310b..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-.\" Copyright 1992 Rickard E. Faith (faith@cs.unc.edu)
-.\" May be distributed under the GNU General Public License
-.\"
-.\"
-.TH SHUTDOWN 8 "2 March 2000" "Linux 2.0" "Linux Programmer's Manual"
-.SH NAME
-shutdown \- close down the system
-.SH SYNOPSIS
-.B shutdown
-.RB [ \-h | \-r ]
-.RB [ \-fqs ]
-.RB [ now | \fIhh\fP:\fIss\fP | +\fImins\fP ]
-.RI [ message ]
-.br
-.B reboot
-.RB [ \-h | \-r ]
-.RB [ \-fqs ]
-.RB [ now | \fIhh\fP:\fIss\fP | +\fImins\fP ]
-.RI [ message ]
-.br
-.B fastboot
-.RB [ \-h | \-r ]
-.RB [ \-fqs ]
-.RB [ now | \fIhh\fP:\fIss\fP | +\fImins\fP ]
-.RI [ message ]
-.br
-.B halt
-.RB [ \-h | \-r ]
-.RB [ \-fqs ]
-.RB [ now | \fIhh\fP:\fIss\fP | +\fImins\fP ]
-.RI [ message ]
-.br
-.B fasthalt
-.RB [ \-h | \-r ]
-.RB [ \-fqs ]
-.RB [ now | \fIhh\fP:\fIss\fP | +\fImins\fP ]
-.RI [ message ]
-.SH DESCRIPTION
-.\" " for emacs hilit19
-In general,
-.B shutdown
-prepares the system for a power down or reboot.  A absolute or delta time
-can be given, and periodic messages will be sent to all users warning of
-the shutdown. If no message is specified on the command line,
-.B shutdown
-will ask for a message to be sent, unless the
-.B \-q
-option is set.
-
-.B halt
-is the same as
-.B "shutdown -h -q now"
-
-.B fasthalt
-is the same as
-.B "shutdown -h -q -f now"
-
-.B reboot
-is the same as
-.B "shutdown -r -q now"
-
-.B fastboot
-is the same as
-.B "shutdown -r -q -f now"
-
-The default delta time, if none is specified, is 2 minutes.
-
-Five minutes before shutdown (or immediately, if shutdown is less than five
-minutes away), the
-.I /etc/nologin
-file is created with a message stating that the system is going down and
-that logins are no longer permitted.  The
-.BR login (1)
-program will not allow non-superusers to login during this period.  A
-message will be sent to all users at this time.
-
-When the shutdown time arrives,
-.B shutdown
-notifies all users, tells
-.BR init (8)
-not to spawn more
-.BR getty (8)'s,
-writes the shutdown time into the
-.I /var/log/wtmp
-file, kills all other processes on the system,
-.BR sync (2)'s,
-unmounts all the disks,
-.BR sync (2)'s
-again, waits for a second, and then either terminates or reboots the
-system.
-
-Prior to unmounting all discs, the \fBSIGQUIT\fP signal is sent to the
-\fBinit\fP process, which will in turn exec \fBshutdown\fP(8). This
-allows for clean unmounting, even if the old inode for the \fBinit\fP
-process was unlinked. If the current process ID (PID) equals 1, then
-\fBshutdown\fP(8) will pause forever.
-.SH OPTIONS
-.TP
-.B \-h
-Halt the system.  Do not reboot.  This option is used when powering down
-the system.
-.TP
-.B \-r
-Reboot the system.
-.TP
-.B \-f
-Fast.  When the system is rebooted, the file systems will not be checked.
-This is arranged by creating
-.IR /fastboot ,
-which
-.I /etc/rc
-must detect (and delete).
-.TP
-.B \-q
-Quiet.  This uses a default broadcast message, and does not prompt the user
-for one.
-.TP
-.B \-s
-Reboot in single user mode.  This is arranged by creating
-.IR /etc/singleboot ,
-which
-.BR simpleinit (8)
-detects (and deletes).
-.SH FILES
-.nf
-.I /etc/rc
-.I /fastboot
-.I /etc/singleboot
-.I /etc/nologin
-.I /var/log/wtmp
-.I /etc/shutdown.conf
-.fi
-.SH CONFIG
-The configuration file \fI/etc/shutdown.conf\fP is used to determine
-the action to take when halting the machine. The currently supported
-file format is extremely primitive. The first line must contain two
-strings separated by whitespace. The first string must be
-\fBHALT_ACTION\fP and the second specifies the action you wish to take
-on halt. The options allowed are:
-.TP
-.B halt
-This will simply halt the system. This is the default behaviour.
-Note also that this is the fallback if another option fails.
-.TP
-.B power_off
-This will use the kernel power shutdown facility. This is usually only
-available on machines with Advanced Power Management (APM).
-.TP
-.I programname
-This specifies a command to run to shut down the power. The first
-character must be a "/". Bear in mind that this command will be run
-with only the root filesystem mounted (and it will be read-only), and
-no daemons running.
-.SH "SEE ALSO"
-.BR umount (8),
-.BR login (1),
-.BR reboot (2),
-.BR simpleinit (8),
-.BR init (8)
-.SH BUGS
-Unlike the BSD
-.BR shutdown ,
-users are notified of shutdown only once or twice, instead of many times,
-and at shorter and shorter intervals as "apocalypse approaches."
-Some would construe this as a feature.
-.SH AUTHOR
-This page documents the version of
-.B shutdown
-originally written by Peter Orbaek (poe@daimi.aau.dk).
diff --git a/simpleinit/shutdown.c b/simpleinit/shutdown.c
deleted file mode 100644 (file)
index 9bb121c..0000000
+++ /dev/null
@@ -1,747 +0,0 @@
-/* shutdown.c - shutdown a Linux system
- * Initially written by poe@daimi.aau.dk 
- * Currently maintained at ftp://ftp.daimi.aau.dk/pub/Software/Linux/
- */
-
-/*
- * Modified by jrs@world.std.com to try to exec "umount -a" and if
- * that doesn't work, then umount filesystems ourselves in reverse
- * order.  The old-way was in forward order.  Also if the device
- * field of the mtab does not start with a "/" then give umount
- * the mount point instead.  This is needed for the nfs and proc
- * filesystems and yet is compatible with older systems.
- *
- * We also use the mntent library interface to read the mtab file
- * instead of trying to parse it directly and no longer give a
- * warning about not being able to umount the root.
- *
- * The reason "umount -a" should be tried first is because it may do
- * special processing for some filesystems (such as informing an
- * nfs server about nfs umounts) that we don't want to cope with here.
- */
-
-/*
- * Various changes and additions to resemble SunOS 4 shutdown/reboot/halt(8)
- * more closely by Scott Telford (s.telford@ed.ac.uk) 93/05/18.
- * (I butchered Scotts patches somewhat. - poe)
- *
- * Changes by Richard Gooch <rgooch@atnf.csiro.au> (butchered by aeb)
- * introducing shutdown.conf.
- *
- * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
- * - added Native Language Support
- *
- * 2000-03-02 Richard Gooch <rgooch@atnf.csiro.au>
- * - pause forever if (pid == 1) and send SIGQUIT to pid = 1
- *
- * 2000-11-04 Richard Gooch <rgooch@atnf.csiro.au>
- * - continue reaping if (pid == 1)
- *
- * 2000-11-06 Richard Gooch <rgooch@atnf.csiro.au>
- * - shut down "finalprog" from /etc/inittab
- * - kill normal user (non-root and non-daemon) processes first with SIGTERM
- *
- * 2000-11-08 Richard Gooch <rgooch@atnf.csiro.au>
- * - rollback services
- * - do not unmount devfs (otherwise get harmless but annoying messages)
- * - created syncwait() for faster shutting down
- * - kill getty processes
- * 2001-05-12 Richard Gooch <rgooch@atnf.csiro.au>
- * - unblock all signals (sigmask from simpleinit(8) stopped sleep(3))
- * - close all files
- */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <utmp.h>
-#include <time.h>
-#include <string.h>
-#include <ctype.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/param.h>
-#include <termios.h>
-#include <mntent.h>
-#include <sys/mount.h>
-#include <sys/wait.h>
-#include <syslog.h>
-#include <sys/resource.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include "linux_reboot.h"
-#include "pathnames.h"
-#include "strutils.h"
-#include "nls.h"
-#include "usleep.h"
-
-static void usage(void), int_handler(int), write_user(struct utmp *);
-static void wall(void), write_wtmp(void), unmount_disks(void);
-static void unmount_disks_ourselves(void);
-static void swap_off(void), do_halt(char *);
-static void kill_mortals (int sig);
-static void stop_finalprog (void);
-static void syncwait (int timeval);
-
-
-char   *prog;          /* name of the program */
-int    opt_reboot;     /* true if -r option or reboot command */
-int    timeout;        /* number of seconds to shutdown */
-int    opt_quiet;      /* true if no message is wanted */
-int    opt_fast;       /* true if fast boot */
-char   message[90];    /* reason for shutdown if any... */
-int    opt_single = 0; /* true is we want to boot singleuser */
-char   *whom;          /* who is shutting the system down */
-int    opt_msgset = 0; /* message set on command line */
-                       /* change 1 to 0 if no file is to be used by default */
-int    opt_use_config_file = 1;        /* read _PATH_SHUTDOWN_CONF */
-char   halt_action[256];               /* to find out what to do upon halt */
-
-/* #define DEBUGGING */
-
-#define WR(s) write(fd, s, strlen(s))
-#define WRCRLF write(fd, "\r\n", 2)
-#define ERRSTRING strerror(errno)
-
-#define UMOUNT_ARGS            "umount", "-a", "-t", "nodevfs,devtmpfs"
-#define SWAPOFF_ARGS            "swapoff", "-a"
-
-void
-usage(void)
-{
-       fprintf(stderr,
-               _("Usage: shutdown [-h|-r] [-fqs] [now|hh:ss|+mins]\n"));
-       exit(EXIT_FAILURE);
-}
-
-static void
-my_puts(char *s)
-{
-       /* Use a fresh stdout after forking */
-       freopen(_PATH_CONSOLE, "w", stdout);
-       puts(s);
-       fflush(stdout);
-}
-
-void
-int_handler(int sig)
-{
-       unlink(_PATH_NOLOGIN);
-       signal(SIGINT, SIG_DFL);
-       my_puts(_("Shutdown process aborted"));
-       _exit(EXIT_FAILURE);
-}
-
-static int
-iswhitespace(int a) {
-       return (a == ' ' || a == '\t');
-}
-
-int
-main(int argc, char *argv[])
-{
-       int c, i, fd;
-       char *ptr;
-
-       i = getdtablesize ();
-       for (fd = 3; fd < i; fd++) close (fd);
-       if (getpid () == 1)
-       {
-           for (fd = 0; fd < 3; fd++) close (fd);
-           while (1) wait (NULL);  /*  Grim reaper never stops  */
-       }
-       sigsetmask (0); /*  simpleinit(8) blocks all signals: undo for ALRM  */
-       for (i = 1; i < NSIG; i++) signal (i, SIG_DFL);
-
-        setlocale(LC_ALL, "");
-        bindtextdomain(PACKAGE, LOCALEDIR);
-        textdomain(PACKAGE);
-
-#ifndef DEBUGGING
-       if(setreuid (0, 0))
-               errx(EXIT_FAILURE, _("only root can shut a system down."));
-#endif
-
-       if(*argv[0] == '-') argv[0]++;  /* allow shutdown as login shell */
-       prog = argv[0];
-       if((ptr = strrchr(argv[0], '/'))) prog = ++ptr;
-
-       /* All names (halt, reboot, fasthalt, fastboot, shutdown)
-          refer to the same program with the same options,
-          only the defaults differ. */
-       if(!strcmp("halt", prog)) {
-               opt_reboot = 0;
-               opt_quiet = 1;
-               opt_fast = 0;
-               timeout = 0;
-       } else if(!strcmp("fasthalt", prog)) {
-               opt_reboot = 0;
-               opt_quiet = 1;
-               opt_fast = 1;
-               timeout = 0;
-       } else if(!strcmp("reboot", prog)) {
-               opt_reboot = 1;
-               opt_quiet = 1;
-               opt_fast = 0;
-               timeout = 0;
-       } else if(!strcmp("fastboot", prog)) {
-               opt_reboot = 1;
-               opt_quiet = 1;
-               opt_fast = 1;
-               timeout = 0;
-       } else {
-               /* defaults */
-               opt_reboot = 0;
-               opt_quiet = 0;
-               opt_fast = 0;
-               timeout = 2*60;
-       }
-
-       c = 0;
-       while(++c < argc) {
-               if(argv[c][0] == '-') {
-                       for(i = 1; argv[c][i]; i++) {
-                               switch(argv[c][i]) {
-                               case 'C':
-                                       opt_use_config_file = 1;
-                                       break;
-                               case 'h':
-                                       opt_reboot = 0;
-                                       break;
-                               case 'r':
-                                       opt_reboot = 1;
-                                       break;
-                               case 'f':
-                                       opt_fast = 1;
-                                       break;
-                               case 'q':
-                                       opt_quiet = 1;
-                                       break;
-                               case 's':
-                                       opt_single = 1;
-
-                               default:
-                                       usage();
-                               }
-                       }
-               } else if(!strcmp("now", argv[c])) {
-                       timeout = 0;
-               } else if(argv[c][0] == '+') {
-                       timeout = 60 * atoi(&argv[c][1]);
-               } else if (isdigit(argv[c][0])) {
-                       char *colon;
-                       int hour = 0;
-                       int minute = 0;
-                       time_t tics;
-                       struct tm *tt;
-                       int now, then;
-
-                       if((colon = strchr(argv[c], ':'))) {
-                               *colon = '\0';
-                               hour = atoi(argv[c]);
-                               minute = atoi(++colon);
-                       } else usage();
-
-                       (void) time(&tics);
-                       tt = localtime(&tics);
-
-                       now = 3600 * tt->tm_hour + 60 * tt->tm_min;
-                       then = 3600 * hour + 60 * minute;
-                       timeout = then - now;
-                       if(timeout < 0)
-                               errx(EXIT_FAILURE, _("that must be tomorrow, "
-                                                 "can't you wait till then?"));
-               } else {
-                       xstrncpy(message, argv[c], sizeof(message));
-                       opt_msgset = 1;
-               }
-       }
-
-       halt_action[0] = 0;
-
-       /* No doubt we shall want to extend this some day
-          and register a series of commands to be executed
-          at various points during the shutdown sequence,
-          and to define the number of milliseconds to sleep, etc. */
-       if (opt_use_config_file) {
-               char line[256], *p;
-               FILE *fp;
-
-               /*  Read and parse the config file */
-               halt_action[0] = '\0';
-               if ((fp = fopen (_PATH_SHUTDOWN_CONF, "r")) != NULL) {
-                       if (fgets (line, sizeof(line), fp) != NULL &&
-                           strncasecmp (line, "HALT_ACTION", 11) == 0 &&
-                           iswhitespace(line[11])) {
-                               p = strchr(line, '\n');
-                               if (p)
-                                       *p = 0;         /* strip final '\n' */
-                               p = line+11;
-                               while(iswhitespace(*p))
-                                       p++;
-                               strcpy(halt_action, p);
-                       }
-                       fclose (fp);
-               }
-       }
-
-       if(!opt_quiet && !opt_msgset) {
-               /* now ask for message, gets() is insecure */
-               int cnt = sizeof(message)-1;
-               char *ptr;
-
-               printf("Why? "); fflush(stdout);
-
-               ptr = message;
-               while(--cnt >= 0 && (*ptr = getchar()) && *ptr != '\n') {
-                       ptr++;
-               }
-               *ptr = '\0';
-       } else if (!opt_msgset) {
-               strcpy(message, _("for maintenance; bounce, bounce"));
-       }
-
-#ifdef DEBUGGING
-       printf("timeout = %d, quiet = %d, reboot = %d\n",
-               timeout, opt_quiet, opt_reboot);
-#endif
-
-       /* so much for option-processing, now begin termination... */
-       if(!(whom = getlogin()) || !*whom) whom = "ghost";
-       if(strlen(whom) > 40) whom[40] = 0; /* see write_user() */
-
-       setpriority(PRIO_PROCESS, 0, PRIO_MIN);
-       signal(SIGINT,  int_handler);
-       signal(SIGHUP,  int_handler);
-       signal(SIGQUIT, int_handler);
-       signal(SIGTERM, int_handler);
-
-       chdir("/");
-
-       if(timeout > 5*60) {
-               sleep(timeout - 5*60);
-               timeout = 5*60;
-       }
-
-       if((fd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT, 0644)) >= 0) {
-               /* keep xgettext happy and leave \r\n outside strings */
-               WRCRLF;
-               WR(_("The system is being shut down within 5 minutes"));
-               WRCRLF;
-               write(fd, message, strlen(message));
-               WRCRLF;
-               WR(_("Login is therefore prohibited."));
-               WRCRLF;
-               close(fd);
-       }
-
-       signal(SIGPIPE, SIG_IGN);
-
-       if(timeout > 0) {
-               wall();
-               sleep(timeout);
-       }
-
-       timeout = 0;
-       wall();
-       sleep(3);
-
-       /* now there's no turning back... */
-       signal(SIGINT,  SIG_IGN);
-
-       /* do syslog message... */
-       openlog(prog, LOG_CONS, LOG_AUTH);
-       if (opt_reboot)
-               syslog(LOG_NOTICE, _("rebooted by %s: %s"), 
-                      whom, message);
-       else
-               syslog(LOG_NOTICE, _("halted by %s: %s"), 
-                      whom, message);
-       closelog();
-
-       if(opt_fast)
-               if((fd = open("/fastboot", O_WRONLY|O_CREAT, 0644)) >= 0)
-                       close(fd);
-
-       kill(1, SIGTSTP);       /* tell init not to spawn more getty's */
-       write_wtmp();
-       if(opt_single)
-               if((fd = open(_PATH_SINGLE, O_CREAT|O_WRONLY, 0644)) >= 0)
-                       close(fd);
-
-       sync();
-
-       signal(SIGTERM, SIG_IGN);
-       if(fork() > 0) sleep(1000); /* the parent will die soon... */
-       setpgrp();              /* so the shell wont kill us in the fall */
-
-#ifndef DEBUGGING
-       /* a gentle kill of all other processes except init */
-       kill_mortals (SIGTERM);
-       for (fd = 0; fd < 3; fd++) close (fd);
-       stop_finalprog ();
-       sleep (1);                    /*  Time for saves to start           */
-       kill (1, SIGTERM);            /*  Tell init to kill spawned gettys  */
-       usleep (100000);              /*  Wait for gettys to die            */
-       my_puts ("");                 /*  Get past the login prompt         */
-       system ("/sbin/initctl -r");  /*  Roll back services                */
-       syncwait (1);
-       my_puts ("Sending SIGTERM to all remaining processes...");
-       kill (-1, SIGTERM);
-       sleep (2);                    /*  Default 2, some people need 5     */
-
-       kill (-1, SIGKILL);           /*  Now use brute force...            */
-
-       /* turn off accounting */
-       acct(NULL);
-#endif
-       /* RedHat and SuSE like to remove /etc/nologin.
-          Perhaps the usual sequence is
-             touch nologin; shutdown -h; fiddle with hardware;
-             boot; fiddle with software; rm nologin
-          and removing it here will be counterproductive.
-          Let us see whether people complain. */
-       unlink(_PATH_NOLOGIN);
-
-       /*  Tell init(8) to exec so that the old inode may be freed cleanly if
-           required. Need to sleep before remounting root read-only  */
-       kill (1, SIGQUIT);
-
-       sleep (1);      /* Time for processes to die and close files */
-       syncwait (2);
-
-       /* remove swap files and partitions using swapoff */
-       swap_off();
-
-       /* unmount disks... */
-       unmount_disks();
-       syncwait (1);
-
-       if(opt_reboot) {
-               my_reboot(LINUX_REBOOT_CMD_RESTART); /* RB_AUTOBOOT */
-               my_puts(_("\nWhy am I still alive after reboot?"));
-       } else {
-               my_puts(_("\nNow you can turn off the power..."));
-
-               /* allow C-A-D now, faith@cs.unc.edu, re-fixed 8-Jul-96 */
-               my_reboot(LINUX_REBOOT_CMD_CAD_ON); /* RB_ENABLE_CAD */
-               sleep (1);  /*  Wait for devices to finish writing to media  */
-               do_halt(halt_action);
-       }
-       /* NOTREACHED */
-       exit(EXIT_SUCCESS); /* to quiet gcc */
-}
-
-/*** end of main() ***/
-
-void
-do_halt(char *action) {
-       if (strcasecmp (action, "power_off") == 0) {
-               printf(_("Calling kernel power-off facility...\n"));
-               fflush(stdout);
-               my_reboot(LINUX_REBOOT_CMD_POWER_OFF);
-               printf(_("Error powering off\t%s\n"), ERRSTRING);
-               fflush(stdout);
-               sleep (2);
-       } else
-
-       /* This should be improved; e.g. Mike Jagdis wants "/sbin/mdstop -a" */
-       /* Maybe we should also fork and wait */
-       if (action[0] == '/') {
-               printf(_("Executing the program \"%s\" ...\n"), action);
-               fflush(stdout);
-               execl(action, action, NULL);
-               printf(_("Error executing\t%s\n"), ERRSTRING);
-               fflush(stdout);
-               sleep (2);
-       }
-
-       my_reboot(LINUX_REBOOT_CMD_HALT); /* RB_HALT_SYSTEM */
-}
-
-void
-write_user(struct utmp *ut)
-{
-       int fd;
-       int minutes, hours;
-       char term[40] = {'/','d','e','v','/',0};
-       char msg[100];
-
-       minutes = timeout / 60;
-       hours = minutes / 60;
-       minutes %= 60;
-
-       (void) strncat(term, ut->ut_line, sizeof(ut->ut_line));
-
-       /* try not to get stuck on a mangled ut_line entry... */
-       if((fd = open(term, O_WRONLY|O_NONBLOCK)) < 0)
-               return;
-
-       msg[0] = '\007';        /* gettext crashes on \a */
-       sprintf(msg+1, _("URGENT: broadcast message from %s:"), whom);
-       WRCRLF;
-       WR(msg);
-       WRCRLF;
-
-       if (hours > 1)
-               sprintf(msg, _("System going down in %d hours %d minutes"),
-                       hours, minutes);
-       else if (hours == 1)
-               sprintf(msg, _("System going down in 1 hour %d minutes"),
-                       minutes);
-       else if (minutes > 1)
-               sprintf(msg, _("System going down in %d minutes\n"),
-                       minutes);
-       else if (minutes == 1)
-               sprintf(msg, _("System going down in 1 minute\n"));
-       else
-               sprintf(msg, _("System going down IMMEDIATELY!\n"));
-
-       WR(msg);
-       WRCRLF;
-
-       sprintf(msg, _("\t... %s ...\n"), message);
-       WR(msg);
-       WRCRLF;
-
-       close(fd);
-}
-
-void
-wall(void)
-{
-       /* write to all users, that the system is going down. */
-       struct utmp *ut;
-
-       utmpname(_PATH_UTMP);
-       setutent();
-
-       while((ut = getutent())) {
-               if(ut->ut_type == USER_PROCESS)
-                       write_user(ut);
-       }
-       endutent();
-}
-
-void
-write_wtmp(void)
-{
-       /* write in wtmp that we are dying */
-       int fd;
-       struct utmp ut;
-
-       memset((char *)&ut, 0, sizeof(ut));
-       strcpy(ut.ut_line, "~");
-       memcpy(ut.ut_name, "shutdown", sizeof(ut.ut_name));
-
-       time(&ut.ut_time);
-       ut.ut_type = BOOT_TIME;
-
-       if((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0644)) >= 0) {
-               write(fd, (char *)&ut, sizeof(ut));
-               close(fd);
-       }
-}
-
-void
-swap_off(void)
-{
-       /* swapoff esp. swap FILES so the underlying partition can be
-          unmounted. It you don't have swapoff(1) or use mount to
-          add swapspace, this may not be necessary, but I guess it
-          won't hurt */
-
-       int pid;
-       int result;
-       int status;
-
-       sync();
-       if ((pid = fork()) < 0) {
-               my_puts(_("Cannot fork for swapoff. Shrug!"));
-               return;
-       }
-       if (!pid) {
-               execl("/sbin/swapoff", SWAPOFF_ARGS, NULL);
-               execl("/etc/swapoff", SWAPOFF_ARGS, NULL);
-               execl("/bin/swapoff", SWAPOFF_ARGS, NULL);
-               execlp("swapoff", SWAPOFF_ARGS, NULL);
-               my_puts(_("Cannot exec swapoff, "
-                         "hoping umount will do the trick."));
-               exit(EXIT_SUCCESS);
-       }
-       while ((result = wait(&status)) != -1 && result != pid)
-               ;
-}
-
-void
-unmount_disks(void)
-{
-       /* better to use umount directly because it may be smarter than us */
-
-       int pid;
-       int result;
-       int status;
-
-       sync();
-       if ((pid = fork()) < 0) {
-               my_puts(_("Cannot fork for umount, trying manually."));
-               unmount_disks_ourselves();
-               return;
-       }
-       if (!pid) {
-               execl(_PATH_UMOUNT, UMOUNT_ARGS, NULL);
-
-               /* need my_printf instead of my_puts here */
-               freopen(_PATH_CONSOLE, "w", stdout);
-               printf(_("Cannot exec %s, trying umount.\n"), _PATH_UMOUNT);
-               fflush(stdout);
-
-               execlp("umount", UMOUNT_ARGS, NULL);
-               my_puts(_("Cannot exec umount, giving up on umount."));
-               exit(EXIT_SUCCESS);
-       }
-       while ((result = wait(&status)) != -1 && result != pid)
-               ;
-       my_puts(_("Unmounting any remaining filesystems..."));
-       unmount_disks_ourselves();
-}
-
-void
-unmount_disks_ourselves(void)
-{
-       /* unmount all disks */
-
-       FILE *mtab;
-       struct mntent *mnt;
-       char *mntlist[128];
-       int i;
-       int n;
-       char *filesys;
-
-       sync();
-       if (!(mtab = setmntent(_PATH_MOUNTED, "r"))) {
-               my_puts("shutdown: Cannot open " _PATH_MOUNTED ".");
-               return;
-       }
-       n = 0;
-       while (n < 100 && (mnt = getmntent(mtab))) {
-               /*
-                * Neil Phillips: trying to unmount temporary / kernel
-                * filesystems is pointless and may cause error messages;
-                * /dev can be a ramfs managed by udev.
-                */
-               if (strcmp(mnt->mnt_type, "devfs") == 0 ||
-                   strcmp(mnt->mnt_type, "proc") == 0 ||
-                   strcmp(mnt->mnt_type, "sysfs") == 0 ||
-                   strcmp(mnt->mnt_type, "ramfs") == 0 ||
-                   strcmp(mnt->mnt_type, "tmpfs") == 0 ||
-                   strcmp(mnt->mnt_type, "devpts") == 0)
-                       continue;
-               mntlist[n++] = strdup(mnt->mnt_dir);
-       }
-       endmntent(mtab);
-
-       /* we are careful to do this in reverse order of the mtab file */
-
-       for (i = n - 1; i >= 0; i--) {
-               filesys = mntlist[i];
-#ifdef DEBUGGING
-               printf("umount %s\n", filesys);
-#else
-               if (umount(mntlist[i]) < 0)
-                       printf(_("shutdown: Couldn't umount %s: %s\n"),
-                              filesys, ERRSTRING);
-#endif
-       }
-}
-
-static void kill_mortals (int sig)
-{
-    int npids = 0;
-    int index = 0;
-    int pid;
-    struct stat statbuf;
-    DIR *dp;
-    struct dirent *de;
-    pid_t *pids = NULL;
-    char path[256];
-
-    if ( ( dp = opendir ("/proc") ) == NULL ) return;
-    while ( ( de = readdir (dp) ) != NULL )
-    {
-       if ( !isdigit (de->d_name[0]) ) continue;
-       pid = atoi (de->d_name);
-       sprintf (path, "/proc/%d", pid);
-       if (stat (path, &statbuf) != 0) continue;
-       if (statbuf.st_uid < 100) continue;
-       if (index <= npids)
-       {
-           pids = realloc (pids, npids + 16384);
-           if (pids == NULL) return;
-           npids += 16384;
-       }
-       pids[index++] = pid;
-    }
-    fputs ("Sending SIGTERM to mortals...", stderr);
-    for (--index; index >= 0; --index) kill (pids[index], sig);
-    free (pids);
-    closedir (dp);
-}   /*  End Function kill_mortals  */
-
-static void stop_finalprog (void)
-{
-    char *p1, *p2;
-    FILE *fp;
-    char line[256];
-
-    if ( ( fp = fopen (_PATH_INITTAB, "r") ) == NULL ) return;
-    while (fgets (line, 256, fp) != NULL)
-    {
-       pid_t pid;
-
-       line[strlen (line) - 1] = '\0';
-       p1 = line;
-       while ( isspace (*p1) ) ++p1;
-       if (strncmp (p1, "finalprog", 9) != 0) continue;
-       if ( ( p1 = strchr (p1 + 9, '=') ) == NULL ) continue;
-       for (++p1; isspace (*p1); ++p1);
-       if (*p1 == '\0') continue;
-       for (p2 = p1; !isspace (*p2); ++p2);
-       *p2 = '\0';
-       switch ( pid = fork () )
-       {
-         case 0:   /*  Child   */
-           execl (p1, p1, "stop", NULL);
-           break;
-         case -1:  /*  Error   */
-           break;
-         default:  /*  Parent  */
-           waitpid (pid, NULL, 0);
-           break;
-       }
-       fclose (fp);
-       return;
-    }
-    fclose (fp);
-}   /*  End Function stop_finalprog  */
-
-static void syncwait (int timeval)
-{
-    static int do_wait = 0;
-    static int first_time = 1;
-
-    sync ();
-    /*  Kernel version 1.3.20 and after are supposed to wait automatically  */
-    if (first_time)
-    {
-       struct utsname uts;
-
-       first_time = 0;
-       uname (&uts);
-       if (uts.release[0] < '2') do_wait = 1;
-    }
-    if (do_wait) sleep (timeval);
-}   /*  End Function syncwait  */
diff --git a/simpleinit/simpleinit.8 b/simpleinit/simpleinit.8
deleted file mode 100644 (file)
index c253e8b..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-.\" Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu)
-.\" May be distributed under the GNU General Public License
-.\" " for emacs's hilit19 mode :-)
-.TH SIMPLEINIT 8 "25 February 2001" "Linux 0.99" "Linux Programmer's Manual"
-.SH NAME
-simpleinit \- process control initialization
-.SH SYNOPSIS
-.B init
-.RB [ single ]
-.RI [ script ]
-.SH DESCRIPTION
-.B init
-is invoked as the last step in the Linux boot sequence.  If the
-.B single
-option is used, or if the file
-.I /etc/singleboot
-exists, then single user mode will be entered, by starting
-.IR /bin/sh .
-If the file
-.I /etc/securesingle
-exists, then the root password will be required to start single user mode.
-If the root password does not exist, or if
-.I /etc/passwd
-does not exist, the checking of the password will be skipped.
-
-If the file
-.I /etc/TZ
-exists, then the contents of that file will be read, and used to set the TZ
-environment variable for each process started by
-.BR simpleinit .
-This "feature" is only available if it's configured at compile-time. It's
-not normally needed.
-
-After single user mode is terminated, the
-.I /etc/rc
-file is executed, and the information in
-.I /etc/inittab
-will be used to start processes. Alternatively, the \fI/etc/inittab\fP
-file may be configured to run a different boot script. See below for
-details.
-
-.SH "THE INITTAB FILE"
-Because of the number of init programs which are appearing in the Linux
-community, the documentation for the
-.I /etc/inittab
-file, which is usually found with the
-.BR inittab (5)
-man page, is presented here:
-
-The format is
-
-.RS
-.B bootprog=file
-
-.B fileprefix=string
-
-.B PATH=search path
-
-.B INIT_PATH=search path
-
-.B "ttyline:termcap-entry:getty-command"
-
-.B finalprog=path
-.RE
-
-An example is as follows:
-
-.nf
-.RS
-bootprog     =
-fileprefix   =  /sbin/init.d/
-PATH         =  /usr/sbin:/usr/bin:/sbin:/bin
-INIT_PATH    =  /sbin/init.d
-
-tty1:linux:/sbin/getty 9600 tty1
-tty2:linux:/sbin/getty 9600 tty2
-tty3:linux:/sbin/getty 9600 tty3
-tty4:linux:/sbin/getty 9600 tty4
-# tty5:linux:/sbin/getty 9600 tty5
-# ttyS1:dumb:/sbin/getty 9600 ttyS1
-# ttyS2:dumb:/sbin/getty -m -t60 2400 ttyS2
-
-finalprog   = /sbin/rc.xdm
-.RE
-.fi
-
-Lines beginning with the
-.B #
-character are treated as comments.  Please see documentation for the
-.BR getty (8)
-command that you are using, since there are several of these in the Linux
-community at this time.
-
-The \fBbootprog\fP value is appended to the \fBfileprefix\fP value,
-and the result specifies the boot programme (script) to run. If
-unspecified, the default is \fI/etc/rc\fP. If the boot programme is a
-directory, then all scripts in that directory tree are executed, in
-parallel. See the \fBneed\fP(8) programme for details on how to
-elegantly control order of execution and manage dependencies.
-
-The \fBPATH\fP value is assigned to the PATH environment variable of
-child processes (boot scripts).
-
-The \fBINIT_PATH\fP value is used by simpleinit(8) itself to find the
-location of scripts to run (if an absolute path is not given). If
-unset and the boot programme is a directory, that directory is used.
-Finally, if the script cannot be found in this path, the standard
-\fBPATH\fP is used. This separation allows boot scripts to invoke
-programmes of the same name without conflict and without needing to
-specify absolute paths.
-
-The \fBfinalprog\fP value specifies the path of the programme to run
-after all \fBgetty\fP(8) instances are spawned. At bootup, it is
-passed a single argument: "start". At shutdown, it is called again,
-this time with the argument: "stop".
-.SH SIGNALS
-\fBsimpleinit\fP(8) responds to signals in a variety of ways:
-.TP
-.B SIGHUP
-The \fI/etc/inittab\fP configuration file will be read again.
-.TP
-.B SIGTSTP
-This flips a toggle, which controls whether more processes will be
-spawned.
-.TP
-.B SIGINT
-\fBsimpleinit\fP(8) will sync a few times, and try to start
-\fBreboot\fP(8). Failing this, it will execute the system
-\fBreboot\fP(2) call. Under Linux, it is possible to configure the
-Ctrl-Alt-Del sequence to send a signal to the \fBinit\fP process
-instead of rebooting the system (\fBsimpleinit\fP(8) does this by
-default).
-.TP
-.B SIGQUIT
-The \fBreboot\fP(8) programme is executed in place of the
-\fBsimpleinit\fP(8) programme. This allows \fBreboot\fP(8) to cleanly
-remount (read-only) the root filesystem, even if the old inode for the
-\fBinit\fP process was unlinked.
-.SH FILES
-.I /etc/inittab
-.br
-.I /etc/singleboot
-.br
-.I /etc/securesingle
-.br
-.I /etc/TZ
-.br
-.I /etc/passwd
-.br
-.I /etc/rc
-.SH "SEE ALSO"
-.BR inittab (5),
-.BR ctrlaltdel (8)
-.BR reboot (8),
-.BR termcap (5),
-.BR getty (8),
-.BR agetty (8),
-.BR shutdown (8),
-.BR initctl (8)
-.SH BUGS
-This program is called
-.B simpleinit
-to distinguish it from the System V compatible versions of init which are
-starting to appear in the Linux community.
-.B simpleinit
-should be linked to, or made identical with,
-.I init
-for correct functionality.
-.SH AUTHOR
-Peter Orbaek (poe@daimi.aau.dk)
-.br
-Version 1.20, with patches for singleuser mode by Werner Almesberger
-.br
-Richard Gooch <rgooch@atnf.csiro.au>
-.br
-Dependency support
-
-.SH AVAILABILITY
-The simpleinit command is part of the util-linux package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/simpleinit/simpleinit.c b/simpleinit/simpleinit.c
deleted file mode 100644 (file)
index d7f9655..0000000
+++ /dev/null
@@ -1,1251 +0,0 @@
-/* simpleinit.c - poe@daimi.aau.dk */
-/* Version 2.0.2 */
-
-/* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
- * - added Native Language Support
- * 2001-01-25 Richard Gooch <rgooch@atnf.csiro.au>
- * - fixed bug with failed services so they may be later "reclaimed"
- * 2001-02-02 Richard Gooch <rgooch@atnf.csiro.au>
- * - fixed race when reading from pipe and reaping children
- * 2001-02-18 sam@quux.dropbear.id.au
- * - fixed bug in <get_path>: multiple INIT_PATH components did not work
- * 2001-02-21 Richard Gooch <rgooch@atnf.csiro.au>
- * - block signals in handlers, so that longjmp() doesn't kill context
- * 2001-02-25 Richard Gooch <rgooch@atnf.csiro.au>
- * - make default INIT_PATH the boot_prog (if it is a directory) - YECCH
- * 2002-11-20 patch from SuSE
- * - refuse initctl_fd if setting FD_CLOEXEC fails
- */
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <string.h>
-#include <signal.h>
-#include <errno.h>
-#include <time.h>
-#include <pwd.h>
-#include <sys/file.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <dirent.h>
-#include <termios.h>
-#include <utmp.h>
-#include <setjmp.h>
-#include <sched.h>
-#ifdef SHADOW_PWD
-#  include <shadow.h>
-#endif
-
-#ifdef HAVE_CRYPT_H
-#include <crypt.h>
-#endif
-
-#include "pathnames.h"
-#include "linux_reboot.h"
-#include "strutils.h"
-#include "nls.h"
-#include "simpleinit.h"
-
-
-#define CMDSIZ     150 /* max size of a line in inittab */
-#define NUMCMD     30  /* max number of lines in inittab */
-#define NUMTOK     20  /* max number of tokens in inittab command */
-#define PATH_SIZE  (CMDSIZ+CMDSIZ+1)
-
-#define MAX_RESPAWN_RATE  5  /*  number of respawns per 100 seconds  */
-
-#define TZFILE "/etc/TZ"
-char tzone[CMDSIZ];
-/* #define DEBUGGING */
-
-/* Define this if you want init to ignore the termcap field in inittab for
-   console ttys. */
-/* #define SPECIAL_CONSOLE_TERM */
-
-#define ever (;;)
-
-struct initline {
-       pid_t           pid;
-       char            tty[10];
-       char            termcap[30];
-       char            *toks[NUMTOK];
-       char            line[CMDSIZ];
-       struct timeval  last_start;
-       signed long     rate;
-};
-
-struct initline inittab[NUMCMD];
-int numcmd;
-int stopped = 0;       /* are we stopped */
-static char boot_prog[PATH_SIZE] = _PATH_RC;
-static char script_prefix[PATH_SIZE] = "\0";
-static char final_prog[PATH_SIZE] = "\0";
-static char init_path[PATH_SIZE] = "\0";
-static int caught_sigint = 0;
-static int no_reboot = 0;
-static pid_t rc_child = -1;
-static const char *initctl_name = "/dev/initctl";
-static int initctl_fd = -1;
-static volatile int do_longjmp = 0;
-static sigjmp_buf jmp_env;
-
-
-static void do_single (void);
-static int do_rc_tty (const char *path);
-static int process_path (const char *path, int (*func) (const char *path),
-                        int ignore_dangling_symlink);
-static int preload_file (const char *path);
-static int run_file (const char *path);
-static void spawn (int i), read_inittab (void);
-static void sighup_handler (int sig);
-static void sigtstp_handler (int sig);
-static void sigint_handler (int sig);
-static void sigchild_handler (int sig);
-static void sigquit_handler (int sig);
-static void sigterm_handler (int sig);
-#ifdef SET_TZ
-static void set_tz (void);
-#endif
-static void write_wtmp (void);
-static pid_t mywait (int *status);
-static int run_command (const char *file, const char *name, pid_t pid);
-
-
-static void err (char *s)
-{
-       int fd;
-       
-       if((fd = open("/dev/console", O_WRONLY)) < 0) return;
-
-       write(fd, "init: ", 6); 
-       write(fd, s, strlen(s));
-       close(fd);
-}
-
-static void enter_single (void)
-{
-    pid_t pid;
-    int i;
-
-    err(_("Booting to single user mode.\n"));
-    if((pid = fork()) == 0) {
-       /* the child */
-       execl(_PATH_BSHELL, _PATH_BSHELL, NULL);
-       err(_("exec of single user shell failed\n"));
-    } else if(pid > 0) {
-       while (waitpid (pid, &i, 0) != pid)  /*  Nothing  */;
-    } else if(pid < 0) {
-       err(_("fork of single user shell failed\n"));
-    }
-    unlink(_PATH_SINGLE);
-}
-
-int main(int argc, char *argv[])
-{
-       int                     vec, i;
-       int                     want_single = 0;
-       pid_t                   pid;
-       struct sigaction        sa;
-
-
-#ifdef SET_TZ
-       set_tz();
-#endif
-       sigfillset (&sa.sa_mask);  /*  longjmp and nested signals don't mix  */
-       sa.sa_flags = SA_ONESHOT;
-       sa.sa_handler = sigint_handler;
-       sigaction (SIGINT, &sa, NULL);
-       sa.sa_flags = 0;
-       sa.sa_handler = sigtstp_handler;
-       sigaction (SIGTSTP, &sa, NULL);
-       sa.sa_handler = sigterm_handler;
-       sigaction (SIGTERM, &sa, NULL);
-       sa.sa_handler = sigchild_handler;
-       sigaction (SIGCHLD, &sa, NULL);
-       sa.sa_handler = sigquit_handler;
-       sigaction (SIGQUIT, &sa, NULL);
-
-       setlocale(LC_ALL, "");
-       bindtextdomain(PACKAGE, LOCALEDIR);
-       textdomain(PACKAGE);
-
-       my_reboot (LINUX_REBOOT_CMD_CAD_OFF);
-       /*  Find script to run. Command-line overrides config file overrides
-           built-in default  */
-       for (i = 0; i < NUMCMD; i++) inittab[i].pid = -1;
-       read_inittab ();
-       for (i = 1; i < argc; i++) {
-               if (strcmp (argv[i], "single") == 0)
-                       want_single = 1;
-               else if (strcmp (argv[i], "-noreboot") == 0)
-                       no_reboot = 1;
-               else if (strlen(script_prefix) + strlen(argv[i]) < PATH_SIZE) {
-                       char path[PATH_SIZE];
-
-                       strcpy (path, script_prefix);
-                       strcat (path, argv[i]);
-                       if (access (path, R_OK | X_OK) == 0)
-                               strcpy (boot_prog, path);
-               }
-       }
-       if (init_path[0] == '\0')
-       {
-           struct stat statbuf;
-
-           if ( (stat (boot_prog, &statbuf) == 0) && S_ISDIR (statbuf.st_mode) )
-           {
-               strcpy (init_path, boot_prog);
-               i = strlen (init_path);
-               if (init_path[i - 1] == '/') init_path[i - 1] = '\0';
-           }
-       }
-
-       if ( ( initctl_fd = open (initctl_name, O_RDWR, 0) ) < 0 ) {
-               mkfifo (initctl_name, S_IRUSR | S_IWUSR);
-               if ( ( initctl_fd = open (initctl_name, O_RDWR, 0) ) < 0 )
-                       err ( _("error opening fifo\n") );
-       }
-
-       if (initctl_fd >= 0 && fcntl(initctl_fd, F_SETFD, FD_CLOEXEC) != 0) {
-               err ( _("error setting close-on-exec on /dev/initctl") );
-
-               /* Can the fcntl ever fail?  If it does, and we leave
-                  the descriptor open in child processes, then any
-                  process on the system will be able to write to
-                  /dev/initctl and have us execute arbitrary commands
-                  as root. So let's refuse to use the fifo in this case. */
-
-               close(initctl_fd);
-               initctl_fd = -1;
-       }
-
-       if ( want_single || (access (_PATH_SINGLE, R_OK) == 0) ) do_single ();
-
-       /*If we get a SIGTSTP before multi-user mode, do nothing*/
-       while (stopped)
-               pause();
-
-       if ( do_rc_tty (boot_prog) ) do_single ();
-
-       while (stopped)  /*  Also if /etc/rc fails & we get SIGTSTP  */
-               pause();
-
-       write_wtmp();   /* write boottime record */
-#ifdef DEBUGGING
-       for(i = 0; i < numcmd; i++) {
-               char **p;
-               p = inittab[i].toks;
-               printf("toks= %s %s %s %s\n",p[0], p[1], p[2], p[3]);
-               printf("tty= %s\n", inittab[i].tty);
-               printf("termcap= %s\n", inittab[i].termcap);
-       }
-       exit(EXIT_SUCCESS);
-#endif
-       signal (SIGHUP, sighup_handler);  /* Better semantics with signal(2) */
-
-       for (i = 0; i < getdtablesize (); i++)
-               if (i != initctl_fd) close (i);
-
-       for(i = 0; i < numcmd; i++)
-               spawn(i);
-
-       if (final_prog[0] != '\0') {
-               switch ( fork () )
-               {
-                 case 0:   /*  Child   */
-                   execl (final_prog, final_prog, "start", NULL);
-                   err ( _("error running finalprog\n") );
-                   _exit (EXIT_FAILURE);
-                   break;
-                 case -1:  /*  Error   */
-                   err ( _("error forking finalprog\n") );
-                   break;
-                 default:  /*  Parent  */
-                   break;
-               }
-       }
-
-       for ever {
-               pid = mywait (&vec);
-               if (pid < 1) continue;
-
-               /* clear utmp entry, and append to wtmp if possible */
-               {
-                   struct utmp *ut;
-                   int ut_fd, lf;
-
-                   utmpname(_PATH_UTMP);
-                   setutent();
-                   while((ut = getutent())) {
-                       if(ut->ut_pid == pid) {
-                           time(&ut->ut_time);
-                           memset(&ut->ut_user, 0, UT_NAMESIZE);
-                           memset(&ut->ut_host, 0, sizeof(ut->ut_host));
-                           ut->ut_type = DEAD_PROCESS;
-                           ut->ut_pid = 0;
-                           ut->ut_addr = 0;
-                           /*endutent();*/
-                           pututline(ut);
-
-                           if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) {
-                               flock(lf, LOCK_EX|LOCK_NB);
-                               if((ut_fd = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) {
-                                   write(ut_fd, ut, sizeof(struct utmp));
-                                   close(ut_fd);
-                               }
-                               flock(lf, LOCK_UN|LOCK_NB);
-                               close(lf);
-                           }
-                           break;
-                       }
-                   }
-                   endutent();
-               }
-
-               for(i = 0; i < numcmd; i++) {
-                       if(pid == inittab[i].pid || inittab[i].pid < 0) {
-                               if (stopped)
-                                       inittab[i].pid = -1;
-                               else
-                                       spawn(i);
-                               if (pid == inittab[i].pid)
-                                       break;
-                       }
-               }
-       }
-}      
-
-#define MAXTRIES 3 /* number of tries allowed when giving the password */
-
-/*
- * return true if singleuser mode is allowed.
- * If /etc/securesingle exists ask for root password, otherwise always OK.
- */
-static int check_single_ok (void)
-{
-    char *pass, *rootpass = NULL;
-    struct passwd *pwd;
-    int i;
-
-    if (access (_PATH_SECURE, R_OK) != 0) return 1;
-    if ( ( pwd = getpwnam ("root") ) || ( pwd = getpwuid (0) ) )
-       rootpass = pwd->pw_passwd;
-    else
-       return 1; /* a bad /etc/passwd should not lock out */
-
-    for (i = 0; i < MAXTRIES; i++)
-    {
-       pass = getpass (_("Password: "));
-       if (pass == NULL) continue;
-
-       if ( !strcmp (crypt (pass, rootpass), rootpass) ) return 1;
-
-       puts (_("\nWrong password.\n"));
-    }
-    return 0;
-}
-
-static void do_single (void)
-{
-    char path[PATH_SIZE];
-
-    if (caught_sigint) return;
-    strcpy (path, script_prefix);
-    strcat (path, "single");
-    if (access (path, R_OK | X_OK) == 0)
-       if (do_rc_tty (path) == 0) return;
-    if ( check_single_ok () ) enter_single ();
-}   /*  End Function do_single  */
-
-/*
- * run boot script(s). The environment is passed to the script(s), so the RC
- * environment variable can be used to decide what to do.
- * RC may be set from LILO.
- * [RETURNS] 0 on success (exit status convention), otherwise error.
- */
-static int do_rc_tty (const char *path)
-{
-    int status;
-    pid_t pid;
-    sigset_t ss;
-
-    if (caught_sigint) return 0;
-    process_path (path, preload_file, 0);
-    /*  Launch off a subprocess to start a new session (required for frobbing
-       the TTY) and capture control-C  */
-    switch ( rc_child = fork () )
-    {
-      case 0:   /*  Child  */
-       for (status = 1; status < NSIG; status++) signal (status, SIG_DFL);
-       sigfillset (&ss);
-       sigprocmask (SIG_UNBLOCK, &ss, NULL);
-       sigdelset (&ss, SIGINT);
-       sigdelset (&ss, SIGQUIT);
-       setsid ();
-       ioctl (0, TIOCSCTTY, 0);  /*  I want my control-C  */
-       sigsuspend (&ss);  /*  Should never return, should just be killed  */
-       break;             /*  No-one else is controlled by this TTY now   */
-      case -1:  /*  Error  */
-       return (1);
-       /*break;*/
-      default:  /*  Parent  */
-       break;
-    }
-    /*  Parent  */
-    process_path (path, run_file, 0);
-    while (1)
-    {
-       if ( ( pid = mywait (&status) ) == rc_child )
-           return (WTERMSIG (status) == SIGINT) ? 0 : 1;
-       if (pid < 0) break;
-    }
-    kill (rc_child, SIGKILL);
-    while (waitpid (rc_child, NULL, 0) != rc_child)  /*  Nothing  */;
-    return 0;
-}   /*  End Function do_rc_tty  */
-
-static int process_path (const char *path, int (*func) (const char *path),
-                        int ignore_dangling_symlink)
-{
-    struct stat statbuf;
-    DIR *dp;
-    struct dirent *de;
-
-    if (lstat (path, &statbuf) != 0)
-    {
-       err (_("lstat of path failed\n") );
-       return 1;
-    }
-    if ( S_ISLNK (statbuf.st_mode) )
-    {
-       if (stat (path, &statbuf) != 0)
-       {
-           if ( (errno == ENOENT) && ignore_dangling_symlink ) return 0;
-           err (_("stat of path failed\n") );
-           return 1;
-       }
-    }
-    if ( !( statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH) ) ) return 0;
-    if ( !S_ISDIR (statbuf.st_mode) ) return (*func) (path);
-    if ( ( dp = opendir (path) ) == NULL )
-    {
-       err (_("open of directory failed\n") );
-       return 1;
-    }
-    while ( ( de = readdir (dp) ) != NULL )
-    {
-       int retval;
-       char newpath[PATH_SIZE];
-
-       if (de->d_name[0] == '.') continue;
-       retval = snprintf (newpath, sizeof(newpath), "%s/%s", path, de->d_name);
-       if (newpath[retval - 1] == '~') continue;  /*  Common mistake  */
-       if ( ( retval = process_path (newpath, func, 1) ) ) return retval;
-    }
-    closedir (dp);
-    return 0;
-}   /*  End Function process_path  */
-
-static int preload_file (const char *path)
-{
-    int fd;
-    char ch;
-
-    if ( ( fd = open (path, O_RDONLY, 0) ) < 0) return 0;
-    while (read (fd, &ch, 1) == 1) lseek (fd, 1024, SEEK_CUR);
-    close (fd);
-    return 0;
-}   /*  End Function preload_file  */
-
-static int run_file (const char *path)
-{
-    const char *ptr;
-
-    if ( ( ptr = strrchr ( (char *) path, '/' ) ) == NULL ) ptr = path;
-    else ++ptr;
-    return (run_command (path, ptr, 0) == SIG_FAILED) ? 1 : 0;
-}   /*  End Function run_file  */
-
-static void spawn (int i)
-{
-       pid_t pid;
-       int j;
-       signed long ds_taken;
-       struct timeval ct;
-
-       if (inittab[i].toks[0] == NULL) return;
-
-       /*  Check if respawning too fast  */
-       gettimeofday (&ct, NULL);
-       ds_taken = ct.tv_sec - inittab[i].last_start.tv_sec;
-
-       /* On the first iteration last_start==0 and ds_taken
-          may be very large. Avoid overflow. -- Denis Vlasenko */
-       if (ds_taken > 10000)
-               ds_taken = 10000;
-
-       ds_taken *= 10;
-       ds_taken += (ct.tv_usec - inittab[i].last_start.tv_usec) / 100000;
-       if (ds_taken < 1)
-               ds_taken = 1;
-       inittab[i].rate = (9 * inittab[i].rate + 1000 / ds_taken) / 10;
-       if (inittab[i].rate > MAX_RESPAWN_RATE) {
-               char txt[256];
-
-               inittab[i].toks[0] = NULL;
-               inittab[i].pid = -1;
-               inittab[i].rate = 0;
-               snprintf (txt, sizeof(txt),
-                       _("respawning: \"%s\" too fast: quenching entry\n"),
-                        inittab[i].tty);
-               err (txt);
-               return;
-       }
-
-       if((pid = fork()) < 0) {
-               inittab[i].pid = -1;
-               err(_("fork failed\n"));
-               return;
-       }
-       if(pid) {
-               /* this is the parent */
-               inittab[i].pid = pid;
-               inittab[i].last_start = ct;
-               sched_yield ();
-               return;
-       } else {
-               /* this is the child */
-               char term[40];
-#ifdef SET_TZ
-               char tz[CMDSIZ];
-#endif
-               char *env[3];
-               
-               setsid();
-               for(j = 0; j < getdtablesize(); j++)
-                       (void) close(j);
-
-               snprintf(term, sizeof(term), "TERM=%s", inittab[i].termcap);
-               env[0] = term;
-               env[1] = (char *)0;
-#ifdef SET_TZ
-               snprintf(tz, sizeof(tz), "TZ=%s", tzone);
-               env[1] = tz;
-#endif
-               env[2] = (char *)0;
-
-               execve(inittab[i].toks[0], inittab[i].toks, env);
-               err(_("exec failed\n"));
-               sleep(5);
-               _exit(EXIT_FAILURE);
-       }
-}
-
-static void read_inittab (void)
-{
-       FILE *f;
-       char buf[CMDSIZ];
-       int i,j,k;
-       int has_prog = 0;
-       char *ptr, *getty;
-       char prog[PATH_SIZE];
-#ifdef SPECIAL_CONSOLE_TERM
-       char tty[50];
-       struct stat stb;
-#endif
-       char *termenv;
-       
-       termenv = getenv("TERM");       /* set by kernel */
-       /* termenv = "vt100"; */
-                       
-       if(!(f = fopen(_PATH_INITTAB, "r"))) {
-               err(_("cannot open inittab\n"));
-               return;
-       }
-
-       prog[0] = '\0';
-       i = 0;
-       while(!feof(f) && i < NUMCMD - 2) {
-               if(fgets(buf, CMDSIZ - 1, f) == 0) break;
-               buf[CMDSIZ-1] = 0;
-
-               for(k = 0; k < CMDSIZ && buf[k]; k++) {
-                       if ((buf[k] == '#') || (buf[k] == '\n')) { 
-                               buf[k] = 0; break; 
-                       }
-               }
-
-               if(buf[0] == 0 || buf[0] == '\n') continue;
-               ptr = strchr (buf, '=');
-               if (ptr) {
-                       ptr++;
-                       if ( !strncmp (buf, "bootprog", 8) ) {
-                               while ( isspace (*ptr) ) ++ptr;
-                               strcpy (prog, ptr);
-                               has_prog = 1;
-                               continue;
-                       }
-                       if ( !strncmp (buf, "fileprefix", 10) ) {
-                               while ( isspace (*ptr) ) ++ptr;
-                               strcpy (script_prefix, ptr);
-                               continue;
-                       }
-                       if ( !strncmp (buf, "PATH", 4) ) {
-                               while ( isspace (*ptr) ) ++ptr;
-                               setenv ("PATH", ptr, 1);
-                               continue;
-                       }
-                       if ( !strncmp (buf, "INIT_PATH", 9) ) {
-                               while ( isspace (*ptr) ) ++ptr;
-                               strcpy (init_path, ptr);
-                               continue;
-                       }
-                       if ( !strncmp (buf, "finalprog", 8) ) {
-                               while ( isspace (*ptr) ) ++ptr;
-                               strcpy (final_prog, ptr);
-                               continue;
-                       }
-               }
-                       
-
-               (void) strcpy(inittab[i].line, buf);
-
-               (void) strtok(inittab[i].line, ":");
-               xstrncpy(inittab[i].tty, inittab[i].line, 10);
-               xstrncpy(inittab[i].termcap, strtok((char *)0, ":"), 30);
-
-               getty = strtok((char *)0, ":");
-               (void) strtok(getty, " \t\n");
-               inittab[i].toks[0] = getty;
-               j = 1;
-               while((ptr = strtok((char *)0, " \t\n")))
-                       inittab[i].toks[j++] = ptr;
-               inittab[i].toks[j] = (char *)0;
-
-#ifdef SPECIAL_CONSOLE_TERM
-               /* special-case termcap for the console ttys */
-               snprintf(tty, sizeof(tty), "/dev/%s", inittab[i].tty);
-               if(!termenv || stat(tty, &stb) < 0) {
-                       err(_("no TERM or cannot stat tty\n"));
-               } else {
-                       /* is it a console tty? */
-                       if(major(stb.st_rdev) == 4 && minor(stb.st_rdev) < 64)
-                               xstrncpy(inittab[i].termcap, termenv, 30);
-               }
-#endif
-
-               i++;
-       }
-       fclose(f);
-       numcmd = i;
-       if (has_prog) {
-               int len;
-               char path[PATH_SIZE];
-
-               strcpy (path, script_prefix);
-               strcat (path, prog);
-               len = strlen (path);
-               if (path[len - 1] == '/') path[len - 1] = '\0';
-               if (access (path, R_OK | X_OK) == 0)
-                       strcpy (boot_prog, path);
-       }
-}   /*  End Function read_inittab  */
-
-static void sighup_handler (int sig)
-{
-       int i,j;
-       int oldnum;
-       struct initline savetab[NUMCMD];
-       int had_already;
-
-       signal (SIGHUP, SIG_IGN);
-       memcpy(savetab, inittab, NUMCMD * sizeof(struct initline));
-       oldnum = numcmd;                
-       read_inittab ();
-       
-       for(i = 0; i < numcmd; i++) {
-               had_already = 0;
-               for(j = 0; j < oldnum; j++) {
-                       if(!strcmp(savetab[j].tty, inittab[i].tty)) {
-                               had_already = 1;
-                               if((inittab[i].pid = savetab[j].pid) < 0)
-                                       spawn(i);
-                       }
-               }
-               if (!had_already) spawn (i);
-       }
-       signal (SIGHUP, sighup_handler);
-}   /*  End Function sighup_handler  */
-
-static void sigtstp_handler (int sig)
-{
-    stopped = ~stopped;
-    if (!stopped) sighup_handler (sig);
-}   /*  End Function sigtstp_handler  */
-
-static void sigterm_handler (int sig)
-{
-    int i;
-
-    for (i = 0; i < numcmd; i++)
-       if (inittab[i].pid > 0) kill (inittab[i].pid, SIGTERM);
-}   /*  End Function sigterm_handler  */
-
-static void sigint_handler (int sig)
-{
-    pid_t pid;
-
-    caught_sigint = 1;
-    kill (rc_child, SIGKILL);
-    if (no_reboot) _exit (EXIT_FAILURE) /*kill (0, SIGKILL)*/;
-    sync ();
-    sync ();
-    pid = fork ();
-    if (pid > 0) return;  /*  Parent                     */
-    if (pid == 0)        /*  Child: reboot properly...  */
-       execl (_PATH_REBOOT, _PATH_REBOOT, (char *) 0);
-
-    /* fork or exec failed, try the hard way... */
-    my_reboot (LINUX_REBOOT_CMD_RESTART);
-}   /*  End Function sigint_handler  */
-
-static void sigchild_handler (int sig)
-{
-    if (!do_longjmp) return;
-    siglongjmp (jmp_env, 1);
-}
-
-static void sigquit_handler (int sig)
-{
-    execl (_PATH_REBOOT, _PATH_REBOOT, NULL); /*  It knows pid=1 must sleep  */
-}
-
-#ifdef SET_TZ
-static void set_tz (void)
-{
-       FILE *f;
-       int len;
-
-       if((f=fopen(TZFILE, "r")) == (FILE *)NULL) return;
-       fgets(tzone, CMDSIZ-2, f);
-       fclose(f);
-       if((len=strlen(tzone)) < 2) return;
-       tzone[len-1] = 0; /* get rid of the '\n' */
-       setenv("TZ", tzone, 0);
-}
-#endif
-
-static void write_wtmp (void)
-{
-    int fd, lf;
-    struct utmp ut;
-    
-    memset((char *)&ut, 0, sizeof(ut));
-    strcpy(ut.ut_line, "~");
-    memset(ut.ut_name, 0, sizeof(ut.ut_name));
-    time(&ut.ut_time);
-    ut.ut_type = BOOT_TIME;
-
-    if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) {
-       flock(lf, LOCK_EX|LOCK_NB); /* make sure init won't hang */
-       if((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND)) >= 0) {
-           write(fd, (char *)&ut, sizeof(ut));
-           close(fd);
-       }
-       flock(lf, LOCK_UN|LOCK_NB);
-       close(lf);
-    }
-}   /*  End Function write_wtmp  */
-
-
-struct needer_struct
-{
-    struct needer_struct *next;
-    pid_t pid;
-};
-
-struct service_struct
-{
-    struct service_struct *prev, *next;    /*  Script services chain         */
-    struct needer_struct *needers;         /*  Needers waiting for service   */
-    struct script_struct *attempting_providers;
-    int failed;                /*  TRUE if attempting provider failed badly  */
-    char name[1];
-};
-
-struct script_struct
-{
-    pid_t pid;
-    struct script_struct *prev, *next;              /*  For the list         */
-    struct service_struct *first_service, *last_service; /*First is true name*/
-    struct script_struct *next_attempting_provider; /*  Provider chain       */
-};
-
-struct list_head
-{
-    struct script_struct *first, *last;
-    unsigned int num_entries;
-};
-
-
-static struct list_head available_list = {NULL, NULL, 0};
-static struct list_head starting_list = {NULL, NULL, 0};
-static struct service_struct *unavailable_services = NULL;  /*  For needers  */
-static int num_needers = 0;
-
-
-static int process_pidstat (pid_t pid, int status);
-static void process_command (const struct command_struct *command);
-static struct service_struct *find_service_in_list (const char *name,
-                                                   struct service_struct *sv);
-static struct script_struct *find_script_byname
-    (const char *name,struct list_head *head, struct service_struct **service);
-static struct script_struct *find_script_bypid (pid_t pid,
-                                               struct list_head *head);
-static void insert_entry (struct list_head *head, struct script_struct *entry);
-static void remove_entry (struct list_head *head, struct script_struct *entry);
-static void signal_needers (struct service_struct *service, int sig);
-static void handle_nonworking (struct script_struct *script);
-static int force_progress (void);
-static void show_scripts (FILE *fp, const struct script_struct *script,
-                         const char *type);
-static const char *get_path (const char *file);
-
-
-static pid_t mywait (int *status)
-/*  [RETURNS] The pid for a process to be reaped, 0 if no process is to be
-    reaped, and less than 0 if the boot scripts appear to have finished.
-*/
-{
-    pid_t pid;
-    sigset_t ss;
-    long buffer[COMMAND_SIZE / sizeof (long)];
-    struct command_struct *command = (struct command_struct *) buffer;
-
-    if (initctl_fd < 0) return wait (status);
-    /*  Some magic to avoid races which can result in lost signals   */
-    command->command = -1;
-    if ( sigsetjmp (jmp_env, 1) )
-    {   /*  Jump from signal handler  */
-       do_longjmp = 0;
-       process_command (command);
-       return 0;
-    }
-    sigemptyset (&ss);  /*  Block SIGCHLD so wait status cannot be lost  */
-    sigaddset (&ss, SIGCHLD);
-    sigprocmask (SIG_BLOCK, &ss, NULL);
-    if ( ( pid = waitpid (-1, status, WNOHANG) ) > 0 )
-    {
-       sigprocmask (SIG_UNBLOCK, &ss, NULL);
-       return process_pidstat (pid, *status);
-    }
-    do_longjmp = 1;  /*  After this, SIGCHLD will cause a jump backwards  */
-    sigprocmask (SIG_UNBLOCK, &ss, NULL);
-    read (initctl_fd, buffer, sizeof(buffer));
-    do_longjmp = 0;
-    process_command (command);
-    return 0;
-}   /*  End Function mywait  */
-
-static pid_t process_pidstat (pid_t pid, int status)
-/*  [RETURNS] The pid for a process to be reaped, 0 if no process is to be
-    reaped, and less than 0 if the boot scripts appear to have finished.
-*/
-{
-    int failed;
-    struct script_struct *script;
-    struct service_struct *service;
-
-    if ( ( script = find_script_bypid (pid, &starting_list) ) == NULL )
-       return pid;
-    remove_entry (&starting_list, script);
-    if ( WIFEXITED (status) && (WEXITSTATUS (status) == 0) )
-    {
-       struct script_struct *provider;
-
-       /*  Notify needers and other providers  */
-       for (service = script->first_service; service != NULL;
-            service = service->next)
-       {
-           signal_needers (service, SIG_PRESENT);
-           for (provider = service->attempting_providers; provider != NULL;
-                provider = provider->next_attempting_provider)
-               kill (provider->pid, SIG_PRESENT);
-           service->attempting_providers = NULL;
-       }
-       insert_entry (&available_list, script);
-       return force_progress ();
-    }
-    failed = ( WIFEXITED (status) && (WEXITSTATUS (status) == 2) ) ? 0 : 1;
-    for (service = script->first_service; service != NULL;
-        service = service->next)
-       service->failed = failed;
-    handle_nonworking (script);
-    return force_progress ();
-}   /*  End Function process_pidstat  */
-
-static void process_command (const struct command_struct *command)
-{
-    int ival;
-    struct script_struct *script;
-    struct service_struct *service;
-
-    switch (command->command)
-    {
-      case COMMAND_TEST:
-       kill (command->pid,
-             (find_script_byname (command->name, &available_list,
-                                  NULL) == NULL) ?
-             SIG_NOT_PRESENT : SIG_PRESENT);
-       break;
-      case COMMAND_NEED:
-       ival = run_command (command->name, command->name, command->pid);
-       if (ival == 0)
-       {
-           ++num_needers;
-           force_progress ();
-       }
-       else kill (command->pid, ival);
-       break;
-      case COMMAND_ROLLBACK:
-       if (command->name[0] == '\0') script = NULL;
-       else
-       {
-           if ( ( script = find_script_byname (command->name, &available_list,
-                                               NULL) ) == NULL )
-           {
-               kill (command->pid, SIG_NOT_PRESENT);
-               break;
-           }
-       }
-       while (script != available_list.first)
-       {
-           pid_t pid;
-           struct script_struct *victim = available_list.first;
-           char txt[256];
-
-           if ( ( pid = fork () ) == 0 )   /*  Child   */
-           {
-               for (ival = 1; ival < NSIG; ival++) signal (ival, SIG_DFL);
-               open ("/dev/console", O_RDONLY, 0);
-               open ("/dev/console", O_RDWR, 0);
-               dup2 (1, 2);
-               execlp (get_path (victim->first_service->name),
-                       victim->first_service->name, "stop", NULL);
-               snprintf (txt, sizeof(txt),
-                       _("error at stopping service \"%s\"\n"),
-                        victim->first_service->name);
-               err (txt);
-               _exit (SIG_NOT_STOPPED);
-           }
-           else if (pid == -1) break;      /*  Error   */
-           else                            /*  Parent  */
-           {
-               while (waitpid (pid, &ival, 0) != pid) /*  Nothing  */;
-               if ( WIFEXITED (ival) && (WEXITSTATUS (ival) == 0) )
-               {
-                   snprintf (txt, sizeof(txt),
-                            _("Stopped service: %s\n"),
-                            victim->first_service->name);
-                   remove_entry (&available_list, victim);
-                   free (victim);
-                   err (txt);
-               }
-               else break;
-           }
-       }
-       kill (command->pid,
-             (script ==available_list.first) ? SIG_STOPPED : SIG_NOT_STOPPED);
-       break;
-      case COMMAND_DUMP_LIST:
-       if (fork () == 0) /* Do it in a child process so pid=1 doesn't block */
-       {
-           FILE *fp;
-
-           if ( ( fp = fopen (command->name, "w") ) == NULL ) _exit (EXIT_FAILURE);
-           show_scripts (fp, available_list.first, "AVAILABLE");
-           show_scripts (fp, starting_list.first, "STARTING");
-           fputs ("UNAVAILABLE SERVICES:\n", fp);
-           for (service = unavailable_services; service != NULL;
-                service = service->next)
-               fprintf (fp, "%s (%s)\n", service->name,
-                        service->failed ? "FAILED" : "not configured");
-           fclose (fp);
-           _exit (EXIT_SUCCESS);
-       }
-       break;
-      case COMMAND_PROVIDE:
-       /*  Sanity check  */
-       if ( ( script = find_script_bypid (command->ppid, &starting_list) )
-            == NULL )
-       {
-           kill (command->pid, SIG_NOT_CHILD);
-           break;
-       }
-       if (find_script_byname (command->name, &available_list, NULL) != NULL)
-       {
-           kill (command->pid, SIG_PRESENT);
-           break;
-       }
-       if (find_script_byname (command->name, &starting_list, &service)
-           != NULL)
-       {   /*  Someone else is trying to provide  */
-           script->next_attempting_provider = service->attempting_providers;
-           service->attempting_providers = script;
-           break;
-       }
-       if ( ( service = find_service_in_list (command->name,
-                                              unavailable_services) )
-            == NULL )
-       {   /*  We're the first to try and provide: create it  */
-           if ( ( service =
-                  calloc (1, strlen (command->name) + sizeof *service) )
-                == NULL )
-           {
-               kill (command->pid, SIG_NOT_CHILD);
-               break;
-           }
-           strcpy (service->name, command->name);
-       }
-       else
-       {   /*  Orphaned service: unhook and grab it  */
-           if (service->prev == NULL) unavailable_services = service->next;
-           else service->prev->next = service->next;
-           if (service->next != NULL) service->next->prev = service->prev;
-           service->next = NULL;
-       }
-       service->prev = script->last_service;
-       script->last_service->next = service;
-       script->last_service = service;
-       kill (command->pid, SIG_NOT_PRESENT);
-       break;
-      case -1:
-      default:
-       break;
-    }
-}   /*  End Function process_command  */
-
-static int run_command (const char *file, const char *name, pid_t pid)
-{
-    struct script_struct *script;
-    struct needer_struct *needer = NULL;
-    struct service_struct *service;
-
-    if (find_script_byname (name, &available_list, NULL) != NULL)
-       return SIG_PRESENT;
-    if (pid != 0)
-    {
-       needer = calloc (1, sizeof *needer);
-       if (needer == NULL) return SIG_FAILED;
-       needer->pid = pid;
-    }
-    script = find_script_byname (name, &starting_list, &service);
-    if (script == NULL)
-       service = find_service_in_list (name, unavailable_services);
-    if (service == NULL)
-    {
-       int i;
-       char txt[1024];
-
-       if ( ( script = calloc (1, sizeof *script) ) == NULL )
-       {
-           free (needer);
-           return SIG_FAILED;
-       }
-       service = calloc (1, strlen (name) + sizeof *service);
-       if (service == NULL)
-       {
-           free (script);
-           return SIG_FAILED;
-       }
-       strcpy (service->name, name);
-       switch ( script->pid = fork () )
-       {
-         case 0:   /*  Child   */
-           for (i = 1; i < NSIG; i++) signal (i, SIG_DFL);
-           execlp (get_path (file), service->name, "start", NULL);
-           snprintf (txt, sizeof(txt),
-               _("error at starting service \"%s\"\n"), service->name);
-           err (txt);
-           _exit (SIG_FAILED);
-           break;
-         case -1:  /*  Error   */
-           service->next = unavailable_services;
-           if (unavailable_services != NULL)
-               unavailable_services->prev = service;
-           unavailable_services = service;
-           free (script);
-           free (needer);
-           return SIG_FAILED;
-           /*break;*/
-         default:  /*  Parent  */
-           script->first_service = service;
-           script->last_service = service;
-           insert_entry (&starting_list, script);
-           sched_yield ();
-           break;
-       }
-    }
-    if (needer == NULL) return 0;
-    needer->next = service->needers;
-    service->needers = needer;
-    return 0;
-}   /*  End Function run_command  */
-
-static struct service_struct *find_service_in_list (const char *name,
-                                                   struct service_struct *sv)
-{
-    for (; sv != NULL; sv = sv->next)
-       if (strcmp (sv->name, name) == 0) return (sv);
-    return NULL;
-}   /*  End Function find_service_in_list  */
-
-static struct script_struct *find_script_byname (const char *name,
-                                                struct list_head *head,
-                                                struct service_struct **service)
-{
-    struct script_struct *script;
-
-    for (script = head->first; script != NULL; script = script->next)
-    {
-       struct service_struct *sv;
-
-       if ( ( sv = find_service_in_list (name, script->first_service) )
-            != NULL )
-       {
-           if (service != NULL) *service = sv;
-           return (script);
-       }
-    }
-    if (service != NULL) *service = NULL;
-    return NULL;
-}   /*  End Function find_script_byname  */
-
-static struct script_struct *find_script_bypid (pid_t pid,
-                                               struct list_head *head)
-{
-    struct script_struct *script;
-
-    for (script = head->first; script != NULL; script = script->next)
-       if (script->pid == pid) return (script);
-    return NULL;
-}   /*  End Function find_script_bypid  */
-
-static void insert_entry (struct list_head *head, struct script_struct *entry)
-{
-    if (entry == NULL) return;
-    entry->prev = NULL;
-    entry->next = head->first;
-    if (head->first != NULL) head->first->prev = entry;
-    head->first = entry;
-    if (head->last == NULL) head->last = entry;
-    ++head->num_entries;
-}   /*  End Function insert_entry  */
-
-static void remove_entry (struct list_head *head, struct script_struct *entry)
-{
-    if (entry->prev == NULL) head->first = entry->next;
-    else entry->prev->next = entry->next;
-    if (entry->next == NULL) head->last = entry->prev;
-    else entry->next->prev = entry->prev;
-    --head->num_entries;
-}   /*  End Function remove_entry  */
-
-static void signal_needers (struct service_struct *service, int sig)
-{
-    struct needer_struct *needer, *next_needer;
-
-    for (needer = service->needers; needer != NULL; needer = next_needer)
-    {
-       kill (needer->pid, sig);
-       next_needer = needer->next;
-       free (needer);
-       --num_needers;
-    }
-    service->needers = NULL;
-}   /*  End Function signal_needers  */
-
-static void handle_nonworking (struct script_struct *script)
-{
-    struct service_struct *service, *next;
-
-    for (service = script->first_service; service != NULL; service = next)
-    {
-       struct script_struct *provider = service->attempting_providers;
-
-       next = service->next;
-       if (provider == NULL)
-       {
-           service->prev = NULL;
-           service->next = unavailable_services;
-           if (unavailable_services != NULL)
-               unavailable_services->prev = service;
-           unavailable_services = service;
-           continue;
-       }
-       service->attempting_providers = provider->next_attempting_provider;
-       provider->last_service->next = service;
-       service->prev = provider->last_service;
-       provider->last_service = service;
-       service->next = NULL;
-       kill (provider->pid, SIG_NOT_PRESENT);
-    }
-    free (script);
-}   /*  End Function handle_nonworking  */
-
-static int force_progress (void)
-/*  [RETURNS] 0 if boot scripts are still running, else -1.
-*/
-{
-    struct service_struct *service;
-
-    if (starting_list.num_entries > num_needers) return 0;
-    /*  No progress can be made: signal needers  */
-    for (service = unavailable_services; service != NULL;
-        service = service->next)
-       signal_needers (service,
-                       service->failed ? SIG_FAILED : SIG_NOT_PRESENT);
-    return (starting_list.num_entries < 1) ? -1 : 0;
-}   /*  End Function force_progress  */
-
-static void show_scripts (FILE *fp, const struct script_struct *script,
-                         const char *type)
-{
-    fprintf (fp, "%s SERVICES:\n", type);
-    for (; script != NULL; script = script->next)
-    {
-       struct service_struct *service = script->first_service;
-
-       fputs (service->name, fp);
-       for (service = service->next; service != NULL; service = service->next)
-           fprintf (fp, "  (%s)", service->name);
-       putc ('\n', fp);
-    }
-}   /*  End Function show_scripts  */
-
-static const char *get_path (const char *file)
-{
-    char *p1, *p2;
-    static char path[PATH_SIZE];
-
-    if (file[0] == '/') return file;
-    if (init_path[0] == '\0') return file;
-    for (p1 = init_path; *p1 != '\0'; p1 = p2)
-    {
-       if ( ( p2 = strchr (p1, ':') ) == NULL )
-           p2 = p1 + strlen (p1);
-       strncpy (path, p1, p2 - p1);
-       path[p2 - p1] = '/';
-       strcpy (path + (p2 - p1) + 1, file);
-       if (*p2 == ':') ++p2;
-       if (access (path, X_OK) == 0) return path;
-    }
-    return file;
-}   /*  End Function get_path  */
diff --git a/simpleinit/simpleinit.h b/simpleinit/simpleinit.h
deleted file mode 100644 (file)
index 1d87629..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <limits.h>
-#include <errno.h>
-
-
-#define ERRSTRING strerror (errno)
-#define COMMAND_SIZE  (PIPE_BUF - 4)
-
-
-#define COMMAND_TEST       0  /*  No wait, signal                            */
-#define COMMAND_NEED       1  /*  Wait, signal                               */
-#define COMMAND_ROLLBACK   2  /*  Wait, signal                               */
-#define COMMAND_DUMP_LIST  3  /*  No wait, no signal                         */
-#define COMMAND_PROVIDE    4  /*  Wait, signal                               */
-
-#define SIG_PRESENT        SIGUSR1  /*  Service is available                 */
-#define SIG_STOPPED        SIGUSR1  /*  Service was stopped OK               */
-#define SIG_NOT_PRESENT    SIGUSR2  /*  Not present, but that's OK           */
-#define SIG_FAILED         SIGPOLL  /*  Startup failed                       */
-#define SIG_NOT_STOPPED    SIGPOLL  /*  Failed to stop                       */
-#define SIG_NOT_CHILD      SIGPOLL  /*  Not a child of init                  */
-
-struct command_struct  /*  Must always be COMMAND_SIZE  */
-{
-    signed int command;
-    pid_t pid;
-    pid_t ppid;
-    char name[1];
-};