diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/rrdbot-create.c | 94 | 
1 files changed, 91 insertions, 3 deletions
| diff --git a/tools/rrdbot-create.c b/tools/rrdbot-create.c index 86f5b27..c7a7350 100644 --- a/tools/rrdbot-create.c +++ b/tools/rrdbot-create.c @@ -41,7 +41,7 @@  #include <unistd.h>  #include <stdarg.h>  #include <err.h> - +#include <sys/stat.h>  #include <rrd.h>  #include "config-parser.h" @@ -105,7 +105,92 @@ verb(const char* fmt, ...)   * CREATE   */ -void +static int +mkdir_p(char* path) +{ +    struct stat sb; +    int first, last, retval = 0; +    char* p = path; + +    /* Skip leading '/'. */ +    while(p[0] == '/') +        ++p; + +    for(first = 1, last = 0; !last ; ++p) +    { +        if(p[0] == '\0') +            last = 1; +        else if (p[0] != '/') +            continue; +        *p = '\0'; +        if(!last && p[1] == '\0') +            last = 1; + +        /* Modified by the umask */ +        if(mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) < 0) +        { +            if(errno == EEXIST || errno == EISDIR) +            { +                if(stat(path, &sb) < 0) +                { +                    retval = 1; +                    break; +                } +                else if(!S_ISDIR(sb.st_mode)) +                { +                    if (last) +                        errno = EEXIST; +                    else +                        errno = ENOTDIR; +                    retval = 1; +                    break; +                } +            } +            else +            { +                retval = 1; +                break; +            } +        } +        if (!last) +            *p = '/'; +    } + +    return (retval); +} + +static int +create_dir_for_file(const char* path) +{ +    char *p = strrchr(path, '/'); +    char *dir; +    int r; + +    /* No subdirectories, not needed */ +    if (!p) +        return 0; + +    dir = calloc((p - path) + 1, 1); +    if(!dir) +    { +        errno = ENOMEM; +        return -1; +    } + +    memcpy (dir, path, (p - path)); +    r = mkdir_p(dir); +    free(dir); + +    if(r < 0) +    { +        warnx("couldn't create directory for rrd file: %s", dir); +        return r; +    } + +    return r; +} + +static void  create_file(create_ctx* ctx, const char* rrd)  {      create_arg* arg; @@ -113,6 +198,9 @@ create_file(create_ctx* ctx, const char* rrd)      int argc, r;      const char** argv; +    if(create_dir_for_file(rrd)) +        return; +      for(arg = ctx->args; arg; arg = arg->next)          num++; @@ -263,7 +351,7 @@ cfg_value(const char* filename, const char* header, const char* name,          check_create_file(ctx);          /* Do cleanup */ -        ctx->confname = NULL; +        ctx->confname = 0;          while(ctx->args)          { | 
