|
|
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.5 (Berkeley) 1/23/86"; ! 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: ! 170: gettable(tname, tabent, tabstrs); ! 171: if (OPset || EPset || APset) ! 172: APset++, OPset++, EPset++; ! 173: setdefaults(); ! 174: ioctl(0, TIOCFLUSH, 0); /* clear out the crap */ ! 175: if (IS) ! 176: tmode.sg_ispeed = speed(IS); ! 177: else if (SP) ! 178: tmode.sg_ispeed = speed(SP); ! 179: if (OS) ! 180: tmode.sg_ospeed = speed(OS); ! 181: else if (SP) ! 182: tmode.sg_ospeed = speed(SP); ! 183: tmode.sg_flags = setflags(0); ! 184: ioctl(0, TIOCSETP, &tmode); ! 185: setchars(); ! 186: ioctl(0, TIOCSETC, &tc); ! 187: ioctl(0, TIOCSETD, &ldisp); ! 188: if (HC) ! 189: ioctl(0, TIOCHPCL, 0); ! 190: if (AB) { ! 191: extern char *autobaud(); ! 192: ! 193: tname = autobaud(); ! 194: continue; ! 195: } ! 196: if (PS) { ! 197: tname = portselector(); ! 198: continue; ! 199: } ! 200: if (CL && *CL) ! 201: putpad(CL); ! 202: edithost(HE); ! 203: if (IM && *IM) ! 204: putf(IM); ! 205: if (setjmp(timeout)) { ! 206: tmode.sg_ispeed = tmode.sg_ospeed = 0; ! 207: ioctl(0, TIOCSETP, &tmode); ! 208: exit(1); ! 209: } ! 210: if (TO) { ! 211: signal(SIGALRM, dingdong); ! 212: alarm(TO); ! 213: } ! 214: if (getname()) { ! 215: register int i; ! 216: ! 217: oflush(); ! 218: alarm(0); ! 219: signal(SIGALRM, SIG_DFL); ! 220: if (!(upper || lower || digit)) ! 221: continue; ! 222: allflags = setflags(2); ! 223: tmode.sg_flags = allflags & 0xffff; ! 224: allflags >>= 16; ! 225: if (crmod || NL) ! 226: tmode.sg_flags |= CRMOD; ! 227: if (upper || UC) ! 228: tmode.sg_flags |= LCASE; ! 229: if (lower || LC) ! 230: tmode.sg_flags &= ~LCASE; ! 231: ioctl(0, TIOCSETP, &tmode); ! 232: ioctl(0, TIOCSLTC, <c); ! 233: ioctl(0, TIOCLSET, &allflags); ! 234: signal(SIGINT, SIG_DFL); ! 235: for (i = 0; environ[i] != (char *)0; i++) ! 236: env[i] = environ[i]; ! 237: makeenv(&env[i]); ! 238: execle(LO, "login", "-p", name, (char *) 0, env); ! 239: exit(1); ! 240: } ! 241: alarm(0); ! 242: signal(SIGALRM, SIG_DFL); ! 243: signal(SIGINT, SIG_IGN); ! 244: if (NX && *NX) ! 245: tname = NX; ! 246: } ! 247: } ! 248: ! 249: getname() ! 250: { ! 251: register char *np; ! 252: register c; ! 253: char cs; ! 254: ! 255: /* ! 256: * Interrupt may happen if we use CBREAK mode ! 257: */ ! 258: if (setjmp(intrupt)) { ! 259: signal(SIGINT, SIG_IGN); ! 260: return (0); ! 261: } ! 262: signal(SIGINT, interrupt); ! 263: tmode.sg_flags = setflags(0); ! 264: ioctl(0, TIOCSETP, &tmode); ! 265: tmode.sg_flags = setflags(1); ! 266: prompt(); ! 267: if (PF > 0) { ! 268: oflush(); ! 269: sleep(PF); ! 270: PF = 0; ! 271: } ! 272: ioctl(0, TIOCSETP, &tmode); ! 273: crmod = 0; ! 274: upper = 0; ! 275: lower = 0; ! 276: digit = 0; ! 277: np = name; ! 278: for (;;) { ! 279: oflush(); ! 280: if (read(0, &cs, 1) <= 0) ! 281: exit(0); ! 282: if ((c = cs&0177) == 0) ! 283: return (0); ! 284: if (c == EOT) ! 285: exit(1); ! 286: if (c == '\r' || c == '\n' || np >= &name[sizeof name]) { ! 287: putf("\r\n"); ! 288: break; ! 289: } ! 290: if (c >= 'a' && c <= 'z') ! 291: lower++; ! 292: else if (c >= 'A' && c <= 'Z') ! 293: upper++; ! 294: else if (c == ERASE || c == '#' || c == '\b') { ! 295: if (np > name) { ! 296: np--; ! 297: if (tmode.sg_ospeed >= B1200) ! 298: puts("\b \b"); ! 299: else ! 300: putchr(cs); ! 301: } ! 302: continue; ! 303: } else if (c == KILL || c == '@') { ! 304: putchr(cs); ! 305: putchr('\r'); ! 306: if (tmode.sg_ospeed < B1200) ! 307: putchr('\n'); ! 308: /* this is the way they do it down under ... */ ! 309: else if (np > name) ! 310: puts(" \r"); ! 311: prompt(); ! 312: np = name; ! 313: continue; ! 314: } else if (c >= '0' && c <= '9') ! 315: digit++; ! 316: if (IG && (c <= ' ' || c > 0176)) ! 317: continue; ! 318: *np++ = c; ! 319: putchr(cs); ! 320: } ! 321: signal(SIGINT, SIG_IGN); ! 322: *np = 0; ! 323: if (c == '\r') ! 324: crmod++; ! 325: if (upper && !lower && !LC || UC) ! 326: for (np = name; *np; np++) ! 327: if (isupper(*np)) ! 328: *np = tolower(*np); ! 329: return (1); ! 330: } ! 331: ! 332: static ! 333: short tmspc10[] = { ! 334: 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15 ! 335: }; ! 336: ! 337: putpad(s) ! 338: register char *s; ! 339: { ! 340: register pad = 0; ! 341: register mspc10; ! 342: ! 343: if (isdigit(*s)) { ! 344: while (isdigit(*s)) { ! 345: pad *= 10; ! 346: pad += *s++ - '0'; ! 347: } ! 348: pad *= 10; ! 349: if (*s == '.' && isdigit(s[1])) { ! 350: pad += s[1] - '0'; ! 351: s += 2; ! 352: } ! 353: } ! 354: ! 355: puts(s); ! 356: /* ! 357: * If no delay needed, or output speed is ! 358: * not comprehensible, then don't try to delay. ! 359: */ ! 360: if (pad == 0) ! 361: return; ! 362: if (tmode.sg_ospeed <= 0 || ! 363: tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0])) ! 364: return; ! 365: ! 366: /* ! 367: * Round up by a half a character frame, ! 368: * and then do the delay. ! 369: * Too bad there are no user program accessible programmed delays. ! 370: * Transmitting pad characters slows many ! 371: * terminals down and also loads the system. ! 372: */ ! 373: mspc10 = tmspc10[tmode.sg_ospeed]; ! 374: pad += mspc10 / 2; ! 375: for (pad /= mspc10; pad > 0; pad--) ! 376: putchr(*PC); ! 377: } ! 378: ! 379: puts(s) ! 380: register char *s; ! 381: { ! 382: ! 383: while (*s) ! 384: putchr(*s++); ! 385: } ! 386: ! 387: char outbuf[OBUFSIZ]; ! 388: int obufcnt = 0; ! 389: ! 390: putchr(cc) ! 391: { ! 392: char c; ! 393: ! 394: c = cc; ! 395: c |= partab[c&0177] & 0200; ! 396: if (OP) ! 397: c ^= 0200; ! 398: if (!UB) { ! 399: outbuf[obufcnt++] = c; ! 400: if (obufcnt >= OBUFSIZ) ! 401: oflush(); ! 402: } else ! 403: write(1, &c, 1); ! 404: } ! 405: ! 406: oflush() ! 407: { ! 408: if (obufcnt) ! 409: write(1, outbuf, obufcnt); ! 410: obufcnt = 0; ! 411: } ! 412: ! 413: prompt() ! 414: { ! 415: ! 416: putf(LM); ! 417: if (CO) ! 418: putchr('\n'); ! 419: } ! 420: ! 421: putf(cp) ! 422: register char *cp; ! 423: { ! 424: char *ttyn, *slash; ! 425: char datebuffer[60]; ! 426: extern char editedhost[]; ! 427: extern char *ttyname(), *rindex(); ! 428: ! 429: while (*cp) { ! 430: if (*cp != '%') { ! 431: putchr(*cp++); ! 432: continue; ! 433: } ! 434: switch (*++cp) { ! 435: ! 436: case 't': ! 437: ttyn = ttyname(0); ! 438: slash = rindex(ttyn, '/'); ! 439: if (slash == (char *) 0) ! 440: puts(ttyn); ! 441: else ! 442: puts(&slash[1]); ! 443: break; ! 444: ! 445: case 'h': ! 446: puts(editedhost); ! 447: break; ! 448: ! 449: case 'd': ! 450: get_date(datebuffer); ! 451: puts(datebuffer); ! 452: break; ! 453: ! 454: case '%': ! 455: putchr('%'); ! 456: break; ! 457: } ! 458: cp++; ! 459: } ! 460: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.