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