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