diff --git a/CMakeLists.txt b/CMakeLists.txt index 0221530..d935dfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,6 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) find_package(PkgConfig REQUIRED) -pkg_check_modules(LIBUV REQUIRED libuv) pkg_check_modules(FUSE3 REQUIRED fuse3) pkg_check_modules(LWS REQUIRED libwebsockets) pkg_check_modules(JANSSON REQUIRED jansson) @@ -15,7 +14,7 @@ pkg_check_modules(JANSSON REQUIRED jansson) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -Wextra") set(EXTRA_INCLUDE_DIRS - ${LIBUV_INCLUDE_DIRS} + "inc" ${FUSE3_INCLUDE_DIRS} ${LWS_INCLUDE_DIRS} ${JANSSON_INCLUDE_DIRS} @@ -23,7 +22,6 @@ set(EXTRA_INCLUDE_DIRS set(EXTRA_LIBS ${EXTRA_LIBS} - ${LIBUV_LIBRARIES} ${FUSE3_LIBRARIES} ${LWS_LIBRARIES} ${JANSSON_LIBRARIES} @@ -31,7 +29,6 @@ set(EXTRA_LIBS ) set(EXTRA_CFLAGS - ${LIBUV_CFLAGS_OTHER} ${FUSE3_CFLAGS_OTHER} ${LWS_CFLAGS_OTHER} ${JANSSON_CFLAGS_OTHER} @@ -43,7 +40,7 @@ set(EXTRA_CFLAGS add_library(fuse-wsfs src/wsfs/status.c - src/wsfs/operations.c + src/wsfs/filesystem.c src/wsfs/operation/lookup.c src/wsfs/operation/getattr.c src/wsfs/operation/readdir.c @@ -52,7 +49,8 @@ add_library(fuse-wsfs src/wsfs/operation/read.c src/wsfs/response_parser.c src/wsfs/server.c - src/wsfs/protocol.c + src/wsfs/server_config.c + src/wsfs/server_protocol.c src/wsfs/jsonrpc.c ) @@ -66,7 +64,7 @@ add_executable(wsfs ) target_link_libraries(wsfs PUBLIC fuse-wsfs ${EXTRA_LIBS}) -target_include_directories(wsfs PUBLIC src ${EXTRA_INCLUDE_DIRS}) +target_include_directories(wsfs PUBLIC ${EXTRA_INCLUDE_DIRS}) target_compile_options(wsfs PUBLIC ${EXTRA_CFLAGS}) # tests diff --git a/README.md b/README.md index 5a24f70..62c79f6 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,6 @@ fuse-wsfs combines libwebsockets and libfuse. It allows ot attach a remote files # Dependencies -- [libuv](https://github.com/libuv/libuv) - [libfuse3](https://github.com/libfuse/libfuse/) - [libwebsockets](https://libwebsockets.org/) - [Jansson](https://jansson.readthedocs.io) diff --git a/inc/wsfs.h b/inc/wsfs.h new file mode 100644 index 0000000..d041c94 --- /dev/null +++ b/inc/wsfs.h @@ -0,0 +1,7 @@ +#ifndef _WSFS_H +#define _WSFS_H + +#include "wsfs/api.h" +#include "wsfs/server.h" + +#endif diff --git a/inc/wsfs/api.h b/inc/wsfs/api.h new file mode 100644 index 0000000..5cb711a --- /dev/null +++ b/inc/wsfs/api.h @@ -0,0 +1,8 @@ +#ifndef _WSFS_API_H +#define _WSFS_API_H + +#ifndef WSFS_API +#define WSFS_API +#endif + +#endif diff --git a/inc/wsfs/server.h b/inc/wsfs/server.h new file mode 100644 index 0000000..b155dd1 --- /dev/null +++ b/inc/wsfs/server.h @@ -0,0 +1,31 @@ +#ifndef _WSFS_SERVER_H +#define _WSFS_SERVER_H + +#include "wsfs/api.h" + +struct wsfs_server; +struct wsfs_server_config; + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern WSFS_API struct wsfs_server * wsfs_server_create( + struct wsfs_server_config * config); + +extern WSFS_API void wsfs_server_dispose( + struct wsfs_server * server); + +extern WSFS_API void wsfs_server_run( + struct wsfs_server * server); + +extern WSFS_API void wsfs_server_shutdown( + struct wsfs_server * server); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/inc/wsfs/server_config.h b/inc/wsfs/server_config.h new file mode 100644 index 0000000..9c100e4 --- /dev/null +++ b/inc/wsfs/server_config.h @@ -0,0 +1,35 @@ +#ifndef _WSFS_SERVER_CONFIG_H +#define _WSFS_SERVER_CONFIG_H + +#include "wsfs/api.h" + +struct wsfs_server_config +{ + char * mount_point; + char * document_root; + char * key_path; + char * cert_path; + char * vhost_name; + int port; +}; + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern WSFS_API void wsfs_server_config_init( + struct wsfs_server_config * config); + +extern WSFS_API void wsfs_server_config_cleanup( + struct wsfs_server_config * config); + +extern WSFS_API void wsfs_server_config_clone( + struct wsfs_server_config * config, + struct wsfs_server_config * clone); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/wsfs/server_protocol.h b/inc/wsfs/server_protocol.h new file mode 100644 index 0000000..d5a9e9d --- /dev/null +++ b/inc/wsfs/server_protocol.h @@ -0,0 +1,28 @@ +#ifndef _WSFS_SERVER_PROTOCOL_H +#define _WSFS_SERVER_PROTOCOL_H + +#include "wsfs/api.h" + +struct wsfs_server_protocol; +struct lws_protocols; + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern WSFS_API struct wsfs_server_protocol * wsfs_server_protocol_create( + char * mount_point); + +extern WSFS_API void wsfs_server_protocol_dispose( + struct wsfs_server_protocol * protocol); + +extern WSFS_API void wsfs_server_protocol_init_lws( + struct wsfs_server_protocol * protocol, + struct lws_protocols * lws_protocol); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/app/main.c b/src/app/main.c index b645246..d62b61a 100644 --- a/src/app/main.c +++ b/src/app/main.c @@ -3,20 +3,22 @@ #include #include #include +#include #include #include -#include "wsfs/operations.h" #include "wsfs/server.h" +#include "wsfs/server_config.h" struct args { struct wsfs_server_config config; - char * mount_point; bool show_help; }; +static struct wsfs_server * server; + static void show_help(void) { printf( @@ -67,8 +69,8 @@ static int parse_arguments(int argc, char * argv[], struct args * args) finished = true; break; case 'm': - free(args->mount_point); - args->mount_point = strdup(optarg); + free(args->config.mount_point); + args->config.mount_point = strdup(optarg); break; case 'd': free(args->config.document_root); @@ -98,7 +100,7 @@ static int parse_arguments(int argc, char * argv[], struct args * args) if ((EXIT_SUCCESS == result) && (!args->show_help)) { - if (NULL == args->mount_point) + if (NULL == args->config.mount_point) { fprintf(stderr, "error: missing mount point\n"); result = EXIT_FAILURE; @@ -113,19 +115,26 @@ static int parse_arguments(int argc, char * argv[], struct args * args) return result; } +static void on_interrupt(int signal_id) +{ + (void) signal_id; + + wsfs_server_shutdown(server); +} + int main(int argc, char * argv[]) { struct args args = { .config = { + .mount_point = NULL, .document_root = NULL, .cert_path = NULL, .key_path = NULL, .vhost_name = strdup("localhost"), .port = 8080, }, - .mount_point = NULL, .show_help = 0 }; @@ -133,13 +142,11 @@ int main(int argc, char * argv[]) if (!args.show_help) { - struct wsfs_server * server = wsfs_server_create(&args.config); + signal(SIGINT, on_interrupt); + server = wsfs_server_create(&args.config); if (NULL != server) { - wsfs_server_start(server); - struct wsfs_jsonrpc * const rpc = wsfs_server_get_jsonrpc_service(server); - - result = wsfs_operations_loop(args.mount_point, rpc); + wsfs_server_run(server); wsfs_server_dispose(server); } else @@ -153,9 +160,7 @@ int main(int argc, char * argv[]) show_help(); } - wsfs_server_config_clear(&args.config); - free(args.mount_point); - + wsfs_server_config_cleanup(&args.config); return result; } diff --git a/src/wsfs/filesystem.c b/src/wsfs/filesystem.c new file mode 100644 index 0000000..c64d345 --- /dev/null +++ b/src/wsfs/filesystem.c @@ -0,0 +1,79 @@ +#include "wsfs/filesystem.h" +#include "wsfs/operations.h" +#include "wsfs/jsonrpc.h" + +#include +#include +#include + +static struct fuse_lowlevel_ops const wsfs_filesystem_operations = +{ + .lookup = &wsfs_operation_lookup, + .getattr = &wsfs_operation_getattr, + .readdir = &wsfs_operation_readdir, + .open = &wsfs_operation_open, + .release = &wsfs_operation_close, + .read = &wsfs_operation_read +}; + + +void wsfs_filesystem_init( + struct wsfs_filesystem * filesystem, + char * mount_point) +{ + char * argv[] = {"", NULL}; + filesystem->args.argc = 1; + filesystem->args.argv = argv; + filesystem->args.allocated = 0; + + filesystem->user_data.rpc = wsfs_jsonrpc_create(NULL, NULL, NULL); + filesystem->user_data.timeout = 1.0; + memset(&filesystem->buffer, 0, sizeof(struct fuse_buf)); + + filesystem->session = fuse_session_new( + &filesystem->args, + &wsfs_filesystem_operations, + sizeof(wsfs_filesystem_operations), + &filesystem->user_data); + if (NULL != filesystem->session) + { + fuse_session_mount(filesystem->session, mount_point); + } + +} + +void wsfs_filesystem_cleanup( + struct wsfs_filesystem * filesystem) +{ + if (NULL != filesystem->session) + { + fuse_session_reset(filesystem->session); + fuse_session_unmount(filesystem->session); + fuse_session_destroy(filesystem->session); + filesystem->session = NULL; + } + + free(filesystem->buffer.mem); + fuse_opt_free_args(&filesystem->args); +} + +int wsfs_filesystem_get_fd( + struct wsfs_filesystem * filesystem) +{ + return fuse_session_fd(filesystem->session); +} + +void wsfs_filesystem_process_request( + struct wsfs_filesystem * filesystem) +{ + int const result = fuse_session_receive_buf(filesystem->session, &filesystem->buffer); + if (0 < result) + { + fuse_session_process_buf(filesystem->session, &filesystem->buffer); + } + else if (-EINTR != result) + { + // ToDo + } + +} diff --git a/src/wsfs/filesystem.h b/src/wsfs/filesystem.h new file mode 100644 index 0000000..14db9e4 --- /dev/null +++ b/src/wsfs/filesystem.h @@ -0,0 +1,28 @@ +#ifndef _WSFS_FILESYSTEM_H +#define _WSFS_FILESYSTEM_H + +#include "wsfs/fuse_wrapper.h" +#include "wsfs/operations.h" + +struct wsfs_filesystem +{ + struct fuse_args args; + struct fuse_session * session; + struct fuse_buf buffer; + struct wsfs_operations_context user_data; +}; + +extern void wsfs_filesystem_init( + struct wsfs_filesystem * filesystem, + char * mount_point); + +extern void wsfs_filesystem_cleanup( + struct wsfs_filesystem * filesystem); + +extern int wsfs_filesystem_get_fd( + struct wsfs_filesystem * filesystem); + +extern void wsfs_filesystem_process_request( + struct wsfs_filesystem * filesystem); + +#endif diff --git a/src/wsfs/jsonrpc.c b/src/wsfs/jsonrpc.c index a61cf67..d48bd8f 100644 --- a/src/wsfs/jsonrpc.c +++ b/src/wsfs/jsonrpc.c @@ -80,6 +80,8 @@ wsfs_status wsfs_jsonrpc_invoke( ... ) { + return WSFS_BAD_NOTIMPLEMENTED; + // enqueue message pthread_mutex_lock(&rpc->lock); wsfs_status status = WSFS_BAD; diff --git a/src/wsfs/operations.c b/src/wsfs/operations.c deleted file mode 100644 index e938d3d..0000000 --- a/src/wsfs/operations.c +++ /dev/null @@ -1,142 +0,0 @@ -#include "wsfs/operations.h" - -#include -#include -#include -#include -#include - -#include "wsfs/util.h" - -struct wsfs_fuse_context -{ - struct fuse_args args; - struct fuse_session * session; - struct fuse_buf buffer; - struct wsfs_operations_context user_data; - int fd; - bool mounted; -}; - -static struct fuse_lowlevel_ops const wsfs_operations = -{ - .lookup = &wsfs_operation_lookup, - .getattr = &wsfs_operation_getattr, - .readdir = &wsfs_operation_readdir, - .open = &wsfs_operation_open, - .release = &wsfs_operation_close, - .read = &wsfs_operation_read -}; - - -static bool wsfs_fuse_init( - struct wsfs_fuse_context * context, - char * mount_point, - struct wsfs_jsonrpc * rpc) -{ - bool result = false; - - char * argv[] = {"", NULL}; - context->args.argc = 1; - context->args.argv = argv; - context->args.allocated = 0; - - context->user_data.rpc = rpc; - context->user_data.timeout = 1.0; - memset(&context->buffer, 0, sizeof(struct fuse_buf)); - - context->session = fuse_session_new(&context->args, &wsfs_operations, sizeof(wsfs_operations), &context->user_data); - if (NULL != context->session) - { - result = (0 == fuse_session_mount(context->session, mount_point)); - context->fd = fuse_session_fd(context->session); - } - - // cleanup on error - if (!result) - { - if (NULL != context->session) - { - fuse_session_destroy(context->session); - context->session = NULL; - } - - free(context->buffer.mem); - fuse_opt_free_args(&context->args); - } - - return result; -} - -static void wsfs_fuse_cleanup( - struct wsfs_fuse_context * context) -{ - if (NULL != context->session) - { - fuse_session_reset(context->session); - fuse_session_unmount(context->session); - fuse_session_destroy(context->session); - context->session = NULL; - } - - free(context->buffer.mem); - fuse_opt_free_args(&context->args); -} - -static void wsfs_fuse_onreadable( - uv_poll_t* handle, - int WSFS_UNUSED_PARAM(status), - int WSFS_UNUSED_PARAM(events)) -{ - struct wsfs_fuse_context * context = handle->data; - int const result = fuse_session_receive_buf(context->session, &context->buffer); - if (0 < result) - { - fuse_session_process_buf(context->session, &context->buffer); - } - else if (-EINTR != result) - { - uv_poll_stop(handle); - } -} - -static void wsfs_fuse_oninterrupt(uv_signal_t* handle, int WSFS_UNUSED_PARAM(signum)) -{ - uv_poll_t * poll_handle = handle->data; - uv_poll_stop(poll_handle); -} - -int wsfs_operations_loop( - char * mount_point, - struct wsfs_jsonrpc * rpc) -{ - uv_loop_t * loop = malloc(sizeof(uv_loop_t)); - uv_loop_init(loop); - - struct wsfs_fuse_context context; - if (wsfs_fuse_init(&context, mount_point, rpc)) - { - uv_poll_t handle; - uv_poll_init(loop, &handle, context.fd); - handle.data = &context; - uv_poll_start(&handle, UV_READABLE, &wsfs_fuse_onreadable); - - uv_signal_t signal_interrupt; - uv_signal_init(loop, &signal_interrupt); - signal_interrupt.data = &handle; - uv_signal_start_oneshot(&signal_interrupt, &wsfs_fuse_oninterrupt, SIGINT); - - uv_run(loop, UV_RUN_DEFAULT); - - uv_close((uv_handle_t*) &signal_interrupt, NULL); - uv_close((uv_handle_t*) &handle, NULL); - uv_run(loop, UV_RUN_DEFAULT); - - wsfs_fuse_cleanup(&context); - } - - uv_loop_close(loop); - free(loop); - - return 0; -} diff --git a/src/wsfs/operations.h b/src/wsfs/operations.h index dea1c50..b089bbd 100644 --- a/src/wsfs/operations.h +++ b/src/wsfs/operations.h @@ -15,10 +15,6 @@ struct wsfs_operations_context extern "C" { #endif -extern int wsfs_operations_loop( - char * mount_point, - struct wsfs_jsonrpc * rpc); - extern void wsfs_operation_lookup ( fuse_req_t req, fuse_ino_t parent, diff --git a/src/wsfs/server.c b/src/wsfs/server.c index 6e16039..db9d472 100644 --- a/src/wsfs/server.c +++ b/src/wsfs/server.c @@ -2,82 +2,37 @@ #include #include -#include -#include - -#include -#include - #include -#include "wsfs/util.h" -#include "wsfs/protocol.h" -#include "wsfs/jsonrpc.h" +#include "wsfs/server_config.h" +#include "wsfs/server_protocol_intern.h" -#define WSFS_SERVICE_INTERVAL (1 * 1000) +#define WSFS_SERVER_PROTOCOL_COUNT 3 +#define WSFS_SERVER_TIMEOUT (1 * 1000) struct wsfs_server { - pthread_t thread; - bool shutdown_flag; - pthread_mutex_t lock; - struct wsfs_server_config config; - struct wsfs_protocol * protocol; - struct wsfs_jsonrpc * rpc; + struct wsfs_server_config config; + struct wsfs_server_protocol protocol; + struct lws_protocols ws_protocols[WSFS_SERVER_PROTOCOL_COUNT]; + struct lws_context * context; + volatile bool shutdown_requested; }; -static char * wsfs_strdup(char const * value) -{ - char * result = NULL; - if (NULL != value) - { - result = strdup(value); - } - - return result; -} - - -static bool wsfs_server_isshutdown( - struct wsfs_server * server) -{ - bool result; - - pthread_mutex_lock(&server->lock); - result = server->shutdown_flag; - pthread_mutex_unlock(&server->lock); - - return result; -} - static bool wsfs_server_tls_enabled( struct wsfs_server * server) { return ((server->config.key_path != NULL) && (server->config.cert_path != NULL)); } -static void wsfs_server_request_shutdown( - struct wsfs_server * server) -{ - pthread_mutex_lock(&server->lock); - server->shutdown_flag = true; - pthread_mutex_unlock(&server->lock); -} - -static void wsfs_ignore_signal(int WSFS_UNUSED_PARAM(signal_id)) +static struct lws_context * wsfs_server_context_create( + struct wsfs_server * server) { -} - -static void* wsfs_server_run(void * arg) -{ - struct wsfs_server * const server = arg; - - struct lws_protocols protocols[] = - { - {"http", lws_callback_http_dummy, 0, 0, 0, NULL, 0}, - { "fs", NULL, 0 , 0, 0, NULL, 0}, - { NULL, NULL, 0 , 0, 0, NULL, 0} - }; + memset(server->ws_protocols, 0, sizeof(struct lws_protocols) * WSFS_SERVER_PROTOCOL_COUNT); + server->ws_protocols[0].name = "http"; + server->ws_protocols[0].callback = lws_callback_http_dummy; + server->ws_protocols[1].name = "fs"; + wsfs_server_protocol_init_lws(&server->protocol, &server->ws_protocols[1]); struct lws_http_mount mount = { @@ -99,13 +54,11 @@ static void* wsfs_server_run(void * arg) .basic_auth_login_file = NULL }; - wsfs_protocol_init_lws(server->protocol, &protocols[1]); - struct lws_context_creation_info info; memset(&info, 0, sizeof(info)); info.port = server->config.port; info.mounts = &mount; - info.protocols = protocols; + info.protocols = server->ws_protocols; info.vhost_name = server->config.vhost_name; info.ws_ping_pong_interval = 10; info.options = LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE; @@ -113,7 +66,7 @@ static void* wsfs_server_run(void * arg) if (NULL == server->config.document_root) { // disable http - info.protocols = &(protocols[1]); + info.protocols = &server->ws_protocols[1]; info.mounts = NULL; } @@ -124,97 +77,48 @@ static void* wsfs_server_run(void * arg) info.ssl_private_key_filepath = server->config.key_path; } - struct lws_context * context = lws_create_context(&info); - if (NULL == context) - { - fprintf(stderr, "error: unable to start websocket server\n"); - return NULL; - } + struct lws_context * const context = lws_create_context(&info); + return context; - int n = 0; - while ((0 <= n) && (!wsfs_server_isshutdown(server))) - { - wsfs_protocol_check(server->protocol); - n = lws_service(context, WSFS_SERVICE_INTERVAL); - } - - lws_context_destroy(context); - return NULL; -} - -static void wsfs_server_join(struct wsfs_server * server) -{ - wsfs_server_request_shutdown(server); - pthread_join(server->thread, NULL); } struct wsfs_server * wsfs_server_create( - struct wsfs_server_config * config) + struct wsfs_server_config * config) { - signal(SIGUSR1, &wsfs_ignore_signal); - - struct wsfs_server * server = malloc(sizeof(struct wsfs_server)); - if (NULL != server) - { - pthread_mutex_init(&server->lock, NULL); - server->shutdown_flag = false; - server->config.document_root = wsfs_strdup(config->document_root); - server->config.cert_path = wsfs_strdup(config->cert_path); - server->config.key_path = wsfs_strdup(config->key_path); - server->config.vhost_name = wsfs_strdup(config->vhost_name); - server->config.port = config->port; - - server->rpc = wsfs_jsonrpc_create(&wsfs_protocol_message_create, &wsfs_protocol_send, NULL); - server->protocol = wsfs_protocol_create(server); - wsfs_jsonrpc_set_user_data(server->rpc, server->protocol); - } - - return server; + struct wsfs_server * server = malloc(sizeof(struct wsfs_server)); + if (NULL != server) + { + server->shutdown_requested = false; + wsfs_server_config_clone(config, &server->config); + wsfs_server_protocol_init(&server->protocol, config->mount_point); + server->context = wsfs_server_context_create(server); + } + + return server; } void wsfs_server_dispose( - struct wsfs_server * server) + struct wsfs_server * server) { - wsfs_server_join(server); - - wsfs_jsonrpc_dispose(server->rpc); - wsfs_protocol_dispose(server->protocol); - wsfs_server_config_clear(&server->config); - pthread_mutex_destroy(&server->lock); - free(server); + lws_context_destroy(server->context); + wsfs_server_protocol_cleanup(&server->protocol); + wsfs_server_config_cleanup(&server->config); + free(server); } -void wsfs_server_start( - struct wsfs_server * server) -{ - pthread_create(&server->thread, NULL, &wsfs_server_run, server); -} - -void wsfs_server_config_clear(struct wsfs_server_config * config) -{ - free(config->document_root); - free(config->cert_path); - free(config->key_path); - free(config->vhost_name); -} - -struct wsfs_jsonrpc * wsfs_server_get_jsonrpc_service( - struct wsfs_server * server) -{ - return server->rpc; -} - -void wsfs_server_wakeup( - struct wsfs_server * server) +void wsfs_server_run( + struct wsfs_server * server) { - pthread_kill(server->thread, SIGUSR1); + int n = 0; + while ((0 <= n) && (!server->shutdown_requested)) + { + n = lws_service(server->context, WSFS_SERVER_TIMEOUT); + } } -void wsfs_server_handle_message( - struct wsfs_server * server, - char const * message, - size_t length) +void wsfs_server_shutdown( + struct wsfs_server * server) { - wsfs_jsonrpc_on_message(message, length, server->rpc); + server->shutdown_requested = true; } diff --git a/src/wsfs/server.h b/src/wsfs/server.h deleted file mode 100644 index c3671cb..0000000 --- a/src/wsfs/server.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _WSFS_SERVER_H -#define _WSFS_SERVER_H - -#ifndef __cplusplus -#include -#else -#include -using std::size_t; -#endif - -struct wsfs_server; -struct wsfs_jsonrpc; - -struct wsfs_server_config -{ - char * document_root; - char * key_path; - char * cert_path; - char * vhost_name; - int port; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -extern void wsfs_server_config_clear( - struct wsfs_server_config * config); - -extern struct wsfs_server * wsfs_server_create( - struct wsfs_server_config * config); - -extern void wsfs_server_dispose( - struct wsfs_server * server); - -extern struct wsfs_jsonrpc * wsfs_server_get_jsonrpc_service( - struct wsfs_server * server); - -extern void wsfs_server_start( - struct wsfs_server * server); - -extern void wsfs_server_wakeup( - struct wsfs_server * server); - -extern void wsfs_server_handle_message( - struct wsfs_server * server, - char const * message, - size_t length); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/wsfs/server_config.c b/src/wsfs/server_config.c new file mode 100644 index 0000000..1366a4d --- /dev/null +++ b/src/wsfs/server_config.c @@ -0,0 +1,45 @@ +#include "wsfs/server_config.h" + +#include +#include + +static char * wsfs_server_config_strdup(char const * value) +{ + char * result = NULL; + if (NULL != value) + { + result = strdup(value); + } + + return result; +} + +void wsfs_server_config_init( + struct wsfs_server_config * config) +{ + memset(config, 0, sizeof(struct wsfs_server_config)); +} + +void wsfs_server_config_cleanup( + struct wsfs_server_config * config) +{ + free(config->mount_point); + free(config->document_root); + free(config->key_path); + free(config->cert_path); + free(config->vhost_name); + + wsfs_server_config_init(config); +} + +void wsfs_server_config_clone( + struct wsfs_server_config * config, + struct wsfs_server_config * clone) +{ + clone->mount_point = wsfs_server_config_strdup(config->mount_point); + clone->document_root = wsfs_server_config_strdup(config->document_root); + clone->key_path = wsfs_server_config_strdup(config->key_path); + clone->cert_path = wsfs_server_config_strdup(config->cert_path); + clone->vhost_name = wsfs_server_config_strdup(config->vhost_name); + clone->port = config->port; +} diff --git a/src/wsfs/server_protocol.c b/src/wsfs/server_protocol.c new file mode 100644 index 0000000..9e08328 --- /dev/null +++ b/src/wsfs/server_protocol.c @@ -0,0 +1,82 @@ +#include "wsfs/server_protocol_intern.h" + +#include +#include + +#include "wsfs/filesystem.h" +#include "wsfs/util.h" + +static int wsfs_server_protocol_callback( + struct lws * wsi, + enum lws_callback_reasons reason, + void * WSFS_UNUSED_PARAM(user), + void * WSFS_UNUSED_PARAM(in), + size_t WSFS_UNUSED_PARAM(len)) +{ + struct lws_protocols const * ws_protocol = lws_get_protocol(wsi); + struct wsfs_server_protocol * protocol = ws_protocol->user; + + switch (reason) + { + case LWS_CALLBACK_PROTOCOL_INIT: + { + lws_sock_file_fd_type fd; + fd.filefd = wsfs_filesystem_get_fd(&protocol->filesystem); + if (!lws_adopt_descriptor_vhost(lws_get_vhost(wsi), LWS_ADOPT_RAW_FILE_DESC, fd, ws_protocol->name, NULL)) + { + puts("error: unable to adopt fd"); + } + } + break; + case LWS_CALLBACK_RAW_RX_FILE: + { + puts("fd readable"); + wsfs_filesystem_process_request(&protocol->filesystem); + } + break; + default: + break; + } + return 0; +} + +struct wsfs_server_protocol * wsfs_server_protocol_create( + char * mount_point) +{ + struct wsfs_server_protocol * protocol = malloc(sizeof(struct wsfs_server_protocol)); + if (NULL != protocol) + { + wsfs_server_protocol_init(protocol, mount_point); + } + + return protocol; +} + +void wsfs_server_protocol_dispose( + struct wsfs_server_protocol * protocol) +{ + wsfs_server_protocol_cleanup(protocol); + free(protocol); +} + +void wsfs_server_protocol_init_lws( + struct wsfs_server_protocol * protocol, + struct lws_protocols * lws_protocol) +{ + lws_protocol->callback = &wsfs_server_protocol_callback; + lws_protocol->per_session_data_size = 0; + lws_protocol->user = protocol; +} + +void wsfs_server_protocol_init( + struct wsfs_server_protocol * protocol, + char * mount_point) +{ + wsfs_filesystem_init(&protocol->filesystem, mount_point); +} + +void wsfs_server_protocol_cleanup( + struct wsfs_server_protocol * protocol) +{ + wsfs_filesystem_cleanup(&protocol->filesystem); +} diff --git a/src/wsfs/server_protocol_intern.h b/src/wsfs/server_protocol_intern.h new file mode 100644 index 0000000..fe1539a --- /dev/null +++ b/src/wsfs/server_protocol_intern.h @@ -0,0 +1,19 @@ +#ifndef _WSFS_SERVER_PROTOCOL_INTERN_H +#define _WSFS_SERVER_PROTOCOL_INTERN_H + +#include "wsfs/server_protocol.h" +#include "wsfs/filesystem.h" + +struct wsfs_server_protocol +{ + struct wsfs_filesystem filesystem; +}; + +extern void wsfs_server_protocol_init( + struct wsfs_server_protocol * protocol, + char * mount_point); + +extern void wsfs_server_protocol_cleanup( + struct wsfs_server_protocol * protocol); + +#endif