]> git.ipfire.org Git - thirdparty/dhcp.git/blame - omapip/generic.c
- A patch supplied by David Cantrell at RedHat was applied that detects
[thirdparty/dhcp.git] / omapip / generic.c
CommitLineData
61b844bf
TL
1/* generic.c
2
3 Subroutines that support the generic object. */
4
5/*
706792c9 6 * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
98311e4b 7 * Copyright (c) 1999-2003 by Internet Software Consortium
61b844bf 8 *
98311e4b
DH
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.
61b844bf 12 *
98311e4b
DH
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.
61b844bf 20 *
98311e4b
DH
21 * Internet Systems Consortium, Inc.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
25 * http://www.isc.org/
49733f31 26 *
98311e4b 27 * This software has been written for Internet Systems Consortium
49733f31 28 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
98311e4b 29 * To learn more about Internet Systems Consortium, see
49733f31
TL
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''.
61b844bf
TL
33 */
34
fe5b0fdd
DH
35#include "dhcpd.h"
36
6a4c4be8 37#include <omapip/omapip_p.h>
61b844bf 38
20916cae
TL
39OMAPI_OBJECT_ALLOC (omapi_generic,
40 omapi_generic_object_t, omapi_type_generic)
41
4bd8800e
TL
42isc_result_t omapi_generic_new (omapi_object_t **gen,
43 const char *file, int line)
61b844bf 44{
20916cae
TL
45 /* Backwards compatibility. */
46 return omapi_generic_allocate ((omapi_generic_object_t **)gen,
47 file, line);
61b844bf
TL
48}
49
50isc_result_t omapi_generic_set_value (omapi_object_t *h,
51 omapi_object_t *id,
52 omapi_data_string_t *name,
53 omapi_typed_data_t *value)
54{
55 omapi_generic_object_t *g;
56 omapi_value_t *new;
57 omapi_value_t **va;
d758ad8c 58 u_int8_t *ca;
61b844bf 59 int vm_new;
d758ad8c 60 int i, vfree = -1;
61b844bf
TL
61 isc_result_t status;
62
63 if (h -> type != omapi_type_generic)
64 return ISC_R_INVALIDARG;
65 g = (omapi_generic_object_t *)h;
66
67 /* See if there's already a value with this name attached to
68 the generic object, and if so, replace the current value
69 with the new one. */
70 for (i = 0; i < g -> nvalues; i++) {
71 if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
72 /* There's an inconsistency here: the standard
73 behaviour of a set_values method when
74 passed a matching name and a null value is
75 to delete the value associated with that
76 name (where possible). In the generic
77 object, we remember the name/null pair,
78 because generic objects are generally used
79 to pass messages around, and this is the
80 way that remote entities delete values from
81 local objects. If the get_value method of
82 a generic object is called for a name that
83 maps to a name/null pair, ISC_R_NOTFOUND is
84 returned. */
85 new = (omapi_value_t *)0;
4bd8800e 86 status = (omapi_value_new (&new, MDL));
61b844bf
TL
87 if (status != ISC_R_SUCCESS)
88 return status;
4bd8800e 89 omapi_data_string_reference (&new -> name, name, MDL);
61b844bf 90 if (value)
4bd8800e
TL
91 omapi_typed_data_reference (&new -> value,
92 value, MDL);
61b844bf 93
4bd8800e 94 omapi_value_dereference (&(g -> values [i]), MDL);
61b844bf 95 status = (omapi_value_reference
4bd8800e
TL
96 (&(g -> values [i]), new, MDL));
97 omapi_value_dereference (&new, MDL);
d758ad8c 98 g -> changed [i] = 1;
61b844bf
TL
99 return status;
100 }
d758ad8c
TL
101 /* Notice a free slot if we pass one. */
102 else if (vfree == -1 && !g -> values [i])
103 vfree = i;
61b844bf
TL
104 }
105
106 /* If the name isn't already attached to this object, see if an
107 inner object has it. */
581e37e4 108 if (h -> inner && h -> inner -> type -> set_value) {
61b844bf
TL
109 status = ((*(h -> inner -> type -> set_value))
110 (h -> inner, id, name, value));
581e37e4
TL
111 if (status != ISC_R_NOTFOUND)
112 return status;
113 }
61b844bf
TL
114
115 /* Okay, so it's a value that no inner object knows about, and
116 (implicitly, since the outer object set_value method would
117 have called this object's set_value method) it's an object that
118 no outer object knows about, it's this object's responsibility
119 to remember it - that's what generic objects do. */
120
121 /* Arrange for there to be space for the pointer to the new
122 name/value pair if necessary: */
d758ad8c
TL
123 if (vfree == -1) {
124 vfree = g -> nvalues;
125 if (vfree == g -> va_max) {
126 if (g -> va_max)
127 vm_new = 2 * g -> va_max;
128 else
129 vm_new = 10;
130 va = dmalloc (vm_new * sizeof *va, MDL);
131 if (!va)
132 return ISC_R_NOMEMORY;
133 ca = dmalloc (vm_new * sizeof *ca, MDL);
134 if (!ca) {
135 dfree (va, MDL);
136 return ISC_R_NOMEMORY;
137 }
138 if (g -> va_max) {
139 memcpy (va, g -> values,
140 g -> va_max * sizeof *va);
141 memcpy (ca, g -> changed,
142 g -> va_max * sizeof *ca);
143 }
144 memset (va + g -> va_max, 0,
145 (vm_new - g -> va_max) * sizeof *va);
146 memset (ca + g -> va_max, 0,
147 (vm_new - g -> va_max) * sizeof *ca);
148 if (g -> values)
149 dfree (g -> values, MDL);
150 if (g -> changed)
151 dfree (g -> changed, MDL);
152 g -> values = va;
153 g -> changed = ca;
154 g -> va_max = vm_new;
155 }
61b844bf 156 }
d758ad8c 157 status = omapi_value_new (&g -> values [vfree], MDL);
61b844bf
TL
158 if (status != ISC_R_SUCCESS)
159 return status;
d758ad8c 160 omapi_data_string_reference (&g -> values [vfree] -> name,
4bd8800e 161 name, MDL);
61b844bf
TL
162 if (value)
163 omapi_typed_data_reference
d758ad8c
TL
164 (&g -> values [vfree] -> value, value, MDL);
165 g -> changed [vfree] = 1;
166 if (vfree == g -> nvalues)
167 g -> nvalues++;
61b844bf
TL
168 return ISC_R_SUCCESS;
169}
170
171isc_result_t omapi_generic_get_value (omapi_object_t *h,
172 omapi_object_t *id,
173 omapi_data_string_t *name,
174 omapi_value_t **value)
175{
176 int i;
177 omapi_generic_object_t *g;
178
179 if (h -> type != omapi_type_generic)
180 return ISC_R_INVALIDARG;
181 g = (omapi_generic_object_t *)h;
182
183 /* Look up the specified name in our list of objects. */
184 for (i = 0; i < g -> nvalues; i++) {
98311e4b
DH
185 if (!g -> values[i])
186 continue;
61b844bf
TL
187 if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
188 /* If this is a name/null value pair, this is the
189 same as if there were no value that matched
190 the specified name, so return ISC_R_NOTFOUND. */
191 if (!g -> values [i] -> value)
192 return ISC_R_NOTFOUND;
193 /* Otherwise, return the name/value pair. */
4bd8800e
TL
194 return omapi_value_reference (value,
195 g -> values [i], MDL);
61b844bf
TL
196 }
197 }
198
199 if (h -> inner && h -> inner -> type -> get_value)
200 return (*(h -> inner -> type -> get_value))
201 (h -> inner, id, name, value);
202 return ISC_R_NOTFOUND;
203}
204
4bd8800e
TL
205isc_result_t omapi_generic_destroy (omapi_object_t *h,
206 const char *file, int line)
61b844bf
TL
207{
208 omapi_generic_object_t *g;
209 int i;
210
211 if (h -> type != omapi_type_generic)
212 return ISC_R_UNEXPECTED;
213 g = (omapi_generic_object_t *)h;
214
215 if (g -> values) {
216 for (i = 0; i < g -> nvalues; i++) {
217 if (g -> values [i])
218 omapi_value_dereference (&g -> values [i],
4bd8800e 219 file, line);
61b844bf 220 }
4bd8800e 221 dfree (g -> values, file, line);
d758ad8c 222 dfree (g -> changed, file, line);
61b844bf 223 g -> values = (omapi_value_t **)0;
d758ad8c 224 g -> changed = (u_int8_t *)0;
61b844bf
TL
225 g -> va_max = 0;
226 }
227
228 return ISC_R_SUCCESS;
229}
230
231isc_result_t omapi_generic_signal_handler (omapi_object_t *h,
b1b7b521 232 const char *name, va_list ap)
61b844bf
TL
233{
234 if (h -> type != omapi_type_generic)
235 return ISC_R_INVALIDARG;
236
237 if (h -> inner && h -> inner -> type -> signal_handler)
238 return (*(h -> inner -> type -> signal_handler)) (h -> inner,
239 name, ap);
240 return ISC_R_NOTFOUND;
241}
242
243/* Write all the published values associated with the object through the
244 specified connection. */
245
246isc_result_t omapi_generic_stuff_values (omapi_object_t *c,
247 omapi_object_t *id,
248 omapi_object_t *g)
249{
250 omapi_generic_object_t *src;
251 int i;
252 isc_result_t status;
253
254 if (g -> type != omapi_type_generic)
255 return ISC_R_INVALIDARG;
256 src = (omapi_generic_object_t *)g;
257
258 for (i = 0; i < src -> nvalues; i++) {
d758ad8c
TL
259 if (src -> values [i] && src -> values [i] -> name -> len &&
260 src -> changed [i]) {
61b844bf
TL
261 status = (omapi_connection_put_uint16
262 (c, src -> values [i] -> name -> len));
263 if (status != ISC_R_SUCCESS)
264 return status;
581e37e4
TL
265 status = (omapi_connection_copyin
266 (c, src -> values [i] -> name -> value,
61b844bf
TL
267 src -> values [i] -> name -> len));
268 if (status != ISC_R_SUCCESS)
269 return status;
270
271 status = (omapi_connection_write_typed_data
272 (c, src -> values [i] -> value));
273 if (status != ISC_R_SUCCESS)
274 return status;
275 }
276 }
277
278 if (g -> inner && g -> inner -> type -> stuff_values)
279 return (*(g -> inner -> type -> stuff_values)) (c, id,
280 g -> inner);
281 return ISC_R_SUCCESS;
282}
283
d758ad8c
TL
284/* Clear the changed flags on the object. This has the effect that if
285 generic_stuff is called, any attributes that still have a cleared changed
286 flag aren't sent to the peer. This also deletes any values that are
287 null, presuming that these have now been properly handled. */
288
289isc_result_t omapi_generic_clear_flags (omapi_object_t *o)
290{
291 int i;
d758ad8c
TL
292 omapi_generic_object_t *g;
293
294 if (o -> type != omapi_type_generic)
295 return ISC_R_INVALIDARG;
296 g = (omapi_generic_object_t *)o;
297
298 for (i = 0; i < g -> nvalues; i++) {
299 g -> changed [i] = 0;
300 if (g -> values [i] &&
301 !g -> values [i] -> value)
302 omapi_value_dereference (&g -> values [i], MDL);
303 }
304 return ISC_R_SUCCESS;
305}