Annotation of 43BSDTahoe/ucb/rlogin.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)rlogin.c   5.11 (Berkeley) 8/7/86";
        !            15: #endif not lint
        !            16: 
        !            17: /*
        !            18:  * rlogin - remote login
        !            19:  */
        !            20: #include <sys/param.h>
        !            21: #include <sys/errno.h>
        !            22: #include <sys/file.h>
        !            23: #include <sys/socket.h>
        !            24: #include <sys/time.h>
        !            25: #include <sys/resource.h>
        !            26: #include <sys/wait.h>
        !            27: 
        !            28: #include <netinet/in.h>
        !            29: 
        !            30: #include <stdio.h>
        !            31: #include <sgtty.h>
        !            32: #include <errno.h>
        !            33: #include <pwd.h>
        !            34: #include <signal.h>
        !            35: #include <setjmp.h>
        !            36: #include <netdb.h>
        !            37: 
        !            38: # ifndef TIOCPKT_WINDOW
        !            39: # define TIOCPKT_WINDOW 0x80
        !            40: # endif TIOCPKT_WINDOW
        !            41: 
        !            42: /* concession to sun */
        !            43: # ifndef SIGUSR1
        !            44: # define SIGUSR1 30
        !            45: # endif SIGUSR1
        !            46: 
        !            47: char   *index(), *rindex(), *malloc(), *getenv(), *strcat(), *strcpy();
        !            48: struct passwd *getpwuid();
        !            49: char   *name;
        !            50: int    rem;
        !            51: char   cmdchar = '~';
        !            52: int    eight;
        !            53: int    litout;
        !            54: char   *speeds[] =
        !            55:     { "0", "50", "75", "110", "134", "150", "200", "300",
        !            56:       "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
        !            57: char   term[256] = "network";
        !            58: extern int errno;
        !            59: int    lostpeer();
        !            60: int    dosigwinch = 0;
        !            61: #ifndef sigmask
        !            62: #define sigmask(m)     (1 << ((m)-1))
        !            63: #endif
        !            64: #ifdef sun
        !            65: struct winsize {
        !            66:        unsigned short ws_row, ws_col;
        !            67:        unsigned short ws_xpixel, ws_ypixel;
        !            68: };
        !            69: #endif sun
        !            70: struct winsize winsize;
        !            71: int    sigwinch(), oob();
        !            72: 
        !            73: /*
        !            74:  * The following routine provides compatibility (such as it is)
        !            75:  * between 4.2BSD Suns and others.  Suns have only a `ttysize',
        !            76:  * so we convert it to a winsize.
        !            77:  */
        !            78: #ifdef sun
        !            79: int
        !            80: get_window_size(fd, wp)
        !            81:        int fd;
        !            82:        struct winsize *wp;
        !            83: {
        !            84:        struct ttysize ts;
        !            85:        int error;
        !            86: 
        !            87:        if ((error = ioctl(0, TIOCGSIZE, &ts)) != 0)
        !            88:                return (error);
        !            89:        wp->ws_row = ts.ts_lines;
        !            90:        wp->ws_col = ts.ts_cols;
        !            91:        wp->ws_xpixel = 0;
        !            92:        wp->ws_ypixel = 0;
        !            93:        return (0);
        !            94: }
        !            95: #else sun
        !            96: #define get_window_size(fd, wp)        ioctl(fd, TIOCGWINSZ, wp)
        !            97: #endif sun
        !            98: 
        !            99: main(argc, argv)
        !           100:        int argc;
        !           101:        char **argv;
        !           102: {
        !           103:        char *host, *cp;
        !           104:        struct sgttyb ttyb;
        !           105:        struct passwd *pwd;
        !           106:        struct servent *sp;
        !           107:        int uid, options = 0, oldmask;
        !           108:        int on = 1;
        !           109: 
        !           110:        host = rindex(argv[0], '/');
        !           111:        if (host)
        !           112:                host++;
        !           113:        else
        !           114:                host = argv[0];
        !           115:        argv++, --argc;
        !           116:        if (!strcmp(host, "rlogin"))
        !           117:                host = *argv++, --argc;
        !           118: another:
        !           119:        if (argc > 0 && !strcmp(*argv, "-d")) {
        !           120:                argv++, argc--;
        !           121:                options |= SO_DEBUG;
        !           122:                goto another;
        !           123:        }
        !           124:        if (argc > 0 && !strcmp(*argv, "-l")) {
        !           125:                argv++, argc--;
        !           126:                if (argc == 0)
        !           127:                        goto usage;
        !           128:                name = *argv++; argc--;
        !           129:                goto another;
        !           130:        }
        !           131:        if (argc > 0 && !strncmp(*argv, "-e", 2)) {
        !           132:                cmdchar = argv[0][2];
        !           133:                argv++, argc--;
        !           134:                goto another;
        !           135:        }
        !           136:        if (argc > 0 && !strcmp(*argv, "-8")) {
        !           137:                eight = 1;
        !           138:                argv++, argc--;
        !           139:                goto another;
        !           140:        }
        !           141:        if (argc > 0 && !strcmp(*argv, "-L")) {
        !           142:                litout = 1;
        !           143:                argv++, argc--;
        !           144:                goto another;
        !           145:        }
        !           146:        if (host == 0)
        !           147:                goto usage;
        !           148:        if (argc > 0)
        !           149:                goto usage;
        !           150:        pwd = getpwuid(getuid());
        !           151:        if (pwd == 0) {
        !           152:                fprintf(stderr, "Who are you?\n");
        !           153:                exit(1);
        !           154:        }
        !           155:        sp = getservbyname("login", "tcp");
        !           156:        if (sp == 0) {
        !           157:                fprintf(stderr, "rlogin: login/tcp: unknown service\n");
        !           158:                exit(2);
        !           159:        }
        !           160:        cp = getenv("TERM");
        !           161:        if (cp)
        !           162:                (void) strcpy(term, cp);
        !           163:        if (ioctl(0, TIOCGETP, &ttyb) == 0) {
        !           164:                (void) strcat(term, "/");
        !           165:                (void) strcat(term, speeds[ttyb.sg_ospeed]);
        !           166:        }
        !           167:        (void) get_window_size(0, &winsize);
        !           168:        (void) signal(SIGPIPE, lostpeer);
        !           169:        /* will use SIGUSR1 for window size hack, so hold it off */
        !           170:        oldmask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));
        !           171:         rem = rcmd(&host, sp->s_port, pwd->pw_name,
        !           172:            name ? name : pwd->pw_name, term, 0);
        !           173:         if (rem < 0)
        !           174:                 exit(1);
        !           175:        if (options & SO_DEBUG &&
        !           176:            setsockopt(rem, SOL_SOCKET, SO_DEBUG, &on, sizeof (on)) < 0)
        !           177:                perror("rlogin: setsockopt (SO_DEBUG)");
        !           178:        uid = getuid();
        !           179:        if (setuid(uid) < 0) {
        !           180:                perror("rlogin: setuid");
        !           181:                exit(1);
        !           182:        }
        !           183:        doit(oldmask);
        !           184:        /*NOTREACHED*/
        !           185: usage:
        !           186:        fprintf(stderr,
        !           187:            "usage: rlogin host [ -ex ] [ -l username ] [ -8 ] [ -L ]\n");
        !           188:        exit(1);
        !           189: }
        !           190: 
        !           191: #define CRLF "\r\n"
        !           192: 
        !           193: int    child;
        !           194: int    catchild();
        !           195: int    copytochild(), writeroob();
        !           196: 
        !           197: int    defflags, tabflag;
        !           198: int    deflflags;
        !           199: char   deferase, defkill;
        !           200: struct tchars deftc;
        !           201: struct ltchars defltc;
        !           202: struct tchars notc =   { -1, -1, -1, -1, -1, -1 };
        !           203: struct ltchars noltc = { -1, -1, -1, -1, -1, -1 };
        !           204: 
        !           205: doit(oldmask)
        !           206: {
        !           207:        int exit();
        !           208:        struct sgttyb sb;
        !           209: 
        !           210:        (void) ioctl(0, TIOCGETP, (char *)&sb);
        !           211:        defflags = sb.sg_flags;
        !           212:        tabflag = defflags & TBDELAY;
        !           213:        defflags &= ECHO | CRMOD;
        !           214:        deferase = sb.sg_erase;
        !           215:        defkill = sb.sg_kill;
        !           216:        (void) ioctl(0, TIOCLGET, (char *)&deflflags);
        !           217:        (void) ioctl(0, TIOCGETC, (char *)&deftc);
        !           218:        notc.t_startc = deftc.t_startc;
        !           219:        notc.t_stopc = deftc.t_stopc;
        !           220:        (void) ioctl(0, TIOCGLTC, (char *)&defltc);
        !           221:        (void) signal(SIGINT, SIG_IGN);
        !           222:        setsignal(SIGHUP, exit);
        !           223:        setsignal(SIGQUIT, exit);
        !           224:        child = fork();
        !           225:        if (child == -1) {
        !           226:                perror("rlogin: fork");
        !           227:                done(1);
        !           228:        }
        !           229:        if (child == 0) {
        !           230:                mode(1);
        !           231:                if (reader(oldmask) == 0) {
        !           232:                        prf("Connection closed.");
        !           233:                        exit(0);
        !           234:                }
        !           235:                sleep(1);
        !           236:                prf("\007Connection closed.");
        !           237:                exit(3);
        !           238:        }
        !           239: 
        !           240:        /*
        !           241:         * We may still own the socket, and may have a pending SIGURG
        !           242:         * (or might receive one soon) that we really want to send to
        !           243:         * the reader.  Set a trap that simply copies such signals to
        !           244:         * the child.
        !           245:         */
        !           246:        (void) signal(SIGURG, copytochild);
        !           247:        (void) signal(SIGUSR1, writeroob);
        !           248:        (void) sigsetmask(oldmask);
        !           249:        (void) signal(SIGCHLD, catchild);
        !           250:        writer();
        !           251:        prf("Closed connection.");
        !           252:        done(0);
        !           253: }
        !           254: 
        !           255: /*
        !           256:  * Trap a signal, unless it is being ignored.
        !           257:  */
        !           258: setsignal(sig, act)
        !           259:        int sig, (*act)();
        !           260: {
        !           261:        int omask = sigblock(sigmask(sig));
        !           262: 
        !           263:        if (signal(sig, act) == SIG_IGN)
        !           264:                (void) signal(sig, SIG_IGN);
        !           265:        (void) sigsetmask(omask);
        !           266: }
        !           267: 
        !           268: done(status)
        !           269:        int status;
        !           270: {
        !           271:        int w;
        !           272: 
        !           273:        mode(0);
        !           274:        if (child > 0) {
        !           275:                /* make sure catchild does not snap it up */
        !           276:                (void) signal(SIGCHLD, SIG_DFL);
        !           277:                if (kill(child, SIGKILL) >= 0)
        !           278:                        while ((w = wait((union wait *)0)) > 0 && w != child)
        !           279:                                /*void*/;
        !           280:        }
        !           281:        exit(status);
        !           282: }
        !           283: 
        !           284: /*
        !           285:  * Copy SIGURGs to the child process.
        !           286:  */
        !           287: copytochild()
        !           288: {
        !           289: 
        !           290:        (void) kill(child, SIGURG);
        !           291: }
        !           292: 
        !           293: /*
        !           294:  * This is called when the reader process gets the out-of-band (urgent)
        !           295:  * request to turn on the window-changing protocol.
        !           296:  */
        !           297: writeroob()
        !           298: {
        !           299: 
        !           300:        if (dosigwinch == 0) {
        !           301:                sendwindow();
        !           302:                (void) signal(SIGWINCH, sigwinch);
        !           303:        }
        !           304:        dosigwinch = 1;
        !           305: }
        !           306: 
        !           307: catchild()
        !           308: {
        !           309:        union wait status;
        !           310:        int pid;
        !           311: 
        !           312: again:
        !           313:        pid = wait3(&status, WNOHANG|WUNTRACED, (struct rusage *)0);
        !           314:        if (pid == 0)
        !           315:                return;
        !           316:        /*
        !           317:         * if the child (reader) dies, just quit
        !           318:         */
        !           319:        if (pid < 0 || pid == child && !WIFSTOPPED(status))
        !           320:                done((int)(status.w_termsig | status.w_retcode));
        !           321:        goto again;
        !           322: }
        !           323: 
        !           324: /*
        !           325:  * writer: write to remote: 0 -> line.
        !           326:  * ~.  terminate
        !           327:  * ~^Z suspend rlogin process.
        !           328:  * ~^Y  suspend rlogin process, but leave reader alone.
        !           329:  */
        !           330: writer()
        !           331: {
        !           332:        char c;
        !           333:        register n;
        !           334:        register bol = 1;               /* beginning of line */
        !           335:        register local = 0;
        !           336: 
        !           337:        for (;;) {
        !           338:                n = read(0, &c, 1);
        !           339:                if (n <= 0) {
        !           340:                        if (n < 0 && errno == EINTR)
        !           341:                                continue;
        !           342:                        break;
        !           343:                }
        !           344:                /*
        !           345:                 * If we're at the beginning of the line
        !           346:                 * and recognize a command character, then
        !           347:                 * we echo locally.  Otherwise, characters
        !           348:                 * are echo'd remotely.  If the command
        !           349:                 * character is doubled, this acts as a 
        !           350:                 * force and local echo is suppressed.
        !           351:                 */
        !           352:                if (bol) {
        !           353:                        bol = 0;
        !           354:                        if (c == cmdchar) {
        !           355:                                bol = 0;
        !           356:                                local = 1;
        !           357:                                continue;
        !           358:                        }
        !           359:                } else if (local) {
        !           360:                        local = 0;
        !           361:                        if (c == '.' || c == deftc.t_eofc) {
        !           362:                                echo(c);
        !           363:                                break;
        !           364:                        }
        !           365:                        if (c == defltc.t_suspc || c == defltc.t_dsuspc) {
        !           366:                                bol = 1;
        !           367:                                echo(c);
        !           368:                                stop(c);
        !           369:                                continue;
        !           370:                        }
        !           371:                        if (c != cmdchar)
        !           372:                                (void) write(rem, &cmdchar, 1);
        !           373:                }
        !           374:                if (write(rem, &c, 1) == 0) {
        !           375:                        prf("line gone");
        !           376:                        break;
        !           377:                }
        !           378:                bol = c == defkill || c == deftc.t_eofc ||
        !           379:                    c == deftc.t_intrc || c == defltc.t_suspc ||
        !           380:                    c == '\r' || c == '\n';
        !           381:        }
        !           382: }
        !           383: 
        !           384: echo(c)
        !           385: register char c;
        !           386: {
        !           387:        char buf[8];
        !           388:        register char *p = buf;
        !           389: 
        !           390:        c &= 0177;
        !           391:        *p++ = cmdchar;
        !           392:        if (c < ' ') {
        !           393:                *p++ = '^';
        !           394:                *p++ = c + '@';
        !           395:        } else if (c == 0177) {
        !           396:                *p++ = '^';
        !           397:                *p++ = '?';
        !           398:        } else
        !           399:                *p++ = c;
        !           400:        *p++ = '\r';
        !           401:        *p++ = '\n';
        !           402:        (void) write(1, buf, p - buf);
        !           403: }
        !           404: 
        !           405: stop(cmdc)
        !           406:        char cmdc;
        !           407: {
        !           408:        mode(0);
        !           409:        (void) signal(SIGCHLD, SIG_IGN);
        !           410:        (void) kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP);
        !           411:        (void) signal(SIGCHLD, catchild);
        !           412:        mode(1);
        !           413:        sigwinch();                     /* check for size changes */
        !           414: }
        !           415: 
        !           416: sigwinch()
        !           417: {
        !           418:        struct winsize ws;
        !           419: 
        !           420:        if (dosigwinch && get_window_size(0, &ws) == 0 &&
        !           421:            bcmp(&ws, &winsize, sizeof (ws))) {
        !           422:                winsize = ws;
        !           423:                sendwindow();
        !           424:        }
        !           425: }
        !           426: 
        !           427: /*
        !           428:  * Send the window size to the server via the magic escape
        !           429:  */
        !           430: sendwindow()
        !           431: {
        !           432:        char obuf[4 + sizeof (struct winsize)];
        !           433:        struct winsize *wp = (struct winsize *)(obuf+4);
        !           434: 
        !           435:        obuf[0] = 0377;
        !           436:        obuf[1] = 0377;
        !           437:        obuf[2] = 's';
        !           438:        obuf[3] = 's';
        !           439:        wp->ws_row = htons(winsize.ws_row);
        !           440:        wp->ws_col = htons(winsize.ws_col);
        !           441:        wp->ws_xpixel = htons(winsize.ws_xpixel);
        !           442:        wp->ws_ypixel = htons(winsize.ws_ypixel);
        !           443:        (void) write(rem, obuf, sizeof(obuf));
        !           444: }
        !           445: 
        !           446: /*
        !           447:  * reader: read from remote: line -> 1
        !           448:  */
        !           449: #define        READING 1
        !           450: #define        WRITING 2
        !           451: 
        !           452: char   rcvbuf[8 * 1024];
        !           453: int    rcvcnt;
        !           454: int    rcvstate;
        !           455: int    ppid;
        !           456: jmp_buf        rcvtop;
        !           457: 
        !           458: oob()
        !           459: {
        !           460:        int out = FWRITE, atmark, n;
        !           461:        int rcvd = 0;
        !           462:        char waste[BUFSIZ], mark;
        !           463:        struct sgttyb sb;
        !           464: 
        !           465:        while (recv(rem, &mark, 1, MSG_OOB) < 0)
        !           466:                switch (errno) {
        !           467:                
        !           468:                case EWOULDBLOCK:
        !           469:                        /*
        !           470:                         * Urgent data not here yet.
        !           471:                         * It may not be possible to send it yet
        !           472:                         * if we are blocked for output
        !           473:                         * and our input buffer is full.
        !           474:                         */
        !           475:                        if (rcvcnt < sizeof(rcvbuf)) {
        !           476:                                n = read(rem, rcvbuf + rcvcnt,
        !           477:                                        sizeof(rcvbuf) - rcvcnt);
        !           478:                                if (n <= 0)
        !           479:                                        return;
        !           480:                                rcvd += n;
        !           481:                        } else {
        !           482:                                n = read(rem, waste, sizeof(waste));
        !           483:                                if (n <= 0)
        !           484:                                        return;
        !           485:                        }
        !           486:                        continue;
        !           487:                                
        !           488:                default:
        !           489:                        return;
        !           490:        }
        !           491:        if (mark & TIOCPKT_WINDOW) {
        !           492:                /*
        !           493:                 * Let server know about window size changes
        !           494:                 */
        !           495:                (void) kill(ppid, SIGUSR1);
        !           496:        }
        !           497:        if (!eight && (mark & TIOCPKT_NOSTOP)) {
        !           498:                (void) ioctl(0, TIOCGETP, (char *)&sb);
        !           499:                sb.sg_flags &= ~CBREAK;
        !           500:                sb.sg_flags |= RAW;
        !           501:                (void) ioctl(0, TIOCSETN, (char *)&sb);
        !           502:                notc.t_stopc = -1;
        !           503:                notc.t_startc = -1;
        !           504:                (void) ioctl(0, TIOCSETC, (char *)&notc);
        !           505:        }
        !           506:        if (!eight && (mark & TIOCPKT_DOSTOP)) {
        !           507:                (void) ioctl(0, TIOCGETP, (char *)&sb);
        !           508:                sb.sg_flags &= ~RAW;
        !           509:                sb.sg_flags |= CBREAK;
        !           510:                (void) ioctl(0, TIOCSETN, (char *)&sb);
        !           511:                notc.t_stopc = deftc.t_stopc;
        !           512:                notc.t_startc = deftc.t_startc;
        !           513:                (void) ioctl(0, TIOCSETC, (char *)&notc);
        !           514:        }
        !           515:        if (mark & TIOCPKT_FLUSHWRITE) {
        !           516:                (void) ioctl(1, TIOCFLUSH, (char *)&out);
        !           517:                for (;;) {
        !           518:                        if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
        !           519:                                perror("ioctl");
        !           520:                                break;
        !           521:                        }
        !           522:                        if (atmark)
        !           523:                                break;
        !           524:                        n = read(rem, waste, sizeof (waste));
        !           525:                        if (n <= 0)
        !           526:                                break;
        !           527:                }
        !           528:                /*
        !           529:                 * Don't want any pending data to be output,
        !           530:                 * so clear the recv buffer.
        !           531:                 * If we were hanging on a write when interrupted,
        !           532:                 * don't want it to restart.  If we were reading,
        !           533:                 * restart anyway.
        !           534:                 */
        !           535:                rcvcnt = 0;
        !           536:                longjmp(rcvtop, 1);
        !           537:        }
        !           538: 
        !           539:        /*
        !           540:         * oob does not do FLUSHREAD (alas!)
        !           541:         */
        !           542: 
        !           543:        /*
        !           544:         * If we filled the receive buffer while a read was pending,
        !           545:         * longjmp to the top to restart appropriately.  Don't abort
        !           546:         * a pending write, however, or we won't know how much was written.
        !           547:         */
        !           548:        if (rcvd && rcvstate == READING)
        !           549:                longjmp(rcvtop, 1);
        !           550: }
        !           551: 
        !           552: /*
        !           553:  * reader: read from remote: line -> 1
        !           554:  */
        !           555: reader(oldmask)
        !           556:        int oldmask;
        !           557: {
        !           558: #if !defined(BSD) || BSD < 43
        !           559:        int pid = -getpid();
        !           560: #else
        !           561:        int pid = getpid();
        !           562: #endif
        !           563:        int n, remaining;
        !           564:        char *bufp = rcvbuf;
        !           565: 
        !           566:        (void) signal(SIGTTOU, SIG_IGN);
        !           567:        (void) signal(SIGURG, oob);
        !           568:        ppid = getppid();
        !           569:        (void) fcntl(rem, F_SETOWN, pid);
        !           570:        (void) setjmp(rcvtop);
        !           571:        (void) sigsetmask(oldmask);
        !           572:        for (;;) {
        !           573:                while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {
        !           574:                        rcvstate = WRITING;
        !           575:                        n = write(1, bufp, remaining);
        !           576:                        if (n < 0) {
        !           577:                                if (errno != EINTR)
        !           578:                                        return (-1);
        !           579:                                continue;
        !           580:                        }
        !           581:                        bufp += n;
        !           582:                }
        !           583:                bufp = rcvbuf;
        !           584:                rcvcnt = 0;
        !           585:                rcvstate = READING;
        !           586:                rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf));
        !           587:                if (rcvcnt == 0)
        !           588:                        return (0);
        !           589:                if (rcvcnt < 0) {
        !           590:                        if (errno == EINTR)
        !           591:                                continue;
        !           592:                        perror("read");
        !           593:                        return (-1);
        !           594:                }
        !           595:        }
        !           596: }
        !           597: 
        !           598: mode(f)
        !           599: {
        !           600:        struct tchars *tc;
        !           601:        struct ltchars *ltc;
        !           602:        struct sgttyb sb;
        !           603:        int     lflags;
        !           604: 
        !           605:        (void) ioctl(0, TIOCGETP, (char *)&sb);
        !           606:        (void) ioctl(0, TIOCLGET, (char *)&lflags);
        !           607:        switch (f) {
        !           608: 
        !           609:        case 0:
        !           610:                sb.sg_flags &= ~(CBREAK|RAW|TBDELAY);
        !           611:                sb.sg_flags |= defflags|tabflag;
        !           612:                tc = &deftc;
        !           613:                ltc = &defltc;
        !           614:                sb.sg_kill = defkill;
        !           615:                sb.sg_erase = deferase;
        !           616:                lflags = deflflags;
        !           617:                break;
        !           618: 
        !           619:        case 1:
        !           620:                sb.sg_flags |= (eight ? RAW : CBREAK);
        !           621:                sb.sg_flags &= ~defflags;
        !           622:                /* preserve tab delays, but turn off XTABS */
        !           623:                if ((sb.sg_flags & TBDELAY) == XTABS)
        !           624:                        sb.sg_flags &= ~TBDELAY;
        !           625:                tc = &notc;
        !           626:                ltc = &noltc;
        !           627:                sb.sg_kill = sb.sg_erase = -1;
        !           628:                if (litout)
        !           629:                        lflags |= LLITOUT;
        !           630:                break;
        !           631: 
        !           632:        default:
        !           633:                return;
        !           634:        }
        !           635:        (void) ioctl(0, TIOCSLTC, (char *)ltc);
        !           636:        (void) ioctl(0, TIOCSETC, (char *)tc);
        !           637:        (void) ioctl(0, TIOCSETN, (char *)&sb);
        !           638:        (void) ioctl(0, TIOCLSET, (char *)&lflags);
        !           639: }
        !           640: 
        !           641: /*VARARGS*/
        !           642: prf(f, a1, a2, a3, a4, a5)
        !           643:        char *f;
        !           644: {
        !           645: 
        !           646:        fprintf(stderr, f, a1, a2, a3, a4, a5);
        !           647:        fprintf(stderr, CRLF);
        !           648: }
        !           649: 
        !           650: lostpeer()
        !           651: {
        !           652: 
        !           653:        (void) signal(SIGPIPE, SIG_IGN);
        !           654:        prf("\007Connection closed.");
        !           655:        done(1);
        !           656: }
        !           657: 

unix.superglobalmegacorp.com

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