1 /* $NetBSD: support.c,v 1.1.1.3 2014/07/12 11:58:00 spz Exp $ */
4 Subroutines providing general support for objects. */
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
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.
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.
23 * Internet Systems Consortium, Inc.
25 * Redwood City, CA 94063
27 * https://www.isc.org/
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: support.c,v 1.1.1.3 2014/07/12 11:58:00 spz Exp $");
36 #include <omapip/omapip_p.h>
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
;
50 omapi_object_type_t
*omapi_object_types
;
51 int omapi_object_type_count
;
53 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
54 void omapi_type_relinquish ()
56 omapi_object_type_t
*t
, *n
;
58 for (t
= omapi_object_types
; t
; t
= n
) {
62 omapi_object_types
= (omapi_object_type_t
*)0;
66 isc_result_t
omapi_init (void)
70 /* Register all the standard object types... */
71 status
= omapi_object_type_register (&omapi_type_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
,
80 (omapi_connection_object_t
), 0,
82 if (status
!= ISC_R_SUCCESS
)
85 status
= omapi_object_type_register (&omapi_type_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
,
93 sizeof (omapi_listener_object_t
),
95 if (status
!= ISC_R_SUCCESS
)
98 status
= omapi_object_type_register (&omapi_type_io_object
,
103 omapi_io_signal_handler
,
104 omapi_io_stuff_values
,
106 sizeof (omapi_io_object_t
),
108 if (status
!= ISC_R_SUCCESS
)
111 status
= omapi_object_type_register (&omapi_type_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
,
119 sizeof (omapi_generic_object_t
),
121 if (status
!= ISC_R_SUCCESS
)
124 status
= omapi_object_type_register (&omapi_type_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
,
132 sizeof (omapi_protocol_object_t
),
134 if (status
!= ISC_R_SUCCESS
)
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
,
145 sizeof (omapi_protocol_listener_object_t
), 0, RC_MISC
));
146 if (status
!= ISC_R_SUCCESS
)
149 status
= omapi_object_type_register (&omapi_type_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
,
157 sizeof (omapi_message_object_t
),
159 if (status
!= ISC_R_SUCCESS
)
162 status
= omapi_object_type_register (&omapi_type_waiter
,
167 omapi_waiter_signal_handler
, 0,
169 sizeof (omapi_waiter_object_t
),
171 if (status
!= ISC_R_SUCCESS
)
174 status
= omapi_object_type_register (&omapi_type_auth_key
,
177 omapi_auth_key_get_value
,
178 omapi_auth_key_destroy
,
180 omapi_auth_key_stuff_values
,
181 omapi_auth_key_lookup
,
183 sizeof (omapi_auth_key_t
), 0,
185 if (status
!= ISC_R_SUCCESS
)
188 #if defined (TRACING)
189 omapi_listener_trace_setup ();
190 omapi_connection_trace_setup ();
191 omapi_buffer_trace_setup ();
194 /* This seems silly, but leave it. */
195 return ISC_R_SUCCESS
;
198 isc_result_t
omapi_object_type_register (omapi_object_type_t
**type
,
200 isc_result_t (*set_value
)
203 omapi_data_string_t
*,
204 omapi_typed_data_t
*),
205 isc_result_t (*get_value
)
208 omapi_data_string_t
*,
210 isc_result_t (*destroy
)
213 isc_result_t (*signal_handler
)
215 const char *, va_list),
216 isc_result_t (*stuff_values
)
220 isc_result_t (*lookup
)
224 isc_result_t (*create
)
227 isc_result_t (*remove
)
230 isc_result_t (*freer
)
233 isc_result_t (*allocator
)
236 isc_result_t (*sizer
) (size_t),
238 isc_result_t (*initialize
)
243 omapi_object_type_t
*t
;
245 t
= dmalloc (sizeof *t
, MDL
);
247 return ISC_R_NOMEMORY
;
248 memset (t
, 0, sizeof *t
);
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
;
263 t
-> allocator
= allocator
;
264 t
-> initialize
= initialize
;
265 t
-> rc_flag
= rc_flag
;
266 omapi_object_types
= t
;
269 return ISC_R_SUCCESS
;
272 isc_result_t
omapi_signal (omapi_object_t
*handle
, const char *name
, ...)
275 omapi_object_t
*outer
;
279 for (outer
= handle
; outer
-> outer
; outer
= outer
-> outer
)
281 if (outer
-> type
-> signal_handler
)
282 status
= (*(outer
-> type
-> signal_handler
)) (outer
,
285 status
= ISC_R_NOTFOUND
;
290 isc_result_t
omapi_signal_in (omapi_object_t
*handle
, const char *name
, ...)
296 return ISC_R_NOTFOUND
;
299 if (handle
-> type
-> signal_handler
)
300 status
= (*(handle
-> type
-> signal_handler
)) (handle
,
303 status
= ISC_R_NOTFOUND
;
308 isc_result_t
omapi_set_value (omapi_object_t
*h
,
310 omapi_data_string_t
*name
,
311 omapi_typed_data_t
*value
)
313 omapi_object_t
*outer
;
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
,
337 ? (value
-> u
.object
-> type
338 ? value
-> u
.object
-> type
-> name
339 : "(unknown object)")
340 : "(unknown object)");
344 for (outer
= h
; outer
-> outer
; outer
= outer
-> outer
)
346 if (outer
-> type
-> set_value
)
347 status
= (*(outer
-> type
-> set_value
)) (outer
,
350 status
= ISC_R_NOTFOUND
;
352 log_info (" ==> %s", isc_result_totext (status
));
357 isc_result_t
omapi_set_value_str (omapi_object_t
*h
,
360 omapi_typed_data_t
*value
)
362 omapi_data_string_t
*nds
;
365 nds
= (omapi_data_string_t
*)0;
366 status
= omapi_data_string_new (&nds
, strlen (name
), MDL
);
367 if (status
!= ISC_R_SUCCESS
)
369 memcpy (nds
-> value
, name
, strlen (name
));
371 status
= omapi_set_value (h
, id
, nds
, value
);
372 omapi_data_string_dereference (&nds
, MDL
);
376 isc_result_t
omapi_set_boolean_value (omapi_object_t
*h
, omapi_object_t
*id
,
377 const char *name
, int value
)
380 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
381 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
383 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
384 if (status
!= ISC_R_SUCCESS
)
386 memcpy (n
-> value
, name
, strlen (name
));
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
);
394 status
= omapi_set_value (h
, id
, n
, tv
);
395 omapi_data_string_dereference (&n
, MDL
);
396 omapi_typed_data_dereference (&tv
, MDL
);
400 isc_result_t
omapi_set_int_value (omapi_object_t
*h
, omapi_object_t
*id
,
401 const char *name
, int value
)
404 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
405 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
407 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
408 if (status
!= ISC_R_SUCCESS
)
410 memcpy (n
-> value
, name
, strlen (name
));
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
);
418 status
= omapi_set_value (h
, id
, n
, tv
);
419 omapi_data_string_dereference (&n
, MDL
);
420 omapi_typed_data_dereference (&tv
, MDL
);
424 isc_result_t
omapi_set_object_value (omapi_object_t
*h
, omapi_object_t
*id
,
425 const char *name
, omapi_object_t
*value
)
428 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
429 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
431 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
432 if (status
!= ISC_R_SUCCESS
)
434 memcpy (n
-> value
, name
, strlen (name
));
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
);
442 status
= omapi_set_value (h
, id
, n
, tv
);
443 omapi_data_string_dereference (&n
, MDL
);
444 omapi_typed_data_dereference (&tv
, MDL
);
448 isc_result_t
omapi_set_string_value (omapi_object_t
*h
, omapi_object_t
*id
,
449 const char *name
, const char *value
)
452 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
453 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
455 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
456 if (status
!= ISC_R_SUCCESS
)
458 memcpy (n
-> value
, name
, strlen (name
));
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
);
466 status
= omapi_set_value (h
, id
, n
, tv
);
467 omapi_data_string_dereference (&n
, MDL
);
468 omapi_typed_data_dereference (&tv
, MDL
);
472 isc_result_t
omapi_get_value (omapi_object_t
*h
,
474 omapi_data_string_t
*name
,
475 omapi_value_t
**value
)
477 omapi_object_t
*outer
;
479 for (outer
= h
; outer
-> outer
; outer
= outer
-> outer
)
481 if (outer
-> type
-> get_value
)
482 return (*(outer
-> type
-> get_value
)) (outer
,
484 return ISC_R_NOTFOUND
;
487 isc_result_t
omapi_get_value_str (omapi_object_t
*h
,
490 omapi_value_t
**value
)
492 omapi_object_t
*outer
;
493 omapi_data_string_t
*nds
;
496 nds
= (omapi_data_string_t
*)0;
497 status
= omapi_data_string_new (&nds
, strlen (name
), MDL
);
498 if (status
!= ISC_R_SUCCESS
)
500 memcpy (nds
-> value
, name
, strlen (name
));
502 for (outer
= h
; outer
-> outer
; outer
= outer
-> outer
)
504 if (outer
-> type
-> get_value
)
505 status
= (*(outer
-> type
-> get_value
)) (outer
,
508 status
= ISC_R_NOTFOUND
;
509 omapi_data_string_dereference (&nds
, MDL
);
513 isc_result_t
omapi_stuff_values (omapi_object_t
*c
,
517 omapi_object_t
*outer
;
519 for (outer
= o
; outer
-> outer
; outer
= outer
-> outer
)
521 if (outer
-> type
-> stuff_values
)
522 return (*(outer
-> type
-> stuff_values
)) (c
, id
, outer
);
523 return ISC_R_NOTFOUND
;
526 isc_result_t
omapi_object_create (omapi_object_t
**obj
, omapi_object_t
*id
,
527 omapi_object_type_t
*type
)
530 return ISC_R_NOTIMPLEMENTED
;
531 return (*(type
-> create
)) (obj
, id
);
534 isc_result_t
omapi_object_update (omapi_object_t
*obj
, omapi_object_t
*id
,
535 omapi_object_t
*src
, omapi_handle_t handle
)
537 omapi_generic_object_t
*gsrc
;
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
)
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
560 (void) omapi_set_int_value (obj
, id
, "remote-handle", (int)handle
);
561 status
= omapi_signal (obj
, "updated");
562 if (status
!= ISC_R_NOTFOUND
)
564 return ISC_R_SUCCESS
;
567 int omapi_data_string_cmp (omapi_data_string_t
*s1
, omapi_data_string_t
*s2
)
572 if (s1
-> len
> s2
-> len
)
576 rv
= memcmp (s1
-> value
, s2
-> value
, len
);
579 if (s1
-> len
> s2
-> len
)
581 else if (s1
-> len
< s2
-> len
)
586 int omapi_ds_strcmp (omapi_data_string_t
*s1
, const char *s2
)
592 if (slen
> s1
-> len
)
596 rv
= memcmp (s1
-> value
, s2
, len
);
599 if (s1
-> len
> slen
)
601 else if (s1
-> len
< slen
)
606 int omapi_td_strcmp (omapi_typed_data_t
*s1
, const char *s2
)
611 /* If the data type is not compatible, never equal. */
612 if (s1
-> type
!= omapi_datatype_data
&&
613 s1
-> type
!= omapi_datatype_string
)
617 if (slen
> s1
-> u
.buffer
.len
)
618 len
= s1
-> u
.buffer
.len
;
621 rv
= memcmp (s1
-> u
.buffer
.value
, s2
, len
);
624 if (s1
-> u
.buffer
.len
> slen
)
626 else if (s1
-> u
.buffer
.len
< slen
)
631 int omapi_td_strcasecmp (omapi_typed_data_t
*s1
, const char *s2
)
636 /* If the data type is not compatible, never equal. */
637 if (s1
-> type
!= omapi_datatype_data
&&
638 s1
-> type
!= omapi_datatype_string
)
642 if (slen
> s1
-> u
.buffer
.len
)
643 len
= s1
-> u
.buffer
.len
;
646 rv
= casecmp (s1
-> u
.buffer
.value
, s2
, len
);
649 if (s1
-> u
.buffer
.len
> slen
)
651 else if (s1
-> u
.buffer
.len
< slen
)
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
)
663 status
= omapi_value_new (vp
, file
, line
);
664 if (status
!= ISC_R_SUCCESS
)
667 status
= omapi_data_string_reference (&(*vp
) -> name
,
669 if (status
!= ISC_R_SUCCESS
) {
670 omapi_value_dereference (vp
, file
, line
);
674 status
= omapi_typed_data_reference (&(*vp
) -> value
,
676 if (status
!= ISC_R_SUCCESS
) {
677 omapi_value_dereference (vp
, file
, line
);
681 return ISC_R_SUCCESS
;
684 isc_result_t
omapi_make_const_value (omapi_value_t
**vp
,
685 omapi_data_string_t
*name
,
686 const unsigned char *value
,
688 const char *file
, int line
)
692 status
= omapi_value_new (vp
, file
, line
);
693 if (status
!= ISC_R_SUCCESS
)
696 status
= omapi_data_string_reference (&(*vp
) -> name
,
698 if (status
!= ISC_R_SUCCESS
) {
699 omapi_value_dereference (vp
, file
, line
);
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
);
709 memcpy ((*vp
) -> value
-> u
.buffer
.value
, value
, len
);
711 return ISC_R_SUCCESS
;
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
)
720 status
= omapi_value_new (vp
, file
, line
);
721 if (status
!= ISC_R_SUCCESS
)
724 status
= omapi_data_string_reference (&(*vp
) -> name
,
726 if (status
!= ISC_R_SUCCESS
) {
727 omapi_value_dereference (vp
, file
, line
);
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
);
736 return ISC_R_SUCCESS
;
739 isc_result_t
omapi_make_uint_value (omapi_value_t
**vp
,
740 omapi_data_string_t
*name
,
742 const char *file
, int line
)
744 return omapi_make_int_value (vp
, name
, (int)value
, file
, 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
)
754 status
= omapi_value_new (vp
, file
, line
);
755 if (status
!= ISC_R_SUCCESS
)
758 status
= omapi_data_string_reference (&(*vp
) -> name
,
760 if (status
!= ISC_R_SUCCESS
) {
761 omapi_value_dereference (vp
, file
, line
);
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
);
774 return ISC_R_SUCCESS
;
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
)
784 status
= omapi_value_new (vp
, file
, line
);
785 if (status
!= ISC_R_SUCCESS
)
788 status
= omapi_data_string_reference (&(*vp
) -> name
,
790 if (status
!= ISC_R_SUCCESS
) {
791 omapi_value_dereference (vp
, file
, line
);
795 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
797 if (status
!= ISC_R_SUCCESS
) {
798 omapi_value_dereference (vp
, file
, line
);
801 status
= (omapi_object_handle
802 ((omapi_handle_t
*)&(*vp
) -> value
-> u
.integer
,
804 if (status
!= ISC_R_SUCCESS
) {
805 omapi_value_dereference (vp
, file
, line
);
809 return ISC_R_SUCCESS
;
812 isc_result_t
omapi_make_string_value (omapi_value_t
**vp
,
813 omapi_data_string_t
*name
,
815 const char *file
, int line
)
819 status
= omapi_value_new (vp
, file
, line
);
820 if (status
!= ISC_R_SUCCESS
)
823 status
= omapi_data_string_reference (&(*vp
) -> name
,
825 if (status
!= ISC_R_SUCCESS
) {
826 omapi_value_dereference (vp
, file
, line
);
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
);
837 return ISC_R_SUCCESS
;
840 isc_result_t
omapi_get_int_value (unsigned long *v
, omapi_typed_data_t
*t
)
844 if (t
-> type
== omapi_datatype_int
) {
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
);
853 return ISC_R_SUCCESS
;
855 return DHCP_R_INVALIDARG
;