temp files should be protected; bug report 4.3BSD/usr.bin/186
[unix-history] / usr / src / usr.bin / rsh / rsh.c
CommitLineData
22e155fc 1/*
63dd6c18
KB
2 * Copyright (c) 1983 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22e155fc
DF
16 */
17
18#ifndef lint
19char copyright[] =
63dd6c18 20"@(#) Copyright (c) 1983 The Regents of the University of California.\n\
22e155fc 21 All rights reserved.\n";
63dd6c18 22#endif /* not lint */
22e155fc 23
4a31bc6f 24#ifndef lint
63dd6c18
KB
25static char sccsid[] = "@(#)rsh.c 5.7 (Berkeley) %G%";
26#endif /* not lint */
4a31bc6f 27
4a31bc6f
BJ
28#include <sys/types.h>
29#include <sys/socket.h>
e7d6d17a 30#include <sys/ioctl.h>
4a31bc6f 31#include <sys/file.h>
e7d6d17a
SL
32
33#include <netinet/in.h>
34
35#include <stdio.h>
4a31bc6f
BJ
36#include <errno.h>
37#include <signal.h>
4a31bc6f 38#include <pwd.h>
e1e93bd3 39#include <netdb.h>
4a31bc6f
BJ
40
41/*
42 * rsh - remote shell
43 */
44/* VARARGS */
45int error();
06eef7c4 46char *index(), *rindex(), *malloc(), *getpass(), *strcpy();
4a31bc6f
BJ
47
48struct passwd *getpwuid();
49
50int errno;
51int options;
52int rfd2;
e1f4a31c 53int nflag;
4a31bc6f
BJ
54int sendsig();
55
4ca10280
SL
56#define mask(s) (1 << ((s) - 1))
57
4a31bc6f
BJ
58main(argc, argv0)
59 int argc;
60 char **argv0;
61{
62 int rem, pid;
63 char *host, *cp, **ap, buf[BUFSIZ], *args, **argv = argv0, *user = 0;
64 register int cc;
65 int asrsh = 0;
66 struct passwd *pwd;
67 int readfrom, ready;
68 int one = 1;
e1e93bd3 69 struct servent *sp;
4ca10280 70 int omask;
4a31bc6f
BJ
71
72 host = rindex(argv[0], '/');
73 if (host)
74 host++;
75 else
76 host = argv[0];
77 argv++, --argc;
78 if (!strcmp(host, "rsh")) {
79 host = *argv++, --argc;
80 asrsh = 1;
81 }
82another:
4659bf8e 83 if (argc > 0 && !strcmp(*argv, "-l")) {
4a31bc6f
BJ
84 argv++, argc--;
85 if (argc > 0)
86 user = *argv++, argc--;
87 goto another;
88 }
4659bf8e 89 if (argc > 0 && !strcmp(*argv, "-n")) {
4a31bc6f 90 argv++, argc--;
e1f4a31c 91 nflag++;
4a31bc6f
BJ
92 goto another;
93 }
4659bf8e 94 if (argc > 0 && !strcmp(*argv, "-d")) {
4a31bc6f
BJ
95 argv++, argc--;
96 options |= SO_DEBUG;
97 goto another;
98 }
0f09f657 99 /*
eeb173b2 100 * Ignore the -L, -w, -e and -8 flags to allow aliases with rlogin
0f09f657 101 * to work
eeb173b2
JB
102 *
103 * There must be a better way to do this! -jmb
0f09f657 104 */
eeb173b2
JB
105 if (argc > 0 && !strncmp(*argv, "-L", 2)) {
106 argv++, argc--;
107 goto another;
108 }
3c1108f1
JB
109 if (argc > 0 && !strncmp(*argv, "-w", 2)) {
110 argv++, argc--;
111 goto another;
112 }
4659bf8e 113 if (argc > 0 && !strncmp(*argv, "-e", 2)) {
0f09f657
CL
114 argv++, argc--;
115 goto another;
116 }
63556828
JL
117 if (argc > 0 && !strncmp(*argv, "-8", 2)) {
118 argv++, argc--;
119 goto another;
120 }
4a31bc6f
BJ
121 if (host == 0)
122 goto usage;
123 if (argv[0] == 0) {
124 if (asrsh)
125 *argv0 = "rlogin";
126 execv("/usr/ucb/rlogin", argv0);
127 perror("/usr/ucb/rlogin");
128 exit(1);
129 }
130 pwd = getpwuid(getuid());
131 if (pwd == 0) {
132 fprintf(stderr, "who are you?\n");
133 exit(1);
134 }
135 cc = 0;
136 for (ap = argv; *ap; ap++)
137 cc += strlen(*ap) + 1;
138 cp = args = malloc(cc);
139 for (ap = argv; *ap; ap++) {
140 (void) strcpy(cp, *ap);
141 while (*cp)
142 cp++;
143 if (ap[1])
144 *cp++ = ' ';
145 }
e1e93bd3
SL
146 sp = getservbyname("shell", "tcp");
147 if (sp == 0) {
148 fprintf(stderr, "rsh: shell/tcp: unknown service\n");
149 exit(1);
150 }
151 rem = rcmd(&host, sp->s_port, pwd->pw_name,
4a31bc6f
BJ
152 user ? user : pwd->pw_name, args, &rfd2);
153 if (rem < 0)
154 exit(1);
30b254da
SL
155 if (rfd2 < 0) {
156 fprintf(stderr, "rsh: can't establish stderr\n");
157 exit(2);
158 }
159 if (options & SO_DEBUG) {
0975b26d 160 if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof (one)) < 0)
30b254da 161 perror("setsockopt (stdin)");
0975b26d 162 if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one, sizeof (one)) < 0)
30b254da
SL
163 perror("setsockopt (stderr)");
164 }
4a31bc6f 165 (void) setuid(getuid());
4ca10280 166 omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));
4db732ec
JB
167 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
168 signal(SIGINT, sendsig);
169 if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
170 signal(SIGQUIT, sendsig);
171 if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
172 signal(SIGTERM, sendsig);
e1f4a31c
MK
173 if (nflag == 0) {
174 pid = fork();
175 if (pid < 0) {
176 perror("fork");
177 exit(1);
178 }
179 }
4a31bc6f
BJ
180 ioctl(rfd2, FIONBIO, &one);
181 ioctl(rem, FIONBIO, &one);
e1f4a31c 182 if (nflag == 0 && pid == 0) {
4a31bc6f
BJ
183 char *bp; int rembits, wc;
184 (void) close(rfd2);
185 reread:
420d8a52 186 errno = 0;
4a31bc6f
BJ
187 cc = read(0, buf, sizeof buf);
188 if (cc <= 0)
189 goto done;
190 bp = buf;
191 rewrite:
192 rembits = 1<<rem;
e7d6d17a
SL
193 if (select(16, 0, &rembits, 0, 0) < 0) {
194 if (errno != EINTR) {
195 perror("select");
196 exit(1);
197 }
198 goto rewrite;
199 }
4a31bc6f
BJ
200 if ((rembits & (1<<rem)) == 0)
201 goto rewrite;
202 wc = write(rem, bp, cc);
203 if (wc < 0) {
204 if (errno == EWOULDBLOCK)
205 goto rewrite;
206 goto done;
207 }
208 cc -= wc; bp += wc;
209 if (cc == 0)
210 goto reread;
211 goto rewrite;
212 done:
420d8a52 213 (void) shutdown(rem, 1);
4a31bc6f
BJ
214 exit(0);
215 }
4ca10280 216 sigsetmask(omask);
4a31bc6f
BJ
217 readfrom = (1<<rfd2) | (1<<rem);
218 do {
219 ready = readfrom;
e7d6d17a
SL
220 if (select(16, &ready, 0, 0, 0) < 0) {
221 if (errno != EINTR) {
222 perror("select");
223 exit(1);
224 }
225 continue;
226 }
4a31bc6f
BJ
227 if (ready & (1<<rfd2)) {
228 errno = 0;
229 cc = read(rfd2, buf, sizeof buf);
230 if (cc <= 0) {
231 if (errno != EWOULDBLOCK)
232 readfrom &= ~(1<<rfd2);
233 } else
234 (void) write(2, buf, cc);
235 }
236 if (ready & (1<<rem)) {
237 errno = 0;
238 cc = read(rem, buf, sizeof buf);
239 if (cc <= 0) {
240 if (errno != EWOULDBLOCK)
241 readfrom &= ~(1<<rem);
242 } else
243 (void) write(1, buf, cc);
244 }
245 } while (readfrom);
e1f4a31c
MK
246 if (nflag == 0)
247 (void) kill(pid, SIGKILL);
4a31bc6f
BJ
248 exit(0);
249usage:
250 fprintf(stderr,
ff712929 251 "usage: rsh host [ -l login ] [ -n ] command\n");
4a31bc6f
BJ
252 exit(1);
253}
254
4a31bc6f 255sendsig(signo)
8842c908 256 char signo;
4a31bc6f
BJ
257{
258
8842c908 259 (void) write(rfd2, &signo, 1);
4a31bc6f 260}