]> git.ipfire.org Git - thirdparty/dhcp.git/blame - omapip/generic.c
Fix up one mistake from last night's fixes.
[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
23#include <omapip/omapip.h>
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;
128 }
129 status = omapi_value_new (&g -> values [g -> nvalues],
130 "omapi_generic_set_value");
131 if (status != ISC_R_SUCCESS)
132 return status;
133 omapi_data_string_reference (&g -> values [g -> nvalues] -> name, name,
134 "omapi_generic_set_value");
135 if (value)
136 omapi_typed_data_reference
137 (&g -> values [g -> nvalues] -> value, value,
138 "omapi_generic_set_value");
139 g -> nvalues++;
140 return ISC_R_SUCCESS;
141}
142
143isc_result_t omapi_generic_get_value (omapi_object_t *h,
144 omapi_object_t *id,
145 omapi_data_string_t *name,
146 omapi_value_t **value)
147{
148 int i;
149 omapi_generic_object_t *g;
150
151 if (h -> type != omapi_type_generic)
152 return ISC_R_INVALIDARG;
153 g = (omapi_generic_object_t *)h;
154
155 /* Look up the specified name in our list of objects. */
156 for (i = 0; i < g -> nvalues; i++) {
157 if (!omapi_data_string_cmp (name, g -> values [i] -> name)) {
158 /* If this is a name/null value pair, this is the
159 same as if there were no value that matched
160 the specified name, so return ISC_R_NOTFOUND. */
161 if (!g -> values [i] -> value)
162 return ISC_R_NOTFOUND;
163 /* Otherwise, return the name/value pair. */
164 return omapi_value_reference
165 (value, g -> values [i],
166 "omapi_message_get_value");
167 }
168 }
169
170 if (h -> inner && h -> inner -> type -> get_value)
171 return (*(h -> inner -> type -> get_value))
172 (h -> inner, id, name, value);
173 return ISC_R_NOTFOUND;
174}
175
b1b7b521 176isc_result_t omapi_generic_destroy (omapi_object_t *h, const char *name)
61b844bf
TL
177{
178 omapi_generic_object_t *g;
179 int i;
180
181 if (h -> type != omapi_type_generic)
182 return ISC_R_UNEXPECTED;
183 g = (omapi_generic_object_t *)h;
184
185 if (g -> values) {
186 for (i = 0; i < g -> nvalues; i++) {
187 if (g -> values [i])
188 omapi_value_dereference (&g -> values [i],
189 name);
190 }
191 free (g -> values);
192 g -> values = (omapi_value_t **)0;
193 g -> va_max = 0;
194 }
195
196 return ISC_R_SUCCESS;
197}
198
199isc_result_t omapi_generic_signal_handler (omapi_object_t *h,
b1b7b521 200 const char *name, va_list ap)
61b844bf
TL
201{
202 if (h -> type != omapi_type_generic)
203 return ISC_R_INVALIDARG;
204
205 if (h -> inner && h -> inner -> type -> signal_handler)
206 return (*(h -> inner -> type -> signal_handler)) (h -> inner,
207 name, ap);
208 return ISC_R_NOTFOUND;
209}
210
211/* Write all the published values associated with the object through the
212 specified connection. */
213
214isc_result_t omapi_generic_stuff_values (omapi_object_t *c,
215 omapi_object_t *id,
216 omapi_object_t *g)
217{
218 omapi_generic_object_t *src;
219 int i;
220 isc_result_t status;
221
222 if (g -> type != omapi_type_generic)
223 return ISC_R_INVALIDARG;
224 src = (omapi_generic_object_t *)g;
225
226 for (i = 0; i < src -> nvalues; i++) {
227 if (src -> values [i] && src -> values [i] -> name -> len) {
228 status = (omapi_connection_put_uint16
229 (c, src -> values [i] -> name -> len));
230 if (status != ISC_R_SUCCESS)
231 return status;
581e37e4
TL
232 status = (omapi_connection_copyin
233 (c, src -> values [i] -> name -> value,
61b844bf
TL
234 src -> values [i] -> name -> len));
235 if (status != ISC_R_SUCCESS)
236 return status;
237
238 status = (omapi_connection_write_typed_data
239 (c, src -> values [i] -> value));
240 if (status != ISC_R_SUCCESS)
241 return status;
242 }
243 }
244
245 if (g -> inner && g -> inner -> type -> stuff_values)
246 return (*(g -> inner -> type -> stuff_values)) (c, id,
247 g -> inner);
248 return ISC_R_SUCCESS;
249}
250