diff options
author | Richard Purdie <richard@openedhand.com> | 2006-07-21 10:10:31 +0000 |
---|---|---|
committer | Richard Purdie <richard@openedhand.com> | 2006-07-21 10:10:31 +0000 |
commit | b2f192faabe412adce79534e22efe9fb69ee40e2 (patch) | |
tree | 7076c49d4286f8a1733650bd8fbc7161af200d57 /meta/packages/sysvinit/sysvinit-2.86 | |
parent | 2cf0eadf9f730027833af802d7e6c90b44248f80 (diff) | |
download | poky-b2f192faabe412adce79534e22efe9fb69ee40e2.tar.gz |
Rename /openembedded/ -> /meta/
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@530 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'meta/packages/sysvinit/sysvinit-2.86')
-rw-r--r-- | meta/packages/sysvinit/sysvinit-2.86/install.patch | 77 | ||||
-rw-r--r-- | meta/packages/sysvinit/sysvinit-2.86/sysvinit-2.86.patch | 4880 |
2 files changed, 4957 insertions, 0 deletions
diff --git a/meta/packages/sysvinit/sysvinit-2.86/install.patch b/meta/packages/sysvinit/sysvinit-2.86/install.patch new file mode 100644 index 0000000000..01c1367c03 --- /dev/null +++ b/meta/packages/sysvinit/sysvinit-2.86/install.patch | |||
@@ -0,0 +1,77 @@ | |||
1 | |||
2 | # | ||
3 | # Patch managed by http://www.holgerschurig.de/patcher.html | ||
4 | # | ||
5 | |||
6 | --- sysvinit-2.85/src/Makefile~install | ||
7 | +++ sysvinit-2.85/src/Makefile | ||
8 | @@ -47,7 +47,15 @@ | ||
9 | BIN_GROUP = root | ||
10 | BIN_COMBO = $(BIN_OWNER):$(BIN_GROUP) | ||
11 | INSTALL = install -o $(BIN_OWNER) -g $(BIN_GROUP) | ||
12 | -MANDIR = /usr/share/man | ||
13 | + | ||
14 | +ROOT = | ||
15 | +bindir = /bin | ||
16 | +sbindir = /sbin | ||
17 | +usrbindir = /usr/bin | ||
18 | +usrbindir = /usr/bin | ||
19 | +includedir = /usr/include | ||
20 | +mandir = /usr/share/man | ||
21 | + | ||
22 | |||
23 | # Additional libs for GNU libc. | ||
24 | ifneq ($(wildcard /usr/lib/libcrypt.a),) | ||
25 | @@ -110,32 +118,39 @@ | ||
26 | distclean: clobber | ||
27 | |||
28 | install: | ||
29 | + install -d $(ROOT)$(bindir) | ||
30 | for i in $(BIN); do \ | ||
31 | - $(INSTALL) -m 755 $$i $(ROOT)/bin/; \ | ||
32 | + $(INSTALL) -m 755 $$i $(ROOT)$(bindir)/; \ | ||
33 | done | ||
34 | + install -d $(ROOT)$(sbindir) | ||
35 | for i in $(SBIN); do \ | ||
36 | - $(INSTALL) -m 755 $$i $(ROOT)/sbin/; \ | ||
37 | + $(INSTALL) -m 755 $$i $(ROOT)$(sbindir)/; \ | ||
38 | done | ||
39 | + install -d $(ROOT)$(usrbindir) | ||
40 | for i in $(USRBIN); do \ | ||
41 | - $(INSTALL) -m 755 $$i $(ROOT)/usr/bin/; \ | ||
42 | + $(INSTALL) -m 755 $$i $(ROOT)$(usrbindir)/; \ | ||
43 | done | ||
44 | # $(INSTALL) -m 755 etc/initscript.sample $(ROOT)/etc/ | ||
45 | - ln -sf halt $(ROOT)/sbin/reboot | ||
46 | - ln -sf halt $(ROOT)/sbin/poweroff | ||
47 | - ln -sf init $(ROOT)/sbin/telinit | ||
48 | - ln -sf ../sbin/killall5 $(ROOT)/bin/pidof | ||
49 | - if [ ! -f $(ROOT)/usr/bin/lastb ]; then \ | ||
50 | - ln -sf last $(ROOT)/usr/bin/lastb; \ | ||
51 | + ln -sf halt $(ROOT)$(sbindir)/reboot | ||
52 | + ln -sf halt $(ROOT)$(sbindir)/poweroff | ||
53 | + ln -sf init $(ROOT)$(sbindir)/telinit | ||
54 | + ln -sf ../sbin/killall5 $(ROOT)$(bindir)/pidof | ||
55 | + if [ ! -f $(ROOT)$(usrbindir)/lastb ]; then \ | ||
56 | + ln -sf last $(ROOT)$(usrbindir)/lastb; \ | ||
57 | fi | ||
58 | - $(INSTALL) -m 644 initreq.h $(ROOT)/usr/include/ | ||
59 | + install -d $(ROOT)$(includedir) | ||
60 | + $(INSTALL) -m 644 initreq.h $(ROOT)$(includedir)/ | ||
61 | + install -d $(ROOT)$(mandir)/man1 \ | ||
62 | + $(ROOT)$(mandir)/man5 \ | ||
63 | + $(ROOT)$(mandir)/man8 | ||
64 | for i in $(MAN1); do \ | ||
65 | - $(INSTALL) -m 644 ../man/$$i $(ROOT)$(MANDIR)/man1/; \ | ||
66 | + $(INSTALL) -m 644 ../man/$$i $(ROOT)$(mandir)/man1/; \ | ||
67 | done | ||
68 | for i in $(MAN5); do \ | ||
69 | - $(INSTALL) -m 644 ../man/$$i $(ROOT)$(MANDIR)/man5/; \ | ||
70 | + $(INSTALL) -m 644 ../man/$$i $(ROOT)$(mandir)/man5/; \ | ||
71 | done | ||
72 | for i in $(MAN8); do \ | ||
73 | - $(INSTALL) -m 644 ../man/$$i $(ROOT)$(MANDIR)/man8/; \ | ||
74 | + $(INSTALL) -m 644 ../man/$$i $(ROOT)$(mandir)/man8/; \ | ||
75 | done | ||
76 | ifeq ($(ROOT),) | ||
77 | # | ||
diff --git a/meta/packages/sysvinit/sysvinit-2.86/sysvinit-2.86.patch b/meta/packages/sysvinit/sysvinit-2.86/sysvinit-2.86.patch new file mode 100644 index 0000000000..b83f525c3e --- /dev/null +++ b/meta/packages/sysvinit/sysvinit-2.86/sysvinit-2.86.patch | |||
@@ -0,0 +1,4880 @@ | |||
1 | diff -urNd -urNd sysvinit-2.85/COPYRIGHT sysvinit-2.86/COPYRIGHT | ||
2 | --- sysvinit-2.85/COPYRIGHT 2003-04-15 03:45:44.000000000 -0500 | ||
3 | +++ sysvinit-2.86/COPYRIGHT 2004-07-30 07:12:12.000000000 -0500 | ||
4 | @@ -1,4 +1,4 @@ | ||
5 | -Sysvinit is Copyright (C) 1991-2003 Miquel van Smoorenburg | ||
6 | +Sysvinit is Copyright (C) 1991-2004 Miquel van Smoorenburg | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | diff -urNd -urNd sysvinit-2.85/doc/Changelog sysvinit-2.86/doc/Changelog | ||
11 | --- sysvinit-2.85/doc/Changelog 2003-04-15 09:37:58.000000000 -0500 | ||
12 | +++ sysvinit-2.86/doc/Changelog 2004-07-30 07:15:06.000000000 -0500 | ||
13 | @@ -1,3 +1,29 @@ | ||
14 | +sysvinit (2.86) cistron; urgency=low | ||
15 | + | ||
16 | + * Fixed up bootlogd to read /proc/cmdline. Also keep an internal | ||
17 | + linebuffer to process \r, \t and ^H. It is becoming useable. | ||
18 | + * Applied trivial OWL patches | ||
19 | + * Block signals in syslog(), since syslog() is not re-entrant | ||
20 | + (James Olin Oden <joden@malachi.lee.k12.nc.us>, redhat bug #97534) | ||
21 | + * Minor adjustements so that sysvinit compiles on the Hurd | ||
22 | + * killall5 now skips kernel threads | ||
23 | + * Inittab entries with both 'S' and other runlevels were broken. | ||
24 | + Fix by Bryan Kadzban <bryan@kadzban.is-a-geek.net> | ||
25 | + * Changed initreq.h to be more flexible and forwards-compatible. | ||
26 | + * You can now through /dev/initctl set environment variables in | ||
27 | + init that will be inherited by its children. For now, only | ||
28 | + variables prefixed with INIT_ can be set and the maximum is | ||
29 | + 16 variables. There's also a length limit due to the size | ||
30 | + of struct init_request, so it should be safe from abuse. | ||
31 | + * Option -P and -H to shutdown set INIT_HALT=POWERDOWN and | ||
32 | + INIT_HALT=HALT as environment variables as described above | ||
33 | + * Add "mountpoint" utility. | ||
34 | + * Slightly better algorithm in killall5.c:pidof() | ||
35 | + * Added some patches from fedora-core (halt-usage, last -t, | ||
36 | + sulogin-message, user-console) | ||
37 | + | ||
38 | + -- Miquel van Smoorenburg <miquels@cistron.nl> Fri, 30 Jul 2004 14:14:58 +0200 | ||
39 | + | ||
40 | sysvinit (2.85) cistron; urgency=low | ||
41 | |||
42 | * Add IPv6 support in last(1) | ||
43 | diff -urNd -urNd sysvinit-2.85/doc/Install sysvinit-2.86/doc/Install | ||
44 | --- sysvinit-2.85/doc/Install 2003-04-15 03:46:49.000000000 -0500 | ||
45 | +++ sysvinit-2.86/doc/Install 2004-07-30 07:15:40.000000000 -0500 | ||
46 | @@ -1,5 +1,5 @@ | ||
47 | |||
48 | - README for the System V style init, version 2.85 | ||
49 | + README for the System V style init, version 2.86 | ||
50 | |||
51 | init, shutdown, halt, reboot, wall, last, mesg, runlevel, | ||
52 | killall5, pidof, sulogin. | ||
53 | diff -urNd -urNd sysvinit-2.85/doc/bootlogd.README sysvinit-2.86/doc/bootlogd.README | ||
54 | --- sysvinit-2.85/doc/bootlogd.README 2000-09-12 16:54:31.000000000 -0500 | ||
55 | +++ sysvinit-2.86/doc/bootlogd.README 2004-06-09 07:47:45.000000000 -0500 | ||
56 | @@ -1,10 +1,12 @@ | ||
57 | |||
58 | bootlogd: a way to capture all console output during bootup | ||
59 | - in a logfile. ** PROOF OF CONCEPT IMPLEMENTATION ** | ||
60 | + in a logfile. | ||
61 | |||
62 | -- bootlogd opens /dev/console | ||
63 | -- finds out what the real console is with an ioctl() | ||
64 | -- then opens the real console | ||
65 | +- bootlogd opens /dev/console and finds out what the real console is | ||
66 | + with an ioctl() if TIOCCONS is available | ||
67 | +- otherwise bootlogd tries to parse /proc/cmdline for console= | ||
68 | + kernel command line arguments | ||
69 | +- then opens the (most probable) real console | ||
70 | - allocates a pty pair | ||
71 | - redirects console I/O to the pty pair | ||
72 | - then goes in a loop reading from the pty, writing to the real | ||
73 | diff -urNd -urNd sysvinit-2.85/doc/sysvinit-2.85.lsm sysvinit-2.86/doc/sysvinit-2.85.lsm | ||
74 | --- sysvinit-2.85/doc/sysvinit-2.85.lsm 2003-04-18 16:04:12.000000000 -0500 | ||
75 | +++ sysvinit-2.86/doc/sysvinit-2.85.lsm 2004-06-09 07:47:45.000000000 -0500 | ||
76 | @@ -1,7 +1,7 @@ | ||
77 | Begin3 | ||
78 | Title: sysvinit and utilities | ||
79 | Version: 2.85 | ||
80 | -Entered-Date: 18APR2003 | ||
81 | +Entered-Date: 15APR2003 | ||
82 | Description: This is the Linux System V init. | ||
83 | This version can be compiled with glibc 2.0.6 and up. | ||
84 | Author: miquels@cistron.nl (Miquel van Smoorenburg) | ||
85 | diff -urNd -urNd sysvinit-2.85/doc/sysvinit-2.86.lsm sysvinit-2.86/doc/sysvinit-2.86.lsm | ||
86 | --- sysvinit-2.85/doc/sysvinit-2.86.lsm 1969-12-31 18:00:00.000000000 -0600 | ||
87 | +++ sysvinit-2.86/doc/sysvinit-2.86.lsm 2004-07-31 08:35:28.000000000 -0500 | ||
88 | @@ -0,0 +1,14 @@ | ||
89 | +Begin3 | ||
90 | +Title: sysvinit and utilities | ||
91 | +Version: 2.86 | ||
92 | +Entered-Date: 30JUL2004 | ||
93 | +Description: This is the Linux System V init. | ||
94 | + This version can be compiled with glibc 2.0.6 and up. | ||
95 | +Author: miquels@cistron.nl (Miquel van Smoorenburg) | ||
96 | +Primary-Site: ftp.cistron.nl /pub/people/miquels/software | ||
97 | + 92K sysvinit-2.86.tar.gz | ||
98 | +Alternate-Site: sunsite.unc.edu /pub/Linux/system/daemons/init | ||
99 | + 92K sysvinit-2.86.tar.gz | ||
100 | +Copying-Policy: GPL | ||
101 | +Keywords: init shutdown halt reboot | ||
102 | +End | ||
103 | diff -urNd -urNd sysvinit-2.85/man/bootlogd.8 sysvinit-2.86/man/bootlogd.8 | ||
104 | --- sysvinit-2.85/man/bootlogd.8 1969-12-31 18:00:00.000000000 -0600 | ||
105 | +++ sysvinit-2.86/man/bootlogd.8 2004-06-09 07:47:45.000000000 -0500 | ||
106 | @@ -0,0 +1,39 @@ | ||
107 | +.TH BOOTLOGD 8 "Jul 21, 2003" "" "Linux System Administrator's Manual" | ||
108 | +.SH NAME | ||
109 | +bootlogd \- record boot messages | ||
110 | +.SH SYNOPSIS | ||
111 | +.B /sbin/bootlogd | ||
112 | +.RB [ \-d ] | ||
113 | +.RB [ \-r ] | ||
114 | +.RB [ \-v ] | ||
115 | +.RB [ " -l logfile " ] | ||
116 | +.RB [ " -p pidfile " ] | ||
117 | +.SH DESCRIPTION | ||
118 | +\fBBootlogd\fP runs in the background and copies all strings sent to the | ||
119 | +\fI/dev/console\fP device to a logfile. If the logfile is not accessible, | ||
120 | +the messages will be buffered in-memory until it is. | ||
121 | +.SH OPTIONS | ||
122 | +.IP \fB\-d\fP | ||
123 | +Do not fork and run in the background. | ||
124 | +.IP \fB\-r\fP | ||
125 | +If there is an existing logfile called \fIlogfile\fP rename it to | ||
126 | +\fIlogfile~\fP unless \fIlogfile~\fP already exists. | ||
127 | +.IP \fB\-v\fP | ||
128 | +Show version. | ||
129 | +.IP \fB\-l logfile\fP | ||
130 | +Log to this logfile. The default is \fI/var/log/boot\fP. | ||
131 | +.IP \fB\-p pidfile\fP | ||
132 | +Put process-id in this file. The default is no pidfile. | ||
133 | +.SH BUGS | ||
134 | +Bootlogd works by redirecting the console output from the console | ||
135 | +device. It copies that output to the real console device and a | ||
136 | +logfile. There is no standard way to find out the real console device | ||
137 | +if you have a new-style \fI/dev/console\fP device (major 5, minor 1). | ||
138 | +\fBBootlogd\fP tries to parse the kernel command line, looking for | ||
139 | +console= lines and deducts the real console device from that. If that | ||
140 | +syntax is ever changed by the kernel, or a console-type is used | ||
141 | +bootlogd does not know about, bootlogd will not work. | ||
142 | +.SH AUTHOR | ||
143 | +Miquel van Smoorenburg, miquels@cistron.nl | ||
144 | +.SH "SEE ALSO" | ||
145 | +.BR dmesg (8) | ||
146 | diff -urNd -urNd sysvinit-2.85/man/init.8 sysvinit-2.86/man/init.8 | ||
147 | --- sysvinit-2.85/man/init.8 2003-04-18 16:05:03.000000000 -0500 | ||
148 | +++ sysvinit-2.86/man/init.8 2004-07-29 06:21:31.000000000 -0500 | ||
149 | @@ -1,6 +1,6 @@ | ||
150 | .\"{{{}}} | ||
151 | .\"{{{ Title | ||
152 | -.TH INIT 8 "18 April 2003" "" "Linux System Administrator's Manual" | ||
153 | +.TH INIT 8 "29 Jul 2004" "" "Linux System Administrator's Manual" | ||
154 | .\"}}} | ||
155 | .\"{{{ Name | ||
156 | .SH NAME | ||
157 | @@ -160,7 +160,7 @@ | ||
158 | .SH ENVIRONMENT | ||
159 | \fBInit\fP sets the following environment variables for all its children: | ||
160 | .IP \fBPATH\fP | ||
161 | -\fI/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin\fP | ||
162 | +\fI/bin:/usr/bin:/sbin:/usr/sbin\fP | ||
163 | .IP \fBINIT_VERSION\fP | ||
164 | As the name says. Useful to determine if a script runs directly from \fBinit\fP. | ||
165 | .IP \fBRUNLEVEL\fP | ||
166 | diff -urNd -urNd sysvinit-2.85/man/initscript.5 sysvinit-2.86/man/initscript.5 | ||
167 | --- sysvinit-2.85/man/initscript.5 1999-12-24 16:31:21.000000000 -0600 | ||
168 | +++ sysvinit-2.86/man/initscript.5 2004-06-09 07:47:45.000000000 -0500 | ||
169 | @@ -1,4 +1,4 @@ | ||
170 | -.TH INITSCRIPT 5 "December 24, 1999" "" "Linux System Administrator's Manual" | ||
171 | +.TH INITSCRIPT 5 "July 10, 2003" "" "Linux System Administrator's Manual" | ||
172 | .SH NAME | ||
173 | initscript \- script that executes inittab commands. | ||
174 | .SH SYNOPSIS | ||
175 | @@ -40,6 +40,12 @@ | ||
176 | |||
177 | .sp | ||
178 | .RE | ||
179 | +.SH NOTES | ||
180 | +This script is not meant as startup script for daemons or somesuch. | ||
181 | +It has nothing to do with a \fIrc.local\fP style script. It's just | ||
182 | +a handler for things executed from \fB/etc/inittab\fP. Experimenting | ||
183 | +with this can make your system un(re)bootable. | ||
184 | +.RE | ||
185 | .SH FILES | ||
186 | /etc/inittab, | ||
187 | /etc/initscript. | ||
188 | diff -urNd -urNd sysvinit-2.85/man/killall5.8 sysvinit-2.86/man/killall5.8 | ||
189 | --- sysvinit-2.85/man/killall5.8 1997-05-27 05:34:21.000000000 -0500 | ||
190 | +++ sysvinit-2.86/man/killall5.8 2004-06-09 07:47:45.000000000 -0500 | ||
191 | @@ -1,4 +1,4 @@ | ||
192 | -.TH KILLALL5 8 "27 May 1997" "" "Linux System Administrator's Manual" | ||
193 | +.TH KILLALL5 8 "04 Nov 2003" "" "Linux System Administrator's Manual" | ||
194 | .SH NAME | ||
195 | killall5 -- send a signal to all processes. | ||
196 | .SH SYNOPSIS | ||
197 | @@ -7,9 +7,9 @@ | ||
198 | .SH DESCRIPTION | ||
199 | .B killall5 | ||
200 | is the SystemV killall command. It sends a signal to all processes except | ||
201 | -the processes in its own session, so it won't kill the shell that is | ||
202 | -running the script it was called from. Its primary (only) use is in the | ||
203 | -\fBrc\fP scripts found in the /etc/init.d directory. | ||
204 | +kernel threads and the processes in its own session, so it won't kill | ||
205 | +the shell that is running the script it was called from. Its primary | ||
206 | +(only) use is in the \fBrc\fP scripts found in the /etc/init.d directory. | ||
207 | .SH SEE ALSO | ||
208 | .BR halt (8), | ||
209 | .BR reboot (8) | ||
210 | diff -urNd -urNd sysvinit-2.85/man/last.1 sysvinit-2.86/man/last.1 | ||
211 | --- sysvinit-2.85/man/last.1 1999-07-29 05:50:34.000000000 -0500 | ||
212 | +++ sysvinit-2.86/man/last.1 2004-07-30 06:39:18.000000000 -0500 | ||
213 | @@ -1,6 +1,6 @@ | ||
214 | .\"{{{}}} | ||
215 | .\"{{{ Title | ||
216 | -.TH LAST,LASTB 1 "Jul 29, 1999" "" "Linux System Administrator's Manual" | ||
217 | +.TH LAST,LASTB 1 "Jul 31, 2004" "" "Linux System Administrator's Manual" | ||
218 | .\"}}} | ||
219 | .\"{{{ Name | ||
220 | .SH NAME | ||
221 | @@ -14,6 +14,7 @@ | ||
222 | .RB "[ \-\fBn\fP \fInum\fP ]" | ||
223 | .RB [ \-adiox ] | ||
224 | .RB "[ \-\fBf\fP \fIfile\fP ]" | ||
225 | +.RB "[ \-\fBt\fP \fIYYYYMMDDHHMMSS\fP ]" | ||
226 | .RI [ name... ] | ||
227 | .RI [ tty... ] | ||
228 | .br | ||
229 | @@ -54,6 +55,11 @@ | ||
230 | This is a count telling \fBlast\fP how many lines to show. | ||
231 | .IP "\fB\-n\fP \fInum\fP" | ||
232 | The same. | ||
233 | +.IP "\fB\-t\fP \fIYYYYMMDDHHMMSS\fP" | ||
234 | +Display the state of logins as of the specified time. This is | ||
235 | +useful, e.g., to determine easily who was logged in at a particular | ||
236 | +time -- specify that time with \fB\-t\fP and look for "still logged | ||
237 | +in". | ||
238 | .IP \fB\-R\fP | ||
239 | Suppresses the display of the hostname field. | ||
240 | .IP \fB\-a\fP | ||
241 | diff -urNd -urNd sysvinit-2.85/man/mesg.1 sysvinit-2.86/man/mesg.1 | ||
242 | --- sysvinit-2.85/man/mesg.1 2001-02-26 06:01:10.000000000 -0600 | ||
243 | +++ sysvinit-2.86/man/mesg.1 2004-06-09 07:47:45.000000000 -0500 | ||
244 | @@ -27,7 +27,7 @@ | ||
245 | If no option is given, \fBmesg\fP prints out the current access state of your | ||
246 | terminal. | ||
247 | .PP NOTES | ||
248 | -\fBMesg\fP assumes that it's standard input is connected to your | ||
249 | +\fBMesg\fP assumes that its standard input is connected to your | ||
250 | terminal. That also means that if you are logged in multiple times, | ||
251 | you can get/set the mesg status of other sessions by using redirection. | ||
252 | For example "mesg n < /dev/pts/46". | ||
253 | diff -urNd -urNd sysvinit-2.85/man/mountpoint.1 sysvinit-2.86/man/mountpoint.1 | ||
254 | --- sysvinit-2.85/man/mountpoint.1 1969-12-31 18:00:00.000000000 -0600 | ||
255 | +++ sysvinit-2.86/man/mountpoint.1 2004-06-09 07:47:45.000000000 -0500 | ||
256 | @@ -0,0 +1,37 @@ | ||
257 | +.TH MOUNTPOINT 8 "Mar 15, 2004" "" "Linux System Administrator's Manual" | ||
258 | +.SH NAME | ||
259 | +mountpoint \- see if a directory is a mountpoint | ||
260 | +.SH SYNOPSIS | ||
261 | +.B /bin/mountpoint | ||
262 | +.RB [ \-q ] | ||
263 | +.RB [ \-d ] | ||
264 | +.I /path/to/directory | ||
265 | +.br | ||
266 | +.B /bin/mountpoint | ||
267 | +.RB \-x | ||
268 | +.I /dev/device | ||
269 | +.SH DESCRIPTION | ||
270 | +\fBMountpoint\fP checks if the directory is a mountpoint. | ||
271 | + | ||
272 | +.SH OPTIONS | ||
273 | +.IP \fB\-q\fP | ||
274 | +Be quiet - don't print anything. | ||
275 | +.IP \fB\-d\fP | ||
276 | +Print major/minor device number of the filesystem on stdout. | ||
277 | +.IP \fB\-x\fP | ||
278 | +Print major/minor device number of the blockdevice on stdout. | ||
279 | +.SH EXIT STATUS | ||
280 | +Zero if the directory is a mountpoint, non-zero if not. | ||
281 | +.SH NOTES | ||
282 | +Symbolic links are not followed, except when the \fB-x\fP option is | ||
283 | +used. To force following symlinks, add a trailing slash to the | ||
284 | +path of the directory. | ||
285 | +.PP | ||
286 | +The name of the command is misleading when the -x option is used, | ||
287 | +but the option is useful for comparing if a directory and a device | ||
288 | +match up, and there is no other command that can print the info easily. | ||
289 | +.PP | ||
290 | +.SH AUTHOR | ||
291 | +Miquel van Smoorenburg, miquels@cistron.nl | ||
292 | +.SH "SEE ALSO" | ||
293 | +.BR stat (1) | ||
294 | diff -urNd -urNd sysvinit-2.85/man/shutdown.8 sysvinit-2.86/man/shutdown.8 | ||
295 | --- sysvinit-2.85/man/shutdown.8 2001-10-02 16:27:50.000000000 -0500 | ||
296 | +++ sysvinit-2.86/man/shutdown.8 2004-06-09 07:47:45.000000000 -0500 | ||
297 | @@ -1,6 +1,6 @@ | ||
298 | .\"{{{}}} | ||
299 | .\"{{{ Title | ||
300 | -.TH SHUTDOWN 8 "Juli 31, 2001" "" "Linux System Administrator's Manual" | ||
301 | +.TH SHUTDOWN 8 "November 12, 2003" "" "Linux System Administrator's Manual" | ||
302 | .\"}}} | ||
303 | .\"{{{ Name | ||
304 | .SH NAME | ||
305 | @@ -11,7 +11,7 @@ | ||
306 | .B /sbin/shutdown | ||
307 | .RB [ \-t | ||
308 | .IR sec ] | ||
309 | -.RB [ \-arkhncfF ] | ||
310 | +.RB [ \-arkhncfFHP ] | ||
311 | .I time | ||
312 | .RI [ warning-message ] | ||
313 | .\"}}} | ||
314 | @@ -54,7 +54,16 @@ | ||
315 | .\"}}} | ||
316 | .\"{{{ -h | ||
317 | .IP \fB\-h\fP | ||
318 | -Halt after shutdown. | ||
319 | +Halt or poweroff after shutdown. | ||
320 | +.\"}}} | ||
321 | +.\"{{{ -H | ||
322 | +.IP \fB\-H\fP | ||
323 | +Halt action is to halt or drop into boot monitor on systems that | ||
324 | +support it. | ||
325 | +.\"}}} | ||
326 | +.\"{{{ -P | ||
327 | +.IP \fB\-P\fP | ||
328 | +Halt action is to turn off the power. | ||
329 | .\"}}} | ||
330 | .\"{{{ -n | ||
331 | .IP \fB\-n\fP | ||
332 | @@ -141,6 +150,14 @@ | ||
333 | .sp 1 | ||
334 | Note that if \fI/etc/shutdown.allow\fP is not present, the \fB-a\fP | ||
335 | argument is ignored. | ||
336 | +.SH HALT OR POWEROFF | ||
337 | +The \fB-H\fP option just sets the \fIinit\fP environment variable | ||
338 | +\fIINIT_HALT\fP to \fIHALT\fP, and the \fB-P\fP option just sets | ||
339 | +that variable to \fIPOWEROFF\fP. The shutdown script that calls | ||
340 | +\fBhalt\fP(8) as the last thing in the shutdown sequence should | ||
341 | +check these environment variables and call \fBhalt\fP(8) with | ||
342 | +the right options for these options to actually have any effect. | ||
343 | +Debian 3.1 (sarge) supports this. | ||
344 | .SH FILES | ||
345 | .nf | ||
346 | /fastboot | ||
347 | diff -urNd -urNd sysvinit-2.85/man/sulogin.8 sysvinit-2.86/man/sulogin.8 | ||
348 | --- sysvinit-2.85/man/sulogin.8 2000-09-11 07:19:25.000000000 -0500 | ||
349 | +++ sysvinit-2.86/man/sulogin.8 2004-06-09 07:47:45.000000000 -0500 | ||
350 | @@ -1,4 +1,4 @@ | ||
351 | -.TH SULOGIN 8 "11 Sep 2000" "" "Linux System Administrator's Manual" | ||
352 | +.TH SULOGIN 8 "04 Nov 2003" "" "Linux System Administrator's Manual" | ||
353 | .SH NAME | ||
354 | sulogin -- Single-user login | ||
355 | .SH SYNOPSIS | ||
356 | @@ -20,7 +20,7 @@ | ||
357 | .br | ||
358 | (or type Control-D for normal startup): | ||
359 | .PP | ||
360 | -\fIsulogin\fP will connected to the current terminal, or to the | ||
361 | +\fIsulogin\fP will be connected to the current terminal, or to the | ||
362 | optional device that can be specified on the command line | ||
363 | (typically \fB/dev/console\fP). | ||
364 | .PP | ||
365 | @@ -45,16 +45,18 @@ | ||
366 | .PP | ||
367 | boot: linux -b rw sushell=/sbin/sash | ||
368 | .SH FALLBACK METHODS | ||
369 | -\fIsulogin\fP checks the root password using the standard methods first. | ||
370 | -If the \fB-e\fP option was specified, | ||
371 | -\fIsulogin\fP examines the next files to find the root password. If | ||
372 | -they are damaged, or non-existant, it will use fallback methods that | ||
373 | -even go so far as to provide you with a shell prompt without asking | ||
374 | -for the root password if they are irrepairably damaged. | ||
375 | +\fIsulogin\fP checks the root password using the standard method (getpwnam) | ||
376 | +first. | ||
377 | +Then, if the \fB-e\fP option was specified, | ||
378 | +\fIsulogin\fP examines these files directly to find the root password: | ||
379 | .PP | ||
380 | /etc/passwd, | ||
381 | .br | ||
382 | /etc/shadow (if present) | ||
383 | +.PP | ||
384 | +If they are damaged or non-existant, sulogin will start a root shell | ||
385 | +without asking for a password. Only use the \fB-e\fP option if you | ||
386 | +are sure the console is physically protected against unauthorized access. | ||
387 | .SH AUTHOR | ||
388 | Miquel van Smoorenburg <miquels@cistron.nl> | ||
389 | .SH SEE ALSO | ||
390 | diff -urNd -urNd sysvinit-2.85/man/wall.1 sysvinit-2.86/man/wall.1 | ||
391 | --- sysvinit-2.85/man/wall.1 2003-04-16 04:17:38.000000000 -0500 | ||
392 | +++ sysvinit-2.86/man/wall.1 2004-06-09 07:47:45.000000000 -0500 | ||
393 | @@ -47,7 +47,7 @@ | ||
394 | .I Wall | ||
395 | ignores the | ||
396 | .B TZ | ||
397 | -variable - the time printed in the banner is based on the systems | ||
398 | +variable - the time printed in the banner is based on the system's | ||
399 | local time. | ||
400 | |||
401 | .SH SEE ALSO | ||
402 | diff -urNd -urNd sysvinit-2.85/src/Makefile sysvinit-2.86/src/Makefile | ||
403 | --- sysvinit-2.85/src/Makefile 2001-11-06 05:58:16.000000000 -0600 | ||
404 | +++ sysvinit-2.86/src/Makefile 2004-06-09 07:47:45.000000000 -0500 | ||
405 | @@ -5,34 +5,56 @@ | ||
406 | # clean cleans up object files | ||
407 | # clobber really cleans up | ||
408 | # | ||
409 | -# Version: @(#)Makefile 2.83-3 06-Nov-2001 miquels@cistron.nl | ||
410 | +# Version: @(#)Makefile 2.85-13 23-Mar-2004 miquels@cistron.nl | ||
411 | # | ||
412 | |||
413 | -CC = cc | ||
414 | -CFLAGS = -Wall -O2 -D_GNU_SOURCE | ||
415 | +CC = gcc | ||
416 | +CFLAGS = -Wall -O2 -fomit-frame-pointer -D_GNU_SOURCE | ||
417 | LDFLAGS = -s | ||
418 | STATIC = | ||
419 | |||
420 | -# For Debian we do not build all programs, otherwise we do. | ||
421 | -ifeq ($(DEBIAN),) | ||
422 | -PROGS = init halt shutdown killall5 runlevel sulogin utmpdump \ | ||
423 | - last mesg wall | ||
424 | -else | ||
425 | -PROGS = init halt shutdown killall5 runlevel sulogin last mesg | ||
426 | +# For some known distributions we do not build all programs, otherwise we do. | ||
427 | +BIN = | ||
428 | +SBIN = init halt shutdown runlevel killall5 | ||
429 | +USRBIN = last mesg | ||
430 | + | ||
431 | +MAN1 = last.1 lastb.1 mesg.1 | ||
432 | +MAN5 = initscript.5 inittab.5 | ||
433 | +MAN8 = halt.8 init.8 killall5.8 pidof.8 poweroff.8 reboot.8 runlevel.8 | ||
434 | +MAN8 += shutdown.8 telinit.8 | ||
435 | + | ||
436 | +ifeq ($(DISTRO),) | ||
437 | +BIN += mountpoint | ||
438 | +SBIN += sulogin bootlogd | ||
439 | +USRBIN += utmpdump wall | ||
440 | +MAN1 += mountpoint.1 wall.1 | ||
441 | +MAN8 += sulogin.8 bootlogd.8 | ||
442 | +endif | ||
443 | + | ||
444 | +ifeq ($(DISTRO),Debian) | ||
445 | +BIN += mountpoint | ||
446 | +SBIN += sulogin bootlogd | ||
447 | +MAN1 += mountpoint.1 | ||
448 | +MAN8 += sulogin.8 bootlogd.8 | ||
449 | +endif | ||
450 | + | ||
451 | +ifeq ($(DISTRO),Owl) | ||
452 | +USRBIN += wall | ||
453 | +MAN1 += wall.1 | ||
454 | endif | ||
455 | |||
456 | BIN_OWNER = root | ||
457 | BIN_GROUP = root | ||
458 | -BIN_COMBO = $(BIN_OWNER).$(BIN_GROUP) | ||
459 | +BIN_COMBO = $(BIN_OWNER):$(BIN_GROUP) | ||
460 | INSTALL = install -o $(BIN_OWNER) -g $(BIN_GROUP) | ||
461 | MANDIR = /usr/share/man | ||
462 | |||
463 | -# Additional libs for Gnu Libc | ||
464 | +# Additional libs for GNU libc. | ||
465 | ifneq ($(wildcard /usr/lib/libcrypt.a),) | ||
466 | LCRYPT = -lcrypt | ||
467 | endif | ||
468 | |||
469 | -all: $(PROGS) | ||
470 | +all: $(BIN) $(SBIN) $(USRBIN) | ||
471 | |||
472 | init: init.o init_utmp.o | ||
473 | $(CC) $(LDFLAGS) $(STATIC) -o $@ init.o init_utmp.o | ||
474 | @@ -46,6 +68,9 @@ | ||
475 | mesg: mesg.o | ||
476 | $(CC) $(LDFLAGS) -o $@ mesg.o | ||
477 | |||
478 | +mountpoint: mountpoint.o | ||
479 | + $(CC) $(LDFLAGS) -o $@ mountpoint.o | ||
480 | + | ||
481 | utmpdump: utmpdump.o | ||
482 | $(CC) $(LDFLAGS) -o $@ utmpdump.o | ||
483 | |||
484 | @@ -62,9 +87,9 @@ | ||
485 | $(CC) $(LDFLAGS) -o $@ dowall.o shutdown.o utmp.o | ||
486 | |||
487 | bootlogd: bootlogd.o | ||
488 | - $(CC) $(LDFLAGS) -o $@ bootlogd.o | ||
489 | + $(CC) $(LDFLAGS) -o $@ bootlogd.o -lutil | ||
490 | |||
491 | -init.o: init.c init.h set.h reboot.h | ||
492 | +init.o: init.c init.h set.h reboot.h initreq.h | ||
493 | $(CC) -c $(CFLAGS) init.c | ||
494 | |||
495 | utmp.o: utmp.c init.h | ||
496 | @@ -80,36 +105,44 @@ | ||
497 | @echo Type \"make clobber\" to really clean up. | ||
498 | |||
499 | clobber: cleanobjs | ||
500 | - rm -f $(PROGS) | ||
501 | + rm -f $(BIN) $(SBIN) $(USRBIN) | ||
502 | |||
503 | distclean: clobber | ||
504 | |||
505 | install: | ||
506 | - $(INSTALL) -m 755 halt init killall5 sulogin \ | ||
507 | - runlevel shutdown $(ROOT)/sbin | ||
508 | - # These are not installed by default | ||
509 | -ifeq ($(DEBIAN),) | ||
510 | - $(INSTALL) -m 555 utmpdump wall $(ROOT)/usr/bin | ||
511 | -endif | ||
512 | - # $(INSTALL) -m 755 etc/initscript.sample $(ROOT)/etc | ||
513 | - $(INSTALL) -m 755 mesg last $(ROOT)/usr/bin | ||
514 | - cd $(ROOT)/sbin; ln -sf halt reboot; chown $(BIN_COMBO) reboot | ||
515 | - cd $(ROOT)/sbin; ln -sf halt poweroff; chown $(BIN_COMBO) poweroff | ||
516 | - cd $(ROOT)/sbin; ln -sf init telinit; chown $(BIN_COMBO) telinit | ||
517 | - cd $(ROOT)/bin; ln -sf ../sbin/killall5 pidof; chown $(BIN_COMBO) pidof | ||
518 | - cd $(ROOT)/usr/bin; ln -sf last lastb; chown $(BIN_COMBO) lastb | ||
519 | - $(INSTALL) -m 644 initreq.h $(ROOT)/usr/include | ||
520 | - $(INSTALL) -m 644 ../man/*.8 $(ROOT)$(MANDIR)/man8 | ||
521 | - $(INSTALL) -m 644 ../man/*.5 $(ROOT)$(MANDIR)/man5 | ||
522 | -ifeq ($(DEBIAN),) | ||
523 | - $(INSTALL) -m 644 ../man/wall.1 $(ROOT)$(MANDIR)/man1 | ||
524 | -endif | ||
525 | - $(INSTALL) -m 644 ../man/last.1 ../man/lastb.1 ../man/mesg.1 \ | ||
526 | - $(ROOT)$(MANDIR)/man1 | ||
527 | + for i in $(BIN); do \ | ||
528 | + $(INSTALL) -m 755 $$i $(ROOT)/bin/; \ | ||
529 | + done | ||
530 | + for i in $(SBIN); do \ | ||
531 | + $(INSTALL) -m 755 $$i $(ROOT)/sbin/; \ | ||
532 | + done | ||
533 | + for i in $(USRBIN); do \ | ||
534 | + $(INSTALL) -m 755 $$i $(ROOT)/usr/bin/; \ | ||
535 | + done | ||
536 | + # $(INSTALL) -m 755 etc/initscript.sample $(ROOT)/etc/ | ||
537 | + ln -sf halt $(ROOT)/sbin/reboot | ||
538 | + ln -sf halt $(ROOT)/sbin/poweroff | ||
539 | + ln -sf init $(ROOT)/sbin/telinit | ||
540 | + ln -sf ../sbin/killall5 $(ROOT)/bin/pidof | ||
541 | + if [ ! -f $(ROOT)/usr/bin/lastb ]; then \ | ||
542 | + ln -sf last $(ROOT)/usr/bin/lastb; \ | ||
543 | + fi | ||
544 | + $(INSTALL) -m 644 initreq.h $(ROOT)/usr/include/ | ||
545 | + for i in $(MAN1); do \ | ||
546 | + $(INSTALL) -m 644 ../man/$$i $(ROOT)$(MANDIR)/man1/; \ | ||
547 | + done | ||
548 | + for i in $(MAN5); do \ | ||
549 | + $(INSTALL) -m 644 ../man/$$i $(ROOT)$(MANDIR)/man5/; \ | ||
550 | + done | ||
551 | + for i in $(MAN8); do \ | ||
552 | + $(INSTALL) -m 644 ../man/$$i $(ROOT)$(MANDIR)/man8/; \ | ||
553 | + done | ||
554 | +ifeq ($(ROOT),) | ||
555 | # | ||
556 | - # This part is skipped on debian systems, the | ||
557 | + # This part is skipped on Debian systems, the | ||
558 | # debian.preinst script takes care of it. | ||
559 | @if [ ! -p /dev/initctl ]; then \ | ||
560 | echo "Creating /dev/initctl"; \ | ||
561 | rm -f /dev/initctl; \ | ||
562 | mknod -m 600 /dev/initctl p; fi | ||
563 | +endif | ||
564 | Binary files sysvinit-2.85/src/bootlogd and sysvinit-2.86/src/bootlogd differ | ||
565 | diff -urNd -urNd sysvinit-2.85/src/bootlogd.c sysvinit-2.86/src/bootlogd.c | ||
566 | --- sysvinit-2.85/src/bootlogd.c 2001-12-09 08:01:28.000000000 -0600 | ||
567 | +++ sysvinit-2.86/src/bootlogd.c 2004-06-09 07:47:45.000000000 -0500 | ||
568 | @@ -3,12 +3,12 @@ | ||
569 | * The file is usually located on the /var partition, and | ||
570 | * gets written (and fsynced) as soon as possible. | ||
571 | * | ||
572 | - * Version: @(#)bootlogd 2.79 11-Sep-2000 miquels@cistron.nl | ||
573 | + * Version: @(#)bootlogd 2.86pre 12-Jan-2004 miquels@cistron.nl | ||
574 | * | ||
575 | * Bugs: Uses openpty(), only available in glibc. Sorry. | ||
576 | * | ||
577 | * This file is part of the sysvinit suite, | ||
578 | - * Copyright 1991-2000 Miquel van Smoorenburg. | ||
579 | + * Copyright 1991-2004 Miquel van Smoorenburg. | ||
580 | * | ||
581 | * This program is free software; you can redistribute it and/or | ||
582 | * modify it under the terms of the GNU General Public License | ||
583 | @@ -17,7 +17,9 @@ | ||
584 | * | ||
585 | * *NOTE* *NOTE* *NOTE* | ||
586 | * This is a PROOF OF CONCEPT IMPLEMENTATION | ||
587 | - * I do not recommend using this on production systems. | ||
588 | + * | ||
589 | + * I have bigger plans for Debian, but for now | ||
590 | + * this has to do ;) | ||
591 | * | ||
592 | */ | ||
593 | |||
594 | @@ -38,18 +40,14 @@ | ||
595 | #include <dirent.h> | ||
596 | #include <fcntl.h> | ||
597 | #include <pty.h> | ||
598 | - | ||
599 | -char *Version = "@(#) bootlogd 2.79 11-Sep-2000 MvS"; | ||
600 | - | ||
601 | -/* | ||
602 | - * Until the kernel knows about TIOCGDEV, use a really ugly | ||
603 | - * non-portable (not even between architectures) hack. | ||
604 | - */ | ||
605 | -#ifndef TIOCGDEV | ||
606 | -# define TIOCTTYGSTRUCT_HACK 1 | ||
607 | +#include <ctype.h> | ||
608 | +#ifdef __linux__ | ||
609 | +#include <sys/mount.h> | ||
610 | #endif | ||
611 | |||
612 | -#define LOGFILE "/var/log/boot.log" | ||
613 | +char *Version = "@(#) bootlogd 2.86 03-Jun-2004 miquels@cistron.nl"; | ||
614 | + | ||
615 | +#define LOGFILE "/var/log/boot" | ||
616 | |||
617 | char ringbuf[32768]; | ||
618 | char *endptr = ringbuf + sizeof(ringbuf); | ||
619 | @@ -59,29 +57,32 @@ | ||
620 | int got_signal = 0; | ||
621 | int didnl = 1; | ||
622 | |||
623 | +struct line { | ||
624 | + char buf[256]; | ||
625 | + int pos; | ||
626 | +} line; | ||
627 | |||
628 | -#ifdef TIOCTTYGSTRUCT_HACK | ||
629 | -struct tty_offsets { | ||
630 | - char *kver; | ||
631 | - int offset; | ||
632 | -} tty_offsets[] = { | ||
633 | -#if ((~0UL) == 0xffffffff) /* 32 bits */ | ||
634 | - { "2.0.", 236 }, | ||
635 | - { "2.1.", 268 }, | ||
636 | - { "2.2.", 272 }, | ||
637 | - { "2.3.", 272 }, | ||
638 | - { "2.4.", 272 }, | ||
639 | - { "2.5.", 272 }, | ||
640 | -#else /* 64 bits */ | ||
641 | - { "2.2.", 480 }, | ||
642 | - { "2.3.", 480 }, | ||
643 | - { "2.4.", 480 }, | ||
644 | - { "2.5.", 480 }, | ||
645 | -#endif | ||
646 | - { NULL, 0 }, | ||
647 | +/* | ||
648 | + * Console devices as listed on the kernel command line and | ||
649 | + * the mapping to actual devices in /dev | ||
650 | + */ | ||
651 | +struct consdev { | ||
652 | + char *cmdline; | ||
653 | + char *dev1; | ||
654 | + char *dev2; | ||
655 | +} consdev[] = { | ||
656 | + { "ttySC", "/dev/ttySC%s", "/dev/ttsc/%s" }, | ||
657 | + { "ttyS", "/dev/ttyS%s", "/dev/tts/%s" }, | ||
658 | + { "tty", "/dev/tty%s", "/dev/vc/%s" }, | ||
659 | + { "hvc", "/dev/hvc%s", "/dev/hvc/%s" }, | ||
660 | + { NULL, NULL, NULL }, | ||
661 | }; | ||
662 | -#endif | ||
663 | |||
664 | +/* | ||
665 | + * Devices to try as console if not found on kernel command line. | ||
666 | + * Tried from left to right (as opposed to kernel cmdline). | ||
667 | + */ | ||
668 | +char *defcons[] = { "tty0", "hvc0", "ttyS0", "ttySC0", NULL }; | ||
669 | |||
670 | /* | ||
671 | * Catch signals. | ||
672 | @@ -95,6 +96,8 @@ | ||
673 | /* | ||
674 | * Scan /dev and find the device name. | ||
675 | * Side-effect: directory is changed to /dev | ||
676 | + * | ||
677 | + * FIXME: scan subdirectories for devfs support ? | ||
678 | */ | ||
679 | int findtty(char *res, int rlen, dev_t dev) | ||
680 | { | ||
681 | @@ -117,18 +120,88 @@ | ||
682 | } | ||
683 | } | ||
684 | if (ent == NULL) { | ||
685 | - fprintf(stderr, "bootlogd: cannot find console device\n"); | ||
686 | + fprintf(stderr, "bootlogd: cannot find console device " | ||
687 | + "%d:%d in /dev\n", major(dev), minor(dev)); | ||
688 | r = -1; | ||
689 | - } else if (strlen(ent->d_name) >= rlen) { | ||
690 | + } else if (strlen(ent->d_name) + 5 >= rlen) { | ||
691 | fprintf(stderr, "bootlogd: console device name too long\n"); | ||
692 | r = -1; | ||
693 | } else | ||
694 | - strcpy(res, ent->d_name); | ||
695 | + snprintf(res, rlen, "/dev/%s", ent->d_name); | ||
696 | closedir(dir); | ||
697 | |||
698 | return r; | ||
699 | } | ||
700 | |||
701 | +/* | ||
702 | + * For some reason, openpty() in glibc sometimes doesn't | ||
703 | + * work at boot-time. It must be a bug with old-style pty | ||
704 | + * names, as new-style (/dev/pts) is not available at that | ||
705 | + * point. So, we find a pty/tty pair ourself if openpty() | ||
706 | + * fails for whatever reason. | ||
707 | + */ | ||
708 | +int findpty(int *master, int *slave, char *name) | ||
709 | +{ | ||
710 | + char pty[16]; | ||
711 | + char tty[16]; | ||
712 | + int i, j; | ||
713 | + int found; | ||
714 | + | ||
715 | + if (openpty(master, slave, name, NULL, NULL) >= 0) | ||
716 | + return 0; | ||
717 | + | ||
718 | + found = 0; | ||
719 | + | ||
720 | + for (i = 'p'; i <= 'z'; i++) { | ||
721 | + for (j = '0'; j <= 'f'; j++) { | ||
722 | + if (j == '9' + 1) j = 'a'; | ||
723 | + sprintf(pty, "/dev/pty%c%c", i, j); | ||
724 | + sprintf(tty, "/dev/tty%c%c", i, j); | ||
725 | + if ((*master = open(pty, O_RDWR|O_NOCTTY)) >= 0) { | ||
726 | + *slave = open(tty, O_RDWR|O_NOCTTY); | ||
727 | + if (*slave >= 0) { | ||
728 | + found = 1; | ||
729 | + break; | ||
730 | + } | ||
731 | + } | ||
732 | + } | ||
733 | + if (found) break; | ||
734 | + } | ||
735 | + if (found < 0) return -1; | ||
736 | + | ||
737 | + if (name) strcpy(name, tty); | ||
738 | + | ||
739 | + return 0; | ||
740 | +} | ||
741 | +/* | ||
742 | + * See if a console taken from the kernel command line maps | ||
743 | + * to a character device we know about, and if we can open it. | ||
744 | + */ | ||
745 | +int isconsole(char *s, char *res, int rlen) | ||
746 | +{ | ||
747 | + struct consdev *c; | ||
748 | + int l, sl, i, fd; | ||
749 | + char *p, *q; | ||
750 | + | ||
751 | + sl = strlen(s); | ||
752 | + | ||
753 | + for (c = consdev; c->cmdline; c++) { | ||
754 | + l = strlen(c->cmdline); | ||
755 | + if (sl <= l) continue; | ||
756 | + p = s + l; | ||
757 | + if (strncmp(s, c->cmdline, l) != 0 || !isdigit(*p)) | ||
758 | + continue; | ||
759 | + for (i = 0; i < 2; i++) { | ||
760 | + snprintf(res, rlen, i ? c->dev1 : c->dev2, p); | ||
761 | + if ((q = strchr(res, ',')) != NULL) *q = 0; | ||
762 | + if ((fd = open(res, O_RDONLY|O_NONBLOCK)) >= 0) { | ||
763 | + close(fd); | ||
764 | + return 1; | ||
765 | + } | ||
766 | + } | ||
767 | + } | ||
768 | + return 0; | ||
769 | +} | ||
770 | |||
771 | /* | ||
772 | * Find out the _real_ console. Assume that stdin is connected to | ||
773 | @@ -136,21 +209,18 @@ | ||
774 | */ | ||
775 | int consolename(char *res, int rlen) | ||
776 | { | ||
777 | - struct stat st; | ||
778 | -#if TIOCTTYGSTRUCT_HACK | ||
779 | - struct utsname uts; | ||
780 | - struct tty_offsets *tt; | ||
781 | - dev_t dev; | ||
782 | - unsigned short *kdev; | ||
783 | - char buf[4096]; | ||
784 | - int offset = -1; | ||
785 | -#endif | ||
786 | #ifdef TIOCGDEV | ||
787 | - kdev_t kdev; | ||
788 | + unsigned int kdev; | ||
789 | #endif | ||
790 | + struct stat st, st2; | ||
791 | + char buf[256]; | ||
792 | + char *p; | ||
793 | + int didmount = 0; | ||
794 | + int n, r; | ||
795 | + int fd; | ||
796 | |||
797 | fstat(0, &st); | ||
798 | - if (st.st_rdev != 0x0501) { | ||
799 | + if (major(st.st_rdev) != 5 || minor(st.st_rdev) != 1) { | ||
800 | /* | ||
801 | * Old kernel, can find real device easily. | ||
802 | */ | ||
803 | @@ -160,33 +230,78 @@ | ||
804 | #ifdef TIOCGDEV | ||
805 | if (ioctl(0, TIOCGDEV, &kdev) == 0) | ||
806 | return findtty(res, rlen, (dev_t)kdev); | ||
807 | - return -1; | ||
808 | + if (errno != ENOIOCTLCMD) return -1; | ||
809 | #endif | ||
810 | |||
811 | +#ifdef __linux__ | ||
812 | /* | ||
813 | - * New kernel and new console device - hard to find | ||
814 | - * out what device the real console is .. | ||
815 | + * Read /proc/cmdline. | ||
816 | */ | ||
817 | -#if TIOCTTYGSTRUCT_HACK | ||
818 | - if (ioctl(0, TIOCTTYGSTRUCT, buf) != 0) { | ||
819 | - perror("bootlogd: TIOCTTYGSTRUCT"); | ||
820 | + stat("/", &st); | ||
821 | + if (stat("/proc", &st2) < 0) { | ||
822 | + perror("bootlogd: /proc"); | ||
823 | return -1; | ||
824 | } | ||
825 | - uname(&uts); | ||
826 | - for (tt = tty_offsets; tt->kver; tt++) | ||
827 | - if (!strncmp(uts.release, tt->kver, strlen(tt->kver))) { | ||
828 | - offset = tt->offset; | ||
829 | + if (st.st_dev == st2.st_dev) { | ||
830 | + if (mount("proc", "/proc", "proc", 0, NULL) < 0) { | ||
831 | + perror("bootlogd: mount /proc"); | ||
832 | + return -1; | ||
833 | + } | ||
834 | + didmount = 1; | ||
835 | + } | ||
836 | + | ||
837 | + n = 0; | ||
838 | + r = -1; | ||
839 | + if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) { | ||
840 | + perror("bootlogd: /proc/cmdline"); | ||
841 | + } else { | ||
842 | + buf[0] = 0; | ||
843 | + if ((n = read(fd, buf, sizeof(buf) - 1)) >= 0) | ||
844 | + r = 0; | ||
845 | + else | ||
846 | + perror("bootlogd: /proc/cmdline"); | ||
847 | + close(fd); | ||
848 | + } | ||
849 | + if (didmount) umount("/proc"); | ||
850 | + | ||
851 | + if (r < 0) return r; | ||
852 | + | ||
853 | + /* | ||
854 | + * OK, so find console= in /proc/cmdline. | ||
855 | + * Parse in reverse, opening as we go. | ||
856 | + * | ||
857 | + * Valid console devices: ttySC, ttyS, tty, hvc. | ||
858 | + */ | ||
859 | + p = buf + n; | ||
860 | + *p-- = 0; | ||
861 | + r = -1; | ||
862 | + while (p >= buf) { | ||
863 | + if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') { | ||
864 | + *p-- = 0; | ||
865 | + continue; | ||
866 | + } | ||
867 | + if (strncmp(p, "console=", 8) == 0 && | ||
868 | + isconsole(p + 8, res, rlen)) { | ||
869 | + r = 0; | ||
870 | break; | ||
871 | } | ||
872 | - if (offset < 0) { | ||
873 | - fprintf(stderr, "bootlogd: don't know offsetof" | ||
874 | - "(struct tty_struct, device) for kernel %s\n", uts.release); | ||
875 | - return -1; | ||
876 | + p--; | ||
877 | } | ||
878 | - kdev = (unsigned short *)(&buf[offset]); | ||
879 | - dev = (dev_t)(*kdev); | ||
880 | - return findtty(res, rlen, dev); | ||
881 | + | ||
882 | + if (r == 0) return r; | ||
883 | #endif | ||
884 | + | ||
885 | + /* | ||
886 | + * Okay, no console on the command line - | ||
887 | + * guess the default console. | ||
888 | + */ | ||
889 | + for (n = 0; defcons[n]; n++) | ||
890 | + if (isconsole(defcons[n], res, rlen)) | ||
891 | + return 0; | ||
892 | + | ||
893 | + fprintf(stderr, "bootlogd: cannot deduce real console device\n"); | ||
894 | + | ||
895 | + return -1; | ||
896 | } | ||
897 | |||
898 | |||
899 | @@ -197,9 +312,13 @@ | ||
900 | { | ||
901 | time_t t; | ||
902 | char *s; | ||
903 | + char tmp[8]; | ||
904 | int olen = len; | ||
905 | + int dosync = 0; | ||
906 | + int tlen; | ||
907 | |||
908 | while (len > 0) { | ||
909 | + tmp[0] = 0; | ||
910 | if (didnl) { | ||
911 | time(&t); | ||
912 | s = ctime(&t); | ||
913 | @@ -207,24 +326,51 @@ | ||
914 | didnl = 0; | ||
915 | } | ||
916 | switch (*ptr) { | ||
917 | + case 27: /* ESC */ | ||
918 | + strcpy(tmp, "^["); | ||
919 | + break; | ||
920 | case '\r': | ||
921 | + line.pos = 0; | ||
922 | + break; | ||
923 | + case 8: /* ^H */ | ||
924 | + if (line.pos > 0) line.pos--; | ||
925 | break; | ||
926 | case '\n': | ||
927 | didnl = 1; | ||
928 | + dosync = 1; | ||
929 | + break; | ||
930 | case '\t': | ||
931 | + line.pos += (line.pos / 8 + 1) * 8; | ||
932 | + if (line.pos >= sizeof(line.buf)) | ||
933 | + line.pos = sizeof(line.buf) - 1; | ||
934 | + break; | ||
935 | case 32 ... 127: | ||
936 | case 161 ... 255: | ||
937 | - fputc(*ptr, fp); | ||
938 | + tmp[0] = *ptr; | ||
939 | + tmp[1] = 0; | ||
940 | break; | ||
941 | default: | ||
942 | - fprintf(fp, "\\%03o", *ptr); | ||
943 | + sprintf(tmp, "\\%03o", *ptr); | ||
944 | break; | ||
945 | } | ||
946 | ptr++; | ||
947 | len--; | ||
948 | + | ||
949 | + tlen = strlen(tmp); | ||
950 | + if (tlen && (line.pos + tlen < sizeof(line.buf))) { | ||
951 | + memcpy(line.buf + line.pos, tmp, tlen); | ||
952 | + line.pos += tlen; | ||
953 | + } | ||
954 | + if (didnl) { | ||
955 | + fprintf(fp, "%s\n", line.buf); | ||
956 | + memset(&line, 0, sizeof(line)); | ||
957 | + } | ||
958 | + } | ||
959 | + | ||
960 | + if (dosync) { | ||
961 | + fflush(fp); | ||
962 | + fdatasync(fileno(fp)); | ||
963 | } | ||
964 | - fflush(fp); | ||
965 | - fdatasync(fileno(fp)); | ||
966 | |||
967 | outptr += olen; | ||
968 | if (outptr >= endptr) | ||
969 | @@ -242,6 +388,40 @@ | ||
970 | exit(1); | ||
971 | } | ||
972 | |||
973 | +int open_nb(char *buf) | ||
974 | +{ | ||
975 | + int fd, n; | ||
976 | + | ||
977 | + if ((fd = open(buf, O_WRONLY|O_NONBLOCK|O_NOCTTY)) < 0) | ||
978 | + return -1; | ||
979 | + n = fcntl(fd, F_GETFL); | ||
980 | + n &= ~(O_NONBLOCK); | ||
981 | + fcntl(fd, F_SETFL, n); | ||
982 | + | ||
983 | + return fd; | ||
984 | +} | ||
985 | + | ||
986 | +/* | ||
987 | + * We got a write error on the real console. If its an EIO, | ||
988 | + * somebody hung up our filedescriptor, so try to re-open it. | ||
989 | + */ | ||
990 | +int write_err(int pts, int realfd, char *realcons, int e) | ||
991 | +{ | ||
992 | + int fd; | ||
993 | + | ||
994 | + if (e != EIO) { | ||
995 | +werr: | ||
996 | + close(pts); | ||
997 | + fprintf(stderr, "bootlogd: writing to console: %s\n", | ||
998 | + strerror(e)); | ||
999 | + return -1; | ||
1000 | + } | ||
1001 | + close(realfd); | ||
1002 | + if ((fd = open_nb(realcons)) < 0) | ||
1003 | + goto werr; | ||
1004 | + | ||
1005 | + return fd; | ||
1006 | +} | ||
1007 | |||
1008 | int main(int argc, char **argv) | ||
1009 | { | ||
1010 | @@ -249,6 +429,7 @@ | ||
1011 | struct timeval tv; | ||
1012 | fd_set fds; | ||
1013 | char buf[1024]; | ||
1014 | + char realcons[1024]; | ||
1015 | char *p; | ||
1016 | char *logfile; | ||
1017 | char *pidfile; | ||
1018 | @@ -298,23 +479,32 @@ | ||
1019 | /* | ||
1020 | * Open console device directly. | ||
1021 | */ | ||
1022 | - if (consolename(buf, sizeof(buf)) < 0) | ||
1023 | + if (consolename(realcons, sizeof(realcons)) < 0) | ||
1024 | return 1; | ||
1025 | - if ((realfd = open(buf, O_WRONLY|O_NONBLOCK)) < 0) { | ||
1026 | + | ||
1027 | + if (strcmp(realcons, "/dev/tty0") == 0) | ||
1028 | + strcpy(realcons, "/dev/tty1"); | ||
1029 | + if (strcmp(realcons, "/dev/vc/0") == 0) | ||
1030 | + strcpy(realcons, "/dev/vc/1"); | ||
1031 | + | ||
1032 | + if ((realfd = open_nb(realcons)) < 0) { | ||
1033 | fprintf(stderr, "bootlogd: %s: %s\n", buf, strerror(errno)); | ||
1034 | return 1; | ||
1035 | } | ||
1036 | - n = fcntl(realfd, F_GETFL); | ||
1037 | - n &= ~(O_NONBLOCK); | ||
1038 | - fcntl(realfd, F_SETFL, n); | ||
1039 | |||
1040 | /* | ||
1041 | * Grab a pty, and redirect console messages to it. | ||
1042 | */ | ||
1043 | - if (openpty(&ptm, &pts, buf, NULL, NULL) < 0) { | ||
1044 | - fprintf(stderr, "bootlogd: cannot allocate pseudo tty\n"); | ||
1045 | + ptm = -1; | ||
1046 | + pts = -1; | ||
1047 | + buf[0] = 0; | ||
1048 | + if (findpty(&ptm, &pts, buf) < 0) { | ||
1049 | + fprintf(stderr, | ||
1050 | + "bootlogd: cannot allocate pseudo tty: %s\n", | ||
1051 | + strerror(errno)); | ||
1052 | return 1; | ||
1053 | } | ||
1054 | + | ||
1055 | (void)ioctl(0, TIOCCONS, NULL); | ||
1056 | #if 1 | ||
1057 | /* Work around bug in 2.1/2.2 kernels. Fixed in 2.2.13 and 2.3.18 */ | ||
1058 | @@ -357,8 +547,8 @@ | ||
1059 | * open the logfile. There might be buffered messages | ||
1060 | * we want to write. | ||
1061 | */ | ||
1062 | - tv.tv_sec = fp ? 86400 : 5; | ||
1063 | - tv.tv_usec = 0; | ||
1064 | + tv.tv_sec = 0; | ||
1065 | + tv.tv_usec = 500000; | ||
1066 | FD_ZERO(&fds); | ||
1067 | FD_SET(ptm, &fds); | ||
1068 | if (select(ptm + 1, &fds, NULL, NULL, &tv) == 1) { | ||
1069 | @@ -374,10 +564,22 @@ | ||
1070 | p = inptr; | ||
1071 | while (m > 0) { | ||
1072 | i = write(realfd, p, m); | ||
1073 | - if (i <= 0) break; | ||
1074 | - m -= i; | ||
1075 | - p += i; | ||
1076 | + if (i >= 0) { | ||
1077 | + m -= i; | ||
1078 | + p += i; | ||
1079 | + continue; | ||
1080 | + } | ||
1081 | + /* | ||
1082 | + * Handle EIO (somebody hung | ||
1083 | + * up our filedescriptor) | ||
1084 | + */ | ||
1085 | + realfd = write_err(pts, realfd, | ||
1086 | + realcons, errno); | ||
1087 | + if (realfd >= 0) continue; | ||
1088 | + got_signal = 1; /* Not really */ | ||
1089 | + break; | ||
1090 | } | ||
1091 | + | ||
1092 | /* | ||
1093 | * Increment buffer position. Handle | ||
1094 | * wraps, and also drag output pointer | ||
1095 | @@ -410,8 +612,8 @@ | ||
1096 | writelog(fp, outptr, todo); | ||
1097 | } | ||
1098 | |||
1099 | - if (fp && !didnl) { | ||
1100 | - fputc('\n', fp); | ||
1101 | + if (fp) { | ||
1102 | + if (!didnl) fputc('\n', fp); | ||
1103 | fclose(fp); | ||
1104 | } | ||
1105 | |||
1106 | Binary files sysvinit-2.85/src/bootlogd.o and sysvinit-2.86/src/bootlogd.o differ | ||
1107 | diff -urNd -urNd sysvinit-2.85/src/dowall.c sysvinit-2.86/src/dowall.c | ||
1108 | --- sysvinit-2.85/src/dowall.c 2003-04-17 06:32:01.000000000 -0500 | ||
1109 | +++ sysvinit-2.86/src/dowall.c 2004-06-09 07:47:45.000000000 -0500 | ||
1110 | @@ -3,7 +3,7 @@ | ||
1111 | * | ||
1112 | * Author: Miquel van Smoorenburg, miquels@cistron.nl | ||
1113 | * | ||
1114 | - * Version: @(#)dowall.c 2.85-1 15-Apr-2003 miquels@cistron.nl | ||
1115 | + * Version: @(#)dowall.c 2.85-5 02-Jul-2003 miquels@cistron.nl | ||
1116 | * | ||
1117 | * This file is part of the sysvinit suite, | ||
1118 | * Copyright 1991-2003 Miquel van Smoorenburg. | ||
1119 | @@ -135,6 +135,13 @@ | ||
1120 | char *user, *tty; | ||
1121 | int fd, flags; | ||
1122 | |||
1123 | + /* | ||
1124 | + * Make sure tp and fd aren't in a register. Some versions | ||
1125 | + * of gcc clobber those after longjmp (or so I understand). | ||
1126 | + */ | ||
1127 | + (void) &tp; | ||
1128 | + (void) &fd; | ||
1129 | + | ||
1130 | getuidtty(&user, &tty); | ||
1131 | |||
1132 | /* Get the time */ | ||
1133 | Binary files sysvinit-2.85/src/dowall.o and sysvinit-2.86/src/dowall.o differ | ||
1134 | Binary files sysvinit-2.85/src/halt and sysvinit-2.86/src/halt differ | ||
1135 | diff -urNd -urNd sysvinit-2.85/src/halt.c sysvinit-2.86/src/halt.c | ||
1136 | --- sysvinit-2.85/src/halt.c 2001-11-27 06:12:03.000000000 -0600 | ||
1137 | +++ sysvinit-2.86/src/halt.c 2004-07-30 07:16:18.000000000 -0500 | ||
1138 | @@ -8,12 +8,14 @@ | ||
1139 | * execute an "shutdown -r". This is for compatibility with | ||
1140 | * sysvinit 2.4. | ||
1141 | * | ||
1142 | - * Usage: halt [-n] [-w] [-d] [-f] [-p] | ||
1143 | + * Usage: halt [-n] [-w] [-d] [-f] [-h] [-i] [-p] | ||
1144 | * -n: don't sync before halting the system | ||
1145 | * -w: only write a wtmp reboot record and exit. | ||
1146 | * -d: don't write a wtmp record. | ||
1147 | * -f: force halt/reboot, don't call shutdown. | ||
1148 | - * -p: power down the system (if possible, otherwise halt) | ||
1149 | + * -h: put harddisks in standby mode | ||
1150 | + * -i: shut down all network interfaces. | ||
1151 | + * -p: power down the system (if possible, otherwise halt). | ||
1152 | * | ||
1153 | * Reboot and halt are both this program. Reboot | ||
1154 | * is just a link to halt. Invoking the program | ||
1155 | @@ -21,10 +23,10 @@ | ||
1156 | * | ||
1157 | * Author: Miquel van Smoorenburg, miquels@cistron.nl | ||
1158 | * | ||
1159 | - * Version: 2.84, 27-Nov-2001 | ||
1160 | + * Version: 2.86, 30-Jul-2004 | ||
1161 | * | ||
1162 | * This file is part of the sysvinit suite, | ||
1163 | - * Copyright 1991-2001 Miquel van Smoorenburg. | ||
1164 | + * Copyright 1991-2004 Miquel van Smoorenburg. | ||
1165 | * | ||
1166 | * This program is free software; you can redistribute it and/or | ||
1167 | * modify it under the terms of the GNU General Public License | ||
1168 | @@ -47,7 +49,7 @@ | ||
1169 | #include <getopt.h> | ||
1170 | #include "reboot.h" | ||
1171 | |||
1172 | -char *Version = "@(#)halt 2.84 27-Nov-2001 miquels@cistron.nl"; | ||
1173 | +char *Version = "@(#)halt 2.86 31-Jul-2004 miquels@cistron.nl"; | ||
1174 | char *progname; | ||
1175 | |||
1176 | #define KERNEL_MONITOR 1 /* If halt() puts you into the kernel monitor. */ | ||
1177 | @@ -62,7 +64,16 @@ | ||
1178 | */ | ||
1179 | void usage(void) | ||
1180 | { | ||
1181 | - fprintf(stderr, "usage: %s [-n] [-w] [-d] [-f] [-i] [-p]\n", progname); | ||
1182 | + fprintf(stderr, "usage: %s [-n] [-w] [-d] [-f] [-h] [-i]%s\n", | ||
1183 | + progname, strcmp(progname, "halt") ? "" : " [-p]"); | ||
1184 | + fprintf(stderr, "\t-n: don't sync before halting the system\n"); | ||
1185 | + fprintf(stderr, "\t-w: only write a wtmp reboot record and exit.\n"); | ||
1186 | + fprintf(stderr, "\t-d: don't write a wtmp record.\n"); | ||
1187 | + fprintf(stderr, "\t-f: force halt/reboot, don't call shutdown.\n"); | ||
1188 | + fprintf(stderr, "\t-h: put harddisks in standby mode.\n"); | ||
1189 | + fprintf(stderr, "\t-i: shut down all network interfaces.\n"); | ||
1190 | + if (!strcmp(progname, "halt")) | ||
1191 | + fprintf(stderr, "\t-p: power down the system (if possible, otherwise halt).\n"); | ||
1192 | exit(1); | ||
1193 | } | ||
1194 | |||
1195 | @@ -172,11 +183,6 @@ | ||
1196 | else | ||
1197 | progname = argv[0]; | ||
1198 | |||
1199 | - if (geteuid() != 0) { | ||
1200 | - fprintf(stderr, "%s: must be superuser.\n", progname); | ||
1201 | - exit(1); | ||
1202 | - } | ||
1203 | - | ||
1204 | if (!strcmp(progname, "reboot")) do_reboot = 1; | ||
1205 | if (!strcmp(progname, "poweroff")) do_poweroff = 1; | ||
1206 | |||
1207 | @@ -216,6 +222,11 @@ | ||
1208 | } | ||
1209 | if (argc != optind) usage(); | ||
1210 | |||
1211 | + if (geteuid() != 0) { | ||
1212 | + fprintf(stderr, "%s: must be superuser.\n", progname); | ||
1213 | + exit(1); | ||
1214 | + } | ||
1215 | + | ||
1216 | (void)chdir("/"); | ||
1217 | |||
1218 | if (!do_hard && !do_nothing) { | ||
1219 | @@ -236,7 +247,7 @@ | ||
1220 | /* | ||
1221 | * Exit if all we wanted to do was write a wtmp record. | ||
1222 | */ | ||
1223 | - if (do_nothing) exit(0); | ||
1224 | + if (do_nothing && !do_hddown && !do_ifdown) exit(0); | ||
1225 | |||
1226 | if (do_sync) { | ||
1227 | sync(); | ||
1228 | @@ -249,13 +260,17 @@ | ||
1229 | if (do_hddown) | ||
1230 | (void)hddown(); | ||
1231 | |||
1232 | + if (do_nothing) exit(0); | ||
1233 | + | ||
1234 | if (do_reboot) { | ||
1235 | init_reboot(BMAGIC_REBOOT); | ||
1236 | } else { | ||
1237 | /* | ||
1238 | * Turn on hard reboot, CTRL-ALT-DEL will reboot now | ||
1239 | */ | ||
1240 | +#ifdef BMAGIC_HARD | ||
1241 | init_reboot(BMAGIC_HARD); | ||
1242 | +#endif | ||
1243 | |||
1244 | /* | ||
1245 | * Stop init; it is insensitive to the signals sent | ||
1246 | @@ -277,7 +292,9 @@ | ||
1247 | /* | ||
1248 | * If we return, we (c)ontinued from the kernel monitor. | ||
1249 | */ | ||
1250 | +#ifdef BMAGIC_SOFT | ||
1251 | init_reboot(BMAGIC_SOFT); | ||
1252 | +#endif | ||
1253 | kill(1, SIGCONT); | ||
1254 | |||
1255 | exit(0); | ||
1256 | Binary files sysvinit-2.85/src/halt.o and sysvinit-2.86/src/halt.o differ | ||
1257 | diff -urNd -urNd sysvinit-2.85/src/hddown.c sysvinit-2.86/src/hddown.c | ||
1258 | --- sysvinit-2.85/src/hddown.c 2001-11-07 09:11:21.000000000 -0600 | ||
1259 | +++ sysvinit-2.86/src/hddown.c 2004-06-09 07:47:45.000000000 -0500 | ||
1260 | @@ -3,7 +3,7 @@ | ||
1261 | * shut them down. | ||
1262 | * | ||
1263 | */ | ||
1264 | -char *v_hddown = "@(#)hddown.c 1.01 07-Nov-2001 miquels@cistron.nl"; | ||
1265 | +char *v_hddown = "@(#)hddown.c 1.02 22-Apr-2003 miquels@cistron.nl"; | ||
1266 | |||
1267 | #include <stdio.h> | ||
1268 | #include <stdlib.h> | ||
1269 | @@ -13,8 +13,9 @@ | ||
1270 | #include <fcntl.h> | ||
1271 | #include <dirent.h> | ||
1272 | |||
1273 | -#include <sys/ioctl.h> | ||
1274 | +#ifdef __linux__ | ||
1275 | |||
1276 | +#include <sys/ioctl.h> | ||
1277 | #include <linux/hdreg.h> | ||
1278 | |||
1279 | #define MAX_DISKS 64 | ||
1280 | @@ -104,6 +105,15 @@ | ||
1281 | return 0; | ||
1282 | } | ||
1283 | |||
1284 | +#else /* __linux__ */ | ||
1285 | + | ||
1286 | +int hddown(void) | ||
1287 | +{ | ||
1288 | + return 0; | ||
1289 | +} | ||
1290 | + | ||
1291 | +#endif /* __linux__ */ | ||
1292 | + | ||
1293 | #ifdef STANDALONE | ||
1294 | int main(int argc, char **argv) | ||
1295 | { | ||
1296 | Binary files sysvinit-2.85/src/hddown.o and sysvinit-2.86/src/hddown.o differ | ||
1297 | Binary files sysvinit-2.85/src/ifdown.o and sysvinit-2.86/src/ifdown.o differ | ||
1298 | Binary files sysvinit-2.85/src/init and sysvinit-2.86/src/init differ | ||
1299 | diff -urNd -urNd sysvinit-2.85/src/init.c sysvinit-2.86/src/init.c | ||
1300 | --- sysvinit-2.85/src/init.c 2003-04-15 06:16:41.000000000 -0500 | ||
1301 | +++ sysvinit-2.86/src/init.c 2004-07-30 07:16:20.000000000 -0500 | ||
1302 | @@ -5,34 +5,28 @@ | ||
1303 | * init [0123456SsQqAaBbCc] | ||
1304 | * telinit [0123456SsQqAaBbCc] | ||
1305 | * | ||
1306 | - * Version: @(#)init.c 2.85 15-Apr-2003 miquels@cistron.nl | ||
1307 | + * Version: @(#)init.c 2.86 30-Jul-2004 miquels@cistron.nl | ||
1308 | */ | ||
1309 | -#define VERSION "2.85" | ||
1310 | -#define DATE "15-Apr-2003" | ||
1311 | +#define VERSION "2.86" | ||
1312 | +#define DATE "31-Jul-2004" | ||
1313 | /* | ||
1314 | * This file is part of the sysvinit suite, | ||
1315 | - * Copyright 1991-2003 Miquel van Smoorenburg. | ||
1316 | + * Copyright 1991-2004 Miquel van Smoorenburg. | ||
1317 | * | ||
1318 | * This program is free software; you can redistribute it and/or | ||
1319 | * modify it under the terms of the GNU General Public License | ||
1320 | * as published by the Free Software Foundation; either version | ||
1321 | * 2 of the License, or (at your option) any later version. | ||
1322 | * | ||
1323 | - * Modified: 21 Feb 1998, Al Viro: | ||
1324 | - * 'U' flag added to telinit. It forces init to re-exec itself | ||
1325 | - * (passing its state through exec, certainly). | ||
1326 | - * May be useful for smoother (heh) upgrades. | ||
1327 | - * 24 Feb 1998, AV: | ||
1328 | - * did_boot made global and added to state - thanks, Miquel. | ||
1329 | - * Yet another file descriptors leak - close state pipe if | ||
1330 | - * re_exec fails. | ||
1331 | */ | ||
1332 | |||
1333 | #include <sys/types.h> | ||
1334 | #include <sys/stat.h> | ||
1335 | #include <sys/ioctl.h> | ||
1336 | #include <sys/wait.h> | ||
1337 | +#ifdef __linux__ | ||
1338 | #include <sys/kd.h> | ||
1339 | +#endif | ||
1340 | #include <sys/resource.h> | ||
1341 | #include <stdlib.h> | ||
1342 | #include <unistd.h> | ||
1343 | @@ -70,6 +64,13 @@ | ||
1344 | # define SIGPWR SIGUSR2 | ||
1345 | #endif | ||
1346 | |||
1347 | +#ifndef CBAUD | ||
1348 | +# define CBAUD 0 | ||
1349 | +#endif | ||
1350 | +#ifndef CBAUDEX | ||
1351 | +# define CBAUDEX 0 | ||
1352 | +#endif | ||
1353 | + | ||
1354 | /* Set a signal handler. */ | ||
1355 | #define SETSIG(sa, sig, fun, flags) \ | ||
1356 | do { \ | ||
1357 | @@ -88,13 +89,13 @@ | ||
1358 | CHILD *newFamily = NULL; /* The list after inittab re-read */ | ||
1359 | |||
1360 | CHILD ch_emerg = { /* Emergency shell */ | ||
1361 | - 0, 0, 0, 0, 0, | ||
1362 | - "~~", | ||
1363 | - "S", | ||
1364 | - 3, | ||
1365 | - "/sbin/sulogin", | ||
1366 | - NULL, | ||
1367 | - NULL | ||
1368 | + 0, 0, 0, 0, 0, | ||
1369 | + "~~", | ||
1370 | + "S", | ||
1371 | + 3, | ||
1372 | + "/sbin/sulogin", | ||
1373 | + NULL, | ||
1374 | + NULL | ||
1375 | }; | ||
1376 | |||
1377 | char runlevel = 'S'; /* The current run level */ | ||
1378 | @@ -108,8 +109,9 @@ | ||
1379 | int wrote_utmp_reboot = 1; /* Set when we wrote the reboot record */ | ||
1380 | int sltime = 5; /* Sleep time between TERM and KILL */ | ||
1381 | char *argv0; /* First arguments; show up in ps listing */ | ||
1382 | -int maxproclen; /* Maximal length of argv[0] without \0 */ | ||
1383 | +int maxproclen; /* Maximal length of argv[0] with \0 */ | ||
1384 | struct utmp utproto; /* Only used for sizeof(utproto.ut_id) */ | ||
1385 | +char *user_console = NULL; /* User console device */ | ||
1386 | char *console_dev; /* Console device. */ | ||
1387 | int pipe_fd = -1; /* /dev/initctl */ | ||
1388 | int did_boot = 0; /* Did we already do BOOT* stuff? */ | ||
1389 | @@ -186,6 +188,10 @@ | ||
1390 | {NULL,0} | ||
1391 | }; | ||
1392 | |||
1393 | +#define NR_EXTRA_ENV 16 | ||
1394 | +char *extra_env[NR_EXTRA_ENV]; | ||
1395 | + | ||
1396 | + | ||
1397 | /* | ||
1398 | * Sleep a number of seconds. | ||
1399 | * | ||
1400 | @@ -203,6 +209,35 @@ | ||
1401 | ; | ||
1402 | } | ||
1403 | |||
1404 | + | ||
1405 | +/* | ||
1406 | + * Non-failing allocation routines (init cannot fail). | ||
1407 | + */ | ||
1408 | +void *imalloc(size_t size) | ||
1409 | +{ | ||
1410 | + void *m; | ||
1411 | + | ||
1412 | + while ((m = malloc(size)) == NULL) { | ||
1413 | + initlog(L_VB, "out of memory"); | ||
1414 | + do_sleep(5); | ||
1415 | + } | ||
1416 | + memset(m, 0, size); | ||
1417 | + return m; | ||
1418 | +} | ||
1419 | + | ||
1420 | + | ||
1421 | +char *istrdup(char *s) | ||
1422 | +{ | ||
1423 | + char *m; | ||
1424 | + int l; | ||
1425 | + | ||
1426 | + l = strlen(s) + 1; | ||
1427 | + m = imalloc(l); | ||
1428 | + memcpy(m, s, l); | ||
1429 | + return m; | ||
1430 | +} | ||
1431 | + | ||
1432 | + | ||
1433 | /* | ||
1434 | * Send the state info of the previous running init to | ||
1435 | * the new one, in a version-independant way. | ||
1436 | @@ -344,12 +379,9 @@ | ||
1437 | } | ||
1438 | } while (cmd != C_REC); | ||
1439 | |||
1440 | - while ((p = (CHILD *)malloc(sizeof(CHILD))) == NULL ) { | ||
1441 | - log(L_VB, "out of memory"); | ||
1442 | - do_sleep(5); | ||
1443 | - } | ||
1444 | - memset(p, 0, sizeof(CHILD)); | ||
1445 | + p = imalloc(sizeof(CHILD)); | ||
1446 | get_string(p->id, sizeof(p->id), f); | ||
1447 | + | ||
1448 | do switch(cmd = get_cmd(f)) { | ||
1449 | case 0: | ||
1450 | case C_EOR: | ||
1451 | @@ -420,7 +452,7 @@ | ||
1452 | #ifdef __GNUC__ | ||
1453 | __attribute__ ((format (printf, 1, 2))) | ||
1454 | #endif | ||
1455 | -int setproctitle(char *fmt, ...) | ||
1456 | +static int setproctitle(char *fmt, ...) | ||
1457 | { | ||
1458 | va_list ap; | ||
1459 | int len; | ||
1460 | @@ -432,8 +464,10 @@ | ||
1461 | len = vsnprintf(buf, sizeof(buf), fmt, ap); | ||
1462 | va_end(ap); | ||
1463 | |||
1464 | - memset(argv0, 0, maxproclen + 1); | ||
1465 | - strncpy(argv0, buf, maxproclen - 1); | ||
1466 | + if (maxproclen > 2) { | ||
1467 | + memset(argv0, 0, maxproclen); | ||
1468 | + strncpy(argv0, buf, maxproclen - 2); | ||
1469 | + } | ||
1470 | |||
1471 | return len; | ||
1472 | } | ||
1473 | @@ -448,7 +482,9 @@ | ||
1474 | int tried_vtmaster = 0; | ||
1475 | char *s; | ||
1476 | |||
1477 | - if ((s = getenv("CONSOLE")) != NULL) | ||
1478 | + if (user_console) { | ||
1479 | + console_dev = user_console; | ||
1480 | + } else if ((s = getenv("CONSOLE")) != NULL) | ||
1481 | console_dev = s; | ||
1482 | else { | ||
1483 | console_dev = CONSOLE; | ||
1484 | @@ -528,10 +564,9 @@ | ||
1485 | if (errno == ECHILD) break; | ||
1486 | for( ch = family; ch; ch = ch->next ) | ||
1487 | if ( ch->pid == pid && (ch->flags & RUNNING) ) { | ||
1488 | -#if DEBUG | ||
1489 | - log(L_VB, "chld_handler: marked %d as zombie", | ||
1490 | + INITDBG(L_VB, | ||
1491 | + "chld_handler: marked %d as zombie", | ||
1492 | ch->pid); | ||
1493 | -#endif | ||
1494 | ADDSET(got_signals, SIGCHLD); | ||
1495 | ch->exstat = st; | ||
1496 | ch->flags |= ZOMBIE; | ||
1497 | @@ -541,11 +576,9 @@ | ||
1498 | } | ||
1499 | break; | ||
1500 | } | ||
1501 | -#if DEBUG | ||
1502 | if (ch == NULL) | ||
1503 | - log(L_VB, "chld_handler: unknown child %d exited.", | ||
1504 | + INITDBG(L_VB, "chld_handler: unknown child %d exited.", | ||
1505 | pid); | ||
1506 | -#endif | ||
1507 | } | ||
1508 | errno = saved_errno; | ||
1509 | } | ||
1510 | @@ -563,28 +596,34 @@ | ||
1511 | } | ||
1512 | |||
1513 | /* | ||
1514 | - * Dump core. Returns 0 if we are the child, so that the caller | ||
1515 | - * can return if it is a signal handler - SIGSEGV is blocked in | ||
1516 | - * the handler, so it will be raised when the handler returns. | ||
1517 | + * Fork and dump core in /. | ||
1518 | */ | ||
1519 | -int coredump(void) | ||
1520 | +void coredump(void) | ||
1521 | { | ||
1522 | - static int dumped = 0; | ||
1523 | - struct rlimit rlim; | ||
1524 | + static int dumped = 0; | ||
1525 | + struct rlimit rlim; | ||
1526 | + sigset_t mask; | ||
1527 | |||
1528 | - if (dumped) return 1; | ||
1529 | + if (dumped) return; | ||
1530 | dumped = 1; | ||
1531 | |||
1532 | - if (fork() != 0) return 1; | ||
1533 | + if (fork() != 0) return; | ||
1534 | + | ||
1535 | + sigfillset(&mask); | ||
1536 | + sigprocmask(SIG_SETMASK, &mask, NULL); | ||
1537 | |||
1538 | rlim.rlim_cur = RLIM_INFINITY; | ||
1539 | rlim.rlim_max = RLIM_INFINITY; | ||
1540 | setrlimit(RLIMIT_CORE, &rlim); | ||
1541 | - | ||
1542 | chdir("/"); | ||
1543 | + | ||
1544 | signal(SIGSEGV, SIG_DFL); | ||
1545 | raise(SIGSEGV); | ||
1546 | - return 0; | ||
1547 | + sigdelset(&mask, SIGSEGV); | ||
1548 | + sigprocmask(SIG_SETMASK, &mask, NULL); | ||
1549 | + | ||
1550 | + do_sleep(5); | ||
1551 | + exit(0); | ||
1552 | } | ||
1553 | |||
1554 | /* | ||
1555 | @@ -592,7 +631,7 @@ | ||
1556 | * If we have the info, print where it occured. | ||
1557 | * Then sleep 30 seconds and try to continue. | ||
1558 | */ | ||
1559 | -#ifdef STACK_DEBUG | ||
1560 | +#if defined(STACK_DEBUG) && defined(__linux__) | ||
1561 | void segv_handler(int sig, struct sigcontext ctx) | ||
1562 | { | ||
1563 | char *p = ""; | ||
1564 | @@ -601,10 +640,10 @@ | ||
1565 | if ((void *)ctx.eip >= (void *)do_sleep && | ||
1566 | (void *)ctx.eip < (void *)main) | ||
1567 | p = " (code)"; | ||
1568 | - log(L_VB, "PANIC: segmentation violation at %p%s! " | ||
1569 | + initlog(L_VB, "PANIC: segmentation violation at %p%s! " | ||
1570 | "sleeping for 30 seconds.", (void *)ctx.eip, p); | ||
1571 | - if (coredump() != 0) | ||
1572 | - do_sleep(30); | ||
1573 | + coredump(); | ||
1574 | + do_sleep(30); | ||
1575 | errno = saved_errno; | ||
1576 | } | ||
1577 | #else | ||
1578 | @@ -612,9 +651,10 @@ | ||
1579 | { | ||
1580 | int saved_errno = errno; | ||
1581 | |||
1582 | - log(L_VB, "PANIC: segmentation violation! sleeping for 30 seconds."); | ||
1583 | - if (coredump() != 0) | ||
1584 | - do_sleep(30); | ||
1585 | + initlog(L_VB, | ||
1586 | + "PANIC: segmentation violation! sleeping for 30 seconds."); | ||
1587 | + coredump(); | ||
1588 | + do_sleep(30); | ||
1589 | errno = saved_errno; | ||
1590 | } | ||
1591 | #endif | ||
1592 | @@ -641,7 +681,7 @@ | ||
1593 | int fd; | ||
1594 | |||
1595 | if ((fd = console_open(O_RDWR|O_NOCTTY)) < 0) { | ||
1596 | - log(L_VB, "can't open %s", console_dev); | ||
1597 | + initlog(L_VB, "can't open %s", console_dev); | ||
1598 | return; | ||
1599 | } | ||
1600 | |||
1601 | @@ -697,10 +737,11 @@ | ||
1602 | #ifdef __GNUC__ | ||
1603 | __attribute__ ((format (printf, 2, 3))) | ||
1604 | #endif | ||
1605 | -void log(int loglevel, char *s, ...) | ||
1606 | +void initlog(int loglevel, char *s, ...) | ||
1607 | { | ||
1608 | va_list va_alist; | ||
1609 | char buf[256]; | ||
1610 | + sigset_t nmask, omask; | ||
1611 | |||
1612 | va_start(va_alist, s); | ||
1613 | vsnprintf(buf, sizeof(buf), s, va_alist); | ||
1614 | @@ -708,11 +749,15 @@ | ||
1615 | |||
1616 | if (loglevel & L_SY) { | ||
1617 | /* | ||
1618 | - * Re-etablish connection with syslogd every time. | ||
1619 | + * Re-establish connection with syslogd every time. | ||
1620 | + * Block signals while talking to syslog. | ||
1621 | */ | ||
1622 | + sigfillset(&nmask); | ||
1623 | + sigprocmask(SIG_BLOCK, &nmask, &omask); | ||
1624 | openlog("init", 0, LOG_DAEMON); | ||
1625 | syslog(LOG_INFO, "%s", buf); | ||
1626 | closelog(); | ||
1627 | + sigprocmask(SIG_SETMASK, &omask, NULL); | ||
1628 | } | ||
1629 | |||
1630 | /* | ||
1631 | @@ -727,14 +772,51 @@ | ||
1632 | |||
1633 | |||
1634 | /* | ||
1635 | - * See if one character of s2 is in s1 | ||
1636 | + * Build a new environment for execve(). | ||
1637 | */ | ||
1638 | -int any(char *s1, char *s2) | ||
1639 | +char **init_buildenv(int child) | ||
1640 | { | ||
1641 | - while(*s2) | ||
1642 | - if (strchr(s1, *s2++) != NULL) | ||
1643 | - return(1); | ||
1644 | - return(0); | ||
1645 | + char i_lvl[] = "RUNLEVEL=x"; | ||
1646 | + char i_prev[] = "PREVLEVEL=x"; | ||
1647 | + char i_cons[32]; | ||
1648 | + char **e; | ||
1649 | + int n, i; | ||
1650 | + | ||
1651 | + for (n = 0; environ[n]; n++) | ||
1652 | + ; | ||
1653 | + n += NR_EXTRA_ENV + 8; | ||
1654 | + e = calloc(n, sizeof(char *)); | ||
1655 | + | ||
1656 | + for (n = 0; environ[n]; n++) | ||
1657 | + e[n] = istrdup(environ[n]); | ||
1658 | + | ||
1659 | + for (i = 0; i < NR_EXTRA_ENV; i++) | ||
1660 | + if (extra_env[i]) | ||
1661 | + e[n++] = istrdup(extra_env[i]); | ||
1662 | + | ||
1663 | + if (child) { | ||
1664 | + snprintf(i_cons, sizeof(i_cons), "CONSOLE=%s", console_dev); | ||
1665 | + i_lvl[9] = thislevel; | ||
1666 | + i_prev[10] = prevlevel; | ||
1667 | + e[n++] = istrdup(i_lvl); | ||
1668 | + e[n++] = istrdup(i_prev); | ||
1669 | + e[n++] = istrdup(i_cons); | ||
1670 | + e[n++] = istrdup(E_VERSION); | ||
1671 | + } | ||
1672 | + | ||
1673 | + e[n++] = NULL; | ||
1674 | + | ||
1675 | + return e; | ||
1676 | +} | ||
1677 | + | ||
1678 | + | ||
1679 | +void init_freeenv(char **e) | ||
1680 | +{ | ||
1681 | + int n; | ||
1682 | + | ||
1683 | + for (n = 0; e[n]; n++) | ||
1684 | + free(e[n]); | ||
1685 | + free(e); | ||
1686 | } | ||
1687 | |||
1688 | |||
1689 | @@ -753,9 +835,6 @@ | ||
1690 | time_t t; /* System time */ | ||
1691 | int oldAlarm; /* Previous alarm value */ | ||
1692 | char *proc = ch->process; /* Command line */ | ||
1693 | - char i_lvl[] = "RUNLEVEL=x"; /* Runlevel in environment. */ | ||
1694 | - char i_prev[] = "PREVLEVEL=x";/* Previous runlevel. */ | ||
1695 | - char i_cons[32]; /* console device. */ | ||
1696 | pid_t pid, pgrp; /* child, console process group. */ | ||
1697 | sigset_t nmask, omask; /* For blocking SIGCHLD */ | ||
1698 | struct sigaction sa; | ||
1699 | @@ -781,8 +860,9 @@ | ||
1700 | /* Do we try to respawn too fast? */ | ||
1701 | if (ch->count >= MAXSPAWN) { | ||
1702 | |||
1703 | - log(L_VB, "Id \"%s\" respawning too fast: disabled for %d minutes", | ||
1704 | - ch->id, SLEEPTIME / 60); | ||
1705 | + initlog(L_VB, | ||
1706 | + "Id \"%s\" respawning too fast: disabled for %d minutes", | ||
1707 | + ch->id, SLEEPTIME / 60); | ||
1708 | ch->flags &= ~RUNNING; | ||
1709 | ch->flags |= FAILING; | ||
1710 | |||
1711 | @@ -813,7 +893,7 @@ | ||
1712 | } | ||
1713 | args[6] = proc; | ||
1714 | args[7] = NULL; | ||
1715 | - } else if (any(proc, "~`!$^&*()=|\\{}[];\"'<>?")) { | ||
1716 | + } else if (strpbrk(proc, "~`!$^&*()=|\\{}[];\"'<>?")) { | ||
1717 | /* See if we need to fire off a shell for this command */ | ||
1718 | /* Give command line to shell */ | ||
1719 | args[1] = SHELL; | ||
1720 | @@ -868,15 +948,6 @@ | ||
1721 | |||
1722 | sigprocmask(SIG_SETMASK, &omask, NULL); | ||
1723 | |||
1724 | - /* Now set RUNLEVEL and PREVLEVEL */ | ||
1725 | - snprintf(i_cons, sizeof(i_cons), "CONSOLE=%s", console_dev); | ||
1726 | - i_lvl[9] = thislevel; | ||
1727 | - i_prev[10] = prevlevel; | ||
1728 | - putenv(i_lvl); | ||
1729 | - putenv(i_prev); | ||
1730 | - putenv(i_cons); | ||
1731 | - putenv(E_VERSION); | ||
1732 | - | ||
1733 | /* | ||
1734 | * In sysinit, boot, bootwait or single user mode: | ||
1735 | * for any wait-type subprocess we _force_ the console | ||
1736 | @@ -896,7 +967,7 @@ | ||
1737 | dup(f); | ||
1738 | } | ||
1739 | if ((pid = fork()) < 0) { | ||
1740 | - log(L_VB, "cannot fork"); | ||
1741 | + initlog(L_VB, "cannot fork"); | ||
1742 | exit(1); | ||
1743 | } | ||
1744 | if (pid > 0) { | ||
1745 | @@ -926,7 +997,7 @@ | ||
1746 | * this with a temporary process. | ||
1747 | */ | ||
1748 | if ((pid = fork()) < 0) { | ||
1749 | - log(L_VB, "cannot fork"); | ||
1750 | + initlog(L_VB, "cannot fork"); | ||
1751 | exit(1); | ||
1752 | } | ||
1753 | if (pid == 0) { | ||
1754 | @@ -946,7 +1017,7 @@ | ||
1755 | } else { | ||
1756 | setsid(); | ||
1757 | if ((f = console_open(O_RDWR|O_NOCTTY)) < 0) { | ||
1758 | - log(L_VB, "open(%s): %s", console_dev, | ||
1759 | + initlog(L_VB, "open(%s): %s", console_dev, | ||
1760 | strerror(errno)); | ||
1761 | f = open("/dev/null", O_RDWR); | ||
1762 | } | ||
1763 | @@ -954,15 +1025,15 @@ | ||
1764 | dup(f); | ||
1765 | } | ||
1766 | |||
1767 | - /* Reset all the signals */ | ||
1768 | + /* Reset all the signals, set up environment */ | ||
1769 | for(f = 1; f < NSIG; f++) SETSIG(sa, f, SIG_DFL, SA_RESTART); | ||
1770 | - execvp(args[1], args + 1); | ||
1771 | + environ = init_buildenv(1); | ||
1772 | |||
1773 | /* | ||
1774 | - * Is this a bug in execvp? It does _not_ execute shell | ||
1775 | - * scripts (/etc/rc !), so we try again with | ||
1776 | - * 'sh -c exec ...' | ||
1777 | + * Execute prog. In case of ENOEXEC try again | ||
1778 | + * as a shell script. | ||
1779 | */ | ||
1780 | + execvp(args[1], args + 1); | ||
1781 | if (errno == ENOEXEC) { | ||
1782 | args[1] = SHELL; | ||
1783 | args[2] = "-c"; | ||
1784 | @@ -972,18 +1043,16 @@ | ||
1785 | args[4] = NULL; | ||
1786 | execvp(args[1], args + 1); | ||
1787 | } | ||
1788 | - log(L_VB, "cannot execute \"%s\"", args[1]); | ||
1789 | + initlog(L_VB, "cannot execute \"%s\"", args[1]); | ||
1790 | exit(1); | ||
1791 | } | ||
1792 | *res = pid; | ||
1793 | sigprocmask(SIG_SETMASK, &omask, NULL); | ||
1794 | |||
1795 | -#if DEBUG | ||
1796 | - log(L_VB, "Started id %s (pid %d)", ch->id, pid); | ||
1797 | -#endif | ||
1798 | + INITDBG(L_VB, "Started id %s (pid %d)", ch->id, pid); | ||
1799 | |||
1800 | if (pid == -1) { | ||
1801 | - log(L_VB, "cannot fork, retry.."); | ||
1802 | + initlog(L_VB, "cannot fork, retry.."); | ||
1803 | do_sleep(5); | ||
1804 | continue; | ||
1805 | } | ||
1806 | @@ -1032,66 +1101,45 @@ | ||
1807 | } | ||
1808 | } | ||
1809 | |||
1810 | -/* | ||
1811 | - * My version of strtok(3). | ||
1812 | - */ | ||
1813 | -char *get_part(char *str, int tok) | ||
1814 | -{ | ||
1815 | - static char *s; | ||
1816 | - char *p, *q; | ||
1817 | - | ||
1818 | - if (str != NULL) | ||
1819 | - s = str; | ||
1820 | - if (s == NULL || *s == 0) | ||
1821 | - return(NULL); | ||
1822 | - q = p = s; | ||
1823 | - while(*p != tok && *p) | ||
1824 | - p++; | ||
1825 | - if (*p == tok) | ||
1826 | - *p++ = 0; | ||
1827 | - s = p; | ||
1828 | - | ||
1829 | - return q; | ||
1830 | -} | ||
1831 | |||
1832 | /* | ||
1833 | * Read the inittab file. | ||
1834 | */ | ||
1835 | void read_inittab(void) | ||
1836 | { | ||
1837 | - FILE *fp; /* The INITTAB file */ | ||
1838 | - char buf[256]; /* Line buffer */ | ||
1839 | - char err[64]; /* Error message. */ | ||
1840 | - char *id, *rlevel, | ||
1841 | - *action, *process; /* Fields of a line */ | ||
1842 | - char *p; | ||
1843 | - CHILD *ch, *old, *i; /* Pointers to CHILD structure */ | ||
1844 | - CHILD *head = NULL; /* Head of linked list */ | ||
1845 | - int lineNo = 0; /* Line number in INITTAB file */ | ||
1846 | - int actionNo; /* Decoded action field */ | ||
1847 | - int f; /* Counter */ | ||
1848 | - int round; /* round 0 for SIGTERM, round 1 for SIGKILL */ | ||
1849 | - int foundOne = 0; /* No killing no sleep */ | ||
1850 | - int talk; /* Talk to the user */ | ||
1851 | - int done = 0; /* Ready yet? */ | ||
1852 | - sigset_t nmask, omask; /* For blocking SIGCHLD. */ | ||
1853 | + FILE *fp; /* The INITTAB file */ | ||
1854 | + CHILD *ch, *old, *i; /* Pointers to CHILD structure */ | ||
1855 | + CHILD *head = NULL; /* Head of linked list */ | ||
1856 | #ifdef INITLVL | ||
1857 | - struct stat st; /* To stat INITLVL */ | ||
1858 | + struct stat st; /* To stat INITLVL */ | ||
1859 | #endif | ||
1860 | + sigset_t nmask, omask; /* For blocking SIGCHLD. */ | ||
1861 | + char buf[256]; /* Line buffer */ | ||
1862 | + char err[64]; /* Error message. */ | ||
1863 | + char *id, *rlevel, | ||
1864 | + *action, *process; /* Fields of a line */ | ||
1865 | + char *p; | ||
1866 | + int lineNo = 0; /* Line number in INITTAB file */ | ||
1867 | + int actionNo; /* Decoded action field */ | ||
1868 | + int f; /* Counter */ | ||
1869 | + int round; /* round 0 for SIGTERM, 1 for SIGKILL */ | ||
1870 | + int foundOne = 0; /* No killing no sleep */ | ||
1871 | + int talk; /* Talk to the user */ | ||
1872 | + int done = 0; /* Ready yet? */ | ||
1873 | |||
1874 | #if DEBUG | ||
1875 | if (newFamily != NULL) { | ||
1876 | - log(L_VB, "PANIC newFamily != NULL"); | ||
1877 | + INITDBG(L_VB, "PANIC newFamily != NULL"); | ||
1878 | exit(1); | ||
1879 | } | ||
1880 | - log(L_VB, "Reading inittab"); | ||
1881 | + INITDBG(L_VB, "Reading inittab"); | ||
1882 | #endif | ||
1883 | |||
1884 | /* | ||
1885 | * Open INITTAB and real line by line. | ||
1886 | */ | ||
1887 | if ((fp = fopen(INITTAB, "r")) == NULL) | ||
1888 | - log(L_VB, "No inittab file found"); | ||
1889 | + initlog(L_VB, "No inittab file found"); | ||
1890 | |||
1891 | while(!done) { | ||
1892 | /* | ||
1893 | @@ -1103,9 +1151,9 @@ | ||
1894 | * See if we have a single user entry. | ||
1895 | */ | ||
1896 | for(old = newFamily; old; old = old->next) | ||
1897 | - if (strcmp(old->rlevel, "S") == 0) break; | ||
1898 | + if (strpbrk(old->rlevel, "S")) break; | ||
1899 | if (old == NULL) | ||
1900 | - snprintf(buf, sizeof(buf), "~~:S:wait:%s\n", SHELL); | ||
1901 | + snprintf(buf, sizeof(buf), "~~:S:wait:%s\n", SULOGIN); | ||
1902 | else | ||
1903 | continue; | ||
1904 | } | ||
1905 | @@ -1120,10 +1168,10 @@ | ||
1906 | /* | ||
1907 | * Decode the fields | ||
1908 | */ | ||
1909 | - id = get_part(p, ':'); | ||
1910 | - rlevel = get_part(NULL, ':'); | ||
1911 | - action = get_part(NULL, ':'); | ||
1912 | - process = get_part(NULL, '\n'); | ||
1913 | + id = strsep(&p, ":"); | ||
1914 | + rlevel = strsep(&p, ":"); | ||
1915 | + action = strsep(&p, ":"); | ||
1916 | + process = strsep(&p, "\n"); | ||
1917 | |||
1918 | /* | ||
1919 | * Check if syntax is OK. Be very verbose here, to | ||
1920 | @@ -1145,10 +1193,8 @@ | ||
1921 | if (action && strlen(action) > 32) | ||
1922 | strcpy(err, "action field too long"); | ||
1923 | if (err[0] != 0) { | ||
1924 | - log(L_VB, "%s[%d]: %s", INITTAB, lineNo, err); | ||
1925 | -#if DEBUG | ||
1926 | - log(L_VB, "%s:%s:%s:%s", id, rlevel, action, process); | ||
1927 | -#endif | ||
1928 | + initlog(L_VB, "%s[%d]: %s", INITTAB, lineNo, err); | ||
1929 | + INITDBG(L_VB, "%s:%s:%s:%s", id, rlevel, action, process); | ||
1930 | continue; | ||
1931 | } | ||
1932 | |||
1933 | @@ -1162,7 +1208,7 @@ | ||
1934 | break; | ||
1935 | } | ||
1936 | if (actionNo == -1) { | ||
1937 | - log(L_VB, "%s[%d]: %s: unknown action field", | ||
1938 | + initlog(L_VB, "%s[%d]: %s: unknown action field", | ||
1939 | INITTAB, lineNo, action); | ||
1940 | continue; | ||
1941 | } | ||
1942 | @@ -1172,7 +1218,7 @@ | ||
1943 | */ | ||
1944 | for(old = newFamily; old; old = old->next) { | ||
1945 | if(strcmp(old->id, id) == 0 && strcmp(id, "~~")) { | ||
1946 | - log(L_VB, "%s[%d]: duplicate ID field \"%s\"", | ||
1947 | + initlog(L_VB, "%s[%d]: duplicate ID field \"%s\"", | ||
1948 | INITTAB, lineNo, id); | ||
1949 | break; | ||
1950 | } | ||
1951 | @@ -1182,11 +1228,7 @@ | ||
1952 | /* | ||
1953 | * Allocate a CHILD structure | ||
1954 | */ | ||
1955 | - while ((ch = malloc(sizeof(CHILD))) == NULL) { | ||
1956 | - log(L_VB, "out of memory"); | ||
1957 | - do_sleep(5); | ||
1958 | - } | ||
1959 | - memset(ch, 0, sizeof(CHILD)); | ||
1960 | + ch = imalloc(sizeof(CHILD)); | ||
1961 | |||
1962 | /* | ||
1963 | * And fill it in. | ||
1964 | @@ -1275,9 +1317,7 @@ | ||
1965 | * be killed. | ||
1966 | */ | ||
1967 | |||
1968 | -#if DEBUG | ||
1969 | - log(L_VB, "Checking for children to kill"); | ||
1970 | -#endif | ||
1971 | + INITDBG(L_VB, "Checking for children to kill"); | ||
1972 | for(round = 0; round < 2; round++) { | ||
1973 | talk = 1; | ||
1974 | for(ch = family; ch; ch = ch->next) { | ||
1975 | @@ -1328,19 +1368,19 @@ | ||
1976 | ch->flags &= ~KILLME; | ||
1977 | continue; | ||
1978 | } | ||
1979 | -#if DEBUG | ||
1980 | - log(L_VB, "Killing \"%s\"", ch->process); | ||
1981 | -#endif | ||
1982 | + INITDBG(L_VB, "Killing \"%s\"", ch->process); | ||
1983 | switch(round) { | ||
1984 | case 0: /* Send TERM signal */ | ||
1985 | if (talk) | ||
1986 | - log(L_CO, "Sending processes the TERM signal"); | ||
1987 | + initlog(L_CO, | ||
1988 | + "Sending processes the TERM signal"); | ||
1989 | kill(-(ch->pid), SIGTERM); | ||
1990 | foundOne = 1; | ||
1991 | break; | ||
1992 | case 1: /* Send KILL signal and collect status */ | ||
1993 | if (talk) | ||
1994 | - log(L_CO, "Sending processes the KILL signal"); | ||
1995 | + initlog(L_CO, | ||
1996 | + "Sending processes the KILL signal"); | ||
1997 | kill(-(ch->pid), SIGKILL); | ||
1998 | break; | ||
1999 | } | ||
2000 | @@ -1380,12 +1420,11 @@ | ||
2001 | for(ch = family; ch; ch = ch->next) | ||
2002 | if (ch->flags & KILLME) { | ||
2003 | if (!(ch->flags & ZOMBIE)) | ||
2004 | - log(L_CO, "Pid %d [id %s] seems to hang", ch->pid, | ||
2005 | + initlog(L_CO, "Pid %d [id %s] seems to hang", ch->pid, | ||
2006 | ch->id); | ||
2007 | else { | ||
2008 | -#if DEBUG | ||
2009 | - log(L_VB, "Updating utmp for pid %d [id %s]", ch->pid, ch->id); | ||
2010 | -#endif | ||
2011 | + INITDBG(L_VB, "Updating utmp for pid %d [id %s]", | ||
2012 | + ch->pid, ch->id); | ||
2013 | ch->flags &= ~RUNNING; | ||
2014 | if (ch->process[0] != '+') | ||
2015 | write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL); | ||
2016 | @@ -1451,15 +1490,13 @@ | ||
2017 | CHILD *ch; /* Pointer to child */ | ||
2018 | int delete; /* Delete this entry from list? */ | ||
2019 | |||
2020 | -#if DEBUG | ||
2021 | - log(L_VB, "Checking for children to start"); | ||
2022 | -#endif | ||
2023 | + INITDBG(L_VB, "Checking for children to start"); | ||
2024 | |||
2025 | for(ch = family; ch; ch = ch->next) { | ||
2026 | |||
2027 | #if DEBUG | ||
2028 | if (ch->rlevel[0] == 'C') { | ||
2029 | - log(L_VB, "%s: flags %d", ch->process, ch->flags); | ||
2030 | + INITDBG(L_VB, "%s: flags %d", ch->process, ch->flags); | ||
2031 | } | ||
2032 | #endif | ||
2033 | |||
2034 | @@ -1545,7 +1582,8 @@ | ||
2035 | if (lvl > 0) { | ||
2036 | if (islower(lvl)) lvl = toupper(lvl); | ||
2037 | if (strchr("0123456789S", lvl) == NULL) { | ||
2038 | - log(L_VB, "Initdefault level '%c' is invalid", lvl); | ||
2039 | + initlog(L_VB, | ||
2040 | + "Initdefault level '%c' is invalid", lvl); | ||
2041 | lvl = 0; | ||
2042 | } | ||
2043 | } | ||
2044 | @@ -1570,98 +1608,99 @@ | ||
2045 | */ | ||
2046 | int read_level(int arg) | ||
2047 | { | ||
2048 | - unsigned char foo = 'X'; /* Contents of INITLVL */ | ||
2049 | - CHILD *ch; /* Walk through list */ | ||
2050 | - int ok = 1; | ||
2051 | + CHILD *ch; /* Walk through list */ | ||
2052 | + unsigned char foo = 'X'; /* Contents of INITLVL */ | ||
2053 | + int ok = 1; | ||
2054 | #ifdef INITLVL | ||
2055 | - FILE *fp; | ||
2056 | - int st; | ||
2057 | - struct stat stt; | ||
2058 | + FILE *fp; | ||
2059 | + struct stat stt; | ||
2060 | + int st; | ||
2061 | #endif | ||
2062 | |||
2063 | - if (arg) foo = arg; | ||
2064 | + if (arg) foo = arg; | ||
2065 | |||
2066 | #ifdef INITLVL | ||
2067 | - ok = 0; | ||
2068 | + ok = 0; | ||
2069 | |||
2070 | - if (arg == 0) { | ||
2071 | - fp = NULL; | ||
2072 | - if (stat(INITLVL, &stt) != 0 || stt.st_size != 0L) | ||
2073 | - fp = fopen(INITLVL, "r"); | ||
2074 | + if (arg == 0) { | ||
2075 | + fp = NULL; | ||
2076 | + if (stat(INITLVL, &stt) != 0 || stt.st_size != 0L) | ||
2077 | + fp = fopen(INITLVL, "r"); | ||
2078 | #ifdef INITLVL2 | ||
2079 | - if (fp == NULL && (stat(INITLVL2, &stt) != 0 || stt.st_size != 0L)) | ||
2080 | - fp = fopen(INITLVL2, "r"); | ||
2081 | + if (fp == NULL && | ||
2082 | + (stat(INITLVL2, &stt) != 0 || stt.st_size != 0L)) | ||
2083 | + fp = fopen(INITLVL2, "r"); | ||
2084 | #endif | ||
2085 | - if (fp == NULL) { | ||
2086 | - /* INITLVL file is empty or not there - act as 'init q' */ | ||
2087 | - log(L_SY, "Re-reading inittab"); | ||
2088 | - return(runlevel); | ||
2089 | + if (fp == NULL) { | ||
2090 | + /* INITLVL file empty or not there - act as 'init q' */ | ||
2091 | + initlog(L_SY, "Re-reading inittab"); | ||
2092 | + return(runlevel); | ||
2093 | + } | ||
2094 | + ok = fscanf(fp, "%c %d", &foo, &st); | ||
2095 | + fclose(fp); | ||
2096 | + } else { | ||
2097 | + /* We go to the new runlevel passed as an argument. */ | ||
2098 | + foo = arg; | ||
2099 | + ok = 1; | ||
2100 | } | ||
2101 | - ok = fscanf(fp, "%c %d", &foo, &st); | ||
2102 | - fclose(fp); | ||
2103 | - } else { | ||
2104 | - /* We go to the new runlevel passed as an argument. */ | ||
2105 | - foo = arg; | ||
2106 | - ok = 1; | ||
2107 | - } | ||
2108 | - if (ok == 2) sltime = st; | ||
2109 | + if (ok == 2) sltime = st; | ||
2110 | |||
2111 | #endif /* INITLVL */ | ||
2112 | |||
2113 | - if (islower(foo)) foo = toupper(foo); | ||
2114 | - if (ok < 1 || ok > 2 || strchr("QS0123456789ABCU", foo) == NULL) { | ||
2115 | - log(L_VB, "bad runlevel: %c", foo); | ||
2116 | - return(runlevel); | ||
2117 | - } | ||
2118 | + if (islower(foo)) foo = toupper(foo); | ||
2119 | + if (ok < 1 || ok > 2 || strchr("QS0123456789ABCU", foo) == NULL) { | ||
2120 | + initlog(L_VB, "bad runlevel: %c", foo); | ||
2121 | + return runlevel; | ||
2122 | + } | ||
2123 | |||
2124 | - /* Log this action */ | ||
2125 | - switch(foo) { | ||
2126 | - case 'S': | ||
2127 | - log(L_VB, "Going single user"); | ||
2128 | - break; | ||
2129 | - case 'Q': | ||
2130 | - log(L_SY, "Re-reading inittab"); | ||
2131 | - break; | ||
2132 | - case 'A': | ||
2133 | - case 'B': | ||
2134 | - case 'C': | ||
2135 | - log(L_SY, "Activating demand-procedures for '%c'", foo); | ||
2136 | - break; | ||
2137 | - case 'U': | ||
2138 | - log(L_SY, "Trying to re-exec init"); | ||
2139 | - return 'U'; | ||
2140 | - default: | ||
2141 | - log(L_VB, "Switching to runlevel: %c", foo); | ||
2142 | - } | ||
2143 | + /* Log this action */ | ||
2144 | + switch(foo) { | ||
2145 | + case 'S': | ||
2146 | + initlog(L_VB, "Going single user"); | ||
2147 | + break; | ||
2148 | + case 'Q': | ||
2149 | + initlog(L_SY, "Re-reading inittab"); | ||
2150 | + break; | ||
2151 | + case 'A': | ||
2152 | + case 'B': | ||
2153 | + case 'C': | ||
2154 | + initlog(L_SY, | ||
2155 | + "Activating demand-procedures for '%c'", foo); | ||
2156 | + break; | ||
2157 | + case 'U': | ||
2158 | + initlog(L_SY, "Trying to re-exec init"); | ||
2159 | + return 'U'; | ||
2160 | + default: | ||
2161 | + initlog(L_VB, "Switching to runlevel: %c", foo); | ||
2162 | + } | ||
2163 | |||
2164 | - if (foo == 'Q') return(runlevel); | ||
2165 | + if (foo == 'Q') return runlevel; | ||
2166 | |||
2167 | - /* Check if this is a runlevel a, b or c */ | ||
2168 | - if (strchr("ABC", foo)) { | ||
2169 | - if (runlevel == 'S') return(runlevel); | ||
2170 | + /* Check if this is a runlevel a, b or c */ | ||
2171 | + if (strchr("ABC", foo)) { | ||
2172 | + if (runlevel == 'S') return(runlevel); | ||
2173 | |||
2174 | - /* Read inittab again first! */ | ||
2175 | - read_inittab(); | ||
2176 | + /* Read inittab again first! */ | ||
2177 | + read_inittab(); | ||
2178 | |||
2179 | - /* Mark those special tasks */ | ||
2180 | - for(ch = family; ch; ch = ch->next) | ||
2181 | - if (strchr(ch->rlevel, foo) != NULL || | ||
2182 | - strchr(ch->rlevel, tolower(foo)) != NULL) { | ||
2183 | - ch->flags |= DEMAND; | ||
2184 | - ch->flags &= ~XECUTED; | ||
2185 | -#if DEBUG | ||
2186 | - log(L_VB, "Marking (%s) as ondemand, flags %d", | ||
2187 | - ch->id, ch->flags); | ||
2188 | -#endif | ||
2189 | - } | ||
2190 | - return(runlevel); | ||
2191 | - } | ||
2192 | + /* Mark those special tasks */ | ||
2193 | + for(ch = family; ch; ch = ch->next) | ||
2194 | + if (strchr(ch->rlevel, foo) != NULL || | ||
2195 | + strchr(ch->rlevel, tolower(foo)) != NULL) { | ||
2196 | + ch->flags |= DEMAND; | ||
2197 | + ch->flags &= ~XECUTED; | ||
2198 | + INITDBG(L_VB, | ||
2199 | + "Marking (%s) as ondemand, flags %d", | ||
2200 | + ch->id, ch->flags); | ||
2201 | + } | ||
2202 | + return runlevel; | ||
2203 | + } | ||
2204 | |||
2205 | - /* Store both the old and the new runlevel. */ | ||
2206 | - write_utmp_wtmp("runlevel", "~~", foo + 256*runlevel, RUN_LVL, "~"); | ||
2207 | - thislevel = foo; | ||
2208 | - prevlevel = runlevel; | ||
2209 | - return(foo); | ||
2210 | + /* Store both the old and the new runlevel. */ | ||
2211 | + write_utmp_wtmp("runlevel", "~~", foo + 256*runlevel, RUN_LVL, "~"); | ||
2212 | + thislevel = foo; | ||
2213 | + prevlevel = runlevel; | ||
2214 | + return foo; | ||
2215 | } | ||
2216 | |||
2217 | |||
2218 | @@ -1674,32 +1713,33 @@ | ||
2219 | */ | ||
2220 | void fail_check(void) | ||
2221 | { | ||
2222 | - time_t t; /* System time */ | ||
2223 | - CHILD *ch; /* Pointer to child structure */ | ||
2224 | - time_t next_alarm = 0; /* When to set next alarm */ | ||
2225 | + CHILD *ch; /* Pointer to child structure */ | ||
2226 | + time_t t; /* System time */ | ||
2227 | + time_t next_alarm = 0; /* When to set next alarm */ | ||
2228 | |||
2229 | - time(&t); | ||
2230 | + time(&t); | ||
2231 | |||
2232 | - for(ch = family; ch; ch = ch->next) { | ||
2233 | + for(ch = family; ch; ch = ch->next) { | ||
2234 | |||
2235 | - if (ch->flags & FAILING) { | ||
2236 | - /* Can we free this sucker? */ | ||
2237 | - if (ch->tm + SLEEPTIME < t) { | ||
2238 | - ch->flags &= ~FAILING; | ||
2239 | - ch->count = 0; | ||
2240 | - ch->tm = 0; | ||
2241 | - } else { | ||
2242 | - /* No, we'll look again later */ | ||
2243 | - if (next_alarm == 0 || ch->tm + SLEEPTIME > next_alarm) | ||
2244 | - next_alarm = ch->tm + SLEEPTIME; | ||
2245 | + if (ch->flags & FAILING) { | ||
2246 | + /* Can we free this sucker? */ | ||
2247 | + if (ch->tm + SLEEPTIME < t) { | ||
2248 | + ch->flags &= ~FAILING; | ||
2249 | + ch->count = 0; | ||
2250 | + ch->tm = 0; | ||
2251 | + } else { | ||
2252 | + /* No, we'll look again later */ | ||
2253 | + if (next_alarm == 0 || | ||
2254 | + ch->tm + SLEEPTIME > next_alarm) | ||
2255 | + next_alarm = ch->tm + SLEEPTIME; | ||
2256 | + } | ||
2257 | } | ||
2258 | } | ||
2259 | - } | ||
2260 | - if (next_alarm) { | ||
2261 | - next_alarm -= t; | ||
2262 | - if (next_alarm < 1) next_alarm = 1; | ||
2263 | - alarm(next_alarm); | ||
2264 | - } | ||
2265 | + if (next_alarm) { | ||
2266 | + next_alarm -= t; | ||
2267 | + if (next_alarm < 1) next_alarm = 1; | ||
2268 | + alarm(next_alarm); | ||
2269 | + } | ||
2270 | } | ||
2271 | |||
2272 | /* Set all 'Fail' timers to 0 */ | ||
2273 | @@ -1752,9 +1792,9 @@ | ||
2274 | */ | ||
2275 | int check_pipe(int fd) | ||
2276 | { | ||
2277 | - struct timeval t; | ||
2278 | - fd_set s; | ||
2279 | - char signature[8]; | ||
2280 | + struct timeval t; | ||
2281 | + fd_set s; | ||
2282 | + char signature[8]; | ||
2283 | |||
2284 | FD_ZERO(&s); | ||
2285 | FD_SET(fd, &s); | ||
2286 | @@ -1789,10 +1829,11 @@ | ||
2287 | */ | ||
2288 | void re_exec(void) | ||
2289 | { | ||
2290 | - sigset_t mask, oldset; | ||
2291 | - pid_t pid; | ||
2292 | - int fd; | ||
2293 | - CHILD *ch; | ||
2294 | + CHILD *ch; | ||
2295 | + sigset_t mask, oldset; | ||
2296 | + pid_t pid; | ||
2297 | + char **env; | ||
2298 | + int fd; | ||
2299 | |||
2300 | if (strchr("S12345",runlevel) == NULL) | ||
2301 | return; | ||
2302 | @@ -1825,27 +1866,26 @@ | ||
2303 | */ | ||
2304 | for(ch = family; ch; ch = ch->next) | ||
2305 | if (ch->flags & ZOMBIE) { | ||
2306 | -#if DEBUG | ||
2307 | - log(L_VB, "Child died, PID= %d", ch->pid); | ||
2308 | -#endif | ||
2309 | + INITDBG(L_VB, "Child died, PID= %d", ch->pid); | ||
2310 | ch->flags &= ~(RUNNING|ZOMBIE|WAITING); | ||
2311 | if (ch->process[0] != '+') | ||
2312 | write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL); | ||
2313 | } | ||
2314 | |||
2315 | - if ((pid = fork()) > 0) { | ||
2316 | - /* | ||
2317 | - * Yup. _Parent_ exec's ... | ||
2318 | - */ | ||
2319 | - execl(myname, myname, "--init", NULL); | ||
2320 | - } else if (pid == 0) { | ||
2321 | + if ((pid = fork()) == 0) { | ||
2322 | /* | ||
2323 | - * ... while child sends her the | ||
2324 | - * state information and dies | ||
2325 | + * Child sends state information to the parent. | ||
2326 | */ | ||
2327 | send_state(fd); | ||
2328 | exit(0); | ||
2329 | } | ||
2330 | + | ||
2331 | + /* | ||
2332 | + * The existing init process execs a new init binary. | ||
2333 | + */ | ||
2334 | + env = init_buildenv(0); | ||
2335 | + execl(myname, myname, "--init", NULL, env); | ||
2336 | + | ||
2337 | /* | ||
2338 | * We shouldn't be here, something failed. | ||
2339 | * Bitch, close the state pipe, unblock signals and return. | ||
2340 | @@ -1853,7 +1893,8 @@ | ||
2341 | close(fd); | ||
2342 | close(STATE_PIPE); | ||
2343 | sigprocmask(SIG_SETMASK, &oldset, NULL); | ||
2344 | - log(L_CO, "Attempt to re-exec failed"); | ||
2345 | + init_freeenv(env); | ||
2346 | + initlog(L_CO, "Attempt to re-exec failed"); | ||
2347 | } | ||
2348 | |||
2349 | |||
2350 | @@ -1863,10 +1904,10 @@ | ||
2351 | */ | ||
2352 | void fifo_new_level(int level) | ||
2353 | { | ||
2354 | - int oldlevel; | ||
2355 | #if CHANGE_WAIT | ||
2356 | - CHILD *ch; | ||
2357 | + CHILD *ch; | ||
2358 | #endif | ||
2359 | + int oldlevel; | ||
2360 | |||
2361 | if (level == runlevel) return; | ||
2362 | |||
2363 | @@ -1894,6 +1935,59 @@ | ||
2364 | } | ||
2365 | } | ||
2366 | |||
2367 | + | ||
2368 | +/* | ||
2369 | + * Set/unset environment variables. The variables are | ||
2370 | + * encoded as KEY=VAL\0KEY=VAL\0\0. With "=VAL" it means | ||
2371 | + * setenv, without it means unsetenv. | ||
2372 | + */ | ||
2373 | +void initcmd_setenv(char *data, int size) | ||
2374 | +{ | ||
2375 | + char *env, *p, *e, *eq; | ||
2376 | + int i, sz; | ||
2377 | + | ||
2378 | + e = data + size; | ||
2379 | + | ||
2380 | + while (*data && data < e) { | ||
2381 | + eq = NULL; | ||
2382 | + for (p = data; *p && p < e; p++) | ||
2383 | + if (*p == '=') eq = p; | ||
2384 | + if (*p) break; | ||
2385 | + env = data; | ||
2386 | + data = ++p; | ||
2387 | + | ||
2388 | + sz = eq ? (eq - env) : (p - env); | ||
2389 | + | ||
2390 | + /*initlog(L_SY, "init_setenv: %s, %s, %d", env, eq, sz);*/ | ||
2391 | + | ||
2392 | + /* | ||
2393 | + * We only allow INIT_* to be set. | ||
2394 | + */ | ||
2395 | + if (strncmp(env, "INIT_", 5) != 0) | ||
2396 | + continue; | ||
2397 | + | ||
2398 | + /* Free existing vars. */ | ||
2399 | + for (i = 0; i < NR_EXTRA_ENV; i++) { | ||
2400 | + if (extra_env[i] == NULL) continue; | ||
2401 | + if (!strncmp(extra_env[i], env, sz) && | ||
2402 | + extra_env[i][sz] == '=') { | ||
2403 | + free(extra_env[i]); | ||
2404 | + extra_env[i] = NULL; | ||
2405 | + } | ||
2406 | + } | ||
2407 | + | ||
2408 | + /* Set new vars if needed. */ | ||
2409 | + if (eq == NULL) continue; | ||
2410 | + for (i = 0; i < NR_EXTRA_ENV; i++) { | ||
2411 | + if (extra_env[i] == NULL) { | ||
2412 | + extra_env[i] = istrdup(env); | ||
2413 | + break; | ||
2414 | + } | ||
2415 | + } | ||
2416 | + } | ||
2417 | +} | ||
2418 | + | ||
2419 | + | ||
2420 | /* | ||
2421 | * Read from the init FIFO. Processes like telnetd and rlogind can | ||
2422 | * ask us to create login processes on their behalf. | ||
2423 | @@ -1906,12 +2000,12 @@ | ||
2424 | */ | ||
2425 | void check_init_fifo(void) | ||
2426 | { | ||
2427 | - struct init_request request; | ||
2428 | - int n; | ||
2429 | - fd_set fds; | ||
2430 | - int quit = 0; | ||
2431 | - struct stat st, st2; | ||
2432 | - struct timeval tv; | ||
2433 | + struct init_request request; | ||
2434 | + struct timeval tv; | ||
2435 | + struct stat st, st2; | ||
2436 | + fd_set fds; | ||
2437 | + int n; | ||
2438 | + int quit = 0; | ||
2439 | |||
2440 | /* | ||
2441 | * First, try to create /dev/initctl if not present. | ||
2442 | @@ -1940,7 +2034,7 @@ | ||
2443 | if ((pipe_fd = open(INIT_FIFO, O_RDWR|O_NONBLOCK)) >= 0) { | ||
2444 | fstat(pipe_fd, &st); | ||
2445 | if (!S_ISFIFO(st.st_mode)) { | ||
2446 | - log(L_VB, "%s is not a fifo", INIT_FIFO); | ||
2447 | + initlog(L_VB, "%s is not a fifo", INIT_FIFO); | ||
2448 | close(pipe_fd); | ||
2449 | pipe_fd = -1; | ||
2450 | } | ||
2451 | @@ -1987,7 +2081,7 @@ | ||
2452 | } | ||
2453 | if (n <= 0) { | ||
2454 | if (errno == EINTR) return; | ||
2455 | - log(L_VB, "error reading initrequest"); | ||
2456 | + initlog(L_VB, "error reading initrequest"); | ||
2457 | continue; | ||
2458 | } | ||
2459 | |||
2460 | @@ -2001,7 +2095,7 @@ | ||
2461 | * Process request. | ||
2462 | */ | ||
2463 | if (request.magic != INIT_MAGIC || n != sizeof(request)) { | ||
2464 | - log(L_VB, "got bogus initrequest"); | ||
2465 | + initlog(L_VB, "got bogus initrequest"); | ||
2466 | continue; | ||
2467 | } | ||
2468 | switch(request.cmd) { | ||
2469 | @@ -2025,8 +2119,23 @@ | ||
2470 | do_power_fail('O'); | ||
2471 | quit = 1; | ||
2472 | break; | ||
2473 | + case INIT_CMD_SETENV: | ||
2474 | + initcmd_setenv(request.i.data, sizeof(request.i.data)); | ||
2475 | + break; | ||
2476 | + case INIT_CMD_CHANGECONS: | ||
2477 | + if (user_console) { | ||
2478 | + free(user_console); | ||
2479 | + user_console = NULL; | ||
2480 | + } | ||
2481 | + if (!request.i.bsd.reserved[0]) | ||
2482 | + user_console = NULL; | ||
2483 | + else | ||
2484 | + user_console = strdup(request.i.bsd.reserved); | ||
2485 | + console_init(); | ||
2486 | + quit = 1; | ||
2487 | + break; | ||
2488 | default: | ||
2489 | - log(L_VB, "got unimplemented initrequest."); | ||
2490 | + initlog(L_VB, "got unimplemented initrequest."); | ||
2491 | break; | ||
2492 | } | ||
2493 | } | ||
2494 | @@ -2045,11 +2154,11 @@ | ||
2495 | */ | ||
2496 | void boot_transitions() | ||
2497 | { | ||
2498 | - CHILD *ch; | ||
2499 | - static int newlevel = 0; | ||
2500 | - int loglevel; | ||
2501 | - int oldlevel; | ||
2502 | - static int warn = 1; | ||
2503 | + CHILD *ch; | ||
2504 | + static int newlevel = 0; | ||
2505 | + static int warn = 1; | ||
2506 | + int loglevel; | ||
2507 | + int oldlevel; | ||
2508 | |||
2509 | /* Check if there is something to wait for! */ | ||
2510 | for( ch = family; ch; ch = ch->next ) | ||
2511 | @@ -2061,9 +2170,7 @@ | ||
2512 | oldlevel = 'N'; | ||
2513 | switch(runlevel) { | ||
2514 | case '#': /* SYSINIT -> BOOT */ | ||
2515 | -#if DEBUG | ||
2516 | - log(L_VB, "SYSINIT -> BOOT"); | ||
2517 | -#endif | ||
2518 | + INITDBG(L_VB, "SYSINIT -> BOOT"); | ||
2519 | |||
2520 | /* Write a boot record. */ | ||
2521 | wrote_utmp_reboot = 0; | ||
2522 | @@ -2080,9 +2187,7 @@ | ||
2523 | runlevel = '*'; | ||
2524 | break; | ||
2525 | case '*': /* BOOT -> NORMAL */ | ||
2526 | -#if DEBUG | ||
2527 | - log(L_VB, "BOOT -> NORMAL"); | ||
2528 | -#endif | ||
2529 | + INITDBG(L_VB, "BOOT -> NORMAL"); | ||
2530 | if (runlevel != newlevel) | ||
2531 | loglevel = newlevel; | ||
2532 | runlevel = newlevel; | ||
2533 | @@ -2091,9 +2196,7 @@ | ||
2534 | break; | ||
2535 | case 'S': /* Ended SU mode */ | ||
2536 | case 's': | ||
2537 | -#if DEBUG | ||
2538 | - log(L_VB, "END SU MODE"); | ||
2539 | -#endif | ||
2540 | + INITDBG(L_VB, "END SU MODE"); | ||
2541 | newlevel = get_init_default(); | ||
2542 | if (!did_boot && newlevel != 'S') | ||
2543 | runlevel = '*'; | ||
2544 | @@ -2110,7 +2213,8 @@ | ||
2545 | break; | ||
2546 | default: | ||
2547 | if (warn) | ||
2548 | - log(L_VB, "no more processes left in this runlevel"); | ||
2549 | + initlog(L_VB, | ||
2550 | + "no more processes left in this runlevel"); | ||
2551 | warn = 0; | ||
2552 | loglevel = -1; | ||
2553 | if (got_signals == 0) | ||
2554 | @@ -2118,7 +2222,7 @@ | ||
2555 | break; | ||
2556 | } | ||
2557 | if (loglevel > 0) { | ||
2558 | - log(L_VB, "Entering runlevel: %c", runlevel); | ||
2559 | + initlog(L_VB, "Entering runlevel: %c", runlevel); | ||
2560 | write_utmp_wtmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~"); | ||
2561 | thislevel = runlevel; | ||
2562 | prevlevel = oldlevel; | ||
2563 | @@ -2133,16 +2237,14 @@ | ||
2564 | */ | ||
2565 | void process_signals() | ||
2566 | { | ||
2567 | - int pwrstat; | ||
2568 | - int oldlevel; | ||
2569 | - int fd; | ||
2570 | - CHILD *ch; | ||
2571 | - char c; | ||
2572 | + CHILD *ch; | ||
2573 | + int pwrstat; | ||
2574 | + int oldlevel; | ||
2575 | + int fd; | ||
2576 | + char c; | ||
2577 | |||
2578 | if (ISMEMBER(got_signals, SIGPWR)) { | ||
2579 | -#if DEBUG | ||
2580 | - log(L_VB, "got SIGPWR"); | ||
2581 | -#endif | ||
2582 | + INITDBG(L_VB, "got SIGPWR"); | ||
2583 | /* See _what_ kind of SIGPWR this is. */ | ||
2584 | pwrstat = 0; | ||
2585 | if ((fd = open(PWRSTAT, O_RDONLY)) >= 0) { | ||
2586 | @@ -2157,9 +2259,7 @@ | ||
2587 | } | ||
2588 | |||
2589 | if (ISMEMBER(got_signals, SIGINT)) { | ||
2590 | -#if DEBUG | ||
2591 | - log(L_VB, "got SIGINT"); | ||
2592 | -#endif | ||
2593 | + INITDBG(L_VB, "got SIGINT"); | ||
2594 | /* Tell ctrlaltdel entry to start up */ | ||
2595 | for(ch = family; ch; ch = ch->next) | ||
2596 | if (ch->action == CTRLALTDEL) | ||
2597 | @@ -2168,9 +2268,7 @@ | ||
2598 | } | ||
2599 | |||
2600 | if (ISMEMBER(got_signals, SIGWINCH)) { | ||
2601 | -#if DEBUG | ||
2602 | - log(L_VB, "got SIGWINCH"); | ||
2603 | -#endif | ||
2604 | + INITDBG(L_VB, "got SIGWINCH"); | ||
2605 | /* Tell kbrequest entry to start up */ | ||
2606 | for(ch = family; ch; ch = ch->next) | ||
2607 | if (ch->action == KBREQUEST) | ||
2608 | @@ -2179,26 +2277,20 @@ | ||
2609 | } | ||
2610 | |||
2611 | if (ISMEMBER(got_signals, SIGALRM)) { | ||
2612 | -#if DEBUG | ||
2613 | - log(L_VB, "got SIGALRM"); | ||
2614 | -#endif | ||
2615 | + INITDBG(L_VB, "got SIGALRM"); | ||
2616 | /* The timer went off: check it out */ | ||
2617 | DELSET(got_signals, SIGALRM); | ||
2618 | } | ||
2619 | |||
2620 | if (ISMEMBER(got_signals, SIGCHLD)) { | ||
2621 | -#if DEBUG | ||
2622 | - log(L_VB, "got SIGCHLD"); | ||
2623 | -#endif | ||
2624 | + INITDBG(L_VB, "got SIGCHLD"); | ||
2625 | /* First set flag to 0 */ | ||
2626 | DELSET(got_signals, SIGCHLD); | ||
2627 | |||
2628 | /* See which child this was */ | ||
2629 | for(ch = family; ch; ch = ch->next) | ||
2630 | if (ch->flags & ZOMBIE) { | ||
2631 | -#if DEBUG | ||
2632 | - log(L_VB, "Child died, PID= %d", ch->pid); | ||
2633 | -#endif | ||
2634 | + INITDBG(L_VB, "Child died, PID= %d", ch->pid); | ||
2635 | ch->flags &= ~(RUNNING|ZOMBIE|WAITING); | ||
2636 | if (ch->process[0] != '+') | ||
2637 | write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL); | ||
2638 | @@ -2207,9 +2299,7 @@ | ||
2639 | } | ||
2640 | |||
2641 | if (ISMEMBER(got_signals, SIGHUP)) { | ||
2642 | -#if DEBUG | ||
2643 | - log(L_VB, "got SIGHUP"); | ||
2644 | -#endif | ||
2645 | + INITDBG(L_VB, "got SIGHUP"); | ||
2646 | #if CHANGE_WAIT | ||
2647 | /* Are we waiting for a child? */ | ||
2648 | for(ch = family; ch; ch = ch->next) | ||
2649 | @@ -2240,9 +2330,7 @@ | ||
2650 | /* | ||
2651 | * SIGUSR1 means close and reopen /dev/initctl | ||
2652 | */ | ||
2653 | -#if DEBUG | ||
2654 | - log(L_VB, "got SIGUSR1"); | ||
2655 | -#endif | ||
2656 | + INITDBG(L_VB, "got SIGUSR1"); | ||
2657 | close(pipe_fd); | ||
2658 | pipe_fd = -1; | ||
2659 | DELSET(got_signals, SIGUSR1); | ||
2660 | @@ -2254,11 +2342,11 @@ | ||
2661 | */ | ||
2662 | int init_main() | ||
2663 | { | ||
2664 | - int f, st; | ||
2665 | - pid_t rc; | ||
2666 | - CHILD *ch; | ||
2667 | - sigset_t sgt; | ||
2668 | - struct sigaction sa; | ||
2669 | + CHILD *ch; | ||
2670 | + struct sigaction sa; | ||
2671 | + sigset_t sgt; | ||
2672 | + pid_t rc; | ||
2673 | + int f, st; | ||
2674 | |||
2675 | if (!reload) { | ||
2676 | |||
2677 | @@ -2278,6 +2366,7 @@ | ||
2678 | } | ||
2679 | #endif | ||
2680 | |||
2681 | +#ifdef __linux__ | ||
2682 | /* | ||
2683 | * Tell the kernel to send us SIGINT when CTRL-ALT-DEL | ||
2684 | * is pressed, and that we want to handle keyboard signals. | ||
2685 | @@ -2288,6 +2377,7 @@ | ||
2686 | close(f); | ||
2687 | } else | ||
2688 | (void) ioctl(0, KDSIGACCEPT, SIGWINCH); | ||
2689 | +#endif | ||
2690 | |||
2691 | /* | ||
2692 | * Ignore all signals. | ||
2693 | @@ -2320,9 +2410,9 @@ | ||
2694 | setsid(); | ||
2695 | |||
2696 | /* | ||
2697 | - * Set default PATH variable (for ksh) | ||
2698 | + * Set default PATH variable. | ||
2699 | */ | ||
2700 | - if (getenv("PATH") == NULL) putenv(PATH_DFL); | ||
2701 | + putenv(PATH_DFL); | ||
2702 | |||
2703 | /* | ||
2704 | * Initialize /var/run/utmp (only works if /var is on | ||
2705 | @@ -2333,7 +2423,7 @@ | ||
2706 | /* | ||
2707 | * Say hello to the world | ||
2708 | */ | ||
2709 | - log(L_CO, bootmsg, "booting"); | ||
2710 | + initlog(L_CO, bootmsg, "booting"); | ||
2711 | |||
2712 | /* | ||
2713 | * See if we have to start an emergency shell. | ||
2714 | @@ -2358,7 +2448,7 @@ | ||
2715 | /* | ||
2716 | * Restart: unblock signals and let the show go on | ||
2717 | */ | ||
2718 | - log(L_CO, bootmsg, "reloading"); | ||
2719 | + initlog(L_CO, bootmsg, "reloading"); | ||
2720 | sigfillset(&sgt); | ||
2721 | sigprocmask(SIG_UNBLOCK, &sgt, NULL); | ||
2722 | } | ||
2723 | @@ -2368,9 +2458,7 @@ | ||
2724 | |||
2725 | /* See if we need to make the boot transitions. */ | ||
2726 | boot_transitions(); | ||
2727 | -#if DEBUG | ||
2728 | - log(L_VB, "init_main: waiting.."); | ||
2729 | -#endif | ||
2730 | + INITDBG(L_VB, "init_main: waiting.."); | ||
2731 | |||
2732 | /* Check if there are processes to be waited on. */ | ||
2733 | for(ch = family; ch; ch = ch->next) | ||
2734 | @@ -2405,10 +2493,10 @@ | ||
2735 | /* | ||
2736 | * Tell the user about the syntax we expect. | ||
2737 | */ | ||
2738 | -void Usage(char *s) | ||
2739 | +void usage(char *s) | ||
2740 | { | ||
2741 | - fprintf(stderr, "Usage: %s 0123456SsQqAaBbCcUu\n", s); | ||
2742 | - exit(1); | ||
2743 | + fprintf(stderr, "Usage: %s 0123456SsQqAaBbCcUu\n", s); | ||
2744 | + exit(1); | ||
2745 | } | ||
2746 | |||
2747 | int telinit(char *progname, int argc, char **argv) | ||
2748 | @@ -2418,28 +2506,51 @@ | ||
2749 | #endif | ||
2750 | struct init_request request; | ||
2751 | struct sigaction sa; | ||
2752 | - int f, fd; | ||
2753 | + int f, fd, l; | ||
2754 | + char *env = NULL; | ||
2755 | |||
2756 | - while((f = getopt(argc, argv, "t:")) != EOF) switch(f) { | ||
2757 | + memset(&request, 0, sizeof(request)); | ||
2758 | + request.magic = INIT_MAGIC; | ||
2759 | + | ||
2760 | + while ((f = getopt(argc, argv, "t:e:")) != EOF) switch(f) { | ||
2761 | case 't': | ||
2762 | sltime = atoi(optarg); | ||
2763 | break; | ||
2764 | + case 'e': | ||
2765 | + if (env == NULL) | ||
2766 | + env = request.i.data; | ||
2767 | + l = strlen(optarg); | ||
2768 | + if (env + l + 2 > request.i.data + sizeof(request.i.data)) { | ||
2769 | + fprintf(stderr, "%s: -e option data " | ||
2770 | + "too large\n", progname); | ||
2771 | + exit(1); | ||
2772 | + } | ||
2773 | + memcpy(env, optarg, l); | ||
2774 | + env += l; | ||
2775 | + *env++ = 0; | ||
2776 | + break; | ||
2777 | default: | ||
2778 | - Usage(progname); | ||
2779 | + usage(progname); | ||
2780 | break; | ||
2781 | } | ||
2782 | |||
2783 | - /* Check syntax. */ | ||
2784 | - if (argc - optind != 1 || strlen(argv[optind]) != 1) Usage(progname); | ||
2785 | - if (!strchr("0123456789SsQqAaBbCcUu", argv[optind][0])) Usage(progname); | ||
2786 | + if (env) *env++ = 0; | ||
2787 | |||
2788 | - /* Open the fifo and write a command. */ | ||
2789 | - memset(&request, 0, sizeof(request)); | ||
2790 | - request.magic = INIT_MAGIC; | ||
2791 | - request.cmd = INIT_CMD_RUNLVL; | ||
2792 | - request.runlevel = argv[optind][0]; | ||
2793 | - request.sleeptime = sltime; | ||
2794 | + if (env) { | ||
2795 | + if (argc != optind) | ||
2796 | + usage(progname); | ||
2797 | + request.cmd = INIT_CMD_SETENV; | ||
2798 | + } else { | ||
2799 | + if (argc - optind != 1 || strlen(argv[optind]) != 1) | ||
2800 | + usage(progname); | ||
2801 | + if (!strchr("0123456789SsQqAaBbCcUu", argv[optind][0])) | ||
2802 | + usage(progname); | ||
2803 | + request.cmd = INIT_CMD_RUNLVL; | ||
2804 | + request.runlevel = env ? 0 : argv[optind][0]; | ||
2805 | + request.sleeptime = sltime; | ||
2806 | + } | ||
2807 | |||
2808 | + /* Open the fifo and write a command. */ | ||
2809 | /* Make sure we don't hang on opening /dev/initctl */ | ||
2810 | SETSIG(sa, SIGALRM, signal_handler, 0); | ||
2811 | alarm(3); | ||
2812 | @@ -2449,7 +2560,27 @@ | ||
2813 | alarm(0); | ||
2814 | return 0; | ||
2815 | } | ||
2816 | -#ifndef TELINIT_USES_INITLVL | ||
2817 | + | ||
2818 | +#ifdef TELINIT_USES_INITLVL | ||
2819 | + if (request.cmd == INIT_CMD_RUNLVL) { | ||
2820 | + /* Fallthrough to the old method. */ | ||
2821 | + | ||
2822 | + /* Now write the new runlevel. */ | ||
2823 | + if ((fp = fopen(INITLVL, "w")) == NULL) { | ||
2824 | + fprintf(stderr, "%s: cannot create %s\n", | ||
2825 | + progname, INITLVL); | ||
2826 | + exit(1); | ||
2827 | + } | ||
2828 | + fprintf(fp, "%s %d", argv[optind], sltime); | ||
2829 | + fclose(fp); | ||
2830 | + | ||
2831 | + /* And tell init about the pending runlevel change. */ | ||
2832 | + if (kill(INITPID, SIGHUP) < 0) perror(progname); | ||
2833 | + | ||
2834 | + return 0; | ||
2835 | + } | ||
2836 | +#endif | ||
2837 | + | ||
2838 | fprintf(stderr, "%s: ", progname); | ||
2839 | if (ISMEMBER(got_signals, SIGALRM)) { | ||
2840 | fprintf(stderr, "timeout opening/writing control channel %s\n", | ||
2841 | @@ -2458,24 +2589,6 @@ | ||
2842 | perror(INIT_FIFO); | ||
2843 | } | ||
2844 | return 1; | ||
2845 | -#endif | ||
2846 | - | ||
2847 | - /* Fallthrough to the old method. */ | ||
2848 | - | ||
2849 | -#ifdef TELINIT_USES_INITLVL | ||
2850 | - /* Now write the new runlevel. */ | ||
2851 | - if ((fp = fopen(INITLVL, "w")) == NULL) { | ||
2852 | - fprintf(stderr, "%s: cannot create %s\n", progname, INITLVL); | ||
2853 | - exit(1); | ||
2854 | - } | ||
2855 | - fprintf(fp, "%s %d", argv[optind], sltime); | ||
2856 | - fclose(fp); | ||
2857 | - | ||
2858 | - /* And tell init about the pending runlevel change. */ | ||
2859 | - if (kill(INITPID, SIGHUP) < 0) perror(progname); | ||
2860 | - | ||
2861 | - return 0; | ||
2862 | -#endif | ||
2863 | } | ||
2864 | |||
2865 | /* | ||
2866 | @@ -2518,7 +2631,7 @@ | ||
2867 | |||
2868 | receive_state(STATE_PIPE); | ||
2869 | |||
2870 | - myname = strdup(argv[0]); | ||
2871 | + myname = istrdup(argv[0]); | ||
2872 | argv0 = argv[0]; | ||
2873 | maxproclen = 0; | ||
2874 | for (f = 0; f < argc; f++) | ||
2875 | diff -urNd -urNd sysvinit-2.85/src/init.h sysvinit-2.86/src/init.h | ||
2876 | --- sysvinit-2.85/src/init.h 1999-06-03 14:22:59.000000000 -0500 | ||
2877 | +++ sysvinit-2.86/src/init.h 2004-07-29 06:21:01.000000000 -0500 | ||
2878 | @@ -2,9 +2,8 @@ | ||
2879 | * init.h Several defines and declarations to be | ||
2880 | * included by all modules of the init program. | ||
2881 | * | ||
2882 | - * Version: @(#)init.h 2.74 09-Mar-1998 miquels@cistron.nl | ||
2883 | + * Version: @(#)init.h 2.85-5 02-Jul-2003 miquels@cistron.nl | ||
2884 | * | ||
2885 | - * Modified: Re-exec patch; 24 Feb 1998, Al Viro. | ||
2886 | */ | ||
2887 | |||
2888 | /* Standard configuration */ | ||
2889 | @@ -24,17 +23,26 @@ | ||
2890 | #define TESTTIME 120 /* this much seconds */ | ||
2891 | #define SLEEPTIME 300 /* Disable time */ | ||
2892 | |||
2893 | -/* Default path inherited by every child if it's not set. */ | ||
2894 | -#define PATH_DFL "PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin" | ||
2895 | +/* Default path inherited by every child. */ | ||
2896 | +#define PATH_DFL "PATH=/bin:/usr/bin:/sbin:/usr/sbin" | ||
2897 | |||
2898 | |||
2899 | /* Prototypes. */ | ||
2900 | void write_utmp_wtmp(char *user, char *id, int pid, int type, char *line); | ||
2901 | void write_wtmp(char *user, char *id, int pid, int type, char *line); | ||
2902 | -void log(int loglevel, char *fmt, ...); | ||
2903 | +#ifdef __GNUC__ | ||
2904 | +__attribute__ ((format (printf, 2, 3))) | ||
2905 | +#endif | ||
2906 | +void initlog(int loglevel, char *fmt, ...); | ||
2907 | void set_term(int how); | ||
2908 | void print(char *fmt); | ||
2909 | |||
2910 | +#if DEBUG | ||
2911 | +# define INITDBG(level, fmt, args...) initlog(level, fmt, ##args) | ||
2912 | +#else | ||
2913 | +# define INITDBG(level, fmt, args...) | ||
2914 | +#endif | ||
2915 | + | ||
2916 | /* Actions to be taken by init */ | ||
2917 | #define RESPAWN 1 | ||
2918 | #define WAIT 2 | ||
2919 | Binary files sysvinit-2.85/src/init.o and sysvinit-2.86/src/init.o differ | ||
2920 | Binary files sysvinit-2.85/src/init_utmp.o and sysvinit-2.86/src/init_utmp.o differ | ||
2921 | diff -urNd -urNd sysvinit-2.85/src/initreq.h sysvinit-2.86/src/initreq.h | ||
2922 | --- sysvinit-2.85/src/initreq.h 1996-01-02 12:22:06.000000000 -0600 | ||
2923 | +++ sysvinit-2.86/src/initreq.h 2004-07-30 06:56:51.000000000 -0500 | ||
2924 | @@ -1,41 +1,77 @@ | ||
2925 | /* | ||
2926 | - * initreq.h Interface to let init spawn programs on behalf of | ||
2927 | - * other programs/daemons. | ||
2928 | - * Definitions based on sys_term.c from the BSD 4.4 | ||
2929 | - * telnetd source. | ||
2930 | + * initreq.h Interface to talk to init through /dev/initctl. | ||
2931 | * | ||
2932 | - * Version: @(#)initreq.h 1.25 28-Dec-1995 MvS | ||
2933 | + * Copyright (C) 1995-2004 Miquel van Smoorenburg | ||
2934 | + * | ||
2935 | + * This library is free software; you can redistribute it and/or | ||
2936 | + * modify it under the terms of the GNU Lesser General Public | ||
2937 | + * License as published by the Free Software Foundation; either | ||
2938 | + * version 2 of the License, or (at your option) any later version. | ||
2939 | + * | ||
2940 | + * Version: @(#)initreq.h 1.28 31-Mar-2004 MvS | ||
2941 | * | ||
2942 | - * Notes: Implemented in sysvinit-2.58 and up, but only | ||
2943 | - * for "telinit". Support for rlogind, telnetd | ||
2944 | - * and rxvt/xterm will follow shortly. | ||
2945 | */ | ||
2946 | #ifndef _INITREQ_H | ||
2947 | #define _INITREQ_H | ||
2948 | |||
2949 | #include <sys/param.h> | ||
2950 | |||
2951 | +#if defined(__FreeBSD_kernel__) | ||
2952 | +# define INIT_FIFO "/etc/.initctl" | ||
2953 | +#else | ||
2954 | +# define INIT_FIFO "/dev/initctl" | ||
2955 | +#endif | ||
2956 | + | ||
2957 | #define INIT_MAGIC 0x03091969 | ||
2958 | -#define INIT_FIFO "/dev/initctl" | ||
2959 | -#define INIT_CMD_START 0 | ||
2960 | -#define INIT_CMD_RUNLVL 1 | ||
2961 | -#define INIT_CMD_POWERFAIL 2 | ||
2962 | -#define INIT_CMD_POWERFAILNOW 3 | ||
2963 | -#define INIT_CMD_POWEROK 4 | ||
2964 | +#define INIT_CMD_START 0 | ||
2965 | +#define INIT_CMD_RUNLVL 1 | ||
2966 | +#define INIT_CMD_POWERFAIL 2 | ||
2967 | +#define INIT_CMD_POWERFAILNOW 3 | ||
2968 | +#define INIT_CMD_POWEROK 4 | ||
2969 | +#define INIT_CMD_BSD 5 | ||
2970 | +#define INIT_CMD_SETENV 6 | ||
2971 | +#define INIT_CMD_UNSETENV 7 | ||
2972 | + | ||
2973 | +#define INIT_CMD_CHANGECONS 12345 | ||
2974 | + | ||
2975 | +#ifdef MAXHOSTNAMELEN | ||
2976 | +# define INITRQ_HLEN MAXHOSTNAMELEN | ||
2977 | +#else | ||
2978 | +# define INITRQ_HLEN 64 | ||
2979 | +#endif | ||
2980 | + | ||
2981 | +/* | ||
2982 | + * This is what BSD 4.4 uses when talking to init. | ||
2983 | + * Linux doesn't use this right now. | ||
2984 | + */ | ||
2985 | +struct init_request_bsd { | ||
2986 | + char gen_id[8]; /* Beats me.. telnetd uses "fe" */ | ||
2987 | + char tty_id[16]; /* Tty name minus /dev/tty */ | ||
2988 | + char host[INITRQ_HLEN]; /* Hostname */ | ||
2989 | + char term_type[16]; /* Terminal type */ | ||
2990 | + int signal; /* Signal to send */ | ||
2991 | + int pid; /* Process to send to */ | ||
2992 | + char exec_name[128]; /* Program to execute */ | ||
2993 | + char reserved[128]; /* For future expansion. */ | ||
2994 | +}; | ||
2995 | + | ||
2996 | |||
2997 | +/* | ||
2998 | + * Because of legacy interfaces, "runlevel" and "sleeptime" | ||
2999 | + * aren't in a seperate struct in the union. | ||
3000 | + * | ||
3001 | + * The weird sizes are because init expects the whole | ||
3002 | + * struct to be 384 bytes. | ||
3003 | + */ | ||
3004 | struct init_request { | ||
3005 | - int magic; /* Magic number */ | ||
3006 | - int cmd; /* What kind of request */ | ||
3007 | - int runlevel; /* Runlevel to change to */ | ||
3008 | - int sleeptime; /* Time between TERM and KILL */ | ||
3009 | - char gen_id[8]; /* Beats me.. telnetd uses "fe" */ | ||
3010 | - char tty_id[16]; /* Tty name minus /dev/tty */ | ||
3011 | - char host[MAXHOSTNAMELEN]; /* Hostname */ | ||
3012 | - char term_type[16]; /* Terminal type */ | ||
3013 | - int signal; /* Signal to send */ | ||
3014 | - int pid; /* Process to send to */ | ||
3015 | - char exec_name[128]; /* Program to execute */ | ||
3016 | - char reserved[128]; /* For future expansion. */ | ||
3017 | + int magic; /* Magic number */ | ||
3018 | + int cmd; /* What kind of request */ | ||
3019 | + int runlevel; /* Runlevel to change to */ | ||
3020 | + int sleeptime; /* Time between TERM and KILL */ | ||
3021 | + union { | ||
3022 | + struct init_request_bsd bsd; | ||
3023 | + char data[368]; | ||
3024 | + } i; | ||
3025 | }; | ||
3026 | |||
3027 | #endif | ||
3028 | Binary files sysvinit-2.85/src/killall5 and sysvinit-2.86/src/killall5 differ | ||
3029 | diff -urNd -urNd sysvinit-2.85/src/killall5.c sysvinit-2.86/src/killall5.c | ||
3030 | --- sysvinit-2.85/src/killall5.c 2003-04-14 04:59:11.000000000 -0500 | ||
3031 | +++ sysvinit-2.86/src/killall5.c 2004-07-30 07:16:23.000000000 -0500 | ||
3032 | @@ -5,7 +5,7 @@ | ||
3033 | * | ||
3034 | * pidof.c Tries to get the pid of the process[es] named. | ||
3035 | * | ||
3036 | - * Version: 2.85 14-Apr-2003 MvS | ||
3037 | + * Version: 2.86 30-Jul-2004 MvS | ||
3038 | * | ||
3039 | * Usage: killall5 [-][signal] | ||
3040 | * pidof [-s] [-o omitpid [-o omitpid]] program [program..] | ||
3041 | @@ -20,7 +20,7 @@ | ||
3042 | * - swapped out programs pids are caught now | ||
3043 | * | ||
3044 | * This file is part of the sysvinit suite, | ||
3045 | - * Copyright 1991-2003 Miquel van Smoorenburg. | ||
3046 | + * Copyright 1991-2004 Miquel van Smoorenburg. | ||
3047 | * | ||
3048 | * This program is free software; you can redistribute it and/or | ||
3049 | * modify it under the terms of the GNU General Public License | ||
3050 | @@ -41,34 +41,43 @@ | ||
3051 | #include <getopt.h> | ||
3052 | #include <stdarg.h> | ||
3053 | |||
3054 | -char *Version = "@(#)killall5 2.85 14-Apr-2003 miquels@cistron.nl"; | ||
3055 | +char *Version = "@(#)killall5 2.86 31-Jul-2004 miquels@cistron.nl"; | ||
3056 | + | ||
3057 | +#define STATNAMELEN 15 | ||
3058 | |||
3059 | /* Info about a process. */ | ||
3060 | -typedef struct _proc_ | ||
3061 | -{ | ||
3062 | - char *fullname; /* Name as found out from argv[0] */ | ||
3063 | - char *basename; /* Only the part after the last / */ | ||
3064 | - char *statname; /* the statname without braces */ | ||
3065 | - ino_t ino; /* Inode number */ | ||
3066 | - dev_t dev; /* Device it is on */ | ||
3067 | - pid_t pid; /* Process ID. */ | ||
3068 | - int sid; /* Session ID. */ | ||
3069 | - struct _proc_ *next; /* Pointer to next struct. */ | ||
3070 | +typedef struct proc { | ||
3071 | + char *argv0; /* Name as found out from argv[0] */ | ||
3072 | + char *argv0base; /* `basename argv[1]` */ | ||
3073 | + char *argv1; /* Name as found out from argv[1] */ | ||
3074 | + char *argv1base; /* `basename argv[1]` */ | ||
3075 | + char *statname; /* the statname without braces */ | ||
3076 | + ino_t ino; /* Inode number */ | ||
3077 | + dev_t dev; /* Device it is on */ | ||
3078 | + pid_t pid; /* Process ID. */ | ||
3079 | + int sid; /* Session ID. */ | ||
3080 | + int kernel; /* Kernel thread or zombie. */ | ||
3081 | + struct proc *next; /* Pointer to next struct. */ | ||
3082 | } PROC; | ||
3083 | |||
3084 | /* pid queue */ | ||
3085 | -typedef struct _pidq_ { | ||
3086 | - struct _pidq_ *front; | ||
3087 | - struct _pidq_ *next; | ||
3088 | - struct _pidq_ *rear; | ||
3089 | - PROC *proc; | ||
3090 | + | ||
3091 | +typedef struct pidq { | ||
3092 | + PROC *proc; | ||
3093 | + struct pidq *next; | ||
3094 | } PIDQ; | ||
3095 | |||
3096 | +typedef struct { | ||
3097 | + PIDQ *head; | ||
3098 | + PIDQ *tail; | ||
3099 | + PIDQ *next; | ||
3100 | +} PIDQ_HEAD; | ||
3101 | + | ||
3102 | /* List of processes. */ | ||
3103 | PROC *plist; | ||
3104 | |||
3105 | -/* Did we stop a number of processes? */ | ||
3106 | -int stopped; | ||
3107 | +/* Did we stop all processes ? */ | ||
3108 | +int sent_sigstop; | ||
3109 | |||
3110 | int scripts_too = 0; | ||
3111 | |||
3112 | @@ -86,7 +95,7 @@ | ||
3113 | void *p; | ||
3114 | |||
3115 | if ((p = malloc(bytes)) == NULL) { | ||
3116 | - if (stopped) kill(-1, SIGCONT); | ||
3117 | + if (sent_sigstop) kill(-1, SIGCONT); | ||
3118 | nsyslog(LOG_ERR, "out of memory"); | ||
3119 | exit(1); | ||
3120 | } | ||
3121 | @@ -98,14 +107,14 @@ | ||
3122 | */ | ||
3123 | int mount_proc(void) | ||
3124 | { | ||
3125 | - struct stat st; | ||
3126 | - pid_t pid, rc; | ||
3127 | - int wst; | ||
3128 | - char *args[] = { "mount", "-t", "proc", "none", "/proc", NULL }; | ||
3129 | - int did_mount = 0; | ||
3130 | + struct stat st; | ||
3131 | + char *args[] = { "mount", "-t", "proc", "proc", "/proc", 0 }; | ||
3132 | + pid_t pid, rc; | ||
3133 | + int wst; | ||
3134 | + int did_mount = 0; | ||
3135 | |||
3136 | /* Stat /proc/version to see if /proc is mounted. */ | ||
3137 | - if (stat("/proc/version", &st) < 0) { | ||
3138 | + if (stat("/proc/version", &st) < 0 && errno == ENOENT) { | ||
3139 | |||
3140 | /* It's not there, so mount it. */ | ||
3141 | if ((pid = fork()) < 0) { | ||
3142 | @@ -115,7 +124,6 @@ | ||
3143 | if (pid == 0) { | ||
3144 | /* Try a few mount binaries. */ | ||
3145 | execv("/sbin/mount", args); | ||
3146 | - execv("/etc/mount", args); | ||
3147 | execv("/bin/mount", args); | ||
3148 | |||
3149 | /* Okay, I give up. */ | ||
3150 | @@ -134,28 +142,42 @@ | ||
3151 | |||
3152 | /* See if mount succeeded. */ | ||
3153 | if (stat("/proc/version", &st) < 0) { | ||
3154 | - nsyslog(LOG_ERR, "/proc not mounted, failed to mount."); | ||
3155 | + if (errno == ENOENT) | ||
3156 | + nsyslog(LOG_ERR, "/proc not mounted, failed to mount."); | ||
3157 | + else | ||
3158 | + nsyslog(LOG_ERR, "/proc unavailable."); | ||
3159 | exit(1); | ||
3160 | } | ||
3161 | |||
3162 | return did_mount; | ||
3163 | } | ||
3164 | |||
3165 | +int readarg(FILE *fp, char *buf, int sz) | ||
3166 | +{ | ||
3167 | + int c = 0, f = 0; | ||
3168 | + | ||
3169 | + while (f < (sz-1) && (c = fgetc(fp)) != EOF && c) | ||
3170 | + buf[f++] = c; | ||
3171 | + buf[f] = 0; | ||
3172 | + | ||
3173 | + return (c == EOF && f == 0) ? c : f; | ||
3174 | +} | ||
3175 | + | ||
3176 | /* | ||
3177 | * Read the proc filesystem. | ||
3178 | */ | ||
3179 | int readproc() | ||
3180 | { | ||
3181 | - DIR *dir; | ||
3182 | - struct dirent *d; | ||
3183 | - char path[256]; | ||
3184 | - char buf[256]; | ||
3185 | - char *s, *q; | ||
3186 | - FILE *fp; | ||
3187 | - int pid, f; | ||
3188 | - PROC *p, *n; | ||
3189 | - struct stat st; | ||
3190 | - int c; | ||
3191 | + DIR *dir; | ||
3192 | + FILE *fp; | ||
3193 | + PROC *p, *n; | ||
3194 | + struct dirent *d; | ||
3195 | + struct stat st; | ||
3196 | + char path[256]; | ||
3197 | + char buf[256]; | ||
3198 | + char *s, *q; | ||
3199 | + unsigned long startcode, endcode; | ||
3200 | + int pid, f; | ||
3201 | |||
3202 | /* Open the /proc directory. */ | ||
3203 | if ((dir = opendir("/proc")) == NULL) { | ||
3204 | @@ -167,7 +189,8 @@ | ||
3205 | n = plist; | ||
3206 | for (p = plist; n; p = n) { | ||
3207 | n = p->next; | ||
3208 | - if (p->fullname) free(p->fullname); | ||
3209 | + if (p->argv0) free(p->argv0); | ||
3210 | + if (p->argv1) free(p->argv1); | ||
3211 | free(p); | ||
3212 | } | ||
3213 | plist = NULL; | ||
3214 | @@ -188,7 +211,7 @@ | ||
3215 | /* Read SID & statname from it. */ | ||
3216 | if ((fp = fopen(path, "r")) != NULL) { | ||
3217 | buf[0] = 0; | ||
3218 | - fgets(buf, 256, fp); | ||
3219 | + fgets(buf, sizeof(buf), fp); | ||
3220 | |||
3221 | /* See if name starts with '(' */ | ||
3222 | s = buf; | ||
3223 | @@ -215,14 +238,21 @@ | ||
3224 | p->statname = (char *)xmalloc(strlen(s)+1); | ||
3225 | strcpy(p->statname, s); | ||
3226 | |||
3227 | - /* This could be replaced by getsid(pid) */ | ||
3228 | - if (sscanf(q, "%*c %*d %*d %d", &p->sid) != 1) { | ||
3229 | + /* Get session, startcode, endcode. */ | ||
3230 | + startcode = endcode = 0; | ||
3231 | + if (sscanf(q, "%*c %*d %*d %d %*d %*d %*u %*u " | ||
3232 | + "%*u %*u %*u %*u %*u %*d %*d " | ||
3233 | + "%*d %*d %*d %*d %*u %*u %*d " | ||
3234 | + "%*u %lu %lu", | ||
3235 | + &p->sid, &startcode, &endcode) != 3) { | ||
3236 | p->sid = 0; | ||
3237 | nsyslog(LOG_ERR, "can't read sid from %s\n", | ||
3238 | path); | ||
3239 | free(p); | ||
3240 | continue; | ||
3241 | } | ||
3242 | + if (startcode == 0 && endcode == 0) | ||
3243 | + p->kernel = 1; | ||
3244 | fclose(fp); | ||
3245 | } else { | ||
3246 | /* Process disappeared.. */ | ||
3247 | @@ -230,24 +260,44 @@ | ||
3248 | continue; | ||
3249 | } | ||
3250 | |||
3251 | - /* Now read argv[0] */ | ||
3252 | snprintf(path, sizeof(path), "/proc/%s/cmdline", d->d_name); | ||
3253 | if ((fp = fopen(path, "r")) != NULL) { | ||
3254 | - f = 0; | ||
3255 | - while(f < 127 && (c = fgetc(fp)) != EOF && c) | ||
3256 | - buf[f++] = c; | ||
3257 | - buf[f++] = 0; | ||
3258 | - fclose(fp); | ||
3259 | |||
3260 | - /* Store the name into malloced memory. */ | ||
3261 | - p->fullname = (char *)xmalloc(f); | ||
3262 | - strcpy(p->fullname, buf); | ||
3263 | + /* Now read argv[0] */ | ||
3264 | + f = readarg(fp, buf, sizeof(buf)); | ||
3265 | + | ||
3266 | + if (buf[0]) { | ||
3267 | + /* Store the name into malloced memory. */ | ||
3268 | + p->argv0 = (char *)xmalloc(f + 1); | ||
3269 | + strcpy(p->argv0, buf); | ||
3270 | + | ||
3271 | + /* Get a pointer to the basename. */ | ||
3272 | + p->argv0base = strrchr(p->argv0, '/'); | ||
3273 | + if (p->argv0base != NULL) | ||
3274 | + p->argv0base++; | ||
3275 | + else | ||
3276 | + p->argv0base = p->argv0; | ||
3277 | + } | ||
3278 | + | ||
3279 | + /* And read argv[1] */ | ||
3280 | + while ((f = readarg(fp, buf, sizeof(buf))) != EOF) | ||
3281 | + if (buf[0] != '-') break; | ||
3282 | + | ||
3283 | + if (buf[0]) { | ||
3284 | + /* Store the name into malloced memory. */ | ||
3285 | + p->argv1 = (char *)xmalloc(f + 1); | ||
3286 | + strcpy(p->argv1, buf); | ||
3287 | + | ||
3288 | + /* Get a pointer to the basename. */ | ||
3289 | + p->argv1base = strrchr(p->argv1, '/'); | ||
3290 | + if (p->argv1base != NULL) | ||
3291 | + p->argv1base++; | ||
3292 | + else | ||
3293 | + p->argv1base = p->argv1; | ||
3294 | + } | ||
3295 | + | ||
3296 | + fclose(fp); | ||
3297 | |||
3298 | - /* Get a pointer to the basename. */ | ||
3299 | - if ((p->basename = strrchr(p->fullname, '/')) != NULL) | ||
3300 | - p->basename++; | ||
3301 | - else | ||
3302 | - p->basename = p->fullname; | ||
3303 | } else { | ||
3304 | /* Process disappeared.. */ | ||
3305 | free(p); | ||
3306 | @@ -272,19 +322,18 @@ | ||
3307 | return 0; | ||
3308 | } | ||
3309 | |||
3310 | -PIDQ *init_pid_q(PIDQ *q) | ||
3311 | +PIDQ_HEAD *init_pid_q(PIDQ_HEAD *q) | ||
3312 | { | ||
3313 | - q->front = q->next = q->rear = NULL; | ||
3314 | - q->proc = NULL; | ||
3315 | + q->head = q->next = q->tail = NULL; | ||
3316 | return q; | ||
3317 | } | ||
3318 | |||
3319 | -int empty_q(PIDQ *q) | ||
3320 | +int empty_q(PIDQ_HEAD *q) | ||
3321 | { | ||
3322 | - return (q->front == NULL); | ||
3323 | + return (q->head == NULL); | ||
3324 | } | ||
3325 | |||
3326 | -int add_pid_to_q(PIDQ *q, PROC *p) | ||
3327 | +int add_pid_to_q(PIDQ_HEAD *q, PROC *p) | ||
3328 | { | ||
3329 | PIDQ *tmp; | ||
3330 | |||
3331 | @@ -294,23 +343,23 @@ | ||
3332 | tmp->next = NULL; | ||
3333 | |||
3334 | if (empty_q(q)) { | ||
3335 | - q->front = tmp; | ||
3336 | - q->rear = tmp; | ||
3337 | + q->head = tmp; | ||
3338 | + q->tail = tmp; | ||
3339 | } else { | ||
3340 | - q->rear->next = tmp; | ||
3341 | - q->rear = tmp; | ||
3342 | + q->tail->next = tmp; | ||
3343 | + q->tail = tmp; | ||
3344 | } | ||
3345 | return 0; | ||
3346 | } | ||
3347 | |||
3348 | -PROC *get_next_from_pid_q(PIDQ *q) | ||
3349 | +PROC *get_next_from_pid_q(PIDQ_HEAD *q) | ||
3350 | { | ||
3351 | - PROC *p; | ||
3352 | - PIDQ *tmp = q->front; | ||
3353 | + PROC *p; | ||
3354 | + PIDQ *tmp = q->head; | ||
3355 | |||
3356 | if (!empty_q(q)) { | ||
3357 | - p = q->front->proc; | ||
3358 | - q->front = tmp->next; | ||
3359 | + p = q->head->proc; | ||
3360 | + q->head = tmp->next; | ||
3361 | free(tmp); | ||
3362 | return p; | ||
3363 | } | ||
3364 | @@ -319,15 +368,15 @@ | ||
3365 | } | ||
3366 | |||
3367 | /* Try to get the process ID of a given process. */ | ||
3368 | -PIDQ *pidof(char *prog) | ||
3369 | +PIDQ_HEAD *pidof(char *prog) | ||
3370 | { | ||
3371 | - struct stat st; | ||
3372 | - int dostat = 0; | ||
3373 | - PROC *p; | ||
3374 | - PIDQ *q; | ||
3375 | - char *s; | ||
3376 | - int foundone = 0; | ||
3377 | - int ok = 0; | ||
3378 | + PROC *p; | ||
3379 | + PIDQ_HEAD *q; | ||
3380 | + struct stat st; | ||
3381 | + char *s; | ||
3382 | + int dostat = 0; | ||
3383 | + int foundone = 0; | ||
3384 | + int ok = 0; | ||
3385 | |||
3386 | /* Try to stat the executable. */ | ||
3387 | if (prog[0] == '/' && stat(prog, &st) == 0) dostat++; | ||
3388 | @@ -338,7 +387,7 @@ | ||
3389 | else | ||
3390 | s++; | ||
3391 | |||
3392 | - q = (PIDQ *)xmalloc(sizeof(PIDQ)); | ||
3393 | + q = (PIDQ_HEAD *)xmalloc(sizeof(PIDQ_HEAD)); | ||
3394 | q = init_pid_q(q); | ||
3395 | |||
3396 | /* First try to find a match based on dev/ino pair. */ | ||
3397 | @@ -352,20 +401,31 @@ | ||
3398 | } | ||
3399 | |||
3400 | /* If we didn't find a match based on dev/ino, try the name. */ | ||
3401 | - if (!foundone) { | ||
3402 | - for (p = plist; p; p = p->next) { | ||
3403 | - ok = 0; | ||
3404 | + if (!foundone) for (p = plist; p; p = p->next) { | ||
3405 | + ok = 0; | ||
3406 | |||
3407 | - ok += (strcmp(p->fullname, prog) == 0); | ||
3408 | - ok += (strcmp(p->basename, s) == 0); | ||
3409 | + /* Compare name (both basename and full path) */ | ||
3410 | + ok += (p->argv0 && strcmp(p->argv0, prog) == 0); | ||
3411 | + ok += (p->argv0 && strcmp(p->argv0base, s) == 0); | ||
3412 | |||
3413 | - if (p->fullname[0] == 0 || | ||
3414 | - strchr(p->fullname, ' ') || | ||
3415 | - scripts_too) | ||
3416 | - ok += (strcmp(p->statname, s) == 0); | ||
3417 | + /* For scripts, compare argv[1] as well. */ | ||
3418 | + if (scripts_too && p->argv1 && | ||
3419 | + !strncmp(p->statname, p->argv1base, STATNAMELEN)) { | ||
3420 | + ok += (strcmp(p->argv1, prog) == 0); | ||
3421 | + ok += (strcmp(p->argv1base, s) == 0); | ||
3422 | + } | ||
3423 | |||
3424 | - if (ok) add_pid_to_q(q, p); | ||
3425 | + /* | ||
3426 | + * if we have a space in argv0, process probably | ||
3427 | + * used setproctitle so try statname. | ||
3428 | + */ | ||
3429 | + if (strlen(s) <= STATNAMELEN && | ||
3430 | + (p->argv0 == NULL || | ||
3431 | + p->argv0[0] == 0 || | ||
3432 | + strchr(p->argv0, ' '))) { | ||
3433 | + ok += (strcmp(p->statname, s) == 0); | ||
3434 | } | ||
3435 | + if (ok) add_pid_to_q(q, p); | ||
3436 | } | ||
3437 | |||
3438 | return q; | ||
3439 | @@ -410,12 +470,12 @@ | ||
3440 | */ | ||
3441 | int main_pidof(int argc, char **argv) | ||
3442 | { | ||
3443 | - PROC *p; | ||
3444 | - PIDQ *q; | ||
3445 | - int f; | ||
3446 | - int first = 1; | ||
3447 | - int i,oind, opt, flags = 0; | ||
3448 | - pid_t opid[PIDOF_OMITSZ], spid; | ||
3449 | + PIDQ_HEAD *q; | ||
3450 | + PROC *p; | ||
3451 | + pid_t opid[PIDOF_OMITSZ], spid; | ||
3452 | + int f; | ||
3453 | + int first = 1; | ||
3454 | + int i, oind, opt, flags = 0; | ||
3455 | |||
3456 | for (oind = PIDOF_OMITSZ-1; oind > 0; oind--) | ||
3457 | opid[oind] = 0; | ||
3458 | @@ -498,9 +558,9 @@ | ||
3459 | /* Main for either killall or pidof. */ | ||
3460 | int main(int argc, char **argv) | ||
3461 | { | ||
3462 | - PROC *p; | ||
3463 | - int pid, sid = -1; | ||
3464 | - int sig = SIGKILL; | ||
3465 | + PROC *p; | ||
3466 | + int pid, sid = -1; | ||
3467 | + int sig = SIGKILL; | ||
3468 | |||
3469 | /* Get program name. */ | ||
3470 | if ((progname = strrchr(argv[0], '/')) == NULL) | ||
3471 | @@ -511,9 +571,6 @@ | ||
3472 | /* Now connect to syslog. */ | ||
3473 | openlog(progname, LOG_CONS|LOG_PID, LOG_DAEMON); | ||
3474 | |||
3475 | - /* First get the /proc filesystem online. */ | ||
3476 | - mount_proc(); | ||
3477 | - | ||
3478 | /* Were we called as 'pidof' ? */ | ||
3479 | if (strcmp(progname, "pidof") == 0) | ||
3480 | return main_pidof(argc, argv); | ||
3481 | @@ -525,6 +582,9 @@ | ||
3482 | if ((sig = atoi(argv[1])) <= 0 || sig > 31) usage(); | ||
3483 | } | ||
3484 | |||
3485 | + /* First get the /proc filesystem online. */ | ||
3486 | + mount_proc(); | ||
3487 | + | ||
3488 | /* | ||
3489 | * Ignoring SIGKILL and SIGSTOP do not make sense, but | ||
3490 | * someday kill(-1, sig) might kill ourself if we don't | ||
3491 | @@ -537,24 +597,19 @@ | ||
3492 | |||
3493 | /* Now stop all processes. */ | ||
3494 | kill(-1, SIGSTOP); | ||
3495 | - stopped = 1; | ||
3496 | + sent_sigstop = 1; | ||
3497 | |||
3498 | - /* Find out our own 'sid'. */ | ||
3499 | + /* Read /proc filesystem */ | ||
3500 | if (readproc() < 0) { | ||
3501 | kill(-1, SIGCONT); | ||
3502 | exit(1); | ||
3503 | } | ||
3504 | |||
3505 | - pid = getpid(); | ||
3506 | - for (p = plist; p; p = p->next) | ||
3507 | - if (p->pid == pid) { | ||
3508 | - sid = p->sid; | ||
3509 | - break; | ||
3510 | - } | ||
3511 | - | ||
3512 | /* Now kill all processes except our session. */ | ||
3513 | + sid = (int)getsid(0); | ||
3514 | + pid = (int)getpid(); | ||
3515 | for (p = plist; p; p = p->next) | ||
3516 | - if (p->pid != pid && p->sid != sid) | ||
3517 | + if (p->pid != pid && p->sid != sid && !p->kernel) | ||
3518 | kill(p->pid, sig); | ||
3519 | |||
3520 | /* And let them continue. */ | ||
3521 | Binary files sysvinit-2.85/src/last and sysvinit-2.86/src/last differ | ||
3522 | diff -urNd -urNd sysvinit-2.85/src/last.c sysvinit-2.86/src/last.c | ||
3523 | --- sysvinit-2.85/src/last.c 2003-04-17 06:38:56.000000000 -0500 | ||
3524 | +++ sysvinit-2.86/src/last.c 2004-07-30 07:16:26.000000000 -0500 | ||
3525 | @@ -6,10 +6,10 @@ | ||
3526 | * | ||
3527 | * Author: Miquel van Smoorenburg, miquels@cistron.nl | ||
3528 | * | ||
3529 | - * Version: @(#)last 2.85 16-Apr-2003 miquels@cistron.nl | ||
3530 | + * Version: @(#)last 2.85 30-Jul-2004 miquels@cistron.nl | ||
3531 | * | ||
3532 | * This file is part of the sysvinit suite, | ||
3533 | - * Copyright 1991-2003 Miquel van Smoorenburg. | ||
3534 | + * Copyright 1991-2004 Miquel van Smoorenburg. | ||
3535 | * | ||
3536 | * This program is free software; you can redistribute it and/or | ||
3537 | * modify it under the terms of the GNU General Public License | ||
3538 | @@ -40,7 +40,7 @@ | ||
3539 | # define SHUTDOWN_TIME 254 | ||
3540 | #endif | ||
3541 | |||
3542 | -char *Version = "@(#) last 2.85 16-Apr-2003 miquels"; | ||
3543 | +char *Version = "@(#) last 2.85 31-Apr-2004 miquels"; | ||
3544 | |||
3545 | #define CHOP_DOMAIN 0 /* Define to chop off local domainname. */ | ||
3546 | #define NEW_UTMP 1 /* Fancy & fast utmp read code. */ | ||
3547 | @@ -491,10 +491,48 @@ | ||
3548 | void usage(char *s) | ||
3549 | { | ||
3550 | fprintf(stderr, "Usage: %s [-num | -n num] [-f file] " | ||
3551 | + "[-t YYYYMMDDHHMMSS] " | ||
3552 | "[-R] [-x] [-o] [username..] [tty..]\n", s); | ||
3553 | exit(1); | ||
3554 | } | ||
3555 | |||
3556 | +time_t parsetm(char *ts) | ||
3557 | +{ | ||
3558 | + struct tm u = {0}, origu; | ||
3559 | + time_t tm; | ||
3560 | + | ||
3561 | + if (sscanf(ts, "%4d%2d%2d%2d%2d%2d", &u.tm_year, | ||
3562 | + &u.tm_mon, &u.tm_mday, &u.tm_hour, &u.tm_min, | ||
3563 | + &u.tm_sec) != 6) | ||
3564 | + return (time_t)-1; | ||
3565 | + | ||
3566 | + u.tm_year -= 1900; | ||
3567 | + u.tm_mon -= 1; | ||
3568 | + u.tm_isdst = -1; | ||
3569 | + | ||
3570 | + origu = u; | ||
3571 | + | ||
3572 | + if ((tm = mktime(&u)) == (time_t)-1) | ||
3573 | + return tm; | ||
3574 | + | ||
3575 | + /* | ||
3576 | + * Unfortunately mktime() is much more forgiving than | ||
3577 | + * it should be. For example, it'll gladly accept | ||
3578 | + * "30" as a valid month number. This behavior is by | ||
3579 | + * design, but we don't like it, so we want to detect | ||
3580 | + * it and complain. | ||
3581 | + */ | ||
3582 | + if (u.tm_year != origu.tm_year || | ||
3583 | + u.tm_mon != origu.tm_mon || | ||
3584 | + u.tm_mday != origu.tm_mday || | ||
3585 | + u.tm_hour != origu.tm_hour || | ||
3586 | + u.tm_min != origu.tm_min || | ||
3587 | + u.tm_sec != origu.tm_sec) | ||
3588 | + return (time_t)-1; | ||
3589 | + | ||
3590 | + return tm; | ||
3591 | +} | ||
3592 | + | ||
3593 | int main(int argc, char **argv) | ||
3594 | { | ||
3595 | FILE *fp; /* Filepointer of wtmp file */ | ||
3596 | @@ -518,10 +556,12 @@ | ||
3597 | int extended = 0; /* Lots of info. */ | ||
3598 | char *altufile = NULL;/* Alternate wtmp */ | ||
3599 | |||
3600 | + time_t until = 0; /* at what time to stop parsing the file */ | ||
3601 | + | ||
3602 | progname = mybasename(argv[0]); | ||
3603 | |||
3604 | /* Process the arguments. */ | ||
3605 | - while((c = getopt(argc, argv, "f:n:Rxadio0123456789")) != EOF) | ||
3606 | + while((c = getopt(argc, argv, "f:n:Rxadiot:0123456789")) != EOF) | ||
3607 | switch(c) { | ||
3608 | case 'R': | ||
3609 | showhost = 0; | ||
3610 | @@ -552,6 +592,13 @@ | ||
3611 | case 'a': | ||
3612 | altlist++; | ||
3613 | break; | ||
3614 | + case 't': | ||
3615 | + if ((until = parsetm(optarg)) == (time_t)-1) { | ||
3616 | + fprintf(stderr, "%s: Invalid time value \"%s\"\n", | ||
3617 | + progname, optarg); | ||
3618 | + usage(progname); | ||
3619 | + } | ||
3620 | + break; | ||
3621 | case '0': case '1': case '2': case '3': case '4': | ||
3622 | case '5': case '6': case '7': case '8': case '9': | ||
3623 | maxrecs = 10*maxrecs + c - '0'; | ||
3624 | @@ -650,6 +697,9 @@ | ||
3625 | if (uread(fp, &ut, &quit) != 1) | ||
3626 | break; | ||
3627 | |||
3628 | + if (until && until < ut.ut_time) | ||
3629 | + continue; | ||
3630 | + | ||
3631 | if (memcmp(&ut, &oldut, sizeof(struct utmp)) == 0) continue; | ||
3632 | memcpy(&oldut, &ut, sizeof(struct utmp)); | ||
3633 | lastdate = ut.ut_time; | ||
3634 | Binary files sysvinit-2.85/src/last.o and sysvinit-2.86/src/last.o differ | ||
3635 | Binary files sysvinit-2.85/src/mesg and sysvinit-2.86/src/mesg differ | ||
3636 | Binary files sysvinit-2.85/src/mesg.o and sysvinit-2.86/src/mesg.o differ | ||
3637 | Binary files sysvinit-2.85/src/mountpoint and sysvinit-2.86/src/mountpoint differ | ||
3638 | diff -urNd -urNd sysvinit-2.85/src/mountpoint.c sysvinit-2.86/src/mountpoint.c | ||
3639 | --- sysvinit-2.85/src/mountpoint.c 1969-12-31 18:00:00.000000000 -0600 | ||
3640 | +++ sysvinit-2.86/src/mountpoint.c 2004-06-09 07:47:45.000000000 -0500 | ||
3641 | @@ -0,0 +1,119 @@ | ||
3642 | +/* | ||
3643 | + * mountpoint See if a directory is a mountpoint. | ||
3644 | + * | ||
3645 | + * Author: Miquel van Smoorenburg. | ||
3646 | + * | ||
3647 | + * Version: @(#)mountpoint 2.85-12 17-Mar-2004 miquels@cistron.nl | ||
3648 | + * | ||
3649 | + * This file is part of the sysvinit suite, | ||
3650 | + * Copyright 1991-2004 Miquel van Smoorenburg. | ||
3651 | + * | ||
3652 | + * This program is free software; you can redistribute it and/or | ||
3653 | + * modify it under the terms of the GNU General Public License | ||
3654 | + * as published by the Free Software Foundation; either version | ||
3655 | + * 2 of the License, or (at your option) any later version. | ||
3656 | + */ | ||
3657 | + | ||
3658 | +#include <sys/stat.h> | ||
3659 | +#include <unistd.h> | ||
3660 | +#include <stdlib.h> | ||
3661 | +#include <string.h> | ||
3662 | +#include <errno.h> | ||
3663 | +#include <stdarg.h> | ||
3664 | +#include <getopt.h> | ||
3665 | +#include <stdio.h> | ||
3666 | + | ||
3667 | +int dostat(char *path, struct stat *st, int do_lstat, int quiet) | ||
3668 | +{ | ||
3669 | + int n; | ||
3670 | + | ||
3671 | + if (do_lstat) | ||
3672 | + n = lstat(path, st); | ||
3673 | + else | ||
3674 | + n = stat(path, st); | ||
3675 | + | ||
3676 | + if (n != 0) { | ||
3677 | + if (!quiet) | ||
3678 | + fprintf(stderr, "mountpoint: %s: %s\n", path, | ||
3679 | + strerror(errno)); | ||
3680 | + return -1; | ||
3681 | + } | ||
3682 | + return 0; | ||
3683 | +} | ||
3684 | + | ||
3685 | +void usage(void) { | ||
3686 | + fprintf(stderr, "Usage: mountpoint [-q] [-d] [-x] path\n"); | ||
3687 | + exit(1); | ||
3688 | +} | ||
3689 | + | ||
3690 | +int main(int argc, char **argv) | ||
3691 | +{ | ||
3692 | + struct stat st, st2; | ||
3693 | + char buf[256]; | ||
3694 | + char *path; | ||
3695 | + int quiet = 0; | ||
3696 | + int showdev = 0; | ||
3697 | + int xdev = 0; | ||
3698 | + int c, r; | ||
3699 | + | ||
3700 | + while ((c = getopt(argc, argv, "dqx")) != EOF) switch(c) { | ||
3701 | + case 'd': | ||
3702 | + showdev = 1; | ||
3703 | + break; | ||
3704 | + case 'q': | ||
3705 | + quiet = 1; | ||
3706 | + break; | ||
3707 | + case 'x': | ||
3708 | + xdev = 1; | ||
3709 | + break; | ||
3710 | + default: | ||
3711 | + usage(); | ||
3712 | + break; | ||
3713 | + } | ||
3714 | + if (optind != argc - 1) usage(); | ||
3715 | + path = argv[optind]; | ||
3716 | + | ||
3717 | + if (dostat(path, &st, !xdev, quiet) < 0) | ||
3718 | + return 1; | ||
3719 | + | ||
3720 | + if (xdev) { | ||
3721 | +#ifdef __linux__ | ||
3722 | + if (!S_ISBLK(st.st_mode)) | ||
3723 | +#else | ||
3724 | + if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) | ||
3725 | +#endif | ||
3726 | + { | ||
3727 | + if (quiet) | ||
3728 | + printf("\n"); | ||
3729 | + else | ||
3730 | + fprintf(stderr, "mountpoint: %s: not a block device\n", | ||
3731 | + path); | ||
3732 | + return 1; | ||
3733 | + } | ||
3734 | + printf("%u:%u\n", major(st.st_rdev), minor(st.st_rdev)); | ||
3735 | + return 0; | ||
3736 | + } | ||
3737 | + | ||
3738 | + if (!S_ISDIR(st.st_mode)) { | ||
3739 | + if (!quiet) | ||
3740 | + fprintf(stderr, "mountpoint: %s: not a directory\n", | ||
3741 | + path); | ||
3742 | + return 1; | ||
3743 | + } | ||
3744 | + | ||
3745 | + memset(buf, 0, sizeof(buf)); | ||
3746 | + strncpy(buf, path, sizeof(buf) - 4); | ||
3747 | + strcat(buf, "/.."); | ||
3748 | + if (dostat(buf, &st2, 0, quiet) < 0) | ||
3749 | + return 1; | ||
3750 | + | ||
3751 | + r = (st.st_dev != st2.st_dev) || | ||
3752 | + (st.st_dev == st2.st_dev && st.st_ino == st2.st_ino); | ||
3753 | + | ||
3754 | + if (!quiet && !showdev) | ||
3755 | + printf("%s is %sa mountpoint\n", path, r ? "" : "not "); | ||
3756 | + if (showdev) | ||
3757 | + printf("%u:%u\n", major(st.st_dev), minor(st.st_dev)); | ||
3758 | + | ||
3759 | + return r ? 0 : 1; | ||
3760 | +} | ||
3761 | Binary files sysvinit-2.85/src/mountpoint.o and sysvinit-2.86/src/mountpoint.o differ | ||
3762 | diff -urNd -urNd sysvinit-2.85/src/paths.h sysvinit-2.86/src/paths.h | ||
3763 | --- sysvinit-2.85/src/paths.h 2003-04-14 06:37:01.000000000 -0500 | ||
3764 | +++ sysvinit-2.86/src/paths.h 2004-06-09 07:47:45.000000000 -0500 | ||
3765 | @@ -1,7 +1,7 @@ | ||
3766 | /* | ||
3767 | * paths.h Paths of files that init and related utilities need. | ||
3768 | * | ||
3769 | - * Version: @(#) paths.h 2.84 27-Nov-2001 | ||
3770 | + * Version: @(#) paths.h 2.85-8 05-Nov-2003 | ||
3771 | * | ||
3772 | * Author: Miquel van Smoorenburg, <miquels@cistron.nl> | ||
3773 | * | ||
3774 | @@ -24,6 +24,7 @@ | ||
3775 | #define FORCEFSCK "/forcefsck" /* Force fsck on boot */ | ||
3776 | #define SDPID "/var/run/shutdown.pid" /* PID of shutdown program */ | ||
3777 | #define SHELL "/bin/sh" /* Default shell */ | ||
3778 | +#define SULOGIN "/sbin/sulogin" /* Sulogin */ | ||
3779 | #define INITSCRIPT "/etc/initscript" /* Initscript. */ | ||
3780 | #define PWRSTAT "/etc/powerstatus" /* COMPAT: SIGPWR reason (OK/BAD) */ | ||
3781 | |||
3782 | diff -urNd -urNd sysvinit-2.85/src/reboot.h sysvinit-2.86/src/reboot.h | ||
3783 | --- sysvinit-2.85/src/reboot.h 1997-09-24 03:55:52.000000000 -0500 | ||
3784 | +++ sysvinit-2.86/src/reboot.h 2004-06-09 07:47:45.000000000 -0500 | ||
3785 | @@ -2,22 +2,35 @@ | ||
3786 | * reboot.h Headerfile that defines how to handle | ||
3787 | * the reboot() system call. | ||
3788 | * | ||
3789 | - * Version: @(#)reboot.h 1.00 23-Jul-1996 miquels@cistron.nl | ||
3790 | + * Version: @(#)reboot.h 2.85-17 04-Jun-2004 miquels@cistron.nl | ||
3791 | * | ||
3792 | */ | ||
3793 | |||
3794 | -#if defined(__GLIBC__) | ||
3795 | -# include <sys/reboot.h> | ||
3796 | +#include <sys/reboot.h> | ||
3797 | + | ||
3798 | +#ifdef RB_ENABLE_CAD | ||
3799 | +# define BMAGIC_HARD RB_ENABLE_CAD | ||
3800 | #endif | ||
3801 | |||
3802 | -#define BMAGIC_HARD 0x89ABCDEF | ||
3803 | -#define BMAGIC_SOFT 0 | ||
3804 | -#define BMAGIC_REBOOT 0x01234567 | ||
3805 | -#define BMAGIC_HALT 0xCDEF0123 | ||
3806 | -#define BMAGIC_POWEROFF 0x4321FEDC | ||
3807 | +#ifdef RB_DISABLE_CAD | ||
3808 | +# define BMAGIC_SOFT RB_DISABLE_CAD | ||
3809 | +#endif | ||
3810 | |||
3811 | -#if defined(__GLIBC__) | ||
3812 | - #define init_reboot(magic) reboot(magic) | ||
3813 | +#ifdef RB_HALT_SYSTEM | ||
3814 | +# define BMAGIC_HALT RB_HALT_SYSTEM | ||
3815 | #else | ||
3816 | - #define init_reboot(magic) reboot(0xfee1dead, 672274793, magic) | ||
3817 | +# define BMAGIC_HALT RB_HALT | ||
3818 | #endif | ||
3819 | + | ||
3820 | +#define BMAGIC_REBOOT RB_AUTOBOOT | ||
3821 | + | ||
3822 | +#ifdef RB_POWER_OFF | ||
3823 | +# define BMAGIC_POWEROFF RB_POWER_OFF | ||
3824 | +#elif defined(RB_POWEROFF) | ||
3825 | +# define BMAGIC_POWEROFF RB_POWEROFF | ||
3826 | +#else | ||
3827 | +# define BMAGIC_POWEROFF BMAGIC_HALT | ||
3828 | +#endif | ||
3829 | + | ||
3830 | +#define init_reboot(magic) reboot(magic) | ||
3831 | + | ||
3832 | Binary files sysvinit-2.85/src/runlevel and sysvinit-2.86/src/runlevel differ | ||
3833 | Binary files sysvinit-2.85/src/runlevel.o and sysvinit-2.86/src/runlevel.o differ | ||
3834 | Binary files sysvinit-2.85/src/shutdown and sysvinit-2.86/src/shutdown differ | ||
3835 | diff -urNd -urNd sysvinit-2.85/src/shutdown.c sysvinit-2.86/src/shutdown.c | ||
3836 | --- sysvinit-2.85/src/shutdown.c 2003-04-14 06:35:51.000000000 -0500 | ||
3837 | +++ sysvinit-2.86/src/shutdown.c 2004-07-30 06:59:04.000000000 -0500 | ||
3838 | @@ -13,10 +13,10 @@ | ||
3839 | * | ||
3840 | * Author: Miquel van Smoorenburg, miquels@cistron.nl | ||
3841 | * | ||
3842 | - * Version: @(#)shutdown 2.85 14-Apr-2003 miquels@cistron.nl | ||
3843 | + * Version: @(#)shutdown 2.86-1 31-Jul-2004 miquels@cistron.nl | ||
3844 | * | ||
3845 | * This file is part of the sysvinit suite, | ||
3846 | - * Copyright 1991-2003 Miquel van Smoorenburg. | ||
3847 | + * Copyright 1991-2004 Miquel van Smoorenburg. | ||
3848 | * | ||
3849 | * This program is free software; you can redistribute it and/or | ||
3850 | * modify it under the terms of the GNU General Public License | ||
3851 | @@ -36,10 +36,12 @@ | ||
3852 | #include <fcntl.h> | ||
3853 | #include <stdarg.h> | ||
3854 | #include <utmp.h> | ||
3855 | +#include <syslog.h> | ||
3856 | #include "paths.h" | ||
3857 | #include "reboot.h" | ||
3858 | +#include "initreq.h" | ||
3859 | |||
3860 | -char *Version = "@(#) shutdown 2.85 14-Apr-2003 miquels@cistron.nl"; | ||
3861 | +char *Version = "@(#) shutdown 2.86-1 31-Jul-2004 miquels@cistron.nl"; | ||
3862 | |||
3863 | #define MESSAGELEN 256 | ||
3864 | |||
3865 | @@ -52,6 +54,7 @@ | ||
3866 | char *sltime = 0; /* Sleep time */ | ||
3867 | char newstate[64]; /* What are we gonna do */ | ||
3868 | int doself = 0; /* Don't use init */ | ||
3869 | +int got_alrm = 0; | ||
3870 | |||
3871 | char *clean_env[] = { | ||
3872 | "HOME=/", | ||
3873 | @@ -67,93 +70,152 @@ | ||
3874 | extern void write_wtmp(char *user, char *id, int pid, int type, char *line); | ||
3875 | |||
3876 | /* | ||
3877 | - * Sleep without being interrupted. | ||
3878 | + * Sleep without being interrupted. | ||
3879 | */ | ||
3880 | void hardsleep(int secs) | ||
3881 | { | ||
3882 | - struct timespec ts, rem; | ||
3883 | + struct timespec ts, rem; | ||
3884 | |||
3885 | - ts.tv_sec = secs; | ||
3886 | - ts.tv_nsec = 0; | ||
3887 | + ts.tv_sec = secs; | ||
3888 | + ts.tv_nsec = 0; | ||
3889 | |||
3890 | - while(nanosleep(&ts, &rem) < 0 && errno == EINTR) | ||
3891 | + while(nanosleep(&ts, &rem) < 0 && errno == EINTR) | ||
3892 | ts = rem; | ||
3893 | } | ||
3894 | |||
3895 | /* | ||
3896 | - * Break off an already running shutdown. | ||
3897 | + * Break off an already running shutdown. | ||
3898 | */ | ||
3899 | -void stopit() | ||
3900 | +void stopit(int sig) | ||
3901 | { | ||
3902 | - unlink(NOLOGIN); | ||
3903 | - unlink(FASTBOOT); | ||
3904 | - unlink(FORCEFSCK); | ||
3905 | - unlink(SDPID); | ||
3906 | - printf("\r\nShutdown cancelled.\r\n"); | ||
3907 | - exit(0); | ||
3908 | + unlink(NOLOGIN); | ||
3909 | + unlink(FASTBOOT); | ||
3910 | + unlink(FORCEFSCK); | ||
3911 | + unlink(SDPID); | ||
3912 | + printf("\r\nShutdown cancelled.\r\n"); | ||
3913 | + exit(0); | ||
3914 | } | ||
3915 | |||
3916 | /* | ||
3917 | - * Show usage message. | ||
3918 | + * Show usage message. | ||
3919 | */ | ||
3920 | -void usage() | ||
3921 | +void usage(void) | ||
3922 | { | ||
3923 | - fprintf(stderr, | ||
3924 | - "Usage:\t shutdown [-akrhfnc] [-t secs] time [warning message]\n" | ||
3925 | + fprintf(stderr, | ||
3926 | + "Usage:\t shutdown [-akrhHPfnc] [-t secs] time [warning message]\n" | ||
3927 | "\t\t -a: use /etc/shutdown.allow\n" | ||
3928 | "\t\t -k: don't really shutdown, only warn.\n" | ||
3929 | "\t\t -r: reboot after shutdown.\n" | ||
3930 | "\t\t -h: halt after shutdown.\n" | ||
3931 | + "\t\t -P: halt action is to turn off power.\n" | ||
3932 | + "\t\t -H: halt action is to just halt.\n" | ||
3933 | "\t\t -f: do a 'fast' reboot (skip fsck).\n" | ||
3934 | "\t\t -F: Force fsck on reboot.\n" | ||
3935 | "\t\t -n: do not go through \"init\" but go down real fast.\n" | ||
3936 | "\t\t -c: cancel a running shutdown.\n" | ||
3937 | "\t\t -t secs: delay between warning and kill signal.\n" | ||
3938 | "\t\t ** the \"time\" argument is mandatory! (try \"now\") **\n"); | ||
3939 | - exit(1); | ||
3940 | + exit(1); | ||
3941 | } | ||
3942 | |||
3943 | + | ||
3944 | +void alrm_handler(int sig) | ||
3945 | +{ | ||
3946 | + got_alrm = sig; | ||
3947 | +} | ||
3948 | + | ||
3949 | + | ||
3950 | /* | ||
3951 | - * Tell everyone the system is going down in 'mins' minutes. | ||
3952 | + * Set environment variables in the init process. | ||
3953 | */ | ||
3954 | -void warn(mins) | ||
3955 | -int mins; | ||
3956 | +int init_setenv(char *name, char *value) | ||
3957 | { | ||
3958 | - char buf[MESSAGELEN + sizeof(newstate)]; | ||
3959 | - int len; | ||
3960 | + struct init_request request; | ||
3961 | + struct sigaction sa; | ||
3962 | + int fd; | ||
3963 | + int nl, vl; | ||
3964 | |||
3965 | - buf[0] = 0; | ||
3966 | - strncat(buf, message, sizeof(buf) - 1); | ||
3967 | - len = strlen(buf); | ||
3968 | + memset(&request, 0, sizeof(request)); | ||
3969 | + request.magic = INIT_MAGIC; | ||
3970 | + request.cmd = INIT_CMD_SETENV; | ||
3971 | + nl = strlen(name); | ||
3972 | + vl = value ? strlen(value) : 0; | ||
3973 | |||
3974 | - if (mins == 0) | ||
3975 | - snprintf(buf + len, sizeof(buf) - len, | ||
3976 | - "\rThe system is going down %s NOW!\r\n", | ||
3977 | - newstate); | ||
3978 | - else | ||
3979 | - snprintf(buf + len, sizeof(buf) - len, | ||
3980 | - "\rThe system is going DOWN %s in %d minute%s!\r\n", | ||
3981 | - newstate, mins, mins == 1 ? "" : "s"); | ||
3982 | - wall(buf, 1, 0); | ||
3983 | + if (nl + vl + 3 >= sizeof(request.i.data)) | ||
3984 | + return -1; | ||
3985 | + | ||
3986 | + memcpy(request.i.data, name, nl); | ||
3987 | + if (value) { | ||
3988 | + request.i.data[nl] = '='; | ||
3989 | + memcpy(request.i.data + nl + 1, value, vl); | ||
3990 | + } | ||
3991 | + | ||
3992 | + /* | ||
3993 | + * Open the fifo and write the command. | ||
3994 | + * Make sure we don't hang on opening /dev/initctl | ||
3995 | + */ | ||
3996 | + memset(&sa, 0, sizeof(sa)); | ||
3997 | + sa.sa_handler = alrm_handler; | ||
3998 | + sigaction(SIGALRM, &sa, NULL); | ||
3999 | + got_alrm = 0; | ||
4000 | + alarm(3); | ||
4001 | + if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0 && | ||
4002 | + write(fd, &request, sizeof(request)) == sizeof(request)) { | ||
4003 | + close(fd); | ||
4004 | + alarm(0); | ||
4005 | + return 0; | ||
4006 | + } | ||
4007 | + | ||
4008 | + fprintf(stderr, "shutdown: "); | ||
4009 | + if (got_alrm) { | ||
4010 | + fprintf(stderr, "timeout opening/writing control channel %s\n", | ||
4011 | + INIT_FIFO); | ||
4012 | + } else { | ||
4013 | + perror(INIT_FIFO); | ||
4014 | + } | ||
4015 | + return -1; | ||
4016 | } | ||
4017 | |||
4018 | + | ||
4019 | /* | ||
4020 | - * Create the /etc/nologin file. | ||
4021 | + * Tell everyone the system is going down in 'mins' minutes. | ||
4022 | + */ | ||
4023 | +void warn(int mins) | ||
4024 | +{ | ||
4025 | + char buf[MESSAGELEN + sizeof(newstate)]; | ||
4026 | + int len; | ||
4027 | + | ||
4028 | + buf[0] = 0; | ||
4029 | + strncat(buf, message, sizeof(buf) - 1); | ||
4030 | + len = strlen(buf); | ||
4031 | + | ||
4032 | + if (mins == 0) | ||
4033 | + snprintf(buf + len, sizeof(buf) - len, | ||
4034 | + "\rThe system is going down %s NOW!\r\n", | ||
4035 | + newstate); | ||
4036 | + else | ||
4037 | + snprintf(buf + len, sizeof(buf) - len, | ||
4038 | + "\rThe system is going DOWN %s in %d minute%s!\r\n", | ||
4039 | + newstate, mins, mins == 1 ? "" : "s"); | ||
4040 | + wall(buf, 1, 0); | ||
4041 | +} | ||
4042 | + | ||
4043 | +/* | ||
4044 | + * Create the /etc/nologin file. | ||
4045 | */ | ||
4046 | void donologin(int min) | ||
4047 | { | ||
4048 | - FILE *fp; | ||
4049 | - time_t t; | ||
4050 | + FILE *fp; | ||
4051 | + time_t t; | ||
4052 | |||
4053 | - time(&t); | ||
4054 | - t += 60 * min; | ||
4055 | + time(&t); | ||
4056 | + t += 60 * min; | ||
4057 | |||
4058 | - unlink(NOLOGIN); | ||
4059 | - if ((fp = fopen(NOLOGIN, "w")) != NULL) { | ||
4060 | - fprintf(fp, "\rThe system is going down on %s\r\n", ctime(&t)); | ||
4061 | - if (message[0]) fputs(message, fp); | ||
4062 | - fclose(fp); | ||
4063 | - } | ||
4064 | + if ((fp = fopen(NOLOGIN, "w")) != NULL) { | ||
4065 | + fprintf(fp, "\rThe system is going down on %s\r\n", ctime(&t)); | ||
4066 | + if (message[0]) fputs(message, fp); | ||
4067 | + fclose(fp); | ||
4068 | + } | ||
4069 | } | ||
4070 | |||
4071 | /* | ||
4072 | @@ -202,131 +264,146 @@ | ||
4073 | return 0; | ||
4074 | } | ||
4075 | |||
4076 | -/* Kill all processes, call /etc/init.d/halt (if present) */ | ||
4077 | +/* | ||
4078 | + * Kill all processes, call /etc/init.d/halt (if present) | ||
4079 | + */ | ||
4080 | void fastdown() | ||
4081 | { | ||
4082 | - int do_halt = (down_level[0] == '0'); | ||
4083 | - int i; | ||
4084 | + int do_halt = (down_level[0] == '0'); | ||
4085 | + int i; | ||
4086 | #if 0 | ||
4087 | - char cmd[128]; | ||
4088 | - char *script; | ||
4089 | + char cmd[128]; | ||
4090 | + char *script; | ||
4091 | |||
4092 | - /* Currently, the halt script is either init.d/halt OR rc.d/rc.0, | ||
4093 | - * likewise for the reboot script. Test for the presence | ||
4094 | - * of either. | ||
4095 | - */ | ||
4096 | - if (do_halt) { | ||
4097 | - if (access(HALTSCRIPT1, X_OK) == 0) | ||
4098 | - script = HALTSCRIPT1; | ||
4099 | - else | ||
4100 | - script = HALTSCRIPT2; | ||
4101 | - } else { | ||
4102 | - if (access(REBOOTSCRIPT1, X_OK) == 0) | ||
4103 | - script = REBOOTSCRIPT1; | ||
4104 | - else | ||
4105 | - script = REBOOTSCRIPT2; | ||
4106 | - } | ||
4107 | + /* | ||
4108 | + * Currently, the halt script is either init.d/halt OR rc.d/rc.0, | ||
4109 | + * likewise for the reboot script. Test for the presence | ||
4110 | + * of either. | ||
4111 | + */ | ||
4112 | + if (do_halt) { | ||
4113 | + if (access(HALTSCRIPT1, X_OK) == 0) | ||
4114 | + script = HALTSCRIPT1; | ||
4115 | + else | ||
4116 | + script = HALTSCRIPT2; | ||
4117 | + } else { | ||
4118 | + if (access(REBOOTSCRIPT1, X_OK) == 0) | ||
4119 | + script = REBOOTSCRIPT1; | ||
4120 | + else | ||
4121 | + script = REBOOTSCRIPT2; | ||
4122 | + } | ||
4123 | #endif | ||
4124 | |||
4125 | - /* First close all files. */ | ||
4126 | - for(i = 0; i < 3; i++) | ||
4127 | - if (!isatty(i)) { | ||
4128 | - close(i); | ||
4129 | - open("/dev/null", O_RDWR); | ||
4130 | - } | ||
4131 | - for(i = 3; i < 20; i++) close(i); | ||
4132 | - close(255); | ||
4133 | + /* First close all files. */ | ||
4134 | + for(i = 0; i < 3; i++) | ||
4135 | + if (!isatty(i)) { | ||
4136 | + close(i); | ||
4137 | + open("/dev/null", O_RDWR); | ||
4138 | + } | ||
4139 | + for(i = 3; i < 20; i++) close(i); | ||
4140 | + close(255); | ||
4141 | |||
4142 | - /* First idle init. */ | ||
4143 | - if (kill(1, SIGTSTP) < 0) { | ||
4144 | - fprintf(stderr, "shutdown: can't idle init.\r\n"); | ||
4145 | - exit(1); | ||
4146 | - } | ||
4147 | + /* First idle init. */ | ||
4148 | + if (kill(1, SIGTSTP) < 0) { | ||
4149 | + fprintf(stderr, "shutdown: can't idle init.\r\n"); | ||
4150 | + exit(1); | ||
4151 | + } | ||
4152 | |||
4153 | - /* Kill all processes. */ | ||
4154 | - fprintf(stderr, "shutdown: sending all processes the TERM signal...\r\n"); | ||
4155 | - (void) kill(-1, SIGTERM); | ||
4156 | - if (sltime) | ||
4157 | - sleep(atoi(sltime)); | ||
4158 | - else | ||
4159 | - sleep(3); | ||
4160 | - fprintf(stderr, "shutdown: sending all processes the KILL signal.\r\n"); | ||
4161 | - (void) kill(-1, SIGKILL); | ||
4162 | + /* Kill all processes. */ | ||
4163 | + fprintf(stderr, "shutdown: sending all processes the TERM signal...\r\n"); | ||
4164 | + kill(-1, SIGTERM); | ||
4165 | + sleep(sltime ? atoi(sltime) : 3); | ||
4166 | + fprintf(stderr, "shutdown: sending all processes the KILL signal.\r\n"); | ||
4167 | + (void) kill(-1, SIGKILL); | ||
4168 | |||
4169 | #if 0 | ||
4170 | - /* See if we can run /etc/init.d/halt */ | ||
4171 | - if (access(script, X_OK) == 0) { | ||
4172 | - spawn(1, cmd, "fast", NULL); | ||
4173 | - fprintf(stderr, "shutdown: %s returned - falling back on default routines\r\n", script); | ||
4174 | - } | ||
4175 | + /* See if we can run /etc/init.d/halt */ | ||
4176 | + if (access(script, X_OK) == 0) { | ||
4177 | + spawn(1, cmd, "fast", NULL); | ||
4178 | + fprintf(stderr, "shutdown: %s returned - falling back " | ||
4179 | + "on default routines\r\n", script); | ||
4180 | + } | ||
4181 | #endif | ||
4182 | |||
4183 | - /* script failed or not present: do it ourself. */ | ||
4184 | - sleep(1); /* Give init the chance to collect zombies. */ | ||
4185 | + /* script failed or not present: do it ourself. */ | ||
4186 | + sleep(1); /* Give init the chance to collect zombies. */ | ||
4187 | |||
4188 | - /* Record the fact that we're going down */ | ||
4189 | - write_wtmp("shutdown", "~~", 0, RUN_LVL, "~~"); | ||
4190 | + /* Record the fact that we're going down */ | ||
4191 | + write_wtmp("shutdown", "~~", 0, RUN_LVL, "~~"); | ||
4192 | |||
4193 | - /* This is for those who have quota installed. */ | ||
4194 | - spawn(1, "accton", NULL); | ||
4195 | - spawn(1, "quotaoff", "-a", NULL); | ||
4196 | + /* This is for those who have quota installed. */ | ||
4197 | + spawn(1, "accton", NULL); | ||
4198 | + spawn(1, "quotaoff", "-a", NULL); | ||
4199 | |||
4200 | - sync(); | ||
4201 | - fprintf(stderr, "shutdown: turning off swap\r\n"); | ||
4202 | - spawn(0, "swapoff", "-a", NULL); | ||
4203 | - fprintf(stderr, "shutdown: unmounting all file systems\r\n"); | ||
4204 | - spawn(0, "umount", "-a", NULL); | ||
4205 | + sync(); | ||
4206 | + fprintf(stderr, "shutdown: turning off swap\r\n"); | ||
4207 | + spawn(0, "swapoff", "-a", NULL); | ||
4208 | + fprintf(stderr, "shutdown: unmounting all file systems\r\n"); | ||
4209 | + spawn(0, "umount", "-a", NULL); | ||
4210 | |||
4211 | - /* We're done, halt or reboot now. */ | ||
4212 | - if (do_halt) { | ||
4213 | - fprintf(stderr, "The system is halted. Press CTRL-ALT-DEL or turn off power\r\n"); | ||
4214 | - init_reboot(BMAGIC_HALT); | ||
4215 | + /* We're done, halt or reboot now. */ | ||
4216 | + if (do_halt) { | ||
4217 | + fprintf(stderr, "The system is halted. Press CTRL-ALT-DEL " | ||
4218 | + "or turn off power\r\n"); | ||
4219 | + init_reboot(BMAGIC_HALT); | ||
4220 | + exit(0); | ||
4221 | + } | ||
4222 | + | ||
4223 | + fprintf(stderr, "Please stand by while rebooting the system.\r\n"); | ||
4224 | + init_reboot(BMAGIC_REBOOT); | ||
4225 | exit(0); | ||
4226 | - } | ||
4227 | - fprintf(stderr, "Please stand by while rebooting the system.\r\n"); | ||
4228 | - init_reboot(BMAGIC_REBOOT); | ||
4229 | - exit(0); | ||
4230 | } | ||
4231 | |||
4232 | /* | ||
4233 | - * Go to runlevel 0, 1 or 6. | ||
4234 | + * Go to runlevel 0, 1 or 6. | ||
4235 | */ | ||
4236 | -void shutdown() | ||
4237 | +void shutdown(char *halttype) | ||
4238 | { | ||
4239 | - char *args[8]; | ||
4240 | - int argp = 0; | ||
4241 | + char *args[8]; | ||
4242 | + int argp = 0; | ||
4243 | + int do_halt = (down_level[0] == '0'); | ||
4244 | |||
4245 | - /* Warn for the last time (hehe) */ | ||
4246 | - warn(0); | ||
4247 | - if (dontshut) { | ||
4248 | - hardsleep(1); | ||
4249 | - stopit(); | ||
4250 | - } | ||
4251 | + /* Warn for the last time */ | ||
4252 | + warn(0); | ||
4253 | + if (dontshut) { | ||
4254 | + hardsleep(1); | ||
4255 | + stopit(0); | ||
4256 | + } | ||
4257 | + openlog("shutdown", LOG_PID, LOG_USER); | ||
4258 | + if (do_halt) | ||
4259 | + syslog(LOG_NOTICE, "shutting down for system halt"); | ||
4260 | + else | ||
4261 | + syslog(LOG_NOTICE, "shutting down for system reboot"); | ||
4262 | + closelog(); | ||
4263 | |||
4264 | - /* See if we have to do it ourself. */ | ||
4265 | - if (doself) fastdown(); | ||
4266 | + /* See if we have to do it ourself. */ | ||
4267 | + if (doself) fastdown(); | ||
4268 | |||
4269 | - /* Create the arguments for init. */ | ||
4270 | - args[argp++] = INIT; | ||
4271 | - if (sltime) { | ||
4272 | - args[argp++] = "-t"; | ||
4273 | - args[argp++] = sltime; | ||
4274 | - } | ||
4275 | - args[argp++] = down_level; | ||
4276 | - args[argp] = (char *)NULL; | ||
4277 | + /* Create the arguments for init. */ | ||
4278 | + args[argp++] = INIT; | ||
4279 | + if (sltime) { | ||
4280 | + args[argp++] = "-t"; | ||
4281 | + args[argp++] = sltime; | ||
4282 | + } | ||
4283 | + args[argp++] = down_level; | ||
4284 | + args[argp] = (char *)NULL; | ||
4285 | |||
4286 | - unlink(SDPID); | ||
4287 | - unlink(NOLOGIN); | ||
4288 | + unlink(SDPID); | ||
4289 | + unlink(NOLOGIN); | ||
4290 | |||
4291 | - /* Now execute init to change runlevel. */ | ||
4292 | - sync(); | ||
4293 | - execv(INIT, args); | ||
4294 | + /* Now execute init to change runlevel. */ | ||
4295 | + sync(); | ||
4296 | + init_setenv("INIT_HALT", halttype); | ||
4297 | + execv(INIT, args); | ||
4298 | |||
4299 | - /* Oops - failed. */ | ||
4300 | - fprintf(stderr, "\rshutdown: cannot execute %s\r\n", INIT); | ||
4301 | - unlink(FASTBOOT); | ||
4302 | - unlink(FORCEFSCK); | ||
4303 | - exit(1); | ||
4304 | + /* Oops - failed. */ | ||
4305 | + fprintf(stderr, "\rshutdown: cannot execute %s\r\n", INIT); | ||
4306 | + unlink(FASTBOOT); | ||
4307 | + unlink(FORCEFSCK); | ||
4308 | + init_setenv("INIT_HALT", NULL); | ||
4309 | + openlog("shutdown", LOG_PID, LOG_USER); | ||
4310 | + syslog(LOG_NOTICE, "shutdown failed"); | ||
4311 | + closelog(); | ||
4312 | + exit(1); | ||
4313 | } | ||
4314 | |||
4315 | /* | ||
4316 | @@ -349,274 +426,287 @@ | ||
4317 | } | ||
4318 | |||
4319 | /* | ||
4320 | - * Main program. | ||
4321 | - * Process the options and do the final countdown. | ||
4322 | + * Main program. | ||
4323 | + * Process the options and do the final countdown. | ||
4324 | */ | ||
4325 | -int main(argc, argv) | ||
4326 | -int argc; | ||
4327 | -char **argv; | ||
4328 | +int main(int argc, char **argv) | ||
4329 | { | ||
4330 | - extern int getopt(); | ||
4331 | - extern int optind; | ||
4332 | - int c, i, wt, hours, mins; | ||
4333 | - struct tm *lt; | ||
4334 | - time_t t; | ||
4335 | - char *sp; | ||
4336 | - char *when = NULL; | ||
4337 | - int didnolog = 0; | ||
4338 | - int cancel = 0; | ||
4339 | - int useacl = 0; | ||
4340 | - int pid = 0; | ||
4341 | - uid_t realuid; | ||
4342 | - FILE *fp; | ||
4343 | - char *downusers[32]; | ||
4344 | - char buf[128]; | ||
4345 | - char term[UT_LINESIZE + 6]; | ||
4346 | - struct stat st; | ||
4347 | - struct utmp *ut; | ||
4348 | - int user_ok = 0; | ||
4349 | - struct sigaction sa; | ||
4350 | + FILE *fp; | ||
4351 | + extern int getopt(); | ||
4352 | + extern int optind; | ||
4353 | + struct sigaction sa; | ||
4354 | + struct tm *lt; | ||
4355 | + struct stat st; | ||
4356 | + struct utmp *ut; | ||
4357 | + time_t t; | ||
4358 | + uid_t realuid; | ||
4359 | + char *halttype; | ||
4360 | + char *downusers[32]; | ||
4361 | + char buf[128]; | ||
4362 | + char term[UT_LINESIZE + 6]; | ||
4363 | + char *sp; | ||
4364 | + char *when = NULL; | ||
4365 | + int c, i, wt; | ||
4366 | + int hours, mins; | ||
4367 | + int didnolog = 0; | ||
4368 | + int cancel = 0; | ||
4369 | + int useacl = 0; | ||
4370 | + int pid = 0; | ||
4371 | + int user_ok = 0; | ||
4372 | |||
4373 | - /* We can be installed setuid root (executable for a special group) */ | ||
4374 | - realuid = getuid(); | ||
4375 | - setuid(geteuid()); | ||
4376 | + /* We can be installed setuid root (executable for a special group) */ | ||
4377 | + realuid = getuid(); | ||
4378 | + setuid(geteuid()); | ||
4379 | |||
4380 | - if (getuid() != 0) { | ||
4381 | - fprintf(stderr, "shutdown: you must be root to do that!\n"); | ||
4382 | - exit(1); | ||
4383 | - } | ||
4384 | - strcpy(down_level, "1"); | ||
4385 | + if (getuid() != 0) { | ||
4386 | + fprintf(stderr, "shutdown: you must be root to do that!\n"); | ||
4387 | + exit(1); | ||
4388 | + } | ||
4389 | + strcpy(down_level, "1"); | ||
4390 | + halttype = NULL; | ||
4391 | |||
4392 | - /* Process the options. */ | ||
4393 | - while((c = getopt(argc, argv, "acqkrhnfFyt:g:i:")) != EOF) { | ||
4394 | - switch(c) { | ||
4395 | - case 'a': /* Access control. */ | ||
4396 | - useacl = 1; | ||
4397 | - break; | ||
4398 | - case 'c': /* Cancel an already running shutdown. */ | ||
4399 | - cancel = 1; | ||
4400 | - break; | ||
4401 | - case 'k': /* Don't really shutdown, only warn.*/ | ||
4402 | - dontshut = 1; | ||
4403 | - break; | ||
4404 | - case 'r': /* Automatic reboot */ | ||
4405 | - down_level[0] = '6'; | ||
4406 | - break; | ||
4407 | - case 'h': /* Halt after shutdown */ | ||
4408 | - down_level[0] = '0'; | ||
4409 | - break; | ||
4410 | - case 'f': /* Don't perform fsck after next boot */ | ||
4411 | - fastboot = 1; | ||
4412 | - break; | ||
4413 | - case 'F': /* Force fsck after next boot */ | ||
4414 | - forcefsck = 1; | ||
4415 | - break; | ||
4416 | - case 'n': /* Don't switch runlevels. */ | ||
4417 | - doself = 1; | ||
4418 | - break; | ||
4419 | - case 't': /* Delay between TERM and KILL */ | ||
4420 | - sltime = optarg; | ||
4421 | - break; | ||
4422 | - case 'y': /* Ignored for sysV compatibility */ | ||
4423 | - break; | ||
4424 | - case 'g': /* sysv style to specify time. */ | ||
4425 | - when = optarg; | ||
4426 | - down_level[0] = '0'; | ||
4427 | - break; | ||
4428 | - case 'i': /* Level to go to. */ | ||
4429 | - if (!strchr("0156aAbBcCsS", optarg[0])) { | ||
4430 | - fprintf(stderr, "shutdown: `%s': bad runlevel\n", | ||
4431 | + /* Process the options. */ | ||
4432 | + while((c = getopt(argc, argv, "HPacqkrhnfFyt:g:i:")) != EOF) { | ||
4433 | + switch(c) { | ||
4434 | + case 'H': | ||
4435 | + halttype = "HALT"; | ||
4436 | + break; | ||
4437 | + case 'P': | ||
4438 | + halttype = "POWERDOWN"; | ||
4439 | + break; | ||
4440 | + case 'a': /* Access control. */ | ||
4441 | + useacl = 1; | ||
4442 | + break; | ||
4443 | + case 'c': /* Cancel an already running shutdown. */ | ||
4444 | + cancel = 1; | ||
4445 | + break; | ||
4446 | + case 'k': /* Don't really shutdown, only warn.*/ | ||
4447 | + dontshut = 1; | ||
4448 | + break; | ||
4449 | + case 'r': /* Automatic reboot */ | ||
4450 | + down_level[0] = '6'; | ||
4451 | + break; | ||
4452 | + case 'h': /* Halt after shutdown */ | ||
4453 | + down_level[0] = '0'; | ||
4454 | + break; | ||
4455 | + case 'f': /* Don't perform fsck after next boot */ | ||
4456 | + fastboot = 1; | ||
4457 | + break; | ||
4458 | + case 'F': /* Force fsck after next boot */ | ||
4459 | + forcefsck = 1; | ||
4460 | + break; | ||
4461 | + case 'n': /* Don't switch runlevels. */ | ||
4462 | + doself = 1; | ||
4463 | + break; | ||
4464 | + case 't': /* Delay between TERM and KILL */ | ||
4465 | + sltime = optarg; | ||
4466 | + break; | ||
4467 | + case 'y': /* Ignored for sysV compatibility */ | ||
4468 | + break; | ||
4469 | + case 'g': /* sysv style to specify time. */ | ||
4470 | + when = optarg; | ||
4471 | + break; | ||
4472 | + case 'i': /* Level to go to. */ | ||
4473 | + if (!strchr("0156aAbBcCsS", optarg[0])) { | ||
4474 | + fprintf(stderr, | ||
4475 | + "shutdown: `%s': bad runlevel\n", | ||
4476 | optarg); | ||
4477 | - exit(1); | ||
4478 | - } | ||
4479 | - down_level[0] = optarg[0]; | ||
4480 | - break; | ||
4481 | - default: | ||
4482 | - usage(); | ||
4483 | - break; | ||
4484 | - } | ||
4485 | - } | ||
4486 | + exit(1); | ||
4487 | + } | ||
4488 | + down_level[0] = optarg[0]; | ||
4489 | + break; | ||
4490 | + default: | ||
4491 | + usage(); | ||
4492 | + break; | ||
4493 | + } | ||
4494 | + } | ||
4495 | |||
4496 | - /* Do we need to use the shutdown.allow file ? */ | ||
4497 | - if (useacl && (fp = fopen(SDALLOW, "r")) != NULL) { | ||
4498 | + /* Do we need to use the shutdown.allow file ? */ | ||
4499 | + if (useacl && (fp = fopen(SDALLOW, "r")) != NULL) { | ||
4500 | |||
4501 | - /* Read /etc/shutdown.allow. */ | ||
4502 | - i = 0; | ||
4503 | - while(fgets(buf, 128, fp)) { | ||
4504 | - if (buf[0] == '#' || buf[0] == '\n') continue; | ||
4505 | - if (i > 31) continue; | ||
4506 | - for(sp = buf; *sp; sp++) if (*sp == '\n') *sp = 0; | ||
4507 | - downusers[i++] = strdup(buf); | ||
4508 | - } | ||
4509 | - if (i < 32) downusers[i] = 0; | ||
4510 | - fclose(fp); | ||
4511 | + /* Read /etc/shutdown.allow. */ | ||
4512 | + i = 0; | ||
4513 | + while(fgets(buf, 128, fp)) { | ||
4514 | + if (buf[0] == '#' || buf[0] == '\n') continue; | ||
4515 | + if (i > 31) continue; | ||
4516 | + for(sp = buf; *sp; sp++) if (*sp == '\n') *sp = 0; | ||
4517 | + downusers[i++] = strdup(buf); | ||
4518 | + } | ||
4519 | + if (i < 32) downusers[i] = 0; | ||
4520 | + fclose(fp); | ||
4521 | |||
4522 | - /* Now walk through /var/run/utmp to find logged in users. */ | ||
4523 | - while(!user_ok && (ut = getutent()) != NULL) { | ||
4524 | + /* Now walk through /var/run/utmp to find logged in users. */ | ||
4525 | + while(!user_ok && (ut = getutent()) != NULL) { | ||
4526 | |||
4527 | - /* See if this is a user process on a VC. */ | ||
4528 | - if (ut->ut_type != USER_PROCESS) continue; | ||
4529 | - sprintf(term, "/dev/%.*s", UT_LINESIZE, ut->ut_line); | ||
4530 | - if (stat(term, &st) < 0) continue; | ||
4531 | + /* See if this is a user process on a VC. */ | ||
4532 | + if (ut->ut_type != USER_PROCESS) continue; | ||
4533 | + sprintf(term, "/dev/%.*s", UT_LINESIZE, ut->ut_line); | ||
4534 | + if (stat(term, &st) < 0) continue; | ||
4535 | #ifdef major /* glibc */ | ||
4536 | - if (major(st.st_rdev) != 4 || | ||
4537 | - minor(st.st_rdev) > 63) continue; | ||
4538 | + if (major(st.st_rdev) != 4 || | ||
4539 | + minor(st.st_rdev) > 63) continue; | ||
4540 | #else | ||
4541 | - if ((st.st_rdev & 0xFFC0) != 0x0400) continue; | ||
4542 | + if ((st.st_rdev & 0xFFC0) != 0x0400) continue; | ||
4543 | #endif | ||
4544 | - /* Root is always OK. */ | ||
4545 | - if (strcmp(ut->ut_user, "root") == 0) { | ||
4546 | - user_ok++; | ||
4547 | - break; | ||
4548 | - } | ||
4549 | - | ||
4550 | - /* See if this is an allowed user. */ | ||
4551 | - for(i = 0; i < 32 && downusers[i]; i++) | ||
4552 | - if (!strncmp(downusers[i], ut->ut_user, UT_NAMESIZE)) { | ||
4553 | + /* Root is always OK. */ | ||
4554 | + if (strcmp(ut->ut_user, "root") == 0) { | ||
4555 | user_ok++; | ||
4556 | break; | ||
4557 | } | ||
4558 | - } | ||
4559 | - endutent(); | ||
4560 | |||
4561 | - /* See if user was allowed. */ | ||
4562 | - if (!user_ok) { | ||
4563 | - if ((fp = fopen(CONSOLE, "w")) != NULL) { | ||
4564 | - fprintf(fp, "\rshutdown: no authorized users logged in.\r\n"); | ||
4565 | - fclose(fp); | ||
4566 | + /* See if this is an allowed user. */ | ||
4567 | + for(i = 0; i < 32 && downusers[i]; i++) | ||
4568 | + if (!strncmp(downusers[i], ut->ut_user, | ||
4569 | + UT_NAMESIZE)) { | ||
4570 | + user_ok++; | ||
4571 | + break; | ||
4572 | + } | ||
4573 | } | ||
4574 | - exit(1); | ||
4575 | - } | ||
4576 | - } | ||
4577 | + endutent(); | ||
4578 | |||
4579 | - /* Read pid of running shutdown from a file */ | ||
4580 | - if ((fp = fopen(SDPID, "r")) != NULL) { | ||
4581 | - fscanf(fp, "%d", &pid); | ||
4582 | - fclose(fp); | ||
4583 | - } | ||
4584 | + /* See if user was allowed. */ | ||
4585 | + if (!user_ok) { | ||
4586 | + if ((fp = fopen(CONSOLE, "w")) != NULL) { | ||
4587 | + fprintf(fp, "\rshutdown: no authorized users " | ||
4588 | + "logged in.\r\n"); | ||
4589 | + fclose(fp); | ||
4590 | + } | ||
4591 | + exit(1); | ||
4592 | + } | ||
4593 | + } | ||
4594 | |||
4595 | - /* Read remaining words, skip time if needed. */ | ||
4596 | - message[0] = 0; | ||
4597 | - for(c = optind + (!cancel && !when); c < argc; c++) { | ||
4598 | - if (strlen(message) + strlen(argv[c]) + 4 > MESSAGELEN) | ||
4599 | - break; | ||
4600 | - strcat(message, argv[c]); | ||
4601 | - strcat(message, " "); | ||
4602 | - } | ||
4603 | - if (message[0]) strcat(message, "\r\n"); | ||
4604 | + /* Read pid of running shutdown from a file */ | ||
4605 | + if ((fp = fopen(SDPID, "r")) != NULL) { | ||
4606 | + fscanf(fp, "%d", &pid); | ||
4607 | + fclose(fp); | ||
4608 | + } | ||
4609 | |||
4610 | - /* See if we want to run or cancel. */ | ||
4611 | - if (cancel) { | ||
4612 | - if (pid <= 0) { | ||
4613 | - fprintf(stderr, "shutdown: cannot find pid of running shutdown.\n"); | ||
4614 | - exit(1); | ||
4615 | + /* Read remaining words, skip time if needed. */ | ||
4616 | + message[0] = 0; | ||
4617 | + for(c = optind + (!cancel && !when); c < argc; c++) { | ||
4618 | + if (strlen(message) + strlen(argv[c]) + 4 > MESSAGELEN) | ||
4619 | + break; | ||
4620 | + strcat(message, argv[c]); | ||
4621 | + strcat(message, " "); | ||
4622 | } | ||
4623 | - if (kill(pid, SIGINT) < 0) { | ||
4624 | - fprintf(stderr, "shutdown: not running.\n"); | ||
4625 | - exit(1); | ||
4626 | + if (message[0]) strcat(message, "\r\n"); | ||
4627 | + | ||
4628 | + /* See if we want to run or cancel. */ | ||
4629 | + if (cancel) { | ||
4630 | + if (pid <= 0) { | ||
4631 | + fprintf(stderr, "shutdown: cannot find pid " | ||
4632 | + "of running shutdown.\n"); | ||
4633 | + exit(1); | ||
4634 | + } | ||
4635 | + init_setenv("INIT_HALT", NULL); | ||
4636 | + if (kill(pid, SIGINT) < 0) { | ||
4637 | + fprintf(stderr, "shutdown: not running.\n"); | ||
4638 | + exit(1); | ||
4639 | + } | ||
4640 | + if (message[0]) wall(message, 1, 0); | ||
4641 | + exit(0); | ||
4642 | } | ||
4643 | - if (message[0]) wall(message, 1, 0); | ||
4644 | - exit(0); | ||
4645 | - } | ||
4646 | |||
4647 | - /* Check syntax. */ | ||
4648 | - if (when == NULL) { | ||
4649 | - if (optind == argc) usage(); | ||
4650 | - when = argv[optind++]; | ||
4651 | - } | ||
4652 | + /* Check syntax. */ | ||
4653 | + if (when == NULL) { | ||
4654 | + if (optind == argc) usage(); | ||
4655 | + when = argv[optind++]; | ||
4656 | + } | ||
4657 | |||
4658 | - /* See if we are already running. */ | ||
4659 | - if (pid > 0 && kill(pid, 0) == 0) { | ||
4660 | - fprintf(stderr, "\rshutdown: already running.\r\n"); | ||
4661 | - exit(1); | ||
4662 | - } | ||
4663 | + /* See if we are already running. */ | ||
4664 | + if (pid > 0 && kill(pid, 0) == 0) { | ||
4665 | + fprintf(stderr, "\rshutdown: already running.\r\n"); | ||
4666 | + exit(1); | ||
4667 | + } | ||
4668 | |||
4669 | - /* Extra check. */ | ||
4670 | - if (doself && down_level[0] != '0' && down_level[0] != '6') { | ||
4671 | - fprintf(stderr, "shutdown: can use \"-n\" for halt or reboot only.\r\n"); | ||
4672 | - exit(1); | ||
4673 | - } | ||
4674 | + /* Extra check. */ | ||
4675 | + if (doself && down_level[0] != '0' && down_level[0] != '6') { | ||
4676 | + fprintf(stderr, | ||
4677 | + "shutdown: can use \"-n\" for halt or reboot only.\r\n"); | ||
4678 | + exit(1); | ||
4679 | + } | ||
4680 | |||
4681 | - /* Tell users what we're gonna do. */ | ||
4682 | - switch(down_level[0]) { | ||
4683 | - case '0': | ||
4684 | - strcpy(newstate, "for system halt"); | ||
4685 | - break; | ||
4686 | - case '6': | ||
4687 | - strcpy(newstate, "for reboot"); | ||
4688 | - break; | ||
4689 | - case '1': | ||
4690 | - strcpy(newstate, "to maintenance mode"); | ||
4691 | - break; | ||
4692 | - default: | ||
4693 | - sprintf(newstate, "to runlevel %s", down_level); | ||
4694 | - break; | ||
4695 | - } | ||
4696 | + /* Tell users what we're gonna do. */ | ||
4697 | + switch(down_level[0]) { | ||
4698 | + case '0': | ||
4699 | + strcpy(newstate, "for system halt"); | ||
4700 | + break; | ||
4701 | + case '6': | ||
4702 | + strcpy(newstate, "for reboot"); | ||
4703 | + break; | ||
4704 | + case '1': | ||
4705 | + strcpy(newstate, "to maintenance mode"); | ||
4706 | + break; | ||
4707 | + default: | ||
4708 | + sprintf(newstate, "to runlevel %s", down_level); | ||
4709 | + break; | ||
4710 | + } | ||
4711 | |||
4712 | - /* Create a new PID file. */ | ||
4713 | - unlink(SDPID); | ||
4714 | - umask(022); | ||
4715 | - if ((fp = fopen(SDPID, "w")) != NULL) { | ||
4716 | - fprintf(fp, "%d\n", getpid()); | ||
4717 | - fclose(fp); | ||
4718 | - } else if (errno != EROFS) | ||
4719 | - fprintf(stderr, "shutdown: warning: cannot open %s\n", SDPID); | ||
4720 | + /* Create a new PID file. */ | ||
4721 | + unlink(SDPID); | ||
4722 | + umask(022); | ||
4723 | + if ((fp = fopen(SDPID, "w")) != NULL) { | ||
4724 | + fprintf(fp, "%d\n", getpid()); | ||
4725 | + fclose(fp); | ||
4726 | + } else if (errno != EROFS) | ||
4727 | + fprintf(stderr, "shutdown: warning: cannot open %s\n", SDPID); | ||
4728 | |||
4729 | - /* | ||
4730 | - * Catch some common signals. | ||
4731 | - */ | ||
4732 | - signal(SIGQUIT, SIG_IGN); | ||
4733 | - signal(SIGCHLD, SIG_IGN); | ||
4734 | - signal(SIGHUP, SIG_IGN); | ||
4735 | - signal(SIGTSTP, SIG_IGN); | ||
4736 | - signal(SIGTTIN, SIG_IGN); | ||
4737 | - signal(SIGTTOU, SIG_IGN); | ||
4738 | + /* | ||
4739 | + * Catch some common signals. | ||
4740 | + */ | ||
4741 | + signal(SIGQUIT, SIG_IGN); | ||
4742 | + signal(SIGCHLD, SIG_IGN); | ||
4743 | + signal(SIGHUP, SIG_IGN); | ||
4744 | + signal(SIGTSTP, SIG_IGN); | ||
4745 | + signal(SIGTTIN, SIG_IGN); | ||
4746 | + signal(SIGTTOU, SIG_IGN); | ||
4747 | |||
4748 | - sa.sa_handler = stopit; | ||
4749 | - sa.sa_flags = SA_RESTART; | ||
4750 | - sigaction(SIGINT, &sa, NULL); | ||
4751 | + memset(&sa, 0, sizeof(sa)); | ||
4752 | + sa.sa_handler = stopit; | ||
4753 | + sigaction(SIGINT, &sa, NULL); | ||
4754 | |||
4755 | - /* Go to the root directory */ | ||
4756 | - chdir("/"); | ||
4757 | - if (fastboot) close(open(FASTBOOT, O_CREAT | O_RDWR, 0644)); | ||
4758 | - if (forcefsck) close(open(FORCEFSCK, O_CREAT | O_RDWR, 0644)); | ||
4759 | + /* Go to the root directory */ | ||
4760 | + chdir("/"); | ||
4761 | + if (fastboot) close(open(FASTBOOT, O_CREAT | O_RDWR, 0644)); | ||
4762 | + if (forcefsck) close(open(FORCEFSCK, O_CREAT | O_RDWR, 0644)); | ||
4763 | |||
4764 | - /* Alias now and take care of old '+mins' notation. */ | ||
4765 | - if (!strcmp(when, "now")) strcpy(when, "0"); | ||
4766 | - if (when[0] == '+') when++; | ||
4767 | + /* Alias now and take care of old '+mins' notation. */ | ||
4768 | + if (!strcmp(when, "now")) strcpy(when, "0"); | ||
4769 | + if (when[0] == '+') when++; | ||
4770 | |||
4771 | - /* Decode shutdown time. */ | ||
4772 | - for (sp = when; *sp; sp++) { | ||
4773 | - if (*sp != ':' && (*sp < '0' || *sp > '9')) | ||
4774 | - usage(); | ||
4775 | - } | ||
4776 | - if (strchr(when, ':') == NULL) { | ||
4777 | - /* Time in minutes. */ | ||
4778 | - wt = atoi(when); | ||
4779 | - if (wt == 0 && when[0] != '0') usage(); | ||
4780 | - } else { | ||
4781 | - /* Time in hh:mm format. */ | ||
4782 | - if (sscanf(when, "%d:%2d", &hours, &mins) != 2) usage(); | ||
4783 | - if (hours > 23 || mins > 59) usage(); | ||
4784 | - time(&t); | ||
4785 | - lt = localtime(&t); | ||
4786 | - wt = (60*hours + mins) - (60*lt->tm_hour + lt->tm_min); | ||
4787 | - if (wt < 0) wt += 1440; | ||
4788 | - } | ||
4789 | - /* Shutdown NOW if time == 0 */ | ||
4790 | - if (wt == 0) shutdown(); | ||
4791 | + /* Decode shutdown time. */ | ||
4792 | + for (sp = when; *sp; sp++) { | ||
4793 | + if (*sp != ':' && (*sp < '0' || *sp > '9')) | ||
4794 | + usage(); | ||
4795 | + } | ||
4796 | + if (strchr(when, ':') == NULL) { | ||
4797 | + /* Time in minutes. */ | ||
4798 | + wt = atoi(when); | ||
4799 | + if (wt == 0 && when[0] != '0') usage(); | ||
4800 | + } else { | ||
4801 | + /* Time in hh:mm format. */ | ||
4802 | + if (sscanf(when, "%d:%2d", &hours, &mins) != 2) usage(); | ||
4803 | + if (hours > 23 || mins > 59) usage(); | ||
4804 | + time(&t); | ||
4805 | + lt = localtime(&t); | ||
4806 | + wt = (60*hours + mins) - (60*lt->tm_hour + lt->tm_min); | ||
4807 | + if (wt < 0) wt += 1440; | ||
4808 | + } | ||
4809 | + /* Shutdown NOW if time == 0 */ | ||
4810 | + if (wt == 0) shutdown(halttype); | ||
4811 | |||
4812 | - /* Give warnings on regular intervals and finally shutdown. */ | ||
4813 | - if (wt < 15 && !needwarning(wt)) warn(wt); | ||
4814 | - while(wt) { | ||
4815 | - if (wt <= 5 && !didnolog) { | ||
4816 | - donologin(wt); | ||
4817 | - didnolog++; | ||
4818 | + /* Give warnings on regular intervals and finally shutdown. */ | ||
4819 | + if (wt < 15 && !needwarning(wt)) warn(wt); | ||
4820 | + while(wt) { | ||
4821 | + if (wt <= 5 && !didnolog) { | ||
4822 | + donologin(wt); | ||
4823 | + didnolog++; | ||
4824 | + } | ||
4825 | + if (needwarning(wt)) warn(wt); | ||
4826 | + hardsleep(60); | ||
4827 | + wt--; | ||
4828 | } | ||
4829 | - if (needwarning(wt)) warn(wt); | ||
4830 | - hardsleep(60); | ||
4831 | - wt--; | ||
4832 | - } | ||
4833 | - shutdown(); | ||
4834 | - return(0); /* Never happens */ | ||
4835 | + shutdown(halttype); | ||
4836 | + | ||
4837 | + return 0; /* Never happens */ | ||
4838 | } | ||
4839 | Binary files sysvinit-2.85/src/shutdown.o and sysvinit-2.86/src/shutdown.o differ | ||
4840 | Binary files sysvinit-2.85/src/sulogin and sysvinit-2.86/src/sulogin differ | ||
4841 | diff -urNd -urNd sysvinit-2.85/src/sulogin.c sysvinit-2.86/src/sulogin.c | ||
4842 | --- sysvinit-2.85/src/sulogin.c 2003-04-14 04:53:49.000000000 -0500 | ||
4843 | +++ sysvinit-2.86/src/sulogin.c 2004-07-30 06:40:28.000000000 -0500 | ||
4844 | @@ -8,7 +8,7 @@ | ||
4845 | * encrypted root password is "x" the shadow | ||
4846 | * password will be used. | ||
4847 | * | ||
4848 | - * Version: @(#)sulogin 2.85 14-Apr-2003 miquels@cistron.nl | ||
4849 | + * Version: @(#)sulogin 2.85-3 23-Apr-2003 miquels@cistron.nl | ||
4850 | * | ||
4851 | */ | ||
4852 | |||
4853 | @@ -35,11 +35,15 @@ | ||
4854 | #define F_SHADOW "/etc/shadow" | ||
4855 | #define BINSH "/bin/sh" | ||
4856 | |||
4857 | -char *Version = "@(#)sulogin 2.85 14-Apr-2003 miquels@cistron.nl"; | ||
4858 | +char *Version = "@(#)sulogin 2.85-3 23-Apr-2003 miquels@cistron.nl"; | ||
4859 | |||
4860 | int timeout = 0; | ||
4861 | int profile = 0; | ||
4862 | |||
4863 | +#ifndef IUCLC | ||
4864 | +# define IUCLC 0 | ||
4865 | +#endif | ||
4866 | + | ||
4867 | #if 0 | ||
4868 | /* | ||
4869 | * Fix the tty modes and set reasonable defaults. | ||
4870 | @@ -252,7 +256,7 @@ | ||
4871 | printf("Give root password for maintenance\n"); | ||
4872 | else | ||
4873 | printf("Press enter for maintenance\n"); | ||
4874 | - printf("(or type Control-D for normal startup): "); | ||
4875 | + printf("(or type Control-D to continue): "); | ||
4876 | fflush(stdout); | ||
4877 | |||
4878 | tcgetattr(0, &old); | ||
4879 | Binary files sysvinit-2.85/src/sulogin.o and sysvinit-2.86/src/sulogin.o differ | ||
4880 | Binary files sysvinit-2.85/src/utmp.o and sysvinit-2.86/src/utmp.o differ | ||