X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Falloc.c;h=4089c00367444764cde7e8d2700d5f7bfff4ed49;hb=b6ea83cedbf3e034fa91d66a7f180f788f34f907;hp=81670ea80bcbab0a131adccc0635db99553c6e71;hpb=cdbbeef9cde260e429854dd313bc0bf7560e1e24;p=debian%2Famanda diff --git a/common-src/alloc.c b/common-src/alloc.c index 81670ea..4089c00 100644 --- a/common-src/alloc.c +++ b/common-src/alloc.c @@ -24,7 +24,7 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: alloc.c,v 1.37 2006/07/05 10:41:32 martinea Exp $ + * $Id: alloc.c 5280 2007-02-13 15:58:56Z martineau $ * * Memory allocators with error handling. If the allocation fails, * errordump() is called, relieving the caller from checking the return @@ -34,164 +34,29 @@ #include "arglist.h" #include "queue.h" -static char *internal_vstralloc(const char *, va_list); +#define MIN_ALLOC 64 -/* - *===================================================================== - * debug_caller_loc -- keep track of all allocation callers - * - * const char *debug_caller_loc(const char *file, int line) - * - * entry: file = source file - * line = source line - * exit: a string like "genversion.c@999" - * - * The debug malloc library has a concept of a call stack that can be used - * to fine tune what was running when a particular allocation was done. - * We use it to tell who called our various allocation wrappers since - * it wouldn't do much good to tell us a problem happened because of - * the malloc call in alloc (they are all from there at some point). - * - * But the library expects the string passed to malloc_enter/malloc_leave - * to be static, so we build a linked list of each one we get (there are - * not really that many during a given execution). When we get a repeat - * we return the previously allocated string. For a bit of performance, - * we keep the list in least recently used order, which helps because - * the calls to us come in pairs (one for malloc_enter and one right - * after for malloc_leave). - *===================================================================== - */ - -const char * -debug_caller_loc( - const char *file, - int line) -{ - /*@keep@*/ - struct loc_str { - char *str; - LIST_ENTRY(loc_str) le; - } *ls; - static LIST_HEAD(, loc_str) root = LIST_HEAD_INITIALIZER(root); - static char loc[256]; /* big enough for filename@lineno */ - const char *p; - - if ((p = strrchr(file, '/')) != NULL) - file = p + 1; /* just the last path element */ - - snprintf(loc, SIZEOF(loc), "%s@%d", file, line); - - for (ls = LIST_FIRST(&root); ls != NULL; ls = LIST_NEXT(ls, le)) { - if (strcmp(loc, ls->str) == 0) { - if (ls != LIST_FIRST(&root)) { - /* - * This is a repeat and was not at the head of the list. - * Unlink it and move it to the front. - */ - LIST_REMOVE(ls, le); - LIST_INSERT_HEAD(&root, ls, le); - } - return (ls->str); - } - } - - /* - * This is a new entry. Put it at the head of the list. - */ - ls = malloc(SIZEOF(*ls)); - if (ls == NULL) - return ("??"); /* not much better than abort */ - ls->str = malloc(strlen(loc) + 1); - if (ls->str == NULL) { - free(ls); - return ("??"); /* not much better than abort */ - } - strcpy(ls->str, loc); - malloc_mark(ls); - malloc_mark(ls->str); - LIST_INSERT_HEAD(&root, ls, le); - return (ls->str); -} - -/* - *===================================================================== - * Save the current source line for vstralloc/newvstralloc. - * - * int debug_alloc_push (char *s, int l) - * - * entry: s = source file - * l = source line - * exit: always zero - * - * See the comments in amanda.h about what this is used for. - *===================================================================== - */ - -#define DEBUG_ALLOC_SAVE_MAX 10 - -static struct { - char *file; - int line; -} debug_alloc_loc_info[DEBUG_ALLOC_SAVE_MAX]; -static int debug_alloc_ptr = 0; - -static char *saved_file; -static int saved_line; - -int -debug_alloc_push( - char *s, - int l) -{ - debug_alloc_loc_info[debug_alloc_ptr].file = s; - debug_alloc_loc_info[debug_alloc_ptr].line = l; - debug_alloc_ptr = (debug_alloc_ptr + 1) % DEBUG_ALLOC_SAVE_MAX; - return 0; -} - -/* - *===================================================================== - * Pop the current source line information for vstralloc/newvstralloc. - * - * int debug_alloc_pop (void) - * - * entry: none - * exit: none - * - * See the comments in amanda.h about what this is used for. - *===================================================================== - */ - -void -debug_alloc_pop(void) -{ - debug_alloc_ptr = - (debug_alloc_ptr + DEBUG_ALLOC_SAVE_MAX - 1) % DEBUG_ALLOC_SAVE_MAX; - saved_file = debug_alloc_loc_info[debug_alloc_ptr].file; - saved_line = debug_alloc_loc_info[debug_alloc_ptr].line; -} +static char *internal_vstralloc(const char *, int, const char *, va_list); /* * alloc - a wrapper for malloc. */ void * debug_alloc( - const char *s, - int l, - size_t size) + const char *file, + int line, + size_t size) { void *addr; - malloc_enter(debug_caller_loc(s, l)); addr = (void *)malloc(max(size, 1)); if (addr == NULL) { - errordump("%s@%d: memory allocation failed (" SIZE_T_FMT " bytes requested)", - s ? s : "(unknown)", - s ? l : -1, - (SIZE_T_FMT_TYPE)size); + errordump(_("%s@%d: memory allocation failed (%zu bytes requested)"), + file ? file : _("(unknown)"), + file ? line : -1, + size); /*NOTREACHED*/ } - malloc_leave(debug_caller_loc(s, l)); return addr; } @@ -201,17 +66,15 @@ debug_alloc( */ void * debug_newalloc( - const char *s, - int l, - void *old, - size_t size) + const char *file, + int line, + void * old, + size_t size) { char *addr; - malloc_enter(debug_caller_loc(s, l)); - addr = debug_alloc(s, l, size); + addr = debug_alloc(file, line, size); amfree(old); - malloc_leave(debug_caller_loc(s, l)); return addr; } @@ -222,41 +85,17 @@ debug_newalloc( */ char * debug_stralloc( - const char *s, - int l, + const char *file, + int line, const char *str) { char *addr; - malloc_enter(debug_caller_loc(s, l)); - addr = debug_alloc(s, l, strlen(str) + 1); + addr = debug_alloc(file, line, strlen(str) + 1); strcpy(addr, str); - malloc_leave(debug_caller_loc(s, l)); return (addr); } -/* vstrextend -- Extends the existing string by appending the other - * arguments. */ -/*@ignore@*/ -arglist_function( - char *vstrextend, - char **, oldstr) -{ - char *keep = *oldstr; - va_list ap; - - arglist_start(ap, oldstr); - - if (*oldstr == NULL) - *oldstr = ""; - *oldstr = internal_vstralloc(*oldstr, ap); - amfree(keep); - - arglist_end(ap); - return *oldstr; -} -/*@end@*/ - /* * internal_vstralloc - copies up to MAX_STR_ARGS strings into newly * allocated memory. @@ -269,6 +108,8 @@ arglist_function( static char * internal_vstralloc( + const char *file, + int line, const char *str, va_list argp) { @@ -281,7 +122,7 @@ internal_vstralloc( size_t l; if (str == NULL) { - errordump("internal_vstralloc: str is NULL"); + errordump(_("internal_vstralloc: str is NULL")); /*NOTREACHED*/ } @@ -296,9 +137,9 @@ internal_vstralloc( continue; /* minor optimisation */ } if (a >= MAX_VSTRALLOC_ARGS) { - errordump("%s@%d: more than %d args to vstralloc", - saved_file ? saved_file : "(unknown)", - saved_file ? saved_line : -1, + errordump(_("%s@%d: more than %d args to vstralloc"), + file ? file : _("(unknown)"), + file ? line : -1, MAX_VSTRALLOC_ARGS); /*NOTREACHED*/ } @@ -308,7 +149,7 @@ internal_vstralloc( a++; } - result = debug_alloc(saved_file, saved_line, total_len+1); + result = debug_alloc(file, line, total_len+1); next = result; for (b = 0; b < a; b++) { @@ -324,19 +165,19 @@ internal_vstralloc( /* * vstralloc - copies multiple strings into newly allocated memory. */ -arglist_function( - char *debug_vstralloc, - const char *, str) +char * +debug_vstralloc( + const char *file, + int line, + const char *str, + ...) { va_list argp; char *result; - debug_alloc_pop(); - malloc_enter(debug_caller_loc(saved_file, saved_line)); arglist_start(argp, str); - result = internal_vstralloc(str, argp); + result = internal_vstralloc(file, line, str, argp); arglist_end(argp); - malloc_leave(debug_caller_loc(saved_file, saved_line)); return result; } @@ -346,17 +187,15 @@ arglist_function( */ char * debug_newstralloc( - const char *s, - int l, - char *oldstr, + const char *file, + int line, + char * oldstr, const char *newstr) { char *addr; - malloc_enter(debug_caller_loc(s, l)); - addr = debug_stralloc(s, l, newstr); + addr = debug_stralloc(file, line, newstr); amfree(oldstr); - malloc_leave(debug_caller_loc(s, l)); return (addr); } @@ -364,25 +203,121 @@ debug_newstralloc( /* * newvstralloc - free existing string and then vstralloc a new one. */ -arglist_function1( - char *debug_newvstralloc, - char *, oldstr, - const char *, newstr) +char * +debug_newvstralloc( + const char *file, + int line, + char * oldstr, + const char *newstr, + ...) { va_list argp; char *result; - debug_alloc_pop(); - malloc_enter(debug_caller_loc(saved_file, saved_line)); arglist_start(argp, newstr); - result = internal_vstralloc(newstr, argp); + result = internal_vstralloc(file, line, newstr, argp); arglist_end(argp); amfree(oldstr); - malloc_leave(debug_caller_loc(saved_file, saved_line)); return result; } +/* + * vstrallocf - copies printf formatted string into newly allocated memory. + */ +char * +debug_vstrallocf( + const char *file, + int line, + const char *fmt, + ...) +{ + char * result; + size_t size; + va_list argp; + + + result = debug_alloc(file, line, MIN_ALLOC); + if (result != NULL) { + + arglist_start(argp, fmt); + size = g_vsnprintf(result, MIN_ALLOC, fmt, argp); + arglist_end(argp); + + if (size >= (size_t)MIN_ALLOC) { + amfree(result); + result = debug_alloc(file, line, size + 1); + + arglist_start(argp, fmt); + (void)g_vsnprintf(result, size + 1, fmt, argp); + arglist_end(argp); + } + } + + return result; +} + + +/* + * newvstrallocf - free existing string and then vstrallocf a new one. + */ +char * +debug_newvstrallocf( + const char *file, + int line, + char * oldstr, + const char *fmt, + ...) +{ + size_t size; + char * result; + va_list argp; + + result = debug_alloc(file, line, MIN_ALLOC); + if (result != NULL) { + + arglist_start(argp, fmt); + size = g_vsnprintf(result, MIN_ALLOC, fmt, argp); + arglist_end(argp); + + if (size >= MIN_ALLOC) { + amfree(result); + result = debug_alloc(file, line, size + 1); + + arglist_start(argp, fmt); + (void)g_vsnprintf(result, size + 1, fmt, argp); + arglist_end(argp); + } + } + amfree(oldstr); + return result; +} + +/* vstrextend -- Extends the existing string by appending the other + * arguments. */ +char * +debug_vstrextend( + const char *file, + int line, + char ** oldstr, + ...) +{ + char *keep = *oldstr; + va_list ap; + + arglist_start(ap, oldstr); + + if (*oldstr == NULL) + *oldstr = ""; + *oldstr = internal_vstralloc(file, line, *oldstr, ap); + amfree(keep); + + arglist_end(ap); + return *oldstr; +} + + +extern char **environ; /* * safe_env - build a "safe" environment list. */ @@ -415,6 +350,27 @@ safe_env(void) char *s; char *v; size_t l1, l2; + char **env; + int env_cnt; + + if (getuid() == geteuid() && getgid() == getegid()) { + env_cnt = 1; + for (env = environ; *env != NULL; env++) + env_cnt++; + if ((q = (char **)malloc(env_cnt*SIZEOF(char *))) != NULL) { + envp = q; + p = envp; + for (env = environ; *env != NULL; env++) { + if (strncmp("LANG=", *env, 5) != 0 && + strncmp("LC_", *env, 3) != 0) { + *p = stralloc(*env); + p++; + } + } + *p = NULL; + } + return envp; + } if ((q = (char **)malloc(SIZEOF(safe_env_list))) != NULL) { envp = q; @@ -453,13 +409,13 @@ safe_env(void) int debug_amtable_alloc( - const char *s, - int l, - void **table, - size_t *current, - size_t elsize, - size_t count, - int bump, + const char *file, + int line, + void ** table, + size_t * current, + size_t elsize, + size_t count, + int bump, void (*init_func)(void *)) { void *table_new; @@ -468,7 +424,7 @@ debug_amtable_alloc( if (count >= *current) { table_count_new = ((count + bump) / bump) * bump; - table_new = debug_alloc(s, l, table_count_new * elsize); + table_new = debug_alloc(file, line, table_count_new * elsize); if (0 != *table) { memcpy(table_new, *table, *current * elsize); free(*table); @@ -498,8 +454,8 @@ debug_amtable_alloc( void amtable_free( - void **table, - size_t *current) + void ** table, + size_t * current) { amfree(*table); *current = 0;