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