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