Commit | Line | Data |
---|---|---|
48435ab0 WJ |
1 | /* dgram.c - datagram (CL-mode TS) abstractions */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/compat/RCS/dgram.c,v 7.11 91/02/22 09:15:07 mrose Interim $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/compat/RCS/dgram.c,v 7.11 91/02/22 09:15:07 mrose Interim $ | |
9 | * | |
10 | * | |
11 | * $Log: dgram.c,v $ | |
12 | * Revision 7.11 91/02/22 09:15:07 mrose | |
13 | * Interim 6.8 | |
14 | * | |
15 | * Revision 7.10 91/01/10 04:10:25 mrose | |
16 | * set_check_fd | |
17 | * | |
18 | * Revision 7.9 91/01/07 12:39:50 mrose | |
19 | * update | |
20 | * | |
21 | * Revision 7.8 90/12/17 22:17:21 mrose | |
22 | * marv | |
23 | * | |
24 | * Revision 7.7 90/07/09 14:31:43 mrose | |
25 | * sync | |
26 | * | |
27 | * Revision 7.6 90/04/23 00:08:08 mrose | |
28 | * touch-up | |
29 | * | |
30 | * Revision 7.5 90/01/11 18:35:03 mrose | |
31 | * real-sync | |
32 | * | |
33 | * Revision 7.4 89/12/19 17:57:34 mrose | |
34 | * touch-up | |
35 | * | |
36 | * Revision 7.3 89/12/19 15:15:31 mrose | |
37 | * dgram | |
38 | * | |
39 | * Revision 7.2 89/12/17 18:30:11 mrose | |
40 | * foo | |
41 | * | |
42 | * Revision 7.1 89/12/11 16:22:25 mrose | |
43 | * more dgram | |
44 | * | |
45 | * Revision 7.0 89/12/01 10:42:35 mrose | |
46 | * Release 6.0 | |
47 | * | |
48 | */ | |
49 | ||
50 | /* | |
51 | * NOTICE | |
52 | * | |
53 | * Acquisition, use, and distribution of this module and related | |
54 | * materials are subject to the restrictions of a license agreement. | |
55 | * Consult the Preface in the User's Manual for the full terms of | |
56 | * this agreement. | |
57 | * | |
58 | */ | |
59 | ||
60 | ||
61 | /* LINTLIBRARY */ | |
62 | ||
63 | #include <errno.h> | |
64 | #include <stdio.h> | |
65 | #include "general.h" | |
66 | #include "manifest.h" | |
67 | #include "tailor.h" | |
68 | ||
69 | #include "dgram.h" | |
70 | #ifdef TCP | |
71 | #include "internet.h" | |
72 | #endif | |
73 | #ifdef TP4 | |
74 | #include "tp4.h" | |
75 | #endif | |
76 | ||
77 | ||
78 | #if defined(SOCKETS) && (defined(TCP) || defined(CLTS)) | |
79 | #ifndef DEBUG | |
80 | #define action(s,f,i) | |
81 | #endif | |
82 | ||
83 | extern int errno; | |
84 | ||
85 | /* \f */ | |
86 | ||
87 | union sockaddr_un { /* 'cause sizeof (struct sockaddr_iso) == 32 */ | |
88 | struct sockaddr sa; | |
89 | ||
90 | #ifdef TCP | |
91 | struct sockaddr_in sin; | |
92 | #endif | |
93 | ||
94 | #ifdef BSD_TP4 | |
95 | union sockaddr_osi sosi; | |
96 | #endif | |
97 | }; | |
98 | ||
99 | ||
100 | struct dgramblk { | |
101 | int dgram_parent; | |
102 | union sockaddr_un dgram_peer; | |
103 | #ifdef BSD44 | |
104 | u_char dgram_addrlen; | |
105 | #endif | |
106 | ||
107 | struct qbuf dgram_queue; | |
108 | }; | |
109 | ||
110 | ||
111 | static int maxpeers = 0; | |
112 | static struct dgramblk *peers = NULL; | |
113 | ||
114 | /* \f */ | |
115 | ||
116 | #ifdef TCP | |
117 | ||
118 | /* ARGSUSED */ | |
119 | ||
120 | int start_udp_server (sock, backlog, opt1, opt2) | |
121 | struct sockaddr_in *sock; | |
122 | int backlog, | |
123 | opt1, | |
124 | opt2; | |
125 | { | |
126 | register int port; | |
127 | int sd; | |
128 | #ifdef BSD43 | |
129 | int onoff; | |
130 | #endif | |
131 | register struct dgramblk *up, | |
132 | *vp; | |
133 | ||
134 | if (peers == NULL) { | |
135 | maxpeers = getdtablesize (); | |
136 | peers = (struct dgramblk *) calloc ((unsigned)maxpeers, sizeof *peers); | |
137 | if (peers == NULL) | |
138 | return NOTOK; | |
139 | ||
140 | for (vp = (up = peers) + maxpeers; up < vp; up++) { | |
141 | up -> dgram_parent = NOTOK; | |
142 | up -> dgram_queue.qb_forw = up -> dgram_queue.qb_back = | |
143 | &up -> dgram_queue; | |
144 | } | |
145 | } | |
146 | ||
147 | if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) == NOTOK) | |
148 | return NOTOK; | |
149 | ||
150 | if (sock -> sin_port != 0) { | |
151 | action ("BIND", sd, (struct sockaddr *) sock); | |
152 | ||
153 | if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK) | |
154 | goto got_socket; | |
155 | ||
156 | (void) close (sd); | |
157 | return NOTOK; | |
158 | } | |
159 | else | |
160 | sock -> sin_family = AF_INET; | |
161 | ||
162 | for (port = IPPORT_RESERVED;; port++) { | |
163 | sock -> sin_port = htons ((u_short) port); | |
164 | ||
165 | action ("BIND", sd, (struct sockaddr *) sock); | |
166 | ||
167 | if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK) | |
168 | break; | |
169 | ||
170 | switch (errno) { | |
171 | case EADDRINUSE: | |
172 | continue; | |
173 | ||
174 | case EADDRNOTAVAIL: | |
175 | default: | |
176 | (void) close (sd); | |
177 | return NOTOK; | |
178 | } | |
179 | } | |
180 | ||
181 | got_socket: ; | |
182 | #ifdef DEBUG | |
183 | { | |
184 | int len = sizeof *sock; | |
185 | ||
186 | action ("FOO1", sd, (struct sockaddr *) sock); | |
187 | if (getsockname (sd, (struct sockaddr *) sock, &len) != NOTOK) | |
188 | action ("FOO2", sd, (struct sockaddr *) sock); | |
189 | } | |
190 | #endif | |
191 | ||
192 | #ifndef BSD43 | |
193 | if (opt1) | |
194 | (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0); | |
195 | if (opt2) | |
196 | (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0); | |
197 | #else | |
198 | onoff = 1; | |
199 | if (opt1) | |
200 | (void) setsockopt (sd, SOL_SOCKET, opt1, (char *)&onoff, sizeof onoff); | |
201 | if (opt2) | |
202 | (void) setsockopt (sd, SOL_SOCKET, opt2, (char *)&onoff, sizeof onoff); | |
203 | #endif | |
204 | ||
205 | (void) set_check_fd (sd, check_dgram_socket, NULLCP); | |
206 | return (peers[sd].dgram_parent = sd); | |
207 | } | |
208 | #endif | |
209 | ||
210 | /* \f */ | |
211 | ||
212 | #ifdef BSD_TP4 | |
213 | ||
214 | /* ARGSUSED */ | |
215 | ||
216 | int start_clts_server (sock, backlog, opt1, opt2) | |
217 | union sockaddr_osi *sock; | |
218 | int backlog, | |
219 | opt1, | |
220 | opt2; | |
221 | { | |
222 | int sd; | |
223 | #ifdef BSD43 | |
224 | int onoff; | |
225 | #endif | |
226 | u_char *cp; | |
227 | register struct dgramblk *up, | |
228 | *vp; | |
229 | struct sockaddr_iso *ifaddr = &sock -> osi_sockaddr; | |
230 | ||
231 | if (peers == NULL) { | |
232 | maxpeers = getdtablesize (); | |
233 | peers = (struct dgramblk *) calloc ((unsigned)maxpeers, sizeof *peers); | |
234 | if (peers == NULL) | |
235 | return NOTOK; | |
236 | ||
237 | for (vp = (up = peers) + maxpeers; up < vp; up++) { | |
238 | up -> dgram_parent = NOTOK; | |
239 | up -> dgram_queue.qb_forw = up -> dgram_queue.qb_back = | |
240 | &up -> dgram_queue; | |
241 | } | |
242 | } | |
243 | ||
244 | if ((sd = socket (AF_ISO, SOCK_DGRAM, 0)) == NOTOK) | |
245 | return NOTOK; | |
246 | ||
247 | if (ifaddr -> siso_tlen != 0) { | |
248 | action ("BIND", sd, (struct sockaddr *) ifaddr); | |
249 | ||
250 | if (bind (sd, (struct sockaddr *) ifaddr, (int) ifaddr -> siso_len) | |
251 | != NOTOK) | |
252 | goto got_socket; | |
253 | ||
254 | (void) close (sd); | |
255 | return NOTOK; | |
256 | } | |
257 | else | |
258 | ifaddr -> siso_family = AF_ISO; | |
259 | ||
260 | { | |
261 | int pid; | |
262 | u_char *dp, | |
263 | *ep, | |
264 | *fp; | |
265 | ||
266 | pid = getpid (); | |
267 | cp = fp = (u_char *) ifaddr -> siso_data + ifaddr -> siso_nlen; | |
268 | for (ep = (dp = (u_char *) &pid) + sizeof pid; dp < ep; dp++) | |
269 | *cp++ = *dp; | |
270 | ifaddr -> siso_tlen = (cp - fp) + 1; | |
271 | ifaddr -> siso_slen = ifaddr -> siso_plen = 0; | |
272 | ifaddr -> siso_len = sizeof *ifaddr; | |
273 | } | |
274 | ||
275 | for (*cp = 0x00; *cp < 0xff; *cp += 1) { | |
276 | action ("BIND", sd, (struct sockaddr *) ifaddr); | |
277 | ||
278 | if (bind (sd, (struct sockaddr *) ifaddr, (int) ifaddr -> siso_len) | |
279 | != NOTOK) | |
280 | goto got_socket; | |
281 | ||
282 | switch (errno) { | |
283 | case EADDRINUSE: | |
284 | continue; | |
285 | ||
286 | case EADDRNOTAVAIL: | |
287 | default: | |
288 | (void) close (sd); | |
289 | return NOTOK; | |
290 | } | |
291 | } | |
292 | (void) close (sd); | |
293 | errno = EADDRNOTAVAIL; | |
294 | return NOTOK; | |
295 | ||
296 | got_socket: ; | |
297 | #ifdef DEBUG | |
298 | { | |
299 | int len = sizeof *sock; | |
300 | ||
301 | action ("FOO1", sd, ifaddr); | |
302 | if (getsockname (sd, (struct sockaddr *) ifaddr, &len) != NOTOK) | |
303 | action ("FOO2", sd, ifaddr); | |
304 | } | |
305 | #endif | |
306 | ||
307 | #ifndef BSD43 | |
308 | if (opt1) | |
309 | (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0); | |
310 | if (opt2) | |
311 | (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0); | |
312 | #else | |
313 | onoff = 1; | |
314 | if (opt1) | |
315 | (void) setsockopt (sd, SOL_SOCKET, opt1, (char *)&onoff, sizeof onoff); | |
316 | if (opt2) | |
317 | (void) setsockopt (sd, SOL_SOCKET, opt2, (char *)&onoff, sizeof onoff); | |
318 | #endif | |
319 | ||
320 | (void) set_check_fd (sd, check_dgram_socket, NULLCP); | |
321 | return (peers[sd].dgram_parent = sd); | |
322 | } | |
323 | #endif | |
324 | ||
325 | /* \f */ | |
326 | ||
327 | int join_dgram_aux (fd, sock, newfd) | |
328 | int fd, | |
329 | newfd; | |
330 | struct sockaddr *sock; | |
331 | { | |
332 | int nfds, | |
333 | sd; | |
334 | fd_set ifds; | |
335 | register struct qbuf *qb; | |
336 | register struct dgramblk *up; | |
337 | ||
338 | if (fd < 0 || fd >= maxpeers || peers[fd].dgram_parent != fd) { | |
339 | errno = EINVAL; | |
340 | return NOTOK; | |
341 | } | |
342 | ||
343 | if (newfd) { | |
344 | FD_ZERO (&ifds); | |
345 | ||
346 | nfds = fd + 1; | |
347 | FD_SET (fd, &ifds); | |
348 | if (select_dgram_socket (nfds, &ifds, NULLFD, NULLFD, OK) == NOTOK) | |
349 | return NOTOK; | |
350 | ||
351 | up = &peers[fd]; | |
352 | if ((qb = up -> dgram_queue.qb_forw) == &up -> dgram_queue) { | |
353 | errno = EWOULDBLOCK; | |
354 | return NOTOK; | |
355 | } | |
356 | ||
357 | if ((sd = dup (fd)) == NOTOK) | |
358 | return NOTOK; | |
359 | (void) set_check_fd (fd, check_dgram_socket, NULLCP); | |
360 | ||
361 | up = &peers[sd]; | |
362 | #ifdef BSD44 | |
363 | bcopy (qb -> qb_base, (caddr_t) sock, | |
364 | ((struct sockaddr *) qb -> qb_base) -> sa_len); | |
365 | #else | |
366 | *sock = *((struct sockaddr *) qb -> qb_base); /* struct copy */ | |
367 | #endif | |
368 | ||
369 | remque (qb); | |
370 | insque (qb, up -> dgram_queue.qb_back); | |
371 | } | |
372 | else | |
373 | up = &peers[fd]; | |
374 | ||
375 | up -> dgram_parent = fd; | |
376 | #ifdef BSD44 | |
377 | if (sock -> sa_len == 0) | |
378 | sock -> sa_len = sizeof *sock; | |
379 | bcopy ((caddr_t) sock, (caddr_t) &up -> dgram_peer, sock -> sa_len); | |
380 | { | |
381 | struct sockaddr_in *sin; | |
382 | ||
383 | up -> dgram_addrlen = sock -> sa_family != AF_INET ? sock -> sa_len | |
384 | : sizeof *sin - sizeof sin -> sin_zero; | |
385 | } | |
386 | #else | |
387 | up -> dgram_peer.sa = *sock; /* struct copy */ | |
388 | #endif | |
389 | ||
390 | action ("JOIN", newfd ? sd : fd, sock); | |
391 | ||
392 | return (newfd ? sd : OK); | |
393 | } | |
394 | ||
395 | /* \f */ | |
396 | ||
397 | int read_dgram_socket (fd, q) | |
398 | int fd; | |
399 | struct qbuf **q; | |
400 | { | |
401 | int nfds; | |
402 | fd_set ifds, | |
403 | mask; | |
404 | register struct qbuf *qb; | |
405 | register struct dgramblk *up; | |
406 | ||
407 | if (fd < 0 | |
408 | || fd >= maxpeers | |
409 | || (up = &peers[fd]) -> dgram_parent == NOTOK) { | |
410 | errno = EINVAL; | |
411 | return NOTOK; | |
412 | } | |
413 | ||
414 | if ((qb = up -> dgram_queue.qb_forw) == &up -> dgram_queue) { | |
415 | FD_ZERO (&mask); | |
416 | ||
417 | nfds = fd + 1; | |
418 | FD_SET (fd, &mask); | |
419 | for (ifds = mask;; ifds = mask) { | |
420 | if (select_dgram_socket (nfds, &ifds, NULLFD, NULLFD, NOTOK) | |
421 | == NOTOK) | |
422 | return NOTOK; | |
423 | ||
424 | if ((qb = up -> dgram_queue.qb_forw) != &up -> dgram_queue) | |
425 | break; | |
426 | } | |
427 | } | |
428 | ||
429 | remque (qb); | |
430 | qb -> qb_forw = qb -> qb_back = qb; | |
431 | ||
432 | *q = qb; | |
433 | ||
434 | return qb -> qb_len; | |
435 | } | |
436 | ||
437 | /* \f */ | |
438 | ||
439 | int hack_dgram_socket (fd, sock) | |
440 | int fd; | |
441 | struct sockaddr *sock; | |
442 | { | |
443 | register struct dgramblk *up; | |
444 | ||
445 | if (fd < 0 | |
446 | || fd >= maxpeers | |
447 | || (up = &peers[fd]) -> dgram_parent != fd) { | |
448 | errno = EINVAL; | |
449 | return NOTOK; | |
450 | } | |
451 | ||
452 | if (sock == NULL) { | |
453 | bzero ((caddr_t) &up -> dgram_peer, sizeof up -> dgram_peer); | |
454 | return OK; | |
455 | } | |
456 | ||
457 | #ifdef BSD44 | |
458 | if (sock -> sa_len == 0) | |
459 | sock -> sa_len = sizeof *sock; | |
460 | bcopy ((caddr_t) sock, (caddr_t) &up -> dgram_peer, sock -> sa_len); | |
461 | up -> dgram_addrlen = 0; | |
462 | #else | |
463 | up -> dgram_peer.sa = *sock; /* struct copy */ | |
464 | #endif | |
465 | ||
466 | action ("HACK", fd, sock); | |
467 | ||
468 | return OK; | |
469 | } | |
470 | ||
471 | ||
472 | int write_dgram_socket (fd, qb) | |
473 | int fd; | |
474 | register struct qbuf *qb; | |
475 | { | |
476 | register struct dgramblk *up; | |
477 | ||
478 | if (fd < 0 | |
479 | || fd >= maxpeers | |
480 | || (up = &peers[fd]) -> dgram_parent == NOTOK | |
481 | || up -> dgram_peer.sa.sa_family == 0) { | |
482 | errno = EINVAL; | |
483 | return NOTOK; | |
484 | } | |
485 | ||
486 | action ("SENDTO", fd, &up -> dgram_peer.sa); | |
487 | ||
488 | #ifdef BSD44 | |
489 | return sendto (fd, qb -> qb_data, qb -> qb_len, NULL, | |
490 | &up -> dgram_peer.sa, (int) up -> dgram_peer.sa.sa_len); | |
491 | #else | |
492 | return sendto (fd, qb -> qb_data, qb -> qb_len, NULL, | |
493 | &up -> dgram_peer.sa, sizeof up -> dgram_peer.sa); | |
494 | #endif | |
495 | } | |
496 | ||
497 | ||
498 | /* \f */ | |
499 | ||
500 | int close_dgram_socket (fd) | |
501 | int fd; | |
502 | { | |
503 | register struct dgramblk *up, | |
504 | *vp; | |
505 | ||
506 | if (fd < 0 | |
507 | || fd >= maxpeers | |
508 | || (up = &peers[fd]) -> dgram_parent == NOTOK) { | |
509 | errno = EINVAL; | |
510 | return NOTOK; | |
511 | } | |
512 | ||
513 | action ("CLOSE", fd, &up -> dgram_peer.sa); | |
514 | ||
515 | up -> dgram_parent = NOTOK; | |
516 | bzero ((char *) &up -> dgram_peer, sizeof up -> dgram_peer); | |
517 | QBFREE (&up -> dgram_queue); | |
518 | ||
519 | for (vp = (up = peers) + maxpeers; up < vp; up++) | |
520 | if (up -> dgram_parent == fd) | |
521 | up -> dgram_parent = up - peers; | |
522 | ||
523 | (void) set_check_fd (fd, NULLIFP, NULLCP); | |
524 | return close (fd); | |
525 | } | |
526 | ||
527 | /* \f */ | |
528 | ||
529 | int select_dgram_socket (nfds, rfds, wfds, efds, secs) | |
530 | int nfds; | |
531 | fd_set *rfds, | |
532 | *wfds, | |
533 | *efds; | |
534 | int secs; | |
535 | { | |
536 | register int fd; | |
537 | int cc, | |
538 | mfds, | |
539 | result; | |
540 | fd_set ifds, | |
541 | jfds; | |
542 | register struct qbuf *qb; | |
543 | register struct dgramblk *up, | |
544 | *vp; | |
545 | struct dgramblk *wp; | |
546 | union sockaddr_un *sock; | |
547 | ||
548 | if (rfds) { | |
549 | jfds = *rfds; | |
550 | ||
551 | if (secs != OK) | |
552 | for (vp = (up = peers) + maxpeers, fd = 0; up < vp; up++, fd++) | |
553 | if (up -> dgram_parent != NOTOK | |
554 | && FD_ISSET (fd, &jfds) | |
555 | && up -> dgram_queue.qb_forw != &up -> dgram_queue) { | |
556 | secs = OK; | |
557 | break; | |
558 | } | |
559 | } | |
560 | ||
561 | if ((result = selsocket (nfds, rfds, wfds, efds, secs)) == NOTOK | |
562 | || rfds == NULLFD) | |
563 | return result; | |
564 | ||
565 | ifds = *rfds; | |
566 | if ((mfds = nfds) > maxpeers) | |
567 | mfds = maxpeers; | |
568 | for (fd = 0, up = peers; fd < mfds; fd++, up++) | |
569 | if (FD_ISSET (fd, &ifds)) { | |
570 | int slen; | |
571 | u_char len; | |
572 | char *data; | |
573 | ||
574 | FD_CLR (fd, &ifds); | |
575 | ||
576 | if (up -> dgram_parent == NOTOK) | |
577 | continue; | |
578 | ||
579 | if ((qb = (struct qbuf *) malloc ((unsigned) (sizeof *qb | |
580 | + (slen | |
581 | = sizeof *sock) | |
582 | + MAXDGRAM))) | |
583 | == NULL) | |
584 | return NOTOK; | |
585 | ||
586 | sock = (union sockaddr_un *) qb -> qb_base; | |
587 | qb -> qb_data = qb -> qb_base + slen; | |
588 | if ((cc = recvfrom (fd, qb -> qb_data, MAXDGRAM, NULL, | |
589 | &sock -> sa, &slen)) == NOTOK) { | |
590 | free ((char *) qb); | |
591 | return NOTOK; | |
592 | } | |
593 | #ifdef BSD44 | |
594 | sock -> sa.sa_len = slen; | |
595 | #endif | |
596 | qb -> qb_len = cc; | |
597 | ||
598 | action ("RECVFROM", fd, &sock -> sa); | |
599 | ||
600 | vp = up; | |
601 | data = sock -> sa.sa_data; | |
602 | switch (sock -> sa.sa_family) { | |
603 | case AF_INET: /* XXX: doesn't take into account padding */ | |
604 | len = sizeof sock -> sa.sa_data | |
605 | - sizeof sock -> sin.sin_zero; | |
606 | break; | |
607 | ||
608 | default: | |
609 | #ifdef BSD44 | |
610 | len = sock -> sa.sa_len; | |
611 | #else | |
612 | len = sizeof sock -> sa; | |
613 | #endif | |
614 | break; | |
615 | } | |
616 | if ( | |
617 | #ifdef BSD44 | |
618 | len != up -> dgram_addrlen || | |
619 | #endif | |
620 | bcmp (data, up -> dgram_peer.sa.sa_data, (int) len) | |
621 | != 0) { | |
622 | for (wp = (vp = peers) + maxpeers; vp < wp; vp++) | |
623 | if (vp != up | |
624 | && vp -> dgram_parent == up -> dgram_parent | |
625 | #ifdef BSD44 | |
626 | && len == vp -> dgram_addrlen | |
627 | #endif | |
628 | && bcmp (data, vp -> dgram_peer.sa.sa_data, | |
629 | (int) len) == 0) | |
630 | break; | |
631 | if (vp >= wp | |
632 | && (vp = &peers[up -> dgram_parent]) | |
633 | -> dgram_peer.sa.sa_family != 0) { | |
634 | free ((char *) qb); | |
635 | continue; | |
636 | } | |
637 | } | |
638 | ||
639 | insque (qb, vp -> dgram_queue.qb_back); | |
640 | ||
641 | if (--result <= 0 | |
642 | || (result = selsocket (nfds, &ifds, NULLFD, NULLFD, OK)) | |
643 | <= 0) | |
644 | break; | |
645 | ||
646 | } | |
647 | ||
648 | for (vp = (up = peers) + maxpeers, fd = 0; up < vp; up++, fd++) | |
649 | if (up -> dgram_parent != NOTOK && FD_ISSET (fd, &jfds)) | |
650 | if (up -> dgram_queue.qb_forw != &up -> dgram_queue) | |
651 | FD_SET (fd, rfds); | |
652 | else | |
653 | FD_CLR (fd, rfds); | |
654 | ||
655 | result = 0; | |
656 | ifds = *rfds; | |
657 | if (wfds) | |
658 | for (fd = 0; fd < nfds; fd++) | |
659 | if (FD_ISSET (fd, wfds)) | |
660 | FD_SET (fd, &ifds); | |
661 | if (efds) | |
662 | for (fd = 0; fd < nfds; fd++) | |
663 | if (FD_ISSET (fd, efds)) | |
664 | FD_SET (fd, &ifds); | |
665 | for (fd = 0; fd < nfds; fd++) | |
666 | if (FD_ISSET (fd, &ifds)) | |
667 | result++; | |
668 | ||
669 | return result; | |
670 | } | |
671 | ||
672 | /* \f */ | |
673 | ||
674 | int check_dgram_socket (fd) | |
675 | int fd; | |
676 | { | |
677 | int nfds; | |
678 | fd_set ifds; | |
679 | ||
680 | FD_ZERO (&ifds); | |
681 | ||
682 | nfds = fd + 1; | |
683 | FD_SET (fd, &ifds); | |
684 | ||
685 | return select_dgram_socket (nfds, &ifds, NULLFD, NULLFD, OK); | |
686 | } | |
687 | ||
688 | /* \f */ | |
689 | ||
690 | #ifdef DEBUG | |
691 | ||
692 | #ifdef TCP | |
693 | #include "isoaddrs.h" | |
694 | ||
695 | ||
696 | static inetprint (sin, bp) | |
697 | struct sockaddr_in *sin; | |
698 | char *bp; | |
699 | { | |
700 | (void) sprintf (bp, "Internet=%s+%d+%d", inet_ntoa (sin -> sin_addr), | |
701 | (int) ntohs (sin -> sin_port), NA_TSET_UDP); | |
702 | } | |
703 | #endif | |
704 | ||
705 | /* \f */ | |
706 | ||
707 | #ifdef CLTS | |
708 | /* prints OSI address using the format described in: | |
709 | ||
710 | "A string encoding of Presentation Address" | |
711 | ||
712 | S.E. Kille, Research Note RN/89/14, February 1989 | |
713 | Department of Computer Science | |
714 | University College London | |
715 | ||
716 | */ | |
717 | ||
718 | #ifndef SSEL | |
719 | #define SSEL(s) ((s)->siso_tlen + TSEL(s)) | |
720 | #define PSEL(s) ((s)->siso_slen + SSEL(s)) | |
721 | #endif | |
722 | ||
723 | ||
724 | static isoprint (siso, bp) | |
725 | register struct sockaddr_iso *siso; | |
726 | char *bp; | |
727 | { | |
728 | int didone = 0; | |
729 | ||
730 | if (siso -> siso_plen) { | |
731 | hexprint (bp, siso -> siso_plen, PSEL (siso), "'", "'H"); | |
732 | bp += strlen (bp); | |
733 | *bp++ = '/'; | |
734 | didone++; | |
735 | } | |
736 | if (siso -> siso_slen || didone) { | |
737 | hexprint (bp, siso -> siso_slen, SSEL (siso), "'", "'H"); | |
738 | bp += strlen (bp); | |
739 | *bp++ = '/'; | |
740 | didone++; | |
741 | } | |
742 | if (siso -> siso_tlen || didone) { | |
743 | hexprint (bp, siso -> siso_tlen, TSEL (siso), "'", "'H"); | |
744 | bp += strlen (bp); | |
745 | *bp++ = '/'; | |
746 | didone++; | |
747 | } | |
748 | hexprint (bp, siso -> siso_nlen, siso -> siso_data, "NS+", ""); | |
749 | } | |
750 | ||
751 | ||
752 | static hexprint (bp, n, buf, start, stop) | |
753 | char *bp; | |
754 | int n; | |
755 | u_char *buf; | |
756 | char *start, | |
757 | *stop; | |
758 | { | |
759 | register u_char *in = buf, *top = in + n; | |
760 | ||
761 | if (n == 0) | |
762 | return; | |
763 | ||
764 | (void) strcpy (bp, start); | |
765 | bp += strlen (bp); | |
766 | ||
767 | while (in < top) { | |
768 | (void) sprintf (bp, "%02x", *in++ & 0xff); | |
769 | bp += 2; | |
770 | } | |
771 | ||
772 | (void) strcpy (bp, stop); | |
773 | } | |
774 | #endif | |
775 | ||
776 | /* \f */ | |
777 | ||
778 | static struct printent { | |
779 | int p_family; | |
780 | IFP p_function; | |
781 | } ents[] = { | |
782 | #ifdef TCP | |
783 | AF_INET, inetprint, | |
784 | #endif | |
785 | ||
786 | #ifdef CLTS | |
787 | AF_ISO, isoprint, | |
788 | #endif | |
789 | ||
790 | NULL | |
791 | }; | |
792 | ||
793 | static action (s, fd, sock) | |
794 | char *s; | |
795 | int fd; | |
796 | struct sockaddr *sock; | |
797 | { | |
798 | char buffer[BUFSIZ]; | |
799 | register struct printent *p; | |
800 | ||
801 | if (!(compat_log -> ll_events & LLOG_TRACE)) | |
802 | return; | |
803 | ||
804 | for (p = ents; p -> p_family; p++) | |
805 | if (p -> p_family == sock -> sa_family) | |
806 | break; | |
807 | if (!p -> p_family) { | |
808 | DLOG (compat_log, LLOG_EXCEPTIONS, | |
809 | ("unknown dgram address family 0x%x", sock -> sa_family)); | |
810 | return; | |
811 | } | |
812 | ||
813 | (void) (*p -> p_function) (sock, buffer); | |
814 | ||
815 | DLOG (compat_log, LLOG_TRACE, ("%-10.10s %d %s", s, fd, buffer)); | |
816 | } | |
817 | #endif | |
818 | ||
819 | #else | |
820 | ||
821 | /* \f */ | |
822 | ||
823 | int dgram_dummy () {} | |
824 | ||
825 | #endif |