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

unix.superglobalmegacorp.com

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