diff --git a/sysvinit-2.88dsf-multiple-sulogin.patch b/sysvinit-2.88dsf-multiple-sulogin.patch index 539a355..3cdae20 100644 --- a/sysvinit-2.88dsf-multiple-sulogin.patch +++ b/sysvinit-2.88dsf-multiple-sulogin.patch @@ -32,11 +32,11 @@ Index: src/sulogin.c +# define MNT_DETACH 2 +# endif +#endif - ++ +#define BS CTRL('h') +#define NL CTRL('j') +#define CR CTRL('m') -+ + #ifdef WITH_SELINUX # include # include @@ -48,7 +48,7 @@ Index: src/sulogin.c #define CHECK_DES 1 #define CHECK_MD5 1 -@@ -63,102 +86,218 @@ +@@ -63,102 +86,245 @@ char *Version = "@(#)sulogin 2.85-3 23-A static int timeout; static int profile; @@ -97,16 +97,12 @@ Index: src/sulogin.c + con->flags |= CON_NOTTY; + return; + } - -- /* Use defaults of 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); ++ + /* Handle serial lines here */ + if (ioctl (fd, TIOCMGET, (char*)&serial) == 0) { + speed_t ispeed, ospeed; - ++ struct winsize ws; ++ + /* this is a modem line */ + con->flags |= CON_SERIAL; + @@ -115,6 +111,9 @@ Index: src/sulogin.c + + ispeed = cfgetispeed(tio); + ospeed = cfgetospeed(tio); ++ ++ if (!ispeed) ispeed = TTYDEF_SPEED; ++ if (!ospeed) ospeed = TTYDEF_SPEED; + + tio->c_iflag = tio->c_lflag = tio->c_oflag = 0; + tio->c_cflag = CREAD | CS8 | HUPCL | (tio->c_cflag & CLOCAL); @@ -126,6 +125,24 @@ Index: src/sulogin.c + tio->c_cc[VTIME] = 0; + tio->c_cc[VMIN] = 1; + ++ if (ioctl(fd, TIOCGWINSZ, &ws) == 0) { ++ int set = 0; ++ if (ws.ws_row == 0) { ++ ws.ws_row = 24; ++ set++; ++ } ++ if (ws.ws_col == 0) { ++ ws.ws_col = 80; ++ set++; ++ } ++ (void)ioctl(fd, TIOCSWINSZ, &ws); ++ } + +- /* Use defaults of 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); + goto setattr; + } +#if defined(SANE_TIO) && (SANE_TIO == 1) @@ -136,8 +153,11 @@ Index: src/sulogin.c + tio->c_iflag |= TTYDEF_IFLAG; + tio->c_oflag |= TTYDEF_OFLAG; + tio->c_lflag |= TTYDEF_LFLAG; -+ tio->c_cflag |= (TTYDEF_SPEED | TTYDEF_CFLAG); -+ ++# ifdef CBAUD ++ tio->c_lflag &= ~CBAUD; ++# endif ++ tio->c_cflag |= (B38400 | TTYDEF_CFLAG); + /* Sane setting, allow eight bit characters, no carriage return delay * the same result as `stty sane cr0 pass8' */ @@ -146,7 +166,7 @@ Index: src/sulogin.c - tty.c_oflag |= (OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0); - tty.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |\ + tio->c_iflag |= (BRKINT | ICRNL | IMAXBEL); -+ tio->c_iflag &= ~(IGNBRK | INLCR | IGNCR | IXOFF | IUCLC | IXANY | ISTRIP); ++ tio->c_iflag &= ~(IGNBRK | INLCR | IGNCR | IXOFF | IUCLC | IXANY | INPCK | ISTRIP); + tio->c_oflag |= (OPOST | ONLCR | NL0 | CR0 | TAB0 | BS0 | VT0 | FF0); + tio->c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |\ NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); @@ -156,8 +176,8 @@ Index: src/sulogin.c - tty.c_cflag &= ~(PARENB); + tio->c_lflag |= (ISIG | ICANON | IEXTEN | ECHO|ECHOE|ECHOK|ECHOKE); + tio->c_lflag &= ~(ECHONL|ECHOCTL|ECHOPRT | NOFLSH | XCASE | TOSTOP); -+ tio->c_cflag |= (CREAD | CS8 | CLOCAL | HUPCL | B38400); -+ tio->c_cflag &= ~(PARENB); ++ tio->c_cflag |= (CREAD | CS8 | HUPCL); ++ tio->c_cflag &= ~(PARODD | PARENB); - /* VTIME and VMIN can overlap with VEOF and VEOL since they are + /* @@ -182,6 +202,10 @@ Index: src/sulogin.c - tty.c_cc[VWERASE] = CWERASE; - tty.c_cc[VLNEXT] = CLNEXT; - tty.c_cc[VEOL2] = _POSIX_VDISABLE; +- +- tcsetattr(0, TCSANOW, &tty); +-out: +- return; + tio->c_cc[VTIME] = 0; + tio->c_cc[VMIN] = CMIN; + tio->c_cc[VINTR] = CINTR; @@ -207,10 +231,7 @@ Index: src/sulogin.c +setattr: + /* Set line attributes */ + tcsetattr(fd, TCSANOW, tio); - -- tcsetattr(0, TCSANOW, &tty); --out: -- return; ++ + /* Enable blocking mode for read and write */ + if ((flags = fcntl(fd, F_GETFL, 0)) != -1) + (void)fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); @@ -241,19 +262,24 @@ Index: src/sulogin.c + if (con->flags & CON_NOTTY) + return; + setenv("TERM", "vt100", 1); - ++ ++ tio->c_iflag |= (IXON | IXOFF); ++ tio->c_lflag |= (ICANON | ISIG | ECHO|ECHOE|ECHOK|ECHOKE); + tio->c_oflag |= OPOST; - ++ + tio->c_cc[VINTR] = CINTR; + tio->c_cc[VQUIT] = CQUIT; + tio->c_cc[VERASE] = con->cp.erase; + tio->c_cc[VKILL] = con->cp.kill; + tio->c_cc[VEOF] = CEOF; -+# ifdef VSWTC ++#ifdef VSWTC + tio->c_cc[VSWTC] = _POSIX_VDISABLE; -+# else ++#else + tio->c_cc[VSWTCH] = _POSIX_VDISABLE; -+# endif ++#endif ++ tio->c_cc[VSTART] = CSTART; ++ tio->c_cc[VSTOP] = CSTOP; ++ tio->c_cc[VSUSP] = CSUSP; + tio->c_cc[VEOL] = _POSIX_VDISABLE; + + if (con->cp.eol == CR) { @@ -266,24 +292,26 @@ Index: src/sulogin.c + switch (con->cp.parity) { + default: + case 0: ++ tio->c_cflag &= ~(PARODD | PARENB); ++ tio->c_iflag &= ~(INPCK | ISTRIP); + break; + case 1: /* odd parity */ + tio->c_cflag |= PARODD; + /* fall through */ + case 2: /* even parity */ + tio->c_cflag |= PARENB; -+ tio->c_iflag |= INPCK | ISTRIP; ++ tio->c_iflag |= (INPCK | ISTRIP); + /* fall through */ + case (1 | 2): /* no parity bit */ + tio->c_cflag &= ~CSIZE; + tio->c_cflag |= CS7; + break; + } -+ + + /* Set line attributes */ + (void)tcsetattr(fd, TCSANOW, tio); +} -+ + /* * Called at timeout. */ @@ -319,7 +347,37 @@ Index: src/sulogin.c } /* -@@ -343,57 +482,200 @@ +@@ -305,7 +471,7 @@ struct passwd *getrootpwent(int try_manu + * or not found, return. + */ + if (p == NULL) { +- fprintf(stderr, "%s: no entry for root\n", F_PASSWD); ++ fprintf(stderr, "%s: no entry for root\n\r", F_PASSWD); + return &pwd; + } + if (valid(pwd.pw_passwd)) return &pwd; +@@ -316,7 +482,7 @@ struct passwd *getrootpwent(int try_manu + */ + strcpy(pwd.pw_passwd, ""); + if ((fp = fopen(F_SHADOW, "r")) == NULL) { +- fprintf(stderr, "%s: root password garbled\n", F_PASSWD); ++ fprintf(stderr, "%s: root password garbled\n\r", F_PASSWD); + return &pwd; + } + while((p = fgets(sline, 256, fp)) != NULL) { +@@ -333,67 +499,212 @@ struct passwd *getrootpwent(int try_manu + * NULL it, and return. + */ + if (p == NULL) { +- fprintf(stderr, "%s: no entry for root\n", F_SHADOW); ++ fprintf(stderr, "%s: no entry for root\n\r", F_SHADOW); + strcpy(pwd.pw_passwd, ""); + } + if (!valid(pwd.pw_passwd)) { +- fprintf(stderr, "%s: root password garbled\n", F_SHADOW); ++ fprintf(stderr, "%s: root password garbled\n\r", F_SHADOW); + strcpy(pwd.pw_passwd, ""); } + return &pwd; } /* @@ -361,7 +419,7 @@ Index: src/sulogin.c #else if (crypted[0]) - printf("Give root password for maintenance\n"); -+ fprintf(con->file, "Give root password for maintenance\n"); ++ fprintf(con->file, "Give root password for maintenance\n\r"); else - printf("Press enter for maintenance"); - printf("(or type Control-D to continue): "); @@ -377,6 +435,9 @@ Index: src/sulogin.c - tcgetattr(0, &old); - tcgetattr(0, &tty); +- tty.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); +- tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); +- tcsetattr(0, TCSANOW, &tty); +/* + * Make sure to have an own session and controlling terminal + */ @@ -405,7 +466,8 @@ Index: src/sulogin.c + setpgid(0, getpgid(getppid())); + setsid(); + } -+ + +- pass[sizeof(pass) - 1] = 0; + signal(SIGHUP, SIG_IGN); + if (ttypgrp > 0) + ioctl(0, TIOCNOTTY, (char *)1); @@ -453,14 +515,10 @@ Index: src/sulogin.c + cp = &con->cp; + + tty = con->tio; - tty.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); -- tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); -- tcsetattr(0, TCSANOW, &tty); ++ tty.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); + tty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP|ISIG); + tc = (tcsetattr(fd, TCSAFLUSH, &tty) == 0); -- pass[sizeof(pass) - 1] = 0; -- sa.sa_handler = alrm_handler; sa.sa_flags = 0; sigaction(SIGALRM, &sa, NULL); @@ -473,7 +531,7 @@ Index: src/sulogin.c - if (pass[i] == '\r' || pass[i] == '\n') { - pass[i] = 0; + ptr = &pass[0]; -+ cp->eol = '\0'; ++ cp->eol = *ptr = '\0'; + + eightbit = ((con->flags & CON_SERIAL) == 0 || (tty.c_cflag & (PARODD|PARENB)) == 0); + while (cp->eol == 0) { @@ -487,12 +545,13 @@ Index: src/sulogin.c + case 0: + case EIO: + case ESRCH: ++ case EINVAL: + case ENOENT: break; + default: -+ fprintf(stderr, "sulogin: read(%s): %m\n", con->tty); ++ fprintf(stderr, "sulogin: read(%s): %m\n\r", con->tty); + break; - } ++ } + goto quit; + } + @@ -525,14 +584,13 @@ Index: src/sulogin.c + ptr--; + break; + case CEOF: -+ tcfinal(con); + goto quit; + default: + if ((size_t)(ptr - &pass[0]) >= (sizeof(pass) -1 )) { -+ fprintf(stderr, "sulogin: input overrun at %s\n", con->tty); ++ fprintf(stderr, "sulogin: input overrun at %s\n\r", con->tty); + ret = (char*)0; + goto quit; -+ } + } + *ptr++ = ascval; + break; + } @@ -540,15 +598,18 @@ Index: src/sulogin.c +quit: alarm(0); - tcsetattr(0, TCSANOW, &old); +- printf("\n"); +- + if (tc) + (void)tcsetattr(fd, TCSAFLUSH, &con->tio); - printf("\n"); -- ++ if (ret && *ret != '\0') ++ tcfinal(con); ++ printf("\r\n"); +out: return ret; } -@@ -411,7 +693,10 @@ +@@ -411,7 +722,10 @@ void sushell(struct passwd *pwd) /* * Set directory and shell. */ @@ -560,7 +621,7 @@ Index: src/sulogin.c if ((p = getenv("SUSHELL")) != NULL) sushell = p; else if ((p = getenv("sushell")) != NULL) -@@ -431,7 +716,8 @@ +@@ -431,7 +745,8 @@ void sushell(struct passwd *pwd) /* * Set some important environment variables. */ @@ -570,7 +631,7 @@ Index: src/sulogin.c setenv("HOME", home, 1); setenv("LOGNAME", "root", 1); setenv("USER", "root", 1); -@@ -445,17 +731,18 @@ +@@ -445,17 +760,18 @@ void sushell(struct passwd *pwd) signal(SIGINT, saved_sigint); signal(SIGTSTP, saved_sigtstp); signal(SIGQUIT, saved_sigquit); @@ -592,13 +653,13 @@ Index: src/sulogin.c + if (getseuserbyname("root", &seuser, &level) == 0) + if (get_default_context_with_level(seuser, level, 0, &scon) == 0) { + if (setexeccon(scon) != 0) -+ fprintf(stderr, "setexeccon failed\n"); ++ fprintf(stderr, "setexeccon failed\n\r"); + freecon(scon); + } free(seuser); free(level); } -@@ -474,6 +761,46 @@ +@@ -474,20 +790,68 @@ void sushell(struct passwd *pwd) perror(STATICSH); } @@ -645,7 +706,10 @@ Index: src/sulogin.c static void usage(void) { -@@ -483,13 +810,21 @@ +- fprintf(stderr, "Usage: sulogin [-e] [-p] [-t timeout] [tty device]\n"); ++ fprintf(stderr, "Usage: sulogin [-e] [-p] [-t timeout] [tty device]\n\r"); + } + int main(int argc, char **argv) { char *tty = NULL; @@ -657,20 +721,23 @@ Index: src/sulogin.c - pid_t pid, pgrp, ppgrp, ttypgrp; + struct console *con; + pid_t pid; - - /* ++ ++ /* + * We are init. We hence need to set uo a session. + */ + if ((pid = getpid()) == 1) { + setsid(); + (void)ioctl(0, TIOCSCTTY, (char *)1); + } -+ -+ /* + + /* * See if we have a timeout flag. - */ - opterr = 0; -@@ -514,77 +849,24 @@ +@@ -510,115 +874,128 @@ int main(int argc, char **argv) + } + + if (geteuid() != 0) { +- fprintf(stderr, "sulogin: only root can run sulogin.\n"); ++ fprintf(stderr, "sulogin: only root can run sulogin.\n\r"); exit(1); } @@ -684,23 +751,12 @@ Index: src/sulogin.c + saved_sighup = signal(SIGHUP, SIG_IGN); - if (tty || (tty = getenv("CONSOLE"))) { -+ /* -+ * See if we need to open an other tty device. -+ */ -+ if (optind < argc) -+ tty = argv[optind]; -+ if (!tty || *tty == '\0') -+ tty = getenv("CONSOLE"); - +- - if ((fd = open(tty, O_RDWR)) < 0) { - perror(tty); - fd = dup(0); - } -+ /* -+ * Detect possible consoles, use stdin as fallback. -+ */ -+ detect_consoles(tty, 0); - +- - if (!isatty(fd)) { - fprintf(stderr, "%s: not a tty\n", tty); - close(fd); @@ -752,15 +808,29 @@ Index: src/sulogin.c - if (ioctl(0, TIOCSCTTY, (char *)1)) - perror("ioctl(TIOCSCTTY)"); - } -- ++ /* ++ * See if we need to open an other tty device. ++ */ ++ if (optind < argc) ++ tty = argv[optind]; ++ if (!tty || *tty == '\0') ++ tty = getenv("CONSOLE"); + -#if defined(SANE_TIO) && (SANE_TIO == 1) - fixtty(); -#endif -- ++ /* ++ * Detect possible consoles, use stdin as fallback. ++ */ ++ detect_consoles(tty, 0); + /* * Get the root password. */ -@@ -594,31 +876,97 @@ + if ((pwd = getrootpwent(opt_e)) == NULL) { +- fprintf(stderr, "sulogin: cannot open password database!\n"); ++ fprintf(stderr, "sulogin: cannot open password database!\n\r"); + sleep(2); } /* @@ -785,14 +855,19 @@ Index: src/sulogin.c - signal(SIGINT, SIG_IGN); - if (failed) { - printf("Can not execute su shell.\n"); +- break; +- } else +- printf("Login incorrect.\n"); + if ((con->fd = open(con->tty, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) + continue; + openfd |= (1<fd); + tcinit(con); -+ } + } + con = consoles; + usemask = (uint32_t*)mmap(NULL, sizeof(uint32_t), PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, -1, 0); -+ + +- if (alarm_rised) +- printf("Timed out.\n"); + if (con->next == (struct console*)0) + goto nofork; + @@ -825,26 +900,24 @@ Index: src/sulogin.c + signal(SIGINT, SIG_IGN); + + if (failed) { -+ fprintf(stderr, "Can not execute su shell.\n"); ++ fprintf(stderr, "Can not execute su shell.\n\r"); + break; + } -+ fprintf(stderr, "Login incorrect.\n"); ++ fprintf(stderr, "Login incorrect.\n\r"); + } + if (alarm_rised) { + tcfinal(con); -+ printf("Timed out.\n"); ++ printf("Timed out.\n\r"); + } + /* + * User may pressed Control-D. + */ + exit(0); + case -1: -+ fprintf(stderr, "sulogin: can not fork: %m\n"); ++ fprintf(stderr, "sulogin: can not fork: %m\n\r"); + /* fall through */ + default: - break; -- } else -- printf("Login incorrect.\n"); ++ break; + } + } while ((con = con->next) && (con->id < CONMAX)); + @@ -868,12 +941,9 @@ Index: src/sulogin.c + usleep(5000); + kill(con->pid, SIGKILL); + } - } ++ } + signal(SIGCHLD, SIG_DFL); -- if (alarm_rised) -- printf("Timed out.\n"); -- - /* - * User may pressed Control-D. - */ @@ -883,17 +953,15 @@ Index: src/consoles.c =================================================================== --- src/consoles.c (revision 100) +++ src/consoles.c (working copy) -@@ -27,9 +27,23 @@ +@@ -27,9 +27,21 @@ #include #include #include +#include +#ifdef __linux__ -+# ifndef TIOCGDEV +# include +# include +# include -+# endif +#endif +#include #include @@ -907,7 +975,7 @@ Index: src/consoles.c #if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) # ifndef typeof # define typeof __typeof__ -@@ -43,8 +57,93 @@ +@@ -43,8 +55,93 @@ struct console *consoles; @@ -1002,7 +1070,7 @@ Index: src/consoles.c { char *name = (char*)0; struct dirent *dent; -@@ -69,41 +168,232 @@ +@@ -69,41 +166,310 @@ static char* scandev(DIR *dir) return name; } @@ -1045,21 +1113,94 @@ Index: src/consoles.c + consoles->next = tail; +} + -+void detect_consoles(const char *console, int fallback) ++void detect_consoles(const char *device, int fallback) +{ ++ int fd; +#ifdef __linux__ + char *attrib, *cmdline; FILE *fc; - if ((fc = fopen("/proc/consoles", "r"))) { ++#endif ++ if (!device || *device == '\0') ++ fd = dup(fallback); ++ else fd = open(device, O_RDWR|O_NONBLOCK|O_NOCTTY|O_CLOEXEC); + ++ if (fd >= 0) { ++ DIR *dir; ++ char *name; ++ struct stat st; ++#ifdef TIOCGDEV ++ unsigned int devnum; ++#endif ++ ++ if (fstat(fd, &st) < 0) { ++ close(fd); ++ goto fallback; ++ } ++ comparedev = st.st_rdev; ++#ifdef __linux__ ++ /* ++ * Check if the device detection for Linux system console should be used. ++ */ ++ if (comparedev == makedev(TTYAUX_MAJOR, 0)) { /* /dev/tty */ ++ close(fd); ++ device = "/dev/tty"; ++ goto fallback; ++ } ++ if (comparedev == makedev(TTYAUX_MAJOR, 1)) { /* /dev/console */ ++ close(fd); ++ goto console; ++ } ++ if (comparedev == makedev(TTYAUX_MAJOR, 2)) { /* /dev/ptmx */ ++ close(fd); ++ device = "/dev/tty"; ++ goto fallback; ++ } ++ if (comparedev == makedev(TTY_MAJOR, 0)) { /* /dev/tty0 */ ++ struct vt_stat vt; ++ if (ioctl(fd, VT_GETSTATE, &vt) < 0) { ++ close(fd); ++ goto fallback; ++ } ++ comparedev = makedev(TTY_MAJOR, (int)vt.v_active); ++ } ++#endif ++#ifdef TIOCGDEV ++ if (ioctl (fd, TIOCGDEV, &devnum) < 0) { ++ close(fd); ++ goto fallback; ++ } ++ comparedev = (dev_t)devnum; ++#endif ++ close(fd); ++ dir = opendir("/dev"); ++ if (!dir) ++ goto fallback; ++ name = scandev(dir); ++ if (name) ++ consalloc(name); ++ closedir(dir); ++ if (!consoles) ++ goto fallback; ++ return; ++ } ++#ifdef __linux__ ++console: ++ /* ++ * Detection of devices used for Linux system consolei using ++ * the /proc/consoles API with kernel 2.6.38 and higher. ++ */ + if ((fc = fopen("/proc/consoles", "re"))) { char fbuf[16]; int maj, min; DIR *dir; dir = opendir("/dev"); - if (!dir) +- if (!dir) - goto out; -+ goto out1; ++ if (!dir) { ++ fclose(fc); ++ goto fallback; ++ } while ((fscanf(fc, "%*s %*s (%[^)]) %d:%d", &fbuf[0], &maj, &min) == 3)) { - struct console *restrict tail; char * name; @@ -1074,18 +1215,22 @@ Index: src/consoles.c + consalloc(name); + } + closedir(dir); -+out1: + fclose(fc); + return; + } - ++ /* ++ * Detection of devices used for Linux system console using ++ * the sysfs /sys/class/tty/ API with kernel 2.6.37 and higher. ++ */ + if ((attrib = actattr("console"))) { + char *words = attrib, *token; + DIR *dir; -+ + + dir = opendir("/dev"); -+ if (!dir) -+ goto out2; ++ if (!dir) { ++ free(attrib); ++ goto fallback; ++ } + while ((token = strsep(&words, " \t\r\n"))) { + char * name; + @@ -1106,27 +1251,25 @@ Index: src/consoles.c + consalloc(name); + } + closedir(dir); -+out2: + free(attrib); ++ if (!consoles) ++ goto fallback; + return; - -- if (posix_memalign((void*)&tail, sizeof(void*), alignof(typeof(struct console))) != 0) -- perror("memory allocation"); ++ + } - -- tail->next = (struct console*)0; -- tail->tty = name; ++ /* ++ * Detection of devices used for Linux system console using ++ * kernel parameter on the kernels command line. ++ */ + if ((cmdline = oneline("/proc/cmdline"))) { + char *words= cmdline, *token; + DIR *dir; - -- if (!consoles) -- consoles = tail; -- else -- consoles->next = tail; ++ + dir = opendir("/dev"); -+ if (!dir) -+ goto out3; ++ if (!dir) { ++ free(cmdline); ++ goto fallback; ++ } + while ((token = strsep(&words, " \t\r\n"))) { +#ifdef TIOCGDEV + unsigned int devnum; @@ -1135,7 +1278,6 @@ Index: src/consoles.c + struct stat st; +#endif + char *colon, *name; -+ int fd; + + if (*token != 'c') + continue; @@ -1143,12 +1285,16 @@ Index: src/consoles.c + if (strncmp(token, "console=", 8) != 0) + continue; + token += 8; -+ + +- if (posix_memalign((void*)&tail, sizeof(void*), alignof(typeof(struct console))) != 0) +- perror("memory allocation"); + if (strcmp(token, "brl") == 0) + token += 4; + if ((colon = strchr(token, ','))) + *colon = '\0'; -+ + +- tail->next = (struct console*)0; +- tail->tty = name; + if (asprintf(&name, "/dev/%s", token) < 0) + continue; + @@ -1178,7 +1324,11 @@ Index: src/consoles.c + } +#endif + close(fd); -+ + +- if (!consoles) +- consoles = tail; +- else +- consoles->next = tail; + name = scandev(dir); + if (!name) + continue; @@ -1187,67 +1337,64 @@ Index: src/consoles.c closedir(dir); -out: - fclose(fc); -+out3: + free(cmdline); -+ return; - } -+#endif /* __linux __ */ -+ if (console && *console) { -+ int fd; -+ DIR *dir; -+ char *name; ++ /* ++ * Detection of the device used for Linux system console using ++ * the ioctl TIOCGDEV if available (e.g. official 2.6.38). ++ */ ++ if (!consoles) { +#ifdef TIOCGDEV -+ unsigned int devnum; -+#else -+# ifdef __linux__ -+ struct vt_stat vt; -+# endif -+ struct stat st; -+#endif ++ unsigned int devnum; ++ const char *name; + -+ if ((fd = open(console, O_RDWR|O_NONBLOCK|O_NOCTTY|O_CLOEXEC)) < 0) -+ return; -+#ifdef TIOCGDEV -+ if (ioctl (fd, TIOCGDEV, &devnum) < 0) { -+ close(fd); -+ return; -+ } -+ comparedev = (dev_t)devnum; -+#else -+ if (fstat(fd, &st) < 0) { -+ close(fd); -+ return; -+ } -+# ifdef __linux__ -+ comparedev = st.st_rdev; -+ if (comparedev == makedev(TTY_MAJOR, 0)) { -+ if (ioctl(fd, VT_GETSTATE, &vt) < 0) { ++ if (!device || *device == '\0') ++ fd = dup(fallback); ++ else fd = open(device, O_RDWR|O_NONBLOCK|O_NOCTTY|O_CLOEXEC); ++ ++ if (fd < 0) ++ goto fallback; ++ ++ if (ioctl (fd, TIOCGDEV, &devnum) < 0) { + close(fd); ++ goto fallback; ++ } ++ comparedev = (dev_t)devnum; ++ close(fd); ++ ++ if (device && *device != '\0') ++ name = device; ++ else name = ttyname(fallback); ++ ++ if (!name) ++ name = "/dev/tty1"; ++ ++ consalloc(strdup(name)); ++ if (consoles) { ++ if (!device || *device == '\0') ++ consoles->fd = fallback; + return; + } -+ comparedev = makedev(TTY_MAJOR, (int)vt.v_active); -+ } -+# endif +#endif -+ close(fd); -+ dir = opendir("/dev"); -+ if (!dir) -+ return; -+ name = scandev(dir); -+ if (name) -+ consalloc(name); -+ closedir(dir); ++ goto fallback; ++ } + return; + } -+ ++#endif /* __linux __ */ ++fallback: + if (fallback >= 0) { -+ const char *name = ttyname(fallback); ++ const char *name; ++ ++ if (device && *device != '\0') ++ name = device; ++ else name = ttyname(fallback); ++ + if (!name) -+ name = "/dev/console"; ++ name = "/dev/tty"; ++ + consalloc(strdup(name)); + if (consoles) + consoles->fd = fallback; -+ } + } } Index: src/consoles.h =================================================================== @@ -1285,12 +1432,12 @@ Index: src/consoles.h }; extern struct console *consoles; -extern void detect_consoles(void); -+extern void detect_consoles(const char *console, int fallback); ++extern void detect_consoles(const char *, int); Index: src/Makefile =================================================================== --- src/Makefile (revision 100) +++ src/Makefile (working copy) -@@ -105,7 +105,7 @@ +@@ -112,7 +112,7 @@ utmpdump: utmpdump.o runlevel: runlevel.o sulogin: LDLIBS += $(SULOGINLIBS) $(STATIC) diff --git a/sysvinit.changes b/sysvinit.changes index eee74ba..a5651ea 100644 --- a/sysvinit.changes +++ b/sysvinit.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------ +Fri Apr 1 15:00:19 CEST 2011 - werner@suse.de + +- Let sulogin respect device on the comman line as well as the + standard input +- Let sulogin initialize serial terminals + ------------------------------------------------------------------ Thu Mar 31 16:14:55 CEST 2011 - werner@suse.de