mirror of
https://github.com/falk-werner/webfuse
synced 2024-10-27 20:34:10 +00:00
use libwebsockets as loop for fuse fd; removed dependency to libuv, since it is not needed anymore; disabled jsonrpc temporary, until refactoring is finished (will not work properly)
This commit is contained in:
parent
84aa5daf32
commit
b74c459942
@ -7,7 +7,6 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
|
|||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
pkg_check_modules(LIBUV REQUIRED libuv)
|
|
||||||
pkg_check_modules(FUSE3 REQUIRED fuse3)
|
pkg_check_modules(FUSE3 REQUIRED fuse3)
|
||||||
pkg_check_modules(LWS REQUIRED libwebsockets)
|
pkg_check_modules(LWS REQUIRED libwebsockets)
|
||||||
pkg_check_modules(JANSSON REQUIRED jansson)
|
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(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -Wextra")
|
||||||
|
|
||||||
set(EXTRA_INCLUDE_DIRS
|
set(EXTRA_INCLUDE_DIRS
|
||||||
${LIBUV_INCLUDE_DIRS}
|
"inc"
|
||||||
${FUSE3_INCLUDE_DIRS}
|
${FUSE3_INCLUDE_DIRS}
|
||||||
${LWS_INCLUDE_DIRS}
|
${LWS_INCLUDE_DIRS}
|
||||||
${JANSSON_INCLUDE_DIRS}
|
${JANSSON_INCLUDE_DIRS}
|
||||||
@ -23,7 +22,6 @@ set(EXTRA_INCLUDE_DIRS
|
|||||||
|
|
||||||
set(EXTRA_LIBS
|
set(EXTRA_LIBS
|
||||||
${EXTRA_LIBS}
|
${EXTRA_LIBS}
|
||||||
${LIBUV_LIBRARIES}
|
|
||||||
${FUSE3_LIBRARIES}
|
${FUSE3_LIBRARIES}
|
||||||
${LWS_LIBRARIES}
|
${LWS_LIBRARIES}
|
||||||
${JANSSON_LIBRARIES}
|
${JANSSON_LIBRARIES}
|
||||||
@ -31,7 +29,6 @@ set(EXTRA_LIBS
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(EXTRA_CFLAGS
|
set(EXTRA_CFLAGS
|
||||||
${LIBUV_CFLAGS_OTHER}
|
|
||||||
${FUSE3_CFLAGS_OTHER}
|
${FUSE3_CFLAGS_OTHER}
|
||||||
${LWS_CFLAGS_OTHER}
|
${LWS_CFLAGS_OTHER}
|
||||||
${JANSSON_CFLAGS_OTHER}
|
${JANSSON_CFLAGS_OTHER}
|
||||||
@ -43,7 +40,7 @@ set(EXTRA_CFLAGS
|
|||||||
|
|
||||||
add_library(fuse-wsfs
|
add_library(fuse-wsfs
|
||||||
src/wsfs/status.c
|
src/wsfs/status.c
|
||||||
src/wsfs/operations.c
|
src/wsfs/filesystem.c
|
||||||
src/wsfs/operation/lookup.c
|
src/wsfs/operation/lookup.c
|
||||||
src/wsfs/operation/getattr.c
|
src/wsfs/operation/getattr.c
|
||||||
src/wsfs/operation/readdir.c
|
src/wsfs/operation/readdir.c
|
||||||
@ -52,7 +49,8 @@ add_library(fuse-wsfs
|
|||||||
src/wsfs/operation/read.c
|
src/wsfs/operation/read.c
|
||||||
src/wsfs/response_parser.c
|
src/wsfs/response_parser.c
|
||||||
src/wsfs/server.c
|
src/wsfs/server.c
|
||||||
src/wsfs/protocol.c
|
src/wsfs/server_config.c
|
||||||
|
src/wsfs/server_protocol.c
|
||||||
src/wsfs/jsonrpc.c
|
src/wsfs/jsonrpc.c
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -66,7 +64,7 @@ add_executable(wsfs
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(wsfs PUBLIC fuse-wsfs ${EXTRA_LIBS})
|
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})
|
target_compile_options(wsfs PUBLIC ${EXTRA_CFLAGS})
|
||||||
|
|
||||||
# tests
|
# tests
|
||||||
|
@ -18,7 +18,6 @@ fuse-wsfs combines libwebsockets and libfuse. It allows ot attach a remote files
|
|||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|
||||||
- [libuv](https://github.com/libuv/libuv)
|
|
||||||
- [libfuse3](https://github.com/libfuse/libfuse/)
|
- [libfuse3](https://github.com/libfuse/libfuse/)
|
||||||
- [libwebsockets](https://libwebsockets.org/)
|
- [libwebsockets](https://libwebsockets.org/)
|
||||||
- [Jansson](https://jansson.readthedocs.io)
|
- [Jansson](https://jansson.readthedocs.io)
|
||||||
|
7
inc/wsfs.h
Normal file
7
inc/wsfs.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef _WSFS_H
|
||||||
|
#define _WSFS_H
|
||||||
|
|
||||||
|
#include "wsfs/api.h"
|
||||||
|
#include "wsfs/server.h"
|
||||||
|
|
||||||
|
#endif
|
8
inc/wsfs/api.h
Normal file
8
inc/wsfs/api.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _WSFS_API_H
|
||||||
|
#define _WSFS_API_H
|
||||||
|
|
||||||
|
#ifndef WSFS_API
|
||||||
|
#define WSFS_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
31
inc/wsfs/server.h
Normal file
31
inc/wsfs/server.h
Normal file
@ -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
|
35
inc/wsfs/server_config.h
Normal file
35
inc/wsfs/server_config.h
Normal file
@ -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
|
28
inc/wsfs/server_protocol.h
Normal file
28
inc/wsfs/server_protocol.h
Normal file
@ -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
|
@ -3,20 +3,22 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
|
||||||
#include "wsfs/operations.h"
|
|
||||||
#include "wsfs/server.h"
|
#include "wsfs/server.h"
|
||||||
|
#include "wsfs/server_config.h"
|
||||||
|
|
||||||
struct args
|
struct args
|
||||||
{
|
{
|
||||||
struct wsfs_server_config config;
|
struct wsfs_server_config config;
|
||||||
char * mount_point;
|
|
||||||
bool show_help;
|
bool show_help;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct wsfs_server * server;
|
||||||
|
|
||||||
static void show_help(void)
|
static void show_help(void)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
@ -67,8 +69,8 @@ static int parse_arguments(int argc, char * argv[], struct args * args)
|
|||||||
finished = true;
|
finished = true;
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
free(args->mount_point);
|
free(args->config.mount_point);
|
||||||
args->mount_point = strdup(optarg);
|
args->config.mount_point = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
free(args->config.document_root);
|
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 ((EXIT_SUCCESS == result) && (!args->show_help))
|
||||||
{
|
{
|
||||||
if (NULL == args->mount_point)
|
if (NULL == args->config.mount_point)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "error: missing mount point\n");
|
fprintf(stderr, "error: missing mount point\n");
|
||||||
result = EXIT_FAILURE;
|
result = EXIT_FAILURE;
|
||||||
@ -113,19 +115,26 @@ static int parse_arguments(int argc, char * argv[], struct args * args)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void on_interrupt(int signal_id)
|
||||||
|
{
|
||||||
|
(void) signal_id;
|
||||||
|
|
||||||
|
wsfs_server_shutdown(server);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char * argv[])
|
int main(int argc, char * argv[])
|
||||||
{
|
{
|
||||||
struct args args =
|
struct args args =
|
||||||
{
|
{
|
||||||
.config =
|
.config =
|
||||||
{
|
{
|
||||||
|
.mount_point = NULL,
|
||||||
.document_root = NULL,
|
.document_root = NULL,
|
||||||
.cert_path = NULL,
|
.cert_path = NULL,
|
||||||
.key_path = NULL,
|
.key_path = NULL,
|
||||||
.vhost_name = strdup("localhost"),
|
.vhost_name = strdup("localhost"),
|
||||||
.port = 8080,
|
.port = 8080,
|
||||||
},
|
},
|
||||||
.mount_point = NULL,
|
|
||||||
.show_help = 0
|
.show_help = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -133,13 +142,11 @@ int main(int argc, char * argv[])
|
|||||||
|
|
||||||
if (!args.show_help)
|
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)
|
if (NULL != server)
|
||||||
{
|
{
|
||||||
wsfs_server_start(server);
|
wsfs_server_run(server);
|
||||||
struct wsfs_jsonrpc * const rpc = wsfs_server_get_jsonrpc_service(server);
|
|
||||||
|
|
||||||
result = wsfs_operations_loop(args.mount_point, rpc);
|
|
||||||
wsfs_server_dispose(server);
|
wsfs_server_dispose(server);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -153,9 +160,7 @@ int main(int argc, char * argv[])
|
|||||||
show_help();
|
show_help();
|
||||||
}
|
}
|
||||||
|
|
||||||
wsfs_server_config_clear(&args.config);
|
wsfs_server_config_cleanup(&args.config);
|
||||||
free(args.mount_point);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
79
src/wsfs/filesystem.c
Normal file
79
src/wsfs/filesystem.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#include "wsfs/filesystem.h"
|
||||||
|
#include "wsfs/operations.h"
|
||||||
|
#include "wsfs/jsonrpc.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
28
src/wsfs/filesystem.h
Normal file
28
src/wsfs/filesystem.h
Normal file
@ -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
|
@ -80,6 +80,8 @@ wsfs_status wsfs_jsonrpc_invoke(
|
|||||||
...
|
...
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
return WSFS_BAD_NOTIMPLEMENTED;
|
||||||
|
|
||||||
// enqueue message
|
// enqueue message
|
||||||
pthread_mutex_lock(&rpc->lock);
|
pthread_mutex_lock(&rpc->lock);
|
||||||
wsfs_status status = WSFS_BAD;
|
wsfs_status status = WSFS_BAD;
|
||||||
|
@ -1,142 +0,0 @@
|
|||||||
#include "wsfs/operations.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <uv.h>
|
|
||||||
|
|
||||||
#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;
|
|
||||||
}
|
|
@ -15,10 +15,6 @@ struct wsfs_operations_context
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int wsfs_operations_loop(
|
|
||||||
char * mount_point,
|
|
||||||
struct wsfs_jsonrpc * rpc);
|
|
||||||
|
|
||||||
extern void wsfs_operation_lookup (
|
extern void wsfs_operation_lookup (
|
||||||
fuse_req_t req,
|
fuse_req_t req,
|
||||||
fuse_ino_t parent,
|
fuse_ino_t parent,
|
||||||
|
@ -2,82 +2,37 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
#include <libwebsockets.h>
|
#include <libwebsockets.h>
|
||||||
|
|
||||||
#include "wsfs/util.h"
|
#include "wsfs/server_config.h"
|
||||||
#include "wsfs/protocol.h"
|
#include "wsfs/server_protocol_intern.h"
|
||||||
#include "wsfs/jsonrpc.h"
|
|
||||||
|
|
||||||
#define WSFS_SERVICE_INTERVAL (1 * 1000)
|
#define WSFS_SERVER_PROTOCOL_COUNT 3
|
||||||
|
#define WSFS_SERVER_TIMEOUT (1 * 1000)
|
||||||
|
|
||||||
struct wsfs_server
|
struct wsfs_server
|
||||||
{
|
{
|
||||||
pthread_t thread;
|
struct wsfs_server_config config;
|
||||||
bool shutdown_flag;
|
struct wsfs_server_protocol protocol;
|
||||||
pthread_mutex_t lock;
|
struct lws_protocols ws_protocols[WSFS_SERVER_PROTOCOL_COUNT];
|
||||||
struct wsfs_server_config config;
|
struct lws_context * context;
|
||||||
struct wsfs_protocol * protocol;
|
volatile bool shutdown_requested;
|
||||||
struct wsfs_jsonrpc * rpc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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(
|
static bool wsfs_server_tls_enabled(
|
||||||
struct wsfs_server * server)
|
struct wsfs_server * server)
|
||||||
{
|
{
|
||||||
return ((server->config.key_path != NULL) && (server->config.cert_path != NULL));
|
return ((server->config.key_path != NULL) && (server->config.cert_path != NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wsfs_server_request_shutdown(
|
static struct lws_context * wsfs_server_context_create(
|
||||||
struct wsfs_server * server)
|
struct wsfs_server * server)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&server->lock);
|
memset(server->ws_protocols, 0, sizeof(struct lws_protocols) * WSFS_SERVER_PROTOCOL_COUNT);
|
||||||
server->shutdown_flag = true;
|
server->ws_protocols[0].name = "http";
|
||||||
pthread_mutex_unlock(&server->lock);
|
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]);
|
||||||
static void wsfs_ignore_signal(int WSFS_UNUSED_PARAM(signal_id))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
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}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct lws_http_mount mount =
|
struct lws_http_mount mount =
|
||||||
{
|
{
|
||||||
@ -99,13 +54,11 @@ static void* wsfs_server_run(void * arg)
|
|||||||
.basic_auth_login_file = NULL
|
.basic_auth_login_file = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
wsfs_protocol_init_lws(server->protocol, &protocols[1]);
|
|
||||||
|
|
||||||
struct lws_context_creation_info info;
|
struct lws_context_creation_info info;
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
info.port = server->config.port;
|
info.port = server->config.port;
|
||||||
info.mounts = &mount;
|
info.mounts = &mount;
|
||||||
info.protocols = protocols;
|
info.protocols = server->ws_protocols;
|
||||||
info.vhost_name = server->config.vhost_name;
|
info.vhost_name = server->config.vhost_name;
|
||||||
info.ws_ping_pong_interval = 10;
|
info.ws_ping_pong_interval = 10;
|
||||||
info.options = LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
|
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)
|
if (NULL == server->config.document_root)
|
||||||
{
|
{
|
||||||
// disable http
|
// disable http
|
||||||
info.protocols = &(protocols[1]);
|
info.protocols = &server->ws_protocols[1];
|
||||||
info.mounts = NULL;
|
info.mounts = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,97 +77,48 @@ static void* wsfs_server_run(void * arg)
|
|||||||
info.ssl_private_key_filepath = server->config.key_path;
|
info.ssl_private_key_filepath = server->config.key_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lws_context * context = lws_create_context(&info);
|
struct lws_context * const context = lws_create_context(&info);
|
||||||
if (NULL == context)
|
return context;
|
||||||
{
|
|
||||||
fprintf(stderr, "error: unable to start websocket server\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 * 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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
struct wsfs_server * server = malloc(sizeof(struct wsfs_server));
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wsfs_server_dispose(
|
void wsfs_server_dispose(
|
||||||
struct wsfs_server * server)
|
struct wsfs_server * server)
|
||||||
{
|
{
|
||||||
wsfs_server_join(server);
|
lws_context_destroy(server->context);
|
||||||
|
wsfs_server_protocol_cleanup(&server->protocol);
|
||||||
wsfs_jsonrpc_dispose(server->rpc);
|
wsfs_server_config_cleanup(&server->config);
|
||||||
wsfs_protocol_dispose(server->protocol);
|
free(server);
|
||||||
wsfs_server_config_clear(&server->config);
|
|
||||||
pthread_mutex_destroy(&server->lock);
|
|
||||||
free(server);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wsfs_server_start(
|
void wsfs_server_run(
|
||||||
struct wsfs_server * server)
|
struct wsfs_server * server)
|
||||||
{
|
{
|
||||||
pthread_create(&server->thread, NULL, &wsfs_server_run, server);
|
int n = 0;
|
||||||
|
while ((0 <= n) && (!server->shutdown_requested))
|
||||||
|
{
|
||||||
|
n = lws_service(server->context, WSFS_SERVER_TIMEOUT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wsfs_server_config_clear(struct wsfs_server_config * config)
|
void wsfs_server_shutdown(
|
||||||
|
struct wsfs_server * server)
|
||||||
{
|
{
|
||||||
free(config->document_root);
|
server->shutdown_requested = true;
|
||||||
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)
|
|
||||||
{
|
|
||||||
pthread_kill(server->thread, SIGUSR1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wsfs_server_handle_message(
|
|
||||||
struct wsfs_server * server,
|
|
||||||
char const * message,
|
|
||||||
size_t length)
|
|
||||||
{
|
|
||||||
wsfs_jsonrpc_on_message(message, length, server->rpc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
#ifndef _WSFS_SERVER_H
|
|
||||||
#define _WSFS_SERVER_H
|
|
||||||
|
|
||||||
#ifndef __cplusplus
|
|
||||||
#include <stddef.h>
|
|
||||||
#else
|
|
||||||
#include <cstddef>
|
|
||||||
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
|
|
||||||
|
|
45
src/wsfs/server_config.c
Normal file
45
src/wsfs/server_config.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "wsfs/server_config.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
82
src/wsfs/server_protocol.c
Normal file
82
src/wsfs/server_protocol.c
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#include "wsfs/server_protocol_intern.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <libwebsockets.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
19
src/wsfs/server_protocol_intern.h
Normal file
19
src/wsfs/server_protocol_intern.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user