mirror of
https://github.com/falk-werner/webfuse
synced 2024-10-27 20:34:10 +00:00
completed filesystem implemenation
This commit is contained in:
parent
6f6555cc90
commit
2479a6c2d6
@ -1,5 +1,8 @@
|
|||||||
#include "webfuse/filesystem.hpp"
|
#include "webfuse/filesystem.hpp"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace webfuse
|
namespace webfuse
|
||||||
{
|
{
|
||||||
@ -56,8 +59,14 @@ int filesystem::readlink(std::string const & path, std::string & out)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::readlink_req);
|
messagewriter req(message_type::readlink_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
int const result = reader.read_result();
|
||||||
|
if (0 == result)
|
||||||
|
{
|
||||||
|
out = reader.read_str();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -70,8 +79,10 @@ int filesystem::symlink(std::string const & target, std::string const & linkpath
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::symlink_req);
|
messagewriter req(message_type::symlink_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(target);
|
||||||
return -ENOENT;
|
req.write_str(linkpath);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -84,8 +95,10 @@ int filesystem::link(std::string const & old_path, std::string const & new_path)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::link_req);
|
messagewriter req(message_type::link_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(old_path);
|
||||||
return -ENOENT;
|
req.write_str(new_path);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -98,8 +111,11 @@ int filesystem::rename(std::string const & old_path, std::string const & new_pat
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::rename_req);
|
messagewriter req(message_type::rename_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(old_path);
|
||||||
return -ENOENT;
|
req.write_str(new_path);
|
||||||
|
req.write_rename_flags(flags);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -112,8 +128,10 @@ int filesystem::chmod(std::string const & path, mode_t mode)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::chmod_req);
|
messagewriter req(message_type::chmod_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
req.write_mode(mode);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -126,8 +144,11 @@ int filesystem::chown(std::string const & path, uid_t uid, gid_t gid)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::chown_req);
|
messagewriter req(message_type::chown_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
req.write_uid(uid);
|
||||||
|
req.write_gid(gid);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -140,8 +161,11 @@ int filesystem::truncate(std::string const & path, uint64_t size, uint64_t handl
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::truncate_req);
|
messagewriter req(message_type::truncate_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
req.write_u64(size);
|
||||||
|
req.write_u64(handle);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -154,8 +178,11 @@ int filesystem::fsync(std::string const & path, bool is_datasync, uint64_t handl
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::fsync_req);
|
messagewriter req(message_type::fsync_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
req.write_bool(is_datasync);
|
||||||
|
req.write_u64(handle);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -168,8 +195,15 @@ int filesystem::open(std::string const & path, int flags, uint64_t & handle)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::open_req);
|
messagewriter req(message_type::open_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
req.write_openflags(flags);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
int result = reader.read_result();
|
||||||
|
if (0 == result)
|
||||||
|
{
|
||||||
|
handle = reader.read_u64();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -182,8 +216,11 @@ int filesystem::mknod(std::string const & path, mode_t mode, dev_t rdev)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::mknod_req);
|
messagewriter req(message_type::mknod_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
req.write_mode(mode);
|
||||||
|
req.write_u64(rdev);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -196,8 +233,15 @@ int filesystem::create(std::string const & path, mode_t mode, uint64_t & handle)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::create_req);
|
messagewriter req(message_type::create_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
req.write_mode(mode);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
int result = reader.read_result();
|
||||||
|
if (0 == result)
|
||||||
|
{
|
||||||
|
handle = reader.read_u64();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -210,8 +254,10 @@ int filesystem::release(std::string const & path, uint64_t handle)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::release_req);
|
messagewriter req(message_type::release_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
req.write_u64(handle);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -224,8 +270,9 @@ int filesystem::unlink(std::string const & path)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::unlink_req);
|
messagewriter req(message_type::unlink_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -238,8 +285,25 @@ int filesystem::read(std::string const & path, char * buffer, size_t buffer_size
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::read_req);
|
messagewriter req(message_type::read_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
req.write_u32(buffer_size);
|
||||||
|
req.write_u64(offset);
|
||||||
|
req.write_u64(handle);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
int result = reader.read_result();
|
||||||
|
if (result > 0)
|
||||||
|
{
|
||||||
|
std::string data = reader.read_bytes();
|
||||||
|
if (data.size() <= buffer_size)
|
||||||
|
{
|
||||||
|
memcpy(reinterpret_cast<void*>(buffer), reinterpret_cast<void const*>(data.data()), data.size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("invalid message");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -252,8 +316,12 @@ int filesystem::write(std::string const & path, char const * buffer, size_t buff
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::write_req);
|
messagewriter req(message_type::write_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
req.write_data(buffer, buffer_size);
|
||||||
|
req.write_u64(offset);
|
||||||
|
req.write_u64(handle);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -266,8 +334,10 @@ int filesystem::mkdir(std::string const & path, mode_t mode)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::mkdir_req);
|
messagewriter req(message_type::mkdir_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
req.write_mode(mode);
|
||||||
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -300,8 +370,9 @@ int filesystem::rmdir(std::string const & path)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::rmdir_req);
|
messagewriter req(message_type::rmdir_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
return reader.read_result();
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@ -314,8 +385,14 @@ int filesystem::statfs(std::string const & path, struct statvfs * statistics)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
messagewriter req(message_type::statfs_req);
|
messagewriter req(message_type::statfs_req);
|
||||||
proxy.perform(std::move(req));
|
req.write_str(path);
|
||||||
return -ENOENT;
|
auto reader = proxy.perform(std::move(req));
|
||||||
|
int result = reader.read_result();
|
||||||
|
if (0 == result)
|
||||||
|
{
|
||||||
|
reader.read_statistics(statistics);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
@ -55,6 +55,19 @@ void messagereader::read_attr(struct stat * attr)
|
|||||||
attr->st_ctim.tv_nsec = static_cast<long>(read_u32());
|
attr->st_ctim.tv_nsec = static_cast<long>(read_u32());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void messagereader::read_statistics(struct statvfs * statistics)
|
||||||
|
{
|
||||||
|
statistics->f_bsize = read_u64();
|
||||||
|
statistics->f_frsize = read_u64();
|
||||||
|
statistics->f_blocks = read_u64();
|
||||||
|
statistics->f_bfree = read_u64();
|
||||||
|
statistics->f_bavail = read_u64();
|
||||||
|
statistics->f_files = read_u64();
|
||||||
|
statistics->f_ffree = read_u64();
|
||||||
|
statistics->f_namemax = read_u64();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
mode_t messagereader::read_mode()
|
mode_t messagereader::read_mode()
|
||||||
{
|
{
|
||||||
filemode mode(read_u32());
|
filemode mode(read_u32());
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
@ -24,6 +25,7 @@ public:
|
|||||||
|
|
||||||
int read_result();
|
int read_result();
|
||||||
void read_attr(struct stat * attr);
|
void read_attr(struct stat * attr);
|
||||||
|
void read_statistics(struct statvfs * statistics);
|
||||||
mode_t read_mode();
|
mode_t read_mode();
|
||||||
|
|
||||||
uint8_t read_u8();
|
uint8_t read_u8();
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
#include "webfuse/ws/messagewriter.hpp"
|
#include "webfuse/ws/messagewriter.hpp"
|
||||||
#include "webfuse/filesystem/accessmode.hpp"
|
#include "webfuse/filesystem/accessmode.hpp"
|
||||||
|
#include "webfuse/filesystem/filemode.hpp"
|
||||||
|
#include "webfuse/filesystem/openflags.hpp"
|
||||||
|
|
||||||
#include <libwebsockets.h>
|
#include <libwebsockets.h>
|
||||||
|
|
||||||
namespace webfuse
|
namespace webfuse
|
||||||
{
|
{
|
||||||
|
|
||||||
|
constexpr uint8_t const rename_noreplace = 0x01;
|
||||||
|
constexpr uint8_t const rename_exchange = 0x02;
|
||||||
|
|
||||||
messagewriter::messagewriter(message_type msg_type)
|
messagewriter::messagewriter(message_type msg_type)
|
||||||
: id(0)
|
: id(0)
|
||||||
, data(LWS_PRE)
|
, data(LWS_PRE)
|
||||||
@ -125,6 +130,37 @@ void messagewriter::write_access_mode(int value)
|
|||||||
write_i8(mode);
|
write_i8(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void messagewriter::write_rename_flags(unsigned int value)
|
||||||
|
{
|
||||||
|
uint8_t flags = 0;
|
||||||
|
if (RENAME_NOREPLACE == (value & RENAME_NOREPLACE)) { flags |= rename_noreplace; }
|
||||||
|
if (RENAME_EXCHANGE == (value & RENAME_EXCHANGE )) { flags |= rename_exchange; }
|
||||||
|
|
||||||
|
write_u8(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void messagewriter::write_mode(mode_t value)
|
||||||
|
{
|
||||||
|
filemode mode = filemode::from_mode(value);
|
||||||
|
write_u32(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void messagewriter::write_uid(uid_t value)
|
||||||
|
{
|
||||||
|
write_u32(static_cast<uint32_t>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void messagewriter::write_gid(gid_t value)
|
||||||
|
{
|
||||||
|
write_u32(static_cast<uint32_t>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void messagewriter::write_openflags(int value)
|
||||||
|
{
|
||||||
|
openflags flags = openflags::from_int(value);
|
||||||
|
write_i32(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned char * messagewriter::get_data(size_t &size)
|
unsigned char * messagewriter::get_data(size_t &size)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,11 @@ public:
|
|||||||
void write_strings(std::vector<std::string> const & list);
|
void write_strings(std::vector<std::string> const & list);
|
||||||
|
|
||||||
void write_access_mode(int value);
|
void write_access_mode(int value);
|
||||||
|
void write_rename_flags(unsigned int value);
|
||||||
|
void write_mode(mode_t value);
|
||||||
|
void write_uid(uid_t value);
|
||||||
|
void write_gid(gid_t value);
|
||||||
|
void write_openflags(int value);
|
||||||
|
|
||||||
unsigned char * get_data(size_t &size);
|
unsigned char * get_data(size_t &size);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user