00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "dhcpd.h"
00030
00031 #include <omapip/omapip_p.h>
00032 #include <sys/time.h>
00033
00034 static omapi_io_object_t omapi_io_states;
00035 struct timeval cur_tv;
00036
00037 struct eventqueue *rw_queue_empty;
00038
00039 OMAPI_OBJECT_ALLOC (omapi_io,
00040 omapi_io_object_t, omapi_type_io_object)
00041 OMAPI_OBJECT_ALLOC (omapi_waiter,
00042 omapi_waiter_object_t, omapi_type_waiter)
00043
00044 void
00045 register_eventhandler(struct eventqueue **queue, void (*handler)(void *))
00046 {
00047 struct eventqueue *t, *q;
00048
00049
00050 t = NULL;
00051 for (q = *queue ; q ; q = q->next) {
00052 if (q->handler == handler)
00053 return;
00054 t = q;
00055 }
00056
00057 q = ((struct eventqueue *)dmalloc(sizeof(struct eventqueue), MDL));
00058 if (!q)
00059 log_fatal("register_eventhandler: no memory!");
00060 memset(q, 0, sizeof *q);
00061 if (t)
00062 t->next = q;
00063 else
00064 *queue = q;
00065 q->handler = handler;
00066 return;
00067 }
00068
00069 void
00070 unregister_eventhandler(struct eventqueue **queue, void (*handler)(void *))
00071 {
00072 struct eventqueue *t, *q;
00073
00074
00075 t= NULL;
00076 for (q = *queue ; q ; q = q->next) {
00077 if (q->handler == handler) {
00078 if (t)
00079 t->next = q->next;
00080 else
00081 *queue = q->next;
00082 dfree(q, MDL);
00083 break;
00084 }
00085 t = q;
00086 }
00087 return;
00088 }
00089
00090 void
00091 trigger_event(struct eventqueue **queue)
00092 {
00093 struct eventqueue *q;
00094
00095 for (q=*queue ; q ; q=q->next) {
00096 if (q->handler)
00097 (*q->handler)(NULL);
00098 }
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 #define SOCKDELETE 1
00119 int
00120 omapi_iscsock_cb(isc_task_t *task,
00121 isc_socket_t *socket,
00122 void *cbarg,
00123 int flags)
00124 {
00125 omapi_io_object_t *obj;
00126 isc_result_t status;
00127
00128
00129 gettimeofday (&cur_tv, (struct timezone *)0);
00130
00131
00132 #if SOCKDELETE
00133
00134
00135
00136
00137 for (obj = omapi_io_states.next;
00138 (obj != NULL) && (obj->next != NULL);
00139 obj = obj->next) {
00140 if (obj == cbarg)
00141 break;
00142 }
00143 if (obj == NULL) {
00144 return(0);
00145 }
00146 #else
00147
00148 if (((omapi_object_t *)cbarg) -> type != omapi_type_io_object) {
00149 log_fatal ("Incorrect object type, must be of type io_object");
00150 }
00151 obj = (omapi_io_object_t *)cbarg;
00152
00153
00154
00155
00156
00157
00158
00159
00160 if (obj->closed == ISC_TRUE) {
00161 return(0);
00162 }
00163 #endif
00164
00165 if ((flags == ISC_SOCKFDWATCH_READ) &&
00166 (obj->reader != NULL) &&
00167 (obj->inner != NULL)) {
00168 status = obj->reader(obj->inner);
00169
00170
00171
00172
00173
00174 if (status == ISC_R_SHUTTINGDOWN)
00175 return (0);
00176
00177 return (1);
00178 } else if ((flags == ISC_SOCKFDWATCH_WRITE) &&
00179 (obj->writer != NULL) &&
00180 (obj->inner != NULL)) {
00181 status = obj->writer(obj->inner);
00182
00183
00184 if (status == ISC_R_INPROGRESS) {
00185 return (1);
00186 }
00187 }
00188
00189
00190
00191
00192
00193
00194 return (0);
00195 }
00196
00197
00198
00199 isc_result_t omapi_register_io_object (omapi_object_t *h,
00200 int (*readfd) (omapi_object_t *),
00201 int (*writefd) (omapi_object_t *),
00202 isc_result_t (*reader)
00203 (omapi_object_t *),
00204 isc_result_t (*writer)
00205 (omapi_object_t *),
00206 isc_result_t (*reaper)
00207 (omapi_object_t *))
00208 {
00209 isc_result_t status;
00210 omapi_io_object_t *obj, *p;
00211 int fd_flags = 0, fd = 0;
00212
00213
00214
00215
00216
00217
00218 if (!omapi_io_states.refcnt) {
00219 omapi_io_states.refcnt = 1;
00220 omapi_io_states.type = omapi_type_io_object;
00221 }
00222
00223 obj = (omapi_io_object_t *)0;
00224 status = omapi_io_allocate (&obj, MDL);
00225 if (status != ISC_R_SUCCESS)
00226 return status;
00227 obj->closed = ISC_FALSE;
00228
00229 status = omapi_object_reference (&obj -> inner, h, MDL);
00230 if (status != ISC_R_SUCCESS) {
00231 omapi_io_dereference (&obj, MDL);
00232 return status;
00233 }
00234
00235 status = omapi_object_reference (&h -> outer,
00236 (omapi_object_t *)obj, MDL);
00237 if (status != ISC_R_SUCCESS) {
00238 omapi_io_dereference (&obj, MDL);
00239 return status;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249 if (readfd) {
00250 fd_flags |= ISC_SOCKFDWATCH_READ;
00251 fd = readfd(h);
00252 }
00253
00254 if (writefd) {
00255 fd_flags |= ISC_SOCKFDWATCH_WRITE;
00256 fd = writefd(h);
00257 }
00258
00259 if (fd_flags != 0) {
00260 status = isc_socket_fdwatchcreate(dhcp_gbl_ctx.socketmgr,
00261 fd, fd_flags,
00262 omapi_iscsock_cb,
00263 obj,
00264 dhcp_gbl_ctx.task,
00265 &obj->fd);
00266 if (status != ISC_R_SUCCESS) {
00267 log_error("Unable to register fd with library %s",
00268 isc_result_totext(status));
00269
00270
00271
00272 omapi_object_dereference(&h->outer, MDL);
00273 omapi_io_dereference (&obj, MDL);
00274 return (status);
00275 }
00276 }
00277
00278
00279
00280 for (p = omapi_io_states.next;
00281 p && p -> next; p = p -> next)
00282 ;
00283 if (p)
00284 omapi_io_reference (&p -> next, obj, MDL);
00285 else
00286 omapi_io_reference (&omapi_io_states.next, obj, MDL);
00287
00288 obj -> readfd = readfd;
00289 obj -> writefd = writefd;
00290 obj -> reader = reader;
00291 obj -> writer = writer;
00292 obj -> reaper = reaper;
00293
00294 omapi_io_dereference(&obj, MDL);
00295 return ISC_R_SUCCESS;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 isc_result_t omapi_reregister_io_object (omapi_object_t *h,
00307 int (*readfd) (omapi_object_t *),
00308 int (*writefd) (omapi_object_t *),
00309 isc_result_t (*reader)
00310 (omapi_object_t *),
00311 isc_result_t (*writer)
00312 (omapi_object_t *),
00313 isc_result_t (*reaper)
00314 (omapi_object_t *))
00315 {
00316 omapi_io_object_t *obj;
00317 int fd_flags = 0;
00318
00319 if ((!h -> outer) || (h -> outer -> type != omapi_type_io_object)) {
00320
00321
00322
00323
00324
00325
00326 return (omapi_register_io_object (h, readfd, writefd,
00327 reader, writer, reaper));
00328 }
00329
00330
00331
00332
00333
00334
00335 obj = (omapi_io_object_t *)h->outer;
00336
00337 obj->readfd = readfd;
00338 obj->writefd = writefd;
00339 obj->reader = reader;
00340 obj->writer = writer;
00341 obj->reaper = reaper;
00342
00343 if (readfd) {
00344 fd_flags |= ISC_SOCKFDWATCH_READ;
00345 }
00346
00347 if (writefd) {
00348 fd_flags |= ISC_SOCKFDWATCH_WRITE;
00349 }
00350
00351 isc_socket_fdwatchpoke(obj->fd, fd_flags);
00352
00353 return (ISC_R_SUCCESS);
00354 }
00355
00356 isc_result_t omapi_unregister_io_object (omapi_object_t *h)
00357 {
00358 omapi_io_object_t *obj, *ph;
00359 #if SOCKDELETE
00360 omapi_io_object_t *p, *last;
00361 #endif
00362
00363 if (!h -> outer || h -> outer -> type != omapi_type_io_object)
00364 return DHCP_R_INVALIDARG;
00365 obj = (omapi_io_object_t *)h -> outer;
00366 ph = (omapi_io_object_t *)0;
00367 omapi_io_reference (&ph, obj, MDL);
00368
00369 #if SOCKDELETE
00370
00371
00372
00373
00374
00375
00376
00377
00378 last = &omapi_io_states;
00379 for (p = omapi_io_states.next; p; p = p -> next) {
00380 if (p == obj) {
00381 omapi_io_dereference (&last -> next, MDL);
00382 omapi_io_reference (&last -> next, p -> next, MDL);
00383 break;
00384 }
00385 last = p;
00386 }
00387 if (obj -> next)
00388 omapi_io_dereference (&obj -> next, MDL);
00389 #endif
00390
00391 if (obj -> outer) {
00392 if (obj -> outer -> inner == (omapi_object_t *)obj)
00393 omapi_object_dereference (&obj -> outer -> inner,
00394 MDL);
00395 omapi_object_dereference (&obj -> outer, MDL);
00396 }
00397 omapi_object_dereference (&obj -> inner, MDL);
00398 omapi_object_dereference (&h -> outer, MDL);
00399
00400 #if SOCKDELETE
00401
00402 if (obj->fd != NULL) {
00403 isc_socket_cancel(obj->fd, dhcp_gbl_ctx.task,
00404 ISC_SOCKCANCEL_ALL);
00405 isc_socket_detach(&obj->fd);
00406 }
00407 #else
00408 obj->closed = ISC_TRUE;
00409 #endif
00410
00411 omapi_io_dereference (&ph, MDL);
00412 return ISC_R_SUCCESS;
00413 }
00414
00415 isc_result_t omapi_dispatch (struct timeval *t)
00416 {
00417 return omapi_wait_for_completion ((omapi_object_t *)&omapi_io_states,
00418 t);
00419 }
00420
00421 isc_result_t omapi_wait_for_completion (omapi_object_t *object,
00422 struct timeval *t)
00423 {
00424 isc_result_t status;
00425 omapi_waiter_object_t *waiter;
00426 omapi_object_t *inner;
00427
00428 if (object) {
00429 waiter = (omapi_waiter_object_t *)0;
00430 status = omapi_waiter_allocate (&waiter, MDL);
00431 if (status != ISC_R_SUCCESS)
00432 return status;
00433
00434
00435
00436 for (inner = object; inner -> inner; inner = inner -> inner)
00437 ;
00438
00439 status = omapi_object_reference (&waiter -> outer, inner, MDL);
00440 if (status != ISC_R_SUCCESS) {
00441 omapi_waiter_dereference (&waiter, MDL);
00442 return status;
00443 }
00444
00445 status = omapi_object_reference (&inner -> inner,
00446 (omapi_object_t *)waiter,
00447 MDL);
00448 if (status != ISC_R_SUCCESS) {
00449 omapi_waiter_dereference (&waiter, MDL);
00450 return status;
00451 }
00452 } else
00453 waiter = (omapi_waiter_object_t *)0;
00454
00455 do {
00456 status = omapi_one_dispatch ((omapi_object_t *)waiter, t);
00457 if (status != ISC_R_SUCCESS)
00458 return status;
00459 } while (!waiter || !waiter -> ready);
00460
00461 if (waiter -> outer) {
00462 if (waiter -> outer -> inner) {
00463 omapi_object_dereference (&waiter -> outer -> inner,
00464 MDL);
00465 if (waiter -> inner)
00466 omapi_object_reference
00467 (&waiter -> outer -> inner,
00468 waiter -> inner, MDL);
00469 }
00470 omapi_object_dereference (&waiter -> outer, MDL);
00471 }
00472 if (waiter -> inner)
00473 omapi_object_dereference (&waiter -> inner, MDL);
00474
00475 status = waiter -> waitstatus;
00476 omapi_waiter_dereference (&waiter, MDL);
00477 return status;
00478 }
00479
00480 isc_result_t omapi_one_dispatch (omapi_object_t *wo,
00481 struct timeval *t)
00482 {
00483 fd_set r, w, x, rr, ww, xx;
00484 int max = 0;
00485 int count;
00486 int desc;
00487 struct timeval now, to;
00488 omapi_io_object_t *io, *prev, *next;
00489 omapi_waiter_object_t *waiter;
00490 omapi_object_t *tmp = (omapi_object_t *)0;
00491
00492 if (!wo || wo -> type != omapi_type_waiter)
00493 waiter = (omapi_waiter_object_t *)0;
00494 else
00495 waiter = (omapi_waiter_object_t *)wo;
00496
00497 FD_ZERO (&x);
00498
00499
00500 if (t) {
00501 gettimeofday (&now, (struct timezone *)0);
00502 cur_tv.tv_sec = now.tv_sec;
00503 cur_tv.tv_usec = now.tv_usec;
00504 if (now.tv_sec > t -> tv_sec ||
00505 (now.tv_sec == t -> tv_sec && now.tv_usec >= t -> tv_usec))
00506 return ISC_R_TIMEDOUT;
00507
00508
00509
00510 to.tv_sec = t -> tv_sec - now.tv_sec;
00511 to.tv_usec = t -> tv_usec - now.tv_usec;
00512 if (to.tv_usec < 0) {
00513 to.tv_usec += 1000000;
00514 to.tv_sec--;
00515 }
00516
00517
00518
00519
00520
00521 if (to.tv_sec > (60 * 60 * 24))
00522 to.tv_sec = 60 * 60 * 24;
00523 }
00524
00525
00526
00527 if (waiter && waiter -> ready)
00528 return ISC_R_SUCCESS;
00529
00530 again:
00531
00532 if (!(io = omapi_io_states.next))
00533 return ISC_R_NOMORE;
00534
00535
00536 FD_ZERO (&r);
00537 FD_ZERO (&w);
00538
00539 for (; io; io = io -> next) {
00540
00541
00542
00543 if (io -> readfd && io -> inner &&
00544 (desc = (*(io -> readfd)) (io -> inner)) >= 0) {
00545 FD_SET (desc, &r);
00546 if (desc > max)
00547 max = desc;
00548 }
00549
00550
00551 if (io -> writefd && io -> inner &&
00552 (desc = (*(io -> writefd)) (io -> inner)) >= 0) {
00553 FD_SET (desc, &w);
00554 if (desc > max)
00555 max = desc;
00556 }
00557 }
00558
00559
00560 now.tv_sec = 0;
00561 now.tv_usec = 0;
00562 rr=r;
00563 ww=w;
00564 xx=x;
00565
00566
00567 count = select(max + 1, &r, &w, &x, &now);
00568 if (!count) {
00569
00570 trigger_event(&rw_queue_empty);
00571
00572 r = rr;
00573 w = ww;
00574 x = xx;
00575 count = select(max + 1, &r, &w, &x, t ? &to : NULL);
00576 }
00577
00578
00579 gettimeofday (&cur_tv, (struct timezone *)0);
00580
00581
00582
00583
00584 if (count < 0) {
00585 struct timeval t0;
00586 omapi_io_object_t *prev = (omapi_io_object_t *)0;
00587 io = (omapi_io_object_t *)0;
00588 if (omapi_io_states.next)
00589 omapi_io_reference (&io, omapi_io_states.next, MDL);
00590
00591 while (io) {
00592 omapi_object_t *obj;
00593 FD_ZERO (&r);
00594 FD_ZERO (&w);
00595 t0.tv_sec = t0.tv_usec = 0;
00596
00597 if (io -> readfd && io -> inner &&
00598 (desc = (*(io -> readfd)) (io -> inner)) >= 0) {
00599 FD_SET (desc, &r);
00600 count = select (desc + 1, &r, &w, &x, &t0);
00601 bogon:
00602 if (count < 0) {
00603 log_error ("Bad descriptor %d.", desc);
00604 for (obj = (omapi_object_t *)io;
00605 obj -> outer;
00606 obj = obj -> outer)
00607 ;
00608 for (; obj; obj = obj -> inner) {
00609 omapi_value_t *ov;
00610 int len;
00611 const char *s;
00612 ov = (omapi_value_t *)0;
00613 omapi_get_value_str (obj,
00614 (omapi_object_t *)0,
00615 "name", &ov);
00616 if (ov && ov -> value &&
00617 (ov -> value -> type ==
00618 omapi_datatype_string)) {
00619 s = (char *)
00620 ov -> value -> u.buffer.value;
00621 len = ov -> value -> u.buffer.len;
00622 } else {
00623 s = "";
00624 len = 0;
00625 }
00626 log_error ("Object %lx %s%s%.*s",
00627 (unsigned long)obj,
00628 obj -> type -> name,
00629 len ? " " : "",
00630 len, s);
00631 if (len)
00632 omapi_value_dereference (&ov, MDL);
00633 }
00634 (*(io -> reaper)) (io -> inner);
00635 if (prev) {
00636 omapi_io_dereference (&prev -> next, MDL);
00637 if (io -> next)
00638 omapi_io_reference (&prev -> next,
00639 io -> next, MDL);
00640 } else {
00641 omapi_io_dereference
00642 (&omapi_io_states.next, MDL);
00643 if (io -> next)
00644 omapi_io_reference
00645 (&omapi_io_states.next,
00646 io -> next, MDL);
00647 }
00648 omapi_io_dereference (&io, MDL);
00649 goto again;
00650 }
00651 }
00652
00653 FD_ZERO (&r);
00654 FD_ZERO (&w);
00655 t0.tv_sec = t0.tv_usec = 0;
00656
00657
00658 if (io -> writefd && io -> inner &&
00659 (desc = (*(io -> writefd)) (io -> inner)) >= 0) {
00660 FD_SET (desc, &w);
00661 count = select (desc + 1, &r, &w, &x, &t0);
00662 if (count < 0)
00663 goto bogon;
00664 }
00665 if (prev)
00666 omapi_io_dereference (&prev, MDL);
00667 omapi_io_reference (&prev, io, MDL);
00668 omapi_io_dereference (&io, MDL);
00669 if (prev -> next)
00670 omapi_io_reference (&io, prev -> next, MDL);
00671 }
00672 if (prev)
00673 omapi_io_dereference (&prev, MDL);
00674
00675 }
00676
00677 for (io = omapi_io_states.next; io; io = io -> next) {
00678 if (!io -> inner)
00679 continue;
00680 omapi_object_reference (&tmp, io -> inner, MDL);
00681
00682
00683 if (io -> readfd &&
00684 (desc = (*(io -> readfd)) (tmp)) >= 0) {
00685 if (FD_ISSET (desc, &r))
00686 ((*(io -> reader)) (tmp));
00687 }
00688
00689
00690 if (io -> writefd &&
00691 (desc = (*(io -> writefd)) (tmp)) >= 0)
00692 {
00693 if (FD_ISSET (desc, &w))
00694 ((*(io -> writer)) (tmp));
00695 }
00696 omapi_object_dereference (&tmp, MDL);
00697 }
00698
00699
00700
00701 prev = NULL;
00702 io = NULL;
00703 if (omapi_io_states.next != NULL) {
00704 omapi_io_reference(&io, omapi_io_states.next, MDL);
00705 }
00706 while (io != NULL) {
00707 if ((io->inner == NULL) ||
00708 ((io->reaper != NULL) &&
00709 ((io->reaper)(io->inner) != ISC_R_SUCCESS)))
00710 {
00711
00712 omapi_io_object_t *tmp = NULL;
00713
00714
00715 if (io->next != NULL) {
00716 omapi_io_reference(&tmp, io->next, MDL);
00717 omapi_io_dereference(&io->next, MDL);
00718 }
00719 if (prev != NULL) {
00720 omapi_io_dereference(&prev->next, MDL);
00721 if (tmp != NULL)
00722 omapi_io_reference(&prev->next,
00723 tmp, MDL);
00724 } else {
00725 omapi_io_dereference(&omapi_io_states.next,
00726 MDL);
00727 if (tmp != NULL)
00728 omapi_io_reference
00729 (&omapi_io_states.next,
00730 tmp, MDL);
00731 else
00732 omapi_signal_in(
00733 (omapi_object_t *)
00734 &omapi_io_states,
00735 "ready");
00736 }
00737 if (tmp != NULL)
00738 omapi_io_dereference(&tmp, MDL);
00739
00740 } else {
00741
00742 if (prev != NULL) {
00743 omapi_io_dereference(&prev, MDL);
00744 }
00745 omapi_io_reference(&prev, io, MDL);
00746 }
00747
00748
00749
00750
00751
00752
00753 next = NULL;
00754 if (io->next != NULL) {
00755 omapi_io_reference(&next, io->next, MDL);
00756 }
00757 omapi_io_dereference(&io, MDL);
00758 if (next != NULL) {
00759 omapi_io_reference(&io, next, MDL);
00760 omapi_io_dereference(&next, MDL);
00761 }
00762 }
00763 if (prev != NULL) {
00764 omapi_io_dereference(&prev, MDL);
00765 }
00766
00767 return ISC_R_SUCCESS;
00768 }
00769
00770 isc_result_t omapi_io_set_value (omapi_object_t *h,
00771 omapi_object_t *id,
00772 omapi_data_string_t *name,
00773 omapi_typed_data_t *value)
00774 {
00775 if (h -> type != omapi_type_io_object)
00776 return DHCP_R_INVALIDARG;
00777
00778 if (h -> inner && h -> inner -> type -> set_value)
00779 return (*(h -> inner -> type -> set_value))
00780 (h -> inner, id, name, value);
00781 return ISC_R_NOTFOUND;
00782 }
00783
00784 isc_result_t omapi_io_get_value (omapi_object_t *h,
00785 omapi_object_t *id,
00786 omapi_data_string_t *name,
00787 omapi_value_t **value)
00788 {
00789 if (h -> type != omapi_type_io_object)
00790 return DHCP_R_INVALIDARG;
00791
00792 if (h -> inner && h -> inner -> type -> get_value)
00793 return (*(h -> inner -> type -> get_value))
00794 (h -> inner, id, name, value);
00795 return ISC_R_NOTFOUND;
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806 isc_result_t omapi_io_destroy (omapi_object_t *h, const char *file, int line)
00807 {
00808 omapi_io_object_t *obj = NULL, *p, *last = NULL, **holder;
00809
00810 if (h -> type != omapi_type_io_object)
00811 return DHCP_R_INVALIDARG;
00812
00813
00814 for (p = omapi_io_states.next; p; p = p -> next) {
00815 if (p == (omapi_io_object_t *)h) {
00816 omapi_io_reference (&obj, p, MDL);
00817
00818 if (last)
00819 holder = &last -> next;
00820 else
00821 holder = &omapi_io_states.next;
00822
00823 omapi_io_dereference (holder, MDL);
00824
00825 if (obj -> next) {
00826 omapi_io_reference (holder, obj -> next, MDL);
00827 omapi_io_dereference (&obj -> next, MDL);
00828 }
00829
00830 return omapi_io_dereference (&obj, MDL);
00831 }
00832 last = p;
00833 }
00834
00835 return ISC_R_NOTFOUND;
00836 }
00837
00838 isc_result_t omapi_io_signal_handler (omapi_object_t *h,
00839 const char *name, va_list ap)
00840 {
00841 if (h -> type != omapi_type_io_object)
00842 return DHCP_R_INVALIDARG;
00843
00844 if (h -> inner && h -> inner -> type -> signal_handler)
00845 return (*(h -> inner -> type -> signal_handler)) (h -> inner,
00846 name, ap);
00847 return ISC_R_NOTFOUND;
00848 }
00849
00850 isc_result_t omapi_io_stuff_values (omapi_object_t *c,
00851 omapi_object_t *id,
00852 omapi_object_t *i)
00853 {
00854 if (i -> type != omapi_type_io_object)
00855 return DHCP_R_INVALIDARG;
00856
00857 if (i -> inner && i -> inner -> type -> stuff_values)
00858 return (*(i -> inner -> type -> stuff_values)) (c, id,
00859 i -> inner);
00860 return ISC_R_SUCCESS;
00861 }
00862
00863 isc_result_t omapi_waiter_signal_handler (omapi_object_t *h,
00864 const char *name, va_list ap)
00865 {
00866 omapi_waiter_object_t *waiter;
00867
00868 if (h -> type != omapi_type_waiter)
00869 return DHCP_R_INVALIDARG;
00870
00871 if (!strcmp (name, "ready")) {
00872 waiter = (omapi_waiter_object_t *)h;
00873 waiter -> ready = 1;
00874 waiter -> waitstatus = ISC_R_SUCCESS;
00875 return ISC_R_SUCCESS;
00876 }
00877
00878 if (!strcmp(name, "status")) {
00879 waiter = (omapi_waiter_object_t *)h;
00880 waiter->ready = 1;
00881 waiter->waitstatus = va_arg(ap, isc_result_t);
00882 return ISC_R_SUCCESS;
00883 }
00884
00885 if (!strcmp (name, "disconnect")) {
00886 waiter = (omapi_waiter_object_t *)h;
00887 waiter -> ready = 1;
00888 waiter -> waitstatus = DHCP_R_CONNRESET;
00889 return ISC_R_SUCCESS;
00890 }
00891
00892 if (h -> inner && h -> inner -> type -> signal_handler)
00893 return (*(h -> inner -> type -> signal_handler)) (h -> inner,
00894 name, ap);
00895 return ISC_R_NOTFOUND;
00896 }
00897
00905 isc_result_t omapi_io_state_foreach (isc_result_t (*func) (omapi_object_t *,
00906 void *),
00907 void *p)
00908 {
00909 omapi_io_object_t *io = NULL;
00910 isc_result_t status;
00911 omapi_io_object_t *next = NULL;
00912
00913
00914
00915
00916
00917
00918
00919
00920 if (omapi_io_states.next) {
00921 omapi_object_reference((omapi_object_t**)&io,
00922 (omapi_object_t*)omapi_io_states.next,
00923 MDL);
00924 }
00925
00926 while(io) {
00927
00928 if (io->next) {
00929 omapi_object_reference((omapi_object_t**)&next,
00930 (omapi_object_t*)io->next, MDL);
00931 }
00932 if (io->inner) {
00933 status = (*func) (io->inner, p);
00934 if (status != ISC_R_SUCCESS) {
00935
00936
00937 omapi_object_dereference((omapi_object_t**)&io, MDL);
00938 if (next) {
00939 omapi_object_dereference((omapi_object_t**)&next, MDL);
00940 }
00941 return status;
00942 }
00943 }
00944
00945 omapi_object_dereference((omapi_object_t**)&io, MDL);
00946 if (next) {
00947 omapi_object_reference((omapi_object_t**)&io,
00948 (omapi_object_t*)next,
00949 MDL);
00950 omapi_object_dereference((omapi_object_t**)&next, MDL);
00951 }
00952 }
00953
00954
00955
00956
00957
00958 return ISC_R_SUCCESS;
00959 }