formatting
[unix-history] / usr / src / usr.bin / rsh / rsh.c
CommitLineData
4a31bc6f 1#ifndef lint
420d8a52 2static char sccsid[] = "@(#)rsh.c 4.7 83/02/23";
4a31bc6f
BJ
3#endif
4
4a31bc6f
BJ
5#include <sys/types.h>
6#include <sys/socket.h>
e7d6d17a 7#include <sys/ioctl.h>
4a31bc6f 8#include <sys/file.h>
e7d6d17a
SL
9
10#include <netinet/in.h>
11
12#include <stdio.h>
4a31bc6f
BJ
13#include <errno.h>
14#include <signal.h>
4a31bc6f 15#include <pwd.h>
e1e93bd3 16#include <netdb.h>
4a31bc6f
BJ
17
18/*
19 * rsh - remote shell
20 */
21/* VARARGS */
22int error();
23char *index(), *rindex(), *malloc(), *getpass(), *sprintf(), *strcpy();
24
25struct passwd *getpwuid();
26
27int errno;
28int options;
29int rfd2;
30int sendsig();
31
32main(argc, argv0)
33 int argc;
34 char **argv0;
35{
36 int rem, pid;
37 char *host, *cp, **ap, buf[BUFSIZ], *args, **argv = argv0, *user = 0;
38 register int cc;
39 int asrsh = 0;
40 struct passwd *pwd;
41 int readfrom, ready;
42 int one = 1;
e1e93bd3 43 struct servent *sp;
4a31bc6f
BJ
44
45 host = rindex(argv[0], '/');
46 if (host)
47 host++;
48 else
49 host = argv[0];
50 argv++, --argc;
51 if (!strcmp(host, "rsh")) {
52 host = *argv++, --argc;
53 asrsh = 1;
54 }
55another:
4659bf8e 56 if (argc > 0 && !strcmp(*argv, "-l")) {
4a31bc6f
BJ
57 argv++, argc--;
58 if (argc > 0)
59 user = *argv++, argc--;
60 goto another;
61 }
4659bf8e 62 if (argc > 0 && !strcmp(*argv, "-n")) {
4a31bc6f
BJ
63 argv++, argc--;
64 (void) close(0);
65 (void) open("/dev/null", 0);
66 goto another;
67 }
4659bf8e 68 if (argc > 0 && !strcmp(*argv, "-d")) {
4a31bc6f
BJ
69 argv++, argc--;
70 options |= SO_DEBUG;
71 goto another;
72 }
0f09f657
CL
73 /*
74 * Ignore the -e flag to allow aliases with rlogin
75 * to work
76 */
4659bf8e 77 if (argc > 0 && !strncmp(*argv, "-e", 2)) {
0f09f657
CL
78 argv++, argc--;
79 goto another;
80 }
4a31bc6f
BJ
81 if (host == 0)
82 goto usage;
83 if (argv[0] == 0) {
84 if (asrsh)
85 *argv0 = "rlogin";
86 execv("/usr/ucb/rlogin", argv0);
87 perror("/usr/ucb/rlogin");
88 exit(1);
89 }
90 pwd = getpwuid(getuid());
91 if (pwd == 0) {
92 fprintf(stderr, "who are you?\n");
93 exit(1);
94 }
95 cc = 0;
96 for (ap = argv; *ap; ap++)
97 cc += strlen(*ap) + 1;
98 cp = args = malloc(cc);
99 for (ap = argv; *ap; ap++) {
100 (void) strcpy(cp, *ap);
101 while (*cp)
102 cp++;
103 if (ap[1])
104 *cp++ = ' ';
105 }
e1e93bd3
SL
106 sp = getservbyname("shell", "tcp");
107 if (sp == 0) {
108 fprintf(stderr, "rsh: shell/tcp: unknown service\n");
109 exit(1);
110 }
111 rem = rcmd(&host, sp->s_port, pwd->pw_name,
4a31bc6f
BJ
112 user ? user : pwd->pw_name, args, &rfd2);
113 if (rem < 0)
114 exit(1);
30b254da
SL
115 if (rfd2 < 0) {
116 fprintf(stderr, "rsh: can't establish stderr\n");
117 exit(2);
118 }
119 if (options & SO_DEBUG) {
120 if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
121 perror("setsockopt (stdin)");
122 if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
123 perror("setsockopt (stderr)");
124 }
4a31bc6f
BJ
125 (void) setuid(getuid());
126 sigacts(SIG_HOLD);
127 pid = fork();
128 if (pid < 0) {
129 perror("fork");
130 exit(1);
131 }
132 ioctl(rfd2, FIONBIO, &one);
133 ioctl(rem, FIONBIO, &one);
134 if (pid == 0) {
135 char *bp; int rembits, wc;
136 (void) close(rfd2);
137 reread:
420d8a52 138 errno = 0;
4a31bc6f
BJ
139 cc = read(0, buf, sizeof buf);
140 if (cc <= 0)
141 goto done;
142 bp = buf;
143 rewrite:
144 rembits = 1<<rem;
e7d6d17a
SL
145 if (select(16, 0, &rembits, 0, 0) < 0) {
146 if (errno != EINTR) {
147 perror("select");
148 exit(1);
149 }
150 goto rewrite;
151 }
4a31bc6f
BJ
152 if ((rembits & (1<<rem)) == 0)
153 goto rewrite;
154 wc = write(rem, bp, cc);
155 if (wc < 0) {
156 if (errno == EWOULDBLOCK)
157 goto rewrite;
158 goto done;
159 }
160 cc -= wc; bp += wc;
161 if (cc == 0)
162 goto reread;
163 goto rewrite;
164 done:
420d8a52 165 (void) shutdown(rem, 1);
4a31bc6f
BJ
166 exit(0);
167 }
168 sigacts(sendsig);
169 readfrom = (1<<rfd2) | (1<<rem);
170 do {
171 ready = readfrom;
e7d6d17a
SL
172 if (select(16, &ready, 0, 0, 0) < 0) {
173 if (errno != EINTR) {
174 perror("select");
175 exit(1);
176 }
177 continue;
178 }
4a31bc6f
BJ
179 if (ready & (1<<rfd2)) {
180 errno = 0;
181 cc = read(rfd2, buf, sizeof buf);
182 if (cc <= 0) {
183 if (errno != EWOULDBLOCK)
184 readfrom &= ~(1<<rfd2);
185 } else
186 (void) write(2, buf, cc);
187 }
188 if (ready & (1<<rem)) {
189 errno = 0;
190 cc = read(rem, buf, sizeof buf);
191 if (cc <= 0) {
192 if (errno != EWOULDBLOCK)
193 readfrom &= ~(1<<rem);
194 } else
195 (void) write(1, buf, cc);
196 }
197 } while (readfrom);
198 (void) kill(pid, SIGKILL);
199 exit(0);
200usage:
201 fprintf(stderr,
202 "usage: rsh host [ -l login ] [ -p passwd ] command\n");
203 exit(1);
204}
205
206sigacts(state)
207 int (*state)();
208{
209
210 sigset(SIGINT, state);
211 sigset(SIGQUIT, state);
212 sigset(SIGTERM, state);
213}
214
215sendsig(signo)
216 int signo;
217{
218
219 (void) write(rfd2, (char *)&signo, 1);
220}