xref: /minix3/external/bsd/dhcp/dist/dhcpctl/dhcpctl.c (revision 83ee113ee0d94f3844d44065af2311604e9a30ad)
1*83ee113eSDavid van Moolenbroek /*	$NetBSD: dhcpctl.c,v 1.1.1.2 2014/07/12 11:57:52 spz Exp $	*/
2*83ee113eSDavid van Moolenbroek /* dhcpctl.c
3*83ee113eSDavid van Moolenbroek 
4*83ee113eSDavid van Moolenbroek    Subroutines providing general support for objects. */
5*83ee113eSDavid van Moolenbroek 
6*83ee113eSDavid van Moolenbroek /*
7*83ee113eSDavid van Moolenbroek  * Copyright (c) 2009,2013,2014 by Internet Systems Consortium, Inc. ("ISC")
8*83ee113eSDavid van Moolenbroek  * Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC")
9*83ee113eSDavid van Moolenbroek  * Copyright (c) 1999-2003 by Internet Software Consortium
10*83ee113eSDavid van Moolenbroek  *
11*83ee113eSDavid van Moolenbroek  * Permission to use, copy, modify, and distribute this software for any
12*83ee113eSDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
13*83ee113eSDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
14*83ee113eSDavid van Moolenbroek  *
15*83ee113eSDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16*83ee113eSDavid van Moolenbroek  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17*83ee113eSDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
18*83ee113eSDavid van Moolenbroek  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19*83ee113eSDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20*83ee113eSDavid van Moolenbroek  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21*83ee113eSDavid van Moolenbroek  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22*83ee113eSDavid van Moolenbroek  *
23*83ee113eSDavid van Moolenbroek  *   Internet Systems Consortium, Inc.
24*83ee113eSDavid van Moolenbroek  *   950 Charter Street
25*83ee113eSDavid van Moolenbroek  *   Redwood City, CA 94063
26*83ee113eSDavid van Moolenbroek  *   <info@isc.org>
27*83ee113eSDavid van Moolenbroek  *   https://www.isc.org/
28*83ee113eSDavid van Moolenbroek  *
29*83ee113eSDavid van Moolenbroek  */
30*83ee113eSDavid van Moolenbroek 
31*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
32*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: dhcpctl.c,v 1.1.1.2 2014/07/12 11:57:52 spz Exp $");
33*83ee113eSDavid van Moolenbroek 
34*83ee113eSDavid van Moolenbroek #include "dhcpd.h"
35*83ee113eSDavid van Moolenbroek #include <omapip/omapip_p.h>
36*83ee113eSDavid van Moolenbroek #include "dhcpctl.h"
37*83ee113eSDavid van Moolenbroek 
38*83ee113eSDavid van Moolenbroek omapi_object_type_t *dhcpctl_callback_type;
39*83ee113eSDavid van Moolenbroek omapi_object_type_t *dhcpctl_remote_type;
40*83ee113eSDavid van Moolenbroek 
41*83ee113eSDavid van Moolenbroek /* dhcpctl_initialize ()
42*83ee113eSDavid van Moolenbroek 
43*83ee113eSDavid van Moolenbroek    Must be called before any other dhcpctl function. */
44*83ee113eSDavid van Moolenbroek 
dhcpctl_initialize()45*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_initialize ()
46*83ee113eSDavid van Moolenbroek {
47*83ee113eSDavid van Moolenbroek 	isc_result_t status;
48*83ee113eSDavid van Moolenbroek 
49*83ee113eSDavid van Moolenbroek 	/* Set up the isc and dns library managers */
50*83ee113eSDavid van Moolenbroek 	status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
51*83ee113eSDavid van Moolenbroek 				     NULL, NULL);
52*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
53*83ee113eSDavid van Moolenbroek 		return status;
54*83ee113eSDavid van Moolenbroek 
55*83ee113eSDavid van Moolenbroek 	status = omapi_init();
56*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
57*83ee113eSDavid van Moolenbroek 		return status;
58*83ee113eSDavid van Moolenbroek 
59*83ee113eSDavid van Moolenbroek 	status = omapi_object_type_register (&dhcpctl_callback_type,
60*83ee113eSDavid van Moolenbroek 					     "dhcpctl-callback",
61*83ee113eSDavid van Moolenbroek 					     dhcpctl_callback_set_value,
62*83ee113eSDavid van Moolenbroek 					     dhcpctl_callback_get_value,
63*83ee113eSDavid van Moolenbroek 					     dhcpctl_callback_destroy,
64*83ee113eSDavid van Moolenbroek 					     dhcpctl_callback_signal_handler,
65*83ee113eSDavid van Moolenbroek 					     dhcpctl_callback_stuff_values,
66*83ee113eSDavid van Moolenbroek 					     0, 0, 0, 0, 0, 0,
67*83ee113eSDavid van Moolenbroek 					     sizeof
68*83ee113eSDavid van Moolenbroek 					     (dhcpctl_callback_object_t), 0,
69*83ee113eSDavid van Moolenbroek 					     RC_MISC);
70*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
71*83ee113eSDavid van Moolenbroek 		return status;
72*83ee113eSDavid van Moolenbroek 
73*83ee113eSDavid van Moolenbroek 	status = omapi_object_type_register (&dhcpctl_remote_type,
74*83ee113eSDavid van Moolenbroek 					     "dhcpctl-remote",
75*83ee113eSDavid van Moolenbroek 					     dhcpctl_remote_set_value,
76*83ee113eSDavid van Moolenbroek 					     dhcpctl_remote_get_value,
77*83ee113eSDavid van Moolenbroek 					     dhcpctl_remote_destroy,
78*83ee113eSDavid van Moolenbroek 					     dhcpctl_remote_signal_handler,
79*83ee113eSDavid van Moolenbroek 					     dhcpctl_remote_stuff_values,
80*83ee113eSDavid van Moolenbroek 					     0, 0, 0, 0, 0, 0,
81*83ee113eSDavid van Moolenbroek 					     sizeof (dhcpctl_remote_object_t),
82*83ee113eSDavid van Moolenbroek 					     0, RC_MISC);
83*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
84*83ee113eSDavid van Moolenbroek 		return status;
85*83ee113eSDavid van Moolenbroek 
86*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
87*83ee113eSDavid van Moolenbroek }
88*83ee113eSDavid van Moolenbroek 
89*83ee113eSDavid van Moolenbroek /* dhcpctl_connect
90*83ee113eSDavid van Moolenbroek 
91*83ee113eSDavid van Moolenbroek    synchronous
92*83ee113eSDavid van Moolenbroek    returns nonzero status code if it didn't connect, zero otherwise
93*83ee113eSDavid van Moolenbroek    stores connection handle through connection, which can be used
94*83ee113eSDavid van Moolenbroek    for subsequent access to the specified server.
95*83ee113eSDavid van Moolenbroek    server_name is the name of the server, and port is the TCP
96*83ee113eSDavid van Moolenbroek    port on which it is listening.
97*83ee113eSDavid van Moolenbroek    authinfo is the handle to an object containing authentication
98*83ee113eSDavid van Moolenbroek    information. */
99*83ee113eSDavid van Moolenbroek 
dhcpctl_connect(dhcpctl_handle * connection,const char * server_name,int port,dhcpctl_handle authinfo)100*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection,
101*83ee113eSDavid van Moolenbroek 				const char *server_name, int port,
102*83ee113eSDavid van Moolenbroek 				dhcpctl_handle authinfo)
103*83ee113eSDavid van Moolenbroek {
104*83ee113eSDavid van Moolenbroek 	isc_result_t status;
105*83ee113eSDavid van Moolenbroek 
106*83ee113eSDavid van Moolenbroek 	status = omapi_generic_new (connection, MDL);
107*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
108*83ee113eSDavid van Moolenbroek 		return status;
109*83ee113eSDavid van Moolenbroek 	}
110*83ee113eSDavid van Moolenbroek 
111*83ee113eSDavid van Moolenbroek 	status = omapi_protocol_connect (*connection, server_name,
112*83ee113eSDavid van Moolenbroek 					 (unsigned)port, authinfo);
113*83ee113eSDavid van Moolenbroek 	if (status == ISC_R_SUCCESS)
114*83ee113eSDavid van Moolenbroek 		return status;
115*83ee113eSDavid van Moolenbroek 	if (status != DHCP_R_INCOMPLETE) {
116*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (connection, MDL);
117*83ee113eSDavid van Moolenbroek 		return status;
118*83ee113eSDavid van Moolenbroek 	}
119*83ee113eSDavid van Moolenbroek 
120*83ee113eSDavid van Moolenbroek 	status = omapi_wait_for_completion (*connection, 0);
121*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
122*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (connection, MDL);
123*83ee113eSDavid van Moolenbroek 		return status;
124*83ee113eSDavid van Moolenbroek 	}
125*83ee113eSDavid van Moolenbroek 
126*83ee113eSDavid van Moolenbroek 	return status;
127*83ee113eSDavid van Moolenbroek }
128*83ee113eSDavid van Moolenbroek 
129*83ee113eSDavid van Moolenbroek /* dhcpctl_wait_for_completion
130*83ee113eSDavid van Moolenbroek 
131*83ee113eSDavid van Moolenbroek    synchronous
132*83ee113eSDavid van Moolenbroek    returns zero if the callback completes, a nonzero status if
133*83ee113eSDavid van Moolenbroek    there was some problem relating to the wait operation.   The
134*83ee113eSDavid van Moolenbroek    status of the queued request will be stored through s, and
135*83ee113eSDavid van Moolenbroek    will also be either zero for success or nonzero for some kind
136*83ee113eSDavid van Moolenbroek    of failure.    Never returns until completion or until the
137*83ee113eSDavid van Moolenbroek    connection to the server is lost.   This performs the same
138*83ee113eSDavid van Moolenbroek    function as dhcpctl_set_callback and the subsequent callback,
139*83ee113eSDavid van Moolenbroek    for programs that want to do inline execution instead of using
140*83ee113eSDavid van Moolenbroek    callbacks. */
141*83ee113eSDavid van Moolenbroek 
dhcpctl_wait_for_completion(dhcpctl_handle h,dhcpctl_status * s)142*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle h,
143*83ee113eSDavid van Moolenbroek 					    dhcpctl_status *s)
144*83ee113eSDavid van Moolenbroek {
145*83ee113eSDavid van Moolenbroek 	isc_result_t status;
146*83ee113eSDavid van Moolenbroek 	status = omapi_wait_for_completion (h, 0);
147*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
148*83ee113eSDavid van Moolenbroek 		return status;
149*83ee113eSDavid van Moolenbroek 	if (h -> type == dhcpctl_remote_type)
150*83ee113eSDavid van Moolenbroek 		*s = ((dhcpctl_remote_object_t *)h) -> waitstatus;
151*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
152*83ee113eSDavid van Moolenbroek }
153*83ee113eSDavid van Moolenbroek 
154*83ee113eSDavid van Moolenbroek /* dhcpctl_get_value
155*83ee113eSDavid van Moolenbroek 
156*83ee113eSDavid van Moolenbroek    synchronous
157*83ee113eSDavid van Moolenbroek    returns zero if the call succeeded, a nonzero status code if
158*83ee113eSDavid van Moolenbroek    it didn't.
159*83ee113eSDavid van Moolenbroek    result is the address of an empty data string (initialized
160*83ee113eSDavid van Moolenbroek    with bzero or cleared with data_string_forget).   On
161*83ee113eSDavid van Moolenbroek    successful completion, the addressed data string will contain
162*83ee113eSDavid van Moolenbroek    the value that was fetched.
163*83ee113eSDavid van Moolenbroek    dhcpctl_handle refers to some dhcpctl item
164*83ee113eSDavid van Moolenbroek    value_name refers to some value related to that item - e.g.,
165*83ee113eSDavid van Moolenbroek    for a handle associated with a completed host lookup, value
166*83ee113eSDavid van Moolenbroek    could be one of "hardware-address", "dhcp-client-identifier",
167*83ee113eSDavid van Moolenbroek    "known" or "client-hostname". */
168*83ee113eSDavid van Moolenbroek 
dhcpctl_get_value(dhcpctl_data_string * result,dhcpctl_handle h,const char * value_name)169*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_get_value (dhcpctl_data_string *result,
170*83ee113eSDavid van Moolenbroek 				  dhcpctl_handle h, const char *value_name)
171*83ee113eSDavid van Moolenbroek {
172*83ee113eSDavid van Moolenbroek 	isc_result_t status;
173*83ee113eSDavid van Moolenbroek 	omapi_value_t *tv = (omapi_value_t *)0;
174*83ee113eSDavid van Moolenbroek 	unsigned len;
175*83ee113eSDavid van Moolenbroek 	int ip;
176*83ee113eSDavid van Moolenbroek 
177*83ee113eSDavid van Moolenbroek 	status = omapi_get_value_str (h, (omapi_object_t *)0, value_name, &tv);
178*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
179*83ee113eSDavid van Moolenbroek 		return status;
180*83ee113eSDavid van Moolenbroek 
181*83ee113eSDavid van Moolenbroek 	switch (tv -> value -> type) {
182*83ee113eSDavid van Moolenbroek 	      case omapi_datatype_int:
183*83ee113eSDavid van Moolenbroek 		len = sizeof (int);
184*83ee113eSDavid van Moolenbroek 		break;
185*83ee113eSDavid van Moolenbroek 
186*83ee113eSDavid van Moolenbroek 	      case omapi_datatype_string:
187*83ee113eSDavid van Moolenbroek 	      case omapi_datatype_data:
188*83ee113eSDavid van Moolenbroek 		len = tv -> value -> u.buffer.len;
189*83ee113eSDavid van Moolenbroek 		break;
190*83ee113eSDavid van Moolenbroek 
191*83ee113eSDavid van Moolenbroek 	      case omapi_datatype_object:
192*83ee113eSDavid van Moolenbroek 		len = sizeof (omapi_handle_t);
193*83ee113eSDavid van Moolenbroek 		break;
194*83ee113eSDavid van Moolenbroek 
195*83ee113eSDavid van Moolenbroek 	      default:
196*83ee113eSDavid van Moolenbroek 		omapi_typed_data_dereference (&tv -> value, MDL);
197*83ee113eSDavid van Moolenbroek 		return ISC_R_UNEXPECTED;
198*83ee113eSDavid van Moolenbroek 	}
199*83ee113eSDavid van Moolenbroek 
200*83ee113eSDavid van Moolenbroek 	status = omapi_data_string_new (result, len, MDL);
201*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
202*83ee113eSDavid van Moolenbroek 		omapi_typed_data_dereference (&tv -> value, MDL);
203*83ee113eSDavid van Moolenbroek 		return status;
204*83ee113eSDavid van Moolenbroek 	}
205*83ee113eSDavid van Moolenbroek 
206*83ee113eSDavid van Moolenbroek 	switch (tv -> value -> type) {
207*83ee113eSDavid van Moolenbroek 	      case omapi_datatype_int:
208*83ee113eSDavid van Moolenbroek 		ip = htonl (tv -> value -> u.integer);
209*83ee113eSDavid van Moolenbroek 		memcpy ((*result) -> value, &ip, sizeof ip);
210*83ee113eSDavid van Moolenbroek 		break;
211*83ee113eSDavid van Moolenbroek 
212*83ee113eSDavid van Moolenbroek 	      case omapi_datatype_string:
213*83ee113eSDavid van Moolenbroek 	      case omapi_datatype_data:
214*83ee113eSDavid van Moolenbroek 		memcpy ((*result) -> value,
215*83ee113eSDavid van Moolenbroek 			tv -> value -> u.buffer.value,
216*83ee113eSDavid van Moolenbroek 			tv -> value -> u.buffer.len);
217*83ee113eSDavid van Moolenbroek 		break;
218*83ee113eSDavid van Moolenbroek 
219*83ee113eSDavid van Moolenbroek 	      case omapi_datatype_object:
220*83ee113eSDavid van Moolenbroek 		ip = htonl (tv -> value -> u.object -> handle);
221*83ee113eSDavid van Moolenbroek 		memcpy ((*result) -> value, &ip, sizeof ip);
222*83ee113eSDavid van Moolenbroek 		break;
223*83ee113eSDavid van Moolenbroek 	}
224*83ee113eSDavid van Moolenbroek 
225*83ee113eSDavid van Moolenbroek 	omapi_value_dereference (&tv, MDL);
226*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
227*83ee113eSDavid van Moolenbroek }
228*83ee113eSDavid van Moolenbroek 
229*83ee113eSDavid van Moolenbroek /* dhcpctl_get_boolean
230*83ee113eSDavid van Moolenbroek 
231*83ee113eSDavid van Moolenbroek    like dhcpctl_get_value, but more convenient for boolean
232*83ee113eSDavid van Moolenbroek    values, since no data_string needs to be dealt with. */
233*83ee113eSDavid van Moolenbroek 
dhcpctl_get_boolean(int * result,dhcpctl_handle h,const char * value_name)234*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_get_boolean (int *result,
235*83ee113eSDavid van Moolenbroek 				    dhcpctl_handle h, const char *value_name)
236*83ee113eSDavid van Moolenbroek {
237*83ee113eSDavid van Moolenbroek 	isc_result_t status;
238*83ee113eSDavid van Moolenbroek 	dhcpctl_data_string data = (dhcpctl_data_string)0;
239*83ee113eSDavid van Moolenbroek 	int rv;
240*83ee113eSDavid van Moolenbroek 
241*83ee113eSDavid van Moolenbroek 	status = dhcpctl_get_value (&data, h, value_name);
242*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
243*83ee113eSDavid van Moolenbroek 		return status;
244*83ee113eSDavid van Moolenbroek 	if (data -> len != sizeof rv) {
245*83ee113eSDavid van Moolenbroek 		omapi_data_string_dereference (&data, MDL);
246*83ee113eSDavid van Moolenbroek 		return ISC_R_UNEXPECTED;
247*83ee113eSDavid van Moolenbroek 	}
248*83ee113eSDavid van Moolenbroek 	memcpy (&rv, data -> value, sizeof rv);
249*83ee113eSDavid van Moolenbroek 	*result = ntohl (rv);
250*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
251*83ee113eSDavid van Moolenbroek }
252*83ee113eSDavid van Moolenbroek 
253*83ee113eSDavid van Moolenbroek /* dhcpctl_set_value
254*83ee113eSDavid van Moolenbroek 
255*83ee113eSDavid van Moolenbroek    Sets a value on an object referred to by a dhcpctl_handle.
256*83ee113eSDavid van Moolenbroek    The opposite of dhcpctl_get_value.   Does not update the
257*83ee113eSDavid van Moolenbroek    server - just sets the value on the handle. */
258*83ee113eSDavid van Moolenbroek 
dhcpctl_set_value(dhcpctl_handle h,dhcpctl_data_string value,const char * value_name)259*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_set_value (dhcpctl_handle h, dhcpctl_data_string value,
260*83ee113eSDavid van Moolenbroek 				  const char *value_name)
261*83ee113eSDavid van Moolenbroek {
262*83ee113eSDavid van Moolenbroek 	isc_result_t status;
263*83ee113eSDavid van Moolenbroek 	omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
264*83ee113eSDavid van Moolenbroek 	omapi_data_string_t *name = (omapi_data_string_t *)0;
265*83ee113eSDavid van Moolenbroek 
266*83ee113eSDavid van Moolenbroek 	status = omapi_data_string_new (&name, strlen (value_name), MDL);
267*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
268*83ee113eSDavid van Moolenbroek 		return status;
269*83ee113eSDavid van Moolenbroek 	memcpy (name -> value, value_name, strlen (value_name));
270*83ee113eSDavid van Moolenbroek 
271*83ee113eSDavid van Moolenbroek 	status = omapi_typed_data_new (MDL, &tv, omapi_datatype_data,
272*83ee113eSDavid van Moolenbroek 				       value -> len);
273*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
274*83ee113eSDavid van Moolenbroek 		omapi_data_string_dereference (&name, MDL);
275*83ee113eSDavid van Moolenbroek 		return status;
276*83ee113eSDavid van Moolenbroek 	}
277*83ee113eSDavid van Moolenbroek 	memcpy (tv -> u.buffer.value, value -> value, value -> len);
278*83ee113eSDavid van Moolenbroek 
279*83ee113eSDavid van Moolenbroek 	status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
280*83ee113eSDavid van Moolenbroek 	omapi_data_string_dereference (&name, MDL);
281*83ee113eSDavid van Moolenbroek 	omapi_typed_data_dereference (&tv, MDL);
282*83ee113eSDavid van Moolenbroek 	return status;
283*83ee113eSDavid van Moolenbroek }
284*83ee113eSDavid van Moolenbroek 
285*83ee113eSDavid van Moolenbroek /* dhcpctl_set_string_value
286*83ee113eSDavid van Moolenbroek 
287*83ee113eSDavid van Moolenbroek    Sets a NUL-terminated ASCII value on an object referred to by
288*83ee113eSDavid van Moolenbroek    a dhcpctl_handle.   like dhcpctl_set_value, but saves the
289*83ee113eSDavid van Moolenbroek    trouble of creating a data_string for a NUL-terminated string.
290*83ee113eSDavid van Moolenbroek    Does not update the server - just sets the value on the handle. */
291*83ee113eSDavid van Moolenbroek 
dhcpctl_set_string_value(dhcpctl_handle h,const char * value,const char * value_name)292*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle h, const char *value,
293*83ee113eSDavid van Moolenbroek 					 const char *value_name)
294*83ee113eSDavid van Moolenbroek {
295*83ee113eSDavid van Moolenbroek 	isc_result_t status;
296*83ee113eSDavid van Moolenbroek 	omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
297*83ee113eSDavid van Moolenbroek 	omapi_data_string_t *name = (omapi_data_string_t *)0;
298*83ee113eSDavid van Moolenbroek 
299*83ee113eSDavid van Moolenbroek 	status = omapi_data_string_new (&name, strlen (value_name), MDL);
300*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
301*83ee113eSDavid van Moolenbroek 		return status;
302*83ee113eSDavid van Moolenbroek 	memcpy (name -> value, value_name, strlen (value_name));
303*83ee113eSDavid van Moolenbroek 
304*83ee113eSDavid van Moolenbroek 	status = omapi_typed_data_new (MDL, &tv, omapi_datatype_string, value);
305*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
306*83ee113eSDavid van Moolenbroek 		omapi_data_string_dereference (&name, MDL);
307*83ee113eSDavid van Moolenbroek 		return status;
308*83ee113eSDavid van Moolenbroek 	}
309*83ee113eSDavid van Moolenbroek 
310*83ee113eSDavid van Moolenbroek 	status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
311*83ee113eSDavid van Moolenbroek 	omapi_data_string_dereference (&name, MDL);
312*83ee113eSDavid van Moolenbroek 	omapi_typed_data_dereference (&tv, MDL);
313*83ee113eSDavid van Moolenbroek 	return status;
314*83ee113eSDavid van Moolenbroek }
315*83ee113eSDavid van Moolenbroek 
316*83ee113eSDavid van Moolenbroek /* dhcpctl_set_buffer_value
317*83ee113eSDavid van Moolenbroek 
318*83ee113eSDavid van Moolenbroek    Sets a value on an object referred to by a dhcpctl_handle.  like
319*83ee113eSDavid van Moolenbroek    dhcpctl_set_value, but saves the trouble of creating a data_string
320*83ee113eSDavid van Moolenbroek    for string for which we have a buffer and length.  Does not update
321*83ee113eSDavid van Moolenbroek    the server - just sets the value on the handle. */
322*83ee113eSDavid van Moolenbroek 
dhcpctl_set_data_value(dhcpctl_handle h,const char * value,unsigned len,const char * value_name)323*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle h,
324*83ee113eSDavid van Moolenbroek 				       const char *value, unsigned len,
325*83ee113eSDavid van Moolenbroek 				       const char *value_name)
326*83ee113eSDavid van Moolenbroek {
327*83ee113eSDavid van Moolenbroek 	isc_result_t status;
328*83ee113eSDavid van Moolenbroek 	omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
329*83ee113eSDavid van Moolenbroek 	omapi_data_string_t *name = (omapi_data_string_t *)0;
330*83ee113eSDavid van Moolenbroek 	unsigned ll;
331*83ee113eSDavid van Moolenbroek 
332*83ee113eSDavid van Moolenbroek 	ll = strlen (value_name);
333*83ee113eSDavid van Moolenbroek 	status = omapi_data_string_new (&name, ll, MDL);
334*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
335*83ee113eSDavid van Moolenbroek 		return status;
336*83ee113eSDavid van Moolenbroek 	memcpy (name -> value, value_name, ll);
337*83ee113eSDavid van Moolenbroek 
338*83ee113eSDavid van Moolenbroek 	status = omapi_typed_data_new (MDL, &tv,
339*83ee113eSDavid van Moolenbroek 				       omapi_datatype_data, len, value);
340*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
341*83ee113eSDavid van Moolenbroek 		omapi_data_string_dereference (&name, MDL);
342*83ee113eSDavid van Moolenbroek 		return status;
343*83ee113eSDavid van Moolenbroek 	}
344*83ee113eSDavid van Moolenbroek 	memcpy (tv -> u.buffer.value, value, len);
345*83ee113eSDavid van Moolenbroek 
346*83ee113eSDavid van Moolenbroek 	status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
347*83ee113eSDavid van Moolenbroek 	omapi_data_string_dereference (&name, MDL);
348*83ee113eSDavid van Moolenbroek 	omapi_typed_data_dereference (&tv, MDL);
349*83ee113eSDavid van Moolenbroek 	return status;
350*83ee113eSDavid van Moolenbroek }
351*83ee113eSDavid van Moolenbroek 
352*83ee113eSDavid van Moolenbroek /* dhcpctl_set_null_value
353*83ee113eSDavid van Moolenbroek 
354*83ee113eSDavid van Moolenbroek    Sets a null value on an object referred to by a dhcpctl_handle. */
355*83ee113eSDavid van Moolenbroek 
dhcpctl_set_null_value(dhcpctl_handle h,const char * value_name)356*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_set_null_value (dhcpctl_handle h,
357*83ee113eSDavid van Moolenbroek 				       const char *value_name)
358*83ee113eSDavid van Moolenbroek {
359*83ee113eSDavid van Moolenbroek 	isc_result_t status;
360*83ee113eSDavid van Moolenbroek 	omapi_data_string_t *name = (omapi_data_string_t *)0;
361*83ee113eSDavid van Moolenbroek 	unsigned ll;
362*83ee113eSDavid van Moolenbroek 
363*83ee113eSDavid van Moolenbroek 	ll = strlen (value_name);
364*83ee113eSDavid van Moolenbroek 	status = omapi_data_string_new (&name, ll, MDL);
365*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
366*83ee113eSDavid van Moolenbroek 		return status;
367*83ee113eSDavid van Moolenbroek 	memcpy (name -> value, value_name, ll);
368*83ee113eSDavid van Moolenbroek 
369*83ee113eSDavid van Moolenbroek 	status = omapi_set_value (h, (omapi_object_t *)0, name,
370*83ee113eSDavid van Moolenbroek 				  (omapi_typed_data_t *)0);
371*83ee113eSDavid van Moolenbroek 	omapi_data_string_dereference (&name, MDL);
372*83ee113eSDavid van Moolenbroek 	return status;
373*83ee113eSDavid van Moolenbroek }
374*83ee113eSDavid van Moolenbroek 
375*83ee113eSDavid van Moolenbroek /* dhcpctl_set_boolean_value
376*83ee113eSDavid van Moolenbroek 
377*83ee113eSDavid van Moolenbroek    Sets a boolean value on an object - like dhcpctl_set_value,
378*83ee113eSDavid van Moolenbroek    only more convenient for booleans. */
379*83ee113eSDavid van Moolenbroek 
dhcpctl_set_boolean_value(dhcpctl_handle h,int value,const char * value_name)380*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_set_boolean_value (dhcpctl_handle h, int value,
381*83ee113eSDavid van Moolenbroek 					  const char *value_name)
382*83ee113eSDavid van Moolenbroek {
383*83ee113eSDavid van Moolenbroek 	isc_result_t status;
384*83ee113eSDavid van Moolenbroek 	omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
385*83ee113eSDavid van Moolenbroek 	omapi_data_string_t *name = (omapi_data_string_t *)0;
386*83ee113eSDavid van Moolenbroek 
387*83ee113eSDavid van Moolenbroek 	status = omapi_data_string_new (&name, strlen (value_name), MDL);
388*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
389*83ee113eSDavid van Moolenbroek 		return status;
390*83ee113eSDavid van Moolenbroek 	memcpy (name -> value, value_name, strlen (value_name));
391*83ee113eSDavid van Moolenbroek 
392*83ee113eSDavid van Moolenbroek 	status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
393*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
394*83ee113eSDavid van Moolenbroek 		omapi_data_string_dereference (&name, MDL);
395*83ee113eSDavid van Moolenbroek 		return status;
396*83ee113eSDavid van Moolenbroek 	}
397*83ee113eSDavid van Moolenbroek 
398*83ee113eSDavid van Moolenbroek 	status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
399*83ee113eSDavid van Moolenbroek 	omapi_data_string_dereference (&name, MDL);
400*83ee113eSDavid van Moolenbroek 	omapi_typed_data_dereference (&tv, MDL);
401*83ee113eSDavid van Moolenbroek 	return status;
402*83ee113eSDavid van Moolenbroek }
403*83ee113eSDavid van Moolenbroek 
404*83ee113eSDavid van Moolenbroek /* dhcpctl_set_int_value
405*83ee113eSDavid van Moolenbroek 
406*83ee113eSDavid van Moolenbroek    Sets a boolean value on an object - like dhcpctl_set_value,
407*83ee113eSDavid van Moolenbroek    only more convenient for booleans. */
408*83ee113eSDavid van Moolenbroek 
dhcpctl_set_int_value(dhcpctl_handle h,int value,const char * value_name)409*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_set_int_value (dhcpctl_handle h, int value,
410*83ee113eSDavid van Moolenbroek 				      const char *value_name)
411*83ee113eSDavid van Moolenbroek {
412*83ee113eSDavid van Moolenbroek 	isc_result_t status;
413*83ee113eSDavid van Moolenbroek 	omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
414*83ee113eSDavid van Moolenbroek 	omapi_data_string_t *name = (omapi_data_string_t *)0;
415*83ee113eSDavid van Moolenbroek 
416*83ee113eSDavid van Moolenbroek 	status = omapi_data_string_new (&name, strlen (value_name), MDL);
417*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
418*83ee113eSDavid van Moolenbroek 		return status;
419*83ee113eSDavid van Moolenbroek 	memcpy (name -> value, value_name, strlen (value_name));
420*83ee113eSDavid van Moolenbroek 
421*83ee113eSDavid van Moolenbroek 	status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
422*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
423*83ee113eSDavid van Moolenbroek 		omapi_data_string_dereference (&name, MDL);
424*83ee113eSDavid van Moolenbroek 		return status;
425*83ee113eSDavid van Moolenbroek 	}
426*83ee113eSDavid van Moolenbroek 
427*83ee113eSDavid van Moolenbroek 	status = omapi_set_value (h, (omapi_object_t *)0, name, tv);
428*83ee113eSDavid van Moolenbroek 	omapi_data_string_dereference (&name, MDL);
429*83ee113eSDavid van Moolenbroek 	omapi_typed_data_dereference (&tv, MDL);
430*83ee113eSDavid van Moolenbroek 	return status;
431*83ee113eSDavid van Moolenbroek }
432*83ee113eSDavid van Moolenbroek 
433*83ee113eSDavid van Moolenbroek /* dhcpctl_object_update
434*83ee113eSDavid van Moolenbroek 
435*83ee113eSDavid van Moolenbroek    Queues an update on the object referenced by the handle (there
436*83ee113eSDavid van Moolenbroek    can't be any other work in progress on the handle).   An
437*83ee113eSDavid van Moolenbroek    update means local parameters will be sent to the server. */
438*83ee113eSDavid van Moolenbroek 
dhcpctl_object_update(dhcpctl_handle connection,dhcpctl_handle h)439*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_object_update (dhcpctl_handle connection,
440*83ee113eSDavid van Moolenbroek 				      dhcpctl_handle h)
441*83ee113eSDavid van Moolenbroek {
442*83ee113eSDavid van Moolenbroek 	isc_result_t status;
443*83ee113eSDavid van Moolenbroek 	omapi_object_t *message = (omapi_object_t *)0;
444*83ee113eSDavid van Moolenbroek 	dhcpctl_remote_object_t *ro;
445*83ee113eSDavid van Moolenbroek 
446*83ee113eSDavid van Moolenbroek 	if (h -> type != dhcpctl_remote_type)
447*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
448*83ee113eSDavid van Moolenbroek 	ro = (dhcpctl_remote_object_t *)h;
449*83ee113eSDavid van Moolenbroek 
450*83ee113eSDavid van Moolenbroek 	status = omapi_message_new (&message, MDL);
451*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
452*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&message, MDL);
453*83ee113eSDavid van Moolenbroek 		return status;
454*83ee113eSDavid van Moolenbroek 	}
455*83ee113eSDavid van Moolenbroek 	status = omapi_set_int_value (message, (omapi_object_t *)0,
456*83ee113eSDavid van Moolenbroek 				      "op", OMAPI_OP_UPDATE);
457*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
458*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&message, MDL);
459*83ee113eSDavid van Moolenbroek 		return status;
460*83ee113eSDavid van Moolenbroek 	}
461*83ee113eSDavid van Moolenbroek 
462*83ee113eSDavid van Moolenbroek 	status = omapi_set_object_value (message, (omapi_object_t *)0,
463*83ee113eSDavid van Moolenbroek 					 "object", h);
464*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
465*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&message, MDL);
466*83ee113eSDavid van Moolenbroek 		return status;
467*83ee113eSDavid van Moolenbroek 	}
468*83ee113eSDavid van Moolenbroek 
469*83ee113eSDavid van Moolenbroek 	status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
470*83ee113eSDavid van Moolenbroek 				      (int)(ro -> remote_handle));
471*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
472*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&message, MDL);
473*83ee113eSDavid van Moolenbroek 		return status;
474*83ee113eSDavid van Moolenbroek 	}
475*83ee113eSDavid van Moolenbroek 
476*83ee113eSDavid van Moolenbroek 	omapi_message_register (message);
477*83ee113eSDavid van Moolenbroek 	status = omapi_protocol_send_message (connection -> outer,
478*83ee113eSDavid van Moolenbroek 					      (omapi_object_t *)0,
479*83ee113eSDavid van Moolenbroek 					      message, (omapi_object_t *)0);
480*83ee113eSDavid van Moolenbroek 	omapi_object_dereference (&message, MDL);
481*83ee113eSDavid van Moolenbroek 	return status;
482*83ee113eSDavid van Moolenbroek }
483*83ee113eSDavid van Moolenbroek 
484*83ee113eSDavid van Moolenbroek /* Requests a refresh on the object referenced by the handle (there
485*83ee113eSDavid van Moolenbroek    can't be any other work in progress on the handle).   A
486*83ee113eSDavid van Moolenbroek    refresh means local parameters are updated from the server. */
487*83ee113eSDavid van Moolenbroek 
dhcpctl_object_refresh(dhcpctl_handle connection,dhcpctl_handle h)488*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_object_refresh (dhcpctl_handle connection,
489*83ee113eSDavid van Moolenbroek 				       dhcpctl_handle h)
490*83ee113eSDavid van Moolenbroek {
491*83ee113eSDavid van Moolenbroek 	isc_result_t status;
492*83ee113eSDavid van Moolenbroek 	omapi_object_t *message = (omapi_object_t *)0;
493*83ee113eSDavid van Moolenbroek 	dhcpctl_remote_object_t *ro;
494*83ee113eSDavid van Moolenbroek 
495*83ee113eSDavid van Moolenbroek 	if (h -> type != dhcpctl_remote_type)
496*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
497*83ee113eSDavid van Moolenbroek 	ro = (dhcpctl_remote_object_t *)h;
498*83ee113eSDavid van Moolenbroek 
499*83ee113eSDavid van Moolenbroek 	status = omapi_message_new (&message, MDL);
500*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
501*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&message, MDL);
502*83ee113eSDavid van Moolenbroek 		return status;
503*83ee113eSDavid van Moolenbroek 	}
504*83ee113eSDavid van Moolenbroek 	status = omapi_set_int_value (message, (omapi_object_t *)0,
505*83ee113eSDavid van Moolenbroek 				      "op", OMAPI_OP_REFRESH);
506*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
507*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&message, MDL);
508*83ee113eSDavid van Moolenbroek 		return status;
509*83ee113eSDavid van Moolenbroek 	}
510*83ee113eSDavid van Moolenbroek 	status = omapi_set_int_value (message, (omapi_object_t *)0,
511*83ee113eSDavid van Moolenbroek 				      "handle", (int)(ro -> remote_handle));
512*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
513*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&message, MDL);
514*83ee113eSDavid van Moolenbroek 		return status;
515*83ee113eSDavid van Moolenbroek 	}
516*83ee113eSDavid van Moolenbroek 
517*83ee113eSDavid van Moolenbroek 	omapi_message_register (message);
518*83ee113eSDavid van Moolenbroek 	status = omapi_protocol_send_message (connection -> outer,
519*83ee113eSDavid van Moolenbroek 					      (omapi_object_t *)0,
520*83ee113eSDavid van Moolenbroek 					      message, (omapi_object_t *)0);
521*83ee113eSDavid van Moolenbroek 
522*83ee113eSDavid van Moolenbroek 	/* We don't want to send the contents of the object down the
523*83ee113eSDavid van Moolenbroek 	   wire, but we do need to reference it so that we know what
524*83ee113eSDavid van Moolenbroek 	   to do with the update. */
525*83ee113eSDavid van Moolenbroek 	status = omapi_set_object_value (message, (omapi_object_t *)0,
526*83ee113eSDavid van Moolenbroek 					 "object", h);
527*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
528*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&message, MDL);
529*83ee113eSDavid van Moolenbroek 		return status;
530*83ee113eSDavid van Moolenbroek 	}
531*83ee113eSDavid van Moolenbroek 
532*83ee113eSDavid van Moolenbroek 	omapi_object_dereference (&message, MDL);
533*83ee113eSDavid van Moolenbroek 	return status;
534*83ee113eSDavid van Moolenbroek }
535*83ee113eSDavid van Moolenbroek 
536*83ee113eSDavid van Moolenbroek /* Requests the removal of the object referenced by the handle (there
537*83ee113eSDavid van Moolenbroek    can't be any other work in progress on the handle).   A
538*83ee113eSDavid van Moolenbroek    removal means that all searchable references to the object on the
539*83ee113eSDavid van Moolenbroek    server are deleted. */
540*83ee113eSDavid van Moolenbroek 
dhcpctl_object_remove(dhcpctl_handle connection,dhcpctl_handle h)541*83ee113eSDavid van Moolenbroek dhcpctl_status dhcpctl_object_remove (dhcpctl_handle connection,
542*83ee113eSDavid van Moolenbroek 				      dhcpctl_handle h)
543*83ee113eSDavid van Moolenbroek {
544*83ee113eSDavid van Moolenbroek 	isc_result_t status;
545*83ee113eSDavid van Moolenbroek 	omapi_object_t *message = (omapi_object_t *)0;
546*83ee113eSDavid van Moolenbroek 	dhcpctl_remote_object_t *ro;
547*83ee113eSDavid van Moolenbroek 
548*83ee113eSDavid van Moolenbroek 	if (h -> type != dhcpctl_remote_type)
549*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
550*83ee113eSDavid van Moolenbroek 	ro = (dhcpctl_remote_object_t *)h;
551*83ee113eSDavid van Moolenbroek 
552*83ee113eSDavid van Moolenbroek 	status = omapi_message_new (&message, MDL);
553*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
554*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&message, MDL);
555*83ee113eSDavid van Moolenbroek 		return status;
556*83ee113eSDavid van Moolenbroek 	}
557*83ee113eSDavid van Moolenbroek 	status = omapi_set_int_value (message, (omapi_object_t *)0,
558*83ee113eSDavid van Moolenbroek 				      "op", OMAPI_OP_DELETE);
559*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
560*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&message, MDL);
561*83ee113eSDavid van Moolenbroek 		return status;
562*83ee113eSDavid van Moolenbroek 	}
563*83ee113eSDavid van Moolenbroek 
564*83ee113eSDavid van Moolenbroek 	status = omapi_set_int_value (message, (omapi_object_t *)0, "handle",
565*83ee113eSDavid van Moolenbroek 				      (int)(ro -> remote_handle));
566*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
567*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&message, MDL);
568*83ee113eSDavid van Moolenbroek 		return status;
569*83ee113eSDavid van Moolenbroek 	}
570*83ee113eSDavid van Moolenbroek 
571*83ee113eSDavid van Moolenbroek 	status = omapi_set_object_value (message, (omapi_object_t *)0,
572*83ee113eSDavid van Moolenbroek 					 "notify-object", h);
573*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
574*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&message, MDL);
575*83ee113eSDavid van Moolenbroek 		return status;
576*83ee113eSDavid van Moolenbroek 	}
577*83ee113eSDavid van Moolenbroek 
578*83ee113eSDavid van Moolenbroek 	omapi_message_register (message);
579*83ee113eSDavid van Moolenbroek 	status = omapi_protocol_send_message (connection -> outer,
580*83ee113eSDavid van Moolenbroek 					      (omapi_object_t *)0,
581*83ee113eSDavid van Moolenbroek 					      message, (omapi_object_t *)0);
582*83ee113eSDavid van Moolenbroek 	omapi_object_dereference (&message, MDL);
583*83ee113eSDavid van Moolenbroek 	return status;
584*83ee113eSDavid van Moolenbroek }
585*83ee113eSDavid van Moolenbroek 
dhcpctl_data_string_dereference(dhcpctl_data_string * vp,const char * file,int line)586*83ee113eSDavid van Moolenbroek isc_result_t dhcpctl_data_string_dereference (dhcpctl_data_string *vp,
587*83ee113eSDavid van Moolenbroek 					      const char *file, int line)
588*83ee113eSDavid van Moolenbroek {
589*83ee113eSDavid van Moolenbroek 	return omapi_data_string_dereference (vp, file, line);
590*83ee113eSDavid van Moolenbroek }
591