- Add patch to make last(1) knowing latest IPv6 specs
- Update to sysvinit (2.88dsf) world; urgency=low * Mention new home on Savannah in README. * Revert change from Fedora/RedHat where the now obsolete command INIT_CMD_CHANGECONS was introduced. Based on feedback and patch from Bill Nottingham. * Adjust makefile to make sure the install directories are created before files are copied into them. * Simplify build rules, based on patch from Mike Frysinger and Gentoo. * Fix minor bug in optimizing of argument parsing. Based on report from jakemus on freshmeat. * Add casts to get rid of compiler warning about signed/unsigned issues. * Change tty handling in init to make sure the UTF-8 flag is not cleared on boot. Patch from Samuel Thibault. * Add Makefile in toplevel directory. * Print usage information when shutdown is used by non-root user. Patch from Mike Frysinger and Gentoo. * Sync shutdown manual page and usage information. Patch from Mike Frysinger and Gentoo. * Fix race condition in utmp writing. Patch from Gil Kloepfer via Mike Frysinger and Gentoo. * Rewrite findtty() in bootlogd to recursively search /dev/ for the correct device, to handle terminal devices for example in /dev/pty/. Patch from Debian. * Make sure bootlogd findpty() returns an error value when it fails to find a usable pty. Patch from Rob Leslie via Debian. * Make sure bootlogd fflush() every line, even if asked not to flush to disk using fdatasync(). Patch from Scott Gifford via Debian. * Add compatibility code to handle old path "/etc/powerstatus" for a while. * Incude definition for MNT_DETACH which is missing in older GNU libc headers. * Do not strip binaries before installing them, to make it easier to get binaries with debug information installed. * Add the comment from Andrea Arcangeli about the correct place of setting the default childhandler within spawn(). * Make sure that newline is printed out for last(1) even if an utmp record entry is truncated. * Check if utmp not only exists but also is writable and delay writing out of the utmp runlevel record if utmp is not writable. * Be able to find libcrypt also on 64 bit based architectures. * Add option -w to the last command to display the full user and domain names in the output. Patch from Petr Lautrbach. * Add a manual page for utmpdump as this tool is sometimes very useful even if not intended for normal use. * Use paths.h macros for wall * Change path "/etc/powerstatus" to "/var/run/powerstatus" * Detected also removable block devices at halt/reboot to be able to flush data and send them the ATA standby command. This should avoid data loss on USB sticks and other removable block devices. * Flush block devices on halt/reboot if not done by the kernel. * Set SHELL to /bin/sh in the environmant of shutdown. * Retry to write out shutdown messages if interrupted. * pidof/killall5 - make omit pid list a dynamic one. * pidof - provide '-n' to skip stat(2) syscall on network based FS. * init - avoid compiler warnings * init - initialize console by using the macros from ttydefaults.h * init - add the possiblity to ignore further interrupts from keyboard * init - add the possiblity to set sane terminal line settings * sulogin - add the possibility to reset the terminal io * Fix some minor problems * init - enable is_selinux_enabled() to detect selinuxfs * Add fix for Debian bug #536574 -- Can be enabled by -DACCTON_OFF * Add helper program fstab-decode to make it easier to handle /etc/mtab content. Patch by Miloslav Trmac and Fedora. * Add fix for Debian bug #335023 - Make sure TERM is set on FreeBSD. * Add fix for Debian bug #374038 - Make it clear that shutdown -c can only cancel a waiting shutdown, not an active one. * Add note to pidof manual page about the use of readlink(2). Patch by Bill Nottingham and Fedora. * Add PAM patch contrib/notify-pam-dead.patch based on Debian bug #68621, which will add PAM support for programs spawned by init on the console like sulogin. Based on patch by Topi Miettinen. This patch is not applied by default yet while we review its usefullness. It is only helpful for session handling, as sulogin do not use and will not use a PAM conv() function. The current sulogin is able to handle DES as well as MD5, SHA, and Blowfish encrypted passwords due using getpwnam(3). * Move utmp/wtmp before the execvp() in spawn() to be sure to use the correct pid even on a controlling tty * Remaining problem is that the pid of the second fork() for getting a controlling tty isn't that reported by spawn() * Re-enable writting utmp/wtmp for boot scripts * Extend sulogin to support additional encryption algorithms * Re-enable maintenance message of sulogin * Enable the sulogin fallback password check to handle MD5, SHA, and Blowfish encrypted passwords in case of getpwnam(3) fails. * sulogin picking the SELinux context was broken. Patch by Daniel Walsh - Test out sysvinit (2.88dsf) UNRELEASED; urgency=low - Update to sysvinit (2.87dsf) world; urgency=low * Document -e and -t options for telinit in init(8). * Document in halt(8) that -n might not disable all syncing. Patch by Bill Nottingham and Fedora * Adjust output from "last -x". In reboot lines, print endpoint of uptime too. In shutdown lines print downtimes rather than the time between downs. Fix typo in string compare in last.c. Patch by Thomas Hood. * Improve handling of IPv6 addresses in last. Patch from Fedora. * Add new option -F to last, to output full date string instead of the short form provided by default. Patch from Olaf Dabrunz and SuSe. * Fix utmp/wtmp updating on 64-bit platforms. Patch by Bill Nottingham and Fedora. * Avoid unchecked return value from malloc() in utmpdump. Patch from Christian 'Dr. Disk' Hechelmann and Fedora. * Make sure to use execle and no execl when passing environment to the new process. Patch from RedHat. * Correct init to make sure the waiting status is preserved across re-exec. Patch from RedHat. * Correct init to avoid race condition when starting programs during boot. Patch from SuSe. * Allow 'telinit u' in runlevels 0 and 6. Patch from Thomas Hood. * Improve error message from init if fork() fail. Patch found in Suse. * Add support for SE Linux capability handling. Patch from Manoj Srivastava, adjusted to avoid aborting if SE policy was loaded in the initrd with patch from Bill Nottingham and Fedora. * Add -c option to pidof for only matching processes with the same process root. Ignore -c when not running as root. Patch from Thomas Woerner and Fedora. * Add usleep in killall5 after killing processes, to force the kernel to reschedule. Patch from SuSe. * Modify pidof to not print empty line if no pid was found. * Modify init and sulogin to fix emergency mode's tty, making sure ^C and ^Z work when booting with 'emergency' kernel option. Patch from Samuel Thibault. * Modify init to allow some time for failed opens to resolve themselves. Patch from Bill Nottingham and Fedora. * Modify init to shut down IDE, SCSI and SATA disks properly. Patches from Sebastian Reichelt, Werner Fink and SuSe. * Modify wall to use UT_LINESIZE from <utmp.h> instead of hardcoded string lengths. Patch from SuSe. * Change wall to make halt include hostname in output. * Change killall to avoid killing init by mistake. Patch from SuSe. * Change killall5 to use the exit value to report if it found any processes to kill. Patch from Debian. * Add option -o opmitpid to killall5, to make it possible to skip some pids during shutdown. Based on patch from Colin Watson and Ubuntu. * Modify killall to work better with user space file system, by changing cwd to /proc when stopping and killing processes, and avoiding stat() when the value isn't used. Also, lock process pages in memory to avoid paging when user processes are stopped. Patch from Debian and Goswin von Brederlow with changes by Kel Modderman. * Change shutdown to only accept flags -H and -P with the -h flag, and document this requirement in the manual page. * Change reboot/halt to work properly when used as a login shell. Patch by Dale R. Worley and Fedora. * Let sulogin fall back to the staticly linked /bin/sash if both roots shell and /bin/sh fail to execute. OBS-URL: https://build.opensuse.org/package/show/Base:System/sysvinit?expand=0&rev=40
This commit is contained in:
parent
f418e2638e
commit
3afec739d5
212
notify-pam-dead.patch
Normal file
212
notify-pam-dead.patch
Normal file
@ -0,0 +1,212 @@
|
||||
--- src/Makefile
|
||||
+++ src/Makefile 2010-04-13 00:00:00.000000000 +0000
|
||||
@@ -8,7 +8,7 @@
|
||||
# Version: @(#)Makefile 2.85-13 23-Mar-2004 miquels@cistron.nl
|
||||
#
|
||||
|
||||
-CPPFLAGS =
|
||||
+CPPFLAGS = -DUSE_PAM
|
||||
CFLAGS ?= -ansi -O2 -fomit-frame-pointer
|
||||
override CFLAGS += -W -Wall -D_GNU_SOURCE
|
||||
STATIC =
|
||||
@@ -78,6 +78,13 @@ else
|
||||
endif
|
||||
|
||||
# Additional libs for GNU libc.
|
||||
+ifneq ($(findstring -DUSE_PAM,$(CPPFLAGS)),)
|
||||
+ INITLIBS += -lpam
|
||||
+ PAMDOTD = /etc/pam.d
|
||||
+ PAMINIT = $(PAMDOTD)/init
|
||||
+endif
|
||||
+
|
||||
+# Additional libs for GNU libc.
|
||||
ifneq ($(wildcard /usr/lib*/libcrypt.a),)
|
||||
SULOGINLIBS += -lcrypt
|
||||
endif
|
||||
@@ -149,6 +156,11 @@ install:
|
||||
for i in $(USRBIN); do \
|
||||
$(INSTALL_EXEC) $$i $(ROOT)/usr/bin/ ; \
|
||||
done
|
||||
+ifneq ($(findstring -DUSE_PAM,$(CPPFLAGS)),)
|
||||
+ $(INSTALL_DIR) $(ROOT)$(PAMDOTD)
|
||||
+ test -s $(ROOT)$(PAMINIT) || \
|
||||
+ $(INSTALL_DATA) init.sample $(ROOT)$(PAMINIT)
|
||||
+endif
|
||||
# $(INSTALL_DIR) $(ROOT)/etc/
|
||||
# $(INSTALL_EXEC) initscript.sample $(ROOT)/etc/
|
||||
ln -sf halt $(ROOT)/sbin/reboot
|
||||
--- src/init.c
|
||||
+++ src/init.c 2010-04-13 00:00:00.000000000 +0000
|
||||
@@ -79,6 +79,10 @@
|
||||
#include "reboot.h"
|
||||
#include "set.h"
|
||||
|
||||
+#ifdef USE_PAM
|
||||
+extern void notify_pam_dead_session(const char *id);
|
||||
+#endif
|
||||
+
|
||||
#ifndef SIGPWR
|
||||
# define SIGPWR SIGUSR2
|
||||
#endif
|
||||
@@ -1132,6 +1136,9 @@ pid_t spawn(CHILD *ch, int *res)
|
||||
}
|
||||
dup(f);
|
||||
dup(f);
|
||||
+#ifdef USE_PAM
|
||||
+ notify_pam_dead_session(ch->id);
|
||||
+#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1551,6 +1558,9 @@ void read_inittab(void)
|
||||
INITDBG(L_VB, "Updating utmp for pid %d [id %s]",
|
||||
ch->pid, ch->id);
|
||||
ch->flags &= ~RUNNING;
|
||||
+#ifdef USE_PAM
|
||||
+ notify_pam_dead_session(ch->id);
|
||||
+#endif
|
||||
if (ch->process[0] != '+')
|
||||
write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
|
||||
}
|
||||
@@ -2012,6 +2022,9 @@ void re_exec(void)
|
||||
if (ch->flags & ZOMBIE) {
|
||||
INITDBG(L_VB, "Child died, PID= %d", ch->pid);
|
||||
ch->flags &= ~(RUNNING|ZOMBIE|WAITING);
|
||||
+#ifdef USE_PAM
|
||||
+ notify_pam_dead_session(ch->id);
|
||||
+#endif
|
||||
if (ch->process[0] != '+')
|
||||
write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
|
||||
}
|
||||
@@ -2465,6 +2478,9 @@ void process_signals()
|
||||
if (ch->flags & ZOMBIE) {
|
||||
INITDBG(L_VB, "Child died, PID= %d", ch->pid);
|
||||
ch->flags &= ~(RUNNING|ZOMBIE|WAITING);
|
||||
+#ifdef USE_PAM
|
||||
+ notify_pam_dead_session(ch->id);
|
||||
+#endif
|
||||
if (ch->process[0] != '+')
|
||||
write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
|
||||
}
|
||||
--- src/init.sample
|
||||
+++ src/init.sample 2010-04-13 00:00:00.000000000 +0000
|
||||
@@ -0,0 +1,9 @@
|
||||
+#%PAM-1.0
|
||||
+#
|
||||
+# The PAM configuration file for /sbin/init
|
||||
+# Used for updating the lastlog logging file
|
||||
+#
|
||||
+auth sufficient pam_rootok.so
|
||||
+account include common-account
|
||||
+session include common-session
|
||||
+session requisite pam_lastlog.so silent
|
||||
--- src/utmp.c
|
||||
+++ src/utmp.c 2010-04-13 00:00:00.000000000 +0000
|
||||
@@ -34,10 +34,18 @@
|
||||
#include <string.h>
|
||||
#include <utmp.h>
|
||||
|
||||
+#if defined(USE_PAM) && defined(INIT_MAIN)
|
||||
+# include <security/pam_appl.h>
|
||||
+# include <security/pam_misc.h>
|
||||
+#endif
|
||||
+
|
||||
#include "init.h"
|
||||
#include "initreq.h"
|
||||
#include "paths.h"
|
||||
|
||||
+#ifndef _PATH_DEV
|
||||
+# define _PATH_DEV "/dev/"
|
||||
+#endif
|
||||
|
||||
#if defined(__GLIBC__)
|
||||
# if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0) && defined(__powerpc__)
|
||||
@@ -127,9 +135,9 @@ char *line) /* Which line is this */
|
||||
strncpy(utmp.ut_name, user, sizeof(utmp.ut_name));
|
||||
strncpy(utmp.ut_id , id , sizeof(utmp.ut_id ));
|
||||
strncpy(utmp.ut_line, line, sizeof(utmp.ut_line));
|
||||
-
|
||||
- /* Put the OS version in place of the hostname */
|
||||
- if (uname(&uname_buf) == 0)
|
||||
+
|
||||
+ /* Put the OS version in place of the hostname */
|
||||
+ if (uname(&uname_buf) == 0)
|
||||
strncpy(utmp.ut_host, uname_buf.release, sizeof(utmp.ut_host));
|
||||
|
||||
#if HAVE_UPDWTMP
|
||||
@@ -262,3 +270,75 @@ char *line) /* LINE if used. */
|
||||
write_wtmp(user, id, pid, type, line && line[0] ? line : oldline);
|
||||
}
|
||||
|
||||
+#if defined(USE_PAM) && defined(INIT_MAIN)
|
||||
+static pam_handle_t *pamh = NULL;
|
||||
+# ifdef __GNUC__
|
||||
+static int
|
||||
+null_conv(int num_msg, const struct pam_message **msgm,
|
||||
+ struct pam_response **response __attribute__((unused)),
|
||||
+ void *appdata_ptr __attribute__((unused)))
|
||||
+# else
|
||||
+static int
|
||||
+null_conv(int num_msg, const struct pam_message **msgm,
|
||||
+ struct pam_response **response, void *appdata_ptr)
|
||||
+# endif
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0; i < num_msg; i++) {
|
||||
+ const struct pam_message *msg = msgm[i];
|
||||
+ if (msg == (const struct pam_message*)0)
|
||||
+ continue;
|
||||
+ if (msg->msg == (char*)0)
|
||||
+ continue;
|
||||
+ switch (msg->msg_style) {
|
||||
+ case PAM_ERROR_MSG:
|
||||
+ case PAM_TEXT_INFO:
|
||||
+ initlog(L_VB, "pam_message %s", msg->msg);
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+static const struct pam_conv conv = { null_conv, NULL };
|
||||
+# define PAM_FAIL_CHECK(func, args...) \
|
||||
+ { \
|
||||
+ if ((pam_ret = (func)(args)) != PAM_SUCCESS) { \
|
||||
+ initlog(L_VB, "%s", pam_strerror(pamh, pam_ret)); \
|
||||
+ goto pam_error; \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+void notify_pam_dead_session(const char *id)
|
||||
+{
|
||||
+ struct utmp *oldut, ut;
|
||||
+
|
||||
+ setutent();
|
||||
+
|
||||
+ memset(&ut, 0, sizeof(ut));
|
||||
+ ut.ut_type = DEAD_PROCESS;
|
||||
+ strncpy(ut.ut_id, id, sizeof(ut.ut_id));
|
||||
+
|
||||
+ if ((oldut = getutid(&ut)) && (oldut->ut_type == USER_PROCESS)) {
|
||||
+ int pam_ret;
|
||||
+ char tty[UT_LINESIZE+ strlen(_PATH_DEV) + 1];
|
||||
+
|
||||
+ if (strncmp(oldut->ut_line, _PATH_DEV, strlen(_PATH_DEV)))
|
||||
+ snprintf(tty, sizeof(tty), _PATH_DEV "%.*s",
|
||||
+ UT_LINESIZE, oldut->ut_line);
|
||||
+ else
|
||||
+ snprintf(tty, sizeof(tty), "%.*s",
|
||||
+ UT_LINESIZE, oldut->ut_line);
|
||||
+
|
||||
+ PAM_FAIL_CHECK(pam_start, "init", oldut->ut_user, &conv, &pamh);
|
||||
+ PAM_FAIL_CHECK(pam_set_item, pamh, PAM_TTY, tty);
|
||||
+ PAM_FAIL_CHECK(pam_set_item, pamh, PAM_RHOST, oldut->ut_host);
|
||||
+ PAM_FAIL_CHECK(pam_close_session, pamh, PAM_SILENT);
|
||||
+ pam_error:
|
||||
+ pam_end(pamh, pam_ret);
|
||||
+ }
|
||||
+
|
||||
+ endutent();
|
||||
+}
|
||||
+#endif /* USE_PAM && INIT_MAIN */
|
||||
+
|
@ -1,53 +0,0 @@
|
||||
--- contrib/start-stop-daemon.c
|
||||
+++ contrib/start-stop-daemon.c
|
||||
@@ -108,28 +108,28 @@
|
||||
static void
|
||||
do_help(void)
|
||||
{
|
||||
- printf("\
|
||||
-start-stop-daemon for Debian Linux - small and fast C version written by\n\
|
||||
-Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>, public domain.\n"
|
||||
-VERSION "\n\
|
||||
-\n\
|
||||
-Usage:
|
||||
- start-stop-daemon -S|--start options ... -- arguments ...\n\
|
||||
- start-stop-daemon -K|--stop options ...\n\
|
||||
- start-stop-daemon -H|--help\n\
|
||||
- start-stop-daemon -V|--version\n\
|
||||
-\n\
|
||||
-Options (at least one of --exec|--pidfile|--user is required):
|
||||
- -x|--exec <executable> program to start/check if it is running\n\
|
||||
- -p|--pidfile <pid-file> pid file to check\n\
|
||||
- -u|--user <username>|<uid> stop this user's processes\n\
|
||||
- -n|--name <process-name> start/stop processes with this name\n\
|
||||
- -s|--signal <signal> signal to send (default 15)\n\
|
||||
- -t|--test test mode, don't do anything\n\
|
||||
- -o|--oknodo exit status 0 (not 1) if nothing done\n\
|
||||
- -q|--quiet | -v, --verbose\n\
|
||||
-\n\
|
||||
-Exit status: 0 = done 1 = nothing done (=> 0 if --oknodo) 2 = trouble\n");
|
||||
+ printf(
|
||||
+"start-stop-daemon for Debian Linux - small and fast C version written by\n"
|
||||
+"Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>, public domain.\n"
|
||||
+VERSION "\n"
|
||||
+"\n"
|
||||
+"Usage:\n"
|
||||
+" start-stop-daemon -S|--start options ... -- arguments ...\n"
|
||||
+" start-stop-daemon -K|--stop options ...\n"
|
||||
+" start-stop-daemon -H|--help\n"
|
||||
+" start-stop-daemon -V|--version\n"
|
||||
+"\n"
|
||||
+"Options (at least one of --exec|--pidfile|--user is required):\n"
|
||||
+" -x|--exec <executable> program to start/check if it is running\n"
|
||||
+" -p|--pidfile <pid-file> pid file to check\n"
|
||||
+" -u|--user <username>|<uid> stop this user's processes\n"
|
||||
+" -n|--name <process-name> start/stop processes with this name\n"
|
||||
+" -s|--signal <signal> signal to send (default 15)\n"
|
||||
+" -t|--test test mode, don't do anything\n"
|
||||
+" -o|--oknodo exit status 0 (not 1) if nothing done\n"
|
||||
+" -q|--quiet | -v, --verbose\n"
|
||||
+"\n"
|
||||
+"Exit status: 0 = done 1 = nothing done (=> 0 if --oknodo) 2 = trouble\n");
|
||||
}
|
||||
|
||||
|
@ -1,26 +0,0 @@
|
||||
--- man/init.8
|
||||
+++ man/init.8 2004-03-12 12:44:29.000000000 +0000
|
||||
@@ -232,7 +232,7 @@ It activates the \fIkbrequest\fP action.
|
||||
.SH CONFORMING TO
|
||||
\fBInit\fP is compatible with the System V init. It works closely
|
||||
together with the scripts in the directories
|
||||
-\fI/etc/init.d\fP and \fI/etc/rc{runlevel}.d\fP.
|
||||
+\fI/etc/init.d\fP and \fI/etc/init.d/rc{runlevel}.d\fP.
|
||||
If your system uses this convention, there should be a \fIREADME\fP
|
||||
file in the directory \fI/etc/init.d\fP explaining how these scripts work.
|
||||
.\"}}}
|
||||
--- src/paths.h
|
||||
+++ src/paths.h 2004-03-12 12:45:00.000000000 +0000
|
||||
@@ -26,10 +26,10 @@
|
||||
#define SHELL "/bin/sh" /* Default shell */
|
||||
#define SULOGIN "/sbin/sulogin" /* Sulogin */
|
||||
#define INITSCRIPT "/etc/initscript" /* Initscript. */
|
||||
-#define PWRSTAT "/etc/powerstatus" /* COMPAT: SIGPWR reason (OK/BAD) */
|
||||
+#define PWRSTAT "/var/run/powerstatus" /* COMPAT: SIGPWR reason (OK/BAD) */
|
||||
|
||||
#if 0
|
||||
-#define INITLVL "/etc/initrunlvl" /* COMPAT: New runlevel */
|
||||
+#define INITLVL "/var/run/initrunlvl" /* COMPAT: New runlevel */
|
||||
#define INITLVL2 "/var/log/initrunlvl" /* COMPAT: New runlevel */
|
||||
/* Note: INITLVL2 definition needs INITLVL */
|
||||
#define HALTSCRIPT1 "/etc/init.d/halt" /* Called by "fast" shutdown */
|
@ -1,164 +0,0 @@
|
||||
man/last.1 | 6 ++++--
|
||||
src/last.c | 43 ++++++++++++++++++++++++++++++++-----------
|
||||
2 files changed, 36 insertions(+), 13 deletions(-)
|
||||
|
||||
Index: man/last.1
|
||||
===================================================================
|
||||
--- man/last.1 2005-12-05 18:05:40.000000000 +0100
|
||||
+++ man/last.1 2005-12-05 18:09:27.000000000 +0100
|
||||
@@ -12,7 +12,7 @@ last, lastb \- show listing of last logg
|
||||
.RB [ \-R ]
|
||||
.RB [ \-\fInum\fP ]
|
||||
.RB "[ \-\fBn\fP \fInum\fP ]"
|
||||
-.RB [ \-adiox ]
|
||||
+.RB [ \-adFiox ]
|
||||
.RB "[ \-\fBf\fP \fIfile\fP ]"
|
||||
.RB "[ \-\fBt\fP \fIYYYYMMDDHHMMSS\fP ]"
|
||||
.RI [ name... ]
|
||||
@@ -23,7 +23,7 @@ last, lastb \- show listing of last logg
|
||||
.RB [ \-\fInum\fP ]
|
||||
.RB "[ \-\fBn\fP \fInum\fP ]"
|
||||
.RB "[ \-\fBf\fP \fIfile\fP ]"
|
||||
-.RB [ \-adiox ]
|
||||
+.RB [ \-adFiox ]
|
||||
.RI [ name... ]
|
||||
.RI [ tty... ]
|
||||
.\"}}}
|
||||
@@ -69,6 +69,8 @@ with the next flag.
|
||||
For non-local logins, Linux stores not only the host name of the remote
|
||||
host but its IP number as well. This option translates the IP number
|
||||
back into a hostname.
|
||||
+.IP \fB\-F\fP
|
||||
+Print full login and logout times and dates.
|
||||
.IP \fB\-i\fP
|
||||
This option is like \fB-d\fP in that it displays the IP number of the remote
|
||||
host, but it displays the IP number in numbers-and-dots notation.
|
||||
Index: src/last.c
|
||||
===================================================================
|
||||
--- src/last.c 2005-12-05 18:07:21.000000000 +0100
|
||||
+++ src/last.c 2009-02-20 16:37:27.380797018 +0100
|
||||
@@ -70,6 +70,7 @@ int showhost = 1; /* Show hostname too?
|
||||
int altlist = 0; /* Show hostname at the end. */
|
||||
int usedns = 0; /* Use DNS to lookup the hostname. */
|
||||
int useip = 0; /* Print IP address in number format */
|
||||
+int fulltime = 0; /* Print full dates and times */
|
||||
int oldfmt = 0; /* Use old libc5 format? */
|
||||
char **show = NULL; /* What do they want us to show */
|
||||
char *ufile; /* Filename of this file */
|
||||
@@ -388,9 +389,13 @@ int list(struct utmp *p, time_t t, int w
|
||||
*/
|
||||
tmp = (time_t)p->ut_time;
|
||||
strcpy(logintime, ctime(&tmp));
|
||||
- logintime[16] = 0;
|
||||
- sprintf(logouttime, "- %s", ctime(&t) + 11);
|
||||
- logouttime[7] = 0;
|
||||
+ if (fulltime)
|
||||
+ sprintf(logouttime, "- %s", ctime(&t));
|
||||
+ else {
|
||||
+ logintime[16] = 0;
|
||||
+ sprintf(logouttime, "- %s", ctime(&t) + 11);
|
||||
+ logouttime[7] = 0;
|
||||
+ }
|
||||
secs = t - p->ut_time;
|
||||
mins = (secs / 60) % 60;
|
||||
hours = (secs / 3600) % 24;
|
||||
@@ -409,13 +414,21 @@ int list(struct utmp *p, time_t t, int w
|
||||
break;
|
||||
case R_NOW:
|
||||
length[0] = 0;
|
||||
- sprintf(logouttime, " still");
|
||||
- sprintf(length, "logged in");
|
||||
+ if (fulltime)
|
||||
+ sprintf(logouttime, " still logged in");
|
||||
+ else {
|
||||
+ sprintf(logouttime, " still");
|
||||
+ sprintf(length, "logged in");
|
||||
+ }
|
||||
break;
|
||||
case R_PHANTOM:
|
||||
length[0] = 0;
|
||||
- sprintf(logouttime, " gone");
|
||||
- sprintf(length, "- no logout");
|
||||
+ if (fulltime)
|
||||
+ sprintf(logouttime, " gone - no logout");
|
||||
+ else {
|
||||
+ sprintf(logouttime, " gone");
|
||||
+ sprintf(length, "- no logout");
|
||||
+ }
|
||||
break;
|
||||
case R_REBOOT:
|
||||
logouttime[0] = 0; /* Print machine uptime */
|
||||
@@ -450,23 +463,30 @@ int list(struct utmp *p, time_t t, int w
|
||||
strcmp(s + 1, domainname) == 0) *s = 0;
|
||||
#endif
|
||||
if (!altlist) {
|
||||
- snprintf(final, sizeof(final),
|
||||
- "%-8.8s %-12.12s %-16.16s "
|
||||
- "%-16.16s %-7.7s %-12.12s\n",
|
||||
+ len = snprintf(final, sizeof(final),
|
||||
+ fulltime ?
|
||||
+ "%-8.8s %-12.12s %-16.16s %-24.24s %-26.26s %-12.12s\n" :
|
||||
+ "%-8.8s %-12.12s %-16.16s %-16.16s %-7.7s %-12.12s\n",
|
||||
p->ut_name, utline,
|
||||
domain, logintime, logouttime, length);
|
||||
} else {
|
||||
- snprintf(final, sizeof(final),
|
||||
+ len = snprintf(final, sizeof(final),
|
||||
+ fulltime ?
|
||||
+ "%-8.8s %-12.12s %-24.24s %-26.26s %-12.12s %s\n" :
|
||||
"%-8.8s %-12.12s %-16.16s %-7.7s %-12.12s %s\n",
|
||||
p->ut_name, utline,
|
||||
logintime, logouttime, length, domain);
|
||||
}
|
||||
} else
|
||||
- snprintf(final, sizeof(final),
|
||||
+ len = snprintf(final, sizeof(final),
|
||||
+ fulltime ?
|
||||
+ "%-8.8s %-12.12s %-24.24s %-26.26s %-12.12s\n" :
|
||||
"%-8.8s %-12.12s %-16.16s %-7.7s %-12.12s\n",
|
||||
p->ut_name, utline,
|
||||
logintime, logouttime, length);
|
||||
|
||||
+ final[sizeof(final)-1] = '\0';
|
||||
+
|
||||
/*
|
||||
* Print out "final" string safely.
|
||||
*/
|
||||
@@ -477,6 +497,9 @@ int list(struct utmp *p, time_t t, int w
|
||||
putchar('*');
|
||||
}
|
||||
|
||||
+ if (len < 0 || len >= sizeof(final))
|
||||
+ putchar('\n');
|
||||
+
|
||||
recsdone++;
|
||||
if (maxrecs && recsdone >= maxrecs)
|
||||
return 1;
|
||||
@@ -492,7 +515,7 @@ void usage(char *s)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-num | -n num] [-f file] "
|
||||
"[-t YYYYMMDDHHMMSS] "
|
||||
- "[-R] [-a] [-d] [-i] [-o] [-x] "
|
||||
+ "[-R] [-a] [-d] [-F] [-i] [-o] [-x] "
|
||||
"[username..] [tty..]\n", s);
|
||||
|
||||
exit(1);
|
||||
@@ -563,7 +586,7 @@ int main(int argc, char **argv)
|
||||
progname = mybasename(argv[0]);
|
||||
|
||||
/* Process the arguments. */
|
||||
- while((c = getopt(argc, argv, "f:n:Rxadiot:0123456789")) != EOF)
|
||||
+ while((c = getopt(argc, argv, "f:n:RxadFiot:0123456789")) != EOF)
|
||||
switch(c) {
|
||||
case 'R':
|
||||
showhost = 0;
|
||||
@@ -594,6 +617,9 @@ int main(int argc, char **argv)
|
||||
case 'a':
|
||||
altlist++;
|
||||
break;
|
||||
+ case 'F':
|
||||
+ fulltime++;
|
||||
+ break;
|
||||
case 't':
|
||||
if ((until = parsetm(optarg)) == (time_t)-1) {
|
||||
fprintf(stderr, "%s: Invalid time value \"%s\"\n",
|
@ -1,90 +0,0 @@
|
||||
--- src/killall5.c
|
||||
+++ src/killall5.c 2009-01-27 15:32:40.000000000 +0000
|
||||
@@ -59,6 +59,8 @@ typedef struct proc {
|
||||
pid_t pid; /* Process ID. */
|
||||
int sid; /* Session ID. */
|
||||
char kernel; /* Kernel thread or zombie. */
|
||||
+ char isfuse; /* Provides FUSE filesystems */
|
||||
+ char isudev; /* Is the uevent handler */
|
||||
char nfs; /* Binary is loacted on NFS part. */
|
||||
struct proc *next; /* Pointer to next struct. */
|
||||
} PROC;
|
||||
@@ -410,6 +412,38 @@ int readarg(FILE *fp, char *buf, int sz)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Scan the filedescriptors of pid for /dev/fuse
|
||||
+ */
|
||||
+int is_fuse(const char *pid) {
|
||||
+ DIR *dir;
|
||||
+ char path[256];
|
||||
+ char buf[256];
|
||||
+ struct dirent *d;
|
||||
+ ssize_t len;
|
||||
+
|
||||
+ /* Open /proc/pid/fd/ */
|
||||
+ snprintf(path, sizeof(path), "/proc/%s/fd", pid);
|
||||
+ if ((dir = opendir(path)) != NULL) {
|
||||
+ int dfd = dirfd(dir);
|
||||
+ /* Walk through the directory. */
|
||||
+ while ((d = readdir(dir)) != NULL) {
|
||||
+ if (*d->d_name == '.')
|
||||
+ continue;
|
||||
+ /* check for /dev/fuse */
|
||||
+ if ((len = readlinkat(dfd, d->d_name, buf, sizeof(buf))) > 0) {
|
||||
+ buf[len] = '\0';
|
||||
+ if (strcmp("/dev/fuse", buf) == 0)
|
||||
+ return 1; /* Fuse filesystem */
|
||||
+ }
|
||||
+ }
|
||||
+ closedir(dir);
|
||||
+ }
|
||||
+
|
||||
+ /* Not a fuse filesystem */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Read the proc filesystem.
|
||||
*/
|
||||
int readproc()
|
||||
@@ -565,13 +599,19 @@ int readproc()
|
||||
|
||||
/* Try to stat the executable. */
|
||||
snprintf(path, sizeof(path), "/proc/%s/exe", d->d_name);
|
||||
- if (check4nfs(path, NULL))
|
||||
+ if (check4nfs(path, buf))
|
||||
p->nfs = 1;
|
||||
if ((p->nfs == 0) && (stat(path, &st) == 0)) {
|
||||
p->dev = st.st_dev;
|
||||
p->ino = st.st_ino;
|
||||
}
|
||||
|
||||
+ /* Check for uevent handler */
|
||||
+ p->isudev = (strncmp(buf, "/sbin/udevd", 11) == 0);
|
||||
+
|
||||
+ /* Check for provider of FUSE filesystems */
|
||||
+ p->isfuse = is_fuse(d->d_name);
|
||||
+
|
||||
/* Link it into the list. */
|
||||
p->next = plist;
|
||||
plist = p;
|
||||
@@ -907,14 +947,16 @@ int main(int argc, char **argv)
|
||||
}
|
||||
clear_mnt();
|
||||
|
||||
- /* Now kill all processes except our session. */
|
||||
+ /* Now kill all processes except init (pid 1), our session, and FUSE filesystems. */
|
||||
sid = (int)getsid(0);
|
||||
pid = (int)getpid();
|
||||
for (p = plist; p; p = p->next) {
|
||||
- if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel) {
|
||||
+ if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel || p->isfuse) {
|
||||
kill(p->pid, SIGCONT);
|
||||
continue;
|
||||
}
|
||||
+ if (((sig == SIGTERM) || (sig == SIGKILL)) && p->isudev)
|
||||
+ continue;
|
||||
kill(p->pid, sig);
|
||||
}
|
||||
|
@ -1,428 +0,0 @@
|
||||
--- src/halt.c
|
||||
+++ src/halt.c 2008-05-21 14:04:11.762054000 +0200
|
||||
@@ -57,6 +57,7 @@ char *progname;
|
||||
|
||||
extern int ifdown(void);
|
||||
extern int hddown(void);
|
||||
+extern int hdflush(void);
|
||||
extern void write_wtmp(char *user, char *id, int pid, int type, char *line);
|
||||
|
||||
/*
|
||||
@@ -259,6 +260,8 @@ int main(int argc, char **argv)
|
||||
|
||||
if (do_hddown)
|
||||
(void)hddown();
|
||||
+ else
|
||||
+ (void)hdflush();
|
||||
|
||||
if (do_nothing) exit(0);
|
||||
|
||||
--- src/hddown.c
|
||||
+++ src/hddown.c 2008-05-21 14:48:40.913836000 +0200
|
||||
@@ -5,6 +5,9 @@
|
||||
*/
|
||||
char *v_hddown = "@(#)hddown.c 1.02 22-Apr-2003 miquels@cistron.nl";
|
||||
|
||||
+#ifndef _GNU_SOURCE
|
||||
+#define _GNU_SOURCE
|
||||
+#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -17,7 +20,371 @@ char *v_hddown = "@(#)hddown.c 1.02 22
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/hdreg.h>
|
||||
+#include <linux/fs.h>
|
||||
+
|
||||
+#define USE_SYSFS
|
||||
+#ifdef USE_SYSFS
|
||||
+/*
|
||||
+ * sysfs part Find all disks on the system, list out IDE and unmanaged
|
||||
+ * SATA disks, flush the cache of those and shut them down.
|
||||
+ * Author: Werner Fink <werner@suse.de>, 2007/06/12
|
||||
+ *
|
||||
+ */
|
||||
+#include <limits.h>
|
||||
+#include <errno.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <sys/types.h>
|
||||
+#ifdef WORDS_BIGENDIAN
|
||||
+#include <byteswap.h>
|
||||
+#endif
|
||||
+
|
||||
+#define SYS_BLK "/sys/block"
|
||||
+#define SYS_CLASS "/sys/class/scsi_disk"
|
||||
+#define DEV_BASE "/dev"
|
||||
+#define ISSPACE(c) (((c)==' ')||((c)=='\n')||((c)=='\t')||((c)=='\v')||((c)=='\r')||((c)=='\f'))
|
||||
+
|
||||
+/* Used in flush_cache_ext(), compare with <linux/hdreg.h> */
|
||||
+#define IDBYTES 512
|
||||
+#define MASK_EXT 0xE000 /* Bit 15 shall be zero, bit 14 shall be one, bit 13 flush cache ext */
|
||||
+#define TEST_EXT 0x6000
|
||||
+
|
||||
+/* Maybe set in list_disks() and used in do_standby_idedisk() */
|
||||
+#define DISK_IS_IDE 0x00000001
|
||||
+#define DISK_IS_SATA 0x00000002
|
||||
+#define DISK_EXTFLUSH 0x00000004
|
||||
+#define DISK_REMOVABLE 0x00000008
|
||||
+#define DISK_MANAGED 0x00000010
|
||||
+#define DISK_NOSTANDBY 0x00000020
|
||||
+#define DISK_FLUSHONLY DISK_NOSTANDBY
|
||||
+
|
||||
+static char *strstrip(char *str);
|
||||
+static FILE *hdopen(const char* const format, const char* const name);
|
||||
+static int flush_cache_ext(const char *device);
|
||||
+
|
||||
+/*
|
||||
+ * Find all disks through /sys/block.
|
||||
+ */
|
||||
+static char *list_disks(DIR* blk, unsigned int* flags)
|
||||
+{
|
||||
+ struct dirent *d;
|
||||
+
|
||||
+ while ((d = readdir(blk))) {
|
||||
+ (*flags) = 0;
|
||||
+ if (d->d_name[1] == 'd' && (d->d_name[0] == 'h' || d->d_name[0] == 's')) {
|
||||
+ char buf[NAME_MAX+1], lnk[NAME_MAX+1], *ptr;
|
||||
+ FILE *fp;
|
||||
+ int ret;
|
||||
+
|
||||
+ fp = hdopen(SYS_BLK "/%s/removable", d->d_name);
|
||||
+ if ((long)fp <= 0) {
|
||||
+ if ((long)fp < 0)
|
||||
+ goto empty; /* error */
|
||||
+ continue; /* no entry `removable' */
|
||||
+ }
|
||||
+
|
||||
+ ret = getc(fp);
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ if (ret != '0')
|
||||
+ (*flags) |= DISK_REMOVABLE;
|
||||
+
|
||||
+ if (d->d_name[0] == 'h') {
|
||||
+ if ((*flags) & DISK_REMOVABLE)
|
||||
+ continue; /* not a hard disk */
|
||||
+
|
||||
+ (*flags) |= DISK_IS_IDE;
|
||||
+ if ((ret = flush_cache_ext(d->d_name))) {
|
||||
+ if (ret < 0)
|
||||
+ goto empty;
|
||||
+ (*flags) |= DISK_EXTFLUSH;
|
||||
+ }
|
||||
+ break; /* old IDE disk not managed by kernel, out here */
|
||||
+ }
|
||||
+
|
||||
+ ret = snprintf(buf, sizeof(buf), SYS_BLK "/%s/device", d->d_name);
|
||||
+ if ((ret >= (int)sizeof(buf)) || (ret < 0))
|
||||
+ goto empty; /* error */
|
||||
+
|
||||
+ ret = readlink(buf, lnk, sizeof(lnk));
|
||||
+ if (ret >= (int)sizeof(lnk))
|
||||
+ goto empty; /* error */
|
||||
+ if (ret < 0) {
|
||||
+ if (errno != ENOENT)
|
||||
+ goto empty; /* error */
|
||||
+ continue; /* no entry `device' */
|
||||
+ }
|
||||
+ lnk[ret] = '\0';
|
||||
+
|
||||
+ ptr = basename(lnk);
|
||||
+ if (!ptr || !*ptr)
|
||||
+ continue; /* should not happen */
|
||||
+
|
||||
+ fp = hdopen(SYS_CLASS "/%s/manage_start_stop", ptr);
|
||||
+ if ((long)fp <= 0) {
|
||||
+ if ((long)fp < 0)
|
||||
+ goto empty; /* error */
|
||||
+ } else {
|
||||
+ ret = getc(fp);
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ if (ret != '0') {
|
||||
+ (*flags) |= DISK_MANAGED;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ fp = hdopen(SYS_BLK "/%s/device/vendor", d->d_name);
|
||||
+ if ((long)fp <= 0) {
|
||||
+ if ((long)fp < 0)
|
||||
+ goto empty; /* error */
|
||||
+ continue; /* no entry `device/vendor' */
|
||||
+ }
|
||||
+
|
||||
+ ptr = fgets(buf, sizeof(buf), fp);
|
||||
+ fclose(fp);
|
||||
+ if (ptr == (char*)0)
|
||||
+ continue; /* should not happen */
|
||||
+
|
||||
+ ptr = strstrip(buf);
|
||||
+ if (*ptr == '\0')
|
||||
+ continue; /* should not happen */
|
||||
+
|
||||
+ if (strncmp(buf, "ATA", sizeof(buf)) == 0) {
|
||||
+ if ((*flags) & DISK_REMOVABLE)
|
||||
+ continue; /* not a hard disk */
|
||||
+
|
||||
+ (*flags) |= (DISK_IS_IDE|DISK_IS_SATA);
|
||||
+ if ((ret = flush_cache_ext(d->d_name))) {
|
||||
+ if (ret < 0)
|
||||
+ goto empty;
|
||||
+ (*flags) |= DISK_EXTFLUSH;
|
||||
+ }
|
||||
+ break; /* new SATA disk to shutdown, out here */
|
||||
+ }
|
||||
+
|
||||
+ if (((*flags) & DISK_REMOVABLE) == 0)
|
||||
+ continue; /* Seems to be a real SCSI disk */
|
||||
+
|
||||
+ if ((ret = flush_cache_ext(d->d_name))) {
|
||||
+ if (ret < 0)
|
||||
+ goto empty;
|
||||
+ (*flags) |= DISK_EXTFLUSH;
|
||||
+ }
|
||||
+ break; /* Removable disk like USB stick to shutdown */
|
||||
+ }
|
||||
+ }
|
||||
+ if (d == (struct dirent*)0)
|
||||
+ goto empty;
|
||||
+ return d->d_name;
|
||||
+empty:
|
||||
+ return (char*)0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Put an disk in standby mode.
|
||||
+ * Code stolen from hdparm.c
|
||||
+ */
|
||||
+static int do_standby_disk(char *device, unsigned int flags)
|
||||
+{
|
||||
+#ifndef WIN_STANDBYNOW1
|
||||
+#define WIN_STANDBYNOW1 0xE0
|
||||
+#endif
|
||||
+#ifndef WIN_STANDBYNOW2
|
||||
+#define WIN_STANDBYNOW2 0x94
|
||||
+#endif
|
||||
+#ifndef WIN_FLUSH_CACHE_EXT
|
||||
+#define WIN_FLUSH_CACHE_EXT 0xEA
|
||||
+#endif
|
||||
+#ifndef WIN_FLUSH_CACHE
|
||||
+#define WIN_FLUSH_CACHE 0xE7
|
||||
+#endif
|
||||
+ unsigned char flush1[4] = {WIN_FLUSH_CACHE_EXT,0,0,0};
|
||||
+ unsigned char flush2[4] = {WIN_FLUSH_CACHE,0,0,0};
|
||||
+ unsigned char stdby1[4] = {WIN_STANDBYNOW1,0,0,0};
|
||||
+ unsigned char stdby2[4] = {WIN_STANDBYNOW2,0,0,0};
|
||||
+ char buf[NAME_MAX+1];
|
||||
+ int fd, ret;
|
||||
+
|
||||
+ ret = snprintf(buf, sizeof(buf), DEV_BASE "/%s", device);
|
||||
+ if ((ret >= (int)sizeof(buf)) || (ret < 0))
|
||||
+ return -1;
|
||||
+
|
||||
+ if ((fd = open(buf, O_RDWR|O_NONBLOCK)) < 0)
|
||||
+ return -1;
|
||||
|
||||
+ switch (flags & DISK_EXTFLUSH) {
|
||||
+ case DISK_EXTFLUSH:
|
||||
+ if ((ret = ioctl(fd, HDIO_DRIVE_CMD, &flush1)) == 0)
|
||||
+ break;
|
||||
+ /* Extend flush rejected, try standard flush */
|
||||
+ default:
|
||||
+ ret = ioctl(fd, HDIO_DRIVE_CMD, &flush2) &&
|
||||
+ ioctl(fd, BLKFLSBUF);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if ((flags & DISK_NOSTANDBY) == 0x0) {
|
||||
+ ret = ioctl(fd, HDIO_DRIVE_CMD, &stdby1) &&
|
||||
+ ioctl(fd, HDIO_DRIVE_CMD, &stdby2);
|
||||
+ }
|
||||
+
|
||||
+ close(fd);
|
||||
+
|
||||
+ if (ret)
|
||||
+ return -1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * List all disks and put them in standby mode.
|
||||
+ * This has the side-effect of flushing the writecache,
|
||||
+ * which is exactly what we want on poweroff.
|
||||
+ */
|
||||
+int hddown(void)
|
||||
+{
|
||||
+ unsigned int flags;
|
||||
+ char *disk;
|
||||
+ DIR *blk;
|
||||
+
|
||||
+ if ((blk = opendir(SYS_BLK)) == (DIR*)0)
|
||||
+ return -1;
|
||||
+
|
||||
+ while ((disk = list_disks(blk, &flags)))
|
||||
+ do_standby_disk(disk, flags);
|
||||
+
|
||||
+ return closedir(blk);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * List all disks and cause them to flush their buffers.
|
||||
+ */
|
||||
+int hdflush(void)
|
||||
+{
|
||||
+ unsigned int flags;
|
||||
+ char *disk;
|
||||
+ DIR *blk;
|
||||
+
|
||||
+ if ((blk = opendir(SYS_BLK)) == (DIR*)0)
|
||||
+ return -1;
|
||||
+
|
||||
+ while ((disk = list_disks(blk, &flags)))
|
||||
+ do_standby_disk(disk, (flags|DISK_NOSTANDBY));
|
||||
+
|
||||
+ return closedir(blk);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Strip off trailing white spaces
|
||||
+ */
|
||||
+static char *strstrip(char *str)
|
||||
+{
|
||||
+ const size_t len = strlen(str);
|
||||
+ if (len) {
|
||||
+ char* end = str + len - 1;
|
||||
+ while ((end != str) && ISSPACE(*end))
|
||||
+ end--;
|
||||
+ *(end + 1) = '\0'; /* remove trailing white spaces */
|
||||
+ }
|
||||
+ return str;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Open a sysfs file without getting a controlling tty
|
||||
+ * and return FILE* pointer.
|
||||
+ */
|
||||
+static FILE *hdopen(const char* const format, const char* const name)
|
||||
+{
|
||||
+ char buf[NAME_MAX+1];
|
||||
+ FILE *fp = (FILE*)-1;
|
||||
+ int fd, ret;
|
||||
+
|
||||
+ ret = snprintf(buf, sizeof(buf), format, name);
|
||||
+ if ((ret >= (int)sizeof(buf)) || (ret < 0))
|
||||
+ goto error; /* error */
|
||||
+
|
||||
+ fd = open(buf, O_RDONLY|O_NOCTTY);
|
||||
+ if (fd < 0) {
|
||||
+ if (errno != ENOENT)
|
||||
+ goto error; /* error */
|
||||
+ fp = (FILE*)0;
|
||||
+ goto error; /* no entry `removable' */
|
||||
+ }
|
||||
+
|
||||
+ fp = fdopen(fd, "r");
|
||||
+ if (fp == (FILE*)0)
|
||||
+ close(fd); /* should not happen */
|
||||
+error:
|
||||
+ return fp;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Check IDE/(S)ATA hard disk identity for
|
||||
+ * the FLUSH CACHE EXT bit set.
|
||||
+ */
|
||||
+static int flush_cache_ext(const char *device)
|
||||
+{
|
||||
+#ifndef WIN_IDENTIFY
|
||||
+#define WIN_IDENTIFY 0xEC
|
||||
+#endif
|
||||
+ unsigned char args[4+IDBYTES];
|
||||
+ unsigned short *id = (unsigned short*)(&args[4]);
|
||||
+ char buf[NAME_MAX+1], *ptr;
|
||||
+ int fd = -1, ret = 0;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ fp = hdopen(SYS_BLK "/%s/size", device);
|
||||
+ if ((long)fp <= 0) {
|
||||
+ if ((long)fp < 0)
|
||||
+ return -1; /* error */
|
||||
+ goto out; /* no entry `size' */
|
||||
+ }
|
||||
+
|
||||
+ ptr = fgets(buf, sizeof(buf), fp);
|
||||
+ fclose(fp);
|
||||
+ if (ptr == (char*)0)
|
||||
+ goto out; /* should not happen */
|
||||
+
|
||||
+ ptr = strstrip(buf);
|
||||
+ if (*ptr == '\0')
|
||||
+ goto out; /* should not happen */
|
||||
+
|
||||
+ if ((size_t)atoll(buf) < (1<<28))
|
||||
+ goto out; /* small disk */
|
||||
+
|
||||
+ ret = snprintf(buf, sizeof(buf), DEV_BASE "/%s", device);
|
||||
+ if ((ret >= (int)sizeof(buf)) || (ret < 0))
|
||||
+ return -1; /* error */
|
||||
+
|
||||
+ if ((fd = open(buf, O_RDONLY|O_NONBLOCK)) < 0)
|
||||
+ goto out;
|
||||
+
|
||||
+ memset(&args[0], 0, sizeof(args));
|
||||
+ args[0] = WIN_IDENTIFY;
|
||||
+ args[3] = 1;
|
||||
+ if (ioctl(fd, HDIO_DRIVE_CMD, &args))
|
||||
+ goto out;
|
||||
+#ifdef WORDS_BIGENDIAN
|
||||
+# if 0
|
||||
+ {
|
||||
+ const unsigned short *end = id + IDBYTES/2;
|
||||
+ const unsigned short *from = id;
|
||||
+ unsigned short *to = id;
|
||||
+
|
||||
+ while (from < end)
|
||||
+ *to++ = bswap_16(*from++);
|
||||
+ }
|
||||
+# else
|
||||
+ id[83] = bswap_16(id[83]);
|
||||
+# endif
|
||||
+#endif
|
||||
+ if ((id[83] & MASK_EXT) == TEST_EXT)
|
||||
+ ret = 1;
|
||||
+out:
|
||||
+ if (fd >= 0)
|
||||
+ close(fd);
|
||||
+ return ret;
|
||||
+}
|
||||
+#else /* ! USE_SYSFS */
|
||||
#define MAX_DISKS 64
|
||||
#define PROC_IDE "/proc/ide"
|
||||
#define DEV_BASE "/dev"
|
||||
@@ -105,6 +472,12 @@ int hddown(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int hdflush(void)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#endif /* ! USE_SYSFS */
|
||||
#else /* __linux__ */
|
||||
|
||||
int hddown(void)
|
||||
@@ -112,6 +485,11 @@ int hddown(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int hdflush(void)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
#endif /* __linux__ */
|
||||
|
||||
#ifdef STANDALONE
|
@ -1,11 +0,0 @@
|
||||
--- src/Makefile
|
||||
+++ src/Makefile 2005-10-19 12:03:39.000000000 +0200
|
||||
@@ -50,7 +50,7 @@
|
||||
MANDIR = /usr/share/man
|
||||
|
||||
# Additional libs for GNU libc.
|
||||
-ifneq ($(wildcard /usr/lib/libcrypt.a),)
|
||||
+ifneq ($(wildcard /usr/lib*/libcrypt.a),)
|
||||
LCRYPT = -lcrypt
|
||||
endif
|
||||
|
@ -1,40 +0,0 @@
|
||||
---
|
||||
src/killall5.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
--- src/killall5.c
|
||||
+++ src/killall5.c
|
||||
@@ -62,6 +62,7 @@ typedef struct proc {
|
||||
char isfuse; /* Provides FUSE filesystems */
|
||||
char isudev; /* Is the uevent handler */
|
||||
char nfs; /* Binary is loacted on NFS part. */
|
||||
+ char ismdmon; /* Is an instance of /sbin/mdmon. */
|
||||
struct proc *next; /* Pointer to next struct. */
|
||||
} PROC;
|
||||
|
||||
@@ -609,6 +610,9 @@ int readproc()
|
||||
/* Check for uevent handler */
|
||||
p->isudev = (strncmp(buf, "/sbin/udevd", 11) == 0);
|
||||
|
||||
+ /* Check for mdmon */
|
||||
+ p->ismdmon = (strncmp(buf, "/sbin/mdmon", 11) == 0);
|
||||
+
|
||||
/* Check for provider of FUSE filesystems */
|
||||
p->isfuse = is_fuse(d->d_name);
|
||||
|
||||
@@ -947,11 +951,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
clear_mnt();
|
||||
|
||||
- /* Now kill all processes except init (pid 1), our session, and FUSE filesystems. */
|
||||
+ /* Now kill all processes except init (pid 1), our session,
|
||||
+ * FUSE filesystems and /sbin/mdmon */
|
||||
sid = (int)getsid(0);
|
||||
pid = (int)getpid();
|
||||
for (p = plist; p; p = p->next) {
|
||||
- if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel || p->isfuse) {
|
||||
+ if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel
|
||||
+ || p->isfuse || p->ismdmon) {
|
||||
kill(p->pid, SIGCONT);
|
||||
continue;
|
||||
}
|
@ -1,480 +0,0 @@
|
||||
--- src/killall5.c
|
||||
+++ src/killall5.c 2009-03-27 11:42:17.780766281 +0100
|
||||
@@ -40,6 +40,8 @@
|
||||
#include <syslog.h>
|
||||
#include <getopt.h>
|
||||
#include <stdarg.h>
|
||||
+#include <mntent.h>
|
||||
+#include <sys/param.h>
|
||||
|
||||
char *Version = "@(#)killall5 2.86 31-Jul-2004 miquels@cistron.nl";
|
||||
|
||||
@@ -56,7 +58,8 @@ typedef struct proc {
|
||||
dev_t dev; /* Device it is on */
|
||||
pid_t pid; /* Process ID. */
|
||||
int sid; /* Session ID. */
|
||||
- int kernel; /* Kernel thread or zombie. */
|
||||
+ char kernel; /* Kernel thread or zombie. */
|
||||
+ char nfs; /* Binary is loacted on NFS part. */
|
||||
struct proc *next; /* Pointer to next struct. */
|
||||
} PROC;
|
||||
|
||||
@@ -73,9 +76,35 @@ typedef struct {
|
||||
PIDQ *next;
|
||||
} PIDQ_HEAD;
|
||||
|
||||
+typedef struct shadow
|
||||
+{
|
||||
+ struct shadow *next;
|
||||
+ struct shadow *prev;
|
||||
+ size_t nlen;
|
||||
+ char * name;
|
||||
+} SHADOW;
|
||||
+
|
||||
+typedef struct nfs
|
||||
+{
|
||||
+ struct nfs *next; /* Pointer to next struct. */
|
||||
+ struct nfs *prev; /* Pointer to previous st. */
|
||||
+ SHADOW *shadow; /* Pointer to shadows */
|
||||
+ char * name;
|
||||
+ size_t nlen;
|
||||
+} NFS;
|
||||
+#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
|
||||
+# ifndef restrict
|
||||
+# define restrict __restrict__
|
||||
+# endif
|
||||
+#endif
|
||||
+#define alignof(type) ((sizeof(type)+(sizeof(void*)-1)) & ~(sizeof(void*)-1))
|
||||
+
|
||||
/* List of processes. */
|
||||
PROC *plist;
|
||||
|
||||
+/* List of NFS mountes partitions. */
|
||||
+NFS *nlist;
|
||||
+
|
||||
/* Did we stop all processes ? */
|
||||
int sent_sigstop;
|
||||
|
||||
@@ -102,6 +131,18 @@ void *xmalloc(int bytes)
|
||||
return p;
|
||||
}
|
||||
|
||||
+#ifdef __GNUC__
|
||||
+static inline void xmemalign(void **, size_t, size_t) __attribute__ ((nonnull (1)));
|
||||
+#endif
|
||||
+static inline void xmemalign(void **memptr, size_t alignment, size_t size)
|
||||
+{
|
||||
+ if ((posix_memalign(memptr, alignment, size)) < 0) {
|
||||
+ if (sent_sigstop) kill(-1, SIGCONT);
|
||||
+ nsyslog(LOG_ERR, "out of memory");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* See if the proc filesystem is there. Mount if needed.
|
||||
*/
|
||||
@@ -152,6 +193,211 @@ int mount_proc(void)
|
||||
return did_mount;
|
||||
}
|
||||
|
||||
+static inline int isnetfs(const char * type)
|
||||
+{
|
||||
+ static const char* netfs[] = {"nfs", "nfs4", "smbfs", "cifs", "afs", "ncpfs", (char*)0};
|
||||
+ int n;
|
||||
+ for (n = 0; netfs[n]; n++)
|
||||
+ if (!strcasecmp(netfs[n], type))
|
||||
+ return 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Remember all NFS typed partitions.
|
||||
+ */
|
||||
+void init_nfs(void)
|
||||
+{
|
||||
+ struct stat st;
|
||||
+ struct mntent * ent;
|
||||
+ FILE * mnt;
|
||||
+
|
||||
+ nlist = (NFS*)0;
|
||||
+
|
||||
+ if (stat("/proc/version", &st) < 0)
|
||||
+ return;
|
||||
+ if ((mnt = setmntent("/proc/mounts", "r")) == (FILE*)0)
|
||||
+ return;
|
||||
+
|
||||
+ while ((ent = getmntent(mnt))) {
|
||||
+ if (isnetfs(ent->mnt_type)) {
|
||||
+ size_t nlen = strlen(ent->mnt_dir);
|
||||
+ NFS *restrict p;
|
||||
+ xmemalign((void*)&p, sizeof(void*), alignof(NFS)+(nlen+1));
|
||||
+ p->name = ((char*)p)+alignof(NFS);
|
||||
+ p->nlen = nlen;
|
||||
+ p->shadow = (SHADOW*)0;
|
||||
+
|
||||
+ strcpy(p->name, ent->mnt_dir);
|
||||
+ if (nlist)
|
||||
+ nlist->prev = p;
|
||||
+ p->next = nlist;
|
||||
+ p->prev = (NFS*)0;
|
||||
+ nlist = p;
|
||||
+ }
|
||||
+ }
|
||||
+ endmntent(mnt);
|
||||
+
|
||||
+ if ((mnt = setmntent("/proc/mounts", "r")) == (FILE*)0)
|
||||
+ return;
|
||||
+
|
||||
+ while ((ent = getmntent(mnt))) {
|
||||
+ NFS *p;
|
||||
+
|
||||
+ for (p = nlist; p; p = p->next) {
|
||||
+ SHADOW * restrict s;
|
||||
+ size_t nlen;
|
||||
+
|
||||
+ if (strcmp(ent->mnt_dir, p->name) == 0)
|
||||
+ continue;
|
||||
+ if (strncmp(ent->mnt_dir, p->name, p->nlen) != 0)
|
||||
+ continue;
|
||||
+
|
||||
+ nlen = strlen(ent->mnt_dir);
|
||||
+ xmemalign((void*)&s, sizeof(void*), alignof(SHADOW)+(nlen+1));
|
||||
+ s->name = ((char*)s)+alignof(SHADOW);
|
||||
+ s->nlen = nlen;
|
||||
+
|
||||
+ strcpy(s->name, ent->mnt_dir);
|
||||
+ if (p->shadow)
|
||||
+ p->shadow->prev = s;
|
||||
+ s->next = p->shadow;
|
||||
+ s->prev = (SHADOW*)0;
|
||||
+ p->shadow = s;
|
||||
+ }
|
||||
+ }
|
||||
+ endmntent(mnt);
|
||||
+}
|
||||
+
|
||||
+static void clear_shadow(SHADOW *restrict shadow)
|
||||
+{
|
||||
+ SHADOW *s, *n, *l;
|
||||
+
|
||||
+ n = shadow;
|
||||
+ l = (SHADOW*)0;
|
||||
+ for (s = shadow; n; s = n) {
|
||||
+ l = s->prev;
|
||||
+ n = s->next;
|
||||
+ if (s == shadow) {
|
||||
+ if (n) n->prev = (SHADOW*)0;
|
||||
+ shadow = n;
|
||||
+ } else if (l) {
|
||||
+ if (n) n->prev = l;
|
||||
+ l->next = n;
|
||||
+ }
|
||||
+ free(s);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void clear_mnt(void)
|
||||
+{
|
||||
+ NFS *p, *n, *l;
|
||||
+
|
||||
+ n = nlist;
|
||||
+ l = (NFS*)0;
|
||||
+ for (p = nlist; n; p = n) {
|
||||
+ l = p->prev;
|
||||
+ n = p->next;
|
||||
+ if (p == nlist) {
|
||||
+ if (n) n->prev = (NFS*)0;
|
||||
+ nlist = n;
|
||||
+ } else if (l) {
|
||||
+ if (n) n->prev = l;
|
||||
+ l->next = n;
|
||||
+ }
|
||||
+ if (p->shadow)
|
||||
+ clear_shadow(p->shadow);
|
||||
+ free(p);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Check if path is ia shadow off a NFS partition.
|
||||
+ */
|
||||
+static int shadow(SHADOW *restrict this, const char *restrict name, const size_t nlen)
|
||||
+{
|
||||
+ SHADOW *s;
|
||||
+
|
||||
+ if (!this)
|
||||
+ goto out;
|
||||
+ for (s = this; s; s = s->next) {
|
||||
+ if (nlen < s->nlen)
|
||||
+ continue;
|
||||
+ if (name[s->nlen] != '\0' && name[s->nlen] != '/')
|
||||
+ continue;
|
||||
+ if (strncmp(name, s->name, s->nlen) == 0)
|
||||
+ return 1;
|
||||
+ }
|
||||
+out:
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Check path is located on a NFS partition.
|
||||
+ */
|
||||
+int check4nfs(const char * path, char * real)
|
||||
+{
|
||||
+ char buf[PATH_MAX+1];
|
||||
+ const char *curr;
|
||||
+ int deep = MAXSYMLINKS;
|
||||
+
|
||||
+ if (!nlist) return 0;
|
||||
+
|
||||
+ curr = path;
|
||||
+ do {
|
||||
+ const char *prev;
|
||||
+ int len;
|
||||
+
|
||||
+ if ((prev = strdupa(curr)) == NULL) {
|
||||
+ nsyslog(LOG_ERR, "strdupa(): %s\n", strerror(errno));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ errno = 0;
|
||||
+ if ((len = readlink(curr, buf, PATH_MAX)) < 0)
|
||||
+ break;
|
||||
+ buf[len] = '\0';
|
||||
+
|
||||
+ if (buf[0] != '/') {
|
||||
+ const char *slash;
|
||||
+
|
||||
+ if ((slash = strrchr(prev, '/'))) {
|
||||
+ size_t off = slash - prev + 1;
|
||||
+
|
||||
+ if (off + len > PATH_MAX)
|
||||
+ len = PATH_MAX - off;
|
||||
+
|
||||
+ memmove(&buf[off], &buf[0], len + 1);
|
||||
+ memcpy(&buf[0], prev, off);
|
||||
+ }
|
||||
+ }
|
||||
+ curr = &buf[0];
|
||||
+
|
||||
+ if (deep-- <= 0) return 0;
|
||||
+
|
||||
+ } while (1);
|
||||
+
|
||||
+ if (real) strcpy(real, curr);
|
||||
+
|
||||
+ if (errno == EINVAL) {
|
||||
+ const size_t nlen = strlen(curr);
|
||||
+ NFS *p;
|
||||
+ for (p = nlist; p; p = p->next) {
|
||||
+ if (nlen < p->nlen)
|
||||
+ continue;
|
||||
+ if (curr[p->nlen] != '\0' && curr[p->nlen] != '/')
|
||||
+ continue;
|
||||
+ if (!strncmp(curr, p->name, p->nlen)) {
|
||||
+ if (shadow(p->shadow, curr, nlen))
|
||||
+ continue;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int readarg(FILE *fp, char *buf, int sz)
|
||||
{
|
||||
int c = 0, f = 0;
|
||||
@@ -173,8 +419,8 @@ int readproc()
|
||||
PROC *p, *n;
|
||||
struct dirent *d;
|
||||
struct stat st;
|
||||
- char path[256];
|
||||
- char buf[256];
|
||||
+ char path[PATH_MAX+1];
|
||||
+ char buf[PATH_MAX+1];
|
||||
char *s, *q;
|
||||
unsigned long startcode, endcode;
|
||||
int pid, f;
|
||||
@@ -191,6 +437,7 @@ int readproc()
|
||||
n = p->next;
|
||||
if (p->argv0) free(p->argv0);
|
||||
if (p->argv1) free(p->argv1);
|
||||
+ if (p->statname) free(p->statname);
|
||||
free(p);
|
||||
}
|
||||
plist = NULL;
|
||||
@@ -225,6 +472,9 @@ int readproc()
|
||||
nsyslog(LOG_ERR,
|
||||
"can't get program name from %s\n",
|
||||
path);
|
||||
+ if (p->argv0) free(p->argv0);
|
||||
+ if (p->argv1) free(p->argv1);
|
||||
+ if (p->statname) free(p->statname);
|
||||
free(p);
|
||||
continue;
|
||||
}
|
||||
@@ -248,6 +498,9 @@ int readproc()
|
||||
p->sid = 0;
|
||||
nsyslog(LOG_ERR, "can't read sid from %s\n",
|
||||
path);
|
||||
+ if (p->argv0) free(p->argv0);
|
||||
+ if (p->argv1) free(p->argv1);
|
||||
+ if (p->statname) free(p->statname);
|
||||
free(p);
|
||||
continue;
|
||||
}
|
||||
@@ -256,6 +509,9 @@ int readproc()
|
||||
fclose(fp);
|
||||
} else {
|
||||
/* Process disappeared.. */
|
||||
+ if (p->argv0) free(p->argv0);
|
||||
+ if (p->argv1) free(p->argv1);
|
||||
+ if (p->statname) free(p->statname);
|
||||
free(p);
|
||||
continue;
|
||||
}
|
||||
@@ -300,13 +556,18 @@ int readproc()
|
||||
|
||||
} else {
|
||||
/* Process disappeared.. */
|
||||
+ if (p->argv0) free(p->argv0);
|
||||
+ if (p->argv1) free(p->argv1);
|
||||
+ if (p->statname) free(p->statname);
|
||||
free(p);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Try to stat the executable. */
|
||||
snprintf(path, sizeof(path), "/proc/%s/exe", d->d_name);
|
||||
- if (stat(path, &st) == 0) {
|
||||
+ if (check4nfs(path, NULL))
|
||||
+ p->nfs = 1;
|
||||
+ if ((p->nfs == 0) && (stat(path, &st) == 0)) {
|
||||
p->dev = st.st_dev;
|
||||
p->ino = st.st_ino;
|
||||
}
|
||||
@@ -374,12 +635,25 @@ PIDQ_HEAD *pidof(char *prog)
|
||||
PIDQ_HEAD *q;
|
||||
struct stat st;
|
||||
char *s;
|
||||
+ int nfs = 0;
|
||||
int dostat = 0;
|
||||
int foundone = 0;
|
||||
int ok = 0;
|
||||
+ char real[PATH_MAX+1];
|
||||
|
||||
/* Try to stat the executable. */
|
||||
- if (prog[0] == '/' && stat(prog, &st) == 0) dostat++;
|
||||
+ if (prog[0] == '/') {
|
||||
+ memset(&real[0], 0, sizeof(real));
|
||||
+
|
||||
+ if (check4nfs(prog, real))
|
||||
+ nfs++; /* Binary located on NFS partition. */
|
||||
+
|
||||
+ if (real[0] != '\0')
|
||||
+ prog = &real[0]; /* Binary or its symlink located on NFS. */
|
||||
+
|
||||
+ if ((nfs == 0) && (stat(prog, &st) == 0))
|
||||
+ dostat++; /* Binary located on a local file system. */
|
||||
+ }
|
||||
|
||||
/* Get basename of program. */
|
||||
if ((s = strrchr(prog, '/')) == NULL)
|
||||
@@ -393,10 +667,30 @@ PIDQ_HEAD *pidof(char *prog)
|
||||
/* First try to find a match based on dev/ino pair. */
|
||||
if (dostat) {
|
||||
for (p = plist; p; p = p->next) {
|
||||
- if (p->dev == st.st_dev && p->ino == st.st_ino) {
|
||||
- add_pid_to_q(q, p);
|
||||
- foundone++;
|
||||
- }
|
||||
+ if (p->nfs)
|
||||
+ continue;
|
||||
+ if (p->dev != st.st_dev || p->ino != st.st_ino)
|
||||
+ continue;
|
||||
+ add_pid_to_q(q, p);
|
||||
+ foundone++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Second try to find a match based on full path name on NFS located binaries */
|
||||
+ if (!foundone && nfs) {
|
||||
+ for (p = plist; p; p = p->next) {
|
||||
+ char exe [PATH_MAX+1];
|
||||
+ char path[PATH_MAX+1];
|
||||
+ int len;
|
||||
+
|
||||
+ snprintf(exe, sizeof(exe), "/proc/%d/exe", p->pid);
|
||||
+ if ((len = readlink(exe, path, PATH_MAX)) < 0)
|
||||
+ continue;
|
||||
+ path[len] = '\0';
|
||||
+ if (strcmp(prog, path) != 0)
|
||||
+ continue;
|
||||
+ add_pid_to_q(q, p);
|
||||
+ foundone++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,7 +722,7 @@ PIDQ_HEAD *pidof(char *prog)
|
||||
if (ok) add_pid_to_q(q, p);
|
||||
}
|
||||
|
||||
- return q;
|
||||
+ return q;
|
||||
}
|
||||
|
||||
/* Give usage message and exit. */
|
||||
@@ -477,6 +771,9 @@ int main_pidof(int argc, char **argv)
|
||||
int first = 1;
|
||||
int i, oind, opt, flags = 0;
|
||||
|
||||
+ /* Which NFS partitions are online? */
|
||||
+ init_nfs();
|
||||
+
|
||||
for (oind = PIDOF_OMITSZ-1; oind > 0; oind--)
|
||||
opid[oind] = 0;
|
||||
opterr = 0;
|
||||
@@ -561,6 +858,7 @@ int main(int argc, char **argv)
|
||||
PROC *p;
|
||||
int pid, sid = -1;
|
||||
int sig = SIGKILL;
|
||||
+ int did_mount;
|
||||
|
||||
/* Get program name. */
|
||||
if ((progname = strrchr(argv[0], '/')) == NULL)
|
||||
@@ -583,7 +881,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* First get the /proc filesystem online. */
|
||||
- mount_proc();
|
||||
+ did_mount = mount_proc();
|
||||
+
|
||||
+ /* Which NFS partitions are online? */
|
||||
+ init_nfs();
|
||||
|
||||
/*
|
||||
* Ignoring SIGKILL and SIGSTOP do not make sense, but
|
||||
@@ -604,13 +905,18 @@ int main(int argc, char **argv)
|
||||
kill(-1, SIGCONT);
|
||||
exit(1);
|
||||
}
|
||||
+ clear_mnt();
|
||||
|
||||
/* Now kill all processes except our session. */
|
||||
sid = (int)getsid(0);
|
||||
pid = (int)getpid();
|
||||
- for (p = plist; p; p = p->next)
|
||||
- if (p->pid != pid && p->sid != sid && !p->kernel)
|
||||
- kill(p->pid, sig);
|
||||
+ for (p = plist; p; p = p->next) {
|
||||
+ if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel) {
|
||||
+ kill(p->pid, SIGCONT);
|
||||
+ continue;
|
||||
+ }
|
||||
+ kill(p->pid, sig);
|
||||
+ }
|
||||
|
||||
/* And let them continue. */
|
||||
kill(-1, SIGCONT);
|
@ -1,33 +0,0 @@
|
||||
--- src/init.c
|
||||
+++ src/init.c 2005-10-19 10:01:15.000000000 +0000
|
||||
@@ -20,6 +20,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
+/*
|
||||
+ * 4 Sep 2001, Andrea Arcangeli:
|
||||
+ * Fix a race in spawn() that is used to deadlock init in a
|
||||
+ * waitpid() loop: must set the childhandler as default before forking
|
||||
+ * off the child or the chld_handler could run before the waitpid loop
|
||||
+ * has a chance to find its zombie-child.
|
||||
+ */
|
||||
+
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -976,6 +984,7 @@ int spawn(CHILD *ch, int *res)
|
||||
dup(f);
|
||||
dup(f);
|
||||
}
|
||||
+ SETSIG(sa, SIGCHLD, SIG_DFL, SA_RESTART);
|
||||
if ((pid = fork()) < 0) {
|
||||
initlog(L_VB, "cannot fork");
|
||||
exit(1);
|
||||
@@ -988,7 +997,6 @@ int spawn(CHILD *ch, int *res)
|
||||
SETSIG(sa, SIGINT, SIG_IGN, SA_RESTART);
|
||||
SETSIG(sa, SIGTSTP, SIG_IGN, SA_RESTART);
|
||||
SETSIG(sa, SIGQUIT, SIG_IGN, SA_RESTART);
|
||||
- SETSIG(sa, SIGCHLD, SIG_DFL, SA_RESTART);
|
||||
|
||||
while ((rc = waitpid(pid, &st, 0)) != pid)
|
||||
if (rc < 0 && errno == ECHILD)
|
@ -1,93 +0,0 @@
|
||||
--- src/Makefile
|
||||
+++ src/Makefile
|
||||
@@ -57,7 +57,7 @@
|
||||
all: $(BIN) $(SBIN) $(USRBIN)
|
||||
|
||||
init: init.o init_utmp.o
|
||||
- $(CC) $(LDFLAGS) $(STATIC) -o $@ init.o init_utmp.o
|
||||
+ $(CC) $(LDFLAGS) $(STATIC) -o $@ init.o init_utmp.o -lselinux -lsepol
|
||||
|
||||
halt: halt.o ifdown.o hddown.o utmp.o reboot.h
|
||||
$(CC) $(LDFLAGS) -o $@ halt.o ifdown.o hddown.o utmp.o
|
||||
@@ -78,7 +78,7 @@
|
||||
$(CC) $(LDFLAGS) -o $@ runlevel.o
|
||||
|
||||
sulogin: sulogin.o
|
||||
- $(CC) $(LDFLAGS) $(STATIC) -o $@ sulogin.o $(LCRYPT)
|
||||
+ $(CC) $(LDFLAGS) $(STATIC) -o $@ sulogin.o $(LCRYPT) -lselinux
|
||||
|
||||
wall: dowall.o wall.o
|
||||
$(CC) $(LDFLAGS) -o $@ dowall.o wall.o
|
||||
--- src/init.c
|
||||
+++ src/init.c
|
||||
@@ -50,6 +50,8 @@
|
||||
#include <stdarg.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/time.h>
|
||||
+#include <selinux/selinux.h>
|
||||
+#include <sepol/sepol.h>
|
||||
|
||||
#ifdef __i386__
|
||||
# if (__GLIBC__ >= 2)
|
||||
@@ -2643,6 +2645,7 @@
|
||||
char *p;
|
||||
int f;
|
||||
int isinit;
|
||||
+ int enforce = 0;
|
||||
|
||||
/* Get my own name */
|
||||
if ((p = strrchr(argv[0], '/')) != NULL)
|
||||
@@ -2706,6 +2709,20 @@
|
||||
maxproclen += strlen(argv[f]) + 1;
|
||||
}
|
||||
|
||||
+ if (getenv("SELINUX_INIT") == NULL && !is_selinux_enabled()) {
|
||||
+ putenv("SELINUX_INIT=YES");
|
||||
+ if (selinux_init_load_policy(&enforce) == 0 ) {
|
||||
+ execv(myname, argv);
|
||||
+ } else {
|
||||
+ if (enforce > 0) {
|
||||
+ /* SELinux in enforcing mode but load_policy failed */
|
||||
+ /* At this point, we probably can't open /dev/console, so log() won't work */
|
||||
+ printf("Unable to load SELinux Policy. Machine is in enforcing mode. Halting now.\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Start booting. */
|
||||
argv0 = argv[0];
|
||||
argv[1] = NULL;
|
||||
--- src/sulogin.c
|
||||
+++ src/sulogin.c
|
||||
@@ -29,6 +29,8 @@
|
||||
#if defined(__GLIBC__)
|
||||
# include <crypt.h>
|
||||
#endif
|
||||
+#include <selinux/selinux.h>
|
||||
+#include <selinux/get_context_list.h>
|
||||
|
||||
#define CHECK_DES 1
|
||||
#define CHECK_MD5 1
|
||||
@@ -374,6 +376,21 @@
|
||||
signal(SIGINT, saved_sigint);
|
||||
signal(SIGTSTP, saved_sigtstp);
|
||||
signal(SIGQUIT, saved_sigquit);
|
||||
+
|
||||
+ if (is_selinux_enabled > 0) {
|
||||
+ security_context_t scon=NULL;
|
||||
+ char *seuser=NULL;
|
||||
+ char *level=NULL;
|
||||
+ if (getseuserbyname("root", &seuser, &level) == 0)
|
||||
+ if (get_default_context_with_level(seuser, level, 0, &scon) > 0) {
|
||||
+ if (setexeccon(scon) != 0)
|
||||
+ fprintf(stderr, "setexeccon faile\n");
|
||||
+ freecon(scon);
|
||||
+ }
|
||||
+ free(seuser);
|
||||
+ free(level);
|
||||
+ }
|
||||
+
|
||||
execl(sushell, shell, NULL);
|
||||
perror(sushell);
|
||||
|
@ -1,334 +0,0 @@
|
||||
--- src/sulogin.c
|
||||
+++ src/sulogin.c 2005-10-19 11:56:43.000000000 +0200
|
||||
@@ -23,13 +23,16 @@
|
||||
#include <pwd.h>
|
||||
#include <shadow.h>
|
||||
#include <termios.h>
|
||||
+#include <sys/ttydefaults.h>
|
||||
#include <sys/ioctl.h>
|
||||
+#include <errno.h>
|
||||
#if defined(__GLIBC__)
|
||||
# include <crypt.h>
|
||||
#endif
|
||||
|
||||
#define CHECK_DES 1
|
||||
#define CHECK_MD5 1
|
||||
+#define FIXTTY 1
|
||||
|
||||
#define F_PASSWD "/etc/passwd"
|
||||
#define F_SHADOW "/etc/shadow"
|
||||
@@ -37,49 +40,80 @@
|
||||
|
||||
char *Version = "@(#)sulogin 2.85-3 23-Apr-2003 miquels@cistron.nl";
|
||||
|
||||
-int timeout = 0;
|
||||
-int profile = 0;
|
||||
+static int timeout;
|
||||
+static int profile;
|
||||
+
|
||||
+static void (*saved_sigint) = SIG_DFL;
|
||||
+static void (*saved_sigtstp) = SIG_DFL;
|
||||
+static void (*saved_sigquit) = SIG_DFL;
|
||||
|
||||
#ifndef IUCLC
|
||||
# define IUCLC 0
|
||||
#endif
|
||||
|
||||
-#if 0
|
||||
+#if FIXTTY
|
||||
/*
|
||||
* Fix the tty modes and set reasonable defaults.
|
||||
* (I'm not sure if this is needed under Linux, but..)
|
||||
*/
|
||||
+static
|
||||
void fixtty(void)
|
||||
{
|
||||
struct termios tty;
|
||||
+ int serial;
|
||||
+
|
||||
+ /* Skip serial console */
|
||||
+ if (ioctl (0, TIOCMGET, (char*)&serial) == 0)
|
||||
+ goto out;
|
||||
+ /* Expected error */
|
||||
+ serial = errno = 0;
|
||||
|
||||
tcgetattr(0, &tty);
|
||||
|
||||
- /*
|
||||
- * Set or adjust tty modes.
|
||||
- */
|
||||
- tty.c_iflag &= ~(INLCR|IGNCR|IUCLC);
|
||||
- tty.c_iflag |= ICRNL;
|
||||
- tty.c_oflag &= ~(OCRNL|OLCUC|ONOCR|ONLRET|OFILL);
|
||||
- tty.c_oflag |= OPOST|ONLCR;
|
||||
- tty.c_cflag |= CLOCAL;
|
||||
- tty.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE;
|
||||
-
|
||||
- /*
|
||||
- * Set the most important characters */
|
||||
- */
|
||||
- tty.c_cc[VINTR] = 3;
|
||||
- tty.c_cc[VQUIT] = 28;
|
||||
- tty.c_cc[VERASE] = 127;
|
||||
- tty.c_cc[VKILL] = 24;
|
||||
- tty.c_cc[VEOF] = 4;
|
||||
- tty.c_cc[VTIME] = 0;
|
||||
- tty.c_cc[VMIN] = 1;
|
||||
- tty.c_cc[VSTART] = 17;
|
||||
- tty.c_cc[VSTOP] = 19;
|
||||
- tty.c_cc[VSUSP] = 26;
|
||||
+ /* Use defaults of <sys/ttydefaults.h> for base settings */
|
||||
+ tty.c_iflag |= TTYDEF_IFLAG;
|
||||
+ tty.c_oflag |= TTYDEF_OFLAG;
|
||||
+ tty.c_lflag |= TTYDEF_LFLAG;
|
||||
+ tty.c_cflag |= (TTYDEF_SPEED | TTYDEF_CFLAG);
|
||||
+
|
||||
+ /* Sane setting, allow eight bit characters, no carriage return delay
|
||||
+ * the same result as `stty sane cr0 pass8'
|
||||
+ */
|
||||
+ tty.c_iflag |= (BRKINT | ICRNL | IMAXBEL);
|
||||
+ tty.c_iflag &= ~(IGNBRK | INLCR | IGNCR | IXOFF | IUCLC | IXANY | ISTRIP);
|
||||
+ tty.c_oflag |= (OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0);
|
||||
+ tty.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |\
|
||||
+ NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
|
||||
+ tty.c_lflag |= (ISIG | ICANON | IEXTEN | ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE);
|
||||
+ tty.c_lflag &= ~(ECHONL | NOFLSH | XCASE | TOSTOP | ECHOPRT);
|
||||
+ tty.c_cflag |= (CREAD | CS8 | B9600);
|
||||
+ tty.c_cflag &= ~(PARENB);
|
||||
+
|
||||
+ /* VTIME and VMIN can overlap with VEOF and VEOL since they are
|
||||
+ * only used for non-canonical mode. We just set the at the
|
||||
+ * beginning, so nothing bad should happen.
|
||||
+ */
|
||||
+ tty.c_cc[VTIME] = 0;
|
||||
+ tty.c_cc[VMIN] = 1;
|
||||
+ tty.c_cc[VINTR] = CINTR;
|
||||
+ tty.c_cc[VQUIT] = CQUIT;
|
||||
+ tty.c_cc[VERASE] = CERASE; /* ASCII DEL (0177) */
|
||||
+ tty.c_cc[VKILL] = CKILL;
|
||||
+ tty.c_cc[VEOF] = CEOF;
|
||||
+ tty.c_cc[VSWTC] = _POSIX_VDISABLE;
|
||||
+ tty.c_cc[VSTART] = CSTART;
|
||||
+ tty.c_cc[VSTOP] = CSTOP;
|
||||
+ tty.c_cc[VSUSP] = CSUSP;
|
||||
+ tty.c_cc[VEOL] = _POSIX_VDISABLE;
|
||||
+ tty.c_cc[VREPRINT] = CREPRINT;
|
||||
+ tty.c_cc[VDISCARD] = CDISCARD;
|
||||
+ tty.c_cc[VWERASE] = CWERASE;
|
||||
+ tty.c_cc[VLNEXT] = CLNEXT;
|
||||
+ tty.c_cc[VEOL2] = _POSIX_VDISABLE;
|
||||
|
||||
tcsetattr(0, TCSANOW, &tty);
|
||||
+out:
|
||||
+ return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -87,7 +121,8 @@
|
||||
/*
|
||||
* Called at timeout.
|
||||
*/
|
||||
-void alrm_handler()
|
||||
+static
|
||||
+void alrm_handler(int sig)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -96,6 +131,7 @@
|
||||
* password is checked for traditional-style DES and
|
||||
* FreeBSD-style MD5 encryption.
|
||||
*/
|
||||
+static
|
||||
int valid(char *pass)
|
||||
{
|
||||
char *s;
|
||||
@@ -134,6 +170,7 @@
|
||||
/*
|
||||
* Set a variable if the value is not NULL.
|
||||
*/
|
||||
+static
|
||||
void set(char **var, char *val)
|
||||
{
|
||||
if (val) *var = val;
|
||||
@@ -142,6 +179,7 @@
|
||||
/*
|
||||
* Get the root password entry.
|
||||
*/
|
||||
+static
|
||||
struct passwd *getrootpwent(int try_manually)
|
||||
{
|
||||
static struct passwd pwd;
|
||||
@@ -244,6 +282,7 @@
|
||||
* Ask for the password. Note that there is no
|
||||
* default timeout as we normally skip this during boot.
|
||||
*/
|
||||
+static
|
||||
char *getpasswd(char *crypted)
|
||||
{
|
||||
struct sigaction sa;
|
||||
@@ -252,11 +291,10 @@
|
||||
char *ret = pass;
|
||||
int i;
|
||||
|
||||
- if (crypted[0])
|
||||
- printf("Give root password for maintenance\n");
|
||||
- else
|
||||
- printf("Press enter for maintenance\n");
|
||||
- printf("(or type Control-D to continue): ");
|
||||
+ if (crypted[0]) {
|
||||
+ printf("Give root password for login: ");
|
||||
+ } else
|
||||
+ printf("Press enter for login: ");
|
||||
fflush(stdout);
|
||||
|
||||
tcgetattr(0, &old);
|
||||
@@ -291,6 +329,7 @@
|
||||
/*
|
||||
* Password was OK, execute a shell.
|
||||
*/
|
||||
+static
|
||||
void sushell(struct passwd *pwd)
|
||||
{
|
||||
char shell[128];
|
||||
@@ -332,9 +371,9 @@
|
||||
* Try to execute a shell.
|
||||
*/
|
||||
setenv("SHELL", sushell, 1);
|
||||
- signal(SIGINT, SIG_DFL);
|
||||
- signal(SIGTSTP, SIG_DFL);
|
||||
- signal(SIGQUIT, SIG_DFL);
|
||||
+ signal(SIGINT, saved_sigint);
|
||||
+ signal(SIGTSTP, saved_sigtstp);
|
||||
+ signal(SIGQUIT, saved_sigquit);
|
||||
execl(sushell, shell, NULL);
|
||||
perror(sushell);
|
||||
|
||||
@@ -343,6 +382,7 @@
|
||||
perror(BINSH);
|
||||
}
|
||||
|
||||
+static
|
||||
void usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: sulogin [-e] [-p] [-t timeout] [tty device]\n");
|
||||
@@ -385,50 +425,69 @@
|
||||
/*
|
||||
* See if we need to open an other tty device.
|
||||
*/
|
||||
- signal(SIGINT, SIG_IGN);
|
||||
- signal(SIGQUIT, SIG_IGN);
|
||||
- signal(SIGTSTP, SIG_IGN);
|
||||
+ saved_sigint = signal(SIGINT, SIG_IGN);
|
||||
+ saved_sigtstp = signal(SIGQUIT, SIG_IGN);
|
||||
+ saved_sigquit = signal(SIGTSTP, SIG_IGN);
|
||||
if (optind < argc) tty = argv[optind];
|
||||
- if (tty) {
|
||||
- if ((fd = open(tty, O_RDWR)) < 0) {
|
||||
- perror(tty);
|
||||
- } else if (!isatty(fd)) {
|
||||
- fprintf(stderr, "%s: not a tty\n", tty);
|
||||
- close(fd);
|
||||
- } else {
|
||||
-
|
||||
- /*
|
||||
- * Only go through this trouble if the new
|
||||
- * tty doesn't fall in this process group.
|
||||
- */
|
||||
- pid = getpid();
|
||||
- pgrp = getpgid(0);
|
||||
- ppgrp = getpgid(getppid());
|
||||
- ioctl(fd, TIOCGPGRP, &ttypgrp);
|
||||
-
|
||||
- if (pgrp != ttypgrp && ppgrp != ttypgrp) {
|
||||
- if (pid != getsid(0)) {
|
||||
- if (pid == getpgid(0))
|
||||
- setpgid(0, getpgid(getppid()));
|
||||
- setsid();
|
||||
- }
|
||||
|
||||
- signal(SIGHUP, SIG_IGN);
|
||||
+ if (!tty && !(tty = getenv("CONSOLE")))
|
||||
+ tty = "/dev/console";
|
||||
+
|
||||
+ if ((fd = open(tty, O_RDWR)) < 0) {
|
||||
+ perror(tty);
|
||||
+ fd = dup(0);
|
||||
+ }
|
||||
+
|
||||
+ if (!isatty(fd)) {
|
||||
+ fprintf(stderr, "%s: not a tty\n", tty);
|
||||
+ close(fd);
|
||||
+ } else {
|
||||
+
|
||||
+ /*
|
||||
+ * Only go through this trouble if the new
|
||||
+ * tty doesn't fall in this process group.
|
||||
+ */
|
||||
+ pid = getpid();
|
||||
+ pgrp = getpgid(0);
|
||||
+ ppgrp = getpgid(getppid());
|
||||
+ ttypgrp = tcgetpgrp(fd);
|
||||
+
|
||||
+ if (pgrp != ttypgrp && ppgrp != ttypgrp) {
|
||||
+ if (pid != getsid(0)) {
|
||||
+ if (pid == getpgid(0))
|
||||
+ setpgid(0, getpgid(getppid()));
|
||||
+ setsid();
|
||||
+ }
|
||||
+
|
||||
+ signal(SIGHUP, SIG_IGN);
|
||||
+ if (ttypgrp > 0)
|
||||
ioctl(0, TIOCNOTTY, (char *)1);
|
||||
- signal(SIGHUP, SIG_DFL);
|
||||
- close(0);
|
||||
- close(1);
|
||||
- close(2);
|
||||
+ signal(SIGHUP, SIG_DFL);
|
||||
+ close(0);
|
||||
+ close(1);
|
||||
+ close(2);
|
||||
+ if (fd > 2)
|
||||
close(fd);
|
||||
- fd = open(tty, O_RDWR);
|
||||
+ if ((fd = open(tty, O_RDWR)) < 0) {
|
||||
+ perror(tty);
|
||||
+ } else {
|
||||
+ tcsetpgrp(fd, ppgrp);
|
||||
ioctl(0, TIOCSCTTY, (char *)1);
|
||||
- dup(fd);
|
||||
- dup(fd);
|
||||
- } else
|
||||
+ dup2(fd, 0);
|
||||
+ dup2(fd, 1);
|
||||
+ dup2(fd, 2);
|
||||
+ if (fd > 2)
|
||||
+ close(fd);
|
||||
+ }
|
||||
+ } else
|
||||
+ if (fd > 2)
|
||||
close(fd);
|
||||
- }
|
||||
}
|
||||
|
||||
+#if FIXTTY
|
||||
+ fixtty();
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Get the root password.
|
||||
*/
|
||||
@@ -445,6 +504,9 @@
|
||||
if (pwd->pw_passwd[0] == 0 ||
|
||||
strcmp(crypt(p, pwd->pw_passwd), pwd->pw_passwd) == 0)
|
||||
sushell(pwd);
|
||||
+ saved_sigquit = signal(SIGQUIT, SIG_IGN);
|
||||
+ saved_sigtstp = signal(SIGTSTP, SIG_IGN);
|
||||
+ saved_sigint = signal(SIGINT, SIG_IGN);
|
||||
printf("Login incorrect.\n");
|
||||
}
|
||||
|
||||
@@ -453,4 +515,3 @@
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
-
|
@ -1,18 +0,0 @@
|
||||
src/last.c | 4 +++-
|
||||
1 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
Index: src/last.c
|
||||
===================================================================
|
||||
--- src/last.c.orig 2005-12-05 18:05:40.000000000 +0100
|
||||
+++ src/last.c 2005-12-05 18:07:21.000000000 +0100
|
||||
@@ -492,7 +492,9 @@ void usage(char *s)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-num | -n num] [-f file] "
|
||||
"[-t YYYYMMDDHHMMSS] "
|
||||
- "[-R] [-x] [-o] [username..] [tty..]\n", s);
|
||||
+ "[-R] [-a] [-d] [-i] [-o] [-x] "
|
||||
+ "[username..] [tty..]\n", s);
|
||||
+
|
||||
exit(1);
|
||||
}
|
||||
|
@ -1,203 +0,0 @@
|
||||
--- src/init.c
|
||||
+++ src/init.c 2006-08-22 13:04:27.000000000 +0000
|
||||
@@ -107,6 +107,8 @@ sig_atomic_t got_signals; /* Set if we r
|
||||
int emerg_shell = 0; /* Start emergency shell? */
|
||||
int wrote_wtmp_reboot = 1; /* Set when we wrote the reboot record */
|
||||
int wrote_utmp_reboot = 1; /* Set when we wrote the reboot record */
|
||||
+int wrote_wtmp_rlevel = 1; /* Set when we wrote the runlevel record */
|
||||
+int wrote_utmp_rlevel = 1; /* Set when we wrote the runlevel record */
|
||||
int sltime = 5; /* Sleep time between TERM and KILL */
|
||||
char *argv0; /* First arguments; show up in ps listing */
|
||||
int maxproclen; /* Maximal length of argv[0] with \0 */
|
||||
@@ -176,6 +178,8 @@ struct {
|
||||
{ "-WU", D_WROTE_UTMP_REBOOT},
|
||||
{ "-ST", D_SLTIME },
|
||||
{ "-DB", D_DIDBOOT },
|
||||
+ { "-LW", D_WROTE_WTMP_RLEVEL},
|
||||
+ { "-LU", D_WROTE_UTMP_RLEVEL},
|
||||
{ "", 0 }
|
||||
};
|
||||
struct {
|
||||
@@ -371,6 +375,12 @@ static CHILD *get_record(FILE *f)
|
||||
case D_DIDBOOT:
|
||||
fscanf(f, "%d\n", &did_boot);
|
||||
break;
|
||||
+ case D_WROTE_WTMP_RLEVEL:
|
||||
+ fscanf(f, "%d\n", &wrote_wtmp_rlevel);
|
||||
+ break;
|
||||
+ case D_WROTE_UTMP_RLEVEL:
|
||||
+ fscanf(f, "%d\n", &wrote_utmp_rlevel);
|
||||
+ break;
|
||||
default:
|
||||
if (cmd > 0 || cmd == C_EOF) {
|
||||
oops_error = -1;
|
||||
@@ -1697,6 +1707,8 @@ int read_level(int arg)
|
||||
}
|
||||
|
||||
/* Store both the old and the new runlevel. */
|
||||
+ wrote_utmp_rlevel = 0;
|
||||
+ wrote_wtmp_rlevel = 0;
|
||||
write_utmp_wtmp("runlevel", "~~", foo + 256*runlevel, RUN_LVL, "~");
|
||||
thislevel = foo;
|
||||
prevlevel = runlevel;
|
||||
@@ -1897,6 +1909,25 @@ void re_exec(void)
|
||||
initlog(L_CO, "Attempt to re-exec failed");
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Redo utmp/wtmp entries if required or requested
|
||||
+ * Check for written records and size of utmp
|
||||
+ */
|
||||
+static
|
||||
+void redo_utmp_wtmp(void)
|
||||
+{
|
||||
+ struct stat ustat;
|
||||
+ const int ret = stat(UTMP_FILE, &ustat);
|
||||
+
|
||||
+ if ((ret < 0) || (ustat.st_size == 0))
|
||||
+ wrote_utmp_rlevel = wrote_utmp_reboot = 0;
|
||||
+
|
||||
+ if ((wrote_wtmp_reboot == 0) || (wrote_utmp_reboot == 0))
|
||||
+ write_utmp_wtmp("reboot", "~~", 0, BOOT_TIME, "~");
|
||||
+
|
||||
+ if ((wrote_wtmp_rlevel == 0) || (wrote_wtmp_rlevel == 0))
|
||||
+ write_utmp_wtmp("runlevel", "~~", thislevel + 256 * prevlevel, RUN_LVL, "~");
|
||||
+}
|
||||
|
||||
/*
|
||||
* We got a change runlevel request through the
|
||||
@@ -1928,6 +1959,7 @@ void fifo_new_level(int level)
|
||||
if (oldlevel != 'S' && runlevel == 'S') console_stty();
|
||||
if (runlevel == '6' || runlevel == '0' ||
|
||||
runlevel == '1') console_stty();
|
||||
+ if (runlevel > '1' && runlevel < '6') redo_utmp_wtmp();
|
||||
read_inittab();
|
||||
fail_cancel();
|
||||
setproctitle("init [%c]", runlevel);
|
||||
@@ -2223,6 +2255,8 @@ void boot_transitions()
|
||||
}
|
||||
if (loglevel > 0) {
|
||||
initlog(L_VB, "Entering runlevel: %c", runlevel);
|
||||
+ wrote_utmp_rlevel = 0;
|
||||
+ wrote_wtmp_rlevel = 0;
|
||||
write_utmp_wtmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~");
|
||||
thislevel = runlevel;
|
||||
prevlevel = oldlevel;
|
||||
@@ -2401,6 +2435,7 @@ int init_main()
|
||||
console_init();
|
||||
|
||||
if (!reload) {
|
||||
+ int fd;
|
||||
|
||||
/* Close whatever files are open, and reset the console. */
|
||||
close(0);
|
||||
@@ -2418,7 +2453,8 @@ int init_main()
|
||||
* Initialize /var/run/utmp (only works if /var is on
|
||||
* root and mounted rw)
|
||||
*/
|
||||
- (void) close(open(UTMP_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0644));
|
||||
+ if ((fd = open(UTMP_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0644)) >= 0)
|
||||
+ close(fd);
|
||||
|
||||
/*
|
||||
* Say hello to the world
|
||||
--- src/init.h
|
||||
+++ src/init.h 2006-08-22 12:29:39.000000000 +0000
|
||||
@@ -99,6 +99,10 @@ typedef struct _child_ {
|
||||
extern CHILD *family;
|
||||
extern int wrote_wtmp_reboot;
|
||||
extern int wrote_utmp_reboot;
|
||||
+extern int wrote_wtmp_rlevel;
|
||||
+extern int wrote_utmp_rlevel;
|
||||
+extern char thislevel;
|
||||
+extern char prevlevel;
|
||||
|
||||
/* Tokens in state parser */
|
||||
#define C_VER 1
|
||||
@@ -120,4 +124,6 @@ extern int wrote_utmp_reboot;
|
||||
#define D_WROTE_UTMP_REBOOT -7
|
||||
#define D_SLTIME -8
|
||||
#define D_DIDBOOT -9
|
||||
+#define D_WROTE_WTMP_RLEVEL -16
|
||||
+#define D_WROTE_UTMP_RLEVEL -17
|
||||
|
||||
--- src/utmp.c
|
||||
+++ src/utmp.c 2006-08-22 12:28:52.000000000 +0000
|
||||
@@ -49,6 +49,12 @@ char *line) /* Which line is this */
|
||||
struct utsname uname_buf;
|
||||
|
||||
/*
|
||||
+ * Can't do much if WTMP_FILE is not present or not writable.
|
||||
+ */
|
||||
+ if (access(WTMP_FILE, W_OK) < 0)
|
||||
+ return;
|
||||
+
|
||||
+ /*
|
||||
* Try to open the wtmp file. Note that we even try
|
||||
* this if we have updwtmp() so we can see if the
|
||||
* wtmp file is accessible.
|
||||
@@ -69,6 +75,23 @@ char *line) /* Which line is this */
|
||||
*/
|
||||
if (wrote_wtmp_reboot == 0 && type != BOOT_TIME)
|
||||
write_wtmp("reboot", "~~", 0, BOOT_TIME, "~");
|
||||
+
|
||||
+ /*
|
||||
+ * Note if we are going to write a runlevel record.
|
||||
+ */
|
||||
+ if (type == RUN_LVL) wrote_wtmp_rlevel++;
|
||||
+
|
||||
+ /*
|
||||
+ * See if we need to write a runlevel record. The reason that
|
||||
+ * we are being so paranoid is that when we first tried to
|
||||
+ * write the reboot record, /var was possibly not mounted
|
||||
+ * yet. As soon as we can open WTMP we write a delayed runlevel record.
|
||||
+ */
|
||||
+ if (wrote_wtmp_rlevel == 0 && type != RUN_LVL) {
|
||||
+ int runlevel = thislevel;
|
||||
+ int oldlevel = prevlevel;
|
||||
+ write_wtmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~");
|
||||
+ }
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -115,9 +138,9 @@ char *oldline) /* Line of old utmp ent
|
||||
struct utmp *utmptr;
|
||||
|
||||
/*
|
||||
- * Can't do much if UTMP_FILE is not present.
|
||||
+ * Can't do much if UTMP_FILE is not present or not writable.
|
||||
*/
|
||||
- if (access(UTMP_FILE, F_OK) < 0)
|
||||
+ if (access(UTMP_FILE, W_OK) < 0)
|
||||
return;
|
||||
|
||||
#ifdef INIT_MAIN
|
||||
@@ -130,10 +153,27 @@ char *oldline) /* Line of old utmp ent
|
||||
* See if we need to write a reboot record. The reason that
|
||||
* we are being so paranoid is that when we first tried to
|
||||
* write the reboot record, /var was possibly not mounted
|
||||
- * yet. As soon as we can open WTMP we write a delayed boot record.
|
||||
+ * yet. As soon as we can open UTMP we write a delayed boot record.
|
||||
*/
|
||||
if (wrote_utmp_reboot == 0 && type != BOOT_TIME)
|
||||
write_utmp("reboot", "~~", 0, BOOT_TIME, "~", NULL);
|
||||
+
|
||||
+ /*
|
||||
+ * Note if we are going to write a runlevel record.
|
||||
+ */
|
||||
+ if (type == RUN_LVL) wrote_utmp_rlevel++;
|
||||
+
|
||||
+ /*
|
||||
+ * See if we need to write a runlevel record. The reason that
|
||||
+ * we are being so paranoid is that when we first tried to
|
||||
+ * write the reboot record, /var was possibly not mounted
|
||||
+ * yet. As soon as we can open UTMP we write a delayed runlevel record.
|
||||
+ */
|
||||
+ if (wrote_utmp_rlevel == 0 && type != RUN_LVL) {
|
||||
+ int runlevel = thislevel;
|
||||
+ int oldlevel = prevlevel;
|
||||
+ write_utmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~", NULL);
|
||||
+ }
|
||||
#endif
|
||||
|
||||
/*
|
@ -1,970 +0,0 @@
|
||||
--- .pkgextract
|
||||
+++ .pkgextract 2006-08-18 14:45:28.000000000 +0200
|
||||
@@ -0,0 +1,15 @@
|
||||
+patch -p0 -b -s --suffix=.nfs4pidof < ../sysvinit-2.86-nfs4pidof.patch
|
||||
+patch -p0 -b -s --suffix=.sulogin < ../sysvinit-2.86-sulogin.patch
|
||||
+patch -p0 -b -s --suffix=.ststdmn < ../sysvinit-2.82-startstop.patch
|
||||
+patch -p0 -b -s --suffix=.suse < ../sysvinit-2.85-suse.patch
|
||||
+patch -p0 -b -s --suffix=.paths < ../sysvinit-2.85-paths.patch
|
||||
+patch -p0 -b -s --suffix=.utmp < ../sysvinit-2.86-utmp.patch
|
||||
+patch -p0 -b -s --suffix=.race < ../sysvinit-2.86-race.patch
|
||||
+patch -p0 -b -s --suffix=.lib64 < ../sysvinit-2.86-lib64.patch
|
||||
+patch -p0 -b -s --suffix=.mltline < ../sysvinit-2.82-multiline.patch
|
||||
+patch -p0 -b -s --suffix=.usage < ../sysvinit-2.86-usage-message.patch
|
||||
+patch -p0 -b -s --suffix=.fulltime < ../sysvinit-2.86-full-time.patch
|
||||
+patch -p0 -b -s --suffix=.hddown < ../sysvinit-2.86-hddown.patch
|
||||
+patch -p0 -b -s --suffix=.selinux < ../sysvinit-2.86-selinux.patch
|
||||
+patch -p0 -b -s --suffix=.fuse < ../sysvinit-2.86-fuse-no-kill.patch
|
||||
+patch -p0 -b -s --suffix=.mdmon < ../sysvinit-2.86-mdmon-no-kill.patch
|
||||
--- src/Makefile
|
||||
+++ src/Makefile 2009-05-11 10:05:28.482401539 +0200
|
||||
@@ -8,17 +8,20 @@
|
||||
# Version: @(#)Makefile 2.85-13 23-Mar-2004 miquels@cistron.nl
|
||||
#
|
||||
|
||||
+DISTRO = SuSE
|
||||
+
|
||||
CC = gcc
|
||||
-CFLAGS = -Wall -O2 -fomit-frame-pointer -D_GNU_SOURCE
|
||||
-LDFLAGS = -s
|
||||
-STATIC =
|
||||
+CFLAGS = -Wall $(RPM_OPT_FLAGS) -D_GNU_SOURCE -pipe
|
||||
+LDFLAGS = -Wl,-warn-common,--as-needed,-O2
|
||||
+STATIC = -Wl,--reduce-memory-overheads,--hash-size=8599
|
||||
+IFLAGS = -D__NO_STRING_INLINES -D__OPTIMIZE_SIZE__ -Os
|
||||
|
||||
# For some known distributions we do not build all programs, otherwise we do.
|
||||
BIN =
|
||||
SBIN = init halt shutdown runlevel killall5
|
||||
-USRBIN = last mesg
|
||||
+USRBIN = last
|
||||
|
||||
-MAN1 = last.1 lastb.1 mesg.1
|
||||
+MAN1 = last.1 lastb.1
|
||||
MAN5 = initscript.5 inittab.5
|
||||
MAN8 = halt.8 init.8 killall5.8 pidof.8 poweroff.8 reboot.8 runlevel.8
|
||||
MAN8 += shutdown.8 telinit.8
|
||||
@@ -26,27 +29,36 @@ MAN8 += shutdown.8 telinit.8
|
||||
ifeq ($(DISTRO),)
|
||||
BIN += mountpoint
|
||||
SBIN += sulogin bootlogd
|
||||
-USRBIN += utmpdump wall
|
||||
-MAN1 += mountpoint.1 wall.1
|
||||
+USRBIN += utmpdump wall mesg
|
||||
+MAN1 += utmpdump.1 mountpoint.1 wall.1 mesg.1
|
||||
MAN8 += sulogin.8 bootlogd.8
|
||||
endif
|
||||
|
||||
ifeq ($(DISTRO),Debian)
|
||||
BIN += mountpoint
|
||||
SBIN += sulogin bootlogd
|
||||
-MAN1 += mountpoint.1
|
||||
+USRBIN += mesg
|
||||
+MAN1 += mountpoint.1 mesg.1
|
||||
MAN8 += sulogin.8 bootlogd.8
|
||||
endif
|
||||
|
||||
ifeq ($(DISTRO),Owl)
|
||||
-USRBIN += wall
|
||||
-MAN1 += wall.1
|
||||
+USRBIN += wall mesg
|
||||
+MAN1 += wall.1 mesg.1
|
||||
+endif
|
||||
+
|
||||
+ifeq ($(DISTRO),SuSE)
|
||||
+BIN += mountpoint
|
||||
+SBIN += sulogin
|
||||
+USRBIN += utmpdump
|
||||
+MAN1 += utmpdump.1 mountpoint.1
|
||||
+MAN8 += sulogin.8
|
||||
endif
|
||||
|
||||
BIN_OWNER = root
|
||||
BIN_GROUP = root
|
||||
BIN_COMBO = $(BIN_OWNER):$(BIN_GROUP)
|
||||
-INSTALL = install -o $(BIN_OWNER) -g $(BIN_GROUP)
|
||||
+INSTALL = install
|
||||
MANDIR = /usr/share/man
|
||||
|
||||
# Additional libs for GNU libc.
|
||||
@@ -90,13 +102,13 @@ bootlogd: bootlogd.o
|
||||
$(CC) $(LDFLAGS) -o $@ bootlogd.o -lutil
|
||||
|
||||
init.o: init.c init.h set.h reboot.h initreq.h
|
||||
- $(CC) -c $(CFLAGS) init.c
|
||||
+ $(CC) -c $(CFLAGS) $(IFLAGS) init.c
|
||||
|
||||
utmp.o: utmp.c init.h
|
||||
$(CC) -c $(CFLAGS) utmp.c
|
||||
|
||||
init_utmp.o: utmp.c init.h
|
||||
- $(CC) -c $(CFLAGS) -DINIT_MAIN utmp.c -o init_utmp.o
|
||||
+ $(CC) -c $(CFLAGS) -DINIT_MAIN $(IFLAGS) utmp.c -o init_utmp.o
|
||||
|
||||
cleanobjs:
|
||||
rm -f *.o *.bak
|
||||
@@ -119,10 +131,10 @@ install:
|
||||
for i in $(USRBIN); do \
|
||||
$(INSTALL) -m 755 $$i $(ROOT)/usr/bin/; \
|
||||
done
|
||||
- # $(INSTALL) -m 755 etc/initscript.sample $(ROOT)/etc/
|
||||
- ln -sf halt $(ROOT)/sbin/reboot
|
||||
- ln -sf halt $(ROOT)/sbin/poweroff
|
||||
- ln -sf init $(ROOT)/sbin/telinit
|
||||
+ ln -sf halt $(ROOT)/sbin/reboot
|
||||
+ ln -sf halt $(ROOT)/sbin/poweroff
|
||||
+ ln -sf init $(ROOT)/sbin/telinit
|
||||
+ ln -sf killall5 $(ROOT)/sbin/pidof
|
||||
ln -sf ../sbin/killall5 $(ROOT)/bin/pidof
|
||||
if [ ! -f $(ROOT)/usr/bin/lastb ]; then \
|
||||
ln -sf last $(ROOT)/usr/bin/lastb; \
|
||||
--- src/bootlogd.c
|
||||
+++ src/bootlogd.c 2006-08-18 14:45:28.000000000 +0200
|
||||
@@ -210,7 +210,7 @@ int isconsole(char *s, char *res, int rl
|
||||
int consolename(char *res, int rlen)
|
||||
{
|
||||
#ifdef TIOCGDEV
|
||||
- unsigned int kdev;
|
||||
+ kdev_t kdev;
|
||||
#endif
|
||||
struct stat st, st2;
|
||||
char buf[256];
|
||||
@@ -506,7 +506,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
(void)ioctl(0, TIOCCONS, NULL);
|
||||
-#if 1
|
||||
+#if 0
|
||||
/* Work around bug in 2.1/2.2 kernels. Fixed in 2.2.13 and 2.3.18 */
|
||||
if ((n = open("/dev/tty0", O_RDWR)) >= 0) {
|
||||
(void)ioctl(n, TIOCCONS, NULL);
|
||||
--- src/dowall.c
|
||||
+++ src/dowall.c 2006-08-18 14:45:28.000000000 +0200
|
||||
@@ -65,7 +65,7 @@ static void getuidtty(char **userp, char
|
||||
uid_t uid;
|
||||
char *tty;
|
||||
static char uidbuf[32];
|
||||
- static char ttynm[32];
|
||||
+ static char ttynm[UT_LINESIZE + 4];
|
||||
static int init = 0;
|
||||
|
||||
if (!init) {
|
||||
@@ -79,9 +79,13 @@ static void getuidtty(char **userp, char
|
||||
}
|
||||
|
||||
if ((tty = ttyname(0)) != NULL) {
|
||||
- if (strncmp(tty, "/dev/", 5) == 0)
|
||||
- tty += 5;
|
||||
- sprintf(ttynm, "(%.28s) ", tty);
|
||||
+ if (strncmp(tty, _PATH_DEV, strlen(_PATH_DEV)) == 0) {
|
||||
+ tty += strlen(_PATH_DEV);
|
||||
+ if (tty[0] == '/')
|
||||
+ tty ++;
|
||||
+ }
|
||||
+ snprintf(ttynm, sizeof(ttynm), "(%.*s) ",
|
||||
+ UT_LINESIZE, tty);
|
||||
} else
|
||||
ttynm[0] = 0;
|
||||
init++;
|
||||
@@ -129,7 +133,7 @@ void wall(char *text, int fromshutdown,
|
||||
struct sigaction sa;
|
||||
struct utmp *utmp;
|
||||
time_t t;
|
||||
- char term[UT_LINESIZE+6];
|
||||
+ char term[UT_LINESIZE + strlen(_PATH_DEV) + 1];
|
||||
char line[81];
|
||||
char *date, *p;
|
||||
char *user, *tty;
|
||||
@@ -178,11 +182,11 @@ void wall(char *text, int fromshutdown,
|
||||
while ((utmp = getutent()) != NULL) {
|
||||
if(utmp->ut_type != USER_PROCESS ||
|
||||
utmp->ut_user[0] == 0) continue;
|
||||
- if (strncmp(utmp->ut_line, "/dev/", 5) == 0) {
|
||||
+ if (strncmp(utmp->ut_line, _PATH_DEV, strlen(_PATH_DEV)) == 0) {
|
||||
term[0] = 0;
|
||||
- strncat(term, utmp->ut_line, UT_LINESIZE);
|
||||
+ strncat(term, utmp->ut_line, sizeof(term)-1);
|
||||
} else
|
||||
- snprintf(term, sizeof(term), "/dev/%.*s",
|
||||
+ snprintf(term, sizeof(term), _PATH_DEV "%.*s",
|
||||
UT_LINESIZE, utmp->ut_line);
|
||||
if (strstr(term, "/../")) continue;
|
||||
|
||||
--- src/init.c
|
||||
+++ src/init.c 2009-05-11 00:00:00.000000000 +0200
|
||||
@@ -54,12 +54,12 @@
|
||||
#include <sepol/sepol.h>
|
||||
|
||||
#ifdef __i386__
|
||||
-# if (__GLIBC__ >= 2)
|
||||
- /* GNU libc 2.x */
|
||||
+# if defined (__GLIBC__)
|
||||
# define STACK_DEBUG 1
|
||||
# if (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
|
||||
- /* Only glibc 2.0 needs this */
|
||||
# include <sigcontext.h>
|
||||
+# elif ( __GLIBC__ > 2) && ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
|
||||
+# include <bits/sigcontext.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
@@ -70,6 +70,12 @@
|
||||
#include "reboot.h"
|
||||
#include "set.h"
|
||||
|
||||
+#ifdef __GNUC__
|
||||
+ __attribute__ ((format (printf, 2, 3)))
|
||||
+#endif
|
||||
+static void initlog(int loglevel, char *fmt, ...);
|
||||
+static void print(char *fmt);
|
||||
+
|
||||
#ifndef SIGPWR
|
||||
# define SIGPWR SIGUSR2
|
||||
#endif
|
||||
@@ -84,11 +90,15 @@
|
||||
/* Set a signal handler. */
|
||||
#define SETSIG(sa, sig, fun, flags) \
|
||||
do { \
|
||||
+ memset(&sa, 0, sizeof(sa)); \
|
||||
sa.sa_handler = fun; \
|
||||
sa.sa_flags = flags; \
|
||||
sigemptyset(&sa.sa_mask); \
|
||||
sigaction(sig, &sa, NULL); \
|
||||
} while(0)
|
||||
+#ifndef mem_barrier
|
||||
+# define mem_barrier() __asm__ __volatile__("": : :"memory")
|
||||
+#endif
|
||||
|
||||
/* Version information */
|
||||
char *Version = "@(#) init " VERSION " " DATE " miquels@cistron.nl";
|
||||
@@ -212,6 +222,7 @@ char *extra_env[NR_EXTRA_ENV];
|
||||
* This only works correctly because the linux select updates
|
||||
* the elapsed time in the struct timeval passed to select!
|
||||
*/
|
||||
+static
|
||||
void do_sleep(int sec)
|
||||
{
|
||||
struct timeval tv;
|
||||
@@ -220,13 +231,14 @@ void do_sleep(int sec)
|
||||
tv.tv_usec = 0;
|
||||
|
||||
while(select(0, NULL, NULL, NULL, &tv) < 0 && errno == EINTR)
|
||||
- ;
|
||||
+ mem_barrier();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Non-failing allocation routines (init cannot fail).
|
||||
*/
|
||||
+static
|
||||
void *imalloc(size_t size)
|
||||
{
|
||||
void *m;
|
||||
@@ -239,7 +251,7 @@ void *imalloc(size_t size)
|
||||
return m;
|
||||
}
|
||||
|
||||
-
|
||||
+static
|
||||
char *istrdup(char *s)
|
||||
{
|
||||
char *m;
|
||||
@@ -256,6 +268,7 @@ char *istrdup(char *s)
|
||||
* Send the state info of the previous running init to
|
||||
* the new one, in a version-independant way.
|
||||
*/
|
||||
+static
|
||||
void send_state(int fd)
|
||||
{
|
||||
FILE *fp;
|
||||
@@ -320,7 +333,7 @@ static int get_void(FILE *f)
|
||||
int c;
|
||||
|
||||
while ((c = getc(f)) != EOF && c != '\n')
|
||||
- ;
|
||||
+ mem_barrier();
|
||||
|
||||
return (c != EOF);
|
||||
}
|
||||
@@ -337,7 +350,7 @@ static int get_cmd(FILE *f)
|
||||
return C_EOF;
|
||||
|
||||
for(i = 0; cmds[i].cmd && strcmp(cmds[i].name, cmd) != 0; i++)
|
||||
- ;
|
||||
+ mem_barrier();
|
||||
return cmds[i].cmd;
|
||||
}
|
||||
|
||||
@@ -448,6 +461,7 @@ static CHILD *get_record(FILE *f)
|
||||
* Read the complete state info from the state pipe.
|
||||
* Returns 0 on success
|
||||
*/
|
||||
+static
|
||||
int receive_state(int fd)
|
||||
{
|
||||
FILE *f;
|
||||
@@ -461,7 +475,7 @@ int receive_state(int fd)
|
||||
get_string(old_version, sizeof(old_version), f);
|
||||
oops_error = 0;
|
||||
for (pp = &family; (*pp = get_record(f)) != NULL; pp = &((*pp)->next))
|
||||
- ;
|
||||
+ mem_barrier();
|
||||
fclose(f);
|
||||
return oops_error;
|
||||
}
|
||||
@@ -495,6 +509,7 @@ static int setproctitle(char *fmt, ...)
|
||||
/*
|
||||
* Set console_dev to a working console.
|
||||
*/
|
||||
+static
|
||||
void console_init(void)
|
||||
{
|
||||
int fd;
|
||||
@@ -534,6 +549,7 @@ void console_init(void)
|
||||
/*
|
||||
* Open the console with retries.
|
||||
*/
|
||||
+static
|
||||
int console_open(int mode)
|
||||
{
|
||||
int f, fd = -1;
|
||||
@@ -563,6 +579,7 @@ int console_open(int mode)
|
||||
/*
|
||||
* We got a signal (HUP PWR WINCH ALRM INT)
|
||||
*/
|
||||
+static
|
||||
void signal_handler(int sig)
|
||||
{
|
||||
ADDSET(got_signals, sig);
|
||||
@@ -571,6 +588,7 @@ void signal_handler(int sig)
|
||||
/*
|
||||
* SIGCHLD: one of our children has died.
|
||||
*/
|
||||
+static
|
||||
void chld_handler()
|
||||
{
|
||||
CHILD *ch;
|
||||
@@ -610,7 +628,8 @@ void chld_handler()
|
||||
*
|
||||
* The SIGCONT handler
|
||||
*/
|
||||
-void cont_handler()
|
||||
+static
|
||||
+void cont_handler(int sig)
|
||||
{
|
||||
got_cont = 1;
|
||||
}
|
||||
@@ -618,6 +637,7 @@ void cont_handler()
|
||||
/*
|
||||
* Fork and dump core in /.
|
||||
*/
|
||||
+static
|
||||
void coredump(void)
|
||||
{
|
||||
static int dumped = 0;
|
||||
@@ -651,6 +671,7 @@ void coredump(void)
|
||||
* If we have the info, print where it occured.
|
||||
* Then sleep 30 seconds and try to continue.
|
||||
*/
|
||||
+static
|
||||
#if defined(STACK_DEBUG) && defined(__linux__)
|
||||
void segv_handler(int sig, struct sigcontext ctx)
|
||||
{
|
||||
@@ -667,7 +688,7 @@ void segv_handler(int sig, struct sigcon
|
||||
errno = saved_errno;
|
||||
}
|
||||
#else
|
||||
-void segv_handler()
|
||||
+void segv_handler(int sig)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
|
||||
@@ -682,7 +703,8 @@ void segv_handler()
|
||||
/*
|
||||
* The SIGSTOP & SIGTSTP handler
|
||||
*/
|
||||
-void stop_handler()
|
||||
+static
|
||||
+void stop_handler(int sig)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
|
||||
@@ -695,6 +717,7 @@ void stop_handler()
|
||||
/*
|
||||
* Set terminal settings to reasonable defaults
|
||||
*/
|
||||
+static
|
||||
void console_stty(void)
|
||||
{
|
||||
struct termios tty;
|
||||
@@ -710,16 +733,23 @@ void console_stty(void)
|
||||
tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
|
||||
tty.c_cflag |= HUPCL|CLOCAL|CREAD;
|
||||
|
||||
- tty.c_cc[VINTR] = 3; /* ctrl('c') */
|
||||
- tty.c_cc[VQUIT] = 28; /* ctrl('\\') */
|
||||
- tty.c_cc[VERASE] = 127;
|
||||
- tty.c_cc[VKILL] = 24; /* ctrl('x') */
|
||||
- tty.c_cc[VEOF] = 4; /* ctrl('d') */
|
||||
- tty.c_cc[VTIME] = 0;
|
||||
- tty.c_cc[VMIN] = 1;
|
||||
- tty.c_cc[VSTART] = 17; /* ctrl('q') */
|
||||
- tty.c_cc[VSTOP] = 19; /* ctrl('s') */
|
||||
- tty.c_cc[VSUSP] = 26; /* ctrl('z') */
|
||||
+ tty.c_cc[VTIME] = 0;
|
||||
+ tty.c_cc[VMIN] = 1;
|
||||
+ tty.c_cc[VINTR] = CINTR;
|
||||
+ tty.c_cc[VQUIT] = CQUIT;
|
||||
+ tty.c_cc[VERASE] = CERASE; /* ASCII DEL (0177) */
|
||||
+ tty.c_cc[VKILL] = CKILL;
|
||||
+ tty.c_cc[VEOF] = CEOF;
|
||||
+ tty.c_cc[VSWTC] = _POSIX_VDISABLE;
|
||||
+ tty.c_cc[VSTART] = CSTART;
|
||||
+ tty.c_cc[VSTOP] = CSTOP;
|
||||
+ tty.c_cc[VSUSP] = CSUSP;
|
||||
+ tty.c_cc[VEOL] = _POSIX_VDISABLE;
|
||||
+ tty.c_cc[VREPRINT] = CREPRINT;
|
||||
+ tty.c_cc[VDISCARD] = CDISCARD;
|
||||
+ tty.c_cc[VWERASE] = CWERASE;
|
||||
+ tty.c_cc[VLNEXT] = CLNEXT;
|
||||
+ tty.c_cc[VEOL2] = _POSIX_VDISABLE;
|
||||
|
||||
/*
|
||||
* Set pre and post processing
|
||||
@@ -729,6 +759,14 @@ void console_stty(void)
|
||||
tty.c_lflag = ISIG|ICANON|ECHO|ECHOCTL|ECHOPRT|ECHOKE;
|
||||
|
||||
/*
|
||||
+ * Setting for SuSE: No flow control (-ixon), ignore break (ignbrk),
|
||||
+ * and make nl/cr more usable (sane).
|
||||
+ */
|
||||
+ tty.c_iflag |= IGNBRK;
|
||||
+ tty.c_iflag &= ~(BRKINT|INLCR|IGNCR|IXON);
|
||||
+ tty.c_oflag &= ~(OCRNL|ONLRET);
|
||||
+
|
||||
+ /*
|
||||
* Now set the terminal line.
|
||||
* We don't care about non-transmitted output data
|
||||
* and non-read input data.
|
||||
@@ -741,6 +779,7 @@ void console_stty(void)
|
||||
/*
|
||||
* Print to the system console
|
||||
*/
|
||||
+static
|
||||
void print(char *s)
|
||||
{
|
||||
int fd;
|
||||
@@ -757,6 +796,7 @@ void print(char *s)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
#endif
|
||||
+static
|
||||
void initlog(int loglevel, char *s, ...)
|
||||
{
|
||||
va_list va_alist;
|
||||
@@ -799,6 +839,7 @@ char **init_buildenv(int child)
|
||||
char i_lvl[] = "RUNLEVEL=x";
|
||||
char i_prev[] = "PREVLEVEL=x";
|
||||
char i_cons[32];
|
||||
+ char i_shell[] = "SHELL=" SHELL;
|
||||
char **e;
|
||||
int n, i;
|
||||
|
||||
@@ -818,6 +859,7 @@ char **init_buildenv(int child)
|
||||
snprintf(i_cons, sizeof(i_cons), "CONSOLE=%s", console_dev);
|
||||
i_lvl[9] = thislevel;
|
||||
i_prev[10] = prevlevel;
|
||||
+ e[n++] = istrdup(i_shell);
|
||||
e[n++] = istrdup(i_lvl);
|
||||
e[n++] = istrdup(i_prev);
|
||||
e[n++] = istrdup(i_cons);
|
||||
@@ -846,6 +888,7 @@ void init_freeenv(char **e)
|
||||
* This function is too long and indents too deep.
|
||||
*
|
||||
*/
|
||||
+static
|
||||
int spawn(CHILD *ch, int *res)
|
||||
{
|
||||
char *args[16]; /* Argv array */
|
||||
@@ -988,7 +1031,7 @@ int spawn(CHILD *ch, int *res)
|
||||
}
|
||||
SETSIG(sa, SIGCHLD, SIG_DFL, SA_RESTART);
|
||||
if ((pid = fork()) < 0) {
|
||||
- initlog(L_VB, "cannot fork");
|
||||
+ initlog(L_VB, "cannot fork: %s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (pid > 0) {
|
||||
@@ -1017,7 +1060,7 @@ int spawn(CHILD *ch, int *res)
|
||||
* this with a temporary process.
|
||||
*/
|
||||
if ((pid = fork()) < 0) {
|
||||
- initlog(L_VB, "cannot fork");
|
||||
+ initlog(L_VB, "cannot fork: %s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (pid == 0) {
|
||||
@@ -1083,6 +1126,7 @@ int spawn(CHILD *ch, int *res)
|
||||
/*
|
||||
* Start a child running!
|
||||
*/
|
||||
+static
|
||||
void startup(CHILD *ch)
|
||||
{
|
||||
/*
|
||||
@@ -1125,6 +1169,7 @@ void startup(CHILD *ch)
|
||||
/*
|
||||
* Read the inittab file.
|
||||
*/
|
||||
+static
|
||||
void read_inittab(void)
|
||||
{
|
||||
FILE *fp; /* The INITTAB file */
|
||||
@@ -1182,7 +1227,7 @@ void read_inittab(void)
|
||||
* Skip comments and empty lines
|
||||
*/
|
||||
for(p = buf; *p == ' ' || *p == '\t'; p++)
|
||||
- ;
|
||||
+ mem_barrier();
|
||||
if (*p == '#' || *p == '\n') continue;
|
||||
|
||||
/*
|
||||
@@ -1505,6 +1550,7 @@ void read_inittab(void)
|
||||
* The entries that do not belong here at all are removed
|
||||
* from the list.
|
||||
*/
|
||||
+static
|
||||
void start_if_needed(void)
|
||||
{
|
||||
CHILD *ch; /* Pointer to child */
|
||||
@@ -1550,6 +1596,7 @@ void start_if_needed(void)
|
||||
/*
|
||||
* Ask the user on the console for a runlevel
|
||||
*/
|
||||
+static
|
||||
int ask_runlevel(void)
|
||||
{
|
||||
const char prompt[] = "\nEnter runlevel: ";
|
||||
@@ -1578,6 +1625,7 @@ int ask_runlevel(void)
|
||||
* Search the INITTAB file for the 'initdefault' field, with the default
|
||||
* runlevel. If this fails, ask the user to supply a runlevel.
|
||||
*/
|
||||
+static
|
||||
int get_init_default(void)
|
||||
{
|
||||
CHILD *ch;
|
||||
@@ -1626,6 +1674,7 @@ int get_init_default(void)
|
||||
* the "old" INITLVL and arg == 0, try to read the new
|
||||
* runlevel from that file first.
|
||||
*/
|
||||
+static
|
||||
int read_level(int arg)
|
||||
{
|
||||
CHILD *ch; /* Walk through list */
|
||||
@@ -1694,7 +1743,16 @@ int read_level(int arg)
|
||||
initlog(L_VB, "Switching to runlevel: %c", foo);
|
||||
}
|
||||
|
||||
- if (foo == 'Q') return runlevel;
|
||||
+ if (foo == 'Q') {
|
||||
+ struct sigaction sa;
|
||||
+
|
||||
+ /*
|
||||
+ * Re-enable SIGINT's, which may disabled by
|
||||
+ * an former Ctrl-Alt-Del action in process_signals().
|
||||
+ */
|
||||
+ SETSIG(sa, SIGINT, signal_handler, 0);
|
||||
+ return(runlevel);
|
||||
+ }
|
||||
|
||||
/* Check if this is a runlevel a, b or c */
|
||||
if (strchr("ABC", foo)) {
|
||||
@@ -1733,6 +1791,7 @@ int read_level(int arg)
|
||||
* longer than 5 minutes, or inittab was read again due
|
||||
* to user interaction.
|
||||
*/
|
||||
+static
|
||||
void fail_check(void)
|
||||
{
|
||||
CHILD *ch; /* Pointer to child structure */
|
||||
@@ -1765,6 +1824,7 @@ void fail_check(void)
|
||||
}
|
||||
|
||||
/* Set all 'Fail' timers to 0 */
|
||||
+static
|
||||
void fail_cancel(void)
|
||||
{
|
||||
CHILD *ch;
|
||||
@@ -1779,6 +1839,7 @@ void fail_cancel(void)
|
||||
/*
|
||||
* Start up powerfail entries.
|
||||
*/
|
||||
+static
|
||||
void do_power_fail(int pwrstat)
|
||||
{
|
||||
CHILD *ch;
|
||||
@@ -1812,6 +1873,7 @@ void do_power_fail(int pwrstat)
|
||||
/*
|
||||
* Check for state-pipe presence
|
||||
*/
|
||||
+static
|
||||
int check_pipe(int fd)
|
||||
{
|
||||
struct timeval t;
|
||||
@@ -1832,6 +1894,7 @@ int check_pipe(int fd)
|
||||
/*
|
||||
* Make a state-pipe.
|
||||
*/
|
||||
+static
|
||||
int make_pipe(int fd)
|
||||
{
|
||||
int fds[2];
|
||||
@@ -1849,6 +1912,7 @@ int make_pipe(int fd)
|
||||
/*
|
||||
* Attempt to re-exec.
|
||||
*/
|
||||
+static
|
||||
void re_exec(void)
|
||||
{
|
||||
CHILD *ch;
|
||||
@@ -1906,7 +1970,7 @@ void re_exec(void)
|
||||
* The existing init process execs a new init binary.
|
||||
*/
|
||||
env = init_buildenv(0);
|
||||
- execl(myname, myname, "--init", NULL, env);
|
||||
+ execle(myname, myname, "--init", NULL, env);
|
||||
|
||||
/*
|
||||
* We shouldn't be here, something failed.
|
||||
@@ -1943,6 +2007,7 @@ void redo_utmp_wtmp(void)
|
||||
* We got a change runlevel request through the
|
||||
* init.fifo. Process it.
|
||||
*/
|
||||
+static
|
||||
void fifo_new_level(int level)
|
||||
{
|
||||
#if CHANGE_WAIT
|
||||
@@ -1972,7 +2037,7 @@ void fifo_new_level(int level)
|
||||
if (runlevel > '1' && runlevel < '6') redo_utmp_wtmp();
|
||||
read_inittab();
|
||||
fail_cancel();
|
||||
- setproctitle("init [%c]", runlevel);
|
||||
+ setproctitle("init [%c]", (int)runlevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2040,6 +2105,7 @@ void initcmd_setenv(char *data, int size
|
||||
* the 2.2 kernel credential stuff to see who we're talking to.
|
||||
*
|
||||
*/
|
||||
+static
|
||||
void check_init_fifo(void)
|
||||
{
|
||||
struct init_request request;
|
||||
@@ -2105,7 +2171,7 @@ void check_init_fifo(void)
|
||||
tv.tv_usec = 0;
|
||||
n = select(pipe_fd + 1, &fds, NULL, NULL, &tv);
|
||||
if (n <= 0) {
|
||||
- if (n == 0 || errno == EINTR) return;
|
||||
+ if (n == 0 || errno == EINTR || errno == EAGAIN) return;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2122,7 +2188,7 @@ void check_init_fifo(void)
|
||||
return;
|
||||
}
|
||||
if (n <= 0) {
|
||||
- if (errno == EINTR) return;
|
||||
+ if (errno == EINTR || errno == EAGAIN) return;
|
||||
initlog(L_VB, "error reading initrequest");
|
||||
continue;
|
||||
}
|
||||
@@ -2194,6 +2260,7 @@ void check_init_fifo(void)
|
||||
* This function is used in the transition
|
||||
* sysinit (-> single user) boot -> multi-user.
|
||||
*/
|
||||
+static
|
||||
void boot_transitions()
|
||||
{
|
||||
CHILD *ch;
|
||||
@@ -2270,7 +2337,7 @@ void boot_transitions()
|
||||
write_utmp_wtmp("runlevel", "~~", runlevel + 256 * oldlevel, RUN_LVL, "~");
|
||||
thislevel = runlevel;
|
||||
prevlevel = oldlevel;
|
||||
- setproctitle("init [%c]", runlevel);
|
||||
+ setproctitle("init [%c]", (int)runlevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2279,6 +2346,7 @@ void boot_transitions()
|
||||
* Init got hit by a signal. See which signal it is,
|
||||
* and act accordingly.
|
||||
*/
|
||||
+static
|
||||
void process_signals()
|
||||
{
|
||||
CHILD *ch;
|
||||
@@ -2303,7 +2371,12 @@ void process_signals()
|
||||
}
|
||||
|
||||
if (ISMEMBER(got_signals, SIGINT)) {
|
||||
+ struct sigaction sa;
|
||||
INITDBG(L_VB, "got SIGINT");
|
||||
+
|
||||
+ /* we don't want any more SIGINT's */
|
||||
+ SETSIG(sa, SIGINT, SIG_IGN, SA_RESTART);
|
||||
+
|
||||
/* Tell ctrlaltdel entry to start up */
|
||||
for(ch = family; ch; ch = ch->next)
|
||||
if (ch->action == CTRLALTDEL)
|
||||
@@ -2365,7 +2438,7 @@ void process_signals()
|
||||
runlevel == '1') console_stty();
|
||||
read_inittab();
|
||||
fail_cancel();
|
||||
- setproctitle("init [%c]", runlevel);
|
||||
+ setproctitle("init [%c]", (int)runlevel);
|
||||
DELSET(got_signals, SIGHUP);
|
||||
}
|
||||
}
|
||||
@@ -2384,7 +2457,8 @@ void process_signals()
|
||||
/*
|
||||
* The main loop
|
||||
*/
|
||||
-int init_main()
|
||||
+static
|
||||
+void init_main(void)
|
||||
{
|
||||
CHILD *ch;
|
||||
struct sigaction sa;
|
||||
@@ -2539,6 +2613,7 @@ int init_main()
|
||||
/*
|
||||
* Tell the user about the syntax we expect.
|
||||
*/
|
||||
+static
|
||||
void usage(char *s)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s 0123456SsQqAaBbCcUu\n", s);
|
||||
@@ -2596,12 +2671,38 @@ int telinit(char *progname, int argc, ch
|
||||
request.sleeptime = sltime;
|
||||
}
|
||||
|
||||
+ /* Catch some common signals. */
|
||||
+ signal(SIGQUIT, SIG_IGN);
|
||||
+ signal(SIGCHLD, SIG_IGN);
|
||||
+ signal(SIGHUP, SIG_IGN);
|
||||
+ signal(SIGTSTP, SIG_IGN);
|
||||
+ signal(SIGTTIN, SIG_IGN);
|
||||
+ signal(SIGTTOU, SIG_IGN);
|
||||
+ signal(SIGINT, SIG_IGN);
|
||||
+
|
||||
+ /* Go to the root directory. */
|
||||
+ chdir("/");
|
||||
+
|
||||
/* Open the fifo and write a command. */
|
||||
+
|
||||
/* Make sure we don't hang on opening /dev/initctl */
|
||||
SETSIG(sa, SIGALRM, signal_handler, 0);
|
||||
alarm(3);
|
||||
- if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0 &&
|
||||
- write(fd, &request, sizeof(request)) == sizeof(request)) {
|
||||
+ if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) {
|
||||
+ ssize_t p = 0;
|
||||
+ size_t s = sizeof(request);
|
||||
+ void *ptr = &request;
|
||||
+
|
||||
+ while (s > 0) {
|
||||
+ p = write(fd, ptr, s);
|
||||
+ if (p < 0) {
|
||||
+ if (errno == EINTR || errno == EAGAIN)
|
||||
+ continue;
|
||||
+ break;
|
||||
+ }
|
||||
+ ptr += p;
|
||||
+ s -= p;
|
||||
+ }
|
||||
close(fd);
|
||||
alarm(0);
|
||||
return 0;
|
||||
@@ -2652,6 +2753,8 @@ int main(int argc, char **argv)
|
||||
p++;
|
||||
else
|
||||
p = argv[0];
|
||||
+
|
||||
+ /* Common umask */
|
||||
umask(022);
|
||||
|
||||
/* Quick check */
|
||||
@@ -2684,7 +2787,7 @@ int main(int argc, char **argv)
|
||||
for (f = 0; f < argc; f++)
|
||||
maxproclen += strlen(argv[f]) + 1;
|
||||
reload = 1;
|
||||
- setproctitle("init [%c]",runlevel);
|
||||
+ setproctitle("init [%c]", (int)runlevel);
|
||||
|
||||
init_main();
|
||||
}
|
||||
@@ -2727,7 +2830,7 @@ int main(int argc, char **argv)
|
||||
argv0 = argv[0];
|
||||
argv[1] = NULL;
|
||||
setproctitle("init boot");
|
||||
- init_main(dfl_level);
|
||||
+ init_main();
|
||||
|
||||
/*NOTREACHED*/
|
||||
return 0;
|
||||
--- src/init.h
|
||||
+++ src/init.h 2006-08-18 14:45:28.000000000 +0200
|
||||
@@ -30,12 +30,6 @@
|
||||
/* Prototypes. */
|
||||
void write_utmp_wtmp(char *user, char *id, int pid, int type, char *line);
|
||||
void write_wtmp(char *user, char *id, int pid, int type, char *line);
|
||||
-#ifdef __GNUC__
|
||||
-__attribute__ ((format (printf, 2, 3)))
|
||||
-#endif
|
||||
-void initlog(int loglevel, char *fmt, ...);
|
||||
-void set_term(int how);
|
||||
-void print(char *fmt);
|
||||
|
||||
#if DEBUG
|
||||
# define INITDBG(level, fmt, args...) initlog(level, fmt, ##args)
|
||||
--- src/shutdown.c
|
||||
+++ src/shutdown.c 2006-08-18 14:45:28.000000000 +0200
|
||||
@@ -60,6 +60,7 @@ char *clean_env[] = {
|
||||
"HOME=/",
|
||||
"PATH=/bin:/usr/bin:/sbin:/usr/sbin",
|
||||
"TERM=dumb",
|
||||
+ "SHELL=/bin/sh",
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -159,11 +160,24 @@ int init_setenv(char *name, char *value)
|
||||
sigaction(SIGALRM, &sa, NULL);
|
||||
got_alrm = 0;
|
||||
alarm(3);
|
||||
- if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0 &&
|
||||
- write(fd, &request, sizeof(request)) == sizeof(request)) {
|
||||
- close(fd);
|
||||
- alarm(0);
|
||||
- return 0;
|
||||
+ if ((fd = open(INIT_FIFO, O_WRONLY)) >= 0) {
|
||||
+ ssize_t p = 0;
|
||||
+ size_t s = sizeof(request);
|
||||
+ void *ptr = &request;
|
||||
+
|
||||
+ while (s > 0) {
|
||||
+ p = write(fd, ptr, s);
|
||||
+ if (p < 0) {
|
||||
+ if (errno == EINTR || errno == EAGAIN)
|
||||
+ continue;
|
||||
+ break;
|
||||
+ }
|
||||
+ ptr += p;
|
||||
+ s -= p;
|
||||
+ }
|
||||
+ close(fd);
|
||||
+ alarm(0);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "shutdown: ");
|
||||
--- src/utmp.c
|
||||
+++ src/utmp.c 2006-08-18 14:45:28.000000000 +0200
|
||||
@@ -47,6 +47,9 @@ char *line) /* Which line is this */
|
||||
int fd;
|
||||
struct utmp utmp;
|
||||
struct utsname uname_buf;
|
||||
+#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
|
||||
+ struct timeval tv;
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Can't do much if WTMP_FILE is not present or not writable.
|
||||
@@ -99,7 +102,13 @@ char *line) /* Which line is this */
|
||||
*/
|
||||
memset(&utmp, 0, sizeof(utmp));
|
||||
#if defined(__GLIBC__)
|
||||
+# if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
|
||||
+ gettimeofday(&tv, NULL);
|
||||
+ utmp.ut_tv.tv_sec = (int32_t)tv.tv_sec;
|
||||
+ utmp.ut_tv.tv_usec = (int32_t)tv.tv_usec;
|
||||
+# else
|
||||
gettimeofday(&utmp.ut_tv, NULL);
|
||||
+# endif
|
||||
#else
|
||||
time(&utmp.ut_time);
|
||||
#endif
|
||||
@@ -136,6 +145,9 @@ char *oldline) /* Line of old utmp ent
|
||||
struct utmp utmp;
|
||||
struct utmp tmp;
|
||||
struct utmp *utmptr;
|
||||
+#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
|
||||
+ struct timeval tv;
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Can't do much if UTMP_FILE is not present or not writable.
|
||||
@@ -184,7 +196,13 @@ char *oldline) /* Line of old utmp ent
|
||||
utmp.ut_pid = pid;
|
||||
strncpy(utmp.ut_id, id, sizeof(utmp.ut_id));
|
||||
#if defined(__GLIBC__)
|
||||
+# if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32
|
||||
+ gettimeofday(&tv, NULL);
|
||||
+ utmp.ut_tv.tv_sec = (int32_t)tv.tv_sec;
|
||||
+ utmp.ut_tv.tv_usec = (int32_t)tv.tv_usec;
|
||||
+# else
|
||||
gettimeofday(&utmp.ut_tv, NULL);
|
||||
+# endif
|
||||
#else
|
||||
time(&utmp.ut_time);
|
||||
#endif
|
||||
--- doc/utmpdump.1
|
||||
+++ doc/utmpdump.1 2010-02-08 13:41:51.154825000 +0000
|
||||
@@ -0,0 +1,47 @@
|
||||
+.TH UTMPDUMP 1 "Februar 8, 2010" "" "Linux System Administrator's Manual"
|
||||
+.SH NAME
|
||||
+utmpdump \- dump UTMP and WTMP files in raw format
|
||||
+.SH SYNOPSIS
|
||||
+.B utmpdump
|
||||
+.RB [ \-froh ]
|
||||
+.I filename
|
||||
+.SH DESCRIPTION
|
||||
+\fButmpdump\fP is a simple program to dump UTMP and WTMP files
|
||||
+in raw format, so they can be examined.
|
||||
+.SH OPTIONS
|
||||
+.IP \fB\-f\fP
|
||||
+output appended data as the file grows.
|
||||
+.IP "\fB\-r\fP"
|
||||
+reverse. Write back edited login information into utmp or wtmp files.
|
||||
+.IP \fB\-o\fP
|
||||
+use old libc5 format.
|
||||
+.IP \fB\-h\fP
|
||||
+usage information.
|
||||
+.PP
|
||||
+utmpdump can be useful in cases of corrupted utmp or wtmp entries.
|
||||
+It can dump out utmp/wtmp to an ASCII file, then that file can
|
||||
+be edited to remove bogus entries and reintegrated, using
|
||||
+.PP
|
||||
+.sp 1
|
||||
+.in +1c
|
||||
+.nf
|
||||
+\fButmpdump -r < ascii file > wtmp\fP
|
||||
+.fi
|
||||
+.in -1c
|
||||
+.sp 1
|
||||
+but be warned as
|
||||
+.B utmpdump
|
||||
+was written for debugging purpose only.
|
||||
+.SH BUGS
|
||||
+You may
|
||||
+.B not
|
||||
+use the option \fB\-r\fP as the format for the
|
||||
+utmp/wtmp files strongly depends on the
|
||||
+input format. This tool is
|
||||
+.B not
|
||||
+supported, use it at your own risk only.
|
||||
+.SH "SEE ALSO"
|
||||
+.BR last (1),
|
||||
+.BR w (1),
|
||||
+.BR who (1),
|
||||
+.BR utmp (5),
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2e2357e6449737b0ca2fe2d727b709e722dda8d64428e1266ad7da28d25ddc2b
|
||||
size 84163
|
76
sysvinit-2.88dsf-no-kill.patch
Normal file
76
sysvinit-2.88dsf-no-kill.patch
Normal file
@ -0,0 +1,76 @@
|
||||
--- src/killall5.c
|
||||
+++ src/killall5.c 2010-03-19 14:29:44.000000000 +0000
|
||||
@@ -444,6 +444,38 @@ int readarg(FILE *fp, char *buf, int sz)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Scan the filedescriptors of pid for /dev/fuse
|
||||
+ */
|
||||
+int is_fuse(const char *pid) {
|
||||
+ DIR *dir;
|
||||
+ char path[256];
|
||||
+ char buf[256];
|
||||
+ struct dirent *d;
|
||||
+ ssize_t len;
|
||||
+
|
||||
+ /* Open /proc/pid/fd/ */
|
||||
+ snprintf(path, sizeof(path), "/proc/%s/fd", pid);
|
||||
+ if ((dir = opendir(path)) != NULL) {
|
||||
+ int dfd = dirfd(dir);
|
||||
+ /* Walk through the directory. */
|
||||
+ while ((d = readdir(dir)) != NULL) {
|
||||
+ if (*d->d_name == '.')
|
||||
+ continue;
|
||||
+ /* check for /dev/fuse */
|
||||
+ if ((len = readlinkat(dfd, d->d_name, buf, sizeof(buf))) > 0) {
|
||||
+ buf[len] = '\0';
|
||||
+ if (strcmp("/dev/fuse", buf) == 0)
|
||||
+ return 1; /* Fuse filesystem */
|
||||
+ }
|
||||
+ }
|
||||
+ closedir(dir);
|
||||
+ }
|
||||
+
|
||||
+ /* Not a fuse filesystem */
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Read the proc filesystem.
|
||||
* CWD must be /proc to avoid problems if / is affected by the killing (ie depend on fuse).
|
||||
*/
|
||||
@@ -458,6 +490,7 @@ int readproc(int do_stat)
|
||||
char buf[PATH_MAX+1];
|
||||
char *s, *q;
|
||||
unsigned long startcode, endcode;
|
||||
+ ssize_t len;
|
||||
int pid, f;
|
||||
|
||||
/* Open the /proc directory. */
|
||||
@@ -608,6 +641,26 @@ int readproc(int do_stat)
|
||||
p->nfs = 0;
|
||||
|
||||
switch (do_stat) {
|
||||
+ case NO_STAT:
|
||||
+ if ((len = readlink(path, buf, PATH_MAX)) < 0)
|
||||
+ break;
|
||||
+ buf[len] = '\0';
|
||||
+
|
||||
+ /* Check for uevent handler, mdmon, and for providers
|
||||
+ of FUSE filesystems */
|
||||
+ if ((strncmp(buf, "/sbin/udevd", 11) == 0) ||
|
||||
+ (strncmp(buf, "/sbin/mdmon", 11) == 0) ||
|
||||
+ (is_fuse(d->d_name))) {
|
||||
+ OMIT *restrict optr;
|
||||
+
|
||||
+ xmemalign((void*)&optr, sizeof(void*), alignof(OMIT));
|
||||
+ optr->next = omit;
|
||||
+ optr->prev = (OMIT*)0;
|
||||
+ optr->pid = pid;
|
||||
+ omit = optr;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
case DO_NETFS:
|
||||
if ((p->nfs = check4nfs(path, buf)))
|
||||
break;
|
@ -1,6 +1,15 @@
|
||||
--- man/init.8
|
||||
+++ man/init.8 Fri Mar 12 12:26:35 2004
|
||||
@@ -272,6 +272,7 @@
|
||||
+++ man/init.8 2010-03-19 14:44:16.000000000 +0000
|
||||
@@ -261,7 +261,7 @@ It activates the \fIkbrequest\fP action.
|
||||
.SH CONFORMING TO
|
||||
\fBInit\fP is compatible with the System V init. It works closely
|
||||
together with the scripts in the directories
|
||||
-\fI/etc/init.d\fP and \fI/etc/rc{runlevel}.d\fP.
|
||||
+\fI/etc/init.d\fP and \fI/etc/init.d/rc{runlevel}.d\fP.
|
||||
If your system uses this convention, there should be a \fIREADME\fP
|
||||
file in the directory \fI/etc/init.d\fP explaining how these scripts work.
|
||||
.\"}}}
|
||||
@@ -301,6 +301,7 @@ page by Michael Haardt (u31b3hs@pool.inf
|
||||
.\"}}}
|
||||
.\"{{{ See also
|
||||
.SH "SEE ALSO"
|
||||
@ -9,8 +18,8 @@
|
||||
.BR login (1),
|
||||
.BR sh (1),
|
||||
--- man/inittab.5
|
||||
+++ man/inittab.5 Fri Mar 12 12:33:05 2004
|
||||
@@ -180,7 +180,7 @@
|
||||
+++ man/inittab.5 2004-03-12 12:33:05.000000000 +0000
|
||||
@@ -197,7 +197,7 @@ rc::bootwait:/etc/rc
|
||||
.fi
|
||||
.sp
|
||||
.RE
|
||||
@ -19,7 +28,7 @@
|
||||
on tty1\-tty4.
|
||||
.PP
|
||||
A more elaborate \fBinittab\fP with different runlevels (see the comments
|
||||
@@ -188,23 +188,20 @@
|
||||
@@ -205,23 +205,20 @@ inside):
|
||||
.RS
|
||||
.sp
|
||||
.nf
|
||||
@ -52,7 +61,7 @@
|
||||
|
||||
l0:0:wait:/etc/init.d/rc 0
|
||||
l1:1:wait:/etc/init.d/rc 1
|
||||
@@ -214,17 +211,27 @@
|
||||
@@ -231,17 +228,27 @@ l4:4:wait:/etc/init.d/rc 4
|
||||
l5:5:wait:/etc/init.d/rc 5
|
||||
l6:6:wait:/etc/init.d/rc 6
|
||||
|
||||
@ -89,7 +98,7 @@
|
||||
|
||||
.fi
|
||||
.sp
|
||||
@@ -244,5 +251,8 @@
|
||||
@@ -261,5 +268,8 @@ by Michael Haardt (u31b3hs@pool.informat
|
||||
.\"{{{ See also
|
||||
.SH "SEE ALSO"
|
||||
.BR init (8),
|
||||
@ -100,32 +109,34 @@
|
||||
+.BR mgetty (8)
|
||||
.\"}}}
|
||||
--- man/killall5.8
|
||||
+++ man/killall5.8 Fri Mar 12 12:26:35 2004
|
||||
@@ -13,5 +13,6 @@
|
||||
+++ man/killall5.8 2010-03-19 14:43:25.000000000 +0000
|
||||
@@ -44,6 +44,7 @@ process were killed, and 1 if it was una
|
||||
.SH SEE ALSO
|
||||
.BR halt (8),
|
||||
.BR reboot (8)
|
||||
.BR reboot (8),
|
||||
-.BR pidof (8)
|
||||
+.BR pidof (8),
|
||||
+.BR killproc (8)
|
||||
.SH AUTHOR
|
||||
Miquel van Smoorenburg, miquels@cistron.nl
|
||||
--- man/pidof.8
|
||||
+++ man/pidof.8 Fri Mar 12 12:26:35 2004
|
||||
@@ -40,6 +40,7 @@
|
||||
that it returns pids of running programs that happen to have the same name
|
||||
as the program you're after but are actually other programs.
|
||||
+++ man/pidof.8 2004-03-12 12:26:35.000000000 +0000
|
||||
@@ -83,6 +83,7 @@ that the executable name of running proc
|
||||
so symbolic links to executables will also match.
|
||||
|
||||
.SH SEE ALSO
|
||||
+.BR pidofproc (8),
|
||||
.BR shutdown (8),
|
||||
.BR init (8),
|
||||
.BR halt (8),
|
||||
--- man/sulogin.8
|
||||
+++ man/sulogin.8 Fri Mar 12 12:26:35 2004
|
||||
@@ -16,7 +16,7 @@
|
||||
+++ man/sulogin.8 2004-03-12 12:26:35.000000000 +0000
|
||||
@@ -35,7 +35,7 @@ passes it the \fB\-b\fP option.
|
||||
.PP
|
||||
The user is prompted
|
||||
.IP "" .5i
|
||||
-Give root password for system maintenance
|
||||
+Give root password for system login
|
||||
.br
|
||||
(or type Control-D for normal startup):
|
||||
(or type Control\-D for normal startup):
|
||||
.PP
|
52
sysvinit-2.88dsf.dif
Normal file
52
sysvinit-2.88dsf.dif
Normal file
@ -0,0 +1,52 @@
|
||||
--- src/Makefile
|
||||
+++ src/Makefile 2010-03-23 15:11:12.000000000 +0000
|
||||
@@ -9,16 +9,16 @@
|
||||
#
|
||||
|
||||
CPPFLAGS = -DUSE_PAM
|
||||
-CFLAGS ?= -ansi -O2 -fomit-frame-pointer
|
||||
+CFLAGS ?= $(RPM_OPT_FLAGS)
|
||||
override CFLAGS += -W -Wall -D_GNU_SOURCE
|
||||
STATIC =
|
||||
|
||||
# For some known distributions we do not build all programs, otherwise we do.
|
||||
BIN =
|
||||
SBIN = init halt shutdown runlevel killall5 fstab-decode
|
||||
-USRBIN = last mesg
|
||||
+USRBIN = last
|
||||
|
||||
-MAN1 = last.1 lastb.1 mesg.1
|
||||
+MAN1 = last.1 lastb.1
|
||||
MAN5 = initscript.5 inittab.5
|
||||
MAN8 = halt.8 init.8 killall5.8 pidof.8 poweroff.8 reboot.8 runlevel.8
|
||||
MAN8 += shutdown.8 telinit.8 fstab-decode.8
|
||||
@@ -170,7 +170,8 @@ endif
|
||||
ln -sf halt $(ROOT)/sbin/reboot
|
||||
ln -sf halt $(ROOT)/sbin/poweroff
|
||||
ln -sf init $(ROOT)/sbin/telinit
|
||||
- ln -sf /sbin/killall5 $(ROOT)/bin/pidof
|
||||
+ ln -sf killall5 $(ROOT)/sbin/pidof
|
||||
+ ln -sf ../sbin/killall5 $(ROOT)/bin/pidof
|
||||
if [ ! -f $(ROOT)/usr/bin/lastb ]; then \
|
||||
ln -sf last $(ROOT)/usr/bin/lastb; \
|
||||
fi
|
||||
--- src/bootlogd.c
|
||||
+++ src/bootlogd.c 2006-08-18 12:45:28.000000000 +0000
|
||||
@@ -241,7 +241,7 @@ int isconsole(char *s, char *res, int rl
|
||||
int consolename(char *res, int rlen)
|
||||
{
|
||||
#ifdef TIOCGDEV
|
||||
- unsigned int kdev;
|
||||
+ kdev_t kdev;
|
||||
#endif
|
||||
struct stat st, st2;
|
||||
char buf[256];
|
||||
@@ -555,7 +555,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
(void)ioctl(0, TIOCCONS, NULL);
|
||||
-#if 1
|
||||
+#if 0
|
||||
/* Work around bug in 2.1/2.2 kernels. Fixed in 2.2.13 and 2.3.18 */
|
||||
if ((n = open("/dev/tty0", O_RDWR)) >= 0) {
|
||||
(void)ioctl(n, TIOCCONS, NULL);
|
3
sysvinit-2.88dsf.tar.bz2
Normal file
3
sysvinit-2.88dsf.tar.bz2
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:60bbc8c1e1792056e23761d22960b30bb13eccc2cabff8c7310a01f4d5df1519
|
||||
size 105551
|
40
sysvinit-last-ipv6-heuristic.patch
Normal file
40
sysvinit-last-ipv6-heuristic.patch
Normal file
@ -0,0 +1,40 @@
|
||||
diff --git a/trunk/src/last.c b/trunk/src/last.c
|
||||
index 5003c7c..02103e0 100644
|
||||
--- a/trunk/src/last.c
|
||||
+++ b/trunk/src/last.c
|
||||
@@ -318,30 +318,22 @@ int dns_lookup(char *result, int size, int useip, int32_t *a)
|
||||
struct sockaddr_in6 sin6;
|
||||
struct sockaddr *sa;
|
||||
int salen, flags;
|
||||
- unsigned int topnibble;
|
||||
- unsigned int azero = 0, sitelocal = 0;
|
||||
int mapped = 0;
|
||||
|
||||
flags = useip ? NI_NUMERICHOST : 0;
|
||||
|
||||
/*
|
||||
- * IPv4 or IPv6 ? We use 2 heuristics:
|
||||
- * 1. Current IPv6 range uses 2000-3fff or fec0-feff.
|
||||
- * Outside of that is illegal and must be IPv4.
|
||||
- * 2. If last 3 bytes are 0, must be IPv4
|
||||
- * 3. If IPv6 in IPv4, handle as IPv4
|
||||
+ * IPv4 or IPv6 ?
|
||||
+ * 1. If last 3 4bytes are 0, must be IPv4
|
||||
+ * 2. If IPv6 in IPv4, handle as IPv4
|
||||
+ * 3. Anything else is IPv6
|
||||
*
|
||||
* Ugly.
|
||||
*/
|
||||
if (a[0] == 0 && a[1] == 0 && a[2] == (int32_t)htonl (0xffff))
|
||||
mapped = 1;
|
||||
- topnibble = ntohl((unsigned int)a[0]) >> 28;
|
||||
|
||||
- azero = ntohl((unsigned int)a[0]) >> 16;
|
||||
- sitelocal = (azero >= 0xfec0 && azero <= 0xfeff) ? 1 : 0;
|
||||
-
|
||||
- if (((topnibble < 2 || topnibble > 3) && (!sitelocal)) || mapped ||
|
||||
- (a[1] == 0 && a[2] == 0 && a[3] == 0)) {
|
||||
+ if (mapped || (a[1] == 0 && a[2] == 0 && a[3] == 0)) {
|
||||
/* IPv4 */
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = 0;
|
160
sysvinit.changes
160
sysvinit.changes
@ -1,3 +1,8 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Apr 13 18:27:02 CEST 2010 - werner@suse.de
|
||||
|
||||
- Add patch to make last(1) knowing latest IPv6 specs
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Apr 12 17:49:46 CEST 2010 - werner@suse.de
|
||||
|
||||
@ -7,12 +12,167 @@ Mon Apr 12 17:49:46 CEST 2010 - werner@suse.de
|
||||
Fri Apr 9 15:45:51 CEST 2010 - werner@suse.de
|
||||
|
||||
- Correct Pre-Requires to reflect package split
|
||||
- Update to sysvinit (2.88dsf) world; urgency=low
|
||||
|
||||
* Mention new home on Savannah in README.
|
||||
* Revert change from Fedora/RedHat where the now obsolete command
|
||||
INIT_CMD_CHANGECONS was introduced. Based on feedback and patch
|
||||
from Bill Nottingham.
|
||||
* Adjust makefile to make sure the install directories are created
|
||||
before files are copied into them.
|
||||
* Simplify build rules, based on patch from Mike Frysinger and Gentoo.
|
||||
* Fix minor bug in optimizing of argument parsing. Based on
|
||||
report from jakemus on freshmeat.
|
||||
* Add casts to get rid of compiler warning about signed/unsigned issues.
|
||||
* Change tty handling in init to make sure the UTF-8 flag is not cleared
|
||||
on boot. Patch from Samuel Thibault.
|
||||
* Add Makefile in toplevel directory.
|
||||
* Print usage information when shutdown is used by non-root user.
|
||||
Patch from Mike Frysinger and Gentoo.
|
||||
* Sync shutdown manual page and usage information. Patch from Mike
|
||||
Frysinger and Gentoo.
|
||||
* Fix race condition in utmp writing. Patch from Gil Kloepfer via
|
||||
Mike Frysinger and Gentoo.
|
||||
* Rewrite findtty() in bootlogd to recursively search /dev/ for the
|
||||
correct device, to handle terminal devices for example in /dev/pty/.
|
||||
Patch from Debian.
|
||||
* Make sure bootlogd findpty() returns an error value when it fails to
|
||||
find a usable pty. Patch from Rob Leslie via Debian.
|
||||
* Make sure bootlogd fflush() every line, even if asked not to flush
|
||||
to disk using fdatasync(). Patch from Scott Gifford via Debian.
|
||||
* Add compatibility code to handle old path "/etc/powerstatus" for a
|
||||
while.
|
||||
* Incude definition for MNT_DETACH which is missing in older GNU libc
|
||||
headers.
|
||||
* Do not strip binaries before installing them, to make it easier to
|
||||
get binaries with debug information installed.
|
||||
* Add the comment from Andrea Arcangeli about the correct
|
||||
place of setting the default childhandler within spawn().
|
||||
* Make sure that newline is printed out for last(1) even
|
||||
if an utmp record entry is truncated.
|
||||
* Check if utmp not only exists but also is writable and delay
|
||||
writing out of the utmp runlevel record if utmp is not writable.
|
||||
* Be able to find libcrypt also on 64 bit based architectures.
|
||||
* Add option -w to the last command to display the full user and
|
||||
domain names in the output. Patch from Petr Lautrbach.
|
||||
* Add a manual page for utmpdump as this tool is sometimes
|
||||
very useful even if not intended for normal use.
|
||||
* Use paths.h macros for wall
|
||||
* Change path "/etc/powerstatus" to "/var/run/powerstatus"
|
||||
* Detected also removable block devices at halt/reboot to be able
|
||||
to flush data and send them the ATA standby command. This should
|
||||
avoid data loss on USB sticks and other removable block devices.
|
||||
* Flush block devices on halt/reboot if not done by the kernel.
|
||||
* Set SHELL to /bin/sh in the environmant of shutdown.
|
||||
* Retry to write out shutdown messages if interrupted.
|
||||
* pidof/killall5 - make omit pid list a dynamic one.
|
||||
* pidof - provide '-n' to skip stat(2) syscall on network based FS.
|
||||
* init - avoid compiler warnings
|
||||
* init - initialize console by using the macros from ttydefaults.h
|
||||
* init - add the possiblity to ignore further interrupts from keyboard
|
||||
* init - add the possiblity to set sane terminal line settings
|
||||
* sulogin - add the possibility to reset the terminal io
|
||||
* Fix some minor problems
|
||||
* init - enable is_selinux_enabled() to detect selinuxfs
|
||||
* Add fix for Debian bug #536574 -- Can be enabled by -DACCTON_OFF
|
||||
* Add helper program fstab-decode to make it easier to handle
|
||||
/etc/mtab content. Patch by Miloslav Trmac and Fedora.
|
||||
* Add fix for Debian bug #335023 - Make sure TERM is set on FreeBSD.
|
||||
* Add fix for Debian bug #374038 - Make it clear that shutdown -c can
|
||||
only cancel a waiting shutdown, not an active one.
|
||||
* Add note to pidof manual page about the use of readlink(2). Patch by
|
||||
Bill Nottingham and Fedora.
|
||||
* Add PAM patch contrib/notify-pam-dead.patch based on Debian bug
|
||||
#68621, which will add PAM support for programs spawned by init on
|
||||
the console like sulogin. Based on patch by Topi Miettinen. This
|
||||
patch is not applied by default yet while we review its
|
||||
usefullness. It is only helpful for session handling, as sulogin
|
||||
do not use and will not use a PAM conv() function. The current
|
||||
sulogin is able to handle DES as well as MD5, SHA, and Blowfish
|
||||
encrypted passwords due using getpwnam(3).
|
||||
* Move utmp/wtmp before the execvp() in spawn() to be sure to
|
||||
use the correct pid even on a controlling tty
|
||||
* Remaining problem is that the pid of the second fork() for
|
||||
getting a controlling tty isn't that reported by spawn()
|
||||
* Re-enable writting utmp/wtmp for boot scripts
|
||||
* Extend sulogin to support additional encryption algorithms
|
||||
* Re-enable maintenance message of sulogin
|
||||
* Enable the sulogin fallback password check to handle MD5, SHA, and
|
||||
Blowfish encrypted passwords in case of getpwnam(3) fails.
|
||||
* sulogin picking the SELinux context was broken. Patch by Daniel Walsh
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Apr 9 14:30:08 CEST 2010 - werner@suse.de
|
||||
|
||||
- Start the service sshd as early as possible (bnc#594223)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Mar 23 17:21:06 CET 2010 - werner@suse.de
|
||||
|
||||
- Test out sysvinit (2.88dsf) UNRELEASED; urgency=low
|
||||
- Update to sysvinit (2.87dsf) world; urgency=low
|
||||
|
||||
* Document -e and -t options for telinit in init(8).
|
||||
* Document in halt(8) that -n might not disable all syncing.
|
||||
Patch by Bill Nottingham and Fedora
|
||||
* Adjust output from "last -x". In reboot lines, print endpoint
|
||||
of uptime too. In shutdown lines print downtimes rather than
|
||||
the time between downs. Fix typo in string compare in last.c.
|
||||
Patch by Thomas Hood.
|
||||
* Improve handling of IPv6 addresses in last. Patch from Fedora.
|
||||
* Add new option -F to last, to output full date string instead
|
||||
of the short form provided by default. Patch from Olaf Dabrunz
|
||||
and SuSe.
|
||||
* Fix utmp/wtmp updating on 64-bit platforms. Patch by Bill
|
||||
Nottingham and Fedora.
|
||||
* Avoid unchecked return value from malloc() in utmpdump.
|
||||
Patch from Christian 'Dr. Disk' Hechelmann and Fedora.
|
||||
* Make sure to use execle and no execl when passing environment to
|
||||
the new process. Patch from RedHat.
|
||||
* Correct init to make sure the waiting status is preserved across
|
||||
re-exec. Patch from RedHat.
|
||||
* Correct init to avoid race condition when starting programs during
|
||||
boot. Patch from SuSe.
|
||||
* Allow 'telinit u' in runlevels 0 and 6. Patch from Thomas Hood.
|
||||
* Improve error message from init if fork() fail. Patch found in Suse.
|
||||
* Add support for SE Linux capability handling. Patch from Manoj
|
||||
Srivastava, adjusted to avoid aborting if SE policy was loaded in
|
||||
the initrd with patch from Bill Nottingham and Fedora.
|
||||
* Add -c option to pidof for only matching processes with the same
|
||||
process root. Ignore -c when not running as root. Patch from
|
||||
Thomas Woerner and Fedora.
|
||||
* Add usleep in killall5 after killing processes, to force the kernel
|
||||
to reschedule. Patch from SuSe.
|
||||
* Modify pidof to not print empty line if no pid was found.
|
||||
* Modify init and sulogin to fix emergency mode's tty, making sure ^C
|
||||
and ^Z work when booting with 'emergency' kernel option. Patch from
|
||||
Samuel Thibault.
|
||||
* Modify init to allow some time for failed opens to resolve themselves.
|
||||
Patch from Bill Nottingham and Fedora.
|
||||
* Modify init to shut down IDE, SCSI and SATA disks properly. Patches
|
||||
from Sebastian Reichelt, Werner Fink and SuSe.
|
||||
* Modify wall to use UT_LINESIZE from <utmp.h> instead of hardcoded
|
||||
string lengths. Patch from SuSe.
|
||||
* Change wall to make halt include hostname in output.
|
||||
* Change killall to avoid killing init by mistake. Patch from SuSe.
|
||||
* Change killall5 to use the exit value to report if it found any
|
||||
processes to kill. Patch from Debian.
|
||||
* Add option -o opmitpid to killall5, to make it possible to skip
|
||||
some pids during shutdown. Based on patch from Colin Watson and
|
||||
Ubuntu.
|
||||
* Modify killall to work better with user space file system, by
|
||||
changing cwd to /proc when stopping and killing processes, and
|
||||
avoiding stat() when the value isn't used. Also, lock process
|
||||
pages in memory to avoid paging when user processes are stopped.
|
||||
Patch from Debian and Goswin von Brederlow with changes by Kel
|
||||
Modderman.
|
||||
* Change shutdown to only accept flags -H and -P with the -h flag,
|
||||
and document this requirement in the manual page.
|
||||
* Change reboot/halt to work properly when used as a login shell.
|
||||
Patch by Dale R. Worley and Fedora.
|
||||
* Let sulogin fall back to the staticly linked /bin/sash if both roots
|
||||
shell and /bin/sh fail to execute.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Mar 3 13:22:11 UTC 2010 - coolo@novell.com
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# spec file for package sysvinit (Version 2.86)
|
||||
# spec file for package sysvinit (Version 2.88)
|
||||
#
|
||||
# Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
#
|
||||
@ -23,17 +23,17 @@ Name: sysvinit
|
||||
%define PDVER 2.0.2
|
||||
%define KPVER 2.16
|
||||
%define SCVER 1.10
|
||||
%define SIVER 2.86
|
||||
%define SIVER 2.88
|
||||
%define START 0.54
|
||||
License: GPLv2+
|
||||
Group: System/Base
|
||||
AutoReqProv: on
|
||||
Version: 2.86
|
||||
Release: 223
|
||||
Version: 2.88
|
||||
Release: 1
|
||||
Summary: SysV-Style init
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
BuildRequires: libselinux-devel libsepol-devel
|
||||
Source: sysvinit-2.86.tar.bz2
|
||||
BuildRequires: audit-devel libselinux-devel libsepol-devel pam-devel
|
||||
Source: http://download.savannah.gnu.org/releases/sysvinit/sysvinit-2.88dsf.tar.bz2
|
||||
Source2: killproc-2.16.tar.bz2
|
||||
Source3: powerd-2.0.2.tar.bz2
|
||||
Source4: showconsole-1.10.tar.bz2
|
||||
@ -43,26 +43,16 @@ Source7: sysvinit-rpmlintrc
|
||||
Source8: mkinitrd-boot.sh
|
||||
Source9: mkinitrd-kill1.sh
|
||||
Source10: mkinitrd-kill2.sh
|
||||
Patch: sysvinit-2.86.dif
|
||||
Patch1: sysvinit-2.86-nfs4pidof.patch
|
||||
Patch2: powerd-2.0.2.dif
|
||||
Patch3: killproc-2.16.dif
|
||||
Patch5: sysvinit-2.86-sulogin.patch
|
||||
Patch6: sysvinit-2.82-startstop.patch
|
||||
Patch7: sysvinit-2.85-suse.patch
|
||||
Patch8: sysvinit-2.85-paths.patch
|
||||
Patch9: sysvinit-2.86-utmp.patch
|
||||
Patch10: showconsole-1.10.dif
|
||||
Patch11: sysvinit-2.86-race.patch
|
||||
Patch12: sysvinit-2.86-lib64.patch
|
||||
Patch13: sysvinit-2.82-multiline.patch
|
||||
Patch14: startpar-0.54.dif
|
||||
Patch15: sysvinit-2.86-usage-message.patch
|
||||
Patch16: sysvinit-2.86-full-time.patch
|
||||
Patch17: sysvinit-2.86-hddown.patch
|
||||
Patch18: sysvinit-2.86-selinux.patch
|
||||
Patch19: sysvinit-2.86-fuse-no-kill.patch
|
||||
Patch20: sysvinit-2.86-mdmon-no-kill.patch
|
||||
Patch: sysvinit-2.88dsf.dif
|
||||
Patch1: sysvinit-2.82-startstop.patch
|
||||
Patch2: sysvinit-2.88dsf-suse.patch
|
||||
Patch3: sysvinit-2.88dsf-no-kill.patch
|
||||
Patch4: notify-pam-dead.patch
|
||||
Patch5: sysvinit-last-ipv6-heuristic.patch
|
||||
Patch20: powerd-2.0.2.dif
|
||||
Patch30: killproc-2.16.dif
|
||||
Patch40: showconsole-1.10.dif
|
||||
Patch50: startpar-0.54.dif
|
||||
Requires: sysvinit-tools
|
||||
Provides: sbin_init
|
||||
|
||||
@ -84,7 +74,7 @@ Group: System/Base
|
||||
Requires(preun): coreutils mkinitrd %insserv_prereq
|
||||
Requires(postun): coreutils mkinitrd %insserv_prereq
|
||||
%else
|
||||
PreReq: coreutils mkinitrd %insserv_prereq
|
||||
PreReq: coreutils mkinitrd %insserv_prereq
|
||||
%endif
|
||||
|
||||
%description tools
|
||||
@ -93,45 +83,34 @@ to startpar, killproc and pidof. System V init specific programs are in the
|
||||
sysvinit package.
|
||||
|
||||
%prep
|
||||
%setup -q -b 2 -b 3 -b 4 -b 5
|
||||
%patch -P 1 -b .nfs4pidof
|
||||
%patch -P 5 -b .sulogin
|
||||
%patch -P 6 -b .ststdmn
|
||||
%patch -P 7 -b .suse
|
||||
%patch -P 8 -b .paths
|
||||
%patch -P 9 -b .utmp
|
||||
%patch -P 11 -b .race
|
||||
%patch -P 12 -b .lib64
|
||||
%patch -P 13 -b .multiline
|
||||
%patch -P 15 -b .usage
|
||||
%patch -P 16 -b .fulltime
|
||||
%patch -P 17 -b .hddown
|
||||
%patch -P 18 -b .selinux
|
||||
%patch -P 19 -b .fuse
|
||||
%patch -P 20 -b .mdmon
|
||||
%setup -n sysvinit-%{SIVER}dsf -q -b 2 -b 3 -b 4 -b 5
|
||||
%patch1 -p0 -b .startstop
|
||||
%patch2 -p0 -b .suse
|
||||
%patch3 -p0 -b .no-kill
|
||||
%patch4 -p0 -b .pam
|
||||
%patch5 -p2 -b .ipv6
|
||||
%patch
|
||||
pushd ../powerd-%{PDVER}
|
||||
%patch -P 2
|
||||
%patch20
|
||||
popd
|
||||
pushd ../killproc-%{KPVER}
|
||||
%patch -P 3
|
||||
%patch30
|
||||
popd
|
||||
pushd ../showconsole-%{SCVER}
|
||||
%patch -P 10
|
||||
%patch40
|
||||
popd
|
||||
pushd ../startpar-%{START}
|
||||
%patch -P 14
|
||||
%patch50
|
||||
popd
|
||||
%_fixowner .
|
||||
%_fixgroup .
|
||||
/bin/chmod -Rf a+rX,g-w,o-w .
|
||||
|
||||
%build
|
||||
RPM_OPT_FLAGS="${RPM_OPT_FLAGS} -D_FILE_OFFSET_BITS=64"
|
||||
export RPM_OPT_FLAGS
|
||||
CFLAGS="-Wall ${RPM_OPT_FLAGS} -D_GNU_SOURCE -D__NO_STRING_INLINES -pipe"
|
||||
RPM_OPT_FLAGS="${RPM_OPT_FLAGS} -D_FILE_OFFSET_BITS=64 -pipe"
|
||||
CC=gcc
|
||||
make %{?jobs:-j%jobs} -C src CFLAGS="$CFLAGS" CC="$CC"
|
||||
export RPM_OPT_FLAGS CC
|
||||
make %{?_smp_mflags} WITH_SELINUX=yes DISTRO=SuSE
|
||||
pushd ../showconsole-%{SCVER}
|
||||
make %{?_smp_mflags}
|
||||
popd
|
||||
@ -143,7 +122,7 @@ pushd ../powerd-%{PDVER}
|
||||
./configure --prefix= --bindir='$(DESTDIR)/sbin' \
|
||||
--mandir='$(DESTDIR)%{_mandir}' \
|
||||
--sbindir='$(DESTDIR)/sbin'
|
||||
make %{?_smp_mflags} CFLAGS="-I../sysvinit-%{version}/src $CFLAGS"
|
||||
make %{?_smp_mflags} CFLAGS="-I../sysvinit-%{SIVER}dsf/src $RPM_OPT_FLAGS "
|
||||
%endif
|
||||
popd
|
||||
pushd ../startpar-%{START}
|
||||
@ -162,7 +141,7 @@ popd
|
||||
mkdir -m 755 -p ${RPM_BUILD_ROOT}%{_mandir}/man1
|
||||
mkdir -m 755 -p ${RPM_BUILD_ROOT}%{_mandir}/man5
|
||||
mkdir -m 755 -p ${RPM_BUILD_ROOT}%{_mandir}/man8
|
||||
make install -C src MANPATH=%{_mandir} ROOT=${RPM_BUILD_ROOT}
|
||||
make install -C src MANPATH=%{_mandir} ROOT=${RPM_BUILD_ROOT} WITH_SELINUX=yes DISTRO=SuSE
|
||||
test -p ${RPM_BUILD_ROOT}/dev/initctl || {
|
||||
rm -f ${RPM_BUILD_ROOT}/dev/initctl
|
||||
mknod ${RPM_BUILD_ROOT}/dev/initctl p
|
||||
@ -237,6 +216,7 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
|
||||
%files
|
||||
%defattr (-,root,root,755)
|
||||
%config /etc/pam.d/init
|
||||
/sbin/halt
|
||||
/sbin/init
|
||||
/sbin/poweroff
|
||||
@ -282,6 +262,7 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
# /sbin/intr
|
||||
/sbin/blogger
|
||||
/sbin/blogd
|
||||
/sbin/fstab-decode
|
||||
/sbin/showconsole
|
||||
/sbin/setconsole
|
||||
/sbin/isserial
|
||||
@ -304,16 +285,14 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
%doc %{_mandir}/man1/lastb.1.gz
|
||||
%doc %{_mandir}/man1/usleep.1.gz
|
||||
%doc %{_mandir}/man1/fsync.1.gz
|
||||
%ifnarch s390 s390x
|
||||
%doc %{_mandir}/man8/powerd.8.gz
|
||||
%doc %{_mandir}/man8/detectups.8.gz
|
||||
%endif
|
||||
# /usr/include/libblogger.h
|
||||
# /usr/lib/libblogger.a
|
||||
%doc %{_mandir}/man1/mountpoint.1.gz
|
||||
%doc %{_mandir}/man1/utmpdump.1.gz
|
||||
# %doc %{_mandir}/man8/bootlogd.8.gz
|
||||
%doc %{_mandir}/man8/blogger.8.gz
|
||||
%doc %{_mandir}/man8/blogd.8.gz
|
||||
%doc %{_mandir}/man8/fstab-decode.8.gz
|
||||
%doc %{_mandir}/man8/showconsole.8.gz
|
||||
%doc %{_mandir}/man8/setconsole.8.gz
|
||||
%doc %{_mandir}/man8/isserial.8.gz
|
||||
@ -323,6 +302,10 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
%doc %{_mandir}/man8/killall5.8.gz
|
||||
%doc %{_mandir}/man8/killproc.8.gz
|
||||
%doc %{_mandir}/man8/pidof.8.gz
|
||||
%ifnarch s390 s390x
|
||||
%doc %{_mandir}/man8/powerd.8.gz
|
||||
%doc %{_mandir}/man8/detectups.8.gz
|
||||
%endif
|
||||
%doc %{_mandir}/man8/startproc.8.gz
|
||||
%doc %{_mandir}/man8/start_daemon.8.gz
|
||||
%doc %{_mandir}/man8/startpar.8.gz
|
||||
|
Loading…
Reference in New Issue
Block a user