Annotation of 42BSD/ucb/rsh.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)rsh.c      4.8 83/06/10";
                      3: #endif
                      4: 
                      5: #include <sys/types.h>
                      6: #include <sys/socket.h>
                      7: #include <sys/ioctl.h>
                      8: #include <sys/file.h>
                      9: 
                     10: #include <netinet/in.h>
                     11: 
                     12: #include <stdio.h>
                     13: #include <errno.h>
                     14: #include <signal.h>
                     15: #include <pwd.h>
                     16: #include <netdb.h>
                     17: 
                     18: /*
                     19:  * rsh - remote shell
                     20:  */
                     21: /* VARARGS */
                     22: int    error();
                     23: char   *index(), *rindex(), *malloc(), *getpass(), *sprintf(), *strcpy();
                     24: 
                     25: struct passwd *getpwuid();
                     26: 
                     27: int    errno;
                     28: int    options;
                     29: int    rfd2;
                     30: int    sendsig();
                     31: 
                     32: #define        mask(s) (1 << ((s) - 1))
                     33: 
                     34: main(argc, argv0)
                     35:        int argc;
                     36:        char **argv0;
                     37: {
                     38:        int rem, pid;
                     39:        char *host, *cp, **ap, buf[BUFSIZ], *args, **argv = argv0, *user = 0;
                     40:        register int cc;
                     41:        int asrsh = 0;
                     42:        struct passwd *pwd;
                     43:        int readfrom, ready;
                     44:        int one = 1;
                     45:        struct servent *sp;
                     46:        int omask;
                     47: 
                     48:        host = rindex(argv[0], '/');
                     49:        if (host)
                     50:                host++;
                     51:        else
                     52:                host = argv[0];
                     53:        argv++, --argc;
                     54:        if (!strcmp(host, "rsh")) {
                     55:                host = *argv++, --argc;
                     56:                asrsh = 1;
                     57:        }
                     58: another:
                     59:        if (argc > 0 && !strcmp(*argv, "-l")) {
                     60:                argv++, argc--;
                     61:                if (argc > 0)
                     62:                        user = *argv++, argc--;
                     63:                goto another;
                     64:        }
                     65:        if (argc > 0 && !strcmp(*argv, "-n")) {
                     66:                argv++, argc--;
                     67:                (void) close(0);
                     68:                (void) open("/dev/null", 0);
                     69:                goto another;
                     70:        }
                     71:        if (argc > 0 && !strcmp(*argv, "-d")) {
                     72:                argv++, argc--;
                     73:                options |= SO_DEBUG;
                     74:                goto another;
                     75:        }
                     76:        /*
                     77:         * Ignore the -e flag to allow aliases with rlogin
                     78:         * to work
                     79:         */
                     80:        if (argc > 0 && !strncmp(*argv, "-e", 2)) {
                     81:                argv++, argc--;
                     82:                goto another;
                     83:        }
                     84:        if (host == 0)
                     85:                goto usage;
                     86:        if (argv[0] == 0) {
                     87:                if (asrsh)
                     88:                        *argv0 = "rlogin";
                     89:                execv("/usr/ucb/rlogin", argv0);
                     90:                perror("/usr/ucb/rlogin");
                     91:                exit(1);
                     92:        }
                     93:        pwd = getpwuid(getuid());
                     94:        if (pwd == 0) {
                     95:                fprintf(stderr, "who are you?\n");
                     96:                exit(1);
                     97:        }
                     98:        cc = 0;
                     99:        for (ap = argv; *ap; ap++)
                    100:                cc += strlen(*ap) + 1;
                    101:        cp = args = malloc(cc);
                    102:        for (ap = argv; *ap; ap++) {
                    103:                (void) strcpy(cp, *ap);
                    104:                while (*cp)
                    105:                        cp++;
                    106:                if (ap[1])
                    107:                        *cp++ = ' ';
                    108:        }
                    109:        sp = getservbyname("shell", "tcp");
                    110:        if (sp == 0) {
                    111:                fprintf(stderr, "rsh: shell/tcp: unknown service\n");
                    112:                exit(1);
                    113:        }
                    114:         rem = rcmd(&host, sp->s_port, pwd->pw_name,
                    115:            user ? user : pwd->pw_name, args, &rfd2);
                    116:         if (rem < 0)
                    117:                 exit(1);
                    118:        if (rfd2 < 0) {
                    119:                fprintf(stderr, "rsh: can't establish stderr\n");
                    120:                exit(2);
                    121:        }
                    122:        if (options & SO_DEBUG) {
                    123:                if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
                    124:                        perror("setsockopt (stdin)");
                    125:                if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
                    126:                        perror("setsockopt (stderr)");
                    127:        }
                    128:        (void) setuid(getuid());
                    129:        omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));
                    130:        signal(SIGINT, sendsig);
                    131:        signal(SIGQUIT, sendsig);
                    132:        signal(SIGTERM, sendsig);
                    133:         pid = fork();
                    134:         if (pid < 0) {
                    135:                perror("fork");
                    136:                 exit(1);
                    137:         }
                    138:        ioctl(rfd2, FIONBIO, &one);
                    139:        ioctl(rem, FIONBIO, &one);
                    140:         if (pid == 0) {
                    141:                char *bp; int rembits, wc;
                    142:                (void) close(rfd2);
                    143:        reread:
                    144:                errno = 0;
                    145:                cc = read(0, buf, sizeof buf);
                    146:                if (cc <= 0)
                    147:                        goto done;
                    148:                bp = buf;
                    149:        rewrite:
                    150:                rembits = 1<<rem;
                    151:                if (select(16, 0, &rembits, 0, 0) < 0) {
                    152:                        if (errno != EINTR) {
                    153:                                perror("select");
                    154:                                exit(1);
                    155:                        }
                    156:                        goto rewrite;
                    157:                }
                    158:                if ((rembits & (1<<rem)) == 0)
                    159:                        goto rewrite;
                    160:                wc = write(rem, bp, cc);
                    161:                if (wc < 0) {
                    162:                        if (errno == EWOULDBLOCK)
                    163:                                goto rewrite;
                    164:                        goto done;
                    165:                }
                    166:                cc -= wc; bp += wc;
                    167:                if (cc == 0)
                    168:                        goto reread;
                    169:                goto rewrite;
                    170:        done:
                    171:                (void) shutdown(rem, 1);
                    172:                exit(0);
                    173:        }
                    174:        sigsetmask(omask);
                    175:        readfrom = (1<<rfd2) | (1<<rem);
                    176:        do {
                    177:                ready = readfrom;
                    178:                if (select(16, &ready, 0, 0, 0) < 0) {
                    179:                        if (errno != EINTR) {
                    180:                                perror("select");
                    181:                                exit(1);
                    182:                        }
                    183:                        continue;
                    184:                }
                    185:                if (ready & (1<<rfd2)) {
                    186:                        errno = 0;
                    187:                        cc = read(rfd2, buf, sizeof buf);
                    188:                        if (cc <= 0) {
                    189:                                if (errno != EWOULDBLOCK)
                    190:                                        readfrom &= ~(1<<rfd2);
                    191:                        } else
                    192:                                (void) write(2, buf, cc);
                    193:                }
                    194:                if (ready & (1<<rem)) {
                    195:                        errno = 0;
                    196:                        cc = read(rem, buf, sizeof buf);
                    197:                        if (cc <= 0) {
                    198:                                if (errno != EWOULDBLOCK)
                    199:                                        readfrom &= ~(1<<rem);
                    200:                        } else
                    201:                                (void) write(1, buf, cc);
                    202:                }
                    203:         } while (readfrom);
                    204:         (void) kill(pid, SIGKILL);
                    205:        exit(0);
                    206: usage:
                    207:        fprintf(stderr,
                    208:            "usage: rsh host [ -l login ] [ -p passwd ] command\n");
                    209:        exit(1);
                    210: }
                    211: 
                    212: sendsig(signo)
                    213:        int signo;
                    214: {
                    215: 
                    216:        (void) write(rfd2, (char *)&signo, 1);
                    217: }

unix.superglobalmegacorp.com

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