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