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
;
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)
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
)
100 status
= omapi_object_type_register (&omapi_type_io_object
,
105 omapi_io_signal_handler
,
106 omapi_io_stuff_values
,
108 sizeof (omapi_io_object_t
),
110 if (status
!= ISC_R_SUCCESS
)
113 status
= omapi_object_type_register (&omapi_type_generic
,
115 omapi_generic_set_value
,
116 omapi_generic_get_value
,
117 omapi_generic_destroy
,
118 omapi_generic_signal_handler
,
119 omapi_generic_stuff_values
,
121 sizeof (omapi_generic_object_t
),
123 if (status
!= ISC_R_SUCCESS
)
126 status
= omapi_object_type_register (&omapi_type_protocol
,
128 omapi_protocol_set_value
,
129 omapi_protocol_get_value
,
130 omapi_protocol_destroy
,
131 omapi_protocol_signal_handler
,
132 omapi_protocol_stuff_values
,
134 sizeof (omapi_protocol_object_t
),
136 if (status
!= ISC_R_SUCCESS
)
139 status
= (omapi_object_type_register
140 (&omapi_type_protocol_listener
, "protocol-listener",
141 omapi_protocol_listener_set_value
,
142 omapi_protocol_listener_get_value
,
143 omapi_protocol_listener_destroy
,
144 omapi_protocol_listener_signal
,
145 omapi_protocol_listener_stuff
,
147 sizeof (omapi_protocol_listener_object_t
), 0, RC_MISC
));
148 if (status
!= ISC_R_SUCCESS
)
151 status
= omapi_object_type_register (&omapi_type_message
,
153 omapi_message_set_value
,
154 omapi_message_get_value
,
155 omapi_message_destroy
,
156 omapi_message_signal_handler
,
157 omapi_message_stuff_values
,
159 sizeof (omapi_message_object_t
),
161 if (status
!= ISC_R_SUCCESS
)
164 status
= omapi_object_type_register (&omapi_type_waiter
,
169 omapi_waiter_signal_handler
, 0,
171 sizeof (omapi_waiter_object_t
),
173 if (status
!= ISC_R_SUCCESS
)
176 status
= omapi_object_type_register (&omapi_type_auth_key
,
179 omapi_auth_key_get_value
,
180 omapi_auth_key_destroy
,
182 omapi_auth_key_stuff_values
,
183 omapi_auth_key_lookup
,
185 sizeof (omapi_auth_key_t
), 0,
187 if (status
!= ISC_R_SUCCESS
)
190 #if defined (TRACING)
191 omapi_listener_trace_setup ();
192 omapi_connection_trace_setup ();
193 omapi_buffer_trace_setup ();
197 /* This seems silly, but leave it. */
198 return ISC_R_SUCCESS
;
201 isc_result_t
omapi_object_type_register (omapi_object_type_t
**type
,
203 isc_result_t (*set_value
)
206 omapi_data_string_t
*,
207 omapi_typed_data_t
*),
208 isc_result_t (*get_value
)
211 omapi_data_string_t
*,
213 isc_result_t (*destroy
)
216 isc_result_t (*signal_handler
)
218 const char *, va_list),
219 isc_result_t (*stuff_values
)
223 isc_result_t (*lookup
)
227 isc_result_t (*create
)
230 isc_result_t (*remove
)
233 isc_result_t (*freer
)
236 isc_result_t (*allocator
)
239 isc_result_t (*sizer
) (size_t),
241 isc_result_t (*initialize
)
246 omapi_object_type_t
*t
;
248 t
= dmalloc (sizeof *t
, MDL
);
250 return ISC_R_NOMEMORY
;
251 memset (t
, 0, sizeof *t
);
254 t
-> set_value
= set_value
;
255 t
-> get_value
= get_value
;
256 t
-> destroy
= destroy
;
257 t
-> signal_handler
= signal_handler
;
258 t
-> stuff_values
= stuff_values
;
259 t
-> lookup
= lookup
;
260 t
-> create
= create
;
261 t
-> remove
= remove
;
262 t
-> next
= omapi_object_types
;
266 t
-> allocator
= allocator
;
267 t
-> initialize
= initialize
;
268 t
-> rc_flag
= rc_flag
;
269 omapi_object_types
= t
;
272 return ISC_R_SUCCESS
;
275 isc_result_t
omapi_signal (omapi_object_t
*handle
, const char *name
, ...)
278 omapi_object_t
*outer
;
282 for (outer
= handle
; outer
-> outer
; outer
= outer
-> outer
)
284 if (outer
-> type
-> signal_handler
)
285 status
= (*(outer
-> type
-> signal_handler
)) (outer
,
288 status
= ISC_R_NOTFOUND
;
293 isc_result_t
omapi_signal_in (omapi_object_t
*handle
, const char *name
, ...)
296 // omapi_object_t *outer;
300 return ISC_R_NOTFOUND
;
303 if (handle
-> type
-> signal_handler
)
304 status
= (*(handle
-> type
-> signal_handler
)) (handle
,
307 status
= ISC_R_NOTFOUND
;
312 isc_result_t
omapi_set_value (omapi_object_t
*h
,
314 omapi_data_string_t
*name
,
315 omapi_typed_data_t
*value
)
317 omapi_object_t
*outer
;
322 log_info ("omapi_set_value (%.*s, NULL)",
323 (int)name
-> len
, name
-> value
);
324 } else if (value
-> type
== omapi_datatype_int
) {
325 log_info ("omapi_set_value (%.*s, %ld)",
326 (int)name
-> len
, name
-> value
,
327 (long)value
-> u
.integer
);
328 } else if (value
-> type
== omapi_datatype_string
) {
329 log_info ("omapi_set_value (%.*s, %.*s)",
330 (int)name
-> len
, name
-> value
,
331 (int)value
-> u
.buffer
.len
, value
-> u
.buffer
.value
);
332 } else if (value
-> type
== omapi_datatype_data
) {
333 log_info ("omapi_set_value (%.*s, %ld %lx)",
334 (int)name
-> len
, name
-> value
,
335 (long)value
-> u
.buffer
.len
,
336 (unsigned long)value
-> u
.buffer
.value
);
337 } else if (value
-> type
== omapi_datatype_object
) {
338 log_info ("omapi_set_value (%.*s, %s)",
339 (int)name
-> len
, name
-> value
,
341 ? (value
-> u
.object
-> type
342 ? value
-> u
.object
-> type
-> name
343 : "(unknown object)")
344 : "(unknown object)");
348 for (outer
= h
; outer
-> outer
; outer
= outer
-> outer
)
350 if (outer
-> type
-> set_value
)
351 status
= (*(outer
-> type
-> set_value
)) (outer
,
354 status
= ISC_R_NOTFOUND
;
356 log_info (" ==> %s", isc_result_totext (status
));
361 isc_result_t
omapi_set_value_str (omapi_object_t
*h
,
364 omapi_typed_data_t
*value
)
366 // omapi_object_t *outer;
367 omapi_data_string_t
*nds
;
370 nds
= (omapi_data_string_t
*)0;
371 status
= omapi_data_string_new (&nds
, strlen (name
), MDL
);
372 if (status
!= ISC_R_SUCCESS
)
374 memcpy (nds
-> value
, name
, strlen (name
));
376 status
= omapi_set_value (h
, id
, nds
, value
);
377 omapi_data_string_dereference (&nds
, MDL
);
381 isc_result_t
omapi_set_boolean_value (omapi_object_t
*h
, omapi_object_t
*id
,
382 const char *name
, int value
)
385 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
386 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
390 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
391 if (status
!= ISC_R_SUCCESS
)
393 memcpy (n
-> value
, name
, strlen (name
));
395 status
= omapi_typed_data_new (MDL
, &tv
, omapi_datatype_int
, value
);
396 if (status
!= ISC_R_SUCCESS
) {
397 omapi_data_string_dereference (&n
, MDL
);
401 status
= omapi_set_value (h
, id
, n
, tv
);
402 omapi_data_string_dereference (&n
, MDL
);
403 omapi_typed_data_dereference (&tv
, MDL
);
407 isc_result_t
omapi_set_int_value (omapi_object_t
*h
, omapi_object_t
*id
,
408 const char *name
, int value
)
411 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
412 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
416 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
417 if (status
!= ISC_R_SUCCESS
)
419 memcpy (n
-> value
, name
, strlen (name
));
421 status
= omapi_typed_data_new (MDL
, &tv
, omapi_datatype_int
, value
);
422 if (status
!= ISC_R_SUCCESS
) {
423 omapi_data_string_dereference (&n
, MDL
);
427 status
= omapi_set_value (h
, id
, n
, tv
);
428 omapi_data_string_dereference (&n
, MDL
);
429 omapi_typed_data_dereference (&tv
, MDL
);
433 isc_result_t
omapi_set_object_value (omapi_object_t
*h
, omapi_object_t
*id
,
434 const char *name
, omapi_object_t
*value
)
437 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
438 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
442 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
443 if (status
!= ISC_R_SUCCESS
)
445 memcpy (n
-> value
, name
, strlen (name
));
447 status
= omapi_typed_data_new (MDL
, &tv
, omapi_datatype_object
, value
);
448 if (status
!= ISC_R_SUCCESS
) {
449 omapi_data_string_dereference (&n
, MDL
);
453 status
= omapi_set_value (h
, id
, n
, tv
);
454 omapi_data_string_dereference (&n
, MDL
);
455 omapi_typed_data_dereference (&tv
, MDL
);
459 isc_result_t
omapi_set_string_value (omapi_object_t
*h
, omapi_object_t
*id
,
460 const char *name
, const char *value
)
463 omapi_typed_data_t
*tv
= (omapi_typed_data_t
*)0;
464 omapi_data_string_t
*n
= (omapi_data_string_t
*)0;
468 status
= omapi_data_string_new (&n
, strlen (name
), MDL
);
469 if (status
!= ISC_R_SUCCESS
)
471 memcpy (n
-> value
, name
, strlen (name
));
473 status
= omapi_typed_data_new (MDL
, &tv
, omapi_datatype_string
, value
);
474 if (status
!= ISC_R_SUCCESS
) {
475 omapi_data_string_dereference (&n
, MDL
);
479 status
= omapi_set_value (h
, id
, n
, tv
);
480 omapi_data_string_dereference (&n
, MDL
);
481 omapi_typed_data_dereference (&tv
, MDL
);
485 isc_result_t
omapi_get_value (omapi_object_t
*h
,
487 omapi_data_string_t
*name
,
488 omapi_value_t
**value
)
490 omapi_object_t
*outer
;
492 for (outer
= h
; outer
-> outer
; outer
= outer
-> outer
)
494 if (outer
-> type
-> get_value
)
495 return (*(outer
-> type
-> get_value
)) (outer
,
497 return ISC_R_NOTFOUND
;
500 isc_result_t
omapi_get_value_str (omapi_object_t
*h
,
503 omapi_value_t
**value
)
505 omapi_object_t
*outer
;
506 omapi_data_string_t
*nds
;
509 nds
= (omapi_data_string_t
*)0;
510 status
= omapi_data_string_new (&nds
, strlen (name
), MDL
);
511 if (status
!= ISC_R_SUCCESS
)
513 memcpy (nds
-> value
, name
, strlen (name
));
515 for (outer
= h
; outer
-> outer
; outer
= outer
-> outer
)
517 if (outer
-> type
-> get_value
)
518 status
= (*(outer
-> type
-> get_value
)) (outer
,
521 status
= ISC_R_NOTFOUND
;
522 omapi_data_string_dereference (&nds
, MDL
);
526 isc_result_t
omapi_stuff_values (omapi_object_t
*c
,
530 omapi_object_t
*outer
;
532 for (outer
= o
; outer
-> outer
; outer
= outer
-> outer
)
534 if (outer
-> type
-> stuff_values
)
535 return (*(outer
-> type
-> stuff_values
)) (c
, id
, outer
);
536 return ISC_R_NOTFOUND
;
539 isc_result_t
omapi_object_create (omapi_object_t
**obj
, omapi_object_t
*id
,
540 omapi_object_type_t
*type
)
543 return ISC_R_NOTIMPLEMENTED
;
544 return (*(type
-> create
)) (obj
, id
);
547 isc_result_t
omapi_object_update (omapi_object_t
*obj
, omapi_object_t
*id
,
548 omapi_object_t
*src
, omapi_handle_t handle
)
550 omapi_generic_object_t
*gsrc
;
555 return ISC_R_INVALIDARG
;
556 if (src
-> type
!= omapi_type_generic
)
557 return ISC_R_NOTIMPLEMENTED
;
558 gsrc
= (omapi_generic_object_t
*)src
;
559 for (i
= 0; i
< gsrc
-> nvalues
; i
++) {
560 status
= omapi_set_value (obj
, id
,
561 gsrc
-> values
[i
] -> name
,
562 gsrc
-> values
[i
] -> value
);
563 if (status
!= ISC_R_SUCCESS
&& status
!= ISC_R_UNCHANGED
)
567 omapi_set_int_value (obj
, id
, "remote-handle", (int)handle
);
568 status
= omapi_signal (obj
, "updated");
569 if (status
!= ISC_R_NOTFOUND
)
571 return ISC_R_SUCCESS
;
574 int omapi_data_string_cmp (omapi_data_string_t
*s1
, omapi_data_string_t
*s2
)
579 if (s1
-> len
> s2
-> len
)
583 rv
= memcmp (s1
-> value
, s2
-> value
, len
);
586 if (s1
-> len
> s2
-> len
)
588 else if (s1
-> len
< s2
-> len
)
593 int omapi_ds_strcmp (omapi_data_string_t
*s1
, const char *s2
)
599 if (slen
> s1
-> len
)
603 rv
= memcmp (s1
-> value
, s2
, len
);
606 if (s1
-> len
> slen
)
608 else if (s1
-> len
< slen
)
613 int omapi_td_strcmp (omapi_typed_data_t
*s1
, const char *s2
)
618 /* If the data type is not compatible, never equal. */
619 if (s1
-> type
!= omapi_datatype_data
&&
620 s1
-> type
!= omapi_datatype_string
)
624 if (slen
> s1
-> u
.buffer
.len
)
625 len
= s1
-> u
.buffer
.len
;
628 rv
= memcmp (s1
-> u
.buffer
.value
, s2
, len
);
631 if (s1
-> u
.buffer
.len
> slen
)
633 else if (s1
-> u
.buffer
.len
< slen
)
638 int omapi_td_strcasecmp (omapi_typed_data_t
*s1
, const char *s2
)
643 /* If the data type is not compatible, never equal. */
644 if (s1
-> type
!= omapi_datatype_data
&&
645 s1
-> type
!= omapi_datatype_string
)
649 if (slen
> s1
-> u
.buffer
.len
)
650 len
= s1
-> u
.buffer
.len
;
653 rv
= casecmp (s1
-> u
.buffer
.value
, s2
, len
);
656 if (s1
-> u
.buffer
.len
> slen
)
658 else if (s1
-> u
.buffer
.len
< slen
)
663 isc_result_t
omapi_make_value (omapi_value_t
**vp
,
664 omapi_data_string_t
*name
,
665 omapi_typed_data_t
*value
,
666 const char *file
, int line
)
670 status
= omapi_value_new (vp
, file
, line
);
671 if (status
!= ISC_R_SUCCESS
)
674 status
= omapi_data_string_reference (&(*vp
) -> name
,
676 if (status
!= ISC_R_SUCCESS
) {
677 omapi_value_dereference (vp
, file
, line
);
681 status
= omapi_typed_data_reference (&(*vp
) -> value
,
683 if (status
!= ISC_R_SUCCESS
) {
684 omapi_value_dereference (vp
, file
, line
);
688 return ISC_R_SUCCESS
;
691 isc_result_t
omapi_make_const_value (omapi_value_t
**vp
,
692 omapi_data_string_t
*name
,
693 const unsigned char *value
,
695 const char *file
, int line
)
699 status
= omapi_value_new (vp
, file
, line
);
700 if (status
!= ISC_R_SUCCESS
)
703 status
= omapi_data_string_reference (&(*vp
) -> name
,
705 if (status
!= ISC_R_SUCCESS
) {
706 omapi_value_dereference (vp
, file
, line
);
710 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
711 omapi_datatype_data
, len
);
712 if (status
!= ISC_R_SUCCESS
) {
713 omapi_value_dereference (vp
, file
, line
);
716 memcpy ((*vp
) -> value
-> u
.buffer
.value
, value
, len
);
718 return ISC_R_SUCCESS
;
721 isc_result_t
omapi_make_int_value (omapi_value_t
**vp
,
722 omapi_data_string_t
*name
,
723 int value
, const char *file
, int line
)
727 status
= omapi_value_new (vp
, file
, line
);
728 if (status
!= ISC_R_SUCCESS
)
731 status
= omapi_data_string_reference (&(*vp
) -> name
,
733 if (status
!= ISC_R_SUCCESS
) {
734 omapi_value_dereference (vp
, file
, line
);
737 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
738 omapi_datatype_int
, value
);
739 if (status
!= ISC_R_SUCCESS
) {
740 omapi_value_dereference (vp
, file
, line
);
743 return ISC_R_SUCCESS
;
746 isc_result_t
omapi_make_uint_value (omapi_value_t
**vp
,
747 omapi_data_string_t
*name
,
749 const char *file
, int line
)
751 return omapi_make_int_value (vp
, name
, (int)value
, file
, line
);
754 isc_result_t
omapi_make_object_value (omapi_value_t
**vp
,
755 omapi_data_string_t
*name
,
756 omapi_object_t
*value
,
757 const char *file
, int line
)
761 status
= omapi_value_new (vp
, file
, line
);
762 if (status
!= ISC_R_SUCCESS
)
765 status
= omapi_data_string_reference (&(*vp
) -> name
,
767 if (status
!= ISC_R_SUCCESS
) {
768 omapi_value_dereference (vp
, file
, line
);
773 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
774 omapi_datatype_object
, value
);
775 if (status
!= ISC_R_SUCCESS
) {
776 omapi_value_dereference (vp
, file
, line
);
781 return ISC_R_SUCCESS
;
784 isc_result_t
omapi_make_handle_value (omapi_value_t
**vp
,
785 omapi_data_string_t
*name
,
786 omapi_object_t
*value
,
787 const char *file
, int line
)
791 status
= omapi_value_new (vp
, file
, line
);
792 if (status
!= ISC_R_SUCCESS
)
795 status
= omapi_data_string_reference (&(*vp
) -> name
,
797 if (status
!= ISC_R_SUCCESS
) {
798 omapi_value_dereference (vp
, file
, line
);
802 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
804 if (status
!= ISC_R_SUCCESS
) {
805 omapi_value_dereference (vp
, file
, line
);
808 status
= (omapi_object_handle
809 ((omapi_handle_t
*)&(*vp
) -> value
-> u
.integer
,
811 if (status
!= ISC_R_SUCCESS
) {
812 omapi_value_dereference (vp
, file
, line
);
816 return ISC_R_SUCCESS
;
819 isc_result_t
omapi_make_string_value (omapi_value_t
**vp
,
820 omapi_data_string_t
*name
,
822 const char *file
, int line
)
826 status
= omapi_value_new (vp
, file
, line
);
827 if (status
!= ISC_R_SUCCESS
)
830 status
= omapi_data_string_reference (&(*vp
) -> name
,
832 if (status
!= ISC_R_SUCCESS
) {
833 omapi_value_dereference (vp
, file
, line
);
837 status
= omapi_typed_data_new (file
, line
, &(*vp
) -> value
,
838 omapi_datatype_string
, value
);
839 if (status
!= ISC_R_SUCCESS
) {
840 omapi_value_dereference (vp
, file
, line
);
844 return ISC_R_SUCCESS
;
847 isc_result_t
omapi_get_int_value (unsigned long *v
, omapi_typed_data_t
*t
)
851 if (t
-> type
== omapi_datatype_int
) {
853 return ISC_R_SUCCESS
;
854 } else if (t
-> type
== omapi_datatype_string
||
855 t
-> type
== omapi_datatype_data
) {
856 if (t
-> u
.buffer
.len
!= sizeof (rv
))
857 return ISC_R_INVALIDARG
;
858 memcpy (&rv
, t
-> u
.buffer
.value
, sizeof rv
);
860 return ISC_R_SUCCESS
;
862 return ISC_R_INVALIDARG
;