113795Ssam #ifndef lint 2*13828Skre static char sccsid[] = "@(#)main.c 4.2 (Berkeley) 83/07/07"; 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> 1513795Ssam #include "gettytab.h" 1613795Ssam 1713795Ssam struct sgttyb tmode = { 1813795Ssam 0, 0, CERASE, CKILL, 0 1913795Ssam }; 2013795Ssam struct tchars tc = { 2113795Ssam CINTR, CQUIT, CSTART, 2213795Ssam CSTOP, CEOF, CBRK, 2313795Ssam }; 2413795Ssam struct ltchars ltc = { 2513795Ssam CSUSP, CDSUSP, CRPRNT, 2613795Ssam CFLUSH, CWERASE, CLNEXT 2713795Ssam }; 2813795Ssam 2913795Ssam int crmod; 3013795Ssam int upper; 3113795Ssam int lower; 3213795Ssam int digit; 3313795Ssam 3413795Ssam char hostname[32]; 3513795Ssam char name[16]; 3613795Ssam char *portselector(); 3713795Ssam 38*13828Skre #define OBUFSIZ 128 3913795Ssam #define TABBUFSIZ 512 4013795Ssam 4113795Ssam char defent[TABBUFSIZ]; 4213795Ssam char defstrs[TABBUFSIZ]; 4313795Ssam char tabent[TABBUFSIZ]; 4413795Ssam char tabstrs[TABBUFSIZ]; 4513795Ssam 4613795Ssam char *env[128]; 4713795Ssam 4813795Ssam char partab[] = { 4913795Ssam 0001,0201,0201,0001,0201,0001,0001,0201, 5013795Ssam 0202,0004,0003,0205,0005,0206,0201,0001, 5113795Ssam 0201,0001,0001,0201,0001,0201,0201,0001, 5213795Ssam 0001,0201,0201,0001,0201,0001,0001,0201, 5313795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 5413795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 5513795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 5613795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 5713795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 5813795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 5913795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 6013795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 6113795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 6213795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 6313795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 6413795Ssam 0000,0200,0200,0000,0200,0000,0000,0201 6513795Ssam }; 6613795Ssam 6713795Ssam #define ERASE tmode.sg_erase 6813795Ssam #define KILL tmode.sg_kill 6913795Ssam #define EOT tc.t_eofc 7013795Ssam 7113795Ssam jmp_buf timeout; 7213795Ssam 7313795Ssam dingdong() 7413795Ssam { 7513795Ssam 7613795Ssam alarm(0); 7713795Ssam signal(SIGALRM, SIG_DFL); 7813795Ssam longjmp(timeout, 1); 7913795Ssam } 8013795Ssam 81*13828Skre jmp_buf intrupt; 82*13828Skre 83*13828Skre interrupt() 84*13828Skre { 85*13828Skre 86*13828Skre signal(SIGINT, interrupt); 87*13828Skre longjmp(intrupt, 1); 88*13828Skre } 89*13828Skre 9013795Ssam main(argc, argv) 9113795Ssam char *argv[]; 9213795Ssam { 9313795Ssam char *tname; 9413795Ssam long allflags; 9513795Ssam 96*13828Skre signal(SIGINT, SIG_IGN); 9713795Ssam /* 9813795Ssam signal(SIGQUIT, SIG_DFL); 9913795Ssam */ 10013795Ssam gethostname(hostname, sizeof(hostname)); 10113795Ssam if (hostname[0] == '\0') 10213795Ssam strcpy(hostname, "Amnesiac"); 10313795Ssam gettable("default", defent, defstrs); 10413795Ssam gendefaults(); 10513795Ssam tname = "default"; 10613795Ssam if (argc > 1) 10713795Ssam tname = argv[1]; 10813795Ssam for (;;) { 10913795Ssam int ldisp = OTTYDISC; 11013795Ssam 11113795Ssam gettable(tname, tabent, tabstrs); 112*13828Skre if (OPset || EPset || APset) 113*13828Skre APset++, OPset++, EPset++; 11413795Ssam setdefaults(); 11513795Ssam ioctl(0, TIOCFLUSH, 0); /* clear out the crap */ 11613795Ssam if (IS) 11713795Ssam tmode.sg_ispeed = speed(IS); 11813795Ssam else if (SP) 11913795Ssam tmode.sg_ispeed = speed(SP); 12013795Ssam if (OS) 12113795Ssam tmode.sg_ospeed = speed(OS); 12213795Ssam else if (SP) 12313795Ssam tmode.sg_ospeed = speed(SP); 12413795Ssam tmode.sg_flags = setflags(0); 12513795Ssam ioctl(0, TIOCSETP, &tmode); 12613795Ssam setchars(); 12713795Ssam ioctl(0, TIOCSETC, &tc); 12813795Ssam ioctl(0, TIOCSETD, &ldisp); 12913795Ssam if (HC) 13013795Ssam ioctl(0, TIOCHPCL, 0); 13113795Ssam if (PS) { 13213795Ssam tname = portselector(); 13313795Ssam continue; 13413795Ssam } 13513795Ssam if (CL && *CL) 13613795Ssam putpad(CL); 13713795Ssam edithost(HE); 13813795Ssam if (IM && *IM) 13913795Ssam putf(IM); 14013795Ssam if (setjmp(timeout)) { 14113795Ssam tmode.sg_ispeed = tmode.sg_ospeed = 0; 14213795Ssam ioctl(0, TIOCSETP, &tmode); 14313795Ssam exit(1); 14413795Ssam } 14513795Ssam if (TO) { 14613795Ssam signal(SIGALRM, dingdong); 14713795Ssam alarm(TO); 14813795Ssam } 14913795Ssam if (getname()) { 15013795Ssam alarm(0); 15113795Ssam signal(SIGALRM, SIG_DFL); 15213795Ssam if (!(upper||lower||digit)) 15313795Ssam continue; 15413795Ssam allflags = setflags(2); 15513795Ssam tmode.sg_flags = allflags & 0xffff; 15613795Ssam allflags >>= 16; 15713795Ssam if (crmod || NL) 15813795Ssam tmode.sg_flags |= CRMOD; 15913795Ssam if (upper || UC) 16013795Ssam tmode.sg_flags |= LCASE; 16113795Ssam if (lower || LC) 16213795Ssam tmode.sg_flags &= ~LCASE; 16313795Ssam ioctl(0, TIOCSETP, &tmode); 16413795Ssam ioctl(0, TIOCSLTC, <c); 16513795Ssam ioctl(0, TIOCLSET, &allflags); 16613795Ssam putchr('\n'); 16713795Ssam makeenv(env); 168*13828Skre signal(SIGINT, SIG_DFL); 16913795Ssam execle(LO, "login", name, (char *)0, env); 17013795Ssam exit(1); 17113795Ssam } 17213795Ssam alarm(0); 17313795Ssam signal(SIGALRM, SIG_DFL); 174*13828Skre signal(SIGINT, SIG_IGN); 17513795Ssam if (NX && *NX) 17613795Ssam tname = NX; 17713795Ssam } 17813795Ssam } 17913795Ssam 18013795Ssam getname() 18113795Ssam { 18213795Ssam register char *np; 18313795Ssam register c; 18413795Ssam char cs; 18513795Ssam 186*13828Skre /* 187*13828Skre * interrupt may happen if we use CBREAK mode 188*13828Skre */ 189*13828Skre if (setjmp(intrupt)) { 190*13828Skre signal(SIGINT, SIG_IGN); 191*13828Skre return (0); 192*13828Skre } 193*13828Skre signal(SIGINT, interrupt); 19413795Ssam tmode.sg_flags = setflags(0); 19513795Ssam ioctl(0, TIOCSETP, &tmode); 19613795Ssam tmode.sg_flags = setflags(1); 19713795Ssam prompt(); 19813795Ssam ioctl(0, TIOCSETP, &tmode); 19913795Ssam crmod = 0; 20013795Ssam upper = 0; 20113795Ssam lower = 0; 20213795Ssam digit = 0; 20313795Ssam np = name; 20413795Ssam for (;;) { 205*13828Skre oflush(); 20613795Ssam if (read(0, &cs, 1) <= 0) 20713795Ssam exit(0); 20813795Ssam if ((c = cs&0177) == 0) 20913795Ssam return (0); 21013795Ssam if (c==EOT) 21113795Ssam exit(1); 21213795Ssam if (c=='\r' || c=='\n' || np >= &name[16]) 21313795Ssam break; 21413795Ssam 21513795Ssam if (c>='a' && c <='z') 21613795Ssam lower++; 21713795Ssam else if (c>='A' && c<='Z') { 21813795Ssam upper++; 219*13828Skre } else if (c==ERASE || c=='#' || c=='\b') { 22013795Ssam if (np > name) { 22113795Ssam np--; 22213795Ssam if (tmode.sg_ospeed >= B1200) 22313795Ssam puts("\b \b"); 22413795Ssam else 22513795Ssam putchr(cs); 22613795Ssam } 22713795Ssam continue; 228*13828Skre } else if (c==KILL || c=='@') { 22913795Ssam putchr(cs); 23013795Ssam putchr('\r'); 23113795Ssam if (tmode.sg_ospeed < B1200) 23213795Ssam putchr('\n'); 23313795Ssam /* this is the way they do it down under ... */ 23413795Ssam else if (np > name) 23513795Ssam puts(" \r"); 23613795Ssam prompt(); 23713795Ssam np = name; 23813795Ssam continue; 23913795Ssam } else if (c == ' ') 24013795Ssam c = '_'; 24113795Ssam else if (c >= '0' && c <= '9') 24213795Ssam digit++; 24313795Ssam if (IG && (c < ' ' || c > 0176)) 24413795Ssam continue; 24513795Ssam *np++ = c; 24613795Ssam putchr(cs); 24713795Ssam } 248*13828Skre signal(SIGINT, SIG_IGN); 24913795Ssam *np = 0; 25013795Ssam if (c == '\r') 25113795Ssam crmod++; 25213795Ssam if (upper && !lower && !LC || UC) 25313795Ssam for (np = name; *np; np++) 25413795Ssam if (isupper(*np)) 25513795Ssam *np = tolower(*np); 25613795Ssam return (1); 25713795Ssam } 25813795Ssam 25913795Ssam static 26013795Ssam short tmspc10[] = { 26113795Ssam 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15 26213795Ssam }; 26313795Ssam 26413795Ssam putpad(s) 26513795Ssam register char *s; 26613795Ssam { 26713795Ssam register pad = 0; 26813795Ssam register mspc10; 26913795Ssam 27013795Ssam if (isdigit(*s)) { 27113795Ssam while (isdigit(*s)) { 27213795Ssam pad *= 10; 27313795Ssam pad += *s++ - '0'; 27413795Ssam } 27513795Ssam pad *= 10; 27613795Ssam if (*s == '.' && isdigit(s[1])) { 27713795Ssam pad += s[1] - '0'; 27813795Ssam s += 2; 27913795Ssam } 28013795Ssam } 28113795Ssam 28213795Ssam puts(s); 28313795Ssam /* 28413795Ssam * If no delay needed, or output speed is 28513795Ssam * not comprehensible, then don't try to delay. 28613795Ssam */ 28713795Ssam if (pad == 0) 28813795Ssam return; 28913795Ssam if (tmode.sg_ospeed <= 0 || 29013795Ssam tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0])) 29113795Ssam return; 29213795Ssam 29313795Ssam /* 29413795Ssam * Round up by a half a character frame, 29513795Ssam * and then do the delay. 29613795Ssam * Too bad there are no user program accessible programmed delays. 29713795Ssam * Transmitting pad characters slows many 29813795Ssam * terminals down and also loads the system. 29913795Ssam */ 30013795Ssam mspc10 = tmspc10[tmode.sg_ospeed]; 30113795Ssam pad += mspc10 / 2; 30213795Ssam for (pad /= mspc10; pad > 0; pad--) 30313795Ssam putchr(*PC); 30413795Ssam } 30513795Ssam 30613795Ssam puts(s) 30713795Ssam register char *s; 30813795Ssam { 30913795Ssam 31013795Ssam while (*s) 31113795Ssam putchr(*s++); 31213795Ssam } 31313795Ssam 314*13828Skre char outbuf[OBUFSIZ]; 315*13828Skre int obufcnt = 0; 316*13828Skre 31713795Ssam putchr(cc) 31813795Ssam { 31913795Ssam char c; 32013795Ssam 32113795Ssam c = cc; 32213795Ssam c |= partab[c&0177] & 0200; 32313795Ssam if (OP) 32413795Ssam c ^= 0200; 325*13828Skre if (!UB) { 326*13828Skre outbuf[obufcnt++] = c; 327*13828Skre if (obufcnt >= OBUFSIZ) 328*13828Skre oflush(); 329*13828Skre } else 330*13828Skre write(1, &c, 1); 33113795Ssam } 33213795Ssam 333*13828Skre oflush() 334*13828Skre { 335*13828Skre if (obufcnt) 336*13828Skre write(1, outbuf, obufcnt); 337*13828Skre obufcnt = 0; 338*13828Skre } 339*13828Skre 34013795Ssam prompt() 34113795Ssam { 34213795Ssam 34313795Ssam putf(LM); 34413795Ssam if (CO) 34513795Ssam putchr('\n'); 34613795Ssam } 34713795Ssam 34813795Ssam putf(cp) 34913795Ssam register char *cp; 35013795Ssam { 35113795Ssam extern char editedhost[]; 35213795Ssam 35313795Ssam while (*cp) { 35413795Ssam if (*cp != '%') { 35513795Ssam putchr(*cp++); 35613795Ssam continue; 35713795Ssam } 35813795Ssam switch (*++cp) { 35913795Ssam 36013795Ssam case 'h': 36113795Ssam puts(editedhost); 36213795Ssam break; 36313795Ssam 36413795Ssam case '%': 36513795Ssam putchr('%'); 36613795Ssam break; 36713795Ssam } 36813795Ssam cp++; 36913795Ssam } 37013795Ssam } 371