summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2016-07-13 12:17:58 +0200
committerJakub Hrozek <jhrozek@redhat.com>2016-08-09 14:59:59 +0200
commit9c7e046cc10a834b86457844df3ba810866cad45 (patch)
treedeccd2eec0f5230778f2f7a8bb6be2a045f702a8 /src/tools
parent08cd034c8584b6f058cf565ce66f7f9f7120622f (diff)
downloadsssd-9c7e046cc10a834b86457844df3ba810866cad45.tar.gz
sssd-9c7e046cc10a834b86457844df3ba810866cad45.tar.xz
sssd-9c7e046cc10a834b86457844df3ba810866cad45.zip
utils: add remove_subtree
Remove all entries in a directory but will not remove the directory itself. Reviewed-by: Petr Cech <pcech@redhat.com>
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/files.c35
-rw-r--r--src/tools/tools_util.h1
2 files changed, 29 insertions, 7 deletions
diff --git a/src/tools/files.c b/src/tools/files.c
index 8f1aa68be..9f4e7caa7 100644
--- a/src/tools/files.c
+++ b/src/tools/files.c
@@ -137,7 +137,8 @@ static int sss_futime_set(int fd, const struct stat *statp)
static int remove_tree_with_ctx(TALLOC_CTX *mem_ctx,
int parent_fd,
const char *dir_name,
- dev_t parent_dev);
+ dev_t parent_dev,
+ bool keep_root_dir);
int remove_tree(const char *root)
{
@@ -149,7 +150,22 @@ int remove_tree(const char *root)
return ENOMEM;
}
- ret = remove_tree_with_ctx(tmp_ctx, AT_FDCWD, root, 0);
+ ret = remove_tree_with_ctx(tmp_ctx, AT_FDCWD, root, 0, false);
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+int remove_subtree(const char *root)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ int ret;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ ret = remove_tree_with_ctx(tmp_ctx, AT_FDCWD, root, 0, true);
talloc_free(tmp_ctx);
return ret;
}
@@ -162,7 +178,8 @@ int remove_tree(const char *root)
static int remove_tree_with_ctx(TALLOC_CTX *mem_ctx,
int parent_fd,
const char *dir_name,
- dev_t parent_dev)
+ dev_t parent_dev,
+ bool keep_root_dir)
{
struct dirent *result;
struct stat statres;
@@ -213,7 +230,8 @@ static int remove_tree_with_ctx(TALLOC_CTX *mem_ctx,
goto fail;
}
- ret = remove_tree_with_ctx(mem_ctx, dir_fd, result->d_name, statres.st_dev);
+ ret = remove_tree_with_ctx(mem_ctx, dir_fd, result->d_name,
+ statres.st_dev, false);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Removing subdirectory failed: [%d][%s]\n",
@@ -239,9 +257,12 @@ static int remove_tree_with_ctx(TALLOC_CTX *mem_ctx,
goto fail;
}
- ret = unlinkat(parent_fd, dir_name, AT_REMOVEDIR);
- if (ret == -1) {
- ret = errno;
+ if (!keep_root_dir) {
+ /* Remove also root directory. */
+ ret = unlinkat(parent_fd, dir_name, AT_REMOVEDIR);
+ if (ret == -1) {
+ ret = errno;
+ }
}
ret = EOK;
diff --git a/src/tools/tools_util.h b/src/tools/tools_util.h
index f31e843de..389c7b5c4 100644
--- a/src/tools/tools_util.h
+++ b/src/tools/tools_util.h
@@ -113,6 +113,7 @@ errno_t sss_mc_refresh_grouplist(struct tools_ctx *tctx,
/* from files.c */
int remove_tree(const char *root);
+int remove_subtree(const char *root);
int copy_tree(const char *src_root, const char *dst_root,
mode_t mode_root, uid_t uid, gid_t gid);