fix problem with hostname returning name w/o a domain
[unix-history] / usr / src / lib / libc / net / rcmd.c
CommitLineData
586c39b1
DF
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
f0bb4ca8 7#ifndef lint
49528010 8static char sccsid[] = "@(#)rcmd.c 5.4 (Berkeley) %G%";
586c39b1 9#endif not lint
f0bb4ca8
BJ
10
11#include <stdio.h>
20ac274b
JB
12#include <ctype.h>
13#include <sys/param.h>
f0bb4ca8 14#include <sys/socket.h>
40d6b022
SL
15
16#include <netinet/in.h>
17
3f5b52bc 18#include <netdb.h>
40d6b022 19#include <errno.h>
f0bb4ca8
BJ
20
21extern errno;
22char *index(), *sprintf();
f0bb4ca8
BJ
23
24rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
25 char **ahost;
26 int rport;
27 char *locuser, *remuser, *cmd;
28 int *fd2p;
29{
40d6b022 30 int s, timo = 1;
f0bb4ca8
BJ
31 struct sockaddr_in sin, sin2, from;
32 char c;
40d6b022 33 int lport = IPPORT_RESERVED - 1;
3f5b52bc 34 struct hostent *hp;
f0bb4ca8 35
3f5b52bc
SL
36 hp = gethostbyname(*ahost);
37 if (hp == 0) {
f0bb4ca8
BJ
38 fprintf(stderr, "%s: unknown host\n", *ahost);
39 return (-1);
40 }
3f5b52bc 41 *ahost = hp->h_name;
f0bb4ca8 42retry:
c1dfbf19 43 s = rresvport(&lport);
f0bb4ca8
BJ
44 if (s < 0)
45 return (-1);
3f5b52bc 46 sin.sin_family = hp->h_addrtype;
40d6b022 47 bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
b567f18d 48 sin.sin_port = rport;
40d6b022 49 if (connect(s, (caddr_t)&sin, sizeof (sin), 0) < 0) {
ea19968f 50 (void) close(s);
40d6b022 51 if (errno == EADDRINUSE) {
40d6b022
SL
52 lport--;
53 goto retry;
54 }
f0bb4ca8 55 if (errno == ECONNREFUSED && timo <= 16) {
f0bb4ca8
BJ
56 sleep(timo);
57 timo *= 2;
58 goto retry;
59 }
40d6b022 60 perror(hp->h_name);
f0bb4ca8
BJ
61 return (-1);
62 }
40d6b022 63 lport--;
f0bb4ca8
BJ
64 if (fd2p == 0) {
65 write(s, "", 1);
c1dfbf19 66 lport = 0;
f0bb4ca8
BJ
67 } else {
68 char num[8];
c1dfbf19 69 int s2 = rresvport(&lport), s3;
ea19968f 70 int len = sizeof (from);
f0bb4ca8 71
ea19968f
RC
72 if (s2 < 0)
73 goto bad;
40d6b022 74 listen(s2, 1);
c1dfbf19 75 (void) sprintf(num, "%d", lport);
2c510808
SL
76 if (write(s, num, strlen(num)+1) != strlen(num)+1) {
77 perror("write: setting up stderr");
78 (void) close(s2);
79 goto bad;
80 }
ea19968f
RC
81 s3 = accept(s2, &from, &len, 0);
82 (void) close(s2);
83 if (s3 < 0) {
f0bb4ca8 84 perror("accept");
c1dfbf19 85 lport = 0;
f0bb4ca8
BJ
86 goto bad;
87 }
40d6b022
SL
88 *fd2p = s3;
89 from.sin_port = ntohs((u_short)from.sin_port);
f0bb4ca8
BJ
90 if (from.sin_family != AF_INET ||
91 from.sin_port >= IPPORT_RESERVED) {
92 fprintf(stderr,
93 "socket: protocol failure in circuit setup.\n");
40d6b022 94 goto bad2;
f0bb4ca8 95 }
f0bb4ca8
BJ
96 }
97 (void) write(s, locuser, strlen(locuser)+1);
98 (void) write(s, remuser, strlen(remuser)+1);
99 (void) write(s, cmd, strlen(cmd)+1);
100 if (read(s, &c, 1) != 1) {
101 perror(*ahost);
40d6b022 102 goto bad2;
f0bb4ca8
BJ
103 }
104 if (c != 0) {
105 while (read(s, &c, 1) == 1) {
106 (void) write(2, &c, 1);
107 if (c == '\n')
108 break;
109 }
40d6b022 110 goto bad2;
f0bb4ca8
BJ
111 }
112 return (s);
40d6b022 113bad2:
c1dfbf19 114 if (lport)
f0bb4ca8 115 (void) close(*fd2p);
40d6b022 116bad:
f0bb4ca8
BJ
117 (void) close(s);
118 return (-1);
119}
120
c1dfbf19
SL
121rresvport(alport)
122 int *alport;
f0bb4ca8
BJ
123{
124 struct sockaddr_in sin;
f0bb4ca8
BJ
125 int s;
126
40d6b022 127 sin.sin_family = AF_INET;
9a89481f
MK
128 sin.sin_addr.s_addr = INADDR_ANY;
129 s = socket(AF_INET, SOCK_STREAM, 0);
40d6b022
SL
130 if (s < 0)
131 return (-1);
f0bb4ca8 132 for (;;) {
40d6b022
SL
133 sin.sin_port = htons((u_short)*alport);
134 if (bind(s, (caddr_t)&sin, sizeof (sin), 0) >= 0)
f0bb4ca8 135 return (s);
9a89481f
MK
136 if (errno == EADDRNOTAVAIL)
137 return (-1);
138 if (errno != EADDRINUSE) {
f0bb4ca8 139 perror("socket");
ea19968f 140 (void) close(s);
f0bb4ca8
BJ
141 return (-1);
142 }
40d6b022
SL
143 (*alport)--;
144 if (*alport == IPPORT_RESERVED/2) {
f0bb4ca8 145 fprintf(stderr, "socket: All ports in use\n");
ea19968f 146 (void) close(s);
f0bb4ca8
BJ
147 return (-1);
148 }
149 }
150}
151
ff3164c8
SL
152ruserok(rhost, superuser, ruser, luser)
153 char *rhost;
154 int superuser;
155 char *ruser, *luser;
f0bb4ca8
BJ
156{
157 FILE *hostf;
20ac274b
JB
158 char fhost[MAXHOSTNAMELEN];
159 char ahost[MAXHOSTNAMELEN];
f0bb4ca8 160 int first = 1;
20ac274b
JB
161 register char *sp, *p;
162 int baselen = -1;
f0bb4ca8 163
20ac274b
JB
164 sp = rhost;
165 p = fhost;
166 while (*sp) {
167 if (*sp == '.') {
168 if (baselen == -1)
169 baselen = sp - rhost;
170 *p++ = *sp++;
171 } else {
172 *p++ = isupper(*sp) ? tolower(*sp++) : *sp++;
173 }
174 }
175 *p = '\0';
ff3164c8 176 hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r");
f0bb4ca8
BJ
177again:
178 if (hostf) {
179 while (fgets(ahost, sizeof (ahost), hostf)) {
180 char *user;
7620d83a
JB
181
182 p = ahost;
183 while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
20ac274b 184 *p++ = isupper(*p) ? tolower(*p) : *p;
7620d83a
JB
185 if (*p == ' ' || *p == '\t') {
186 *p++ = '\0';
187 while (*p == ' ' || *p == '\t')
188 p++;
189 user = p;
190 while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
191 p++;
192 } else
193 user = p;
194 *p = '\0';
20ac274b 195 if (_checkhost(fhost, ahost, baselen) &&
7620d83a 196 !strcmp(ruser, *user ? user : luser)) {
ff3164c8
SL
197 (void) fclose(hostf);
198 return (0);
199 }
f0bb4ca8
BJ
200 }
201 (void) fclose(hostf);
202 }
203 if (first == 1) {
204 first = 0;
205 hostf = fopen(".rhosts", "r");
206 goto again;
207 }
208 return (-1);
f0bb4ca8 209}
20ac274b
JB
210
211_checkhost(rhost, lhost, len)
212char *rhost, *lhost;
213int len;
214{
215 static char ldomain[MAXHOSTNAMELEN];
216 static char *domainp = NULL;
217 register char *cp;
218
219 if (len == -1)
220 return(!strcmp(rhost, lhost));
221 if (strncmp(rhost, lhost, len))
222 return(0);
223 if (!strcmp(rhost, lhost))
224 return(1);
225 if (*(lhost + len) != '\0')
226 return(0);
227 if (!domainp) {
228 if (gethostname(ldomain, sizeof(ldomain)) == -1) {
229 domainp = (char *)1;
230 return(0);
231 }
232 ldomain[MAXHOSTNAMELEN] = NULL;
49528010
JB
233 if ((domainp = index(ldomain, '.') + 1) == (char *)1)
234 return(0);
20ac274b
JB
235 cp = domainp;
236 while (*cp)
237 *cp++ = isupper(*cp) ? tolower(*cp) : *cp;
238 }
239 if (domainp == (char *)1)
240 return(0);
241 return(!strcmp(domainp, rhost + len +1));
242}