X-Git-Url: https://git.octo.it/?p=rrdtool.git;a=blobdiff_plain;f=src%2Frrd_utils.c;h=add19c31af61027762f10aa3e658e9e5419a2066;hp=39d2aca1601cac61e5507047fcf0802f4af5163a;hb=0b3205462f58dc3d59fe016563629e0bd03f8ae3;hpb=2f0b984b0dfee0a8ab2cb1d41670f40a07ec5cdb diff --git a/src/rrd_utils.c b/src/rrd_utils.c index 39d2aca..add19c3 100644 --- a/src/rrd_utils.c +++ b/src/rrd_utils.c @@ -1,4 +1,8 @@ /** + * RRDtool - src/rrd_utils.c + * Copyright (C) 2009 Kevin Brintnall + * Copyright (C) 2008 Sebastian Harl + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; only version 2 of the License is applicable. @@ -11,18 +15,34 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * kevin brintnall + * Sebastian Harl **/ #include "rrd_tool.h" +#include +#include #include - +#include +#include +#include +#ifndef _MSC_VER +#include +#include +#endif #ifdef WIN32 # define random() rand() # define srandom(x) srand(x) # define getpid() 0 #endif /* WIN32 */ +#ifndef S_ISDIR +#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) +#endif + /* make sure that the random number generator seeded EXACTLY ONCE */ long rrd_random(void) { @@ -34,3 +54,161 @@ long rrd_random(void) return random(); } + +/* rrd_add_ptr_chunk: add a pointer to a dynamically sized array of + * pointers, realloc as necessary in multiples of "chunk". + * + * "alloc" is the number of pointers allocated + * "dest_size" is the number of valid pointers + * + * returns 1 on success, 0 on failure. + */ + +int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src, + size_t *alloc, size_t chunk) +{ + void **temp; + + assert(dest != NULL); + assert(alloc != NULL); + assert(*alloc >= *dest_size); + + if (*alloc == *dest_size) + { + temp = (void **) rrd_realloc(*dest, (*alloc+chunk) * sizeof(*dest)); + if (!temp) + return 0; + + *dest = temp; + *alloc += chunk; + } + + (*dest)[*dest_size] = src; + (*dest_size)++; + + return 1; +} + +/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers, + * realloc as necessary. returns 1 on success, 0 on failure. + */ +int rrd_add_ptr(void ***dest, size_t *dest_size, void *src) +{ + size_t alloc = *dest_size; + + return rrd_add_ptr_chunk(dest, dest_size, src, &alloc, 1); +} + +/* like rrd_add_ptr_chunk, but calls strdup() on a string first. */ +int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src, + size_t *alloc, size_t chunk) +{ + char *dup_src; + int add_ok; + + assert(dest != NULL); + assert(src != NULL); + + dup_src = strdup(src); + if (!dup_src) + return 0; + + add_ok = rrd_add_ptr_chunk((void ***)dest, dest_size, (void *)dup_src, alloc, chunk); + if (!add_ok) + free(dup_src); + + return add_ok; +} + +int rrd_add_strdup(char ***dest, size_t *dest_size, char *src) +{ + size_t alloc = *dest_size; + + return rrd_add_strdup_chunk(dest, dest_size, src, &alloc, 1); +} + +void rrd_free_ptrs(void ***src, size_t *cnt) +{ + void **sp; + + assert(src != NULL); + sp = *src; + + if (sp == NULL) + return; + + while (*cnt > 0) { + (*cnt)--; + free(sp[*cnt]); + } + + free (sp); + *src = NULL; +} + +/* recursively create the directory named by 'pathname' + * (similar to "mkdir -p" on the command line) */ +int rrd_mkdir_p(const char *pathname, mode_t mode) +{ + struct stat sb; + + char *pathname_copy; + char *base_dir; + + if ((NULL == pathname) || ('\0' == *pathname)) { + errno = EINVAL; + return -1; + } + + if (0 == stat(pathname, &sb)) { + if (! S_ISDIR(sb.st_mode)) { + errno = ENOTDIR; + return -1; + } + return 0; + } + + /* keep errno as set by stat() */ + if (ENOENT != errno) + return -1; + + /* dirname might modify its first argument */ + if (NULL == (pathname_copy = strdup(pathname))) + return -1; + +#ifndef _MSC_VER + /* the data pointedd too by dirname might change too (bsd) */ + if (NULL == (base_dir = strdup(dirname(pathname_copy)))) { + free(pathname_copy); + return -1; + } +#else + _splitpath(pathname_copy, NULL, base_dir, NULL, NULL); +#endif + + if (0 != rrd_mkdir_p(base_dir, mode)) { + int orig_errno = errno; + free(pathname_copy); +#ifndef _MSC_VER + free(base_dir); +#endif + errno = orig_errno; + return -1; + } + + free(pathname_copy); +#ifndef _MSC_VER + free(base_dir); +#endif + + /* keep errno as set by mkdir() */ +#ifdef _MSC_VER + if (0 != mkdir(pathname)) + return -1; +#else + if (0 != mkdir(pathname, mode)) + return -1; +#endif + return 0; +} /* rrd_mkdir_p */ +