mirror of
https://github.com/falk-werner/webfuse
synced 2024-10-27 20:34:10 +00:00
3a7c064af7
* fixes verbosity option when set through command line * adds support for build type and allows to run gdb in container * adds missing toolchain headers to project * renames container macros * adds gdbserver * fixes verbosity option when set through command line * adds support for build type and allows to run gdb in container * adds missing toolchain headers to project * renames container macros * adds gdbserver * removes language settings, which contains alternating values * adds wrapper script to launch gdbserver * fix docker command in wrapper script * fixes run in dind setup * replaces docker's init through dump-init * moves filesystem to session * fixes verbosity option when set through command line * adds support for build type and allows to run gdb in container * renames container macros * adds gdbserver * fixes verbosity option when set through command line * adds support for build type and allows to run gdb in container * renames container macros * adds gdbserver * adds wrapper script to launch gdbserver * fix docker command in wrapper script * fixes run in dind setup * replaces docker's init through dump-init * moves filesystem to session * adds container_of * added dlist * allows multiple clients to connect * removes directory when session is closed * adds dependecy to uuid-dev * allow clients to register filesystems * updates documentation * moves mountpoint handling into filesystem: mountpoints are removed during session cleanup * adds filesystem name/id to request parameters * fixes security issue: add_filesystem did not check name * removes default link, if it is broken * recreates symlink "default", if filesystem is gone * updates documentation * fixes memory leak * makes authentication work .. again * updates provider to support changed protocol * removes execute right of hello.txt * fixes style issues * fixes javascript style issues * fixes flase positive from Flawfinder * fixes some javascript style issues * removes use of PATH_MAX * removes use of GNU extensions in container_of implementation * ignores findings of flawfinder * replaces dlist by slist * removes duplicate implementation of slist (message_queue)
209 lines
4.8 KiB
C
209 lines
4.8 KiB
C
#include "webfuse/adapter/impl/filesystem.h"
|
|
#include "webfuse/adapter/impl/operations.h"
|
|
#include "webfuse/adapter/impl/session.h"
|
|
|
|
#include "webfuse/core/string.h"
|
|
|
|
#include <libwebsockets.h>
|
|
#include <uuid/uuid.h>
|
|
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <dirent.h>
|
|
|
|
#include <stdlib.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
static struct fuse_lowlevel_ops const filesystem_operations =
|
|
{
|
|
.lookup = &wf_impl_operation_lookup,
|
|
.getattr = &wf_impl_operation_getattr,
|
|
.readdir = &wf_impl_operation_readdir,
|
|
.open = &wf_impl_operation_open,
|
|
.release = &wf_impl_operation_close,
|
|
.read = &wf_impl_operation_read
|
|
};
|
|
|
|
static char * wf_impl_filesystem_create_id(void)
|
|
{
|
|
uuid_t uuid;
|
|
uuid_generate(uuid);
|
|
char id[UUID_STR_LEN];
|
|
uuid_unparse(uuid, id);
|
|
|
|
return strdup(id);
|
|
}
|
|
|
|
static bool wf_impl_filesystem_is_link_broken(char const * path, char const * id)
|
|
{
|
|
bool result = false;
|
|
|
|
char buffer[UUID_STR_LEN];
|
|
ssize_t count = readlink(path, buffer, UUID_STR_LEN);
|
|
if ((0 < count) && (count < UUID_STR_LEN))
|
|
{
|
|
buffer[count] = '\0';
|
|
result = (0 == strcmp(buffer, id));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static bool wf_impl_filesystem_link_first_subdir(
|
|
char const * link_path,
|
|
char const * path)
|
|
{
|
|
bool result = false;
|
|
DIR * dir = opendir(path);
|
|
if (NULL != dir)
|
|
{
|
|
struct dirent * entry = readdir(dir);
|
|
while (NULL != entry)
|
|
{
|
|
if ((DT_DIR == entry->d_type) && ('.' != entry->d_name[0]))
|
|
{
|
|
symlink(entry->d_name, link_path);
|
|
result = true;
|
|
break;
|
|
}
|
|
|
|
entry = readdir(dir);
|
|
}
|
|
|
|
closedir(dir);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static void wf_impl_filesystem_cleanup(
|
|
struct wf_impl_filesystem * filesystem)
|
|
{
|
|
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);
|
|
|
|
rmdir(filesystem->root_path);
|
|
|
|
if (wf_impl_filesystem_is_link_broken(filesystem->default_path, filesystem->id))
|
|
{
|
|
unlink(filesystem->default_path);
|
|
|
|
bool const success = wf_impl_filesystem_link_first_subdir(filesystem->default_path, filesystem->service_path);
|
|
if (!success)
|
|
{
|
|
rmdir(filesystem->service_path);
|
|
}
|
|
}
|
|
|
|
|
|
free(filesystem->user_data.name);
|
|
free(filesystem->id);
|
|
free(filesystem->root_path);
|
|
free(filesystem->default_path);
|
|
free(filesystem->service_path);
|
|
}
|
|
|
|
|
|
static bool wf_impl_filesystem_init(
|
|
struct wf_impl_filesystem * filesystem,
|
|
struct wf_impl_session * session,
|
|
char const * name)
|
|
{
|
|
bool result = false;
|
|
|
|
char * argv[] = {"", NULL};
|
|
filesystem->args.argc = 1;
|
|
filesystem->args.argv = argv;
|
|
filesystem->args.allocated = 0;
|
|
|
|
filesystem->user_data.session = session;
|
|
filesystem->user_data.timeout = 1.0;
|
|
filesystem->user_data.name = strdup(name);
|
|
memset(&filesystem->buffer, 0, sizeof(struct fuse_buf));
|
|
|
|
filesystem->service_path = wf_create_string("%s/%s", session->mount_point, name);
|
|
mkdir(filesystem->service_path, 0755);
|
|
|
|
filesystem->id = wf_impl_filesystem_create_id();
|
|
filesystem->root_path = wf_create_string("%s/%s/%s", session->mount_point, name, filesystem->id);
|
|
mkdir(filesystem->root_path, 0755);
|
|
|
|
filesystem->default_path = wf_create_string("%s/%s/default", session->mount_point, name);
|
|
symlink(filesystem->id, filesystem->default_path);
|
|
|
|
filesystem->session = fuse_session_new(
|
|
&filesystem->args,
|
|
&filesystem_operations,
|
|
sizeof(filesystem_operations),
|
|
&filesystem->user_data);
|
|
if (NULL != filesystem->session)
|
|
{
|
|
result = (0 == fuse_session_mount(filesystem->session, filesystem->root_path));
|
|
}
|
|
|
|
if (result)
|
|
{
|
|
lws_sock_file_fd_type fd;
|
|
fd.filefd = fuse_session_fd(filesystem->session);
|
|
struct lws_protocols const * protocol = lws_get_protocol(session->wsi);
|
|
filesystem->wsi = lws_adopt_descriptor_vhost(lws_get_vhost(session->wsi), LWS_ADOPT_RAW_FILE_DESC, fd, protocol->name, session->wsi);
|
|
|
|
if (NULL == filesystem->wsi)
|
|
{
|
|
wf_impl_filesystem_cleanup(filesystem);
|
|
result = false;
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
struct wf_impl_filesystem * wf_impl_filesystem_create(
|
|
struct wf_impl_session * session,
|
|
char const * name)
|
|
{
|
|
struct wf_impl_filesystem * filesystem = malloc(sizeof(struct wf_impl_filesystem));
|
|
if (NULL != filesystem)
|
|
{
|
|
bool success = wf_impl_filesystem_init(filesystem, session, name);
|
|
if (!success)
|
|
{
|
|
free(filesystem);
|
|
filesystem = NULL;
|
|
}
|
|
}
|
|
|
|
return filesystem;
|
|
}
|
|
|
|
void wf_impl_filesystem_dispose(
|
|
struct wf_impl_filesystem * filesystem)
|
|
{
|
|
wf_impl_filesystem_cleanup(filesystem);
|
|
free(filesystem);
|
|
}
|
|
|
|
void wf_impl_filesystem_process_request(
|
|
struct wf_impl_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
|
|
}
|
|
|
|
}
|