|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.