date and time created 82/04/02 10:29:03 by wnj
[unix-history] / usr / src / usr.bin / rsh / rsh.c
CommitLineData
4a31bc6f
BJ
1#ifndef lint
2static char sccsid[] = "@(#)rsh.c 4.1 82/04/02";
3#endif
4
5#include <stdio.h>
6#include <sys/types.h>
7#include <sys/socket.h>
8#include <net/in.h>
9#include <sys/file.h>
10#include <errno.h>
11#include <signal.h>
12#include <sys/ioctl.h>
13#include <pwd.h>
14
15/*
16 * rsh - remote shell
17 */
18/* VARARGS */
19int error();
20char *index(), *rindex(), *malloc(), *getpass(), *sprintf(), *strcpy();
21
22struct passwd *getpwuid();
23
24int errno;
25int options;
26int rfd2;
27int sendsig();
28
29main(argc, argv0)
30 int argc;
31 char **argv0;
32{
33 int rem, pid;
34 char *host, *cp, **ap, buf[BUFSIZ], *args, **argv = argv0, *user = 0;
35 register int cc;
36 int asrsh = 0;
37 struct passwd *pwd;
38 int readfrom, ready;
39 int one = 1;
40
41 host = rindex(argv[0], '/');
42 if (host)
43 host++;
44 else
45 host = argv[0];
46 argv++, --argc;
47 if (!strcmp(host, "rsh")) {
48 host = *argv++, --argc;
49 asrsh = 1;
50 }
51another:
52 if (!strcmp(*argv, "-l")) {
53 argv++, argc--;
54 if (argc > 0)
55 user = *argv++, argc--;
56 goto another;
57 }
58 if (!strcmp(*argv, "-n")) {
59 argv++, argc--;
60 (void) close(0);
61 (void) open("/dev/null", 0);
62 goto another;
63 }
64 if (!strcmp(*argv, "-d")) {
65 argv++, argc--;
66 options |= SO_DEBUG;
67 goto another;
68 }
69 if (host == 0)
70 goto usage;
71 if (argv[0] == 0) {
72 if (asrsh)
73 *argv0 = "rlogin";
74 execv("/usr/ucb/rlogin", argv0);
75 perror("/usr/ucb/rlogin");
76 exit(1);
77 }
78 pwd = getpwuid(getuid());
79 if (pwd == 0) {
80 fprintf(stderr, "who are you?\n");
81 exit(1);
82 }
83 cc = 0;
84 for (ap = argv; *ap; ap++)
85 cc += strlen(*ap) + 1;
86 cp = args = malloc(cc);
87 for (ap = argv; *ap; ap++) {
88 (void) strcpy(cp, *ap);
89 while (*cp)
90 cp++;
91 if (ap[1])
92 *cp++ = ' ';
93 }
94 rem = rcmd(&host, IPPORT_CMDSERVER, pwd->pw_name,
95 user ? user : pwd->pw_name, args, &rfd2);
96 if (rem < 0)
97 exit(1);
98 (void) setuid(getuid());
99 sigacts(SIG_HOLD);
100 pid = fork();
101 if (pid < 0) {
102 perror("fork");
103 exit(1);
104 }
105 ioctl(rfd2, FIONBIO, &one);
106 ioctl(rem, FIONBIO, &one);
107 if (pid == 0) {
108 char *bp; int rembits, wc;
109 (void) close(rfd2);
110 reread:
111 cc = read(0, buf, sizeof buf);
112 if (cc <= 0)
113 goto done;
114 bp = buf;
115 rewrite:
116 rembits = 1<<rem;
117 (void) select(20, 0, &rembits, 100000);
118 if ((rembits & (1<<rem)) == 0)
119 goto rewrite;
120 wc = write(rem, bp, cc);
121 if (wc < 0) {
122 if (errno == EWOULDBLOCK)
123 goto rewrite;
124 goto done;
125 }
126 cc -= wc; bp += wc;
127 if (cc == 0)
128 goto reread;
129 goto rewrite;
130 done:
131 { int flags = 1; ioctl(rem, SIOCDONE, &flags); }
132 exit(0);
133 }
134 sigacts(sendsig);
135 readfrom = (1<<rfd2) | (1<<rem);
136 do {
137 ready = readfrom;
138 (void) select(32, &ready, 0, 10000000);
139 if (ready & (1<<rfd2)) {
140 errno = 0;
141 cc = read(rfd2, buf, sizeof buf);
142 if (cc <= 0) {
143 if (errno != EWOULDBLOCK)
144 readfrom &= ~(1<<rfd2);
145 } else
146 (void) write(2, buf, cc);
147 }
148 if (ready & (1<<rem)) {
149 errno = 0;
150 cc = read(rem, buf, sizeof buf);
151 if (cc <= 0) {
152 if (errno != EWOULDBLOCK)
153 readfrom &= ~(1<<rem);
154 } else
155 (void) write(1, buf, cc);
156 }
157 } while (readfrom);
158 (void) kill(pid, SIGKILL);
159 exit(0);
160usage:
161 fprintf(stderr,
162 "usage: rsh host [ -l login ] [ -p passwd ] command\n");
163 exit(1);
164}
165
166sigacts(state)
167 int (*state)();
168{
169
170 sigset(SIGINT, state);
171 sigset(SIGQUIT, state);
172 sigset(SIGTERM, state);
173}
174
175sendsig(signo)
176 int signo;
177{
178
179 (void) write(rfd2, (char *)&signo, 1);
180}