00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "dhcpd.h"
00033
00034 #include <omapip/omapip_p.h>
00035
00036 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
00037 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
00038 struct dmalloc_preamble *dmalloc_list;
00039 unsigned long dmalloc_outstanding;
00040 unsigned long dmalloc_longterm;
00041 unsigned long dmalloc_generation;
00042 unsigned long dmalloc_cutoff_generation;
00043 #endif
00044
00045 #if defined (DEBUG_RC_HISTORY)
00046 struct rc_history_entry rc_history [RC_HISTORY_MAX];
00047 int rc_history_index;
00048 int rc_history_count;
00049 #endif
00050
00051 #if defined (DEBUG_RC_HISTORY)
00052 static void print_rc_hist_entry (int);
00053 #endif
00054
00055 void *
00056 dmalloc(unsigned size, const char *file, int line) {
00057 unsigned char *foo;
00058 unsigned len;
00059 void **bar;
00060 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
00061 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
00062 int i;
00063 struct dmalloc_preamble *dp;
00064 #endif
00065
00066 len = size + DMDSIZE;
00067 if (len < size)
00068 return NULL;
00069
00070 foo = malloc(len);
00071
00072 if (!foo)
00073 return NULL;
00074 bar = (void *)(foo + DMDOFFSET);
00075 memset (bar, 0, size);
00076
00077 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
00078 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
00079 dp = (struct dmalloc_preamble *)foo;
00080 dp -> prev = dmalloc_list;
00081 if (dmalloc_list)
00082 dmalloc_list -> next = dp;
00083 dmalloc_list = dp;
00084 dp -> next = (struct dmalloc_preamble *)0;
00085 dp -> size = size;
00086 dp -> file = file;
00087 dp -> line = line;
00088 dp -> generation = dmalloc_generation++;
00089 dmalloc_outstanding += size;
00090 for (i = 0; i < DMLFSIZE; i++)
00091 dp -> low_fence [i] =
00092 (((unsigned long)
00093 (&dp -> low_fence [i])) % 143) + 113;
00094 for (i = DMDOFFSET; i < DMDSIZE; i++)
00095 foo [i + size] =
00096 (((unsigned long)
00097 (&foo [i + size])) % 143) + 113;
00098 #if defined (DEBUG_MALLOC_POOL_EXHAUSTIVELY)
00099
00100 for (dp = dmalloc_list; dp; dp = dp -> prev) {
00101 for (i = 0; i < DMLFSIZE; i++) {
00102 if (dp -> low_fence [i] !=
00103 (((unsigned long)
00104 (&dp -> low_fence [i])) % 143) + 113)
00105 {
00106 log_error ("malloc fence modified: %s(%d)",
00107 dp -> file, dp -> line);
00108 abort ();
00109 }
00110 }
00111 foo = (unsigned char *)dp;
00112 for (i = DMDOFFSET; i < DMDSIZE; i++) {
00113 if (foo [i + dp -> size] !=
00114 (((unsigned long)
00115 (&foo [i + dp -> size])) % 143) + 113) {
00116 log_error ("malloc fence modified: %s(%d)",
00117 dp -> file, dp -> line);
00118 abort ();
00119 }
00120 }
00121 }
00122 #endif
00123 #endif
00124 #ifdef DEBUG_REFCNT_DMALLOC_FREE
00125 rc_register (file, line, 0, foo + DMDOFFSET, 1, 0, RC_MALLOC);
00126 #endif
00127 return bar;
00128 }
00129
00130 void
00131 dfree(void *ptr, const char *file, int line) {
00132 if (!ptr) {
00133 log_error ("dfree %s(%d): free on null pointer.", file, line);
00134 return;
00135 }
00136 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
00137 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
00138 {
00139 unsigned char *bar = ptr;
00140 struct dmalloc_preamble *dp, *cur;
00141 int i;
00142 bar -= DMDOFFSET;
00143 cur = (struct dmalloc_preamble *)bar;
00144 for (dp = dmalloc_list; dp; dp = dp -> prev)
00145 if (dp == cur)
00146 break;
00147 if (!dp) {
00148 log_error ("%s(%d): freeing unknown memory: %lx",
00149 file, line, (unsigned long)cur);
00150 abort ();
00151 }
00152 if (dp -> prev)
00153 dp -> prev -> next = dp -> next;
00154 if (dp -> next)
00155 dp -> next -> prev = dp -> prev;
00156 if (dp == dmalloc_list)
00157 dmalloc_list = dp -> prev;
00158 if (dp -> generation >= dmalloc_cutoff_generation)
00159 dmalloc_outstanding -= dp -> size;
00160 else
00161 dmalloc_longterm -= dp -> size;
00162
00163 for (i = 0; i < DMLFSIZE; i++) {
00164 if (dp -> low_fence [i] !=
00165 (((unsigned long)
00166 (&dp -> low_fence [i])) % 143) + 113)
00167 {
00168 log_error ("malloc fence modified: %s(%d)",
00169 dp -> file, dp -> line);
00170 abort ();
00171 }
00172 }
00173 for (i = DMDOFFSET; i < DMDSIZE; i++) {
00174 if (bar [i + dp -> size] !=
00175 (((unsigned long)
00176 (&bar [i + dp -> size])) % 143) + 113) {
00177 log_error ("malloc fence modified: %s(%d)",
00178 dp -> file, dp -> line);
00179 abort ();
00180 }
00181 }
00182 ptr = bar;
00183 }
00184 #endif
00185 #ifdef DEBUG_REFCNT_DMALLOC_FREE
00186 rc_register (file, line,
00187 0, (unsigned char *)ptr + DMDOFFSET, 0, 1, RC_MALLOC);
00188 #endif
00189 free (ptr);
00190 }
00191
00192 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
00193 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
00194
00195
00196
00197 void
00198 dmalloc_reuse(void *foo, const char *file, int line, int justref) {
00199 struct dmalloc_preamble *dp;
00200
00201
00202 dp = foo;
00203 dp--;
00204
00205
00206
00207
00208
00209 if (dp -> generation == dmalloc_generation)
00210 return;
00211
00212
00213
00214
00215 if (dp -> generation < dmalloc_cutoff_generation && justref)
00216 return;
00217
00218
00219 if (dp -> prev)
00220 dp -> prev -> next = dp -> next;
00221 if (dp -> next)
00222 dp -> next -> prev = dp -> prev;
00223 if (dp == dmalloc_list)
00224 dmalloc_list = dp -> prev;
00225
00226
00227 if (dp -> generation >= dmalloc_cutoff_generation)
00228 dmalloc_outstanding -= dp -> size;
00229 else
00230 dmalloc_longterm -= dp -> size;
00231
00232
00233 dp -> prev = dmalloc_list;
00234 if (dmalloc_list)
00235 dmalloc_list -> next = dp;
00236 dmalloc_list = dp;
00237 dp -> next = (struct dmalloc_preamble *)0;
00238
00239
00240 dp -> file = file;
00241 dp -> line = line;
00242
00243
00244 dp -> generation = dmalloc_generation++;
00245
00246
00247 dmalloc_outstanding += dp -> size;
00248 }
00249
00250 void dmalloc_dump_outstanding ()
00251 {
00252 static unsigned long dmalloc_cutoff_point;
00253 struct dmalloc_preamble *dp;
00254 #if defined(DEBUG_MALLOC_POOL)
00255 unsigned char *foo;
00256 int i;
00257 #endif
00258
00259 if (!dmalloc_cutoff_point)
00260 dmalloc_cutoff_point = dmalloc_cutoff_generation;
00261 for (dp = dmalloc_list; dp; dp = dp -> prev) {
00262 if (dp -> generation <= dmalloc_cutoff_point)
00263 break;
00264 #if defined (DEBUG_MALLOC_POOL)
00265 for (i = 0; i < DMLFSIZE; i++) {
00266 if (dp -> low_fence [i] !=
00267 (((unsigned long)
00268 (&dp -> low_fence [i])) % 143) + 113)
00269 {
00270 log_error ("malloc fence modified: %s(%d)",
00271 dp -> file, dp -> line);
00272 abort ();
00273 }
00274 }
00275 foo = (unsigned char *)dp;
00276 for (i = DMDOFFSET; i < DMDSIZE; i++) {
00277 if (foo [i + dp -> size] !=
00278 (((unsigned long)
00279 (&foo [i + dp -> size])) % 143) + 113) {
00280 log_error ("malloc fence modified: %s(%d)",
00281 dp -> file, dp -> line);
00282 abort ();
00283 }
00284 }
00285 #endif
00286 #if defined (DEBUG_MEMORY_LEAKAGE) || \
00287 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
00288
00289
00290 if (dp -> file) {
00291 #if defined (DEBUG_RC_HISTORY)
00292 int i, count, inhistory = 0, noted = 0;
00293
00294
00295
00296 if (rc_history_count < RC_HISTORY_MAX) {
00297 count = rc_history_count;
00298 } else
00299 count = RC_HISTORY_MAX;
00300 i = rc_history_index - 1;
00301 if (i < 0)
00302 i += RC_HISTORY_MAX;
00303
00304 do {
00305 if (rc_history [i].addr == dp + 1) {
00306 inhistory = 1;
00307 if (!noted) {
00308 log_info (" %s(%d): %ld", dp -> file,
00309 dp -> line, (long) dp -> size);
00310 noted = 1;
00311 }
00312 print_rc_hist_entry (i);
00313 if (!rc_history [i].refcnt)
00314 break;
00315 }
00316 if (--i < 0)
00317 i = RC_HISTORY_MAX - 1;
00318 } while (count--);
00319 if (!inhistory)
00320 #endif
00321 log_info (" %s(%d): %ld",
00322 dp -> file, dp -> line,
00323 (long) dp -> size);
00324 }
00325 #endif
00326 }
00327 if (dmalloc_list)
00328 dmalloc_cutoff_point = dmalloc_list -> generation;
00329 }
00330 #endif
00331
00332 #if defined (DEBUG_RC_HISTORY)
00333 static void print_rc_hist_entry (int i)
00334 {
00335 log_info (" referenced by %s(%d)[%lx]: addr = %lx refcnt = %x",
00336 rc_history [i].file, rc_history [i].line,
00337 (unsigned long)rc_history [i].reference,
00338 (unsigned long)rc_history [i].addr,
00339 rc_history [i].refcnt);
00340 }
00341
00342 void dump_rc_history (void *addr)
00343 {
00344 int i;
00345
00346 i = rc_history_index;
00347 if (!rc_history [i].file)
00348 i = 0;
00349 else if (rc_history_count < RC_HISTORY_MAX) {
00350 i -= rc_history_count;
00351 if (i < 0)
00352 i += RC_HISTORY_MAX;
00353 }
00354 rc_history_count = 0;
00355
00356 while (rc_history [i].file) {
00357 if (!addr || addr == rc_history [i].addr)
00358 print_rc_hist_entry (i);
00359 ++i;
00360 if (i == RC_HISTORY_MAX)
00361 i = 0;
00362 if (i == rc_history_index)
00363 break;
00364 }
00365 }
00366 void rc_history_next (int d)
00367 {
00368 #if defined (RC_HISTORY_COMPRESSION)
00369 int i, j = 0, m, n = 0;
00370 void *ap, *rp;
00371
00372
00373
00374
00375 if (d) {
00376 m = rc_history_index - 1000;
00377 if (m < -1)
00378 m = -1;
00379 ap = rc_history [rc_history_index].addr;
00380 rp = rc_history [rc_history_index].reference;
00381 for (i = rc_history_index - 1; i > m; i--) {
00382 if (rc_history [i].addr == ap) {
00383 if (rc_history [i].reference == rp) {
00384 if (n > 10) {
00385 for (n = i; n <= rc_history_index; n++)
00386 print_rc_hist_entry (n);
00387 n = 11;
00388 }
00389 memmove (&rc_history [i],
00390 &rc_history [i + 1],
00391 (unsigned)((rc_history_index - i) *
00392 sizeof (struct rc_history_entry)));
00393 --rc_history_count;
00394 --rc_history_index;
00395 for (j = i; j < rc_history_count; j++) {
00396 if (rc_history [j].addr == ap)
00397 --rc_history [j].refcnt;
00398 }
00399 if (n > 10) {
00400 for (n = i; n <= rc_history_index; n++)
00401 print_rc_hist_entry (n);
00402 n = 11;
00403 exit (0);
00404 }
00405 return;
00406 }
00407 }
00408 }
00409 }
00410 #endif
00411 if (++rc_history_index == RC_HISTORY_MAX)
00412 rc_history_index = 0;
00413 ++rc_history_count;
00414 }
00415 #endif
00416
00417 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
00418 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
00419 struct caller {
00420 struct dmalloc_preamble *dp;
00421 int count;
00422 };
00423
00424 static int dmalloc_find_entry (struct dmalloc_preamble *dp,
00425 struct caller *array,
00426 int min, int max)
00427 {
00428 int middle;
00429
00430 middle = (min + max) / 2;
00431 if (middle == min)
00432 return middle;
00433 if (array [middle].dp -> file == dp -> file) {
00434 if (array [middle].dp -> line == dp -> line)
00435 return middle;
00436 else if (array [middle].dp -> line < dp -> line)
00437 return dmalloc_find_entry (dp, array, middle, max);
00438 else
00439 return dmalloc_find_entry (dp, array, 0, middle);
00440 } else if (array [middle].dp -> file < dp -> file)
00441 return dmalloc_find_entry (dp, array, middle, max);
00442 else
00443 return dmalloc_find_entry (dp, array, 0, middle);
00444 }
00445
00446 void omapi_print_dmalloc_usage_by_caller ()
00447 {
00448 struct dmalloc_preamble *dp;
00449 int ccur, cmax, i;
00450 struct caller cp [1024];
00451
00452 cmax = 1024;
00453 ccur = 0;
00454
00455 memset (cp, 0, sizeof cp);
00456 for (dp = dmalloc_list; dp; dp = dp -> prev) {
00457 i = dmalloc_find_entry (dp, cp, 0, ccur);
00458 if ((i == ccur ||
00459 cp [i].dp -> file != dp -> file ||
00460 cp [i].dp -> line != dp -> line) &&
00461 ccur == cmax) {
00462 log_error ("no space for memory usage summary.");
00463 return;
00464 }
00465 if (i == ccur) {
00466 cp [ccur++].dp = dp;
00467 cp [i].count = 1;
00468 } else if (cp [i].dp -> file < dp -> file ||
00469 (cp [i].dp -> file == dp -> file &&
00470 cp [i].dp -> line < dp -> line)) {
00471 if (i + 1 != ccur)
00472 memmove (cp + i + 2, cp + i + 1,
00473 (ccur - i) * sizeof *cp);
00474 cp [i + 1].dp = dp;
00475 cp [i + 1].count = 1;
00476 ccur++;
00477 } else if (cp [i].dp -> file != dp -> file ||
00478 cp [i].dp -> line != dp -> line) {
00479 memmove (cp + i + 1,
00480 cp + i, (ccur - i) * sizeof *cp);
00481 cp [i].dp = dp;
00482 cp [i].count = 1;
00483 ccur++;
00484 } else
00485 cp [i].count++;
00486 #if 0
00487 printf ("%d\t%s:%d\n", i, dp -> file, dp -> line);
00488 dump_rc_history (dp + 1);
00489 #endif
00490 }
00491 for (i = 0; i < ccur; i++) {
00492 printf ("%d\t%s:%d\t%d\n", i,
00493 cp [i].dp -> file, cp [i].dp -> line, cp [i].count);
00494 #if defined(DUMP_RC_HISTORY)
00495 dump_rc_history (cp [i].dp + 1);
00496 #endif
00497 }
00498 }
00499 #endif
00500
00501 isc_result_t omapi_object_allocate (omapi_object_t **o,
00502 omapi_object_type_t *type,
00503 size_t size,
00504 const char *file, int line)
00505 {
00506 size_t tsize;
00507 omapi_object_t *foo;
00508 isc_result_t status;
00509
00510 if (type -> allocator) {
00511 foo = (omapi_object_t *)0;
00512 status = (*type -> allocator) (&foo, file, line);
00513 tsize = type -> size;
00514 } else {
00515 status = ISC_R_NOMEMORY;
00516 tsize = 0;
00517 }
00518
00519 if (status == ISC_R_NOMEMORY) {
00520 if (type -> sizer)
00521 tsize = (*type -> sizer) (size);
00522 else
00523 tsize = type -> size;
00524
00525
00526 if (tsize < sizeof (omapi_object_t))
00527 return DHCP_R_INVALIDARG;
00528
00529 foo = dmalloc (tsize, file, line);
00530 if (!foo)
00531 return ISC_R_NOMEMORY;
00532 }
00533
00534 status = omapi_object_initialize (foo, type, size, tsize, file, line);
00535 if (status != ISC_R_SUCCESS) {
00536 if (type -> freer)
00537 (*type -> freer) (foo, file, line);
00538 else
00539 dfree (foo, file, line);
00540 return status;
00541 }
00542 return omapi_object_reference (o, foo, file, line);
00543 }
00544
00545 isc_result_t omapi_object_initialize (omapi_object_t *o,
00546 omapi_object_type_t *type,
00547 size_t usize, size_t psize,
00548 const char *file, int line)
00549 {
00550 memset (o, 0, psize);
00551 o -> type = type;
00552 if (type -> initialize)
00553 (*type -> initialize) (o, file, line);
00554 return ISC_R_SUCCESS;
00555 }
00556
00557 isc_result_t omapi_object_reference (omapi_object_t **r,
00558 omapi_object_t *h,
00559 const char *file, int line)
00560 {
00561 if (!h || !r)
00562 return DHCP_R_INVALIDARG;
00563
00564 if (*r) {
00565 #if defined (POINTER_DEBUG)
00566 log_error ("%s(%d): reference store into non-null pointer!",
00567 file, line);
00568 abort ();
00569 #else
00570 return DHCP_R_INVALIDARG;
00571 #endif
00572 }
00573 *r = h;
00574 h -> refcnt++;
00575 rc_register (file, line, r, h, h -> refcnt, 0, h -> type -> rc_flag);
00576 return ISC_R_SUCCESS;
00577 }
00578
00579 isc_result_t omapi_object_dereference (omapi_object_t **h,
00580 const char *file, int line)
00581 {
00582 int outer_reference = 0;
00583 int inner_reference = 0;
00584 int handle_reference = 0;
00585 int extra_references;
00586 omapi_object_t *p, *hp;
00587
00588 if (!h)
00589 return DHCP_R_INVALIDARG;
00590
00591 if (!*h) {
00592 #if defined (POINTER_DEBUG)
00593 log_error ("%s(%d): dereference of null pointer!", file, line);
00594 abort ();
00595 #else
00596 return DHCP_R_INVALIDARG;
00597 #endif
00598 }
00599
00600 if ((*h) -> refcnt <= 0) {
00601 #if defined (POINTER_DEBUG)
00602 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
00603 file, line);
00604 #if defined (DEBUG_RC_HISTORY)
00605 dump_rc_history (*h);
00606 #endif
00607 abort ();
00608 #else
00609 *h = 0;
00610 return DHCP_R_INVALIDARG;
00611 #endif
00612 }
00613
00614
00615
00616
00617 if ((*h) -> inner && (*h) -> inner -> outer &&
00618 h != &((*h) -> inner -> outer))
00619 inner_reference = 1;
00620
00621
00622 if ((*h) -> outer && (*h) -> outer -> inner &&
00623 h != &((*h) -> outer -> inner))
00624 outer_reference = 1;
00625
00626
00627
00628
00629
00630
00631
00632 if ((*h) -> handle)
00633 handle_reference = 1;
00634
00635
00636
00637
00638
00639
00640
00641 if ((*h) -> refcnt ==
00642 inner_reference + outer_reference + handle_reference + 1) {
00643 if (inner_reference || outer_reference || handle_reference) {
00644
00645
00646 extra_references = 0;
00647 for (p = (*h) -> inner;
00648 p && !extra_references; p = p -> inner) {
00649 extra_references += p -> refcnt;
00650 if (p -> inner && p -> inner -> outer == p)
00651 --extra_references;
00652 if (p -> outer)
00653 --extra_references;
00654 if (p -> handle)
00655 --extra_references;
00656 }
00657 for (p = (*h) -> outer;
00658 p && !extra_references; p = p -> outer) {
00659 extra_references += p -> refcnt;
00660 if (p -> outer && p -> outer -> inner == p)
00661 --extra_references;
00662 if (p -> inner)
00663 --extra_references;
00664 if (p -> handle)
00665 --extra_references;
00666 }
00667 } else
00668 extra_references = 0;
00669
00670 if (!extra_references) {
00671 hp = *h;
00672 *h = 0;
00673 hp -> refcnt--;
00674 if (inner_reference)
00675 omapi_object_dereference
00676 (&hp -> inner, file, line);
00677 if (outer_reference)
00678 omapi_object_dereference
00679 (&hp -> outer, file, line);
00680
00681 rc_register (file, line, h, hp,
00682 0, 1, hp -> type -> rc_flag);
00683 if (handle_reference) {
00684 if (omapi_handle_clear(hp->handle) !=
00685 ISC_R_SUCCESS) {
00686 log_debug("Attempt to clear null "
00687 "handle pointer");
00688 }
00689 }
00690 if (hp -> type -> destroy)
00691 (*(hp -> type -> destroy)) (hp, file, line);
00692 if (hp -> type -> freer)
00693 (hp -> type -> freer (hp, file, line));
00694 else
00695 dfree (hp, file, line);
00696 } else {
00697 (*h) -> refcnt--;
00698
00699 rc_register (file, line,
00700 h, *h, (*h) -> refcnt, 1,
00701 (*h) -> type -> rc_flag);
00702 }
00703 } else {
00704 (*h) -> refcnt--;
00705
00706 rc_register (file, line, h, *h, (*h) -> refcnt, 1,
00707 (*h) -> type -> rc_flag);
00708 }
00709 *h = 0;
00710 return ISC_R_SUCCESS;
00711 }
00712
00713 isc_result_t omapi_buffer_new (omapi_buffer_t **h,
00714 const char *file, int line)
00715 {
00716 omapi_buffer_t *t;
00717 isc_result_t status;
00718
00719 t = (omapi_buffer_t *)dmalloc (sizeof *t, file, line);
00720 if (!t)
00721 return ISC_R_NOMEMORY;
00722 memset (t, 0, sizeof *t);
00723 status = omapi_buffer_reference (h, t, file, line);
00724 if (status != ISC_R_SUCCESS)
00725 dfree (t, file, line);
00726 (*h) -> head = sizeof ((*h) -> buf) - 1;
00727 return status;
00728 }
00729
00730 isc_result_t omapi_buffer_reference (omapi_buffer_t **r,
00731 omapi_buffer_t *h,
00732 const char *file, int line)
00733 {
00734 if (!h || !r)
00735 return DHCP_R_INVALIDARG;
00736
00737 if (*r) {
00738 #if defined (POINTER_DEBUG)
00739 log_error ("%s(%d): reference store into non-null pointer!",
00740 file, line);
00741 abort ();
00742 #else
00743 return DHCP_R_INVALIDARG;
00744 #endif
00745 }
00746 *r = h;
00747 h -> refcnt++;
00748 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
00749 return ISC_R_SUCCESS;
00750 }
00751
00752 isc_result_t omapi_buffer_dereference (omapi_buffer_t **h,
00753 const char *file, int line)
00754 {
00755 if (!h)
00756 return DHCP_R_INVALIDARG;
00757
00758 if (!*h) {
00759 #if defined (POINTER_DEBUG)
00760 log_error ("%s(%d): dereference of null pointer!", file, line);
00761 abort ();
00762 #else
00763 return DHCP_R_INVALIDARG;
00764 #endif
00765 }
00766
00767 if ((*h) -> refcnt <= 0) {
00768 #if defined (POINTER_DEBUG)
00769 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
00770 file, line);
00771 #if defined (DEBUG_RC_HISTORY)
00772 dump_rc_history (*h);
00773 #endif
00774 abort ();
00775 #else
00776 *h = 0;
00777 return DHCP_R_INVALIDARG;
00778 #endif
00779 }
00780
00781 --(*h) -> refcnt;
00782 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
00783 if ((*h) -> refcnt == 0)
00784 dfree (*h, file, line);
00785 *h = 0;
00786 return ISC_R_SUCCESS;
00787 }
00788
00789 isc_result_t omapi_typed_data_new (const char *file, int line,
00790 omapi_typed_data_t **t,
00791 omapi_datatype_t type, ...)
00792 {
00793 va_list l;
00794 omapi_typed_data_t *new;
00795 unsigned len;
00796 unsigned val = 0;
00797 int intval = 0;
00798 char *s = NULL;
00799 isc_result_t status;
00800 omapi_object_t *obj = NULL;
00801
00802 va_start (l, type);
00803
00804 switch (type) {
00805 case omapi_datatype_int:
00806 len = OMAPI_TYPED_DATA_INT_LEN;
00807 intval = va_arg (l, int);
00808 break;
00809 case omapi_datatype_string:
00810 s = va_arg (l, char *);
00811 val = strlen (s);
00812 len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
00813 if (len < val) {
00814 va_end(l);
00815 return DHCP_R_INVALIDARG;
00816 }
00817 break;
00818 case omapi_datatype_data:
00819 val = va_arg (l, unsigned);
00820 len = OMAPI_TYPED_DATA_NOBUFFER_LEN + val;
00821 if (len < val) {
00822 va_end(l);
00823 return DHCP_R_INVALIDARG;
00824 }
00825 break;
00826 case omapi_datatype_object:
00827 len = OMAPI_TYPED_DATA_OBJECT_LEN;
00828 obj = va_arg (l, omapi_object_t *);
00829 break;
00830 default:
00831 va_end (l);
00832 return DHCP_R_INVALIDARG;
00833 }
00834 va_end (l);
00835
00836 new = dmalloc (len, file, line);
00837 if (!new)
00838 return ISC_R_NOMEMORY;
00839 memset (new, 0, len);
00840
00841 switch (type) {
00842 case omapi_datatype_int:
00843 new -> u.integer = intval;
00844 break;
00845 case omapi_datatype_string:
00846 memcpy (new -> u.buffer.value, s, val);
00847 new -> u.buffer.len = val;
00848 break;
00849 case omapi_datatype_data:
00850 new -> u.buffer.len = val;
00851 break;
00852 case omapi_datatype_object:
00853 status = omapi_object_reference (&new -> u.object, obj,
00854 file, line);
00855 if (status != ISC_R_SUCCESS) {
00856 dfree (new, file, line);
00857 return status;
00858 }
00859 break;
00860 }
00861 new -> type = type;
00862
00863 return omapi_typed_data_reference (t, new, file, line);
00864 }
00865
00866 isc_result_t omapi_typed_data_reference (omapi_typed_data_t **r,
00867 omapi_typed_data_t *h,
00868 const char *file, int line)
00869 {
00870 if (!h || !r)
00871 return DHCP_R_INVALIDARG;
00872
00873 if (*r) {
00874 #if defined (POINTER_DEBUG)
00875 log_error ("%s(%d): reference store into non-null pointer!", file, line);
00876 abort ();
00877 #else
00878 return DHCP_R_INVALIDARG;
00879 #endif
00880 }
00881 *r = h;
00882 h -> refcnt++;
00883 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
00884 return ISC_R_SUCCESS;
00885 }
00886
00887 isc_result_t omapi_typed_data_dereference (omapi_typed_data_t **h,
00888 const char *file, int line)
00889 {
00890 if (!h)
00891 return DHCP_R_INVALIDARG;
00892
00893 if (!*h) {
00894 #if defined (POINTER_DEBUG)
00895 log_error ("%s(%d): dereference of null pointer!", file, line);
00896 abort ();
00897 #else
00898 return DHCP_R_INVALIDARG;
00899 #endif
00900 }
00901
00902 if ((*h) -> refcnt <= 0) {
00903 #if defined (POINTER_DEBUG)
00904 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
00905 file, line);
00906 #if defined (DEBUG_RC_HISTORY)
00907 dump_rc_history (*h);
00908 #endif
00909 abort ();
00910 #else
00911 *h = 0;
00912 return DHCP_R_INVALIDARG;
00913 #endif
00914 }
00915
00916 --((*h) -> refcnt);
00917 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
00918 if ((*h) -> refcnt <= 0 ) {
00919 switch ((*h) -> type) {
00920 case omapi_datatype_int:
00921 case omapi_datatype_string:
00922 case omapi_datatype_data:
00923 default:
00924 break;
00925 case omapi_datatype_object:
00926 omapi_object_dereference (&(*h) -> u.object,
00927 file, line);
00928 break;
00929 }
00930 dfree (*h, file, line);
00931 }
00932 *h = 0;
00933 return ISC_R_SUCCESS;
00934 }
00935
00936 isc_result_t omapi_data_string_new (omapi_data_string_t **d, unsigned len,
00937 const char *file, int line)
00938 {
00939 omapi_data_string_t *new;
00940 unsigned nlen;
00941
00942 nlen = OMAPI_DATA_STRING_EMPTY_SIZE + len;
00943 if (nlen < len)
00944 return DHCP_R_INVALIDARG;
00945 new = dmalloc (nlen, file, line);
00946 if (!new)
00947 return ISC_R_NOMEMORY;
00948 memset (new, 0, OMAPI_DATA_STRING_EMPTY_SIZE);
00949 new -> len = len;
00950 return omapi_data_string_reference (d, new, file, line);
00951 }
00952
00953 isc_result_t omapi_data_string_reference (omapi_data_string_t **r,
00954 omapi_data_string_t *h,
00955 const char *file, int line)
00956 {
00957 if (!h || !r)
00958 return DHCP_R_INVALIDARG;
00959
00960 if (*r) {
00961 #if defined (POINTER_DEBUG)
00962 log_error ("%s(%d): reference store into non-null pointer!", file, line);
00963 abort ();
00964 #else
00965 return DHCP_R_INVALIDARG;
00966 #endif
00967 }
00968 *r = h;
00969 h -> refcnt++;
00970 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
00971 return ISC_R_SUCCESS;
00972 }
00973
00974 isc_result_t omapi_data_string_dereference (omapi_data_string_t **h,
00975 const char *file, int line)
00976 {
00977 if (!h)
00978 return DHCP_R_INVALIDARG;
00979
00980 if (!*h) {
00981 #if defined (POINTER_DEBUG)
00982 log_error ("%s(%d): dereference of null pointer!", file, line);
00983 abort ();
00984 #else
00985 return DHCP_R_INVALIDARG;
00986 #endif
00987 }
00988
00989 if ((*h) -> refcnt <= 0) {
00990 #if defined (POINTER_DEBUG)
00991 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
00992 file, line);
00993 #if defined (DEBUG_RC_HISTORY)
00994 dump_rc_history (*h);
00995 #endif
00996 abort ();
00997 #else
00998 *h = 0;
00999 return DHCP_R_INVALIDARG;
01000 #endif
01001 }
01002
01003 --((*h) -> refcnt);
01004 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
01005 if ((*h) -> refcnt <= 0 ) {
01006 dfree (*h, file, line);
01007 }
01008 *h = 0;
01009 return ISC_R_SUCCESS;
01010 }
01011
01012 isc_result_t omapi_value_new (omapi_value_t **d,
01013 const char *file, int line)
01014 {
01015 omapi_value_t *new;
01016
01017 new = dmalloc (sizeof *new, file, line);
01018 if (!new)
01019 return ISC_R_NOMEMORY;
01020 memset (new, 0, sizeof *new);
01021 return omapi_value_reference (d, new, file, line);
01022 }
01023
01024 isc_result_t omapi_value_reference (omapi_value_t **r,
01025 omapi_value_t *h,
01026 const char *file, int line)
01027 {
01028 if (!h || !r)
01029 return DHCP_R_INVALIDARG;
01030
01031 if (*r) {
01032 #if defined (POINTER_DEBUG)
01033 log_error ("%s(%d): reference store into non-null pointer!",
01034 file, line);
01035 abort ();
01036 #else
01037 return DHCP_R_INVALIDARG;
01038 #endif
01039 }
01040 *r = h;
01041 h -> refcnt++;
01042 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
01043 return ISC_R_SUCCESS;
01044 }
01045
01046 isc_result_t omapi_value_dereference (omapi_value_t **h,
01047 const char *file, int line)
01048 {
01049 if (!h)
01050 return DHCP_R_INVALIDARG;
01051
01052 if (!*h) {
01053 #if defined (POINTER_DEBUG)
01054 log_error ("%s(%d): dereference of null pointer!", file, line);
01055 abort ();
01056 #else
01057 return DHCP_R_INVALIDARG;
01058 #endif
01059 }
01060
01061 if ((*h) -> refcnt <= 0) {
01062 #if defined (POINTER_DEBUG)
01063 log_error ("%s(%d): dereference of pointer with refcnt of zero!",
01064 file, line);
01065 #if defined (DEBUG_RC_HISTORY)
01066 dump_rc_history (*h);
01067 #endif
01068 abort ();
01069 #else
01070 *h = 0;
01071 return DHCP_R_INVALIDARG;
01072 #endif
01073 }
01074
01075 --((*h) -> refcnt);
01076 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
01077 if ((*h) -> refcnt == 0) {
01078 if ((*h) -> name)
01079 omapi_data_string_dereference (&(*h) -> name,
01080 file, line);
01081 if ((*h) -> value)
01082 omapi_typed_data_dereference (&(*h) -> value,
01083 file, line);
01084 dfree (*h, file, line);
01085 }
01086 *h = 0;
01087 return ISC_R_SUCCESS;
01088 }
01089
01090 isc_result_t omapi_addr_list_new (omapi_addr_list_t **d, unsigned count,
01091 const char *file, int line)
01092 {
01093 omapi_addr_list_t *new;
01094
01095 new = dmalloc ((count * sizeof (omapi_addr_t)) +
01096 sizeof (omapi_addr_list_t), file, line);
01097 if (!new)
01098 return ISC_R_NOMEMORY;
01099 memset (new, 0, ((count * sizeof (omapi_addr_t)) +
01100 sizeof (omapi_addr_list_t)));
01101 new -> count = count;
01102 new -> addresses = (omapi_addr_t *)(new + 1);
01103 return omapi_addr_list_reference (d, new, file, line);
01104 }
01105
01106 isc_result_t omapi_addr_list_reference (omapi_addr_list_t **r,
01107 omapi_addr_list_t *h,
01108 const char *file, int line)
01109 {
01110 if (!h || !r)
01111 return DHCP_R_INVALIDARG;
01112
01113 if (*r) {
01114 #if defined (POINTER_DEBUG)
01115 log_error ("%s(%d): reference store into non-null pointer!",
01116 file, line);
01117 abort ();
01118 #else
01119 return DHCP_R_INVALIDARG;
01120 #endif
01121 }
01122 *r = h;
01123 h -> refcnt++;
01124 rc_register (file, line, r, h, h -> refcnt, 0, RC_MISC);
01125 return ISC_R_SUCCESS;
01126 }
01127
01128 isc_result_t omapi_addr_list_dereference (omapi_addr_list_t **h,
01129 const char *file, int line)
01130 {
01131 if (!h)
01132 return DHCP_R_INVALIDARG;
01133
01134 if (!*h) {
01135 #if defined (POINTER_DEBUG)
01136 log_error ("%s(%d): dereference of null pointer!", file, line);
01137 abort ();
01138 #else
01139 return DHCP_R_INVALIDARG;
01140 #endif
01141 }
01142
01143 if ((*h) -> refcnt <= 0) {
01144 #if defined (POINTER_DEBUG)
01145 log_error ("%s(%d): dereference of pointer with zero refcnt!",
01146 file, line);
01147 #if defined (DEBUG_RC_HISTORY)
01148 dump_rc_history (*h);
01149 #endif
01150 abort ();
01151 #else
01152 *h = 0;
01153 return DHCP_R_INVALIDARG;
01154 #endif
01155 }
01156
01157 --((*h) -> refcnt);
01158 rc_register (file, line, h, *h, (*h) -> refcnt, 1, RC_MISC);
01159 if ((*h) -> refcnt <= 0 ) {
01160 dfree (*h, file, line);
01161 }
01162 *h = 0;
01163 return ISC_R_SUCCESS;
01164 }
01165