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

refactoring: removed filesystem

This commit is contained in:
Falk Werner 2019-01-29 23:11:46 +01:00
parent c05c9c0cc2
commit 1e4647356d
11 changed files with 265 additions and 369 deletions

View File

@ -36,8 +36,12 @@ set(EXTRA_CFLAGS
# libfuse-wsfs # libfuse-wsfs
add_library(fuse-wsfs add_library(fuse-wsfs
src/wsfs/status.c
src/wsfs/operations.c src/wsfs/operations.c
src/wsfs/filesystem.c src/wsfs/operation/getattr.c
src/wsfs/operation/readdir.c
src/wsfs/operation/open.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/protocol.c

View File

@ -1,205 +0,0 @@
#include "wsfs/filesystem.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jansson.h>
#include "wsfs/util.h"
#include "wsfs/jsonrpc.h"
struct wsfs_filesystem
{
struct wsfs_jsonrpc * rpc;
};
struct wsfs_filesystem * wsfs_filesystem_create(
struct wsfs_jsonrpc * rpc)
{
struct wsfs_filesystem * filesystem = malloc(sizeof(struct wsfs_filesystem));
if (NULL != filesystem)
{
filesystem->rpc = rpc;
}
return filesystem;
}
void wsfs_filesystem_dispose(
struct wsfs_filesystem * filesystem)
{
free(filesystem);
}
static int wsfs_json_get_int(json_t * object, char const * key, int default_value)
{
int result = default_value;
json_t * holder = json_object_get(object, key);
if ((NULL != holder) && (json_is_integer(holder)))
{
result = json_integer_value(holder);
}
return result;
}
wsfs_status wsfs_filesystem_getattr(
struct wsfs_filesystem * filesystem,
char const * path,
struct stat * result)
{
json_t * data = NULL;
wsfs_status status = wsfs_jsonrpc_invoke(filesystem->rpc, &data, "getattr", "s", path);
if (NULL != result)
{
json_t * mode_holder = json_object_get(data, "mode");
json_t * type_holder = json_object_get(data, "type");
if ((NULL != mode_holder) && (json_is_integer(mode_holder)) &&
(NULL != type_holder) && (json_is_string(type_holder)))
{
result->st_mode = json_integer_value(mode_holder) & 0777;
char const * type = json_string_value(type_holder);
if (0 == strcmp("file", type))
{
result->st_mode |= S_IFREG;
}
else if (0 == strcmp("dir", type))
{
result->st_mode |= S_IFDIR;
}
result->st_size = wsfs_json_get_int(data, "size", 0);
result->st_atime = wsfs_json_get_int(data, "atime", 0);
result->st_mtime = wsfs_json_get_int(data, "mtime", 0);
result->st_ctime = wsfs_json_get_int(data, "ctime", 0);
}
else
{
status = WSFS_BAD_FORMAT;
}
json_decref(data);
}
return status;
}
wsfs_status wsfs_filesystem_readdir(
struct wsfs_filesystem * filesystem,
char const * path,
void * buffer,
wsfs_add_entry_fn * add_entry)
{
json_t * result = NULL;
wsfs_status const status = wsfs_jsonrpc_invoke(filesystem->rpc, &result, "readdir", "s", path);
if (NULL != result)
{
if (json_is_array(result))
{
bool has_capacity = true;
size_t const count = json_array_size(result);
for(size_t i = 0; (has_capacity) && (i < count); i++)
{
json_t * entry =json_array_get(result, i);
if (json_is_string(entry))
{
has_capacity = add_entry(buffer, json_string_value(entry));
}
}
}
json_decref(result);
}
return status;
}
wsfs_status wsfs_filesystem_open(
struct wsfs_filesystem * filesystem,
char const * path,
int flags)
{
json_t * result = NULL;
wsfs_status const status = wsfs_jsonrpc_invoke(filesystem->rpc, &result, "open", "si", path, flags);
if (NULL != result)
{
// unused
json_decref(result);
}
return status;
}
#define WSFS_MAX_READ_LENGTH 4096
static wsfs_status wsfs_fill_buffer(
char * buffer,
size_t buffer_size,
char const * format,
char const * data,
size_t count)
{
wsfs_status status = WSFS_GOOD;
size_t const copy_count = (buffer_size < count) ? buffer_size : count;
if (0 < copy_count)
{
if (0 == strcmp("identity", format))
{
memcpy(buffer, data, copy_count);
}
else
{
status = WSFS_BAD;
}
}
return status;
}
wsfs_status wsfs_filesystem_read(
struct wsfs_filesystem * filesystem,
char const * path,
char * buffer,
size_t buffer_size,
size_t offset,
size_t * read_count)
{
int const length = (buffer_size <= WSFS_MAX_READ_LENGTH) ? (int) buffer_size : WSFS_MAX_READ_LENGTH;
*read_count = 0;
json_t * result = NULL;
wsfs_status status = wsfs_jsonrpc_invoke(filesystem->rpc, &result, "read", "sii", path, (int) offset, length);
if (NULL != result)
{
json_t * data_holder = json_object_get(result, "data");
json_t * format_holder = json_object_get(result, "format");
json_t * count_holder = json_object_get(result, "count");
if ((NULL != data_holder) && (json_is_string(data_holder)) &&
(NULL != format_holder) && (json_is_string(format_holder)) &&
(NULL != count_holder) && (json_is_integer(count_holder)))
{
char const * const data = json_string_value(data_holder);
char const * const format = json_string_value(format_holder);
size_t const count = (size_t) json_integer_value(count_holder);
status = wsfs_fill_buffer(buffer, buffer_size, format, data, count);
if (WSFS_GOOD == status)
{
*read_count = count;
}
}
else
{
status = WSFS_BAD_FORMAT;
}
json_decref(result);
}
return status;
}

View File

@ -1,49 +0,0 @@
#ifndef _WSFS_FILESYSTEM_H
#define _WSFS_FILESYSTEM_H
#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "wsfs/status.h"
struct wsfs_filesystem;
struct wsfs_jsonrpc;
typedef bool wsfs_add_entry_fn(void * buffer, char const * path);
extern struct wsfs_filesystem * wsfs_filesystem_create(
struct wsfs_jsonrpc * service);
extern void wsfs_filesystem_dispose(
struct wsfs_filesystem * filesystem);
extern wsfs_status wsfs_filesystem_getattr(
struct wsfs_filesystem * filesystem,
char const * path,
struct stat * result);
extern wsfs_status wsfs_filesystem_readdir(
struct wsfs_filesystem * filesystem,
char const * path,
void * buffer,
wsfs_add_entry_fn * add_entry);
extern wsfs_status wsfs_filesystem_open(
struct wsfs_filesystem * filesystem,
char const * path,
int flags);
extern wsfs_status wsfs_filesystem_read(
struct wsfs_filesystem * filesystem,
char const * path,
char * buffer,
size_t buffer_size,
size_t offset,
size_t * read_count);
#endif

View File

@ -0,0 +1,72 @@
#include "wsfs/operations.h"
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <jansson.h>
#include "wsfs/util.h"
#include "wsfs/jsonrpc.h"
static int wsfs_json_get_int(json_t * object, char const * key, int default_value)
{
int result = default_value;
json_t * holder = json_object_get(object, key);
if ((NULL != holder) && (json_is_integer(holder)))
{
result = json_integer_value(holder);
}
return result;
}
int wsfs_operation_getattr(
char const * path,
struct stat * buffer,
struct fuse_file_info * WSFS_UNUSED_PARAM(file_info))
{
struct fuse_context * const context = fuse_get_context();
struct wsfs_jsonrpc * const rpc = context->private_data;
json_t * data = NULL;
wsfs_status status = wsfs_jsonrpc_invoke(rpc, &data, "getattr", "s", path);
if (NULL != data)
{
json_t * mode_holder = json_object_get(data, "mode");
json_t * type_holder = json_object_get(data, "type");
if ((NULL != mode_holder) && (json_is_integer(mode_holder)) &&
(NULL != type_holder) && (json_is_string(type_holder)))
{
buffer->st_mode = json_integer_value(mode_holder) & 0555;
char const * type = json_string_value(type_holder);
if (0 == strcmp("file", type))
{
buffer->st_mode |= S_IFREG;
}
else if (0 == strcmp("dir", type))
{
buffer->st_mode |= S_IFDIR;
}
buffer->st_uid = context->uid;
buffer->st_gid = context->gid;
buffer->st_nlink = 1;
buffer->st_size = wsfs_json_get_int(data, "size", 0);
buffer->st_atime = wsfs_json_get_int(data, "atime", 0);
buffer->st_mtime = wsfs_json_get_int(data, "mtime", 0);
buffer->st_ctime = wsfs_json_get_int(data, "ctime", 0);
}
else
{
status = WSFS_BAD_FORMAT;
}
json_decref(data);
}
return wsfs_status_to_rc(status);
}

22
src/wsfs/operation/open.c Normal file
View File

@ -0,0 +1,22 @@
#include "wsfs/operations.h"
#include <jansson.h>
#include "wsfs/jsonrpc.h"
int wsfs_operation_open(
char const *path,
struct fuse_file_info * file_info)
{
struct fuse_context * context = fuse_get_context();
struct wsfs_jsonrpc * rpc = context->private_data;
json_t * result = NULL;
wsfs_status const status = wsfs_jsonrpc_invoke(rpc, &result, "open", "si", path, file_info->flags);
if (NULL != result)
{
// unused
json_decref(result);
}
return wsfs_status_to_rc(status);
}

84
src/wsfs/operation/read.c Normal file
View File

@ -0,0 +1,84 @@
#include "wsfs/operations.h"
#include <string.h>
#include <jansson.h>
#include "wsfs/util.h"
#include "wsfs/jsonrpc.h"
#define WSFS_MAX_READ_LENGTH 4096
static wsfs_status wsfs_fill_buffer(
char * buffer,
size_t buffer_size,
char const * format,
char const * data,
size_t count)
{
wsfs_status status = WSFS_GOOD;
size_t const copy_count = (buffer_size < count) ? buffer_size : count;
if (0 < copy_count)
{
if (0 == strcmp("identity", format))
{
memcpy(buffer, data, copy_count);
}
else
{
status = WSFS_BAD;
}
}
return status;
}
int wsfs_operation_read(
const char * path,
char * buffer,
size_t buffer_size,
off_t offset,
struct fuse_file_info * WSFS_UNUSED_PARAM(file_info))
{
struct fuse_context * context = fuse_get_context();
struct wsfs_jsonrpc * rpc = context->private_data;
int const length = (buffer_size <= WSFS_MAX_READ_LENGTH) ? (int) buffer_size : WSFS_MAX_READ_LENGTH;
int result = 0;
json_t * data = NULL;
wsfs_status status = wsfs_jsonrpc_invoke(rpc, &data, "read", "sii", path, (int) offset, length);
if (NULL != data)
{
json_t * data_holder = json_object_get(data, "data");
json_t * format_holder = json_object_get(data, "format");
json_t * count_holder = json_object_get(data, "count");
if ((NULL != data_holder) && (json_is_string(data_holder)) &&
(NULL != format_holder) && (json_is_string(format_holder)) &&
(NULL != count_holder) && (json_is_integer(count_holder)))
{
char const * const data = json_string_value(data_holder);
char const * const format = json_string_value(format_holder);
int const count = json_integer_value(count_holder);
status = wsfs_fill_buffer(buffer, buffer_size, format, data, count);
if (WSFS_GOOD == status)
{
result = count;
}
}
else
{
status = WSFS_BAD_FORMAT;
}
json_decref(data);
}
if (WSFS_GOOD != status)
{
result = wsfs_status_to_rc(status);
}
return result;
}

View File

@ -0,0 +1,41 @@
#include "wsfs/operations.h"
#include <jansson.h>
#include "wsfs/util.h"
#include "wsfs/jsonrpc.h"
int wsfs_operation_readdir(
char const * path,
void * buffer,
fuse_fill_dir_t filler,
off_t WSFS_UNUSED_PARAM(offset),
struct fuse_file_info * WSFS_UNUSED_PARAM(file_info),
enum fuse_readdir_flags WSFS_UNUSED_PARAM(flags))
{
struct fuse_context * context = fuse_get_context();
struct wsfs_jsonrpc * rpc = context->private_data;
json_t * result = NULL;
wsfs_status const status = wsfs_jsonrpc_invoke(rpc, &result, "readdir", "s", path);
if (NULL != result)
{
if (json_is_array(result))
{
bool buffer_full = false;
size_t const count = json_array_size(result);
for(size_t i = 0; (!buffer_full) && (i < count); i++)
{
json_t * entry =json_array_get(result, i);
if (json_is_string(entry))
{
buffer_full = filler(buffer, json_string_value(entry), NULL, 0, 0);
}
}
}
json_decref(result);
}
return wsfs_status_to_rc(status);
}

View File

@ -1,44 +1,9 @@
#include "wsfs/operations.h" #include "wsfs/operations.h"
#include <stddef.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include "wsfs/util.h" #include "wsfs/util.h"
#include "wsfs/filesystem.h" #include "wsfs/jsonrpc.h"
struct wsfs_readdir_context
{
void * buffer;
fuse_fill_dir_t filler;
};
static int wsfs_result_from_status(wsfs_status status)
{
switch(status)
{
case WSFS_GOOD: return 0;
case WSFS_BAD_NOENTRY: return -ENOENT;
case WSFS_BAD_NOACCESS: return -EACCES;
default: return -ENOENT;
}
}
static struct wsfs_filesystem * wsfs_get_filesystem(void)
{
struct fuse_context * const context = fuse_get_context();
struct wsfs_filesystem * const filesystem = context->private_data;
return filesystem;
}
static bool wsfs_add_entry(void * buffer, char const * path)
{
struct wsfs_readdir_context * context = buffer;
int const result = context->filler(context->buffer, path, NULL, 0, 0);
return (0 == result);
}
static void* wsfs_operation_init( static void* wsfs_operation_init(
struct fuse_conn_info * WSFS_UNUSED_PARAM(connection), struct fuse_conn_info * WSFS_UNUSED_PARAM(connection),
@ -47,83 +12,7 @@ static void* wsfs_operation_init(
struct fuse_context * const context = fuse_get_context(); struct fuse_context * const context = fuse_get_context();
config->kernel_cache = 1; config->kernel_cache = 1;
return wsfs_filesystem_create(context->private_data); return context->private_data;
}
static void wsfs_operation_destroy(void * private_data)
{
struct wsfs_filesystem * const filesystem = private_data;
wsfs_filesystem_dispose(filesystem);
}
static int wsfs_operation_getattr(
char const * path,
struct stat * buffer,
struct fuse_file_info * WSFS_UNUSED_PARAM(file_info))
{
struct fuse_context * const context = fuse_get_context();
struct wsfs_filesystem * const filesystem = wsfs_get_filesystem();
wsfs_status const status = wsfs_filesystem_getattr(filesystem, path, buffer);
if (WSFS_GOOD == status)
{
buffer->st_uid = context->uid;
buffer->st_gid = context->gid;
buffer->st_nlink = 1;
}
return wsfs_result_from_status(status);
}
static int wsfs_operation_readdir(
char const * path,
void * buffer,
fuse_fill_dir_t filler,
off_t WSFS_UNUSED_PARAM(offset),
struct fuse_file_info * WSFS_UNUSED_PARAM(file_info),
enum fuse_readdir_flags WSFS_UNUSED_PARAM(flags))
{
struct wsfs_filesystem * filesystem = wsfs_get_filesystem();
struct wsfs_readdir_context context =
{
.buffer = buffer,
.filler = filler
};
wsfs_status const status = wsfs_filesystem_readdir(filesystem, path, &context, &wsfs_add_entry);
return wsfs_result_from_status(status);
}
static int wsfs_operation_open(
char const *path,
struct fuse_file_info * file_info)
{
struct wsfs_filesystem * filesystem = wsfs_get_filesystem();
wsfs_status const status = wsfs_filesystem_open(filesystem, path, file_info->flags);
return wsfs_result_from_status(status);
}
static int wsfs_operation_read(
const char * path,
char * buffer,
size_t buffer_size,
off_t offset,
struct fuse_file_info * WSFS_UNUSED_PARAM(file_info))
{
struct wsfs_filesystem * filesystem = wsfs_get_filesystem();
size_t count;
wsfs_status const status = wsfs_filesystem_read(filesystem, path, buffer, buffer_size, offset, &count);
if (WSFS_GOOD == status)
{
return count;
}
else
{
return wsfs_result_from_status(status);
}
} }
void wsfs_operations_init( void wsfs_operations_init(
@ -131,7 +20,6 @@ void wsfs_operations_init(
{ {
memset(operations, 0, sizeof(struct fuse_operations)); memset(operations, 0, sizeof(struct fuse_operations));
operations->init = &wsfs_operation_init; operations->init = &wsfs_operation_init;
operations->destroy = &wsfs_operation_destroy;
operations->getattr = &wsfs_operation_getattr; operations->getattr = &wsfs_operation_getattr;
operations->readdir = &wsfs_operation_readdir; operations->readdir = &wsfs_operation_readdir;
operations->open = &wsfs_operation_open; operations->open = &wsfs_operation_open;

View File

@ -6,5 +6,29 @@
extern void wsfs_operations_init( extern void wsfs_operations_init(
struct fuse_operations * operations); struct fuse_operations * operations);
extern int wsfs_operation_readdir(
char const * path,
void * buffer,
fuse_fill_dir_t filler,
off_t offset,
struct fuse_file_info * file_info,
enum fuse_readdir_flags flags);
extern int wsfs_operation_getattr(
char const * path,
struct stat * buffer,
struct fuse_file_info * file_info);
extern int wsfs_operation_open(
char const *path,
struct fuse_file_info * file_info);
extern int wsfs_operation_read(
const char * path,
char * buffer,
size_t buffer_size,
off_t offset,
struct fuse_file_info * file_info);
#endif #endif

14
src/wsfs/status.c Normal file
View File

@ -0,0 +1,14 @@
#include "wsfs/status.h"
#include <errno.h>
int wsfs_status_to_rc(wsfs_status status)
{
switch(status)
{
case WSFS_GOOD: return 0;
case WSFS_BAD_NOENTRY: return -ENOENT;
case WSFS_BAD_NOACCESS: return -EACCES;
default: return -ENOENT;
}
}

View File

@ -13,6 +13,7 @@
typedef int wsfs_status; typedef int wsfs_status;
extern int wsfs_status_to_rc(wsfs_status status);
#endif #endif