From 16705acf810d33739795055c7876f6d55d685578 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Thu, 13 Feb 2020 21:48:42 +0100 Subject: [PATCH 01/10] added mountpoint factory interface --- include/webfuse/adapter/mountpoint.h | 28 ++++++++++++++++++++ include/webfuse/adapter/mountpoint_factory.h | 24 +++++++++++++++++ include/webfuse/adapter/server_config.h | 7 ++++- 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 include/webfuse/adapter/mountpoint.h create mode 100644 include/webfuse/adapter/mountpoint_factory.h diff --git a/include/webfuse/adapter/mountpoint.h b/include/webfuse/adapter/mountpoint.h new file mode 100644 index 0000000..9b1d57f --- /dev/null +++ b/include/webfuse/adapter/mountpoint.h @@ -0,0 +1,28 @@ +#ifndef WF_ADAPTER_MOUNTPOINT_H +#define WF_ADAPTER_MOUNTPOINT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_mountpoint; + +extern struct wf_mountpoint * +wf_mountpoint_create( + char const * path); + +extern void +wf_mountpoint_release( + struct wf_mountpoint * mountpoint); + +extern char const * +wf_mountpoint_get_path( + struct wf_mountpoint const * mountpoint); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/include/webfuse/adapter/mountpoint_factory.h b/include/webfuse/adapter/mountpoint_factory.h new file mode 100644 index 0000000..a265c6f --- /dev/null +++ b/include/webfuse/adapter/mountpoint_factory.h @@ -0,0 +1,24 @@ +#ifndef WF_ADAPTER_MOUNTPOINT_FACTORY_H +#define WF_ADAPTER_MOUNTPOINT_FACTORY_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_mountpoint; + +typedef struct wf_mountpoint * +wf_create_mountpoint_fn( + char const * filesystem, + void * user_data); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/include/webfuse/adapter/server_config.h b/include/webfuse/adapter/server_config.h index cc1b6d3..778cc8c 100644 --- a/include/webfuse/adapter/server_config.h +++ b/include/webfuse/adapter/server_config.h @@ -3,6 +3,7 @@ #include "webfuse/adapter/api.h" #include "webfuse/adapter/authenticate.h" +#include "webfuse/adapter/mountpoint_factory.h" #ifdef __cplusplus extern "C" @@ -16,11 +17,15 @@ extern WF_API struct wf_server_config * wf_server_config_create(void); extern WF_API void wf_server_config_dispose( struct wf_server_config * config); - extern WF_API void wf_server_config_set_mountpoint( struct wf_server_config * config, char const * mount_point); +extern WF_API void wf_server_config_set_mountpoint_factory( + struct wf_server_config * config, + wf_create_mountpoint_fn * create_mountpoint, + void * user_data); + extern WF_API void wf_server_config_set_documentroot( struct wf_server_config * config, char const * document_root); From e727a9a54d3505f911aee201cc3da0c545e7185a Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sat, 15 Feb 2020 15:11:35 +0100 Subject: [PATCH 02/10] added implementation of mountpoint --- cmake/unit_tests.cmake | 1 + cmake/webfuse_adapter.cmake | 1 + include/webfuse/adapter/mountpoint.h | 2 +- include/webfuse_adapter.h | 1 + lib/webfuse/adapter/api.c | 24 +++++++++++++++++++ lib/webfuse/adapter/impl/mountpoint.c | 34 +++++++++++++++++++++++++++ lib/webfuse/adapter/impl/mountpoint.h | 26 ++++++++++++++++++++ test/adapter/test_mountpoint.cc | 12 ++++++++++ 8 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 lib/webfuse/adapter/impl/mountpoint.c create mode 100644 lib/webfuse/adapter/impl/mountpoint.h create mode 100644 test/adapter/test_mountpoint.cc diff --git a/cmake/unit_tests.cmake b/cmake/unit_tests.cmake index 5af183a..b5ae7ad 100644 --- a/cmake/unit_tests.cmake +++ b/cmake/unit_tests.cmake @@ -26,6 +26,7 @@ add_executable(alltests test/adapter/test_credentials.cc test/adapter/test_authenticator.cc test/adapter/test_authenticators.cc + test/adapter/test_mountpoint.cc test/adapter/test_fuse_req.cc test/adapter/jsonrpc/test_util.cc test/adapter/jsonrpc/test_is_request.cc diff --git a/cmake/webfuse_adapter.cmake b/cmake/webfuse_adapter.cmake index 329a123..f970ef7 100644 --- a/cmake/webfuse_adapter.cmake +++ b/cmake/webfuse_adapter.cmake @@ -15,6 +15,7 @@ add_library(webfuse-adapter-static STATIC lib/webfuse/adapter/impl/authenticators.c lib/webfuse/adapter/impl/credentials.c lib/webfuse/adapter/impl/operations.c + lib/webfuse/adapter/impl/mountpoint.c lib/webfuse/adapter/impl/time/timepoint.c lib/webfuse/adapter/impl/time/timer.c lib/webfuse/adapter/impl/time/timeout_manager.c diff --git a/include/webfuse/adapter/mountpoint.h b/include/webfuse/adapter/mountpoint.h index 9b1d57f..0dba1cd 100644 --- a/include/webfuse/adapter/mountpoint.h +++ b/include/webfuse/adapter/mountpoint.h @@ -13,7 +13,7 @@ wf_mountpoint_create( char const * path); extern void -wf_mountpoint_release( +wf_mountpoint_dispose( struct wf_mountpoint * mountpoint); extern char const * diff --git a/include/webfuse_adapter.h b/include/webfuse_adapter.h index 8edad51..37c39c2 100644 --- a/include/webfuse_adapter.h +++ b/include/webfuse_adapter.h @@ -9,5 +9,6 @@ #include #include #include +#include #endif diff --git a/lib/webfuse/adapter/api.c b/lib/webfuse/adapter/api.c index af68a8e..370a55e 100644 --- a/lib/webfuse/adapter/api.c +++ b/lib/webfuse/adapter/api.c @@ -4,6 +4,7 @@ #include "webfuse/adapter/impl/server_protocol.h" #include "webfuse/adapter/impl/server_config.h" #include "webfuse/adapter/impl/credentials.h" +#include "webfuse/adapter/impl/mountpoint.h" // server @@ -134,3 +135,26 @@ char const * wf_credentials_get( { return wf_impl_credentials_get(credentials, key); } + +// mountpoint + +struct wf_mountpoint * +wf_mountpoint_create( + char const * path) +{ + return wf_impl_mountpoint_create(path); +} + +void +wf_mountpoint_dispose( + struct wf_mountpoint * mountpoint) +{ + wf_impl_mountpoint_dispose(mountpoint); +} + +char const * +wf_mountpoint_get_path( + struct wf_mountpoint const * mountpoint) +{ + return wf_impl_mountpoint_get_path(mountpoint); +} diff --git a/lib/webfuse/adapter/impl/mountpoint.c b/lib/webfuse/adapter/impl/mountpoint.c new file mode 100644 index 0000000..55535d6 --- /dev/null +++ b/lib/webfuse/adapter/impl/mountpoint.c @@ -0,0 +1,34 @@ +#include "webfuse/adapter/impl/mountpoint.h" + +#include +#include + +struct wf_mountpoint +{ + char * path; +}; + +struct wf_mountpoint * +wf_impl_mountpoint_create( + char const * path) +{ + struct wf_mountpoint * mountpoint = malloc(sizeof(struct wf_mountpoint)); + mountpoint->path = strdup(path); + + return mountpoint; +} + +void +wf_impl_mountpoint_dispose( + struct wf_mountpoint * mountpoint) +{ + free(mountpoint->path); + free(mountpoint); +} + +char const * +wf_impl_mountpoint_get_path( + struct wf_mountpoint const * mountpoint) +{ + return mountpoint->path; +} diff --git a/lib/webfuse/adapter/impl/mountpoint.h b/lib/webfuse/adapter/impl/mountpoint.h new file mode 100644 index 0000000..eb0145c --- /dev/null +++ b/lib/webfuse/adapter/impl/mountpoint.h @@ -0,0 +1,26 @@ +#ifndef WF_IMPL_MOUNTPOINT_H +#define WF_IMPL_MOUNTPOINT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern struct wf_mountpoint * +wf_impl_mountpoint_create( + char const * path); + +extern void +wf_impl_mountpoint_dispose( + struct wf_mountpoint * mountpoint); + +extern char const * +wf_impl_mountpoint_get_path( + struct wf_mountpoint const * mountpoint); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test/adapter/test_mountpoint.cc b/test/adapter/test_mountpoint.cc new file mode 100644 index 0000000..e21d176 --- /dev/null +++ b/test/adapter/test_mountpoint.cc @@ -0,0 +1,12 @@ +#include +#include "webfuse/adapter/mountpoint.h" + +TEST(mountpoint, get_path) +{ + wf_mountpoint * mountpoint = wf_mountpoint_create("/some/path"); + + ASSERT_NE(nullptr, mountpoint); + ASSERT_STREQ("/some/path", wf_mountpoint_get_path(mountpoint)); + + wf_mountpoint_dispose(mountpoint); +} From 6a94cea6f91497653900e6d6f36eef333bc314e8 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sat, 15 Feb 2020 15:50:32 +0100 Subject: [PATCH 03/10] added ondispose to mountpoint to allow custom cleanup --- include/webfuse/adapter/mountpoint.h | 9 +++++++ lib/webfuse/adapter/api.c | 8 ++++++ lib/webfuse/adapter/impl/mountpoint.c | 19 +++++++++++++++ lib/webfuse/adapter/impl/mountpoint.h | 6 +++++ test/adapter/test_mountpoint.cc | 35 ++++++++++++++++++++++++++- 5 files changed, 76 insertions(+), 1 deletion(-) diff --git a/include/webfuse/adapter/mountpoint.h b/include/webfuse/adapter/mountpoint.h index 0dba1cd..7936b83 100644 --- a/include/webfuse/adapter/mountpoint.h +++ b/include/webfuse/adapter/mountpoint.h @@ -8,6 +8,10 @@ extern "C" struct wf_mountpoint; +typedef void +wf_mountpoint_ondispose_fn( + struct wf_mountpoint * mountpoint); + extern struct wf_mountpoint * wf_mountpoint_create( char const * path); @@ -20,6 +24,11 @@ extern char const * wf_mountpoint_get_path( struct wf_mountpoint const * mountpoint); +extern void +wf_mountpoint_set_ondispose( + struct wf_mountpoint * mountpoint, + wf_mountpoint_ondispose_fn * ondispose); + #ifdef __cplusplus } #endif diff --git a/lib/webfuse/adapter/api.c b/lib/webfuse/adapter/api.c index 370a55e..64f55a3 100644 --- a/lib/webfuse/adapter/api.c +++ b/lib/webfuse/adapter/api.c @@ -158,3 +158,11 @@ wf_mountpoint_get_path( { return wf_impl_mountpoint_get_path(mountpoint); } + +void +wf_mountpoint_set_ondispose( + struct wf_mountpoint * mountpoint, + wf_mountpoint_ondispose_fn * ondispose) +{ + wf_impl_mountpoint_set_ondispose(mountpoint, ondispose); +} diff --git a/lib/webfuse/adapter/impl/mountpoint.c b/lib/webfuse/adapter/impl/mountpoint.c index 55535d6..ade1223 100644 --- a/lib/webfuse/adapter/impl/mountpoint.c +++ b/lib/webfuse/adapter/impl/mountpoint.c @@ -6,14 +6,23 @@ struct wf_mountpoint { char * path; + wf_mountpoint_ondispose_fn * ondispose; }; +static void wf_impl_mountpoint_default_ondispose( + struct wf_mountpoint * mountpoint) +{ + (void) mountpoint; + // empty +} + struct wf_mountpoint * wf_impl_mountpoint_create( char const * path) { struct wf_mountpoint * mountpoint = malloc(sizeof(struct wf_mountpoint)); mountpoint->path = strdup(path); + mountpoint->ondispose = &wf_impl_mountpoint_default_ondispose; return mountpoint; } @@ -22,6 +31,8 @@ void wf_impl_mountpoint_dispose( struct wf_mountpoint * mountpoint) { + mountpoint->ondispose(mountpoint); + free(mountpoint->path); free(mountpoint); } @@ -32,3 +43,11 @@ wf_impl_mountpoint_get_path( { return mountpoint->path; } + +void +wf_impl_mountpoint_set_ondispose( + struct wf_mountpoint * mountpoint, + wf_mountpoint_ondispose_fn * ondispose) +{ + mountpoint->ondispose = ondispose; +} diff --git a/lib/webfuse/adapter/impl/mountpoint.h b/lib/webfuse/adapter/impl/mountpoint.h index eb0145c..a7041f8 100644 --- a/lib/webfuse/adapter/impl/mountpoint.h +++ b/lib/webfuse/adapter/impl/mountpoint.h @@ -1,6 +1,8 @@ #ifndef WF_IMPL_MOUNTPOINT_H #define WF_IMPL_MOUNTPOINT_H +#include "webfuse/adapter/mountpoint.h" + #ifdef __cplusplus extern "C" { @@ -18,6 +20,10 @@ extern char const * wf_impl_mountpoint_get_path( struct wf_mountpoint const * mountpoint); +extern void +wf_impl_mountpoint_set_ondispose( + struct wf_mountpoint * mointpoint, + wf_mountpoint_ondispose_fn * ondispose); #ifdef __cplusplus } diff --git a/test/adapter/test_mountpoint.cc b/test/adapter/test_mountpoint.cc index e21d176..a3d82c6 100644 --- a/test/adapter/test_mountpoint.cc +++ b/test/adapter/test_mountpoint.cc @@ -1,12 +1,45 @@ #include +#include #include "webfuse/adapter/mountpoint.h" +namespace +{ + class MockMountpointDisposer + { + public: + MOCK_METHOD1(ondispose, void(wf_mountpoint * mountpoint)); + }; + + MockMountpointDisposer * global_disposer = nullptr; + + void ondispose(wf_mountpoint * mountpoint) + { + global_disposer->ondispose(mountpoint); + } +} + TEST(mountpoint, get_path) { wf_mountpoint * mountpoint = wf_mountpoint_create("/some/path"); - ASSERT_NE(nullptr, mountpoint); + ASSERT_STREQ("/some/path", wf_mountpoint_get_path(mountpoint)); wf_mountpoint_dispose(mountpoint); } + + + +TEST(mountpoint, ondispose) +{ + MockMountpointDisposer disposer; + global_disposer = &disposer; + + wf_mountpoint * mountpoint = wf_mountpoint_create("/some/path"); + ASSERT_NE(nullptr, mountpoint); + + wf_mountpoint_set_ondispose(mountpoint, ondispose); + EXPECT_CALL(disposer, ondispose(mountpoint)).Times(1); + + wf_mountpoint_dispose(mountpoint); +} \ No newline at end of file From cfadf85f49f16a1f3396950d3a3d72b13b3e47fb Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sun, 16 Feb 2020 04:02:23 +0100 Subject: [PATCH 04/10] added uuid mountpoint and factory --- cmake/webfuse_adapter.cmake | 2 + include/webfuse/adapter/mountpoint.h | 11 +- lib/webfuse/adapter/api.c | 7 +- lib/webfuse/adapter/impl/mountpoint.c | 28 ++-- lib/webfuse/adapter/impl/mountpoint.h | 7 +- lib/webfuse/adapter/impl/uuid_mountpoint.c | 123 ++++++++++++++++++ lib/webfuse/adapter/impl/uuid_mountpoint.h | 20 +++ .../adapter/impl/uuid_mountpoint_factory.c | 47 +++++++ .../adapter/impl/uuid_mountpoint_factory.h | 29 +++++ test/adapter/test_mountpoint.cc | 18 +-- 10 files changed, 259 insertions(+), 33 deletions(-) create mode 100644 lib/webfuse/adapter/impl/uuid_mountpoint.c create mode 100644 lib/webfuse/adapter/impl/uuid_mountpoint.h create mode 100644 lib/webfuse/adapter/impl/uuid_mountpoint_factory.c create mode 100644 lib/webfuse/adapter/impl/uuid_mountpoint_factory.h diff --git a/cmake/webfuse_adapter.cmake b/cmake/webfuse_adapter.cmake index f970ef7..aa343b7 100644 --- a/cmake/webfuse_adapter.cmake +++ b/cmake/webfuse_adapter.cmake @@ -16,6 +16,8 @@ add_library(webfuse-adapter-static STATIC lib/webfuse/adapter/impl/credentials.c lib/webfuse/adapter/impl/operations.c lib/webfuse/adapter/impl/mountpoint.c + lib/webfuse/adapter/impl/uuid_mountpoint_factory.c + lib/webfuse/adapter/impl/uuid_mountpoint.c lib/webfuse/adapter/impl/time/timepoint.c lib/webfuse/adapter/impl/time/timer.c lib/webfuse/adapter/impl/time/timeout_manager.c diff --git a/include/webfuse/adapter/mountpoint.h b/include/webfuse/adapter/mountpoint.h index 7936b83..62f59f3 100644 --- a/include/webfuse/adapter/mountpoint.h +++ b/include/webfuse/adapter/mountpoint.h @@ -9,8 +9,8 @@ extern "C" struct wf_mountpoint; typedef void -wf_mountpoint_ondispose_fn( - struct wf_mountpoint * mountpoint); +wf_mountpoint_userdata_dispose_fn( + void * user_data); extern struct wf_mountpoint * wf_mountpoint_create( @@ -25,9 +25,10 @@ wf_mountpoint_get_path( struct wf_mountpoint const * mountpoint); extern void -wf_mountpoint_set_ondispose( - struct wf_mountpoint * mountpoint, - wf_mountpoint_ondispose_fn * ondispose); +wf_mountpoint_set_userdata( + struct wf_mountpoint * mointpoint, + void * user_data, + wf_mountpoint_userdata_dispose_fn * dispose); #ifdef __cplusplus } diff --git a/lib/webfuse/adapter/api.c b/lib/webfuse/adapter/api.c index 64f55a3..2d1bac2 100644 --- a/lib/webfuse/adapter/api.c +++ b/lib/webfuse/adapter/api.c @@ -160,9 +160,10 @@ wf_mountpoint_get_path( } void -wf_mountpoint_set_ondispose( +wf_mountpoint_set_userdata( struct wf_mountpoint * mountpoint, - wf_mountpoint_ondispose_fn * ondispose) + void * user_data, + wf_mountpoint_userdata_dispose_fn * dispose) { - wf_impl_mountpoint_set_ondispose(mountpoint, ondispose); + wf_impl_mountpoint_set_userdata(mountpoint, user_data, dispose); } diff --git a/lib/webfuse/adapter/impl/mountpoint.c b/lib/webfuse/adapter/impl/mountpoint.c index ade1223..a459510 100644 --- a/lib/webfuse/adapter/impl/mountpoint.c +++ b/lib/webfuse/adapter/impl/mountpoint.c @@ -6,23 +6,18 @@ struct wf_mountpoint { char * path; - wf_mountpoint_ondispose_fn * ondispose; + void * user_data; + wf_mountpoint_userdata_dispose_fn * dispose; }; -static void wf_impl_mountpoint_default_ondispose( - struct wf_mountpoint * mountpoint) -{ - (void) mountpoint; - // empty -} - struct wf_mountpoint * wf_impl_mountpoint_create( char const * path) { struct wf_mountpoint * mountpoint = malloc(sizeof(struct wf_mountpoint)); mountpoint->path = strdup(path); - mountpoint->ondispose = &wf_impl_mountpoint_default_ondispose; + mountpoint->user_data = NULL; + mountpoint->dispose = NULL; return mountpoint; } @@ -31,7 +26,10 @@ void wf_impl_mountpoint_dispose( struct wf_mountpoint * mountpoint) { - mountpoint->ondispose(mountpoint); + if (NULL != mountpoint->dispose) + { + mountpoint->dispose(mountpoint->user_data); + } free(mountpoint->path); free(mountpoint); @@ -44,10 +42,12 @@ wf_impl_mountpoint_get_path( return mountpoint->path; } -void -wf_impl_mountpoint_set_ondispose( +extern void +wf_impl_mountpoint_set_userdata( struct wf_mountpoint * mountpoint, - wf_mountpoint_ondispose_fn * ondispose) + void * user_data, + wf_mountpoint_userdata_dispose_fn * dispose) { - mountpoint->ondispose = ondispose; + mountpoint->user_data = user_data; + mountpoint->dispose = dispose; } diff --git a/lib/webfuse/adapter/impl/mountpoint.h b/lib/webfuse/adapter/impl/mountpoint.h index a7041f8..77fc0ea 100644 --- a/lib/webfuse/adapter/impl/mountpoint.h +++ b/lib/webfuse/adapter/impl/mountpoint.h @@ -21,9 +21,10 @@ wf_impl_mountpoint_get_path( struct wf_mountpoint const * mountpoint); extern void -wf_impl_mountpoint_set_ondispose( - struct wf_mountpoint * mointpoint, - wf_mountpoint_ondispose_fn * ondispose); +wf_impl_mountpoint_set_userdata( + struct wf_mountpoint * mountpoint, + void * user_data, + wf_mountpoint_userdata_dispose_fn * dispose); #ifdef __cplusplus } diff --git a/lib/webfuse/adapter/impl/uuid_mountpoint.c b/lib/webfuse/adapter/impl/uuid_mountpoint.c new file mode 100644 index 0000000..1b0cd8a --- /dev/null +++ b/lib/webfuse/adapter/impl/uuid_mountpoint.c @@ -0,0 +1,123 @@ +#include "webfuse/adapter/impl/uuid_mountpoint.h" +#include "webfuse/adapter/impl/mountpoint.h" + +#include "webfuse/core/string.h" + +#include + +#include +#include +#include +#include + +#include +#include +#include + +struct wf_impl_uuid_mountpoint_data +{ + char * id; + char * filesystem_path; + char * default_path; + char * full_path; +}; + +static char * wf_impl_uuid_mountpoint_create_id(void) +{ + uuid_t uuid; + uuid_generate(uuid); + char id[UUID_STR_LEN]; + uuid_unparse(uuid, id); + + return strdup(id); +} + +static bool wf_impl_uuid_mountpoint_is_link_broken(char const * path, char const * id) +{ + bool result = false; + + char buffer[UUID_STR_LEN]; + ssize_t count = readlink(path, buffer, UUID_STR_LEN); + if ((0 < count) && (count < UUID_STR_LEN)) + { + buffer[count] = '\0'; + result = (0 == strcmp(buffer, id)); + } + + return result; +} + +static bool wf_impl_uuid_mountpoint_link_first_subdir( + char const * link_path, + char const * path) +{ + bool result = false; + DIR * dir = opendir(path); + if (NULL != dir) + { + struct dirent * entry = readdir(dir); + while (NULL != entry) + { + if ((DT_DIR == entry->d_type) && ('.' != entry->d_name[0])) + { + symlink(entry->d_name, link_path); + result = true; + break; + } + + entry = readdir(dir); + } + + closedir(dir); + } + + return result; +} + +static void +wf_impl_uuid_mountpoint_data_dispose( + void * user_data) +{ + struct wf_impl_uuid_mountpoint_data * data = user_data; + + rmdir(data->full_path); + + if (wf_impl_filesystem_is_link_broken(data->default_path, data->id)) + { + unlink(data->default_path); + + bool const success = wf_impl_filesystem_link_first_subdir(data->default_path, data->filesystem_path); + if (!success) + { + rmdir(data->filesystem_path); + } + } + + free(data->id); + free(data->filesystem_path); + free(data->default_path); + free(data->full_path); + free(data); +} + +struct wf_mountpoint * +wf_impl_uuid_mountpoint_create( + char const * root_path, + char const * filesystem) +{ + struct wf_impl_uuid_mountpoint_data * data = malloc(sizeof(struct wf_impl_uuid_mountpoint_data)); + data->filesystem_path = wf_create_string("%s/%s", root_path, filesystem); + mkdir(data->filesystem_path, 0755); + + data->id = wf_impl_uuid_mountpoint_create_id(); + char * full_path = wf_create_string("%s/%s/%s", root_path, filesystem, data->id); + mkdir(data->full_path, 0755); + + data->default_path = wf_create_string("%s/%s/default", root_path, data->filesystem_path); + symlink(data->id, data->default_path); + + struct wf_mountpoint * mountpoint = wf_impl_mountpoint_create(full_path); + wf_impl_mountpoint_set_userdata(mountpoint, data, &wf_impl_uuid_mountpoint_data_dispose); + + return mountpoint; +} diff --git a/lib/webfuse/adapter/impl/uuid_mountpoint.h b/lib/webfuse/adapter/impl/uuid_mountpoint.h new file mode 100644 index 0000000..7287be3 --- /dev/null +++ b/lib/webfuse/adapter/impl/uuid_mountpoint.h @@ -0,0 +1,20 @@ +#ifndef WF_IMPL_UUID_MOUNTPOINT_H +#define WF_IMPL_UUID_MOUNTPOINT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_mountpoint; + +extern struct wf_mountpoint * +wf_impl_uuid_mountpoint_create( + char const * root_path, + char const * filesystem); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/webfuse/adapter/impl/uuid_mountpoint_factory.c b/lib/webfuse/adapter/impl/uuid_mountpoint_factory.c new file mode 100644 index 0000000..f982f5b --- /dev/null +++ b/lib/webfuse/adapter/impl/uuid_mountpoint_factory.c @@ -0,0 +1,47 @@ +#include "webfuse/adapter/impl/uuid_mountpoint_factory.h" +#include "webfuse/adapter/impl/uuid_mountpoint.h" + +#include +#include +#include + +#include +#include + +struct wf_impl_uuid_mountpoint_factory +{ + char * root_path; +}; + +void * +wf_impl_uuid_mountpoint_factory_create( + char * root_path) +{ + mkdir(root_path, 0755); + + struct wf_impl_uuid_mountpoint_factory * factory = malloc(sizeof(struct wf_impl_uuid_mountpoint_factory)); + factory->root_path = strdup(root_path); + + return factory; +} + +void +wf_impl_uuid_mountpoint_factory_dispose( + void * user_data) +{ + struct wf_impl_uuid_mountpoint_factory * factory = user_data; + + rmdir(factory->root_path); + free(factory->root_path); + free(factory); +} + +struct wf_mountpoint * +wf_impl_uuid_mountpoint_factory_create_mountpoint( + char const * filesystem, + void * user_data) +{ + struct wf_impl_uuid_mountpoint_factory * factory = user_data; + + return wf_impl_uuid_mountpoint_create(factory->root_path, filesystem); +} diff --git a/lib/webfuse/adapter/impl/uuid_mountpoint_factory.h b/lib/webfuse/adapter/impl/uuid_mountpoint_factory.h new file mode 100644 index 0000000..a406597 --- /dev/null +++ b/lib/webfuse/adapter/impl/uuid_mountpoint_factory.h @@ -0,0 +1,29 @@ +#ifndef WF_IMPL_UUID_MOUNTPOINT_FACTORY_H +#define WF_IMPL_UUID_MOUNTPOINT_FACTORY_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wf_mountpoint; + +extern void * +wf_impl_uuid_mountpoint_factory_create( + char * root_path); + +extern void +wf_impl_uuid_mountpoint_factory_dispose( + void * user_data); + +extern struct wf_mountpoint * +wf_impl_uuid_mountpoint_factory_create_mountpiont( + char const * filesystem, + void * user_data); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test/adapter/test_mountpoint.cc b/test/adapter/test_mountpoint.cc index a3d82c6..6bb486b 100644 --- a/test/adapter/test_mountpoint.cc +++ b/test/adapter/test_mountpoint.cc @@ -4,17 +4,17 @@ namespace { - class MockMountpointDisposer + class MockUserDataDisposer { public: - MOCK_METHOD1(ondispose, void(wf_mountpoint * mountpoint)); + MOCK_METHOD1(dispose, void(void * mountpoint)); }; - MockMountpointDisposer * global_disposer = nullptr; + MockUserDataDisposer * global_disposer = nullptr; - void ondispose(wf_mountpoint * mountpoint) + void ondispose(void * user_data) { - global_disposer->ondispose(mountpoint); + global_disposer->dispose(user_data); } } @@ -32,14 +32,16 @@ TEST(mountpoint, get_path) TEST(mountpoint, ondispose) { - MockMountpointDisposer disposer; + MockUserDataDisposer disposer; global_disposer = &disposer; wf_mountpoint * mountpoint = wf_mountpoint_create("/some/path"); ASSERT_NE(nullptr, mountpoint); - wf_mountpoint_set_ondispose(mountpoint, ondispose); - EXPECT_CALL(disposer, ondispose(mountpoint)).Times(1); + int value = 42; + void * user_data = reinterpret_cast(&value); + wf_mountpoint_set_userdata(mountpoint, user_data, ondispose); + EXPECT_CALL(disposer, dispose(user_data)).Times(1); wf_mountpoint_dispose(mountpoint); } \ No newline at end of file From 096c24444596a38d072ed070bf359fd285132160 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sun, 16 Feb 2020 14:47:21 +0100 Subject: [PATCH 05/10] added unit tests for uuid_mountpoint --- cmake/unit_tests.cmake | 2 + lib/webfuse/adapter/impl/uuid_mountpoint.c | 10 +- test/adapter/test_uuid_mountpoint.cc | 102 +++++++++++++++++++++ test/tempdir.cc | 33 +++++++ test/tempdir.hpp | 21 +++++ 5 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 test/adapter/test_uuid_mountpoint.cc create mode 100644 test/tempdir.cc create mode 100644 test/tempdir.hpp diff --git a/cmake/unit_tests.cmake b/cmake/unit_tests.cmake index b5ae7ad..1301b15 100644 --- a/cmake/unit_tests.cmake +++ b/cmake/unit_tests.cmake @@ -7,6 +7,7 @@ include(GoogleTest) pkg_check_modules(GMOCK gmock) add_executable(alltests + test/tempdir.cc test/msleep.cc test/die_if.cc test/mock_authenticator.cc @@ -27,6 +28,7 @@ add_executable(alltests test/adapter/test_authenticator.cc test/adapter/test_authenticators.cc test/adapter/test_mountpoint.cc + test/adapter/test_uuid_mountpoint.cc test/adapter/test_fuse_req.cc test/adapter/jsonrpc/test_util.cc test/adapter/jsonrpc/test_is_request.cc diff --git a/lib/webfuse/adapter/impl/uuid_mountpoint.c b/lib/webfuse/adapter/impl/uuid_mountpoint.c index 1b0cd8a..eafa444 100644 --- a/lib/webfuse/adapter/impl/uuid_mountpoint.c +++ b/lib/webfuse/adapter/impl/uuid_mountpoint.c @@ -82,11 +82,11 @@ wf_impl_uuid_mountpoint_data_dispose( rmdir(data->full_path); - if (wf_impl_filesystem_is_link_broken(data->default_path, data->id)) + if (wf_impl_uuid_mountpoint_is_link_broken(data->default_path, data->id)) { unlink(data->default_path); - bool const success = wf_impl_filesystem_link_first_subdir(data->default_path, data->filesystem_path); + bool const success = wf_impl_uuid_mountpoint_link_first_subdir(data->default_path, data->filesystem_path); if (!success) { rmdir(data->filesystem_path); @@ -110,13 +110,13 @@ wf_impl_uuid_mountpoint_create( mkdir(data->filesystem_path, 0755); data->id = wf_impl_uuid_mountpoint_create_id(); - char * full_path = wf_create_string("%s/%s/%s", root_path, filesystem, data->id); + data->full_path = wf_create_string("%s/%s/%s", root_path, filesystem, data->id); mkdir(data->full_path, 0755); - data->default_path = wf_create_string("%s/%s/default", root_path, data->filesystem_path); + data->default_path = wf_create_string("%s/%s/default", root_path, filesystem); symlink(data->id, data->default_path); - struct wf_mountpoint * mountpoint = wf_impl_mountpoint_create(full_path); + struct wf_mountpoint * mountpoint = wf_impl_mountpoint_create(data->full_path); wf_impl_mountpoint_set_userdata(mountpoint, data, &wf_impl_uuid_mountpoint_data_dispose); return mountpoint; diff --git a/test/adapter/test_uuid_mountpoint.cc b/test/adapter/test_uuid_mountpoint.cc new file mode 100644 index 0000000..cfa4000 --- /dev/null +++ b/test/adapter/test_uuid_mountpoint.cc @@ -0,0 +1,102 @@ +#include + +#include +#include +#include + +#include "tempdir.hpp" +#include "webfuse_adapter.h" +#include "webfuse/adapter/impl/uuid_mountpoint.h" + +#include + +using webfuse_test::TempDir; + +namespace +{ + bool is_dir(std::string const & path) + { + struct stat info; + int rc = stat(path.c_str(), &info); + + return (0 == rc) && (S_ISDIR(info.st_mode)); + } + + bool is_symlink(std::string const & path) + { + struct stat info; + int rc = lstat(path.c_str(), &info); + + return (0 == rc) && (S_ISLNK(info.st_mode)); + } + + bool is_same_path(std::string const & path, std::string const & other) + { + struct stat info; + int rc = stat(path.c_str(), &info); + + struct stat info_other; + int rc_other = stat(other.c_str(), &info_other); + + return (0 == rc) && (0 == rc_other) && (info.st_ino == info_other.st_ino); + } +} + +TEST(uuid_mountpoint, create) +{ + TempDir temp("uuid_mountpoint"); + + std::string filesystem_path = std::string(temp.path()) + "/dummy"; + std::string default_path = std::string(temp.path()) + "/dummy/default"; + + wf_mountpoint * mountpoint = wf_impl_uuid_mountpoint_create(temp.path(), "dummy"); + std::string path = wf_mountpoint_get_path(mountpoint); + ASSERT_NE(nullptr, mountpoint); + ASSERT_TRUE(is_dir(filesystem_path)); + ASSERT_TRUE(is_symlink(default_path)); + ASSERT_TRUE(is_dir(default_path)); + ASSERT_TRUE(is_dir(path)); + ASSERT_TRUE(is_same_path(default_path, path)); + + wf_mountpoint_dispose(mountpoint); + ASSERT_FALSE(is_dir(filesystem_path)); + ASSERT_FALSE(is_symlink(default_path)); + ASSERT_FALSE(is_dir(default_path)); + ASSERT_FALSE(is_dir(path)); +} + +TEST(uuid_mountpoint, relink_default) +{ + TempDir temp("uuid_mountpoint"); + + std::string filesystem_path = std::string(temp.path()) + "/dummy"; + std::string default_path = std::string(temp.path()) + "/dummy/default"; + + wf_mountpoint * mountpoint_a = wf_impl_uuid_mountpoint_create(temp.path(), "dummy"); + std::string path_a = wf_mountpoint_get_path(mountpoint_a); + + wf_mountpoint * mountpoint_b = wf_impl_uuid_mountpoint_create(temp.path(), "dummy"); + std::string path_b = wf_mountpoint_get_path(mountpoint_b); + + ASSERT_TRUE(is_dir(filesystem_path)); + ASSERT_TRUE(is_symlink(default_path)); + ASSERT_TRUE(is_dir(default_path)); + ASSERT_TRUE(is_dir(path_a)); + ASSERT_TRUE(is_dir(path_b)); + ASSERT_TRUE(is_same_path(default_path, path_a)); + + wf_mountpoint_dispose(mountpoint_a); + ASSERT_TRUE(is_dir(filesystem_path)); + ASSERT_TRUE(is_symlink(default_path)); + ASSERT_TRUE(is_dir(default_path)); + ASSERT_FALSE(is_dir(path_a)); + ASSERT_TRUE(is_dir(path_b)); + ASSERT_TRUE(is_same_path(default_path, path_b)); + + wf_mountpoint_dispose(mountpoint_b); + ASSERT_FALSE(is_dir(filesystem_path)); + ASSERT_FALSE(is_symlink(default_path)); + ASSERT_FALSE(is_dir(default_path)); + ASSERT_FALSE(is_dir(path_a)); + ASSERT_FALSE(is_dir(path_b)); +} diff --git a/test/tempdir.cc b/test/tempdir.cc new file mode 100644 index 0000000..040aed1 --- /dev/null +++ b/test/tempdir.cc @@ -0,0 +1,33 @@ +#include "webfuse/core/string.h" +#include "tempdir.hpp" + +#include +#include +#include + +namespace webfuse_test +{ + +TempDir::TempDir(char const * prefix) +: path_(wf_create_string("/tmp/%s_XXXXXX", prefix)) +{ + char * result = mkdtemp(path_); + if (NULL == result) + { + throw std::runtime_error("unable to create temp dir"); + } +} + +TempDir::~TempDir() +{ + rmdir(path_); + free(path_); +} + +char const * TempDir::path() +{ + return path_; +} + + +} \ No newline at end of file diff --git a/test/tempdir.hpp b/test/tempdir.hpp new file mode 100644 index 0000000..0c28a80 --- /dev/null +++ b/test/tempdir.hpp @@ -0,0 +1,21 @@ +#ifndef WF_TEST_TEMPDIR_HPP +#define WF_TEST_TEMPDIR_HPP + +namespace webfuse_test +{ + +class TempDir +{ + TempDir(TempDir const &) = delete; + TempDir & operator=(TempDir const &) = delete; +public: + TempDir(char const * prefix); + ~TempDir(); + char const * path(); +private: + char * path_; +}; + +} + +#endif From 2b91f159cf278850444645f910393435b761b169 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sun, 16 Feb 2020 17:33:11 +0100 Subject: [PATCH 06/10] added unit tests of uuid_mountpoint_factory --- cmake/unit_tests.cmake | 2 + .../adapter/impl/uuid_mountpoint_factory.c | 30 ++++++++-- .../adapter/impl/uuid_mountpoint_factory.h | 4 +- test/adapter/test_uuid_mountpoint.cc | 38 ++---------- test/adapter/test_uuid_mountpoint_factory.cc | 60 +++++++++++++++++++ test/file_utils.cc | 38 ++++++++++++ test/file_utils.hpp | 17 ++++++ 7 files changed, 148 insertions(+), 41 deletions(-) create mode 100644 test/adapter/test_uuid_mountpoint_factory.cc create mode 100644 test/file_utils.cc create mode 100644 test/file_utils.hpp diff --git a/cmake/unit_tests.cmake b/cmake/unit_tests.cmake index 1301b15..933d78e 100644 --- a/cmake/unit_tests.cmake +++ b/cmake/unit_tests.cmake @@ -8,6 +8,7 @@ pkg_check_modules(GMOCK gmock) add_executable(alltests test/tempdir.cc + test/file_utils.cc test/msleep.cc test/die_if.cc test/mock_authenticator.cc @@ -29,6 +30,7 @@ add_executable(alltests test/adapter/test_authenticators.cc test/adapter/test_mountpoint.cc test/adapter/test_uuid_mountpoint.cc + test/adapter/test_uuid_mountpoint_factory.cc test/adapter/test_fuse_req.cc test/adapter/jsonrpc/test_util.cc test/adapter/jsonrpc/test_is_request.cc diff --git a/lib/webfuse/adapter/impl/uuid_mountpoint_factory.c b/lib/webfuse/adapter/impl/uuid_mountpoint_factory.c index f982f5b..1f28e64 100644 --- a/lib/webfuse/adapter/impl/uuid_mountpoint_factory.c +++ b/lib/webfuse/adapter/impl/uuid_mountpoint_factory.c @@ -7,20 +7,36 @@ #include #include +#include struct wf_impl_uuid_mountpoint_factory { char * root_path; + bool root_created; }; void * wf_impl_uuid_mountpoint_factory_create( - char * root_path) + char const * root_path) { - mkdir(root_path, 0755); + struct wf_impl_uuid_mountpoint_factory * factory = NULL; + bool root_created = false; + + struct stat info; + int rc = stat(root_path, &info); + if ((0 != rc) || (!S_ISDIR(info.st_mode))) + { + rc = mkdir(root_path, 0755); + root_created = true; + } + + if (0 == rc) + { + factory = malloc(sizeof(struct wf_impl_uuid_mountpoint_factory)); + factory->root_path = strdup(root_path); + factory->root_created = root_created; + } - struct wf_impl_uuid_mountpoint_factory * factory = malloc(sizeof(struct wf_impl_uuid_mountpoint_factory)); - factory->root_path = strdup(root_path); return factory; } @@ -31,7 +47,11 @@ wf_impl_uuid_mountpoint_factory_dispose( { struct wf_impl_uuid_mountpoint_factory * factory = user_data; - rmdir(factory->root_path); + if (factory->root_created) + { + rmdir(factory->root_path); + } + free(factory->root_path); free(factory); } diff --git a/lib/webfuse/adapter/impl/uuid_mountpoint_factory.h b/lib/webfuse/adapter/impl/uuid_mountpoint_factory.h index a406597..52d5c57 100644 --- a/lib/webfuse/adapter/impl/uuid_mountpoint_factory.h +++ b/lib/webfuse/adapter/impl/uuid_mountpoint_factory.h @@ -10,14 +10,14 @@ struct wf_mountpoint; extern void * wf_impl_uuid_mountpoint_factory_create( - char * root_path); + char const * root_path); extern void wf_impl_uuid_mountpoint_factory_dispose( void * user_data); extern struct wf_mountpoint * -wf_impl_uuid_mountpoint_factory_create_mountpiont( +wf_impl_uuid_mountpoint_factory_create_mountpoint( char const * filesystem, void * user_data); diff --git a/test/adapter/test_uuid_mountpoint.cc b/test/adapter/test_uuid_mountpoint.cc index cfa4000..8bff760 100644 --- a/test/adapter/test_uuid_mountpoint.cc +++ b/test/adapter/test_uuid_mountpoint.cc @@ -1,46 +1,16 @@ #include -#include -#include -#include - #include "tempdir.hpp" +#include "file_utils.hpp" #include "webfuse_adapter.h" #include "webfuse/adapter/impl/uuid_mountpoint.h" #include using webfuse_test::TempDir; - -namespace -{ - bool is_dir(std::string const & path) - { - struct stat info; - int rc = stat(path.c_str(), &info); - - return (0 == rc) && (S_ISDIR(info.st_mode)); - } - - bool is_symlink(std::string const & path) - { - struct stat info; - int rc = lstat(path.c_str(), &info); - - return (0 == rc) && (S_ISLNK(info.st_mode)); - } - - bool is_same_path(std::string const & path, std::string const & other) - { - struct stat info; - int rc = stat(path.c_str(), &info); - - struct stat info_other; - int rc_other = stat(other.c_str(), &info_other); - - return (0 == rc) && (0 == rc_other) && (info.st_ino == info_other.st_ino); - } -} +using webfuse_test::is_dir; +using webfuse_test::is_symlink; +using webfuse_test::is_same_path; TEST(uuid_mountpoint, create) { diff --git a/test/adapter/test_uuid_mountpoint_factory.cc b/test/adapter/test_uuid_mountpoint_factory.cc new file mode 100644 index 0000000..abb0b27 --- /dev/null +++ b/test/adapter/test_uuid_mountpoint_factory.cc @@ -0,0 +1,60 @@ +#include +#include "webfuse_adapter.h" +#include "webfuse/adapter/impl/uuid_mountpoint_factory.h" +#include "tempdir.hpp" +#include "file_utils.hpp" + +using webfuse_test::TempDir; +using webfuse_test::is_dir; + +TEST(uuid_mountpoint_factory, create_existing_dir) +{ + TempDir temp("uuid_mountpoint_factory"); + + void * factory = wf_impl_uuid_mountpoint_factory_create(temp.path()); + ASSERT_NE(nullptr, factory); + ASSERT_TRUE(is_dir(temp.path())); + + wf_mountpoint * mountpoint = wf_impl_uuid_mountpoint_factory_create_mountpoint("dummy", factory); + std::string path = wf_mountpoint_get_path(mountpoint); + ASSERT_NE(nullptr, factory); + ASSERT_TRUE(is_dir(path)); + + wf_mountpoint_dispose(mountpoint); + ASSERT_FALSE(is_dir(path)); + + wf_impl_uuid_mountpoint_factory_dispose(factory); + // keep dir not created by factory + ASSERT_TRUE(is_dir(temp.path())); +} + +TEST(uuid_mountpoint_factory, create_nonexisting_dir) +{ + TempDir temp("uuid_mountpoint_factory"); + std::string root_path = std::string(temp.path()) + "/root"; + + void * factory = wf_impl_uuid_mountpoint_factory_create(root_path.c_str()); + ASSERT_NE(nullptr, factory); + ASSERT_TRUE(is_dir(root_path)); + + wf_mountpoint * mountpoint = wf_impl_uuid_mountpoint_factory_create_mountpoint("dummy", factory); + std::string path = wf_mountpoint_get_path(mountpoint); + ASSERT_NE(nullptr, factory); + ASSERT_TRUE(is_dir(path)); + + wf_mountpoint_dispose(mountpoint); + ASSERT_FALSE(is_dir(path)); + + wf_impl_uuid_mountpoint_factory_dispose(factory); + // remove dir, created by factory + ASSERT_FALSE(is_dir(root_path)); +} + +TEST(uuid_mountpoint_factory, fail_to_created_nested_dir) +{ + TempDir temp("uuid_mountpoint_factory"); + std::string root_path = std::string(temp.path()) + "/nested/root"; + + void * factory = wf_impl_uuid_mountpoint_factory_create(root_path.c_str()); + ASSERT_EQ(nullptr, factory); +} \ No newline at end of file diff --git a/test/file_utils.cc b/test/file_utils.cc new file mode 100644 index 0000000..0d3ff81 --- /dev/null +++ b/test/file_utils.cc @@ -0,0 +1,38 @@ +#include "file_utils.hpp" + +#include +#include +#include + +namespace webfuse_test +{ + +bool is_dir(std::string const & path) +{ + struct stat info; + int rc = stat(path.c_str(), &info); + + return (0 == rc) && (S_ISDIR(info.st_mode)); +} + +bool is_symlink(std::string const & path) +{ + struct stat info; + int rc = lstat(path.c_str(), &info); + + return (0 == rc) && (S_ISLNK(info.st_mode)); +} + +bool is_same_path(std::string const & path, std::string const & other) +{ + struct stat info; + int rc = stat(path.c_str(), &info); + + struct stat info_other; + int rc_other = stat(other.c_str(), &info_other); + + return (0 == rc) && (0 == rc_other) && (info.st_ino == info_other.st_ino); +} + + +} \ No newline at end of file diff --git a/test/file_utils.hpp b/test/file_utils.hpp new file mode 100644 index 0000000..0c8cbc1 --- /dev/null +++ b/test/file_utils.hpp @@ -0,0 +1,17 @@ +#ifndef WF_TEST_FILE_UTILS_HPP +#define WF_TEST_FILE_UTILS_HPP + +#include + +namespace webfuse_test +{ + +bool is_dir(std::string const & path); + +bool is_symlink(std::string const & path); + +bool is_same_path(std::string const & path, std::string const & other); + +} + +#endif From 77627b7c8b4aef842a89be323afbff5c258ad26c Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sun, 16 Feb 2020 21:03:17 +0100 Subject: [PATCH 07/10] integrated uuid_mountpoint_factory --- cmake/webfuse_adapter.cmake | 1 + include/webfuse/adapter/server_protocol.h | 5 + lib/webfuse/adapter/api.c | 16 ++++ lib/webfuse/adapter/impl/filesystem.c | 92 ++----------------- lib/webfuse/adapter/impl/filesystem.h | 10 +- lib/webfuse/adapter/impl/mountpoint_factory.c | 67 ++++++++++++++ lib/webfuse/adapter/impl/mountpoint_factory.h | 61 ++++++++++++ lib/webfuse/adapter/impl/server.c | 24 +---- lib/webfuse/adapter/impl/server_config.c | 22 ++++- lib/webfuse/adapter/impl/server_config.h | 8 +- lib/webfuse/adapter/impl/server_protocol.c | 37 ++++++-- lib/webfuse/adapter/impl/server_protocol.h | 9 +- lib/webfuse/adapter/impl/session.c | 33 +++++-- lib/webfuse/adapter/impl/session.h | 5 +- lib/webfuse/adapter/impl/session_manager.c | 6 +- lib/webfuse/adapter/impl/session_manager.h | 4 +- .../adapter/impl/uuid_mountpoint_factory.c | 27 +++++- .../adapter/impl/uuid_mountpoint_factory.h | 20 ++-- test/adapter/test_uuid_mountpoint_factory.cc | 25 ++--- 19 files changed, 304 insertions(+), 168 deletions(-) create mode 100644 lib/webfuse/adapter/impl/mountpoint_factory.c create mode 100644 lib/webfuse/adapter/impl/mountpoint_factory.h diff --git a/cmake/webfuse_adapter.cmake b/cmake/webfuse_adapter.cmake index aa343b7..269204d 100644 --- a/cmake/webfuse_adapter.cmake +++ b/cmake/webfuse_adapter.cmake @@ -16,6 +16,7 @@ add_library(webfuse-adapter-static STATIC lib/webfuse/adapter/impl/credentials.c lib/webfuse/adapter/impl/operations.c lib/webfuse/adapter/impl/mountpoint.c + lib/webfuse/adapter/impl/mountpoint_factory.c lib/webfuse/adapter/impl/uuid_mountpoint_factory.c lib/webfuse/adapter/impl/uuid_mountpoint.c lib/webfuse/adapter/impl/time/timepoint.c diff --git a/include/webfuse/adapter/server_protocol.h b/include/webfuse/adapter/server_protocol.h index d77cbc3..6491a05 100644 --- a/include/webfuse/adapter/server_protocol.h +++ b/include/webfuse/adapter/server_protocol.h @@ -3,6 +3,7 @@ #include #include +#include #ifdef __cplusplus extern "C" @@ -15,6 +16,10 @@ struct lws_protocols; extern WF_API struct wf_server_protocol * wf_server_protocol_create( char * mount_point); +extern WF_API struct wf_server_protocol * wf_server_protocol_create2( + wf_create_mountpoint_fn * create_mountpoint, + void * create_mountpoint_context); + extern WF_API void wf_server_protocol_dispose( struct wf_server_protocol * protocol); diff --git a/lib/webfuse/adapter/api.c b/lib/webfuse/adapter/api.c index 2d1bac2..adecac2 100644 --- a/lib/webfuse/adapter/api.c +++ b/lib/webfuse/adapter/api.c @@ -35,6 +35,13 @@ struct wf_server_protocol * wf_server_protocol_create( return wf_impl_server_protocol_create(mount_point); } +struct wf_server_protocol * wf_server_protocol_create2( + wf_create_mountpoint_fn * create_mountpoint, + void * create_mountpoint_context) +{ + return wf_impl_server_protocol_create2(create_mountpoint, create_mountpoint_context); +} + void wf_server_protocol_dispose( struct wf_server_protocol * protocol) { @@ -77,6 +84,15 @@ void wf_server_config_set_mountpoint( wf_impl_server_config_set_mountpoint(config, mount_point); } +void wf_server_config_set_mountpoint_factory( + struct wf_server_config * config, + wf_create_mountpoint_fn * create_mountpoint, + void * user_data) +{ + wf_impl_server_config_set_mountpoint_factory( + config, create_mountpoint, user_data); +} + void wf_server_config_set_documentroot( struct wf_server_config * config, char const * document_root) diff --git a/lib/webfuse/adapter/impl/filesystem.c b/lib/webfuse/adapter/impl/filesystem.c index 3cfcca7..e4a3435 100644 --- a/lib/webfuse/adapter/impl/filesystem.c +++ b/lib/webfuse/adapter/impl/filesystem.c @@ -1,6 +1,7 @@ #include "webfuse/adapter/impl/filesystem.h" #include "webfuse/adapter/impl/operations.h" #include "webfuse/adapter/impl/session.h" +#include "webfuse/adapter/impl/mountpoint.h" #include "webfuse/core/string.h" @@ -27,58 +28,6 @@ static struct fuse_lowlevel_ops const filesystem_operations = .read = &wf_impl_operation_read }; -static char * wf_impl_filesystem_create_id(void) -{ - uuid_t uuid; - uuid_generate(uuid); - char id[UUID_STR_LEN]; - uuid_unparse(uuid, id); - - return strdup(id); -} - -static bool wf_impl_filesystem_is_link_broken(char const * path, char const * id) -{ - bool result = false; - - char buffer[UUID_STR_LEN]; - ssize_t count = readlink(path, buffer, UUID_STR_LEN); - if ((0 < count) && (count < UUID_STR_LEN)) - { - buffer[count] = '\0'; - result = (0 == strcmp(buffer, id)); - } - - return result; -} - -static bool wf_impl_filesystem_link_first_subdir( - char const * link_path, - char const * path) -{ - bool result = false; - DIR * dir = opendir(path); - if (NULL != dir) - { - struct dirent * entry = readdir(dir); - while (NULL != entry) - { - if ((DT_DIR == entry->d_type) && ('.' != entry->d_name[0])) - { - symlink(entry->d_name, link_path); - result = true; - break; - } - - entry = readdir(dir); - } - - closedir(dir); - } - - return result; -} - static void wf_impl_filesystem_cleanup( struct wf_impl_filesystem * filesystem) { @@ -90,32 +39,17 @@ static void wf_impl_filesystem_cleanup( free(filesystem->buffer.mem); fuse_opt_free_args(&filesystem->args); - rmdir(filesystem->root_path); - - if (wf_impl_filesystem_is_link_broken(filesystem->default_path, filesystem->id)) - { - unlink(filesystem->default_path); - - bool const success = wf_impl_filesystem_link_first_subdir(filesystem->default_path, filesystem->service_path); - if (!success) - { - rmdir(filesystem->service_path); - } - } - + wf_mountpoint_dispose(filesystem->mountpoint); free(filesystem->user_data.name); - free(filesystem->id); - free(filesystem->root_path); - free(filesystem->default_path); - free(filesystem->service_path); } static bool wf_impl_filesystem_init( struct wf_impl_filesystem * filesystem, struct wf_impl_session * session, - char const * name) + char const * name, + struct wf_mountpoint * mountpoint) { bool result = false; @@ -129,15 +63,7 @@ static bool wf_impl_filesystem_init( filesystem->user_data.name = strdup(name); memset(&filesystem->buffer, 0, sizeof(struct fuse_buf)); - filesystem->service_path = wf_create_string("%s/%s", session->mount_point, name); - mkdir(filesystem->service_path, 0755); - - filesystem->id = wf_impl_filesystem_create_id(); - filesystem->root_path = wf_create_string("%s/%s/%s", session->mount_point, name, filesystem->id); - mkdir(filesystem->root_path, 0755); - - filesystem->default_path = wf_create_string("%s/%s/default", session->mount_point, name); - symlink(filesystem->id, filesystem->default_path); + filesystem->mountpoint = mountpoint; filesystem->session = fuse_session_new( &filesystem->args, @@ -146,7 +72,8 @@ static bool wf_impl_filesystem_init( &filesystem->user_data); if (NULL != filesystem->session) { - result = (0 == fuse_session_mount(filesystem->session, filesystem->root_path)); + char const * path = wf_mountpoint_get_path(filesystem->mountpoint); + result = (0 == fuse_session_mount(filesystem->session, path)); } if (result) @@ -169,12 +96,13 @@ static bool wf_impl_filesystem_init( struct wf_impl_filesystem * wf_impl_filesystem_create( struct wf_impl_session * session, - char const * name) + char const * name, + struct wf_mountpoint * mountpoint) { struct wf_impl_filesystem * filesystem = malloc(sizeof(struct wf_impl_filesystem)); if (NULL != filesystem) { - bool success = wf_impl_filesystem_init(filesystem, session, name); + bool success = wf_impl_filesystem_init(filesystem, session, name, mountpoint); if (!success) { free(filesystem); diff --git a/lib/webfuse/adapter/impl/filesystem.h b/lib/webfuse/adapter/impl/filesystem.h index 648dfbd..83660d8 100644 --- a/lib/webfuse/adapter/impl/filesystem.h +++ b/lib/webfuse/adapter/impl/filesystem.h @@ -14,6 +14,7 @@ extern "C" { #endif +struct wf_mountpoint; struct wf_impl_session; struct lws; @@ -25,16 +26,13 @@ struct wf_impl_filesystem struct fuse_buf buffer; struct wf_impl_operations_context user_data; struct lws * wsi; - char * name; - char * id; - char * service_path; - char * default_path; - char * root_path; + struct wf_mountpoint * mountpoint; }; extern struct wf_impl_filesystem * wf_impl_filesystem_create( struct wf_impl_session * session, - char const * name); + char const * name, + struct wf_mountpoint * mountpoint); extern void wf_impl_filesystem_dispose( struct wf_impl_filesystem * filesystem); diff --git a/lib/webfuse/adapter/impl/mountpoint_factory.c b/lib/webfuse/adapter/impl/mountpoint_factory.c new file mode 100644 index 0000000..54679ef --- /dev/null +++ b/lib/webfuse/adapter/impl/mountpoint_factory.c @@ -0,0 +1,67 @@ +#include "webfuse/adapter/impl/mountpoint_factory.h" +#include + +void +wf_impl_mountpoint_factory_init_default( + struct wf_impl_mountpoint_factory * factory) +{ + factory->create_mountpoint = NULL; + factory->user_data = NULL; + factory->dispose = NULL; +} + +void +wf_impl_mountpoint_factory_init( + struct wf_impl_mountpoint_factory * factory, + wf_create_mountpoint_fn * create_mountpoint, + void * user_data, + wf_impl_mountpoint_factory_dispose_fn * dispose) +{ + factory->create_mountpoint = create_mountpoint; + factory->user_data = user_data; + factory->dispose = dispose; +} + +void +wf_impl_mountpoint_factory_move( + struct wf_impl_mountpoint_factory * factory, + struct wf_impl_mountpoint_factory * other) +{ + other->create_mountpoint = factory->create_mountpoint; + other->user_data = factory->user_data; + other->dispose = factory->dispose; + + factory->create_mountpoint = NULL; + factory->dispose = NULL; + factory->user_data = NULL; +} + +bool +wf_impl_mountpoint_factory_isvalid( + struct wf_impl_mountpoint_factory * factory) +{ + return (NULL != factory->create_mountpoint); +} + +void +wf_impl_mountpoint_factory_cleanup( + struct wf_impl_mountpoint_factory * factory) +{ + if (NULL != factory->dispose) + { + factory->dispose(factory->user_data); + } + + factory->create_mountpoint = NULL; + factory->dispose = NULL; + factory->user_data = NULL; +} + +struct wf_mountpoint * +wf_impl_mountpoint_factory_create_mountpoint( + struct wf_impl_mountpoint_factory * factory, + char const * filesystem) +{ + return factory->create_mountpoint(filesystem, factory->user_data); +} + diff --git a/lib/webfuse/adapter/impl/mountpoint_factory.h b/lib/webfuse/adapter/impl/mountpoint_factory.h new file mode 100644 index 0000000..98e5469 --- /dev/null +++ b/lib/webfuse/adapter/impl/mountpoint_factory.h @@ -0,0 +1,61 @@ +#ifndef WF_ADAPTER_IMPL_MOUNTPOINT_FACTORY_H +#define WF_ADAPTER_IMPL_MOUNTPOINT_FACTORY_H + +#include "webfuse/adapter/mountpoint_factory.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef void +wf_impl_mountpoint_factory_dispose_fn( + void * user_data); + +struct wf_impl_mountpoint_factory +{ + wf_create_mountpoint_fn * create_mountpoint; + wf_impl_mountpoint_factory_dispose_fn * dispose; + void * user_data; +}; + +extern void +wf_impl_mountpoint_factory_init_default( + struct wf_impl_mountpoint_factory * factory); + +extern void +wf_impl_mountpoint_factory_init( + struct wf_impl_mountpoint_factory * factory, + wf_create_mountpoint_fn * create_mountpoint, + void * user_data, + wf_impl_mountpoint_factory_dispose_fn * dispose); + +extern void +wf_impl_mountpoint_factory_move( + struct wf_impl_mountpoint_factory * factory, + struct wf_impl_mountpoint_factory * other); + +extern bool +wf_impl_mountpoint_factory_isvalid( + struct wf_impl_mountpoint_factory * factory); + +extern void +wf_impl_mountpoint_factory_init_from( + struct wf_impl_mountpoint_factory * factory, + struct wf_impl_mountpoint_factory * other); + +extern void +wf_impl_mountpoint_factory_cleanup( + struct wf_impl_mountpoint_factory * factory); + +extern struct wf_mountpoint * +wf_impl_mountpoint_factory_create_mountpoint( + struct wf_impl_mountpoint_factory * factory, + char const * filesystem); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/webfuse/adapter/impl/server.c b/lib/webfuse/adapter/impl/server.c index 15e18f4..ad3e5c2 100644 --- a/lib/webfuse/adapter/impl/server.c +++ b/lib/webfuse/adapter/impl/server.c @@ -76,37 +76,17 @@ static struct lws_context * wf_impl_server_context_create( } -static bool wf_impl_server_check_mountpoint( - struct wf_server_config * config) -{ - bool result = false; - - if (NULL != config->mount_point) - { - struct stat info; - int const rc = stat(config->mount_point, &info); - result = ((0 == rc) && (S_ISDIR(info.st_mode))); - - if (!result) - { - result = (0 == mkdir(config->mount_point, 0755)); - } - } - - return result; -} - struct wf_server * wf_impl_server_create( struct wf_server_config * config) { struct wf_server * server = NULL; - if (wf_impl_server_check_mountpoint(config)) + if (wf_impl_mountpoint_factory_isvalid(&config->mountpoint_factory)) { server = malloc(sizeof(struct wf_server)); if (NULL != server) { - wf_impl_server_protocol_init(&server->protocol, config->mount_point); + wf_impl_server_protocol_init(&server->protocol, &config->mountpoint_factory); wf_impl_server_config_clone(config, &server->config); wf_impl_authenticators_move(&server->config.authenticators, &server->protocol.authenticators); server->context = wf_impl_server_context_create(server); diff --git a/lib/webfuse/adapter/impl/server_config.c b/lib/webfuse/adapter/impl/server_config.c index 7098dac..2d9fc6d 100644 --- a/lib/webfuse/adapter/impl/server_config.c +++ b/lib/webfuse/adapter/impl/server_config.c @@ -1,4 +1,5 @@ #include "webfuse/adapter/impl/server_config.h" +#include "webfuse/adapter/impl/uuid_mountpoint_factory.h" #include #include @@ -20,14 +21,15 @@ void wf_impl_server_config_init( memset(config, 0, sizeof(struct wf_server_config)); wf_impl_authenticators_init(&config->authenticators); + wf_impl_mountpoint_factory_init_default(&config->mountpoint_factory); } void wf_impl_server_config_cleanup( struct wf_server_config * config) { wf_impl_authenticators_cleanup(&config->authenticators); + wf_impl_mountpoint_factory_cleanup(&config->mountpoint_factory); - free(config->mount_point); free(config->document_root); free(config->key_path); free(config->cert_path); @@ -40,7 +42,6 @@ void wf_impl_server_config_clone( struct wf_server_config * config, struct wf_server_config * clone) { - clone->mount_point = wf_impl_server_config_strdup(config->mount_point); clone->document_root = wf_impl_server_config_strdup(config->document_root); clone->key_path = wf_impl_server_config_strdup(config->key_path); clone->cert_path = wf_impl_server_config_strdup(config->cert_path); @@ -48,6 +49,9 @@ void wf_impl_server_config_clone( clone->port = config->port; wf_impl_authenticators_clone(&config->authenticators, &clone->authenticators); + + // ToDo: remove this: move is not clone :-/ + wf_impl_mountpoint_factory_move(&config->mountpoint_factory, &clone->mountpoint_factory); } struct wf_server_config * wf_impl_server_config_create(void) @@ -72,10 +76,20 @@ void wf_impl_server_config_set_mountpoint( struct wf_server_config * config, char const * mount_point) { - free(config->mount_point); - config->mount_point = strdup(mount_point); + wf_impl_uuid_mountpoint_factory_init(&config->mountpoint_factory, + mount_point); } +void wf_impl_server_config_set_mountpoint_factory( + struct wf_server_config * config, + wf_create_mountpoint_fn * create_mountpoint, + void * create_mountpoint_context) +{ + wf_impl_mountpoint_factory_init(&config->mountpoint_factory, + create_mountpoint, create_mountpoint_context, NULL); +} + + void wf_impl_server_config_set_documentroot( struct wf_server_config * config, char const * document_root) diff --git a/lib/webfuse/adapter/impl/server_config.h b/lib/webfuse/adapter/impl/server_config.h index 734c83a..48de4ed 100644 --- a/lib/webfuse/adapter/impl/server_config.h +++ b/lib/webfuse/adapter/impl/server_config.h @@ -2,6 +2,7 @@ #define WF_ADAPTER_IMPL_SERVER_CONFIG_H #include "webfuse/adapter/impl/authenticators.h" +#include "webfuse/adapter/impl/mountpoint_factory.h" #ifdef __cplusplus extern "C" { @@ -9,13 +10,13 @@ extern "C" { struct wf_server_config { - char * mount_point; char * document_root; char * key_path; char * cert_path; char * vhost_name; int port; struct wf_impl_authenticators authenticators; + struct wf_impl_mountpoint_factory mountpoint_factory; }; extern struct wf_server_config * wf_impl_server_config_create(void); @@ -37,6 +38,11 @@ extern void wf_impl_server_config_set_mountpoint( struct wf_server_config * config, char const * mount_point); +extern void wf_impl_server_config_set_mountpoint_factory( + struct wf_server_config * config, + wf_create_mountpoint_fn * create_mountpoint, + void * create_mountpoint_context); + extern void wf_impl_server_config_set_documentroot( struct wf_server_config * config, char const * document_root); diff --git a/lib/webfuse/adapter/impl/server_protocol.c b/lib/webfuse/adapter/impl/server_protocol.c index 65f6047..02efd80 100644 --- a/lib/webfuse/adapter/impl/server_protocol.c +++ b/lib/webfuse/adapter/impl/server_protocol.c @@ -9,6 +9,7 @@ #include "webfuse/adapter/impl/credentials.h" #include "webfuse/adapter/impl/jsonrpc/request.h" +#include "webfuse/adapter/impl/uuid_mountpoint_factory.h" static int wf_impl_server_protocol_callback( struct lws * wsi, @@ -38,9 +39,9 @@ static int wf_impl_server_protocol_callback( &protocol->session_manager, wsi, &protocol->authenticators, + &protocol->mountpoint_factory, &protocol->timeout_manager, - &protocol->server, - protocol->mount_point); + &protocol->server); if (NULL != session) { @@ -81,12 +82,34 @@ struct wf_server_protocol * wf_impl_server_protocol_create( struct wf_server_protocol * protocol = malloc(sizeof(struct wf_server_protocol)); if (NULL != protocol) { - wf_impl_server_protocol_init(protocol, mount_point); + struct wf_impl_mountpoint_factory mountpoint_factory; + wf_impl_uuid_mountpoint_factory_init(&mountpoint_factory, mount_point); + + wf_impl_server_protocol_init(protocol, &mountpoint_factory); } return protocol; } +struct wf_server_protocol * wf_impl_server_protocol_create2( + wf_create_mountpoint_fn * create_mountpoint, + void * create_mountpoint_context) +{ + struct wf_server_protocol * protocol = malloc(sizeof(struct wf_server_protocol)); + if (NULL != protocol) + { + struct wf_impl_mountpoint_factory mountpoint_factory; + wf_impl_mountpoint_factory_init(&mountpoint_factory, + create_mountpoint, create_mountpoint_context, NULL); + + wf_impl_server_protocol_init(protocol, &mountpoint_factory); + } + + return protocol; + +} + + void wf_impl_server_protocol_dispose( struct wf_server_protocol * protocol) { @@ -203,14 +226,14 @@ static void wf_impl_server_protocol_add_filesystem( } - void wf_impl_server_protocol_init( struct wf_server_protocol * protocol, - char * mount_point) + struct wf_impl_mountpoint_factory * mountpoint_factory) { - protocol->mount_point = strdup(mount_point); protocol->is_operational = false; + wf_impl_mountpoint_factory_move(mountpoint_factory, &protocol->mountpoint_factory); + wf_impl_timeout_manager_init(&protocol->timeout_manager); wf_impl_session_manager_init(&protocol->session_manager); wf_impl_authenticators_init(&protocol->authenticators); @@ -223,13 +246,13 @@ void wf_impl_server_protocol_init( void wf_impl_server_protocol_cleanup( struct wf_server_protocol * protocol) { - free(protocol->mount_point); protocol->is_operational = false; wf_impl_jsonrpc_server_cleanup(&protocol->server); wf_impl_timeout_manager_cleanup(&protocol->timeout_manager); wf_impl_authenticators_cleanup(&protocol->authenticators); wf_impl_session_manager_cleanup(&protocol->session_manager); + wf_impl_mountpoint_factory_cleanup(&protocol->mountpoint_factory); } void wf_impl_server_protocol_add_authenticator( diff --git a/lib/webfuse/adapter/impl/server_protocol.h b/lib/webfuse/adapter/impl/server_protocol.h index 8e4cd8d..16da34d 100644 --- a/lib/webfuse/adapter/impl/server_protocol.h +++ b/lib/webfuse/adapter/impl/server_protocol.h @@ -4,6 +4,7 @@ #include "webfuse/adapter/impl/jsonrpc/proxy.h" #include "webfuse/adapter/impl/time/timeout_manager.h" #include "webfuse/adapter/impl/authenticators.h" +#include "webfuse/adapter/impl/mountpoint_factory.h" #include "webfuse/adapter/impl/session_manager.h" #include "webfuse/adapter/impl/jsonrpc/server.h" @@ -20,9 +21,9 @@ struct lws_protocols; struct wf_server_protocol { - char * mount_point; struct wf_impl_timeout_manager timeout_manager; struct wf_impl_authenticators authenticators; + struct wf_impl_mountpoint_factory mountpoint_factory; struct wf_impl_session_manager session_manager; struct wf_impl_jsonrpc_server server; bool is_operational; @@ -30,7 +31,7 @@ struct wf_server_protocol extern void wf_impl_server_protocol_init( struct wf_server_protocol * protocol, - char * mount_point); + struct wf_impl_mountpoint_factory * mountpoint_factory); extern void wf_impl_server_protocol_cleanup( struct wf_server_protocol * protocol); @@ -38,6 +39,10 @@ extern void wf_impl_server_protocol_cleanup( extern struct wf_server_protocol * wf_impl_server_protocol_create( char * mount_point); +extern WF_API struct wf_server_protocol * wf_impl_server_protocol_create2( + wf_create_mountpoint_fn * create_mountpoint, + void * create_mountpoint_context); + extern void wf_impl_server_protocol_dispose( struct wf_server_protocol * protocol); diff --git a/lib/webfuse/adapter/impl/session.c b/lib/webfuse/adapter/impl/session.c index 82f9b80..fb2885a 100644 --- a/lib/webfuse/adapter/impl/session.c +++ b/lib/webfuse/adapter/impl/session.c @@ -5,6 +5,8 @@ #include "webfuse/adapter/impl/jsonrpc/proxy.h" #include "webfuse/adapter/impl/jsonrpc/request.h" #include "webfuse/adapter/impl/jsonrpc/response.h" +#include "webfuse/adapter/impl/mountpoint_factory.h" +#include "webfuse/adapter/impl/mountpoint.h" #include "webfuse/core/container_of.h" #include "webfuse/core/util.h" @@ -44,7 +46,7 @@ struct wf_impl_session * wf_impl_session_create( struct wf_impl_authenticators * authenticators, struct wf_impl_timeout_manager * timeout_manager, struct wf_impl_jsonrpc_server * server, - char const * mount_point) + struct wf_impl_mountpoint_factory * mountpoint_factory) { struct wf_impl_session * session = malloc(sizeof(struct wf_impl_session)); @@ -52,11 +54,11 @@ struct wf_impl_session * wf_impl_session_create( { wf_slist_init(&session->filesystems); - session->mount_point = strdup(mount_point); session->wsi = wsi; session->is_authenticated = false; session->authenticators = authenticators; session->server = server; + session->mountpoint_factory = mountpoint_factory; wf_impl_jsonrpc_proxy_init(&session->rpc, timeout_manager, WF_DEFAULT_TIMEOUT, &wf_impl_session_send, session); wf_slist_init(&session->messages); } @@ -88,8 +90,8 @@ void wf_impl_session_dispose( session->is_authenticated = false; session->wsi = NULL; session->authenticators = NULL; + session->mountpoint_factory = NULL; session->server = NULL; - free(session->mount_point); free(session); } @@ -106,9 +108,28 @@ bool wf_impl_session_add_filesystem( struct wf_impl_session * session, char const * name) { - struct wf_impl_filesystem * filesystem = wf_impl_filesystem_create(session, name); - wf_slist_append(&session->filesystems, &filesystem->item); - return (NULL != filesystem); + bool result; + + struct wf_mountpoint * mountpoint = wf_impl_mountpoint_factory_create_mountpoint(session->mountpoint_factory, name); + result = (NULL != mountpoint); + + if (result) + { + struct wf_impl_filesystem * filesystem = wf_impl_filesystem_create(session, name, mountpoint); + wf_slist_append(&session->filesystems, &filesystem->item); + result = (NULL != filesystem); + } + + // cleanup on error + if (!result) + { + if (NULL != mountpoint) + { + wf_impl_mountpoint_dispose(mountpoint); + } + } + + return result; } diff --git a/lib/webfuse/adapter/impl/session.h b/lib/webfuse/adapter/impl/session.h index cb1a19d..9f9b10a 100644 --- a/lib/webfuse/adapter/impl/session.h +++ b/lib/webfuse/adapter/impl/session.h @@ -24,16 +24,17 @@ struct lws; struct wf_message; struct wf_credentials; struct wf_impl_authenticators; +struct wf_impl_mountpoint_factory; struct wf_impl_timeout_manager; struct wf_impl_session { struct wf_slist_item item; - char * mount_point; struct lws * wsi; bool is_authenticated; struct wf_slist messages; struct wf_impl_authenticators * authenticators; + struct wf_impl_mountpoint_factory * mountpoint_factory; struct wf_impl_jsonrpc_server * server; struct wf_impl_jsonrpc_proxy rpc; struct wf_slist filesystems; @@ -44,7 +45,7 @@ extern struct wf_impl_session * wf_impl_session_create( struct wf_impl_authenticators * authenticators, struct wf_impl_timeout_manager * timeout_manager, struct wf_impl_jsonrpc_server * server, - char const * mount_point); + struct wf_impl_mountpoint_factory * mountpoint_factory); extern void wf_impl_session_dispose( struct wf_impl_session * session); diff --git a/lib/webfuse/adapter/impl/session_manager.c b/lib/webfuse/adapter/impl/session_manager.c index a48489b..0574c98 100644 --- a/lib/webfuse/adapter/impl/session_manager.c +++ b/lib/webfuse/adapter/impl/session_manager.c @@ -27,12 +27,12 @@ struct wf_impl_session * wf_impl_session_manager_add( struct wf_impl_session_manager * manager, struct lws * wsi, struct wf_impl_authenticators * authenticators, + struct wf_impl_mountpoint_factory * mountpoint_factory, struct wf_impl_timeout_manager * timeout_manager, - struct wf_impl_jsonrpc_server * server, - char const * mount_point) + struct wf_impl_jsonrpc_server * server) { struct wf_impl_session * session = wf_impl_session_create( - wsi, authenticators, timeout_manager, server, mount_point); + wsi, authenticators, timeout_manager, server, mountpoint_factory); if (NULL != session) { wf_slist_append(&manager->sessions, &session->item); diff --git a/lib/webfuse/adapter/impl/session_manager.h b/lib/webfuse/adapter/impl/session_manager.h index bfe4aa3..25b4367 100644 --- a/lib/webfuse/adapter/impl/session_manager.h +++ b/lib/webfuse/adapter/impl/session_manager.h @@ -33,9 +33,9 @@ extern struct wf_impl_session * wf_impl_session_manager_add( struct wf_impl_session_manager * manager, struct lws * wsi, struct wf_impl_authenticators * authenticators, + struct wf_impl_mountpoint_factory * mountpoint_factory, struct wf_impl_timeout_manager * timeout_manager, - struct wf_impl_jsonrpc_server * server, - char const * mount_point); + struct wf_impl_jsonrpc_server * server); extern struct wf_impl_session * wf_impl_session_manager_get( struct wf_impl_session_manager * manager, diff --git a/lib/webfuse/adapter/impl/uuid_mountpoint_factory.c b/lib/webfuse/adapter/impl/uuid_mountpoint_factory.c index 1f28e64..3b4d543 100644 --- a/lib/webfuse/adapter/impl/uuid_mountpoint_factory.c +++ b/lib/webfuse/adapter/impl/uuid_mountpoint_factory.c @@ -15,8 +15,8 @@ struct wf_impl_uuid_mountpoint_factory bool root_created; }; -void * -wf_impl_uuid_mountpoint_factory_create( +static void * +wf_impl_uuid_mountpoint_factory_create_context( char const * root_path) { struct wf_impl_uuid_mountpoint_factory * factory = NULL; @@ -37,11 +37,10 @@ wf_impl_uuid_mountpoint_factory_create( factory->root_created = root_created; } - return factory; } -void +static void wf_impl_uuid_mountpoint_factory_dispose( void * user_data) { @@ -56,7 +55,7 @@ wf_impl_uuid_mountpoint_factory_dispose( free(factory); } -struct wf_mountpoint * +static struct wf_mountpoint * wf_impl_uuid_mountpoint_factory_create_mountpoint( char const * filesystem, void * user_data) @@ -65,3 +64,21 @@ wf_impl_uuid_mountpoint_factory_create_mountpoint( return wf_impl_uuid_mountpoint_create(factory->root_path, filesystem); } + +bool +wf_impl_uuid_mountpoint_factory_init( + struct wf_impl_mountpoint_factory * factory, + char const * root_path) +{ + void * context = wf_impl_uuid_mountpoint_factory_create_context(root_path); + bool const result = (NULL != context); + + if (result) + { + factory->create_mountpoint = &wf_impl_uuid_mountpoint_factory_create_mountpoint; + factory->user_data = context; + factory->dispose = &wf_impl_uuid_mountpoint_factory_dispose; + } + + return result; +} diff --git a/lib/webfuse/adapter/impl/uuid_mountpoint_factory.h b/lib/webfuse/adapter/impl/uuid_mountpoint_factory.h index 52d5c57..eed8fa0 100644 --- a/lib/webfuse/adapter/impl/uuid_mountpoint_factory.h +++ b/lib/webfuse/adapter/impl/uuid_mountpoint_factory.h @@ -1,27 +1,19 @@ #ifndef WF_IMPL_UUID_MOUNTPOINT_FACTORY_H #define WF_IMPL_UUID_MOUNTPOINT_FACTORY_H +#include "webfuse/adapter/impl/mountpoint_factory.h" +#include + #ifdef __cplusplus extern "C" { #endif -struct wf_mountpoint; - -extern void * -wf_impl_uuid_mountpoint_factory_create( +extern bool +wf_impl_uuid_mountpoint_factory_init( + struct wf_impl_mountpoint_factory * factory, char const * root_path); -extern void -wf_impl_uuid_mountpoint_factory_dispose( - void * user_data); - -extern struct wf_mountpoint * -wf_impl_uuid_mountpoint_factory_create_mountpoint( - char const * filesystem, - void * user_data); - - #ifdef __cplusplus } #endif diff --git a/test/adapter/test_uuid_mountpoint_factory.cc b/test/adapter/test_uuid_mountpoint_factory.cc index abb0b27..b097ae0 100644 --- a/test/adapter/test_uuid_mountpoint_factory.cc +++ b/test/adapter/test_uuid_mountpoint_factory.cc @@ -11,19 +11,19 @@ TEST(uuid_mountpoint_factory, create_existing_dir) { TempDir temp("uuid_mountpoint_factory"); - void * factory = wf_impl_uuid_mountpoint_factory_create(temp.path()); - ASSERT_NE(nullptr, factory); + struct wf_impl_mountpoint_factory factory; + bool factory_created = wf_impl_uuid_mountpoint_factory_init(&factory, temp.path()); + ASSERT_TRUE(factory_created); ASSERT_TRUE(is_dir(temp.path())); - wf_mountpoint * mountpoint = wf_impl_uuid_mountpoint_factory_create_mountpoint("dummy", factory); + wf_mountpoint * mountpoint = wf_impl_mountpoint_factory_create_mountpoint(&factory, "dummy"); std::string path = wf_mountpoint_get_path(mountpoint); - ASSERT_NE(nullptr, factory); ASSERT_TRUE(is_dir(path)); wf_mountpoint_dispose(mountpoint); ASSERT_FALSE(is_dir(path)); - wf_impl_uuid_mountpoint_factory_dispose(factory); + wf_impl_mountpoint_factory_cleanup(&factory); // keep dir not created by factory ASSERT_TRUE(is_dir(temp.path())); } @@ -33,19 +33,19 @@ TEST(uuid_mountpoint_factory, create_nonexisting_dir) TempDir temp("uuid_mountpoint_factory"); std::string root_path = std::string(temp.path()) + "/root"; - void * factory = wf_impl_uuid_mountpoint_factory_create(root_path.c_str()); - ASSERT_NE(nullptr, factory); + struct wf_impl_mountpoint_factory factory; + bool factory_created = wf_impl_uuid_mountpoint_factory_init(&factory, root_path.c_str()); + ASSERT_TRUE(factory_created); ASSERT_TRUE(is_dir(root_path)); - wf_mountpoint * mountpoint = wf_impl_uuid_mountpoint_factory_create_mountpoint("dummy", factory); + wf_mountpoint * mountpoint = wf_impl_mountpoint_factory_create_mountpoint(&factory, "dummy"); std::string path = wf_mountpoint_get_path(mountpoint); - ASSERT_NE(nullptr, factory); ASSERT_TRUE(is_dir(path)); wf_mountpoint_dispose(mountpoint); ASSERT_FALSE(is_dir(path)); - wf_impl_uuid_mountpoint_factory_dispose(factory); + wf_impl_mountpoint_factory_cleanup(&factory); // remove dir, created by factory ASSERT_FALSE(is_dir(root_path)); } @@ -55,6 +55,7 @@ TEST(uuid_mountpoint_factory, fail_to_created_nested_dir) TempDir temp("uuid_mountpoint_factory"); std::string root_path = std::string(temp.path()) + "/nested/root"; - void * factory = wf_impl_uuid_mountpoint_factory_create(root_path.c_str()); - ASSERT_EQ(nullptr, factory); + struct wf_impl_mountpoint_factory factory; + bool factory_created = wf_impl_uuid_mountpoint_factory_init(&factory, root_path.c_str()); + ASSERT_FALSE(factory_created); } \ No newline at end of file From ae9fb639009b8d780de42b6c1520d7988b7cb5a3 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sun, 16 Feb 2020 21:38:37 +0100 Subject: [PATCH 08/10] fix: made c'tor explicit --- test/tempdir.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tempdir.hpp b/test/tempdir.hpp index 0c28a80..6a03fc5 100644 --- a/test/tempdir.hpp +++ b/test/tempdir.hpp @@ -9,7 +9,7 @@ class TempDir TempDir(TempDir const &) = delete; TempDir & operator=(TempDir const &) = delete; public: - TempDir(char const * prefix); + explicit TempDir(char const * prefix); ~TempDir(); char const * path(); private: From bc1b5343df2f3d301beb5a9a6ce0e295426281e7 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sun, 16 Feb 2020 22:36:31 +0100 Subject: [PATCH 09/10] added unit tests for server_config --- cmake/unit_tests.cmake | 1 + test/adapter/test_server_config.cc | 175 +++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 test/adapter/test_server_config.cc diff --git a/cmake/unit_tests.cmake b/cmake/unit_tests.cmake index 933d78e..b49cca9 100644 --- a/cmake/unit_tests.cmake +++ b/cmake/unit_tests.cmake @@ -23,6 +23,7 @@ add_executable(alltests test/core/test_message_queue.cc test/adapter/test_response_parser.cc test/adapter/test_server.cc + test/adapter/test_server_config.cc test/adapter/test_timepoint.cc test/adapter/test_timer.cc test/adapter/test_credentials.cc diff --git a/test/adapter/test_server_config.cc b/test/adapter/test_server_config.cc new file mode 100644 index 0000000..5a03f5c --- /dev/null +++ b/test/adapter/test_server_config.cc @@ -0,0 +1,175 @@ +#include +#include "webfuse/adapter/server_config.h" +#include "webfuse/adapter/impl/server_config.h" +#include "webfuse/adapter/impl/authenticator.h" +#include "tempdir.hpp" + +using webfuse_test::TempDir; + +namespace +{ + +wf_mountpoint * create_mountpoint( + char const * filesystem, + void * user_data) +{ + (void) filesystem; + (void) user_data; + + return nullptr; +} + +bool authenticate( + wf_credentials * credentials, + void * user_data) +{ + (void) credentials; + (void) user_data; + + return false; +} + +} + + +TEST(server_config, create_dispose) +{ + wf_server_config * config = wf_server_config_create(); + ASSERT_NE(nullptr, config); + + wf_server_config_dispose(config); +} + +TEST(server_config, set_documentroot) +{ + wf_server_config * config = wf_server_config_create(); + ASSERT_NE(nullptr, config); + + ASSERT_EQ(nullptr, config->document_root); + + wf_server_config_set_documentroot(config, "www"); + ASSERT_STREQ("www", config->document_root); + + wf_server_config_set_documentroot(config, "/var/www"); + ASSERT_STREQ("/var/www", config->document_root); + + wf_server_config_dispose(config); +} + +TEST(server_config, set_keypath) +{ + wf_server_config * config = wf_server_config_create(); + ASSERT_NE(nullptr, config); + + ASSERT_EQ(nullptr, config->key_path); + + wf_server_config_set_keypath(config, "key.pem"); + ASSERT_STREQ("key.pem", config->key_path); + + wf_server_config_set_keypath(config, "pki/self/key.pem"); + ASSERT_STREQ("pki/self/key.pem", config->key_path); + + wf_server_config_dispose(config); +} + +TEST(server_config, set_certpath) +{ + wf_server_config * config = wf_server_config_create(); + ASSERT_NE(nullptr, config); + + ASSERT_EQ(nullptr, config->key_path); + + wf_server_config_set_certpath(config, "cert.pem"); + ASSERT_STREQ("cert.pem", config->cert_path); + + wf_server_config_set_certpath(config, "pki/self/cert.pem"); + ASSERT_STREQ("pki/self/cert.pem", config->cert_path); + + wf_server_config_dispose(config); +} + +TEST(server_config, set_vhostname) +{ + wf_server_config * config = wf_server_config_create(); + ASSERT_NE(nullptr, config); + + ASSERT_EQ(nullptr, config->key_path); + + wf_server_config_set_vhostname(config, "webfuse"); + ASSERT_STREQ("webfuse", config->vhost_name); + + wf_server_config_set_vhostname(config, "localhost"); + ASSERT_STREQ("localhost", config->vhost_name); + + wf_server_config_dispose(config); +} + +TEST(server_config, set_port) +{ + wf_server_config * config = wf_server_config_create(); + ASSERT_NE(nullptr, config); + + ASSERT_EQ(0, config->port); + + wf_server_config_set_port(config, 8443); + ASSERT_EQ(8443, config->port); + + wf_server_config_set_port(config, 8080); + ASSERT_EQ(8080, config->port); + + wf_server_config_dispose(config); +} + +TEST(server_config, set_mountpoint) +{ + TempDir temp("server_config"); + + wf_server_config * config = wf_server_config_create(); + ASSERT_NE(nullptr, config); + ASSERT_EQ(nullptr, config->mountpoint_factory.create_mountpoint); + ASSERT_EQ(nullptr, config->mountpoint_factory.user_data); + ASSERT_EQ(nullptr, config->mountpoint_factory.dispose); + + wf_server_config_set_mountpoint(config, temp.path()); + ASSERT_NE(nullptr, config->mountpoint_factory.create_mountpoint); + ASSERT_NE(nullptr, config->mountpoint_factory.user_data); + ASSERT_NE(nullptr, config->mountpoint_factory.dispose); + + wf_server_config_dispose(config); +} + +TEST(server_cnfig, set_mounpoint_factory) +{ + wf_server_config * config = wf_server_config_create(); + ASSERT_NE(nullptr, config); + ASSERT_EQ(nullptr, config->mountpoint_factory.create_mountpoint); + ASSERT_EQ(nullptr, config->mountpoint_factory.user_data); + ASSERT_EQ(nullptr, config->mountpoint_factory.dispose); + + int value = 42; + void * user_data = reinterpret_cast(&value); + wf_server_config_set_mountpoint_factory(config, &create_mountpoint, user_data); + ASSERT_NE(&create_mountpoint, config->mountpoint_factory.create_mountpoint); + ASSERT_EQ(user_data, config->mountpoint_factory.user_data); + ASSERT_EQ(nullptr, config->mountpoint_factory.dispose); + + wf_server_config_dispose(config); +} + +TEST(server_config, add_authenticator) +{ + wf_server_config * config = wf_server_config_create(); + ASSERT_NE(nullptr, config); + ASSERT_EQ(nullptr, config->authenticators.first); + + int value = 42; + void * user_data = reinterpret_cast(&value); + wf_server_config_add_authenticator(config, "username", &authenticate, user_data); + + wf_impl_authenticator * authenticator = config->authenticators.first; + ASSERT_STREQ("username", authenticator->type); + ASSERT_EQ(&authenticate, authenticator->authenticate); + ASSERT_EQ(user_data, authenticator->user_data); + + wf_server_config_dispose(config); +} \ No newline at end of file From 8f40f73072817dfe1f59487dd819ac44f28f4668 Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sun, 16 Feb 2020 22:58:28 +0100 Subject: [PATCH 10/10] fixed test expectation --- test/adapter/test_server_config.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/adapter/test_server_config.cc b/test/adapter/test_server_config.cc index 5a03f5c..cb176d6 100644 --- a/test/adapter/test_server_config.cc +++ b/test/adapter/test_server_config.cc @@ -138,7 +138,7 @@ TEST(server_config, set_mountpoint) wf_server_config_dispose(config); } -TEST(server_cnfig, set_mounpoint_factory) +TEST(server_config, set_mounpoint_factory) { wf_server_config * config = wf_server_config_create(); ASSERT_NE(nullptr, config); @@ -149,7 +149,7 @@ TEST(server_cnfig, set_mounpoint_factory) int value = 42; void * user_data = reinterpret_cast(&value); wf_server_config_set_mountpoint_factory(config, &create_mountpoint, user_data); - ASSERT_NE(&create_mountpoint, config->mountpoint_factory.create_mountpoint); + ASSERT_EQ(&create_mountpoint, config->mountpoint_factory.create_mountpoint); ASSERT_EQ(user_data, config->mountpoint_factory.user_data); ASSERT_EQ(nullptr, config->mountpoint_factory.dispose);