|
|
1.1 root 1: /* client.c - connect to a server */
2:
3: #ifdef BSD42
4: #include "../h/strings.h"
5: #include <stdio.h>
6: #include "mts.h"
7: #include <errno.h>
8: #include <sys/types.h>
9: #include <sys/socket.h>
10: #include <netinet/in.h>
11: #include <netdb.h>
12: #include <arpa/inet.h>
13:
14:
15: #define NOTOK (-1)
16: #define OK 0
17: #define DONE 1
18:
19: #define TRUE 1
20: #define FALSE 0
21:
22: #define OOPS1 (-2)
23: #define OOPS2 (-3)
24:
25: #define MAXARGS 1000
26: #define MAXNETS 5
27: #define MAXHOSTS 25
28:
29: /* */
30:
31: extern int errno;
32: extern int sys_nerr;
33: extern char *sys_errlist[];
34:
35:
36: struct addrent {
37: int a_addrtype; /* assumes AF_INET for inet_netof () */
38:
39: union {
40: int un_net;
41: char un_addr[14];
42: } un;
43: #define a_net un.un_net
44: #define a_addr un.un_addr
45: };
46:
47: static struct addrent *ne, *nz;
48: static struct addrent nets[MAXNETS];
49:
50: static struct addrent *he, *hz;
51: static struct addrent hosts[MAXHOSTS];
52:
53:
54: char *getcpy (), **brkstring (), **copyip ();
55:
56: /* */
57:
58: int client (args, protocol, service, rproto, response)
59: char *args,
60: *protocol,
61: *service,
62: *response;
63: int rproto;
64: {
65: int sd;
66: register char **ap;
67: char *arguments[MAXARGS];
68: register struct hostent *hp;
69: #ifndef BIND
70: register struct netent *np;
71: #endif BIND
72: register struct servent *sp;
73:
74: if ((sp = getservbyname (service, protocol)) == NULL) {
75: (void) sprintf (response, "%s/%s: unknown service", protocol, service);
76: return NOTOK;
77: }
78:
79: ap = arguments;
80: if (args != NULL && *args != NULL)
81: ap = copyip (brkstring (getcpy (args), " ", "\n"), ap);
82: else
83: if (servers != NULL && *servers != NULL)
84: ap = copyip (brkstring (getcpy (servers), " ", "\n"), ap);
85: if (ap == arguments) {
86: *ap++ = getcpy ("localhost");
87: *ap = NULL;
88: }
89:
90: nz = (ne = nets) + sizeof nets / sizeof nets[0];
91: hz = (he = hosts) + sizeof hosts / sizeof hosts[0];
92:
93: for (ap = arguments; *ap; ap++) {
94: if (**ap == '\01') {
95: #ifndef BIND
96: if (np = getnetbyname (*ap + 1)) {
97: sethostent (1);
98: while (hp = gethostent ())
99: if (np -> n_addrtype == hp -> h_addrtype
100: && inet (hp, np -> n_net)) {
101: switch (sd = rcaux (sp, hp, rproto, response)) {
102: case NOTOK:
103: continue;
104: case OOPS1:
105: break;
106: case OOPS2:
107: return NOTOK;
108:
109: default:
110: return sd;
111: }
112: break;
113: }
114: }
115: #endif not BIND
116: continue;
117: }
118:
119: if (hp = gethostbyname (*ap)) {
120: switch (sd = rcaux (sp, hp, rproto, response)) {
121: case NOTOK:
122: case OOPS1:
123: break;
124: case OOPS2:
125: return NOTOK;
126:
127: default:
128: return sd;
129: }
130: continue;
131: }
132: }
133:
134: (void) strcpy (response, "no servers available");
135: return NOTOK;
136: }
137:
138: /* */
139:
140: static int rcaux (sp, hp, rproto, response)
141: register struct servent *sp;
142: register struct hostent *hp;
143: int rproto;
144: register char *response;
145: {
146: int sd;
147: struct in_addr in;
148: register struct addrent *ap;
149: struct sockaddr_in in_socket;
150: register struct sockaddr_in *isock = &in_socket;
151:
152: for (ap = nets; ap < ne; ap++)
153: if (ap -> a_addrtype == hp -> h_addrtype && inet (hp, ap -> a_net))
154: return NOTOK;
155:
156: for (ap = hosts; ap < he; ap++)
157: if (ap -> a_addrtype == hp -> h_addrtype
158: && bcmp (ap -> a_addr, hp -> h_addr, hp -> h_length) == 0)
159: return NOTOK;
160:
161: if ((sd = getport (rproto, hp -> h_addrtype, response)) == NOTOK)
162: return OOPS2;
163:
164: bzero ((char *) isock, sizeof *isock);
165: isock -> sin_family = hp -> h_addrtype;
166: isock -> sin_port = sp -> s_port;
167: bcopy (hp -> h_addr, (char *) &isock -> sin_addr, hp -> h_length);
168:
169: if (connect (sd, (struct sockaddr *) isock, sizeof *isock) == NOTOK)
170: switch (errno) {
171: case ENETDOWN:
172: case ENETUNREACH:
173: (void) close (sd);
174: if (ne < nz) {
175: ne -> a_addrtype = hp -> h_addrtype;
176: bcopy (hp -> h_addr, (char *) &in, sizeof in);
177: ne -> a_net = inet_netof (in);
178: ne++;
179: }
180: return OOPS1;
181:
182: case ETIMEDOUT:
183: case ECONNREFUSED:
184: default:
185: (void) close (sd);
186: if (he < hz) {
187: he -> a_addrtype = hp -> h_addrtype;
188: bcopy (hp -> h_addr, he -> a_addr, hp -> h_length);
189: he++;
190: }
191: return NOTOK;
192: }
193:
194: return sd;
195: }
196:
197: /* */
198:
199: static int getport (rproto, addrtype, response)
200: int rproto,
201: addrtype;
202: register char *response;
203: {
204: int sd,
205: port;
206: struct sockaddr_in in_socket,
207: *isock = &in_socket;
208:
209: if (rproto && addrtype != AF_INET) {
210: (void) sprintf (response, "reserved ports not supported for af=%d",
211: addrtype);
212: errno = ENOPROTOOPT;
213: return NOTOK;
214: }
215:
216: if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK) {
217: (void) sprintf (response, "unable to create socket: %s",
218: errno > 0 && errno < sys_nerr ? sys_errlist[errno]
219: : "unknown error");
220: return NOTOK;
221: }
222: if (!rproto)
223: return sd;
224:
225: bzero ((char *) isock, sizeof *isock);
226: isock -> sin_family = addrtype;
227: for (port = IPPORT_RESERVED - 1;;) {
228: isock -> sin_port = htons ((u_short) port);
229: if (bind (sd, (struct sockaddr *) isock, sizeof *isock) != NOTOK)
230: return sd;
231:
232: switch (errno) {
233: case EADDRINUSE:
234: case EADDRNOTAVAIL:
235: if (--port <= IPPORT_RESERVED / 2) {
236: (void) strcpy (response, "ports available");
237: return NOTOK;
238: }
239: break;
240:
241: default:
242: (void) sprintf (response, "unable to bind socket: %s",
243: errno > 0 && errno < sys_nerr ? sys_errlist[errno]
244: : "unknown error");
245: return NOTOK;
246: }
247: }
248: }
249:
250: /* */
251:
252: static int inet (hp, net)
253: register struct hostent *hp;
254: int net;
255: {
256: struct in_addr in;
257:
258: bcopy (hp -> h_addr, (char *) &in, sizeof in);
259: return (inet_netof (in) == net);
260: }
261:
262: /* */
263:
264: /* static copies of three MH subroutines... (sigh) */
265:
266: char *malloc ();
267:
268:
269: static char *broken[MAXARGS + 1];
270:
271:
272: static char **brkstring (strg, brksep, brkterm)
273: register char *strg;
274: register char *brksep,
275: *brkterm;
276: {
277: register int bi;
278: register char c,
279: *sp;
280:
281: sp = strg;
282:
283: for (bi = 0; bi < MAXARGS; bi++) {
284: while (brkany (c = *sp, brksep))
285: *sp++ = 0;
286: if (!c || brkany (c, brkterm)) {
287: *sp = 0;
288: broken[bi] = 0;
289: return broken;
290: }
291:
292: broken[bi] = sp;
293: while ((c = *++sp) && !brkany (c, brksep) && !brkany (c, brkterm))
294: continue;
295: }
296: broken[MAXARGS] = 0;
297:
298: return broken;
299: }
300:
301:
302: static brkany (chr, strg)
303: register char chr,
304: *strg;
305: {
306: register char *sp;
307:
308: if (strg)
309: for (sp = strg; *sp; sp++)
310: if (chr == *sp)
311: return 1;
312: return 0;
313: }
314:
315:
316: static char **copyip (p, q)
317: register char **p,
318: **q;
319: {
320: while (*p)
321: *q++ = *p++;
322: *q = 0;
323:
324: return q;
325: }
326:
327:
328: static char *getcpy (str)
329: register char *str;
330: {
331: register char *cp;
332:
333: if ((cp = malloc ((unsigned) (strlen (str) + 1))) == NULL)
334: return NULL;
335:
336: (void) strcpy (cp, str);
337: return cp;
338: }
339: #endif BSD42
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.