Remove building with NOCRYPTO option
[minix3.git] / external / bsd / dhcp / dist / omapip / alloc.c
blob0835548f37b75fa1d0e06f14c9aa3e4aac7ac2ef
1 /* $NetBSD: alloc.c,v 1.1.1.3 2014/07/12 11:57:58 spz Exp $ */
2 /* alloc.c
4 Functions supporting memory allocation for the object management
5 protocol... */
7 /*
8 * Copyright (c) 2012,2014 by Internet Systems Consortium, Inc. ("ISC")
9 * Copyright (c) 2009-2010 by Internet Systems Consortium, Inc. ("ISC")
10 * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
11 * Copyright (c) 1999-2003 by Internet Software Consortium
13 * Permission to use, copy, modify, and distribute this software for any
14 * purpose with or without fee is hereby granted, provided that the above
15 * copyright notice and this permission notice appear in all copies.
17 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
18 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
20 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
23 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 * Internet Systems Consortium, Inc.
26 * 950 Charter Street
27 * Redwood City, CA 94063
28 * <info@isc.org>
29 * https://www.isc.org/
33 #include <sys/cdefs.h>
34 __RCSID("$NetBSD: alloc.c,v 1.1.1.3 2014/07/12 11:57:58 spz Exp $");
36 #include "dhcpd.h"
38 #include <omapip/omapip_p.h>
40 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
41 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
42 struct dmalloc_preamble *dmalloc_list;
43 unsigned long dmalloc_outstanding;
44 unsigned long dmalloc_longterm;
45 unsigned long dmalloc_generation;
46 unsigned long dmalloc_cutoff_generation;
47 #endif
49 #if defined (DEBUG_RC_HISTORY)
50 struct rc_history_entry rc_history [RC_HISTORY_MAX];
51 int rc_history_index;
52 int rc_history_count;
53 #endif
55 #if defined (DEBUG_RC_HISTORY)
56 static void print_rc_hist_entry (int);
57 #endif
59 void *
60 dmalloc(unsigned size, const char *file, int line) {
61 unsigned char *foo;
62 unsigned len;
63 void **bar;
64 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
65 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
66 int i;
67 struct dmalloc_preamble *dp;
68 #endif
70 len = size + DMDSIZE;
71 if (len < size)
72 return NULL;
74 foo = malloc(len);
76 if (!foo)
77 return NULL;
78 bar = (void *)(foo + DMDOFFSET);
79 memset (bar, 0, size);
81 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
82 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
83 dp = (struct dmalloc_preamble *)foo;
84 dp -> prev = dmalloc_list;
85 if (dmalloc_list)
86 dmalloc_list -> next = dp;
87 dmalloc_list = dp;
88 dp -> next = (struct dmalloc_preamble *)0;
89 dp -> size = size;
90 dp -> file = file;
91 dp -> line = line;
92 dp -> generation = dmalloc_generation++;
93 dmalloc_outstanding += size;
94 for (i = 0; i < DMLFSIZE; i++)
95 dp -> low_fence [i] =
96 (((unsigned long)
97 (&dp -> low_fence [i])) % 143) + 113;
98 for (i = DMDOFFSET; i < DMDSIZE; i++)
99 foo [i + size] =
100 (((unsigned long)
101 (&foo [i + size])) % 143) + 113;
102 #if defined (DEBUG_MALLOC_POOL_EXHAUSTIVELY)
103 /* Check _every_ entry in the pool! Very expensive. */
104 for (dp = dmalloc_list; dp; dp = dp -> prev) {
105 for (i = 0; i < DMLFSIZE; i++) {
106 if (dp -> low_fence [i] !=
107 (((unsigned long)
108 (&dp -> low_fence [i])) % 143) + 113)
110 log_error ("malloc fence modified: %s(%d)",
111 dp -> file, dp -> line);
112 abort ();
115 foo = (unsigned char *)dp;
116 for (i = DMDOFFSET; i < DMDSIZE; i++) {
117 if (foo [i + dp -> size] !=
118 (((unsigned long)
119 (&foo [i + dp -> size])) % 143) + 113) {
120 log_error ("malloc fence modified: %s(%d)",
121 dp -> file, dp -> line);
122 abort ();
126 #endif
127 #endif
128 #ifdef DEBUG_REFCNT_DMALLOC_FREE
129 rc_register (file, line, 0, foo + DMDOFFSET, 1, 0, RC_MALLOC);
130 #endif
131 return bar;
134 void
135 dfree(void *ptr, const char *file, int line) {
136 if (!ptr) {
137 log_error ("dfree %s(%d): free on null pointer.", file, line);
138 return;
140 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
141 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
143 unsigned char *bar = ptr;
144 struct dmalloc_preamble *dp, *cur;
145 int i;
146 bar -= DMDOFFSET;
147 cur = (struct dmalloc_preamble *)bar;
148 for (dp = dmalloc_list; dp; dp = dp -> prev)
149 if (dp == cur)
150 break;
151 if (!dp) {
152 log_error ("%s(%d): freeing unknown memory: %lx",
153 file, line, (unsigned long)cur);
154 abort ();
156 if (dp -> prev)
157 dp -> prev -> next = dp -> next;
158 if (dp -> next)
159 dp -> next -> prev = dp -> prev;
160 if (dp == dmalloc_list)
161 dmalloc_list = dp -> prev;
162 if (dp -> generation >= dmalloc_cutoff_generation)
163 dmalloc_outstanding -= dp -> size;
164 else
165 dmalloc_longterm -= dp -> size;
167 for (i = 0; i < DMLFSIZE; i++) {
168 if (dp -> low_fence [i] !=
169 (((unsigned long)
170 (&dp -> low_fence [i])) % 143) + 113)
172 log_error ("malloc fence modified: %s(%d)",
173 dp -> file, dp -> line);
174 abort ();
177 for (i = DMDOFFSET; i < DMDSIZE; i++) {
178 if (bar [i + dp -> size] !=
179 (((unsigned long)
180 (&bar [i + dp -> size])) % 143) + 113) {
181 log_error ("malloc fence modified: %s(%d)",
182 dp -> file, dp -> line);
183 abort ();
186 ptr = bar;
188 #endif
189 #ifdef DEBUG_REFCNT_DMALLOC_FREE
190 rc_register (file, line,
191 0, (unsigned char *)ptr + DMDOFFSET, 0, 1, RC_MALLOC);
192 #endif
193 free (ptr);
196 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
197 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
198 /* For allocation functions that keep their own free lists, we want to
199 account for the reuse of the memory. */
201 void
202 dmalloc_reuse(void *foo, const char *file, int line, int justref) {
203 struct dmalloc_preamble *dp;
205 /* Get the pointer to the dmalloc header. */
206 dp = foo;
207 dp--;
209 /* If we just allocated this and are now referencing it, this
210 function would almost be a no-op, except that it would
211 increment the generation count needlessly. So just return
212 in this case. */
213 if (dp -> generation == dmalloc_generation)
214 return;
216 /* If this is longterm data, and we just made reference to it,
217 don't put it on the short-term list or change its name -
218 we don't need to know about this. */
219 if (dp -> generation < dmalloc_cutoff_generation && justref)
220 return;
222 /* Take it out of the place in the allocated list where it was. */
223 if (dp -> prev)
224 dp -> prev -> next = dp -> next;
225 if (dp -> next)
226 dp -> next -> prev = dp -> prev;
227 if (dp == dmalloc_list)
228 dmalloc_list = dp -> prev;
230 /* Account for its removal. */
231 if (dp -> generation >= dmalloc_cutoff_generation)
232 dmalloc_outstanding -= dp -> size;
233 else
234 dmalloc_longterm -= dp -> size;
236 /* Now put it at the head of the list. */
237 dp -> prev = dmalloc_list;
238 if (dmalloc_list)
239 dmalloc_list -> next = dp;
240 dmalloc_list = dp;
241 dp -> next = (struct dmalloc_preamble *)0;
243 /* Change the reference location information. */
244 dp -> file = file;
245 dp -> line = line;
247 /* Increment the generation. */
248 dp -> generation = dmalloc_generation++;
250 /* Account for it. */
251 dmalloc_outstanding += dp -> size;
254 void dmalloc_dump_outstanding ()
256 static unsigned long dmalloc_cutoff_point;
257 struct dmalloc_preamble *dp;
258 #if defined(DEBUG_MALLOC_POOL)
259 unsigned char *foo;
260 int i;
261 #endif
263 if (!dmalloc_cutoff_point)
264 dmalloc_cutoff_point = dmalloc_cutoff_generation;
265 for (dp = dmalloc_list; dp; dp = dp -> prev) {
266 if (dp -> generation <= dmalloc_cutoff_point)
267 break;
268 #if defined (DEBUG_MALLOC_POOL)
269 for (i = 0; i < DMLFSIZE; i++) {
270 if (dp -> low_fence [i] !=
271 (((unsigned long)
272 (&dp -> low_fence [i])) % 143) + 113)
274 log_error ("malloc fence modified: %s(%d)",
275 dp -> file, dp -> line);
276 abort ();
279 foo = (unsigned char *)dp;
280 for (i = DMDOFFSET; i < DMDSIZE; i++) {
281 if (foo [i + dp -> size] !=
282 (((unsigned long)
283 (&foo [i + dp -> size])) % 143) + 113) {
284 log_error ("malloc fence modified: %s(%d)",
285 dp -> file, dp -> line);
286 abort ();
289 #endif
290 #if defined (DEBUG_MEMORY_LEAKAGE) || \
291 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
292 /* Don't count data that's actually on a free list
293 somewhere. */
294 if (dp -> file) {
295 #if defined (DEBUG_RC_HISTORY)
296 int i, count, inhistory = 0, noted = 0;
298 /* If we have the info, see if this is actually
299 new garbage. */
300 if (rc_history_count < RC_HISTORY_MAX) {
301 count = rc_history_count;
302 } else
303 count = RC_HISTORY_MAX;
304 i = rc_history_index - 1;
305 if (i < 0)
306 i += RC_HISTORY_MAX;
308 do {
309 if (rc_history [i].addr == dp + 1) {
310 inhistory = 1;
311 if (!noted) {
312 log_info (" %s(%d): %ld", dp -> file,
313 dp -> line, (long) dp -> size);
314 noted = 1;
316 print_rc_hist_entry (i);
317 if (!rc_history [i].refcnt)
318 break;
320 if (--i < 0)
321 i = RC_HISTORY_MAX - 1;
322 } while (count--);
323 if (!inhistory)
324 #endif
325 log_info (" %s(%d): %ld",
326 dp -> file, dp -> line,
327 (long) dp -> size);
329 #endif
331 if (dmalloc_list)
332 dmalloc_cutoff_point = dmalloc_list -> generation;
334 #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
336 #if defined (DEBUG_RC_HISTORY)
337 static void print_rc_hist_entry (int i)
339 log_info (" referenced by %s(%d)[%lx]: addr = %lx refcnt = %x",
340 rc_history [i].file, rc_history [i].line,
341 (unsigned long)rc_history [i].reference,
342 (unsigned long)rc_history [i].addr,
343 rc_history [i].refcnt);
346 void dump_rc_history (void *addr)
348 int i;
350 i = rc_history_index;
351 if (!rc_history [i].file)
352 i = 0;
353 else if (rc_history_count < RC_HISTORY_MAX) {
354 i -= rc_history_count;
355 if (i < 0)
356 i += RC_HISTORY_MAX;
358 rc_history_count = 0;
360 while (rc_history [i].file) {
361 if (!addr || addr == rc_history [i].addr)
362 print_rc_hist_entry (i);
363 ++i;
364 if (i == RC_HISTORY_MAX)
365 i = 0;
366 if (i == rc_history_index)
367 break;
370 void rc_history_next (int d)
372 #if defined (RC_HISTORY_COMPRESSION)
373 int i, j = 0, m, n = 0;
374 void *ap, *rp;
376 /* If we are decreasing the reference count, try to find the
377 entry where the reference was made and eliminate it; then
378 we can also eliminate this reference. */
379 if (d) {
380 m = rc_history_index - 1000;
381 if (m < -1)
382 m = -1;
383 ap = rc_history [rc_history_index].addr;
384 rp = rc_history [rc_history_index].reference;
385 for (i = rc_history_index - 1; i > m; i--) {
386 if (rc_history [i].addr == ap) {
387 if (rc_history [i].reference == rp) {
388 if (n > 10) {
389 for (n = i; n <= rc_history_index; n++)
390 print_rc_hist_entry (n);
391 n = 11;
393 memmove (&rc_history [i],
394 &rc_history [i + 1],
395 (unsigned)((rc_history_index - i) *
396 sizeof (struct rc_history_entry)));
397 --rc_history_count;
398 --rc_history_index;
399 for (j = i; j < rc_history_count; j++) {
400 if (rc_history [j].addr == ap)
401 --rc_history [j].refcnt;
403 if (n > 10) {
404 for (n = i; n <= rc_history_index; n++)
405 print_rc_hist_entry (n);
406 n = 11;
407 exit (0);
409 return;
414 #endif
415 if (++rc_history_index == RC_HISTORY_MAX)
416 rc_history_index = 0;
417 ++rc_history_count;
419 #endif /* DEBUG_RC_HISTORY */
421 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
422 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
423 struct caller {
424 struct dmalloc_preamble *dp;
425 int count;
428 static int dmalloc_find_entry (struct dmalloc_preamble *dp,
429 struct caller *array,
430 int min, int max)
432 int middle;
434 middle = (min + max) / 2;
435 if (middle == min)
436 return middle;
437 if (array [middle].dp -> file == dp -> file) {
438 if (array [middle].dp -> line == dp -> line)
439 return middle;
440 else if (array [middle].dp -> line < dp -> line)
441 return dmalloc_find_entry (dp, array, middle, max);
442 else
443 return dmalloc_find_entry (dp, array, 0, middle);
444 } else if (array [middle].dp -> file < dp -> file)
445 return dmalloc_find_entry (dp, array, middle, max);
446 else
447 return dmalloc_find_entry (dp, array, 0, middle);
450 void omapi_print_dmalloc_usage_by_caller ()
452 struct dmalloc_preamble *dp;
453 int ccur, cmax, i;
454 struct caller cp [1024];
456 cmax = 1024;
457 ccur = 0;
459 memset (cp, 0, sizeof cp);
460 for (dp = dmalloc_list; dp; dp = dp -> prev) {
461 i = dmalloc_find_entry (dp, cp, 0, ccur);
462 if ((i == ccur ||
463 cp [i].dp -> file != dp -> file ||
464 cp [i].dp -> line != dp -> line) &&
465 ccur == cmax) {
466 log_error ("no space for memory usage summary.");
467 return;
469 if (i == ccur) {
470 cp [ccur++].dp = dp;
471 cp [i].count = 1;
472 } else if (cp [i].dp -> file < dp -> file ||
473 (cp [i].dp -> file == dp -> file &&
474 cp [i].dp -> line < dp -> line)) {
475 if (i + 1 != ccur)
476 memmove (cp + i + 2, cp + i + 1,
477 (ccur - i) * sizeof *cp);
478 cp [i + 1].dp = dp;
479 cp [i + 1].count = 1;
480 ccur++;
481 } else if (cp [i].dp -> file != dp -> file ||
482 cp [i].dp -> line != dp -> line) {
483 memmove (cp + i + 1,
484 cp + i, (ccur - i) * sizeof *cp);
485 cp [i].dp = dp;
486 cp [i].count = 1;
487 ccur++;
488 } else
489 cp [i].count++;
490 #if 0
491 printf ("%d\t%s:%d\n", i, dp -> file, dp -> line);
492 dump_rc_history (dp + 1);
493 #endif
495 for (i = 0; i < ccur; i++) {
496 printf ("%d\t%s:%d\t%d\n", i,
497 cp [i].dp -> file, cp [i].dp -> line, cp [i].count);
498 #if defined(DUMP_RC_HISTORY)
499 dump_rc_history (cp [i].dp + 1);
500 #endif
503 #endif /* DEBUG_MEMORY_LEAKAGE || DEBUG_MALLOC_POOL */
505 isc_result_t omapi_object_allocate (omapi_object_t **o,
506 omapi_object_type_t *type,
507 size_t size,
508 const char *file, int line)
510 size_t tsize;
511 omapi_object_t *foo;
512 isc_result_t status;
514 if (type -> allocator) {
515 foo = (omapi_object_t *)0;
516 status = (*type -> allocator) (&foo, file, line);
517 tsize = type -> size;
518 } else {
519 status = ISC_R_NOMEMORY;
520 tsize = 0;
523 if (status == ISC_R_NOMEMORY) {
524 if (type -> sizer)
525 tsize = (*type -> sizer) (size);
526 else
527 tsize = type -> size;
529 /* Sanity check. */
530 if (tsize < sizeof (omapi_object_t))
531 return DHCP_R_INVALIDARG;
533 foo = dmalloc (tsize, file, line);
534 if (!foo)
535 return ISC_R_NOMEMORY;
538 status = omapi_object_initialize (foo, type, size, tsize, file, line);
539 if (status != ISC_R_SUCCESS) {
540 if (type -> freer)
541 (*type -> freer) (foo, file, line);
542 else
543 dfree (foo, file, line);
544 return status;
546 return omapi_object_reference (o, foo, file, line);
549 isc_result_t omapi_object_initialize (omapi_object_t *o,
550 omapi_object_type_t *type,
551 size_t usize, size_t psize,
552 const char *file, int line)
554 memset (o, 0, psize);
555 o -> type = type;
556 if (type -> initialize)
557 (*type -> initialize) (o, file, line);
558 return ISC_R_SUCCESS;
561 isc_result_t omapi_object_reference (omapi_object_t **r,
562 omapi_object_t *h,
563 const char *file, int line)
565 if (!h || !r)
566 return DHCP_R_INVALIDARG;
568 if (*r) {
569 #if defined (POINTER_DEBUG)
570 log_error ("%s(%d): reference store into non-null pointer!",
571 file, line);
572 abort ();
573 #else
574 return DHCP_R_INVALIDARG;
575 #endif
577 *r = h;
578 h -> refcnt++;
579 rc_register (file, line, r, h, h -> refcnt, 0, h -> type -> rc_flag);
580 return ISC_R_SUCCESS;
583 isc_result_t omapi_object_dereference (omapi_object_t **h,
584 const char *file, int line)
586 int outer_reference = 0;
587 int inner_reference = 0;
588 int handle_reference = 0;
589 int extra_references;
590 omapi_object_t *p, *hp;
592 if (!h)
593 return DHCP_R_INVALIDARG;
595 if (!*h) {
596 #if defined (POINTER_DEBUG)
597 log_error ("%s(%d): dereference of null pointer!", file, line);
598 abort ();
599 #else
600 return DHCP_R_INVALIDARG;
601 #endif
604 if ((*h) -> refcnt <= 0) {
605 #if defined (POINTER_DEBUG)
606 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
607 file, line);
608 #if defined (DEBUG_RC_HISTORY)
609 dump_rc_history (*h);
610 #endif
611 abort ();
612 #else
613 *h = 0;
614 return DHCP_R_INVALIDARG;
615 #endif
618 /* See if this object's inner object refers to it, but don't
619 count this as a reference if we're being asked to free the
620 reference from the inner object. */
621 if ((*h) -> inner && (*h) -> inner -> outer &&
622 h != &((*h) -> inner -> outer))
623 inner_reference = 1;
625 /* Ditto for the outer object. */
626 if ((*h) -> outer && (*h) -> outer -> inner &&
627 h != &((*h) -> outer -> inner))
628 outer_reference = 1;
630 /* Ditto for the outer object. The code below assumes that
631 the only reason we'd get a dereference from the handle
632 table is if this function does it - otherwise we'd have to
633 traverse the handle table to find the address where the
634 reference is stored and compare against that, and we don't
635 want to do that if we can avoid it. */
636 if ((*h) -> handle)
637 handle_reference = 1;
639 /* If we are getting rid of the last reference other than
640 references to inner and outer objects, or from the handle
641 table, then we must examine all the objects in either
642 direction to see if they hold any non-inner, non-outer,
643 non-handle-table references. If not, we need to free the
644 entire chain of objects. */
645 if ((*h) -> refcnt ==
646 inner_reference + outer_reference + handle_reference + 1) {
647 if (inner_reference || outer_reference || handle_reference) {
648 /* XXX we could check for a reference from the
649 handle table here. */
650 extra_references = 0;
651 for (p = (*h) -> inner;
652 p && !extra_references; p = p -> inner) {
653 extra_references += p -> refcnt;
654 if (p -> inner && p -> inner -> outer == p)
655 --extra_references;
656 if (p -> outer)
657 --extra_references;
658 if (p -> handle)
659 --extra_references;
661 for (p = (*h) -> outer;
662 p && !extra_references; p = p -> outer) {
663 extra_references += p -> refcnt;
664 if (p -> outer && p -> outer -> inner == p)
665 --extra_references;
666 if (p -> inner)
667 --extra_references;
668 if (p -> handle)
669 --extra_references;
671 } else
672 extra_references = 0;
674 if (!extra_references) {
675 hp = *h;
676 *h = 0;
677 hp -> refcnt--;
678 if (inner_reference)
679 omapi_object_dereference
680 (&hp -> inner, file, line);
681 if (outer_reference)
682 omapi_object_dereference
683 (&hp -> outer, file, line);
684 /* if (!hp -> type -> freer) */
685 rc_register (file, line, h, hp,
686 0, 1, hp -> type -> rc_flag);
687 if (handle_reference) {
688 if (omapi_handle_clear(hp->handle) !=
689 ISC_R_SUCCESS) {
690 log_debug("Attempt to clear null "
691 "handle pointer");
694 if (hp -> type -> destroy)
695 (*(hp -> type -> destroy)) (hp, file, line);
696 if (hp -> type -> freer)
697 (hp -> type -> freer (hp, file, line));
698 else
699 dfree (hp, file, line);
700 } else {
701 (*h) -> refcnt--;
702 /* if (!(*h) -> type -> freer) */
703 rc_register (file, line,
704 h, *h, (*h) -> refcnt, 1,
705 (*h) -> type -> rc_flag);
707 } else {
708 (*h) -> refcnt--;
709 /* if (!(*h) -> type -> freer) */
710 rc_register (file, line, h, *h, (*h) -> refcnt, 1,
711 (*h) -> type -> rc_flag);
713 *h = 0;
714 return ISC_R_SUCCESS;
717 isc_result_t omapi_buffer_new (omapi_buffer_t **h,
718 const char *file, int line)
720 omapi_buffer_t *t;
721 isc_result_t status;
723 t = (omapi_buffer_t *)dmalloc (sizeof *t, file, line);
724 if (!t)
725 return ISC_R_NOMEMORY;
726 memset (t, 0, sizeof *t);
727 status = omapi_buffer_reference (h, t, file, line);
728 if (status != ISC_R_SUCCESS)
729 dfree (t, file, line);
730 (*h) -> head = sizeof ((*h) -> buf) - 1;
731 return status;
734 isc_result_t omapi_buffer_reference (omapi_buffer_t **r,
735 omapi_buffer_t *h,
736 const char *file, int line)
738 if (!h || !r)
739 return DHCP_R_INVALIDARG;
741 if (*r) {
742 #if defined (POINTER_DEBUG)
743 log_error ("%s(%d): reference store into non-null pointer!",
744 file, line);
745 abort ();
746 #else
747 return DHCP_R_INVALIDARG;
748 #endif
750 *r = h;
751 h -> refcnt++;
752 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
753 return ISC_R_SUCCESS;
756 isc_result_t omapi_buffer_dereference (omapi_buffer_t **h,
757 const char *file, int line)
759 if (!h)
760 return DHCP_R_INVALIDARG;
762 if (!*h) {
763 #if defined (POINTER_DEBUG)
764 log_error ("%s(%d): dereference of null pointer!", file, line);
765 abort ();
766 #else
767 return DHCP_R_INVALIDARG;
768 #endif
771 if ((*h) -> refcnt <= 0) {
772 #if defined (POINTER_DEBUG)
773 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
774 file, line);
775 #if defined (DEBUG_RC_HISTORY)
776 dump_rc_history (*h);
777 #endif
778 abort ();
779 #else
780 *h = 0;
781 return DHCP_R_INVALIDARG;
782 #endif
785 --(*h) -> refcnt;
786 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
787 if ((*h) -> refcnt == 0)
788 dfree (*h, file, line);
789 *h = 0;
790 return ISC_R_SUCCESS;
793 isc_result_t omapi_typed_data_new (const char *file, int line,
794 omapi_typed_data_t **t,
795 omapi_datatype_t type, ...)
797 va_list l;
798 omapi_typed_data_t *new;
799 unsigned len;
800 unsigned val = 0;
801 int intval = 0;
802 char *s = NULL;
803 isc_result_t status;
804 omapi_object_t *obj = NULL;
806 va_start (l, type);
808 switch (type) {
809 case omapi_datatype_int:
810 len = OMAPI_TYPED_DATA_INT_LEN;
811 intval = va_arg (l, int);
812 break;
813 case omapi_datatype_string:
814 s = va_arg (l, char *);
815 val = strlen (s);
816 len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
817 if (len < val) {
818 va_end(l);
819 return DHCP_R_INVALIDARG;
821 break;
822 case omapi_datatype_data:
823 val = va_arg (l, unsigned);
824 len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
825 if (len < val) {
826 va_end(l);
827 return DHCP_R_INVALIDARG;
829 break;
830 case omapi_datatype_object:
831 len = OMAPI_TYPED_DATA_OBJECT_LEN;
832 obj = va_arg (l, omapi_object_t *);
833 break;
834 default:
835 va_end (l);
836 return DHCP_R_INVALIDARG;
838 va_end (l);
840 new = dmalloc (len, file, line);
841 if (!new)
842 return ISC_R_NOMEMORY;
843 memset (new, 0, len);
845 switch (type) {
846 case omapi_datatype_int:
847 new -> u.integer = intval;
848 break;
849 case omapi_datatype_string:
850 memcpy (new -> u.buffer.value, s, val);
851 new -> u.buffer.len = val;
852 break;
853 case omapi_datatype_data:
854 new -> u.buffer.len = val;
855 break;
856 case omapi_datatype_object:
857 status = omapi_object_reference (&new -> u.object, obj,
858 file, line);
859 if (status != ISC_R_SUCCESS) {
860 dfree (new, file, line);
861 return status;
863 break;
865 new -> type = type;
867 return omapi_typed_data_reference (t, new, file, line);
870 isc_result_t omapi_typed_data_reference (omapi_typed_data_t **r,
871 omapi_typed_data_t *h,
872 const char *file, int line)
874 if (!h || !r)
875 return DHCP_R_INVALIDARG;
877 if (*r) {
878 #if defined (POINTER_DEBUG)
879 log_error ("%s(%d): reference store into non-null pointer!", file, line);
880 abort ();
881 #else
882 return DHCP_R_INVALIDARG;
883 #endif
885 *r = h;
886 h -> refcnt++;
887 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
888 return ISC_R_SUCCESS;
891 isc_result_t omapi_typed_data_dereference (omapi_typed_data_t **h,
892 const char *file, int line)
894 if (!h)
895 return DHCP_R_INVALIDARG;
897 if (!*h) {
898 #if defined (POINTER_DEBUG)
899 log_error ("%s(%d): dereference of null pointer!", file, line);
900 abort ();
901 #else
902 return DHCP_R_INVALIDARG;
903 #endif
906 if ((*h) -> refcnt <= 0) {
907 #if defined (POINTER_DEBUG)
908 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
909 file, line);
910 #if defined (DEBUG_RC_HISTORY)
911 dump_rc_history (*h);
912 #endif
913 abort ();
914 #else
915 *h = 0;
916 return DHCP_R_INVALIDARG;
917 #endif
920 --((*h) -> refcnt);
921 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
922 if ((*h) -> refcnt <= 0 ) {
923 switch ((*h) -> type) {
924 case omapi_datatype_int:
925 case omapi_datatype_string:
926 case omapi_datatype_data:
927 default:
928 break;
929 case omapi_datatype_object:
930 omapi_object_dereference (&(*h) -> u.object,
931 file, line);
932 break;
934 dfree (*h, file, line);
936 *h = 0;
937 return ISC_R_SUCCESS;
940 isc_result_t omapi_data_string_new (omapi_data_string_t **d, unsigned len,
941 const char *file, int line)
943 omapi_data_string_t *new;
944 unsigned nlen;
946 nlen = OMAPI_DATA_STRING_EMPTY_SIZE + len;
947 if (nlen < len)
948 return DHCP_R_INVALIDARG;
949 new = dmalloc (nlen, file, line);
950 if (!new)
951 return ISC_R_NOMEMORY;
952 memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
953 new -> len = len;
954 return omapi_data_string_reference (d, new, file, line);
957 isc_result_t omapi_data_string_reference (omapi_data_string_t **r,
958 omapi_data_string_t *h,
959 const char *file, int line)
961 if (!h || !r)
962 return DHCP_R_INVALIDARG;
964 if (*r) {
965 #if defined (POINTER_DEBUG)
966 log_error ("%s(%d): reference store into non-null pointer!", file, line);
967 abort ();
968 #else
969 return DHCP_R_INVALIDARG;
970 #endif
972 *r = h;
973 h -> refcnt++;
974 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
975 return ISC_R_SUCCESS;
978 isc_result_t omapi_data_string_dereference (omapi_data_string_t **h,
979 const char *file, int line)
981 if (!h)
982 return DHCP_R_INVALIDARG;
984 if (!*h) {
985 #if defined (POINTER_DEBUG)
986 log_error ("%s(%d): dereference of null pointer!", file, line);
987 abort ();
988 #else
989 return DHCP_R_INVALIDARG;
990 #endif
993 if ((*h) -> refcnt <= 0) {
994 #if defined (POINTER_DEBUG)
995 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
996 file, line);
997 #if defined (DEBUG_RC_HISTORY)
998 dump_rc_history (*h);
999 #endif
1000 abort ();
1001 #else
1002 *h = 0;
1003 return DHCP_R_INVALIDARG;
1004 #endif
1007 --((*h) -> refcnt);
1008 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1009 if ((*h) -> refcnt <= 0 ) {
1010 dfree (*h, file, line);
1012 *h = 0;
1013 return ISC_R_SUCCESS;
1016 isc_result_t omapi_value_new (omapi_value_t **d,
1017 const char *file, int line)
1019 omapi_value_t *new;
1021 new = dmalloc (sizeof *new, file, line);
1022 if (!new)
1023 return ISC_R_NOMEMORY;
1024 memset (new, 0, sizeof *new);
1025 return omapi_value_reference (d, new, file, line);
1028 isc_result_t omapi_value_reference (omapi_value_t **r,
1029 omapi_value_t *h,
1030 const char *file, int line)
1032 if (!h || !r)
1033 return DHCP_R_INVALIDARG;
1035 if (*r) {
1036 #if defined (POINTER_DEBUG)
1037 log_error ("%s(%d): reference store into non-null pointer!",
1038 file, line);
1039 abort ();
1040 #else
1041 return DHCP_R_INVALIDARG;
1042 #endif
1044 *r = h;
1045 h -> refcnt++;
1046 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
1047 return ISC_R_SUCCESS;
1050 isc_result_t omapi_value_dereference (omapi_value_t **h,
1051 const char *file, int line)
1053 if (!h)
1054 return DHCP_R_INVALIDARG;
1056 if (!*h) {
1057 #if defined (POINTER_DEBUG)
1058 log_error ("%s(%d): dereference of null pointer!", file, line);
1059 abort ();
1060 #else
1061 return DHCP_R_INVALIDARG;
1062 #endif
1065 if ((*h) -> refcnt <= 0) {
1066 #if defined (POINTER_DEBUG)
1067 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
1068 file, line);
1069 #if defined (DEBUG_RC_HISTORY)
1070 dump_rc_history (*h);
1071 #endif
1072 abort ();
1073 #else
1074 *h = 0;
1075 return DHCP_R_INVALIDARG;
1076 #endif
1079 --((*h) -> refcnt);
1080 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1081 if ((*h) -> refcnt == 0) {
1082 if ((*h) -> name)
1083 omapi_data_string_dereference (&(*h) -> name,
1084 file, line);
1085 if ((*h) -> value)
1086 omapi_typed_data_dereference (&(*h) -> value,
1087 file, line);
1088 dfree (*h, file, line);
1090 *h = 0;
1091 return ISC_R_SUCCESS;
1094 isc_result_t omapi_addr_list_new (omapi_addr_list_t **d, unsigned count,
1095 const char *file, int line)
1097 omapi_addr_list_t *new;
1099 new = dmalloc ((count * sizeof (omapi_addr_t)) +
1100 sizeof (omapi_addr_list_t), file, line);
1101 if (!new)
1102 return ISC_R_NOMEMORY;
1103 memset (new, 0, ((count * sizeof (omapi_addr_t)) +
1104 sizeof (omapi_addr_list_t)));
1105 new -> count = count;
1106 new -> addresses = (omapi_addr_t *)(new + 1);
1107 return omapi_addr_list_reference (d, new, file, line);
1110 isc_result_t omapi_addr_list_reference (omapi_addr_list_t **r,
1111 omapi_addr_list_t *h,
1112 const char *file, int line)
1114 if (!h || !r)
1115 return DHCP_R_INVALIDARG;
1117 if (*r) {
1118 #if defined (POINTER_DEBUG)
1119 log_error ("%s(%d): reference store into non-null pointer!",
1120 file, line);
1121 abort ();
1122 #else
1123 return DHCP_R_INVALIDARG;
1124 #endif
1126 *r = h;
1127 h -> refcnt++;
1128 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
1129 return ISC_R_SUCCESS;
1132 isc_result_t omapi_addr_list_dereference (omapi_addr_list_t **h,
1133 const char *file, int line)
1135 if (!h)
1136 return DHCP_R_INVALIDARG;
1138 if (!*h) {
1139 #if defined (POINTER_DEBUG)
1140 log_error ("%s(%d): dereference of null pointer!", file, line);
1141 abort ();
1142 #else
1143 return DHCP_R_INVALIDARG;
1144 #endif
1147 if ((*h) -> refcnt <= 0) {
1148 #if defined (POINTER_DEBUG)
1149 log_error ("%s(%d): dereference of pointer with zero refcnt!",
1150 file, line);
1151 #if defined (DEBUG_RC_HISTORY)
1152 dump_rc_history (*h);
1153 #endif
1154 abort ();
1155 #else
1156 *h = 0;
1157 return DHCP_R_INVALIDARG;
1158 #endif
1161 --((*h) -> refcnt);
1162 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
1163 if ((*h) -> refcnt <= 0 ) {
1164 dfree (*h, file, line);
1166 *h = 0;
1167 return ISC_R_SUCCESS;