1
0
mirror of https://github.com/falk-werner/webfuse-provider synced 2024-10-27 20:44:10 +00:00

Merge pull request #45 from falk-werner/mountpoint_provider

In order to give the (library) user some control of where the remote filesystem is mounted, a mounpoint factory is introduced to preplace the global root mount point and the uuid logic.

To keep compatiblity, uuid stuff is not removed now (, but should be removed in near future...).
This commit is contained in:
Falk Werner 2020-02-17 16:23:34 +01:00 committed by GitHub
commit cd144a3143
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 1172 additions and 138 deletions

View File

@ -7,6 +7,8 @@ include(GoogleTest)
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
@ -21,11 +23,15 @@ 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
test/adapter/test_authenticator.cc
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

View File

@ -15,6 +15,10 @@ 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/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
lib/webfuse/adapter/impl/time/timer.c
lib/webfuse/adapter/impl/time/timeout_manager.c

View File

@ -0,0 +1,38 @@
#ifndef WF_ADAPTER_MOUNTPOINT_H
#define WF_ADAPTER_MOUNTPOINT_H
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_mountpoint;
typedef void
wf_mountpoint_userdata_dispose_fn(
void * user_data);
extern struct wf_mountpoint *
wf_mountpoint_create(
char const * path);
extern void
wf_mountpoint_dispose(
struct wf_mountpoint * mountpoint);
extern char const *
wf_mountpoint_get_path(
struct wf_mountpoint const * mountpoint);
extern void
wf_mountpoint_set_userdata(
struct wf_mountpoint * mointpoint,
void * user_data,
wf_mountpoint_userdata_dispose_fn * dispose);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,24 @@
#ifndef WF_ADAPTER_MOUNTPOINT_FACTORY_H
#define WF_ADAPTER_MOUNTPOINT_FACTORY_H
#include <webfuse/adapter/api.h>
#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

View File

@ -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);

View File

@ -3,6 +3,7 @@
#include <webfuse/adapter/api.h>
#include <webfuse/adapter/authenticate.h>
#include <webfuse/adapter/mountpoint_factory.h>
#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);

View File

@ -9,5 +9,6 @@
#include <webfuse/adapter/server_protocol.h>
#include <webfuse/adapter/authenticate.h>
#include <webfuse/adapter/credentials.h>
#include <webfuse/adapter/mountpoint.h>
#endif

View File

@ -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
@ -34,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)
{
@ -76,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)
@ -134,3 +151,35 @@ 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);
}
void
wf_mountpoint_set_userdata(
struct wf_mountpoint * mountpoint,
void * user_data,
wf_mountpoint_userdata_dispose_fn * dispose)
{
wf_impl_mountpoint_set_userdata(mountpoint, user_data, dispose);
}

View File

@ -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);

View File

@ -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);

View File

@ -0,0 +1,53 @@
#include "webfuse/adapter/impl/mountpoint.h"
#include <stdlib.h>
#include <string.h>
struct wf_mountpoint
{
char * path;
void * user_data;
wf_mountpoint_userdata_dispose_fn * dispose;
};
struct wf_mountpoint *
wf_impl_mountpoint_create(
char const * path)
{
struct wf_mountpoint * mountpoint = malloc(sizeof(struct wf_mountpoint));
mountpoint->path = strdup(path);
mountpoint->user_data = NULL;
mountpoint->dispose = NULL;
return mountpoint;
}
void
wf_impl_mountpoint_dispose(
struct wf_mountpoint * mountpoint)
{
if (NULL != mountpoint->dispose)
{
mountpoint->dispose(mountpoint->user_data);
}
free(mountpoint->path);
free(mountpoint);
}
char const *
wf_impl_mountpoint_get_path(
struct wf_mountpoint const * mountpoint)
{
return mountpoint->path;
}
extern void
wf_impl_mountpoint_set_userdata(
struct wf_mountpoint * mountpoint,
void * user_data,
wf_mountpoint_userdata_dispose_fn * dispose)
{
mountpoint->user_data = user_data;
mountpoint->dispose = dispose;
}

View File

@ -0,0 +1,33 @@
#ifndef WF_IMPL_MOUNTPOINT_H
#define WF_IMPL_MOUNTPOINT_H
#include "webfuse/adapter/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);
extern void
wf_impl_mountpoint_set_userdata(
struct wf_mountpoint * mountpoint,
void * user_data,
wf_mountpoint_userdata_dispose_fn * dispose);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,67 @@
#include "webfuse/adapter/impl/mountpoint_factory.h"
#include <stddef.h>
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);
}

View File

@ -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 <stdbool.h>
#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

View File

@ -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);

View File

@ -1,4 +1,5 @@
#include "webfuse/adapter/impl/server_config.h"
#include "webfuse/adapter/impl/uuid_mountpoint_factory.h"
#include <stdlib.h>
#include <string.h>
@ -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)

View File

@ -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);

View File

@ -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(

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -0,0 +1,123 @@
#include "webfuse/adapter/impl/uuid_mountpoint.h"
#include "webfuse/adapter/impl/mountpoint.h"
#include "webfuse/core/string.h"
#include <uuid/uuid.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
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_uuid_mountpoint_is_link_broken(data->default_path, data->id))
{
unlink(data->default_path);
bool const success = wf_impl_uuid_mountpoint_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();
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, filesystem);
symlink(data->id, data->default_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;
}

View File

@ -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

View File

@ -0,0 +1,84 @@
#include "webfuse/adapter/impl/uuid_mountpoint_factory.h"
#include "webfuse/adapter/impl/uuid_mountpoint.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
struct wf_impl_uuid_mountpoint_factory
{
char * root_path;
bool root_created;
};
static void *
wf_impl_uuid_mountpoint_factory_create_context(
char const * root_path)
{
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;
}
return factory;
}
static void
wf_impl_uuid_mountpoint_factory_dispose(
void * user_data)
{
struct wf_impl_uuid_mountpoint_factory * factory = user_data;
if (factory->root_created)
{
rmdir(factory->root_path);
}
free(factory->root_path);
free(factory);
}
static 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);
}
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;
}

View File

@ -0,0 +1,21 @@
#ifndef WF_IMPL_UUID_MOUNTPOINT_FACTORY_H
#define WF_IMPL_UUID_MOUNTPOINT_FACTORY_H
#include "webfuse/adapter/impl/mountpoint_factory.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C"
{
#endif
extern bool
wf_impl_uuid_mountpoint_factory_init(
struct wf_impl_mountpoint_factory * factory,
char const * root_path);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,47 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "webfuse/adapter/mountpoint.h"
namespace
{
class MockUserDataDisposer
{
public:
MOCK_METHOD1(dispose, void(void * mountpoint));
};
MockUserDataDisposer * global_disposer = nullptr;
void ondispose(void * user_data)
{
global_disposer->dispose(user_data);
}
}
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)
{
MockUserDataDisposer disposer;
global_disposer = &disposer;
wf_mountpoint * mountpoint = wf_mountpoint_create("/some/path");
ASSERT_NE(nullptr, mountpoint);
int value = 42;
void * user_data = reinterpret_cast<void*>(&value);
wf_mountpoint_set_userdata(mountpoint, user_data, ondispose);
EXPECT_CALL(disposer, dispose(user_data)).Times(1);
wf_mountpoint_dispose(mountpoint);
}

View File

@ -0,0 +1,175 @@
#include <gtest/gtest.h>
#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_config, 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<void*>(&value);
wf_server_config_set_mountpoint_factory(config, &create_mountpoint, user_data);
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);
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<void*>(&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);
}

View File

@ -0,0 +1,72 @@
#include <gtest/gtest.h>
#include "tempdir.hpp"
#include "file_utils.hpp"
#include "webfuse_adapter.h"
#include "webfuse/adapter/impl/uuid_mountpoint.h"
#include <string>
using webfuse_test::TempDir;
using webfuse_test::is_dir;
using webfuse_test::is_symlink;
using webfuse_test::is_same_path;
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));
}

View File

@ -0,0 +1,61 @@
#include <gtest/gtest.h>
#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");
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_mountpoint_factory_create_mountpoint(&factory, "dummy");
std::string path = wf_mountpoint_get_path(mountpoint);
ASSERT_TRUE(is_dir(path));
wf_mountpoint_dispose(mountpoint);
ASSERT_FALSE(is_dir(path));
wf_impl_mountpoint_factory_cleanup(&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";
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_mountpoint_factory_create_mountpoint(&factory, "dummy");
std::string path = wf_mountpoint_get_path(mountpoint);
ASSERT_TRUE(is_dir(path));
wf_mountpoint_dispose(mountpoint);
ASSERT_FALSE(is_dir(path));
wf_impl_mountpoint_factory_cleanup(&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";
struct wf_impl_mountpoint_factory factory;
bool factory_created = wf_impl_uuid_mountpoint_factory_init(&factory, root_path.c_str());
ASSERT_FALSE(factory_created);
}

38
test/file_utils.cc Normal file
View File

@ -0,0 +1,38 @@
#include "file_utils.hpp"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
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);
}
}

17
test/file_utils.hpp Normal file
View File

@ -0,0 +1,17 @@
#ifndef WF_TEST_FILE_UTILS_HPP
#define WF_TEST_FILE_UTILS_HPP
#include <string>
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

33
test/tempdir.cc Normal file
View File

@ -0,0 +1,33 @@
#include "webfuse/core/string.h"
#include "tempdir.hpp"
#include <unistd.h>
#include <cstdlib>
#include <stdexcept>
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_;
}
}

21
test/tempdir.hpp Normal file
View File

@ -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:
explicit TempDir(char const * prefix);
~TempDir();
char const * path();
private:
char * path_;
};
}
#endif