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