diff options
Diffstat (limited to 'utils/filepath.c')
-rw-r--r-- | utils/filepath.c | 85 |
1 files changed, 84 insertions, 1 deletions
diff --git a/utils/filepath.c b/utils/filepath.c index d088777e5..d82dfc627 100644 --- a/utils/filepath.c +++ b/utils/filepath.c @@ -202,7 +202,13 @@ filepath_generate(char * const *pathv, const char * const *langv) return respath; } -/* expand ${} in a string into environment variables */ +/** + * expand ${} in a string into environment variables. + * + * @param path The pathname to expand. + * @param pathlen The length of the path element. + * @return A string with the expanded path or NULL on empty expansion or error. + */ static char * expand_path(const char *path, int pathlen) { @@ -317,3 +323,80 @@ void filepath_free_strvec(char **pathv) } free(pathv); } + +/* exported interface documented in filepath.h */ +char *filepath_append(const char *path, const char *leaf) +{ + int dirname_len; + char *dirname; + + if ((path == NULL) || (leaf == NULL)) { + return NULL; + } + + dirname_len = strlen(path) + strlen(leaf) + 2; + dirname = malloc(dirname_len); + if (dirname != NULL) { + snprintf(dirname, dirname_len, "%s/%s", path, leaf); + } + + return dirname; +} + +/* exported interface documented in filepath.h */ +nserror filepath_mkdir_all(const char *fname) +{ + char *dname; + char *sep; + struct stat sb; + + dname = strdup(fname); + + sep = strrchr(dname, '/'); + if (sep == NULL) { + /* no directory separator path is just filename so its ok */ + free(dname); + return NSERROR_OK; + } + + *sep = 0; /* null terminate directory path */ + + if (stat(dname, &sb) == 0) { + free(dname); + if (S_ISDIR(sb.st_mode)) { + /* path to file exists and is a directory */ + return NSERROR_OK; + } + return NSERROR_NOT_DIRECTORY; + } + *sep = '/'; /* restore separator */ + + sep = dname; + while (*sep == '/') { + sep++; + } + while ((sep = strchr(sep, '/')) != NULL) { + *sep = 0; + if (stat(dname, &sb) != 0) { + if (mkdir(dname, S_IRWXU) != 0) { + /* could not create path element */ + free(dname); + return NSERROR_NOT_FOUND; + } + } else { + if (! S_ISDIR(sb.st_mode)) { + /* path element not a directory */ + free(dname); + return NSERROR_NOT_DIRECTORY; + } + } + *sep = '/'; /* restore separator */ + /* skip directory separators */ + while (*sep == '/') { + sep++; + } + } + + free(dname); + return NSERROR_OK; +} |