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