Annotation of 42BSD/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;
        !           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 = deftc.t_startc;
        !           142:        notc.t_stopc = deftc.t_stopc;
        !           143:        ioctl(0, TIOCGLTC, (char *)&defltc);
        !           144:        signal(SIGINT, exit);
        !           145:        signal(SIGHUP, exit);
        !           146:        signal(SIGQUIT, exit);
        !           147:        child = fork();
        !           148:        if (child == -1) {
        !           149:                perror("rlogin: fork");
        !           150:                done();
        !           151:        }
        !           152:        signal(SIGINT, SIG_IGN);
        !           153:        mode(1);
        !           154:        if (child == 0) {
        !           155:                reader();
        !           156:                sleep(1);
        !           157:                prf("\007Connection closed.");
        !           158:                exit(3);
        !           159:        }
        !           160:        signal(SIGCHLD, catchild);
        !           161:        writer();
        !           162:        prf("Closed connection.");
        !           163:        done();
        !           164: }
        !           165: 
        !           166: done()
        !           167: {
        !           168: 
        !           169:        mode(0);
        !           170:        if (child > 0 && kill(child, SIGKILL) >= 0)
        !           171:                wait((int *)0);
        !           172:        exit(0);
        !           173: }
        !           174: 
        !           175: catchild()
        !           176: {
        !           177:        union wait status;
        !           178:        int pid;
        !           179: 
        !           180: again:
        !           181:        pid = wait3(&status, WNOHANG|WUNTRACED, 0);
        !           182:        if (pid == 0)
        !           183:                return;
        !           184:        /*
        !           185:         * if the child (reader) dies, just quit
        !           186:         */
        !           187:        if (pid < 0 || pid == child && !WIFSTOPPED(status))
        !           188:                done();
        !           189:        goto again;
        !           190: }
        !           191: 
        !           192: /*
        !           193:  * writer: write to remote: 0 -> line.
        !           194:  * ~.  terminate
        !           195:  * ~^Z suspend rlogin process.
        !           196:  * ~^Y  suspend rlogin process, but leave reader alone.
        !           197:  */
        !           198: writer()
        !           199: {
        !           200:        char b[600], c;
        !           201:        register char *p;
        !           202:        register n;
        !           203: 
        !           204: top:
        !           205:        p = b;
        !           206:        for (;;) {
        !           207:                int local;
        !           208: 
        !           209:                n = read(0, &c, 1);
        !           210:                if (n == 0)
        !           211:                        break;
        !           212:                if (n < 0)
        !           213:                        if (errno == EINTR)
        !           214:                                continue;
        !           215:                        else
        !           216:                                break;
        !           217: 
        !           218:                if (eight == 0)
        !           219:                        c &= 0177;
        !           220:                /*
        !           221:                 * If we're at the beginning of the line
        !           222:                 * and recognize a command character, then
        !           223:                 * we echo locally.  Otherwise, characters
        !           224:                 * are echo'd remotely.  If the command
        !           225:                 * character is doubled, this acts as a 
        !           226:                 * force and local echo is suppressed.
        !           227:                 */
        !           228:                if (p == b)
        !           229:                        local = (c == cmdchar);
        !           230:                if (p == b + 1 && *b == cmdchar)
        !           231:                        local = (c != cmdchar);
        !           232:                if (!local) {
        !           233:                        if (write(rem, &c, 1) == 0) {
        !           234:                                prf("line gone");
        !           235:                                return;
        !           236:                        }
        !           237:                        if (eight == 0)
        !           238:                                c &= 0177;
        !           239:                } else {
        !           240:                        if (c == '\r' || c == '\n') {
        !           241:                                char cmdc = b[1];
        !           242: 
        !           243:                                if (cmdc == '.' || cmdc == deftc.t_eofc) {
        !           244:                                        write(0, CRLF, sizeof(CRLF));
        !           245:                                        return;
        !           246:                                }
        !           247:                                if (cmdc == defltc.t_suspc ||
        !           248:                                    cmdc == defltc.t_dsuspc) {
        !           249:                                        write(0, CRLF, sizeof(CRLF));
        !           250:                                        mode(0);
        !           251:                                        signal(SIGCHLD, SIG_IGN);
        !           252:                                        kill(cmdc == defltc.t_suspc ?
        !           253:                                          0 : getpid(), SIGTSTP);
        !           254:                                        signal(SIGCHLD, catchild);
        !           255:                                        mode(1);
        !           256:                                        goto top;
        !           257:                                }
        !           258:                                *p++ = c;
        !           259:                                write(rem, b, p - b);
        !           260:                                goto top;
        !           261:                        }
        !           262:                        write(1, &c, 1);
        !           263:                }
        !           264:                *p++ = c;
        !           265:                if (c == deferase) {
        !           266:                        p -= 2; 
        !           267:                        if (p < b)
        !           268:                                goto top;
        !           269:                }
        !           270:                if (c == defkill || c == deftc.t_eofc ||
        !           271:                    c == '\r' || c == '\n')
        !           272:                        goto top;
        !           273:                if (p >= &b[sizeof b])
        !           274:                        p--;
        !           275:        }
        !           276: }
        !           277: 
        !           278: oob()
        !           279: {
        !           280:        int out = 1+1, atmark;
        !           281:        char waste[BUFSIZ], mark;
        !           282: 
        !           283:        ioctl(1, TIOCFLUSH, (char *)&out);
        !           284:        for (;;) {
        !           285:                if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
        !           286:                        perror("ioctl");
        !           287:                        break;
        !           288:                }
        !           289:                if (atmark)
        !           290:                        break;
        !           291:                (void) read(rem, waste, sizeof (waste));
        !           292:        }
        !           293:        recv(rem, &mark, 1, MSG_OOB);
        !           294:        if (mark & TIOCPKT_NOSTOP) {
        !           295:                notc.t_stopc = -1;
        !           296:                notc.t_startc = -1;
        !           297:                ioctl(0, TIOCSETC, (char *)&notc);
        !           298:        }
        !           299:        if (mark & TIOCPKT_DOSTOP) {
        !           300:                notc.t_stopc = deftc.t_stopc;
        !           301:                notc.t_startc = deftc.t_startc;
        !           302:                ioctl(0, TIOCSETC, (char *)&notc);
        !           303:        }
        !           304: }
        !           305: 
        !           306: /*
        !           307:  * reader: read from remote: line -> 1
        !           308:  */
        !           309: reader()
        !           310: {
        !           311:        char rb[BUFSIZ];
        !           312:        register int cnt;
        !           313: 
        !           314:        signal(SIGURG, oob);
        !           315:        { int pid = -getpid();
        !           316:          ioctl(rem, SIOCSPGRP, (char *)&pid); }
        !           317:        for (;;) {
        !           318:                cnt = read(rem, rb, sizeof (rb));
        !           319:                if (cnt == 0)
        !           320:                        break;
        !           321:                if (cnt < 0) {
        !           322:                        if (errno == EINTR)
        !           323:                                continue;
        !           324:                        break;
        !           325:                }
        !           326:                write(1, rb, cnt);
        !           327:        }
        !           328: }
        !           329: 
        !           330: mode(f)
        !           331: {
        !           332:        struct tchars *tc;
        !           333:        struct ltchars *ltc;
        !           334:        struct sgttyb sb;
        !           335: 
        !           336:        ioctl(0, TIOCGETP, (char *)&sb);
        !           337:        switch (f) {
        !           338: 
        !           339:        case 0:
        !           340:                sb.sg_flags &= ~(CBREAK|RAW|TBDELAY);
        !           341:                sb.sg_flags |= defflags|tabflag;
        !           342:                tc = &deftc;
        !           343:                ltc = &defltc;
        !           344:                sb.sg_kill = defkill;
        !           345:                sb.sg_erase = deferase;
        !           346:                break;
        !           347: 
        !           348:        case 1:
        !           349:                sb.sg_flags |= (eight ? RAW : CBREAK);
        !           350:                sb.sg_flags &= ~defflags;
        !           351:                /* preserve tab delays, but turn off XTABS */
        !           352:                if ((sb.sg_flags & TBDELAY) == XTABS)
        !           353:                        sb.sg_flags &= ~TBDELAY;
        !           354:                tc = &notc;
        !           355:                ltc = &noltc;
        !           356:                sb.sg_kill = sb.sg_erase = -1;
        !           357:                break;
        !           358: 
        !           359:        default:
        !           360:                return;
        !           361:        }
        !           362:        ioctl(0, TIOCSLTC, (char *)ltc);
        !           363:        ioctl(0, TIOCSETC, (char *)tc);
        !           364:        ioctl(0, TIOCSETN, (char *)&sb);
        !           365: }
        !           366: 
        !           367: /*VARARGS*/
        !           368: prf(f, a1, a2, a3)
        !           369:        char *f;
        !           370: {
        !           371:        fprintf(stderr, f, a1, a2, a3);
        !           372:        fprintf(stderr, CRLF);
        !           373: }
        !           374: 
        !           375: lostpeer()
        !           376: {
        !           377:        signal(SIGPIPE, SIG_IGN);
        !           378:        prf("\007Connection closed.");
        !           379:        done();
        !           380: }

unix.superglobalmegacorp.com

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