Annotation of 43BSD/etc/getty/main.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.