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;