]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Add daemon to delete a whole directory, fix broken HTTP unit test
authorpcarana <pc.moreno2099@gmail.com>
Thu, 5 Dec 2019 01:13:36 +0000 (19:13 -0600)
committerpcarana <pc.moreno2099@gmail.com>
Thu, 5 Dec 2019 01:13:36 +0000 (19:13 -0600)
src/Makefile.am
src/delete_dir_daemon.c [new file with mode: 0644]
src/delete_dir_daemon.h [new file with mode: 0644]
test/http_test.c

index c1e09b47acce1e2f8b8fffea348bb4a561a3f131..d78bf133e2f81a3489cea23ca3102e5687c88163 100644 (file)
@@ -14,6 +14,7 @@ fort_SOURCES += clients.c clients.h
 fort_SOURCES += common.c common.h
 fort_SOURCES += config.h config.c
 fort_SOURCES += debug.h debug.c
+fort_SOURCES += delete_dir_daemon.h delete_dir_daemon.c
 fort_SOURCES += extension.h extension.c
 fort_SOURCES += file.h file.c
 fort_SOURCES += json_parser.c json_parser.h
diff --git a/src/delete_dir_daemon.c b/src/delete_dir_daemon.c
new file mode 100644 (file)
index 0000000..cb066ee
--- /dev/null
@@ -0,0 +1,108 @@
+#define _XOPEN_SOURCE 500
+
+#include "delete_dir_daemon.h"
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <ftw.h>
+#include <unistd.h>
+#include "common.h"
+#include "log.h"
+
+#define MAX_FD_ALLOWED 20
+
+static int
+remove_file(char const *location)
+{
+       if (remove(location))
+               return pr_errno(errno, "Couldn't delete file '%s'", location);
+       return 0;
+}
+
+static int
+remove_dir(char const *location)
+{
+       if (rmdir(location))
+               return pr_errno(errno, "Couldn't delete directory '%s'",
+                   location);
+       return 0;
+}
+
+static int
+traverse(char const *path, struct stat const *sb, int flag, struct FTW *ftwbuf)
+{
+       /*
+        * FTW_SLN:
+        *   Will never be present since FTW_PHYS flag is utilized
+        */
+       switch (flag) {
+       case FTW_DP:
+               return remove_dir(path);
+       case FTW_F:
+               return remove_file(path);
+       case FTW_DNR:
+               return pr_err("Can't access '%s', stop deletion.", path);
+       case FTW_NS:
+               return pr_err("Can't get information of '%s', stop deletion.",
+                   path);
+       case FTW_SL:
+               return pr_err("Can't delete '%s' since is a symbolic link, stop deletion.",
+                   path);
+       case FTW_D:
+               return pr_err("Can't delete '%s' dir before deleting its content.",
+                   path);
+       default:
+               return pr_warn("Unknown path flag %d, doing nothing to '%s'.",
+                   flag, path);
+       }
+}
+
+static void *
+remove_from_root(void *arg)
+{
+       char const *root = arg;
+       struct stat attr;
+       int error;
+
+       error = stat(root, &attr);
+       if (error) {
+               pr_errno(errno, "Error reading path '%s'", root);
+               return NULL;
+       }
+
+       if (!S_ISDIR(attr.st_mode)) {
+               pr_err("Path '%s' exists and is not a directory.", root);
+               return NULL;
+       }
+
+       error = nftw(root, traverse, MAX_FD_ALLOWED,
+           FTW_DEPTH|FTW_MOUNT|FTW_PHYS);
+       if (error) {
+               if (errno)
+                       pr_errno(errno, "Error deleting directory '%s'", root);
+               else
+                       pr_err("Couldn't delete directory '%s'", root);
+       }
+       return NULL;
+}
+
+/*
+ * Start the @thread that will delete every file under @path, @thread must be
+ * joined.
+ */
+int
+delete_dir_daemon_start(pthread_t *thread, char const *path)
+{
+       errno = pthread_create(thread, NULL, remove_from_root, (void *) path);
+       if (errno)
+               return -pr_errno(errno,
+                   "Could not spawn the update daemon thread");
+
+       return 0;
+}
+
+void
+delete_dir_daemon_destroy(pthread_t thread)
+{
+       close_thread(thread, "Delete dir");
+}
diff --git a/src/delete_dir_daemon.h b/src/delete_dir_daemon.h
new file mode 100644 (file)
index 0000000..fd93ba5
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef SRC_DELETE_DIR_DAEMON_H_
+#define SRC_DELETE_DIR_DAEMON_H_
+
+#include <pthread.h>
+
+int delete_dir_daemon_start(pthread_t *, char const *);
+void delete_dir_daemon_destroy(pthread_t);
+
+#endif /* SRC_DELETE_DIR_DAEMON_H_ */
index cb928f4acc836959af722ad636ce5d895c61be3b..765b722a90878c9d7387ce2dbbb9d274e134247e 100644 (file)
@@ -41,7 +41,7 @@ write_cb(unsigned char *content, size_t size, size_t nmemb, void *arg)
 }
 
 static int
-local_download(char const *url, struct response *resp)
+local_download(char const *url, long *response_code, struct response *resp)
 {
        struct http_handler handler;
        int error;
@@ -50,7 +50,7 @@ local_download(char const *url, struct response *resp)
        if (error)
                return error;
 
-       error = http_fetch(&handler, url, write_cb, resp);
+       error = http_fetch(&handler, url, response_code, write_cb, resp);
        http_easy_cleanup(&handler);
        return error;
 }
@@ -58,16 +58,22 @@ local_download(char const *url, struct response *resp)
 START_TEST(http_fetch_normal)
 {
        struct response resp;
+       long response_code;
        char const *url = "https://rrdp.ripe.net/notification.xml";
 
        init_response(&resp);
+       response_code = 0;
 
        ck_assert_int_eq(http_init(), 0);
-       ck_assert_int_eq(local_download(url, &resp), 0);
+       ck_assert_int_eq(local_download(url, &response_code, &resp), 0);
        ck_assert_int_gt(resp.size, 0);
 
        http_cleanup();
        free(resp.content);
+       if (response_code == 0)
+               ck_abort_msg("NO response code received");
+       else if (response_code >= HTTP_BAD_REQUEST)
+               ck_abort_msg("Received response code %ld", response_code);
 }
 END_TEST