113795Ssam #ifndef lint 2*14322Ssam static char sccsid[] = "@(#)main.c 4.5 (Berkeley) 83/08/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> 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 3813828Skre #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 8113828Skre jmp_buf intrupt; 8213828Skre 8313828Skre interrupt() 8413828Skre { 8513828Skre 8613828Skre signal(SIGINT, interrupt); 8713828Skre longjmp(intrupt, 1); 8813828Skre } 8913828Skre 9013795Ssam main(argc, argv) 9113795Ssam char *argv[]; 9213795Ssam { 9313795Ssam char *tname; 9413795Ssam long allflags; 9513795Ssam 9613828Skre 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); 11213828Skre if (OPset || EPset || APset) 11313828Skre 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); 15213831Ssam 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'); 16713831Ssam oflush(); 16813795Ssam makeenv(env); 16913828Skre signal(SIGINT, SIG_DFL); 17013795Ssam execle(LO, "login", name, (char *)0, env); 17113795Ssam exit(1); 17213795Ssam } 17313795Ssam alarm(0); 17413795Ssam signal(SIGALRM, SIG_DFL); 17513828Skre signal(SIGINT, SIG_IGN); 17613795Ssam if (NX && *NX) 17713795Ssam tname = NX; 17813795Ssam } 17913795Ssam } 18013795Ssam 18113795Ssam getname() 18213795Ssam { 18313795Ssam register char *np; 18413795Ssam register c; 18513795Ssam char cs; 18613795Ssam 18713828Skre /* 18813831Ssam * Interrupt may happen if we use CBREAK mode 18913828Skre */ 19013828Skre if (setjmp(intrupt)) { 19113828Skre signal(SIGINT, SIG_IGN); 19213828Skre return (0); 19313828Skre } 19413828Skre signal(SIGINT, interrupt); 19513795Ssam tmode.sg_flags = setflags(0); 19613795Ssam ioctl(0, TIOCSETP, &tmode); 19713795Ssam tmode.sg_flags = setflags(1); 19813795Ssam prompt(); 19913885Ssam if (PF > 0) { 200*14322Ssam oflush(); 20113885Ssam sleep(PF); 20213885Ssam PF = 0; 20313885Ssam } 20413795Ssam ioctl(0, TIOCSETP, &tmode); 20513795Ssam crmod = 0; 20613795Ssam upper = 0; 20713795Ssam lower = 0; 20813795Ssam digit = 0; 20913795Ssam np = name; 21013795Ssam for (;;) { 21113828Skre oflush(); 21213795Ssam if (read(0, &cs, 1) <= 0) 21313795Ssam exit(0); 21413795Ssam if ((c = cs&0177) == 0) 21513795Ssam return (0); 21613831Ssam if (c == EOT) 21713795Ssam exit(1); 21813831Ssam if (c == '\r' || c == '\n' || np >= &name[16]) 21913795Ssam break; 22013795Ssam 22113831Ssam if (c >= 'a' && c <= 'z') 22213795Ssam lower++; 22313831Ssam else if (c >= 'A' && c <= 'Z') { 22413795Ssam upper++; 22513831Ssam } else if (c == ERASE || c == '#' || c == '\b') { 22613795Ssam if (np > name) { 22713795Ssam np--; 22813795Ssam if (tmode.sg_ospeed >= B1200) 22913795Ssam puts("\b \b"); 23013795Ssam else 23113795Ssam putchr(cs); 23213795Ssam } 23313795Ssam continue; 23413831Ssam } else if (c == KILL || c == '@') { 23513795Ssam putchr(cs); 23613795Ssam putchr('\r'); 23713795Ssam if (tmode.sg_ospeed < B1200) 23813795Ssam putchr('\n'); 23913795Ssam /* this is the way they do it down under ... */ 24013795Ssam else if (np > name) 24113795Ssam puts(" \r"); 24213795Ssam prompt(); 24313795Ssam np = name; 24413795Ssam continue; 24513795Ssam } else if (c == ' ') 24613795Ssam c = '_'; 24713795Ssam else if (c >= '0' && c <= '9') 24813795Ssam digit++; 24913795Ssam if (IG && (c < ' ' || c > 0176)) 25013795Ssam continue; 25113795Ssam *np++ = c; 25213795Ssam putchr(cs); 25313795Ssam } 25413828Skre signal(SIGINT, SIG_IGN); 25513795Ssam *np = 0; 25613795Ssam if (c == '\r') 25713795Ssam crmod++; 25813795Ssam if (upper && !lower && !LC || UC) 25913795Ssam for (np = name; *np; np++) 26013795Ssam if (isupper(*np)) 26113795Ssam *np = tolower(*np); 26213795Ssam return (1); 26313795Ssam } 26413795Ssam 26513795Ssam static 26613795Ssam short tmspc10[] = { 26713795Ssam 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15 26813795Ssam }; 26913795Ssam 27013795Ssam putpad(s) 27113795Ssam register char *s; 27213795Ssam { 27313795Ssam register pad = 0; 27413795Ssam register mspc10; 27513795Ssam 27613795Ssam if (isdigit(*s)) { 27713795Ssam while (isdigit(*s)) { 27813795Ssam pad *= 10; 27913795Ssam pad += *s++ - '0'; 28013795Ssam } 28113795Ssam pad *= 10; 28213795Ssam if (*s == '.' && isdigit(s[1])) { 28313795Ssam pad += s[1] - '0'; 28413795Ssam s += 2; 28513795Ssam } 28613795Ssam } 28713795Ssam 28813795Ssam puts(s); 28913795Ssam /* 29013795Ssam * If no delay needed, or output speed is 29113795Ssam * not comprehensible, then don't try to delay. 29213795Ssam */ 29313795Ssam if (pad == 0) 29413795Ssam return; 29513795Ssam if (tmode.sg_ospeed <= 0 || 29613795Ssam tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0])) 29713795Ssam return; 29813795Ssam 29913795Ssam /* 30013795Ssam * Round up by a half a character frame, 30113795Ssam * and then do the delay. 30213795Ssam * Too bad there are no user program accessible programmed delays. 30313795Ssam * Transmitting pad characters slows many 30413795Ssam * terminals down and also loads the system. 30513795Ssam */ 30613795Ssam mspc10 = tmspc10[tmode.sg_ospeed]; 30713795Ssam pad += mspc10 / 2; 30813795Ssam for (pad /= mspc10; pad > 0; pad--) 30913795Ssam putchr(*PC); 31013795Ssam } 31113795Ssam 31213795Ssam puts(s) 31313795Ssam register char *s; 31413795Ssam { 31513795Ssam 31613795Ssam while (*s) 31713795Ssam putchr(*s++); 31813795Ssam } 31913795Ssam 32013828Skre char outbuf[OBUFSIZ]; 32113828Skre int obufcnt = 0; 32213828Skre 32313795Ssam putchr(cc) 32413795Ssam { 32513795Ssam char c; 32613795Ssam 32713795Ssam c = cc; 32813795Ssam c |= partab[c&0177] & 0200; 32913795Ssam if (OP) 33013795Ssam c ^= 0200; 33113828Skre if (!UB) { 33213828Skre outbuf[obufcnt++] = c; 33313828Skre if (obufcnt >= OBUFSIZ) 33413828Skre oflush(); 33513828Skre } else 33613828Skre write(1, &c, 1); 33713795Ssam } 33813795Ssam 33913828Skre oflush() 34013828Skre { 34113828Skre if (obufcnt) 34213828Skre write(1, outbuf, obufcnt); 34313828Skre obufcnt = 0; 34413828Skre } 34513828Skre 34613795Ssam prompt() 34713795Ssam { 34813795Ssam 34913795Ssam putf(LM); 35013795Ssam if (CO) 35113795Ssam putchr('\n'); 35213795Ssam } 35313795Ssam 35413795Ssam putf(cp) 35513795Ssam register char *cp; 35613795Ssam { 35713795Ssam extern char editedhost[]; 35813795Ssam 35913795Ssam while (*cp) { 36013795Ssam if (*cp != '%') { 36113795Ssam putchr(*cp++); 36213795Ssam continue; 36313795Ssam } 36413795Ssam switch (*++cp) { 36513795Ssam 36613795Ssam case 'h': 36713795Ssam puts(editedhost); 36813795Ssam break; 36913795Ssam 37013795Ssam case '%': 37113795Ssam putchr('%'); 37213795Ssam break; 37313795Ssam } 37413795Ssam cp++; 37513795Ssam } 37613795Ssam } 377