1ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley/* getty.c - A getty program to get controlling terminal. 2ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley * 3ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley * Copyright 2012 Sandeep Sharma <sandeep.jack2756@gamil.com> 4ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley * Copyright 2013 Kyungwan Han <asura321@gmail.com> 5ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley * 6ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley * No Standard. 7ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 8ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob LandleyUSE_GETTY(NEWTOY(getty, "<2t#<0H:I:l:f:iwnmLh",TOYFLAG_SBIN)) 9ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 10ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleyconfig GETTY 11ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley bool "getty" 12ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley default n 13ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley help 143297e87c2ab798696b0fb3d06904dccea076b77aRob Landley usage: getty [OPTIONS] BAUD_RATE[,BAUD_RATE]... TTY [TERMTYPE] 15ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 16ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley -h Enable hardware RTS/CTS flow control 17ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley -L Set CLOCAL (ignore Carrier Detect state) 18ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley -m Get baud rate from modem's CONNECT status message 19ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley -n Don't prompt for login name 20ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley -w Wait for CR or LF before sending /etc/issue 21ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley -i Don't display /etc/issue 22ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley -f ISSUE_FILE Display ISSUE_FILE instead of /etc/issue 23ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley -l LOGIN Invoke LOGIN instead of /bin/login 24ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley -t SEC Terminate after SEC if no login name is read 25ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley -I INITSTR Send INITSTR before anything else 26ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley -H HOST Log HOST into the utmp file as the hostname 27ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley*/ 28ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#define FOR_getty 29ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#include "toys.h" 30ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#include <utmp.h> 31ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 32ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob LandleyGLOBALS( 33ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley char *issue_str; 34ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley char *login_str; 35ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley char *init_str; 36ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley char *host_str; 37ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley long timeout; 38ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 39ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley char *tty_name; 40ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley int speeds[20]; 41ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley int sc; 42ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley struct termios termios; 43ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley char buff[128]; 44ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley) 45ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 46ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#define CTL(x) ((x) ^ 0100) 47ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#define HOSTNAME_SIZE 32 48ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 49ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleytypedef void (*sighandler_t)(int); 50ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleystruct speed_mapper { 51ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley long speed; 52ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley speed_t code; 53ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley}; 54ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 55ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleystruct speed_mapper speedtab[] = { 56ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley {50, B50}, {75, B75}, {110, B110}, {134, B134}, {150, B150}, {200, B200}, 57ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley {300, B300}, {600, B600}, {1200, B1200}, {1800, B1800}, {2400, B2400}, 58ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley {4800, B4800}, {9600, B9600}, 59ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#ifdef B19200 60ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley {19200, B19200}, 61ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#endif 62ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#ifdef B38400 63ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley {38400, B38400}, 64ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#endif 65ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#ifdef EXTA 66ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley {19200, EXTA}, 67ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#endif 68ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#ifdef EXTB 69ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley {38400, B38400}, 70ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#endif 71ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#ifdef B57600 72ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley {57600, B57600}, 73ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#endif 74ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#ifdef B115200 75ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley {115200, B115200}, 76ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#endif 77ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#ifdef B230400 78ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley {230400, B230400}, 79ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#endif 80ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley {0, 0}, 81ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley}; 82ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 83ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley// Find speed from mapper array 84ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleystatic speed_t encode(char *s) 85ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley{ 86ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley struct speed_mapper *sp; 87ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley long speed = atolx(s); 88ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 89ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (!speed) return 0; 90ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley for (sp = speedtab; sp->speed; sp++) if (sp->speed == speed) return sp->code; 91ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley return (speed_t) -1; 92ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley} 93ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 94ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleystatic void get_speed(char *sp) 95ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley{ 96ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley char *ptr; 97ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 98ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.sc = 0; 99ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley while ((ptr = strsep(&sp, ","))) { 100ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.speeds[TT.sc] = encode(ptr); 1018b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham if (TT.speeds[TT.sc] < 0) perror_exit("bad speed"); 1028b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham if (++TT.sc > 10) perror_exit("too many speeds, max is 10"); 103ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } 104ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley} 105ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 106ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley// Parse args and set TERM env. variable 107ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleystatic void parse_arguments(void) 108ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley{ 109ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (isdigit(**toys.optargs)) { 110ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley get_speed(*toys.optargs); 1118b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham if (*++toys.optargs) TT.tty_name = xmprintf("%s", *toys.optargs); 112ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } else { 1138b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham TT.tty_name = xmprintf("%s", *toys.optargs); 114ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (*++toys.optargs) get_speed(*toys.optargs); 115ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } 116ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (*++toys.optargs) setenv("TERM", *toys.optargs, 1); 117ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley} 118ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 119ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley// Get controlling terminal and redirect stdio 120ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleystatic void open_tty(void) 121ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley{ 122ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (strcmp(TT.tty_name, "-")) { 1238b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham if (*(TT.tty_name) != '/') TT.tty_name = xmprintf("/dev/%s", TT.tty_name); 124ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley // Sends SIGHUP to all foreground process if Session leader don't die,Ignore 125ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley sighandler_t sig = signal(SIGHUP, SIG_IGN); 126ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley ioctl(0, TIOCNOTTY, 0); // Giveup if there is any controlling terminal 127ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley signal(SIGHUP, sig); 1288b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham if ((setsid() < 0) && (getpid() != getsid(0))) 1298b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham perror_exit("setsid"); 130ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley xclose(0); 131027a73a903af306449710ce12bc09e0e3550c6c9Rob Landley xopen_stdio(TT.tty_name, O_RDWR|O_NDELAY|O_CLOEXEC); 132ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley fcntl(0, F_SETFL, fcntl(0, F_GETFL) & ~O_NONBLOCK); // Block read 133ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley dup2(0, 1); 134ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley dup2(0, 2); 135ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (ioctl(0, TIOCSCTTY, 1) < 0) perror_msg("ioctl(TIOCSCTTY)"); 1368b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham if (!isatty(0)) perror_exit("/dev/%s: not a tty", TT.tty_name); 137ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley chown(TT.tty_name, 0, 0); // change ownership, Hope login will change this 138ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley chmod(TT.tty_name, 0620); 139ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } else { // We already have opened TTY 1408b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham if (setsid() < 0) perror_msg("setsid failed"); 141ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if ((fcntl(0, F_GETFL) & (O_RDWR|O_RDONLY|O_WRONLY)) != O_RDWR) 1428b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham perror_exit("no read/write permission"); 143ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } 144ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley} 145ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 146ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley// Intialise terminal settings 147ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleystatic void termios_init(void) 148ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley{ 149ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (tcgetattr(STDIN_FILENO, &TT.termios) < 0) perror_exit("tcgetattr"); 150ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley // Flush input and output queues, important for modems! 151ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley tcflush(STDIN_FILENO, TCIOFLUSH); 152ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_cflag &= (0|CSTOPB|PARENB|PARODD); 153ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#ifdef CRTSCTS 154ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (toys.optflags & FLAG_h) TT.termios.c_cflag |= CRTSCTS; 155ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley#endif 156ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (toys.optflags & FLAG_L) TT.termios.c_cflag |= CLOCAL; 157ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_cc[VTIME] = 0; 158ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_cc[VMIN] = 1; 159ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_oflag = OPOST|ONLCR; 160ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_cflag |= CS8|CREAD|HUPCL|CBAUDEX; 161ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley // login will disable echo for passwd. 162ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_lflag |= ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOKE; 163ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_cc[VINTR] = CTL('C'); 164ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_cc[VQUIT] = CTL('\\'); 165ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_cc[VEOF] = CTL('D'); 166ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_cc[VEOL] = '\n'; 167ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_cc[VKILL] = CTL('U'); 168c962e0fd295525978de0d9a0af584f47a83d9699Rob Landley TT.termios.c_cc[VERASE] = 127; // CERASE 1698b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham TT.termios.c_iflag = ICRNL|IXON|IXOFF; 170ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley // set non-zero baud rate. Zero baud rate left it unchanged. 171ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (TT.speeds[0] != B0) cfsetspeed(&TT.termios, TT.speeds[0]); 172ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (tcsetattr(STDIN_FILENO, TCSANOW, &TT.termios) < 0) 173ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley perror_exit("tcsetattr"); 174ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley} 175ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 176ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley// Get the baud rate from modems CONNECT mesage, Its of form <junk><BAUD><Junk> 177ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleystatic void sense_baud(void) 178ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley{ 179ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley int vmin; 180ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley ssize_t size; 181ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley char *ptr; 182ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley speed_t speed; 183ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 184ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley vmin = TT.termios.c_cc[VMIN]; // Store old 185ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_cc[VMIN] = 0; // No block even queue is empty. 186ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (tcsetattr(STDIN_FILENO, TCSANOW, &TT.termios) < 0) 187ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley perror_exit("tcsetattr"); 188ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley size = readall(STDIN_FILENO, TT.buff, sizeof(TT.buff)-1); 189ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (size > 0) { 190ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley for (ptr = TT.buff; ptr < TT.buff+size; ptr++) { 191ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (isdigit(*ptr)) { 192ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley speed = encode(ptr); 193ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (speed > 0) cfsetspeed(&TT.termios,speed); 194ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley break; 195ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } 196ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } 197ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } 198ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.termios.c_cc[VMIN] = vmin; //restore old value 199ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (tcsetattr(STDIN_FILENO, TCSANOW, &TT.termios) < 0) 200ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley perror_exit("tcsetattr"); 201ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley} 202ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 203ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley// Just prompt for login name 204ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleyvoid print_prompt(void) 205ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley{ 206ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley char *hostname; 207ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley struct utsname uts; 208ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 209ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley uname(&uts); 210ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley hostname = xstrdup(uts.nodename); 211ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley fputs(hostname, stdout); 2128b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham fputs(" login: ", stdout); 213ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley fflush(NULL); 214ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley free(hostname); 215ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley hostname = NULL; 216ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley} 217ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 218ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley// Print /etc/isuue with taking care of each escape sequence 219ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleyvoid write_issue(char *file) 220ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley{ 221ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley char buff[20] = {0,}; 222ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley struct utsname u; 223ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley uname(&u); 224ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley int size, fd = open(TT.issue_str, O_RDONLY); 225ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 226ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (fd < 0) return; 227ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley while ((size = readall(fd, buff, 1)) > 0) { 228ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley char *ch = buff; 229ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 230ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (*ch == '\\' || *ch == '%') { 231ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (readall(fd, buff, 1) <= 0) perror_exit("readall"); 232ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (*ch == 's') fputs(u.sysname, stdout); 233ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (*ch == 'n'|| *ch == 'h') fputs(u.nodename, stdout); 234ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (*ch == 'r') fputs(u.release, stdout); 235ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (*ch == 'm') fputs(u.machine, stdout); 236ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (*ch == 'l') fputs(TT.tty_name, stdout); 237ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } else xputc(*ch); 238ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } 239ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley} 240ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 241ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley// Read login name and print prompt and Issue file. 242ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleystatic int read_login_name(void) 243ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley{ 244ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley tcflush(STDIN_FILENO, TCIFLUSH); // Flush pending speed switches 245ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley int i = 0; 246ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 247ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley while (1) { // Option -i will overide -f 248ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (!(toys.optflags & FLAG_i)) write_issue(TT.issue_str); 249ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley print_prompt(); 250ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.buff[0] = getchar(); 251ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (!TT.buff[0] && TT.sc > 1) return 0; // Switch speed 252ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (TT.buff[0] == '\n') continue; 253ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (TT.buff[0] != '\n') 254ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (!fgets(&TT.buff[1], HOSTNAME_SIZE-1, stdin)) _exit(1); 255ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley while (i < HOSTNAME_SIZE-1 && isgraph(TT.buff[i])) i++; 256ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley TT.buff[i] = 0; 257ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley break; 258ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } 259ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley return 1; 260ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley} 261ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 262ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley// Put hostname entry in utmp file 263ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleystatic void utmp_entry(void) 264ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley{ 265ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley struct utmp entry; 266ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley struct utmp *utp_ptr; 267ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley pid_t pid = getpid(); 2688b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham char *utmperr = "can't make utmp entry, host length greater than UT_HOSTSIZE(256)"; 269ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 270ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley utmpname(_PATH_UTMP); 271ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley setutent(); // Starts from start 272ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley while ((utp_ptr = getutent())) 273ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (utp_ptr->ut_pid == pid && utp_ptr->ut_type >= INIT_PROCESS) break; 274ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (!utp_ptr) { 275ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley entry.ut_type = LOGIN_PROCESS; 276ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley entry.ut_pid = getpid(); 277ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley xstrncpy(entry.ut_line, ttyname(STDIN_FILENO) + 278ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley strlen("/dev/"), UT_LINESIZE); 279ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley time((time_t *)&entry.ut_time); 280ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley xstrncpy(entry.ut_user, "LOGIN", UT_NAMESIZE); 281ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (strlen(TT.host_str) > UT_HOSTSIZE) 2828b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham perror_msg(utmperr); 283ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley else xstrncpy(entry.ut_host, TT.host_str, UT_HOSTSIZE); 284ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley setutent(); 285ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley pututline(&entry); 286ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley return; 287ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } 288ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley xstrncpy(entry.ut_line, ttyname(STDIN_FILENO) + strlen("/dev/"), UT_LINESIZE); 289ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley xstrncpy(entry.ut_user, "LOGIN", UT_NAMESIZE); 290ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (strlen(TT.host_str) > UT_HOSTSIZE) 2918b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham perror_msg(utmperr); 292ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley else xstrncpy(entry.ut_host, TT.host_str, UT_HOSTSIZE); 293ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley time((time_t *)&entry.ut_time); 294ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley setutent(); 295ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley pututline(&entry); 296ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley} 297ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 298ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landleyvoid getty_main(void) 299ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley{ 300ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley pid_t pid = getpid(); 3018b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham char *ptr[3] = {"/bin/login", NULL, NULL}; //2 NULLs so we can add username 302ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 303ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (!(toys.optflags & FLAG_f)) TT.issue_str = "/etc/issue"; 304ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (toys.optflags & FLAG_l) ptr[0] = TT.login_str; 305ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley parse_arguments(); 306ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley open_tty(); 307ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley termios_init(); 308ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley tcsetpgrp(STDIN_FILENO, pid); 309ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (toys.optflags & FLAG_H) utmp_entry(); 310ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (toys.optflags & FLAG_I) 311ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley writeall(STDOUT_FILENO,TT.init_str,strlen(TT.init_str)); 312ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (toys.optflags & FLAG_m) sense_baud(); 313ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (toys.optflags & FLAG_t) alarm(TT.timeout); 314ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (toys.optflags & FLAG_w) { 315ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley char ch; 316ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 317ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley while (readall(STDIN_FILENO, &ch, 1) != 1) 318ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (ch == '\n' || ch == '\r') break; 319ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } 320ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (!(toys.optflags & FLAG_n)) { 321ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley int index = 1; // 0th we already set. 322ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 323ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley while (1) { 324ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley int l = read_login_name(); 325ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley 326ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (l) break; 327ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley index = index % TT.sc; 328ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley cfsetspeed(&TT.termios, TT.speeds[index]); // Select from multiple speeds 329ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley //Necessary after cfsetspeed 330ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley if (tcsetattr(STDIN_FILENO, TCSANOW, &TT.termios) < 0) 331ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley perror_exit("tcsetattr"); 332ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } 3338b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham ptr[1]=TT.buff; //put the username in the login command line 334ca51eb88831521ae4df60e88d5f3cd3c4b99d46dRob Landley } 3358b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham xexec(ptr); 3368b6d56c4f75efed9d4769d2d959ee7706e314152Isaac Dunham} 337