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