X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Futils%2Fos.c;h=7858825e1c889ad040b028284b9c4725c29a8068;hb=3577da85f5922d92a078ec690b6a33dc16ae5433;hp=b1e143a6a651d140e0ee10ce36fdff7f05da421b;hpb=42e0a931f1424c2d13794e3a064d328669ed7767;p=sysdb.git diff --git a/src/utils/os.c b/src/utils/os.c index b1e143a..7858825 100644 --- a/src/utils/os.c +++ b/src/utils/os.c @@ -36,25 +36,24 @@ #include #include +#include + #include +#include #include #include #include /* - * private helper functions + * public API */ -/* - * Recursively create the directory 'pathname' using the specified 'mode'. If - * 'enforce_mode' is true, the mode will be enforced even if the directory - * exists already. - */ -static int -mkdir_rec(const char *pathname, mode_t mode, _Bool enforce_mode) +int +sdb_mkdir_all(const char *pathname, mode_t mode) { struct stat st; + char *pathname_copy; char *base_dir; int status = 0; @@ -70,9 +69,6 @@ mkdir_rec(const char *pathname, mode_t mode, _Bool enforce_mode) errno = ENOTDIR; return -1; } - - if ((st.st_mode != mode) && enforce_mode) - return chmod(pathname, mode); return 0; } @@ -80,29 +76,69 @@ mkdir_rec(const char *pathname, mode_t mode, _Bool enforce_mode) /* pathname exists but we cannot access it */ return -1; - base_dir = strdup(pathname); - if (! base_dir) + pathname_copy = strdup(pathname); + if (! pathname_copy) return -1; - base_dir = dirname(base_dir); + base_dir = dirname(pathname_copy); - /* don't enforce the mode on parent directories */ - status = mkdir_rec(base_dir, mode, 0); + status = sdb_mkdir_all(base_dir, mode); if (! status) status = mkdir(pathname, mode); - free(base_dir); + free(pathname_copy); return status; -} /* mkdir_rec */ - -/* - * public API - */ +} /* sdb_mkdir_all */ int -sdb_mkdir_all(const char *pathname, mode_t mode) +sdb_remove_all(const char *pathname) { - return mkdir_rec(pathname, mode, 1); -} /* sdb_mkdir_all */ + struct stat st; + + if ((! pathname) || (! *pathname)) { + errno = EINVAL; + return -1; + } + + memset(&st, 0, sizeof(st)); + if (stat(pathname, &st)) + return -1; + + if (S_ISDIR(st.st_mode)) { + DIR *d = opendir(pathname); + + if (! d) + return -1; + + while (42) { + struct dirent de; + struct dirent *res = NULL; + + char filename[strlen(pathname) + sizeof(de.d_name) + 2]; + + memset(&de, 0, sizeof(de)); + if (readdir_r(d, &de, &res)) { + closedir(d); + return -1; + } + + if (! res) + break; + + if ((de.d_name[0] == '.') && ((de.d_name[1] == '\0') + || ((de.d_name[1] == '.')&& (de.d_name[2] == '\0')))) + continue; + + snprintf(filename, sizeof(filename), + "%s/%s", pathname, de.d_name); + if (sdb_remove_all(filename)) { + closedir(d); + return -1; + } + } + closedir(d); + } + return remove(pathname); +} /* sdb_remove_all */ /* vim: set tw=78 sw=4 ts=4 noexpandtab : */