xref: /csrg-svn/lib/libc/net/rcmd.c (revision 10594)
1 #ifndef lint
2 static char sccsid[] = "@(#)rcmd.c	4.6 01/22/83";
3 #endif
4 
5 #include <stdio.h>
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 
9 #include <netinet/in.h>
10 
11 #include <netdb.h>
12 #include <errno.h>
13 
14 extern	errno;
15 char	*index(), *sprintf();
16 
17 rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
18 	char **ahost;
19 	int rport;
20 	char *locuser, *remuser, *cmd;
21 	int *fd2p;
22 {
23 	int s, timo = 1;
24 	struct sockaddr_in sin, sin2, from;
25 	char c;
26 	int lport = IPPORT_RESERVED - 1;
27 	struct hostent *hp;
28 
29 	hp = gethostbyname(*ahost);
30 	if (hp == 0) {
31 		fprintf(stderr, "%s: unknown host\n", *ahost);
32 		return (-1);
33 	}
34 	*ahost = hp->h_name;
35 retry:
36 	s = rresvport(&lport);
37 	if (s < 0)
38 		return (-1);
39 	sin.sin_family = hp->h_addrtype;
40 	bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
41 	sin.sin_port = rport;
42 	if (connect(s, (caddr_t)&sin, sizeof (sin), 0) < 0) {
43 		if (errno == EADDRINUSE) {
44 			close(s);
45 			lport--;
46 			goto retry;
47 		}
48 		if (errno == ECONNREFUSED && timo <= 16) {
49 			(void) close(s);
50 			sleep(timo);
51 			timo *= 2;
52 			goto retry;
53 		}
54 		perror(hp->h_name);
55 		return (-1);
56 	}
57 	lport--;
58 	if (fd2p == 0) {
59 		write(s, "", 1);
60 		lport = 0;
61 	} else {
62 		char num[8];
63 		int s2 = rresvport(&lport), s3;
64 
65 		if (s2 < 0) {
66 			(void) close(s);
67 			return (-1);
68 		}
69 		listen(s2, 1);
70 		(void) sprintf(num, "%d", lport);
71 		if (write(s, num, strlen(num)+1) != strlen(num)+1) {
72 			perror("write: setting up stderr");
73 			(void) close(s2);
74 			goto bad;
75 		}
76 		{ int len = sizeof (from);
77 		  s3 = accept(s2, &from, &len, 0);
78 		  close(s2);
79 		  if (s3 < 0) {
80 			perror("accept");
81 			lport = 0;
82 			goto bad;
83 		  }
84 		}
85 		*fd2p = s3;
86 		from.sin_port = ntohs((u_short)from.sin_port);
87 		if (from.sin_family != AF_INET ||
88 		    from.sin_port >= IPPORT_RESERVED) {
89 			fprintf(stderr,
90 			    "socket: protocol failure in circuit setup.\n");
91 			goto bad2;
92 		}
93 	}
94 	(void) write(s, locuser, strlen(locuser)+1);
95 	(void) write(s, remuser, strlen(remuser)+1);
96 	(void) write(s, cmd, strlen(cmd)+1);
97 	if (read(s, &c, 1) != 1) {
98 		perror(*ahost);
99 		goto bad2;
100 	}
101 	if (c != 0) {
102 		while (read(s, &c, 1) == 1) {
103 			(void) write(2, &c, 1);
104 			if (c == '\n')
105 				break;
106 		}
107 		goto bad2;
108 	}
109 	return (s);
110 bad2:
111 	if (lport)
112 		(void) close(*fd2p);
113 bad:
114 	(void) close(s);
115 	return (-1);
116 }
117 
118 rresvport(alport)
119 	int *alport;
120 {
121 	struct sockaddr_in sin;
122 	int s;
123 
124 	sin.sin_family = AF_INET;
125 	sin.sin_addr.s_addr = 0;
126 	s = socket(AF_INET, SOCK_STREAM, 0, 0);
127 	if (s < 0)
128 		return (-1);
129 	for (;;) {
130 		sin.sin_port = htons((u_short)*alport);
131 		if (bind(s, (caddr_t)&sin, sizeof (sin), 0) >= 0)
132 			return (s);
133 		if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) {
134 			perror("socket");
135 			return (-1);
136 		}
137 		(*alport)--;
138 		if (*alport == IPPORT_RESERVED/2) {
139 			fprintf(stderr, "socket: All ports in use\n");
140 			return (-1);
141 		}
142 	}
143 }
144 
145 ruserok(rhost, ruser, luser)
146 	char *rhost, *ruser, *luser;
147 {
148 	FILE *hostf;
149 	char ahost[32];
150 	int first = 1;
151 
152 	hostf = fopen("/etc/hosts.equiv", "r");
153 again:
154 	if (hostf) {
155 		while (fgets(ahost, sizeof (ahost), hostf)) {
156 			char *user;
157 			if (index(ahost, '\n'))
158 				*index(ahost, '\n') = 0;
159 			user = index(ahost, ' ');
160 			if (user)
161 				*user++ = 0;
162 			if (!strcmp(rhost, ahost) &&
163 			    !strcmp(ruser, user ? user : luser))
164 				goto ok;
165 		}
166 		(void) fclose(hostf);
167 	}
168 	if (first == 1) {
169 		first = 0;
170 		hostf = fopen(".rhosts", "r");
171 		goto again;
172 	}
173 	return (-1);
174 ok:
175 	(void) fclose(hostf);
176 	return (0);
177 }
178 
179 socketaddr(x, y)
180 {
181 
182 	syscall(103,x,y);
183 }
184