Annotation of 43BSDReno/libexec/telnetd/sys_term.c, revision 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.