]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/sysvinit/sysvinit-2.86/sysvinit-2.86.patch
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / sysvinit / sysvinit-2.86 / sysvinit-2.86.patch
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