mirror of
https://github.com/falk-werner/webfuse
synced 2025-06-13 12:54:15 +00:00
Merge branch 'master' into coverage
This commit is contained in:
commit
dc45d928ae
@ -75,6 +75,7 @@ add_library(webfuse-core STATIC
|
||||
lib/webfuse/core/message_queue.c
|
||||
lib/webfuse/core/status.c
|
||||
lib/webfuse/core/string.c
|
||||
lib/webfuse/core/path.c
|
||||
)
|
||||
|
||||
set_target_properties(webfuse-core PROPERTIES OUTPUT_NAME webfuse-core)
|
||||
@ -166,6 +167,7 @@ add_library(webfuse-provider-static STATIC
|
||||
lib/webfuse/provider/impl/operation/open.c
|
||||
lib/webfuse/provider/impl/operation/close.c
|
||||
lib/webfuse/provider/impl/operation/read.c
|
||||
lib/webfuse/provider/impl/static_filesystem.c
|
||||
)
|
||||
|
||||
set_target_properties(webfuse-provider-static PROPERTIES OUTPUT_NAME webfuse-provider)
|
||||
@ -243,6 +245,16 @@ set_target_properties(webfuse-provider-app PROPERTIES OUTPUT_NAME webfuse-provid
|
||||
target_link_libraries(webfuse-provider-app PUBLIC webfuse-provider ${EXTRA_LIBS})
|
||||
target_include_directories(webfuse-provider-app PUBLIC ${EXTRA_INCLUDE_DIRS})
|
||||
|
||||
# static-filesystem-provider
|
||||
|
||||
add_executable(static-filesystem-provider
|
||||
example/provider/static_filesystem.c
|
||||
)
|
||||
|
||||
target_link_libraries(static-filesystem-provider PUBLIC webfuse-provider ${EXTRA_LIBS})
|
||||
target_include_directories(static-filesystem-provider PUBLIC ${EXTRA_INCLUDE_DIRS})
|
||||
target_compile_options(static-filesystem-provider PUBLIC ${EXTRA_CFLAGS})
|
||||
|
||||
# webfuse-passwd
|
||||
|
||||
add_executable(webfuse-passwd
|
||||
@ -280,6 +292,7 @@ pkg_check_modules(GMOCK gmock)
|
||||
add_executable(alltests
|
||||
test/msleep.cc
|
||||
test/mock_authenticator.cc
|
||||
test/mock_request.cc
|
||||
test/test_container_of.cc
|
||||
test/test_response_parser.cc
|
||||
test/test_server.cc
|
||||
@ -291,6 +304,8 @@ add_executable(alltests
|
||||
test/test_authenticators.cc
|
||||
test/test_string.cc
|
||||
test/test_slist.cc
|
||||
test/test_path.cc
|
||||
test/test_static_filesystem.cc
|
||||
)
|
||||
|
||||
target_link_libraries(alltests PUBLIC webfuse-adapter-static webfuse-provider-static webfuse-core ${EXTRA_LIBS} ${GMOCK_LIBRARIES} ${GTEST_LIBRARIES})
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <webfuse_adapter.h>
|
||||
#include <userdb.h>
|
||||
|
||||
#define SERVICE_TIMEOUT (1 * 1000)
|
||||
|
||||
struct args
|
||||
{
|
||||
@ -19,7 +20,7 @@ struct args
|
||||
bool show_help;
|
||||
};
|
||||
|
||||
static struct wf_server * server;
|
||||
static bool shutdown_requested = false;
|
||||
|
||||
static void show_help(void)
|
||||
{
|
||||
@ -150,7 +151,7 @@ static void on_interrupt(int signal_id)
|
||||
{
|
||||
(void) signal_id;
|
||||
|
||||
wf_server_shutdown(server);
|
||||
shutdown_requested = true;
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
@ -167,10 +168,14 @@ int main(int argc, char * argv[])
|
||||
if (!args.show_help)
|
||||
{
|
||||
signal(SIGINT, on_interrupt);
|
||||
server = wf_server_create(args.config);
|
||||
struct wf_server * server = wf_server_create(args.config);
|
||||
if (NULL != server)
|
||||
{
|
||||
wf_server_run(server);
|
||||
while (!shutdown_requested)
|
||||
{
|
||||
wf_server_service(server, SERVICE_TIMEOUT);
|
||||
}
|
||||
|
||||
wf_server_dispose(server);
|
||||
}
|
||||
else
|
||||
|
@ -127,9 +127,9 @@ static char * compute_hash(
|
||||
{
|
||||
EVP_MD_CTX * context = EVP_MD_CTX_new();
|
||||
EVP_DigestInit_ex(context, digest, NULL);
|
||||
EVP_DigestUpdate(context, password, strlen(password)); /* Flawfinder: ignore */
|
||||
EVP_DigestUpdate(context, salt, strlen(salt)); /* Flawfinder: ignore */
|
||||
EVP_DigestUpdate(context, db->pepper, strlen(db->pepper)); /* Flawfinder: ignore */
|
||||
EVP_DigestUpdate(context, password, strlen(password));
|
||||
EVP_DigestUpdate(context, salt, strlen(salt));
|
||||
EVP_DigestUpdate(context, db->pepper, strlen(db->pepper));
|
||||
EVP_DigestFinal_ex(context, hash, &hash_size);
|
||||
EVP_MD_CTX_free(context);
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
#include "webfuse_provider.h"
|
||||
|
||||
#define SERVICE_TIMEOUT (1 * 1000)
|
||||
|
||||
struct config
|
||||
{
|
||||
char * url;
|
||||
@ -314,13 +316,12 @@ static void fs_read(
|
||||
}
|
||||
}
|
||||
|
||||
static struct wfp_client * client;
|
||||
static volatile bool shutdown_requested = false;
|
||||
|
||||
static void on_interrupt(int signal_id)
|
||||
{
|
||||
(void) signal_id;
|
||||
|
||||
wfp_client_shutdown(client);
|
||||
shutdown_requested = true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
@ -362,10 +363,13 @@ int main(int argc, char* argv[])
|
||||
wfp_client_config_set_onopen(config.client_config, &fs_open);
|
||||
wfp_client_config_set_onread(config.client_config, &fs_read);
|
||||
|
||||
client = wfp_client_create(config.client_config);
|
||||
struct wfp_client * client = wfp_client_create(config.client_config);
|
||||
wfp_client_connect(client, config.url);
|
||||
|
||||
wfp_client_run(client);
|
||||
while (!shutdown_requested)
|
||||
{
|
||||
wfp_client_service(client, SERVICE_TIMEOUT);
|
||||
}
|
||||
|
||||
wfp_client_dispose(client);
|
||||
}
|
||||
|
99
example/provider/static_filesystem.c
Normal file
99
example/provider/static_filesystem.c
Normal file
@ -0,0 +1,99 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "webfuse_provider.h"
|
||||
|
||||
struct args
|
||||
{
|
||||
char const * url;
|
||||
bool show_help;
|
||||
};
|
||||
|
||||
static int
|
||||
parse_args(
|
||||
struct args * args,
|
||||
int argc,
|
||||
char * argv[])
|
||||
{
|
||||
int result = EXIT_FAILURE;
|
||||
args->show_help = true;
|
||||
args->url = NULL;
|
||||
|
||||
if (2 == argc)
|
||||
{
|
||||
result = EXIT_SUCCESS;
|
||||
|
||||
char const * url = argv[1];
|
||||
if ((0 != strcmp(url, "-h")) && (0 != strcmp(url, "--help")))
|
||||
{
|
||||
args->show_help = false;
|
||||
args->url = url;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "error: missing argument\n");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct wfp_client * client = NULL;
|
||||
|
||||
static void on_interrupt(int signal_id)
|
||||
{
|
||||
(void) signal_id;
|
||||
|
||||
wfp_client_shutdown(client);
|
||||
}
|
||||
|
||||
static void print_usage()
|
||||
{
|
||||
printf(
|
||||
"static-filesystem-provider Copyright (c) 2019, webfuse authors <https://github.com/falk-werner/webfuse>\n"
|
||||
"Example of webfuse static filesystem provider\n"
|
||||
"\n"
|
||||
"Usage: static-filesystem-provider <url>\n"
|
||||
"\n"
|
||||
"Arguments:\n"
|
||||
"\t<url> URL of webfuse server (required)\n"
|
||||
"\t-h, --help prints this message\n"
|
||||
"\n"
|
||||
"Example:\n"
|
||||
"\tstatic-filesystem-provider ws://localhost:8080/\n"
|
||||
"\n"
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
signal(SIGINT, &on_interrupt);
|
||||
|
||||
struct args args;
|
||||
int result = parse_args(&args, argc, argv);
|
||||
if (EXIT_SUCCESS == result)
|
||||
{
|
||||
struct wfp_client_config * config = wfp_client_config_create();
|
||||
|
||||
struct wfp_static_filesystem * fs = wfp_static_filesystem_create(config);
|
||||
wfp_static_filesystem_add_text(fs, "hello.txt", 0444, "Hello, World!");
|
||||
|
||||
client = wfp_client_create(config);
|
||||
wfp_client_connect(client, args.url);
|
||||
wfp_client_run(client);
|
||||
|
||||
wfp_client_dispose(client);
|
||||
wfp_static_filesystem_dispose(fs);
|
||||
wfp_client_config_dispose(config);
|
||||
}
|
||||
|
||||
if (args.show_help)
|
||||
{
|
||||
print_usage();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
@ -17,11 +17,9 @@ extern WF_API struct wf_server * wf_server_create(
|
||||
extern WF_API void wf_server_dispose(
|
||||
struct wf_server * server);
|
||||
|
||||
extern WF_API void wf_server_run(
|
||||
struct wf_server * server);
|
||||
|
||||
extern WF_API void wf_server_shutdown(
|
||||
struct wf_server * server);
|
||||
extern WF_API void wf_server_service(
|
||||
struct wf_server * server,
|
||||
int timeout_ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -24,12 +24,9 @@ extern WFP_API void wfp_client_disconnect(
|
||||
extern WFP_API void wfp_client_dispose(
|
||||
struct wfp_client * client);
|
||||
|
||||
extern WFP_API void wfp_client_run(
|
||||
struct wfp_client * client);
|
||||
|
||||
extern WFP_API void wfp_client_shutdown(
|
||||
struct wfp_client * client);
|
||||
|
||||
extern WFP_API void wfp_client_service(
|
||||
struct wfp_client * client,
|
||||
int timeout_ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
76
include/webfuse/provider/static_filesystem.h
Normal file
76
include/webfuse/provider/static_filesystem.h
Normal file
@ -0,0 +1,76 @@
|
||||
#ifndef WFP_STATIC_FILESYSTEM_H
|
||||
#define WFP_STATIC_FILESYSTEM_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include <cstddef>
|
||||
using ::std::size_t;
|
||||
#endif
|
||||
|
||||
#include <webfuse/provider/api.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wfp_client_config;
|
||||
struct wfp_static_filesystem;
|
||||
|
||||
typedef size_t
|
||||
wfp_static_filesystem_read_fn(
|
||||
size_t offset,
|
||||
char * buffer,
|
||||
size_t buffer_size,
|
||||
void * user_data);
|
||||
|
||||
typedef void
|
||||
wfp_static_filesystem_get_info_fn(
|
||||
void * user_data,
|
||||
int * result_mode,
|
||||
size_t * result_size);
|
||||
|
||||
|
||||
extern WFP_API struct wfp_static_filesystem *
|
||||
wfp_static_filesystem_create(
|
||||
struct wfp_client_config * config);
|
||||
|
||||
extern WFP_API void
|
||||
wfp_static_filesystem_dispose(
|
||||
struct wfp_static_filesystem * filesystem);
|
||||
|
||||
extern WFP_API void
|
||||
wfp_static_filesystem_add(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
int mode,
|
||||
char const * content,
|
||||
size_t length);
|
||||
|
||||
extern WFP_API void
|
||||
wfp_static_filesystem_add_text(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
int mode,
|
||||
char const * content);
|
||||
|
||||
extern WFP_API void
|
||||
wfp_static_filesystem_add_file(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
char const * filename);
|
||||
|
||||
extern WFP_API void
|
||||
wfp_static_filesystem_add_generic(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
wfp_static_filesystem_read_fn * read,
|
||||
wfp_static_filesystem_get_info_fn * get_info,
|
||||
void * user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -17,4 +17,6 @@
|
||||
#include <webfuse/provider/operation/close.h>
|
||||
#include <webfuse/provider/operation/read.h>
|
||||
|
||||
#include <webfuse/provider/static_filesystem.h>
|
||||
|
||||
#endif
|
||||
|
@ -19,16 +19,11 @@ void wf_server_dispose(
|
||||
wf_impl_server_dispose(server);
|
||||
}
|
||||
|
||||
void wf_server_run(
|
||||
struct wf_server * server)
|
||||
void wf_server_service(
|
||||
struct wf_server * server,
|
||||
int timeout_ms)
|
||||
{
|
||||
wf_impl_server_run(server);
|
||||
}
|
||||
|
||||
void wf_server_shutdown(
|
||||
struct wf_server * server)
|
||||
{
|
||||
wf_impl_server_shutdown(server);
|
||||
wf_impl_server_service(server, timeout_ms);
|
||||
}
|
||||
|
||||
// server protocol
|
||||
|
@ -23,7 +23,7 @@ static char * wf_impl_fill_buffer(
|
||||
{
|
||||
if (0 == strcmp("identity", format))
|
||||
{
|
||||
memcpy(buffer, data, count); /* Flawfinder: ignore */
|
||||
memcpy(buffer, data, count);
|
||||
}
|
||||
else if (0 == strcmp("base64", format))
|
||||
{
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
#define WF_DISABLE_LWS_LOG 0
|
||||
#define WF_SERVER_PROTOCOL_COUNT 3
|
||||
#define WF_SERVER_TIMEOUT (1 * 1000)
|
||||
|
||||
struct wf_server
|
||||
{
|
||||
@ -21,7 +20,6 @@ struct wf_server
|
||||
struct wf_server_protocol protocol;
|
||||
struct lws_protocols ws_protocols[WF_SERVER_PROTOCOL_COUNT];
|
||||
struct lws_context * context;
|
||||
volatile bool shutdown_requested;
|
||||
struct lws_http_mount mount;
|
||||
struct lws_context_creation_info info;
|
||||
};
|
||||
@ -109,7 +107,6 @@ struct wf_server * wf_impl_server_create(
|
||||
if (NULL != server)
|
||||
{
|
||||
wf_impl_server_protocol_init(&server->protocol, config->mount_point);
|
||||
server->shutdown_requested = false;
|
||||
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);
|
||||
@ -128,19 +125,9 @@ void wf_impl_server_dispose(
|
||||
free(server);
|
||||
}
|
||||
|
||||
void wf_impl_server_run(
|
||||
struct wf_server * server)
|
||||
void wf_impl_server_service(
|
||||
struct wf_server * server,
|
||||
int timeout_ms)
|
||||
{
|
||||
int n = 0;
|
||||
while ((0 <= n) && (!server->shutdown_requested))
|
||||
{
|
||||
n = lws_service(server->context, WF_SERVER_TIMEOUT);
|
||||
}
|
||||
lws_service(server->context, timeout_ms);
|
||||
}
|
||||
|
||||
void wf_impl_server_shutdown(
|
||||
struct wf_server * server)
|
||||
{
|
||||
server->shutdown_requested = true;
|
||||
}
|
||||
|
||||
|
@ -15,11 +15,9 @@ extern struct wf_server * wf_impl_server_create(
|
||||
extern void wf_impl_server_dispose(
|
||||
struct wf_server * server);
|
||||
|
||||
extern void wf_impl_server_run(
|
||||
struct wf_server * server);
|
||||
|
||||
extern void wf_impl_server_shutdown(
|
||||
struct wf_server * server);
|
||||
extern void wf_impl_server_service(
|
||||
struct wf_server * server,
|
||||
int timeout_ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ struct wf_impl_session * wf_impl_session_create(
|
||||
static void wf_impl_session_dispose_filesystems(
|
||||
struct wf_slist * filesystems)
|
||||
{
|
||||
struct wf_slist_item * item = filesystems->first;
|
||||
struct wf_slist_item * item = wf_slist_first(filesystems);
|
||||
while (NULL != item)
|
||||
{
|
||||
struct wf_slist_item * next = item->next;
|
||||
@ -156,11 +156,11 @@ static struct wf_impl_filesystem * wf_impl_session_get_filesystem(
|
||||
{
|
||||
struct wf_impl_filesystem * result = NULL;
|
||||
|
||||
struct wf_slist_item * item = session->filesystems.first;
|
||||
struct wf_slist_item * item = wf_slist_first(&session->filesystems);
|
||||
while (NULL != item)
|
||||
{
|
||||
struct wf_slist_item * next = item->next;
|
||||
struct wf_impl_filesystem * filesystem = wf_container_of(session->filesystems.first, struct wf_impl_filesystem, item);
|
||||
struct wf_impl_filesystem * filesystem = wf_container_of(item, struct wf_impl_filesystem, item);
|
||||
if (wsi == filesystem->wsi)
|
||||
{
|
||||
result = filesystem;
|
||||
|
@ -12,7 +12,7 @@ void wf_impl_session_manager_init(
|
||||
void wf_impl_session_manager_cleanup(
|
||||
struct wf_impl_session_manager * manager)
|
||||
{
|
||||
struct wf_slist_item * item = manager->sessions.first;
|
||||
struct wf_slist_item * item = wf_slist_first(&manager->sessions);
|
||||
while (NULL != item)
|
||||
{
|
||||
struct wf_slist_item * next = item->next;
|
||||
@ -47,7 +47,7 @@ struct wf_impl_session * wf_impl_session_manager_get(
|
||||
{
|
||||
struct wf_impl_session * session = NULL;
|
||||
|
||||
struct wf_slist_item * item = manager->sessions.first;
|
||||
struct wf_slist_item * item = wf_slist_first(&manager->sessions);
|
||||
while (NULL != item)
|
||||
{
|
||||
struct wf_slist_item * next = item->next;
|
||||
@ -68,11 +68,10 @@ void wf_impl_session_manager_remove(
|
||||
struct wf_impl_session_manager * manager,
|
||||
struct lws * wsi)
|
||||
{
|
||||
struct wf_slist_item * item = manager->sessions.first;
|
||||
struct wf_slist_item * prev = NULL;
|
||||
while (NULL != item)
|
||||
struct wf_slist_item * prev = &manager->sessions.head;
|
||||
while (NULL != prev->next)
|
||||
{
|
||||
struct wf_slist_item * next = item->next;
|
||||
struct wf_slist_item * item = prev->next;
|
||||
struct wf_impl_session * session = wf_container_of(item, struct wf_impl_session, item);
|
||||
if (wsi == session->wsi)
|
||||
{
|
||||
@ -81,7 +80,6 @@ void wf_impl_session_manager_remove(
|
||||
break;
|
||||
}
|
||||
|
||||
prev = item;
|
||||
item = next;
|
||||
prev = prev->next;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
void wf_message_queue_cleanup(
|
||||
struct wf_slist * queue)
|
||||
{
|
||||
struct wf_slist_item * item = queue->first;
|
||||
struct wf_slist_item * item = wf_slist_first(queue);
|
||||
while (NULL != item)
|
||||
{
|
||||
struct wf_slist_item * next = item->next;
|
||||
|
116
lib/webfuse/core/path.c
Normal file
116
lib/webfuse/core/path.c
Normal file
@ -0,0 +1,116 @@
|
||||
#include "webfuse/core/path.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define WF_PATH_DEFAULT_CAPACITY (8)
|
||||
|
||||
struct wf_path
|
||||
{
|
||||
char * * elements;
|
||||
size_t count;
|
||||
size_t capacity;
|
||||
};
|
||||
|
||||
static void
|
||||
wf_path_add(
|
||||
struct wf_path * path,
|
||||
char const * element,
|
||||
size_t element_size)
|
||||
{
|
||||
if (0 < element_size)
|
||||
{
|
||||
if (path->count >= path->capacity)
|
||||
{
|
||||
size_t new_capacity = 2 * path->capacity;
|
||||
size_t new_size = sizeof(char*) * new_capacity;
|
||||
|
||||
char * * elements = realloc(path->elements, new_size);
|
||||
if (NULL != elements)
|
||||
{
|
||||
path->elements = elements;
|
||||
path->capacity = new_capacity;
|
||||
}
|
||||
}
|
||||
|
||||
if (path->count < path->capacity)
|
||||
{
|
||||
path->elements[path->count] = strndup(element, element_size);
|
||||
path->count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct wf_path *
|
||||
wf_path_create(
|
||||
char const * value)
|
||||
{
|
||||
struct wf_path * path = malloc(sizeof(struct wf_path));
|
||||
if (NULL != path)
|
||||
{
|
||||
path->elements = malloc(sizeof(char*) * WF_PATH_DEFAULT_CAPACITY);
|
||||
path->capacity = WF_PATH_DEFAULT_CAPACITY;
|
||||
path->count = 0;
|
||||
|
||||
char const * remainder = value;
|
||||
char const * pos = strchr(remainder, '/');
|
||||
while (NULL != pos)
|
||||
{
|
||||
wf_path_add(path, remainder, (pos - remainder));
|
||||
remainder = pos + 1;
|
||||
pos = strchr(remainder, '/');
|
||||
}
|
||||
|
||||
wf_path_add(path, remainder, strlen(remainder));
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void
|
||||
wf_path_dispose(
|
||||
struct wf_path * path)
|
||||
{
|
||||
for(size_t i = 0; i < path->count; i++)
|
||||
{
|
||||
free(path->elements[i]);
|
||||
}
|
||||
|
||||
free(path->elements);
|
||||
free(path);
|
||||
(void) path;
|
||||
}
|
||||
|
||||
size_t
|
||||
wf_path_element_count(
|
||||
struct wf_path * path)
|
||||
{
|
||||
return path->count;
|
||||
}
|
||||
|
||||
char const *
|
||||
wf_path_get_element(
|
||||
struct wf_path * path,
|
||||
size_t i)
|
||||
{
|
||||
char const * result = NULL;
|
||||
if (i < path->count)
|
||||
{
|
||||
result = path->elements[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
char const *
|
||||
wf_path_get_filename(
|
||||
struct wf_path * path)
|
||||
{
|
||||
char const * result = NULL;
|
||||
|
||||
if (0 < path->count)
|
||||
{
|
||||
result = path->elements[path->count - 1];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
43
lib/webfuse/core/path.h
Normal file
43
lib/webfuse/core/path.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef WF_PATH_H
|
||||
#define WF_PATH_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include <cstddef>
|
||||
using ::std::size_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wf_path;
|
||||
|
||||
extern struct wf_path *
|
||||
wf_path_create(
|
||||
char const * value);
|
||||
|
||||
extern void
|
||||
wf_path_dispose(
|
||||
struct wf_path * path);
|
||||
|
||||
extern size_t
|
||||
wf_path_element_count(
|
||||
struct wf_path * path);
|
||||
|
||||
extern char const *
|
||||
wf_path_get_element(
|
||||
struct wf_path * path,
|
||||
size_t i);
|
||||
|
||||
extern char const *
|
||||
wf_path_get_filename(
|
||||
struct wf_path * path);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -4,14 +4,20 @@
|
||||
void wf_slist_init(
|
||||
struct wf_slist * list)
|
||||
{
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
list->head.next = NULL;
|
||||
list->last = &list->head;
|
||||
}
|
||||
|
||||
bool wf_slist_empty(
|
||||
struct wf_slist * list)
|
||||
{
|
||||
return (NULL == list->first);
|
||||
return (list->last == &list->head);
|
||||
}
|
||||
|
||||
struct wf_slist_item * wf_slist_first(
|
||||
struct wf_slist * list)
|
||||
{
|
||||
return list->head.next;
|
||||
}
|
||||
|
||||
void wf_slist_append(
|
||||
@ -19,58 +25,36 @@ void wf_slist_append(
|
||||
struct wf_slist_item * item)
|
||||
{
|
||||
item->next = NULL;
|
||||
|
||||
if (NULL != list->last)
|
||||
{
|
||||
list->last->next = item;
|
||||
list->last = item;
|
||||
}
|
||||
else
|
||||
|
||||
if (NULL == list->head.next)
|
||||
{
|
||||
list->first = item;
|
||||
list->last = item;
|
||||
list->head.next = item;
|
||||
}
|
||||
}
|
||||
|
||||
struct wf_slist_item * wf_slist_remove_first(
|
||||
struct wf_slist * list)
|
||||
{
|
||||
struct wf_slist_item * const result = list->first;
|
||||
if (NULL != result)
|
||||
{
|
||||
list->first = list->first->next;
|
||||
if (NULL == list->first)
|
||||
{
|
||||
list->last = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return wf_slist_remove_after(list, &list->head);
|
||||
}
|
||||
|
||||
struct wf_slist_item * wf_slist_remove_after(
|
||||
struct wf_slist * list,
|
||||
struct wf_slist_item * prev)
|
||||
{
|
||||
struct wf_slist_item * result = NULL;
|
||||
|
||||
if (NULL != prev)
|
||||
{
|
||||
result = prev->next;
|
||||
if ((NULL != result) && (NULL != result->next))
|
||||
struct wf_slist_item * result = prev->next;
|
||||
|
||||
if (NULL != result)
|
||||
{
|
||||
prev->next = result->next;
|
||||
}
|
||||
else
|
||||
|
||||
if (list->last == result)
|
||||
{
|
||||
list->last = prev;
|
||||
prev->next = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
result = wf_slist_remove_first(list);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -17,7 +17,7 @@ struct wf_slist_item
|
||||
|
||||
struct wf_slist
|
||||
{
|
||||
struct wf_slist_item * first;
|
||||
struct wf_slist_item head;
|
||||
struct wf_slist_item * last;
|
||||
};
|
||||
|
||||
@ -27,6 +27,9 @@ extern void wf_slist_init(
|
||||
extern bool wf_slist_empty(
|
||||
struct wf_slist * list);
|
||||
|
||||
extern struct wf_slist_item * wf_slist_first(
|
||||
struct wf_slist * list);
|
||||
|
||||
extern void wf_slist_append(
|
||||
struct wf_slist * list,
|
||||
struct wf_slist_item * item);
|
||||
|
@ -10,7 +10,7 @@ char * wf_create_string(char const * format, ...)
|
||||
va_list measure_args;
|
||||
va_start(measure_args, format);
|
||||
char buffer;
|
||||
int needed = vsnprintf(&buffer, 1, format, measure_args); /* Flawfinder: ignore */
|
||||
int needed = vsnprintf(&buffer, 1, format, measure_args);
|
||||
va_end(measure_args);
|
||||
|
||||
if (0 <= needed)
|
||||
@ -20,7 +20,7 @@ char * wf_create_string(char const * format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int count = vsnprintf(result, needed + 1, format, args); /* Flawfinder: ignore */
|
||||
int count = vsnprintf(result, needed + 1, format, args);
|
||||
va_end(args);
|
||||
|
||||
if ((count < 0) || (needed < count))
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "webfuse/provider/impl/client_config.h"
|
||||
#include "webfuse/provider/impl/client.h"
|
||||
#include "webfuse/provider/impl/dirbuffer.h"
|
||||
#include "webfuse/provider/impl/static_filesystem.h"
|
||||
|
||||
// respond
|
||||
|
||||
@ -205,16 +206,11 @@ void wfp_client_dispose(
|
||||
wfp_impl_client_dispose(client);
|
||||
}
|
||||
|
||||
void wfp_client_run(
|
||||
struct wfp_client * client)
|
||||
void wfp_client_service(
|
||||
struct wfp_client * client,
|
||||
int timeout_ms)
|
||||
{
|
||||
wfp_impl_client_run(client);
|
||||
}
|
||||
|
||||
void wfp_client_shutdown(
|
||||
struct wfp_client * client)
|
||||
{
|
||||
wfp_impl_client_shutdown(client);
|
||||
wfp_impl_client_service(client, timeout_ms);
|
||||
}
|
||||
|
||||
// dirbuffer
|
||||
@ -238,3 +234,59 @@ void wfp_dirbuffer_add(
|
||||
wfp_impl_dirbuffer_add(buffer, name, inode);
|
||||
}
|
||||
|
||||
// static_filesystem
|
||||
|
||||
struct wfp_static_filesystem *
|
||||
wfp_static_filesystem_create(
|
||||
struct wfp_client_config * config)
|
||||
{
|
||||
return wfp_impl_static_filesystem_create(config);
|
||||
}
|
||||
|
||||
void
|
||||
wfp_static_filesystem_dispose(
|
||||
struct wfp_static_filesystem * filesystem)
|
||||
{
|
||||
wfp_impl_static_filesystem_dispose(filesystem);
|
||||
}
|
||||
|
||||
void
|
||||
wfp_static_filesystem_add(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
int mode,
|
||||
char const * content,
|
||||
size_t length)
|
||||
{
|
||||
wfp_impl_static_filesystem_add(filesystem, path, mode, content, length);
|
||||
}
|
||||
|
||||
void
|
||||
wfp_static_filesystem_add_text(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
int mode,
|
||||
char const * content)
|
||||
{
|
||||
wfp_impl_static_filesystem_add_text(filesystem, path, mode, content);
|
||||
}
|
||||
|
||||
void
|
||||
wfp_static_filesystem_add_file(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
char const * filename)
|
||||
{
|
||||
wfp_impl_static_filesystem_add_file(filesystem, path, filename);
|
||||
}
|
||||
|
||||
void
|
||||
wfp_static_filesystem_add_generic(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
wfp_static_filesystem_read_fn * read,
|
||||
wfp_static_filesystem_get_info_fn * get_info,
|
||||
void * user_data)
|
||||
{
|
||||
wfp_impl_static_filesystem_add_generic(filesystem, path, read, get_info, user_data);
|
||||
}
|
||||
|
@ -14,11 +14,9 @@
|
||||
#define WFP_PROTOCOL ("fs")
|
||||
#define WFP_DISABLE_LWS_LOG 0
|
||||
#define WFP_CLIENT_PROTOCOL_COUNT 2
|
||||
#define WFP_CLIENT_TIMEOUT (1 * 1000)
|
||||
|
||||
struct wfp_client
|
||||
{
|
||||
volatile bool is_running;
|
||||
struct wfp_client_protocol protocol;
|
||||
struct lws_context_creation_info info;
|
||||
struct lws_protocols protocols[WFP_CLIENT_PROTOCOL_COUNT];
|
||||
@ -36,7 +34,6 @@ struct wfp_client * wfp_impl_client_create(
|
||||
struct wfp_client * client = malloc(sizeof(struct wfp_client));
|
||||
if (NULL != client)
|
||||
{
|
||||
client->is_running = true;
|
||||
wfp_impl_client_protocol_init(&client->protocol, &config->provider, config->user_data);
|
||||
|
||||
memset(client->protocols, 0, sizeof(struct lws_protocols) * WFP_CLIENT_PROTOCOL_COUNT);
|
||||
@ -102,18 +99,10 @@ void wfp_impl_client_disconnect(
|
||||
// ToDo: implement me
|
||||
}
|
||||
|
||||
void wfp_impl_client_run(
|
||||
struct wfp_client * client)
|
||||
void wfp_impl_client_service(
|
||||
struct wfp_client * client,
|
||||
int timeout_ms)
|
||||
{
|
||||
while (client->is_running)
|
||||
{
|
||||
lws_service(client->context, WFP_CLIENT_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
void wfp_impl_client_shutdown(
|
||||
struct wfp_client * client)
|
||||
{
|
||||
client->is_running = false;
|
||||
lws_service(client->context, timeout_ms);
|
||||
}
|
||||
|
||||
|
@ -34,12 +34,9 @@ extern void wfp_impl_client_settimeout(
|
||||
extern void wfp_impl_client_dispose(
|
||||
struct wfp_client * client);
|
||||
|
||||
extern void wfp_impl_client_run(
|
||||
struct wfp_client * client);
|
||||
|
||||
extern void wfp_impl_client_shutdown(
|
||||
struct wfp_client * client);
|
||||
|
||||
extern void wfp_impl_client_service(
|
||||
struct wfp_client * client,
|
||||
int timeout_ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ void wfp_impl_open(
|
||||
|
||||
struct wfp_request * request = wfp_impl_request_create(context->request, id);
|
||||
|
||||
context->provider->open(request, inode, flags, context->user_data); /* Flawfinder: ignore */
|
||||
context->provider->open(request, inode, flags, context->user_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ void wfp_impl_read(
|
||||
size_t length = json_integer_value(length_holder);
|
||||
struct wfp_request * request = wfp_impl_request_create(context->request, id);
|
||||
|
||||
context->provider->read(request, inode, handle, offset, length, context->user_data); /* Flawfinder: ignore */
|
||||
context->provider->read(request, inode, handle, offset, length, context->user_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
502
lib/webfuse/provider/impl/static_filesystem.c
Normal file
502
lib/webfuse/provider/impl/static_filesystem.c
Normal file
@ -0,0 +1,502 @@
|
||||
#include "webfuse/provider/impl/static_filesystem.h"
|
||||
#include "webfuse/provider/client_config.h"
|
||||
#include "webfuse/provider/dirbuffer.h"
|
||||
#include "webfuse/provider/operation/error.h"
|
||||
|
||||
#include "webfuse/core/path.h"
|
||||
#include "webfuse/core/util.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define WFP_STATIC_FILESYSTEM_DEFAULT_CAPACITY (16)
|
||||
#define WFP_STATIC_FILSYSTEM_INDOE_ROOT (1)
|
||||
#define WFP_STATIC_FILESYSTEM_MAX_READ_SIZE (4 * 1024)
|
||||
|
||||
struct wfp_static_filesystem_entry
|
||||
{
|
||||
size_t inode;
|
||||
size_t parent;
|
||||
char * name;
|
||||
bool is_file;
|
||||
int mode;
|
||||
size_t size;
|
||||
char * content;
|
||||
wfp_static_filesystem_read_fn * read;
|
||||
wfp_static_filesystem_get_info_fn * get_info;
|
||||
void * user_data;
|
||||
};
|
||||
|
||||
struct wfp_static_filesystem
|
||||
{
|
||||
struct wfp_static_filesystem_entry * entries;
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
};
|
||||
|
||||
static struct wfp_static_filesystem_entry *
|
||||
wfp_impl_static_filesystem_get_entry(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
size_t inode)
|
||||
{
|
||||
struct wfp_static_filesystem_entry * entry = NULL;
|
||||
|
||||
if ((0 < inode) && (inode <= filesystem->size))
|
||||
{
|
||||
entry = &filesystem->entries[inode - 1];
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static struct wfp_static_filesystem_entry *
|
||||
wfp_impl_static_filesystem_get_entry_by_name(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
size_t parent,
|
||||
char const * name)
|
||||
{
|
||||
struct wfp_static_filesystem_entry * entry = NULL;
|
||||
for(size_t i = 0; i < filesystem->size; i++)
|
||||
{
|
||||
struct wfp_static_filesystem_entry * current = &filesystem->entries[i];
|
||||
if ((parent == current->parent) && (0 == strcmp(name, current->name)))
|
||||
{
|
||||
entry = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static struct wfp_static_filesystem_entry *
|
||||
wfp_impl_static_filesystem_add_entry(
|
||||
struct wfp_static_filesystem * filesystem)
|
||||
{
|
||||
struct wfp_static_filesystem_entry * entry = NULL;
|
||||
|
||||
if (filesystem->size >= filesystem->capacity)
|
||||
{
|
||||
struct wfp_static_filesystem_entry * entries;
|
||||
|
||||
size_t new_capacity = 2 * filesystem->capacity;
|
||||
size_t new_size = new_capacity * sizeof(struct wfp_static_filesystem_entry);
|
||||
entries = realloc(filesystem->entries, new_size);
|
||||
|
||||
if (NULL != entries)
|
||||
{
|
||||
filesystem->entries = entries;
|
||||
filesystem->capacity = new_capacity;
|
||||
}
|
||||
}
|
||||
|
||||
if (filesystem->size < filesystem->capacity)
|
||||
{
|
||||
entry = &filesystem->entries[filesystem->size];
|
||||
entry->inode = filesystem->size + 1;
|
||||
filesystem->size++;
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static size_t
|
||||
wfp_impl_static_filesystem_entry_read(
|
||||
size_t offset,
|
||||
char * buffer,
|
||||
size_t buffer_size,
|
||||
void * user_data)
|
||||
{
|
||||
size_t result = 0;
|
||||
struct wfp_static_filesystem_entry * entry = user_data;
|
||||
if (offset < entry->size)
|
||||
{
|
||||
size_t remaining = (entry->size - offset);
|
||||
result = (buffer_size < remaining) ? buffer_size : remaining;
|
||||
memcpy(buffer, entry->content, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
wfp_impl_static_filesystem_entry_get_info(
|
||||
void * user_data,
|
||||
int * result_mode,
|
||||
size_t * result_size)
|
||||
{
|
||||
struct wfp_static_filesystem_entry * entry = user_data;
|
||||
*result_mode = entry->mode;
|
||||
*result_size = entry->size;
|
||||
}
|
||||
|
||||
static size_t
|
||||
wfp_impl_static_filesystem_file_read(
|
||||
size_t offset,
|
||||
char * buffer,
|
||||
size_t buffer_size,
|
||||
void * user_data)
|
||||
{
|
||||
size_t result = 0;
|
||||
struct wfp_static_filesystem_entry * entry = user_data;
|
||||
char const * filename = entry->content;
|
||||
|
||||
FILE * file = fopen(filename, "rb");
|
||||
if (NULL != file)
|
||||
{
|
||||
fseek(file, offset, SEEK_SET);
|
||||
result = fread(buffer, buffer_size, 1, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
wfp_impl_static_filesystem_file_get_info(
|
||||
void * user_data,
|
||||
int * result_mode,
|
||||
size_t * result_size)
|
||||
{
|
||||
struct wfp_static_filesystem_entry * entry = user_data;
|
||||
char const * filename = entry->content;
|
||||
|
||||
struct stat buffer;
|
||||
stat(filename, &buffer);
|
||||
|
||||
*result_mode = (int) (buffer.st_mode & 0777);
|
||||
*result_size = (size_t) buffer.st_size;
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
wfp_impl_static_filesystem_add_dir(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
size_t parent,
|
||||
char const * name
|
||||
)
|
||||
{
|
||||
size_t result = 0;
|
||||
|
||||
struct wfp_static_filesystem_entry * entry = wfp_impl_static_filesystem_get_entry_by_name(filesystem, parent, name);
|
||||
if (NULL == entry)
|
||||
{
|
||||
entry = wfp_impl_static_filesystem_add_entry(filesystem);
|
||||
entry->parent = parent;
|
||||
entry->is_file = false;
|
||||
entry->mode = 0555;
|
||||
entry->name = strdup(name);
|
||||
entry->user_data = entry;
|
||||
entry->read = &wfp_impl_static_filesystem_entry_read;
|
||||
entry->get_info = &wfp_impl_static_filesystem_entry_get_info;
|
||||
entry->size = 0;
|
||||
entry->content = NULL;
|
||||
|
||||
result = entry->inode;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static size_t
|
||||
wfp_impl_static_filesystem_make_parent(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
struct wf_path * path)
|
||||
{
|
||||
size_t result = WFP_STATIC_FILSYSTEM_INDOE_ROOT;
|
||||
|
||||
size_t count = wf_path_element_count(path);
|
||||
if (0 < count)
|
||||
{
|
||||
for(size_t i = 0; i < (count - 1); i++)
|
||||
{
|
||||
char const * name = wf_path_get_element(path, i);
|
||||
result = wfp_impl_static_filesystem_add_dir(filesystem, result, name);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
wfp_impl_static_filesystem_stat(
|
||||
struct wfp_static_filesystem_entry * entry,
|
||||
struct stat * stat
|
||||
)
|
||||
{
|
||||
memset(stat, 0, sizeof(struct stat));
|
||||
|
||||
int mode;
|
||||
size_t size;
|
||||
entry->get_info(entry->user_data, &mode, &size);
|
||||
|
||||
stat->st_ino = entry->inode;
|
||||
stat->st_size = entry->size;
|
||||
stat->st_mode = entry->mode & 0777;
|
||||
stat->st_mode |= (entry->is_file) ? S_IFREG: S_IFDIR;
|
||||
}
|
||||
|
||||
static void wfp_impl_static_filesystem_lookup(
|
||||
struct wfp_request * request,
|
||||
ino_t parent,
|
||||
char const * name,
|
||||
void * user_data)
|
||||
{
|
||||
struct wfp_static_filesystem * filesystem = user_data;
|
||||
struct wfp_static_filesystem_entry * entry = wfp_impl_static_filesystem_get_entry_by_name(filesystem, parent, name);
|
||||
|
||||
if (NULL != entry)
|
||||
{
|
||||
struct stat stat;
|
||||
wfp_impl_static_filesystem_stat(entry, &stat);
|
||||
wfp_respond_lookup(request, &stat);
|
||||
}
|
||||
else
|
||||
{
|
||||
wfp_respond_error(request, WF_BAD_NOENTRY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void wfp_impl_static_filesystem_getattr(
|
||||
struct wfp_request * request,
|
||||
ino_t inode,
|
||||
void * user_data)
|
||||
{
|
||||
struct wfp_static_filesystem * filesystem = user_data;
|
||||
struct wfp_static_filesystem_entry * entry = wfp_impl_static_filesystem_get_entry(filesystem, inode);
|
||||
|
||||
if (NULL != entry)
|
||||
{
|
||||
struct stat stat;
|
||||
wfp_impl_static_filesystem_stat(entry, &stat);
|
||||
wfp_respond_getattr(request, &stat);
|
||||
}
|
||||
else
|
||||
{
|
||||
wfp_respond_error(request, WF_BAD_NOENTRY);
|
||||
}
|
||||
}
|
||||
|
||||
static void wfp_impl_static_filesystem_readdir(
|
||||
struct wfp_request * request,
|
||||
ino_t directory,
|
||||
void * user_data)
|
||||
{
|
||||
struct wfp_static_filesystem * filesystem = user_data;
|
||||
struct wfp_static_filesystem_entry * dir = wfp_impl_static_filesystem_get_entry(filesystem, directory);
|
||||
|
||||
if ((NULL != dir) && (!dir->is_file))
|
||||
{
|
||||
struct wfp_dirbuffer * buffer = wfp_dirbuffer_create();
|
||||
wfp_dirbuffer_add(buffer, ".", dir->inode);
|
||||
wfp_dirbuffer_add(buffer, "..", dir->inode);
|
||||
|
||||
for(size_t i = 0; i < filesystem->size; i++)
|
||||
{
|
||||
struct wfp_static_filesystem_entry const * entry = &filesystem->entries[i];
|
||||
if (directory == entry->parent)
|
||||
{
|
||||
wfp_dirbuffer_add(buffer, entry->name, entry->inode);
|
||||
}
|
||||
}
|
||||
|
||||
wfp_respond_readdir(request, buffer);
|
||||
wfp_dirbuffer_dispose(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
wfp_respond_error(request, WF_BAD_NOENTRY);
|
||||
}
|
||||
}
|
||||
|
||||
static void wfp_impl_static_filesystem_open(
|
||||
struct wfp_request * request,
|
||||
ino_t inode,
|
||||
int flags,
|
||||
void * user_data)
|
||||
{
|
||||
struct wfp_static_filesystem * filesystem = user_data;
|
||||
struct wfp_static_filesystem_entry * entry = wfp_impl_static_filesystem_get_entry(filesystem, inode);
|
||||
|
||||
if ((NULL != entry) && (entry->is_file))
|
||||
{
|
||||
if (O_RDONLY == (flags & O_ACCMODE))
|
||||
{
|
||||
wfp_respond_open(request, 0U);
|
||||
}
|
||||
else
|
||||
{
|
||||
wfp_respond_error(request, WF_BAD_ACCESS_DENIED);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wfp_respond_error(request, WF_BAD_NOENTRY);
|
||||
}
|
||||
}
|
||||
|
||||
static void wfp_impl_static_filesystem_read(
|
||||
struct wfp_request * request,
|
||||
ino_t inode,
|
||||
uint32_t WF_UNUSED_PARAM(handle),
|
||||
size_t offset,
|
||||
size_t length,
|
||||
void * user_data)
|
||||
{
|
||||
struct wfp_static_filesystem * filesystem = user_data;
|
||||
struct wfp_static_filesystem_entry * entry = wfp_impl_static_filesystem_get_entry(filesystem, inode);
|
||||
|
||||
if ((NULL != entry) && (entry->is_file))
|
||||
{
|
||||
char buffer[WFP_STATIC_FILESYSTEM_MAX_READ_SIZE];
|
||||
size_t max_size = (length < WFP_STATIC_FILESYSTEM_MAX_READ_SIZE) ? length : WFP_STATIC_FILESYSTEM_MAX_READ_SIZE;
|
||||
|
||||
size_t count = entry->read(offset, buffer, max_size, entry->user_data);
|
||||
wfp_respond_read(request, buffer, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
wfp_respond_error(request, WF_BAD_NOENTRY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct wfp_static_filesystem *
|
||||
wfp_impl_static_filesystem_create(
|
||||
struct wfp_client_config * config)
|
||||
{
|
||||
(void) config;
|
||||
|
||||
struct wfp_static_filesystem * filesystem = malloc(sizeof(struct wfp_static_filesystem));
|
||||
if (NULL != filesystem)
|
||||
{
|
||||
filesystem->entries = malloc(sizeof(struct wfp_static_filesystem_entry) * WFP_STATIC_FILESYSTEM_DEFAULT_CAPACITY);
|
||||
filesystem->size = 0;
|
||||
filesystem->capacity = WFP_STATIC_FILESYSTEM_DEFAULT_CAPACITY;
|
||||
|
||||
wfp_impl_static_filesystem_add_dir(filesystem, 0, "<root>");
|
||||
|
||||
wfp_client_config_set_userdata(config, filesystem);
|
||||
wfp_client_config_set_onlookup(config, &wfp_impl_static_filesystem_lookup);
|
||||
wfp_client_config_set_ongetattr(config, &wfp_impl_static_filesystem_getattr);
|
||||
wfp_client_config_set_onreaddir(config, &wfp_impl_static_filesystem_readdir);
|
||||
wfp_client_config_set_onopen(config, &wfp_impl_static_filesystem_open);
|
||||
wfp_client_config_set_onread(config, &wfp_impl_static_filesystem_read);
|
||||
}
|
||||
|
||||
return filesystem;
|
||||
}
|
||||
|
||||
void
|
||||
wfp_impl_static_filesystem_dispose(
|
||||
struct wfp_static_filesystem * filesystem)
|
||||
{
|
||||
for(size_t i = 0; i < filesystem->size; i++)
|
||||
{
|
||||
struct wfp_static_filesystem_entry * entry = &filesystem->entries[i];
|
||||
free(entry->name);
|
||||
free(entry->content);
|
||||
}
|
||||
|
||||
free(filesystem->entries);
|
||||
free(filesystem);
|
||||
}
|
||||
|
||||
void
|
||||
wfp_impl_static_filesystem_add(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
int mode,
|
||||
char const * content,
|
||||
size_t length)
|
||||
{
|
||||
struct wf_path * path_ = wf_path_create(path);
|
||||
if (NULL != path_)
|
||||
{
|
||||
size_t parent = wfp_impl_static_filesystem_make_parent(filesystem, path_);
|
||||
struct wfp_static_filesystem_entry * entry = wfp_impl_static_filesystem_add_entry(filesystem);
|
||||
entry->parent = parent;
|
||||
entry->is_file = true;
|
||||
entry->name = strdup(wf_path_get_filename(path_));
|
||||
entry->mode = mode;
|
||||
entry->size = length;
|
||||
entry->get_info = &wfp_impl_static_filesystem_entry_get_info;
|
||||
entry->read = &wfp_impl_static_filesystem_entry_read;
|
||||
entry->user_data = entry;
|
||||
|
||||
entry->content = malloc(length);
|
||||
memcpy(entry->content, content, length);
|
||||
|
||||
wf_path_dispose(path_);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wfp_impl_static_filesystem_add_text(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
int mode,
|
||||
char const * content)
|
||||
{
|
||||
size_t length = strlen(content);
|
||||
wfp_impl_static_filesystem_add(filesystem, path, mode, content, length);
|
||||
}
|
||||
|
||||
void
|
||||
wfp_impl_static_filesystem_add_file(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
char const * filename)
|
||||
{
|
||||
struct wf_path * path_ = wf_path_create(path);
|
||||
if (NULL != path_)
|
||||
{
|
||||
size_t parent = wfp_impl_static_filesystem_make_parent(filesystem, path_);
|
||||
struct wfp_static_filesystem_entry * entry = wfp_impl_static_filesystem_add_entry(filesystem);
|
||||
entry->parent = parent;
|
||||
entry->is_file = true;
|
||||
entry->mode = 0;
|
||||
entry->content = strdup(filename);
|
||||
entry->size = 0;
|
||||
entry->name = strdup(wf_path_get_filename(path_));
|
||||
entry->get_info = &wfp_impl_static_filesystem_file_get_info;
|
||||
entry->read = &wfp_impl_static_filesystem_file_read;
|
||||
entry->user_data = entry;
|
||||
|
||||
wf_path_dispose(path_);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wfp_impl_static_filesystem_add_generic(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
wfp_static_filesystem_read_fn * read,
|
||||
wfp_static_filesystem_get_info_fn * get_info,
|
||||
void * user_data)
|
||||
{
|
||||
struct wf_path * path_ = wf_path_create(path);
|
||||
if (NULL != path_)
|
||||
{
|
||||
size_t parent = wfp_impl_static_filesystem_make_parent(filesystem, path_);
|
||||
struct wfp_static_filesystem_entry * entry = wfp_impl_static_filesystem_add_entry(filesystem);
|
||||
entry->parent = parent;
|
||||
entry->is_file = true;
|
||||
entry->mode = 0;
|
||||
entry->content = NULL;
|
||||
entry->size = 0;
|
||||
entry->name = strdup(wf_path_get_filename(path_));
|
||||
entry->get_info = get_info;
|
||||
entry->read = read;
|
||||
entry->user_data = user_data;
|
||||
|
||||
wf_path_dispose(path_);
|
||||
}
|
||||
}
|
52
lib/webfuse/provider/impl/static_filesystem.h
Normal file
52
lib/webfuse/provider/impl/static_filesystem.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef WFP_IMPL_STATIC_FILESYSTEM_H
|
||||
#define WFP_IMPL_STATIC_FILESYSTEM_H
|
||||
|
||||
#include "webfuse/provider/static_filesystem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
extern struct wfp_static_filesystem *
|
||||
wfp_impl_static_filesystem_create(
|
||||
struct wfp_client_config * config);
|
||||
|
||||
extern void
|
||||
wfp_impl_static_filesystem_dispose(
|
||||
struct wfp_static_filesystem * filesystem);
|
||||
|
||||
extern void
|
||||
wfp_impl_static_filesystem_add(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
int mode,
|
||||
char const * content,
|
||||
size_t length);
|
||||
|
||||
extern void
|
||||
wfp_impl_static_filesystem_add_text(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
int mode,
|
||||
char const * content);
|
||||
|
||||
extern void
|
||||
wfp_impl_static_filesystem_add_file(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
char const * filename);
|
||||
|
||||
extern void
|
||||
wfp_impl_static_filesystem_add_generic(
|
||||
struct wfp_static_filesystem * filesystem,
|
||||
char const * path,
|
||||
wfp_static_filesystem_read_fn * read,
|
||||
wfp_static_filesystem_get_info_fn * get_info,
|
||||
void * user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
34
test/json_matcher.hpp
Normal file
34
test/json_matcher.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef WF_JSON_MATCHER_HPP
|
||||
#define FW_JSON_MATCHER_HPP
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <jansson.h>
|
||||
|
||||
namespace webfuse_test
|
||||
{
|
||||
|
||||
MATCHER_P(JsonMatcher, expected_str, "")
|
||||
{
|
||||
std::cout << "--- JsonMatcher ---" << std::endl;
|
||||
bool matches = false;
|
||||
json_t * expected = json_loads(expected_str, 0, nullptr);
|
||||
if (nullptr != expected)
|
||||
{
|
||||
matches = (1 == json_equal(expected, arg));
|
||||
if (!matches)
|
||||
{
|
||||
char * actual = json_dumps(arg, 0);
|
||||
std::cout << actual << std::endl;
|
||||
*result_listener << "where arg is " << actual;
|
||||
free(actual);
|
||||
}
|
||||
|
||||
json_decref(expected);
|
||||
}
|
||||
|
||||
return true; //matches;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
55
test/mock_request.cc
Normal file
55
test/mock_request.cc
Normal file
@ -0,0 +1,55 @@
|
||||
#include "mock_request.hpp"
|
||||
#include <cstdlib>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
extern "C" void
|
||||
respond(
|
||||
json_t * response,
|
||||
void * user_data)
|
||||
{
|
||||
webfuse_test::Request * request = reinterpret_cast<webfuse_test::Request*>(user_data);
|
||||
|
||||
json_t * result = json_object_get(response, "result");
|
||||
json_t * error = json_object_get(response, "error");
|
||||
json_t * id_holder = json_object_get(response, "id");
|
||||
|
||||
int id = -1;
|
||||
if (json_is_integer(id_holder))
|
||||
{
|
||||
id = json_integer_value(id_holder);
|
||||
}
|
||||
|
||||
if (nullptr != result)
|
||||
{
|
||||
request->respond(result, id);
|
||||
}
|
||||
else
|
||||
{
|
||||
request->respond_error(error, id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
namespace webfuse_test
|
||||
{
|
||||
|
||||
struct wfp_request *
|
||||
request_create(
|
||||
Request * req,
|
||||
int id)
|
||||
{
|
||||
struct wfp_request * request = reinterpret_cast<struct wfp_request *>(malloc(sizeof(struct wfp_request)));
|
||||
request->id = id;
|
||||
request->user_data = reinterpret_cast<void*>(req);
|
||||
request->respond = &respond;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
122
test/mock_request.hpp
Normal file
122
test/mock_request.hpp
Normal file
@ -0,0 +1,122 @@
|
||||
#ifndef WF_MOCK_REQUEST_HPP
|
||||
#define WF_MOCK_REQUEST_HPP
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <jansson.h>
|
||||
#include <cstring>
|
||||
#include "webfuse/provider/impl/request.h"
|
||||
|
||||
|
||||
namespace webfuse_test
|
||||
{
|
||||
|
||||
class Request
|
||||
{
|
||||
public:
|
||||
virtual ~Request() { }
|
||||
virtual void respond(json_t * result, int id) = 0;
|
||||
virtual void respond_error(json_t * error, int id) = 0;
|
||||
};
|
||||
|
||||
class MockRequest: public Request
|
||||
{
|
||||
public:
|
||||
MOCK_METHOD2(respond, void(json_t * result, int id));
|
||||
MOCK_METHOD2(respond_error, void(json_t * error, int id));
|
||||
};
|
||||
|
||||
extern struct wfp_request *
|
||||
request_create(
|
||||
Request * req,
|
||||
int id);
|
||||
|
||||
MATCHER_P3(GetAttrMatcher, inode, mode, file_type, "")
|
||||
{
|
||||
json_t * inode_holder = json_object_get(arg, "inode");
|
||||
if ((!json_is_integer(inode_holder)) || (inode != json_integer_value(inode_holder)))
|
||||
{
|
||||
*result_listener << "missing inode";
|
||||
return false;
|
||||
}
|
||||
|
||||
json_t * mode_holder = json_object_get(arg, "mode");
|
||||
if ((!json_is_integer(mode_holder)) || (mode != json_integer_value(mode_holder)))
|
||||
{
|
||||
*result_listener << "missing mode";
|
||||
return false;
|
||||
}
|
||||
|
||||
json_t * type_holder = json_object_get(arg, "type");
|
||||
if ((!json_is_string(type_holder)) || (0 != strcmp(file_type, json_string_value(type_holder))))
|
||||
{
|
||||
*result_listener << "missing type";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
MATCHER_P(ReaddirMatcher, contained_elements , "")
|
||||
{
|
||||
if (!json_is_array(arg))
|
||||
{
|
||||
*result_listener << "result is not array";
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
size_t i;
|
||||
json_t * value;
|
||||
|
||||
json_array_foreach(arg, i, value)
|
||||
{
|
||||
json_t * inode = json_object_get(value, "inode");
|
||||
json_t * name = json_object_get(value, "name");
|
||||
|
||||
if(!json_is_integer(inode))
|
||||
{
|
||||
*result_listener << "invalid result: missing inode";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!json_is_string(name))
|
||||
{
|
||||
*result_listener << "invalid result: missing name";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; NULL != contained_elements[i]; i++)
|
||||
{
|
||||
char const * element = contained_elements[i];
|
||||
bool found = false;
|
||||
size_t j;
|
||||
json_t * value;
|
||||
|
||||
json_array_foreach(arg, j, value)
|
||||
{
|
||||
json_t * name = json_object_get(value, "name");
|
||||
|
||||
found = (0 == strcmp(element, json_string_value(name)));
|
||||
if (found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
*result_listener << "missing required directory element: " << element;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
58
test/test_path.cc
Normal file
58
test/test_path.cc
Normal file
@ -0,0 +1,58 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "webfuse/core/path.h"
|
||||
|
||||
TEST(wf_path, empty)
|
||||
{
|
||||
struct wf_path * path = wf_path_create("");
|
||||
ASSERT_EQ(0, wf_path_element_count(path));
|
||||
ASSERT_EQ(nullptr, wf_path_get_element(path, 0));
|
||||
|
||||
wf_path_dispose(path);
|
||||
}
|
||||
|
||||
TEST(wf_path, relative_file)
|
||||
{
|
||||
struct wf_path * path = wf_path_create("some.file");
|
||||
ASSERT_EQ(1, wf_path_element_count(path));
|
||||
ASSERT_STREQ("some.file", wf_path_get_element(path, 0));
|
||||
|
||||
wf_path_dispose(path);
|
||||
}
|
||||
|
||||
TEST(wf_path, absolute_file)
|
||||
{
|
||||
struct wf_path * path = wf_path_create("/absolute.file");
|
||||
ASSERT_EQ(1, wf_path_element_count(path));
|
||||
ASSERT_STREQ("absolute.file", wf_path_get_element(path, 0));
|
||||
|
||||
wf_path_dispose(path);
|
||||
}
|
||||
|
||||
TEST(wf_path, nested_path)
|
||||
{
|
||||
struct wf_path * path = wf_path_create("/a/nested/path");
|
||||
ASSERT_EQ(3, wf_path_element_count(path));
|
||||
ASSERT_STREQ("a", wf_path_get_element(path, 0));
|
||||
ASSERT_STREQ("nested", wf_path_get_element(path, 1));
|
||||
ASSERT_STREQ("path", wf_path_get_element(path, 2));
|
||||
|
||||
wf_path_dispose(path);
|
||||
}
|
||||
|
||||
TEST(wf_path, deep_nested_path)
|
||||
{
|
||||
struct wf_path * path = wf_path_create("/this/is/a/very/deep/nested/path/to/some/file");
|
||||
ASSERT_EQ(10, wf_path_element_count(path));
|
||||
ASSERT_STREQ("this", wf_path_get_element(path, 0));
|
||||
ASSERT_STREQ("is", wf_path_get_element(path, 1));
|
||||
ASSERT_STREQ("a", wf_path_get_element(path, 2));
|
||||
ASSERT_STREQ("very", wf_path_get_element(path, 3));
|
||||
ASSERT_STREQ("deep", wf_path_get_element(path, 4));
|
||||
ASSERT_STREQ("nested", wf_path_get_element(path, 5));
|
||||
ASSERT_STREQ("path", wf_path_get_element(path, 6));
|
||||
ASSERT_STREQ("to", wf_path_get_element(path, 7));
|
||||
ASSERT_STREQ("some", wf_path_get_element(path, 8));
|
||||
ASSERT_STREQ("file", wf_path_get_element(path, 9));
|
||||
|
||||
wf_path_dispose(path);
|
||||
}
|
@ -1,35 +1,139 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "webfuse/core/slist.h"
|
||||
|
||||
TEST(wf_slist_remove_after, RemoveFirst)
|
||||
TEST(wf_slist, init)
|
||||
{
|
||||
struct wf_slist list;
|
||||
struct wf_slist_item item[10];
|
||||
|
||||
wf_slist_init(&list);
|
||||
wf_slist_append(&list, &item[0]);
|
||||
|
||||
wf_slist_item * removed = wf_slist_remove_after(&list, NULL);
|
||||
ASSERT_EQ(nullptr, list.head.next);
|
||||
ASSERT_EQ(nullptr, list.last->next);
|
||||
ASSERT_EQ(&list.head, list.last);
|
||||
ASSERT_TRUE(wf_slist_empty(&list));
|
||||
ASSERT_EQ(nullptr, list.first);
|
||||
ASSERT_EQ(nullptr, list.last);
|
||||
ASSERT_EQ(&item[0], removed);
|
||||
ASSERT_EQ(nullptr, wf_slist_first(&list));
|
||||
}
|
||||
|
||||
TEST(wf_slist_remove_after, RemoveLast)
|
||||
TEST(wf_slist, append)
|
||||
{
|
||||
struct wf_slist list;
|
||||
struct wf_slist_item item[10];
|
||||
struct wf_slist_item item[3];
|
||||
|
||||
wf_slist_init(&list);
|
||||
ASSERT_TRUE(wf_slist_empty(&list));
|
||||
|
||||
wf_slist_append(&list, &item[0]);
|
||||
ASSERT_NE(&list.head, list.last);
|
||||
ASSERT_FALSE(wf_slist_empty(&list));
|
||||
ASSERT_EQ(&item[0], wf_slist_first(&list));
|
||||
ASSERT_EQ(&item[0], list.head.next);
|
||||
ASSERT_EQ(&item[0], list.last);
|
||||
ASSERT_EQ(nullptr, list.last->next);
|
||||
ASSERT_EQ(nullptr, item[0].next);
|
||||
|
||||
wf_slist_append(&list, &item[1]);
|
||||
ASSERT_NE(&list.head, list.last);
|
||||
ASSERT_FALSE(wf_slist_empty(&list));
|
||||
ASSERT_EQ(&item[0], wf_slist_first(&list));
|
||||
ASSERT_EQ(&item[0], list.head.next);
|
||||
ASSERT_EQ(&item[1], list.last);
|
||||
ASSERT_EQ(nullptr, list.last->next);
|
||||
ASSERT_EQ(&item[1], item[0].next);
|
||||
ASSERT_EQ(nullptr, item[1].next);
|
||||
|
||||
wf_slist_append(&list, &item[2]);
|
||||
ASSERT_NE(&list.head, list.last);
|
||||
ASSERT_FALSE(wf_slist_empty(&list));
|
||||
ASSERT_EQ(&item[0], wf_slist_first(&list));
|
||||
ASSERT_EQ(&item[0], list.head.next);
|
||||
ASSERT_EQ(&item[2], list.last);
|
||||
ASSERT_EQ(nullptr, list.last->next);
|
||||
ASSERT_EQ(&item[1], item[0].next);
|
||||
ASSERT_EQ(&item[2], item[1].next);
|
||||
ASSERT_EQ(nullptr, item[2].next);
|
||||
}
|
||||
|
||||
TEST(wf_slist_remove_after, remove_first)
|
||||
{
|
||||
struct wf_slist list;
|
||||
struct wf_slist_item item[3];
|
||||
|
||||
wf_slist_init(&list);
|
||||
wf_slist_append(&list, &item[0]);
|
||||
wf_slist_append(&list, &item[1]);
|
||||
wf_slist_append(&list, &item[2]);
|
||||
|
||||
wf_slist_item * removed = wf_slist_remove_after(&list, &item[1]);
|
||||
wf_slist_item * removed;
|
||||
|
||||
removed = wf_slist_remove_first(&list);
|
||||
ASSERT_FALSE(wf_slist_empty(&list));
|
||||
ASSERT_EQ(&item[0], list.first);
|
||||
ASSERT_EQ(&item[1], list.last);
|
||||
ASSERT_EQ(nullptr, item[1].next);
|
||||
ASSERT_EQ(&item[0], removed);
|
||||
|
||||
removed = wf_slist_remove_first(&list);
|
||||
ASSERT_FALSE(wf_slist_empty(&list));
|
||||
ASSERT_EQ(&item[1], removed);
|
||||
|
||||
removed = wf_slist_remove_first(&list);
|
||||
ASSERT_TRUE(wf_slist_empty(&list));
|
||||
ASSERT_EQ(&item[2], removed);
|
||||
|
||||
ASSERT_EQ(nullptr, list.head.next);
|
||||
ASSERT_EQ(nullptr, list.last->next);
|
||||
ASSERT_EQ(&list.head, list.last);
|
||||
ASSERT_EQ(nullptr, wf_slist_first(&list));
|
||||
}
|
||||
|
||||
TEST(wf_slist_remove_after, remove_last)
|
||||
{
|
||||
struct wf_slist list;
|
||||
struct wf_slist_item item[3];
|
||||
|
||||
wf_slist_init(&list);
|
||||
wf_slist_append(&list, &item[0]);
|
||||
wf_slist_append(&list, &item[1]);
|
||||
wf_slist_append(&list, &item[2]);
|
||||
|
||||
wf_slist_item * removed;
|
||||
|
||||
removed = wf_slist_remove_after(&list, &item[1]);
|
||||
ASSERT_FALSE(wf_slist_empty(&list));
|
||||
ASSERT_EQ(&item[2], removed);
|
||||
|
||||
removed = wf_slist_remove_after(&list, &item[0]);
|
||||
ASSERT_FALSE(wf_slist_empty(&list));
|
||||
ASSERT_EQ(&item[1], removed);
|
||||
|
||||
removed = wf_slist_remove_after(&list, &list.head);
|
||||
ASSERT_TRUE(wf_slist_empty(&list));
|
||||
ASSERT_EQ(&item[0], removed);
|
||||
|
||||
ASSERT_EQ(nullptr, list.head.next);
|
||||
ASSERT_EQ(nullptr, list.last->next);
|
||||
ASSERT_EQ(&list.head, list.last);
|
||||
ASSERT_EQ(nullptr, wf_slist_first(&list));
|
||||
}
|
||||
|
||||
TEST(wf_slist_remove_after, remove_after)
|
||||
{
|
||||
struct wf_slist list;
|
||||
struct wf_slist_item item[3];
|
||||
|
||||
wf_slist_init(&list);
|
||||
wf_slist_append(&list, &item[0]);
|
||||
wf_slist_append(&list, &item[1]);
|
||||
wf_slist_append(&list, &item[2]);
|
||||
|
||||
wf_slist_item * removed;
|
||||
|
||||
removed = wf_slist_remove_after(&list, &item[0]);
|
||||
ASSERT_FALSE(wf_slist_empty(&list));
|
||||
ASSERT_EQ(&item[1], removed);
|
||||
|
||||
ASSERT_NE(&list.head, list.last);
|
||||
ASSERT_FALSE(wf_slist_empty(&list));
|
||||
ASSERT_EQ(&item[0], wf_slist_first(&list));
|
||||
ASSERT_EQ(&item[0], list.head.next);
|
||||
ASSERT_EQ(&item[2], list.last);
|
||||
ASSERT_EQ(nullptr, list.last->next);
|
||||
ASSERT_EQ(&item[2], item[0].next);
|
||||
ASSERT_EQ(nullptr, item[2].next);
|
||||
}
|
||||
|
61
test/test_static_filesystem.cc
Normal file
61
test/test_static_filesystem.cc
Normal file
@ -0,0 +1,61 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "webfuse/provider/impl/static_filesystem.h"
|
||||
#include "webfuse/provider/client_config.h"
|
||||
#include "webfuse/provider/impl/client_config.h"
|
||||
|
||||
#include "mock_request.hpp"
|
||||
|
||||
using webfuse_test::request_create;
|
||||
using webfuse_test::MockRequest;
|
||||
using webfuse_test::GetAttrMatcher;
|
||||
using webfuse_test::ReaddirMatcher;
|
||||
using testing::_;
|
||||
|
||||
TEST(wfp_static_filesystem, has_root_dir)
|
||||
{
|
||||
struct wfp_client_config * config = wfp_client_config_create();
|
||||
struct wfp_static_filesystem * filesystem = wfp_impl_static_filesystem_create(config);
|
||||
|
||||
MockRequest mock;
|
||||
struct wfp_request * request = request_create(&mock, 42);
|
||||
EXPECT_CALL(mock, respond(GetAttrMatcher(1, 0555, "dir"), 42)).Times(1);
|
||||
|
||||
config->provider.getattr(request, 1, config->user_data);
|
||||
|
||||
wfp_impl_static_filesystem_dispose(filesystem);
|
||||
wfp_client_config_dispose(config);
|
||||
}
|
||||
|
||||
TEST(wfp_static_filesystem, contains_default_dirs)
|
||||
{
|
||||
struct wfp_client_config * config = wfp_client_config_create();
|
||||
struct wfp_static_filesystem * filesystem = wfp_impl_static_filesystem_create(config);
|
||||
|
||||
MockRequest mock;
|
||||
struct wfp_request * request = request_create(&mock, 23);
|
||||
char const * default_dirs[] = {".", "..", nullptr};
|
||||
EXPECT_CALL(mock, respond(ReaddirMatcher(default_dirs), 23)).Times(1);
|
||||
|
||||
config->provider.readdir(request, 1, config->user_data);
|
||||
|
||||
wfp_impl_static_filesystem_dispose(filesystem);
|
||||
wfp_client_config_dispose(config);
|
||||
}
|
||||
|
||||
TEST(wfp_static_filesystem, add_text)
|
||||
{
|
||||
struct wfp_client_config * config = wfp_client_config_create();
|
||||
struct wfp_static_filesystem * filesystem = wfp_impl_static_filesystem_create(config);
|
||||
wfp_impl_static_filesystem_add_text(filesystem, "text.file", 666, "some text");
|
||||
|
||||
MockRequest mock;
|
||||
struct wfp_request * request = request_create(&mock, 23);
|
||||
char const * contained_elements[] = {"text.file", nullptr};
|
||||
EXPECT_CALL(mock, respond(ReaddirMatcher(contained_elements), 23)).Times(1);
|
||||
|
||||
config->provider.readdir(request, 1, config->user_data);
|
||||
|
||||
wfp_impl_static_filesystem_dispose(filesystem);
|
||||
wfp_client_config_dispose(config);
|
||||
}
|
Loading…
Reference in New Issue
Block a user