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