3 Subroutines that support the generic object. */
6 * Copyright (c) 1996-2000 Internet Software Consortium.
7 * Use is subject to license terms which appear in the file named
8 * ISC-LICENSE that should have accompanied this file when you
9 * received it. If a file named ISC-LICENSE did not accompany this
10 * file, or you are not sure the one you have is correct, you may
11 * obtain an applicable copy of the license at:
13 * http://www.isc.org/isc-license-1.0.html.
15 * This file is part of the ISC DHCP distribution. The documentation
16 * associated with this file is listed in the file DOCUMENTATION,
17 * included in the top-level directory of this release.
19 * Support and other services are available for ISC products - see
20 * http://www.isc.org for more information.
23 #include <omapip/omapip_p.h>
25 isc_result_t
omapi_generic_new (omapi_object_t
**gen
,
26 const char *file
, int line
)
28 omapi_generic_object_t
*obj
;
30 obj
= dmalloc (sizeof *obj
, file
, line
);
32 return ISC_R_NOMEMORY
;
33 memset (obj
, 0, sizeof *obj
);
35 obj
-> type
= omapi_type_generic
;
37 return omapi_object_reference (gen
, (omapi_object_t
*)obj
, file
, line
);
40 isc_result_t
omapi_generic_set_value (omapi_object_t
*h
,
42 omapi_data_string_t
*name
,
43 omapi_typed_data_t
*value
)
45 omapi_generic_object_t
*g
;
52 if (h
-> type
!= omapi_type_generic
)
53 return ISC_R_INVALIDARG
;
54 g
= (omapi_generic_object_t
*)h
;
56 /* See if there's already a value with this name attached to
57 the generic object, and if so, replace the current value
59 for (i
= 0; i
< g
-> nvalues
; i
++) {
60 if (!omapi_data_string_cmp (name
, g
-> values
[i
] -> name
)) {
61 /* There's an inconsistency here: the standard
62 behaviour of a set_values method when
63 passed a matching name and a null value is
64 to delete the value associated with that
65 name (where possible). In the generic
66 object, we remember the name/null pair,
67 because generic objects are generally used
68 to pass messages around, and this is the
69 way that remote entities delete values from
70 local objects. If the get_value method of
71 a generic object is called for a name that
72 maps to a name/null pair, ISC_R_NOTFOUND is
74 new = (omapi_value_t
*)0;
75 status
= (omapi_value_new (&new, MDL
));
76 if (status
!= ISC_R_SUCCESS
)
78 omapi_data_string_reference (&new -> name
, name
, MDL
);
80 omapi_typed_data_reference (&new -> value
,
83 omapi_value_dereference (&(g
-> values
[i
]), MDL
);
84 status
= (omapi_value_reference
85 (&(g
-> values
[i
]), new, MDL
));
86 omapi_value_dereference (&new, MDL
);
91 /* If the name isn't already attached to this object, see if an
92 inner object has it. */
93 if (h
-> inner
&& h
-> inner
-> type
-> set_value
) {
94 status
= ((*(h
-> inner
-> type
-> set_value
))
95 (h
-> inner
, id
, name
, value
));
96 if (status
!= ISC_R_NOTFOUND
)
100 /* Okay, so it's a value that no inner object knows about, and
101 (implicitly, since the outer object set_value method would
102 have called this object's set_value method) it's an object that
103 no outer object knows about, it's this object's responsibility
104 to remember it - that's what generic objects do. */
106 /* Arrange for there to be space for the pointer to the new
107 name/value pair if necessary: */
108 if (g
-> nvalues
== g
-> va_max
) {
110 vm_new
= 2 * g
-> va_max
;
113 va
= dmalloc (vm_new
* sizeof *va
, MDL
);
115 return ISC_R_NOMEMORY
;
117 memcpy (va
, g
-> values
, g
-> va_max
* sizeof *va
);
118 memset (va
+ g
-> va_max
, 0,
119 (vm_new
- g
-> va_max
) * sizeof *va
);
121 dfree (g
-> values
, MDL
);
123 g
-> va_max
= vm_new
;
125 status
= omapi_value_new (&g
-> values
[g
-> nvalues
], MDL
);
126 if (status
!= ISC_R_SUCCESS
)
128 omapi_data_string_reference (&g
-> values
[g
-> nvalues
] -> name
,
131 omapi_typed_data_reference
132 (&g
-> values
[g
-> nvalues
] -> value
, value
, MDL
);
134 return ISC_R_SUCCESS
;
137 isc_result_t
omapi_generic_get_value (omapi_object_t
*h
,
139 omapi_data_string_t
*name
,
140 omapi_value_t
**value
)
143 omapi_generic_object_t
*g
;
145 if (h
-> type
!= omapi_type_generic
)
146 return ISC_R_INVALIDARG
;
147 g
= (omapi_generic_object_t
*)h
;
149 /* Look up the specified name in our list of objects. */
150 for (i
= 0; i
< g
-> nvalues
; i
++) {
151 if (!omapi_data_string_cmp (name
, g
-> values
[i
] -> name
)) {
152 /* If this is a name/null value pair, this is the
153 same as if there were no value that matched
154 the specified name, so return ISC_R_NOTFOUND. */
155 if (!g
-> values
[i
] -> value
)
156 return ISC_R_NOTFOUND
;
157 /* Otherwise, return the name/value pair. */
158 return omapi_value_reference (value
,
159 g
-> values
[i
], MDL
);
163 if (h
-> inner
&& h
-> inner
-> type
-> get_value
)
164 return (*(h
-> inner
-> type
-> get_value
))
165 (h
-> inner
, id
, name
, value
);
166 return ISC_R_NOTFOUND
;
169 isc_result_t
omapi_generic_destroy (omapi_object_t
*h
,
170 const char *file
, int line
)
172 omapi_generic_object_t
*g
;
175 if (h
-> type
!= omapi_type_generic
)
176 return ISC_R_UNEXPECTED
;
177 g
= (omapi_generic_object_t
*)h
;
180 for (i
= 0; i
< g
-> nvalues
; i
++) {
182 omapi_value_dereference (&g
-> values
[i
],
185 dfree (g
-> values
, file
, line
);
186 g
-> values
= (omapi_value_t
**)0;
190 return ISC_R_SUCCESS
;
193 isc_result_t
omapi_generic_signal_handler (omapi_object_t
*h
,
194 const char *name
, va_list ap
)
196 if (h
-> type
!= omapi_type_generic
)
197 return ISC_R_INVALIDARG
;
199 if (h
-> inner
&& h
-> inner
-> type
-> signal_handler
)
200 return (*(h
-> inner
-> type
-> signal_handler
)) (h
-> inner
,
202 return ISC_R_NOTFOUND
;
205 /* Write all the published values associated with the object through the
206 specified connection. */
208 isc_result_t
omapi_generic_stuff_values (omapi_object_t
*c
,
212 omapi_generic_object_t
*src
;
216 if (g
-> type
!= omapi_type_generic
)
217 return ISC_R_INVALIDARG
;
218 src
= (omapi_generic_object_t
*)g
;
220 for (i
= 0; i
< src
-> nvalues
; i
++) {
221 if (src
-> values
[i
] && src
-> values
[i
] -> name
-> len
) {
222 status
= (omapi_connection_put_uint16
223 (c
, src
-> values
[i
] -> name
-> len
));
224 if (status
!= ISC_R_SUCCESS
)
226 status
= (omapi_connection_copyin
227 (c
, src
-> values
[i
] -> name
-> value
,
228 src
-> values
[i
] -> name
-> len
));
229 if (status
!= ISC_R_SUCCESS
)
232 status
= (omapi_connection_write_typed_data
233 (c
, src
-> values
[i
] -> value
));
234 if (status
!= ISC_R_SUCCESS
)
239 if (g
-> inner
&& g
-> inner
-> type
-> stuff_values
)
240 return (*(g
-> inner
-> type
-> stuff_values
)) (c
, id
,
242 return ISC_R_SUCCESS
;