2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1999 University of Maryland at College Park
4 * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved.
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of U.M. not be used in advertising or
12 * publicity pertaining to distribution of the software without specific,
13 * written prior permission. U.M. makes no representations about the
14 * suitability of this software for any purpose. It is provided "as is"
15 * without express or implied warranty.
17 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
19 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 * Authors: the Amanda Development Team. Its members are listed in a
25 * file named AUTHORS, in the root directory of this distribution.
28 * $Id: alloc.c 5280 2007-02-13 15:58:56Z martineau $
30 * Memory allocators with error handling. If the allocation fails,
31 * errordump() is called, relieving the caller from checking the return
39 static char *internal_vstralloc(const char *, int, const char *, va_list);
42 * alloc - a wrapper for malloc.
52 addr = (void *)malloc(max(size, 1));
54 errordump(_("%s@%d: memory allocation failed (%zu bytes requested)"),
55 file ? file : _("(unknown)"),
65 * newalloc - free existing buffer and then alloc a new one.
76 addr = debug_alloc(file, line, size);
83 * stralloc - copies the given string into newly allocated memory.
94 addr = debug_alloc(file, line, strlen(str) + 1);
100 * internal_vstralloc - copies up to MAX_STR_ARGS strings into newly
103 * The MAX_STR_ARGS limit is purely an efficiency issue so we do not have
104 * to scan the strings more than necessary.
107 #define MAX_VSTRALLOC_ARGS 40
120 const char *arg[MAX_VSTRALLOC_ARGS+1];
121 size_t len[MAX_VSTRALLOC_ARGS+1];
125 errordump(_("internal_vstralloc: str is NULL"));
132 total_len = len[a] = l;
135 while ((next = arglist_val(argp, char *)) != NULL) {
136 if ((l = strlen(next)) == 0) {
137 continue; /* minor optimisation */
139 if (a >= MAX_VSTRALLOC_ARGS) {
140 errordump(_("%s@%d: more than %d args to vstralloc"),
141 file ? file : _("(unknown)"),
152 result = debug_alloc(file, line, total_len+1);
155 for (b = 0; b < a; b++) {
156 memcpy(next, arg[b], len[b]);
166 * vstralloc - copies multiple strings into newly allocated memory.
178 arglist_start(argp, str);
179 result = internal_vstralloc(file, line, str, argp);
186 * newstralloc - free existing string and then stralloc a new one.
197 addr = debug_stralloc(file, line, newstr);
204 * newvstralloc - free existing string and then vstralloc a new one.
217 arglist_start(argp, newstr);
218 result = internal_vstralloc(file, line, newstr, argp);
226 * vstrallocf - copies printf formatted string into newly allocated memory.
240 result = debug_alloc(file, line, MIN_ALLOC);
241 if (result != NULL) {
243 arglist_start(argp, fmt);
244 size = g_vsnprintf(result, MIN_ALLOC, fmt, argp);
247 if (size >= (size_t)MIN_ALLOC) {
249 result = debug_alloc(file, line, size + 1);
251 arglist_start(argp, fmt);
252 (void)g_vsnprintf(result, size + 1, fmt, argp);
262 * newvstrallocf - free existing string and then vstrallocf a new one.
276 result = debug_alloc(file, line, MIN_ALLOC);
277 if (result != NULL) {
279 arglist_start(argp, fmt);
280 size = g_vsnprintf(result, MIN_ALLOC, fmt, argp);
283 if (size >= MIN_ALLOC) {
285 result = debug_alloc(file, line, size + 1);
287 arglist_start(argp, fmt);
288 (void)g_vsnprintf(result, size + 1, fmt, argp);
296 /* vstrextend -- Extends the existing string by appending the other
305 char *keep = *oldstr;
308 arglist_start(ap, oldstr);
312 *oldstr = internal_vstralloc(file, line, *oldstr, ap);
320 * safe_env_full - build a "safe" environment list.
323 safe_env_full(char **add)
325 static char *safe_env_list[] = {
338 * If the initial environment pointer malloc fails, set up to
339 * pass back a pointer to the NULL string pointer at the end of
340 * safe_env_list so our result is always a valid, although possibly
341 * empty, environment list.
343 #define SAFE_ENV_CNT (size_t)(sizeof(safe_env_list) / sizeof(*safe_env_list))
344 char **envp = safe_env_list + SAFE_ENV_CNT - 1;
356 for (p = add; p && *p; p++)
359 if (getuid() == geteuid() && getgid() == getegid()) {
361 for (env = environ; *env != NULL; env++)
363 if ((q = (char **)malloc((nadd+env_cnt)*SIZEOF(char *))) != NULL) {
367 for (env = add; env && *env; env++) {
371 for (env = environ; *env != NULL; env++) {
372 if (strncmp("LANG=", *env, 5) != 0 &&
373 strncmp("LC_", *env, 3) != 0) {
383 if ((q = (char **)malloc(nadd*sizeof(char *) + SIZEOF(safe_env_list))) != NULL) {
386 for (p = add; p && *p; p++) {
391 /* and copy any SAFE_ENV that are already set */
392 for (p = safe_env_list; *p != NULL; p++) {
393 if ((v = getenv(*p)) == NULL) {
394 continue; /* no variable to dup */
396 l1 = strlen(*p); /* variable name w/o null */
397 l2 = strlen(v) + 1; /* include null byte here */
398 if ((s = (char *)malloc(l1 + 1 + l2)) == NULL) {
399 break; /* out of memory */
401 *q++ = s; /* save the new pointer */
402 memcpy(s, *p, l1); /* left hand side */
405 memcpy(s, v, l2); /* right hand side and null */
407 *q = NULL; /* terminate the list */