* Fix signal and alarm handling based on the patch from Florent Viard.
authorDr. Werner Fink <werner@suse.de>
Fri, 11 Mar 2011 16:10:42 +0000 (16:10 +0000)
committerDr. Werner Fink <werner@suse.de>
Fri, 11 Mar 2011 16:10:42 +0000 (16:10 +0000)
  (was local bug #32304)
* Add fix for Redhat bug #573346: last incorrectly displays IPv6
  addresses (was local bug #29497)

git-svn-id: svn://svn.sv.gnu.org/sysvinit/sysvinit/trunk@98 456724a4-4300-0410-8514-c89748c515a2

doc/Changelog
src/last.c
src/sulogin.c

index ef6cce47cae3568a18e75869780a9f80fa615adb..9983501751bbaa6b0707108e7ae61a553d740061 100644 (file)
@@ -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.
index 5003c7c9b8bb9b2b30113bf789e83b791c1b8c0d..02103e03f7f9549ce23c1c9ef21b0ed8d8d36769 100644 (file)
@@ -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;
index cf69f2acfec82f306bd4ad9ca88fe18edeabbf52..91cbe7c9800b2d45529f71fe0568c25cc918c407 100644 (file)
@@ -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;
 }