diff options
Diffstat (limited to 'toys/pending/getty.c')
-rw-r--r-- | toys/pending/getty.c | 160 |
1 files changed, 49 insertions, 111 deletions
diff --git a/toys/pending/getty.c b/toys/pending/getty.c index 9b8bdf1e..cc4fce0b 100644 --- a/toys/pending/getty.c +++ b/toys/pending/getty.c @@ -35,85 +35,39 @@ GLOBALS( char *issue_str; char *login_str; char *init_str; - char *host_str; + char *host_str; long timeout; - + char *tty_name, buff[128]; int speeds[20], sc; struct termios termios; ) -#define CTL(x) ((x) ^ 0100) +#define CTL(x) ((x) ^ 0100) #define HOSTNAME_SIZE 32 -typedef void (*sighandler_t)(int); -struct speed_mapper { - long speed; - speed_t code; -}; - -struct speed_mapper speedtab[] = { - {50, B50}, {75, B75}, {110, B110}, {134, B134}, {150, B150}, {200, B200}, - {300, B300}, {600, B600}, {1200, B1200}, {1800, B1800}, {2400, B2400}, - {4800, B4800}, {9600, B9600}, -#ifdef B19200 - {19200, B19200}, -#endif -#ifdef B38400 - {38400, B38400}, -#endif -#ifdef EXTA - {19200, EXTA}, -#endif -#ifdef EXTB - {38400, B38400}, -#endif -#ifdef B57600 - {57600, B57600}, -#endif -#ifdef B115200 - {115200, B115200}, -#endif -#ifdef B230400 - {230400, B230400}, -#endif - {0, 0}, -}; - -// Find speed from mapper array -static speed_t encode(char *s) -{ - struct speed_mapper *sp; - long speed = atolx(s); - - if (!speed) return 0; - for (sp = speedtab; sp->speed; sp++) if (sp->speed == speed) return sp->code; - return (speed_t) -1; -} - -static void get_speed(char *sp) +static void parse_speeds(char *sp) { char *ptr; TT.sc = 0; while ((ptr = strsep(&sp, ","))) { - TT.speeds[TT.sc] = encode(ptr); - if (TT.speeds[TT.sc] < 0) perror_exit("bad speed"); + TT.speeds[TT.sc] = atolx_range(ptr, 0, INT_MAX); + if (TT.speeds[TT.sc] < 0) perror_exit("bad speed %s", ptr); if (++TT.sc > 10) perror_exit("too many speeds, max is 10"); } } -// Get controlling terminal and redirect stdio +// Get controlling terminal and redirect stdio static void open_tty(void) { if (strcmp(TT.tty_name, "-")) { if (*(TT.tty_name) != '/') TT.tty_name = xmprintf("/dev/%s", TT.tty_name); // Sends SIGHUP to all foreground process if Session leader don't die,Ignore - sighandler_t sig = signal(SIGHUP, SIG_IGN); + void* handler = signal(SIGHUP, SIG_IGN); ioctl(0, TIOCNOTTY, 0); // Giveup if there is any controlling terminal - signal(SIGHUP, sig); - if ((setsid() < 0) && (getpid() != getsid(0))) - perror_exit("setsid"); + signal(SIGHUP, handler); + if ((setsid() < 0) && (getpid() != getsid(0))) perror_exit("setsid"); xclose(0); xopen_stdio(TT.tty_name, O_RDWR|O_NDELAY|O_CLOEXEC); fcntl(0, F_SETFL, fcntl(0, F_GETFL) & ~O_NONBLOCK); // Block read @@ -130,17 +84,16 @@ static void open_tty(void) } } -// Intialise terminal settings static void termios_init(void) { - if (tcgetattr(STDIN_FILENO, &TT.termios) < 0) perror_exit("tcgetattr"); + if (tcgetattr(0, &TT.termios) < 0) perror_exit("tcgetattr"); // Flush input and output queues, important for modems! - tcflush(STDIN_FILENO, TCIOFLUSH); + tcflush(0, TCIOFLUSH); TT.termios.c_cflag &= (0|CSTOPB|PARENB|PARODD); #ifdef CRTSCTS - if (toys.optflags & FLAG_h) TT.termios.c_cflag |= CRTSCTS; + if (FLAG(h)) TT.termios.c_cflag |= CRTSCTS; #endif - if (toys.optflags & FLAG_L) TT.termios.c_cflag |= CLOCAL; + if (FLAG(L)) TT.termios.c_cflag |= CLOCAL; TT.termios.c_cc[VTIME] = 0; TT.termios.c_cc[VMIN] = 1; TT.termios.c_oflag = OPOST|ONLCR; @@ -154,61 +107,40 @@ static void termios_init(void) TT.termios.c_cc[VKILL] = CTL('U'); TT.termios.c_cc[VERASE] = 127; // CERASE TT.termios.c_iflag = ICRNL|IXON|IXOFF; - // set non-zero baud rate. Zero baud rate left it unchanged. - if (TT.speeds[0] != B0) cfsetspeed(&TT.termios, TT.speeds[0]); - if (tcsetattr(STDIN_FILENO, TCSANOW, &TT.termios) < 0) - perror_exit("tcsetattr"); + // Set non-zero baud rate. Zero baud rate left it unchanged. + if (TT.speeds[0] != 0) xsetspeed(&TT.termios, TT.speeds[0]); + if (tcsetattr(0, TCSANOW, &TT.termios) < 0) perror_exit("tcsetattr"); } // Get the baud rate from modems CONNECT mesage, Its of form <junk><BAUD><Junk> static void sense_baud(void) { - int vmin; + int vmin, speed; ssize_t size; char *ptr; - speed_t speed; vmin = TT.termios.c_cc[VMIN]; // Store old TT.termios.c_cc[VMIN] = 0; // No block even queue is empty. - if (tcsetattr(STDIN_FILENO, TCSANOW, &TT.termios) < 0) - perror_exit("tcsetattr"); - size = readall(STDIN_FILENO, TT.buff, sizeof(TT.buff)-1); + if (tcsetattr(0, TCSANOW, &TT.termios) < 0) perror_exit("tcsetattr"); + size = readall(0, TT.buff, sizeof(TT.buff)-1); if (size > 0) { for (ptr = TT.buff; ptr < TT.buff+size; ptr++) { if (isdigit(*ptr)) { - speed = encode(ptr); - if (speed > 0) cfsetspeed(&TT.termios,speed); + speed = atolx_range(ptr, 0, INT_MAX); + if (speed > 0) xsetspeed(&TT.termios, speed); break; } - } + } } TT.termios.c_cc[VMIN] = vmin; //restore old value - if (tcsetattr(STDIN_FILENO, TCSANOW, &TT.termios) < 0) - perror_exit("tcsetattr"); -} - -// Just prompt for login name -void print_prompt(void) -{ - char *hostname; - struct utsname uts; - - uname(&uts); - hostname = xstrdup(uts.nodename); - fputs(hostname, stdout); - fputs(" login: ", stdout); - fflush(NULL); - free(hostname); - hostname = NULL; + if (tcsetattr(0, TCSANOW, &TT.termios) < 0) perror_exit("tcsetattr"); } // Print /etc/isuue with taking care of each escape sequence -void write_issue(char *file) +void write_issue(char *file, struct utsname *uts) { char buff[20] = {0,}; - struct utsname u; - uname(&u); - int size, fd = open(TT.issue_str, O_RDONLY); + int fd = open(TT.issue_str, O_RDONLY), size; if (fd < 0) return; while ((size = readall(fd, buff, 1)) > 0) { @@ -216,24 +148,30 @@ void write_issue(char *file) if (*ch == '\\' || *ch == '%') { if (readall(fd, buff, 1) <= 0) perror_exit("readall"); - if (*ch == 's') fputs(u.sysname, stdout); - if (*ch == 'n'|| *ch == 'h') fputs(u.nodename, stdout); - if (*ch == 'r') fputs(u.release, stdout); - if (*ch == 'm') fputs(u.machine, stdout); + if (*ch == 's') fputs(uts->sysname, stdout); + if (*ch == 'n'|| *ch == 'h') fputs(uts->nodename, stdout); + if (*ch == 'r') fputs(uts->release, stdout); + if (*ch == 'm') fputs(uts->machine, stdout); if (*ch == 'l') fputs(TT.tty_name, stdout); } else xputc(*ch); } } -// Read login name and print prompt and Issue file. +// Read login name and print prompt and Issue file. static int read_login_name(void) { - tcflush(STDIN_FILENO, TCIFLUSH); // Flush pending speed switches - int i = 0; + tcflush(0, TCIFLUSH); // Flush pending speed switches + while (1) { + struct utsname uts; + int i = 0; + + uname(&uts); + + if (!FLAG(i)) write_issue(TT.issue_str, &uts); + + printf("%s login: ", uts.nodename); + xflush(1); - while (1) { // Option -i will overide -f - if (!(toys.optflags & FLAG_i)) write_issue(TT.issue_str); - print_prompt(); TT.buff[0] = getchar(); if (!TT.buff[0] && TT.sc > 1) return 0; // Switch speed if (TT.buff[0] == '\n') continue; @@ -279,18 +217,18 @@ static void utmp_entry(void) void getty_main(void) { - char ch, *ptr[3] = {"/bin/login", 0, 0}; // space to add username + char ch, *cmd[3] = {"/bin/login", 0, 0}; // space to add username if (!FLAG(f)) TT.issue_str = "/etc/issue"; - if (FLAG(l)) ptr[0] = TT.login_str; + if (FLAG(l)) cmd[0] = TT.login_str; // parse arguments and set $TERM if (isdigit(**toys.optargs)) { - get_speed(*toys.optargs); + parse_speeds(*toys.optargs); if (*++toys.optargs) TT.tty_name = xmprintf("%s", *toys.optargs); } else { TT.tty_name = xmprintf("%s", *toys.optargs); - if (*++toys.optargs) get_speed(*toys.optargs); + if (*++toys.optargs) parse_speeds(*toys.optargs); } if (*++toys.optargs) setenv("TERM", *toys.optargs, 1); @@ -308,11 +246,11 @@ void getty_main(void) for (;;) { if (read_login_name()) break; index %= TT.sc; - cfsetspeed(&TT.termios, TT.speeds[index]); // Select from multiple speeds + xsetspeed(&TT.termios, TT.speeds[index]); //Necessary after cfsetspeed if (tcsetattr(0, TCSANOW, &TT.termios) < 0) perror_exit("tcsetattr"); } - ptr[1] = TT.buff; //put the username in the login command line + cmd[1] = TT.buff; //put the username in the login command line } - xexec(ptr); + xexec(cmd); } |