1 /* $NetBSD: callback.c,v 1.3 2022/04/03 01:10:58 christos Exp $ */ 2 3 /* callback.c 4 5 The dhcpctl callback object. */ 6 7 /* 8 * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC") 9 * Copyright (c) 1999-2003 by Internet Software Consortium 10 * 11 * This Source Code Form is subject to the terms of the Mozilla Public 12 * License, v. 2.0. If a copy of the MPL was not distributed with this 13 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 * 23 * Internet Systems Consortium, Inc. 24 * PO Box 360 25 * Newmarket, NH 03857 USA 26 * <info@isc.org> 27 * https://www.isc.org/ 28 * 29 */ 30 31 #include <sys/cdefs.h> 32 __RCSID("$NetBSD: callback.c,v 1.3 2022/04/03 01:10:58 christos Exp $"); 33 34 #include "dhcpd.h" 35 #include <omapip/omapip_p.h> 36 #include "dhcpctl.h" 37 38 /* dhcpctl_set_callback 39 40 synchronous, with asynchronous aftereffect 41 handle is some object upon which some kind of process has been 42 started - e.g., an open, an update or a refresh. 43 data is an anonymous pointer containing some information that 44 the callback will use to figure out what event completed. 45 return value of 0 means callback was successfully set, a nonzero 46 status code is returned otherwise. 47 Upon completion of whatever task is in process, the callback 48 will be passed the handle to the object, a status code 49 indicating what happened, and the anonymous pointer passed to */ 50 51 dhcpctl_status dhcpctl_set_callback (dhcpctl_handle h, void *data, 52 void (*func) (dhcpctl_handle, 53 dhcpctl_status, void *)) 54 { 55 dhcpctl_callback_object_t *callback; 56 omapi_object_t *inner; 57 58 callback = dmalloc (sizeof *callback, MDL); 59 if (!callback) 60 return ISC_R_NOMEMORY; 61 62 /* Tie the callback object to the innermost object in the chain. */ 63 for (inner = h; inner -> inner; inner = inner -> inner) 64 ; 65 omapi_object_reference (&inner -> inner, 66 (omapi_object_t *)callback, MDL); 67 omapi_object_reference ((omapi_object_t **)&callback -> outer, 68 inner, MDL); 69 70 /* Save the actual handle pointer we were passed for the callback. */ 71 omapi_object_reference (&callback -> object, h, MDL); 72 callback -> data = data; 73 callback -> callback = func; 74 75 return ISC_R_SUCCESS; 76 } 77 78 /* Callback methods (not meant to be called directly) */ 79 80 isc_result_t dhcpctl_callback_set_value (omapi_object_t *h, 81 omapi_object_t *id, 82 omapi_data_string_t *name, 83 omapi_typed_data_t *value) 84 { 85 if (h -> type != dhcpctl_callback_type) 86 return DHCP_R_INVALIDARG; 87 88 if (h -> inner && h -> inner -> type -> set_value) 89 return (*(h -> inner -> type -> set_value)) 90 (h -> inner, id, name, value); 91 return ISC_R_NOTFOUND; 92 } 93 94 isc_result_t dhcpctl_callback_get_value (omapi_object_t *h, 95 omapi_object_t *id, 96 omapi_data_string_t *name, 97 omapi_value_t **value) 98 { 99 if (h -> type != dhcpctl_callback_type) 100 return DHCP_R_INVALIDARG; 101 102 if (h -> inner && h -> inner -> type -> get_value) 103 return (*(h -> inner -> type -> get_value)) 104 (h -> inner, id, name, value); 105 return ISC_R_NOTFOUND; 106 } 107 108 isc_result_t dhcpctl_callback_signal_handler (omapi_object_t *o, 109 const char *name, va_list ap) 110 { 111 dhcpctl_callback_object_t *p; 112 isc_result_t waitstatus; 113 114 if (o -> type != dhcpctl_callback_type) 115 return DHCP_R_INVALIDARG; 116 p = (dhcpctl_callback_object_t *)o; 117 118 /* Not a signal we recognize? */ 119 if (strcmp (name, "ready")) { 120 if (p -> inner && p -> inner -> type -> signal_handler) 121 return (*(p -> inner -> type -> signal_handler)) 122 (p -> inner, name, ap); 123 return ISC_R_NOTFOUND; 124 } 125 126 if (p -> object -> type == dhcpctl_remote_type) { 127 waitstatus = (((dhcpctl_remote_object_t *) 128 (p -> object)) -> waitstatus); 129 } else 130 waitstatus = ISC_R_SUCCESS; 131 132 /* Do the callback. */ 133 if (p -> callback) 134 (*(p -> callback)) (p -> object, waitstatus, p -> data); 135 136 return ISC_R_SUCCESS; 137 } 138 139 isc_result_t dhcpctl_callback_destroy (omapi_object_t *h, 140 const char *file, int line) 141 { 142 dhcpctl_callback_object_t *p; 143 if (h -> type != dhcpctl_callback_type) 144 return DHCP_R_INVALIDARG; 145 p = (dhcpctl_callback_object_t *)h; 146 if (p -> handle) 147 omapi_object_dereference ((omapi_object_t **)&p -> handle, 148 file, line); 149 return ISC_R_SUCCESS; 150 } 151 152 /* Write all the published values associated with the object through the 153 specified connection. */ 154 155 isc_result_t dhcpctl_callback_stuff_values (omapi_object_t *c, 156 omapi_object_t *id, 157 omapi_object_t *p) 158 { 159 if (p -> type != dhcpctl_callback_type) 160 return DHCP_R_INVALIDARG; 161 162 if (p -> inner && p -> inner -> type -> stuff_values) 163 return (*(p -> inner -> type -> stuff_values)) (c, id, 164 p -> inner); 165 return ISC_R_SUCCESS; 166 } 167