File sysvinit-2.86-sulogin.patch of Package sysvinit

--- 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;
 }
-
openSUSE Build Service is sponsored by