Annotation of 42BSD/ucb/rlogin.c, revision 1.1.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.