]> git.ipfire.org Git - thirdparty/dhcp.git/blame - omapip/dispatch.c
autoconf regeneration
[thirdparty/dhcp.git] / omapip / dispatch.c
CommitLineData
61b844bf
TL
1/* dispatch.c
2
3 I/O dispatcher. */
4
5/*
dccb6edf 6 * Copyright (c) 2004,2007-2008 by Internet Systems Consortium, Inc. ("ISC")
98311e4b 7 * Copyright (c) 1999-2003 by Internet Software Consortium
61b844bf 8 *
98311e4b
DH
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
61b844bf 12 *
98311e4b
DH
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
61b844bf 20 *
98311e4b
DH
21 * Internet Systems Consortium, Inc.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
2c85ac9b 25 * https://www.isc.org/
49733f31 26 *
98311e4b 27 * This software has been written for Internet Systems Consortium
49733f31 28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
98311e4b 29 * To learn more about Internet Systems Consortium, see
2c85ac9b 30 * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
49733f31
TL
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
61b844bf
TL
33 */
34
fe5b0fdd
DH
35#include "dhcpd.h"
36
6a4c4be8 37#include <omapip/omapip_p.h>
28868515 38#include <sys/time.h>
61b844bf
TL
39
40static omapi_io_object_t omapi_io_states;
be62cf06 41struct timeval cur_tv;
61b844bf 42
6368a1bd
DH
43struct eventqueue *rw_queue_empty;
44
20916cae
TL
45OMAPI_OBJECT_ALLOC (omapi_io,
46 omapi_io_object_t, omapi_type_io_object)
47OMAPI_OBJECT_ALLOC (omapi_waiter,
48 omapi_waiter_object_t, omapi_type_waiter)
49
6368a1bd
DH
50void
51register_eventhandler(struct eventqueue **queue, void (*handler)(void *))
52{
53 struct eventqueue *t, *q;
54
55 /* traverse to end of list */
56 t = NULL;
57 for (q = *queue ; q ; q = q->next) {
58 if (q->handler == handler)
59 return; /* handler already registered */
60 t = q;
61 }
62
63 q = ((struct eventqueue *)dmalloc(sizeof(struct eventqueue), MDL));
64 if (!q)
65 log_fatal("register_eventhandler: no memory!");
66 memset(q, 0, sizeof *q);
67 if (t)
68 t->next = q;
69 else
70 *queue = q;
71 q->handler = handler;
72 return;
73}
74
75void
76unregister_eventhandler(struct eventqueue **queue, void (*handler)(void *))
77{
78 struct eventqueue *t, *q;
79
80 /* traverse to end of list */
81 t= NULL;
82 for (q = *queue ; q ; q = q->next) {
83 if (q->handler == handler) {
84 if (t)
85 t->next = q->next;
86 else
87 *queue = q->next;
88 dfree(q, MDL); /* Don't access q after this!*/
89 break;
90 }
91 t = q;
92 }
93 return;
94}
95
96void
97trigger_event(struct eventqueue **queue)
98{
99 struct eventqueue *q;
100
101 for (q=*queue ; q ; q=q->next) {
102 if (q->handler)
103 (*q->handler)(NULL);
104 }
105}
106
107
61b844bf
TL
108/* Register an I/O handle so that we can do asynchronous I/O on it. */
109
110isc_result_t omapi_register_io_object (omapi_object_t *h,
111 int (*readfd) (omapi_object_t *),
112 int (*writefd) (omapi_object_t *),
113 isc_result_t (*reader)
114 (omapi_object_t *),
115 isc_result_t (*writer)
116 (omapi_object_t *),
117 isc_result_t (*reaper)
118 (omapi_object_t *))
119{
120 isc_result_t status;
121 omapi_io_object_t *obj, *p;
122
123 /* omapi_io_states is a static object. If its reference count
124 is zero, this is the first I/O handle to be registered, so
125 we need to initialize it. Because there is no inner or outer
126 pointer on this object, and we're setting its refcnt to 1, it
127 will never be freed. */
128 if (!omapi_io_states.refcnt) {
129 omapi_io_states.refcnt = 1;
130 omapi_io_states.type = omapi_type_io_object;
131 }
132
20916cae
TL
133 obj = (omapi_io_object_t *)0;
134 status = omapi_io_allocate (&obj, MDL);
135 if (status != ISC_R_SUCCESS)
136 return status;
61b844bf 137
4bd8800e 138 status = omapi_object_reference (&obj -> inner, h, MDL);
61b844bf 139 if (status != ISC_R_SUCCESS) {
20916cae 140 omapi_io_dereference (&obj, MDL);
61b844bf
TL
141 return status;
142 }
143
4bd8800e
TL
144 status = omapi_object_reference (&h -> outer,
145 (omapi_object_t *)obj, MDL);
61b844bf 146 if (status != ISC_R_SUCCESS) {
20916cae 147 omapi_io_dereference (&obj, MDL);
61b844bf
TL
148 return status;
149 }
150
151 /* Find the last I/O state, if there are any. */
152 for (p = omapi_io_states.next;
153 p && p -> next; p = p -> next)
154 ;
155 if (p)
20916cae 156 omapi_io_reference (&p -> next, obj, MDL);
61b844bf 157 else
20916cae 158 omapi_io_reference (&omapi_io_states.next, obj, MDL);
61b844bf
TL
159
160 obj -> readfd = readfd;
161 obj -> writefd = writefd;
162 obj -> reader = reader;
163 obj -> writer = writer;
164 obj -> reaper = reaper;
4619c0a2
DH
165
166 omapi_io_dereference(&obj, MDL);
61b844bf
TL
167 return ISC_R_SUCCESS;
168}
169
b6237fb2
TL
170isc_result_t omapi_unregister_io_object (omapi_object_t *h)
171{
20916cae 172 omapi_io_object_t *p, *obj, *last, *ph;
b6237fb2 173
20916cae
TL
174 if (!h -> outer || h -> outer -> type != omapi_type_io_object)
175 return ISC_R_INVALIDARG;
b6237fb2 176 obj = (omapi_io_object_t *)h -> outer;
20916cae
TL
177 ph = (omapi_io_object_t *)0;
178 omapi_io_reference (&ph, obj, MDL);
b6237fb2
TL
179
180 /* remove from the list of I/O states */
c3064fe0 181 last = &omapi_io_states;
b6237fb2 182 for (p = omapi_io_states.next; p; p = p -> next) {
20916cae
TL
183 if (p == obj) {
184 omapi_io_dereference (&last -> next, MDL);
185 omapi_io_reference (&last -> next, p -> next, MDL);
b6237fb2
TL
186 break;
187 }
188 last = p;
189 }
190 if (obj -> next)
20916cae
TL
191 omapi_io_dereference (&obj -> next, MDL);
192
b6237fb2
TL
193 if (obj -> outer) {
194 if (obj -> outer -> inner == (omapi_object_t *)obj)
195 omapi_object_dereference (&obj -> outer -> inner,
196 MDL);
197 omapi_object_dereference (&obj -> outer, MDL);
198 }
199 omapi_object_dereference (&obj -> inner, MDL);
200 omapi_object_dereference (&h -> outer, MDL);
20916cae 201 omapi_io_dereference (&ph, MDL);
b6237fb2
TL
202 return ISC_R_SUCCESS;
203}
204
61b844bf
TL
205isc_result_t omapi_dispatch (struct timeval *t)
206{
207 return omapi_wait_for_completion ((omapi_object_t *)&omapi_io_states,
208 t);
209}
210
211isc_result_t omapi_wait_for_completion (omapi_object_t *object,
212 struct timeval *t)
213{
214 isc_result_t status;
215 omapi_waiter_object_t *waiter;
216 omapi_object_t *inner;
217
218 if (object) {
20916cae
TL
219 waiter = (omapi_waiter_object_t *)0;
220 status = omapi_waiter_allocate (&waiter, MDL);
221 if (status != ISC_R_SUCCESS)
222 return status;
61b844bf
TL
223
224 /* Paste the waiter object onto the inner object we're
225 waiting on. */
226 for (inner = object; inner -> inner; inner = inner -> inner)
227 ;
228
4bd8800e 229 status = omapi_object_reference (&waiter -> outer, inner, MDL);
61b844bf 230 if (status != ISC_R_SUCCESS) {
20916cae 231 omapi_waiter_dereference (&waiter, MDL);
61b844bf
TL
232 return status;
233 }
234
235 status = omapi_object_reference (&inner -> inner,
236 (omapi_object_t *)waiter,
4bd8800e 237 MDL);
61b844bf 238 if (status != ISC_R_SUCCESS) {
20916cae 239 omapi_waiter_dereference (&waiter, MDL);
61b844bf
TL
240 return status;
241 }
242 } else
243 waiter = (omapi_waiter_object_t *)0;
244
245 do {
6a4c4be8 246 status = omapi_one_dispatch ((omapi_object_t *)waiter, t);
61b844bf
TL
247 if (status != ISC_R_SUCCESS)
248 return status;
249 } while (!waiter || !waiter -> ready);
250
727ebc3a
TL
251 if (waiter -> outer) {
252 if (waiter -> outer -> inner) {
253 omapi_object_dereference (&waiter -> outer -> inner,
4bd8800e 254 MDL);
727ebc3a
TL
255 if (waiter -> inner)
256 omapi_object_reference
257 (&waiter -> outer -> inner,
4bd8800e 258 waiter -> inner, MDL);
727ebc3a 259 }
4bd8800e 260 omapi_object_dereference (&waiter -> outer, MDL);
727ebc3a
TL
261 }
262 if (waiter -> inner)
4bd8800e 263 omapi_object_dereference (&waiter -> inner, MDL);
727ebc3a 264
49146f3c 265 status = waiter -> waitstatus;
20916cae 266 omapi_waiter_dereference (&waiter, MDL);
86a9cf83 267 return status;
61b844bf
TL
268}
269
6a4c4be8 270isc_result_t omapi_one_dispatch (omapi_object_t *wo,
61b844bf
TL
271 struct timeval *t)
272{
6368a1bd 273 fd_set r, w, x, rr, ww, xx;
61b844bf
TL
274 int max = 0;
275 int count;
276 int desc;
277 struct timeval now, to;
4619c0a2 278 omapi_io_object_t *io, *prev, *next;
6a4c4be8 279 omapi_waiter_object_t *waiter;
b6237fb2 280 omapi_object_t *tmp = (omapi_object_t *)0;
6a4c4be8
TL
281
282 if (!wo || wo -> type != omapi_type_waiter)
283 waiter = (omapi_waiter_object_t *)0;
284 else
285 waiter = (omapi_waiter_object_t *)wo;
61b844bf
TL
286
287 FD_ZERO (&x);
288
289 /* First, see if the timeout has expired, and if so return. */
290 if (t) {
291 gettimeofday (&now, (struct timezone *)0);
be62cf06
FD
292 cur_tv.tv_sec = now.tv_sec;
293 cur_tv.tv_usec = now.tv_usec;
61b844bf
TL
294 if (now.tv_sec > t -> tv_sec ||
295 (now.tv_sec == t -> tv_sec && now.tv_usec >= t -> tv_usec))
296 return ISC_R_TIMEDOUT;
297
298 /* We didn't time out, so figure out how long until
299 we do. */
300 to.tv_sec = t -> tv_sec - now.tv_sec;
301 to.tv_usec = t -> tv_usec - now.tv_usec;
302 if (to.tv_usec < 0) {
303 to.tv_usec += 1000000;
304 to.tv_sec--;
305 }
d01dde76
DN
306
307 /* It is possible for the timeout to get set larger than
308 the largest time select() is willing to accept.
309 Restricting the timeout to a maximum of one day should
310 work around this. -DPN. (Ref: Bug #416) */
311 if (to.tv_sec > (60 * 60 * 24))
312 to.tv_sec = 60 * 60 * 24;
61b844bf
TL
313 }
314
315 /* If the object we're waiting on has reached completion,
316 return now. */
317 if (waiter && waiter -> ready)
318 return ISC_R_SUCCESS;
319
cfb3f45d 320 again:
61b844bf
TL
321 /* If we have no I/O state, we can't proceed. */
322 if (!(io = omapi_io_states.next))
323 return ISC_R_NOMORE;
324
325 /* Set up the read and write masks. */
326 FD_ZERO (&r);
327 FD_ZERO (&w);
328
329 for (; io; io = io -> next) {
330 /* Check for a read socket. If we shouldn't be
331 trying to read for this I/O object, either there
332 won't be a readfd function, or it'll return -1. */
d8c46740 333 if (io -> readfd && io -> inner &&
61b844bf
TL
334 (desc = (*(io -> readfd)) (io -> inner)) >= 0) {
335 FD_SET (desc, &r);
336 if (desc > max)
337 max = desc;
338 }
339
340 /* Same deal for write fdets. */
d8c46740 341 if (io -> writefd && io -> inner &&
61b844bf
TL
342 (desc = (*(io -> writefd)) (io -> inner)) >= 0) {
343 FD_SET (desc, &w);
344 if (desc > max)
345 max = desc;
346 }
347 }
348
6368a1bd
DH
349 /* poll if all reader are dry */
350 now.tv_sec = 0;
351 now.tv_usec = 0;
352 rr=r;
353 ww=w;
354 xx=x;
355
356 /* poll once */
357 count = select(max + 1, &r, &w, &x, &now);
358 if (!count) {
359 /* We are dry now */
360 trigger_event(&rw_queue_empty);
361 /* Wait for a packet or a timeout... XXX */
f9453d21
DH
362 r = rr;
363 w = ww;
364 x = xx;
365 count = select(max + 1, &r, &w, &x, t ? &to : NULL);
6368a1bd 366 }
61b844bf
TL
367
368 /* Get the current time... */
be62cf06 369 gettimeofday (&cur_tv, (struct timezone *)0);
61b844bf 370
cfb3f45d
TL
371 /* We probably have a bad file descriptor. Figure out which one.
372 When we find it, call the reaper function on it, which will
373 maybe make it go away, and then try again. */
374 if (count < 0) {
375 struct timeval t0;
9bf59e83
TL
376 omapi_io_object_t *prev = (omapi_io_object_t *)0;
377 io = (omapi_io_object_t *)0;
378 if (omapi_io_states.next)
379 omapi_io_reference (&io, omapi_io_states.next, MDL);
cfb3f45d 380
9bf59e83 381 while (io) {
cfb3f45d
TL
382 omapi_object_t *obj;
383 FD_ZERO (&r);
384 FD_ZERO (&w);
385 t0.tv_sec = t0.tv_usec = 0;
386
387 if (io -> readfd && io -> inner &&
388 (desc = (*(io -> readfd)) (io -> inner)) >= 0) {
389 FD_SET (desc, &r);
cfb3f45d
TL
390 count = select (desc + 1, &r, &w, &x, &t0);
391 bogon:
392 if (count < 0) {
393 log_error ("Bad descriptor %d.", desc);
394 for (obj = (omapi_object_t *)io;
395 obj -> outer;
396 obj = obj -> outer)
397 ;
645eab7b
TL
398 for (; obj; obj = obj -> inner) {
399 omapi_value_t *ov;
400 int len;
401 const char *s;
402 ov = (omapi_value_t *)0;
403 omapi_get_value_str (obj,
404 (omapi_object_t *)0,
405 "name", &ov);
406 if (ov && ov -> value &&
407 (ov -> value -> type ==
408 omapi_datatype_string)) {
409 s = (char *)
410 ov -> value -> u.buffer.value;
411 len = ov -> value -> u.buffer.len;
412 } else {
413 s = "";
414 len = 0;
415 }
416 log_error ("Object %lx %s%s%.*s",
417 (unsigned long)obj,
418 obj -> type -> name,
419 len ? " " : "",
420 len, s);
421 if (len)
422 omapi_value_dereference (&ov, MDL);
423 }
98311e4b 424 (*(io -> reaper)) (io -> inner);
9bf59e83
TL
425 if (prev) {
426 omapi_io_dereference (&prev -> next, MDL);
427 if (io -> next)
428 omapi_io_reference (&prev -> next,
429 io -> next, MDL);
430 } else {
431 omapi_io_dereference
432 (&omapi_io_states.next, MDL);
433 if (io -> next)
434 omapi_io_reference
435 (&omapi_io_states.next,
436 io -> next, MDL);
437 }
438 omapi_io_dereference (&io, MDL);
cfb3f45d
TL
439 goto again;
440 }
441 }
442
443 FD_ZERO (&r);
444 FD_ZERO (&w);
445 t0.tv_sec = t0.tv_usec = 0;
446
447 /* Same deal for write fdets. */
448 if (io -> writefd && io -> inner &&
449 (desc = (*(io -> writefd)) (io -> inner)) >= 0) {
450 FD_SET (desc, &w);
cfb3f45d
TL
451 count = select (desc + 1, &r, &w, &x, &t0);
452 if (count < 0)
453 goto bogon;
454 }
9bf59e83
TL
455 if (prev)
456 omapi_io_dereference (&prev, MDL);
457 omapi_io_reference (&prev, io, MDL);
458 omapi_io_dereference (&io, MDL);
459 if (prev -> next)
460 omapi_io_reference (&io, prev -> next, MDL);
cfb3f45d 461 }
9bf59e83
TL
462 if (prev)
463 omapi_io_dereference (&prev, MDL);
464
cfb3f45d 465 }
61b844bf
TL
466
467 for (io = omapi_io_states.next; io; io = io -> next) {
d8c46740
TL
468 if (!io -> inner)
469 continue;
b6237fb2 470 omapi_object_reference (&tmp, io -> inner, MDL);
61b844bf
TL
471 /* Check for a read descriptor, and if there is one,
472 see if we got input on that socket. */
473 if (io -> readfd &&
b6237fb2 474 (desc = (*(io -> readfd)) (tmp)) >= 0) {
61b844bf 475 if (FD_ISSET (desc, &r))
98311e4b 476 ((*(io -> reader)) (tmp));
61b844bf
TL
477 }
478
479 /* Same deal for write descriptors. */
480 if (io -> writefd &&
b6237fb2 481 (desc = (*(io -> writefd)) (tmp)) >= 0)
61b844bf
TL
482 {
483 if (FD_ISSET (desc, &w))
98311e4b 484 ((*(io -> writer)) (tmp));
61b844bf 485 }
b6237fb2 486 omapi_object_dereference (&tmp, MDL);
61b844bf
TL
487 }
488
489 /* Now check for I/O handles that are no longer valid,
490 and remove them from the list. */
4619c0a2
DH
491 prev = NULL;
492 io = NULL;
493 if (omapi_io_states.next != NULL) {
494 omapi_io_reference(&io, omapi_io_states.next, MDL);
495 }
496 while (io != NULL) {
497 if ((io->inner == NULL) ||
498 ((io->reaper != NULL) &&
499 ((io->reaper)(io->inner) != ISC_R_SUCCESS)))
500 {
501
502 omapi_io_object_t *tmp = NULL;
503 /* Save a reference to the next
504 pointer, if there is one. */
505 if (io->next != NULL) {
506 omapi_io_reference(&tmp, io->next, MDL);
507 omapi_io_dereference(&io->next, MDL);
61b844bf 508 }
4619c0a2
DH
509 if (prev != NULL) {
510 omapi_io_dereference(&prev->next, MDL);
511 if (tmp != NULL)
512 omapi_io_reference(&prev->next,
513 tmp, MDL);
514 } else {
515 omapi_io_dereference(&omapi_io_states.next,
516 MDL);
517 if (tmp != NULL)
518 omapi_io_reference
519 (&omapi_io_states.next,
520 tmp, MDL);
521 else
522 omapi_signal_in(
523 (omapi_object_t *)
524 &omapi_io_states,
525 "ready");
526 }
527 if (tmp != NULL)
528 omapi_io_dereference(&tmp, MDL);
529
530 } else {
531
532 if (prev != NULL) {
533 omapi_io_dereference(&prev, MDL);
534 }
535 omapi_io_reference(&prev, io, MDL);
536
61b844bf 537 }
4619c0a2
DH
538
539 /*
540 * Equivalent to:
541 * io = io->next
542 * But using our reference counting voodoo.
543 */
544 next = NULL;
545 if (io->next != NULL) {
546 omapi_io_reference(&next, io->next, MDL);
547 }
548 omapi_io_dereference(&io, MDL);
549 if (next != NULL) {
550 omapi_io_reference(&io, next, MDL);
551 omapi_io_dereference(&next, MDL);
552 }
553 }
554 if (prev != NULL) {
555 omapi_io_dereference(&prev, MDL);
61b844bf
TL
556 }
557
558 return ISC_R_SUCCESS;
559}
560
561isc_result_t omapi_io_set_value (omapi_object_t *h,
562 omapi_object_t *id,
563 omapi_data_string_t *name,
564 omapi_typed_data_t *value)
565{
566 if (h -> type != omapi_type_io_object)
567 return ISC_R_INVALIDARG;
568
569 if (h -> inner && h -> inner -> type -> set_value)
570 return (*(h -> inner -> type -> set_value))
571 (h -> inner, id, name, value);
572 return ISC_R_NOTFOUND;
573}
574
575isc_result_t omapi_io_get_value (omapi_object_t *h,
576 omapi_object_t *id,
577 omapi_data_string_t *name,
578 omapi_value_t **value)
579{
580 if (h -> type != omapi_type_io_object)
581 return ISC_R_INVALIDARG;
582
583 if (h -> inner && h -> inner -> type -> get_value)
584 return (*(h -> inner -> type -> get_value))
585 (h -> inner, id, name, value);
586 return ISC_R_NOTFOUND;
587}
588
98311e4b
DH
589/* omapi_io_destroy (object, MDL);
590 *
20ae1aff 591 * Find the requested IO [object] and remove it from the list of io
98311e4b
DH
592 * states, causing the cleanup functions to destroy it. Note that we must
593 * hold a reference on the object while moving its ->next reference and
594 * removing the reference in the chain to the target object...otherwise it
595 * may be cleaned up from under us.
596 */
4bd8800e 597isc_result_t omapi_io_destroy (omapi_object_t *h, const char *file, int line)
61b844bf 598{
98311e4b 599 omapi_io_object_t *obj = NULL, *p, *last = NULL, **holder;
bdcaf7b9 600
61b844bf
TL
601 if (h -> type != omapi_type_io_object)
602 return ISC_R_INVALIDARG;
bdcaf7b9 603
b6237fb2
TL
604 /* remove from the list of I/O states */
605 for (p = omapi_io_states.next; p; p = p -> next) {
98311e4b
DH
606 if (p == (omapi_io_object_t *)h) {
607 omapi_io_reference (&obj, p, MDL);
608
609 if (last)
610 holder = &last -> next;
611 else
612 holder = &omapi_io_states.next;
613
614 omapi_io_dereference (holder, MDL);
615
616 if (obj -> next) {
617 omapi_io_reference (holder, obj -> next, MDL);
618 omapi_io_dereference (&obj -> next, MDL);
619 }
620
621 return omapi_io_dereference (&obj, MDL);
bdcaf7b9 622 }
b6237fb2 623 last = p;
bdcaf7b9 624 }
98311e4b
DH
625
626 return ISC_R_NOTFOUND;
61b844bf
TL
627}
628
629isc_result_t omapi_io_signal_handler (omapi_object_t *h,
b1b7b521 630 const char *name, va_list ap)
61b844bf
TL
631{
632 if (h -> type != omapi_type_io_object)
633 return ISC_R_INVALIDARG;
634
635 if (h -> inner && h -> inner -> type -> signal_handler)
636 return (*(h -> inner -> type -> signal_handler)) (h -> inner,
637 name, ap);
638 return ISC_R_NOTFOUND;
639}
640
641isc_result_t omapi_io_stuff_values (omapi_object_t *c,
642 omapi_object_t *id,
643 omapi_object_t *i)
644{
645 if (i -> type != omapi_type_io_object)
646 return ISC_R_INVALIDARG;
647
648 if (i -> inner && i -> inner -> type -> stuff_values)
649 return (*(i -> inner -> type -> stuff_values)) (c, id,
650 i -> inner);
651 return ISC_R_SUCCESS;
652}
653
654isc_result_t omapi_waiter_signal_handler (omapi_object_t *h,
b1b7b521 655 const char *name, va_list ap)
61b844bf
TL
656{
657 omapi_waiter_object_t *waiter;
658
659 if (h -> type != omapi_type_waiter)
660 return ISC_R_INVALIDARG;
661
662 if (!strcmp (name, "ready")) {
663 waiter = (omapi_waiter_object_t *)h;
664 waiter -> ready = 1;
49146f3c
DN
665 waiter -> waitstatus = ISC_R_SUCCESS;
666 return ISC_R_SUCCESS;
667 }
668
669 if (!strcmp (name, "status")) {
670 waiter = (omapi_waiter_object_t *)h;
671 waiter -> ready = 1;
672 waiter -> waitstatus = va_arg (ap, isc_result_t);
61b844bf
TL
673 return ISC_R_SUCCESS;
674 }
675
d758ad8c
TL
676 if (!strcmp (name, "disconnect")) {
677 waiter = (omapi_waiter_object_t *)h;
678 waiter -> ready = 1;
679 waiter -> waitstatus = ISC_R_CONNRESET;
680 return ISC_R_SUCCESS;
681 }
682
61b844bf
TL
683 if (h -> inner && h -> inner -> type -> signal_handler)
684 return (*(h -> inner -> type -> signal_handler)) (h -> inner,
685 name, ap);
686 return ISC_R_NOTFOUND;
687}
688
d758ad8c
TL
689isc_result_t omapi_io_state_foreach (isc_result_t (*func) (omapi_object_t *,
690 void *),
691 void *p)
692{
693 omapi_io_object_t *io;
694 isc_result_t status;
695
696 for (io = omapi_io_states.next; io; io = io -> next) {
697 if (io -> inner) {
698 status = (*func) (io -> inner, p);
699 if (status != ISC_R_SUCCESS)
700 return status;
701 }
702 }
703 return ISC_R_SUCCESS;
704}