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