Annotation of 43BSDReno/usr.bin/rlogin/rlogin.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983, 1990 The 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: char copyright[] =
        !            22: "@(#) Copyright (c) 1983, 1990 The Regents of the University of California.\n\
        !            23:  All rights reserved.\n";
        !            24: #endif /* not lint */
        !            25: 
        !            26: #ifndef lint
        !            27: static char sccsid[] = "@(#)rlogin.c   5.29 (Berkeley) 6/27/90";
        !            28: #endif /* not lint */
        !            29: 
        !            30: /*
        !            31:  * $Source: mit/rlogin/RCS/rlogin.c,v $
        !            32:  * $Header: mit/rlogin/RCS/rlogin.c,v 5.2 89/07/26 12:11:21 kfall
        !            33:  *     Exp Locker: kfall $
        !            34:  */
        !            35: 
        !            36: /*
        !            37:  * rlogin - remote login
        !            38:  */
        !            39: #include <sys/param.h>
        !            40: #include <sys/file.h>
        !            41: #include <sys/socket.h>
        !            42: #include <sys/signal.h>
        !            43: #include <sys/time.h>
        !            44: #include <sys/resource.h>
        !            45: #include <sys/wait.h>
        !            46: 
        !            47: #include <netinet/in.h>
        !            48: #include <netinet/in_systm.h>
        !            49: #include <netinet/ip.h>
        !            50: #include <netdb.h>
        !            51: 
        !            52: #include <sgtty.h>
        !            53: #include <setjmp.h>
        !            54: #include <errno.h>
        !            55: #include <varargs.h>
        !            56: #include <pwd.h>
        !            57: #include <stdio.h>
        !            58: #include <unistd.h>
        !            59: #include <string.h>
        !            60: 
        !            61: #ifdef KERBEROS
        !            62: #include <kerberosIV/des.h>
        !            63: #include <kerberosIV/krb.h>
        !            64: 
        !            65: CREDENTIALS cred;
        !            66: Key_schedule schedule;
        !            67: int use_kerberos = 1, encrypt;
        !            68: char dst_realm_buf[REALM_SZ], *dest_realm = NULL;
        !            69: extern char *krb_realmofhost();
        !            70: #endif
        !            71: 
        !            72: #ifndef TIOCPKT_WINDOW
        !            73: #define        TIOCPKT_WINDOW  0x80
        !            74: #endif
        !            75: 
        !            76: /* concession to Sun */
        !            77: #ifndef SIGUSR1
        !            78: #define        SIGUSR1 30
        !            79: #endif
        !            80: 
        !            81: extern int errno;
        !            82: int eight, litout, rem;
        !            83: char cmdchar;
        !            84: char *speeds[] = {
        !            85:        "0", "50", "75", "110", "134", "150", "200", "300", "600", "1200",
        !            86:        "1800", "2400", "4800", "9600", "19200", "38400"
        !            87: };
        !            88: 
        !            89: #ifdef sun
        !            90: struct winsize {
        !            91:        unsigned short ws_row, ws_col;
        !            92:        unsigned short ws_xpixel, ws_ypixel;
        !            93: };
        !            94: #endif
        !            95: struct winsize winsize;
        !            96: 
        !            97: #ifndef sun
        !            98: #define        get_window_size(fd, wp) ioctl(fd, TIOCGWINSZ, wp)
        !            99: #endif
        !           100: 
        !           101: void exit();
        !           102: 
        !           103: main(argc, argv)
        !           104:        int argc;
        !           105:        char **argv;
        !           106: {
        !           107:        extern char *optarg;
        !           108:        extern int optind;
        !           109:        struct passwd *pw;
        !           110:        struct servent *sp;
        !           111:        struct sgttyb ttyb;
        !           112:        long omask;
        !           113:        int argoff, ch, dflag, one, uid;
        !           114:        char *host, *p, *user, term[1024];
        !           115:        void lostpeer();
        !           116:        char *getenv();
        !           117: 
        !           118:        argoff = dflag = 0;
        !           119:        one = 1;
        !           120:        host = user = NULL;
        !           121:        cmdchar = '~';
        !           122: 
        !           123:        if (p = rindex(argv[0], '/'))
        !           124:                ++p;
        !           125:        else
        !           126:                p = argv[0];
        !           127: 
        !           128:        if (strcmp(p, "rlogin"))
        !           129:                host = p;
        !           130: 
        !           131:        /* handle "rlogin host flags" */
        !           132:        if (!host && argc > 2 && argv[1][0] != '-') {
        !           133:                host = argv[1];
        !           134:                argoff = 1;
        !           135:        }
        !           136: 
        !           137: #ifdef KERBEROS
        !           138: #define        OPTIONS "8KLde:k:l:x"
        !           139: #else
        !           140: #define        OPTIONS "8KLde:l:"
        !           141: #endif
        !           142:        while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != EOF)
        !           143:                switch(ch) {
        !           144:                case '8':
        !           145:                        eight = 1;
        !           146:                        break;
        !           147:                case 'K':
        !           148: #ifdef KERBEROS
        !           149:                        use_kerberos = 0;
        !           150: #endif
        !           151:                        break;
        !           152:                case 'L':
        !           153:                        litout = 1;
        !           154:                        break;
        !           155:                case 'd':
        !           156:                        dflag = 1;
        !           157:                        break;
        !           158:                case 'e':
        !           159:                        cmdchar = optarg[0];
        !           160:                        break;
        !           161: #ifdef KERBEROS
        !           162:                case 'k':
        !           163:                        dest_realm = dst_realm_buf;
        !           164:                        (void)strncpy(dest_realm, optarg, REALM_SZ);
        !           165:                        break;
        !           166: #endif
        !           167:                case 'l':
        !           168:                        user = optarg;
        !           169:                        break;
        !           170: #ifdef KERBEROS
        !           171:                case 'x':
        !           172:                        encrypt = 1;
        !           173:                        des_set_key(cred.session, schedule);
        !           174:                        break;
        !           175: #endif
        !           176:                case '?':
        !           177:                default:
        !           178:                        usage();
        !           179:                }
        !           180:        optind += argoff;
        !           181:        argc -= optind;
        !           182:        argv += optind;
        !           183: 
        !           184:        /* if haven't gotten a host yet, do so */
        !           185:        if (!host && !(host = *argv++))
        !           186:                usage();
        !           187: 
        !           188:        if (*argv)
        !           189:                usage();
        !           190: 
        !           191:        if (!(pw = getpwuid(uid = getuid()))) {
        !           192:                (void)fprintf(stderr, "rlogin: unknown user id.\n");
        !           193:                exit(1);
        !           194:        }
        !           195:        if (!user)
        !           196:                user = pw->pw_name;
        !           197: 
        !           198:        sp = NULL;
        !           199: #ifdef KERBEROS
        !           200:        if (use_kerberos) {
        !           201:                sp = getservbyname((encrypt ? "eklogin" : "klogin"), "tcp");
        !           202:                if (sp == NULL) {
        !           203:                        use_kerberos = 0;
        !           204:                        warning("can't get entry for %s/tcp service",
        !           205:                            encrypt ? "eklogin" : "klogin");
        !           206:                }
        !           207:        }
        !           208: #endif
        !           209:        if (sp == NULL)
        !           210:                sp = getservbyname("login", "tcp");
        !           211:        if (sp == NULL) {
        !           212:                (void)fprintf(stderr, "rlogin: login/tcp: unknown service.\n");
        !           213:                exit(1);
        !           214:        }
        !           215: 
        !           216:        (void)strcpy(term, (p = getenv("TERM")) ? p : "network");
        !           217:        if (ioctl(0, TIOCGETP, &ttyb) == 0) {
        !           218:                (void)strcat(term, "/");
        !           219:                (void)strcat(term, speeds[ttyb.sg_ospeed]);
        !           220:        }
        !           221: 
        !           222:        (void)get_window_size(0, &winsize);
        !           223: 
        !           224:        (void)signal(SIGPIPE, lostpeer);
        !           225:        /* will use SIGUSR1 for window size hack, so hold it off */
        !           226:        omask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));
        !           227: 
        !           228: #ifdef KERBEROS
        !           229: try_connect:
        !           230:        if (use_kerberos) {
        !           231:                rem = KSUCCESS;
        !           232:                errno = 0;
        !           233:                if (dest_realm == NULL)
        !           234:                        dest_realm = krb_realmofhost(host);
        !           235: 
        !           236:                if (encrypt)
        !           237:                        rem = krcmd_mutual(&host, sp->s_port, user, term, 0,
        !           238:                            dest_realm, &cred, schedule);
        !           239:                else
        !           240:                        rem = krcmd(&host, sp->s_port, user, term, 0,
        !           241:                            dest_realm);
        !           242:                if (rem < 0) {
        !           243:                        use_kerberos = 0;
        !           244:                        sp = getservbyname("login", "tcp");
        !           245:                        if (sp == NULL) {
        !           246:                                (void)fprintf(stderr,
        !           247:                                    "rlogin: unknown service login/tcp.\n");
        !           248:                                exit(1);
        !           249:                        }
        !           250:                        if (errno == ECONNREFUSED)
        !           251:                                warning("remote host doesn't support Kerberos");
        !           252:                        if (errno == ENOENT)
        !           253:                                warning("can't provide Kerberos auth data");
        !           254:                        goto try_connect;
        !           255:                }
        !           256:        } else {
        !           257:                if (encrypt) {
        !           258:                        (void)fprintf(stderr,
        !           259:                            "rlogin: the -x flag requires Kerberos authentication.\n");
        !           260:                        exit(1);
        !           261:                }
        !           262:                rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0);
        !           263:        }
        !           264: #else
        !           265:        rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0);
        !           266: #endif
        !           267: 
        !           268:        if (rem < 0)
        !           269:                exit(1);
        !           270: 
        !           271:        if (dflag &&
        !           272:            setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0)
        !           273:                (void)fprintf(stderr, "rlogin: setsockopt: %s.\n",
        !           274:                    strerror(errno));
        !           275:        one = IPTOS_LOWDELAY;
        !           276:        if (setsockopt(rem, IPPROTO_IP, IP_TOS, (char *)&one, sizeof(int)) < 0)
        !           277:                perror("rlogin: setsockopt TOS (ignored)");
        !           278: 
        !           279:        (void)setuid(uid);
        !           280:        doit(omask);
        !           281:        /*NOTREACHED*/
        !           282: }
        !           283: 
        !           284: int child, defflags, deflflags, tabflag;
        !           285: char deferase, defkill;
        !           286: struct tchars deftc;
        !           287: struct ltchars defltc;
        !           288: struct tchars notc = { -1, -1, -1, -1, -1, -1 };
        !           289: struct ltchars noltc = { -1, -1, -1, -1, -1, -1 };
        !           290: 
        !           291: doit(omask)
        !           292:        long omask;
        !           293: {
        !           294:        struct sgttyb sb;
        !           295:        void catch_child(), copytochild(), exit(), writeroob();
        !           296: 
        !           297:        (void)ioctl(0, TIOCGETP, (char *)&sb);
        !           298:        defflags = sb.sg_flags;
        !           299:        tabflag = defflags & TBDELAY;
        !           300:        defflags &= ECHO | CRMOD;
        !           301:        deferase = sb.sg_erase;
        !           302:        defkill = sb.sg_kill;
        !           303:        (void)ioctl(0, TIOCLGET, (char *)&deflflags);
        !           304:        (void)ioctl(0, TIOCGETC, (char *)&deftc);
        !           305:        notc.t_startc = deftc.t_startc;
        !           306:        notc.t_stopc = deftc.t_stopc;
        !           307:        (void)ioctl(0, TIOCGLTC, (char *)&defltc);
        !           308:        (void)signal(SIGINT, SIG_IGN);
        !           309:        setsignal(SIGHUP, exit);
        !           310:        setsignal(SIGQUIT, exit);
        !           311:        child = fork();
        !           312:        if (child == -1) {
        !           313:                (void)fprintf(stderr, "rlogin: fork: %s.\n", strerror(errno));
        !           314:                done(1);
        !           315:        }
        !           316:        if (child == 0) {
        !           317:                mode(1);
        !           318:                if (reader(omask) == 0) {
        !           319:                        msg("connection closed.");
        !           320:                        exit(0);
        !           321:                }
        !           322:                sleep(1);
        !           323:                msg("\007connection closed.");
        !           324:                exit(1);
        !           325:        }
        !           326: 
        !           327:        /*
        !           328:         * We may still own the socket, and may have a pending SIGURG (or might
        !           329:         * receive one soon) that we really want to send to the reader.  Set a
        !           330:         * trap that simply copies such signals to the child.
        !           331:         */
        !           332:        (void)signal(SIGURG, copytochild);
        !           333:        (void)signal(SIGUSR1, writeroob);
        !           334:        (void)sigsetmask(omask);
        !           335:        (void)signal(SIGCHLD, catch_child);
        !           336:        writer();
        !           337:        msg("closed connection.");
        !           338:        done(0);
        !           339: }
        !           340: 
        !           341: /* trap a signal, unless it is being ignored. */
        !           342: setsignal(sig, act)
        !           343:        int sig;
        !           344:        void (*act)();
        !           345: {
        !           346:        int omask = sigblock(sigmask(sig));
        !           347: 
        !           348:        if (signal(sig, act) == SIG_IGN)
        !           349:                (void)signal(sig, SIG_IGN);
        !           350:        (void)sigsetmask(omask);
        !           351: }
        !           352: 
        !           353: done(status)
        !           354:        int status;
        !           355: {
        !           356:        int w;
        !           357: 
        !           358:        mode(0);
        !           359:        if (child > 0) {
        !           360:                /* make sure catch_child does not snap it up */
        !           361:                (void)signal(SIGCHLD, SIG_DFL);
        !           362:                if (kill(child, SIGKILL) >= 0)
        !           363:                        while ((w = wait((union wait *)0)) > 0 && w != child);
        !           364:        }
        !           365:        exit(status);
        !           366: }
        !           367: 
        !           368: int dosigwinch;
        !           369: 
        !           370: /*
        !           371:  * This is called when the reader process gets the out-of-band (urgent)
        !           372:  * request to turn on the window-changing protocol.
        !           373:  */
        !           374: void
        !           375: writeroob()
        !           376: {
        !           377:        void sigwinch();
        !           378: 
        !           379:        if (dosigwinch == 0) {
        !           380:                sendwindow();
        !           381:                (void)signal(SIGWINCH, sigwinch);
        !           382:        }
        !           383:        dosigwinch = 1;
        !           384: }
        !           385: 
        !           386: void
        !           387: catch_child()
        !           388: {
        !           389:        union wait status;
        !           390:        int pid;
        !           391: 
        !           392:        for (;;) {
        !           393:                pid = wait3(&status, WNOHANG|WUNTRACED, (struct rusage *)0);
        !           394:                if (pid == 0)
        !           395:                        return;
        !           396:                /* if the child (reader) dies, just quit */
        !           397:                if (pid < 0 || pid == child && !WIFSTOPPED(status))
        !           398:                        done((int)(status.w_termsig | status.w_retcode));
        !           399:        }
        !           400:        /* NOTREACHED */
        !           401: }
        !           402: 
        !           403: /*
        !           404:  * writer: write to remote: 0 -> line.
        !           405:  * ~.  terminate
        !           406:  * ~^Z suspend rlogin process.
        !           407:  * ~^Y  suspend rlogin process, but leave reader alone.
        !           408:  */
        !           409: writer()
        !           410: {
        !           411:        char c;
        !           412:        register int bol, local, n;
        !           413: 
        !           414:        bol = 1;                        /* beginning of line */
        !           415:        local = 0;
        !           416:        for (;;) {
        !           417:                n = read(STDIN_FILENO, &c, 1);
        !           418:                if (n <= 0) {
        !           419:                        if (n < 0 && errno == EINTR)
        !           420:                                continue;
        !           421:                        break;
        !           422:                }
        !           423:                /*
        !           424:                 * If we're at the beginning of the line and recognize a
        !           425:                 * command character, then we echo locally.  Otherwise,
        !           426:                 * characters are echo'd remotely.  If the command character
        !           427:                 * is doubled, this acts as a force and local echo is
        !           428:                 * suppressed.
        !           429:                 */
        !           430:                if (bol) {
        !           431:                        bol = 0;
        !           432:                        if (c == cmdchar) {
        !           433:                                bol = 0;
        !           434:                                local = 1;
        !           435:                                continue;
        !           436:                        }
        !           437:                } else if (local) {
        !           438:                        local = 0;
        !           439:                        if (c == '.' || c == deftc.t_eofc) {
        !           440:                                echo(c);
        !           441:                                break;
        !           442:                        }
        !           443:                        if (c == defltc.t_suspc || c == defltc.t_dsuspc) {
        !           444:                                bol = 1;
        !           445:                                echo(c);
        !           446:                                stop(c);
        !           447:                                continue;
        !           448:                        }
        !           449:                        if (c != cmdchar) {
        !           450: #ifdef KERBEROS
        !           451:                                if (encrypt) {
        !           452:                                        (void)des_write(rem, &cmdchar, 1);
        !           453:                                } else
        !           454: #endif
        !           455:                                        (void)write(rem, &cmdchar, 1);
        !           456:                        }
        !           457:                }
        !           458: 
        !           459: #ifdef KERBEROS
        !           460:                if (encrypt) {
        !           461:                        if (des_write(rem, &c, 1) == 0) {
        !           462:                                msg("line gone");
        !           463:                                break;
        !           464:                        }
        !           465:                } else
        !           466: #endif
        !           467:                        if (write(rem, &c, 1) == 0) {
        !           468:                                msg("line gone");
        !           469:                                break;
        !           470:                        }
        !           471:                bol = c == defkill || c == deftc.t_eofc ||
        !           472:                    c == deftc.t_intrc || c == defltc.t_suspc ||
        !           473:                    c == '\r' || c == '\n';
        !           474:        }
        !           475: }
        !           476: 
        !           477: echo(c)
        !           478: register char c;
        !           479: {
        !           480:        register char *p;
        !           481:        char buf[8];
        !           482: 
        !           483:        p = buf;
        !           484:        c &= 0177;
        !           485:        *p++ = cmdchar;
        !           486:        if (c < ' ') {
        !           487:                *p++ = '^';
        !           488:                *p++ = c + '@';
        !           489:        } else if (c == 0177) {
        !           490:                *p++ = '^';
        !           491:                *p++ = '?';
        !           492:        } else
        !           493:                *p++ = c;
        !           494:        *p++ = '\r';
        !           495:        *p++ = '\n';
        !           496:        (void)write(1, buf, p - buf);
        !           497: }
        !           498: 
        !           499: stop(cmdc)
        !           500:        char cmdc;
        !           501: {
        !           502:        mode(0);
        !           503:        (void)signal(SIGCHLD, SIG_IGN);
        !           504:        (void)kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP);
        !           505:        (void)signal(SIGCHLD, catch_child);
        !           506:        mode(1);
        !           507:        sigwinch();                     /* check for size changes */
        !           508: }
        !           509: 
        !           510: void
        !           511: sigwinch()
        !           512: {
        !           513:        struct winsize ws;
        !           514: 
        !           515:        if (dosigwinch && get_window_size(0, &ws) == 0 &&
        !           516:            bcmp(&ws, &winsize, sizeof(ws))) {
        !           517:                winsize = ws;
        !           518:                sendwindow();
        !           519:        }
        !           520: }
        !           521: 
        !           522: /*
        !           523:  * Send the window size to the server via the magic escape
        !           524:  */
        !           525: sendwindow()
        !           526: {
        !           527:        struct winsize *wp;
        !           528:        char obuf[4 + sizeof (struct winsize)];
        !           529: 
        !           530:        wp = (struct winsize *)(obuf+4);
        !           531:        obuf[0] = 0377;
        !           532:        obuf[1] = 0377;
        !           533:        obuf[2] = 's';
        !           534:        obuf[3] = 's';
        !           535:        wp->ws_row = htons(winsize.ws_row);
        !           536:        wp->ws_col = htons(winsize.ws_col);
        !           537:        wp->ws_xpixel = htons(winsize.ws_xpixel);
        !           538:        wp->ws_ypixel = htons(winsize.ws_ypixel);
        !           539: 
        !           540: #ifdef KERBEROS
        !           541:        if(encrypt)
        !           542:                (void)des_write(rem, obuf, sizeof(obuf));
        !           543:        else
        !           544: #endif
        !           545:                (void)write(rem, obuf, sizeof(obuf));
        !           546: }
        !           547: 
        !           548: /*
        !           549:  * reader: read from remote: line -> 1
        !           550:  */
        !           551: #define        READING 1
        !           552: #define        WRITING 2
        !           553: 
        !           554: jmp_buf rcvtop;
        !           555: int ppid, rcvcnt, rcvstate;
        !           556: char rcvbuf[8 * 1024];
        !           557: 
        !           558: void
        !           559: oob()
        !           560: {
        !           561:        struct sgttyb sb;
        !           562:        int atmark, n, out, rcvd;
        !           563:        char waste[BUFSIZ], mark;
        !           564: 
        !           565:        out = O_RDWR;
        !           566:        rcvd = 0;
        !           567:        while (recv(rem, &mark, 1, MSG_OOB) < 0)
        !           568:                switch (errno) {
        !           569:                case EWOULDBLOCK:
        !           570:                        /*
        !           571:                         * Urgent data not here yet.  It may not be possible
        !           572:                         * to send it yet if we are blocked for output and
        !           573:                         * our input buffer is full.
        !           574:                         */
        !           575:                        if (rcvcnt < sizeof(rcvbuf)) {
        !           576:                                n = read(rem, rcvbuf + rcvcnt,
        !           577:                                    sizeof(rcvbuf) - rcvcnt);
        !           578:                                if (n <= 0)
        !           579:                                        return;
        !           580:                                rcvd += n;
        !           581:                        } else {
        !           582:                                n = read(rem, waste, sizeof(waste));
        !           583:                                if (n <= 0)
        !           584:                                        return;
        !           585:                        }
        !           586:                        continue;
        !           587:                default:
        !           588:                        return;
        !           589:        }
        !           590:        if (mark & TIOCPKT_WINDOW) {
        !           591:                /* Let server know about window size changes */
        !           592:                (void)kill(ppid, SIGUSR1);
        !           593:        }
        !           594:        if (!eight && (mark & TIOCPKT_NOSTOP)) {
        !           595:                (void)ioctl(0, TIOCGETP, (char *)&sb);
        !           596:                sb.sg_flags &= ~CBREAK;
        !           597:                sb.sg_flags |= RAW;
        !           598:                (void)ioctl(0, TIOCSETN, (char *)&sb);
        !           599:                notc.t_stopc = -1;
        !           600:                notc.t_startc = -1;
        !           601:                (void)ioctl(0, TIOCSETC, (char *)&notc);
        !           602:        }
        !           603:        if (!eight && (mark & TIOCPKT_DOSTOP)) {
        !           604:                (void)ioctl(0, TIOCGETP, (char *)&sb);
        !           605:                sb.sg_flags &= ~RAW;
        !           606:                sb.sg_flags |= CBREAK;
        !           607:                (void)ioctl(0, TIOCSETN, (char *)&sb);
        !           608:                notc.t_stopc = deftc.t_stopc;
        !           609:                notc.t_startc = deftc.t_startc;
        !           610:                (void)ioctl(0, TIOCSETC, (char *)&notc);
        !           611:        }
        !           612:        if (mark & TIOCPKT_FLUSHWRITE) {
        !           613:                (void)ioctl(1, TIOCFLUSH, (char *)&out);
        !           614:                for (;;) {
        !           615:                        if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
        !           616:                                (void)fprintf(stderr, "rlogin: ioctl: %s.\n",
        !           617:                                    strerror(errno));
        !           618:                                break;
        !           619:                        }
        !           620:                        if (atmark)
        !           621:                                break;
        !           622:                        n = read(rem, waste, sizeof (waste));
        !           623:                        if (n <= 0)
        !           624:                                break;
        !           625:                }
        !           626:                /*
        !           627:                 * Don't want any pending data to be output, so clear the recv
        !           628:                 * buffer.  If we were hanging on a write when interrupted,
        !           629:                 * don't want it to restart.  If we were reading, restart
        !           630:                 * anyway.
        !           631:                 */
        !           632:                rcvcnt = 0;
        !           633:                longjmp(rcvtop, 1);
        !           634:        }
        !           635: 
        !           636:        /* oob does not do FLUSHREAD (alas!) */
        !           637: 
        !           638:        /*
        !           639:         * If we filled the receive buffer while a read was pending, longjmp
        !           640:         * to the top to restart appropriately.  Don't abort a pending write,
        !           641:         * however, or we won't know how much was written.
        !           642:         */
        !           643:        if (rcvd && rcvstate == READING)
        !           644:                longjmp(rcvtop, 1);
        !           645: }
        !           646: 
        !           647: /* reader: read from remote: line -> 1 */
        !           648: reader(omask)
        !           649:        int omask;
        !           650: {
        !           651:        void oob();
        !           652: 
        !           653: #if !defined(BSD) || BSD < 43
        !           654:        int pid = -getpid();
        !           655: #else
        !           656:        int pid = getpid();
        !           657: #endif
        !           658:        int n, remaining;
        !           659:        char *bufp = rcvbuf;
        !           660: 
        !           661:        (void)signal(SIGTTOU, SIG_IGN);
        !           662:        (void)signal(SIGURG, oob);
        !           663:        ppid = getppid();
        !           664:        (void)fcntl(rem, F_SETOWN, pid);
        !           665:        (void)setjmp(rcvtop);
        !           666:        (void)sigsetmask(omask);
        !           667:        for (;;) {
        !           668:                while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {
        !           669:                        rcvstate = WRITING;
        !           670:                        n = write(1, bufp, remaining);
        !           671:                        if (n < 0) {
        !           672:                                if (errno != EINTR)
        !           673:                                        return(-1);
        !           674:                                continue;
        !           675:                        }
        !           676:                        bufp += n;
        !           677:                }
        !           678:                bufp = rcvbuf;
        !           679:                rcvcnt = 0;
        !           680:                rcvstate = READING;
        !           681: 
        !           682: #ifdef KERBEROS
        !           683:                if (encrypt)
        !           684:                        rcvcnt = des_read(rem, rcvbuf, sizeof(rcvbuf));
        !           685:                else
        !           686: #endif
        !           687:                        rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf));
        !           688:                if (rcvcnt == 0)
        !           689:                        return (0);
        !           690:                if (rcvcnt < 0) {
        !           691:                        if (errno == EINTR)
        !           692:                                continue;
        !           693:                        (void)fprintf(stderr, "rlogin: read: %s.\n",
        !           694:                            strerror(errno));
        !           695:                        return(-1);
        !           696:                }
        !           697:        }
        !           698: }
        !           699: 
        !           700: mode(f)
        !           701: {
        !           702:        struct ltchars *ltc;
        !           703:        struct sgttyb sb;
        !           704:        struct tchars *tc;
        !           705:        int lflags;
        !           706: 
        !           707:        (void)ioctl(0, TIOCGETP, (char *)&sb);
        !           708:        (void)ioctl(0, TIOCLGET, (char *)&lflags);
        !           709:        switch(f) {
        !           710:        case 0:
        !           711:                sb.sg_flags &= ~(CBREAK|RAW|TBDELAY);
        !           712:                sb.sg_flags |= defflags|tabflag;
        !           713:                tc = &deftc;
        !           714:                ltc = &defltc;
        !           715:                sb.sg_kill = defkill;
        !           716:                sb.sg_erase = deferase;
        !           717:                lflags = deflflags;
        !           718:                break;
        !           719:        case 1:
        !           720:                sb.sg_flags |= (eight ? RAW : CBREAK);
        !           721:                sb.sg_flags &= ~defflags;
        !           722:                /* preserve tab delays, but turn off XTABS */
        !           723:                if ((sb.sg_flags & TBDELAY) == XTABS)
        !           724:                        sb.sg_flags &= ~TBDELAY;
        !           725:                tc = &notc;
        !           726:                ltc = &noltc;
        !           727:                sb.sg_kill = sb.sg_erase = -1;
        !           728:                if (litout)
        !           729:                        lflags |= LLITOUT;
        !           730:                break;
        !           731:        default:
        !           732:                return;
        !           733:        }
        !           734:        (void)ioctl(0, TIOCSLTC, (char *)ltc);
        !           735:        (void)ioctl(0, TIOCSETC, (char *)tc);
        !           736:        (void)ioctl(0, TIOCSETN, (char *)&sb);
        !           737:        (void)ioctl(0, TIOCLSET, (char *)&lflags);
        !           738: }
        !           739: 
        !           740: void
        !           741: lostpeer()
        !           742: {
        !           743:        (void)signal(SIGPIPE, SIG_IGN);
        !           744:        msg("\007connection closed.");
        !           745:        done(1);
        !           746: }
        !           747: 
        !           748: /* copy SIGURGs to the child process. */
        !           749: void
        !           750: copytochild()
        !           751: {
        !           752:        (void)kill(child, SIGURG);
        !           753: }
        !           754: 
        !           755: msg(str)
        !           756:        char *str;
        !           757: {
        !           758:        (void)fprintf(stderr, "rlogin: %s\r\n", str);
        !           759: }
        !           760: 
        !           761: #ifdef KERBEROS
        !           762: /* VARARGS */
        !           763: warning(va_alist)
        !           764: va_dcl
        !           765: {
        !           766:        va_list ap;
        !           767:        char *fmt;
        !           768: 
        !           769:        (void)fprintf(stderr, "rlogin: warning, using standard rlogin: ");
        !           770:        va_start(ap);
        !           771:        fmt = va_arg(ap, char *);
        !           772:        vfprintf(stderr, fmt, ap);
        !           773:        va_end(ap);
        !           774:        (void)fprintf(stderr, ".\n");
        !           775: }
        !           776: #endif
        !           777: 
        !           778: usage()
        !           779: {
        !           780:        (void)fprintf(stderr,
        !           781:            "usage: rlogin [ -%s]%s[-e char] [ -l username ] host\n",
        !           782: #ifdef KERBEROS
        !           783:            "8Lx", " [-k realm] ");
        !           784: #else
        !           785:            "8L", " ");
        !           786: #endif
        !           787:        exit(1);
        !           788: }
        !           789: 
        !           790: /*
        !           791:  * The following routine provides compatibility (such as it is) between 4.2BSD
        !           792:  * Suns and others.  Suns have only a `ttysize', so we convert it to a winsize.
        !           793:  */
        !           794: #ifdef sun
        !           795: int
        !           796: get_window_size(fd, wp)
        !           797:        int fd;
        !           798:        struct winsize *wp;
        !           799: {
        !           800:        struct ttysize ts;
        !           801:        int error;
        !           802: 
        !           803:        if ((error = ioctl(0, TIOCGSIZE, &ts)) != 0)
        !           804:                return(error);
        !           805:        wp->ws_row = ts.ts_lines;
        !           806:        wp->ws_col = ts.ts_cols;
        !           807:        wp->ws_xpixel = 0;
        !           808:        wp->ws_ypixel = 0;
        !           809:        return(0);
        !           810: }
        !           811: #endif

unix.superglobalmegacorp.com

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