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