diff --git a/src/webfuse/filesystem.cpp b/src/webfuse/filesystem.cpp index a8517fa..574f990 100644 --- a/src/webfuse/filesystem.cpp +++ b/src/webfuse/filesystem.cpp @@ -1,5 +1,8 @@ #include "webfuse/filesystem.hpp" + #include +#include +#include namespace webfuse { @@ -56,8 +59,14 @@ int filesystem::readlink(std::string const & path, std::string & out) try { messagewriter req(message_type::readlink_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + auto reader = proxy.perform(std::move(req)); + int const result = reader.read_result(); + if (0 == result) + { + out = reader.read_str(); + } + return result; } catch(...) { @@ -70,8 +79,10 @@ int filesystem::symlink(std::string const & target, std::string const & linkpath try { messagewriter req(message_type::symlink_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(target); + req.write_str(linkpath); + auto reader = proxy.perform(std::move(req)); + return reader.read_result(); } catch(...) { @@ -84,8 +95,10 @@ int filesystem::link(std::string const & old_path, std::string const & new_path) try { messagewriter req(message_type::link_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(old_path); + req.write_str(new_path); + auto reader = proxy.perform(std::move(req)); + return reader.read_result(); } catch(...) { @@ -98,8 +111,11 @@ int filesystem::rename(std::string const & old_path, std::string const & new_pat try { messagewriter req(message_type::rename_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(old_path); + req.write_str(new_path); + req.write_rename_flags(flags); + auto reader = proxy.perform(std::move(req)); + return reader.read_result(); } catch(...) { @@ -112,8 +128,10 @@ int filesystem::chmod(std::string const & path, mode_t mode) try { messagewriter req(message_type::chmod_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + req.write_mode(mode); + auto reader = proxy.perform(std::move(req)); + return reader.read_result(); } catch(...) { @@ -126,8 +144,11 @@ int filesystem::chown(std::string const & path, uid_t uid, gid_t gid) try { messagewriter req(message_type::chown_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + req.write_uid(uid); + req.write_gid(gid); + auto reader = proxy.perform(std::move(req)); + return reader.read_result(); } catch(...) { @@ -140,8 +161,11 @@ int filesystem::truncate(std::string const & path, uint64_t size, uint64_t handl try { messagewriter req(message_type::truncate_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + req.write_u64(size); + req.write_u64(handle); + auto reader = proxy.perform(std::move(req)); + return reader.read_result(); } catch(...) { @@ -154,8 +178,11 @@ int filesystem::fsync(std::string const & path, bool is_datasync, uint64_t handl try { messagewriter req(message_type::fsync_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + req.write_bool(is_datasync); + req.write_u64(handle); + auto reader = proxy.perform(std::move(req)); + return reader.read_result(); } catch(...) { @@ -168,8 +195,15 @@ int filesystem::open(std::string const & path, int flags, uint64_t & handle) try { messagewriter req(message_type::open_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + 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(...) { @@ -182,8 +216,11 @@ int filesystem::mknod(std::string const & path, mode_t mode, dev_t rdev) try { messagewriter req(message_type::mknod_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + req.write_mode(mode); + req.write_u64(rdev); + auto reader = proxy.perform(std::move(req)); + return reader.read_result(); } catch(...) { @@ -196,8 +233,15 @@ int filesystem::create(std::string const & path, mode_t mode, uint64_t & handle) try { messagewriter req(message_type::create_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + 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(...) { @@ -210,8 +254,10 @@ int filesystem::release(std::string const & path, uint64_t handle) try { messagewriter req(message_type::release_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + req.write_u64(handle); + auto reader = proxy.perform(std::move(req)); + return reader.read_result(); } catch(...) { @@ -224,8 +270,9 @@ int filesystem::unlink(std::string const & path) try { messagewriter req(message_type::unlink_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + auto reader = proxy.perform(std::move(req)); + return reader.read_result(); } catch(...) { @@ -238,8 +285,25 @@ int filesystem::read(std::string const & path, char * buffer, size_t buffer_size try { messagewriter req(message_type::read_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + 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(buffer), reinterpret_cast(data.data()), data.size()); + } + else + { + throw std::runtime_error("invalid message"); + } + } + return result; } catch(...) { @@ -252,8 +316,12 @@ int filesystem::write(std::string const & path, char const * buffer, size_t buff try { messagewriter req(message_type::write_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + 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(...) { @@ -266,8 +334,10 @@ int filesystem::mkdir(std::string const & path, mode_t mode) try { messagewriter req(message_type::mkdir_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + req.write_mode(mode); + auto reader = proxy.perform(std::move(req)); + return reader.read_result(); } catch(...) { @@ -300,8 +370,9 @@ int filesystem::rmdir(std::string const & path) try { messagewriter req(message_type::rmdir_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + auto reader = proxy.perform(std::move(req)); + return reader.read_result(); } catch(...) { @@ -314,8 +385,14 @@ int filesystem::statfs(std::string const & path, struct statvfs * statistics) try { messagewriter req(message_type::statfs_req); - proxy.perform(std::move(req)); - return -ENOENT; + req.write_str(path); + auto reader = proxy.perform(std::move(req)); + int result = reader.read_result(); + if (0 == result) + { + reader.read_statistics(statistics); + } + return result; } catch(...) { diff --git a/src/webfuse/ws/messagereader.cpp b/src/webfuse/ws/messagereader.cpp index 9f3439b..f04c52a 100644 --- a/src/webfuse/ws/messagereader.cpp +++ b/src/webfuse/ws/messagereader.cpp @@ -55,6 +55,19 @@ void messagereader::read_attr(struct stat * attr) attr->st_ctim.tv_nsec = static_cast(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() { filemode mode(read_u32()); diff --git a/src/webfuse/ws/messagereader.hpp b/src/webfuse/ws/messagereader.hpp index 6cdceeb..9157d8c 100644 --- a/src/webfuse/ws/messagereader.hpp +++ b/src/webfuse/ws/messagereader.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -24,6 +25,7 @@ public: int read_result(); void read_attr(struct stat * attr); + void read_statistics(struct statvfs * statistics); mode_t read_mode(); uint8_t read_u8(); diff --git a/src/webfuse/ws/messagewriter.cpp b/src/webfuse/ws/messagewriter.cpp index 86822bb..7cdcbd8 100644 --- a/src/webfuse/ws/messagewriter.cpp +++ b/src/webfuse/ws/messagewriter.cpp @@ -1,11 +1,16 @@ #include "webfuse/ws/messagewriter.hpp" #include "webfuse/filesystem/accessmode.hpp" +#include "webfuse/filesystem/filemode.hpp" +#include "webfuse/filesystem/openflags.hpp" #include namespace webfuse { +constexpr uint8_t const rename_noreplace = 0x01; +constexpr uint8_t const rename_exchange = 0x02; + messagewriter::messagewriter(message_type msg_type) : id(0) , data(LWS_PRE) @@ -125,6 +130,37 @@ void messagewriter::write_access_mode(int value) 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(value)); +} + +void messagewriter::write_gid(gid_t value) +{ + write_u32(static_cast(value)); +} + +void messagewriter::write_openflags(int value) +{ + openflags flags = openflags::from_int(value); + write_i32(flags); +} + unsigned char * messagewriter::get_data(size_t &size) { diff --git a/src/webfuse/ws/messagewriter.hpp b/src/webfuse/ws/messagewriter.hpp index dc5e30a..c44ab11 100644 --- a/src/webfuse/ws/messagewriter.hpp +++ b/src/webfuse/ws/messagewriter.hpp @@ -34,6 +34,11 @@ public: void write_strings(std::vector const & list); 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);