3 Subroutines providing general support for objects. */
6 * Copyright (c) 1999-2001 Internet Software Consortium.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of The Internet Software Consortium nor the names
19 * of its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * This software has been written for the Internet Software Consortium
37 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
38 * To learn more about the Internet Software Consortium, see
39 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
40 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
41 * ``http://www.nominum.com''.
44 #include <omapip/omapip_p.h>
46 omapi_object_type_t *omapi_type_connection;
47 omapi_object_type_t *omapi_type_listener;
48 omapi_object_type_t *omapi_type_io_object;
49 omapi_object_type_t *omapi_type_datagram;
50 omapi_object_type_t *omapi_type_generic;
51 omapi_object_type_t *omapi_type_protocol;
52 omapi_object_type_t *omapi_type_protocol_listener;
53 omapi_object_type_t *omapi_type_waiter;
54 omapi_object_type_t *omapi_type_remote;
55 omapi_object_type_t *omapi_type_message;
56 omapi_object_type_t *omapi_type_auth_key;
58 omapi_object_type_t *omapi_object_types;
59 int omapi_object_type_count;
62 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
63 void omapi_type_relinquish ()
65 omapi_object_type_t *t, *n;
67 for (t = omapi_object_types; t; t = n) {
71 omapi_object_types = (omapi_object_type_t *)0;
75 isc_result_t omapi_init (void)
81 /* Register all the standard object types... */
82 status = omapi_object_type_register (&omapi_type_connection,
84 omapi_connection_set_value,
85 omapi_connection_get_value,
86 omapi_connection_destroy,
87 omapi_connection_signal_handler,
88 omapi_connection_stuff_values,
91 (omapi_connection_object_t), 0,
93 if (status != ISC_R_SUCCESS)
96 status = omapi_object_type_register (&omapi_type_listener,
98 omapi_listener_set_value,
99 omapi_listener_get_value,
100 omapi_listener_destroy,
101 omapi_listener_signal_handler,
102 omapi_listener_stuff_values,
104 sizeof (omapi_listener_object_t),
106 if (status != ISC_R_SUCCESS)
109 status = omapi_object_type_register (&omapi_type_io_object,
114 omapi_io_signal_handler,
115 omapi_io_stuff_values,
117 sizeof (omapi_io_object_t),
119 if (status != ISC_R_SUCCESS)
122 status = omapi_object_type_register (&omapi_type_generic,
124 omapi_generic_set_value,
125 omapi_generic_get_value,
126 omapi_generic_destroy,
127 omapi_generic_signal_handler,
128 omapi_generic_stuff_values,
130 sizeof (omapi_generic_object_t),
132 if (status != ISC_R_SUCCESS)
135 status = omapi_object_type_register (&omapi_type_protocol,
137 omapi_protocol_set_value,
138 omapi_protocol_get_value,
139 omapi_protocol_destroy,
140 omapi_protocol_signal_handler,
141 omapi_protocol_stuff_values,
143 sizeof (omapi_protocol_object_t),
145 if (status != ISC_R_SUCCESS)
148 status = (omapi_object_type_register
149 (&omapi_type_protocol_listener, "protocol-listener",
150 omapi_protocol_listener_set_value,
151 omapi_protocol_listener_get_value,
152 omapi_protocol_listener_destroy,
153 omapi_protocol_listener_signal,
154 omapi_protocol_listener_stuff,
156 sizeof (omapi_protocol_listener_object_t), 0, RC_MISC));
157 if (status != ISC_R_SUCCESS)
160 status = omapi_object_type_register (&omapi_type_message,
162 omapi_message_set_value,
163 omapi_message_get_value,
164 omapi_message_destroy,
165 omapi_message_signal_handler,
166 omapi_message_stuff_values,
168 sizeof (omapi_message_object_t),
170 if (status != ISC_R_SUCCESS)
173 status = omapi_object_type_register (&omapi_type_waiter,
178 omapi_waiter_signal_handler, 0,
180 sizeof (omapi_waiter_object_t),
182 if (status != ISC_R_SUCCESS)
185 status = omapi_object_type_register (&omapi_type_auth_key,
188 omapi_auth_key_get_value,
189 omapi_auth_key_destroy,
191 omapi_auth_key_stuff_values,
192 omapi_auth_key_lookup,
194 sizeof (omapi_auth_key_t), 0,
196 if (status != ISC_R_SUCCESS)
199 #if defined (TRACING)
200 omapi_listener_trace_setup ();
201 omapi_connection_trace_setup ();
202 omapi_buffer_trace_setup ();
206 /* This seems silly, but leave it. */
207 return ISC_R_SUCCESS;
210 isc_result_t omapi_object_type_register (omapi_object_type_t **type,
212 isc_result_t (*set_value)
215 omapi_data_string_t *,
216 omapi_typed_data_t *),
217 isc_result_t (*get_value)
220 omapi_data_string_t *,
222 isc_result_t (*destroy)
225 isc_result_t (*signal_handler)
227 const char *, va_list),
228 isc_result_t (*stuff_values)
232 isc_result_t (*lookup)
236 isc_result_t (*create)
239 isc_result_t (*remove)
242 isc_result_t (*freer)
245 isc_result_t (*allocator)
248 isc_result_t (*sizer) (size_t),
250 isc_result_t (*initialize)
255 omapi_object_type_t *t;
257 t = dmalloc (sizeof *t, MDL);
259 return ISC_R_NOMEMORY;
260 memset (t, 0, sizeof *t);
263 t -> set_value = set_value;
264 t -> get_value = get_value;
265 t -> destroy = destroy;
266 t -> signal_handler = signal_handler;
267 t -> stuff_values = stuff_values;
268 t -> lookup = lookup;
269 t -> create = create;
270 t -> remove = remove;
271 t -> next = omapi_object_types;
275 t -> allocator = allocator;
276 t -> initialize = initialize;
277 t -> rc_flag = rc_flag;
278 omapi_object_types = t;
281 return ISC_R_SUCCESS;
284 isc_result_t omapi_signal (omapi_object_t *handle, const char *name, ...)
287 omapi_object_t *outer;
291 for (outer = handle; outer -> outer; outer = outer -> outer)
293 if (outer -> type -> signal_handler)
294 status = (*(outer -> type -> signal_handler)) (outer,
297 status = ISC_R_NOTFOUND;
302 isc_result_t omapi_signal_in (omapi_object_t *handle, const char *name, ...)
305 omapi_object_t *outer;
309 return ISC_R_NOTFOUND;
312 if (handle -> type -> signal_handler)
313 status = (*(handle -> type -> signal_handler)) (handle,
316 status = ISC_R_NOTFOUND;
321 isc_result_t omapi_set_value (omapi_object_t *h,
323 omapi_data_string_t *name,
324 omapi_typed_data_t *value)
326 omapi_object_t *outer;
331 log_info ("omapi_set_value (%.*s, NULL)",
332 (int)name -> len, name -> value);
333 } else if (value -> type == omapi_datatype_int) {
334 log_info ("omapi_set_value (%.*s, %ld)",
335 (int)name -> len, name -> value,
336 (long)value -> u.integer);
337 } else if (value -> type == omapi_datatype_string) {
338 log_info ("omapi_set_value (%.*s, %.*s)",
339 (int)name -> len, name -> value,
340 (int)value -> u.buffer.len, value -> u.buffer.value);
341 } else if (value -> type == omapi_datatype_data) {
342 log_info ("omapi_set_value (%.*s, %ld %lx)",
343 (int)name -> len, name -> value,
344 (long)value -> u.buffer.len,
345 (unsigned long)value -> u.buffer.value);
346 } else if (value -> type == omapi_datatype_object) {
347 log_info ("omapi_set_value (%.*s, %s)",
348 (int)name -> len, name -> value,
350 ? (value -> u.object -> type
351 ? value -> u.object -> type -> name
352 : "(unknown object)")
353 : "(unknown object)");
357 for (outer = h; outer -> outer; outer = outer -> outer)
359 if (outer -> type -> set_value)
360 status = (*(outer -> type -> set_value)) (outer,
363 status = ISC_R_NOTFOUND;
365 log_info (" ==> %s", isc_result_totext (status));
370 isc_result_t omapi_set_value_str (omapi_object_t *h,
373 omapi_typed_data_t *value)
375 omapi_object_t *outer;
376 omapi_data_string_t *nds;
379 nds = (omapi_data_string_t *)0;
380 status = omapi_data_string_new (&nds, strlen (name), MDL);
381 if (status != ISC_R_SUCCESS)
383 memcpy (nds -> value, name, strlen (name));
385 status = omapi_set_value (h, id, nds, value);
386 omapi_data_string_dereference (&nds, MDL);
390 isc_result_t omapi_set_boolean_value (omapi_object_t *h, omapi_object_t *id,
391 const char *name, int value)
394 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
395 omapi_data_string_t *n = (omapi_data_string_t *)0;
399 status = omapi_data_string_new (&n, strlen (name), MDL);
400 if (status != ISC_R_SUCCESS)
402 memcpy (n -> value, name, strlen (name));
404 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
405 if (status != ISC_R_SUCCESS) {
406 omapi_data_string_dereference (&n, MDL);
410 status = omapi_set_value (h, id, n, tv);
411 omapi_data_string_dereference (&n, MDL);
412 omapi_typed_data_dereference (&tv, MDL);
416 isc_result_t omapi_set_int_value (omapi_object_t *h, omapi_object_t *id,
417 const char *name, int value)
420 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
421 omapi_data_string_t *n = (omapi_data_string_t *)0;
425 status = omapi_data_string_new (&n, strlen (name), MDL);
426 if (status != ISC_R_SUCCESS)
428 memcpy (n -> value, name, strlen (name));
430 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
431 if (status != ISC_R_SUCCESS) {
432 omapi_data_string_dereference (&n, MDL);
436 status = omapi_set_value (h, id, n, tv);
437 omapi_data_string_dereference (&n, MDL);
438 omapi_typed_data_dereference (&tv, MDL);
442 isc_result_t omapi_set_object_value (omapi_object_t *h, omapi_object_t *id,
443 const char *name, omapi_object_t *value)
446 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
447 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_object, 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_set_string_value (omapi_object_t *h, omapi_object_t *id,
469 const char *name, const char *value)
472 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
473 omapi_data_string_t *n = (omapi_data_string_t *)0;
477 status = omapi_data_string_new (&n, strlen (name), MDL);
478 if (status != ISC_R_SUCCESS)
480 memcpy (n -> value, name, strlen (name));
482 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_string, value);
483 if (status != ISC_R_SUCCESS) {
484 omapi_data_string_dereference (&n, MDL);
488 status = omapi_set_value (h, id, n, tv);
489 omapi_data_string_dereference (&n, MDL);
490 omapi_typed_data_dereference (&tv, MDL);
494 isc_result_t omapi_get_value (omapi_object_t *h,
496 omapi_data_string_t *name,
497 omapi_value_t **value)
499 omapi_object_t *outer;
501 for (outer = h; outer -> outer; outer = outer -> outer)
503 if (outer -> type -> get_value)
504 return (*(outer -> type -> get_value)) (outer,
506 return ISC_R_NOTFOUND;
509 isc_result_t omapi_get_value_str (omapi_object_t *h,
512 omapi_value_t **value)
514 omapi_object_t *outer;
515 omapi_data_string_t *nds;
518 nds = (omapi_data_string_t *)0;
519 status = omapi_data_string_new (&nds, strlen (name), MDL);
520 if (status != ISC_R_SUCCESS)
522 memcpy (nds -> value, name, strlen (name));
524 for (outer = h; outer -> outer; outer = outer -> outer)
526 if (outer -> type -> get_value)
527 status = (*(outer -> type -> get_value)) (outer,
530 status = ISC_R_NOTFOUND;
531 omapi_data_string_dereference (&nds, MDL);
535 isc_result_t omapi_stuff_values (omapi_object_t *c,
539 omapi_object_t *outer;
541 for (outer = o; outer -> outer; outer = outer -> outer)
543 if (outer -> type -> stuff_values)
544 return (*(outer -> type -> stuff_values)) (c, id, outer);
545 return ISC_R_NOTFOUND;
548 isc_result_t omapi_object_create (omapi_object_t **obj, omapi_object_t *id,
549 omapi_object_type_t *type)
552 return ISC_R_NOTIMPLEMENTED;
553 return (*(type -> create)) (obj, id);
556 isc_result_t omapi_object_update (omapi_object_t *obj, omapi_object_t *id,
557 omapi_object_t *src, omapi_handle_t handle)
559 omapi_generic_object_t *gsrc;
564 return ISC_R_INVALIDARG;
565 if (src -> type != omapi_type_generic)
566 return ISC_R_NOTIMPLEMENTED;
567 gsrc = (omapi_generic_object_t *)src;
568 for (i = 0; i < gsrc -> nvalues; i++) {
569 status = omapi_set_value (obj, id,
570 gsrc -> values [i] -> name,
571 gsrc -> values [i] -> value);
572 if (status != ISC_R_SUCCESS && status != ISC_R_UNCHANGED)
576 omapi_set_int_value (obj, id, "remote-handle", (int)handle);
577 status = omapi_signal (obj, "updated");
578 if (status != ISC_R_NOTFOUND)
580 return ISC_R_SUCCESS;
583 int omapi_data_string_cmp (omapi_data_string_t *s1, omapi_data_string_t *s2)
588 if (s1 -> len > s2 -> len)
592 rv = memcmp (s1 -> value, s2 -> value, len);
595 if (s1 -> len > s2 -> len)
597 else if (s1 -> len < s2 -> len)
602 int omapi_ds_strcmp (omapi_data_string_t *s1, const char *s2)
608 if (slen > s1 -> len)
612 rv = memcmp (s1 -> value, s2, len);
615 if (s1 -> len > slen)
617 else if (s1 -> len < slen)
622 int omapi_td_strcmp (omapi_typed_data_t *s1, const char *s2)
627 /* If the data type is not compatible, never equal. */
628 if (s1 -> type != omapi_datatype_data &&
629 s1 -> type != omapi_datatype_string)
633 if (slen > s1 -> u.buffer.len)
634 len = s1 -> u.buffer.len;
637 rv = memcmp (s1 -> u.buffer.value, s2, len);
640 if (s1 -> u.buffer.len > slen)
642 else if (s1 -> u.buffer.len < slen)
647 int omapi_td_strcasecmp (omapi_typed_data_t *s1, const char *s2)
652 /* If the data type is not compatible, never equal. */
653 if (s1 -> type != omapi_datatype_data &&
654 s1 -> type != omapi_datatype_string)
658 if (slen > s1 -> u.buffer.len)
659 len = s1 -> u.buffer.len;
662 rv = casecmp (s1 -> u.buffer.value, s2, len);
665 if (s1 -> u.buffer.len > slen)
667 else if (s1 -> u.buffer.len < slen)
672 isc_result_t omapi_make_value (omapi_value_t **vp,
673 omapi_data_string_t *name,
674 omapi_typed_data_t *value,
675 const char *file, int line)
679 status = omapi_value_new (vp, file, line);
680 if (status != ISC_R_SUCCESS)
683 status = omapi_data_string_reference (&(*vp) -> name,
685 if (status != ISC_R_SUCCESS) {
686 omapi_value_dereference (vp, file, line);
690 status = omapi_typed_data_reference (&(*vp) -> value,
692 if (status != ISC_R_SUCCESS) {
693 omapi_value_dereference (vp, file, line);
697 return ISC_R_SUCCESS;
700 isc_result_t omapi_make_const_value (omapi_value_t **vp,
701 omapi_data_string_t *name,
702 const unsigned char *value,
704 const char *file, int line)
708 status = omapi_value_new (vp, file, line);
709 if (status != ISC_R_SUCCESS)
712 status = omapi_data_string_reference (&(*vp) -> name,
714 if (status != ISC_R_SUCCESS) {
715 omapi_value_dereference (vp, file, line);
719 status = omapi_typed_data_new (file, line, &(*vp) -> value,
720 omapi_datatype_data, len);
721 if (status != ISC_R_SUCCESS) {
722 omapi_value_dereference (vp, file, line);
725 memcpy ((*vp) -> value -> u.buffer.value, value, len);
727 return ISC_R_SUCCESS;
730 isc_result_t omapi_make_int_value (omapi_value_t **vp,
731 omapi_data_string_t *name,
732 int value, const char *file, int line)
736 status = omapi_value_new (vp, file, line);
737 if (status != ISC_R_SUCCESS)
740 status = omapi_data_string_reference (&(*vp) -> name,
742 if (status != ISC_R_SUCCESS) {
743 omapi_value_dereference (vp, file, line);
746 status = omapi_typed_data_new (file, line, &(*vp) -> value,
747 omapi_datatype_int, value);
748 if (status != ISC_R_SUCCESS) {
749 omapi_value_dereference (vp, file, line);
752 return ISC_R_SUCCESS;
755 isc_result_t omapi_make_uint_value (omapi_value_t **vp,
756 omapi_data_string_t *name,
758 const char *file, int line)
760 return omapi_make_int_value (vp, name, (int)value, file, line);
763 isc_result_t omapi_make_object_value (omapi_value_t **vp,
764 omapi_data_string_t *name,
765 omapi_object_t *value,
766 const char *file, int line)
770 status = omapi_value_new (vp, file, line);
771 if (status != ISC_R_SUCCESS)
774 status = omapi_data_string_reference (&(*vp) -> name,
776 if (status != ISC_R_SUCCESS) {
777 omapi_value_dereference (vp, file, line);
782 status = omapi_typed_data_new (file, line, &(*vp) -> value,
783 omapi_datatype_object, value);
784 if (status != ISC_R_SUCCESS) {
785 omapi_value_dereference (vp, file, line);
790 return ISC_R_SUCCESS;
793 isc_result_t omapi_make_handle_value (omapi_value_t **vp,
794 omapi_data_string_t *name,
795 omapi_object_t *value,
796 const char *file, int line)
800 status = omapi_value_new (vp, file, line);
801 if (status != ISC_R_SUCCESS)
804 status = omapi_data_string_reference (&(*vp) -> name,
806 if (status != ISC_R_SUCCESS) {
807 omapi_value_dereference (vp, file, line);
811 status = omapi_typed_data_new (file, line, &(*vp) -> value,
813 if (status != ISC_R_SUCCESS) {
814 omapi_value_dereference (vp, file, line);
817 status = (omapi_object_handle
818 ((omapi_handle_t *)&(*vp) -> value -> u.integer,
820 if (status != ISC_R_SUCCESS) {
821 omapi_value_dereference (vp, file, line);
825 return ISC_R_SUCCESS;
828 isc_result_t omapi_make_string_value (omapi_value_t **vp,
829 omapi_data_string_t *name,
831 const char *file, int line)
835 status = omapi_value_new (vp, file, line);
836 if (status != ISC_R_SUCCESS)
839 status = omapi_data_string_reference (&(*vp) -> name,
841 if (status != ISC_R_SUCCESS) {
842 omapi_value_dereference (vp, file, line);
846 status = omapi_typed_data_new (file, line, &(*vp) -> value,
847 omapi_datatype_string, value);
848 if (status != ISC_R_SUCCESS) {
849 omapi_value_dereference (vp, file, line);
853 return ISC_R_SUCCESS;
856 isc_result_t omapi_get_int_value (unsigned long *v, omapi_typed_data_t *t)
860 if (t -> type == omapi_datatype_int) {
862 return ISC_R_SUCCESS;
863 } else if (t -> type == omapi_datatype_string ||
864 t -> type == omapi_datatype_data) {
865 if (t -> u.buffer.len != sizeof (rv))
866 return ISC_R_INVALIDARG;
867 memcpy (&rv, t -> u.buffer.value, sizeof rv);
869 return ISC_R_SUCCESS;
871 return ISC_R_INVALIDARG;