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