From: pcarana Date: Thu, 5 Dec 2019 01:13:36 +0000 (-0600) Subject: Add daemon to delete a whole directory, fix broken HTTP unit test X-Git-Tag: v1.2.0~44 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=6b79305163e52c96da64fab555ecca39a482a6ad;p=thirdparty%2FFORT-validator.git Add daemon to delete a whole directory, fix broken HTTP unit test --- diff --git a/src/Makefile.am b/src/Makefile.am index c1e09b47..d78bf133 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 index 00000000..cb066eec --- /dev/null +++ b/src/delete_dir_daemon.c @@ -0,0 +1,108 @@ +#define _XOPEN_SOURCE 500 + +#include "delete_dir_daemon.h" + +#include +#include +#include +#include +#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 index 00000000..fd93ba5e --- /dev/null +++ b/src/delete_dir_daemon.h @@ -0,0 +1,9 @@ +#ifndef SRC_DELETE_DIR_DAEMON_H_ +#define SRC_DELETE_DIR_DAEMON_H_ + +#include + +int delete_dir_daemon_start(pthread_t *, char const *); +void delete_dir_daemon_destroy(pthread_t); + +#endif /* SRC_DELETE_DIR_DAEMON_H_ */ diff --git a/test/http_test.c b/test/http_test.c index cb928f4a..765b722a 100644 --- a/test/http_test.c +++ b/test/http_test.c @@ -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