2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1999 University of Maryland at College Park
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Authors: the Amanda Development Team. Its members are listed in a
24 * file named AUTHORS, in the root directory of this distribution.
27 * $Id: alloc.c 5280 2007-02-13 15:58:56Z martineau $
29 * Memory allocators with error handling. If the allocation fails,
30 * errordump() is called, relieving the caller from checking the return
38 static char *internal_vstralloc(const char *, int, const char *, va_list);
41 * alloc - a wrapper for malloc.
51 addr = (void *)malloc(max(size, 1));
53 errordump(_("%s@%d: memory allocation failed (%zu bytes requested)"),
54 file ? file : _("(unknown)"),
64 * newalloc - free existing buffer and then alloc a new one.
75 addr = debug_alloc(file, line, size);
82 * stralloc - copies the given string into newly allocated memory.
93 addr = debug_alloc(file, line, strlen(str) + 1);
99 * internal_vstralloc - copies up to MAX_STR_ARGS strings into newly
102 * The MAX_STR_ARGS limit is purely an efficiency issue so we do not have
103 * to scan the strings more than necessary.
106 #define MAX_VSTRALLOC_ARGS 40
119 const char *arg[MAX_VSTRALLOC_ARGS+1];
120 size_t len[MAX_VSTRALLOC_ARGS+1];
124 errordump(_("internal_vstralloc: str is NULL"));
131 total_len = len[a] = l;
134 while ((next = arglist_val(argp, char *)) != NULL) {
135 if ((l = strlen(next)) == 0) {
136 continue; /* minor optimisation */
138 if (a >= MAX_VSTRALLOC_ARGS) {
139 errordump(_("%s@%d: more than %d args to vstralloc"),
140 file ? file : _("(unknown)"),
151 result = debug_alloc(file, line, total_len+1);
154 for (b = 0; b < a; b++) {
155 memcpy(next, arg[b], len[b]);
165 * vstralloc - copies multiple strings into newly allocated memory.
177 arglist_start(argp, str);
178 result = internal_vstralloc(file, line, str, argp);
185 * newstralloc - free existing string and then stralloc a new one.
196 addr = debug_stralloc(file, line, newstr);
203 * newvstralloc - free existing string and then vstralloc a new one.
216 arglist_start(argp, newstr);
217 result = internal_vstralloc(file, line, newstr, argp);
225 * vstrallocf - copies printf formatted string into newly allocated memory.
239 result = debug_alloc(file, line, MIN_ALLOC);
240 if (result != NULL) {
242 arglist_start(argp, fmt);
243 size = g_vsnprintf(result, MIN_ALLOC, fmt, argp);
246 if (size >= (size_t)MIN_ALLOC) {
248 result = debug_alloc(file, line, size + 1);
250 arglist_start(argp, fmt);
251 (void)g_vsnprintf(result, size + 1, fmt, argp);
261 * newvstrallocf - free existing string and then vstrallocf a new one.
275 result = debug_alloc(file, line, MIN_ALLOC);
276 if (result != NULL) {
278 arglist_start(argp, fmt);
279 size = g_vsnprintf(result, MIN_ALLOC, fmt, argp);
282 if (size >= MIN_ALLOC) {
284 result = debug_alloc(file, line, size + 1);
286 arglist_start(argp, fmt);
287 (void)g_vsnprintf(result, size + 1, fmt, argp);
295 /* vstrextend -- Extends the existing string by appending the other
304 char *keep = *oldstr;
307 arglist_start(ap, oldstr);
311 *oldstr = internal_vstralloc(file, line, *oldstr, ap);
319 * safe_env_full - build a "safe" environment list.
322 safe_env_full(char **add)
324 static char *safe_env_list[] = {
337 * If the initial environment pointer malloc fails, set up to
338 * pass back a pointer to the NULL string pointer at the end of
339 * safe_env_list so our result is always a valid, although possibly
340 * empty, environment list.
342 #define SAFE_ENV_CNT (size_t)(sizeof(safe_env_list) / sizeof(*safe_env_list))
343 char **envp = safe_env_list + SAFE_ENV_CNT - 1;
355 for (p = add; p && *p; p++)
358 if (getuid() == geteuid() && getgid() == getegid()) {
360 for (env = environ; *env != NULL; env++)
362 if ((q = (char **)malloc((nadd+env_cnt)*SIZEOF(char *))) != NULL) {
366 for (env = add; env && *env; env++) {
370 for (env = environ; *env != NULL; env++) {
371 if (strncmp("LANG=", *env, 5) != 0 &&
372 strncmp("LC_", *env, 3) != 0) {
382 if ((q = (char **)malloc(nadd*sizeof(char *) + SIZEOF(safe_env_list))) != NULL) {
385 for (p = add; p && *p; p++) {
390 /* and copy any SAFE_ENV that are already set */
391 for (p = safe_env_list; *p != NULL; p++) {
392 if ((v = getenv(*p)) == NULL) {
393 continue; /* no variable to dup */
395 l1 = strlen(*p); /* variable name w/o null */
396 l2 = strlen(v) + 1; /* include null byte here */
397 if ((s = (char *)malloc(l1 + 1 + l2)) == NULL) {
398 break; /* out of memory */
400 *q++ = s; /* save the new pointer */
401 memcpy(s, *p, l1); /* left hand side */
404 memcpy(s, v, l2); /* right hand side and null */
406 *q = NULL; /* terminate the list */