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, &ltc);
 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: }

Defined functions

dingdong defined in line 93; used 1 times
getname defined in line 249; used 1 times
interrupt defined in line 103; used 2 times
main defined in line 110; never used
oflush defined in line 406; used 4 times
prompt defined in line 413; used 2 times
putchr defined in line 390; used 10 times
putf defined in line 421; used 3 times
putpad defined in line 337; used 1 times
puts defined in line 379; used 7 times

Defined variables

copyright defined in line 8; never used
crmod defined in line 45; used 3 times
ctty defined in line 53; never used
defent defined in line 61; used 1 times
defstrs defined in line 62; used 1 times
dev defined in line 52; used 2 times
digit defined in line 48; used 3 times
env defined in line 66; used 3 times
hostname defined in line 50; used 5 times
intrupt defined in line 101; used 2 times
lower defined in line 47; used 5 times
ltc defined in line 40; used 13 times
name defined in line 51; used 8 times
obufcnt defined in line 388; used 5 times
outbuf defined in line 387; used 2 times
partab defined in line 68; used 1 times
sccsid defined in line 14; never used
tabent defined in line 63; used 1 times
tabstrs defined in line 64; used 1 times
tc defined in line 36; used 14 times
timeout defined in line 91; used 2 times
tmode defined in line 33; used 29 times
tmspc10 defined in line 333; used 3 times
ttyn defined in line 54; used 13 times
upper defined in line 46; used 5 times

Defined macros

EOT defined in line 89; used 1 times
ERASE defined in line 87; used 1 times
KILL defined in line 88; used 1 times
OBUFSIZ defined in line 58; used 2 times
TABBUFSIZ defined in line 59; used 4 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2089
Valid CSS Valid XHTML 1.0 Strict