rewrite a bit to be more lucid
[unix-history] / usr / src / lib / libc / net / rcmd.c
CommitLineData
f0bb4ca8
BJ
1#ifndef lint
2static char sccsid[] = "@(#)rcmd.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 <errno.h>
10
11extern errno;
12char *index(), *sprintf();
13int rcmdoptions;
14
15rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
16 char **ahost;
17 int rport;
18 char *locuser, *remuser, *cmd;
19 int *fd2p;
20{
21 int s, addr, timo = 1;
22 struct sockaddr_in sin, sin2, from;
23 char c;
24 short port;
25
26 addr = rhost(ahost);
27 if (addr == -1) {
28 fprintf(stderr, "%s: unknown host\n", *ahost);
29 return (-1);
30 }
31retry:
32 s = rresvport(rcmdoptions|SO_KEEPALIVE);
33 if (s < 0)
34 return (-1);
35 sin.sin_family = AF_INET;
36 sin.sin_addr.s_addr = addr;
37 sin.sin_port = rport;
38#ifdef vax
39 sin.sin_port = htons(sin.sin_port);
40#endif
41 if (connect(s, &sin) < 0) {
42 if (errno == ECONNREFUSED && timo <= 16) {
43 (void) close(s);
44 sleep(timo);
45 timo *= 2;
46 goto retry;
47 }
48 perror(*ahost);
49 return (-1);
50 }
51 if (fd2p == 0) {
52 write(s, "", 1);
53 port = 0;
54 } else {
55 char num[8];
56 int s2 = rresvport(rcmdoptions|SO_ACCEPTCONN);
57
58 if (s2 < 0) {
59 (void) close(s);
60 return (-1);
61 }
62 socketaddr(s2, &sin2);
63 port = sin2.sin_port;
64#if vax
65 port = htons((u_short)port);
66#endif
67 (void) sprintf(num, "%d", port);
68 (void) write(s, num, strlen(num)+1);
69 if (accept(s2, &from) < 0) {
70 perror("accept");
71 goto bad;
72 }
73#if vax
74 from.sin_port = ntohs(from.sin_port);
75#endif
76 if (from.sin_family != AF_INET ||
77 from.sin_port >= IPPORT_RESERVED) {
78 fprintf(stderr,
79 "socket: protocol failure in circuit setup.\n");
80 goto bad;
81 }
82 *fd2p = s2;
83 }
84 (void) write(s, locuser, strlen(locuser)+1);
85 (void) write(s, remuser, strlen(remuser)+1);
86 (void) write(s, cmd, strlen(cmd)+1);
87 if (read(s, &c, 1) != 1) {
88 perror(*ahost);
89 goto bad;
90 }
91 if (c != 0) {
92 while (read(s, &c, 1) == 1) {
93 (void) write(2, &c, 1);
94 if (c == '\n')
95 break;
96 }
97 goto bad;
98 }
99 return (s);
100bad:
101 if (port)
102 (void) close(*fd2p);
103 (void) close(s);
104 return (-1);
105}
106
107rresvport(options)
108 int options;
109{
110 struct sockaddr_in sin;
111 short lport = IPPORT_RESERVED - 1;
112 int s;
113
114 for (;;) {
115 sin.sin_family = AF_INET;
116 sin.sin_port = lport;
117 sin.sin_addr.s_addr = 0;
118#ifdef vax
119 sin.sin_port = htons(sin.sin_port);
120#endif
121 s = socket(SOCK_STREAM, 0, &sin, options);
122 if (s >= 0)
123 return (s);
124 if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) {
125 perror("socket");
126 return (-1);
127 }
128 lport--;
129 if (lport == IPPORT_RESERVED/2) {
130 fprintf(stderr, "socket: All ports in use\n");
131 return (-1);
132 }
133 }
134}
135
136ruserok(rhost, ruser, luser)
137 char *rhost, *ruser, *luser;
138{
139 FILE *hostf;
140 char ahost[32];
141 int first = 1;
142
143 hostf = fopen("/etc/hosts.equiv", "r");
144again:
145 if (hostf) {
146 while (fgets(ahost, sizeof (ahost), hostf)) {
147 char *user;
148 if (index(ahost, '\n'))
149 *index(ahost, '\n') = 0;
150 user = index(ahost, ' ');
151 if (user)
152 *user++ = 0;
153 if (!strcmp(rhost, ahost) &&
154 !strcmp(ruser, user ? user : luser))
155 goto ok;
156 }
157 (void) fclose(hostf);
158 }
159 if (first == 1) {
160 first = 0;
161 hostf = fopen(".rhosts", "r");
162 goto again;
163 }
164 return (-1);
165ok:
166 (void) fclose(hostf);
167 return (0);
168}