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