]> git.ipfire.org Git - thirdparty/dhcp.git/blob - omapip/support.c
Go back to the BSD license.
[thirdparty/dhcp.git] / omapip / support.c
1 /* support.c
2
3 Subroutines providing general support for objects. */
4
5 /*
6 * Copyright (c) 1999-2000 Internet Software Consortium.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of The Internet Software Consortium nor the names
19 * of its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * This software has been written for the Internet Software Consortium
37 * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
38 * To learn more about the Internet Software Consortium, see
39 * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
40 * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
41 * ``http://www.nominum.com''.
42 */
43
44 #include <omapip/omapip_p.h>
45
46 omapi_object_type_t *omapi_type_connection;
47 omapi_object_type_t *omapi_type_listener;
48 omapi_object_type_t *omapi_type_io_object;
49 omapi_object_type_t *omapi_type_datagram;
50 omapi_object_type_t *omapi_type_generic;
51 omapi_object_type_t *omapi_type_protocol;
52 omapi_object_type_t *omapi_type_protocol_listener;
53 omapi_object_type_t *omapi_type_waiter;
54 omapi_object_type_t *omapi_type_remote;
55 omapi_object_type_t *omapi_type_message;
56
57 omapi_object_type_t *omapi_object_types;
58 int omapi_object_type_count;
59 static int ot_max;
60
61 isc_result_t omapi_init (void)
62 {
63 isc_result_t status;
64
65 /* Register all the standard object types... */
66 status = omapi_object_type_register (&omapi_type_connection,
67 "connection",
68 omapi_connection_set_value,
69 omapi_connection_get_value,
70 omapi_connection_destroy,
71 omapi_connection_signal_handler,
72 omapi_connection_stuff_values,
73 0, 0, 0);
74 if (status != ISC_R_SUCCESS)
75 return status;
76
77 status = omapi_object_type_register (&omapi_type_listener,
78 "listener",
79 omapi_listener_set_value,
80 omapi_listener_get_value,
81 omapi_listener_destroy,
82 omapi_listener_signal_handler,
83 omapi_listener_stuff_values,
84 0, 0, 0);
85 if (status != ISC_R_SUCCESS)
86 return status;
87
88 status = omapi_object_type_register (&omapi_type_io_object,
89 "io",
90 omapi_io_set_value,
91 omapi_io_get_value,
92 omapi_io_destroy,
93 omapi_io_signal_handler,
94 omapi_io_stuff_values,
95 0, 0, 0);
96 if (status != ISC_R_SUCCESS)
97 return status;
98
99 status = omapi_object_type_register (&omapi_type_generic,
100 "generic",
101 omapi_generic_set_value,
102 omapi_generic_get_value,
103 omapi_generic_destroy,
104 omapi_generic_signal_handler,
105 omapi_generic_stuff_values,
106 0, 0, 0);
107 if (status != ISC_R_SUCCESS)
108 return status;
109
110 status = omapi_object_type_register (&omapi_type_protocol,
111 "protocol",
112 omapi_protocol_set_value,
113 omapi_protocol_get_value,
114 omapi_protocol_destroy,
115 omapi_protocol_signal_handler,
116 omapi_protocol_stuff_values,
117 0, 0, 0);
118 if (status != ISC_R_SUCCESS)
119 return status;
120
121 status = omapi_object_type_register (&omapi_type_protocol_listener,
122 "protocol-listener",
123 omapi_protocol_listener_set_value,
124 omapi_protocol_listener_get_value,
125 omapi_protocol_listener_destroy,
126 omapi_protocol_listener_signal,
127 omapi_protocol_listener_stuff,
128 0, 0, 0);
129 if (status != ISC_R_SUCCESS)
130 return status;
131
132 status = omapi_object_type_register (&omapi_type_message,
133 "message",
134 omapi_message_set_value,
135 omapi_message_get_value,
136 omapi_message_destroy,
137 omapi_message_signal_handler,
138 omapi_message_stuff_values,
139 0, 0, 0);
140 if (status != ISC_R_SUCCESS)
141 return status;
142
143 status = omapi_object_type_register (&omapi_type_waiter,
144 "waiter",
145 0,
146 0,
147 0,
148 omapi_waiter_signal_handler, 0,
149 0, 0, 0);
150 if (status != ISC_R_SUCCESS)
151 return status;
152
153 /* This seems silly, but leave it. */
154 return ISC_R_SUCCESS;
155 }
156
157 isc_result_t omapi_object_type_register (omapi_object_type_t **type,
158 const char *name,
159 isc_result_t (*set_value)
160 (omapi_object_t *,
161 omapi_object_t *,
162 omapi_data_string_t *,
163 omapi_typed_data_t *),
164 isc_result_t (*get_value)
165 (omapi_object_t *,
166 omapi_object_t *,
167 omapi_data_string_t *,
168 omapi_value_t **),
169 isc_result_t (*destroy)
170 (omapi_object_t *,
171 const char *, int),
172 isc_result_t (*signal_handler)
173 (omapi_object_t *,
174 const char *, va_list),
175 isc_result_t (*stuff_values)
176 (omapi_object_t *,
177 omapi_object_t *,
178 omapi_object_t *),
179 isc_result_t (*lookup)
180 (omapi_object_t **,
181 omapi_object_t *,
182 omapi_object_t *),
183 isc_result_t (*create)
184 (omapi_object_t **,
185 omapi_object_t *),
186 isc_result_t (*remove)
187 (omapi_object_t *,
188 omapi_object_t *))
189 {
190 omapi_object_type_t *t;
191
192 t = dmalloc (sizeof *t, MDL);
193 if (!t)
194 return ISC_R_NOMEMORY;
195 memset (t, 0, sizeof *t);
196
197 t -> name = name;
198 t -> set_value = set_value;
199 t -> get_value = get_value;
200 t -> destroy = destroy;
201 t -> signal_handler = signal_handler;
202 t -> stuff_values = stuff_values;
203 t -> lookup = lookup;
204 t -> create = create;
205 t -> remove = remove;
206 t -> next = omapi_object_types;
207 omapi_object_types = t;
208 if (type)
209 *type = t;
210 return ISC_R_SUCCESS;
211 }
212
213 isc_result_t omapi_signal (omapi_object_t *handle, const char *name, ...)
214 {
215 va_list ap;
216 omapi_object_t *outer;
217 isc_result_t status;
218
219 va_start (ap, name);
220 for (outer = handle; outer -> outer; outer = outer -> outer)
221 ;
222 if (outer -> type -> signal_handler)
223 status = (*(outer -> type -> signal_handler)) (outer,
224 name, ap);
225 else
226 status = ISC_R_NOTFOUND;
227 va_end (ap);
228 return status;
229 }
230
231 isc_result_t omapi_signal_in (omapi_object_t *handle, const char *name, ...)
232 {
233 va_list ap;
234 omapi_object_t *outer;
235 isc_result_t status;
236
237 if (!handle)
238 return ISC_R_NOTFOUND;
239 va_start (ap, name);
240
241 if (handle -> type -> signal_handler)
242 status = (*(handle -> type -> signal_handler)) (handle,
243 name, ap);
244 else
245 status = ISC_R_NOTFOUND;
246 va_end (ap);
247 return status;
248 }
249
250 isc_result_t omapi_set_value (omapi_object_t *h,
251 omapi_object_t *id,
252 omapi_data_string_t *name,
253 omapi_typed_data_t *value)
254 {
255 omapi_object_t *outer;
256
257 for (outer = h; outer -> outer; outer = outer -> outer)
258 ;
259 if (outer -> type -> set_value)
260 return (*(outer -> type -> set_value)) (outer,
261 id, name, value);
262 return ISC_R_NOTFOUND;
263 }
264
265 isc_result_t omapi_set_value_str (omapi_object_t *h,
266 omapi_object_t *id,
267 const char *name,
268 omapi_typed_data_t *value)
269 {
270 omapi_object_t *outer;
271 omapi_data_string_t *nds;
272 isc_result_t status;
273
274 nds = (omapi_data_string_t *)0;
275 status = omapi_data_string_new (&nds, strlen (name), MDL);
276 if (status != ISC_R_SUCCESS)
277 return status;
278 memcpy (nds -> value, name, strlen (name));
279
280 return omapi_set_value (h, id, nds, value);
281 }
282
283 isc_result_t omapi_set_boolean_value (omapi_object_t *h, omapi_object_t *id,
284 const char *name, int value)
285 {
286 isc_result_t status;
287 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
288 omapi_data_string_t *n = (omapi_data_string_t *)0;
289 int len;
290 int ip;
291
292 status = omapi_data_string_new (&n, strlen (name), MDL);
293 if (status != ISC_R_SUCCESS)
294 return status;
295 memcpy (n -> value, name, strlen (name));
296
297 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
298 if (status != ISC_R_SUCCESS) {
299 omapi_data_string_dereference (&n, MDL);
300 return status;
301 }
302
303 status = omapi_set_value (h, id, n, tv);
304 omapi_data_string_dereference (&n, MDL);
305 omapi_typed_data_dereference (&tv, MDL);
306 return status;
307 }
308
309 isc_result_t omapi_set_int_value (omapi_object_t *h, omapi_object_t *id,
310 const char *name, int value)
311 {
312 isc_result_t status;
313 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
314 omapi_data_string_t *n = (omapi_data_string_t *)0;
315 int len;
316 int ip;
317
318 status = omapi_data_string_new (&n, strlen (name), MDL);
319 if (status != ISC_R_SUCCESS)
320 return status;
321 memcpy (n -> value, name, strlen (name));
322
323 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
324 if (status != ISC_R_SUCCESS) {
325 omapi_data_string_dereference (&n, MDL);
326 return status;
327 }
328
329 status = omapi_set_value (h, id, n, tv);
330 omapi_data_string_dereference (&n, MDL);
331 omapi_typed_data_dereference (&tv, MDL);
332 return status;
333 }
334
335 isc_result_t omapi_set_object_value (omapi_object_t *h, omapi_object_t *id,
336 const char *name, omapi_object_t *value)
337 {
338 isc_result_t status;
339 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
340 omapi_data_string_t *n = (omapi_data_string_t *)0;
341 int len;
342 int ip;
343
344 status = omapi_data_string_new (&n, strlen (name), MDL);
345 if (status != ISC_R_SUCCESS)
346 return status;
347 memcpy (n -> value, name, strlen (name));
348
349 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_object, value);
350 if (status != ISC_R_SUCCESS) {
351 omapi_data_string_dereference (&n, MDL);
352 return status;
353 }
354
355 status = omapi_set_value (h, id, n, tv);
356 omapi_data_string_dereference (&n, MDL);
357 omapi_typed_data_dereference (&tv, MDL);
358 return status;
359 }
360
361 isc_result_t omapi_set_string_value (omapi_object_t *h, omapi_object_t *id,
362 const char *name, const char *value)
363 {
364 isc_result_t status;
365 omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
366 omapi_data_string_t *n = (omapi_data_string_t *)0;
367 int len;
368 int ip;
369
370 status = omapi_data_string_new (&n, strlen (name), MDL);
371 if (status != ISC_R_SUCCESS)
372 return status;
373 memcpy (n -> value, name, strlen (name));
374
375 status = omapi_typed_data_new (MDL, &tv, omapi_datatype_string, value);
376 if (status != ISC_R_SUCCESS) {
377 omapi_data_string_dereference (&n, MDL);
378 return status;
379 }
380
381 status = omapi_set_value (h, id, n, tv);
382 omapi_data_string_dereference (&n, MDL);
383 omapi_typed_data_dereference (&tv, MDL);
384 return status;
385 }
386
387 isc_result_t omapi_get_value (omapi_object_t *h,
388 omapi_object_t *id,
389 omapi_data_string_t *name,
390 omapi_value_t **value)
391 {
392 omapi_object_t *outer;
393
394 for (outer = h; outer -> outer; outer = outer -> outer)
395 ;
396 if (outer -> type -> get_value)
397 return (*(outer -> type -> get_value)) (outer,
398 id, name, value);
399 return ISC_R_NOTFOUND;
400 }
401
402 isc_result_t omapi_get_value_str (omapi_object_t *h,
403 omapi_object_t *id,
404 const char *name,
405 omapi_value_t **value)
406 {
407 omapi_object_t *outer;
408 omapi_data_string_t *nds;
409 isc_result_t status;
410
411 nds = (omapi_data_string_t *)0;
412 status = omapi_data_string_new (&nds, strlen (name), MDL);
413 if (status != ISC_R_SUCCESS)
414 return status;
415 memcpy (nds -> value, name, strlen (name));
416
417 for (outer = h; outer -> outer; outer = outer -> outer)
418 ;
419 if (outer -> type -> get_value)
420 return (*(outer -> type -> get_value)) (outer,
421 id, nds, value);
422 return ISC_R_NOTFOUND;
423 }
424
425 isc_result_t omapi_stuff_values (omapi_object_t *c,
426 omapi_object_t *id,
427 omapi_object_t *o)
428 {
429 omapi_object_t *outer;
430
431 for (outer = o; outer -> outer; outer = outer -> outer)
432 ;
433 if (outer -> type -> stuff_values)
434 return (*(outer -> type -> stuff_values)) (c, id, outer);
435 return ISC_R_NOTFOUND;
436 }
437
438 isc_result_t omapi_object_create (omapi_object_t **obj, omapi_object_t *id,
439 omapi_object_type_t *type)
440 {
441 if (!type -> create)
442 return ISC_R_NOTIMPLEMENTED;
443 return (*(type -> create)) (obj, id);
444 }
445
446 isc_result_t omapi_object_update (omapi_object_t *obj, omapi_object_t *id,
447 omapi_object_t *src, omapi_handle_t handle)
448 {
449 omapi_generic_object_t *gsrc;
450 isc_result_t status;
451 int i;
452
453 if (!src)
454 return ISC_R_INVALIDARG;
455 if (src -> type != omapi_type_generic)
456 return ISC_R_NOTIMPLEMENTED;
457 gsrc = (omapi_generic_object_t *)src;
458 for (i = 0; i < gsrc -> nvalues; i++) {
459 status = omapi_set_value (obj, id,
460 gsrc -> values [i] -> name,
461 gsrc -> values [i] -> value);
462 if (status != ISC_R_SUCCESS)
463 return status;
464 }
465 if (handle)
466 omapi_set_int_value (obj, id, "remote-handle", (int)handle);
467 status = omapi_signal (obj, "updated");
468 if (status != ISC_R_NOTFOUND)
469 return status;
470 return ISC_R_SUCCESS;
471 }
472
473 int omapi_data_string_cmp (omapi_data_string_t *s1, omapi_data_string_t *s2)
474 {
475 unsigned len;
476 int rv;
477
478 if (s1 -> len > s2 -> len)
479 len = s2 -> len;
480 else
481 len = s1 -> len;
482 rv = memcmp (s1 -> value, s2 -> value, len);
483 if (rv)
484 return rv;
485 if (s1 -> len > s2 -> len)
486 return 1;
487 else if (s1 -> len < s2 -> len)
488 return -1;
489 return 0;
490 }
491
492 int omapi_ds_strcmp (omapi_data_string_t *s1, const char *s2)
493 {
494 unsigned len, slen;
495 int rv;
496
497 slen = strlen (s2);
498 if (slen > s1 -> len)
499 len = s1 -> len;
500 else
501 len = slen;
502 rv = memcmp (s1 -> value, s2, len);
503 if (rv)
504 return rv;
505 if (s1 -> len > slen)
506 return 1;
507 else if (s1 -> len < slen)
508 return -1;
509 return 0;
510 }
511
512 int omapi_td_strcmp (omapi_typed_data_t *s1, const char *s2)
513 {
514 unsigned len, slen;
515 int rv;
516
517 /* If the data type is not compatible, never equal. */
518 if (s1 -> type != omapi_datatype_data &&
519 s1 -> type != omapi_datatype_string)
520 return -1;
521
522 slen = strlen (s2);
523 if (slen > s1 -> u.buffer.len)
524 len = s1 -> u.buffer.len;
525 else
526 len = slen;
527 rv = memcmp (s1 -> u.buffer.value, s2, len);
528 if (rv)
529 return rv;
530 if (s1 -> u.buffer.len > slen)
531 return 1;
532 else if (s1 -> u.buffer.len < slen)
533 return -1;
534 return 0;
535 }
536
537 isc_result_t omapi_make_value (omapi_value_t **vp,
538 omapi_data_string_t *name,
539 omapi_typed_data_t *value,
540 const char *file, int line)
541 {
542 isc_result_t status;
543
544 status = omapi_value_new (vp, file, line);
545 if (status != ISC_R_SUCCESS)
546 return status;
547
548 status = omapi_data_string_reference (&(*vp) -> name,
549 name, file, line);
550 if (status != ISC_R_SUCCESS) {
551 omapi_value_dereference (vp, file, line);
552 return status;
553 }
554 if (value) {
555 status = omapi_typed_data_reference (&(*vp) -> value,
556 value, file, line);
557 if (status != ISC_R_SUCCESS) {
558 omapi_value_dereference (vp, file, line);
559 return status;
560 }
561 }
562 return ISC_R_SUCCESS;
563 }
564
565 isc_result_t omapi_make_const_value (omapi_value_t **vp,
566 omapi_data_string_t *name,
567 const unsigned char *value,
568 unsigned len,
569 const char *file, int line)
570 {
571 isc_result_t status;
572
573 status = omapi_value_new (vp, file, line);
574 if (status != ISC_R_SUCCESS)
575 return status;
576
577 status = omapi_data_string_reference (&(*vp) -> name,
578 name, file, line);
579 if (status != ISC_R_SUCCESS) {
580 omapi_value_dereference (vp, file, line);
581 return status;
582 }
583 if (value) {
584 status = omapi_typed_data_new (file, line, &(*vp) -> value,
585 omapi_datatype_data, len);
586 if (status != ISC_R_SUCCESS) {
587 omapi_value_dereference (vp, file, line);
588 return status;
589 }
590 memcpy ((*vp) -> value -> u.buffer.value, value, len);
591 }
592 return ISC_R_SUCCESS;
593 }
594
595 isc_result_t omapi_make_int_value (omapi_value_t **vp,
596 omapi_data_string_t *name,
597 int value, const char *file, int line)
598 {
599 isc_result_t status;
600
601 status = omapi_value_new (vp, file, line);
602 if (status != ISC_R_SUCCESS)
603 return status;
604
605 status = omapi_data_string_reference (&(*vp) -> name,
606 name, file, line);
607 if (status != ISC_R_SUCCESS) {
608 omapi_value_dereference (vp, file, line);
609 return status;
610 }
611 if (value) {
612 status = omapi_typed_data_new (file, line, &(*vp) -> value,
613 omapi_datatype_int);
614 if (status != ISC_R_SUCCESS) {
615 omapi_value_dereference (vp, file, line);
616 return status;
617 }
618 (*vp) -> value -> u.integer = value;
619 }
620 return ISC_R_SUCCESS;
621 }
622
623 isc_result_t omapi_make_handle_value (omapi_value_t **vp,
624 omapi_data_string_t *name,
625 omapi_object_t *value,
626 const char *file, int line)
627 {
628 isc_result_t status;
629
630 status = omapi_value_new (vp, file, line);
631 if (status != ISC_R_SUCCESS)
632 return status;
633
634 status = omapi_data_string_reference (&(*vp) -> name,
635 name, file, line);
636 if (status != ISC_R_SUCCESS) {
637 omapi_value_dereference (vp, file, line);
638 return status;
639 }
640 if (value) {
641 status = omapi_typed_data_new (file, line, &(*vp) -> value,
642 omapi_datatype_int);
643 if (status != ISC_R_SUCCESS) {
644 omapi_value_dereference (vp, file, line);
645 return status;
646 }
647 status = (omapi_object_handle
648 ((omapi_handle_t *)&(*vp) -> value -> u.integer,
649 value));
650 if (status != ISC_R_SUCCESS) {
651 omapi_value_dereference (vp, file, line);
652 return status;
653 }
654 }
655 return ISC_R_SUCCESS;
656 }
657
658 isc_result_t omapi_make_string_value (omapi_value_t **vp,
659 omapi_data_string_t *name,
660 const char *value,
661 const char *file, int line)
662 {
663 isc_result_t status;
664
665 status = omapi_value_new (vp, file, line);
666 if (status != ISC_R_SUCCESS)
667 return status;
668
669 status = omapi_data_string_reference (&(*vp) -> name,
670 name, file, line);
671 if (status != ISC_R_SUCCESS) {
672 omapi_value_dereference (vp, file, line);
673 return status;
674 }
675 if (value) {
676 status = omapi_typed_data_new (file, line, &(*vp) -> value,
677 omapi_datatype_string, value);
678 if (status != ISC_R_SUCCESS) {
679 omapi_value_dereference (vp, file, line);
680 return status;
681 }
682 }
683 return ISC_R_SUCCESS;
684 }
685
686 isc_result_t omapi_get_int_value (unsigned long *v, omapi_typed_data_t *t)
687 {
688 u_int32_t rv;
689
690 if (t -> type == omapi_datatype_int) {
691 *v = t -> u.integer;
692 return ISC_R_SUCCESS;
693 } else if (t -> type == omapi_datatype_string ||
694 t -> type == omapi_datatype_data) {
695 if (t -> u.buffer.len != sizeof (rv))
696 return ISC_R_INVALIDARG;
697 memcpy (&rv, t -> u.buffer.value, sizeof rv);
698 *v = ntohl (rv);
699 return ISC_R_SUCCESS;
700 }
701 return ISC_R_INVALIDARG;
702 }