3 Subroutines providing general support for objects. */
6 * Copyright (c) 2009,2012,2014 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (c) 1999-2003 by Internet Software Consortium
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.
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.
22 * Internet Systems Consortium, Inc.
24 * Redwood City, CA 94063
26 * https://www.isc.org/
32 #include <omapip/omapip_p.h>
34 omapi_object_type_t
*omapi_type_connection
;
35 omapi_object_type_t
*omapi_type_listener
;
36 omapi_object_type_t
*omapi_type_io_object
;
37 omapi_object_type_t
*omapi_type_datagram
;
38 omapi_object_type_t
*omapi_type_generic
;
39 omapi_object_type_t
*omapi_type_protocol
;
40 omapi_object_type_t
*omapi_type_protocol_listener
;
41 omapi_object_type_t
*omapi_type_waiter
;
42 omapi_object_type_t
*omapi_type_remote
;
43 omapi_object_type_t
*omapi_type_message
;
44 omapi_object_type_t
*omapi_type_auth_key
;
46 omapi_object_type_t
*omapi_object_types
;
47 int omapi_object_type_count
;
49 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
50 void omapi_type_relinquish ()
52 omapi_object_type_t
*t
, *n
;
54 for (t
= omapi_object_types
; t
; t
= n
) {
58 omapi_object_types
= (omapi_object_type_t
*)0;
62 isc_result_t
omapi_init (void)
66 /* Register all the standard object types... */
67 status
= omapi_object_type_register (&omapi_type_connection
,
69 omapi_connection_set_value
,
70 omapi_connection_get_value
,
71 omapi_connection_destroy
,
72 omapi_connection_signal_handler
,
73 omapi_connection_stuff_values
,
76 (omapi_connection_object_t
), 0,
78 if (status
!= ISC_R_SUCCESS
)
81 status
= omapi_object_type_register (&omapi_type_listener
,
83 omapi_listener_set_value
,
84 omapi_listener_get_value
,
85 omapi_listener_destroy
,
86 omapi_listener_signal_handler
,
87 omapi_listener_stuff_values
,
89 sizeof (omapi_listener_object_t
),
91 if (status
!= ISC_R_SUCCESS
)
94 status
= omapi_object_type_register (&omapi_type_io_object
,
99 omapi_io_signal_handler
,
100 omapi_io_stuff_values
,
102 sizeof (omapi_io_object_t
),
104 if (status
!= ISC_R_SUCCESS
)
107 status
= omapi_object_type_register (&omapi_type_generic
,
109 omapi_generic_set_value
,
110 omapi_generic_get_value
,
111 omapi_generic_destroy
,
112 omapi_generic_signal_handler
,
113 omapi_generic_stuff_values
,
115 sizeof (omapi_generic_object_t
),
117 if (status
!= ISC_R_SUCCESS
)
120 status
= omapi_object_type_register (&omapi_type_protocol
,
122 omapi_protocol_set_value
,
123 omapi_protocol_get_value
,
124 omapi_protocol_destroy
,
125 omapi_protocol_signal_handler
,
126 omapi_protocol_stuff_values
,
128 sizeof (omapi_protocol_object_t
),
130 if (status
!= ISC_R_SUCCESS
)
133 status
= (omapi_object_type_register
134 (&omapi_type_protocol_listener
, "protocol-listener",
135 omapi_protocol_listener_set_value
,
136 omapi_protocol_listener_get_value
,
137 omapi_protocol_listener_destroy
,
138 omapi_protocol_listener_signal
,
139 omapi_protocol_listener_stuff
,
141 sizeof (omapi_protocol_listener_object_t
), 0, RC_MISC
));
142 if (status
!= ISC_R_SUCCESS
)
145 status
= omapi_object_type_register (&omapi_type_message
,
147 omapi_message_set_value
,
148 omapi_message_get_value
,
149 omapi_message_destroy
,
150 omapi_message_signal_handler
,
151 omapi_message_stuff_values
,
153 sizeof (omapi_message_object_t
),
155 if (status
!= ISC_R_SUCCESS
)
158 status
= omapi_object_type_register (&omapi_type_waiter
,
163 omapi_waiter_signal_handler
, 0,
165 sizeof (omapi_waiter_object_t
),
167 if (status
!= ISC_R_SUCCESS
)
170 status
= omapi_object_type_register (&omapi_type_auth_key
,
173 omapi_auth_key_get_value
,
174 omapi_auth_key_destroy
,
176 omapi_auth_key_stuff_values
,
177 omapi_auth_key_lookup
,
179 sizeof (omapi_auth_key_t
), 0,
181 if (status
!= ISC_R_SUCCESS
)
184 #if defined (TRACING)
185 omapi_listener_trace_setup ();
186 omapi_connection_trace_setup ();
187 omapi_buffer_trace_setup ();
190 /* This seems silly, but leave it. */
191 return ISC_R_SUCCESS
;
194 isc_result_t
omapi_object_type_register (omapi_object_type_t
**type
,
196 isc_result_t (*set_value
)
199 omapi_data_string_t
*,
200 omapi_typed_data_t
*),
201 isc_result_t (*get_value
)
204 omapi_data_string_t
*,
206 isc_result_t (*destroy
)
209 isc_result_t (*signal_handler
)
211 const char *, va_list),
212 isc_result_t (*stuff_values
)
216 isc_result_t (*lookup
)
220 isc_result_t (*create
)
223 isc_result_t (*remove
)
226 isc_result_t (*freer
)
229 isc_result_t (*allocator
)
232 isc_result_t (*sizer
) (size_t),
234 isc_result_t (*initialize
)
239 omapi_object_type_t
*t
;
241 t
= dmalloc (sizeof *t
, MDL
);
243 return ISC_R_NOMEMORY
;
244 memset (t
, 0, sizeof *t
);
247 t
-> set_value
= set_value
;
248 t
-> get_value
= get_value
;
249 t
-> destroy
= destroy
;
250 t
-> signal_handler
= signal_handler
;
251 t
-> stuff_values
= stuff_values
;
252 t
-> lookup
= lookup
;
253 t
-> create
= create
;
254 t
-> remove
= remove
;
255 t
-> next
= omapi_object_types
;
259 t
-> allocator
= allocator
;
260 t
-> initialize
= initialize
;
261 t
-> rc_flag
= rc_flag
;
262 omapi_object_types
= t
;
265 return ISC_R_SUCCESS
;
268 isc_result_t
omapi_signal (omapi_object_t
*handle
, const char *name
, ...)
271 omapi_object_t
*outer
;
275 for (outer
= handle
; outer
-> outer
; outer
= outer
-> outer
)
277 if (outer
-> type
-> signal_handler
)
278 status
= (*(outer
-> type
-> signal_handler
)) (outer
,
281 status
= ISC_R_NOTFOUND
;
286 isc_result_t
omapi_signal_in (omapi_object_t
*handle
, const char *name
, ...)
292 return ISC_R_NOTFOUND
;
295 if (handle
-> type
-> signal_handler
)
296 status
= (*(handle
-> type
-> signal_handler
)) (handle
,
299 status
= ISC_R_NOTFOUND
;
304 isc_result_t
omapi_set_value (omapi_object_t
*h
,
306 omapi_data_string_t
*name
,
307 omapi_typed_data_t
*value
)
309 omapi_object_t
*outer
;
314 log_info ("omapi_set_value (%.*s, NULL)",
315 (int)name
-> len
, name
-> value
);
316 } else if (value
-> type
== omapi_datatype_int
) {
317 log_info ("omapi_set_value (%.*s, %ld)",
318 (int)name
-> len
, name
-> value
,
319 (long)value
-> u
.integer
);
320 } else if (value
-> type
== omapi_datatype_string
) {
321 log_info ("omapi_set_value (%.*s, %.*s)",
322 (int)name
-> len
, name
-> value
,
323 (int)value
-> u
.buffer
.len
, value
-> u
.buffer
.value
);
324 } else if (value
-> type
== omapi_datatype_data
) {
325 log_info ("omapi_set_value (%.*s, %ld %lx)",
326 (int)name
-> len
, name
-> value
,
327 (long)value
-> u
.buffer
.len
,
328 (unsigned long)value
-> u
.buffer
.value
);
329 } else if (value
-> type
== omapi_datatype_object
) {
330 log_info ("omapi_set_value (%.*s, %s)",
331 (int)name
-> len
, name
-> value
,
333 ? (value
-> u
.object
-> type
334 ? value
-> u
.object
-> type
-> name
335 : "(unknown object)")
336 : "(unknown object)");
340 for (outer
= h
; outer
-> outer
; outer
= outer
-> outer
)
342 if (outer
-> type
-> set_value
)
343 status
= (*(outer
-> type
-> set_value
)) (outer
,
346 status
= ISC_R_NOTFOUND
;
348 log_info (" ==> %s", isc_result_totext (status
));
353 isc_result_t
omapi_set_value_str (omapi_object_t
*h
,
356 omapi_typed_data_t
*value
)
358 omapi_data_string_t
*nds
;
361 nds
= (omapi_data_string_t
*)0;
362 status
= omapi_data_string_new (&nds
, strlen (name
), MDL
);
363 if (status
!= ISC_R_SUCCESS
)
365 memcpy (nds
-> value
, name
, strlen (name
));
367 status
= omapi_set_value (h
, id
, nds
, value
);
368 omapi_data_string_dereference (&nds
, MDL
);
372 isc_result_t
omapi_set_boolean_value (omapi_object_t
*h
, omapi_object_t
*id
,
373 const char *name
, int value
)
376 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
377 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
379 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
380 if (status
!= ISC_R_SUCCESS
)
382 memcpy (n
-> value
, name
, strlen (name
));
384 status
= omapi_typed_data_new (MDL
, &tv
, omapi_datatype_int
, value
);
385 if (status
!= ISC_R_SUCCESS
) {
386 omapi_data_string_dereference (&n
, MDL
);
390 status
= omapi_set_value (h
, id
, n
, tv
);
391 omapi_data_string_dereference (&n
, MDL
);
392 omapi_typed_data_dereference (&tv
, MDL
);
396 isc_result_t
omapi_set_int_value (omapi_object_t
*h
, omapi_object_t
*id
,
397 const char *name
, int value
)
400 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
401 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
403 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
404 if (status
!= ISC_R_SUCCESS
)
406 memcpy (n
-> value
, name
, strlen (name
));
408 status
= omapi_typed_data_new (MDL
, &tv
, omapi_datatype_int
, value
);
409 if (status
!= ISC_R_SUCCESS
) {
410 omapi_data_string_dereference (&n
, MDL
);
414 status
= omapi_set_value (h
, id
, n
, tv
);
415 omapi_data_string_dereference (&n
, MDL
);
416 omapi_typed_data_dereference (&tv
, MDL
);
420 isc_result_t
omapi_set_object_value (omapi_object_t
*h
, omapi_object_t
*id
,
421 const char *name
, omapi_object_t
*value
)
424 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
425 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
427 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
428 if (status
!= ISC_R_SUCCESS
)
430 memcpy (n
-> value
, name
, strlen (name
));
432 status
= omapi_typed_data_new (MDL
, &tv
, omapi_datatype_object
, value
);
433 if (status
!= ISC_R_SUCCESS
) {
434 omapi_data_string_dereference (&n
, MDL
);
438 status
= omapi_set_value (h
, id
, n
, tv
);
439 omapi_data_string_dereference (&n
, MDL
);
440 omapi_typed_data_dereference (&tv
, MDL
);
444 isc_result_t
omapi_set_string_value (omapi_object_t
*h
, omapi_object_t
*id
,
445 const char *name
, const char *value
)
448 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
449 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
451 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
452 if (status
!= ISC_R_SUCCESS
)
454 memcpy (n
-> value
, name
, strlen (name
));
456 status
= omapi_typed_data_new (MDL
, &tv
, omapi_datatype_string
, value
);
457 if (status
!= ISC_R_SUCCESS
) {
458 omapi_data_string_dereference (&n
, MDL
);
462 status
= omapi_set_value (h
, id
, n
, tv
);
463 omapi_data_string_dereference (&n
, MDL
);
464 omapi_typed_data_dereference (&tv
, MDL
);
468 isc_result_t
omapi_get_value (omapi_object_t
*h
,
470 omapi_data_string_t
*name
,
471 omapi_value_t
**value
)
473 omapi_object_t
*outer
;
475 for (outer
= h
; outer
-> outer
; outer
= outer
-> outer
)
477 if (outer
-> type
-> get_value
)
478 return (*(outer
-> type
-> get_value
)) (outer
,
480 return ISC_R_NOTFOUND
;
483 isc_result_t
omapi_get_value_str (omapi_object_t
*h
,
486 omapi_value_t
**value
)
488 omapi_object_t
*outer
;
489 omapi_data_string_t
*nds
;
492 nds
= (omapi_data_string_t
*)0;
493 status
= omapi_data_string_new (&nds
, strlen (name
), MDL
);
494 if (status
!= ISC_R_SUCCESS
)
496 memcpy (nds
-> value
, name
, strlen (name
));
498 for (outer
= h
; outer
-> outer
; outer
= outer
-> outer
)
500 if (outer
-> type
-> get_value
)
501 status
= (*(outer
-> type
-> get_value
)) (outer
,
504 status
= ISC_R_NOTFOUND
;
505 omapi_data_string_dereference (&nds
, MDL
);
509 isc_result_t
omapi_stuff_values (omapi_object_t
*c
,
513 omapi_object_t
*outer
;
515 for (outer
= o
; outer
-> outer
; outer
= outer
-> outer
)
517 if (outer
-> type
-> stuff_values
)
518 return (*(outer
-> type
-> stuff_values
)) (c
, id
, outer
);
519 return ISC_R_NOTFOUND
;
522 isc_result_t
omapi_object_create (omapi_object_t
**obj
, omapi_object_t
*id
,
523 omapi_object_type_t
*type
)
526 return ISC_R_NOTIMPLEMENTED
;
527 return (*(type
-> create
)) (obj
, id
);
530 isc_result_t
omapi_object_update (omapi_object_t
*obj
, omapi_object_t
*id
,
531 omapi_object_t
*src
, omapi_handle_t handle
)
533 omapi_generic_object_t
*gsrc
;
538 return DHCP_R_INVALIDARG
;
539 if (src
-> type
!= omapi_type_generic
)
540 return ISC_R_NOTIMPLEMENTED
;
541 gsrc
= (omapi_generic_object_t
*)src
;
542 for (i
= 0; i
< gsrc
-> nvalues
; i
++) {
543 status
= omapi_set_value (obj
, id
,
544 gsrc
-> values
[i
] -> name
,
545 gsrc
-> values
[i
] -> value
);
546 if (status
!= ISC_R_SUCCESS
&& status
!= DHCP_R_UNCHANGED
)
551 * For now ignore the return value. I'm not sure if we want to
552 * generate an error if we can't set the handle value. If we
553 * do add a check we probably should allow unchanged and notfound
556 (void) omapi_set_int_value (obj
, id
, "remote-handle", (int)handle
);
557 status
= omapi_signal (obj
, "updated");
558 if (status
!= ISC_R_NOTFOUND
)
560 return ISC_R_SUCCESS
;
563 int omapi_data_string_cmp (omapi_data_string_t
*s1
, omapi_data_string_t
*s2
)
568 if (s1
-> len
> s2
-> len
)
572 rv
= memcmp (s1
-> value
, s2
-> value
, len
);
575 if (s1
-> len
> s2
-> len
)
577 else if (s1
-> len
< s2
-> len
)
582 int omapi_ds_strcmp (omapi_data_string_t
*s1
, const char *s2
)
588 if (slen
> s1
-> len
)
592 rv
= memcmp (s1
-> value
, s2
, len
);
595 if (s1
-> len
> slen
)
597 else if (s1
-> len
< slen
)
602 int omapi_td_strcmp (omapi_typed_data_t
*s1
, const char *s2
)
607 /* If the data type is not compatible, never equal. */
608 if (s1
-> type
!= omapi_datatype_data
&&
609 s1
-> type
!= omapi_datatype_string
)
613 if (slen
> s1
-> u
.buffer
.len
)
614 len
= s1
-> u
.buffer
.len
;
617 rv
= memcmp (s1
-> u
.buffer
.value
, s2
, len
);
620 if (s1
-> u
.buffer
.len
> slen
)
622 else if (s1
-> u
.buffer
.len
< slen
)
627 int omapi_td_strcasecmp (omapi_typed_data_t
*s1
, const char *s2
)
632 /* If the data type is not compatible, never equal. */
633 if (s1
-> type
!= omapi_datatype_data
&&
634 s1
-> type
!= omapi_datatype_string
)
638 if (slen
> s1
-> u
.buffer
.len
)
639 len
= s1
-> u
.buffer
.len
;
642 rv
= casecmp (s1
-> u
.buffer
.value
, s2
, len
);
645 if (s1
-> u
.buffer
.len
> slen
)
647 else if (s1
-> u
.buffer
.len
< slen
)
652 isc_result_t
omapi_make_value (omapi_value_t
**vp
,
653 omapi_data_string_t
*name
,
654 omapi_typed_data_t
*value
,
655 const char *file
, int line
)
659 status
= omapi_value_new (vp
, file
, line
);
660 if (status
!= ISC_R_SUCCESS
)
663 status
= omapi_data_string_reference (&(*vp
) -> name
,
665 if (status
!= ISC_R_SUCCESS
) {
666 omapi_value_dereference (vp
, file
, line
);
670 status
= omapi_typed_data_reference (&(*vp
) -> value
,
672 if (status
!= ISC_R_SUCCESS
) {
673 omapi_value_dereference (vp
, file
, line
);
677 return ISC_R_SUCCESS
;
680 isc_result_t
omapi_make_const_value (omapi_value_t
**vp
,
681 omapi_data_string_t
*name
,
682 const unsigned char *value
,
684 const char *file
, int line
)
688 status
= omapi_value_new (vp
, file
, line
);
689 if (status
!= ISC_R_SUCCESS
)
692 status
= omapi_data_string_reference (&(*vp
) -> name
,
694 if (status
!= ISC_R_SUCCESS
) {
695 omapi_value_dereference (vp
, file
, line
);
699 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
700 omapi_datatype_data
, len
);
701 if (status
!= ISC_R_SUCCESS
) {
702 omapi_value_dereference (vp
, file
, line
);
705 memcpy ((*vp
) -> value
-> u
.buffer
.value
, value
, len
);
707 return ISC_R_SUCCESS
;
710 isc_result_t
omapi_make_int_value (omapi_value_t
**vp
,
711 omapi_data_string_t
*name
,
712 int value
, const char *file
, int line
)
716 status
= omapi_value_new (vp
, file
, line
);
717 if (status
!= ISC_R_SUCCESS
)
720 status
= omapi_data_string_reference (&(*vp
) -> name
,
722 if (status
!= ISC_R_SUCCESS
) {
723 omapi_value_dereference (vp
, file
, line
);
726 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
727 omapi_datatype_int
, value
);
728 if (status
!= ISC_R_SUCCESS
) {
729 omapi_value_dereference (vp
, file
, line
);
732 return ISC_R_SUCCESS
;
735 isc_result_t
omapi_make_uint_value (omapi_value_t
**vp
,
736 omapi_data_string_t
*name
,
738 const char *file
, int line
)
740 return omapi_make_int_value (vp
, name
, (int)value
, file
, line
);
743 isc_result_t
omapi_make_object_value (omapi_value_t
**vp
,
744 omapi_data_string_t
*name
,
745 omapi_object_t
*value
,
746 const char *file
, int line
)
750 status
= omapi_value_new (vp
, file
, line
);
751 if (status
!= ISC_R_SUCCESS
)
754 status
= omapi_data_string_reference (&(*vp
) -> name
,
756 if (status
!= ISC_R_SUCCESS
) {
757 omapi_value_dereference (vp
, file
, line
);
762 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
763 omapi_datatype_object
, value
);
764 if (status
!= ISC_R_SUCCESS
) {
765 omapi_value_dereference (vp
, file
, line
);
770 return ISC_R_SUCCESS
;
773 isc_result_t
omapi_make_handle_value (omapi_value_t
**vp
,
774 omapi_data_string_t
*name
,
775 omapi_object_t
*value
,
776 const char *file
, int line
)
780 status
= omapi_value_new (vp
, file
, line
);
781 if (status
!= ISC_R_SUCCESS
)
784 status
= omapi_data_string_reference (&(*vp
) -> name
,
786 if (status
!= ISC_R_SUCCESS
) {
787 omapi_value_dereference (vp
, file
, line
);
791 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
793 if (status
!= ISC_R_SUCCESS
) {
794 omapi_value_dereference (vp
, file
, line
);
797 status
= (omapi_object_handle
798 ((omapi_handle_t
*)&(*vp
) -> value
-> u
.integer
,
800 if (status
!= ISC_R_SUCCESS
) {
801 omapi_value_dereference (vp
, file
, line
);
805 return ISC_R_SUCCESS
;
808 isc_result_t
omapi_make_string_value (omapi_value_t
**vp
,
809 omapi_data_string_t
*name
,
811 const char *file
, int line
)
815 status
= omapi_value_new (vp
, file
, line
);
816 if (status
!= ISC_R_SUCCESS
)
819 status
= omapi_data_string_reference (&(*vp
) -> name
,
821 if (status
!= ISC_R_SUCCESS
) {
822 omapi_value_dereference (vp
, file
, line
);
826 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
827 omapi_datatype_string
, value
);
828 if (status
!= ISC_R_SUCCESS
) {
829 omapi_value_dereference (vp
, file
, line
);
833 return ISC_R_SUCCESS
;
836 isc_result_t
omapi_get_int_value (unsigned long *v
, omapi_typed_data_t
*t
)
840 if (t
-> type
== omapi_datatype_int
) {
842 return ISC_R_SUCCESS
;
843 } else if (t
-> type
== omapi_datatype_string
||
844 t
-> type
== omapi_datatype_data
) {
845 if (t
-> u
.buffer
.len
!= sizeof (rv
))
846 return DHCP_R_INVALIDARG
;
847 memcpy (&rv
, t
-> u
.buffer
.value
, sizeof rv
);
849 return ISC_R_SUCCESS
;
851 return DHCP_R_INVALIDARG
;