Annotation of coherent/d/etc/getty.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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