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