3 Subroutines providing general support for objects. */
6 * Copyright (c) 2004-2007,2009-2010
7 * 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/
28 * This software has been written for Internet Systems Consortium
29 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
30 * To learn more about Internet Systems Consortium, see
31 * ``https://www.isc.org/''. To learn more about Vixie Enterprises,
32 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
33 * ``http://www.nominum.com''.
38 #include <omapip/omapip_p.h>
40 omapi_object_type_t *omapi_type_connection;
41 omapi_object_type_t *omapi_type_listener;
42 omapi_object_type_t *omapi_type_io_object;
43 omapi_object_type_t *omapi_type_datagram;
44 omapi_object_type_t *omapi_type_generic;
45 omapi_object_type_t *omapi_type_protocol;
46 omapi_object_type_t *omapi_type_protocol_listener;
47 omapi_object_type_t *omapi_type_waiter;
48 omapi_object_type_t *omapi_type_remote;
49 omapi_object_type_t *omapi_type_message;
50 omapi_object_type_t *omapi_type_auth_key;
52 omapi_object_type_t *omapi_object_types;
53 int omapi_object_type_count;
55 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
56 void omapi_type_relinquish ()
58 omapi_object_type_t *t, *n;
60 for (t = omapi_object_types; t; t = n) {
64 omapi_object_types = (omapi_object_type_t *)0;
68 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 ();
196 /* This seems silly, but leave it. */
197 return ISC_R_SUCCESS;
200 isc_result_t omapi_object_type_register (omapi_object_type_t **type,
202 isc_result_t (*set_value)
205 omapi_data_string_t *,
206 omapi_typed_data_t *),
207 isc_result_t (*get_value)
210 omapi_data_string_t *,
212 isc_result_t (*destroy)
215 isc_result_t (*signal_handler)
217 const char *, va_list),
218 isc_result_t (*stuff_values)
222 isc_result_t (*lookup)
226 isc_result_t (*create)
229 isc_result_t (*remove)
232 isc_result_t (*freer)
235 isc_result_t (*allocator)
238 isc_result_t (*sizer) (size_t),
240 isc_result_t (*initialize)
245 omapi_object_type_t *t;
247 t = dmalloc (sizeof *t, MDL);
249 return ISC_R_NOMEMORY;
250 memset (t, 0, sizeof *t);
253 t -> set_value = set_value;
254 t -> get_value = get_value;
255 t -> destroy = destroy;
256 t -> signal_handler = signal_handler;
257 t -> stuff_values = stuff_values;
258 t -> lookup = lookup;
259 t -> create = create;
260 t -> remove = remove;
261 t -> next = omapi_object_types;
265 t -> allocator = allocator;
266 t -> initialize = initialize;
267 t -> rc_flag = rc_flag;
268 omapi_object_types = t;
271 return ISC_R_SUCCESS;
274 isc_result_t omapi_signal (omapi_object_t *handle, const char *name, ...)
277 omapi_object_t *outer;
281 for (outer = handle; outer -> outer; outer = outer -> outer)
283 if (outer -> type -> signal_handler)
284 status = (*(outer -> type -> signal_handler)) (outer,
287 status = ISC_R_NOTFOUND;
292 isc_result_t omapi_signal_in (omapi_object_t *handle, const char *name, ...)
298 return ISC_R_NOTFOUND;
301 if (handle -> type -> signal_handler)
302 status = (*(handle -> type -> signal_handler)) (handle,
305 status = ISC_R_NOTFOUND;
310 isc_result_t omapi_set_value (omapi_object_t *h,
312 omapi_data_string_t *name,
313 omapi_typed_data_t *value)
315 omapi_object_t *outer;
320 log_info ("omapi_set_value (%.*s, NULL)",
321 (int)name -> len, name -> value);
322 } else if (value -> type == omapi_datatype_int) {
323 log_info ("omapi_set_value (%.*s, %ld)",
324 (int)name -> len, name -> value,
325 (long)value -> u.integer);
326 } else if (value -> type == omapi_datatype_string) {
327 log_info ("omapi_set_value (%.*s, %.*s)",
328 (int)name -> len, name -> value,
329 (int)value -> u.buffer.len, value -> u.buffer.value);
330 } else if (value -> type == omapi_datatype_data) {
331 log_info ("omapi_set_value (%.*s, %ld %lx)",
332 (int)name -> len, name -> value,
333 (long)value -> u.buffer.len,
334 (unsigned long)value -> u.buffer.value);
335 } else if (value -> type == omapi_datatype_object) {
336 log_info ("omapi_set_value (%.*s, %s)",
337 (int)name -> len, name -> value,
339 ? (value -> u.object -> type
340 ? value -> u.object -> type -> name
341 : "(unknown object)")
342 : "(unknown object)");
346 for (outer = h; outer -> outer; outer = outer -> outer)
348 if (outer -> type -> set_value)
349 status = (*(outer -> type -> set_value)) (outer,
352 status = ISC_R_NOTFOUND;
354 log_info (" ==> %s", isc_result_totext (status));
359 isc_result_t omapi_set_value_str (omapi_object_t *h,
362 omapi_typed_data_t *value)
364 omapi_data_string_t *nds;
367 nds = (omapi_data_string_t *)0;
368 status = omapi_data_string_new (&nds, strlen (name), MDL);
369 if (status != ISC_R_SUCCESS)
371 memcpy (nds -> value, name, strlen (name));
373 status = omapi_set_value (h, id, nds, value);
374 omapi_data_string_dereference (&nds, MDL);
378 isc_result_t omapi_set_boolean_value (omapi_object_t *h, omapi_object_t *id,
379 const char *name, int value)
382 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
383 omapi_data_string_t *n = (omapi_data_string_t *)0;
385 status = omapi_data_string_new (&n, strlen (name), MDL);
386 if (status != ISC_R_SUCCESS)
388 memcpy (n -> value, name, strlen (name));
390 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
391 if (status != ISC_R_SUCCESS) {
392 omapi_data_string_dereference (&n, MDL);
396 status = omapi_set_value (h, id, n, tv);
397 omapi_data_string_dereference (&n, MDL);
398 omapi_typed_data_dereference (&tv, MDL);
402 isc_result_t omapi_set_int_value (omapi_object_t *h, omapi_object_t *id,
403 const char *name, int value)
406 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
407 omapi_data_string_t *n = (omapi_data_string_t *)0;
409 status = omapi_data_string_new (&n, strlen (name), MDL);
410 if (status != ISC_R_SUCCESS)
412 memcpy (n -> value, name, strlen (name));
414 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
415 if (status != ISC_R_SUCCESS) {
416 omapi_data_string_dereference (&n, MDL);
420 status = omapi_set_value (h, id, n, tv);
421 omapi_data_string_dereference (&n, MDL);
422 omapi_typed_data_dereference (&tv, MDL);
426 isc_result_t omapi_set_object_value (omapi_object_t *h, omapi_object_t *id,
427 const char *name, omapi_object_t *value)
430 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
431 omapi_data_string_t *n = (omapi_data_string_t *)0;
433 status = omapi_data_string_new (&n, strlen (name), MDL);
434 if (status != ISC_R_SUCCESS)
436 memcpy (n -> value, name, strlen (name));
438 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_object, value);
439 if (status != ISC_R_SUCCESS) {
440 omapi_data_string_dereference (&n, MDL);
444 status = omapi_set_value (h, id, n, tv);
445 omapi_data_string_dereference (&n, MDL);
446 omapi_typed_data_dereference (&tv, MDL);
450 isc_result_t omapi_set_string_value (omapi_object_t *h, omapi_object_t *id,
451 const char *name, const char *value)
454 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
455 omapi_data_string_t *n = (omapi_data_string_t *)0;
457 status = omapi_data_string_new (&n, strlen (name), MDL);
458 if (status != ISC_R_SUCCESS)
460 memcpy (n -> value, name, strlen (name));
462 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_string, value);
463 if (status != ISC_R_SUCCESS) {
464 omapi_data_string_dereference (&n, MDL);
468 status = omapi_set_value (h, id, n, tv);
469 omapi_data_string_dereference (&n, MDL);
470 omapi_typed_data_dereference (&tv, MDL);
474 isc_result_t omapi_get_value (omapi_object_t *h,
476 omapi_data_string_t *name,
477 omapi_value_t **value)
479 omapi_object_t *outer;
481 for (outer = h; outer -> outer; outer = outer -> outer)
483 if (outer -> type -> get_value)
484 return (*(outer -> type -> get_value)) (outer,
486 return ISC_R_NOTFOUND;
489 isc_result_t omapi_get_value_str (omapi_object_t *h,
492 omapi_value_t **value)
494 omapi_object_t *outer;
495 omapi_data_string_t *nds;
498 nds = (omapi_data_string_t *)0;
499 status = omapi_data_string_new (&nds, strlen (name), MDL);
500 if (status != ISC_R_SUCCESS)
502 memcpy (nds -> value, name, strlen (name));
504 for (outer = h; outer -> outer; outer = outer -> outer)
506 if (outer -> type -> get_value)
507 status = (*(outer -> type -> get_value)) (outer,
510 status = ISC_R_NOTFOUND;
511 omapi_data_string_dereference (&nds, MDL);
515 isc_result_t omapi_stuff_values (omapi_object_t *c,
519 omapi_object_t *outer;
521 for (outer = o; outer -> outer; outer = outer -> outer)
523 if (outer -> type -> stuff_values)
524 return (*(outer -> type -> stuff_values)) (c, id, outer);
525 return ISC_R_NOTFOUND;
528 isc_result_t omapi_object_create (omapi_object_t **obj, omapi_object_t *id,
529 omapi_object_type_t *type)
532 return ISC_R_NOTIMPLEMENTED;
533 return (*(type -> create)) (obj, id);
536 isc_result_t omapi_object_update (omapi_object_t *obj, omapi_object_t *id,
537 omapi_object_t *src, omapi_handle_t handle)
539 omapi_generic_object_t *gsrc;
544 return DHCP_R_INVALIDARG;
545 if (src -> type != omapi_type_generic)
546 return ISC_R_NOTIMPLEMENTED;
547 gsrc = (omapi_generic_object_t *)src;
548 for (i = 0; i < gsrc -> nvalues; i++) {
549 status = omapi_set_value (obj, id,
550 gsrc -> values [i] -> name,
551 gsrc -> values [i] -> value);
552 if (status != ISC_R_SUCCESS && status != DHCP_R_UNCHANGED)
556 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;