1 /* $NetBSD: alloc.c,v 1.3 2014/07/12 12:09:37 spz Exp $ */ 2 /* alloc.c 3 4 Memory allocation... */ 5 6 /* 7 * Copyright (c) 2009,2013-2014 by Internet Systems Consortium, Inc. ("ISC") 8 * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC") 9 * Copyright (c) 1996-2003 by Internet Software Consortium 10 * 11 * Permission to use, copy, modify, and distribute this software for any 12 * purpose with or without fee is hereby granted, provided that the above 13 * copyright notice and this permission notice appear in all copies. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 16 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 18 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 21 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 * 23 * Internet Systems Consortium, Inc. 24 * 950 Charter Street 25 * Redwood City, CA 94063 26 * <info@isc.org> 27 * https://www.isc.org/ 28 * 29 */ 30 31 #include <sys/cdefs.h> 32 __RCSID("$NetBSD: alloc.c,v 1.3 2014/07/12 12:09:37 spz Exp $"); 33 34 #include "dhcpd.h" 35 #include <omapip/omapip_p.h> 36 37 struct dhcp_packet *dhcp_free_list; 38 struct packet *packet_free_list; 39 40 int option_chain_head_allocate (ptr, file, line) 41 struct option_chain_head **ptr; 42 const char *file; 43 int line; 44 { 45 struct option_chain_head *h; 46 47 if (!ptr) { 48 log_error ("%s(%d): null pointer", file, line); 49 #if defined (POINTER_DEBUG) 50 abort (); 51 #else 52 return 0; 53 #endif 54 } 55 if (*ptr) { 56 log_error ("%s(%d): non-null pointer", file, line); 57 #if defined (POINTER_DEBUG) 58 abort (); 59 #else 60 *ptr = (struct option_chain_head *)0; 61 #endif 62 } 63 64 h = dmalloc (sizeof *h, file, line); 65 if (h) { 66 memset (h, 0, sizeof *h); 67 return option_chain_head_reference (ptr, h, file, line); 68 } 69 return 0; 70 } 71 72 int option_chain_head_reference (ptr, bp, file, line) 73 struct option_chain_head **ptr; 74 struct option_chain_head *bp; 75 const char *file; 76 int line; 77 { 78 if (!ptr) { 79 log_error ("%s(%d): null pointer", file, line); 80 #if defined (POINTER_DEBUG) 81 abort (); 82 #else 83 return 0; 84 #endif 85 } 86 if (*ptr) { 87 log_error ("%s(%d): non-null pointer", file, line); 88 #if defined (POINTER_DEBUG) 89 abort (); 90 #else 91 *ptr = (struct option_chain_head *)0; 92 #endif 93 } 94 *ptr = bp; 95 bp -> refcnt++; 96 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC); 97 return 1; 98 } 99 100 int option_chain_head_dereference (ptr, file, line) 101 struct option_chain_head **ptr; 102 const char *file; 103 int line; 104 { 105 struct option_chain_head *option_chain_head; 106 pair car, cdr; 107 108 if (!ptr || !*ptr) { 109 log_error ("%s(%d): null pointer", file, line); 110 #if defined (POINTER_DEBUG) 111 abort (); 112 #else 113 return 0; 114 #endif 115 } 116 117 option_chain_head = *ptr; 118 *ptr = (struct option_chain_head *)0; 119 --option_chain_head -> refcnt; 120 rc_register (file, line, ptr, option_chain_head, 121 option_chain_head -> refcnt, 1, RC_MISC); 122 if (option_chain_head -> refcnt > 0) 123 return 1; 124 125 if (option_chain_head -> refcnt < 0) { 126 log_error ("%s(%d): negative refcnt!", file, line); 127 #if defined (DEBUG_RC_HISTORY) 128 dump_rc_history (option_chain_head); 129 #endif 130 #if defined (POINTER_DEBUG) 131 abort (); 132 #else 133 return 0; 134 #endif 135 } 136 137 /* If there are any options on this head, free them. */ 138 for (car = option_chain_head -> first; car; car = cdr) { 139 cdr = car -> cdr; 140 if (car -> car) 141 option_cache_dereference ((struct option_cache **) 142 (void *)(&car -> car), MDL); 143 dfree (car, MDL); 144 } 145 146 dfree (option_chain_head, file, line); 147 return 1; 148 } 149 150 int group_allocate (ptr, file, line) 151 struct group **ptr; 152 const char *file; 153 int line; 154 { 155 struct group *g; 156 157 if (!ptr) { 158 log_error ("%s(%d): null pointer", file, line); 159 #if defined (POINTER_DEBUG) 160 abort (); 161 #else 162 return 0; 163 #endif 164 } 165 if (*ptr) { 166 log_error ("%s(%d): non-null pointer", file, line); 167 #if defined (POINTER_DEBUG) 168 abort (); 169 #else 170 *ptr = (struct group *)0; 171 #endif 172 } 173 174 g = dmalloc (sizeof *g, file, line); 175 if (g) { 176 memset (g, 0, sizeof *g); 177 return group_reference (ptr, g, file, line); 178 } 179 return 0; 180 } 181 182 int group_reference (ptr, bp, file, line) 183 struct group **ptr; 184 struct group *bp; 185 const char *file; 186 int line; 187 { 188 if (!ptr) { 189 log_error ("%s(%d): null pointer", file, line); 190 #if defined (POINTER_DEBUG) 191 abort (); 192 #else 193 return 0; 194 #endif 195 } 196 if (*ptr) { 197 log_error ("%s(%d): non-null pointer", file, line); 198 #if defined (POINTER_DEBUG) 199 abort (); 200 #else 201 *ptr = (struct group *)0; 202 #endif 203 } 204 *ptr = bp; 205 bp -> refcnt++; 206 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC); 207 return 1; 208 } 209 210 int group_dereference (ptr, file, line) 211 struct group **ptr; 212 const char *file; 213 int line; 214 { 215 struct group *group; 216 217 if (!ptr || !*ptr) { 218 log_error ("%s(%d): null pointer", file, line); 219 #if defined (POINTER_DEBUG) 220 abort (); 221 #else 222 return 0; 223 #endif 224 } 225 226 group = *ptr; 227 *ptr = (struct group *)0; 228 --group -> refcnt; 229 rc_register (file, line, ptr, group, group -> refcnt, 1, RC_MISC); 230 if (group -> refcnt > 0) 231 return 1; 232 233 if (group -> refcnt < 0) { 234 log_error ("%s(%d): negative refcnt!", file, line); 235 #if defined (DEBUG_RC_HISTORY) 236 dump_rc_history (group); 237 #endif 238 #if defined (POINTER_DEBUG) 239 abort (); 240 #else 241 return 0; 242 #endif 243 } 244 245 if (group -> object) 246 group_object_dereference (&group -> object, file, line); 247 if (group -> subnet) 248 subnet_dereference (&group -> subnet, file, line); 249 if (group -> shared_network) 250 shared_network_dereference (&group -> shared_network, 251 file, line); 252 if (group -> statements) 253 executable_statement_dereference (&group -> statements, 254 file, line); 255 if (group -> next) 256 group_dereference (&group -> next, file, line); 257 dfree (group, file, line); 258 return 1; 259 } 260 261 struct dhcp_packet *new_dhcp_packet (file, line) 262 const char *file; 263 int line; 264 { 265 struct dhcp_packet *rval; 266 rval = (struct dhcp_packet *)dmalloc (sizeof (struct dhcp_packet), 267 file, line); 268 return rval; 269 } 270 271 struct protocol *new_protocol (file, line) 272 const char *file; 273 int line; 274 { 275 struct protocol *rval = dmalloc (sizeof (struct protocol), file, line); 276 return rval; 277 } 278 279 struct domain_search_list *new_domain_search_list (file, line) 280 const char *file; 281 int line; 282 { 283 struct domain_search_list *rval = 284 dmalloc (sizeof (struct domain_search_list), file, line); 285 return rval; 286 } 287 288 struct name_server *new_name_server (file, line) 289 const char *file; 290 int line; 291 { 292 struct name_server *rval = 293 dmalloc (sizeof (struct name_server), file, line); 294 return rval; 295 } 296 297 void free_name_server (ptr, file, line) 298 struct name_server *ptr; 299 const char *file; 300 int line; 301 { 302 dfree ((void *)ptr, file, line); 303 } 304 305 struct option *new_option (name, file, line) 306 const char *name; 307 const char *file; 308 int line; 309 { 310 struct option *rval; 311 int len; 312 313 len = strlen(name); 314 315 rval = dmalloc(sizeof(struct option) + len + 1, file, line); 316 317 if(rval) { 318 memcpy(rval + 1, name, len); 319 rval->name = (char *)(rval + 1); 320 } 321 322 return rval; 323 } 324 325 struct universe *new_universe (file, line) 326 const char *file; 327 int line; 328 { 329 struct universe *rval = 330 dmalloc (sizeof (struct universe), file, line); 331 return rval; 332 } 333 334 void free_universe (ptr, file, line) 335 struct universe *ptr; 336 const char *file; 337 int line; 338 { 339 dfree ((void *)ptr, file, line); 340 } 341 342 void free_domain_search_list (ptr, file, line) 343 struct domain_search_list *ptr; 344 const char *file; 345 int line; 346 { 347 dfree ((void *)ptr, file, line); 348 } 349 350 void free_protocol (ptr, file, line) 351 struct protocol *ptr; 352 const char *file; 353 int line; 354 { 355 dfree ((void *)ptr, file, line); 356 } 357 358 void free_dhcp_packet (ptr, file, line) 359 struct dhcp_packet *ptr; 360 const char *file; 361 int line; 362 { 363 dfree ((void *)ptr, file, line); 364 } 365 366 struct client_lease *new_client_lease (file, line) 367 const char *file; 368 int line; 369 { 370 return (struct client_lease *)dmalloc (sizeof (struct client_lease), 371 file, line); 372 } 373 374 void free_client_lease (lease, file, line) 375 struct client_lease *lease; 376 const char *file; 377 int line; 378 { 379 dfree (lease, file, line); 380 } 381 382 pair free_pairs; 383 384 pair new_pair (file, line) 385 const char *file; 386 int line; 387 { 388 pair foo; 389 390 if (free_pairs) { 391 foo = free_pairs; 392 free_pairs = foo -> cdr; 393 memset (foo, 0, sizeof *foo); 394 dmalloc_reuse (foo, file, line, 0); 395 return foo; 396 } 397 398 foo = dmalloc (sizeof *foo, file, line); 399 if (!foo) 400 return foo; 401 memset (foo, 0, sizeof *foo); 402 return foo; 403 } 404 405 void free_pair (foo, file, line) 406 pair foo; 407 const char *file; 408 int line; 409 { 410 foo -> cdr = free_pairs; 411 free_pairs = foo; 412 dmalloc_reuse (free_pairs, __FILE__, __LINE__, 0); 413 } 414 415 #if defined (DEBUG_MEMORY_LEAKAGE) || \ 416 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) 417 void relinquish_free_pairs () 418 { 419 pair pf, pc; 420 421 for (pf = free_pairs; pf; pf = pc) { 422 pc = pf -> cdr; 423 dfree (pf, MDL); 424 } 425 free_pairs = (pair)0; 426 } 427 #endif 428 429 struct expression *free_expressions; 430 431 int expression_allocate (cptr, file, line) 432 struct expression **cptr; 433 const char *file; 434 int line; 435 { 436 struct expression *rval; 437 438 if (free_expressions) { 439 rval = free_expressions; 440 free_expressions = rval -> data.not; 441 dmalloc_reuse (rval, file, line, 1); 442 } else { 443 rval = dmalloc (sizeof (struct expression), file, line); 444 if (!rval) 445 return 0; 446 } 447 memset (rval, 0, sizeof *rval); 448 return expression_reference (cptr, rval, file, line); 449 } 450 451 int expression_reference (ptr, src, file, line) 452 struct expression **ptr; 453 struct expression *src; 454 const char *file; 455 int line; 456 { 457 if (!ptr) { 458 log_error ("%s(%d): null pointer", file, line); 459 #if defined (POINTER_DEBUG) 460 abort (); 461 #else 462 return 0; 463 #endif 464 } 465 if (*ptr) { 466 log_error ("%s(%d): non-null pointer", file, line); 467 #if defined (POINTER_DEBUG) 468 abort (); 469 #else 470 *ptr = (struct expression *)0; 471 #endif 472 } 473 *ptr = src; 474 src -> refcnt++; 475 rc_register (file, line, ptr, src, src -> refcnt, 0, RC_MISC); 476 return 1; 477 } 478 479 void free_expression (expr, file, line) 480 struct expression *expr; 481 const char *file; 482 int line; 483 { 484 expr -> data.not = free_expressions; 485 free_expressions = expr; 486 dmalloc_reuse (free_expressions, __FILE__, __LINE__, 0); 487 } 488 489 #if defined (DEBUG_MEMORY_LEAKAGE) || \ 490 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) 491 void relinquish_free_expressions () 492 { 493 struct expression *e, *n; 494 495 for (e = free_expressions; e; e = n) { 496 n = e -> data.not; 497 dfree (e, MDL); 498 } 499 free_expressions = (struct expression *)0; 500 } 501 #endif 502 503 struct binding_value *free_binding_values; 504 505 int binding_value_allocate (cptr, file, line) 506 struct binding_value **cptr; 507 const char *file; 508 int line; 509 { 510 struct binding_value *rval; 511 512 if (free_binding_values) { 513 rval = free_binding_values; 514 free_binding_values = rval -> value.bv; 515 dmalloc_reuse (rval, file, line, 1); 516 } else { 517 rval = dmalloc (sizeof (struct binding_value), file, line); 518 if (!rval) 519 return 0; 520 } 521 memset (rval, 0, sizeof *rval); 522 return binding_value_reference (cptr, rval, file, line); 523 } 524 525 int binding_value_reference (ptr, src, file, line) 526 struct binding_value **ptr; 527 struct binding_value *src; 528 const char *file; 529 int line; 530 { 531 if (!ptr) { 532 log_error ("%s(%d): null pointer", file, line); 533 #if defined (POINTER_DEBUG) 534 abort (); 535 #else 536 return 0; 537 #endif 538 } 539 if (*ptr) { 540 log_error ("%s(%d): non-null pointer", file, line); 541 #if defined (POINTER_DEBUG) 542 abort (); 543 #else 544 *ptr = (struct binding_value *)0; 545 #endif 546 } 547 *ptr = src; 548 src -> refcnt++; 549 rc_register (file, line, ptr, src, src -> refcnt, 0, RC_MISC); 550 return 1; 551 } 552 553 void free_binding_value (bv, file, line) 554 struct binding_value *bv; 555 const char *file; 556 int line; 557 { 558 bv -> value.bv = free_binding_values; 559 free_binding_values = bv; 560 dmalloc_reuse (free_binding_values, (char *)0, 0, 0); 561 } 562 563 #if defined (DEBUG_MEMORY_LEAKAGE) || \ 564 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) 565 void relinquish_free_binding_values () 566 { 567 struct binding_value *b, *n; 568 569 for (b = free_binding_values; b; b = n) { 570 n = b -> value.bv; 571 dfree (b, MDL); 572 } 573 free_binding_values = (struct binding_value *)0; 574 } 575 #endif 576 577 int fundef_allocate (cptr, file, line) 578 struct fundef **cptr; 579 const char *file; 580 int line; 581 { 582 struct fundef *rval; 583 584 rval = dmalloc (sizeof (struct fundef), file, line); 585 if (!rval) 586 return 0; 587 memset (rval, 0, sizeof *rval); 588 return fundef_reference (cptr, rval, file, line); 589 } 590 591 int fundef_reference (ptr, src, file, line) 592 struct fundef **ptr; 593 struct fundef *src; 594 const char *file; 595 int line; 596 { 597 if (!ptr) { 598 log_error ("%s(%d): null pointer", file, line); 599 #if defined (POINTER_DEBUG) 600 abort (); 601 #else 602 return 0; 603 #endif 604 } 605 if (*ptr) { 606 log_error ("%s(%d): non-null pointer", file, line); 607 #if defined (POINTER_DEBUG) 608 abort (); 609 #else 610 *ptr = (struct fundef *)0; 611 #endif 612 } 613 *ptr = src; 614 src -> refcnt++; 615 rc_register (file, line, ptr, src, src -> refcnt, 0, RC_MISC); 616 return 1; 617 } 618 619 struct option_cache *free_option_caches; 620 621 #if defined (DEBUG_MEMORY_LEAKAGE) || \ 622 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) 623 void relinquish_free_option_caches () 624 { 625 struct option_cache *o, *n; 626 627 for (o = free_option_caches; o; o = n) { 628 n = (struct option_cache *)(o -> expression); 629 dfree (o, MDL); 630 } 631 free_option_caches = (struct option_cache *)0; 632 } 633 #endif 634 635 int option_cache_allocate (cptr, file, line) 636 struct option_cache **cptr; 637 const char *file; 638 int line; 639 { 640 struct option_cache *rval; 641 642 if (free_option_caches) { 643 rval = free_option_caches; 644 free_option_caches = 645 (struct option_cache *)(rval -> expression); 646 dmalloc_reuse (rval, file, line, 0); 647 } else { 648 rval = dmalloc (sizeof (struct option_cache), file, line); 649 if (!rval) 650 return 0; 651 } 652 memset (rval, 0, sizeof *rval); 653 return option_cache_reference (cptr, rval, file, line); 654 } 655 656 int option_cache_reference (ptr, src, file, line) 657 struct option_cache **ptr; 658 struct option_cache *src; 659 const char *file; 660 int line; 661 { 662 if (!ptr) { 663 log_error ("%s(%d): null pointer", file, line); 664 #if defined (POINTER_DEBUG) 665 abort (); 666 #else 667 return 0; 668 #endif 669 } 670 if (*ptr) { 671 log_error ("%s(%d): non-null pointer", file, line); 672 #if defined (POINTER_DEBUG) 673 abort (); 674 #else 675 *ptr = (struct option_cache *)0; 676 #endif 677 } 678 *ptr = src; 679 src -> refcnt++; 680 rc_register (file, line, ptr, src, src -> refcnt, 0, RC_MISC); 681 return 1; 682 } 683 684 int buffer_allocate (ptr, len, file, line) 685 struct buffer **ptr; 686 unsigned len; 687 const char *file; 688 int line; 689 { 690 struct buffer *bp; 691 692 /* XXXSK: should check for bad ptr values, otherwise we 693 leak memory if they are wrong */ 694 bp = dmalloc (len + sizeof *bp, file, line); 695 if (!bp) 696 return 0; 697 /* XXXSK: both of these initializations are unnecessary */ 698 memset (bp, 0, sizeof *bp); 699 bp -> refcnt = 0; 700 return buffer_reference (ptr, bp, file, line); 701 } 702 703 int buffer_reference (ptr, bp, file, line) 704 struct buffer **ptr; 705 struct buffer *bp; 706 const char *file; 707 int line; 708 { 709 if (!ptr) { 710 log_error ("%s(%d): null pointer", file, line); 711 #if defined (POINTER_DEBUG) 712 abort (); 713 #else 714 return 0; 715 #endif 716 } 717 if (*ptr) { 718 log_error ("%s(%d): non-null pointer", file, line); 719 #if defined (POINTER_DEBUG) 720 abort (); 721 #else 722 *ptr = (struct buffer *)0; 723 #endif 724 } 725 *ptr = bp; 726 bp -> refcnt++; 727 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC); 728 return 1; 729 } 730 731 int buffer_dereference (ptr, file, line) 732 struct buffer **ptr; 733 const char *file; 734 int line; 735 { 736 if (!ptr) { 737 log_error ("%s(%d): null pointer", file, line); 738 #if defined (POINTER_DEBUG) 739 abort (); 740 #else 741 return 0; 742 #endif 743 } 744 745 if (!*ptr) { 746 log_error ("%s(%d): null pointer", file, line); 747 #if defined (POINTER_DEBUG) 748 abort (); 749 #else 750 return 0; 751 #endif 752 } 753 754 (*ptr) -> refcnt--; 755 rc_register (file, line, ptr, *ptr, (*ptr) -> refcnt, 1, RC_MISC); 756 if (!(*ptr) -> refcnt) { 757 dfree ((*ptr), file, line); 758 } else if ((*ptr) -> refcnt < 0) { 759 log_error ("%s(%d): negative refcnt!", file, line); 760 #if defined (DEBUG_RC_HISTORY) 761 dump_rc_history (*ptr); 762 #endif 763 #if defined (POINTER_DEBUG) 764 abort (); 765 #else 766 return 0; 767 #endif 768 } 769 *ptr = (struct buffer *)0; 770 return 1; 771 } 772 773 int dns_host_entry_allocate (ptr, hostname, file, line) 774 struct dns_host_entry **ptr; 775 const char *hostname; 776 const char *file; 777 int line; 778 { 779 struct dns_host_entry *bp; 780 781 bp = dmalloc (strlen (hostname) + sizeof *bp, file, line); 782 if (!bp) 783 return 0; 784 memset (bp, 0, sizeof *bp); 785 bp -> refcnt = 0; 786 strcpy (bp -> hostname, hostname); 787 return dns_host_entry_reference (ptr, bp, file, line); 788 } 789 790 int dns_host_entry_reference (ptr, bp, file, line) 791 struct dns_host_entry **ptr; 792 struct dns_host_entry *bp; 793 const char *file; 794 int line; 795 { 796 if (!ptr) { 797 log_error ("%s(%d): null pointer", file, line); 798 #if defined (POINTER_DEBUG) 799 abort (); 800 #else 801 return 0; 802 #endif 803 } 804 if (*ptr) { 805 log_error ("%s(%d): non-null pointer", file, line); 806 #if defined (POINTER_DEBUG) 807 abort (); 808 #else 809 *ptr = (struct dns_host_entry *)0; 810 #endif 811 } 812 *ptr = bp; 813 bp -> refcnt++; 814 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC); 815 return 1; 816 } 817 818 int dns_host_entry_dereference (ptr, file, line) 819 struct dns_host_entry **ptr; 820 const char *file; 821 int line; 822 { 823 if (!ptr || !*ptr) { 824 log_error ("%s(%d): null pointer", file, line); 825 #if defined (POINTER_DEBUG) 826 abort (); 827 #else 828 return 0; 829 #endif 830 } 831 832 (*ptr)->refcnt--; 833 rc_register (file, line, ptr, *ptr, (*ptr)->refcnt, 1, RC_MISC); 834 if ((*ptr)->refcnt == 0) { 835 dfree ((*ptr), file, line); 836 } else if ((*ptr)->refcnt < 0) { 837 log_error ("%s(%d): negative refcnt!", file, line); 838 #if defined (DEBUG_RC_HISTORY) 839 dump_rc_history (*ptr); 840 #endif 841 #if defined (POINTER_DEBUG) 842 abort (); 843 #else 844 return 0; 845 #endif 846 } 847 *ptr = (struct dns_host_entry *)0; 848 return 1; 849 } 850 851 int option_state_allocate (ptr, file, line) 852 struct option_state **ptr; 853 const char *file; 854 int line; 855 { 856 unsigned size; 857 858 if (!ptr) { 859 log_error ("%s(%d): null pointer", file, line); 860 #if defined (POINTER_DEBUG) 861 abort (); 862 #else 863 return 0; 864 #endif 865 } 866 if (*ptr) { 867 log_error ("%s(%d): non-null pointer", file, line); 868 #if defined (POINTER_DEBUG) 869 abort (); 870 #else 871 *ptr = (struct option_state *)0; 872 #endif 873 } 874 875 size = sizeof **ptr + (universe_count - 1) * sizeof (void *); 876 *ptr = dmalloc (size, file, line); 877 if (*ptr) { 878 memset (*ptr, 0, size); 879 (*ptr) -> universe_count = universe_count; 880 (*ptr) -> refcnt = 1; 881 rc_register (file, line, 882 ptr, *ptr, (*ptr) -> refcnt, 0, RC_MISC); 883 return 1; 884 } 885 return 0; 886 } 887 888 int option_state_reference (ptr, bp, file, line) 889 struct option_state **ptr; 890 struct option_state *bp; 891 const char *file; 892 int line; 893 { 894 if (!ptr) { 895 log_error ("%s(%d): null pointer", file, line); 896 #if defined (POINTER_DEBUG) 897 abort (); 898 #else 899 return 0; 900 #endif 901 } 902 if (*ptr) { 903 log_error ("%s(%d): non-null pointer", file, line); 904 #if defined (POINTER_DEBUG) 905 abort (); 906 #else 907 *ptr = (struct option_state *)0; 908 #endif 909 } 910 *ptr = bp; 911 bp -> refcnt++; 912 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC); 913 return 1; 914 } 915 916 int option_state_dereference (ptr, file, line) 917 struct option_state **ptr; 918 const char *file; 919 int line; 920 { 921 int i; 922 struct option_state *options; 923 924 if (!ptr || !*ptr) { 925 log_error ("%s(%d): null pointer", file, line); 926 #if defined (POINTER_DEBUG) 927 abort (); 928 #else 929 return 0; 930 #endif 931 } 932 933 options = *ptr; 934 *ptr = (struct option_state *)0; 935 --options -> refcnt; 936 rc_register (file, line, ptr, options, options -> refcnt, 1, RC_MISC); 937 if (options -> refcnt > 0) 938 return 1; 939 940 if (options -> refcnt < 0) { 941 log_error ("%s(%d): negative refcnt!", file, line); 942 #if defined (DEBUG_RC_HISTORY) 943 dump_rc_history (options); 944 #endif 945 #if defined (POINTER_DEBUG) 946 abort (); 947 #else 948 return 0; 949 #endif 950 } 951 952 /* Loop through the per-universe state. */ 953 for (i = 0; i < options -> universe_count; i++) 954 if (options -> universes [i] && 955 universes [i] -> option_state_dereference) 956 ((*(universes [i] -> option_state_dereference)) 957 (universes [i], options, file, line)); 958 959 dfree (options, file, line); 960 return 1; 961 } 962 963 int executable_statement_allocate (ptr, file, line) 964 struct executable_statement **ptr; 965 const char *file; 966 int line; 967 { 968 struct executable_statement *bp; 969 970 bp = dmalloc (sizeof *bp, file, line); 971 if (!bp) 972 return 0; 973 memset (bp, 0, sizeof *bp); 974 return executable_statement_reference (ptr, bp, file, line); 975 } 976 977 int executable_statement_reference (ptr, bp, file, line) 978 struct executable_statement **ptr; 979 struct executable_statement *bp; 980 const char *file; 981 int line; 982 { 983 if (!ptr) { 984 log_error ("%s(%d): null pointer", file, line); 985 #if defined (POINTER_DEBUG) 986 abort (); 987 #else 988 return 0; 989 #endif 990 } 991 if (*ptr) { 992 log_error ("%s(%d): non-null pointer", file, line); 993 #if defined (POINTER_DEBUG) 994 abort (); 995 #else 996 *ptr = (struct executable_statement *)0; 997 #endif 998 } 999 *ptr = bp; 1000 bp -> refcnt++; 1001 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC); 1002 return 1; 1003 } 1004 1005 static struct packet *free_packets; 1006 1007 #if defined (DEBUG_MEMORY_LEAKAGE) || \ 1008 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT) 1009 void relinquish_free_packets () 1010 { 1011 struct packet *p, *n; 1012 for (p = free_packets; p; p = n) { 1013 n = (struct packet *)(p -> raw); 1014 dfree (p, MDL); 1015 } 1016 free_packets = (struct packet *)0; 1017 } 1018 #endif 1019 1020 int packet_allocate (ptr, file, line) 1021 struct packet **ptr; 1022 const char *file; 1023 int line; 1024 { 1025 struct packet *p; 1026 1027 if (!ptr) { 1028 log_error ("%s(%d): null pointer", file, line); 1029 #if defined (POINTER_DEBUG) 1030 abort (); 1031 #else 1032 return 0; 1033 #endif 1034 } 1035 if (*ptr) { 1036 log_error ("%s(%d): non-null pointer", file, line); 1037 #if defined (POINTER_DEBUG) 1038 abort (); 1039 #else 1040 *ptr = (struct packet *)0; 1041 #endif 1042 } 1043 1044 if (free_packets) { 1045 p = free_packets; 1046 free_packets = (struct packet *)(p -> raw); 1047 dmalloc_reuse (p, file, line, 1); 1048 } else { 1049 p = dmalloc (sizeof *p, file, line); 1050 } 1051 if (p) { 1052 memset (p, 0, sizeof *p); 1053 return packet_reference (ptr, p, file, line); 1054 } 1055 return 0; 1056 } 1057 1058 int packet_reference (ptr, bp, file, line) 1059 struct packet **ptr; 1060 struct packet *bp; 1061 const char *file; 1062 int line; 1063 { 1064 if (!ptr) { 1065 log_error ("%s(%d): null pointer", file, line); 1066 #if defined (POINTER_DEBUG) 1067 abort (); 1068 #else 1069 return 0; 1070 #endif 1071 } 1072 if (*ptr) { 1073 log_error ("%s(%d): non-null pointer", file, line); 1074 #if defined (POINTER_DEBUG) 1075 abort (); 1076 #else 1077 *ptr = (struct packet *)0; 1078 #endif 1079 } 1080 *ptr = bp; 1081 bp -> refcnt++; 1082 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC); 1083 return 1; 1084 } 1085 1086 int packet_dereference (ptr, file, line) 1087 struct packet **ptr; 1088 const char *file; 1089 int line; 1090 { 1091 int i; 1092 struct packet *packet; 1093 1094 if (!ptr || !*ptr) { 1095 log_error ("%s(%d): null pointer", file, line); 1096 #if defined (POINTER_DEBUG) 1097 abort (); 1098 #else 1099 return 0; 1100 #endif 1101 } 1102 1103 packet = *ptr; 1104 *ptr = (struct packet *)0; 1105 --packet -> refcnt; 1106 rc_register (file, line, ptr, packet, packet -> refcnt, 1, RC_MISC); 1107 if (packet -> refcnt > 0) 1108 return 1; 1109 1110 if (packet -> refcnt < 0) { 1111 log_error ("%s(%d): negative refcnt!", file, line); 1112 #if defined (DEBUG_RC_HISTORY) 1113 dump_rc_history (packet); 1114 #endif 1115 #if defined (POINTER_DEBUG) 1116 abort (); 1117 #else 1118 return 0; 1119 #endif 1120 } 1121 1122 if (packet -> options) 1123 option_state_dereference (&packet -> options, file, line); 1124 if (packet -> interface) 1125 interface_dereference (&packet -> interface, MDL); 1126 if (packet -> shared_network) 1127 shared_network_dereference (&packet -> shared_network, MDL); 1128 for (i = 0; i < packet -> class_count && i < PACKET_MAX_CLASSES; i++) { 1129 if (packet -> classes [i]) 1130 omapi_object_dereference ((omapi_object_t **) 1131 &packet -> classes [i], MDL); 1132 } 1133 packet -> raw = (struct dhcp_packet *)free_packets; 1134 free_packets = packet; 1135 dmalloc_reuse (free_packets, __FILE__, __LINE__, 0); 1136 return 1; 1137 } 1138 1139 int dns_zone_allocate (ptr, file, line) 1140 struct dns_zone **ptr; 1141 const char *file; 1142 int line; 1143 { 1144 struct dns_zone *d; 1145 1146 if (!ptr) { 1147 log_error ("%s(%d): null pointer", file, line); 1148 #if defined (POINTER_DEBUG) 1149 abort (); 1150 #else 1151 return 0; 1152 #endif 1153 } 1154 if (*ptr) { 1155 log_error ("%s(%d): non-null pointer", file, line); 1156 #if defined (POINTER_DEBUG) 1157 abort (); 1158 #else 1159 *ptr = (struct dns_zone *)0; 1160 #endif 1161 } 1162 1163 d = dmalloc (sizeof *d, file, line); 1164 if (d) { 1165 memset (d, 0, sizeof *d); 1166 return dns_zone_reference (ptr, d, file, line); 1167 } 1168 return 0; 1169 } 1170 1171 int dns_zone_reference (ptr, bp, file, line) 1172 struct dns_zone **ptr; 1173 struct dns_zone *bp; 1174 const char *file; 1175 int line; 1176 { 1177 if (!ptr) { 1178 log_error ("%s(%d): null pointer", file, line); 1179 #if defined (POINTER_DEBUG) 1180 abort (); 1181 #else 1182 return 0; 1183 #endif 1184 } 1185 if (*ptr) { 1186 log_error ("%s(%d): non-null pointer", file, line); 1187 #if defined (POINTER_DEBUG) 1188 abort (); 1189 #else 1190 *ptr = (struct dns_zone *)0; 1191 #endif 1192 } 1193 *ptr = bp; 1194 bp -> refcnt++; 1195 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC); 1196 return 1; 1197 } 1198 1199 int binding_scope_allocate (ptr, file, line) 1200 struct binding_scope **ptr; 1201 const char *file; 1202 int line; 1203 { 1204 struct binding_scope *bp; 1205 1206 if (!ptr) { 1207 log_error ("%s(%d): null pointer", file, line); 1208 #if defined (POINTER_DEBUG) 1209 abort (); 1210 #else 1211 return 0; 1212 #endif 1213 } 1214 1215 if (*ptr) { 1216 log_error ("%s(%d): non-null pointer", file, line); 1217 #if defined (POINTER_DEBUG) 1218 abort (); 1219 #else 1220 return 0; 1221 #endif 1222 } 1223 1224 bp = dmalloc (sizeof *bp, file, line); 1225 if (!bp) 1226 return 0; 1227 memset (bp, 0, sizeof *bp); 1228 binding_scope_reference (ptr, bp, file, line); 1229 return 1; 1230 } 1231 1232 int binding_scope_reference (ptr, bp, file, line) 1233 struct binding_scope **ptr; 1234 struct binding_scope *bp; 1235 const char *file; 1236 int line; 1237 { 1238 if (!ptr) { 1239 log_error ("%s(%d): null pointer", file, line); 1240 #if defined (POINTER_DEBUG) 1241 abort (); 1242 #else 1243 return 0; 1244 #endif 1245 } 1246 if (*ptr) { 1247 log_error ("%s(%d): non-null pointer", file, line); 1248 #if defined (POINTER_DEBUG) 1249 abort (); 1250 #else 1251 *ptr = (struct binding_scope *)0; 1252 #endif 1253 } 1254 *ptr = bp; 1255 bp -> refcnt++; 1256 rc_register (file, line, ptr, bp, bp -> refcnt, 0, RC_MISC); 1257 return 1; 1258 } 1259 1260 /* Make a copy of the data in data_string, upping the buffer reference 1261 count if there's a buffer. */ 1262 1263 void 1264 data_string_copy(struct data_string *dest, const struct data_string *src, 1265 const char *file, int line) 1266 { 1267 if (src -> buffer) { 1268 buffer_reference (&dest -> buffer, src -> buffer, file, line); 1269 } else { 1270 dest->buffer = NULL; 1271 } 1272 dest -> data = src -> data; 1273 dest -> terminated = src -> terminated; 1274 dest -> len = src -> len; 1275 } 1276 1277 /* Release the reference count to a data string's buffer (if any) and 1278 zero out the other information, yielding the null data string. */ 1279 1280 void data_string_forget (data, file, line) 1281 struct data_string *data; 1282 const char *file; 1283 int line; 1284 { 1285 if (data -> buffer) 1286 buffer_dereference (&data -> buffer, file, line); 1287 memset (data, 0, sizeof *data); 1288 } 1289 1290 /* If the data_string is larger than the specified length, reduce 1291 the data_string to the specified size. */ 1292 1293 void data_string_truncate (dp, len) 1294 struct data_string *dp; 1295 int len; 1296 { 1297 /* XXX: do we need to consider the "terminated" flag in the check? */ 1298 if (len < dp -> len) { 1299 dp -> terminated = 0; 1300 dp -> len = len; 1301 } 1302 } 1303