|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: char copyright[] = ! 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif not lint ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)main.c 5.11 (Berkeley) 6/29/90"; ! 15: #endif not lint ! 16: ! 17: /* ! 18: * getty -- adapt to terminal speed on dialup, and call login ! 19: * ! 20: * Melbourne getty, June 83, kre. ! 21: */ ! 22: ! 23: #define USE_OLD_TTY ! 24: #include <sys/param.h> ! 25: #include <sys/signal.h> ! 26: #include <sys/file.h> ! 27: #include <sgtty.h> ! 28: #include <ctype.h> ! 29: #include <setjmp.h> ! 30: #include <syslog.h> ! 31: #include <ctype.h> ! 32: #include "gettytab.h" ! 33: #include "pathnames.h" ! 34: ! 35: extern char **environ; ! 36: ! 37: struct sgttyb tmode = { ! 38: 0, 0, CERASE, CKILL, 0 ! 39: }; ! 40: struct tchars tc = { ! 41: CINTR, CQUIT, CSTART, ! 42: CSTOP, CEOF, CBRK, ! 43: }; ! 44: struct ltchars ltc = { ! 45: CSUSP, CDSUSP, CRPRNT, ! 46: CFLUSH, CWERASE, CLNEXT ! 47: }; ! 48: ! 49: int crmod; ! 50: int upper; ! 51: int lower; ! 52: int digit; ! 53: ! 54: char hostname[MAXHOSTNAMELEN]; ! 55: char name[16]; ! 56: char dev[] = _PATH_DEV; ! 57: char ttyn[32]; ! 58: char *portselector(); ! 59: char *ttyname(); ! 60: ! 61: #define OBUFSIZ 128 ! 62: #define TABBUFSIZ 512 ! 63: ! 64: char defent[TABBUFSIZ]; ! 65: char defstrs[TABBUFSIZ]; ! 66: char tabent[TABBUFSIZ]; ! 67: char tabstrs[TABBUFSIZ]; ! 68: ! 69: char *env[128]; ! 70: ! 71: char partab[] = { ! 72: 0001,0201,0201,0001,0201,0001,0001,0201, ! 73: 0202,0004,0003,0205,0005,0206,0201,0001, ! 74: 0201,0001,0001,0201,0001,0201,0201,0001, ! 75: 0001,0201,0201,0001,0201,0001,0001,0201, ! 76: 0200,0000,0000,0200,0000,0200,0200,0000, ! 77: 0000,0200,0200,0000,0200,0000,0000,0200, ! 78: 0000,0200,0200,0000,0200,0000,0000,0200, ! 79: 0200,0000,0000,0200,0000,0200,0200,0000, ! 80: 0200,0000,0000,0200,0000,0200,0200,0000, ! 81: 0000,0200,0200,0000,0200,0000,0000,0200, ! 82: 0000,0200,0200,0000,0200,0000,0000,0200, ! 83: 0200,0000,0000,0200,0000,0200,0200,0000, ! 84: 0000,0200,0200,0000,0200,0000,0000,0200, ! 85: 0200,0000,0000,0200,0000,0200,0200,0000, ! 86: 0200,0000,0000,0200,0000,0200,0200,0000, ! 87: 0000,0200,0200,0000,0200,0000,0000,0201 ! 88: }; ! 89: ! 90: #define ERASE tmode.sg_erase ! 91: #define KILL tmode.sg_kill ! 92: #define EOT tc.t_eofc ! 93: ! 94: jmp_buf timeout; ! 95: ! 96: dingdong() ! 97: { ! 98: ! 99: alarm(0); ! 100: signal(SIGALRM, SIG_DFL); ! 101: longjmp(timeout, 1); ! 102: } ! 103: ! 104: jmp_buf intrupt; ! 105: ! 106: interrupt() ! 107: { ! 108: ! 109: signal(SIGINT, interrupt); ! 110: longjmp(intrupt, 1); ! 111: } ! 112: ! 113: main(argc, argv) ! 114: char *argv[]; ! 115: { ! 116: char *tname; ! 117: long allflags; ! 118: int repcnt = 0; ! 119: ! 120: signal(SIGINT, SIG_IGN); ! 121: /* ! 122: signal(SIGQUIT, SIG_DFL); ! 123: */ ! 124: openlog("getty", LOG_ODELAY|LOG_CONS, LOG_AUTH); ! 125: gethostname(hostname, sizeof(hostname)); ! 126: if (hostname[0] == '\0') ! 127: strcpy(hostname, "Amnesiac"); ! 128: /* ! 129: * The following is a work around for vhangup interactions ! 130: * which cause great problems getting window systems started. ! 131: * If the tty line is "-", we do the old style getty presuming ! 132: * that the file descriptors are already set up for us. ! 133: * J. Gettys - MIT Project Athena. ! 134: */ ! 135: if (argc <= 2 || strcmp(argv[2], "-") == 0) ! 136: strcpy(ttyn, ttyname(0)); ! 137: else { ! 138: int i; ! 139: ! 140: strcpy(ttyn, dev); ! 141: strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev)); ! 142: if (strcmp(argv[0], "+") != 0) { ! 143: chown(ttyn, 0, 0); ! 144: chmod(ttyn, 0600); ! 145: revoke(ttyn); ! 146: /* ! 147: * Delay the open so DTR stays down long enough to be detected. ! 148: */ ! 149: sleep(2); ! 150: while ((i = open(ttyn, O_RDWR)) == -1) { ! 151: if (repcnt % 10 == 0) { ! 152: syslog(LOG_ERR, "%s: %m", ttyn); ! 153: closelog(); ! 154: } ! 155: repcnt++; ! 156: sleep(60); ! 157: } ! 158: login_tty(i); ! 159: } ! 160: } ! 161: ! 162: gettable("default", defent, defstrs); ! 163: gendefaults(); ! 164: tname = "default"; ! 165: if (argc > 1) ! 166: tname = argv[1]; ! 167: for (;;) { ! 168: int ldisp = OTTYDISC; ! 169: int off = 0; ! 170: ! 171: gettable(tname, tabent, tabstrs); ! 172: if (OPset || EPset || APset) ! 173: APset++, OPset++, EPset++; ! 174: setdefaults(); ! 175: ioctl(0, TIOCFLUSH, 0); /* clear out the crap */ ! 176: ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */ ! 177: ioctl(0, FIOASYNC, &off); /* ditto for asynchronous mode */ ! 178: if (IS) ! 179: tmode.sg_ispeed = speed(IS); ! 180: else if (SP) ! 181: tmode.sg_ispeed = speed(SP); ! 182: if (OS) ! 183: tmode.sg_ospeed = speed(OS); ! 184: else if (SP) ! 185: tmode.sg_ospeed = speed(SP); ! 186: tmode.sg_flags = setflags(0); ! 187: ioctl(0, TIOCSETP, &tmode); ! 188: setchars(); ! 189: ioctl(0, TIOCSETC, &tc); ! 190: if (HC) ! 191: ioctl(0, TIOCHPCL, 0); ! 192: if (AB) { ! 193: extern char *autobaud(); ! 194: ! 195: tname = autobaud(); ! 196: continue; ! 197: } ! 198: if (PS) { ! 199: tname = portselector(); ! 200: continue; ! 201: } ! 202: if (CL && *CL) ! 203: putpad(CL); ! 204: edithost(HE); ! 205: if (IM && *IM) ! 206: putf(IM); ! 207: if (setjmp(timeout)) { ! 208: tmode.sg_ispeed = tmode.sg_ospeed = 0; ! 209: ioctl(0, TIOCSETP, &tmode); ! 210: exit(1); ! 211: } ! 212: if (TO) { ! 213: signal(SIGALRM, dingdong); ! 214: alarm(TO); ! 215: } ! 216: if (getname()) { ! 217: register int i; ! 218: ! 219: oflush(); ! 220: alarm(0); ! 221: signal(SIGALRM, SIG_DFL); ! 222: if (name[0] == '-') { ! 223: puts("user names may not start with '-'."); ! 224: continue; ! 225: } ! 226: if (!(upper || lower || digit)) ! 227: continue; ! 228: allflags = setflags(2); ! 229: tmode.sg_flags = allflags & 0xffff; ! 230: allflags >>= 16; ! 231: if (crmod || NL) ! 232: tmode.sg_flags |= CRMOD; ! 233: if (upper || UC) ! 234: tmode.sg_flags |= LCASE; ! 235: if (lower || LC) ! 236: tmode.sg_flags &= ~LCASE; ! 237: ioctl(0, TIOCSETP, &tmode); ! 238: ioctl(0, TIOCSLTC, <c); ! 239: ioctl(0, TIOCLSET, &allflags); ! 240: signal(SIGINT, SIG_DFL); ! 241: for (i = 0; environ[i] != (char *)0; i++) ! 242: env[i] = environ[i]; ! 243: makeenv(&env[i]); ! 244: ! 245: /* ! 246: * this is what login was doing anyway. ! 247: * soon we rewrite getty completely. ! 248: */ ! 249: set_ttydefaults(0); ! 250: execle(LO, "login", "-p", name, (char *) 0, env); ! 251: syslog(LOG_ERR, "%s: %m", LO); ! 252: exit(1); ! 253: } ! 254: alarm(0); ! 255: signal(SIGALRM, SIG_DFL); ! 256: signal(SIGINT, SIG_IGN); ! 257: if (NX && *NX) ! 258: tname = NX; ! 259: } ! 260: } ! 261: ! 262: getname() ! 263: { ! 264: register char *np; ! 265: register c; ! 266: char cs; ! 267: ! 268: /* ! 269: * Interrupt may happen if we use CBREAK mode ! 270: */ ! 271: if (setjmp(intrupt)) { ! 272: signal(SIGINT, SIG_IGN); ! 273: return (0); ! 274: } ! 275: signal(SIGINT, interrupt); ! 276: tmode.sg_flags = setflags(0); ! 277: ioctl(0, TIOCSETP, &tmode); ! 278: tmode.sg_flags = setflags(1); ! 279: prompt(); ! 280: if (PF > 0) { ! 281: oflush(); ! 282: sleep(PF); ! 283: PF = 0; ! 284: } ! 285: ioctl(0, TIOCSETP, &tmode); ! 286: crmod = 0; ! 287: upper = 0; ! 288: lower = 0; ! 289: digit = 0; ! 290: np = name; ! 291: for (;;) { ! 292: oflush(); ! 293: if (read(0, &cs, 1) <= 0) ! 294: exit(0); ! 295: if ((c = cs&0177) == 0) ! 296: return (0); ! 297: if (c == EOT) ! 298: exit(1); ! 299: if (c == '\r' || c == '\n' || np >= &name[sizeof name]) { ! 300: putf("\r\n"); ! 301: break; ! 302: } ! 303: if (islower(c)) ! 304: lower++; ! 305: else if (isupper(c)) ! 306: upper++; ! 307: else if (c == ERASE || c == '#' || c == '\b') { ! 308: if (np > name) { ! 309: np--; ! 310: if (tmode.sg_ospeed >= B1200) ! 311: puts("\b \b"); ! 312: else ! 313: putchr(cs); ! 314: } ! 315: continue; ! 316: } else if (c == KILL || c == '@') { ! 317: putchr(cs); ! 318: putchr('\r'); ! 319: if (tmode.sg_ospeed < B1200) ! 320: putchr('\n'); ! 321: /* this is the way they do it down under ... */ ! 322: else if (np > name) ! 323: puts(" \r"); ! 324: prompt(); ! 325: np = name; ! 326: continue; ! 327: } else if (isdigit(c)) ! 328: digit++; ! 329: if (IG && (c <= ' ' || c > 0176)) ! 330: continue; ! 331: *np++ = c; ! 332: putchr(cs); ! 333: } ! 334: signal(SIGINT, SIG_IGN); ! 335: *np = 0; ! 336: if (c == '\r') ! 337: crmod++; ! 338: if (upper && !lower && !LC || UC) ! 339: for (np = name; *np; np++) ! 340: if (isupper(*np)) ! 341: *np = tolower(*np); ! 342: return (1); ! 343: } ! 344: ! 345: static ! 346: short tmspc10[] = { ! 347: 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15 ! 348: }; ! 349: ! 350: putpad(s) ! 351: register char *s; ! 352: { ! 353: register pad = 0; ! 354: register mspc10; ! 355: ! 356: if (isdigit(*s)) { ! 357: while (isdigit(*s)) { ! 358: pad *= 10; ! 359: pad += *s++ - '0'; ! 360: } ! 361: pad *= 10; ! 362: if (*s == '.' && isdigit(s[1])) { ! 363: pad += s[1] - '0'; ! 364: s += 2; ! 365: } ! 366: } ! 367: ! 368: puts(s); ! 369: /* ! 370: * If no delay needed, or output speed is ! 371: * not comprehensible, then don't try to delay. ! 372: */ ! 373: if (pad == 0) ! 374: return; ! 375: if (tmode.sg_ospeed <= 0 || ! 376: tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0])) ! 377: return; ! 378: ! 379: /* ! 380: * Round up by a half a character frame, ! 381: * and then do the delay. ! 382: * Too bad there are no user program accessible programmed delays. ! 383: * Transmitting pad characters slows many ! 384: * terminals down and also loads the system. ! 385: */ ! 386: mspc10 = tmspc10[tmode.sg_ospeed]; ! 387: pad += mspc10 / 2; ! 388: for (pad /= mspc10; pad > 0; pad--) ! 389: putchr(*PC); ! 390: } ! 391: ! 392: puts(s) ! 393: register char *s; ! 394: { ! 395: ! 396: while (*s) ! 397: putchr(*s++); ! 398: } ! 399: ! 400: char outbuf[OBUFSIZ]; ! 401: int obufcnt = 0; ! 402: ! 403: putchr(cc) ! 404: { ! 405: char c; ! 406: ! 407: c = cc; ! 408: c |= partab[c&0177] & 0200; ! 409: if (OP) ! 410: c ^= 0200; ! 411: if (!UB) { ! 412: outbuf[obufcnt++] = c; ! 413: if (obufcnt >= OBUFSIZ) ! 414: oflush(); ! 415: } else ! 416: write(1, &c, 1); ! 417: } ! 418: ! 419: oflush() ! 420: { ! 421: if (obufcnt) ! 422: write(1, outbuf, obufcnt); ! 423: obufcnt = 0; ! 424: } ! 425: ! 426: prompt() ! 427: { ! 428: ! 429: putf(LM); ! 430: if (CO) ! 431: putchr('\n'); ! 432: } ! 433: ! 434: putf(cp) ! 435: register char *cp; ! 436: { ! 437: char *slash; ! 438: char datebuffer[60]; ! 439: extern char editedhost[]; ! 440: extern char *rindex(); ! 441: ! 442: while (*cp) { ! 443: if (*cp != '%') { ! 444: putchr(*cp++); ! 445: continue; ! 446: } ! 447: switch (*++cp) { ! 448: ! 449: case 't': ! 450: slash = rindex(ttyn, '/'); ! 451: if (slash == (char *) 0) ! 452: puts(ttyn); ! 453: else ! 454: puts(&slash[1]); ! 455: break; ! 456: ! 457: case 'h': ! 458: puts(editedhost); ! 459: break; ! 460: ! 461: case 'd': ! 462: get_date(datebuffer); ! 463: puts(datebuffer); ! 464: break; ! 465: ! 466: case '%': ! 467: putchr('%'); ! 468: break; ! 469: } ! 470: cp++; ! 471: } ! 472: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.