]> git.ipfire.org Git - thirdparty/dhcp.git/blame - omapip/generic.c
Debugging allocator needs logging functions.
[thirdparty/dhcp.git] / omapip / generic.c
CommitLineData
61b844bf
TL
1/* generic.c
2
3 Subroutines that support the generic object. */
4
5/*
6 * Copyright (c) 1996-1999 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:
12 *
13 * http://www.isc.org/isc-license-1.0.html.
14 *
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.
18 *
19 * Support and other services are available for ISC products - see
20 * http://www.isc.org for more information.
21 */
22
6a4c4be8 23#include <omapip/omapip_p.h>
61b844bf 24
b1b7b521 25isc_result_t omapi_generic_new (omapi_object_t **gen, const char *name)
61b844bf
TL
26{
27 omapi_generic_object_t *obj;
28
29 obj = malloc (sizeof *obj);
30 if (!obj)
31 return ISC_R_NOMEMORY;
32 memset (obj, 0, sizeof *obj);
33 obj -> refcnt = 0;
34 obj -> type = omapi_type_generic;
35
36 return omapi_object_reference (gen, (omapi_object_t *)obj, name);
37}
38
39isc_result_t omapi_generic_set_value (omapi_object_t *h,
40 omapi_object_t *id,
41 omapi_data_string_t *name,
42 omapi_typed_data_t *value)
43{
44 omapi_generic_object_t *g;
45 omapi_value_t *new;
46 omapi_value_t **va;
47 int vm_new;
48 int i;
49 isc_result_t status;
50
51 if (h -> type != omapi_type_generic)
52 return ISC_R_INVALIDARG;
53 g = (omapi_generic_object_t *)h;
54
55 /* See if there's already a value with this name attached to
56 the generic object, and if so, replace the current value
57 with the new one. */
58 for (i = 0; i < g -> nvalues; i++) {
59 if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
60 /* There's an inconsistency here: the standard
61 behaviour of a set_values method when
62 passed a matching name and a null value is
63 to delete the value associated with that
64 name (where possible). In the generic
65 object, we remember the name/null pair,
66 because generic objects are generally used
67 to pass messages around, and this is the
68 way that remote entities delete values from
69 local objects. If the get_value method of
70 a generic object is called for a name that
71 maps to a name/null pair, ISC_R_NOTFOUND is
72 returned. */
73 new = (omapi_value_t *)0;
74 status = (omapi_value_new (&new,
75 "omapi_message_get_value"));
76 if (status != ISC_R_SUCCESS)
77 return status;
78 omapi_data_string_reference
79 (&new -> name, name,
80 "omapi_message_get_value");
81 if (value)
82 omapi_typed_data_reference
83 (&new -> value, value,
84 "omapi_generic_set_value");
85
86 omapi_value_dereference (&(g -> values [i]),
87 "omapi_message_set_value");
88 status = (omapi_value_reference
89 (&(g -> values [i]), new,
90 "omapi_message_set_value"));
91 omapi_value_dereference (&new,
92 "omapi_message_set_value");
93 return status;
94 }
95 }
96
97 /* If the name isn't already attached to this object, see if an
98 inner object has it. */
581e37e4 99 if (h -> inner && h -> inner -> type -> set_value) {
61b844bf
TL
100 status = ((*(h -> inner -> type -> set_value))
101 (h -> inner, id, name, value));
581e37e4
TL
102 if (status != ISC_R_NOTFOUND)
103 return status;
104 }
61b844bf
TL
105
106 /* Okay, so it's a value that no inner object knows about, and
107 (implicitly, since the outer object set_value method would
108 have called this object's set_value method) it's an object that
109 no outer object knows about, it's this object's responsibility
110 to remember it - that's what generic objects do. */
111
112 /* Arrange for there to be space for the pointer to the new
113 name/value pair if necessary: */
114 if (g -> nvalues == g -> va_max) {
115 if (g -> va_max)
116 vm_new = 2 * g -> va_max;
117 else
118 vm_new = 10;
119 va = malloc (vm_new * sizeof *va);
120 if (!va)
121 return ISC_R_NOMEMORY;
122 if (g -> va_max)
123 memcpy (va, g -> values, g -> va_max * sizeof *va);
124 memset (va + g -> va_max, 0,
125 (vm_new - g -> va_max) * sizeof *va);
126 free (g -> values);
127 g -> values = va;
d82813f8 128 g -> va_max = vm_new;
61b844bf
TL
129 }
130 status = omapi_value_new (&g -> values [g -> nvalues],
131 "omapi_generic_set_value");
132 if (status != ISC_R_SUCCESS)
133 return status;
134 omapi_data_string_reference (&g -> values [g -> nvalues] -> name, name,
135 "omapi_generic_set_value");
136 if (value)
137 omapi_typed_data_reference
138 (&g -> values [g -> nvalues] -> value, value,
139 "omapi_generic_set_value");
140 g -> nvalues++;
141 return ISC_R_SUCCESS;
142}
143
144isc_result_t omapi_generic_get_value (omapi_object_t *h,
145 omapi_object_t *id,
146 omapi_data_string_t *name,
147 omapi_value_t **value)
148{
149 int i;
150 omapi_generic_object_t *g;
151
152 if (h -> type != omapi_type_generic)
153 return ISC_R_INVALIDARG;
154 g = (omapi_generic_object_t *)h;
155
156 /* Look up the specified name in our list of objects. */
157 for (i = 0; i < g -> nvalues; i++) {
158 if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
159 /* If this is a name/null value pair, this is the
160 same as if there were no value that matched
161 the specified name, so return ISC_R_NOTFOUND. */
162 if (!g -> values [i] -> value)
163 return ISC_R_NOTFOUND;
164 /* Otherwise, return the name/value pair. */
165 return omapi_value_reference
166 (value, g -> values [i],
167 "omapi_message_get_value");
168 }
169 }
170
171 if (h -> inner && h -> inner -> type -> get_value)
172 return (*(h -> inner -> type -> get_value))
173 (h -> inner, id, name, value);
174 return ISC_R_NOTFOUND;
175}
176
b1b7b521 177isc_result_t omapi_generic_destroy (omapi_object_t *h, const char *name)
61b844bf
TL
178{
179 omapi_generic_object_t *g;
180 int i;
181
182 if (h -> type != omapi_type_generic)
183 return ISC_R_UNEXPECTED;
184 g = (omapi_generic_object_t *)h;
185
186 if (g -> values) {
187 for (i = 0; i < g -> nvalues; i++) {
188 if (g -> values [i])
189 omapi_value_dereference (&g -> values [i],
190 name);
191 }
192 free (g -> values);
193 g -> values = (omapi_value_t **)0;
194 g -> va_max = 0;
195 }
196
197 return ISC_R_SUCCESS;
198}
199
200isc_result_t omapi_generic_signal_handler (omapi_object_t *h,
b1b7b521 201 const char *name, va_list ap)
61b844bf
TL
202{
203 if (h -> type != omapi_type_generic)
204 return ISC_R_INVALIDARG;
205
206 if (h -> inner && h -> inner -> type -> signal_handler)
207 return (*(h -> inner -> type -> signal_handler)) (h -> inner,
208 name, ap);
209 return ISC_R_NOTFOUND;
210}
211
212/* Write all the published values associated with the object through the
213 specified connection. */
214
215isc_result_t omapi_generic_stuff_values (omapi_object_t *c,
216 omapi_object_t *id,
217 omapi_object_t *g)
218{
219 omapi_generic_object_t *src;
220 int i;
221 isc_result_t status;
222
223 if (g -> type != omapi_type_generic)
224 return ISC_R_INVALIDARG;
225 src = (omapi_generic_object_t *)g;
226
227 for (i = 0; i < src -> nvalues; i++) {
228 if (src -> values [i] && src -> values [i] -> name -> len) {
229 status = (omapi_connection_put_uint16
230 (c, src -> values [i] -> name -> len));
231 if (status != ISC_R_SUCCESS)
232 return status;
581e37e4
TL
233 status = (omapi_connection_copyin
234 (c, src -> values [i] -> name -> value,
61b844bf
TL
235 src -> values [i] -> name -> len));
236 if (status != ISC_R_SUCCESS)
237 return status;
238
239 status = (omapi_connection_write_typed_data
240 (c, src -> values [i] -> value));
241 if (status != ISC_R_SUCCESS)
242 return status;
243 }
244 }
245
246 if (g -> inner && g -> inner -> type -> stuff_values)
247 return (*(g -> inner -> type -> stuff_values)) (c, id,
248 g -> inner);
249 return ISC_R_SUCCESS;
250}
251