Merge branch 'beta'
This commit is contained in:
commit
c0f5983562
8
Makefile
8
Makefile
@ -7,6 +7,7 @@ SVLOGIN=$(shell svn info | sed -rn '/Repository Root:/{ s|.*//(.*)\@.*|\1|p }')
|
|||||||
override TMP:=$(shell mktemp -d $(VERSION).XXXXXXXX)
|
override TMP:=$(shell mktemp -d $(VERSION).XXXXXXXX)
|
||||||
override TARBALL:=$(TMP)/$(PACKAGE)-$(VERSION).tar.bz2
|
override TARBALL:=$(TMP)/$(PACKAGE)-$(VERSION).tar.bz2
|
||||||
override SFTPBATCH:=$(TMP)/$(VERSION)-sftpbatch
|
override SFTPBATCH:=$(TMP)/$(VERSION)-sftpbatch
|
||||||
|
SOURCES=contrib COPYING COPYRIGHT doc Makefile man README src
|
||||||
|
|
||||||
dist: $(TARBALL)
|
dist: $(TARBALL)
|
||||||
@cp $(TARBALL) .
|
@cp $(TARBALL) .
|
||||||
@ -31,9 +32,10 @@ $(TARBALL).sig: $(TARBALL)
|
|||||||
@gpg -q -ba --use-agent -o $@ $<
|
@gpg -q -ba --use-agent -o $@ $<
|
||||||
|
|
||||||
$(TARBALL): $(TMP)/$(PACKAGE)-$(VERSION)
|
$(TARBALL): $(TMP)/$(PACKAGE)-$(VERSION)
|
||||||
@tar --bzip2 --owner=nobody --group=nogroup -cf $@ -C $(TMP) $(PACKAGE)-$(VERSION)
|
@tar --exclude=.git --bzip2 --owner=nobody --group=nogroup -cf $@ -C $(TMP) $(PACKAGE)-$(VERSION)
|
||||||
|
|
||||||
$(TMP)/$(PACKAGE)-$(VERSION): .svn
|
$(TMP)/$(PACKAGE)-$(VERSION):
|
||||||
svn export . $@
|
@mkdir $(TMP)/$(PACKAGE)-$(VERSION)
|
||||||
|
@cp -R $(SOURCES) $(TMP)/$(PACKAGE)-$(VERSION)/
|
||||||
@chmod -R a+r,u+w,og-w $@
|
@chmod -R a+r,u+w,og-w $@
|
||||||
@find $@ -type d | xargs -r chmod a+rx,u+w,og-w
|
@find $@ -type d | xargs -r chmod a+rx,u+w,og-w
|
||||||
|
@ -1,5 +1,87 @@
|
|||||||
sysvinit (2.89) UNRELEASED; urgency=low
|
sysvinit (2.89) UNRELEASED; urgency=low
|
||||||
|
|
||||||
|
[ Jesse Smith ]
|
||||||
|
* Fixed Clang compiler warning regarding variable data parameters to sprintf().
|
||||||
|
* Updated top-level Makefile to work with git repo instead of old svn repo.
|
||||||
|
* Removed unused variables and findtty() function in bootlogd
|
||||||
|
* Add checks to return code for fscanf() called in init.c.
|
||||||
|
This mostly just cleans up compiler warnings.
|
||||||
|
* Perform error check on setuid() call as suggested in manual page.
|
||||||
|
* Fix typo in killall5.c
|
||||||
|
Move initscript sample file from "src" to "doc" directory and updated
|
||||||
|
Makefile to match.
|
||||||
|
* Allow multiple console output
|
||||||
|
When booting a kernel with multiple serial console support, or multuiple
|
||||||
|
console arguments ala "console=tty1 console=ttyS0,9600" the kernel will output
|
||||||
|
messages to all consoles, init however will not. It will only send output to,
|
||||||
|
and accept input from, the last of the consoles.
|
||||||
|
This patch fixes it.
|
||||||
|
(Patch provided by Martin Buck.)
|
||||||
|
* Added Patch from Debian developer Mats Erik Andersson to make
|
||||||
|
ioctl work on GNU/kFreeBSD. Patches bootlogd.
|
||||||
|
* Added Robert Millan's Debian patch to set TERM variable to xterm (instead
|
||||||
|
of cons25) when running on GNU/kFreeBSD.
|
||||||
|
* Added Robert Millan's Debian patch to use /run/initctl as the named
|
||||||
|
pipe for communicating. This works around a limitation on the kFreeBSD
|
||||||
|
branch which prevents us from using /dev/initctl for pipes.
|
||||||
|
* Confirmed we have applied Guillem Jover's patch to make
|
||||||
|
ifdown work on FreeBSD.
|
||||||
|
* Confirmed we have Debian patch to fix enabling SELinux.
|
||||||
|
(Credit to Petter Reinholdtsen)
|
||||||
|
* Confirmed we have Debian patch to make sure utf-8 flag is not cleared from tty.
|
||||||
|
(Credit to Samuel Thibault)
|
||||||
|
* Confirmed we have Roger Leigh's Makefile patch to allow building
|
||||||
|
with multiarch libcrypt.
|
||||||
|
* Applied Justus Winter's symlink patch to make sure killall5
|
||||||
|
builds and runs on Hurd.
|
||||||
|
* Confirmed we have Werner Fink's PATH_MAX patch for getting
|
||||||
|
killall5 to build on Hurd.
|
||||||
|
* Made sure we have Petter Reinholdtsen's patch to init.c which
|
||||||
|
allows init to build on GNU/kFreeBSD despite missing VSWTC.
|
||||||
|
* Dropping Debian patch to use /run/nologin instead of /etc/nologin in paths.h.
|
||||||
|
Seems every distribution uses a different location. Oracle uses /etc/nologin,
|
||||||
|
CentOS seems to use /var/run/nologin.
|
||||||
|
We will use /etc/nologin and let distros patch to suit their own preference.
|
||||||
|
* Updated halt.8 man page with corrections from
|
||||||
|
Christoph Anton Mitterer.
|
||||||
|
* Confirme we have applied patch from Bjarni Ingi Gislason
|
||||||
|
which fixes typo in fstab-decode man page.
|
||||||
|
* Applied Debian patch to allow init to build on GNU Hurd.
|
||||||
|
(Credit: Roger Leigh)
|
||||||
|
* Confirmed we have Debian patch from developer Johannes Truschnigg
|
||||||
|
which informs the user of field size limit.
|
||||||
|
* Applied patch from Debian to the init manual page (init.8)
|
||||||
|
to better address runlevels. (Author unknown)
|
||||||
|
* The pidof command used to discover the correct PID of
|
||||||
|
a process even if the wrong path was given. For example
|
||||||
|
pidof /wrongpath/sleep would find the PID of a command run as "sleep".
|
||||||
|
This bug was reported on Launchpad for Ubuntu and on Savannah.
|
||||||
|
https://bugs.launchpad.net/ubuntu/+source/sysvinit/+bug/1546126
|
||||||
|
http://savannah.nongnu.org/bugs/?47196
|
||||||
|
This bug appears to have been fixed in the development branch,
|
||||||
|
allowing these bugs to be tested/closed.
|
||||||
|
* Confirmed Savannah bug #37114 (mountpoint does not detect
|
||||||
|
mount points using --bind on same file system) still exists,
|
||||||
|
but fixed in Debian and Red Hat.
|
||||||
|
Considering this bug closed since distributions are using
|
||||||
|
util-linux's mountpoint program and ours is no longer
|
||||||
|
built/used by default.
|
||||||
|
Considered importing util-linux mountpoint but that would duplicate
|
||||||
|
effort and pull in a new dependency on libmount.
|
||||||
|
* Problem with pidof breaks after prelink (Savannah bug #34992)
|
||||||
|
fixed. Patch supplied by Dave Dykstra.
|
||||||
|
* Patch to automatically spawn agetty on kernel consoles
|
||||||
|
The feature is useful for developers and admins that occasionally need
|
||||||
|
to boot with e.g. console=ttyS0.
|
||||||
|
The built in default can be overridden via inittab for each device. An
|
||||||
|
entry like "S0::off:" turns off the getty on ttyS0.
|
||||||
|
characters in log file. Also makes parsing easier.
|
||||||
|
This should close Savannah bug report 36528.
|
||||||
|
http://savannah.nongnu.org/bugs/?36528
|
||||||
|
* Applied patches provided in Savannah bug report 49991. Fix tabs in
|
||||||
|
bootlogd and avoid printing unitialized "buf" variable when
|
||||||
|
consolename() fails.
|
||||||
|
|
||||||
[ Werner Fink ]
|
[ Werner Fink ]
|
||||||
* Do not forget room for last NULL of new environment (was
|
* Do not forget room for last NULL of new environment (was
|
||||||
local bug 35866)
|
local bug 35866)
|
||||||
|
@ -66,7 +66,11 @@ You might want to create a file called "/etc/shutdown.allow". Read the
|
|||||||
manual page on shutdown to find out more about this.
|
manual page on shutdown to find out more about this.
|
||||||
|
|
||||||
Running from a read-only file system (CDROM?):
|
Running from a read-only file system (CDROM?):
|
||||||
|
<<<<<<< HEAD
|
||||||
* All communication to init goes through the FIFO /run/initctl.
|
* All communication to init goes through the FIFO /run/initctl.
|
||||||
|
=======
|
||||||
|
o All communication to init goes through the FIFO /run/initctl.
|
||||||
|
>>>>>>> beta
|
||||||
There should be no problem using a read-only root file system
|
There should be no problem using a read-only root file system
|
||||||
IF you use a Linux kernel > 1.3.66. Older kernels don't allow
|
IF you use a Linux kernel > 1.3.66. Older kernels don't allow
|
||||||
writing to a FIFO on a read-only file system.
|
writing to a FIFO on a read-only file system.
|
||||||
|
@ -51,7 +51,7 @@ halt, reboot, poweroff \- stop the system.
|
|||||||
.\"}}}
|
.\"}}}
|
||||||
.\"{{{ Description
|
.\"{{{ Description
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
\fBHalt\fP notes that the system is being brought down in the file
|
\fBhalt\fP notes that the system is being brought down in the file
|
||||||
\fI/var/log/wtmp\fP, and then either tells the kernel to halt, reboot or
|
\fI/var/log/wtmp\fP, and then either tells the kernel to halt, reboot or
|
||||||
power-off the system.
|
power-off the system.
|
||||||
.PP
|
.PP
|
||||||
@ -68,12 +68,12 @@ and 6, that is when the systems shutdown scripts are being run.
|
|||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.IP \fB\-n\fP
|
.IP \fB\-n\fP
|
||||||
Don't sync before reboot or halt. Note that the kernel and storage
|
Don't sync before reboot or halt. Note that the kernel and storage
|
||||||
drivers may still sync.
|
drivers may still sync. This implies \fB\-d\fP.
|
||||||
.IP \fB\-w\fP
|
.IP \fB\-w\fP
|
||||||
Don't actually reboot or halt but only write the wtmp record
|
Don't actually reboot or halt but only write the wtmp record
|
||||||
(in the \fI/var/log/wtmp\fP file).
|
(in the \fI/var/log/wtmp\fP file).
|
||||||
.IP \fB\-d\fP
|
.IP \fB\-d\fP
|
||||||
Don't write the wtmp record. The \fB\-n\fP flag implies \fB\-d\fP.
|
Don't write the wtmp record.
|
||||||
.IP \fB\-f\fP
|
.IP \fB\-f\fP
|
||||||
Force halt or reboot, don't call \fBshutdown\fP(8).
|
Force halt or reboot, don't call \fBshutdown\fP(8).
|
||||||
.IP \fB\-i\fP
|
.IP \fB\-i\fP
|
||||||
|
110
man/init.8
110
man/init.8
@ -56,21 +56,34 @@ A \fIrunlevel\fP is a software configuration of the system which allows
|
|||||||
only a selected group of processes to exist. The processes spawned by
|
only a selected group of processes to exist. The processes spawned by
|
||||||
\fBinit\fP for each of these runlevels are defined in the
|
\fBinit\fP for each of these runlevels are defined in the
|
||||||
\fB/etc/inittab\fP file. \fBInit\fP can be in one of eight runlevels:
|
\fB/etc/inittab\fP file. \fBInit\fP can be in one of eight runlevels:
|
||||||
\fB0\(en6\fP and \fBS\fP or \fBs\fP. The runlevel is
|
\fB0\(en6\fP and \fBS\fP (a.k.a. \fBs\fP). The runlevel is
|
||||||
changed by having a privileged user run \fBtelinit\fP, which sends
|
changed by having a privileged user run \fBtelinit\fP, which sends
|
||||||
appropriate signals to \fBinit\fP, telling it which runlevel to change
|
appropriate signals to \fBinit\fP, telling it which runlevel to change
|
||||||
to.
|
to.
|
||||||
.PP
|
.PP
|
||||||
Runlevels \fB0\fP, \fB1\fP, and \fB6\fP are reserved. Runlevel 0 is used to
|
Runlevels \fBS\fP, \fB0\fP, \fB1\fP, and \fB6\fP are reserved.
|
||||||
halt the system, runlevel 6 is used to reboot the system, and runlevel
|
Runlevel S is used to initialize the system on boot.
|
||||||
1 is used to get the system down into single user mode. Runlevel \fBS\fP
|
When starting runlevel S (on boot)
|
||||||
is not really meant to be used directly, but more for the scripts that are
|
or runlevel 1 (switching from a multi-user runlevel)
|
||||||
executed when entering runlevel 1. For more information on this,
|
the system is entering ``single-user mode'', after which the
|
||||||
|
current runlevel is S.
|
||||||
|
Runlevel 0 is used to halt the system;
|
||||||
|
runlevel 6 is used to reboot the system.
|
||||||
|
.PP
|
||||||
|
After booting through S the system automatically enters one of
|
||||||
|
the multi-user runlevels 2 through 5, unless there was some
|
||||||
|
problem that needs to be fixed by the administrator in
|
||||||
|
single-user mode.
|
||||||
|
Normally after entering single-user mode
|
||||||
|
the administrator performs maintenance and then reboots the system.
|
||||||
|
.PP
|
||||||
|
For more information,
|
||||||
see the manpages for \fBshutdown\fP(8) and \fBinittab\fP(5).
|
see the manpages for \fBshutdown\fP(8) and \fBinittab\fP(5).
|
||||||
.PP
|
.PP
|
||||||
Runlevels 7\(en9 are also valid, though not really documented.
|
Runlevels 7-9 are also valid, though not really documented. This is
|
||||||
This is because "traditional" Unix variants don't use them.
|
because "traditional" Unix variants don't use them.
|
||||||
In case you're curious, runlevels \fIS\fP and \fIs\fP are in fact the same.
|
.PP
|
||||||
|
Runlevels \fIS\fP and \fIs\fP are the same.
|
||||||
Internally they are aliases for the same runlevel.
|
Internally they are aliases for the same runlevel.
|
||||||
.\"}}}
|
.\"}}}
|
||||||
.PP
|
.PP
|
||||||
@ -82,9 +95,10 @@ determines the initial runlevel of the system. If there is no such
|
|||||||
entry (or no \fB/etc/inittab\fP at all), a runlevel must be
|
entry (or no \fB/etc/inittab\fP at all), a runlevel must be
|
||||||
entered at the system console.
|
entered at the system console.
|
||||||
.PP
|
.PP
|
||||||
Runlevel \fBS\fP or \fBs\fP bring the system to single user mode
|
Runlevel \fBS\fP or \fBs\fP initialize the system
|
||||||
and do not require an \fB/etc/inittab\fP file. In single user mode,
|
and do not require an \fB/etc/inittab\fP file.
|
||||||
\fB/sbin/sulogin\fP is invoked on \fB/dev/console\fP.
|
.PP
|
||||||
|
In single user mode, \fB/sbin/sulogin\fP is invoked on \fB/dev/console\fP.
|
||||||
.PP
|
.PP
|
||||||
When entering single user mode, \fBinit\fP initializes the consoles
|
When entering single user mode, \fBinit\fP initializes the consoles
|
||||||
\fBstty\fP settings to sane values. Clocal mode is set. Hardware
|
\fBstty\fP settings to sane values. Clocal mode is set. Hardware
|
||||||
@ -110,7 +124,7 @@ When one of the above three conditions occurs, it re-examines
|
|||||||
the \fB/etc/inittab\fP file. New entries can be added to this file at
|
the \fB/etc/inittab\fP file. New entries can be added to this file at
|
||||||
any time. However, \fBinit\fP still waits for one of the above three
|
any time. However, \fBinit\fP still waits for one of the above three
|
||||||
conditions to occur. To provide for an instantaneous response, the
|
conditions to occur. To provide for an instantaneous response, the
|
||||||
\fBtelinit Q\fP or \fBq\fP command can wake up \fBinit\fP to re-examine the
|
\fBtelinit Q\fP or \fBq\fP command can wake up \fBinit\fP to re-examine (reload) the
|
||||||
\fB/etc/inittab\fP file.
|
\fB/etc/inittab\fP file.
|
||||||
.PP
|
.PP
|
||||||
If \fBinit\fP is not in single user mode and receives a powerfail
|
If \fBinit\fP is not in single user mode and receives a powerfail
|
||||||
@ -130,7 +144,7 @@ letters \fBF\fP, \fBO\fP or \fBL\fP, init will behave as if it has read
|
|||||||
the letter \fBF\fP.
|
the letter \fBF\fP.
|
||||||
.PP
|
.PP
|
||||||
Usage of \fBSIGPWR\fP and \fB/etc/powerstatus\fP is discouraged. Someone
|
Usage of \fBSIGPWR\fP and \fB/etc/powerstatus\fP is discouraged. Someone
|
||||||
wanting to interact with \fBinit\fP should use the \fB/dev/initctl\fP
|
wanting to interact with \fBinit\fP should use the \fB/run/initctl\fP
|
||||||
control channel - see the source code of the \fBsysvinit\fP package
|
control channel - see the source code of the \fBsysvinit\fP package
|
||||||
for more documentation about this.
|
for more documentation about this.
|
||||||
.PP
|
.PP
|
||||||
@ -160,19 +174,18 @@ tell \fBinit\fP to re-examine the \fB/etc/inittab\fP file.
|
|||||||
.IP "\fBS\fP or \fBs\fP"
|
.IP "\fBS\fP or \fBs\fP"
|
||||||
tell \fBinit\fP to switch to single user mode.
|
tell \fBinit\fP to switch to single user mode.
|
||||||
.IP "\fBU\fP or \fBu\fP"
|
.IP "\fBU\fP or \fBu\fP"
|
||||||
tell \fBinit\fP to re-execute itself (preserving the state).
|
tell \fBinit\fP to re-execute itself (preserving the state). No re-examining of
|
||||||
No re-examining of
|
\fB/etc/inittab\fP file happens. Run level should be one of
|
||||||
\fB/etc/inittab\fP file happens.
|
\fBSs0123456\fP
|
||||||
Run level should be one of \fBSs0123456\fP otherwise request would be
|
otherwise request would be silently ignored.
|
||||||
silently ignored.
|
|
||||||
.PP
|
.PP
|
||||||
\fBtelinit\fP can tell \fBinit\fP how long it should wait
|
\fBtelinit\fP can tell \fBinit\fP how long it should wait
|
||||||
between sending processes the SIGTERM and SIGKILL signals. The default
|
between sending processes the SIGTERM and SIGKILL signals. The default
|
||||||
is 5 seconds, but this can be changed with the \fB\-t\fP option.
|
is 5 seconds, but this can be changed with the \fB-t\fP option.
|
||||||
.PP
|
.PP
|
||||||
\fBtelinit \-e\fP tells \fBinit\fP to change the environment
|
\fBtelinit -e\fP tells \fBinit\fP to change the environment
|
||||||
for processes it spawns.
|
for processes it spawns.
|
||||||
The argument of \fB\-e\fP is either of the form \fIVAR\fP=\fIVAL\fP
|
The argument of \fB-e\fP is either of the form \fIVAR\fP=\fIVAL\fP
|
||||||
which sets variable \fIVAR\fP to value \fIVAL\fP,
|
which sets variable \fIVAR\fP to value \fIVAL\fP,
|
||||||
or of the form \fIVAR\fP
|
or of the form \fIVAR\fP
|
||||||
(without an equality sign)
|
(without an equality sign)
|
||||||
@ -202,16 +215,15 @@ The system console. This is really inherited from the kernel; however
|
|||||||
if it is not set \fBinit\fP will set it to \fB/dev/console\fP by default.
|
if it is not set \fBinit\fP will set it to \fB/dev/console\fP by default.
|
||||||
.SH BOOTFLAGS
|
.SH BOOTFLAGS
|
||||||
It is possible to pass a number of flags to \fBinit\fP from the
|
It is possible to pass a number of flags to \fBinit\fP from the
|
||||||
boot monitor (eg.\& LILO).
|
boot monitor (eg. LILO). \fBInit\fP accepts the following flags:
|
||||||
\fBInit\fP accepts the following flags:
|
|
||||||
.TP 0.5i
|
.TP 0.5i
|
||||||
.B -s, S, single
|
.B -s, S, single
|
||||||
Single user mode boot.
|
Single user mode boot. In this mode \fI/etc/inittab\fP is
|
||||||
In this mode \fI/etc/inittab\fP is examined and the bootup rc scripts
|
examined and the bootup rc scripts are usually run before
|
||||||
are usually run before the single user mode shell is started.
|
the single user mode shell is started.
|
||||||
.PP
|
.PP
|
||||||
.TP 0.5i
|
.TP 0.5i
|
||||||
.B 1\(en5
|
.B 1-5
|
||||||
Runlevel to boot into.
|
Runlevel to boot into.
|
||||||
.PP
|
.PP
|
||||||
.TP 0.5i
|
.TP 0.5i
|
||||||
@ -224,25 +236,23 @@ other startup scripts.
|
|||||||
The LILO boot loader adds the word "auto" to the command line if it
|
The LILO boot loader adds the word "auto" to the command line if it
|
||||||
booted the kernel with the default command line (without user intervention).
|
booted the kernel with the default command line (without user intervention).
|
||||||
If this is found \fBinit\fP sets the "AUTOBOOT" environment
|
If this is found \fBinit\fP sets the "AUTOBOOT" environment
|
||||||
variable to "yes".
|
variable to "yes". Note that you cannot use this for any security
|
||||||
Note that you cannot use this for any security measures - of course
|
measures - of course the user could specify "auto" or \-a on the
|
||||||
the user could specify "auto" or \-a on the command line manually.
|
command line manually.
|
||||||
.PP
|
.PP
|
||||||
.TP 0.5i
|
.TP 0.5i
|
||||||
.BI "\-z " xxx
|
.BI "-z " xxx
|
||||||
The argument to \fB\-z\fP is ignored.
|
The argument to \fB-z\fP is ignored. You can use this to expand the command
|
||||||
You can use this to expand the command line a bit, so that it takes
|
line a bit, so that it takes some more space on the stack. \fBInit\fP
|
||||||
some more space on the stack.
|
can then manipulate the command line so that \fBps\fP(1) shows
|
||||||
\fBInit\fP can then manipulate the command line so that \fBps\fP(1)
|
the current runlevel.
|
||||||
shows the current runlevel.
|
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
.SH INTERFACE
|
.SH INTERFACE
|
||||||
Init listens on a \fIfifo\fP in /dev, \fI/dev/initctl\fP, for messages.
|
Init listens on a \fIfifo\fP in /dev, \fI/run/initctl\fP, for messages.
|
||||||
\fBTelinit\fP uses this to communicate with init.
|
\fBTelinit\fP uses this to communicate with init. The interface is not
|
||||||
The interface is not very well documented or finished.
|
very well documented or finished. Those interested should study the
|
||||||
Those interested should study the \fIinitreq.h\fP file in the
|
\fIinitreq.h\fP file in the \fIsrc/\fP subdirectory of the \fBinit\fP
|
||||||
\fIsrc/\fP subdirectory of the \fBinit\fP source code tar archive.
|
source code tar archive.
|
||||||
.SH SIGNALS
|
.SH SIGNALS
|
||||||
Init reacts to several signals:
|
Init reacts to several signals:
|
||||||
.TP 0.5i
|
.TP 0.5i
|
||||||
@ -252,7 +262,7 @@ Has the same effect as \fBtelinit q\fP.
|
|||||||
.TP 0.5i
|
.TP 0.5i
|
||||||
.B SIGUSR1
|
.B SIGUSR1
|
||||||
On receipt of this signals, init closes and re-opens its control fifo,
|
On receipt of this signals, init closes and re-opens its control fifo,
|
||||||
\fB/dev/initctl\fP. Useful for bootscripts when /dev is remounted.
|
\fB/run/initctl\fP. Useful for bootscripts when /dev is remounted.
|
||||||
.TP 0.5i
|
.TP 0.5i
|
||||||
.B SIGINT
|
.B SIGINT
|
||||||
Normally the kernel sends this signal to init when CTRL-ALT-DEL is
|
Normally the kernel sends this signal to init when CTRL-ALT-DEL is
|
||||||
@ -277,7 +287,7 @@ file in the directory \fI/etc/init.d\fP explaining how these scripts work.
|
|||||||
/dev/console
|
/dev/console
|
||||||
/var/run/utmp
|
/var/run/utmp
|
||||||
/var/log/wtmp
|
/var/log/wtmp
|
||||||
/dev/initctl
|
/run/initctl
|
||||||
.fi
|
.fi
|
||||||
.\"}}}
|
.\"}}}
|
||||||
.\"{{{ Warnings
|
.\"{{{ Warnings
|
||||||
@ -287,6 +297,14 @@ remain in the same process group which was originally created
|
|||||||
for them. If the processes change their group, \fBinit\fP can't
|
for them. If the processes change their group, \fBinit\fP can't
|
||||||
kill them and you may end up with two processes reading from one
|
kill them and you may end up with two processes reading from one
|
||||||
terminal line.
|
terminal line.
|
||||||
|
.PP
|
||||||
|
On a Debian system, entering runlevel 1 causes all processes
|
||||||
|
to be killed except for kernel threads and the script that does
|
||||||
|
the killing and other processes in its session.
|
||||||
|
As a consequence of this, it isn't safe to return from runlevel 1
|
||||||
|
to a multi-user runlevel: daemons that were started in runlevel S
|
||||||
|
and are needed for normal operation are no longer running.
|
||||||
|
The system should be rebooted.
|
||||||
.\"}}}
|
.\"}}}
|
||||||
.\"{{{ Diagnostics
|
.\"{{{ Diagnostics
|
||||||
.SH DIAGNOSTICS
|
.SH DIAGNOSTICS
|
||||||
@ -309,7 +327,7 @@ page by Michael Haardt (u31b3hs@pool.informatik.rwth-aachen.de).
|
|||||||
.BR login (1),
|
.BR login (1),
|
||||||
.BR sh (1),
|
.BR sh (1),
|
||||||
.BR runlevel (8),
|
.BR runlevel (8),
|
||||||
.BR shutdown (8),
|
.BR shutdown(8),
|
||||||
.BR kill (1),
|
.BR kill (1),
|
||||||
.BR inittab (5),
|
.BR inittab (5),
|
||||||
.BR initscript (5),
|
.BR initscript (5),
|
||||||
|
11
src/Makefile
11
src/Makefile
@ -11,6 +11,7 @@
|
|||||||
CPPFLAGS =
|
CPPFLAGS =
|
||||||
CFLAGS ?= -ansi -O2 -fomit-frame-pointer -fstack-protector
|
CFLAGS ?= -ansi -O2 -fomit-frame-pointer -fstack-protector
|
||||||
override CFLAGS += -W -Wall -Wunreachable-code -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -D_XOPEN_SOURCE -D_GNU_SOURCE
|
override CFLAGS += -W -Wall -Wunreachable-code -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -D_XOPEN_SOURCE -D_GNU_SOURCE
|
||||||
|
override CFLAGS += $(shell getconf LFS_CFLAGS)
|
||||||
STATIC =
|
STATIC =
|
||||||
MANDB := s@^\('\\\\\"\)[^\*-]*-\*- coding: [^[:blank:]]\+ -\*-@\1@
|
MANDB := s@^\('\\\\\"\)[^\*-]*-\*- coding: [^[:blank:]]\+ -\*-@\1@
|
||||||
|
|
||||||
@ -187,7 +188,7 @@ install:
|
|||||||
$(INSTALL_EXEC) $$i $(ROOT)/usr/bin/ ; \
|
$(INSTALL_EXEC) $$i $(ROOT)/usr/bin/ ; \
|
||||||
done
|
done
|
||||||
# $(INSTALL_DIR) $(ROOT)/etc/
|
# $(INSTALL_DIR) $(ROOT)/etc/
|
||||||
# $(INSTALL_EXEC) initscript.sample $(ROOT)/etc/
|
# $(INSTALL_EXEC) ../doc/initscript.sample $(ROOT)/etc/
|
||||||
ln -sf halt $(ROOT)/sbin/reboot
|
ln -sf halt $(ROOT)/sbin/reboot
|
||||||
ln -sf halt $(ROOT)/sbin/poweroff
|
ln -sf halt $(ROOT)/sbin/poweroff
|
||||||
ln -sf init $(ROOT)/sbin/telinit
|
ln -sf init $(ROOT)/sbin/telinit
|
||||||
@ -216,8 +217,8 @@ ifeq ($(ROOT),)
|
|||||||
#
|
#
|
||||||
# This part is skipped on Debian systems, the
|
# This part is skipped on Debian systems, the
|
||||||
# debian.preinst script takes care of it.
|
# debian.preinst script takes care of it.
|
||||||
@if [ ! -p /dev/initctl ]; then \
|
@if [ ! -p /run/initctl ]; then \
|
||||||
echo "Creating /dev/initctl"; \
|
echo "Creating /run/initctl"; \
|
||||||
rm -f /dev/initctl; \
|
rm -f /run/initctl; \
|
||||||
mknod -m 600 /dev/initctl p; fi
|
mknod -m 600 /run/initctl p; fi
|
||||||
endif
|
endif
|
||||||
|
322
src/bootlogd.c
322
src/bootlogd.c
@ -57,6 +57,7 @@
|
|||||||
char *Version = "@(#) bootlogd 2.86 03-Jun-2004 miquels@cistron.nl";
|
char *Version = "@(#) bootlogd 2.86 03-Jun-2004 miquels@cistron.nl";
|
||||||
|
|
||||||
#define LOGFILE "/var/log/boot"
|
#define LOGFILE "/var/log/boot"
|
||||||
|
#define MAX_CONSOLES 16
|
||||||
|
|
||||||
char ringbuf[32768];
|
char ringbuf[32768];
|
||||||
char *endptr = ringbuf + sizeof(ringbuf);
|
char *endptr = ringbuf + sizeof(ringbuf);
|
||||||
@ -68,10 +69,10 @@ int didnl = 1;
|
|||||||
int createlogfile = 0;
|
int createlogfile = 0;
|
||||||
int syncalot = 0;
|
int syncalot = 0;
|
||||||
|
|
||||||
struct line {
|
struct real_cons {
|
||||||
char buf[256];
|
char name[1024];
|
||||||
int pos;
|
int fd;
|
||||||
} line;
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Console devices as listed on the kernel command line and
|
* Console devices as listed on the kernel command line and
|
||||||
@ -108,62 +109,68 @@ void handler(int sig)
|
|||||||
/*
|
/*
|
||||||
* Scan /dev and find the device name.
|
* Scan /dev and find the device name.
|
||||||
*/
|
*/
|
||||||
static int findtty(char *res, const char *startdir, size_t rlen, dev_t dev)
|
/*
|
||||||
|
This function does not appear to be called anymore. Commenting it
|
||||||
|
out for now, can probably be removed entirely in the future.
|
||||||
|
|
||||||
|
static int findtty(char *res, const char *startdir, int rlen, dev_t dev)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
|
struct stat st;
|
||||||
int r = -1;
|
int r = -1;
|
||||||
|
char *olddir = getcwd(NULL, 0);
|
||||||
|
|
||||||
if ((dir = opendir(startdir)) == NULL) {
|
if (chdir(startdir) < 0 || (dir = opendir(".")) == NULL) {
|
||||||
int msglen = strlen(startdir) + 11;
|
int msglen = strlen(startdir) + 11;
|
||||||
char *msg = malloc(msglen);
|
char *msg = malloc(msglen);
|
||||||
snprintf(msg, msglen, "bootlogd: %s", startdir);
|
snprintf(msg, msglen, "bootlogd: %s", startdir);
|
||||||
perror(msg);
|
perror(msg);
|
||||||
free(msg);
|
free(msg);
|
||||||
|
chdir(olddir);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
while ((ent = readdir(dir)) != NULL) {
|
while ((ent = readdir(dir)) != NULL) {
|
||||||
struct stat st;
|
if (lstat(ent->d_name, &st) != 0)
|
||||||
int pathlen = strlen(startdir) + strlen(ent->d_name) + 2;
|
|
||||||
char *path = malloc(pathlen);
|
|
||||||
snprintf(path, pathlen, "%s/%s", startdir, ent->d_name);
|
|
||||||
|
|
||||||
if (lstat(path, &st) != 0) {
|
|
||||||
free(path);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
if (S_ISDIR(st.st_mode)
|
if (S_ISDIR(st.st_mode)
|
||||||
&& 0 != strcmp(".", ent->d_name)
|
&& 0 != strcmp(".", ent->d_name)
|
||||||
&& 0 != strcmp("..", ent->d_name)) {
|
&& 0 != strcmp("..", ent->d_name)) {
|
||||||
|
char *path = malloc(rlen);
|
||||||
|
snprintf(path, rlen, "%s/%s", startdir, ent->d_name);
|
||||||
r = findtty(res, path, rlen, dev);
|
r = findtty(res, path, rlen, dev);
|
||||||
if (0 == r) { /* device found, return */
|
free(path);
|
||||||
free(path);
|
if (0 == r) {
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
chdir(olddir);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
free(path);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
free(path);
|
|
||||||
path = NULL;
|
|
||||||
if (!S_ISCHR(st.st_mode))
|
if (!S_ISCHR(st.st_mode))
|
||||||
continue;
|
continue;
|
||||||
if (st.st_rdev == dev) {
|
if (st.st_rdev == dev) {
|
||||||
if ( (strlen(ent->d_name) + strlen(startdir) + 1) >= rlen) {
|
if ( (int) (strlen(ent->d_name) + strlen(startdir) + 1) >= rlen) {
|
||||||
fprintf(stderr, "bootlogd: console device name too long\n");
|
fprintf(stderr, "bootlogd: console device name too long\n");
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
chdir(olddir);
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
snprintf(res, rlen, "%s/%s", startdir, ent->d_name);
|
snprintf(res, rlen, "%s/%s", startdir, ent->d_name);
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
chdir(olddir);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|
||||||
|
chdir(olddir);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For some reason, openpty() in glibc sometimes doesn't
|
* For some reason, openpty() in glibc sometimes doesn't
|
||||||
@ -209,7 +216,7 @@ int findpty(int *master, int *slave, char *name)
|
|||||||
* See if a console taken from the kernel command line maps
|
* See if a console taken from the kernel command line maps
|
||||||
* to a character device we know about, and if we can open it.
|
* to a character device we know about, and if we can open it.
|
||||||
*/
|
*/
|
||||||
int isconsole(char *s, char *res, size_t rlen)
|
int isconsole(char *s, char *res, int rlen)
|
||||||
{
|
{
|
||||||
struct consdev *c;
|
struct consdev *c;
|
||||||
int l, sl, i, fd;
|
int l, sl, i, fd;
|
||||||
@ -236,50 +243,21 @@ int isconsole(char *s, char *res, size_t rlen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find out the _real_ console. Assume that stdin is connected to
|
* Find out the _real_ console(s). Assume that stdin is connected to
|
||||||
* the console device (/dev/console).
|
* the console device (/dev/console).
|
||||||
*/
|
*/
|
||||||
int consolename(char *res, size_t rlen)
|
int consolenames(struct real_cons *cons, int max_consoles)
|
||||||
{
|
{
|
||||||
#ifdef TIOCGDEV
|
#ifdef TIOCGDEV
|
||||||
unsigned int kdev;
|
/* This appears to be unused. unsigned int kdev; */
|
||||||
#endif
|
#endif
|
||||||
struct stat st;
|
struct stat st, st2;
|
||||||
int n;
|
|
||||||
#ifdef __linux__
|
|
||||||
char buf[256];
|
char buf[256];
|
||||||
char *p;
|
char *p;
|
||||||
struct stat st2;
|
|
||||||
int didmount = 0;
|
int didmount = 0;
|
||||||
int r;
|
int n;
|
||||||
int fd;
|
int fd;
|
||||||
#endif
|
int considx, num_consoles = 0;
|
||||||
|
|
||||||
fstat(0, &st);
|
|
||||||
if (major(st.st_rdev) != 5 || minor(st.st_rdev) != 1) {
|
|
||||||
/*
|
|
||||||
* Old kernel, can find real device easily.
|
|
||||||
*/
|
|
||||||
int r = findtty(res, "/dev", rlen, st.st_rdev);
|
|
||||||
if (0 != r)
|
|
||||||
fprintf(stderr, "bootlogd: cannot find console device "
|
|
||||||
"%d:%d under /dev\n", major(st.st_rdev), minor(st.st_rdev));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef TIOCGDEV
|
|
||||||
# ifndef ENOIOCTLCMD
|
|
||||||
# define ENOIOCTLCMD 515
|
|
||||||
# endif
|
|
||||||
if (ioctl(0, TIOCGDEV, &kdev) == 0) {
|
|
||||||
int r = findtty(res, "/dev", rlen, (dev_t)kdev);
|
|
||||||
if (0 != r)
|
|
||||||
fprintf(stderr, "bootlogd: cannot find console device "
|
|
||||||
"%d:%d under /dev\n", major(kdev), minor(kdev));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
if (errno != ENOIOCTLCMD) return -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
/*
|
/*
|
||||||
@ -288,7 +266,7 @@ int consolename(char *res, size_t rlen)
|
|||||||
stat("/", &st);
|
stat("/", &st);
|
||||||
if (stat("/proc", &st2) < 0) {
|
if (stat("/proc", &st2) < 0) {
|
||||||
perror("bootlogd: /proc");
|
perror("bootlogd: /proc");
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
if (st.st_dev == st2.st_dev) {
|
if (st.st_dev == st2.st_dev) {
|
||||||
if (mount("proc", "/proc", "proc", 0, NULL) < 0) {
|
if (mount("proc", "/proc", "proc", 0, NULL) < 0) {
|
||||||
@ -298,22 +276,21 @@ int consolename(char *res, size_t rlen)
|
|||||||
didmount = 1;
|
didmount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = 0;
|
n = -1;
|
||||||
r = -1;
|
|
||||||
if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) {
|
if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) {
|
||||||
perror("bootlogd: /proc/cmdline");
|
perror("bootlogd: /proc/cmdline");
|
||||||
} else {
|
} else {
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
if ((n = read(fd, buf, sizeof(buf) - 1)) >= 0) {
|
if ((n = read(fd, buf, sizeof(buf) - 1)) < 0)
|
||||||
r = 0;
|
|
||||||
buf[sizeof(buf)-1] = 0; /* enforce null termination */
|
|
||||||
} else
|
|
||||||
perror("bootlogd: /proc/cmdline");
|
perror("bootlogd: /proc/cmdline");
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
if (didmount) umount("/proc");
|
if (didmount) umount("/proc");
|
||||||
|
|
||||||
if (r < 0) return r;
|
|
||||||
|
if (n < 0) return 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OK, so find console= in /proc/cmdline.
|
* OK, so find console= in /proc/cmdline.
|
||||||
@ -321,21 +298,32 @@ int consolename(char *res, size_t rlen)
|
|||||||
*/
|
*/
|
||||||
p = buf + n;
|
p = buf + n;
|
||||||
*p-- = 0;
|
*p-- = 0;
|
||||||
r = -1;
|
|
||||||
while (p >= buf) {
|
while (p >= buf) {
|
||||||
if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
|
if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') {
|
||||||
*p-- = 0;
|
*p-- = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (strncmp(p, "console=", 8) == 0 &&
|
if (strncmp(p, "console=", 8) == 0 &&
|
||||||
isconsole(p + 8, res, rlen)) {
|
isconsole(p + 8, cons[num_consoles].name, sizeof(cons[num_consoles].name))) {
|
||||||
r = 0;
|
/*
|
||||||
break;
|
* Suppress duplicates
|
||||||
|
*/
|
||||||
|
for (considx = 0; considx < num_consoles; considx++) {
|
||||||
|
if (!strcmp(cons[num_consoles].name, cons[considx].name)) {
|
||||||
|
goto dontuse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
num_consoles++;
|
||||||
|
if (num_consoles >= max_consoles) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
dontuse:
|
||||||
p--;
|
p--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r == 0) return r;
|
if (num_consoles > 0) return num_consoles;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -343,12 +331,12 @@ int consolename(char *res, size_t rlen)
|
|||||||
* guess the default console.
|
* guess the default console.
|
||||||
*/
|
*/
|
||||||
for (n = 0; defcons[n]; n++)
|
for (n = 0; defcons[n]; n++)
|
||||||
if (isconsole(defcons[n], res, rlen))
|
if (isconsole(defcons[n], cons[0].name, sizeof(cons[0].name)))
|
||||||
return 0;
|
return 1;
|
||||||
|
|
||||||
fprintf(stderr, "bootlogd: cannot deduce real console device\n");
|
fprintf(stderr, "bootlogd: cannot deduce real console device\n");
|
||||||
|
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -357,63 +345,75 @@ int consolename(char *res, size_t rlen)
|
|||||||
*/
|
*/
|
||||||
void writelog(FILE *fp, unsigned char *ptr, int len)
|
void writelog(FILE *fp, unsigned char *ptr, int len)
|
||||||
{
|
{
|
||||||
time_t t;
|
int dosync = 0;
|
||||||
char *s;
|
int i;
|
||||||
char tmp[8];
|
static int first_run = 1;
|
||||||
int olen = len;
|
static int inside_esc = 0;
|
||||||
int dosync = 0;
|
|
||||||
int tlen;
|
|
||||||
|
|
||||||
while (len > 0) {
|
for (i = 0; i < len; i++) {
|
||||||
tmp[0] = 0;
|
int ignore = 0;
|
||||||
if (didnl) {
|
|
||||||
|
/* prepend date to every line */
|
||||||
|
if (*(ptr-1) == '\n' || first_run) {
|
||||||
|
time_t t;
|
||||||
|
char *s;
|
||||||
time(&t);
|
time(&t);
|
||||||
s = ctime(&t);
|
s = ctime(&t);
|
||||||
fprintf(fp, "%.24s: ", s);
|
fprintf(fp, "%.24s: ", s);
|
||||||
didnl = 0;
|
dosync = 1;
|
||||||
|
first_run = 0;
|
||||||
}
|
}
|
||||||
switch (*ptr) {
|
|
||||||
case 27: /* ESC */
|
/* remove escape sequences, but do it in a way that allows us to stop
|
||||||
strcpy(tmp, "^[");
|
* in the middle in case the string was cut off */
|
||||||
break;
|
if (inside_esc == 1) {
|
||||||
case '\r':
|
/* first '[' is special because if we encounter it again, it should be considered the final byte */
|
||||||
line.pos = 0;
|
if (*ptr == '[') {
|
||||||
break;
|
/* multi char sequence */
|
||||||
case 8: /* ^H */
|
ignore = 1;
|
||||||
if (line.pos > 0) line.pos--;
|
inside_esc = 2;
|
||||||
break;
|
} else {
|
||||||
case '\n':
|
/* single char sequence */
|
||||||
didnl = 1;
|
if (*ptr >= 64 && *ptr <= 95) {
|
||||||
dosync = 1;
|
ignore = 1;
|
||||||
break;
|
}
|
||||||
case '\t':
|
inside_esc = 0;
|
||||||
line.pos += (line.pos / 8 + 1) * 8;
|
}
|
||||||
if (line.pos >= (int)sizeof(line.buf))
|
} else if (inside_esc == 2) {
|
||||||
line.pos = sizeof(line.buf) - 1;
|
switch (*ptr) {
|
||||||
break;
|
case '0' ... '9': /* intermediate chars of escape sequence */
|
||||||
case 32 ... 127:
|
case ';':
|
||||||
case 161 ... 255:
|
case 32 ... 47:
|
||||||
tmp[0] = *ptr;
|
if (inside_esc) {
|
||||||
tmp[1] = 0;
|
ignore = 1;
|
||||||
break;
|
}
|
||||||
default:
|
break;
|
||||||
sprintf(tmp, "\\%03o", *ptr);
|
case 64 ... 126: /* final char of escape sequence */
|
||||||
break;
|
if (inside_esc) {
|
||||||
|
ignore = 1;
|
||||||
|
inside_esc = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (*ptr) {
|
||||||
|
case '\r':
|
||||||
|
ignore = 1;
|
||||||
|
break;
|
||||||
|
case 27: /* ESC */
|
||||||
|
ignore = 1;
|
||||||
|
inside_esc = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!ignore) {
|
||||||
|
fwrite(ptr, sizeof(char), 1, fp);
|
||||||
|
}
|
||||||
|
|
||||||
ptr++;
|
ptr++;
|
||||||
len--;
|
|
||||||
|
|
||||||
tlen = strlen(tmp);
|
|
||||||
if (tlen && (line.pos + tlen < (int)sizeof(line.buf))) {
|
|
||||||
memcpy(line.buf + line.pos, tmp, tlen);
|
|
||||||
line.pos += tlen;
|
|
||||||
}
|
|
||||||
if (didnl) {
|
|
||||||
fprintf(fp, "%s\n", line.buf);
|
|
||||||
memset(&line, 0, sizeof(line));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dosync) {
|
if (dosync) {
|
||||||
fflush(fp);
|
fflush(fp);
|
||||||
if (syncalot) {
|
if (syncalot) {
|
||||||
@ -421,7 +421,7 @@ void writelog(FILE *fp, unsigned char *ptr, int len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outptr += olen;
|
outptr += len;
|
||||||
if (outptr >= endptr)
|
if (outptr >= endptr)
|
||||||
outptr = ringbuf;
|
outptr = ringbuf;
|
||||||
|
|
||||||
@ -478,19 +478,21 @@ int main(int argc, char **argv)
|
|||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char realcons[1024];
|
|
||||||
char *p;
|
char *p;
|
||||||
char *logfile;
|
char *logfile;
|
||||||
char *pidfile;
|
char *pidfile;
|
||||||
int rotate;
|
int rotate;
|
||||||
int dontfork;
|
int dontfork;
|
||||||
int ptm, pts;
|
int ptm, pts;
|
||||||
int realfd;
|
/* int realfd; -- this is now unused */
|
||||||
int n, m, i;
|
int n, m, i;
|
||||||
int todo;
|
int todo;
|
||||||
#ifndef __linux__ /* BSD-style ioctl needs an argument. */
|
#ifndef __linux__ /* BSD-style ioctl needs an argument. */
|
||||||
int on = 1;
|
int on = 1;
|
||||||
#endif
|
#endif
|
||||||
|
int considx;
|
||||||
|
struct real_cons cons[MAX_CONSOLES];
|
||||||
|
int num_consoles, consoles_left;
|
||||||
|
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
logfile = LOGFILE;
|
logfile = LOGFILE;
|
||||||
@ -537,6 +539,7 @@ int main(int argc, char **argv)
|
|||||||
/*
|
/*
|
||||||
* Open console device directly.
|
* Open console device directly.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
if (consolename(realcons, sizeof(realcons)) < 0)
|
if (consolename(realcons, sizeof(realcons)) < 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -546,9 +549,28 @@ int main(int argc, char **argv)
|
|||||||
strcpy(realcons, "/dev/vc/1");
|
strcpy(realcons, "/dev/vc/1");
|
||||||
|
|
||||||
if ((realfd = open_nb(realcons)) < 0) {
|
if ((realfd = open_nb(realcons)) < 0) {
|
||||||
fprintf(stderr, "bootlogd: %s: %s\n", buf, strerror(errno));
|
fprintf(stderr, "bootlogd: %s: %s\n", realcons, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
if ((num_consoles = consolenames(cons, MAX_CONSOLES)) <= 0)
|
||||||
|
return 1;
|
||||||
|
consoles_left = num_consoles;
|
||||||
|
for (considx = 0; considx < num_consoles; considx++) {
|
||||||
|
if (strcmp(cons[considx].name, "/dev/tty0") == 0)
|
||||||
|
strcpy(cons[considx].name, "/dev/tty1");
|
||||||
|
if (strcmp(cons[considx].name, "/dev/vc/0") == 0)
|
||||||
|
strcpy(cons[considx].name, "/dev/vc/1");
|
||||||
|
|
||||||
|
if ((cons[considx].fd = open_nb(cons[considx].name)) < 0) {
|
||||||
|
fprintf(stderr, "bootlogd: %s: %s\n",
|
||||||
|
cons[considx].name, strerror(errno));
|
||||||
|
consoles_left--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!consoles_left)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Grab a pty, and redirect console messages to it.
|
* Grab a pty, and redirect console messages to it.
|
||||||
@ -632,26 +654,34 @@ int main(int argc, char **argv)
|
|||||||
if ((n = read(ptm, inptr, endptr - inptr)) >= 0) {
|
if ((n = read(ptm, inptr, endptr - inptr)) >= 0) {
|
||||||
/*
|
/*
|
||||||
* Write data (in chunks if needed)
|
* Write data (in chunks if needed)
|
||||||
* to the real output device.
|
* to the real output devices.
|
||||||
*/
|
*/
|
||||||
m = n;
|
for (considx = 0; considx < num_consoles; considx++) {
|
||||||
p = inptr;
|
if (cons[considx].fd < 0) continue;
|
||||||
while (m > 0) {
|
m = n;
|
||||||
i = write(realfd, p, m);
|
p = inptr;
|
||||||
if (i >= 0) {
|
while (m > 0) {
|
||||||
m -= i;
|
i = write(cons[considx].fd, p, m);
|
||||||
p += i;
|
if (i >= 0) {
|
||||||
continue;
|
m -= i;
|
||||||
}
|
p += i;
|
||||||
/*
|
continue;
|
||||||
* Handle EIO (somebody hung
|
}
|
||||||
* up our filedescriptor)
|
/*
|
||||||
*/
|
* Handle EIO (somebody hung
|
||||||
realfd = write_err(pts, realfd,
|
* up our filedescriptor)
|
||||||
realcons, errno);
|
*/
|
||||||
if (realfd >= 0) continue;
|
cons[considx].fd = write_err(pts,
|
||||||
got_signal = 1; /* Not really */
|
cons[considx].fd,
|
||||||
break;
|
cons[considx].name, errno);
|
||||||
|
if (cons[considx].fd >= 0) continue;
|
||||||
|
/*
|
||||||
|
* If this was the last console,
|
||||||
|
* generate a fake signal
|
||||||
|
*/
|
||||||
|
if (--consoles_left <= 0) got_signal = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -697,7 +727,9 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
close(pts);
|
close(pts);
|
||||||
close(ptm);
|
close(ptm);
|
||||||
close(realfd);
|
for (considx = 0; considx < num_consoles; considx++) {
|
||||||
|
close(cons[considx].fd);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,14 @@ static void getuidtty(char **userp, char **ttyp)
|
|||||||
uidbuf[0] = 0;
|
uidbuf[0] = 0;
|
||||||
strncat(uidbuf, pwd->pw_name, sizeof(uidbuf) - 1);
|
strncat(uidbuf, pwd->pw_name, sizeof(uidbuf) - 1);
|
||||||
} else {
|
} else {
|
||||||
|
/* Using variable number of data parameters in one
|
||||||
|
function makes the Clang compiler cry. -- Jesse
|
||||||
sprintf(uidbuf, uid ? "uid %d" : "root", (int)uid);
|
sprintf(uidbuf, uid ? "uid %d" : "root", (int)uid);
|
||||||
|
*/
|
||||||
|
if (uid)
|
||||||
|
sprintf(uidbuf, "uid %d", (int) uid);
|
||||||
|
else
|
||||||
|
sprintf(uidbuf, "root");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tty = ttyname(0)) != NULL) {
|
if ((tty = ttyname(0)) != NULL) {
|
||||||
|
139
src/init.c
139
src/init.c
@ -131,7 +131,7 @@ char *argv0; /* First arguments; show up in ps listing */
|
|||||||
int maxproclen; /* Maximal length of argv[0] with \0 */
|
int maxproclen; /* Maximal length of argv[0] with \0 */
|
||||||
struct utmp utproto; /* Only used for sizeof(utproto.ut_id) */
|
struct utmp utproto; /* Only used for sizeof(utproto.ut_id) */
|
||||||
char *console_dev; /* Console device. */
|
char *console_dev; /* Console device. */
|
||||||
int pipe_fd = -1; /* /dev/initctl */
|
int pipe_fd = -1; /* /run/initctl */
|
||||||
int did_boot = 0; /* Did we already do BOOT* stuff? */
|
int did_boot = 0; /* Did we already do BOOT* stuff? */
|
||||||
int main(int, char **);
|
int main(int, char **);
|
||||||
|
|
||||||
@ -362,6 +362,7 @@ static CHILD *get_record(FILE *f)
|
|||||||
CHILD *p;
|
CHILD *p;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
errno = 0;
|
||||||
switch (cmd = get_cmd(f)) {
|
switch (cmd = get_cmd(f)) {
|
||||||
case C_END:
|
case C_END:
|
||||||
get_void(f);
|
get_void(f);
|
||||||
@ -372,34 +373,54 @@ static CHILD *get_record(FILE *f)
|
|||||||
case C_REC:
|
case C_REC:
|
||||||
break;
|
break;
|
||||||
case D_RUNLEVEL:
|
case D_RUNLEVEL:
|
||||||
fscanf(f, "%c\n", &runlevel);
|
if (fscanf(f, "%c\n", &runlevel) == EOF && errno != 0) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case D_THISLEVEL:
|
case D_THISLEVEL:
|
||||||
fscanf(f, "%c\n", &thislevel);
|
if (fscanf(f, "%c\n", &thislevel) == EOF && errno != 0) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case D_PREVLEVEL:
|
case D_PREVLEVEL:
|
||||||
fscanf(f, "%c\n", &prevlevel);
|
if (fscanf(f, "%c\n", &prevlevel) == EOF && errno != 0) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case D_GOTSIGN:
|
case D_GOTSIGN:
|
||||||
fscanf(f, "%u\n", &got_signals);
|
if (fscanf(f, "%u\n", &got_signals) == EOF && errno != 0) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case D_WROTE_WTMP_REBOOT:
|
case D_WROTE_WTMP_REBOOT:
|
||||||
fscanf(f, "%d\n", &wrote_wtmp_reboot);
|
if (fscanf(f, "%d\n", &wrote_wtmp_reboot) == EOF && errno != 0) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case D_WROTE_UTMP_REBOOT:
|
case D_WROTE_UTMP_REBOOT:
|
||||||
fscanf(f, "%d\n", &wrote_utmp_reboot);
|
if (fscanf(f, "%d\n", &wrote_utmp_reboot) == EOF && errno != 0) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case D_SLTIME:
|
case D_SLTIME:
|
||||||
fscanf(f, "%d\n", &sltime);
|
if (fscanf(f, "%d\n", &sltime) == EOF && errno != 0) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case D_DIDBOOT:
|
case D_DIDBOOT:
|
||||||
fscanf(f, "%d\n", &did_boot);
|
if (fscanf(f, "%d\n", &did_boot) == EOF && errno != 0) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case D_WROTE_WTMP_RLEVEL:
|
case D_WROTE_WTMP_RLEVEL:
|
||||||
fscanf(f, "%d\n", &wrote_wtmp_rlevel);
|
if (fscanf(f, "%d\n", &wrote_wtmp_rlevel) == EOF && errno != 0) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case D_WROTE_UTMP_RLEVEL:
|
case D_WROTE_UTMP_RLEVEL:
|
||||||
fscanf(f, "%d\n", &wrote_utmp_rlevel);
|
if (fscanf(f, "%d\n", &wrote_utmp_rlevel) == EOF && errno != 0) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (cmd > 0 || cmd == C_EOF) {
|
if (cmd > 0 || cmd == C_EOF) {
|
||||||
@ -418,10 +439,14 @@ static CHILD *get_record(FILE *f)
|
|||||||
get_void(f);
|
get_void(f);
|
||||||
break;
|
break;
|
||||||
case C_PID:
|
case C_PID:
|
||||||
fscanf(f, "%d\n", &(p->pid));
|
if (fscanf(f, "%d\n", &(p->pid)) == EOF && errno != 0) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case C_EXS:
|
case C_EXS:
|
||||||
fscanf(f, "%u\n", &(p->exstat));
|
if (fscanf(f, "%u\n", &(p->exstat)) == EOF && errno != 0) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case C_LEV:
|
case C_LEV:
|
||||||
get_string(p->rlevel, sizeof(p->rlevel), f);
|
get_string(p->rlevel, sizeof(p->rlevel), f);
|
||||||
@ -753,11 +778,11 @@ void console_stty(void)
|
|||||||
#ifdef __FreeBSD_kernel__
|
#ifdef __FreeBSD_kernel__
|
||||||
/*
|
/*
|
||||||
* The kernel of FreeBSD expects userland to set TERM. Usually, we want
|
* The kernel of FreeBSD expects userland to set TERM. Usually, we want
|
||||||
* "cons25". Later, gettys might disagree on this (i.e. we're not using
|
* "xterm". Later, gettys might disagree on this (i.e. we're not using
|
||||||
* syscons) but some boot scripts, like /etc/init.d/xserver-xorg, still
|
* syscons) but some boot scripts, like /etc/init.d/xserver-xorg, still
|
||||||
* need a non-dumb terminal.
|
* need a non-dumb terminal.
|
||||||
*/
|
*/
|
||||||
putenv ("TERM=cons25");
|
putenv ("TERM=xterm");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
(void) tcgetattr(fd, &tty);
|
(void) tcgetattr(fd, &tty);
|
||||||
@ -1291,6 +1316,76 @@ void startup(CHILD *ch)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
static
|
||||||
|
void check_kernel_console()
|
||||||
|
{
|
||||||
|
FILE* fp;
|
||||||
|
char buf[4096];
|
||||||
|
if ((fp = fopen("/proc/cmdline", "r")) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fgets(buf, sizeof(buf), fp)) {
|
||||||
|
char* p = buf;
|
||||||
|
while ((p = strstr(p, "console="))) {
|
||||||
|
char* e;
|
||||||
|
p += strlen("console=");
|
||||||
|
for (e = p; *e; ++e) {
|
||||||
|
switch (*e) {
|
||||||
|
case '-' ... '9':
|
||||||
|
case 'A' ... 'Z':
|
||||||
|
case '_':
|
||||||
|
case 'a' ... 'z':
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (p != e) {
|
||||||
|
CHILD* old;
|
||||||
|
int dup = 0;
|
||||||
|
char id[8] = {0};
|
||||||
|
char dev[32] = {0};
|
||||||
|
strncpy(dev, p, MIN(sizeof(dev), (unsigned)(e-p)));
|
||||||
|
if (!strncmp(dev, "tty", 3))
|
||||||
|
strncpy(id, dev+3, sizeof(id));
|
||||||
|
else
|
||||||
|
strncpy(id, dev, sizeof(id));
|
||||||
|
|
||||||
|
for(old = newFamily; old; old = old->next) {
|
||||||
|
if (!strcmp(old->id, id)) {
|
||||||
|
dup = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!dup) {
|
||||||
|
CHILD* ch = imalloc(sizeof(CHILD));
|
||||||
|
ch->action = RESPAWN;
|
||||||
|
strcpy(ch->id, id);
|
||||||
|
strcpy(ch->rlevel, "2345");
|
||||||
|
sprintf(ch->process, "/sbin/agetty -L -s 115200,38400,9600 %s vt102", dev);
|
||||||
|
ch->next = NULL;
|
||||||
|
for(old = family; old; old = old->next) {
|
||||||
|
if (strcmp(old->id, ch->id) == 0) {
|
||||||
|
old->new = ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* add to end */
|
||||||
|
for(old = newFamily; old; old = old->next) {
|
||||||
|
if (!old->next) {
|
||||||
|
old->next = ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initlog(L_VB, "added agetty on %s with id %s", dev, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read the inittab file.
|
* Read the inittab file.
|
||||||
@ -1503,6 +1598,10 @@ void read_inittab(void)
|
|||||||
*/
|
*/
|
||||||
if (fp) fclose(fp);
|
if (fp) fclose(fp);
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
check_kernel_console();
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loop through the list of children, and see if they need to
|
* Loop through the list of children, and see if they need to
|
||||||
* be killed.
|
* be killed.
|
||||||
@ -2252,13 +2351,13 @@ void check_init_fifo(void)
|
|||||||
int quit = 0;
|
int quit = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First, try to create /dev/initctl if not present.
|
* First, try to create /run/initctl if not present.
|
||||||
*/
|
*/
|
||||||
if (stat(INIT_FIFO, &st2) < 0 && errno == ENOENT)
|
if (stat(INIT_FIFO, &st2) < 0 && errno == ENOENT)
|
||||||
(void)mkfifo(INIT_FIFO, 0600);
|
(void)mkfifo(INIT_FIFO, 0600);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If /dev/initctl is open, stat the file to see if it
|
* If /run/initctl is open, stat the file to see if it
|
||||||
* is still the _same_ inode.
|
* is still the _same_ inode.
|
||||||
*/
|
*/
|
||||||
if (pipe_fd >= 0) {
|
if (pipe_fd >= 0) {
|
||||||
@ -2272,7 +2371,7 @@ void check_init_fifo(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now finally try to open /dev/initctl
|
* Now finally try to open /run/initctl
|
||||||
*/
|
*/
|
||||||
if (pipe_fd < 0) {
|
if (pipe_fd < 0) {
|
||||||
if ((pipe_fd = open(INIT_FIFO, O_RDWR|O_NONBLOCK)) >= 0) {
|
if ((pipe_fd = open(INIT_FIFO, O_RDWR|O_NONBLOCK)) >= 0) {
|
||||||
@ -2578,7 +2677,7 @@ void process_signals()
|
|||||||
}
|
}
|
||||||
if (ISMEMBER(got_signals, SIGUSR1)) {
|
if (ISMEMBER(got_signals, SIGUSR1)) {
|
||||||
/*
|
/*
|
||||||
* SIGUSR1 means close and reopen /dev/initctl
|
* SIGUSR1 means close and reopen /run/initctl
|
||||||
*/
|
*/
|
||||||
INITDBG(L_VB, "got SIGUSR1");
|
INITDBG(L_VB, "got SIGUSR1");
|
||||||
close(pipe_fd);
|
close(pipe_fd);
|
||||||
@ -2816,7 +2915,7 @@ int telinit(char *progname, int argc, char **argv)
|
|||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
|
||||||
/* Open the fifo and write a command. */
|
/* Open the fifo and write a command. */
|
||||||
/* Make sure we don't hang on opening /dev/initctl */
|
/* Make sure we don't hang on opening /run/initctl */
|
||||||
SETSIG(sa, SIGALRM, signal_handler, 0);
|
SETSIG(sa, SIGALRM, signal_handler, 0);
|
||||||
alarm(3);
|
alarm(3);
|
||||||
if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) {
|
if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* initreq.h Interface to talk to init through /dev/initctl.
|
* initreq.h Interface to talk to init through /run/initctl.
|
||||||
*
|
*
|
||||||
* Copyright (C) 1995-2004 Miquel van Smoorenburg
|
* Copyright (C) 1995-2004 Miquel van Smoorenburg
|
||||||
*
|
*
|
||||||
@ -26,11 +26,7 @@
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
#ifndef INIT_FIFO
|
#ifndef INIT_FIFO
|
||||||
# if defined(__FreeBSD_kernel__)
|
#define INIT_FIFO "/run/initctl"
|
||||||
# define INIT_FIFO "/etc/.initctl"
|
|
||||||
# else
|
|
||||||
# define INIT_FIFO "/dev/initctl"
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define INIT_MAGIC 0x03091969
|
#define INIT_MAGIC 0x03091969
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* kilall5.c Kill all processes except processes that have the
|
* killall5.c Kill all processes except processes that have the
|
||||||
* same session id, so that the shell that called us
|
* same session id, so that the shell that called us
|
||||||
* won't be killed. Typically used in shutdown scripts.
|
* won't be killed. Typically used in shutdown scripts.
|
||||||
*
|
*
|
||||||
|
@ -173,7 +173,7 @@ int init_setenv(char *name, char *value)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Open the fifo and write the command.
|
* Open the fifo and write the command.
|
||||||
* Make sure we don't hang on opening /dev/initctl
|
* Make sure we don't hang on opening /run/initctl
|
||||||
*/
|
*/
|
||||||
memset(&sa, 0, sizeof(sa));
|
memset(&sa, 0, sizeof(sa));
|
||||||
sa.sa_handler = alrm_handler;
|
sa.sa_handler = alrm_handler;
|
||||||
@ -498,7 +498,15 @@ int main(int argc, char **argv)
|
|||||||
int user_ok = 0;
|
int user_ok = 0;
|
||||||
|
|
||||||
/* We can be installed setuid root (executable for a special group) */
|
/* We can be installed setuid root (executable for a special group) */
|
||||||
setuid(geteuid());
|
/*
|
||||||
|
This way is risky, do error check on setuid call.
|
||||||
|
setuid(geteuid());
|
||||||
|
*/
|
||||||
|
errno = 0;
|
||||||
|
if (setuid(geteuid()) == -1) {
|
||||||
|
fprintf(stderr, "%s (%d): %s\n", __FILE__, __LINE__, strerror(errno));
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
if (getuid() != 0) {
|
if (getuid() != 0) {
|
||||||
fprintf(stderr, "shutdown: you must be root to do that!\n");
|
fprintf(stderr, "shutdown: you must be root to do that!\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user