113795Ssam #ifndef lint 2*13885Ssam static char sccsid[] = "@(#)main.c 4.4 (Berkeley) 83/07/09"; 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(); 199*13885Ssam if (PF > 0) { 200*13885Ssam sleep(PF); 201*13885Ssam PF = 0; 202*13885Ssam } 20313795Ssam ioctl(0, TIOCSETP, &tmode); 20413795Ssam crmod = 0; 20513795Ssam upper = 0; 20613795Ssam lower = 0; 20713795Ssam digit = 0; 20813795Ssam np = name; 20913795Ssam for (;;) { 21013828Skre oflush(); 21113795Ssam if (read(0, &cs, 1) <= 0) 21213795Ssam exit(0); 21313795Ssam if ((c = cs&0177) == 0) 21413795Ssam return (0); 21513831Ssam if (c == EOT) 21613795Ssam exit(1); 21713831Ssam if (c == '\r' || c == '\n' || np >= &name[16]) 21813795Ssam break; 21913795Ssam 22013831Ssam if (c >= 'a' && c <= 'z') 22113795Ssam lower++; 22213831Ssam else if (c >= 'A' && c <= 'Z') { 22313795Ssam upper++; 22413831Ssam } else if (c == ERASE || c == '#' || c == '\b') { 22513795Ssam if (np > name) { 22613795Ssam np--; 22713795Ssam if (tmode.sg_ospeed >= B1200) 22813795Ssam puts("\b \b"); 22913795Ssam else 23013795Ssam putchr(cs); 23113795Ssam } 23213795Ssam continue; 23313831Ssam } else if (c == KILL || c == '@') { 23413795Ssam putchr(cs); 23513795Ssam putchr('\r'); 23613795Ssam if (tmode.sg_ospeed < B1200) 23713795Ssam putchr('\n'); 23813795Ssam /* this is the way they do it down under ... */ 23913795Ssam else if (np > name) 24013795Ssam puts(" \r"); 24113795Ssam prompt(); 24213795Ssam np = name; 24313795Ssam continue; 24413795Ssam } else if (c == ' ') 24513795Ssam c = '_'; 24613795Ssam else if (c >= '0' && c <= '9') 24713795Ssam digit++; 24813795Ssam if (IG && (c < ' ' || c > 0176)) 24913795Ssam continue; 25013795Ssam *np++ = c; 25113795Ssam putchr(cs); 25213795Ssam } 25313828Skre signal(SIGINT, SIG_IGN); 25413795Ssam *np = 0; 25513795Ssam if (c == '\r') 25613795Ssam crmod++; 25713795Ssam if (upper && !lower && !LC || UC) 25813795Ssam for (np = name; *np; np++) 25913795Ssam if (isupper(*np)) 26013795Ssam *np = tolower(*np); 26113795Ssam return (1); 26213795Ssam } 26313795Ssam 26413795Ssam static 26513795Ssam short tmspc10[] = { 26613795Ssam 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15 26713795Ssam }; 26813795Ssam 26913795Ssam putpad(s) 27013795Ssam register char *s; 27113795Ssam { 27213795Ssam register pad = 0; 27313795Ssam register mspc10; 27413795Ssam 27513795Ssam if (isdigit(*s)) { 27613795Ssam while (isdigit(*s)) { 27713795Ssam pad *= 10; 27813795Ssam pad += *s++ - '0'; 27913795Ssam } 28013795Ssam pad *= 10; 28113795Ssam if (*s == '.' && isdigit(s[1])) { 28213795Ssam pad += s[1] - '0'; 28313795Ssam s += 2; 28413795Ssam } 28513795Ssam } 28613795Ssam 28713795Ssam puts(s); 28813795Ssam /* 28913795Ssam * If no delay needed, or output speed is 29013795Ssam * not comprehensible, then don't try to delay. 29113795Ssam */ 29213795Ssam if (pad == 0) 29313795Ssam return; 29413795Ssam if (tmode.sg_ospeed <= 0 || 29513795Ssam tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0])) 29613795Ssam return; 29713795Ssam 29813795Ssam /* 29913795Ssam * Round up by a half a character frame, 30013795Ssam * and then do the delay. 30113795Ssam * Too bad there are no user program accessible programmed delays. 30213795Ssam * Transmitting pad characters slows many 30313795Ssam * terminals down and also loads the system. 30413795Ssam */ 30513795Ssam mspc10 = tmspc10[tmode.sg_ospeed]; 30613795Ssam pad += mspc10 / 2; 30713795Ssam for (pad /= mspc10; pad > 0; pad--) 30813795Ssam putchr(*PC); 30913795Ssam } 31013795Ssam 31113795Ssam puts(s) 31213795Ssam register char *s; 31313795Ssam { 31413795Ssam 31513795Ssam while (*s) 31613795Ssam putchr(*s++); 31713795Ssam } 31813795Ssam 31913828Skre char outbuf[OBUFSIZ]; 32013828Skre int obufcnt = 0; 32113828Skre 32213795Ssam putchr(cc) 32313795Ssam { 32413795Ssam char c; 32513795Ssam 32613795Ssam c = cc; 32713795Ssam c |= partab[c&0177] & 0200; 32813795Ssam if (OP) 32913795Ssam c ^= 0200; 33013828Skre if (!UB) { 33113828Skre outbuf[obufcnt++] = c; 33213828Skre if (obufcnt >= OBUFSIZ) 33313828Skre oflush(); 33413828Skre } else 33513828Skre write(1, &c, 1); 33613795Ssam } 33713795Ssam 33813828Skre oflush() 33913828Skre { 34013828Skre if (obufcnt) 34113828Skre write(1, outbuf, obufcnt); 34213828Skre obufcnt = 0; 34313828Skre } 34413828Skre 34513795Ssam prompt() 34613795Ssam { 34713795Ssam 34813795Ssam putf(LM); 34913795Ssam if (CO) 35013795Ssam putchr('\n'); 35113795Ssam } 35213795Ssam 35313795Ssam putf(cp) 35413795Ssam register char *cp; 35513795Ssam { 35613795Ssam extern char editedhost[]; 35713795Ssam 35813795Ssam while (*cp) { 35913795Ssam if (*cp != '%') { 36013795Ssam putchr(*cp++); 36113795Ssam continue; 36213795Ssam } 36313795Ssam switch (*++cp) { 36413795Ssam 36513795Ssam case 'h': 36613795Ssam puts(editedhost); 36713795Ssam break; 36813795Ssam 36913795Ssam case '%': 37013795Ssam putchr('%'); 37113795Ssam break; 37213795Ssam } 37313795Ssam cp++; 37413795Ssam } 37513795Ssam } 376