Annotation of 43BSDReno/libexec/telnetd/sys_term.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1989 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted provided
                      6:  * that: (1) source distributions retain this entire copyright notice and
                      7:  * comment, and (2) distributions including binaries display the following
                      8:  * acknowledgement:  ``This product includes software developed by the
                      9:  * University of California, Berkeley and its contributors'' in the
                     10:  * documentation or other materials provided with the distribution and in
                     11:  * all advertising materials mentioning features or use of this software.
                     12:  * Neither the name of the University nor the names of its contributors may
                     13:  * be used to endorse or promote products derived from this software without
                     14:  * specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)sys_term.c 5.10 (Berkeley) 6/30/90";
                     22: #endif /* not lint */
                     23: 
                     24: #include "telnetd.h"
                     25: #include "pathnames.h"
                     26: 
                     27: #ifdef NEWINIT
                     28: #include <initreq.h>
                     29: #else  /* NEWINIT*/
                     30: #include <utmp.h>
                     31: struct utmp wtmp;
                     32: 
                     33: # ifndef CRAY
                     34: char   wtmpf[] = "/usr/adm/wtmp";
                     35: char   utmpf[] = "/etc/utmp";
                     36: # else /* CRAY */
                     37: char   wtmpf[] = "/etc/wtmp";
                     38: # endif        /* CRAY */
                     39: #endif /* NEWINIT */
                     40: 
                     41: #define SCPYN(a, b)    (void) strncpy(a, b, sizeof(a))
                     42: #define SCMPN(a, b)    strncmp(a, b, sizeof(a))
                     43: 
                     44: #ifdef STREAMS
                     45: #include <sys/stream.h>
                     46: #endif
                     47: #include <sys/tty.h>
                     48: #ifdef t_erase
                     49: #undef t_erase
                     50: #undef t_kill
                     51: #undef t_intrc
                     52: #undef t_quitc
                     53: #undef t_startc
                     54: #undef t_stopc
                     55: #undef t_eofc
                     56: #undef t_brkc
                     57: #undef t_suspc
                     58: #undef t_dsuspc
                     59: #undef t_rprntc
                     60: #undef t_flushc
                     61: #undef t_werasc
                     62: #undef t_lnextc
                     63: #endif
                     64: 
                     65: #if defined(UNICOS5) && defined(CRAY2) && !defined(EXTPROC)
                     66: # define EXTPROC 0400
                     67: #endif
                     68: 
                     69: #ifndef        USE_TERMIO
                     70: struct termbuf {
                     71:        struct sgttyb sg;
                     72:        struct tchars tc;
                     73:        struct ltchars ltc;
                     74:        int state;
                     75:        int lflags;
                     76: } termbuf, termbuf2;
                     77: #else  /* USE_TERMIO */
                     78: # ifdef        SYSV_TERMIO
                     79: #      define termios termio
                     80: # endif
                     81: # ifndef TCSETA
                     82: #  ifdef TCSETS
                     83: #   define TCSETA TCSETS
                     84: #   define TCGETA TCGETS
                     85: #  else
                     86: #   define TCSETA TIOCSETAW
                     87: #   define TCGETA TIOCGETA
                     88: #  endif
                     89: # endif /* 4.4BSD */
                     90: struct termios termbuf, termbuf2;      /* pty control structure */
                     91: #endif /* USE_TERMIO */
                     92: 
                     93: /*
                     94:  * init_termbuf()
                     95:  * copy_termbuf(cp)
                     96:  * set_termbuf()
                     97:  *
                     98:  * These three routines are used to get and set the "termbuf" structure
                     99:  * to and from the kernel.  init_termbuf() gets the current settings.
                    100:  * copy_termbuf() hands in a new "termbuf" to write to the kernel, and
                    101:  * set_termbuf() writes the structure into the kernel.
                    102:  */
                    103: 
                    104: init_termbuf()
                    105: {
                    106: #ifndef        USE_TERMIO
                    107:        (void) ioctl(pty, TIOCGETP, (char *)&termbuf.sg);
                    108:        (void) ioctl(pty, TIOCGETC, (char *)&termbuf.tc);
                    109:        (void) ioctl(pty, TIOCGLTC, (char *)&termbuf.ltc);
                    110: # ifdef        TIOCGSTATE
                    111:        (void) ioctl(pty, TIOCGSTATE, (char *)&termbuf.state);
                    112: # endif
                    113: #else
                    114:        (void) ioctl(pty, TCGETA, (char *)&termbuf);
                    115: #endif
                    116:        termbuf2 = termbuf;
                    117: }
                    118: 
                    119: #if    defined(LINEMODE) && defined(TIOCPKT_IOCTL)
                    120: copy_termbuf(cp, len)
                    121: char *cp;
                    122: int len;
                    123: {
                    124:        if (len > sizeof(termbuf))
                    125:                len = sizeof(termbuf);
                    126:        bcopy(cp, (char *)&termbuf, len);
                    127:        termbuf2 = termbuf;
                    128: }
                    129: #endif /* defined(LINEMODE) && defined(TIOCPKT_IOCTL) */
                    130: 
                    131: set_termbuf()
                    132: {
                    133:        /*
                    134:         * Only make the necessary changes.
                    135:         */
                    136: #ifndef        USE_TERMIO
                    137:        if (bcmp((char *)&termbuf.sg, (char *)&termbuf2.sg, sizeof(termbuf.sg)))
                    138:                (void) ioctl(pty, TIOCSETP, (char *)&termbuf.sg);
                    139:        if (bcmp((char *)&termbuf.tc, (char *)&termbuf2.tc, sizeof(termbuf.tc)))
                    140:                (void) ioctl(pty, TIOCSETC, (char *)&termbuf.tc);
                    141:        if (bcmp((char *)&termbuf.ltc, (char *)&termbuf2.ltc,
                    142:                                                        sizeof(termbuf.ltc)))
                    143:                (void) ioctl(pty, TIOCSLTC, (char *)&termbuf.ltc);
                    144:        if (termbuf.lflags != termbuf2.lflags)
                    145:                (void) ioctl(pty, TIOCLSET, (char *)&termbuf.lflags);
                    146: #else  /* USE_TERMIO */
                    147:        if (bcmp((char *)&termbuf, (char *)&termbuf2, sizeof(termbuf)))
                    148:                (void) ioctl(pty, TCSETA, (char *)&termbuf);
                    149: # if   defined(CRAY2) && defined(UNCIOS5)
                    150:        needtermstat = 1;
                    151: # endif
                    152: #endif /* USE_TERMIO */
                    153: }
                    154: 
                    155: 
                    156: /*
                    157:  * spcset(func, valp, valpp)
                    158:  *
                    159:  * This function takes various special characters (func), and
                    160:  * sets *valp to the current value of that character, and
                    161:  * *valpp to point to where in the "termbuf" structure that
                    162:  * value is kept.
                    163:  *
                    164:  * It returns the SLC_ level of support for this function.
                    165:  */
                    166: 
                    167: #ifndef        USE_TERMIO
                    168: spcset(func, valp, valpp)
                    169: int func;
                    170: cc_t *valp;
                    171: cc_t **valpp;
                    172: {
                    173:        switch(func) {
                    174:        case SLC_EOF:
                    175:                *valp = termbuf.tc.t_eofc;
                    176:                *valpp = (cc_t *)&termbuf.tc.t_eofc;
                    177:                return(SLC_VARIABLE);
                    178:        case SLC_EC:
                    179:                *valp = termbuf.sg.sg_erase;
                    180:                *valpp = (cc_t *)&termbuf.sg.sg_erase;
                    181:                return(SLC_VARIABLE);
                    182:        case SLC_EL:
                    183:                *valp = termbuf.sg.sg_kill;
                    184:                *valpp = (cc_t *)&termbuf.sg.sg_kill;
                    185:                return(SLC_VARIABLE);
                    186:        case SLC_IP:
                    187:                *valp = termbuf.tc.t_intrc;
                    188:                *valpp = (cc_t *)&termbuf.tc.t_intrc;
                    189:                return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
                    190:        case SLC_ABORT:
                    191:                *valp = termbuf.tc.t_quitc;
                    192:                *valpp = (cc_t *)&termbuf.tc.t_quitc;
                    193:                return(SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
                    194:        case SLC_XON:
                    195:                *valp = termbuf.tc.t_startc;
                    196:                *valpp = (cc_t *)&termbuf.tc.t_startc;
                    197:                return(SLC_VARIABLE);
                    198:        case SLC_XOFF:
                    199:                *valp = termbuf.tc.t_stopc;
                    200:                *valpp = (cc_t *)&termbuf.tc.t_stopc;
                    201:                return(SLC_VARIABLE);
                    202:        case SLC_AO:
                    203:                *valp = termbuf.ltc.t_flushc;
                    204:                *valpp = (cc_t *)&termbuf.ltc.t_flushc;
                    205:                return(SLC_VARIABLE);
                    206:        case SLC_SUSP:
                    207:                *valp = termbuf.ltc.t_suspc;
                    208:                *valpp = (cc_t *)&termbuf.ltc.t_suspc;
                    209:                return(SLC_VARIABLE);
                    210:        case SLC_EW:
                    211:                *valp = termbuf.ltc.t_werasc;
                    212:                *valpp = (cc_t *)&termbuf.ltc.t_werasc;
                    213:                return(SLC_VARIABLE);
                    214:        case SLC_RP:
                    215:                *valp = termbuf.ltc.t_rprntc;
                    216:                *valpp = (cc_t *)&termbuf.ltc.t_rprntc;
                    217:                return(SLC_VARIABLE);
                    218:        case SLC_LNEXT:
                    219:                *valp = termbuf.ltc.t_lnextc;
                    220:                *valpp = (cc_t *)&termbuf.ltc.t_lnextc;
                    221:                return(SLC_VARIABLE);
                    222:        case SLC_FORW1:
                    223:                *valp = termbuf.tc.t_brkc;
                    224:                *valpp = (cc_t *)&termbuf.ltc.t_lnextc;
                    225:                return(SLC_VARIABLE);
                    226:        case SLC_BRK:
                    227:        case SLC_SYNCH:
                    228:        case SLC_AYT:
                    229:        case SLC_EOR:
                    230:                *valp = (cc_t)0;
                    231:                *valpp = (cc_t *)0;
                    232:                return(SLC_DEFAULT);
                    233:        default:
                    234:                *valp = (cc_t)0;
                    235:                *valpp = (cc_t *)0;
                    236:                return(SLC_NOSUPPORT);
                    237:        }
                    238: }
                    239: 
                    240: #else  /* USE_TERMIO */
                    241: 
                    242: spcset(func, valp, valpp)
                    243: int func;
                    244: cc_t *valp;
                    245: cc_t **valpp;
                    246: {
                    247: 
                    248: #define        setval(a, b)    *valp = termbuf.c_cc[a]; \
                    249:                        *valpp = &termbuf.c_cc[a]; \
                    250:                        return(b);
                    251: #define        defval(a) *valp = ((cc_t)a); *valpp = (cc_t *)0; return(SLC_DEFAULT);
                    252: 
                    253:        switch(func) {
                    254:        case SLC_EOF:
                    255:                setval(VEOF, SLC_VARIABLE);
                    256:        case SLC_EC:
                    257:                setval(VERASE, SLC_VARIABLE);
                    258:        case SLC_EL:
                    259:                setval(VKILL, SLC_VARIABLE);
                    260:        case SLC_IP:
                    261:                setval(VINTR, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
                    262:        case SLC_ABORT:
                    263:                setval(VQUIT, SLC_VARIABLE|SLC_FLUSHIN|SLC_FLUSHOUT);
                    264:        case SLC_XON:
                    265: #ifdef VSTART
                    266:                setval(VSTART, SLC_VARIABLE);
                    267: #else
                    268:                defval(0x13);
                    269: #endif
                    270:        case SLC_XOFF:
                    271: #ifdef VSTOP
                    272:                setval(VSTOP, SLC_VARIABLE);
                    273: #else
                    274:                defval(0x11);
                    275: #endif
                    276:        case SLC_EW:
                    277: #ifdef VWERASE
                    278:                setval(VWERASE, SLC_VARIABLE);
                    279: #else
                    280:                defval(0);
                    281: #endif
                    282:        case SLC_RP:
                    283: #ifdef VREPRINT
                    284:                setval(VREPRINT, SLC_VARIABLE);
                    285: #else
                    286:                defval(0);
                    287: #endif
                    288:        case SLC_LNEXT:
                    289: #ifdef VLNEXT
                    290:                setval(VLNEXT, SLC_VARIABLE);
                    291: #else
                    292:                defval(0);
                    293: #endif
                    294:        case SLC_AO:
                    295: #ifdef VFLUSHO
                    296:                setval(VFLUSHO, SLC_VARIABLE|SLC_FLUSHOUT);
                    297: #else
                    298:                defval(0);
                    299: #endif
                    300:        case SLC_SUSP:
                    301: #ifdef VSUSP
                    302:                setval(VSUSP, SLC_VARIABLE|SLC_FLUSHIN);
                    303: #else
                    304:                defval(0);
                    305: #endif
                    306: #ifdef VEOL
                    307:        case SLC_FORW1:
                    308:                setval(VEOL, SLC_VARIABLE);
                    309: #endif
                    310: #ifdef VEOL2
                    311:        case SLC_FORW2:
                    312:                setval(VEOL2, SLC_VARIABLE);
                    313: #endif
                    314: 
                    315:        case SLC_BRK:
                    316:        case SLC_SYNCH:
                    317:        case SLC_AYT:
                    318:        case SLC_EOR:
                    319:                defval(0);
                    320: 
                    321:        default:
                    322:                *valp = 0;
                    323:                *valpp = 0;
                    324:                return(SLC_NOSUPPORT);
                    325:        }
                    326: }
                    327: #endif /* USE_TERMIO */
                    328: 
                    329: #ifdef CRAY
                    330: /*
                    331:  * getnpty()
                    332:  *
                    333:  * Return the number of pty's configured into the system.
                    334:  */
                    335: getnpty()
                    336: {
                    337: #ifdef _SC_CRAY_NPTY
                    338:        return sysconf(_SC_CRAY_NPTY);
                    339: #else
                    340:        return 128;
                    341: #endif /* _SC_CRAY_NPTY */
                    342: }
                    343: #endif /* CRAY */
                    344: 
                    345: /*
                    346:  * getpty()
                    347:  *
                    348:  * Allocate a pty.  As a side effect, the external character
                    349:  * array "line" contains the name of the slave side.
                    350:  *
                    351:  * Returns the file descriptor of the opened pty.
                    352:  */
                    353: char *line = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
                    354: 
                    355: getpty()
                    356: {
                    357:        register int p;
                    358: #ifndef CRAY
                    359:        register char c, *p1, *p2;
                    360:        register int i;
                    361: 
                    362:        (void) sprintf(line, "/dev/ptyXX");
                    363:        p1 = &line[8];
                    364:        p2 = &line[9];
                    365: 
                    366:        for (c = 'p'; c <= 's'; c++) {
                    367:                struct stat stb;
                    368: 
                    369:                *p1 = c;
                    370:                *p2 = '0';
                    371:                if (stat(line, &stb) < 0)
                    372:                        break;
                    373:                for (i = 0; i < 16; i++) {
                    374:                        *p2 = "0123456789abcdef"[i];
                    375:                        p = open(line, 2);
                    376:                        if (p > 0) {
                    377:                                line[5] = 't';
                    378:                                return(p);
                    379:                        }
                    380:                }
                    381:        }
                    382: #else  /* CRAY */
                    383:        register int npty;
                    384:        extern lowpty, highpty;
                    385: 
                    386:        for (npty = lowpty; npty <= highpty; npty++) {
                    387:                (void) sprintf(line, "/dev/pty/%03d", npty);
                    388:                p = open(line, 2);
                    389:                if (p < 0)
                    390:                        continue;
                    391:                (void) sprintf(line, "/dev/ttyp%03d", npty);
                    392:                if (access(line, 6) == 0)
                    393:                        return(p);
                    394:                else {
                    395:                        /* no tty side to pty so skip it */
                    396:                        (void) close(p);
                    397:                }
                    398:        }
                    399: #endif /* CRAY */
                    400:        return(-1);
                    401: }
                    402: 
                    403: #ifdef LINEMODE
                    404: /*
                    405:  * tty_flowmode()      Find out if flow control is enabled or disabled.
                    406:  * tty_linemode()      Find out if linemode (external processing) is enabled.
                    407:  * tty_setlinemod(on)  Turn on/off linemode.
                    408:  * tty_isecho()                Find out if echoing is turned on.
                    409:  * tty_setecho(on)     Enable/disable character echoing.
                    410:  * tty_israw()         Find out if terminal is in RAW mode.
                    411:  * tty_binaryin(on)    Turn on/off BINARY on input.
                    412:  * tty_binaryout(on)   Turn on/off BINARY on output.
                    413:  * tty_isediting()     Find out if line editing is enabled.
                    414:  * tty_istrapsig()     Find out if signal trapping is enabled.
                    415:  * tty_setedit(on)     Turn on/off line editing.
                    416:  * tty_setsig(on)      Turn on/off signal trapping.
                    417:  * tty_issofttab()     Find out if tab expansion is enabled.
                    418:  * tty_setsofttab(on)  Turn on/off soft tab expansion.
                    419:  * tty_islitecho()     Find out if typed control chars are echoed literally
                    420:  * tty_setlitecho()    Turn on/off literal echo of control chars
                    421:  * tty_tspeed(val)     Set transmit speed to val.
                    422:  * tty_rspeed(val)     Set receive speed to val.
                    423:  */
                    424: 
                    425: tty_flowmode()
                    426: {
                    427: #ifndef USE_TERMIO
                    428:        return((termbuf.tc.t_startc) > 0 && (termbuf.tc.t_stopc) > 0);
                    429: #else
                    430:        return(termbuf.c_iflag & IXON ? 1 : 0);
                    431: #endif
                    432: }
                    433: 
                    434: tty_linemode()
                    435: {
                    436: #ifndef        USE_TERMIO
                    437:        return(termbuf.state & TS_EXTPROC);
                    438: #else
                    439:        return(termbuf.c_lflag & EXTPROC);
                    440: #endif
                    441: }
                    442: 
                    443: tty_setlinemode(on)
                    444: int on;
                    445: {
                    446: #ifdef TIOCEXT
                    447:        (void) ioctl(pty, TIOCEXT, (char *)&on);
                    448: #else  /* !TIOCEXT */
                    449: #ifdef EXTPROC
                    450:        if (on)
                    451:                termbuf.c_lflag |= EXTPROC;
                    452:        else
                    453:                termbuf.c_lflag &= ~EXTPROC;
                    454: #endif
                    455:        set_termbuf();
                    456: #endif /* TIOCEXT */
                    457: }
                    458: 
                    459: tty_isecho()
                    460: {
                    461: #ifndef USE_TERMIO
                    462:        return (termbuf.sg.sg_flags & ECHO);
                    463: #else
                    464:        return (termbuf.c_lflag & ECHO);
                    465: #endif
                    466: }
                    467: #endif /* LINEMODE */
                    468: 
                    469: tty_setecho(on)
                    470: {
                    471: #ifndef        USE_TERMIO
                    472:        if (on)
                    473:                termbuf.sg.sg_flags |= ECHO|CRMOD;
                    474:        else
                    475:                termbuf.sg.sg_flags &= ~(ECHO|CRMOD);
                    476: #else
                    477:        if (on)
                    478:                termbuf.c_lflag |= ECHO;
                    479:        else
                    480:                termbuf.c_lflag &= ~ECHO;
                    481: #endif
                    482: }
                    483: 
                    484: #if    defined(LINEMODE) && defined(KLUDGELINEMODE)
                    485: tty_israw()
                    486: {
                    487: #ifndef USE_TERMIO
                    488:        return(termbuf.sg.sg_flags & RAW);
                    489: #else
                    490:        return(!(termbuf.c_lflag & ICANON));
                    491: #endif
                    492: }
                    493: #endif /* defined(LINEMODE) && defined(KLUDGELINEMODE) */
                    494: 
                    495: tty_binaryin(on)
                    496: {
                    497: #ifndef        USE_TERMIO
                    498:        if (on)
                    499:                termbuf.lflags |= LPASS8;
                    500:        else
                    501:                termbuf.lflags &= ~LPASS8;
                    502: #else
                    503:        if (on) {
                    504:                termbuf.c_lflag &= ~ISTRIP;
                    505:        } else {
                    506:                termbuf.c_lflag |= ISTRIP;
                    507:        }
                    508: #endif
                    509: }
                    510: 
                    511: tty_binaryout(on)
                    512: {
                    513: #ifndef        USE_TERMIO
                    514:        if (on)
                    515:                termbuf.lflags |= LLITOUT;
                    516:        else
                    517:                termbuf.lflags &= ~LLITOUT;
                    518: #else
                    519:        if (on) {
                    520:                termbuf.c_cflag &= ~(CSIZE|PARENB);
                    521:                termbuf.c_cflag |= CS8;
                    522:                termbuf.c_oflag &= ~OPOST;
                    523:        } else {
                    524:                termbuf.c_cflag &= ~CSIZE;
                    525:                termbuf.c_cflag |= CS7|PARENB;
                    526:                termbuf.c_oflag |= OPOST;
                    527:        }
                    528: #endif
                    529: }
                    530: 
                    531: tty_isbinaryin()
                    532: {
                    533: #ifndef        USE_TERMIO
                    534:        return(termbuf.lflags & LPASS8);
                    535: #else
                    536:        return(!(termbuf.c_iflag & ISTRIP));
                    537: #endif
                    538: }
                    539: 
                    540: tty_isbinaryout()
                    541: {
                    542: #ifndef        USE_TERMIO
                    543:        return(termbuf.lflags & LLITOUT);
                    544: #else
                    545:        return(!(termbuf.c_oflag&OPOST));
                    546: #endif
                    547: }
                    548: 
                    549: #ifdef LINEMODE
                    550: tty_isediting()
                    551: {
                    552: #ifndef USE_TERMIO
                    553:        return(!(termbuf.sg.sg_flags & (CBREAK|RAW)));
                    554: #else
                    555:        return(termbuf.c_lflag & ICANON);
                    556: #endif
                    557: }
                    558: 
                    559: tty_istrapsig()
                    560: {
                    561: #ifndef USE_TERMIO
                    562:        return(!(termbuf.sg.sg_flags&RAW));
                    563: #else
                    564:        return(termbuf.c_lflag & ISIG);
                    565: #endif
                    566: }
                    567: 
                    568: tty_setedit(on)
                    569: int on;
                    570: {
                    571: #ifndef USE_TERMIO
                    572:        if (on)
                    573:                termbuf.sg.sg_flags &= ~CBREAK;
                    574:        else
                    575:                termbuf.sg.sg_flags |= CBREAK;
                    576: #else
                    577:        if (on)
                    578:                termbuf.c_lflag |= ICANON;
                    579:        else
                    580:                termbuf.c_lflag &= ~ICANON;
                    581: #endif
                    582: }
                    583: 
                    584: tty_setsig(on)
                    585: int on;
                    586: {
                    587: #ifndef        USE_TERMIO
                    588:        if (on)
                    589:                ;
                    590: #else
                    591:        if (on)
                    592:                termbuf.c_lflag |= ISIG;
                    593:        else
                    594:                termbuf.c_lflag &= ~ISIG;
                    595: #endif
                    596: }
                    597: #endif /* LINEMODE */
                    598: 
                    599: tty_issofttab()
                    600: {
                    601: #ifndef        USE_TERMIO
                    602:        return (termbuf.sg.sg_flags & XTABS);
                    603: #else
                    604: # ifdef        OXTABS
                    605:        return (termbuf.c_oflag & OXTABS);
                    606: # endif
                    607: # ifdef        TABDLY
                    608:        return ((termbuf.c_oflag & TABDLY) == TAB3);
                    609: # endif
                    610: #endif
                    611: }
                    612: 
                    613: tty_setsofttab(on)
                    614: int on;
                    615: {
                    616: #ifndef        USE_TERMIO
                    617:        if (on)
                    618:                termbuf.sg.sg_flags |= XTABS;
                    619:        else
                    620:                termbuf.sg.sg_flags &= ~XTABS;
                    621: #else
                    622:        if (on) {
                    623: # ifdef        OXTABS
                    624:                termbuf.c_oflag |= OXTABS;
                    625: # endif
                    626: # ifdef        TABDLY
                    627:                termbuf.c_oflag &= ~TABDLY;
                    628:                termbuf.c_oflag |= TAB3;
                    629: # endif
                    630:        } else {
                    631: # ifdef        OXTABS
                    632:                termbuf.c_oflag &= ~OXTABS;
                    633: # endif
                    634: # ifdef        TABDLY
                    635:                termbuf.c_oflag &= ~TABDLY;
                    636:                termbuf.c_oflag |= TAB0;
                    637: # endif
                    638:        }
                    639: #endif
                    640: }
                    641: 
                    642: tty_islitecho()
                    643: {
                    644: #ifndef        USE_TERMIO
                    645:        return (!(termbuf.sg.sg_flags & CTLECH));
                    646: #else
                    647: # ifdef        ECHOCTL
                    648:        return (!(termbuf.c_lflag & ECHOCTL));
                    649: # endif
                    650: # ifdef        TCTLECH
                    651:        return (!(termbuf.c_lflag & TCTLECH));
                    652: # endif
                    653: # if   !defined(ECHOCTL) && !defined(TCTLECH)
                    654:        return (0);     /* assumes ctl chars are echoed '^x' */
                    655: # endif
                    656: #endif
                    657: }
                    658: 
                    659: tty_setlitecho(on)
                    660: int on;
                    661: {
                    662: #ifndef        USE_TERMIO
                    663:        if (on)
                    664:                termbuf.sg.sg_flags &= ~CTLECH;
                    665:        else
                    666:                termbuf.sg.sg_flags |= CTLECH;
                    667: #else
                    668: # ifdef        ECHOCTL
                    669:        if (on)
                    670:                termbuf.c_lflag &= ~ECHOCTL;
                    671:        else
                    672:                termbuf.c_lflag |= ECHOCTL;
                    673: # endif
                    674: # ifdef        TCTLECH
                    675:        if (on)
                    676:                termbuf.c_lflag &= ~TCTLECH;
                    677:        else
                    678:                termbuf.c_lflag |= TCTLECH;
                    679: # endif
                    680: #endif
                    681: }
                    682: 
                    683: /*
                    684:  * A table of available terminal speeds
                    685:  */
                    686: struct termspeeds {
                    687:        int     speed;
                    688:        int     value;
                    689: } termspeeds[] = {
                    690:        { 0,     B0 },    { 50,    B50 },   { 75,    B75 },
                    691:        { 110,   B110 },  { 134,   B134 },  { 150,   B150 },
                    692:        { 200,   B200 },  { 300,   B300 },  { 600,   B600 },
                    693:        { 1200,  B1200 }, { 1800,  B1800 }, { 2400,  B2400 },
                    694:        { 4800,  B4800 }, { 9600,  B9600 }, { 19200, B9600 },
                    695:        { 38400, B9600 }, { -1,    B9600 }
                    696: };
                    697: 
                    698: tty_tspeed(val)
                    699: {
                    700:        register struct termspeeds *tp;
                    701: 
                    702:        for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
                    703:                ;
                    704: #ifndef        USE_TERMIO
                    705:        termbuf.sg.sg_ospeed = tp->value;
                    706: #else
                    707: # ifdef        CBAUD
                    708:        termbuf.c_cflag &= ~CBAUD;
                    709:        termbuf.c_cflag |= tp->value;
                    710: # else
                    711:        termbuf.c_ospeed = tp->value;
                    712: # endif
                    713: #endif
                    714: }
                    715: 
                    716: tty_rspeed(val)
                    717: {
                    718:        register struct termspeeds *tp;
                    719: 
                    720:        for (tp = termspeeds; (tp->speed != -1) && (val > tp->speed); tp++)
                    721:                ;
                    722: #ifndef        USE_TERMIO
                    723:        termbuf.sg.sg_ispeed = tp->value;
                    724: #else
                    725: # ifdef        CBAUD
                    726:        termbuf.c_cflag &= ~CBAUD;
                    727:        termbuf.c_cflag |= tp->value;
                    728: # else
                    729:        termbuf.c_ispeed = tp->value;
                    730: # endif
                    731: #endif
                    732: }
                    733: 
                    734: #if    defined(CRAY2) && defined(UNICOS5)
                    735: tty_isnewmap()
                    736: {
                    737:        return((termbuf.c_oflag & OPOST) && (termbuf.c_oflag & ONLCR) &&
                    738:                        !(termbuf.c_oflag & ONLRET));
                    739: }
                    740: #endif
                    741: 
                    742: #ifdef CRAY
                    743: # ifndef NEWINIT
                    744: extern struct utmp wtmp;
                    745: extern char wtmpf[];
                    746: # else /* NEWINIT */
                    747: int    gotalarm;
                    748: /* ARGSUSED */
                    749: void
                    750: nologinproc(sig)
                    751: int sig;
                    752: {
                    753:        gotalarm++;
                    754: }
                    755: # endif        /* NEWINIT */
                    756: #endif /* CRAY */
                    757: 
                    758: /*
                    759:  * getptyslave()
                    760:  *
                    761:  * Open the slave side of the pty, and do any initialization
                    762:  * that is necessary.  The return value is a file descriptor
                    763:  * for the slave side.
                    764:  */
                    765: getptyslave()
                    766: {
                    767:        register int t = -1;
                    768: 
                    769: #ifndef        CRAY
                    770:        /*
                    771:         * Disassociate self from control terminal and open ttyp side.
                    772:         * Set important flags on ttyp and ptyp.
                    773:         */
                    774:        t = open(_PATH_TTY, O_RDWR);
                    775:        if (t >= 0) {
                    776:                (void) ioctl(t, TIOCNOTTY, (char *)0);
                    777:                (void) close(t);
                    778:        }
                    779: 
                    780:        t = open(line, O_RDWR);
                    781:        if (t < 0)
                    782:                fatalperror(net, line);
                    783:        if (fchmod(t, 0))
                    784:                fatalperror(net, line);
                    785: #if BSD <= 43
                    786:        (void) signal(SIGHUP, SIG_IGN);
                    787:        vhangup();
                    788:        (void) signal(SIGHUP, SIG_DFL);
                    789:        t = open(line, O_RDWR);
                    790:        if (t < 0)
                    791:                fatalperror(net, line);
                    792: #endif
                    793: 
                    794:        init_termbuf();
                    795: #ifndef        USE_TERMIO
                    796:        termbuf.sg.sg_flags |= CRMOD|ANYP|ECHO|XTABS;
                    797:        termbuf.sg.sg_ospeed = termbuf.sg.sg_ispeed = B9600;
                    798: #else
                    799:        termbuf.c_lflag |= ECHO;
                    800: #ifndef        OXTABS
                    801: #define OXTABS 0
                    802: #endif
                    803:        termbuf.c_oflag |= ONLCR|OXTABS;
                    804:        termbuf.c_iflag |= ICRNL;
                    805:        termbuf.c_iflag &= ~IXOFF;
                    806: # ifdef        CBAUD
                    807:        termbuf.c_cflag &= ~CBAUD;
                    808:        termbuf.c_cflag |= B9600;
                    809: # else /* CBAUD */
                    810:        termbuf.c_ospeed = termbuf.c_ispeed = B9600;
                    811: # endif        /* CBAUD */
                    812: #endif
                    813:        set_termbuf();
                    814: #else  /* CRAY */
                    815:        (void) chown(line, 0, 0);
                    816:        (void) chmod(line, 0600);
                    817: #endif /* CRAY */
                    818:        return(t);
                    819: }
                    820: 
                    821: #ifdef NEWINIT
                    822: char *gen_id = "fe";
                    823: #endif
                    824: 
                    825: /*
                    826:  * startslave(t, host)
                    827:  *
                    828:  * Given a file descriptor (t) for a tty, and a hostname, do whatever
                    829:  * is necessary to startup the login process on the slave side of the pty.
                    830:  */
                    831: 
                    832: /* ARGSUSED */
                    833: startslave(t, host)
                    834: int t;
                    835: char *host;
                    836: {
                    837:        register int i;
                    838:        long time();
                    839: 
                    840: #ifndef        NEWINIT
                    841: # ifdef        CRAY
                    842:        utmp_sig_init();
                    843: # endif        /* CRAY */
                    844: 
                    845:        if ((i = fork()) < 0)
                    846:                fatalperror(net, "fork");
                    847:        if (i) {
                    848: # ifdef        CRAY
                    849:                /*
                    850:                 * Cray parent will create utmp entry for child and send
                    851:                 * signal to child to tell when done.  Child waits for signal
                    852:                 * before doing anything important.
                    853:                 */
                    854:                register int pid = i;
                    855: 
                    856:                setpgrp();
                    857:                utmp_sig_reset();               /* reset handler to default */
                    858:                /*
                    859:                 * Create utmp entry for child
                    860:                 */
                    861:                (void) time(&wtmp.ut_time);
                    862:                wtmp.ut_type = LOGIN_PROCESS;
                    863:                wtmp.ut_pid = pid;
                    864:                SCPYN(wtmp.ut_user, "LOGIN");
                    865:                SCPYN(wtmp.ut_host, host);
                    866:                SCPYN(wtmp.ut_line, line + sizeof("/dev/") - 1);
                    867:                SCPYN(wtmp.ut_id, wtmp.ut_line+3);
                    868:                pututline(&wtmp);
                    869:                endutent();
                    870:                if ((i = open(wtmpf, O_WRONLY|O_APPEND)) >= 0) {
                    871:                        (void) write(i, (char *)&wtmp, sizeof(struct utmp));
                    872:                        (void) close(i);
                    873:                }
                    874:                utmp_sig_notify(pid);
                    875: # endif        /* CRAY */
                    876:                (void) close(t);
                    877:        } else {
                    878:                start_login(t, host);
                    879:                /*NOTREACHED*/
                    880:        }
                    881: #else  /* NEWINIT */
                    882: 
                    883:        extern char *ptyip;
                    884:        struct init_request request;
                    885:        void nologinproc();
                    886:        register int n;
                    887: 
                    888:        /*
                    889:         * Init will start up login process if we ask nicely.  We only wait
                    890:         * for it to start up and begin normal telnet operation.
                    891:         */
                    892:        if ((i = open(INIT_FIFO, O_WRONLY)) < 0) {
                    893:                char tbuf[128];
                    894:                (void) sprintf(tbuf, "Can't open %s\n", INIT_FIFO);
                    895:                fatalperror(net, tbuf);
                    896:        }
                    897:        memset((char *)&request, 0, sizeof(request));
                    898:        request.magic = INIT_MAGIC;
                    899:        SCPYN(request.gen_id, gen_id);
                    900:        SCPYN(request.tty_id, &line[8]);
                    901:        SCPYN(request.host, host);
                    902:        SCPYN(request.term_type, terminaltype);
                    903: #if    !defined(UNICOS5)
                    904:        request.signal = SIGCLD;
                    905:        request.pid = getpid();
                    906: #endif
                    907: #ifdef BFTPDAEMON
                    908:        /*
                    909:         * Are we working as the bftp daemon?
                    910:         */
                    911:        if (bftpd) {
                    912:                SCPYN(request.exec_name, BFTPPATH);
                    913:        }
                    914: #endif /* BFTPDAEMON */
                    915:        if (write(i, (char *)&request, sizeof(request)) < 0) {
                    916:                char tbuf[128];
                    917:                (void) sprintf(tbuf, "Can't write to %s\n", INIT_FIFO);
                    918:                fatalperror(net, tbuf);
                    919:        }
                    920:        (void) close(i);
                    921:        (void) signal(SIGALRM, nologinproc);
                    922:        for (i = 0; ; i++) {
                    923:                char tbuf[128];
                    924:                alarm(15);
                    925:                n = read(pty, ptyip, BUFSIZ);
                    926:                if (i == 3 || n >= 0 || !gotalarm)
                    927:                        break;
                    928:                gotalarm = 0;
                    929:                sprintf(tbuf, "telnetd: waiting for /etc/init to start login process on %s\r\n", line);
                    930:                (void) write(net, tbuf, strlen(tbuf));
                    931:        }
                    932:        if (n < 0 && gotalarm)
                    933:                fatal(net, "/etc/init didn't start login process");
                    934:        pcc += n;
                    935:        alarm(0);
                    936:        (void) signal(SIGALRM, SIG_DFL);
                    937: 
                    938:        return;
                    939: #endif /* NEWINIT */
                    940: }
                    941: 
                    942: char   *envinit[3];
                    943: extern char **environ;
                    944: 
                    945: init_env()
                    946: {
                    947:        extern char *getenv();
                    948:        char **envp;
                    949: 
                    950:        envp = envinit;
                    951:        if (*envp = getenv("TZ"))
                    952:                *envp++ -= 3;
                    953: #ifdef CRAY
                    954:        else
                    955:                *envp++ = "TZ=GMT0";
                    956: #endif
                    957:        *envp = 0;
                    958:        environ = envinit;
                    959: }
                    960: 
                    961: #ifdef CRAY
                    962: /*
                    963:  * These are environment variable that we
                    964:  * don't put on the argument line.
                    965:  */
                    966: char *invalid[] = {
                    967:        "USER=",        /* Set up by login */
                    968:        "HOME=",        /* Set up by login */
                    969:        "LOGNAME=",     /* Set up by login */
                    970:        "TMPDIR=",      /* Set up by login */
                    971:        "SHELL=",       /* Set up by login */
                    972:        "PATH=",        /* Set up by login */
                    973:        "MAIL=",        /* Set up by login */
                    974:        "TZ=",          /* Login gets it from the environment */
                    975:        "TERM=",        /* Login gets it from the environment */
                    976:        0
                    977: };
                    978: #endif
                    979: 
                    980: #ifndef        NEWINIT
                    981: 
                    982: /*
                    983:  * start_login(t, host)
                    984:  *
                    985:  * Assuming that we are now running as a child processes, this
                    986:  * function will turn us into the login process.
                    987:  */
                    988: 
                    989: start_login(t, host)
                    990: int t;
                    991: char *host;
                    992: {
                    993:        register char *cp;
                    994:        register char **argv;
                    995:        char **addarg();
                    996: #ifdef CRAY
                    997:        register char **cpp, **cpp2;
                    998:        utmp_sig_wait();
                    999: # ifndef TCVHUP
                   1000:        setpgrp();
                   1001: # endif
                   1002:        t = open(line, 2);      /* open ttyp */
                   1003:        if (t < 0)
                   1004:                fatalperror(net, line);
                   1005: # ifdef        TCVHUP
                   1006:        /*
                   1007:         * Hangup anybody else using this ttyp, then reopen it for
                   1008:         * ourselves.
                   1009:         */
                   1010:        (void) chown(line, 0, 0);
                   1011:        (void) chmod(line, 0600);
                   1012:        (void) signal(SIGHUP, SIG_IGN);
                   1013:        (void) ioctl(t, TCVHUP, (char *)0);
                   1014:        (void) signal(SIGHUP, SIG_DFL);
                   1015:        setpgrp();
                   1016:        i = open(line, 2);
                   1017:        if (i < 0)
                   1018:                fatalperror(net, line);
                   1019:        (void) close(t);
                   1020:        t = i;
                   1021: # endif        /* TCVHUP */
                   1022:        /*
                   1023:         * set ttyp modes as we like them to be
                   1024:         */
                   1025:        init_termbuf();
                   1026:        termbuf.c_oflag = OPOST|ONLCR|TAB3;
                   1027:        termbuf.c_iflag = IGNPAR|ISTRIP|ICRNL|IXON;
                   1028:        termbuf.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK;
                   1029:        termbuf.c_cflag = EXTB|HUPCL|CS8;
                   1030:        set_termbuf();
                   1031: #endif /* CRAY */
                   1032: 
                   1033:        /*
                   1034:         * set up standard paths before forking to login
                   1035:         */
                   1036: #if BSD > 43
                   1037:        if (login_tty(t) == -1)
                   1038:                fatalperror(net, "login_tty");
                   1039: #else
                   1040:        (void) dup2(t, 0);
                   1041:        (void) dup2(t, 1);
                   1042:        (void) dup2(t, 2);
                   1043:        (void) close(t);
                   1044: #endif
                   1045:        if (net > 2)
                   1046:                (void) close(net);
                   1047:        if (pty > 2)
                   1048:                (void) close(pty);
                   1049:        /*
                   1050:         * -h : pass on name of host.
                   1051:         *              WARNING:  -h is accepted by login if and only if
                   1052:         *                      getuid() == 0.
                   1053:         * -p : don't clobber the environment (so terminal type stays set).
                   1054:         */
                   1055:        argv = addarg(0, "login");
                   1056:        argv = addarg(argv, "-h");
                   1057:        argv = addarg(argv, host);
                   1058: #if    !defined(CRAY) && !defined(NO_LOGIN_P)
                   1059:        argv = addarg(argv, "-p");
                   1060: #endif
                   1061: #ifdef BFTPDAEMON
                   1062:        /*
                   1063:         * Are we working as the bftp daemon?  If so, then ask login
                   1064:         * to start bftp instead of shell.
                   1065:         */
                   1066:        if (bftpd) {
                   1067:                argv = addarg(argv, "-e");
                   1068:                argv = addarg(argv, BFTPPATH);
                   1069:        } else 
                   1070: #endif
                   1071:        if (getenv("USER")) {
                   1072:                argv = addarg(argv, getenv("USER"));
                   1073:        }
                   1074: #ifdef CRAY
                   1075:        for (cpp = environ; *cpp; cpp++) {
                   1076:                for (cpp2 = invalid; *cpp2; cpp2++)
                   1077:                        if (strncmp(*cpp2, *cpp, strlen(*cpp2)) == 0)
                   1078:                                break;
                   1079:                if (*cpp2)
                   1080:                        continue;
                   1081:                argv = addarg(argv, *cpp);
                   1082:        }
                   1083: #endif
                   1084: 
                   1085:        execv(_PATH_LOGIN, argv);
                   1086: 
                   1087:        syslog(LOG_ERR, "%s: %m\n", _PATH_LOGIN);
                   1088:        fatalperror(net, _PATH_LOGIN);
                   1089:        /*NOTREACHED*/
                   1090: }
                   1091: 
                   1092: char **
                   1093: addarg(argv, val)
                   1094: register char **argv;
                   1095: register char *val;
                   1096: {
                   1097:        register char **cpp;
                   1098:        char *malloc();
                   1099: 
                   1100:        if (argv == NULL) {
                   1101:                /*
                   1102:                 * 10 entries, a leading length, and a null
                   1103:                 */
                   1104:                argv = (char **)malloc(sizeof(*argv) * 12);
                   1105:                if (argv == NULL)
                   1106:                        return(NULL);
                   1107:                *argv++ = (char *)10;
                   1108:                *argv = (char *)0;
                   1109:        }
                   1110:        for (cpp = argv; *cpp; cpp++)
                   1111:                ;
                   1112:        if (cpp == &argv[(int)argv[-1]]) {
                   1113:                --argv;
                   1114:                *argv = (char *)((int)(*argv) + 10);
                   1115:                argv = (char **)realloc(argv, (int)(*argv) + 2);
                   1116:                if (argv == NULL)
                   1117:                        return(NULL);
                   1118:                argv++;
                   1119:                cpp = &argv[(int)argv[-1] - 10];
                   1120:        }
                   1121:        *cpp++ = val;
                   1122:        *cpp = 0;
                   1123:        return(argv);
                   1124: }
                   1125: #endif NEWINIT
                   1126: 
                   1127: /*
                   1128:  * cleanup()
                   1129:  *
                   1130:  * This is the routine to call when we are all through, to
                   1131:  * clean up anything that needs to be cleaned up.
                   1132:  */
                   1133: cleanup()
                   1134: {
                   1135: 
                   1136: #ifndef        CRAY
                   1137: # if BSD > 43
                   1138:        char *p;
                   1139: 
                   1140:        p = line + sizeof("/dev/") - 1;
                   1141:        if (logout(p))
                   1142:                logwtmp(p, "", "");
                   1143:        (void)chmod(line, 0666);
                   1144:        (void)chown(line, 0, 0);
                   1145:        *p = 'p';
                   1146:        (void)chmod(line, 0666);
                   1147:        (void)chown(line, 0, 0);
                   1148: # else
                   1149:        rmut();
                   1150:        vhangup();      /* XXX */
                   1151: # endif
                   1152:        (void) shutdown(net, 2);
                   1153: #else  /* CRAY */
                   1154: # ifndef NEWINIT
                   1155:        rmut(line);
                   1156:        (void) shutdown(net, 2);
                   1157:        kill(0, SIGHUP);
                   1158: # else /* NEWINIT */
                   1159:        (void) shutdown(net, 2);
                   1160: # endif        /* NEWINT */
                   1161: #endif /* CRAY */
                   1162:        exit(1);
                   1163: }
                   1164: 
                   1165: #if    defined(CRAY) && !defined(NEWINIT)
                   1166: /*
                   1167:  * _utmp_sig_rcv
                   1168:  * utmp_sig_init
                   1169:  * utmp_sig_wait
                   1170:  *     These three functions are used to coordinate the handling of
                   1171:  *     the utmp file between the server and the soon-to-be-login shell.
                   1172:  *     The server actually creates the utmp structure, the child calls
                   1173:  *     utmp_sig_wait(), until the server calls utmp_sig_notify() and
                   1174:  *     signals the future-login shell to proceed.
                   1175:  */
                   1176: static int caught=0;           /* NZ when signal intercepted */
                   1177: static void (*func)();         /* address of previous handler */
                   1178: 
                   1179: void
                   1180: _utmp_sig_rcv(sig)
                   1181: int sig;
                   1182: {
                   1183:        caught = 1;
                   1184:        (void) signal(SIGUSR1, func);
                   1185: }
                   1186: 
                   1187: utmp_sig_init()
                   1188: {
                   1189:        /*
                   1190:         * register signal handler for UTMP creation
                   1191:         */
                   1192:        if ((int)(func = signal(SIGUSR1, _utmp_sig_rcv)) == -1)
                   1193:                fatalperror(net, "telnetd/signal");
                   1194: }
                   1195: 
                   1196: utmp_sig_reset()
                   1197: {
                   1198:        (void) signal(SIGUSR1, func);   /* reset handler to default */
                   1199: }
                   1200: 
                   1201: utmp_sig_wait()
                   1202: {
                   1203:        /*
                   1204:         * Wait for parent to write our utmp entry.
                   1205:         */
                   1206:        sigoff();
                   1207:        while (caught == 0) {
                   1208:                pause();        /* wait until we get a signal (sigon) */
                   1209:                sigoff();       /* turn off signals while we check caught */
                   1210:        }
                   1211:        sigon();                /* turn on signals again */
                   1212: }
                   1213: 
                   1214: utmp_sig_notify(pid)
                   1215: {
                   1216:        kill(pid, SIGUSR1);
                   1217: }
                   1218: #endif /* defined(CRAY) && !defined(NEWINIT) */
                   1219: 
                   1220: /*
                   1221:  * rmut()
                   1222:  *
                   1223:  * This is the function called by cleanup() to
                   1224:  * remove the utmp entry for this person.
                   1225:  */
                   1226: 
                   1227: #if    !defined(CRAY) && BSD <= 43
                   1228: rmut()
                   1229: {
                   1230:        register f;
                   1231:        int found = 0;
                   1232:        struct utmp *u, *utmp;
                   1233:        int nutmp;
                   1234:        struct stat statbf;
                   1235:        char *malloc();
                   1236:        long time();
                   1237:        off_t lseek();
                   1238: 
                   1239:        f = open(utmpf, O_RDWR);
                   1240:        if (f >= 0) {
                   1241:                (void) fstat(f, &statbf);
                   1242:                utmp = (struct utmp *)malloc((unsigned)statbf.st_size);
                   1243:                if (!utmp)
                   1244:                        syslog(LOG_ERR, "utmp malloc failed");
                   1245:                if (statbf.st_size && utmp) {
                   1246:                        nutmp = read(f, (char *)utmp, (int)statbf.st_size);
                   1247:                        nutmp /= sizeof(struct utmp);
                   1248:                
                   1249:                        for (u = utmp ; u < &utmp[nutmp] ; u++) {
                   1250:                                if (SCMPN(u->ut_line, line+5) ||
                   1251:                                    u->ut_name[0]==0)
                   1252:                                        continue;
                   1253:                                (void) lseek(f, ((long)u)-((long)utmp), L_SET);
                   1254:                                SCPYN(u->ut_name, "");
                   1255:                                SCPYN(u->ut_host, "");
                   1256:                                (void) time(&u->ut_time);
                   1257:                                (void) write(f, (char *)u, sizeof(wtmp));
                   1258:                                found++;
                   1259:                        }
                   1260:                }
                   1261:                (void) close(f);
                   1262:        }
                   1263:        if (found) {
                   1264:                f = open(wtmpf, O_WRONLY|O_APPEND);
                   1265:                if (f >= 0) {
                   1266:                        SCPYN(wtmp.ut_line, line+5);
                   1267:                        SCPYN(wtmp.ut_name, "");
                   1268:                        SCPYN(wtmp.ut_host, "");
                   1269:                        (void) time(&wtmp.ut_time);
                   1270:                        (void) write(f, (char *)&wtmp, sizeof(wtmp));
                   1271:                        (void) close(f);
                   1272:                }
                   1273:        }
                   1274:        (void) chmod(line, 0666);
                   1275:        (void) chown(line, 0, 0);
                   1276:        line[strlen("/dev/")] = 'p';
                   1277:        (void) chmod(line, 0666);
                   1278:        (void) chown(line, 0, 0);
                   1279: }  /* end of rmut */
                   1280: #endif /* CRAY */

unix.superglobalmegacorp.com

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