Commit | Line | Data |
---|---|---|
6dca1d21 JB |
1 | Submitted By: Jim Gifford (jim at cross-lfs dot org) |
2 | Date: 01-07-2008 | |
3 | Initial Package Version: 2.86 | |
4 | Origin: Various | |
5 | Upstream Status: Unknown | |
6 | Description: Fixes to Major issues in Sysvinit -- listed Below | |
7 | IPV6 Displayed Incorrectly | |
8 | On 64bit which have 32bit multilib support, the utmp struct is the same | |
9 | Fix bug where proc names are truncated | |
10 | Fixed support for POSIX capabilite | |
11 | All halt/reboot to handle being called by login correctly | |
12 | Preserve waiting state across re-exec | |
13 | Allow failed console opens some time to resolve themselves | |
14 | ||
15 | New: | |
16 | Added kexec support | |
17 | ||
18 | diff -Naur sysvinit-2.86.orig/man/halt.8 sysvinit-2.86/man/halt.8 | |
19 | --- sysvinit-2.86.orig/man/halt.8 2001-11-21 13:11:22.000000000 -0800 | |
20 | +++ sysvinit-2.86/man/halt.8 2009-01-07 11:07:06.000000000 -0800 | |
21 | @@ -23,6 +23,7 @@ | |
22 | .RB [ \-d ] | |
23 | .RB [ \-f ] | |
24 | .RB [ \-i ] | |
25 | +.RB [ \-k ] | |
26 | .br | |
27 | .B /sbin/poweroff | |
28 | .RB [ \-n ] | |
29 | @@ -65,6 +66,8 @@ | |
30 | .IP \fB\-p\fP | |
31 | When halting the system, do a poweroff. This is the default when halt is | |
32 | called as \fBpoweroff\fP. | |
33 | +.IP \fB\-k\fP | |
34 | +Try to reboot using \fBkexec\fP, if kernel supports it. | |
35 | .\"}}} | |
36 | .\"{{{ Diagnostics | |
37 | .SH DIAGNOSTICS | |
38 | diff -Naur sysvinit-2.86.orig/man/init.8 sysvinit-2.86/man/init.8 | |
39 | --- sysvinit-2.86.orig/man/init.8 2004-07-29 04:21:31.000000000 -0700 | |
40 | +++ sysvinit-2.86/man/init.8 2009-01-07 11:23:45.000000000 -0800 | |
41 | @@ -64,7 +64,7 @@ | |
42 | .PP | |
43 | Runlevel \fBS\fP or \fBs\fP bring the system to single user mode | |
44 | and do not require an \fB/etc/inittab\fP file. In single user mode, | |
45 | -\fB/sbin/sulogin\fP is invoked on \fB/dev/console\fP. | |
46 | +a root shell is opened on \fB/dev/console\fP. | |
47 | .PP | |
48 | When entering single user mode, \fBinit\fP initializes the consoles | |
49 | \fBstty\fP settings to sane values. Clocal mode is set. Hardware | |
50 | diff -Naur sysvinit-2.86.orig/man/last.1 sysvinit-2.86/man/last.1 | |
51 | --- sysvinit-2.86.orig/man/last.1 2004-07-30 04:39:18.000000000 -0700 | |
52 | +++ sysvinit-2.86/man/last.1 2009-01-07 11:23:45.000000000 -0800 | |
53 | @@ -60,6 +60,8 @@ | |
54 | useful, e.g., to determine easily who was logged in at a particular | |
55 | time -- specify that time with \fB\-t\fP and look for "still logged | |
56 | in". | |
57 | +.IP "\fB\-f\fP \fIfile\fP" | |
58 | +Specifies a file to search other than \fB/var/log/wtmp\fP. | |
59 | .IP \fB\-R\fP | |
60 | Suppresses the display of the hostname field. | |
61 | .IP \fB\-a\fP | |
62 | diff -Naur sysvinit-2.86.orig/man/pidof.8 sysvinit-2.86/man/pidof.8 | |
63 | --- sysvinit-2.86.orig/man/pidof.8 1998-09-02 05:49:33.000000000 -0700 | |
64 | +++ sysvinit-2.86/man/pidof.8 2009-01-07 11:22:28.000000000 -0800 | |
65 | @@ -4,6 +4,7 @@ | |
66 | .SH SYNOPSIS | |
67 | .B pidof | |
68 | .RB [ \-s ] | |
69 | +.RB [ \-c ] | |
70 | .RB [ \-x ] | |
71 | .RB [ \-o | |
72 | .IR omitpid ] | |
73 | @@ -24,6 +25,10 @@ | |
74 | .SH OPTIONS | |
75 | .IP -s | |
76 | Single shot - this instructs the program to only return one \fIpid\fP. | |
77 | +.IP -c | |
78 | +Only return process ids that are running with the same root directory. | |
79 | +This option is ignored for non-root users, as they will be unable to check | |
80 | +the current root directory of processes they do not own. | |
81 | .IP -x | |
82 | Scripts too - this causes the program to also return process id's of | |
83 | shells running the named scripts. | |
84 | diff -Naur sysvinit-2.86.orig/man/shutdown.8 sysvinit-2.86/man/shutdown.8 | |
85 | --- sysvinit-2.86.orig/man/shutdown.8 2004-06-09 05:47:45.000000000 -0700 | |
86 | +++ sysvinit-2.86/man/shutdown.8 2009-01-07 11:08:22.000000000 -0800 | |
87 | @@ -9,11 +9,11 @@ | |
88 | .\"{{{ Synopsis | |
89 | .SH SYNOPSIS | |
90 | .B /sbin/shutdown | |
91 | +.RB [ \-akrhPHfFnc ] | |
92 | .RB [ \-t | |
93 | .IR sec ] | |
94 | -.RB [ \-arkhncfFHP ] | |
95 | .I time | |
96 | -.RI [ warning-message ] | |
97 | +.RI [ "warning message" ] | |
98 | .\"}}} | |
99 | .\"{{{ Description | |
100 | .SH DESCRIPTION | |
101 | @@ -39,11 +39,6 @@ | |
102 | .IP "\fB\-a\fP | |
103 | Use \fB/etc/shutdown.allow\fP. | |
104 | .\"}}} | |
105 | -.\"{{{ -t sec | |
106 | -.IP "\fB\-t\fP \fIsec\fP" | |
107 | -Tell \fBinit\fP(8) to wait \fIsec\fP seconds between sending processes the | |
108 | -warning and the kill signal, before changing to another runlevel. | |
109 | -.\"}}} | |
110 | .\"{{{ -k | |
111 | .IP \fB\-k\fP | |
112 | Don't really shutdown; only send the warning messages to everybody. | |
113 | @@ -56,20 +51,14 @@ | |
114 | .IP \fB\-h\fP | |
115 | Halt or poweroff after shutdown. | |
116 | .\"}}} | |
117 | -.\"{{{ -H | |
118 | -.IP \fB\-H\fP | |
119 | -Halt action is to halt or drop into boot monitor on systems that | |
120 | -support it. | |
121 | -.\"}}} | |
122 | .\"{{{ -P | |
123 | .IP \fB\-P\fP | |
124 | Halt action is to turn off the power. | |
125 | .\"}}} | |
126 | -.\"{{{ -n | |
127 | -.IP \fB\-n\fP | |
128 | -[DEPRECATED] Don't call \fBinit\fP(8) to do the shutdown but do it ourself. | |
129 | -The use of this option is discouraged, and its results are not always what | |
130 | -you'd expect. | |
131 | +.\"{{{ -H | |
132 | +.IP \fB\-H\fP | |
133 | +Halt action is to halt or drop into boot monitor on systems that | |
134 | +support it. | |
135 | .\"}}} | |
136 | .\"{{{ -f | |
137 | .IP \fB\-f\fP | |
138 | @@ -79,18 +68,29 @@ | |
139 | .IP \fB\-F\fP | |
140 | Force fsck on reboot. | |
141 | .\"}}} | |
142 | +.\"{{{ -n | |
143 | +.IP \fB\-n\fP | |
144 | +[DEPRECATED] Don't call \fBinit\fP(8) to do the shutdown but do it ourself. | |
145 | +The use of this option is discouraged, and its results are not always what | |
146 | +you'd expect. | |
147 | +.\"}}} | |
148 | .\"{{{ -c | |
149 | .IP \fB\-c\fP | |
150 | Cancel an already running shutdown. With this option it is of course | |
151 | not possible to give the \fBtime\fP argument, but you can enter a | |
152 | explanatory message on the command line that will be sent to all users. | |
153 | .\"}}} | |
154 | +.\"{{{ -t sec | |
155 | +.IP "\fB\-t\fP \fIsec\fP" | |
156 | +Tell \fBinit\fP(8) to wait \fIsec\fP seconds between sending processes the | |
157 | +warning and the kill signal, before changing to another runlevel. | |
158 | +.\"}}} | |
159 | .\"{{{ time | |
160 | .IP \fItime\fP | |
161 | When to shutdown. | |
162 | .\"}}} | |
163 | .\"{{{ warning-message | |
164 | -.IP \fIwarning-message\fP | |
165 | +.IP "\fIwarning message\fP" | |
166 | Message to send to all users. | |
167 | .\"}}} | |
168 | .PP | |
169 | diff -Naur sysvinit-2.86.orig/man/sulogin.8 sysvinit-2.86/man/sulogin.8 | |
170 | --- sysvinit-2.86.orig/man/sulogin.8 2004-06-09 05:47:45.000000000 -0700 | |
171 | +++ sysvinit-2.86/man/sulogin.8 2009-01-07 11:23:45.000000000 -0800 | |
172 | @@ -9,7 +9,7 @@ | |
173 | .RB [ " tty-device " ] | |
174 | .SH DESCRIPTION | |
175 | .I sulogin | |
176 | -is invoked by \fBinit(8)\fP when the system goes into single user mode | |
177 | +can be invoked by \fBinit(8)\fP when the system goes into single user mode | |
178 | (this is done through an entry in \fIinittab(5)\fP). \fBInit\fP also | |
179 | tries to execute \fIsulogin\fP when it is passed the \fB-b\fP flag | |
180 | from the bootmonitor (eg, LILO). | |
181 | diff -Naur sysvinit-2.86.orig/src/bootlogd.c sysvinit-2.86/src/bootlogd.c | |
182 | --- sysvinit-2.86.orig/src/bootlogd.c 2004-06-09 05:47:45.000000000 -0700 | |
183 | +++ sysvinit-2.86/src/bootlogd.c 2009-01-07 11:34:12.000000000 -0800 | |
184 | @@ -609,7 +609,7 @@ | |
185 | else | |
186 | todo = endptr - outptr; | |
187 | if (fp && todo) | |
188 | - writelog(fp, outptr, todo); | |
189 | + writelog(fp, (unsigned char *)outptr, todo); | |
190 | } | |
191 | ||
192 | if (fp) { | |
193 | diff -Naur sysvinit-2.86.orig/src/halt.c sysvinit-2.86/src/halt.c | |
194 | --- sysvinit-2.86.orig/src/halt.c 2004-07-30 05:16:18.000000000 -0700 | |
195 | +++ sysvinit-2.86/src/halt.c 2009-01-07 11:25:19.000000000 -0800 | |
196 | @@ -8,7 +8,7 @@ | |
197 | * execute an "shutdown -r". This is for compatibility with | |
198 | * sysvinit 2.4. | |
199 | * | |
200 | - * Usage: halt [-n] [-w] [-d] [-f] [-h] [-i] [-p] | |
201 | + * Usage: halt [-n] [-w] [-d] [-f] [-h] [-i] [-p] [-k] | |
202 | * -n: don't sync before halting the system | |
203 | * -w: only write a wtmp reboot record and exit. | |
204 | * -d: don't write a wtmp record. | |
205 | @@ -16,6 +16,7 @@ | |
206 | * -h: put harddisks in standby mode | |
207 | * -i: shut down all network interfaces. | |
208 | * -p: power down the system (if possible, otherwise halt). | |
209 | + * -k: reboot the system using kexec. | |
210 | * | |
211 | * Reboot and halt are both this program. Reboot | |
212 | * is just a link to halt. Invoking the program | |
213 | @@ -64,8 +65,10 @@ | |
214 | */ | |
215 | void usage(void) | |
216 | { | |
217 | - fprintf(stderr, "usage: %s [-n] [-w] [-d] [-f] [-h] [-i]%s\n", | |
218 | - progname, strcmp(progname, "halt") ? "" : " [-p]"); | |
219 | + fprintf(stderr, "usage: %s [-n] [-w] [-d] [-f] [-h] [-i]%s%s\n", | |
220 | + progname, | |
221 | + strcmp(progname, "halt") ? "" : " [-p]", | |
222 | + strcmp(progname, "reboot") ? "" : " [-k]"); | |
223 | fprintf(stderr, "\t-n: don't sync before halting the system\n"); | |
224 | fprintf(stderr, "\t-w: only write a wtmp reboot record and exit.\n"); | |
225 | fprintf(stderr, "\t-d: don't write a wtmp record.\n"); | |
226 | @@ -74,6 +77,8 @@ | |
227 | fprintf(stderr, "\t-i: shut down all network interfaces.\n"); | |
228 | if (!strcmp(progname, "halt")) | |
229 | fprintf(stderr, "\t-p: power down the system (if possible, otherwise halt).\n"); | |
230 | + if (!strcmp(progname, "reboot")) | |
231 | + fprintf(stderr, "\t-k: reboot the system using kexec.\n"); | |
232 | exit(1); | |
233 | } | |
234 | ||
235 | @@ -172,12 +177,14 @@ | |
236 | int do_ifdown = 0; | |
237 | int do_hddown = 0; | |
238 | int do_poweroff = 0; | |
239 | + int do_kexec = 0; | |
240 | int c; | |
241 | char *tm = NULL; | |
242 | ||
243 | /* | |
244 | * Find out who we are | |
245 | */ | |
246 | + if (argv[0][0] == '-') argv[0]++; | |
247 | if ((progname = strrchr(argv[0], '/')) != NULL) | |
248 | progname++; | |
249 | else | |
250 | @@ -189,7 +196,7 @@ | |
251 | /* | |
252 | * Get flags | |
253 | */ | |
254 | - while((c = getopt(argc, argv, ":ihdfnpwt:")) != EOF) { | |
255 | + while((c = getopt(argc, argv, ":ihdfnpwkt:")) != EOF) { | |
256 | switch(c) { | |
257 | case 'n': | |
258 | do_sync = 0; | |
259 | @@ -213,6 +220,9 @@ | |
260 | case 'p': | |
261 | do_poweroff = 1; | |
262 | break; | |
263 | + case 'k': | |
264 | + do_kexec = 1; | |
265 | + break; | |
266 | case 't': | |
267 | tm = optarg; | |
268 | break; | |
269 | @@ -230,12 +240,37 @@ | |
270 | (void)chdir("/"); | |
271 | ||
272 | if (!do_hard && !do_nothing) { | |
273 | + c = get_runlevel(); | |
274 | + | |
275 | + /* | |
276 | + * We can't reboot using kexec through this path. | |
277 | + */ | |
278 | + if (c != '6' && do_reboot && do_kexec) { | |
279 | + fprintf(stderr, "ERROR: using -k at this" | |
280 | + " runlevel requires also -f\n" | |
281 | + " (You probably want instead to reboot" | |
282 | + " normally and let your reboot\n" | |
283 | + " script, usually /etc/init.d/reboot," | |
284 | + " specify -k)\n"); | |
285 | + exit(1); | |
286 | + } | |
287 | + | |
288 | /* | |
289 | * See if we are in runlevel 0 or 6. | |
290 | */ | |
291 | - c = get_runlevel(); | |
292 | - if (c != '0' && c != '6') | |
293 | - do_shutdown(do_reboot ? "-r" : "-h", tm); | |
294 | + if (c != '0' && c != '6') { | |
295 | + char *file; | |
296 | + | |
297 | + if (do_poweroff) { | |
298 | + file = strdup("/poweroff"); | |
299 | + } else { | |
300 | + file = strdup("/halt"); | |
301 | + } | |
302 | + close(open(file, O_CREAT|O_RDWR, 0644)); | |
303 | + free(file); | |
304 | + | |
305 | + do_shutdown(do_reboot ? "-r" : "-h", tm); | |
306 | + } | |
307 | } | |
308 | ||
309 | /* | |
310 | @@ -263,6 +298,16 @@ | |
311 | if (do_nothing) exit(0); | |
312 | ||
313 | if (do_reboot) { | |
314 | + /* | |
315 | + * kexec or reboot | |
316 | + */ | |
317 | + if (do_kexec) { | |
318 | + init_reboot(BMAGIC_KEXEC); | |
319 | + } | |
320 | + | |
321 | + /* | |
322 | + * Fall through if failed | |
323 | + */ | |
324 | init_reboot(BMAGIC_REBOOT); | |
325 | } else { | |
326 | /* | |
327 | diff -Naur sysvinit-2.86.orig/src/init.c sysvinit-2.86/src/init.c | |
328 | --- sysvinit-2.86.orig/src/init.c 2004-07-30 05:16:20.000000000 -0700 | |
329 | +++ sysvinit-2.86/src/init.c 2009-01-07 14:02:51.000000000 -0800 | |
330 | @@ -185,6 +185,7 @@ | |
331 | {"RU",RUNNING}, | |
332 | {"DE",DEMAND}, | |
333 | {"XD",XECUTED}, | |
334 | + {"WT",WAITING}, | |
335 | {NULL,0} | |
336 | }; | |
337 | ||
338 | @@ -466,7 +467,7 @@ | |
339 | ||
340 | if (maxproclen > 2) { | |
341 | memset(argv0, 0, maxproclen); | |
342 | - strncpy(argv0, buf, maxproclen - 2); | |
343 | + strncpy(argv0, buf, maxproclen - 1); | |
344 | } | |
345 | ||
346 | return len; | |
347 | @@ -527,8 +528,10 @@ | |
348 | /* | |
349 | * Retry the open five times. | |
350 | */ | |
351 | - for(f = 0; f < 5; f++) | |
352 | + for(f = 0; f < 5; f++) { | |
353 | if ((fd = open(console_dev, m)) >= 0) break; | |
354 | + usleep(100); | |
355 | + } | |
356 | ||
357 | if (fd < 0) return fd; | |
358 | ||
359 | @@ -949,11 +952,30 @@ | |
360 | sigprocmask(SIG_SETMASK, &omask, NULL); | |
361 | ||
362 | /* | |
363 | + * Update utmp/wtmp file prior to starting | |
364 | + * any child. This MUST be done right here in | |
365 | + * the child process in order to prevent a race | |
366 | + * condition that occurs when the child | |
367 | + * process' time slice executes before the | |
368 | + * parent (can and does happen in a uniprocessor | |
369 | + * environment). If the child is a getty and | |
370 | + * the race condition happens, then init's utmp | |
371 | + * update will happen AFTER the getty runs | |
372 | + * and expects utmp to be updated already! | |
373 | + * | |
374 | + * Do NOT log if process field starts with '+' | |
375 | + * FIXME: that's for compatibility with *very* | |
376 | + * old getties - probably it can be taken out. | |
377 | + */ | |
378 | + if (ch->action == RESPAWN && ch->process[0] != '+') | |
379 | + write_utmp_wtmp("", ch->id, getpid(), INIT_PROCESS, ""); | |
380 | + | |
381 | + /* | |
382 | * In sysinit, boot, bootwait or single user mode: | |
383 | * for any wait-type subprocess we _force_ the console | |
384 | * to be its controlling tty. | |
385 | */ | |
386 | - if (strchr("*#sS", runlevel) && ch->flags & WAITING) { | |
387 | + if ((strchr("*#sS", runlevel) || (ch->id[0] == 'l' && isdigit(ch->id[1]))) && ch->flags & WAITING) { | |
388 | /* | |
389 | * We fork once extra. This is so that we can | |
390 | * wait and change the process group and session | |
391 | @@ -1088,15 +1110,7 @@ | |
392 | case ONDEMAND: | |
393 | case RESPAWN: | |
394 | ch->flags |= RUNNING; | |
395 | - if (spawn(ch, &(ch->pid)) < 0) break; | |
396 | - /* | |
397 | - * Do NOT log if process field starts with '+' | |
398 | - * FIXME: that's for compatibility with *very* | |
399 | - * old getties - probably it can be taken out. | |
400 | - */ | |
401 | - if (ch->process[0] != '+') | |
402 | - write_utmp_wtmp("", ch->id, ch->pid, | |
403 | - INIT_PROCESS, ""); | |
404 | + (void)spawn(ch, &(ch->pid)); | |
405 | break; | |
406 | } | |
407 | } | |
408 | @@ -1373,14 +1387,14 @@ | |
409 | case 0: /* Send TERM signal */ | |
410 | if (talk) | |
411 | initlog(L_CO, | |
412 | - "Sending processes the TERM signal"); | |
413 | + "Sending processes started by init the TERM signal"); | |
414 | kill(-(ch->pid), SIGTERM); | |
415 | foundOne = 1; | |
416 | break; | |
417 | case 1: /* Send KILL signal and collect status */ | |
418 | if (talk) | |
419 | initlog(L_CO, | |
420 | - "Sending processes the KILL signal"); | |
421 | + "Sending processes started by init the KILL signal"); | |
422 | kill(-(ch->pid), SIGKILL); | |
423 | break; | |
424 | } | |
425 | @@ -1884,7 +1898,7 @@ | |
426 | * The existing init process execs a new init binary. | |
427 | */ | |
428 | env = init_buildenv(0); | |
429 | - execl(myname, myname, "--init", NULL, env); | |
430 | + execle(myname, myname, "--init", NULL, env); | |
431 | ||
432 | /* | |
433 | * We shouldn't be here, something failed. | |
434 | diff -Naur sysvinit-2.86.orig/src/killall5.c sysvinit-2.86/src/killall5.c | |
435 | --- sysvinit-2.86.orig/src/killall5.c 2004-07-30 05:16:23.000000000 -0700 | |
436 | +++ sysvinit-2.86/src/killall5.c 2009-01-07 14:10:41.000000000 -0800 | |
437 | @@ -51,9 +51,8 @@ | |
438 | char *argv0base; /* `basename argv[1]` */ | |
439 | char *argv1; /* Name as found out from argv[1] */ | |
440 | char *argv1base; /* `basename argv[1]` */ | |
441 | + char *pathname; /* full path to executable */ | |
442 | char *statname; /* the statname without braces */ | |
443 | - ino_t ino; /* Inode number */ | |
444 | - dev_t dev; /* Device it is on */ | |
445 | pid_t pid; /* Process ID. */ | |
446 | int sid; /* Session ID. */ | |
447 | int kernel; /* Kernel thread or zombie. */ | |
448 | @@ -172,7 +171,6 @@ | |
449 | FILE *fp; | |
450 | PROC *p, *n; | |
451 | struct dirent *d; | |
452 | - struct stat st; | |
453 | char path[256]; | |
454 | char buf[256]; | |
455 | char *s, *q; | |
456 | @@ -191,6 +189,8 @@ | |
457 | n = p->next; | |
458 | if (p->argv0) free(p->argv0); | |
459 | if (p->argv1) free(p->argv1); | |
460 | + if (p->pathname) free(p->pathname); | |
461 | + if (p->statname) free(p->statname); | |
462 | free(p); | |
463 | } | |
464 | plist = NULL; | |
465 | @@ -248,6 +248,7 @@ | |
466 | p->sid = 0; | |
467 | nsyslog(LOG_ERR, "can't read sid from %s\n", | |
468 | path); | |
469 | + if (p->statname) free(p->statname); | |
470 | free(p); | |
471 | continue; | |
472 | } | |
473 | @@ -300,15 +301,18 @@ | |
474 | ||
475 | } else { | |
476 | /* Process disappeared.. */ | |
477 | + if (p->statname) free(p->statname); | |
478 | free(p); | |
479 | continue; | |
480 | } | |
481 | ||
482 | /* Try to stat the executable. */ | |
483 | snprintf(path, sizeof(path), "/proc/%s/exe", d->d_name); | |
484 | - if (stat(path, &st) == 0) { | |
485 | - p->dev = st.st_dev; | |
486 | - p->ino = st.st_ino; | |
487 | + p->pathname = (char *)xmalloc(PATH_MAX); | |
488 | + if (readlink(path, p->pathname, PATH_MAX) == -1) { | |
489 | + p->pathname = NULL; | |
490 | + } else { | |
491 | + p->pathname[PATH_MAX-1] = '\0'; | |
492 | } | |
493 | ||
494 | /* Link it into the list. */ | |
495 | @@ -372,14 +376,14 @@ | |
496 | { | |
497 | PROC *p; | |
498 | PIDQ_HEAD *q; | |
499 | - struct stat st; | |
500 | char *s; | |
501 | int dostat = 0; | |
502 | int foundone = 0; | |
503 | int ok = 0; | |
504 | + char *real_path; | |
505 | ||
506 | /* Try to stat the executable. */ | |
507 | - if (prog[0] == '/' && stat(prog, &st) == 0) dostat++; | |
508 | + if (prog[0] == '/' && (real_path = canonicalize_file_name(prog))) dostat++; | |
509 | ||
510 | /* Get basename of program. */ | |
511 | if ((s = strrchr(prog, '/')) == NULL) | |
512 | @@ -390,10 +394,10 @@ | |
513 | q = (PIDQ_HEAD *)xmalloc(sizeof(PIDQ_HEAD)); | |
514 | q = init_pid_q(q); | |
515 | ||
516 | - /* First try to find a match based on dev/ino pair. */ | |
517 | + /* First try to find a match based on pathname. */ | |
518 | if (dostat) { | |
519 | for (p = plist; p; p = p->next) { | |
520 | - if (p->dev == st.st_dev && p->ino == st.st_ino) { | |
521 | + if (p->pathname && strcmp(real_path, p->pathname) == 0) { | |
522 | add_pid_to_q(q, p); | |
523 | foundone++; | |
524 | } | |
525 | @@ -408,11 +412,14 @@ | |
526 | ok += (p->argv0 && strcmp(p->argv0, prog) == 0); | |
527 | ok += (p->argv0 && strcmp(p->argv0base, s) == 0); | |
528 | ||
529 | + if (prog[0] == '/' && p->pathname && strcmp(prog, p->pathname)) | |
530 | + ok = 0; | |
531 | + | |
532 | /* For scripts, compare argv[1] as well. */ | |
533 | if (scripts_too && p->argv1 && | |
534 | !strncmp(p->statname, p->argv1base, STATNAMELEN)) { | |
535 | ok += (strcmp(p->argv1, prog) == 0); | |
536 | - ok += (strcmp(p->argv1base, s) == 0); | |
537 | + if (prog[0] != '/') ok += (strcmp(p->argv1base, s) == 0); | |
538 | } | |
539 | ||
540 | /* | |
541 | @@ -476,16 +483,22 @@ | |
542 | int f; | |
543 | int first = 1; | |
544 | int i, oind, opt, flags = 0; | |
545 | + int chroot_check = 0; | |
546 | + struct stat st; | |
547 | + char tmp[512]; | |
548 | ||
549 | for (oind = PIDOF_OMITSZ-1; oind > 0; oind--) | |
550 | opid[oind] = 0; | |
551 | opterr = 0; | |
552 | ||
553 | - while ((opt = getopt(argc,argv,"ho:sx")) != EOF) switch (opt) { | |
554 | + while ((opt = getopt(argc,argv,"hco:sx")) != EOF) switch (opt) { | |
555 | case '?': | |
556 | nsyslog(LOG_ERR,"invalid options on command line!\n"); | |
557 | closelog(); | |
558 | exit(1); | |
559 | + case 'c': | |
560 | + if (geteuid() == 0) chroot_check = 1; | |
561 | + break; | |
562 | case 'o': | |
563 | if (oind >= PIDOF_OMITSZ -1) { | |
564 | nsyslog(LOG_ERR,"omit pid buffer size %d " | |
565 | @@ -518,6 +531,16 @@ | |
566 | argc -= optind; | |
567 | argv += optind; | |
568 | ||
569 | + /* Check if we are in a chroot */ | |
570 | + if (chroot_check) { | |
571 | + snprintf(tmp, 512, "/proc/%d/root", getpid()); | |
572 | + if (stat(tmp, &st) < 0) { | |
573 | + nsyslog(LOG_ERR, "stat failed for %s!\n", tmp); | |
574 | + closelog(); | |
575 | + exit(1); | |
576 | + } | |
577 | + } | |
578 | + | |
579 | /* Print out process-ID's one by one. */ | |
580 | readproc(); | |
581 | for(f = 0; f < argc; f++) { | |
582 | @@ -541,6 +564,16 @@ | |
583 | else | |
584 | spid = 1; | |
585 | } | |
586 | + if (chroot_check) { | |
587 | + struct stat st2; | |
588 | + snprintf(tmp, 512, "/proc/%d/root", | |
589 | + p->pid); | |
590 | + if (stat(tmp, &st2) < 0 || | |
591 | + st.st_dev != st2.st_dev || | |
592 | + st.st_ino != st2.st_ino) { | |
593 | + continue; | |
594 | + } | |
595 | + } | |
596 | if (!first) | |
597 | printf(" "); | |
598 | printf("%d", p->pid); | |
599 | diff -Naur sysvinit-2.86.orig/src/last.c sysvinit-2.86/src/last.c | |
600 | --- sysvinit-2.86.orig/src/last.c 2004-07-30 05:16:26.000000000 -0700 | |
601 | +++ sysvinit-2.86/src/last.c 2009-01-07 11:18:38.000000000 -0800 | |
602 | @@ -307,14 +307,15 @@ | |
603 | struct sockaddr *sa; | |
604 | int salen, flags; | |
605 | unsigned int topnibble; | |
606 | + unsigned int azero = 0, sitelocal = 0; | |
607 | int mapped = 0; | |
608 | ||
609 | flags = useip ? NI_NUMERICHOST : 0; | |
610 | ||
611 | /* | |
612 | * IPv4 or IPv6 ? We use 2 heuristics: | |
613 | - * 1. Current IPv6 range uses 2000-3fff. Outside of | |
614 | - * that is illegal and must be IPv4. | |
615 | + * 1. Current IPv6 range uses 2000-3fff or fec0-feff. | |
616 | + * Outside of that is illegal and must be IPv4. | |
617 | * 2. If last 3 bytes are 0, must be IPv4 | |
618 | * 3. If IPv6 in IPv4, handle as IPv4 | |
619 | * | |
620 | @@ -323,7 +324,11 @@ | |
621 | if (a[0] == 0 && a[1] == 0 && a[2] == htonl (0xffff)) | |
622 | mapped = 1; | |
623 | topnibble = ntohl((unsigned int)a[0]) >> 28; | |
624 | - if (topnibble < 2 || topnibble > 3 || mapped || | |
625 | + | |
626 | + azero = ntohl((unsigned int)a[0]) >> 16; | |
627 | + sitelocal = (azero >= 0xfec0 && azero <= 0xfeff) ? 1 : 0; | |
628 | + | |
629 | + if (((topnibble < 2 || topnibble > 3) && (!sitelocal)) || mapped || | |
630 | (a[1] == 0 && a[2] == 0 && a[3] == 0)) { | |
631 | /* IPv4 */ | |
632 | sin.sin_family = AF_INET; | |
633 | diff -Naur sysvinit-2.86.orig/src/reboot.h sysvinit-2.86/src/reboot.h | |
634 | --- sysvinit-2.86.orig/src/reboot.h 2004-06-09 05:47:45.000000000 -0700 | |
635 | +++ sysvinit-2.86/src/reboot.h 2009-01-07 11:07:06.000000000 -0800 | |
636 | @@ -32,5 +32,8 @@ | |
637 | # define BMAGIC_POWEROFF BMAGIC_HALT | |
638 | #endif | |
639 | ||
640 | +/* for kexec support */ | |
641 | +#define BMAGIC_KEXEC 0x45584543 | |
642 | + | |
643 | #define init_reboot(magic) reboot(magic) | |
644 | ||
645 | diff -Naur sysvinit-2.86.orig/src/shutdown.c sysvinit-2.86/src/shutdown.c | |
646 | --- sysvinit-2.86.orig/src/shutdown.c 2004-07-30 04:59:04.000000000 -0700 | |
647 | +++ sysvinit-2.86/src/shutdown.c 2009-01-07 11:09:43.000000000 -0800 | |
648 | @@ -102,7 +102,7 @@ | |
649 | void usage(void) | |
650 | { | |
651 | fprintf(stderr, | |
652 | - "Usage:\t shutdown [-akrhHPfnc] [-t secs] time [warning message]\n" | |
653 | + "Usage:\t shutdown [-akrhPHfFnc] [-t sec] time [warning message]\n" | |
654 | "\t\t -a: use /etc/shutdown.allow\n" | |
655 | "\t\t -k: don't really shutdown, only warn.\n" | |
656 | "\t\t -r: reboot after shutdown.\n" | |
657 | @@ -460,6 +460,7 @@ | |
658 | ||
659 | if (getuid() != 0) { | |
660 | fprintf(stderr, "shutdown: you must be root to do that!\n"); | |
661 | + usage(); | |
662 | exit(1); | |
663 | } | |
664 | strcpy(down_level, "1"); | |
665 | diff -Naur sysvinit-2.86.orig/src/utmp.c sysvinit-2.86/src/utmp.c | |
666 | --- sysvinit-2.86.orig/src/utmp.c 1999-06-09 04:11:33.000000000 -0700 | |
667 | +++ sysvinit-2.86/src/utmp.c 2009-01-07 11:11:29.000000000 -0800 | |
668 | @@ -47,6 +47,7 @@ | |
669 | int fd; | |
670 | struct utmp utmp; | |
671 | struct utsname uname_buf; | |
672 | + struct timeval tv; | |
673 | ||
674 | /* | |
675 | * Try to open the wtmp file. Note that we even try | |
676 | @@ -76,7 +77,9 @@ | |
677 | */ | |
678 | memset(&utmp, 0, sizeof(utmp)); | |
679 | #if defined(__GLIBC__) | |
680 | - gettimeofday(&utmp.ut_tv, NULL); | |
681 | + gettimeofday(&tv, NULL); | |
682 | + utmp.ut_tv.tv_sec = tv.tv_sec; | |
683 | + utmp.ut_tv.tv_usec = tv.tv_usec; | |
684 | #else | |
685 | time(&utmp.ut_time); | |
686 | #endif | |
687 | @@ -113,6 +116,7 @@ | |
688 | struct utmp utmp; | |
689 | struct utmp tmp; | |
690 | struct utmp *utmptr; | |
691 | + struct timeval tv; | |
692 | ||
693 | /* | |
694 | * Can't do much if UTMP_FILE is not present. | |
695 | @@ -144,7 +148,9 @@ | |
696 | utmp.ut_pid = pid; | |
697 | strncpy(utmp.ut_id, id, sizeof(utmp.ut_id)); | |
698 | #if defined(__GLIBC__) | |
699 | - gettimeofday(&utmp.ut_tv, NULL); | |
700 | + gettimeofday(&tv, NULL); | |
701 | + utmp.ut_tv.tv_sec = tv.tv_sec; | |
702 | + utmp.ut_tv.tv_usec = tv.tv_usec; | |
703 | #else | |
704 | time(&utmp.ut_time); | |
705 | #endif |