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

Defined functions

dingdong defined in line 91; used 1 times
getname defined in line 244; used 1 times
interrupt defined in line 101; used 2 times
main defined in line 108; never used
oflush defined in line 397; used 4 times
prompt defined in line 404; used 2 times
putchr defined in line 381; used 10 times
putf defined in line 412; used 3 times
putpad defined in line 328; used 1 times
puts defined in line 370; used 7 times

Defined variables

copyright defined in line 8; never used
crmod defined in line 43; used 3 times
ctty defined in line 51; never used
defent defined in line 59; used 1 times
defstrs defined in line 60; used 1 times
dev defined in line 50; used 2 times
digit defined in line 46; used 3 times
env defined in line 64; used 3 times
hostname defined in line 48; used 5 times
intrupt defined in line 99; used 2 times
lower defined in line 45; used 3 times
ltc defined in line 38; used 13 times
name defined in line 49; used 7 times
obufcnt defined in line 379; used 5 times
outbuf defined in line 378; used 2 times
partab defined in line 66; used 1 times
sccsid defined in line 12; never used
tabent defined in line 61; used 1 times
tabstrs defined in line 62; used 1 times
tc defined in line 34; used 14 times
timeout defined in line 89; used 2 times
tmode defined in line 31; used 27 times
tmspc10 defined in line 324; used 3 times
ttyn defined in line 52; used 13 times
upper defined in line 44; used 3 times

Defined macros

EOT defined in line 87; used 1 times
ERASE defined in line 85; used 1 times
KILL defined in line 86; used 1 times
OBUFSIZ defined in line 56; used 2 times
TABBUFSIZ defined in line 57; used 4 times
Last modified: 1994-12-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4628
Valid CSS Valid XHTML 1.0 Strict