diff --git a/libtap/tap/files.c b/libtap/tap/files.c
index 987d80e0a72788b3695684be706b88752cab8384..90f087f3724cfb206f4866b6ce195f73cf65549e 100644
--- a/libtap/tap/files.c
+++ b/libtap/tap/files.c
@@ -16,16 +16,9 @@
 
 #include "files.h"
 
-#include <assert.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <stdbool.h>
-#include <stdio.h>
+#include "../../src/contrib/files.c"
+
 #include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
 
 static char *make_temp(bool is_directory)
 {
@@ -66,68 +59,7 @@ char *test_mkdtemp(void)
 	return make_temp(true);
 }
 
-static bool special_name(const char *name)
-{
-	return strcmp(name, ".") == 0 || strcmp(name, "..") == 0;
-}
-
-static bool rm_dir_contents(int dir_fd)
-{
-	DIR *dir = fdopendir(dir_fd);
-	if (!dir) {
-		return false;
-	}
-
-	bool success = true;
-
-	struct dirent entry = { 0 };
-	struct dirent *result = NULL;
-	while (success && readdir_r(dir, &entry, &result) == 0 && result) {
-		if (special_name(result->d_name)) {
-			continue;
-		}
-
-		bool is_dir = result->d_type == DT_DIR;
-
-		if (is_dir) {
-			int sub = openat(dir_fd, result->d_name, O_NOFOLLOW);
-			success = rm_dir_contents(sub);
-			close(sub);
-		}
-
-		if (success) {
-			int flags = is_dir ? AT_REMOVEDIR : 0;
-			success = unlinkat(dir_fd, result->d_name, flags) == 0;
-		}
-	}
-
-	closedir(dir);
-
-	return success;
-}
-
 bool test_rm_rf(const char *path)
 {
-	if (!path) {
-		return false;
-	}
-
-	int fd = open(path, O_NOFOLLOW);
-	if (fd < 0) {
-		return false;
-	}
-
-	struct stat st = { 0 };
-	if (fstat(fd, &st) != 0) {
-		close(fd);
-		return false;
-	}
-
-	if (S_ISDIR(st.st_mode) && !rm_dir_contents(fd)) {
-		close(fd);
-		return false;
-	}
-
-	close(fd);
-	return (remove(path) == 0);
+	return remove_path(path);
 }
diff --git a/libtap/tap/files.h b/libtap/tap/files.h
index 9461e5a41fac1551bb70d51cbc96ef3cf9ee317e..bfc609058d55f5826af475cbbb94e944e1161c57 100644
--- a/libtap/tap/files.h
+++ b/libtap/tap/files.h
@@ -38,5 +38,7 @@ char *test_mkdtemp(void);
 
 /*!
  * \brief Delete file or directory (recursive).
+ *
+ * \return true on success, false when one or more files failed to be removed.
  */
 bool test_rm_rf(const char *path);
diff --git a/src/Makefile.am b/src/Makefile.am
index cd55fcbeef5ea8d6ac518c42358a581377ab43ed..2ae6af53ffb00891445c3b954942f2909cdfeb99 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -42,6 +42,8 @@ libcontrib_la_SOURCES = 			\
 	contrib/base64.c			\
 	contrib/base64.h			\
 	contrib/endian.h			\
+	contrib/files.c				\
+	contrib/files.h				\
 	contrib/getline.c			\
 	contrib/getline.h			\
 	contrib/hhash.c				\
diff --git a/src/contrib/files.c b/src/contrib/files.c
new file mode 100644
index 0000000000000000000000000000000000000000..8aee482c737e05da11f2a371682ddbfe10cbc045
--- /dev/null
+++ b/src/contrib/files.c
@@ -0,0 +1,90 @@
+/*  Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "files.h"
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+static bool special_name(const char *name)
+{
+	return strcmp(name, ".") == 0 || strcmp(name, "..") == 0;
+}
+
+static bool rm_dir_contents(int dir_fd)
+{
+	DIR *dir = fdopendir(dir_fd);
+	if (!dir) {
+		return false;
+	}
+
+	bool success = true;
+
+	struct dirent *result = NULL;
+	while (success && (result = readdir(dir)) != NULL) {
+		if (special_name(result->d_name)) {
+			continue;
+		}
+
+		bool is_dir = result->d_type == DT_DIR;
+
+		if (is_dir) {
+			int sub = openat(dir_fd, result->d_name, O_NOFOLLOW);
+			success = rm_dir_contents(sub);
+			close(sub);
+		}
+
+		if (success) {
+			int flags = is_dir ? AT_REMOVEDIR : 0;
+			success = unlinkat(dir_fd, result->d_name, flags) == 0;
+		}
+	}
+
+	closedir(dir);
+
+	return success;
+}
+
+bool remove_path(const char *path)
+{
+	if (!path) {
+		return false;
+	}
+
+	int fd = open(path, O_NOFOLLOW);
+	if (fd < 0) {
+		return false;
+	}
+
+	struct stat st = { 0 };
+	if (fstat(fd, &st) != 0) {
+		close(fd);
+		return false;
+	}
+
+	if (S_ISDIR(st.st_mode) && !rm_dir_contents(fd)) {
+		close(fd);
+		return false;
+	}
+
+	close(fd);
+	return (remove(path) == 0);
+}
diff --git a/src/contrib/files.h b/src/contrib/files.h
new file mode 100644
index 0000000000000000000000000000000000000000..982988e62a3064c912f8e5967efcf1bfab8380af
--- /dev/null
+++ b/src/contrib/files.h
@@ -0,0 +1,26 @@
+/*  Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include <stdbool.h>
+
+/*!
+ * \brief Delete file or directory (recursive).
+ *
+ * \return true on success, false when one or more files failed to be removed.
+ */
+bool remove_path(const char *path);
diff --git a/src/knot/conf/base.c b/src/knot/conf/base.c
index d5865b9de33e65fe8aaa418c0aaedfbc4ffac395..8ed6ad6bf5a9728c6bd1e2bbe32405ca274fe3a1 100644
--- a/src/knot/conf/base.c
+++ b/src/knot/conf/base.c
@@ -14,10 +14,6 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include <dirent.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
 #include <urcu.h>
 
 #include "knot/conf/base.h"
@@ -29,6 +25,7 @@
 #include "libknot/libknot.h"
 #include "libknot/yparser/ypformat.h"
 #include "libknot/yparser/yptrafo.h"
+#include "contrib/files.h"
 #include "contrib/mempattern.h"
 #include "contrib/sockaddr.h"
 #include "contrib/string.h"
@@ -41,53 +38,6 @@ conf_t* conf(void) {
 	return s_conf;
 }
 
-static void rm_dir(const char *path)
-{
-	DIR *dir = opendir(path);
-	if (dir == NULL) {
-		CONF_LOG(LOG_WARNING, "failed to remove directory '%s'", path);
-		return;
-	}
-
-	// Prepare own dirent structure (see NOTES in man readdir_r).
-	size_t len = offsetof(struct dirent, d_name) +
-	             fpathconf(dirfd(dir), _PC_NAME_MAX) + 1;
-
-	struct dirent *entry = malloc(len);
-	if (entry == NULL) {
-		CONF_LOG(LOG_WARNING, "failed to remove directory '%s'", path);
-		closedir(dir);
-		return;
-	}
-	memset(entry, 0, len);
-
-	// Firstly, delete all files in the directory.
-	int ret;
-	struct dirent *result = NULL;
-	while ((ret = readdir_r(dir, entry, &result)) == 0 &&
-	       result != NULL) {
-		if (entry->d_name[0] == '.') {
-			continue;
-		}
-
-		char *file = sprintf_alloc("%s/%s", path, entry->d_name);
-		if (file == NULL) {
-			ret = KNOT_ENOMEM;
-			break;
-		}
-		remove(file);
-		free(file);
-	}
-
-	free(entry);
-	closedir(dir);
-
-	// Secondly, delete the directory if it is empty.
-	if (ret != 0 || remove(path) != 0) {
-		CONF_LOG(LOG_WARNING, "failed to remove whole directory '%s'", path);
-	}
-}
-
 static int init_and_check(
 	conf_t *conf,
 	conf_flag_t flags)
@@ -219,7 +169,9 @@ int conf_new(
 		ret = out->api->init(&out->db, out->mm, &lmdb_opts);
 
 		// Remove the database to ensure it is temporary.
-		rm_dir(lmdb_opts.path);
+		if (!remove_path(lmdb_opts.path)) {
+			CONF_LOG(LOG_WARNING, "failed to purge temporary directory '%s'", lmdb_opts.path);
+		}
 	} else {
 		// Set the specified database.
 		lmdb_opts.path = db_dir;