Annotation of cci/usr/src/ucb/rlogin.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)rlogin.c   4.15 (Berkeley) 83/07/02";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * rlogin - remote login
        !             7:  */
        !             8: #include <sys/types.h>
        !             9: #include <sys/socket.h>
        !            10: #include <sys/wait.h>
        !            11: 
        !            12: #include <netinet/in.h>
        !            13: 
        !            14: #include <stdio.h>
        !            15: #include <sgtty.h>
        !            16: #include <errno.h>
        !            17: #include <pwd.h>
        !            18: #include <signal.h>
        !            19: #include <netdb.h>
        !            20: 
        !            21: char   *index(), *rindex(), *malloc(), *getenv();
        !            22: struct passwd *getpwuid();
        !            23: char   *name;
        !            24: int    rem;
        !            25: char   cmdchar = '~';
        !            26: int    eight;
        !            27: char   *speeds[] =
        !            28:     { "0", "50", "75", "110", "134", "150", "200", "300",
        !            29:       "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
        !            30: char   term[64] = "network";
        !            31: extern int errno;
        !            32: int    lostpeer();
        !            33: 
        !            34: main(argc, argv)
        !            35:        int argc;
        !            36:        char **argv;
        !            37: {
        !            38:        char *host, *cp;
        !            39:        struct sgttyb ttyb;
        !            40:        struct passwd *pwd;
        !            41:        struct servent *sp;
        !            42:        int uid, options = 0;
        !            43: 
        !            44:        host = rindex(argv[0], '/');
        !            45:        if (host)
        !            46:                host++;
        !            47:        else
        !            48:                host = argv[0];
        !            49:        argv++, --argc;
        !            50:        if (!strcmp(host, "rlogin"))
        !            51:                host = *argv++, --argc;
        !            52: another:
        !            53:        if (argc > 0 && !strcmp(*argv, "-d")) {
        !            54:                argv++, argc--;
        !            55:                options |= SO_DEBUG;
        !            56:                goto another;
        !            57:        }
        !            58:        if (argc > 0 && !strcmp(*argv, "-l")) {
        !            59:                argv++, argc--;
        !            60:                if (argc == 0)
        !            61:                        goto usage;
        !            62:                name = *argv++; argc--;
        !            63:                goto another;
        !            64:        }
        !            65:        if (argc > 0 && !strncmp(*argv, "-e", 2)) {
        !            66:                cmdchar = argv[0][2];
        !            67:                argv++, argc--;
        !            68:                goto another;
        !            69:        }
        !            70:        if (argc > 0 && !strcmp(*argv, "-8")) {
        !            71:                eight = 1;
        !            72:                argv++, argc--;
        !            73:                goto another;
        !            74:        }
        !            75:        if (host == 0)
        !            76:                goto usage;
        !            77:        if (argc > 0)
        !            78:                goto usage;
        !            79:        pwd = getpwuid(getuid());
        !            80:        if (pwd == 0) {
        !            81:                fprintf(stderr, "Who are you?\n");
        !            82:                exit(1);
        !            83:        }
        !            84:        sp = getservbyname("login", "tcp");
        !            85:        if (sp == 0) {
        !            86:                fprintf(stderr, "rlogin: login/tcp: unknown service\n");
        !            87:                exit(2);
        !            88:        }
        !            89:        cp = getenv("TERM");
        !            90:        if (cp)
        !            91:                strcpy(term, cp);
        !            92:        if (ioctl(0, TIOCGETP, &ttyb)==0) {
        !            93:                strcat(term, "/");
        !            94:                strcat(term, speeds[ttyb.sg_ospeed]);
        !            95:        }
        !            96:        signal(SIGPIPE, lostpeer);
        !            97:         rem = rcmd(&host, sp->s_port, pwd->pw_name,
        !            98:            name ? name : pwd->pw_name, term, 0);
        !            99:         if (rem < 0)
        !           100:                 exit(1);
        !           101:        if (options & SO_DEBUG &&
        !           102:            setsockopt(rem, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
        !           103:                perror("rlogin: setsockopt (SO_DEBUG)");
        !           104:        uid = getuid();
        !           105:        if (setuid(uid) < 0) {
        !           106:                perror("rlogin: setuid");
        !           107:                exit(1);
        !           108:        }
        !           109:        doit();
        !           110:        /*NOTREACHED*/
        !           111: usage:
        !           112:        fprintf(stderr,
        !           113:            "usage: rlogin host [ -ex ] [ -l username ] [ -8 ]\n");
        !           114:        exit(1);
        !           115: }
        !           116: 
        !           117: #define CRLF "\r\n"
        !           118: 
        !           119: int    child;
        !           120: int    catchild();
        !           121: 
        !           122: int    defflags, tabflag;
        !           123: char   deferase, defkill, defstartc, defstopc, defintr;
        !           124: struct tchars deftc;
        !           125: struct ltchars defltc;
        !           126: struct tchars notc =   { -1, -1, -1, -1, -1, -1 };
        !           127: struct ltchars noltc = { -1, -1, -1, -1, -1, -1 };
        !           128: 
        !           129: doit()
        !           130: {
        !           131:        int exit();
        !           132:        struct sgttyb sb;
        !           133: 
        !           134:        ioctl(0, TIOCGETP, (char *)&sb);
        !           135:        defflags = sb.sg_flags;
        !           136:        tabflag = defflags & TBDELAY;
        !           137:        defflags &= ECHO | CRMOD;
        !           138:        deferase = sb.sg_erase;
        !           139:        defkill = sb.sg_kill;
        !           140:        ioctl(0, TIOCGETC, (char *)&deftc);
        !           141:        notc.t_startc = defstartc = deftc.t_startc;
        !           142:        notc.t_stopc = defstopc = deftc.t_stopc;
        !           143:        defintr = deftc.t_intrc;
        !           144:        ioctl(0, TIOCGLTC, (char *)&defltc);
        !           145:        signal(SIGINT, exit);
        !           146:        signal(SIGHUP, exit);
        !           147:        signal(SIGQUIT, exit);
        !           148:        child = fork();
        !           149:        if (child == -1) {
        !           150:                perror("rlogin: fork");
        !           151:                done();
        !           152:        }
        !           153:        signal(SIGINT, SIG_IGN);
        !           154:        mode(1);
        !           155:        if (child == 0) {
        !           156:                reader();
        !           157:                sleep(1);
        !           158:                prf("\007Connection closed.");
        !           159:                exit(3);
        !           160:        }
        !           161:        signal(SIGCHLD, catchild);
        !           162:        writer();
        !           163:        prf("Closed connection.");
        !           164:        done();
        !           165: }
        !           166: 
        !           167: done()
        !           168: {
        !           169: 
        !           170:        mode(0);
        !           171:        if (child > 0 && kill(child, SIGKILL) >= 0)
        !           172:                wait((int *)0);
        !           173:        exit(0);
        !           174: }
        !           175: 
        !           176: catchild()
        !           177: {
        !           178:        union wait status;
        !           179:        int pid;
        !           180: 
        !           181: again:
        !           182:        pid = wait3(&status, WNOHANG|WUNTRACED, 0);
        !           183:        if (pid == 0)
        !           184:                return;
        !           185:        /*
        !           186:         * if the child (reader) dies, just quit
        !           187:         */
        !           188:        if (pid < 0 || pid == child && !WIFSTOPPED(status))
        !           189:                done();
        !           190:        goto again;
        !           191: }
        !           192: 
        !           193: /*
        !           194:  * writer: write to remote: 0 -> line.
        !           195:  * ~.  terminate
        !           196:  * ~^Z suspend rlogin process.
        !           197:  * ~^Y  suspend rlogin process, but leave reader alone.
        !           198:  */
        !           199: writer()
        !           200: {
        !           201:        char b[600], c;
        !           202:        register char *p;
        !           203:        register n;
        !           204: 
        !           205: top:
        !           206:        p = b;
        !           207:        for (;;) {
        !           208:                int local;
        !           209: 
        !           210:                n = read(0, &c, 1);
        !           211:                if (n == 0)
        !           212:                        break;
        !           213:                if (n < 0)
        !           214:                        if (errno == EINTR)
        !           215:                                continue;
        !           216:                        else
        !           217:                                break;
        !           218: 
        !           219:                if (eight == 0)
        !           220:                        c &= 0177;
        !           221:                /*
        !           222:                 * If we're at the beginning of the line
        !           223:                 * and recognize a command character, then
        !           224:                 * we echo locally.  Otherwise, characters
        !           225:                 * are echo'd remotely.  If the command
        !           226:                 * character is doubled, this acts as a 
        !           227:                 * force and local echo is suppressed.
        !           228:                 */
        !           229:                if (p == b)
        !           230:                        local = (c == cmdchar);
        !           231:                if (p == b + 1 && *b == cmdchar)
        !           232:                        local = (c != cmdchar);
        !           233:                if (!local) {
        !           234:                        if (write(rem, &c, 1) == 0) {
        !           235:                                prf("line gone");
        !           236:                                return;
        !           237:                        }
        !           238:                        if (eight == 0)
        !           239:                                c &= 0177;
        !           240:                } else {
        !           241:                        if (c == '\r' || c == '\n') {
        !           242:                                char cmdc = b[1];
        !           243: 
        !           244:                                if (cmdc == '.' || cmdc == deftc.t_eofc) {
        !           245:                                        write(0, CRLF, sizeof(CRLF));
        !           246:                                        return;
        !           247:                                }
        !           248:                                if (cmdc == defltc.t_suspc ||
        !           249:                                    cmdc == defltc.t_dsuspc) {
        !           250:                                        write(0, CRLF, sizeof(CRLF));
        !           251:                                        mode(0);
        !           252:                                        signal(SIGCHLD, SIG_IGN);
        !           253:                                        kill(cmdc == defltc.t_suspc ?
        !           254:                                          0 : getpid(), SIGTSTP);
        !           255:                                        signal(SIGCHLD, catchild);
        !           256:                                        mode(1);
        !           257:                                        goto top;
        !           258:                                }
        !           259:                                *p++ = c;
        !           260:                                write(rem, b, p - b);
        !           261:                                goto top;
        !           262:                        }
        !           263:                        write(1, &c, 1);
        !           264:                }
        !           265:                *p++ = c;
        !           266: #ifdef BOL
        !           267:                if (c == deferase || c == defstartc || c == defstopc) {
        !           268:                        p -= 2; 
        !           269:                        if (p < b)
        !           270:                                goto top;
        !           271:                }
        !           272:                if (c == defkill || c == deftc.t_eofc || c == defintr ||
        !           273:                    c == '\r' || c == '\n')
        !           274: #else  BOL
        !           275:                if (c == '\r' || c == '\n')
        !           276: #endif BOL
        !           277:                        goto top;
        !           278:                if (p >= &b[sizeof b])
        !           279:                        p--;
        !           280:        }
        !           281: }
        !           282: 
        !           283: oob()
        !           284: {
        !           285:        int out = 1+1, atmark;
        !           286:        char waste[BUFSIZ], mark;
        !           287: 
        !           288:        ioctl(1, TIOCFLUSH, (char *)&out);
        !           289:        for (;;) {
        !           290:                if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
        !           291:                        perror("ioctl");
        !           292:                        break;
        !           293:                }
        !           294:                if (atmark)
        !           295:                        break;
        !           296:                (void) read(rem, waste, sizeof (waste));
        !           297:        }
        !           298:        recv(rem, &mark, 1, MSG_OOB);
        !           299:        if (mark & TIOCPKT_NOSTOP) {
        !           300:                notc.t_stopc = -1;
        !           301:                notc.t_startc = -1;
        !           302:                ioctl(0, TIOCSETC, (char *)&notc);
        !           303:        }
        !           304:        if (mark & TIOCPKT_DOSTOP) {
        !           305:                notc.t_stopc = deftc.t_stopc;
        !           306:                notc.t_startc = deftc.t_startc;
        !           307:                ioctl(0, TIOCSETC, (char *)&notc);
        !           308:        }
        !           309: }
        !           310: 
        !           311: /*
        !           312:  * reader: read from remote: line -> 1
        !           313:  */
        !           314: reader()
        !           315: {
        !           316:        char rb[BUFSIZ];
        !           317:        register int cnt;
        !           318: 
        !           319:        signal(SIGURG, oob);
        !           320:        { int pid = -getpid();
        !           321:          ioctl(rem, SIOCSPGRP, (char *)&pid); }
        !           322:        for (;;) {
        !           323:                cnt = read(rem, rb, sizeof (rb));
        !           324:                if (cnt == 0)
        !           325:                        break;
        !           326:                if (cnt < 0) {
        !           327:                        if (errno == EINTR)
        !           328:                                continue;
        !           329:                        break;
        !           330:                }
        !           331:                write(1, rb, cnt);
        !           332:        }
        !           333: }
        !           334: 
        !           335: mode(f)
        !           336: {
        !           337:        struct tchars *tc;
        !           338:        struct ltchars *ltc;
        !           339:        struct sgttyb sb;
        !           340: 
        !           341:        ioctl(0, TIOCGETP, (char *)&sb);
        !           342:        switch (f) {
        !           343: 
        !           344:        case 0:
        !           345:                sb.sg_flags &= ~(CBREAK|RAW|TBDELAY);
        !           346:                sb.sg_flags |= defflags|tabflag;
        !           347:                tc = &deftc;
        !           348:                ltc = &defltc;
        !           349:                sb.sg_kill = defkill;
        !           350:                sb.sg_erase = deferase;
        !           351:                break;
        !           352: 
        !           353:        case 1:
        !           354:                sb.sg_flags |= (eight ? RAW : CBREAK);
        !           355:                sb.sg_flags &= ~defflags;
        !           356:                /* preserve tab delays, but turn off XTABS */
        !           357:                if ((sb.sg_flags & TBDELAY) == XTABS)
        !           358:                        sb.sg_flags &= ~TBDELAY;
        !           359:                tc = &notc;
        !           360:                ltc = &noltc;
        !           361:                sb.sg_kill = sb.sg_erase = -1;
        !           362:                break;
        !           363: 
        !           364:        default:
        !           365:                return;
        !           366:        }
        !           367:        ioctl(0, TIOCSLTC, (char *)ltc);
        !           368:        ioctl(0, TIOCSETC, (char *)tc);
        !           369:        ioctl(0, TIOCSETN, (char *)&sb);
        !           370: }
        !           371: 
        !           372: /*VARARGS*/
        !           373: prf(f, a1, a2, a3)
        !           374:        char *f;
        !           375: {
        !           376:        fprintf(stderr, f, a1, a2, a3);
        !           377:        fprintf(stderr, CRLF);
        !           378: }
        !           379: 
        !           380: lostpeer()
        !           381: {
        !           382:        signal(SIGPIPE, SIG_IGN);
        !           383:        prf("\007Connection closed (lost peer).");
        !           384:        done();
        !           385: }

unix.superglobalmegacorp.com

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