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