checked in (request 38331)

OBS-URL: https://build.opensuse.org/package/show/Base:System/sysvinit?expand=0&rev=41
This commit is contained in:
OBS User autobuild 2010-04-25 16:42:18 +00:00 committed by Git OBS Bridge
parent 3afec739d5
commit a7646a3a3e
23 changed files with 3020 additions and 611 deletions

View File

@ -1,212 +0,0 @@
--- 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 */
+

View File

@ -0,0 +1,53 @@
--- 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");
}

26
sysvinit-2.85-paths.patch Normal file
View File

@ -0,0 +1,26 @@
--- 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 */

View File

@ -1,15 +1,6 @@
--- man/init.8
+++ 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
+++ man/init.8 Fri Mar 12 12:26:35 2004
@@ -272,6 +272,7 @@
.\"}}}
.\"{{{ See also
.SH "SEE ALSO"
@ -18,8 +9,8 @@
.BR login (1),
.BR sh (1),
--- man/inittab.5
+++ man/inittab.5 2004-03-12 12:33:05.000000000 +0000
@@ -197,7 +197,7 @@ rc::bootwait:/etc/rc
+++ man/inittab.5 Fri Mar 12 12:33:05 2004
@@ -180,7 +180,7 @@
.fi
.sp
.RE
@ -28,7 +19,7 @@
on tty1\-tty4.
.PP
A more elaborate \fBinittab\fP with different runlevels (see the comments
@@ -205,23 +205,20 @@ inside):
@@ -188,23 +188,20 @@
.RS
.sp
.nf
@ -61,7 +52,7 @@
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
@@ -231,17 +228,27 @@ l4:4:wait:/etc/init.d/rc 4
@@ -214,17 +211,27 @@
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
@ -98,7 +89,7 @@
.fi
.sp
@@ -261,5 +268,8 @@ by Michael Haardt (u31b3hs@pool.informat
@@ -244,5 +251,8 @@
.\"{{{ See also
.SH "SEE ALSO"
.BR init (8),
@ -109,34 +100,32 @@
+.BR mgetty (8)
.\"}}}
--- man/killall5.8
+++ man/killall5.8 2010-03-19 14:43:25.000000000 +0000
@@ -44,6 +44,7 @@ process were killed, and 1 if it was una
+++ man/killall5.8 Fri Mar 12 12:26:35 2004
@@ -13,5 +13,6 @@
.SH SEE ALSO
.BR halt (8),
.BR reboot (8),
-.BR pidof (8)
+.BR pidof (8),
.BR reboot (8)
+.BR killproc (8)
.SH AUTHOR
Miquel van Smoorenburg, miquels@cistron.nl
--- man/pidof.8
+++ 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.
+++ 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.
.SH SEE ALSO
+.BR pidofproc (8),
.BR shutdown (8),
.BR init (8),
.BR halt (8),
--- man/sulogin.8
+++ man/sulogin.8 2004-03-12 12:26:35.000000000 +0000
@@ -35,7 +35,7 @@ passes it the \fB\-b\fP option.
+++ man/sulogin.8 Fri Mar 12 12:26:35 2004
@@ -16,7 +16,7 @@
.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

View File

@ -0,0 +1,164 @@
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",

View File

@ -0,0 +1,90 @@
--- 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);
}

428
sysvinit-2.86-hddown.patch Normal file
View File

@ -0,0 +1,428 @@
--- 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

11
sysvinit-2.86-lib64.patch Normal file
View File

@ -0,0 +1,11 @@
--- 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

View File

@ -0,0 +1,40 @@
---
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;
}

View File

@ -0,0 +1,480 @@
--- 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);

33
sysvinit-2.86-race.patch Normal file
View File

@ -0,0 +1,33 @@
--- 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)

View File

@ -0,0 +1,93 @@
--- 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);

334
sysvinit-2.86-sulogin.patch Normal file
View File

@ -0,0 +1,334 @@
--- 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;
}
-

View File

@ -0,0 +1,18 @@
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);
}

203
sysvinit-2.86-utmp.patch Normal file
View File

@ -0,0 +1,203 @@
--- 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
/*

970
sysvinit-2.86.dif Normal file
View File

@ -0,0 +1,970 @@
--- .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),

3
sysvinit-2.86.tar.bz2 Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2e2357e6449737b0ca2fe2d727b709e722dda8d64428e1266ad7da28d25ddc2b
size 84163

View File

@ -1,76 +0,0 @@
--- 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;

View File

@ -1,52 +0,0 @@
--- 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);

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:60bbc8c1e1792056e23761d22960b30bb13eccc2cabff8c7310a01f4d5df1519
size 105551

View File

@ -1,40 +0,0 @@
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;

View File

@ -1,8 +1,3 @@
-------------------------------------------------------------------
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
@ -12,167 +7,12 @@ 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

View File

@ -1,5 +1,5 @@
#
# spec file for package sysvinit (Version 2.88)
# spec file for package sysvinit (Version 2.86)
#
# 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.88
%define SIVER 2.86
%define START 0.54
License: GPLv2+
Group: System/Base
AutoReqProv: on
Version: 2.88
Release: 1
Version: 2.86
Release: 223
Summary: SysV-Style init
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: audit-devel libselinux-devel libsepol-devel pam-devel
Source: http://download.savannah.gnu.org/releases/sysvinit/sysvinit-2.88dsf.tar.bz2
BuildRequires: libselinux-devel libsepol-devel
Source: sysvinit-2.86.tar.bz2
Source2: killproc-2.16.tar.bz2
Source3: powerd-2.0.2.tar.bz2
Source4: showconsole-1.10.tar.bz2
@ -43,16 +43,26 @@ Source7: sysvinit-rpmlintrc
Source8: mkinitrd-boot.sh
Source9: mkinitrd-kill1.sh
Source10: mkinitrd-kill2.sh
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
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
Requires: sysvinit-tools
Provides: sbin_init
@ -74,7 +84,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
@ -83,34 +93,45 @@ to startpar, killproc and pidof. System V init specific programs are in the
sysvinit package.
%prep
%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
%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
%patch
pushd ../powerd-%{PDVER}
%patch20
%patch -P 2
popd
pushd ../killproc-%{KPVER}
%patch30
%patch -P 3
popd
pushd ../showconsole-%{SCVER}
%patch40
%patch -P 10
popd
pushd ../startpar-%{START}
%patch50
%patch -P 14
popd
%_fixowner .
%_fixgroup .
/bin/chmod -Rf a+rX,g-w,o-w .
%build
RPM_OPT_FLAGS="${RPM_OPT_FLAGS} -D_FILE_OFFSET_BITS=64 -pipe"
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"
CC=gcc
export RPM_OPT_FLAGS CC
make %{?_smp_mflags} WITH_SELINUX=yes DISTRO=SuSE
make %{?jobs:-j%jobs} -C src CFLAGS="$CFLAGS" CC="$CC"
pushd ../showconsole-%{SCVER}
make %{?_smp_mflags}
popd
@ -122,7 +143,7 @@ pushd ../powerd-%{PDVER}
./configure --prefix= --bindir='$(DESTDIR)/sbin' \
--mandir='$(DESTDIR)%{_mandir}' \
--sbindir='$(DESTDIR)/sbin'
make %{?_smp_mflags} CFLAGS="-I../sysvinit-%{SIVER}dsf/src $RPM_OPT_FLAGS "
make %{?_smp_mflags} CFLAGS="-I../sysvinit-%{version}/src $CFLAGS"
%endif
popd
pushd ../startpar-%{START}
@ -141,7 +162,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} WITH_SELINUX=yes DISTRO=SuSE
make install -C src MANPATH=%{_mandir} ROOT=${RPM_BUILD_ROOT}
test -p ${RPM_BUILD_ROOT}/dev/initctl || {
rm -f ${RPM_BUILD_ROOT}/dev/initctl
mknod ${RPM_BUILD_ROOT}/dev/initctl p
@ -216,7 +237,6 @@ rm -rf ${RPM_BUILD_ROOT}
%files
%defattr (-,root,root,755)
%config /etc/pam.d/init
/sbin/halt
/sbin/init
/sbin/poweroff
@ -262,7 +282,6 @@ rm -rf ${RPM_BUILD_ROOT}
# /sbin/intr
/sbin/blogger
/sbin/blogd
/sbin/fstab-decode
/sbin/showconsole
/sbin/setconsole
/sbin/isserial
@ -285,14 +304,16 @@ 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
@ -302,10 +323,6 @@ 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