+static int rmtree_helper(const char *fpath, const struct stat *sb,
+ int typeflag, struct FTW *ftwbuf)
+{
+ if (S_ISDIR(sb->st_mode))
+ {
+ if (rmdir(fpath) < 0)
+ die("Cannot rmdir %s: %m", fpath);
+ }
+ else
+ {
+ if (unlink(fpath) < 0)
+ die("Cannot unlink %s: %m", fpath);
+ }
+ return FTW_CONTINUE;
+}
+
+static void
+rmtree(char *path)
+{
+ nftw(path, rmtree_helper, 32, FTW_MOUNT | FTW_PHYS | FTW_DEPTH);
+}
+
+static uid_t chown_uid;
+static gid_t chown_gid;
+static int chowntree_helper(const char *fpath, const struct stat *sb,
+ int typeflag, struct FTW *ftwbuf)
+{
+ if (lchown(fpath, chown_uid, chown_gid) < 0)
+ die("Cannot chown %s: %m", fpath);
+ else
+ return FTW_CONTINUE;
+}
+
+static void
+chowntree(char *path, uid_t uid, gid_t gid)
+{
+ chown_uid = uid;
+ chown_gid = gid;
+ nftw(path, chowntree_helper, 32, FTW_MOUNT | FTW_PHYS);
+}
+