simpleinit: remove this deprecated set of utils

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2011-06-08 13:20:37 +02:00
parent ea7e29132e
commit 0ff9e65ea3
15 changed files with 1 additions and 2750 deletions

View 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

View 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

View File

@ -1,3 +0,0 @@
initctl
shutdown
simpleinit

View File

@ -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

View File

@ -1 +0,0 @@
.so man8/shutdown.8

View File

@ -1 +0,0 @@
.so man8/shutdown.8

View File

@ -1 +0,0 @@
.so man8/shutdown.8

View File

@ -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/.

View File

@ -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 */

View File

@ -1 +0,0 @@
.so man8/shutdown.8

View File

@ -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).

View File

@ -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 Mikiewicz <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 */

View File

@ -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/.

File diff suppressed because it is too large Load Diff

View File

@ -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];
};