3 Subroutines providing general support for objects. */
6 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1999-2003 by Internet Software Consortium
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
27 * This software has been written for Internet Systems Consortium
28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29 * To learn more about Internet Systems Consortium, see
30 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
31 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
32 * ``http://www.nominum.com''.
35 #include <omapip/omapip_p.h>
37 omapi_object_type_t
*omapi_type_connection
;
38 omapi_object_type_t
*omapi_type_listener
;
39 omapi_object_type_t
*omapi_type_io_object
;
40 omapi_object_type_t
*omapi_type_datagram
;
41 omapi_object_type_t
*omapi_type_generic
;
42 omapi_object_type_t
*omapi_type_protocol
;
43 omapi_object_type_t
*omapi_type_protocol_listener
;
44 omapi_object_type_t
*omapi_type_waiter
;
45 omapi_object_type_t
*omapi_type_remote
;
46 omapi_object_type_t
*omapi_type_message
;
47 omapi_object_type_t
*omapi_type_auth_key
;
49 omapi_object_type_t
*omapi_object_types
;
50 int omapi_object_type_count
;
52 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
53 void omapi_type_relinquish ()
55 omapi_object_type_t
*t
, *n
;
57 for (t
= omapi_object_types
; t
; t
= n
) {
61 omapi_object_types
= (omapi_object_type_t
*)0;
65 isc_result_t
omapi_init (void)
72 /* Register all the standard object types... */
73 status
= omapi_object_type_register (&omapi_type_connection
,
75 omapi_connection_set_value
,
76 omapi_connection_get_value
,
77 omapi_connection_destroy
,
78 omapi_connection_signal_handler
,
79 omapi_connection_stuff_values
,
82 (omapi_connection_object_t
), 0,
84 if (status
!= ISC_R_SUCCESS
)
87 status
= omapi_object_type_register (&omapi_type_listener
,
89 omapi_listener_set_value
,
90 omapi_listener_get_value
,
91 omapi_listener_destroy
,
92 omapi_listener_signal_handler
,
93 omapi_listener_stuff_values
,
95 sizeof (omapi_listener_object_t
),
97 if (status
!= ISC_R_SUCCESS
)
101 status
= omapi_object_type_register (&omapi_type_io_object
,
106 omapi_io_signal_handler
,
107 omapi_io_stuff_values
,
109 sizeof (omapi_io_object_t
),
111 if (status
!= ISC_R_SUCCESS
)
115 status
= omapi_object_type_register (&omapi_type_generic
,
117 omapi_generic_set_value
,
118 omapi_generic_get_value
,
119 omapi_generic_destroy
,
120 omapi_generic_signal_handler
,
121 omapi_generic_stuff_values
,
123 sizeof (omapi_generic_object_t
),
125 if (status
!= ISC_R_SUCCESS
)
128 status
= omapi_object_type_register (&omapi_type_protocol
,
130 omapi_protocol_set_value
,
131 omapi_protocol_get_value
,
132 omapi_protocol_destroy
,
133 omapi_protocol_signal_handler
,
134 omapi_protocol_stuff_values
,
136 sizeof (omapi_protocol_object_t
),
138 if (status
!= ISC_R_SUCCESS
)
141 status
= (omapi_object_type_register
142 (&omapi_type_protocol_listener
, "protocol-listener",
143 omapi_protocol_listener_set_value
,
144 omapi_protocol_listener_get_value
,
145 omapi_protocol_listener_destroy
,
146 omapi_protocol_listener_signal
,
147 omapi_protocol_listener_stuff
,
149 sizeof (omapi_protocol_listener_object_t
), 0, RC_MISC
));
150 if (status
!= ISC_R_SUCCESS
)
153 status
= omapi_object_type_register (&omapi_type_message
,
155 omapi_message_set_value
,
156 omapi_message_get_value
,
157 omapi_message_destroy
,
158 omapi_message_signal_handler
,
159 omapi_message_stuff_values
,
161 sizeof (omapi_message_object_t
),
163 if (status
!= ISC_R_SUCCESS
)
167 status
= omapi_object_type_register (&omapi_type_waiter
,
172 omapi_waiter_signal_handler
, 0,
174 sizeof (omapi_waiter_object_t
),
176 if (status
!= ISC_R_SUCCESS
)
180 status
= omapi_object_type_register (&omapi_type_auth_key
,
183 omapi_auth_key_get_value
,
184 omapi_auth_key_destroy
,
186 omapi_auth_key_stuff_values
,
187 omapi_auth_key_lookup
,
189 sizeof (omapi_auth_key_t
), 0,
191 if (status
!= ISC_R_SUCCESS
)
195 #if defined (TRACING)
196 omapi_listener_trace_setup ();
197 omapi_connection_trace_setup ();
198 omapi_buffer_trace_setup ();
202 /* This seems silly, but leave it. */
203 return ISC_R_SUCCESS
;
206 isc_result_t
omapi_object_type_register (omapi_object_type_t
**type
,
208 isc_result_t (*set_value
)
211 omapi_data_string_t
*,
212 omapi_typed_data_t
*),
213 isc_result_t (*get_value
)
216 omapi_data_string_t
*,
218 isc_result_t (*destroy
)
221 isc_result_t (*signal_handler
)
223 const char *, va_list),
224 isc_result_t (*stuff_values
)
228 isc_result_t (*lookup
)
232 isc_result_t (*create
)
235 isc_result_t (*remove
)
238 isc_result_t (*freer
)
241 isc_result_t (*allocator
)
244 isc_result_t (*sizer
) (size_t),
246 isc_result_t (*initialize
)
251 omapi_object_type_t
*t
;
253 t
= dmalloc (sizeof *t
, MDL
);
255 return ISC_R_NOMEMORY
;
256 memset (t
, 0, sizeof *t
);
259 t
-> set_value
= set_value
;
260 t
-> get_value
= get_value
;
261 t
-> destroy
= destroy
;
262 t
-> signal_handler
= signal_handler
;
263 t
-> stuff_values
= stuff_values
;
264 t
-> lookup
= lookup
;
265 t
-> create
= create
;
266 t
-> remove
= remove
;
267 t
-> next
= omapi_object_types
;
271 t
-> allocator
= allocator
;
272 t
-> initialize
= initialize
;
273 t
-> rc_flag
= rc_flag
;
274 omapi_object_types
= t
;
277 return ISC_R_SUCCESS
;
280 isc_result_t
omapi_signal (omapi_object_t
*handle
, const char *name
, ...)
283 omapi_object_t
*outer
;
287 for (outer
= handle
; outer
-> outer
; outer
= outer
-> outer
)
289 if (outer
-> type
-> signal_handler
)
290 status
= (*(outer
-> type
-> signal_handler
)) (outer
,
293 status
= ISC_R_NOTFOUND
;
298 isc_result_t
omapi_signal_in (omapi_object_t
*handle
, const char *name
, ...)
304 return ISC_R_NOTFOUND
;
307 if (handle
-> type
-> signal_handler
)
308 status
= (*(handle
-> type
-> signal_handler
)) (handle
,
311 status
= ISC_R_NOTFOUND
;
316 isc_result_t
omapi_set_value (omapi_object_t
*h
,
318 omapi_data_string_t
*name
,
319 omapi_typed_data_t
*value
)
321 omapi_object_t
*outer
;
326 log_info ("omapi_set_value (%.*s, NULL)",
327 (int)name
-> len
, name
-> value
);
328 } else if (value
-> type
== omapi_datatype_int
) {
329 log_info ("omapi_set_value (%.*s, %ld)",
330 (int)name
-> len
, name
-> value
,
331 (long)value
-> u
.integer
);
332 } else if (value
-> type
== omapi_datatype_string
) {
333 log_info ("omapi_set_value (%.*s, %.*s)",
334 (int)name
-> len
, name
-> value
,
335 (int)value
-> u
.buffer
.len
, value
-> u
.buffer
.value
);
336 } else if (value
-> type
== omapi_datatype_data
) {
337 log_info ("omapi_set_value (%.*s, %ld %lx)",
338 (int)name
-> len
, name
-> value
,
339 (long)value
-> u
.buffer
.len
,
340 (unsigned long)value
-> u
.buffer
.value
);
341 } else if (value
-> type
== omapi_datatype_object
) {
342 log_info ("omapi_set_value (%.*s, %s)",
343 (int)name
-> len
, name
-> value
,
345 ? (value
-> u
.object
-> type
346 ? value
-> u
.object
-> type
-> name
347 : "(unknown object)")
348 : "(unknown object)");
352 for (outer
= h
; outer
-> outer
; outer
= outer
-> outer
)
354 if (outer
-> type
-> set_value
)
355 status
= (*(outer
-> type
-> set_value
)) (outer
,
358 status
= ISC_R_NOTFOUND
;
360 log_info (" ==> %s", isc_result_totext (status
));
365 isc_result_t
omapi_set_value_str (omapi_object_t
*h
,
368 omapi_typed_data_t
*value
)
370 omapi_data_string_t
*nds
;
373 nds
= (omapi_data_string_t
*)0;
374 status
= omapi_data_string_new (&nds
, strlen (name
), MDL
);
375 if (status
!= ISC_R_SUCCESS
)
377 memcpy (nds
-> value
, name
, strlen (name
));
379 status
= omapi_set_value (h
, id
, nds
, value
);
380 omapi_data_string_dereference (&nds
, MDL
);
384 isc_result_t
omapi_set_boolean_value (omapi_object_t
*h
, omapi_object_t
*id
,
385 const char *name
, int value
)
388 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
389 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
391 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
392 if (status
!= ISC_R_SUCCESS
)
394 memcpy (n
-> value
, name
, strlen (name
));
396 status
= omapi_typed_data_new (MDL
, &tv
, omapi_datatype_int
, value
);
397 if (status
!= ISC_R_SUCCESS
) {
398 omapi_data_string_dereference (&n
, MDL
);
402 status
= omapi_set_value (h
, id
, n
, tv
);
403 omapi_data_string_dereference (&n
, MDL
);
404 omapi_typed_data_dereference (&tv
, MDL
);
408 isc_result_t
omapi_set_int_value (omapi_object_t
*h
, omapi_object_t
*id
,
409 const char *name
, int value
)
412 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
413 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
415 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
416 if (status
!= ISC_R_SUCCESS
)
418 memcpy (n
-> value
, name
, strlen (name
));
420 status
= omapi_typed_data_new (MDL
, &tv
, omapi_datatype_int
, value
);
421 if (status
!= ISC_R_SUCCESS
) {
422 omapi_data_string_dereference (&n
, MDL
);
426 status
= omapi_set_value (h
, id
, n
, tv
);
427 omapi_data_string_dereference (&n
, MDL
);
428 omapi_typed_data_dereference (&tv
, MDL
);
432 isc_result_t
omapi_set_object_value (omapi_object_t
*h
, omapi_object_t
*id
,
433 const char *name
, omapi_object_t
*value
)
436 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
437 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
439 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
440 if (status
!= ISC_R_SUCCESS
)
442 memcpy (n
-> value
, name
, strlen (name
));
444 status
= omapi_typed_data_new (MDL
, &tv
, omapi_datatype_object
, value
);
445 if (status
!= ISC_R_SUCCESS
) {
446 omapi_data_string_dereference (&n
, MDL
);
450 status
= omapi_set_value (h
, id
, n
, tv
);
451 omapi_data_string_dereference (&n
, MDL
);
452 omapi_typed_data_dereference (&tv
, MDL
);
456 isc_result_t
omapi_set_string_value (omapi_object_t
*h
, omapi_object_t
*id
,
457 const char *name
, const char *value
)
460 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
461 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
463 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
464 if (status
!= ISC_R_SUCCESS
)
466 memcpy (n
-> value
, name
, strlen (name
));
468 status
= omapi_typed_data_new (MDL
, &tv
, omapi_datatype_string
, value
);
469 if (status
!= ISC_R_SUCCESS
) {
470 omapi_data_string_dereference (&n
, MDL
);
474 status
= omapi_set_value (h
, id
, n
, tv
);
475 omapi_data_string_dereference (&n
, MDL
);
476 omapi_typed_data_dereference (&tv
, MDL
);
480 isc_result_t
omapi_get_value (omapi_object_t
*h
,
482 omapi_data_string_t
*name
,
483 omapi_value_t
**value
)
485 omapi_object_t
*outer
;
487 for (outer
= h
; outer
-> outer
; outer
= outer
-> outer
)
489 if (outer
-> type
-> get_value
)
490 return (*(outer
-> type
-> get_value
)) (outer
,
492 return ISC_R_NOTFOUND
;
495 isc_result_t
omapi_get_value_str (omapi_object_t
*h
,
498 omapi_value_t
**value
)
500 omapi_object_t
*outer
;
501 omapi_data_string_t
*nds
;
504 nds
= (omapi_data_string_t
*)0;
505 status
= omapi_data_string_new (&nds
, strlen (name
), MDL
);
506 if (status
!= ISC_R_SUCCESS
)
508 memcpy (nds
-> value
, name
, strlen (name
));
510 for (outer
= h
; outer
-> outer
; outer
= outer
-> outer
)
512 if (outer
-> type
-> get_value
)
513 status
= (*(outer
-> type
-> get_value
)) (outer
,
516 status
= ISC_R_NOTFOUND
;
517 omapi_data_string_dereference (&nds
, MDL
);
521 isc_result_t
omapi_stuff_values (omapi_object_t
*c
,
525 omapi_object_t
*outer
;
527 for (outer
= o
; outer
-> outer
; outer
= outer
-> outer
)
529 if (outer
-> type
-> stuff_values
)
530 return (*(outer
-> type
-> stuff_values
)) (c
, id
, outer
);
531 return ISC_R_NOTFOUND
;
534 isc_result_t
omapi_object_create (omapi_object_t
**obj
, omapi_object_t
*id
,
535 omapi_object_type_t
*type
)
538 return ISC_R_NOTIMPLEMENTED
;
539 return (*(type
-> create
)) (obj
, id
);
542 isc_result_t
omapi_object_update (omapi_object_t
*obj
, omapi_object_t
*id
,
543 omapi_object_t
*src
, omapi_handle_t handle
)
545 omapi_generic_object_t
*gsrc
;
550 return ISC_R_INVALIDARG
;
551 if (src
-> type
!= omapi_type_generic
)
552 return ISC_R_NOTIMPLEMENTED
;
553 gsrc
= (omapi_generic_object_t
*)src
;
554 for (i
= 0; i
< gsrc
-> nvalues
; i
++) {
555 status
= omapi_set_value (obj
, id
,
556 gsrc
-> values
[i
] -> name
,
557 gsrc
-> values
[i
] -> value
);
558 if (status
!= ISC_R_SUCCESS
&& status
!= ISC_R_UNCHANGED
)
562 omapi_set_int_value (obj
, id
, "remote-handle", (int)handle
);
563 status
= omapi_signal (obj
, "updated");
564 if (status
!= ISC_R_NOTFOUND
)
566 return ISC_R_SUCCESS
;
569 int omapi_data_string_cmp (omapi_data_string_t
*s1
, omapi_data_string_t
*s2
)
574 if (s1
-> len
> s2
-> len
)
578 rv
= memcmp (s1
-> value
, s2
-> value
, len
);
581 if (s1
-> len
> s2
-> len
)
583 else if (s1
-> len
< s2
-> len
)
588 int omapi_ds_strcmp (omapi_data_string_t
*s1
, const char *s2
)
594 if (slen
> s1
-> len
)
598 rv
= memcmp (s1
-> value
, s2
, len
);
601 if (s1
-> len
> slen
)
603 else if (s1
-> len
< slen
)
608 int omapi_td_strcmp (omapi_typed_data_t
*s1
, const char *s2
)
613 /* If the data type is not compatible, never equal. */
614 if (s1
-> type
!= omapi_datatype_data
&&
615 s1
-> type
!= omapi_datatype_string
)
619 if (slen
> s1
-> u
.buffer
.len
)
620 len
= s1
-> u
.buffer
.len
;
623 rv
= memcmp (s1
-> u
.buffer
.value
, s2
, len
);
626 if (s1
-> u
.buffer
.len
> slen
)
628 else if (s1
-> u
.buffer
.len
< slen
)
633 int omapi_td_strcasecmp (omapi_typed_data_t
*s1
, const char *s2
)
638 /* If the data type is not compatible, never equal. */
639 if (s1
-> type
!= omapi_datatype_data
&&
640 s1
-> type
!= omapi_datatype_string
)
644 if (slen
> s1
-> u
.buffer
.len
)
645 len
= s1
-> u
.buffer
.len
;
648 rv
= casecmp (s1
-> u
.buffer
.value
, s2
, len
);
651 if (s1
-> u
.buffer
.len
> slen
)
653 else if (s1
-> u
.buffer
.len
< slen
)
658 isc_result_t
omapi_make_value (omapi_value_t
**vp
,
659 omapi_data_string_t
*name
,
660 omapi_typed_data_t
*value
,
661 const char *file
, int line
)
665 status
= omapi_value_new (vp
, file
, line
);
666 if (status
!= ISC_R_SUCCESS
)
669 status
= omapi_data_string_reference (&(*vp
) -> name
,
671 if (status
!= ISC_R_SUCCESS
) {
672 omapi_value_dereference (vp
, file
, line
);
676 status
= omapi_typed_data_reference (&(*vp
) -> value
,
678 if (status
!= ISC_R_SUCCESS
) {
679 omapi_value_dereference (vp
, file
, line
);
683 return ISC_R_SUCCESS
;
686 isc_result_t
omapi_make_const_value (omapi_value_t
**vp
,
687 omapi_data_string_t
*name
,
688 const unsigned char *value
,
690 const char *file
, int line
)
694 status
= omapi_value_new (vp
, file
, line
);
695 if (status
!= ISC_R_SUCCESS
)
698 status
= omapi_data_string_reference (&(*vp
) -> name
,
700 if (status
!= ISC_R_SUCCESS
) {
701 omapi_value_dereference (vp
, file
, line
);
705 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
706 omapi_datatype_data
, len
);
707 if (status
!= ISC_R_SUCCESS
) {
708 omapi_value_dereference (vp
, file
, line
);
711 memcpy ((*vp
) -> value
-> u
.buffer
.value
, value
, len
);
713 return ISC_R_SUCCESS
;
716 isc_result_t
omapi_make_int_value (omapi_value_t
**vp
,
717 omapi_data_string_t
*name
,
718 int value
, const char *file
, int line
)
722 status
= omapi_value_new (vp
, file
, line
);
723 if (status
!= ISC_R_SUCCESS
)
726 status
= omapi_data_string_reference (&(*vp
) -> name
,
728 if (status
!= ISC_R_SUCCESS
) {
729 omapi_value_dereference (vp
, file
, line
);
732 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
733 omapi_datatype_int
, value
);
734 if (status
!= ISC_R_SUCCESS
) {
735 omapi_value_dereference (vp
, file
, line
);
738 return ISC_R_SUCCESS
;
741 isc_result_t
omapi_make_uint_value (omapi_value_t
**vp
,
742 omapi_data_string_t
*name
,
744 const char *file
, int line
)
746 return omapi_make_int_value (vp
, name
, (int)value
, file
, line
);
749 isc_result_t
omapi_make_object_value (omapi_value_t
**vp
,
750 omapi_data_string_t
*name
,
751 omapi_object_t
*value
,
752 const char *file
, int line
)
756 status
= omapi_value_new (vp
, file
, line
);
757 if (status
!= ISC_R_SUCCESS
)
760 status
= omapi_data_string_reference (&(*vp
) -> name
,
762 if (status
!= ISC_R_SUCCESS
) {
763 omapi_value_dereference (vp
, file
, line
);
768 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
769 omapi_datatype_object
, value
);
770 if (status
!= ISC_R_SUCCESS
) {
771 omapi_value_dereference (vp
, file
, line
);
776 return ISC_R_SUCCESS
;
779 isc_result_t
omapi_make_handle_value (omapi_value_t
**vp
,
780 omapi_data_string_t
*name
,
781 omapi_object_t
*value
,
782 const char *file
, int line
)
786 status
= omapi_value_new (vp
, file
, line
);
787 if (status
!= ISC_R_SUCCESS
)
790 status
= omapi_data_string_reference (&(*vp
) -> name
,
792 if (status
!= ISC_R_SUCCESS
) {
793 omapi_value_dereference (vp
, file
, line
);
797 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
799 if (status
!= ISC_R_SUCCESS
) {
800 omapi_value_dereference (vp
, file
, line
);
803 status
= (omapi_object_handle
804 ((omapi_handle_t
*)&(*vp
) -> value
-> u
.integer
,
806 if (status
!= ISC_R_SUCCESS
) {
807 omapi_value_dereference (vp
, file
, line
);
811 return ISC_R_SUCCESS
;
814 isc_result_t
omapi_make_string_value (omapi_value_t
**vp
,
815 omapi_data_string_t
*name
,
817 const char *file
, int line
)
821 status
= omapi_value_new (vp
, file
, line
);
822 if (status
!= ISC_R_SUCCESS
)
825 status
= omapi_data_string_reference (&(*vp
) -> name
,
827 if (status
!= ISC_R_SUCCESS
) {
828 omapi_value_dereference (vp
, file
, line
);
832 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
833 omapi_datatype_string
, value
);
834 if (status
!= ISC_R_SUCCESS
) {
835 omapi_value_dereference (vp
, file
, line
);
839 return ISC_R_SUCCESS
;
842 isc_result_t
omapi_get_int_value (unsigned long *v
, omapi_typed_data_t
*t
)
846 if (t
-> type
== omapi_datatype_int
) {
848 return ISC_R_SUCCESS
;
849 } else if (t
-> type
== omapi_datatype_string
||
850 t
-> type
== omapi_datatype_data
) {
851 if (t
-> u
.buffer
.len
!= sizeof (rv
))
852 return ISC_R_INVALIDARG
;
853 memcpy (&rv
, t
-> u
.buffer
.value
, sizeof rv
);
855 return ISC_R_SUCCESS
;
857 return ISC_R_INVALIDARG
;