xref: /minix/external/bsd/dhcp/dist/omapip/support.c (revision 83ee113e)
1 /*	$NetBSD: support.c,v 1.1.1.3 2014/07/12 11:58:00 spz Exp $	*/
2 /* support.c
3 
4    Subroutines providing general support for objects. */
5 
6 /*
7  * Copyright (c) 2009,2012,2014 by Internet Systems Consortium, Inc. ("ISC")
8  * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
9  * Copyright (c) 1999-2003 by Internet Software Consortium
10  *
11  * Permission to use, copy, modify, and distribute this software for any
12  * purpose with or without fee is hereby granted, provided that the above
13  * copyright notice and this permission notice appear in all copies.
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  *   950 Charter Street
25  *   Redwood City, CA 94063
26  *   <info@isc.org>
27  *   https://www.isc.org/
28  *
29  */
30 
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: support.c,v 1.1.1.3 2014/07/12 11:58:00 spz Exp $");
33 
34 #include "dhcpd.h"
35 
36 #include <omapip/omapip_p.h>
37 
38 omapi_object_type_t *omapi_type_connection;
39 omapi_object_type_t *omapi_type_listener;
40 omapi_object_type_t *omapi_type_io_object;
41 omapi_object_type_t *omapi_type_datagram;
42 omapi_object_type_t *omapi_type_generic;
43 omapi_object_type_t *omapi_type_protocol;
44 omapi_object_type_t *omapi_type_protocol_listener;
45 omapi_object_type_t *omapi_type_waiter;
46 omapi_object_type_t *omapi_type_remote;
47 omapi_object_type_t *omapi_type_message;
48 omapi_object_type_t *omapi_type_auth_key;
49 
50 omapi_object_type_t *omapi_object_types;
51 int omapi_object_type_count;
52 
53 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
omapi_type_relinquish()54 void omapi_type_relinquish ()
55 {
56 	omapi_object_type_t *t, *n;
57 
58 	for (t = omapi_object_types; t; t = n) {
59 		n = t -> next;
60 		dfree (t, MDL);
61 	}
62 	omapi_object_types = (omapi_object_type_t *)0;
63 }
64 #endif
65 
omapi_init(void)66 isc_result_t omapi_init (void)
67 {
68 	isc_result_t status;
69 
70 	/* Register all the standard object types... */
71 	status = omapi_object_type_register (&omapi_type_connection,
72 					     "connection",
73 					     omapi_connection_set_value,
74 					     omapi_connection_get_value,
75 					     omapi_connection_destroy,
76 					     omapi_connection_signal_handler,
77 					     omapi_connection_stuff_values,
78 					     0, 0, 0, 0, 0, 0,
79 					     sizeof
80 					     (omapi_connection_object_t), 0,
81 					     RC_MISC);
82 	if (status != ISC_R_SUCCESS)
83 		return status;
84 
85 	status = omapi_object_type_register (&omapi_type_listener,
86 					     "listener",
87 					     omapi_listener_set_value,
88 					     omapi_listener_get_value,
89 					     omapi_listener_destroy,
90 					     omapi_listener_signal_handler,
91 					     omapi_listener_stuff_values,
92 					     0, 0, 0, 0, 0, 0,
93 					     sizeof (omapi_listener_object_t),
94 					     0, RC_MISC);
95 	if (status != ISC_R_SUCCESS)
96 		return status;
97 
98 	status = omapi_object_type_register (&omapi_type_io_object,
99 					     "io",
100 					     omapi_io_set_value,
101 					     omapi_io_get_value,
102 					     omapi_io_destroy,
103 					     omapi_io_signal_handler,
104 					     omapi_io_stuff_values,
105 					     0, 0, 0, 0, 0, 0,
106 					     sizeof (omapi_io_object_t),
107 					     0, RC_MISC);
108 	if (status != ISC_R_SUCCESS)
109 		return status;
110 
111 	status = omapi_object_type_register (&omapi_type_generic,
112 					     "generic",
113 					     omapi_generic_set_value,
114 					     omapi_generic_get_value,
115 					     omapi_generic_destroy,
116 					     omapi_generic_signal_handler,
117 					     omapi_generic_stuff_values,
118 					     0, 0, 0, 0, 0, 0,
119 					     sizeof (omapi_generic_object_t),
120 					     0, RC_MISC);
121 	if (status != ISC_R_SUCCESS)
122 		return status;
123 
124 	status = omapi_object_type_register (&omapi_type_protocol,
125 					     "protocol",
126 					     omapi_protocol_set_value,
127 					     omapi_protocol_get_value,
128 					     omapi_protocol_destroy,
129 					     omapi_protocol_signal_handler,
130 					     omapi_protocol_stuff_values,
131 					     0, 0, 0, 0, 0, 0,
132 					     sizeof (omapi_protocol_object_t),
133 					     0, RC_MISC);
134 	if (status != ISC_R_SUCCESS)
135 		return status;
136 
137 	status = (omapi_object_type_register
138 		  (&omapi_type_protocol_listener, "protocol-listener",
139 		   omapi_protocol_listener_set_value,
140 		   omapi_protocol_listener_get_value,
141 		   omapi_protocol_listener_destroy,
142 		   omapi_protocol_listener_signal,
143 		   omapi_protocol_listener_stuff,
144 		   0, 0, 0, 0, 0, 0,
145 		   sizeof (omapi_protocol_listener_object_t), 0, RC_MISC));
146 	if (status != ISC_R_SUCCESS)
147 		return status;
148 
149 	status = omapi_object_type_register (&omapi_type_message,
150 					     "message",
151 					     omapi_message_set_value,
152 					     omapi_message_get_value,
153 					     omapi_message_destroy,
154 					     omapi_message_signal_handler,
155 					     omapi_message_stuff_values,
156 					     0, 0, 0, 0, 0, 0,
157 					     sizeof (omapi_message_object_t),
158 					     0, RC_MISC);
159 	if (status != ISC_R_SUCCESS)
160 		return status;
161 
162 	status = omapi_object_type_register (&omapi_type_waiter,
163 					     "waiter",
164 					     0,
165 					     0,
166 					     0,
167 					     omapi_waiter_signal_handler, 0,
168 					     0, 0, 0, 0, 0, 0,
169 					     sizeof (omapi_waiter_object_t),
170 					     0, RC_MISC);
171 	if (status != ISC_R_SUCCESS)
172 		return status;
173 
174 	status = omapi_object_type_register (&omapi_type_auth_key,
175 					     "authenticator",
176 					     0,
177 					     omapi_auth_key_get_value,
178 					     omapi_auth_key_destroy,
179 					     0,
180 					     omapi_auth_key_stuff_values,
181 					     omapi_auth_key_lookup,
182 					     0, 0, 0, 0, 0,
183 					     sizeof (omapi_auth_key_t), 0,
184 					     RC_MISC);
185 	if (status != ISC_R_SUCCESS)
186 		return status;
187 
188 #if defined (TRACING)
189 	omapi_listener_trace_setup ();
190 	omapi_connection_trace_setup ();
191 	omapi_buffer_trace_setup ();
192 #endif
193 
194 	/* This seems silly, but leave it. */
195 	return ISC_R_SUCCESS;
196 }
197 
omapi_object_type_register(omapi_object_type_t ** type,const char * name,isc_result_t (* set_value)(omapi_object_t *,omapi_object_t *,omapi_data_string_t *,omapi_typed_data_t *),isc_result_t (* get_value)(omapi_object_t *,omapi_object_t *,omapi_data_string_t *,omapi_value_t **),isc_result_t (* destroy)(omapi_object_t *,const char *,int),isc_result_t (* signal_handler)(omapi_object_t *,const char *,va_list),isc_result_t (* stuff_values)(omapi_object_t *,omapi_object_t *,omapi_object_t *),isc_result_t (* lookup)(omapi_object_t **,omapi_object_t *,omapi_object_t *),isc_result_t (* create)(omapi_object_t **,omapi_object_t *),isc_result_t (* remove)(omapi_object_t *,omapi_object_t *),isc_result_t (* freer)(omapi_object_t *,const char *,int),isc_result_t (* allocator)(omapi_object_t **,const char *,int),isc_result_t (* sizer)(size_t),size_t size,isc_result_t (* initialize)(omapi_object_t *,const char *,int),int rc_flag)198 isc_result_t omapi_object_type_register (omapi_object_type_t **type,
199 					 const char *name,
200 					 isc_result_t (*set_value)
201 						 (omapi_object_t *,
202 						  omapi_object_t *,
203 						  omapi_data_string_t *,
204 						  omapi_typed_data_t *),
205 					 isc_result_t (*get_value)
206 						(omapi_object_t *,
207 						 omapi_object_t *,
208 						 omapi_data_string_t *,
209 						 omapi_value_t **),
210 					 isc_result_t (*destroy)
211 						(omapi_object_t *,
212 						 const char *, int),
213 					 isc_result_t (*signal_handler)
214 						 (omapi_object_t *,
215 						  const char *, va_list),
216 					 isc_result_t (*stuff_values)
217 						(omapi_object_t *,
218 						 omapi_object_t *,
219 						 omapi_object_t *),
220 					 isc_result_t (*lookup)
221 						(omapi_object_t **,
222 						 omapi_object_t *,
223 						 omapi_object_t *),
224 					 isc_result_t (*create)
225 						(omapi_object_t **,
226 						 omapi_object_t *),
227 					 isc_result_t (*remove)
228 						(omapi_object_t *,
229 						 omapi_object_t *),
230 					 isc_result_t (*freer)
231 						(omapi_object_t *,
232 						 const char *, int),
233 					 isc_result_t (*allocator)
234 						(omapi_object_t **,
235 						 const char *, int),
236 					 isc_result_t (*sizer) (size_t),
237 					 size_t size,
238 					 isc_result_t (*initialize)
239 						(omapi_object_t *,
240 						 const char *, int),
241 					 int rc_flag)
242 {
243 	omapi_object_type_t *t;
244 
245 	t = dmalloc (sizeof *t, MDL);
246 	if (!t)
247 		return ISC_R_NOMEMORY;
248 	memset (t, 0, sizeof *t);
249 
250 	t -> name = name;
251 	t -> set_value = set_value;
252 	t -> get_value = get_value;
253 	t -> destroy = destroy;
254 	t -> signal_handler = signal_handler;
255 	t -> stuff_values = stuff_values;
256 	t -> lookup = lookup;
257 	t -> create = create;
258 	t -> remove = remove;
259 	t -> next = omapi_object_types;
260 	t -> sizer = sizer;
261 	t -> size = size;
262 	t -> freer = freer;
263 	t -> allocator = allocator;
264 	t -> initialize = initialize;
265 	t -> rc_flag = rc_flag;
266 	omapi_object_types = t;
267 	if (type)
268 		*type = t;
269 	return ISC_R_SUCCESS;
270 }
271 
omapi_signal(omapi_object_t * handle,const char * name,...)272 isc_result_t omapi_signal (omapi_object_t *handle, const char *name, ...)
273 {
274 	va_list ap;
275 	omapi_object_t *outer;
276 	isc_result_t status;
277 
278 	va_start (ap, name);
279 	for (outer = handle; outer -> outer; outer = outer -> outer)
280 		;
281 	if (outer -> type -> signal_handler)
282 		status = (*(outer -> type -> signal_handler)) (outer,
283 							       name, ap);
284 	else
285 		status = ISC_R_NOTFOUND;
286 	va_end (ap);
287 	return status;
288 }
289 
omapi_signal_in(omapi_object_t * handle,const char * name,...)290 isc_result_t omapi_signal_in (omapi_object_t *handle, const char *name, ...)
291 {
292 	va_list ap;
293 	isc_result_t status;
294 
295 	if (!handle)
296 		return ISC_R_NOTFOUND;
297 	va_start (ap, name);
298 
299 	if (handle -> type -> signal_handler)
300 		status = (*(handle -> type -> signal_handler)) (handle,
301 								name, ap);
302 	else
303 		status = ISC_R_NOTFOUND;
304 	va_end (ap);
305 	return status;
306 }
307 
omapi_set_value(omapi_object_t * h,omapi_object_t * id,omapi_data_string_t * name,omapi_typed_data_t * value)308 isc_result_t omapi_set_value (omapi_object_t *h,
309 			      omapi_object_t *id,
310 			      omapi_data_string_t *name,
311 			      omapi_typed_data_t *value)
312 {
313 	omapi_object_t *outer;
314 	isc_result_t status;
315 
316 #if defined (DEBUG)
317 	if (!value) {
318 		log_info ("omapi_set_value (%.*s, NULL)",
319 			  (int)name -> len, name -> value);
320 	} else if (value -> type == omapi_datatype_int) {
321 		log_info ("omapi_set_value (%.*s, %ld)",
322 			  (int)name -> len, name -> value,
323 			  (long)value -> u.integer);
324 	} else if (value -> type == omapi_datatype_string) {
325 		log_info ("omapi_set_value (%.*s, %.*s)",
326 			  (int)name -> len, name -> value,
327 			  (int)value -> u.buffer.len, value -> u.buffer.value);
328 	} else if (value -> type == omapi_datatype_data) {
329 		log_info ("omapi_set_value (%.*s, %ld %lx)",
330 			  (int)name -> len, name -> value,
331 			  (long)value -> u.buffer.len,
332 			  (unsigned long)value -> u.buffer.value);
333 	} else if (value -> type == omapi_datatype_object) {
334 		log_info ("omapi_set_value (%.*s, %s)",
335 			  (int)name -> len, name -> value,
336 			  value -> u.object
337 			  ? (value -> u.object -> type
338 			     ? value -> u.object -> type -> name
339 			     : "(unknown object)")
340 			  : "(unknown object)");
341 	}
342 #endif
343 
344 	for (outer = h; outer -> outer; outer = outer -> outer)
345 		;
346 	if (outer -> type -> set_value)
347 		status = (*(outer -> type -> set_value)) (outer,
348 							  id, name, value);
349 	else
350 		status = ISC_R_NOTFOUND;
351 #if defined (DEBUG)
352 	log_info (" ==> %s", isc_result_totext (status));
353 #endif
354 	return status;
355 }
356 
omapi_set_value_str(omapi_object_t * h,omapi_object_t * id,const char * name,omapi_typed_data_t * value)357 isc_result_t omapi_set_value_str (omapi_object_t *h,
358 				  omapi_object_t *id,
359 				  const char *name,
360 				  omapi_typed_data_t *value)
361 {
362 	omapi_data_string_t *nds;
363 	isc_result_t status;
364 
365 	nds = (omapi_data_string_t *)0;
366 	status = omapi_data_string_new (&nds, strlen (name), MDL);
367 	if (status != ISC_R_SUCCESS)
368 		return status;
369 	memcpy (nds -> value, name, strlen (name));
370 
371 	status = omapi_set_value (h, id, nds, value);
372 	omapi_data_string_dereference (&nds, MDL);
373 	return status;
374 }
375 
omapi_set_boolean_value(omapi_object_t * h,omapi_object_t * id,const char * name,int value)376 isc_result_t omapi_set_boolean_value (omapi_object_t *h, omapi_object_t *id,
377 				      const char *name, int value)
378 {
379 	isc_result_t status;
380 	omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
381 	omapi_data_string_t *n = (omapi_data_string_t *)0;
382 
383 	status = omapi_data_string_new (&n, strlen (name), MDL);
384 	if (status != ISC_R_SUCCESS)
385 		return status;
386 	memcpy (n -> value, name, strlen (name));
387 
388 	status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
389 	if (status != ISC_R_SUCCESS) {
390 		omapi_data_string_dereference (&n, MDL);
391 		return status;
392 	}
393 
394 	status = omapi_set_value (h, id, n, tv);
395 	omapi_data_string_dereference (&n, MDL);
396 	omapi_typed_data_dereference (&tv, MDL);
397 	return status;
398 }
399 
omapi_set_int_value(omapi_object_t * h,omapi_object_t * id,const char * name,int value)400 isc_result_t omapi_set_int_value (omapi_object_t *h, omapi_object_t *id,
401 				  const char *name, int value)
402 {
403 	isc_result_t status;
404 	omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
405 	omapi_data_string_t *n = (omapi_data_string_t *)0;
406 
407 	status = omapi_data_string_new (&n, strlen (name), MDL);
408 	if (status != ISC_R_SUCCESS)
409 		return status;
410 	memcpy (n -> value, name, strlen (name));
411 
412 	status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
413 	if (status != ISC_R_SUCCESS) {
414 		omapi_data_string_dereference (&n, MDL);
415 		return status;
416 	}
417 
418 	status = omapi_set_value (h, id, n, tv);
419 	omapi_data_string_dereference (&n, MDL);
420 	omapi_typed_data_dereference (&tv, MDL);
421 	return status;
422 }
423 
omapi_set_object_value(omapi_object_t * h,omapi_object_t * id,const char * name,omapi_object_t * value)424 isc_result_t omapi_set_object_value (omapi_object_t *h, omapi_object_t *id,
425 				     const char *name, omapi_object_t *value)
426 {
427 	isc_result_t status;
428 	omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
429 	omapi_data_string_t *n = (omapi_data_string_t *)0;
430 
431 	status = omapi_data_string_new (&n, strlen (name), MDL);
432 	if (status != ISC_R_SUCCESS)
433 		return status;
434 	memcpy (n -> value, name, strlen (name));
435 
436 	status = omapi_typed_data_new (MDL, &tv, omapi_datatype_object, value);
437 	if (status != ISC_R_SUCCESS) {
438 		omapi_data_string_dereference (&n, MDL);
439 		return status;
440 	}
441 
442 	status = omapi_set_value (h, id, n, tv);
443 	omapi_data_string_dereference (&n, MDL);
444 	omapi_typed_data_dereference (&tv, MDL);
445 	return status;
446 }
447 
omapi_set_string_value(omapi_object_t * h,omapi_object_t * id,const char * name,const char * value)448 isc_result_t omapi_set_string_value (omapi_object_t *h, omapi_object_t *id,
449 				     const char *name, const char *value)
450 {
451 	isc_result_t status;
452 	omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
453 	omapi_data_string_t *n = (omapi_data_string_t *)0;
454 
455 	status = omapi_data_string_new (&n, strlen (name), MDL);
456 	if (status != ISC_R_SUCCESS)
457 		return status;
458 	memcpy (n -> value, name, strlen (name));
459 
460 	status = omapi_typed_data_new (MDL, &tv, omapi_datatype_string, value);
461 	if (status != ISC_R_SUCCESS) {
462 		omapi_data_string_dereference (&n, MDL);
463 		return status;
464 	}
465 
466 	status = omapi_set_value (h, id, n, tv);
467 	omapi_data_string_dereference (&n, MDL);
468 	omapi_typed_data_dereference (&tv, MDL);
469 	return status;
470 }
471 
omapi_get_value(omapi_object_t * h,omapi_object_t * id,omapi_data_string_t * name,omapi_value_t ** value)472 isc_result_t omapi_get_value (omapi_object_t *h,
473 			      omapi_object_t *id,
474 			      omapi_data_string_t *name,
475 			      omapi_value_t **value)
476 {
477 	omapi_object_t *outer;
478 
479 	for (outer = h; outer -> outer; outer = outer -> outer)
480 		;
481 	if (outer -> type -> get_value)
482 		return (*(outer -> type -> get_value)) (outer,
483 							id, name, value);
484 	return ISC_R_NOTFOUND;
485 }
486 
omapi_get_value_str(omapi_object_t * h,omapi_object_t * id,const char * name,omapi_value_t ** value)487 isc_result_t omapi_get_value_str (omapi_object_t *h,
488 				  omapi_object_t *id,
489 				  const char *name,
490 				  omapi_value_t **value)
491 {
492 	omapi_object_t *outer;
493 	omapi_data_string_t *nds;
494 	isc_result_t status;
495 
496 	nds = (omapi_data_string_t *)0;
497 	status = omapi_data_string_new (&nds, strlen (name), MDL);
498 	if (status != ISC_R_SUCCESS)
499 		return status;
500 	memcpy (nds -> value, name, strlen (name));
501 
502 	for (outer = h; outer -> outer; outer = outer -> outer)
503 		;
504 	if (outer -> type -> get_value)
505 		status = (*(outer -> type -> get_value)) (outer,
506 							  id, nds, value);
507 	else
508 		status = ISC_R_NOTFOUND;
509 	omapi_data_string_dereference (&nds, MDL);
510 	return status;
511 }
512 
omapi_stuff_values(omapi_object_t * c,omapi_object_t * id,omapi_object_t * o)513 isc_result_t omapi_stuff_values (omapi_object_t *c,
514 				 omapi_object_t *id,
515 				 omapi_object_t *o)
516 {
517 	omapi_object_t *outer;
518 
519 	for (outer = o; outer -> outer; outer = outer -> outer)
520 		;
521 	if (outer -> type -> stuff_values)
522 		return (*(outer -> type -> stuff_values)) (c, id, outer);
523 	return ISC_R_NOTFOUND;
524 }
525 
omapi_object_create(omapi_object_t ** obj,omapi_object_t * id,omapi_object_type_t * type)526 isc_result_t omapi_object_create (omapi_object_t **obj, omapi_object_t *id,
527 				  omapi_object_type_t *type)
528 {
529 	if (!type -> create)
530 		return ISC_R_NOTIMPLEMENTED;
531 	return (*(type -> create)) (obj, id);
532 }
533 
omapi_object_update(omapi_object_t * obj,omapi_object_t * id,omapi_object_t * src,omapi_handle_t handle)534 isc_result_t omapi_object_update (omapi_object_t *obj, omapi_object_t *id,
535 				  omapi_object_t *src, omapi_handle_t handle)
536 {
537 	omapi_generic_object_t *gsrc;
538 	isc_result_t status;
539 	int i;
540 
541 	if (!src)
542 		return DHCP_R_INVALIDARG;
543 	if (src -> type != omapi_type_generic)
544 		return ISC_R_NOTIMPLEMENTED;
545 	gsrc = (omapi_generic_object_t *)src;
546 	for (i = 0; i < gsrc -> nvalues; i++) {
547 		status = omapi_set_value (obj, id,
548 					  gsrc -> values [i] -> name,
549 					  gsrc -> values [i] -> value);
550 		if (status != ISC_R_SUCCESS && status != DHCP_R_UNCHANGED)
551 			return status;
552 	}
553 
554 	/*
555 	 * For now ignore the return value.  I'm not sure if we want to
556 	 * generate an error if we can't set the handle value.  If we
557 	 * do add a check we probably should allow unchanged and notfound
558 	 */
559 	if (handle)
560 		(void) omapi_set_int_value (obj, id, "remote-handle", (int)handle);
561 	status = omapi_signal (obj, "updated");
562 	if (status != ISC_R_NOTFOUND)
563 		return status;
564 	return ISC_R_SUCCESS;
565 }
566 
omapi_data_string_cmp(omapi_data_string_t * s1,omapi_data_string_t * s2)567 int omapi_data_string_cmp (omapi_data_string_t *s1, omapi_data_string_t *s2)
568 {
569 	unsigned len;
570 	int rv;
571 
572 	if (s1 -> len > s2 -> len)
573 		len = s2 -> len;
574 	else
575 		len = s1 -> len;
576 	rv = memcmp (s1 -> value, s2 -> value, len);
577 	if (rv)
578 		return rv;
579 	if (s1 -> len > s2 -> len)
580 		return 1;
581 	else if (s1 -> len < s2 -> len)
582 		return -1;
583 	return 0;
584 }
585 
omapi_ds_strcmp(omapi_data_string_t * s1,const char * s2)586 int omapi_ds_strcmp (omapi_data_string_t *s1, const char *s2)
587 {
588 	unsigned len, slen;
589 	int rv;
590 
591 	slen = strlen (s2);
592 	if (slen > s1 -> len)
593 		len = s1 -> len;
594 	else
595 		len = slen;
596 	rv = memcmp (s1 -> value, s2, len);
597 	if (rv)
598 		return rv;
599 	if (s1 -> len > slen)
600 		return 1;
601 	else if (s1 -> len < slen)
602 		return -1;
603 	return 0;
604 }
605 
omapi_td_strcmp(omapi_typed_data_t * s1,const char * s2)606 int omapi_td_strcmp (omapi_typed_data_t *s1, const char *s2)
607 {
608 	unsigned len, slen;
609 	int rv;
610 
611 	/* If the data type is not compatible, never equal. */
612 	if (s1 -> type != omapi_datatype_data &&
613 	    s1 -> type != omapi_datatype_string)
614 		return -1;
615 
616 	slen = strlen (s2);
617 	if (slen > s1 -> u.buffer.len)
618 		len = s1 -> u.buffer.len;
619 	else
620 		len = slen;
621 	rv = memcmp (s1 -> u.buffer.value, s2, len);
622 	if (rv)
623 		return rv;
624 	if (s1 -> u.buffer.len > slen)
625 		return 1;
626 	else if (s1 -> u.buffer.len < slen)
627 		return -1;
628 	return 0;
629 }
630 
omapi_td_strcasecmp(omapi_typed_data_t * s1,const char * s2)631 int omapi_td_strcasecmp (omapi_typed_data_t *s1, const char *s2)
632 {
633 	unsigned len, slen;
634 	int rv;
635 
636 	/* If the data type is not compatible, never equal. */
637 	if (s1 -> type != omapi_datatype_data &&
638 	    s1 -> type != omapi_datatype_string)
639 		return -1;
640 
641 	slen = strlen (s2);
642 	if (slen > s1 -> u.buffer.len)
643 		len = s1 -> u.buffer.len;
644 	else
645 		len = slen;
646 	rv = casecmp (s1 -> u.buffer.value, s2, len);
647 	if (rv)
648 		return rv;
649 	if (s1 -> u.buffer.len > slen)
650 		return 1;
651 	else if (s1 -> u.buffer.len < slen)
652 		return -1;
653 	return 0;
654 }
655 
omapi_make_value(omapi_value_t ** vp,omapi_data_string_t * name,omapi_typed_data_t * value,const char * file,int line)656 isc_result_t omapi_make_value (omapi_value_t **vp,
657 			       omapi_data_string_t *name,
658 			       omapi_typed_data_t *value,
659 			       const char *file, int line)
660 {
661 	isc_result_t status;
662 
663 	status = omapi_value_new (vp, file, line);
664 	if (status != ISC_R_SUCCESS)
665 		return status;
666 
667 	status = omapi_data_string_reference (&(*vp) -> name,
668 					      name, file, line);
669 	if (status != ISC_R_SUCCESS) {
670 		omapi_value_dereference (vp, file, line);
671 		return status;
672 	}
673 	if (value) {
674 		status = omapi_typed_data_reference (&(*vp) -> value,
675 						     value, file, line);
676 		if (status != ISC_R_SUCCESS) {
677 			omapi_value_dereference (vp, file, line);
678 			return status;
679 		}
680 	}
681 	return ISC_R_SUCCESS;
682 }
683 
omapi_make_const_value(omapi_value_t ** vp,omapi_data_string_t * name,const unsigned char * value,unsigned len,const char * file,int line)684 isc_result_t omapi_make_const_value (omapi_value_t **vp,
685 				     omapi_data_string_t *name,
686 				     const unsigned char *value,
687 				     unsigned len,
688 				     const char *file, int line)
689 {
690 	isc_result_t status;
691 
692 	status = omapi_value_new (vp, file, line);
693 	if (status != ISC_R_SUCCESS)
694 		return status;
695 
696 	status = omapi_data_string_reference (&(*vp) -> name,
697 					      name, file, line);
698 	if (status != ISC_R_SUCCESS) {
699 		omapi_value_dereference (vp, file, line);
700 		return status;
701 	}
702 	if (value) {
703 		status = omapi_typed_data_new (file, line, &(*vp) -> value,
704 					       omapi_datatype_data, len);
705 		if (status != ISC_R_SUCCESS) {
706 			omapi_value_dereference (vp, file, line);
707 			return status;
708 		}
709 		memcpy ((*vp) -> value -> u.buffer.value, value, len);
710 	}
711 	return ISC_R_SUCCESS;
712 }
713 
omapi_make_int_value(omapi_value_t ** vp,omapi_data_string_t * name,int value,const char * file,int line)714 isc_result_t omapi_make_int_value (omapi_value_t **vp,
715 				   omapi_data_string_t *name,
716 				   int value, const char *file, int line)
717 {
718 	isc_result_t status;
719 
720 	status = omapi_value_new (vp, file, line);
721 	if (status != ISC_R_SUCCESS)
722 		return status;
723 
724 	status = omapi_data_string_reference (&(*vp) -> name,
725 					      name, file, line);
726 	if (status != ISC_R_SUCCESS) {
727 		omapi_value_dereference (vp, file, line);
728 		return status;
729 	}
730 	status = omapi_typed_data_new (file, line, &(*vp) -> value,
731 				       omapi_datatype_int, value);
732 	if (status != ISC_R_SUCCESS) {
733 		omapi_value_dereference (vp, file, line);
734 		return status;
735 	}
736 	return ISC_R_SUCCESS;
737 }
738 
omapi_make_uint_value(omapi_value_t ** vp,omapi_data_string_t * name,unsigned int value,const char * file,int line)739 isc_result_t omapi_make_uint_value (omapi_value_t **vp,
740 				    omapi_data_string_t *name,
741 				    unsigned int value,
742 				    const char *file, int line)
743 {
744 	return omapi_make_int_value (vp, name, (int)value, file, line);
745 }
746 
omapi_make_object_value(omapi_value_t ** vp,omapi_data_string_t * name,omapi_object_t * value,const char * file,int line)747 isc_result_t omapi_make_object_value (omapi_value_t **vp,
748 				      omapi_data_string_t *name,
749 				      omapi_object_t *value,
750 				      const char *file, int line)
751 {
752 	isc_result_t status;
753 
754 	status = omapi_value_new (vp, file, line);
755 	if (status != ISC_R_SUCCESS)
756 		return status;
757 
758 	status = omapi_data_string_reference (&(*vp) -> name,
759                                               name, file, line);
760 	if (status != ISC_R_SUCCESS) {
761 		omapi_value_dereference (vp, file, line);
762 		return status;
763 	}
764 
765 	if (value) {
766 		status = omapi_typed_data_new (file, line, &(*vp) -> value,
767 					       omapi_datatype_object, value);
768 		if (status != ISC_R_SUCCESS) {
769 			omapi_value_dereference (vp, file, line);
770 			return status;
771 		}
772 	}
773 
774 	return ISC_R_SUCCESS;
775 }
776 
omapi_make_handle_value(omapi_value_t ** vp,omapi_data_string_t * name,omapi_object_t * value,const char * file,int line)777 isc_result_t omapi_make_handle_value (omapi_value_t **vp,
778 				      omapi_data_string_t *name,
779 				      omapi_object_t *value,
780 				      const char *file, int line)
781 {
782 	isc_result_t status;
783 
784 	status = omapi_value_new (vp, file, line);
785 	if (status != ISC_R_SUCCESS)
786 		return status;
787 
788 	status = omapi_data_string_reference (&(*vp) -> name,
789 					      name, file, line);
790 	if (status != ISC_R_SUCCESS) {
791 		omapi_value_dereference (vp, file, line);
792 		return status;
793 	}
794 	if (value) {
795 		status = omapi_typed_data_new (file, line, &(*vp) -> value,
796 					       omapi_datatype_int);
797 		if (status != ISC_R_SUCCESS) {
798 			omapi_value_dereference (vp, file, line);
799 			return status;
800 		}
801 		status = (omapi_object_handle
802 			  ((omapi_handle_t *)&(*vp) -> value -> u.integer,
803 			   value));
804 		if (status != ISC_R_SUCCESS) {
805 			omapi_value_dereference (vp, file, line);
806 			return status;
807 		}
808 	}
809 	return ISC_R_SUCCESS;
810 }
811 
omapi_make_string_value(omapi_value_t ** vp,omapi_data_string_t * name,const char * value,const char * file,int line)812 isc_result_t omapi_make_string_value (omapi_value_t **vp,
813 				      omapi_data_string_t *name,
814 				      const char *value,
815 				      const char *file, int line)
816 {
817 	isc_result_t status;
818 
819 	status = omapi_value_new (vp, file, line);
820 	if (status != ISC_R_SUCCESS)
821 		return status;
822 
823 	status = omapi_data_string_reference (&(*vp) -> name,
824 					      name, file, line);
825 	if (status != ISC_R_SUCCESS) {
826 		omapi_value_dereference (vp, file, line);
827 		return status;
828 	}
829 	if (value) {
830 		status = omapi_typed_data_new (file, line, &(*vp) -> value,
831 					       omapi_datatype_string, value);
832 		if (status != ISC_R_SUCCESS) {
833 			omapi_value_dereference (vp, file, line);
834 			return status;
835 		}
836 	}
837 	return ISC_R_SUCCESS;
838 }
839 
omapi_get_int_value(unsigned long * v,omapi_typed_data_t * t)840 isc_result_t omapi_get_int_value (unsigned long *v, omapi_typed_data_t *t)
841 {
842 	u_int32_t rv;
843 
844 	if (t -> type == omapi_datatype_int) {
845 		*v = t -> u.integer;
846 		return ISC_R_SUCCESS;
847 	} else if (t -> type == omapi_datatype_string ||
848 		   t -> type == omapi_datatype_data) {
849 		if (t -> u.buffer.len != sizeof (rv))
850 			return DHCP_R_INVALIDARG;
851 		memcpy (&rv, t -> u.buffer.value, sizeof rv);
852 		*v = ntohl (rv);
853 		return ISC_R_SUCCESS;
854 	}
855 	return DHCP_R_INVALIDARG;
856 }
857