1*13795Ssam #ifndef lint 2*13795Ssam static char sccsid[] = "@(#)main.c 4.1 (Berkeley) 83/07/06"; 3*13795Ssam #endif 4*13795Ssam 5*13795Ssam /* 6*13795Ssam * getty -- adapt to terminal speed on dialup, and call login 7*13795Ssam * 8*13795Ssam * Melbourne getty, June 83, kre. 9*13795Ssam */ 10*13795Ssam 11*13795Ssam #include <sgtty.h> 12*13795Ssam #include <signal.h> 13*13795Ssam #include <ctype.h> 14*13795Ssam #include <setjmp.h> 15*13795Ssam #include "gettytab.h" 16*13795Ssam 17*13795Ssam struct sgttyb tmode = { 18*13795Ssam 0, 0, CERASE, CKILL, 0 19*13795Ssam }; 20*13795Ssam struct tchars tc = { 21*13795Ssam CINTR, CQUIT, CSTART, 22*13795Ssam CSTOP, CEOF, CBRK, 23*13795Ssam }; 24*13795Ssam struct ltchars ltc = { 25*13795Ssam CSUSP, CDSUSP, CRPRNT, 26*13795Ssam CFLUSH, CWERASE, CLNEXT 27*13795Ssam }; 28*13795Ssam 29*13795Ssam int crmod; 30*13795Ssam int upper; 31*13795Ssam int lower; 32*13795Ssam int digit; 33*13795Ssam 34*13795Ssam char hostname[32]; 35*13795Ssam char name[16]; 36*13795Ssam char *portselector(); 37*13795Ssam 38*13795Ssam #define TABBUFSIZ 512 39*13795Ssam 40*13795Ssam char defent[TABBUFSIZ]; 41*13795Ssam char defstrs[TABBUFSIZ]; 42*13795Ssam char tabent[TABBUFSIZ]; 43*13795Ssam char tabstrs[TABBUFSIZ]; 44*13795Ssam 45*13795Ssam char *env[128]; 46*13795Ssam 47*13795Ssam char partab[] = { 48*13795Ssam 0001,0201,0201,0001,0201,0001,0001,0201, 49*13795Ssam 0202,0004,0003,0205,0005,0206,0201,0001, 50*13795Ssam 0201,0001,0001,0201,0001,0201,0201,0001, 51*13795Ssam 0001,0201,0201,0001,0201,0001,0001,0201, 52*13795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 53*13795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 54*13795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 55*13795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 56*13795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 57*13795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 58*13795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 59*13795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 60*13795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 61*13795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 62*13795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 63*13795Ssam 0000,0200,0200,0000,0200,0000,0000,0201 64*13795Ssam }; 65*13795Ssam 66*13795Ssam #define ERASE tmode.sg_erase 67*13795Ssam #define KILL tmode.sg_kill 68*13795Ssam #define EOT tc.t_eofc 69*13795Ssam 70*13795Ssam jmp_buf timeout; 71*13795Ssam 72*13795Ssam dingdong() 73*13795Ssam { 74*13795Ssam 75*13795Ssam alarm(0); 76*13795Ssam signal(SIGALRM, SIG_DFL); 77*13795Ssam longjmp(timeout, 1); 78*13795Ssam } 79*13795Ssam 80*13795Ssam main(argc, argv) 81*13795Ssam char *argv[]; 82*13795Ssam { 83*13795Ssam char *tname; 84*13795Ssam long allflags; 85*13795Ssam 86*13795Ssam /* 87*13795Ssam signal(SIGINT, SIG_IGN); 88*13795Ssam signal(SIGQUIT, SIG_DFL); 89*13795Ssam */ 90*13795Ssam gethostname(hostname, sizeof(hostname)); 91*13795Ssam if (hostname[0] == '\0') 92*13795Ssam strcpy(hostname, "Amnesiac"); 93*13795Ssam gettable("default", defent, defstrs); 94*13795Ssam gendefaults(); 95*13795Ssam tname = "default"; 96*13795Ssam if (argc > 1) 97*13795Ssam tname = argv[1]; 98*13795Ssam for (;;) { 99*13795Ssam int ldisp = OTTYDISC; 100*13795Ssam 101*13795Ssam gettable(tname, tabent, tabstrs); 102*13795Ssam setdefaults(); 103*13795Ssam ioctl(0, TIOCFLUSH, 0); /* clear out the crap */ 104*13795Ssam if (IS) 105*13795Ssam tmode.sg_ispeed = speed(IS); 106*13795Ssam else if (SP) 107*13795Ssam tmode.sg_ispeed = speed(SP); 108*13795Ssam if (OS) 109*13795Ssam tmode.sg_ospeed = speed(OS); 110*13795Ssam else if (SP) 111*13795Ssam tmode.sg_ospeed = speed(SP); 112*13795Ssam tmode.sg_flags = setflags(0); 113*13795Ssam ioctl(0, TIOCSETP, &tmode); 114*13795Ssam setchars(); 115*13795Ssam ioctl(0, TIOCSETC, &tc); 116*13795Ssam ioctl(0, TIOCSETD, &ldisp); 117*13795Ssam if (HC) 118*13795Ssam ioctl(0, TIOCHPCL, 0); 119*13795Ssam if (PS) { 120*13795Ssam tname = portselector(); 121*13795Ssam continue; 122*13795Ssam } 123*13795Ssam if (CL && *CL) 124*13795Ssam putpad(CL); 125*13795Ssam edithost(HE); 126*13795Ssam if (IM && *IM) 127*13795Ssam putf(IM); 128*13795Ssam if (setjmp(timeout)) { 129*13795Ssam tmode.sg_ispeed = tmode.sg_ospeed = 0; 130*13795Ssam ioctl(0, TIOCSETP, &tmode); 131*13795Ssam exit(1); 132*13795Ssam } 133*13795Ssam if (TO) { 134*13795Ssam signal(SIGALRM, dingdong); 135*13795Ssam alarm(TO); 136*13795Ssam } 137*13795Ssam if (getname()) { 138*13795Ssam alarm(0); 139*13795Ssam signal(SIGALRM, SIG_DFL); 140*13795Ssam if (!(upper||lower||digit)) 141*13795Ssam continue; 142*13795Ssam allflags = setflags(2); 143*13795Ssam tmode.sg_flags = allflags & 0xffff; 144*13795Ssam allflags >>= 16; 145*13795Ssam if (crmod || NL) 146*13795Ssam tmode.sg_flags |= CRMOD; 147*13795Ssam if (upper || UC) 148*13795Ssam tmode.sg_flags |= LCASE; 149*13795Ssam if (lower || LC) 150*13795Ssam tmode.sg_flags &= ~LCASE; 151*13795Ssam ioctl(0, TIOCSETP, &tmode); 152*13795Ssam ioctl(0, TIOCSLTC, <c); 153*13795Ssam ioctl(0, TIOCLSET, &allflags); 154*13795Ssam putchr('\n'); 155*13795Ssam makeenv(env); 156*13795Ssam execle(LO, "login", name, (char *)0, env); 157*13795Ssam exit(1); 158*13795Ssam } 159*13795Ssam alarm(0); 160*13795Ssam signal(SIGALRM, SIG_DFL); 161*13795Ssam if (NX && *NX) 162*13795Ssam tname = NX; 163*13795Ssam } 164*13795Ssam } 165*13795Ssam 166*13795Ssam getname() 167*13795Ssam { 168*13795Ssam register char *np; 169*13795Ssam register c; 170*13795Ssam char cs; 171*13795Ssam 172*13795Ssam tmode.sg_flags = setflags(0); 173*13795Ssam ioctl(0, TIOCSETP, &tmode); 174*13795Ssam tmode.sg_flags = setflags(1); 175*13795Ssam prompt(); 176*13795Ssam ioctl(0, TIOCSETP, &tmode); 177*13795Ssam crmod = 0; 178*13795Ssam upper = 0; 179*13795Ssam lower = 0; 180*13795Ssam digit = 0; 181*13795Ssam np = name; 182*13795Ssam for (;;) { 183*13795Ssam if (read(0, &cs, 1) <= 0) 184*13795Ssam exit(0); 185*13795Ssam if ((c = cs&0177) == 0) 186*13795Ssam return (0); 187*13795Ssam if (c==EOT) 188*13795Ssam exit(1); 189*13795Ssam if (c=='\r' || c=='\n' || np >= &name[16]) 190*13795Ssam break; 191*13795Ssam 192*13795Ssam if (c>='a' && c <='z') 193*13795Ssam lower++; 194*13795Ssam else if (c>='A' && c<='Z') { 195*13795Ssam upper++; 196*13795Ssam } else if (c==ERASE) { 197*13795Ssam if (np > name) { 198*13795Ssam np--; 199*13795Ssam if (tmode.sg_ospeed >= B1200) 200*13795Ssam puts("\b \b"); 201*13795Ssam else 202*13795Ssam putchr(cs); 203*13795Ssam } 204*13795Ssam continue; 205*13795Ssam } else if (c==KILL) { 206*13795Ssam putchr(cs); 207*13795Ssam putchr('\r'); 208*13795Ssam if (tmode.sg_ospeed < B1200) 209*13795Ssam putchr('\n'); 210*13795Ssam /* this is the way they do it down under ... */ 211*13795Ssam else if (np > name) 212*13795Ssam puts(" \r"); 213*13795Ssam prompt(); 214*13795Ssam np = name; 215*13795Ssam continue; 216*13795Ssam } else if (c == ' ') 217*13795Ssam c = '_'; 218*13795Ssam else if (c >= '0' && c <= '9') 219*13795Ssam digit++; 220*13795Ssam if (IG && (c < ' ' || c > 0176)) 221*13795Ssam continue; 222*13795Ssam *np++ = c; 223*13795Ssam putchr(cs); 224*13795Ssam } 225*13795Ssam *np = 0; 226*13795Ssam if (c == '\r') 227*13795Ssam crmod++; 228*13795Ssam if (upper && !lower && !LC || UC) 229*13795Ssam for (np = name; *np; np++) 230*13795Ssam if (isupper(*np)) 231*13795Ssam *np = tolower(*np); 232*13795Ssam return (1); 233*13795Ssam } 234*13795Ssam 235*13795Ssam static 236*13795Ssam short tmspc10[] = { 237*13795Ssam 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15 238*13795Ssam }; 239*13795Ssam 240*13795Ssam putpad(s) 241*13795Ssam register char *s; 242*13795Ssam { 243*13795Ssam register pad = 0; 244*13795Ssam register mspc10; 245*13795Ssam 246*13795Ssam if (isdigit(*s)) { 247*13795Ssam while (isdigit(*s)) { 248*13795Ssam pad *= 10; 249*13795Ssam pad += *s++ - '0'; 250*13795Ssam } 251*13795Ssam pad *= 10; 252*13795Ssam if (*s == '.' && isdigit(s[1])) { 253*13795Ssam pad += s[1] - '0'; 254*13795Ssam s += 2; 255*13795Ssam } 256*13795Ssam } 257*13795Ssam 258*13795Ssam puts(s); 259*13795Ssam /* 260*13795Ssam * If no delay needed, or output speed is 261*13795Ssam * not comprehensible, then don't try to delay. 262*13795Ssam */ 263*13795Ssam if (pad == 0) 264*13795Ssam return; 265*13795Ssam if (tmode.sg_ospeed <= 0 || 266*13795Ssam tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0])) 267*13795Ssam return; 268*13795Ssam 269*13795Ssam /* 270*13795Ssam * Round up by a half a character frame, 271*13795Ssam * and then do the delay. 272*13795Ssam * Too bad there are no user program accessible programmed delays. 273*13795Ssam * Transmitting pad characters slows many 274*13795Ssam * terminals down and also loads the system. 275*13795Ssam */ 276*13795Ssam mspc10 = tmspc10[tmode.sg_ospeed]; 277*13795Ssam pad += mspc10 / 2; 278*13795Ssam for (pad /= mspc10; pad > 0; pad--) 279*13795Ssam putchr(*PC); 280*13795Ssam } 281*13795Ssam 282*13795Ssam puts(s) 283*13795Ssam register char *s; 284*13795Ssam { 285*13795Ssam 286*13795Ssam while (*s) 287*13795Ssam putchr(*s++); 288*13795Ssam } 289*13795Ssam 290*13795Ssam putchr(cc) 291*13795Ssam { 292*13795Ssam char c; 293*13795Ssam 294*13795Ssam c = cc; 295*13795Ssam c |= partab[c&0177] & 0200; 296*13795Ssam if (OP) 297*13795Ssam c ^= 0200; 298*13795Ssam write(1, &c, 1); 299*13795Ssam } 300*13795Ssam 301*13795Ssam prompt() 302*13795Ssam { 303*13795Ssam 304*13795Ssam putf(LM); 305*13795Ssam if (CO) 306*13795Ssam putchr('\n'); 307*13795Ssam } 308*13795Ssam 309*13795Ssam putf(cp) 310*13795Ssam register char *cp; 311*13795Ssam { 312*13795Ssam extern char editedhost[]; 313*13795Ssam 314*13795Ssam while (*cp) { 315*13795Ssam if (*cp != '%') { 316*13795Ssam putchr(*cp++); 317*13795Ssam continue; 318*13795Ssam } 319*13795Ssam switch (*++cp) { 320*13795Ssam 321*13795Ssam case 'h': 322*13795Ssam puts(editedhost); 323*13795Ssam break; 324*13795Ssam 325*13795Ssam case '%': 326*13795Ssam putchr('%'); 327*13795Ssam break; 328*13795Ssam } 329*13795Ssam cp++; 330*13795Ssam } 331*13795Ssam } 332