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:
commit
cd144a3143
@ -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
|
||||
|
@ -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
|
||||
|
38
include/webfuse/adapter/mountpoint.h
Normal file
38
include/webfuse/adapter/mountpoint.h
Normal 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
|
24
include/webfuse/adapter/mountpoint_factory.h
Normal file
24
include/webfuse/adapter/mountpoint_factory.h
Normal 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
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
53
lib/webfuse/adapter/impl/mountpoint.c
Normal file
53
lib/webfuse/adapter/impl/mountpoint.c
Normal 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;
|
||||
}
|
33
lib/webfuse/adapter/impl/mountpoint.h
Normal file
33
lib/webfuse/adapter/impl/mountpoint.h
Normal 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
|
67
lib/webfuse/adapter/impl/mountpoint_factory.c
Normal file
67
lib/webfuse/adapter/impl/mountpoint_factory.c
Normal 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);
|
||||
}
|
||||
|
61
lib/webfuse/adapter/impl/mountpoint_factory.h
Normal file
61
lib/webfuse/adapter/impl/mountpoint_factory.h
Normal 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
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
123
lib/webfuse/adapter/impl/uuid_mountpoint.c
Normal file
123
lib/webfuse/adapter/impl/uuid_mountpoint.c
Normal 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;
|
||||
}
|
20
lib/webfuse/adapter/impl/uuid_mountpoint.h
Normal file
20
lib/webfuse/adapter/impl/uuid_mountpoint.h
Normal 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
|
84
lib/webfuse/adapter/impl/uuid_mountpoint_factory.c
Normal file
84
lib/webfuse/adapter/impl/uuid_mountpoint_factory.c
Normal 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;
|
||||
}
|
21
lib/webfuse/adapter/impl/uuid_mountpoint_factory.h
Normal file
21
lib/webfuse/adapter/impl/uuid_mountpoint_factory.h
Normal 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
|
47
test/adapter/test_mountpoint.cc
Normal file
47
test/adapter/test_mountpoint.cc
Normal 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);
|
||||
}
|
175
test/adapter/test_server_config.cc
Normal file
175
test/adapter/test_server_config.cc
Normal 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);
|
||||
}
|
72
test/adapter/test_uuid_mountpoint.cc
Normal file
72
test/adapter/test_uuid_mountpoint.cc
Normal 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));
|
||||
}
|
61
test/adapter/test_uuid_mountpoint_factory.cc
Normal file
61
test/adapter/test_uuid_mountpoint_factory.cc
Normal 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
38
test/file_utils.cc
Normal 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
17
test/file_utils.hpp
Normal 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
33
test/tempdir.cc
Normal 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
21
test/tempdir.hpp
Normal 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
|
Loading…
Reference in New Issue
Block a user