113795Ssam #ifndef lint 2*18543Sralph static char sccsid[] = "@(#)main.c 4.7 (Berkeley) 85/04/01"; 313795Ssam #endif 413795Ssam 513795Ssam /* 613795Ssam * getty -- adapt to terminal speed on dialup, and call login 713795Ssam * 813795Ssam * Melbourne getty, June 83, kre. 913795Ssam */ 1013795Ssam 1113795Ssam #include <sgtty.h> 1213795Ssam #include <signal.h> 1313795Ssam #include <ctype.h> 1413795Ssam #include <setjmp.h> 15*18543Sralph #include <syslog.h> 16*18543Sralph #include <sys/file.h> 1713795Ssam #include "gettytab.h" 1813795Ssam 19*18543Sralph extern char **environ; 20*18543Sralph 2113795Ssam struct sgttyb tmode = { 2213795Ssam 0, 0, CERASE, CKILL, 0 2313795Ssam }; 2413795Ssam struct tchars tc = { 2513795Ssam CINTR, CQUIT, CSTART, 2613795Ssam CSTOP, CEOF, CBRK, 2713795Ssam }; 2813795Ssam struct ltchars ltc = { 2913795Ssam CSUSP, CDSUSP, CRPRNT, 3013795Ssam CFLUSH, CWERASE, CLNEXT 3113795Ssam }; 3213795Ssam 3313795Ssam int crmod; 3413795Ssam int upper; 3513795Ssam int lower; 3613795Ssam int digit; 3713795Ssam 3813795Ssam char hostname[32]; 3913795Ssam char name[16]; 40*18543Sralph char dev[] = "/dev/"; 41*18543Sralph char ctty[] = "/dev/console"; 42*18543Sralph char ttyn[32]; 4313795Ssam char *portselector(); 44*18543Sralph char *ttyname(); 4513795Ssam 4613828Skre #define OBUFSIZ 128 4713795Ssam #define TABBUFSIZ 512 4813795Ssam 4913795Ssam char defent[TABBUFSIZ]; 5013795Ssam char defstrs[TABBUFSIZ]; 5113795Ssam char tabent[TABBUFSIZ]; 5213795Ssam char tabstrs[TABBUFSIZ]; 5313795Ssam 5413795Ssam char *env[128]; 5513795Ssam 5613795Ssam char partab[] = { 5713795Ssam 0001,0201,0201,0001,0201,0001,0001,0201, 5813795Ssam 0202,0004,0003,0205,0005,0206,0201,0001, 5913795Ssam 0201,0001,0001,0201,0001,0201,0201,0001, 6013795Ssam 0001,0201,0201,0001,0201,0001,0001,0201, 6113795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 6213795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 6313795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 6413795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 6513795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 6613795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 6713795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 6813795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 6913795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 7013795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 7113795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 7213795Ssam 0000,0200,0200,0000,0200,0000,0000,0201 7313795Ssam }; 7413795Ssam 7513795Ssam #define ERASE tmode.sg_erase 7613795Ssam #define KILL tmode.sg_kill 7713795Ssam #define EOT tc.t_eofc 7813795Ssam 7913795Ssam jmp_buf timeout; 8013795Ssam 8113795Ssam dingdong() 8213795Ssam { 8313795Ssam 8413795Ssam alarm(0); 8513795Ssam signal(SIGALRM, SIG_DFL); 8613795Ssam longjmp(timeout, 1); 8713795Ssam } 8813795Ssam 8913828Skre jmp_buf intrupt; 9013828Skre 9113828Skre interrupt() 9213828Skre { 9313828Skre 9413828Skre signal(SIGINT, interrupt); 9513828Skre longjmp(intrupt, 1); 9613828Skre } 9713828Skre 9813795Ssam main(argc, argv) 9913795Ssam char *argv[]; 10013795Ssam { 10113795Ssam char *tname; 10213795Ssam long allflags; 103*18543Sralph int repcnt = 0; 10413795Ssam 10513828Skre signal(SIGINT, SIG_IGN); 10613795Ssam /* 10713795Ssam signal(SIGQUIT, SIG_DFL); 10813795Ssam */ 109*18543Sralph openlog("getty", LOG_ODELAY|LOG_CONS, 0); 11013795Ssam gethostname(hostname, sizeof(hostname)); 11113795Ssam if (hostname[0] == '\0') 11213795Ssam strcpy(hostname, "Amnesiac"); 113*18543Sralph /* 114*18543Sralph * The following is a work around for vhangup interactions 115*18543Sralph * which cause great problems getting window systems started. 116*18543Sralph * If the tty line is "-", we do the old style getty presuming 117*18543Sralph * that the file descriptors are already set up for us. 118*18543Sralph * J. Gettys - MIT Project Athena. 119*18543Sralph */ 120*18543Sralph if (argc <= 2 || strcmp(argv[2], "-") == 0) 121*18543Sralph strcpy(ttyn, ttyname(0)); 122*18543Sralph else { 123*18543Sralph strcpy(ttyn, dev); 124*18543Sralph strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev)); 125*18543Sralph chown(ttyn, 0, 0); 126*18543Sralph chmod(ttyn, 0622); 127*18543Sralph while (open(ttyn, O_RDWR) != 0) { 128*18543Sralph if (repcnt % 10 == 0) { 129*18543Sralph syslog(LOG_FAIL, "%s: %m", ttyn); 130*18543Sralph closelog(); 131*18543Sralph } 132*18543Sralph repcnt++; 133*18543Sralph sleep(60); 134*18543Sralph } 135*18543Sralph signal(SIGHUP, SIG_IGN); 136*18543Sralph vhangup(); 137*18543Sralph (void) open(ttyn, O_RDWR); 138*18543Sralph close(0); 139*18543Sralph dup(1); 140*18543Sralph dup(0); 141*18543Sralph signal(SIGHUP, SIG_DFL); 142*18543Sralph } 143*18543Sralph 14413795Ssam gettable("default", defent, defstrs); 14513795Ssam gendefaults(); 14613795Ssam tname = "default"; 14713795Ssam if (argc > 1) 14813795Ssam tname = argv[1]; 14913795Ssam for (;;) { 15013795Ssam int ldisp = OTTYDISC; 15113795Ssam 15213795Ssam gettable(tname, tabent, tabstrs); 15313828Skre if (OPset || EPset || APset) 15413828Skre APset++, OPset++, EPset++; 15513795Ssam setdefaults(); 15613795Ssam ioctl(0, TIOCFLUSH, 0); /* clear out the crap */ 15713795Ssam if (IS) 15813795Ssam tmode.sg_ispeed = speed(IS); 15913795Ssam else if (SP) 16013795Ssam tmode.sg_ispeed = speed(SP); 16113795Ssam if (OS) 16213795Ssam tmode.sg_ospeed = speed(OS); 16313795Ssam else if (SP) 16413795Ssam tmode.sg_ospeed = speed(SP); 16513795Ssam tmode.sg_flags = setflags(0); 16613795Ssam ioctl(0, TIOCSETP, &tmode); 16713795Ssam setchars(); 16813795Ssam ioctl(0, TIOCSETC, &tc); 16913795Ssam ioctl(0, TIOCSETD, &ldisp); 17013795Ssam if (HC) 17113795Ssam ioctl(0, TIOCHPCL, 0); 172*18543Sralph if (AB) { 173*18543Sralph extern char *autobaud(); 174*18543Sralph 175*18543Sralph tname = autobaud(); 176*18543Sralph continue; 177*18543Sralph } 17813795Ssam if (PS) { 17913795Ssam tname = portselector(); 18013795Ssam continue; 18113795Ssam } 18213795Ssam if (CL && *CL) 18313795Ssam putpad(CL); 18413795Ssam edithost(HE); 18513795Ssam if (IM && *IM) 18613795Ssam putf(IM); 18713795Ssam if (setjmp(timeout)) { 18813795Ssam tmode.sg_ispeed = tmode.sg_ospeed = 0; 18913795Ssam ioctl(0, TIOCSETP, &tmode); 19013795Ssam exit(1); 19113795Ssam } 19213795Ssam if (TO) { 19313795Ssam signal(SIGALRM, dingdong); 19413795Ssam alarm(TO); 19513795Ssam } 19613795Ssam if (getname()) { 197*18543Sralph register int i; 198*18543Sralph 199*18543Sralph oflush(); 20013795Ssam alarm(0); 20113795Ssam signal(SIGALRM, SIG_DFL); 20213831Ssam if (!(upper || lower || digit)) 20313795Ssam continue; 20413795Ssam allflags = setflags(2); 20513795Ssam tmode.sg_flags = allflags & 0xffff; 20613795Ssam allflags >>= 16; 20713795Ssam if (crmod || NL) 20813795Ssam tmode.sg_flags |= CRMOD; 20913795Ssam if (upper || UC) 21013795Ssam tmode.sg_flags |= LCASE; 21113795Ssam if (lower || LC) 21213795Ssam tmode.sg_flags &= ~LCASE; 21313795Ssam ioctl(0, TIOCSETP, &tmode); 21413795Ssam ioctl(0, TIOCSLTC, <c); 21513795Ssam ioctl(0, TIOCLSET, &allflags); 21613828Skre signal(SIGINT, SIG_DFL); 217*18543Sralph for (i = 0; environ[i] != (char *)0; i++) 218*18543Sralph env[i] = environ[i]; 219*18543Sralph makeenv(&env[i]); 220*18543Sralph execle(LO, "login", "-p", name, (char *) 0, env); 22113795Ssam exit(1); 22213795Ssam } 22313795Ssam alarm(0); 22413795Ssam signal(SIGALRM, SIG_DFL); 22513828Skre signal(SIGINT, SIG_IGN); 22613795Ssam if (NX && *NX) 22713795Ssam tname = NX; 22813795Ssam } 22913795Ssam } 23013795Ssam 23113795Ssam getname() 23213795Ssam { 23313795Ssam register char *np; 23413795Ssam register c; 23513795Ssam char cs; 23613795Ssam 23713828Skre /* 23813831Ssam * Interrupt may happen if we use CBREAK mode 23913828Skre */ 24013828Skre if (setjmp(intrupt)) { 24113828Skre signal(SIGINT, SIG_IGN); 24213828Skre return (0); 24313828Skre } 24413828Skre signal(SIGINT, interrupt); 24513795Ssam tmode.sg_flags = setflags(0); 24613795Ssam ioctl(0, TIOCSETP, &tmode); 24713795Ssam tmode.sg_flags = setflags(1); 24813795Ssam prompt(); 24913885Ssam if (PF > 0) { 25014322Ssam oflush(); 25113885Ssam sleep(PF); 25213885Ssam PF = 0; 25313885Ssam } 25413795Ssam ioctl(0, TIOCSETP, &tmode); 25513795Ssam crmod = 0; 25613795Ssam upper = 0; 25713795Ssam lower = 0; 25813795Ssam digit = 0; 25913795Ssam np = name; 26013795Ssam for (;;) { 26113828Skre oflush(); 26213795Ssam if (read(0, &cs, 1) <= 0) 26313795Ssam exit(0); 26413795Ssam if ((c = cs&0177) == 0) 26513795Ssam return (0); 26613831Ssam if (c == EOT) 26713795Ssam exit(1); 268*18543Sralph if (c == '\r' || c == '\n' || np >= &name[sizeof name]) { 269*18543Sralph putf("\r\n"); 27013795Ssam break; 271*18543Sralph } 27213831Ssam if (c >= 'a' && c <= 'z') 27313795Ssam lower++; 274*18543Sralph else if (c >= 'A' && c <= 'Z') 27513795Ssam upper++; 276*18543Sralph else if (c == ERASE || c == '#' || c == '\b') { 27713795Ssam if (np > name) { 27813795Ssam np--; 27913795Ssam if (tmode.sg_ospeed >= B1200) 28013795Ssam puts("\b \b"); 28113795Ssam else 28213795Ssam putchr(cs); 28313795Ssam } 28413795Ssam continue; 28513831Ssam } else if (c == KILL || c == '@') { 28613795Ssam putchr(cs); 28713795Ssam putchr('\r'); 28813795Ssam if (tmode.sg_ospeed < B1200) 28913795Ssam putchr('\n'); 29013795Ssam /* this is the way they do it down under ... */ 29113795Ssam else if (np > name) 29213795Ssam puts(" \r"); 29313795Ssam prompt(); 29413795Ssam np = name; 29513795Ssam continue; 296*18543Sralph } else if (c >= '0' && c <= '9') 29713795Ssam digit++; 298*18543Sralph if (IG && (c <= ' ' || c > 0176)) 29913795Ssam continue; 30013795Ssam *np++ = c; 30113795Ssam putchr(cs); 30213795Ssam } 30313828Skre signal(SIGINT, SIG_IGN); 30413795Ssam *np = 0; 30513795Ssam if (c == '\r') 30613795Ssam crmod++; 30713795Ssam if (upper && !lower && !LC || UC) 30813795Ssam for (np = name; *np; np++) 30913795Ssam if (isupper(*np)) 31013795Ssam *np = tolower(*np); 31113795Ssam return (1); 31213795Ssam } 31313795Ssam 31413795Ssam static 31513795Ssam short tmspc10[] = { 31613795Ssam 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15 31713795Ssam }; 31813795Ssam 31913795Ssam putpad(s) 32013795Ssam register char *s; 32113795Ssam { 32213795Ssam register pad = 0; 32313795Ssam register mspc10; 32413795Ssam 32513795Ssam if (isdigit(*s)) { 32613795Ssam while (isdigit(*s)) { 32713795Ssam pad *= 10; 32813795Ssam pad += *s++ - '0'; 32913795Ssam } 33013795Ssam pad *= 10; 33113795Ssam if (*s == '.' && isdigit(s[1])) { 33213795Ssam pad += s[1] - '0'; 33313795Ssam s += 2; 33413795Ssam } 33513795Ssam } 33613795Ssam 33713795Ssam puts(s); 33813795Ssam /* 33913795Ssam * If no delay needed, or output speed is 34013795Ssam * not comprehensible, then don't try to delay. 34113795Ssam */ 34213795Ssam if (pad == 0) 34313795Ssam return; 34413795Ssam if (tmode.sg_ospeed <= 0 || 34513795Ssam tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0])) 34613795Ssam return; 34713795Ssam 34813795Ssam /* 34913795Ssam * Round up by a half a character frame, 35013795Ssam * and then do the delay. 35113795Ssam * Too bad there are no user program accessible programmed delays. 35213795Ssam * Transmitting pad characters slows many 35313795Ssam * terminals down and also loads the system. 35413795Ssam */ 35513795Ssam mspc10 = tmspc10[tmode.sg_ospeed]; 35613795Ssam pad += mspc10 / 2; 35713795Ssam for (pad /= mspc10; pad > 0; pad--) 35813795Ssam putchr(*PC); 35913795Ssam } 36013795Ssam 36113795Ssam puts(s) 36213795Ssam register char *s; 36313795Ssam { 36413795Ssam 36513795Ssam while (*s) 36613795Ssam putchr(*s++); 36713795Ssam } 36813795Ssam 36913828Skre char outbuf[OBUFSIZ]; 37013828Skre int obufcnt = 0; 37113828Skre 37213795Ssam putchr(cc) 37313795Ssam { 37413795Ssam char c; 37513795Ssam 37613795Ssam c = cc; 37713795Ssam c |= partab[c&0177] & 0200; 37813795Ssam if (OP) 37913795Ssam c ^= 0200; 38013828Skre if (!UB) { 38113828Skre outbuf[obufcnt++] = c; 38213828Skre if (obufcnt >= OBUFSIZ) 38313828Skre oflush(); 38413828Skre } else 38513828Skre write(1, &c, 1); 38613795Ssam } 38713795Ssam 38813828Skre oflush() 38913828Skre { 39013828Skre if (obufcnt) 39113828Skre write(1, outbuf, obufcnt); 39213828Skre obufcnt = 0; 39313828Skre } 39413828Skre 39513795Ssam prompt() 39613795Ssam { 39713795Ssam 39813795Ssam putf(LM); 39913795Ssam if (CO) 40013795Ssam putchr('\n'); 40113795Ssam } 40213795Ssam 40313795Ssam putf(cp) 40413795Ssam register char *cp; 40513795Ssam { 406*18543Sralph char *ttyn, *slash; 407*18543Sralph char datebuffer[60]; 40813795Ssam extern char editedhost[]; 409*18543Sralph extern char *ttyname(), *rindex(); 41013795Ssam 41113795Ssam while (*cp) { 41213795Ssam if (*cp != '%') { 41313795Ssam putchr(*cp++); 41413795Ssam continue; 41513795Ssam } 41613795Ssam switch (*++cp) { 41713795Ssam 418*18543Sralph case 't': 419*18543Sralph ttyn = ttyname(0); 420*18543Sralph slash = rindex(ttyn, '/'); 421*18543Sralph if (slash == (char *) 0) 422*18543Sralph puts(ttyn); 423*18543Sralph else 424*18543Sralph puts(&slash[1]); 425*18543Sralph break; 426*18543Sralph 42713795Ssam case 'h': 42813795Ssam puts(editedhost); 42913795Ssam break; 43013795Ssam 431*18543Sralph case 'd': 432*18543Sralph get_date(datebuffer); 433*18543Sralph puts(datebuffer); 43415713Sralph break; 43515713Sralph 43613795Ssam case '%': 43713795Ssam putchr('%'); 43813795Ssam break; 43913795Ssam } 44013795Ssam cp++; 44113795Ssam } 44213795Ssam } 443