|
|
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.