xref: /csrg-svn/lib/libc/net/rcmd.c (revision 21372)
1 #ifndef lint
2 static char sccsid[] = "@(#)rcmd.c	4.10 05/30/85";
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 		(void) close(s);
44 		if (errno == EADDRINUSE) {
45 			lport--;
46 			goto retry;
47 		}
48 		if (errno == ECONNREFUSED && timo <= 16) {
49 			sleep(timo);
50 			timo *= 2;
51 			goto retry;
52 		}
53 		perror(hp->h_name);
54 		return (-1);
55 	}
56 	lport--;
57 	if (fd2p == 0) {
58 		write(s, "", 1);
59 		lport = 0;
60 	} else {
61 		char num[8];
62 		int s2 = rresvport(&lport), s3;
63 		int len = sizeof (from);
64 
65 		if (s2 < 0)
66 			goto bad;
67 		listen(s2, 1);
68 		(void) sprintf(num, "%d", lport);
69 		if (write(s, num, strlen(num)+1) != strlen(num)+1) {
70 			perror("write: setting up stderr");
71 			(void) close(s2);
72 			goto bad;
73 		}
74 		s3 = accept(s2, &from, &len, 0);
75 		(void) close(s2);
76 		if (s3 < 0) {
77 			perror("accept");
78 			lport = 0;
79 			goto bad;
80 		}
81 		*fd2p = s3;
82 		from.sin_port = ntohs((u_short)from.sin_port);
83 		if (from.sin_family != AF_INET ||
84 		    from.sin_port >= IPPORT_RESERVED) {
85 			fprintf(stderr,
86 			    "socket: protocol failure in circuit setup.\n");
87 			goto bad2;
88 		}
89 	}
90 	(void) write(s, locuser, strlen(locuser)+1);
91 	(void) write(s, remuser, strlen(remuser)+1);
92 	(void) write(s, cmd, strlen(cmd)+1);
93 	if (read(s, &c, 1) != 1) {
94 		perror(*ahost);
95 		goto bad2;
96 	}
97 	if (c != 0) {
98 		while (read(s, &c, 1) == 1) {
99 			(void) write(2, &c, 1);
100 			if (c == '\n')
101 				break;
102 		}
103 		goto bad2;
104 	}
105 	return (s);
106 bad2:
107 	if (lport)
108 		(void) close(*fd2p);
109 bad:
110 	(void) close(s);
111 	return (-1);
112 }
113 
114 rresvport(alport)
115 	int *alport;
116 {
117 	struct sockaddr_in sin;
118 	int s;
119 
120 	sin.sin_family = AF_INET;
121 	sin.sin_addr.s_addr = 0;
122 	s = socket(AF_INET, SOCK_STREAM, 0, 0);
123 	if (s < 0)
124 		return (-1);
125 	for (;;) {
126 		sin.sin_port = htons((u_short)*alport);
127 		if (bind(s, (caddr_t)&sin, sizeof (sin), 0) >= 0)
128 			return (s);
129 		if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) {
130 			perror("socket");
131 			(void) close(s);
132 			return (-1);
133 		}
134 		(*alport)--;
135 		if (*alport == IPPORT_RESERVED/2) {
136 			fprintf(stderr, "socket: All ports in use\n");
137 			(void) close(s);
138 			return (-1);
139 		}
140 	}
141 }
142 
143 ruserok(rhost, superuser, ruser, luser)
144 	char *rhost;
145 	int superuser;
146 	char *ruser, *luser;
147 {
148 	FILE *hostf;
149 	char ahost[32];
150 	int first = 1;
151 
152 	hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r");
153 again:
154 	if (hostf) {
155 		while (fgets(ahost, sizeof (ahost), hostf)) {
156 			register char *p;
157 			char *user;
158 
159 			p = ahost;
160 			while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
161 				p++;
162 			if (*p == ' ' || *p == '\t') {
163 				*p++ = '\0';
164 				while (*p == ' ' || *p == '\t')
165 					p++;
166 				user = p;
167 				while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
168 					p++;
169 			} else
170 				user = p;
171 			*p = '\0';
172 			if (!strcmp(rhost, ahost) &&
173 			    !strcmp(ruser, *user ? user : luser)) {
174 				(void) fclose(hostf);
175 				return (0);
176 			}
177 		}
178 		(void) fclose(hostf);
179 	}
180 	if (first == 1) {
181 		first = 0;
182 		hostf = fopen(".rhosts", "r");
183 		goto again;
184 	}
185 	return (-1);
186 }
187