1
0
mirror of https://github.com/falk-werner/webfuse synced 2025-06-13 12:54:15 +00:00

added basic directory listing

This commit is contained in:
Falk Werner 2019-04-19 19:54:04 +02:00
parent a6ce328cc3
commit 579820c21f

View File

@ -1,19 +1,24 @@
#include "webfuse/provider/impl/static_filesystem.h" #include "webfuse/provider/impl/static_filesystem.h"
#include "webfuse/provider/client_config.h" #include "webfuse/provider/client_config.h"
#include "webfuse/provider/dirbuffer.h"
#include "webfuse/provider/operation/error.h" #include "webfuse/provider/operation/error.h"
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <stdbool.h> #include <stdbool.h>
#define WFP_STATIC_FILESYSTEM_DEFAULT_CAPACITY (16) #define WFP_STATIC_FILESYSTEM_DEFAULT_CAPACITY (16)
struct wfp_static_filesystem_entry struct wfp_static_filesystem_entry
{ {
struct wfp_static_filesystem * parent; size_t inode;
char const * name; size_t parent;
char * name;
bool is_file; bool is_file;
int mode; int mode;
size_t size; size_t size;
char * content;
wfp_static_filesystem_read_fn * read; wfp_static_filesystem_read_fn * read;
wfp_static_filesystem_get_info_fn * get_info; wfp_static_filesystem_get_info_fn * get_info;
void * user_data; void * user_data;
@ -26,18 +31,153 @@ struct wfp_static_filesystem
size_t capacity; size_t capacity;
}; };
static struct wfp_static_filesystem_entry *
wfp_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_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_static_filesystem_add_entry(
struct wfp_static_filesystem * filesystem)
{
struct wfp_static_filesystem_entry * entry = NULL;
if (filesystem->size < filesystem->capacity)
{
entry = &filesystem->entries[filesystem->size];
entry->inode = filesystem->size + 1;
filesystem->size++;
}
else
{
fprintf(stderr, "fatal: static filessystem: unable to add entry\n");
exit(EXIT_FAILURE);
}
return entry;
}
static size_t
wfp_static_filesystem_entry_read(
size_t offset,
char * buffer,
size_t buffer_size,
void * user_data)
{
(void) user_data;
(void) offset;
(void) buffer;
(void) buffer_size;
//struct wfp_static_filesystem_entry * entry = user_data;
size_t result = 0;
return result;
}
static void
wfp_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 void
wfp_static_filesystem_add_dir(
struct wfp_static_filesystem * filesystem,
size_t parent,
char const * name
)
{
struct wfp_static_filesystem_entry * entry = wfp_static_filesystem_get_entry_by_name(filesystem, parent, name);
if (NULL == entry)
{
entry = wfp_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_static_filesystem_entry_read;
entry->get_info = &wfp_static_filesystem_entry_get_info;
entry->size = 0;
entry->content = NULL;
}
}
static void wfp_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_static_filesystem_lookup( static void wfp_static_filesystem_lookup(
struct wfp_request * request, struct wfp_request * request,
ino_t parent, ino_t parent,
char const * name, char const * name,
void * user_data) void * user_data)
{ {
(void) parent; struct wfp_static_filesystem * filesystem = user_data;
(void) name; struct wfp_static_filesystem_entry * entry = wfp_static_filesystem_get_entry_by_name(filesystem, parent, name);
(void) user_data;
if (NULL != entry)
{
struct stat stat;
wfp_static_filesystem_stat(entry, &stat);
wfp_respond_lookup(request, &stat);
}
else
{
wfp_respond_error(request, WF_BAD_NOENTRY); wfp_respond_error(request, WF_BAD_NOENTRY);
} }
}
static void wfp_static_filesystem_getattr( static void wfp_static_filesystem_getattr(
@ -45,22 +185,52 @@ static void wfp_static_filesystem_getattr(
ino_t inode, ino_t inode,
void * user_data) void * user_data)
{ {
(void) inode; struct wfp_static_filesystem * filesystem = user_data;
(void) user_data; struct wfp_static_filesystem_entry * entry = wfp_static_filesystem_get_entry(filesystem, inode);
if (NULL != entry)
{
struct stat stat;
wfp_static_filesystem_stat(entry, &stat);
wfp_respond_getattr(request, &stat);
}
else
{
wfp_respond_error(request, WF_BAD_NOENTRY); wfp_respond_error(request, WF_BAD_NOENTRY);
} }
}
static void wfp_static_filesystem_readdir( static void wfp_static_filesystem_readdir(
struct wfp_request * request, struct wfp_request * request,
ino_t directory, ino_t directory,
void * user_data) void * user_data)
{ {
(void) directory; struct wfp_static_filesystem * filesystem = user_data;
(void) user_data; struct wfp_static_filesystem_entry * dir = wfp_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); wfp_respond_error(request, WF_BAD_NOENTRY);
} }
}
static void wfp_static_filesystem_open( static void wfp_static_filesystem_open(
struct wfp_request * request, struct wfp_request * request,
@ -106,14 +276,14 @@ wfp_impl_static_filesystem_create(
filesystem->size = 0; filesystem->size = 0;
filesystem->capacity = WFP_STATIC_FILESYSTEM_DEFAULT_CAPACITY; filesystem->capacity = WFP_STATIC_FILESYSTEM_DEFAULT_CAPACITY;
wfp_static_filesystem_add_dir(filesystem, 0, "<root>");
wfp_client_config_set_userdata(config, filesystem); wfp_client_config_set_userdata(config, filesystem);
wfp_client_config_set_onlookup(config, &wfp_static_filesystem_lookup); wfp_client_config_set_onlookup(config, &wfp_static_filesystem_lookup);
wfp_client_config_set_ongetattr(config, &wfp_static_filesystem_getattr); wfp_client_config_set_ongetattr(config, &wfp_static_filesystem_getattr);
wfp_client_config_set_onreaddir(config, &wfp_static_filesystem_readdir); wfp_client_config_set_onreaddir(config, &wfp_static_filesystem_readdir);
wfp_client_config_set_onopen(config, &wfp_static_filesystem_open); wfp_client_config_set_onopen(config, &wfp_static_filesystem_open);
wfp_client_config_set_onread(config, &wfp_static_filesystem_read); wfp_client_config_set_onread(config, &wfp_static_filesystem_read);
} }
return filesystem; return filesystem;
@ -123,6 +293,13 @@ void
wfp_impl_static_filesystem_dispose( wfp_impl_static_filesystem_dispose(
struct wfp_static_filesystem * filesystem) 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->entries);
free(filesystem); free(filesystem);
} }