|
|
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.6 (Berkeley) 10/22/87"; ! 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(), *strcpy(); ! 36: ! 37: struct passwd *getpwuid(); ! 38: ! 39: int errno; ! 40: int options; ! 41: int rfd2; ! 42: int nflag; ! 43: int sendsig(); ! 44: ! 45: #define mask(s) (1 << ((s) - 1)) ! 46: ! 47: main(argc, argv0) ! 48: int argc; ! 49: char **argv0; ! 50: { ! 51: int rem, pid; ! 52: char *host, *cp, **ap, buf[BUFSIZ], *args, **argv = argv0, *user = 0; ! 53: register int cc; ! 54: int asrsh = 0; ! 55: struct passwd *pwd; ! 56: int readfrom, ready; ! 57: int one = 1; ! 58: struct servent *sp; ! 59: int omask; ! 60: ! 61: host = rindex(argv[0], '/'); ! 62: if (host) ! 63: host++; ! 64: else ! 65: host = argv[0]; ! 66: argv++, --argc; ! 67: if (!strcmp(host, "rsh")) { ! 68: host = *argv++, --argc; ! 69: asrsh = 1; ! 70: } ! 71: another: ! 72: if (argc > 0 && !strcmp(*argv, "-l")) { ! 73: argv++, argc--; ! 74: if (argc > 0) ! 75: user = *argv++, argc--; ! 76: goto another; ! 77: } ! 78: if (argc > 0 && !strcmp(*argv, "-n")) { ! 79: argv++, argc--; ! 80: nflag++; ! 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: if (nflag == 0) { ! 163: pid = fork(); ! 164: if (pid < 0) { ! 165: perror("fork"); ! 166: exit(1); ! 167: } ! 168: } ! 169: ioctl(rfd2, FIONBIO, &one); ! 170: ioctl(rem, FIONBIO, &one); ! 171: if (nflag == 0 && pid == 0) { ! 172: char *bp; int rembits, wc; ! 173: (void) close(rfd2); ! 174: reread: ! 175: errno = 0; ! 176: cc = read(0, buf, sizeof buf); ! 177: if (cc <= 0) ! 178: goto done; ! 179: bp = buf; ! 180: rewrite: ! 181: rembits = 1<<rem; ! 182: if (select(16, 0, &rembits, 0, 0) < 0) { ! 183: if (errno != EINTR) { ! 184: perror("select"); ! 185: exit(1); ! 186: } ! 187: goto rewrite; ! 188: } ! 189: if ((rembits & (1<<rem)) == 0) ! 190: goto rewrite; ! 191: wc = write(rem, bp, cc); ! 192: if (wc < 0) { ! 193: if (errno == EWOULDBLOCK) ! 194: goto rewrite; ! 195: goto done; ! 196: } ! 197: cc -= wc; bp += wc; ! 198: if (cc == 0) ! 199: goto reread; ! 200: goto rewrite; ! 201: done: ! 202: (void) shutdown(rem, 1); ! 203: exit(0); ! 204: } ! 205: sigsetmask(omask); ! 206: readfrom = (1<<rfd2) | (1<<rem); ! 207: do { ! 208: ready = readfrom; ! 209: if (select(16, &ready, 0, 0, 0) < 0) { ! 210: if (errno != EINTR) { ! 211: perror("select"); ! 212: exit(1); ! 213: } ! 214: continue; ! 215: } ! 216: if (ready & (1<<rfd2)) { ! 217: errno = 0; ! 218: cc = read(rfd2, buf, sizeof buf); ! 219: if (cc <= 0) { ! 220: if (errno != EWOULDBLOCK) ! 221: readfrom &= ~(1<<rfd2); ! 222: } else ! 223: (void) write(2, buf, cc); ! 224: } ! 225: if (ready & (1<<rem)) { ! 226: errno = 0; ! 227: cc = read(rem, buf, sizeof buf); ! 228: if (cc <= 0) { ! 229: if (errno != EWOULDBLOCK) ! 230: readfrom &= ~(1<<rem); ! 231: } else ! 232: (void) write(1, buf, cc); ! 233: } ! 234: } while (readfrom); ! 235: if (nflag == 0) ! 236: (void) kill(pid, SIGKILL); ! 237: exit(0); ! 238: usage: ! 239: fprintf(stderr, ! 240: "usage: rsh host [ -l login ] [ -n ] command\n"); ! 241: exit(1); ! 242: } ! 243: ! 244: sendsig(signo) ! 245: char signo; ! 246: { ! 247: ! 248: (void) write(rfd2, &signo, 1); ! 249: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.