cleanup .changes
[profile/ivi/dhcp.git] / omapip / support.c
1 /* support.c
2
3    Subroutines providing general support for objects. */
4
5 /*
6  * Copyright (c) 2004-2007,2009-2010
7  *                              by Internet Systems Consortium, Inc. ("ISC")
8  * Copyright (c) 1999-2003 by Internet Software Consortium
9  *
10  * Permission to use, copy, modify, and distribute this software for any
11  * purpose with or without fee is hereby granted, provided that the above
12  * copyright notice and this permission notice appear in all copies.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
15  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
17  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  *
22  *   Internet Systems Consortium, Inc.
23  *   950 Charter Street
24  *   Redwood City, CA 94063
25  *   <info@isc.org>
26  *   https://www.isc.org/
27  *
28  * This software has been written for Internet Systems Consortium
29  * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
30  * To learn more about Internet Systems Consortium, see
31  * ``https://www.isc.org/''.  To learn more about Vixie Enterprises,
32  * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
33  * ``http://www.nominum.com''.
34  */
35
36 #include "dhcpd.h"
37
38 #include <omapip/omapip_p.h>
39
40 omapi_object_type_t *omapi_type_connection;
41 omapi_object_type_t *omapi_type_listener;
42 omapi_object_type_t *omapi_type_io_object;
43 omapi_object_type_t *omapi_type_datagram;
44 omapi_object_type_t *omapi_type_generic;
45 omapi_object_type_t *omapi_type_protocol;
46 omapi_object_type_t *omapi_type_protocol_listener;
47 omapi_object_type_t *omapi_type_waiter;
48 omapi_object_type_t *omapi_type_remote;
49 omapi_object_type_t *omapi_type_message;
50 omapi_object_type_t *omapi_type_auth_key;
51
52 omapi_object_type_t *omapi_object_types;
53 int omapi_object_type_count;
54
55 #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
56 void omapi_type_relinquish ()
57 {
58         omapi_object_type_t *t, *n;
59
60         for (t = omapi_object_types; t; t = n) {
61                 n = t -> next;
62                 dfree (t, MDL);
63         }
64         omapi_object_types = (omapi_object_type_t *)0;
65 }
66 #endif
67
68 isc_result_t omapi_init (void)
69 {
70         isc_result_t status;
71
72         /* Register all the standard object types... */
73         status = omapi_object_type_register (&omapi_type_connection,
74                                              "connection",
75                                              omapi_connection_set_value,
76                                              omapi_connection_get_value,
77                                              omapi_connection_destroy,
78                                              omapi_connection_signal_handler,
79                                              omapi_connection_stuff_values,
80                                              0, 0, 0, 0, 0, 0,
81                                              sizeof
82                                              (omapi_connection_object_t), 0,
83                                              RC_MISC);
84         if (status != ISC_R_SUCCESS)
85                 return status;
86
87         status = omapi_object_type_register (&omapi_type_listener,
88                                              "listener",
89                                              omapi_listener_set_value,
90                                              omapi_listener_get_value,
91                                              omapi_listener_destroy,
92                                              omapi_listener_signal_handler,
93                                              omapi_listener_stuff_values,
94                                              0, 0, 0, 0, 0, 0,
95                                              sizeof (omapi_listener_object_t),
96                                              0, RC_MISC);
97         if (status != ISC_R_SUCCESS)
98                 return status;
99
100         status = omapi_object_type_register (&omapi_type_io_object,
101                                              "io",
102                                              omapi_io_set_value,
103                                              omapi_io_get_value,
104                                              omapi_io_destroy,
105                                              omapi_io_signal_handler,
106                                              omapi_io_stuff_values,
107                                              0, 0, 0, 0, 0, 0,
108                                              sizeof (omapi_io_object_t),
109                                              0, RC_MISC);
110         if (status != ISC_R_SUCCESS)
111                 return status;
112
113         status = omapi_object_type_register (&omapi_type_generic,
114                                              "generic",
115                                              omapi_generic_set_value,
116                                              omapi_generic_get_value,
117                                              omapi_generic_destroy,
118                                              omapi_generic_signal_handler,
119                                              omapi_generic_stuff_values,
120                                              0, 0, 0, 0, 0, 0,
121                                              sizeof (omapi_generic_object_t),
122                                              0, RC_MISC);
123         if (status != ISC_R_SUCCESS)
124                 return status;
125
126         status = omapi_object_type_register (&omapi_type_protocol,
127                                              "protocol",
128                                              omapi_protocol_set_value,
129                                              omapi_protocol_get_value,
130                                              omapi_protocol_destroy,
131                                              omapi_protocol_signal_handler,
132                                              omapi_protocol_stuff_values,
133                                              0, 0, 0, 0, 0, 0,
134                                              sizeof (omapi_protocol_object_t),
135                                              0, RC_MISC);
136         if (status != ISC_R_SUCCESS)
137                 return status;
138
139         status = (omapi_object_type_register
140                   (&omapi_type_protocol_listener, "protocol-listener",
141                    omapi_protocol_listener_set_value,
142                    omapi_protocol_listener_get_value,
143                    omapi_protocol_listener_destroy,
144                    omapi_protocol_listener_signal,
145                    omapi_protocol_listener_stuff,
146                    0, 0, 0, 0, 0, 0,
147                    sizeof (omapi_protocol_listener_object_t), 0, RC_MISC));
148         if (status != ISC_R_SUCCESS)
149                 return status;
150
151         status = omapi_object_type_register (&omapi_type_message,
152                                              "message",
153                                              omapi_message_set_value,
154                                              omapi_message_get_value,
155                                              omapi_message_destroy,
156                                              omapi_message_signal_handler,
157                                              omapi_message_stuff_values,
158                                              0, 0, 0, 0, 0, 0,
159                                              sizeof (omapi_message_object_t),
160                                              0, RC_MISC);
161         if (status != ISC_R_SUCCESS)
162                 return status;
163
164         status = omapi_object_type_register (&omapi_type_waiter,
165                                              "waiter",
166                                              0,
167                                              0,
168                                              0,
169                                              omapi_waiter_signal_handler, 0,
170                                              0, 0, 0, 0, 0, 0,
171                                              sizeof (omapi_waiter_object_t),
172                                              0, RC_MISC);
173         if (status != ISC_R_SUCCESS)
174                 return status;
175
176         status = omapi_object_type_register (&omapi_type_auth_key,
177                                              "authenticator",
178                                              0,
179                                              omapi_auth_key_get_value,
180                                              omapi_auth_key_destroy,
181                                              0,
182                                              omapi_auth_key_stuff_values,
183                                              omapi_auth_key_lookup,
184                                              0, 0, 0, 0, 0,
185                                              sizeof (omapi_auth_key_t), 0,
186                                              RC_MISC);
187         if (status != ISC_R_SUCCESS)
188                 return status;
189
190 #if defined (TRACING)
191         omapi_listener_trace_setup ();
192         omapi_connection_trace_setup ();
193         omapi_buffer_trace_setup ();
194 #endif
195
196         /* This seems silly, but leave it. */
197         return ISC_R_SUCCESS;
198 }
199
200 isc_result_t omapi_object_type_register (omapi_object_type_t **type,
201                                          const char *name,
202                                          isc_result_t (*set_value)
203                                                  (omapi_object_t *,
204                                                   omapi_object_t *,
205                                                   omapi_data_string_t *,
206                                                   omapi_typed_data_t *),
207                                          isc_result_t (*get_value)
208                                                 (omapi_object_t *,
209                                                  omapi_object_t *,
210                                                  omapi_data_string_t *,
211                                                  omapi_value_t **),
212                                          isc_result_t (*destroy)
213                                                 (omapi_object_t *,
214                                                  const char *, int),
215                                          isc_result_t (*signal_handler)
216                                                  (omapi_object_t *,
217                                                   const char *, va_list),
218                                          isc_result_t (*stuff_values)
219                                                 (omapi_object_t *,
220                                                  omapi_object_t *,
221                                                  omapi_object_t *),
222                                          isc_result_t (*lookup)
223                                                 (omapi_object_t **,
224                                                  omapi_object_t *,
225                                                  omapi_object_t *),
226                                          isc_result_t (*create)
227                                                 (omapi_object_t **,
228                                                  omapi_object_t *),
229                                          isc_result_t (*remove)
230                                                 (omapi_object_t *,
231                                                  omapi_object_t *),
232                                          isc_result_t (*freer)
233                                                 (omapi_object_t *,
234                                                  const char *, int),
235                                          isc_result_t (*allocator)
236                                                 (omapi_object_t **,
237                                                  const char *, int),
238                                          isc_result_t (*sizer) (size_t),
239                                          size_t size,
240                                          isc_result_t (*initialize)
241                                                 (omapi_object_t *,
242                                                  const char *, int),
243                                          int rc_flag)
244 {
245         omapi_object_type_t *t;
246
247         t = dmalloc (sizeof *t, MDL);
248         if (!t)
249                 return ISC_R_NOMEMORY;
250         memset (t, 0, sizeof *t);
251
252         t -> name = name;
253         t -> set_value = set_value;
254         t -> get_value = get_value;
255         t -> destroy = destroy;
256         t -> signal_handler = signal_handler;
257         t -> stuff_values = stuff_values;
258         t -> lookup = lookup;
259         t -> create = create;
260         t -> remove = remove;
261         t -> next = omapi_object_types;
262         t -> sizer = sizer;
263         t -> size = size;
264         t -> freer = freer;
265         t -> allocator = allocator;
266         t -> initialize = initialize;
267         t -> rc_flag = rc_flag;
268         omapi_object_types = t;
269         if (type)
270                 *type = t;
271         return ISC_R_SUCCESS;
272 }
273
274 isc_result_t omapi_signal (omapi_object_t *handle, const char *name, ...)
275 {
276         va_list ap;
277         omapi_object_t *outer;
278         isc_result_t status;
279
280         va_start (ap, name);
281         for (outer = handle; outer -> outer; outer = outer -> outer)
282                 ;
283         if (outer -> type -> signal_handler)
284                 status = (*(outer -> type -> signal_handler)) (outer,
285                                                                name, ap);
286         else
287                 status = ISC_R_NOTFOUND;
288         va_end (ap);
289         return status;
290 }
291
292 isc_result_t omapi_signal_in (omapi_object_t *handle, const char *name, ...)
293 {
294         va_list ap;
295         isc_result_t status;
296
297         if (!handle)
298                 return ISC_R_NOTFOUND;
299         va_start (ap, name);
300
301         if (handle -> type -> signal_handler)
302                 status = (*(handle -> type -> signal_handler)) (handle,
303                                                                 name, ap);
304         else
305                 status = ISC_R_NOTFOUND;
306         va_end (ap);
307         return status;
308 }
309
310 isc_result_t omapi_set_value (omapi_object_t *h,
311                               omapi_object_t *id,
312                               omapi_data_string_t *name,
313                               omapi_typed_data_t *value)
314 {
315         omapi_object_t *outer;
316         isc_result_t status;
317
318 #if defined (DEBUG)
319         if (!value) {
320                 log_info ("omapi_set_value (%.*s, NULL)",
321                           (int)name -> len, name -> value);
322         } else if (value -> type == omapi_datatype_int) {
323                 log_info ("omapi_set_value (%.*s, %ld)",
324                           (int)name -> len, name -> value,
325                           (long)value -> u.integer);
326         } else if (value -> type == omapi_datatype_string) {
327                 log_info ("omapi_set_value (%.*s, %.*s)",
328                           (int)name -> len, name -> value,
329                           (int)value -> u.buffer.len, value -> u.buffer.value);
330         } else if (value -> type == omapi_datatype_data) {
331                 log_info ("omapi_set_value (%.*s, %ld %lx)",
332                           (int)name -> len, name -> value,
333                           (long)value -> u.buffer.len,
334                           (unsigned long)value -> u.buffer.value);
335         } else if (value -> type == omapi_datatype_object) {
336                 log_info ("omapi_set_value (%.*s, %s)",
337                           (int)name -> len, name -> value,
338                           value -> u.object
339                           ? (value -> u.object -> type
340                              ? value -> u.object -> type -> name
341                              : "(unknown object)")
342                           : "(unknown object)");
343         }
344 #endif
345
346         for (outer = h; outer -> outer; outer = outer -> outer)
347                 ;
348         if (outer -> type -> set_value)
349                 status = (*(outer -> type -> set_value)) (outer,
350                                                           id, name, value);
351         else
352                 status = ISC_R_NOTFOUND;
353 #if defined (DEBUG)
354         log_info (" ==> %s", isc_result_totext (status));
355 #endif
356         return status;
357 }
358
359 isc_result_t omapi_set_value_str (omapi_object_t *h,
360                                   omapi_object_t *id,
361                                   const char *name,
362                                   omapi_typed_data_t *value)
363 {
364         omapi_data_string_t *nds;
365         isc_result_t status;
366
367         nds = (omapi_data_string_t *)0;
368         status = omapi_data_string_new (&nds, strlen (name), MDL);
369         if (status != ISC_R_SUCCESS)
370                 return status;
371         memcpy (nds -> value, name, strlen (name));
372
373         status = omapi_set_value (h, id, nds, value);
374         omapi_data_string_dereference (&nds, MDL);
375         return status;
376 }
377
378 isc_result_t omapi_set_boolean_value (omapi_object_t *h, omapi_object_t *id,
379                                       const char *name, int value)
380 {
381         isc_result_t status;
382         omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
383         omapi_data_string_t *n = (omapi_data_string_t *)0;
384
385         status = omapi_data_string_new (&n, strlen (name), MDL);
386         if (status != ISC_R_SUCCESS)
387                 return status;
388         memcpy (n -> value, name, strlen (name));
389
390         status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
391         if (status != ISC_R_SUCCESS) {
392                 omapi_data_string_dereference (&n, MDL);
393                 return status;
394         }
395
396         status = omapi_set_value (h, id, n, tv);
397         omapi_data_string_dereference (&n, MDL);
398         omapi_typed_data_dereference (&tv, MDL);
399         return status;
400 }
401
402 isc_result_t omapi_set_int_value (omapi_object_t *h, omapi_object_t *id,
403                                   const char *name, int value)
404 {
405         isc_result_t status;
406         omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
407         omapi_data_string_t *n = (omapi_data_string_t *)0;
408
409         status = omapi_data_string_new (&n, strlen (name), MDL);
410         if (status != ISC_R_SUCCESS)
411                 return status;
412         memcpy (n -> value, name, strlen (name));
413
414         status = omapi_typed_data_new (MDL, &tv, omapi_datatype_int, value);
415         if (status != ISC_R_SUCCESS) {
416                 omapi_data_string_dereference (&n, MDL);
417                 return status;
418         }
419
420         status = omapi_set_value (h, id, n, tv);
421         omapi_data_string_dereference (&n, MDL);
422         omapi_typed_data_dereference (&tv, MDL);
423         return status;
424 }
425
426 isc_result_t omapi_set_object_value (omapi_object_t *h, omapi_object_t *id,
427                                      const char *name, omapi_object_t *value)
428 {
429         isc_result_t status;
430         omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
431         omapi_data_string_t *n = (omapi_data_string_t *)0;
432
433         status = omapi_data_string_new (&n, strlen (name), MDL);
434         if (status != ISC_R_SUCCESS)
435                 return status;
436         memcpy (n -> value, name, strlen (name));
437
438         status = omapi_typed_data_new (MDL, &tv, omapi_datatype_object, value);
439         if (status != ISC_R_SUCCESS) {
440                 omapi_data_string_dereference (&n, MDL);
441                 return status;
442         }
443
444         status = omapi_set_value (h, id, n, tv);
445         omapi_data_string_dereference (&n, MDL);
446         omapi_typed_data_dereference (&tv, MDL);
447         return status;
448 }
449
450 isc_result_t omapi_set_string_value (omapi_object_t *h, omapi_object_t *id,
451                                      const char *name, const char *value)
452 {
453         isc_result_t status;
454         omapi_typed_data_t *tv = (omapi_typed_data_t *)0;
455         omapi_data_string_t *n = (omapi_data_string_t *)0;
456
457         status = omapi_data_string_new (&n, strlen (name), MDL);
458         if (status != ISC_R_SUCCESS)
459                 return status;
460         memcpy (n -> value, name, strlen (name));
461
462         status = omapi_typed_data_new (MDL, &tv, omapi_datatype_string, value);
463         if (status != ISC_R_SUCCESS) {
464                 omapi_data_string_dereference (&n, MDL);
465                 return status;
466         }
467
468         status = omapi_set_value (h, id, n, tv);
469         omapi_data_string_dereference (&n, MDL);
470         omapi_typed_data_dereference (&tv, MDL);
471         return status;
472 }
473
474 isc_result_t omapi_get_value (omapi_object_t *h,
475                               omapi_object_t *id,
476                               omapi_data_string_t *name,
477                               omapi_value_t **value)
478 {
479         omapi_object_t *outer;
480
481         for (outer = h; outer -> outer; outer = outer -> outer)
482                 ;
483         if (outer -> type -> get_value)
484                 return (*(outer -> type -> get_value)) (outer,
485                                                         id, name, value);
486         return ISC_R_NOTFOUND;
487 }
488
489 isc_result_t omapi_get_value_str (omapi_object_t *h,
490                                   omapi_object_t *id,
491                                   const char *name,
492                                   omapi_value_t **value)
493 {
494         omapi_object_t *outer;
495         omapi_data_string_t *nds;
496         isc_result_t status;
497
498         nds = (omapi_data_string_t *)0;
499         status = omapi_data_string_new (&nds, strlen (name), MDL);
500         if (status != ISC_R_SUCCESS)
501                 return status;
502         memcpy (nds -> value, name, strlen (name));
503
504         for (outer = h; outer -> outer; outer = outer -> outer)
505                 ;
506         if (outer -> type -> get_value)
507                 status = (*(outer -> type -> get_value)) (outer,
508                                                           id, nds, value);
509         else
510                 status = ISC_R_NOTFOUND;
511         omapi_data_string_dereference (&nds, MDL);
512         return status;
513 }
514
515 isc_result_t omapi_stuff_values (omapi_object_t *c,
516                                  omapi_object_t *id,
517                                  omapi_object_t *o)
518 {
519         omapi_object_t *outer;
520
521         for (outer = o; outer -> outer; outer = outer -> outer)
522                 ;
523         if (outer -> type -> stuff_values)
524                 return (*(outer -> type -> stuff_values)) (c, id, outer);
525         return ISC_R_NOTFOUND;
526 }
527
528 isc_result_t omapi_object_create (omapi_object_t **obj, omapi_object_t *id,
529                                   omapi_object_type_t *type)
530 {
531         if (!type -> create)
532                 return ISC_R_NOTIMPLEMENTED;
533         return (*(type -> create)) (obj, id);
534 }
535
536 isc_result_t omapi_object_update (omapi_object_t *obj, omapi_object_t *id,
537                                   omapi_object_t *src, omapi_handle_t handle)
538 {
539         omapi_generic_object_t *gsrc;
540         isc_result_t status;
541         int i;
542
543         if (!src)
544                 return DHCP_R_INVALIDARG;
545         if (src -> type != omapi_type_generic)
546                 return ISC_R_NOTIMPLEMENTED;
547         gsrc = (omapi_generic_object_t *)src;
548         for (i = 0; i < gsrc -> nvalues; i++) {
549                 status = omapi_set_value (obj, id,
550                                           gsrc -> values [i] -> name,
551                                           gsrc -> values [i] -> value);
552                 if (status != ISC_R_SUCCESS && status != DHCP_R_UNCHANGED)
553                         return status;
554         }
555         if (handle)
556                 omapi_set_int_value (obj, id, "remote-handle", (int)handle);
557         status = omapi_signal (obj, "updated");
558         if (status != ISC_R_NOTFOUND)
559                 return status;
560         return ISC_R_SUCCESS;
561 }
562
563 int omapi_data_string_cmp (omapi_data_string_t *s1, omapi_data_string_t *s2)
564 {
565         unsigned len;
566         int rv;
567
568         if (s1 -> len > s2 -> len)
569                 len = s2 -> len;
570         else
571                 len = s1 -> len;
572         rv = memcmp (s1 -> value, s2 -> value, len);
573         if (rv)
574                 return rv;
575         if (s1 -> len > s2 -> len)
576                 return 1;
577         else if (s1 -> len < s2 -> len)
578                 return -1;
579         return 0;
580 }
581
582 int omapi_ds_strcmp (omapi_data_string_t *s1, const char *s2)
583 {
584         unsigned len, slen;
585         int rv;
586
587         slen = strlen (s2);
588         if (slen > s1 -> len)
589                 len = s1 -> len;
590         else
591                 len = slen;
592         rv = memcmp (s1 -> value, s2, len);
593         if (rv)
594                 return rv;
595         if (s1 -> len > slen)
596                 return 1;
597         else if (s1 -> len < slen)
598                 return -1;
599         return 0;
600 }
601
602 int omapi_td_strcmp (omapi_typed_data_t *s1, const char *s2)
603 {
604         unsigned len, slen;
605         int rv;
606
607         /* If the data type is not compatible, never equal. */
608         if (s1 -> type != omapi_datatype_data &&
609             s1 -> type != omapi_datatype_string)
610                 return -1;
611
612         slen = strlen (s2);
613         if (slen > s1 -> u.buffer.len)
614                 len = s1 -> u.buffer.len;
615         else
616                 len = slen;
617         rv = memcmp (s1 -> u.buffer.value, s2, len);
618         if (rv)
619                 return rv;
620         if (s1 -> u.buffer.len > slen)
621                 return 1;
622         else if (s1 -> u.buffer.len < slen)
623                 return -1;
624         return 0;
625 }
626
627 int omapi_td_strcasecmp (omapi_typed_data_t *s1, const char *s2)
628 {
629         unsigned len, slen;
630         int rv;
631
632         /* If the data type is not compatible, never equal. */
633         if (s1 -> type != omapi_datatype_data &&
634             s1 -> type != omapi_datatype_string)
635                 return -1;
636
637         slen = strlen (s2);
638         if (slen > s1 -> u.buffer.len)
639                 len = s1 -> u.buffer.len;
640         else
641                 len = slen;
642         rv = casecmp (s1 -> u.buffer.value, s2, len);
643         if (rv)
644                 return rv;
645         if (s1 -> u.buffer.len > slen)
646                 return 1;
647         else if (s1 -> u.buffer.len < slen)
648                 return -1;
649         return 0;
650 }
651
652 isc_result_t omapi_make_value (omapi_value_t **vp,
653                                omapi_data_string_t *name,
654                                omapi_typed_data_t *value,
655                                const char *file, int line)
656 {
657         isc_result_t status;
658
659         status = omapi_value_new (vp, file, line);
660         if (status != ISC_R_SUCCESS)
661                 return status;
662
663         status = omapi_data_string_reference (&(*vp) -> name,
664                                               name, file, line);
665         if (status != ISC_R_SUCCESS) {
666                 omapi_value_dereference (vp, file, line);
667                 return status;
668         }
669         if (value) {
670                 status = omapi_typed_data_reference (&(*vp) -> value,
671                                                      value, file, line);
672                 if (status != ISC_R_SUCCESS) {
673                         omapi_value_dereference (vp, file, line);
674                         return status;
675                 }
676         }
677         return ISC_R_SUCCESS;
678 }
679
680 isc_result_t omapi_make_const_value (omapi_value_t **vp,
681                                      omapi_data_string_t *name,
682                                      const unsigned char *value,
683                                      unsigned len,
684                                      const char *file, int line)
685 {
686         isc_result_t status;
687
688         status = omapi_value_new (vp, file, line);
689         if (status != ISC_R_SUCCESS)
690                 return status;
691
692         status = omapi_data_string_reference (&(*vp) -> name,
693                                               name, file, line);
694         if (status != ISC_R_SUCCESS) {
695                 omapi_value_dereference (vp, file, line);
696                 return status;
697         }
698         if (value) {
699                 status = omapi_typed_data_new (file, line, &(*vp) -> value,
700                                                omapi_datatype_data, len);
701                 if (status != ISC_R_SUCCESS) {
702                         omapi_value_dereference (vp, file, line);
703                         return status;
704                 }
705                 memcpy ((*vp) -> value -> u.buffer.value, value, len);
706         }
707         return ISC_R_SUCCESS;
708 }
709
710 isc_result_t omapi_make_int_value (omapi_value_t **vp,
711                                    omapi_data_string_t *name,
712                                    int value, const char *file, int line)
713 {
714         isc_result_t status;
715
716         status = omapi_value_new (vp, file, line);
717         if (status != ISC_R_SUCCESS)
718                 return status;
719
720         status = omapi_data_string_reference (&(*vp) -> name,
721                                               name, file, line);
722         if (status != ISC_R_SUCCESS) {
723                 omapi_value_dereference (vp, file, line);
724                 return status;
725         }
726         status = omapi_typed_data_new (file, line, &(*vp) -> value,
727                                        omapi_datatype_int, value);
728         if (status != ISC_R_SUCCESS) {
729                 omapi_value_dereference (vp, file, line);
730                 return status;
731         }
732         return ISC_R_SUCCESS;
733 }
734
735 isc_result_t omapi_make_uint_value (omapi_value_t **vp,
736                                     omapi_data_string_t *name,
737                                     unsigned int value,
738                                     const char *file, int line)
739 {
740         return omapi_make_int_value (vp, name, (int)value, file, line);
741 }
742
743 isc_result_t omapi_make_object_value (omapi_value_t **vp,
744                                       omapi_data_string_t *name,
745                                       omapi_object_t *value,
746                                       const char *file, int line)
747 {
748         isc_result_t status;
749         
750         status = omapi_value_new (vp, file, line);
751         if (status != ISC_R_SUCCESS)
752                 return status;
753         
754         status = omapi_data_string_reference (&(*vp) -> name,
755                                               name, file, line);
756         if (status != ISC_R_SUCCESS) {
757                 omapi_value_dereference (vp, file, line);
758                 return status;
759         }
760         
761         if (value) {
762                 status = omapi_typed_data_new (file, line, &(*vp) -> value,
763                                                omapi_datatype_object, value);
764                 if (status != ISC_R_SUCCESS) {
765                         omapi_value_dereference (vp, file, line);
766                         return status;
767                 }
768         }
769         
770         return ISC_R_SUCCESS;
771 }
772
773 isc_result_t omapi_make_handle_value (omapi_value_t **vp,
774                                       omapi_data_string_t *name,
775                                       omapi_object_t *value,
776                                       const char *file, int line)
777 {
778         isc_result_t status;
779
780         status = omapi_value_new (vp, file, line);
781         if (status != ISC_R_SUCCESS)
782                 return status;
783
784         status = omapi_data_string_reference (&(*vp) -> name,
785                                               name, file, line);
786         if (status != ISC_R_SUCCESS) {
787                 omapi_value_dereference (vp, file, line);
788                 return status;
789         }
790         if (value) {
791                 status = omapi_typed_data_new (file, line, &(*vp) -> value,
792                                                omapi_datatype_int);
793                 if (status != ISC_R_SUCCESS) {
794                         omapi_value_dereference (vp, file, line);
795                         return status;
796                 }
797                 status = (omapi_object_handle
798                           ((omapi_handle_t *)&(*vp) -> value -> u.integer,
799                            value));
800                 if (status != ISC_R_SUCCESS) {
801                         omapi_value_dereference (vp, file, line);
802                         return status;
803                 }
804         }
805         return ISC_R_SUCCESS;
806 }
807
808 isc_result_t omapi_make_string_value (omapi_value_t **vp,
809                                       omapi_data_string_t *name,
810                                       const char *value,
811                                       const char *file, int line)
812 {
813         isc_result_t status;
814
815         status = omapi_value_new (vp, file, line);
816         if (status != ISC_R_SUCCESS)
817                 return status;
818
819         status = omapi_data_string_reference (&(*vp) -> name,
820                                               name, file, line);
821         if (status != ISC_R_SUCCESS) {
822                 omapi_value_dereference (vp, file, line);
823                 return status;
824         }
825         if (value) {
826                 status = omapi_typed_data_new (file, line, &(*vp) -> value,
827                                                omapi_datatype_string, value);
828                 if (status != ISC_R_SUCCESS) {
829                         omapi_value_dereference (vp, file, line);
830                         return status;
831                 }
832         }
833         return ISC_R_SUCCESS;
834 }
835
836 isc_result_t omapi_get_int_value (unsigned long *v, omapi_typed_data_t *t)
837 {
838         u_int32_t rv;
839
840         if (t -> type == omapi_datatype_int) {
841                 *v = t -> u.integer;
842                 return ISC_R_SUCCESS;
843         } else if (t -> type == omapi_datatype_string ||
844                    t -> type == omapi_datatype_data) {
845                 if (t -> u.buffer.len != sizeof (rv))
846                         return DHCP_R_INVALIDARG;
847                 memcpy (&rv, t -> u.buffer.value, sizeof rv);
848                 *v = ntohl (rv);
849                 return ISC_R_SUCCESS;
850         }
851         return DHCP_R_INVALIDARG;
852 }