Add copyright
[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
22e155fc
DF
14static char sccsid[] = "@(#)rsh.c 5.1 (Berkeley) %G%";
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 /*
3c1108f1 89 * Ignore the -w, -e and -8 flags to allow aliases with rlogin
0f09f657
CL
90 * to work
91 */
3c1108f1
JB
92 if (argc > 0 && !strncmp(*argv, "-w", 2)) {
93 argv++, argc--;
94 goto another;
95 }
4659bf8e 96 if (argc > 0 && !strncmp(*argv, "-e", 2)) {
0f09f657
CL
97 argv++, argc--;
98 goto another;
99 }
63556828
JL
100 if (argc > 0 && !strncmp(*argv, "-8", 2)) {
101 argv++, argc--;
102 goto another;
103 }
4a31bc6f
BJ
104 if (host == 0)
105 goto usage;
106 if (argv[0] == 0) {
107 if (asrsh)
108 *argv0 = "rlogin";
109 execv("/usr/ucb/rlogin", argv0);
110 perror("/usr/ucb/rlogin");
111 exit(1);
112 }
113 pwd = getpwuid(getuid());
114 if (pwd == 0) {
115 fprintf(stderr, "who are you?\n");
116 exit(1);
117 }
118 cc = 0;
119 for (ap = argv; *ap; ap++)
120 cc += strlen(*ap) + 1;
121 cp = args = malloc(cc);
122 for (ap = argv; *ap; ap++) {
123 (void) strcpy(cp, *ap);
124 while (*cp)
125 cp++;
126 if (ap[1])
127 *cp++ = ' ';
128 }
e1e93bd3
SL
129 sp = getservbyname("shell", "tcp");
130 if (sp == 0) {
131 fprintf(stderr, "rsh: shell/tcp: unknown service\n");
132 exit(1);
133 }
134 rem = rcmd(&host, sp->s_port, pwd->pw_name,
4a31bc6f
BJ
135 user ? user : pwd->pw_name, args, &rfd2);
136 if (rem < 0)
137 exit(1);
30b254da
SL
138 if (rfd2 < 0) {
139 fprintf(stderr, "rsh: can't establish stderr\n");
140 exit(2);
141 }
142 if (options & SO_DEBUG) {
0975b26d 143 if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof (one)) < 0)
30b254da 144 perror("setsockopt (stdin)");
0975b26d 145 if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one, sizeof (one)) < 0)
30b254da
SL
146 perror("setsockopt (stderr)");
147 }
4a31bc6f 148 (void) setuid(getuid());
4ca10280
SL
149 omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));
150 signal(SIGINT, sendsig);
151 signal(SIGQUIT, sendsig);
152 signal(SIGTERM, sendsig);
4a31bc6f
BJ
153 pid = fork();
154 if (pid < 0) {
155 perror("fork");
156 exit(1);
157 }
158 ioctl(rfd2, FIONBIO, &one);
159 ioctl(rem, FIONBIO, &one);
160 if (pid == 0) {
161 char *bp; int rembits, wc;
162 (void) close(rfd2);
163 reread:
420d8a52 164 errno = 0;
4a31bc6f
BJ
165 cc = read(0, buf, sizeof buf);
166 if (cc <= 0)
167 goto done;
168 bp = buf;
169 rewrite:
170 rembits = 1<<rem;
e7d6d17a
SL
171 if (select(16, 0, &rembits, 0, 0) < 0) {
172 if (errno != EINTR) {
173 perror("select");
174 exit(1);
175 }
176 goto rewrite;
177 }
4a31bc6f
BJ
178 if ((rembits & (1<<rem)) == 0)
179 goto rewrite;
180 wc = write(rem, bp, cc);
181 if (wc < 0) {
182 if (errno == EWOULDBLOCK)
183 goto rewrite;
184 goto done;
185 }
186 cc -= wc; bp += wc;
187 if (cc == 0)
188 goto reread;
189 goto rewrite;
190 done:
420d8a52 191 (void) shutdown(rem, 1);
4a31bc6f
BJ
192 exit(0);
193 }
4ca10280 194 sigsetmask(omask);
4a31bc6f
BJ
195 readfrom = (1<<rfd2) | (1<<rem);
196 do {
197 ready = readfrom;
e7d6d17a
SL
198 if (select(16, &ready, 0, 0, 0) < 0) {
199 if (errno != EINTR) {
200 perror("select");
201 exit(1);
202 }
203 continue;
204 }
4a31bc6f
BJ
205 if (ready & (1<<rfd2)) {
206 errno = 0;
207 cc = read(rfd2, buf, sizeof buf);
208 if (cc <= 0) {
209 if (errno != EWOULDBLOCK)
210 readfrom &= ~(1<<rfd2);
211 } else
212 (void) write(2, buf, cc);
213 }
214 if (ready & (1<<rem)) {
215 errno = 0;
216 cc = read(rem, buf, sizeof buf);
217 if (cc <= 0) {
218 if (errno != EWOULDBLOCK)
219 readfrom &= ~(1<<rem);
220 } else
221 (void) write(1, buf, cc);
222 }
223 } while (readfrom);
224 (void) kill(pid, SIGKILL);
225 exit(0);
226usage:
227 fprintf(stderr,
228 "usage: rsh host [ -l login ] [ -p passwd ] command\n");
229 exit(1);
230}
231
4a31bc6f 232sendsig(signo)
8842c908 233 char signo;
4a31bc6f
BJ
234{
235
8842c908 236 (void) write(rfd2, &signo, 1);
4a31bc6f 237}