From 84e86ebbcd172033b97ffe43ff71a10a9c443815 Mon Sep 17 00:00:00 2001 From: Werner Fink Date: Fri, 11 Mar 2011 16:10:42 +0000 Subject: [PATCH] * Fix signal and alarm handling based on the patch from Florent Viard. (was local bug #32304) * Add fix for Redhat bug #573346: last incorrectly displays IPv6 addresses (was local bug #29497) --- doc/Changelog | 4 ++++ src/last.c | 18 +++++------------- src/sulogin.c | 36 ++++++++++++++++++++++++++++-------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index ef6cce4..9983501 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,10 @@ sysvinit (2.89dsf) UNRELEASED; urgency=low [ Werner Fink ] + * Fix signal and alarm handling based on the patch from Florent Viard. + (was local bug #32304) + * Add fix for Redhat bug #573346: last incorrectly displays IPv6 + addresses (was local bug #29497) * Correct fix for Debian bug #547073: use IUTF8 flag if defined and if already set to make sure the utf-8 flag is not cleared from the tty. Patch from Samuel Thibault. diff --git a/src/last.c b/src/last.c index 5003c7c..02103e0 100644 --- a/src/last.c +++ b/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; diff --git a/src/sulogin.c b/src/sulogin.c index cf69f2a..91cbe7c 100644 --- a/src/sulogin.c +++ b/src/sulogin.c @@ -68,6 +68,8 @@ static void (*saved_sigint) = SIG_DFL; static void (*saved_sigtstp) = SIG_DFL; static void (*saved_sigquit) = SIG_DFL; +static volatile sig_atomic_t alarm_rised; + #ifndef IUCLC # define IUCLC 0 #endif @@ -149,6 +151,14 @@ void alrm_handler(int sig __attribute__((unused))) void alrm_handler(int sig) # endif { + /* Timeout expired */ + alarm_rised++; + + signal(SIGINT, saved_sigint); + signal(SIGTSTP, saved_sigtstp); + signal(SIGQUIT, saved_sigquit); + + /* Never use exit(3) or stdio(3) within a signal handler */ } /* @@ -508,8 +518,8 @@ int main(int argc, char **argv) * See if we need to open an other tty device. */ saved_sigint = signal(SIGINT, SIG_IGN); - saved_sigtstp = signal(SIGQUIT, SIG_IGN); - saved_sigquit = signal(SIGTSTP, SIG_IGN); + saved_sigquit = signal(SIGQUIT, SIG_IGN); + saved_sigtstp = signal(SIGTSTP, SIG_IGN); if (optind < argc) tty = argv[optind]; if (tty || (tty = getenv("CONSOLE"))) { @@ -587,18 +597,28 @@ int main(int argc, char **argv) * Ask for the password. */ while(pwd) { + int failed = 0; if ((p = getpasswd(pwd->pw_passwd)) == NULL) break; if (pwd->pw_passwd[0] == 0 || - strcmp(crypt(p, pwd->pw_passwd), pwd->pw_passwd) == 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"); + failed++; + } + signal(SIGQUIT, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + signal(SIGINT, SIG_IGN); + if (failed) { + printf("Can not execute su shell.\n"); + break; + } else + printf("Login incorrect.\n"); } + if (alarm_rised) + printf("Timed out.\n"); + /* - * User pressed Control-D. + * User may pressed Control-D. */ return 0; }