Add copyright
[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
586c39b1
DF
8static char sccsid[] = "@(#)rcmd.c 5.1 (Berkeley) %G%";
9#endif not lint
f0bb4ca8
BJ
10
11#include <stdio.h>
12#include <sys/types.h>
13#include <sys/socket.h>
40d6b022
SL
14
15#include <netinet/in.h>
16
3f5b52bc 17#include <netdb.h>
40d6b022 18#include <errno.h>
f0bb4ca8
BJ
19
20extern errno;
21char *index(), *sprintf();
f0bb4ca8
BJ
22
23rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
24 char **ahost;
25 int rport;
26 char *locuser, *remuser, *cmd;
27 int *fd2p;
28{
40d6b022 29 int s, timo = 1;
f0bb4ca8
BJ
30 struct sockaddr_in sin, sin2, from;
31 char c;
40d6b022 32 int lport = IPPORT_RESERVED - 1;
3f5b52bc 33 struct hostent *hp;
f0bb4ca8 34
3f5b52bc
SL
35 hp = gethostbyname(*ahost);
36 if (hp == 0) {
f0bb4ca8
BJ
37 fprintf(stderr, "%s: unknown host\n", *ahost);
38 return (-1);
39 }
3f5b52bc 40 *ahost = hp->h_name;
f0bb4ca8 41retry:
c1dfbf19 42 s = rresvport(&lport);
f0bb4ca8
BJ
43 if (s < 0)
44 return (-1);
3f5b52bc 45 sin.sin_family = hp->h_addrtype;
40d6b022 46 bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
b567f18d 47 sin.sin_port = rport;
40d6b022 48 if (connect(s, (caddr_t)&sin, sizeof (sin), 0) < 0) {
ea19968f 49 (void) close(s);
40d6b022 50 if (errno == EADDRINUSE) {
40d6b022
SL
51 lport--;
52 goto retry;
53 }
f0bb4ca8 54 if (errno == ECONNREFUSED && timo <= 16) {
f0bb4ca8
BJ
55 sleep(timo);
56 timo *= 2;
57 goto retry;
58 }
40d6b022 59 perror(hp->h_name);
f0bb4ca8
BJ
60 return (-1);
61 }
40d6b022 62 lport--;
f0bb4ca8
BJ
63 if (fd2p == 0) {
64 write(s, "", 1);
c1dfbf19 65 lport = 0;
f0bb4ca8
BJ
66 } else {
67 char num[8];
c1dfbf19 68 int s2 = rresvport(&lport), s3;
ea19968f 69 int len = sizeof (from);
f0bb4ca8 70
ea19968f
RC
71 if (s2 < 0)
72 goto bad;
40d6b022 73 listen(s2, 1);
c1dfbf19 74 (void) sprintf(num, "%d", lport);
2c510808
SL
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 }
ea19968f
RC
80 s3 = accept(s2, &from, &len, 0);
81 (void) close(s2);
82 if (s3 < 0) {
f0bb4ca8 83 perror("accept");
c1dfbf19 84 lport = 0;
f0bb4ca8
BJ
85 goto bad;
86 }
40d6b022
SL
87 *fd2p = s3;
88 from.sin_port = ntohs((u_short)from.sin_port);
f0bb4ca8
BJ
89 if (from.sin_family != AF_INET ||
90 from.sin_port >= IPPORT_RESERVED) {
91 fprintf(stderr,
92 "socket: protocol failure in circuit setup.\n");
40d6b022 93 goto bad2;
f0bb4ca8 94 }
f0bb4ca8
BJ
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);
40d6b022 101 goto bad2;
f0bb4ca8
BJ
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 }
40d6b022 109 goto bad2;
f0bb4ca8
BJ
110 }
111 return (s);
40d6b022 112bad2:
c1dfbf19 113 if (lport)
f0bb4ca8 114 (void) close(*fd2p);
40d6b022 115bad:
f0bb4ca8
BJ
116 (void) close(s);
117 return (-1);
118}
119
c1dfbf19
SL
120rresvport(alport)
121 int *alport;
f0bb4ca8
BJ
122{
123 struct sockaddr_in sin;
f0bb4ca8
BJ
124 int s;
125
40d6b022
SL
126 sin.sin_family = AF_INET;
127 sin.sin_addr.s_addr = 0;
b567f18d 128 s = socket(AF_INET, SOCK_STREAM, 0, 0);
40d6b022
SL
129 if (s < 0)
130 return (-1);
f0bb4ca8 131 for (;;) {
40d6b022
SL
132 sin.sin_port = htons((u_short)*alport);
133 if (bind(s, (caddr_t)&sin, sizeof (sin), 0) >= 0)
f0bb4ca8
BJ
134 return (s);
135 if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) {
136 perror("socket");
ea19968f 137 (void) close(s);
f0bb4ca8
BJ
138 return (-1);
139 }
40d6b022
SL
140 (*alport)--;
141 if (*alport == IPPORT_RESERVED/2) {
f0bb4ca8 142 fprintf(stderr, "socket: All ports in use\n");
ea19968f 143 (void) close(s);
f0bb4ca8
BJ
144 return (-1);
145 }
146 }
147}
148
ff3164c8
SL
149ruserok(rhost, superuser, ruser, luser)
150 char *rhost;
151 int superuser;
152 char *ruser, *luser;
f0bb4ca8
BJ
153{
154 FILE *hostf;
155 char ahost[32];
156 int first = 1;
157
ff3164c8 158 hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r");
f0bb4ca8
BJ
159again:
160 if (hostf) {
161 while (fgets(ahost, sizeof (ahost), hostf)) {
7620d83a 162 register char *p;
f0bb4ca8 163 char *user;
7620d83a
JB
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';
f0bb4ca8 178 if (!strcmp(rhost, ahost) &&
7620d83a 179 !strcmp(ruser, *user ? user : luser)) {
ff3164c8
SL
180 (void) fclose(hostf);
181 return (0);
182 }
f0bb4ca8
BJ
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);
f0bb4ca8 192}