mv machine dependent
[unix-history] / usr / src / usr.bin / rsh / rsh.c
CommitLineData
22e155fc
DF
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
8char copyright[] =
9"@(#) Copyright (c) 1983 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
4a31bc6f 13#ifndef lint
4db732ec 14static char sccsid[] = "@(#)rsh.c 5.4 (Berkeley) %G%";
22e155fc 15#endif not lint
4a31bc6f 16
4a31bc6f
BJ
17#include <sys/types.h>
18#include <sys/socket.h>
e7d6d17a 19#include <sys/ioctl.h>
4a31bc6f 20#include <sys/file.h>
e7d6d17a
SL
21
22#include <netinet/in.h>
23
24#include <stdio.h>
4a31bc6f
BJ
25#include <errno.h>
26#include <signal.h>
4a31bc6f 27#include <pwd.h>
e1e93bd3 28#include <netdb.h>
4a31bc6f
BJ
29
30/*
31 * rsh - remote shell
32 */
33/* VARARGS */
34int error();
35char *index(), *rindex(), *malloc(), *getpass(), *sprintf(), *strcpy();
36
37struct passwd *getpwuid();
38
39int errno;
40int options;
41int rfd2;
42int sendsig();
43
4ca10280
SL
44#define mask(s) (1 << ((s) - 1))
45
4a31bc6f
BJ
46main(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;
e1e93bd3 57 struct servent *sp;
4ca10280 58 int omask;
4a31bc6f
BJ
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 }
70another:
4659bf8e 71 if (argc > 0 && !strcmp(*argv, "-l")) {
4a31bc6f
BJ
72 argv++, argc--;
73 if (argc > 0)
74 user = *argv++, argc--;
75 goto another;
76 }
4659bf8e 77 if (argc > 0 && !strcmp(*argv, "-n")) {
4a31bc6f
BJ
78 argv++, argc--;
79 (void) close(0);
80 (void) open("/dev/null", 0);
81 goto another;
82 }
4659bf8e 83 if (argc > 0 && !strcmp(*argv, "-d")) {
4a31bc6f
BJ
84 argv++, argc--;
85 options |= SO_DEBUG;
86 goto another;
87 }
0f09f657 88 /*
eeb173b2 89 * Ignore the -L, -w, -e and -8 flags to allow aliases with rlogin
0f09f657 90 * to work
eeb173b2
JB
91 *
92 * There must be a better way to do this! -jmb
0f09f657 93 */
eeb173b2
JB
94 if (argc > 0 && !strncmp(*argv, "-L", 2)) {
95 argv++, argc--;
96 goto another;
97 }
3c1108f1
JB
98 if (argc > 0 && !strncmp(*argv, "-w", 2)) {
99 argv++, argc--;
100 goto another;
101 }
4659bf8e 102 if (argc > 0 && !strncmp(*argv, "-e", 2)) {
0f09f657
CL
103 argv++, argc--;
104 goto another;
105 }
63556828
JL
106 if (argc > 0 && !strncmp(*argv, "-8", 2)) {
107 argv++, argc--;
108 goto another;
109 }
4a31bc6f
BJ
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 }
e1e93bd3
SL
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,
4a31bc6f
BJ
141 user ? user : pwd->pw_name, args, &rfd2);
142 if (rem < 0)
143 exit(1);
30b254da
SL
144 if (rfd2 < 0) {
145 fprintf(stderr, "rsh: can't establish stderr\n");
146 exit(2);
147 }
148 if (options & SO_DEBUG) {
0975b26d 149 if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof (one)) < 0)
30b254da 150 perror("setsockopt (stdin)");
0975b26d 151 if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one, sizeof (one)) < 0)
30b254da
SL
152 perror("setsockopt (stderr)");
153 }
4a31bc6f 154 (void) setuid(getuid());
4ca10280 155 omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));
4db732ec
JB
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);
4a31bc6f
BJ
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:
420d8a52 173 errno = 0;
4a31bc6f
BJ
174 cc = read(0, buf, sizeof buf);
175 if (cc <= 0)
176 goto done;
177 bp = buf;
178 rewrite:
179 rembits = 1<<rem;
e7d6d17a
SL
180 if (select(16, 0, &rembits, 0, 0) < 0) {
181 if (errno != EINTR) {
182 perror("select");
183 exit(1);
184 }
185 goto rewrite;
186 }
4a31bc6f
BJ
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:
420d8a52 200 (void) shutdown(rem, 1);
4a31bc6f
BJ
201 exit(0);
202 }
4ca10280 203 sigsetmask(omask);
4a31bc6f
BJ
204 readfrom = (1<<rfd2) | (1<<rem);
205 do {
206 ready = readfrom;
e7d6d17a
SL
207 if (select(16, &ready, 0, 0, 0) < 0) {
208 if (errno != EINTR) {
209 perror("select");
210 exit(1);
211 }
212 continue;
213 }
4a31bc6f
BJ
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);
235usage:
236 fprintf(stderr,
ff712929 237 "usage: rsh host [ -l login ] [ -n ] command\n");
4a31bc6f
BJ
238 exit(1);
239}
240
4a31bc6f 241sendsig(signo)
8842c908 242 char signo;
4a31bc6f
BJ
243{
244
8842c908 245 (void) write(rfd2, &signo, 1);
4a31bc6f 246}