|
|
1.1 ! root 1: /* ! 2: * Rec'd from Lauren Weinstein, 7-16-84. ! 3: * Read a user name from a terminal. ! 4: * Attempt to determine the proper line ! 5: * speed and mode. Call login. This version ! 6: * explicitly sets all sgtty and tchars values ! 7: * to allow proper resetting of the console device. ! 8: * ! 9: * Responds to explicitly set erase and kill chars, ! 10: * and ALSO to (erase == '#') and (kill == '@'). ! 11: * ! 12: * Compile -s -n -i ! 13: */ ! 14: ! 15: #include <stdio.h> ! 16: #include <ctype.h> ! 17: #include <sgtty.h> ! 18: #if NEWTTYS ! 19: #include <sys/tty.h> ! 20: #endif ! 21: #include <sys/deftty.h> ! 22: #include <signal.h> ! 23: #include <sys/stat.h> ! 24: ! 25: #define FALSE 0 ! 26: #define TRUE 1 ! 27: ! 28: #define MAXTIME 60 /* Maximum attempt time in seconds */ ! 29: #define NTYPE (sizeof stypes/sizeof stypes[0]) ! 30: #define GMODE (ECHO|XTABS|CRT|CRMOD) ! 31: #define LA36M GMODE /* Should have LA36 delays w/a */ ! 32: #define MAXNAME 50 /* Maximum characters in a name */ ! 33: #define LOGMSG "/etc/logmsg" /* alternate login msg file */ ! 34: ! 35: char defm[] = "\n\r\7Coherent login: "; /* default login prompt */ ! 36: ! 37: int xflags; /* Extra flags to set */ ! 38: char remote = FALSE; /* TRUE for remote tty line */ ! 39: int timeout(); /* forward declaration */ ! 40: ! 41: /* ! 42: * Structure for each speed table. ! 43: * The 's_nindex' entry is the next ! 44: * indent in the current table to ! 45: * use (for fixed-speed entries, it ! 46: * should be always 0). ! 47: */ ! 48: struct stable { ! 49: char s_nindex; ! 50: int s_mode; ! 51: char s_ispeed; ! 52: char s_ospeed; ! 53: char *s_lmsg; ! 54: }; ! 55: ! 56: /* ! 57: * Fixed-speed tables. ! 58: */ ! 59: struct stable sA[] = {0, GMODE, B50, B50, defm}; ! 60: struct stable sB[] = {0, GMODE, B75, B75, defm}; ! 61: struct stable sC[] = {0, GMODE, B110, B110, defm}; ! 62: struct stable sD[] = {0, GMODE, B134, B134, defm}; ! 63: struct stable sE[] = {0, GMODE, B150, B150, defm}; ! 64: struct stable sF[] = {0, GMODE, B200, B200, defm}; ! 65: struct stable sG[] = {0, GMODE, B300, B300, defm}; ! 66: struct stable sH[] = {0, GMODE, B600, B600, defm}; ! 67: struct stable sI[] = {0, GMODE, B1200, B1200, defm}; ! 68: struct stable sJ[] = {0, GMODE, B1800, B1800, defm}; ! 69: struct stable sK[] = {0, GMODE, B2000, B2000, defm}; ! 70: struct stable sL[] = {0, GMODE, B2400, B2400, defm}; ! 71: struct stable sM[] = {0, GMODE, B3600, B3600, defm}; ! 72: struct stable sN[] = {0, GMODE, B4800, B4800, defm}; ! 73: struct stable sO[] = {0, GMODE, B7200, B7200, defm}; ! 74: struct stable sP[] = {0, GMODE, B9600, B9600, defm}; ! 75: struct stable sQ[] = {0, GMODE, B19200, B19200, defm}; ! 76: struct stable sR[] = {0, GMODE, EXTA, EXTA, defm}; ! 77: struct stable sS[] = {0, GMODE, EXTB, EXTB, defm}; ! 78: ! 79: /* ! 80: * Variable-speed tables. ! 81: */ ! 82: struct stable sdash[] = { /* TTY 33 */ ! 83: 0, GMODE, B110, B110, defm ! 84: }; ! 85: ! 86: struct stable s0[] = { /* Default--various terminals */ ! 87: 1, GMODE, B300, B300, defm, ! 88: 2, GMODE, B1200, B1200, defm, ! 89: 3, GMODE, B150, B150, defm, ! 90: 0, GMODE, B110, B110, defm ! 91: }; ! 92: ! 93: struct stable s1[] = { /* 150 baud TTY 37 */ ! 94: 0, GMODE, B150, B150, defm ! 95: }; ! 96: ! 97: struct stable s2[] = { /* 9600 baud - Tek 4104 */ ! 98: 0, GMODE, B9600, B9600, defm ! 99: }; ! 100: ! 101: struct stable s3[] = { /* v22.bis & 212 datasets (2400,1200,300) */ ! 102: 1, GMODE, B2400, B2400, defm, ! 103: 2, GMODE, B1200, B1200, defm, ! 104: 0, GMODE, B300, B300, defm ! 105: }; ! 106: ! 107: struct stable s5[] = { /* Reverse of 's3' */ ! 108: 1, GMODE, B300, B300, defm, ! 109: 0, GMODE, B1200, B1200, defm ! 110: }; ! 111: ! 112: struct stable s4[] = { /* LA36 (needs its delays) */ ! 113: 0, LA36M, B300, B300, defm ! 114: }; ! 115: ! 116: struct stable s9[] = { /* 212 with auto speed select via CTS */ ! 117: 1, GMODE, B1200, B1200, defm, /* 1200 */ ! 118: 2, GMODE, B300, B300, defm, /* then 300 */ ! 119: 0, GMODE, B110, B110, defm /* then 110 */ ! 120: }; ! 121: ! 122: /* ! 123: * This table is used to map ! 124: * a speed character argument, passed ! 125: * to "getty" from "init", into a speed ! 126: * table base. ! 127: */ ! 128: struct stypes { ! 129: int s_name; ! 130: struct stable *s_ptr; ! 131: } stypes[] = { ! 132: '-', sdash, ! 133: '0', s0, ! 134: '1', s1, ! 135: '2', s2, ! 136: '3', s3, ! 137: '4', s4, ! 138: '5', s5, ! 139: '9', s9, /* 212 with auto speed select */ ! 140: 'A', sA, ! 141: 'B', sB, ! 142: 'C', sC, ! 143: 'D', sD, ! 144: 'E', sE, ! 145: 'F', sF, ! 146: 'G', sG, ! 147: 'H', sH, ! 148: 'I', sI, ! 149: 'J', sJ, ! 150: 'K', sK, ! 151: 'L', sL, ! 152: 'M', sM, ! 153: 'N', sN, ! 154: 'O', sO, ! 155: 'P', sP, ! 156: 'Q', sQ, ! 157: 'R', sR, ! 158: 'S', sS ! 159: }; ! 160: ! 161: /* ! 162: * Default sgtty and tchars settings. ! 163: */ ! 164: ! 165: struct sgttyb defsgt = { /* Initial sgtty */ ! 166: DEF_SG_ISPEED, ! 167: DEF_SG_OSPEED, ! 168: DEF_SG_ERASE, ! 169: DEF_SG_KILL, ! 170: DEF_SG_FLAGS ! 171: }; ! 172: ! 173: struct tchars deftch = { /* Initial tchars */ ! 174: DEF_T_INTRC, ! 175: DEF_T_QUITC, ! 176: DEF_T_STARTC, ! 177: DEF_T_STOPC, ! 178: DEF_T_EOFC, ! 179: DEF_T_BRKC ! 180: }; ! 181: ! 182: ! 183: main(argc, argv) ! 184: char *argv[]; ! 185: { ! 186: register struct stable *sp; ! 187: register struct stable *stpp; ! 188: register struct stypes *stp; ! 189: register int index; ! 190: char name[MAXNAME]; ! 191: char *ttyn; /* pointer to current tty name */ ! 192: extern char *ttyname(); ! 193: ! 194: if (argc != 2) { ! 195: write(1, "Usage: /etc/getty baudtype\r\n", 28); ! 196: slexit(1); /* error exit */ ! 197: } ! 198: ! 199: signal(SIGINT, SIG_IGN); /* ignore int and quit */ ! 200: signal(SIGQUIT, SIG_IGN); ! 201: ! 202: if ((ttyn = ttyname(1)) == NULL) /* get current tty name */ ! 203: { write(1, "getty: can't get tty name!\r\n", 28); ! 204: slexit(1); /* error exit */ ! 205: } ! 206: if (chmod(ttyn, 04000) < 0) /* setuid bit to indicate line in use */ ! 207: { write(1, "getty: can't chmod!\r\n", 21); ! 208: slexit(1); /* error exit */ ! 209: } ! 210: ! 211: #if NEWTTYS ! 212: if (argv[0][0] == '-' && argv[0][1] == 'r') { ! 213: remote = TRUE; ! 214: signal(SIGALRM, &timeout); /* catch alarm timeouts */ ! 215: alarm(MAXTIME); /* timeout interval */ ! 216: } ! 217: #endif ! 218: ! 219: stpp = s0; ! 220: if (argc > 1) { ! 221: for (stp = stypes; stp < &stypes[NTYPE]; stp++) ! 222: if (*argv[1] == stp->s_name) { ! 223: stpp = stp->s_ptr; ! 224: break; ! 225: } ! 226: } ! 227: for (index=0; ; index=sp->s_nindex) { ! 228: sp = &stpp[index]; ! 229: xflags = 0; ! 230: /* a '9' indicates autospeed mode for first index only */ ! 231: dostty(sp, RAW, 0, (index == 0 && stp->s_name == '9')); ! 232: if (readname(name, sp) != 0) ! 233: break; ! 234: } ! 235: #if NEWTTYS ! 236: alarm(0); /* turn off login alarm timeout */ ! 237: #endif ! 238: dostty(sp, 0, RAW, 0); /* set sgtty modes */ ! 239: ioctl(1, TIOCSETC, &deftch); /* set tchars modes */ ! 240: execl("/bin/login", (remote) ? "-r" : "-", name, NULL); ! 241: slexit(1); ! 242: } ! 243: ! 244: /* ! 245: * Do a "stty" on the terminal. ! 246: * The erase and kill characters come ! 247: * from the defaults in "defsgt". ! 248: * The speeds and the basic mode come ! 249: * from the "stable" pointed to by ! 250: * "sp". The "on" and "off" masks ! 251: * change the modes. ! 252: * If "automode" is non-zero, 212 auto speed ! 253: * mode has been selected. ! 254: */ ! 255: dostty(stabp, on, off, automode) ! 256: register struct stable *stabp; ! 257: { ! 258: #if NEWTTYS ! 259: unsigned msr; ! 260: ! 261: if (automode) /* 212 auto speed mode? */ ! 262: if (ioctl(1, TIOCRMSR, &msr) == 0) /* get modem status register */ ! 263: stabp->s_ispeed = stabp->s_ospeed ! 264: = ((msr & MSRCTS) ? B1200 : B300); /* CTS high means 1200 */ ! 265: #endif ! 266: ! 267: defsgt.sg_ispeed = stabp->s_ispeed; ! 268: defsgt.sg_ospeed = stabp->s_ospeed; ! 269: defsgt.sg_flags = stabp->s_mode; ! 270: defsgt.sg_flags |= xflags|on; ! 271: defsgt.sg_flags &= ~off; ! 272: ioctl(1, TIOCSETP, &defsgt); /* set modes */ ! 273: } ! 274: ! 275: /* ! 276: * Read a name from the terminal. ! 277: * Return true if you get a name, or false ! 278: * if the speed should be cycled. Use the ! 279: * editing characters from the initial ! 280: * defaults. ! 281: */ ! 282: readname(s, sp) ! 283: char *s; ! 284: struct stable *sp; ! 285: { ! 286: register char *cp; ! 287: register int c; ! 288: register int seenupper; ! 289: register int seenlower; ! 290: FILE *msgfp; ! 291: char last; ! 292: ! 293: loop: ! 294: seenlower = 0; ! 295: seenupper = 0; ! 296: xflags = 0; ! 297: if ((msgfp = fopen(LOGMSG, "r")) != NULL) { ! 298: /* Read from login message file. */ ! 299: for (last = '\n'; (c = fgetc(msgfp)) != EOF; last = c) { ! 300: if (last == '\n') ! 301: write(1, "\r", 1); ! 302: write(1, &last, 1); ! 303: } ! 304: if (last != '\n') ! 305: write(1, &last, 1); ! 306: fclose(msgfp); ! 307: } else ! 308: write(1, sp->s_lmsg, strlen(sp->s_lmsg)); /* use standard msg */ ! 309: ! 310: cp = s; ! 311: for (;;) { ! 312: if ((c = getchar() & 0x7F) == 0) ! 313: return(0); /* break advances speed table */ ! 314: if (c==' ' || c=='\t' || c=='\f') ! 315: continue; /* ignore this char */ ! 316: if (c == deftch.t_eofc) /* EOF returns to init */ ! 317: slexit(1); ! 318: if (c == defsgt.sg_kill || c == '@') /* kill this line */ ! 319: { write(1, "\r\n", 2); ! 320: seenupper = seenlower = 0; ! 321: xflags = 0; ! 322: cp = s; ! 323: continue; ! 324: } ! 325: if (c == defsgt.sg_erase || c == '#') /* erase this char */ ! 326: { if (sp != s) ! 327: --cp; ! 328: continue; ! 329: } ! 330: if (c == '\n') ! 331: { putchar('\r'); ! 332: break; ! 333: } ! 334: if (c == '\r') ! 335: { putchar('\n'); ! 336: xflags |= CRMOD; ! 337: break; ! 338: } ! 339: if (isupper(c)) ! 340: seenupper = 1; ! 341: else if (islower(c)) ! 342: seenlower = 1; ! 343: if (cp < s+MAXNAME) ! 344: *cp++ = c; ! 345: } ! 346: if (cp == s) ! 347: goto loop; ! 348: *cp = 0; ! 349: if (seenupper!=0 && seenlower==0) ! 350: { xflags |= LCASE; ! 351: for (cp=s; *cp!=0; ++cp) ! 352: { if (isupper(*cp)) ! 353: *cp = tolower(*cp); ! 354: } ! 355: } ! 356: return(1); ! 357: } ! 358: ! 359: /* login attempt timeout routine */ ! 360: timeout() ! 361: { ! 362: printf("\r\n"); /* neatness */ ! 363: slexit(1); /* terminate and try force hangup */ ! 364: } ! 365: ! 366: /* sleep to make sure output has flushed, then exit */ ! 367: slexit(status) ! 368: { ! 369: sleep(3); ! 370: exit(status); ! 371: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.