2.0.0-rc (#9)
Some checks failed
BlockStorage/repertory_osx/pipeline/head This commit looks good
BlockStorage/repertory_windows/pipeline/head This commit looks good
BlockStorage/repertory/pipeline/head There was a failure building this commit
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good
BlockStorage/repertory_osx_builds/pipeline/head There was a failure building this commit

### Issues

* \#1 \[bug\] Unable to mount S3 due to 'item_not_found' exception
* \#2 Require bucket name for S3 mounts
* \#3 \[bug\] File size is not being updated in S3 mount
* \#4 Upgrade to libfuse-3.x.x
* \#5 Switch to renterd for Sia support
* \#6 Switch to cpp-httplib to further reduce dependencies
* \#7 Remove global_data and calculate used disk space per provider
* \#8 Switch to libcurl for S3 mount support

### Changes from v1.x.x

* Added read-only encrypt provider
  * Pass-through mount point that transparently encrypts source data using `XChaCha20-Poly1305`
* Added S3 encryption support via `XChaCha20-Poly1305`
* Added replay protection to remote mounts
* Added support base64 writes in remote FUSE
* Created static linked Linux binaries for `amd64` and `aarch64` using `musl-libc`
* Removed legacy Sia renter support
* Removed Skynet support
* Fixed multiple remote mount WinFSP API issues on \*NIX servers
* Implemented chunked read and write
  * Writes for non-cached files are performed in chunks of 8Mib
* Removed `repertory-ui` support
* Removed `FreeBSD` support
* Switched to `libsodium` over `CryptoPP`
* Switched to `XChaCha20-Poly1305` for remote mounts
* Updated `GoogleTest` to v1.14.0
* Updated `JSON for Modern C++` to v3.11.2
* Updated `OpenSSL` to v1.1.1w
* Updated `RocksDB` to v8.5.3
* Updated `WinFSP` to 2023
* Updated `boost` to v1.78.0
* Updated `cURL` to v8.3.0
* Updated `zlib` to v1.3
* Use `upload_manager` for all providers
  * Adds a delay to uploads to prevent excessive API calls
  * Supports re-upload after mount restart for incomplete uploads
  * NOTE: Uploads for all providers are full file (no resume support)
    * Multipart upload support is planned for S3

Reviewed-on: #9
This commit is contained in:
2023-10-29 06:55:59 +00:00
parent 3ff46723b8
commit f43c41f88a
839 changed files with 98214 additions and 92959 deletions

View File

@@ -1,67 +1,66 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_DIRECTORY_CACHE_HPP_
#define INCLUDE_DRIVES_DIRECTORY_CACHE_HPP_
#include "common.hpp"
#include "utils/single_thread_service_base.hpp"
namespace repertory {
class directory_iterator;
class directory_cache final {
class directory_cache final : public single_thread_service_base {
public:
typedef std::function<void(directory_iterator &iterator)> execute_callback;
using execute_callback = std::function<void(directory_iterator &)>;
private:
struct open_directory {
directory_iterator *iterator;
std::chrono::system_clock::time_point last_update = std::chrono::system_clock::now();
std::chrono::system_clock::time_point last_update =
std::chrono::system_clock::now();
};
public:
directory_cache() = default;
directory_cache() : single_thread_service_base("directory_cache") {}
~directory_cache() { stop(); }
~directory_cache() override = default;
private:
std::unordered_map<std::string, open_directory> directory_lookup_;
std::recursive_mutex directory_mutex_;
bool is_shutdown_ = true;
std::unique_ptr<std::thread> refresh_thread_;
std::mutex shutdown_mutex_;
std::condition_variable shutdown_notify_;
private:
void refresh_thread();
protected:
void service_function() override;
public:
bool execute_action(const std::string &api_path, const execute_callback &execute);
void execute_action(const std::string &api_path,
const execute_callback &execute);
directory_iterator *remove_directory(const std::string &api_path);
[[nodiscard]] auto remove_directory(const std::string &api_path)
-> directory_iterator *;
void remove_directory(directory_iterator *iterator);
void set_directory(const std::string &api_path, directory_iterator *iterator);
void start();
void stop();
};
} // namespace repertory

View File

@@ -1,25 +1,27 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_DIRECTORY_ITERATOR_HPP_
#define INCLUDE_DRIVES_DIRECTORY_ITERATOR_HPP_
#include "common.hpp"
#include "types/remote.hpp"
#include "types/repertory.hpp"
@@ -27,44 +29,52 @@ namespace repertory {
class directory_iterator final {
public:
#ifndef _WIN32
typedef std::function<void(const std::string &api_path, const std::uint64_t &file_size,
const api_meta_map &meta, const bool &directory, struct stat *st)>
populate_stat_callback;
using populate_stat_callback =
std::function<void(const std::string &, std::uint64_t,
const api_meta_map &, bool, struct stat *)>;
#endif
public:
explicit directory_iterator(directory_item_list list) : items_(std::move(list)) {}
explicit directory_iterator(directory_item_list list)
: items_(std::move(list)) {}
directory_iterator(const directory_iterator &iterator) noexcept : items_(iterator.items_) {}
directory_iterator(const directory_iterator &iterator) noexcept = default;
directory_iterator(directory_iterator &&iterator) noexcept : items_(std::move(iterator.items_)) {}
directory_iterator(directory_iterator &&iterator) noexcept
: items_(std::move(iterator.items_)) {}
private:
directory_item_list items_;
public:
#ifndef _WIN32
int fill_buffer(const remote::file_offset &offset, fuse_fill_dir_t filler_function, void *buffer,
populate_stat_callback populate_stat);
[[nodiscard]] auto fill_buffer(const remote::file_offset &offset,
fuse_fill_dir_t filler_function, void *buffer,
populate_stat_callback populate_stat) -> int;
#endif
int get(const std::size_t &offset, std::string &item);
[[nodiscard]] auto get(std::size_t offset, std::string &item) -> int;
std::size_t get_count() const { return items_.size(); }
[[nodiscard]] auto get_count() const -> std::size_t { return items_.size(); }
api_error get_directory_item(const std::size_t &offset, directory_item &di);
[[nodiscard]] auto get_directory_item(std::size_t offset, directory_item &di)
-> api_error;
api_error get_directory_item(const std::string &api_path, directory_item &di);
[[nodiscard]] auto get_directory_item(const std::string &api_path,
directory_item &di) -> api_error;
int get_json(const std::size_t &offset, json &item);
[[nodiscard]] auto get_json(std::size_t offset, json &item) -> int;
std::size_t get_next_directory_offset(const std::string &api_path) const;
[[nodiscard]] auto
get_next_directory_offset(const std::string &api_path) const -> std::size_t;
public:
directory_iterator &operator=(const directory_iterator &iterator) noexcept;
auto operator=(const directory_iterator &iterator) noexcept
-> directory_iterator &;
directory_iterator &operator=(directory_iterator &&iterator) noexcept;
auto operator=(directory_iterator &&iterator) noexcept
-> directory_iterator &;
directory_iterator &operator=(directory_item_list list) noexcept;
auto operator=(directory_item_list list) noexcept -> directory_iterator &;
};
} // namespace repertory

View File

@@ -1,58 +1,57 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_EVICTION_HPP_
#define INCLUDE_DRIVES_EVICTION_HPP_
#include "common.hpp"
#include "utils/single_thread_service_base.hpp"
namespace repertory {
class app_config;
class i_open_file_table;
class i_file_manager;
class i_provider;
class eviction final {
public:
eviction(i_provider &provider, const app_config &config, i_open_file_table &oft)
: provider_(provider), config_(config), oft_(oft) {}
~eviction() = default;
class eviction final : public single_thread_service_base {
public:
eviction(i_provider &provider, const app_config &config, i_file_manager &fm)
: single_thread_service_base("eviction"),
provider_(provider),
config_(config),
fm_(fm) {}
~eviction() override = default;
private:
i_provider &provider_;
const app_config &config_;
i_open_file_table &oft_;
bool stop_requested_ = false;
std::mutex start_stop_mutex_;
std::condition_variable stop_notify_;
std::unique_ptr<std::thread> eviction_thread_;
std::mutex eviction_mutex_;
i_file_manager &fm_;
private:
void check_items_thread();
[[nodiscard]] auto check_minimum_requirements(const std::string &file_path)
-> bool;
bool check_minimum_requirements(const std::string &file_path);
[[nodiscard]] auto get_filtered_cached_files() -> std::deque<std::string>;
std::deque<std::string> get_filtered_cached_files();
public:
void start();
void stop();
protected:
void service_function() override;
};
} // namespace repertory

View File

@@ -1,25 +1,27 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_FUSE_EVENTS_HPP_
#define INCLUDE_DRIVES_FUSE_EVENTS_HPP_
#include "common.hpp"
#include "events/event_system.hpp"
namespace repertory {

View File

@@ -1,39 +1,40 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_FUSE_FUSE_BASE_HPP_
#define INCLUDE_DRIVES_FUSE_FUSE_BASE_HPP_
#ifndef _WIN32
#include "common.hpp"
#include "events/event_system.hpp"
#include "drives/fuse/i_fuse_drive.hpp"
#include "utils/path_utils.hpp"
namespace repertory {
class app_config;
class i_provider;
class fuse_base : public i_fuse_drive {
class fuse_base {
E_CONSUMER();
public:
explicit fuse_base(app_config &config_);
explicit fuse_base(app_config &config);
virtual ~fuse_base();
@@ -51,454 +52,558 @@ protected:
std::optional<mode_t> forced_umask_;
private:
static fuse_base &instance();
static auto instance() -> fuse_base &;
private:
// clang-format off
struct fuse_operations fuse_ops_ {
.getattr = fuse_base::getattr_,
.readlink = nullptr, // int (*readlink) (const char *, char *, size_t);
.getdir = nullptr, // int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
.mknod = nullptr, // int (*mknod) (const char *, mode_t, dev_t);
.mkdir = fuse_base::mkdir_,
.unlink = fuse_base::unlink_,
.rmdir = fuse_base::rmdir_,
.symlink = nullptr, // int (*symlink) (const char *, const char *);
.rename = fuse_base::rename_,
.link = nullptr, // int (*link) (const char *, const char *);
.chmod = fuse_base::chmod_,
.chown = fuse_base::chown_,
.truncate = fuse_base::truncate_,
.utime = nullptr, // int (*utime) (const char *, struct utimbuf *);
.open = fuse_base::open_,
.read = fuse_base::read_,
.write = fuse_base::write_,
#ifdef __APPLE__
.statfs = nullptr,
#else // __APPLE__
.statfs = fuse_base::statfs_,
#endif // __APPLE__
.flush = nullptr, // int (*flush) (const char *, struct fuse_file_info *);
.release = fuse_base::release_,
.fsync = fuse_base::fsync_,
#if HAS_SETXATTR
.setxattr = fuse_base::setxattr_,
.getxattr = fuse_base::getxattr_,
.listxattr = fuse_base::listxattr_,
.removexattr = fuse_base::removexattr_,
#else // HAS_SETXATTR
.setxattr = nullptr,
.getxattr = nullptr,
.listxattr = nullptr,
.removexattr = nullptr,
#endif // HAS_SETXATTR
.opendir = fuse_base::opendir_,
.readdir = fuse_base::readdir_,
.releasedir = fuse_base::releasedir_,
.fsyncdir = nullptr, // int (*fsyncdir) (const char *, int, struct fuse_file_info *);
.init = fuse_base::init_,
.destroy = fuse_base::destroy_,
.access = fuse_base::access_,
.create = fuse_base::create_,
.ftruncate = fuse_base::ftruncate_,
.fgetattr = fuse_base::fgetattr_,
.lock = nullptr, // int (*lock) (const char *, struct fuse_file_info *, int cmd, struct flock *);
.utimens = fuse_base::utimens_,
.bmap = nullptr, // int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
.flag_nullpath_ok = 0,
.flag_nopath = 0,
.flag_utime_omit_ok = 1,
.flag_reserved = 0,
.ioctl = nullptr, // int (*ioctl) (const char *, int cmd, void *arg, struct fuse_file_info *, unsigned int flags, void *data);
.poll = nullptr, // int (*poll) (const char *, struct fuse_file_info *, struct fuse_pollhandle *ph, unsigned *reventsp);
.write_buf = nullptr, // int (*write_buf) (const char *, struct fuse_bufvec *buf, off_t off, struct fuse_file_info *);
.read_buf = nullptr, // int (*read_buf) (const char *, struct fuse_bufvec **bufp, size_t size, off_t off, struct fuse_file_info *);
.flock = nullptr, // int (*flock) (const char *, struct fuse_file_info *, int op);
.fallocate = fuse_base::fallocate_
};
// clang-format on
struct fuse_operations fuse_ops_ {};
private:
int execute_callback(const std::string &function_name, const char *from, const char *to,
const std::function<api_error(const std::string &, const std::string &)> &cb,
const bool &disable_logging = false);
[[nodiscard]] auto execute_callback(
const std::string &function_name, const char *from, const char *to,
const std::function<api_error(const std::string &, const std::string &)>
&cb,
bool disable_logging = false) -> int;
int execute_callback(const std::string &function_name, const char *path,
const std::function<api_error(const std::string &)> &cb,
const bool &disable_logging = false);
[[nodiscard]] auto
execute_callback(const std::string &function_name, const char *path,
const std::function<api_error(const std::string &)> &cb,
bool disable_logging = false) -> int;
static void execute_void_callback(const std::string &function_name,
const std::function<void()> &cb);
static void *execute_void_pointer_callback(const std::string &function_name,
const std::function<void *()> &cb);
static auto execute_void_pointer_callback(const std::string &function_name,
const std::function<void *()> &cb)
-> void *;
void raise_fuse_event(std::string function_name, const std::string &api_file, const int &ret,
const bool &disable_logging);
void raise_fuse_event(std::string function_name, const std::string &api_file,
int ret, bool disable_logging);
private:
static int access_(const char *path, int mask);
[[nodiscard]] static auto access_(const char *path, int mask) -> int;
#ifdef __APPLE__
static int chflags_(const char *path, uint32_t flags);
[[nodiscard]] static auto chflags_(const char *path, uint32_t flags) -> int;
#endif // __APPLE__
static int chmod_(const char *path, mode_t mode);
#if FUSE_USE_VERSION >= 30
[[nodiscard]] static auto chmod_(const char *path, mode_t mode,
struct fuse_file_info *fi) -> int;
#else
[[nodiscard]] static auto chmod_(const char *path, mode_t mode) -> int;
#endif
static int chown_(const char *path, uid_t uid, gid_t gid);
#if FUSE_USE_VERSION >= 30
[[nodiscard]] static auto chown_(const char *path, uid_t uid, gid_t gid,
struct fuse_file_info *fi) -> int;
#else
[[nodiscard]] static auto chown_(const char *path, uid_t uid, gid_t gid)
-> int;
#endif
static int create_(const char *path, mode_t mode, struct fuse_file_info *fi);
[[nodiscard]] static auto create_(const char *path, mode_t mode,
struct fuse_file_info *fi) -> int;
static void destroy_(void *ptr);
static int fallocate_(const char *path, int mode, off_t offset, off_t length,
struct fuse_file_info *fi);
[[nodiscard]] static auto fallocate_(const char *path, int mode, off_t offset,
off_t length, struct fuse_file_info *fi)
-> int;
static int fgetattr_(const char *path, struct stat *st, struct fuse_file_info *fi);
#if FUSE_USE_VERSION < 30
[[nodiscard]] static auto fgetattr_(const char *path, struct stat *st,
struct fuse_file_info *fi) -> int;
#endif
#ifdef __APPLE__
static int fsetattr_x_(const char *path, struct setattr_x *attr, struct fuse_file_info *fi);
[[nodiscard]] static auto fsetattr_x_(const char *path,
struct setattr_x *attr,
struct fuse_file_info *fi) -> int;
#endif // __APPLE__
static int fsync_(const char *path, int datasync, struct fuse_file_info *fi);
[[nodiscard]] static auto fsync_(const char *path, int datasync,
struct fuse_file_info *fi) -> int;
static int ftruncate_(const char *path, off_t size, struct fuse_file_info *fi);
[[nodiscard]] static auto ftruncate_(const char *path, off_t size,
struct fuse_file_info *fi) -> int;
static int getattr_(const char *path, struct stat *st);
#if FUSE_USE_VERSION >= 30
[[nodiscard]] static auto getattr_(const char *path, struct stat *st,
struct fuse_file_info *fi) -> int;
#else
[[nodiscard]] static auto getattr_(const char *path, struct stat *st) -> int;
#endif
#ifdef __APPLE__
static int getxtimes_(const char *path, struct timespec *bkuptime, struct timespec *crtime);
[[nodiscard]] static auto getxtimes_(const char *path,
struct timespec *bkuptime,
struct timespec *crtime) -> int;
#endif // __APPLE__
static void *init_(struct fuse_conn_info *conn);
#if FUSE_USE_VERSION >= 30
[[nodiscard]] static auto init_(struct fuse_conn_info *conn,
struct fuse_config *cfg) -> void *;
#else
[[nodiscard]] static auto init_(struct fuse_conn_info *conn) -> void *;
#endif
static int mkdir_(const char *path, mode_t mode);
[[nodiscard]] static auto mkdir_(const char *path, mode_t mode) -> int;
static int open_(const char *path, struct fuse_file_info *fi);
[[nodiscard]] static auto open_(const char *path, struct fuse_file_info *fi)
-> int;
static int opendir_(const char *path, struct fuse_file_info *fi);
[[nodiscard]] static auto opendir_(const char *path,
struct fuse_file_info *fi) -> int;
static int read_(const char *path, char *buffer, size_t read_size, off_t read_offset,
struct fuse_file_info *fi);
[[nodiscard]] static auto read_(const char *path, char *buffer,
size_t read_size, off_t read_offset,
struct fuse_file_info *fi) -> int;
static int readdir_(const char *path, void *buf, fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi);
#if FUSE_USE_VERSION >= 30
[[nodiscard]] static auto readdir_(const char *path, void *buf,
fuse_fill_dir_t fuse_fill_dir,
off_t offset, struct fuse_file_info *fi,
fuse_readdir_flags flags) -> int;
#else
[[nodiscard]] static auto readdir_(const char *path, void *buf,
fuse_fill_dir_t fuse_fill_dir,
off_t offset, struct fuse_file_info *fi)
-> int;
#endif
static int release_(const char *path, struct fuse_file_info *fi);
[[nodiscard]] static auto release_(const char *path,
struct fuse_file_info *fi) -> int;
static int releasedir_(const char *path, struct fuse_file_info *fi);
[[nodiscard]] static auto releasedir_(const char *path,
struct fuse_file_info *fi) -> int;
static int rename_(const char *from, const char *to);
#if FUSE_USE_VERSION >= 30
[[nodiscard]] static auto rename_(const char *from, const char *to,
unsigned int flags) -> int;
#else
[[nodiscard]] static auto rename_(const char *from, const char *to) -> int;
#endif
static int rmdir_(const char *path);
[[nodiscard]] static auto rmdir_(const char *path) -> int;
#ifdef HAS_SETXATTR
#ifdef __APPLE__
static int getxattr_(const char *path, const char *name, char *value, size_t size,
uint32_t position);
[[nodiscard]] static auto getxattr_(const char *path, const char *name,
char *value, size_t size,
uint32_t position) -> int;
#else // __APPLE__
static int getxattr_(const char *path, const char *name, char *value, size_t size);
[[nodiscard]] static auto getxattr_(const char *path, const char *name,
char *value, size_t size) -> int;
#endif // __APPLE__
static int listxattr_(const char *path, char *buffer, size_t size);
[[nodiscard]] static auto listxattr_(const char *path, char *buffer,
size_t size) -> int;
static int removexattr_(const char *path, const char *name);
[[nodiscard]] static auto removexattr_(const char *path, const char *name)
-> int;
#ifdef __APPLE__
static int setxattr_(const char *path, const char *name, const char *value, size_t size,
int flags, uint32_t position);
[[nodiscard]] static auto setxattr_(const char *path, const char *name,
const char *value, size_t size, int flags,
uint32_t position) -> int;
#else // __APPLE__
static int setxattr_(const char *path, const char *name, const char *value, size_t size,
int flags);
[[nodiscard]] static auto setxattr_(const char *path, const char *name,
const char *value, size_t size, int flags)
-> int;
#endif // __APPLE__
#endif // HAS_SETXATTR
#ifdef __APPLE__
static int setattr_x_(const char *path, struct setattr_x *attr);
[[nodiscard]] static auto setattr_x_(const char *path, struct setattr_x *attr)
-> int;
static int setbkuptime_(const char *path, const struct timespec *bkuptime);
[[nodiscard]] static auto setbkuptime_(const char *path,
const struct timespec *bkuptime)
-> int;
static int setchgtime_(const char *path, const struct timespec *chgtime);
[[nodiscard]] static auto setchgtime_(const char *path,
const struct timespec *chgtime) -> int;
static int setcrtime_(const char *path, const struct timespec *crtime);
[[nodiscard]] static auto setcrtime_(const char *path,
const struct timespec *crtime) -> int;
static int setvolname_(const char *volname);
[[nodiscard]] static auto setvolname_(const char *volname) -> int;
static int statfs_x_(const char *path, struct statfs *stbuf);
[[nodiscard]] static auto statfs_x_(const char *path, struct statfs *stbuf)
-> int;
#else // __APPLE__
static int statfs_(const char *path, struct statvfs *stbuf);
[[nodiscard]] static auto statfs_(const char *path, struct statvfs *stbuf)
-> int;
#endif // __APPLE__
static int truncate_(const char *path, off_t size);
#if FUSE_USE_VERSION >= 30
[[nodiscard]] static auto truncate_(const char *path, off_t size,
struct fuse_file_info *fi) -> int;
#else
[[nodiscard]] static auto truncate_(const char *path, off_t size) -> int;
#endif
static int unlink_(const char *path);
[[nodiscard]] static auto unlink_(const char *path) -> int;
static int utimens_(const char *path, const struct timespec tv[2]);
#if FUSE_USE_VERSION >= 30
[[nodiscard]] static auto utimens_(const char *path,
const struct timespec tv[2],
struct fuse_file_info *fi) -> int;
#else
[[nodiscard]] static auto utimens_(const char *path,
const struct timespec tv[2]) -> int;
#endif
static int write_(const char *path, const char *buffer, size_t write_size, off_t write_offset,
struct fuse_file_info *fi);
[[nodiscard]] static auto write_(const char *path, const char *buffer,
size_t write_size, off_t write_offset,
struct fuse_file_info *fi) -> int;
protected:
api_error check_access(const std::string &api_path, int mask) const;
api_error check_and_perform(const std::string &api_path, int parent_mask,
const std::function<api_error(api_meta_map &meta)> &action);
uid_t get_effective_uid() const;
gid_t get_effective_gid() const;
static api_error check_open_flags(const int &flags, const int &mask, const api_error &fail_error);
api_error check_owner(const api_meta_map &meta) const;
static api_error check_readable(const int &flags, const api_error &fail_error);
static api_error check_writeable(const int &flags, const api_error &fail_error);
#ifdef __APPLE__
static __uint32_t get_flags_from_meta(const api_meta_map &meta);
#endif // __APPLE__
static gid_t get_gid_from_meta(const api_meta_map &meta);
static mode_t get_mode_from_meta(const api_meta_map &meta);
static void get_timespec_from_meta(const api_meta_map &meta, const std::string &name,
struct timespec &ts);
static uid_t get_uid_from_meta(const api_meta_map &meta);
static void populate_stat(const std::string &api_path, const std::uint64_t &size_or_count,
const api_meta_map &meta, const bool &directory, i_provider &provider,
struct stat *st);
static void set_timespec_from_meta(const api_meta_map &meta, const std::string &name,
struct timespec &ts);
protected:
virtual api_error access_impl(std::string api_path, int mask) {
return check_access(api_path, mask);
[[nodiscard]] virtual auto access_impl(std::string /*api_path*/, int /*mask*/)
-> api_error {
return api_error::not_implemented;
}
#ifdef __APPLE__
virtual api_error chflags_impl(std::string /*api_path*/, uint32_t /*flags*/) {
[[nodiscard]] virtual auto chflags_impl(std::string /*api_path*/,
uint32_t /*flags*/) -> api_error {
return api_error::not_implemented;
}
#endif // __APPLE__
virtual api_error chmod_impl(std::string /*api_path*/, mode_t /*mode*/) {
#if FUSE_USE_VERSION >= 30
[[nodiscard]] virtual auto chmod_impl(std::string /*api_path*/,
mode_t /*mode*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
virtual api_error chown_impl(std::string /*api_path*/, uid_t /*uid*/, gid_t /*gid*/) {
#else
[[nodiscard]] virtual auto chmod_impl(std::string /*api_path*/,
mode_t /*mode*/) -> api_error {
return api_error::not_implemented;
}
#endif
virtual api_error create_impl(std::string /*api_path*/, mode_t /*mode*/,
struct fuse_file_info * /*fi*/) {
#if FUSE_USE_VERSION >= 30
[[nodiscard]] virtual auto chown_impl(std::string /*api_path*/, uid_t /*uid*/,
gid_t /*gid*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
#else
[[nodiscard]] virtual auto chown_impl(std::string /*api_path*/, uid_t /*uid*/,
gid_t /*gid*/) -> api_error {
return api_error::not_implemented;
}
#endif
[[nodiscard]] virtual auto create_impl(std::string /*api_path*/,
mode_t /*mode*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
virtual void destroy_impl(void * /*ptr*/) { return; }
virtual api_error fallocate_impl(std::string /*api_path*/, int /*mode*/, off_t /*offset*/,
off_t /*length*/, struct fuse_file_info * /*fi*/) {
[[nodiscard]] virtual auto
fallocate_impl(std::string /*api_path*/, int /*mode*/, off_t /*offset*/,
off_t /*length*/, struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
virtual api_error fgetattr_impl(std::string /*api_path*/, struct stat * /*st*/,
struct fuse_file_info * /*fi*/) {
return api_error::not_implemented;
}
virtual api_error fsetattr_x_impl(std::string /*api_path*/, struct setattr_x * /*attr*/,
struct fuse_file_info * /*fi*/) {
return api_error::not_implemented;
}
virtual api_error fsync_impl(std::string /*api_path*/, int /*datasync*/,
struct fuse_file_info * /*fi*/) {
return api_error::not_implemented;
}
virtual api_error ftruncate_impl(std::string /*api_path*/, off_t /*size*/,
struct fuse_file_info * /*fi*/) {
return api_error::not_implemented;
}
virtual api_error getattr_impl(std::string /*api_path*/, struct stat * /*st*/) {
[[nodiscard]] virtual auto fgetattr_impl(std::string /*api_path*/,
struct stat * /*st*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
#ifdef __APPLE__
virtual api_error getxtimes_impl(std::string /*api_path*/, struct timespec * /*bkuptime*/,
struct timespec * /*crtime*/) {
[[nodiscard]] virtual auto fsetattr_x_impl(std::string /*api_path*/,
struct setattr_x * /*attr*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
#endif // __APPLE__
virtual void *init_impl(struct fuse_conn_info *conn);
virtual api_error mkdir_impl(std::string /*api_path*/, mode_t /*mode*/) {
[[nodiscard]] virtual auto fsync_impl(std::string /*api_path*/,
int /*datasync*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
virtual api_error open_impl(std::string /*api_path*/, struct fuse_file_info * /*fi*/) {
#if FUSE_USE_VERSION < 30
[[nodiscard]] virtual auto ftruncate_impl(std::string /*api_path*/,
off_t /*size*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
#endif
#if FUSE_USE_VERSION >= 30
[[nodiscard]] virtual auto getattr_impl(std::string /*api_path*/,
struct stat * /*st*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
#else
[[nodiscard]] virtual auto getattr_impl(std::string /*api_path*/,
struct stat * /*st*/) -> api_error {
return api_error::not_implemented;
}
#endif
#ifdef __APPLE__
[[nodiscard]] virtual auto getxtimes_impl(std::string /*api_path*/,
struct timespec * /*bkuptime*/,
struct timespec * /*crtime*/)
-> api_error {
return api_error::not_implemented;
}
#endif // __APPLE__
#if FUSE_USE_VERSION >= 30
virtual auto init_impl(struct fuse_conn_info *conn, struct fuse_config *cfg)
-> void *;
#else
virtual auto init_impl(struct fuse_conn_info *conn) -> void *;
#endif
[[nodiscard]] virtual auto mkdir_impl(std::string /*api_path*/,
mode_t /*mode*/) -> api_error {
return api_error::not_implemented;
}
virtual api_error opendir_impl(std::string /*api_path*/, struct fuse_file_info * /*fi*/) {
[[nodiscard]] virtual auto open_impl(std::string /*api_path*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
virtual api_error read_impl(std::string /*api_path*/, char * /*buffer*/, size_t /*read_size*/,
off_t /*read_offset*/, struct fuse_file_info * /*fi*/,
std::size_t & /*bytes_read*/) {
[[nodiscard]] virtual auto opendir_impl(std::string /*api_path*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
virtual api_error readdir_impl(std::string /*api_path*/, void * /*buf*/,
fuse_fill_dir_t /*fuse_fill_dir*/, off_t /*offset*/,
struct fuse_file_info * /*fi*/) {
[[nodiscard]] virtual auto
read_impl(std::string /*api_path*/, char * /*buffer*/, size_t /*read_size*/,
off_t /*read_offset*/, struct fuse_file_info * /*fi*/,
std::size_t & /*bytes_read*/) -> api_error {
return api_error::not_implemented;
}
virtual api_error release_impl(std::string /*api_path*/, struct fuse_file_info * /*fi*/) {
#if FUSE_USE_VERSION >= 30
[[nodiscard]] virtual auto
readdir_impl(std::string /*api_path*/, void * /*buf*/,
fuse_fill_dir_t /*fuse_fill_dir*/, off_t /*offset*/,
struct fuse_file_info * /*fi*/, fuse_readdir_flags /*flags*/)
-> api_error {
return api_error::not_implemented;
}
#else
[[nodiscard]] virtual auto
readdir_impl(std::string /*api_path*/, void * /*buf*/,
fuse_fill_dir_t /*fuse_fill_dir*/, off_t /*offset*/,
struct fuse_file_info * /*fi*/) -> api_error {
return api_error::not_implemented;
}
#endif
[[nodiscard]] virtual auto release_impl(std::string /*api_path*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
virtual api_error releasedir_impl(std::string /*api_path*/, struct fuse_file_info * /*fi*/) {
[[nodiscard]] virtual auto releasedir_impl(std::string /*api_path*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
virtual api_error rename_impl(std::string /*from_api_path*/, std::string /*to_api_path*/) {
#if FUSE_USE_VERSION >= 30
[[nodiscard]] virtual auto rename_impl(std::string /*from_api_path*/,
std::string /*to_api_path*/,
unsigned int /*flags*/) -> api_error {
return api_error::not_implemented;
}
#else
[[nodiscard]] virtual auto rename_impl(std::string /*from_api_path*/,
std::string /*to_api_path*/)
-> api_error {
return api_error::not_implemented;
}
#endif
virtual api_error rmdir_impl(std::string /*api_path*/) { return api_error::not_implemented; }
[[nodiscard]] virtual auto rmdir_impl(std::string /*api_path*/) -> api_error {
return api_error::not_implemented;
}
#ifdef HAS_SETXATTR
#ifdef __APPLE__
virtual api_error getxattr_impl(std::string /*api_path*/, const char * /*name*/, char * /*value*/,
size_t /*size*/, uint32_t /*position*/,
int & /*attribute_size*/) {
[[nodiscard]] virtual auto
getxattr_impl(std::string /*api_path*/, const char * /*name*/,
char * /*value*/, size_t /*size*/, uint32_t /*position*/,
int & /*attribute_size*/) -> api_error {
return api_error::not_implemented;
}
#else // __APPLE__
virtual api_error getxattr_impl(std::string /*api_path*/, const char * /*name*/, char * /*value*/,
size_t /*size*/, int & /*attribute_size*/) {
[[nodiscard]] virtual auto
getxattr_impl(std::string /*api_path*/, const char * /*name*/,
char * /*value*/, size_t /*size*/, int & /*attribute_size*/)
-> api_error {
return api_error::not_implemented;
}
#endif // __APPLE__
virtual api_error listxattr_impl(std::string /*api_path*/, char * /*buffer*/, size_t /*size*/,
int & /*required_size*/, bool & /*return_size*/) {
[[nodiscard]] virtual auto
listxattr_impl(std::string /*api_path*/, char * /*buffer*/, size_t /*size*/,
int & /*required_size*/, bool & /*return_size*/) -> api_error {
return api_error::not_implemented;
}
virtual api_error removexattr_impl(std::string /*api_path*/, const char * /*name*/) {
[[nodiscard]] virtual auto removexattr_impl(std::string /*api_path*/,
const char * /*name*/)
-> api_error {
return api_error::not_implemented;
}
#ifdef __APPLE__
virtual api_error setxattr_impl(std::string /*api_path*/, const char * /*name*/,
const char * /*value*/, size_t /*size*/, int /*flags*/,
uint32_t /*position*/) {
[[nodiscard]] virtual auto setxattr_impl(std::string /*api_path*/,
const char * /*name*/,
const char * /*value*/,
size_t /*size*/, int /*flags*/,
uint32_t /*position*/) -> api_error {
return api_error::not_implemented;
}
#else // __APPLE__
virtual api_error setxattr_impl(std::string /*api_path*/, const char * /*name*/,
const char * /*value*/, size_t /*size*/, int /*flags*/) {
[[nodiscard]] virtual auto
setxattr_impl(std::string /*api_path*/, const char * /*name*/,
const char * /*value*/, size_t /*size*/, int /*flags*/)
-> api_error {
return api_error::not_implemented;
}
#endif // __APPLE__
#endif // HAS_SETXATTR
#ifdef __APPLE__
virtual api_error setattr_x_impl(std::string /*api_path*/, struct setattr_x * /*attr*/) {
[[nodiscard]] virtual auto setattr_x_impl(std::string /*api_path*/,
struct setattr_x * /*attr*/)
-> api_error {
return api_error::not_implemented;
}
virtual api_error setbkuptime_impl(std::string /*api_path*/,
const struct timespec * /*bkuptime*/) {
[[nodiscard]] virtual auto
setbkuptime_impl(std::string /*api_path*/,
const struct timespec * /*bkuptime*/) -> api_error {
return api_error::not_implemented;
}
virtual api_error setchgtime_impl(std::string /*api_path*/, const struct timespec * /*chgtime*/) {
[[nodiscard]] virtual auto
setchgtime_impl(std::string /*api_path*/, const struct timespec * /*chgtime*/)
-> api_error {
return api_error::not_implemented;
}
virtual api_error setcrtime_impl(std::string /*api_path*/, const struct timespec * /*crtime*/) {
[[nodiscard]] virtual auto setcrtime_impl(std::string /*api_path*/,
const struct timespec * /*crtime*/)
-> api_error {
return api_error::not_implemented;
}
virtual api_error setvolname_impl(const char * /*volname*/) { return api_error::not_implemented; }
[[nodiscard]] virtual auto setvolname_impl(const char * /*volname*/)
-> api_error {
return api_error::not_implemented;
}
virtual api_error statfs_x_impl(std::string /*api_path*/, struct statfs * /*stbuf*/) {
[[nodiscard]] virtual auto statfs_x_impl(std::string /*api_path*/,
struct statfs * /*stbuf*/)
-> api_error {
return api_error::not_implemented;
}
#else // __APPLE__
virtual api_error statfs_impl(std::string /*api_path*/, struct statvfs * /*stbuf*/) {
[[nodiscard]] virtual auto statfs_impl(std::string /*api_path*/,
struct statvfs * /*stbuf*/)
-> api_error {
return api_error::not_implemented;
}
#endif // __APPLE__
virtual api_error truncate_impl(std::string /*api_path*/, off_t /*size*/) {
#if FUSE_USE_VERSION >= 30
[[nodiscard]] virtual auto truncate_impl(std::string /*api_path*/,
off_t /*size*/,
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
#else
[[nodiscard]] virtual auto truncate_impl(std::string /*api_path*/,
off_t /*size*/) -> api_error {
return api_error::not_implemented;
}
#endif
[[nodiscard]] virtual auto unlink_impl(std::string /*api_path*/)
-> api_error {
return api_error::not_implemented;
}
virtual api_error unlink_impl(std::string /*api_path*/) { return api_error::not_implemented; }
virtual api_error utimens_impl(std::string /*api_path*/, const struct timespec /*tv*/[2]) {
#if FUSE_USE_VERSION >= 30
[[nodiscard]] virtual auto utimens_impl(std::string /*api_path*/,
const struct timespec /*tv*/[2],
struct fuse_file_info * /*fi*/)
-> api_error {
return api_error::not_implemented;
}
#else
[[nodiscard]] virtual auto utimens_impl(std::string /*api_path*/,
const struct timespec /*tv*/[2])
-> api_error {
return api_error::not_implemented;
}
#endif
virtual api_error write_impl(std::string /*api_path*/, const char * /*buffer*/,
size_t /*write_size*/, off_t /*write_offset*/,
struct fuse_file_info * /*fi*/, std::size_t & /*bytes_written*/) {
[[nodiscard]] virtual auto
write_impl(std::string /*api_path*/, const char * /*buffer*/,
size_t /*write_size*/, off_t /*write_offset*/,
struct fuse_file_info * /*fi*/, std::size_t & /*bytes_written*/)
-> api_error {
return api_error::not_implemented;
}
protected:
virtual void notify_fuse_args_parsed(const std::vector<std::string> & /*args*/) {}
virtual void notify_fuse_args_parsed(const std::vector<std::string> &args);
virtual void notify_fuse_main_exit(int & /*ret*/) {}
virtual int parse_args(std::vector<std::string> &args);
[[nodiscard]] virtual auto parse_args(std::vector<std::string> &args) -> int;
#ifdef __APPLE__
api_error parse_xattr_parameters(const char *name, const uint32_t &position,
std::string &attribute_name, const std::string &api_path);
#else
api_error parse_xattr_parameters(const char *name, std::string &attribute_name,
const std::string &api_path);
#endif
#ifdef __APPLE__
api_error parse_xattr_parameters(const char *name, const char *value, size_t size,
const uint32_t &position, std::string &attribute_name,
const std::string &api_path);
#else
api_error parse_xattr_parameters(const char *name, const char *value, size_t size,
std::string &attribute_name, const std::string &api_path);
#endif
virtual int shutdown();
virtual void shutdown();
public:
static void display_options(int argc, char *argv[]);
static void display_version_information(int argc, char *argv[]);
api_error check_parent_access(const std::string &api_path, int mask) const override;
static auto unmount(const std::string &mount_location) -> int;
std::string get_mount_location() const { return mount_location_; }
[[nodiscard]] auto get_mount_location() const -> std::string {
return mount_location_;
}
int mount(std::vector<std::string> args);
[[nodiscard]] auto mount(std::vector<std::string> args) -> int;
};
} // namespace repertory

View File

@@ -1,35 +1,36 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_FUSE_FUSE_DRIVE_HPP_
#define INCLUDE_DRIVES_FUSE_FUSE_DRIVE_HPP_
#ifndef _WIN32
#include "common.hpp"
#include "drives/fuse/fuse_base.hpp"
#include "drives/open_file_table.hpp"
#include "drives/fuse/fuse_drive_base.hpp"
#include "file_manager/file_manager.hpp"
namespace repertory {
class i_provider;
class app_config;
class console_consumer;
class directory_cache;
class download_manager;
class eviction;
class full_server;
class lock_data;
@@ -38,7 +39,7 @@ namespace remote_fuse {
class remote_server;
}
class fuse_drive final : public fuse_base {
class fuse_drive final : public fuse_drive_base {
public:
fuse_drive(app_config &config, lock_data &lock_data, i_provider &provider);
@@ -50,166 +51,276 @@ private:
std::shared_ptr<console_consumer> console_consumer_;
std::shared_ptr<directory_cache> directory_cache_;
std::shared_ptr<download_manager> download_manager_;
std::shared_ptr<eviction> eviction_;
std::shared_ptr<file_manager> fm_;
std::shared_ptr<logging_consumer> logging_consumer_;
std::shared_ptr<open_file_table<open_file_data>> oft_;
std::shared_ptr<remote_fuse::remote_server> remote_server_;
std::shared_ptr<full_server> server_;
bool was_mounted_ = false;
private:
void update_accessed_time(const std::string &api_path);
protected:
#ifdef __APPLE__
api_error chflags_impl(std::string api_path, uint32_t flags) override;
[[nodiscard]] auto chflags_impl(std::string api_path, uint32_t flags)
-> api_error override;
#endif // __APPLE__
api_error chmod_impl(std::string api_path, mode_t mode) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode,
struct fuse_file_info *fi)
-> api_error override;
#else
[[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode)
-> api_error override;
#endif
api_error chown_impl(std::string api_path, uid_t uid, gid_t gid) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid,
struct fuse_file_info *fi)
-> api_error override;
#else
[[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid)
-> api_error override;
#endif
api_error create_impl(std::string api_path, mode_t mode, struct fuse_file_info *fi) override;
[[nodiscard]] auto create_impl(std::string api_path, mode_t mode,
struct fuse_file_info *fi)
-> api_error override;
void destroy_impl(void *ptr) override;
api_error fallocate_impl(std::string api_path, int mode, off_t offset, off_t length,
struct fuse_file_info *fi) override;
[[nodiscard]] auto fallocate_impl(std::string api_path, int mode,
off_t offset, off_t length,
struct fuse_file_info *fi)
-> api_error override;
api_error fgetattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info *fi) override;
[[nodiscard]] auto fgetattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info *fi)
-> api_error override;
#ifdef __APPLE__
api_error fsetattr_x_impl(std::string api_path, struct setattr_x *attr,
struct fuse_file_info *fi) override;
[[nodiscard]] auto fsetattr_x_impl(std::string api_path,
struct setattr_x *attr,
struct fuse_file_info *fi)
-> api_error override;
#endif // __APPLE__
api_error fsync_impl(std::string api_path, int datasync, struct fuse_file_info *fi) override;
[[nodiscard]] auto fsync_impl(std::string api_path, int datasync,
struct fuse_file_info *fi)
-> api_error override;
api_error ftruncate_impl(std::string api_path, off_t size, struct fuse_file_info *fi) override;
#if FUSE_USE_VERSION < 30
[[nodiscard]] auto ftruncate_impl(std::string api_path, off_t size,
struct fuse_file_info *fi)
-> api_error override;
#endif
api_error getattr_impl(std::string api_path, struct stat *st) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto getattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info *fi)
-> api_error override;
#else
[[nodiscard]] auto getattr_impl(std::string api_path, struct stat *st)
-> api_error override;
#endif
#ifdef __APPLE__
api_error getxtimes_impl(std::string api_path, struct timespec *bkuptime,
struct timespec *crtime) override;
[[nodiscard]] auto getxtimes_impl(std::string api_path,
struct timespec *bkuptime,
struct timespec *crtime)
-> api_error override;
#endif // __APPLE__
void *init_impl(struct fuse_conn_info *conn) override;
#if FUSE_USE_VERSION >= 30
auto init_impl(struct fuse_conn_info *conn, struct fuse_config *cfg)
-> void * override;
#else
auto init_impl(struct fuse_conn_info *conn) -> void * override;
#endif
api_error mkdir_impl(std::string api_path, mode_t mode) override;
[[nodiscard]] auto mkdir_impl(std::string api_path, mode_t mode)
-> api_error override;
api_error open_impl(std::string api_path, struct fuse_file_info *fi) override;
void notify_fuse_main_exit(int &ret) override;
api_error opendir_impl(std::string api_path, struct fuse_file_info *fi) override;
[[nodiscard]] auto open_impl(std::string api_path, struct fuse_file_info *fi)
-> api_error override;
api_error read_impl(std::string api_path, char *buffer, size_t read_size, off_t read_offset,
struct fuse_file_info *fi, std::size_t &bytes_read) override;
[[nodiscard]] auto opendir_impl(std::string api_path,
struct fuse_file_info *fi)
-> api_error override;
api_error readdir_impl(std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir,
off_t offset, struct fuse_file_info *fi) override;
[[nodiscard]] auto read_impl(std::string api_path, char *buffer,
size_t read_size, off_t read_offset,
struct fuse_file_info *fi,
std::size_t &bytes_read) -> api_error override;
api_error release_impl(std::string api_path, struct fuse_file_info *fi) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto readdir_impl(std::string api_path, void *buf,
fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi,
fuse_readdir_flags flags)
-> api_error override;
#else
[[nodiscard]] auto readdir_impl(std::string api_path, void *buf,
fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi)
-> api_error override;
#endif
api_error releasedir_impl(std::string api_path, struct fuse_file_info *fi) override;
[[nodiscard]] auto release_impl(std::string api_path,
struct fuse_file_info *fi)
-> api_error override;
api_error rename_impl(std::string from_api_path, std::string to_api_path) override;
[[nodiscard]] auto releasedir_impl(std::string api_path,
struct fuse_file_info *fi)
-> api_error override;
api_error rmdir_impl(std::string api_path) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto rename_impl(std::string from_api_path,
std::string to_api_path, unsigned int flags)
-> api_error override;
#else
[[nodiscard]] auto rename_impl(std::string from_api_path,
std::string to_api_path) -> api_error override;
#endif
[[nodiscard]] auto rmdir_impl(std::string api_path) -> api_error override;
#ifdef HAS_SETXATTR
api_error getxattr_common(std::string api_path, const char *name, char *value, size_t size,
int &attribute_size, uint32_t *position);
[[nodiscard]] auto getxattr_common(std::string api_path, const char *name,
char *value, size_t size,
int &attribute_size, uint32_t *position)
-> api_error;
#ifdef __APPLE__
api_error getxattr_impl(std::string api_path, const char *name, char *value, size_t size,
uint32_t position, int &attribute_size) override;
[[nodiscard]] auto getxattr_impl(std::string api_path, const char *name,
char *value, size_t size,
[[nodiscard]] uint32_t position,
int &attribute_size) -> api_error override;
#else // __APPLE__
api_error getxattr_impl(std::string api_path, const char *name, char *value, size_t size,
int &attribute_size) override;
[[nodiscard]] auto getxattr_impl(std::string api_path, const char *name,
char *value, size_t size,
int &attribute_size) -> api_error override;
#endif // __APPLE__
api_error listxattr_impl(std::string api_path, char *buffer, size_t size, int &required_size,
bool &return_size) override;
[[nodiscard]] auto listxattr_impl(std::string api_path, char *buffer,
size_t size, int &required_size,
bool &return_size) -> api_error override;
api_error removexattr_impl(std::string api_path, const char *name) override;
[[nodiscard]] auto removexattr_impl(std::string api_path, const char *name)
-> api_error override;
#ifdef __APPLE__
api_error setxattr_impl(std::string api_path, const char *name, const char *value, size_t size,
int flags, uint32_t position) override;
[[nodiscard]] auto setxattr_impl(std::string api_path, const char *name,
const char *value, size_t size, int flags,
uint32_t position) -> api_error override;
#else // __APPLE__
api_error setxattr_impl(std::string api_path, const char *name, const char *value, size_t size,
int flags) override;
[[nodiscard]] auto setxattr_impl(std::string api_path, const char *name,
const char *value, size_t size, int flags)
-> api_error override;
#endif // __APPLE__
#endif // HAS_SETXATTR
#ifdef __APPLE__
api_error setattr_x_impl(std::string api_path, struct setattr_x *attr) override;
[[nodiscard]] auto setattr_x_impl(std::string api_path,
struct setattr_x *attr)
-> api_error override;
api_error setbkuptime_impl(std::string api_path, const struct timespec *bkuptime) override;
[[nodiscard]] auto setbkuptime_impl(std::string api_path,
const struct timespec *bkuptime)
-> api_error override;
api_error setchgtime_impl(std::string api_path, const struct timespec *chgtime) override;
[[nodiscard]] auto setchgtime_impl(std::string api_path,
const struct timespec *chgtime)
-> api_error override;
api_error setcrtime_impl(std::string api_path, const struct timespec *crtime) override;
[[nodiscard]] auto setcrtime_impl(std::string api_path,
const struct timespec *crtime)
-> api_error override;
api_error setvolname_impl(const char *volname) override;
[[nodiscard]] auto setvolname_impl(const char *volname) -> api_error override;
api_error statfs_x_impl(std::string api_path, struct statfs *stbuf) override;
[[nodiscard]] auto statfs_x_impl(std::string api_path, struct statfs *stbuf)
-> api_error override;
#else // __APPLE__
api_error statfs_impl(std::string api_path, struct statvfs *stbuf) override;
[[nodiscard]] auto statfs_impl(std::string api_path, struct statvfs *stbuf)
-> api_error override;
#endif // __APPLE__
api_error truncate_impl(std::string api_path, off_t size) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto truncate_impl(std::string api_path, off_t size,
struct fuse_file_info *fi)
-> api_error override;
#else
[[nodiscard]] auto truncate_impl(std::string api_path, off_t size)
-> api_error override;
#endif
api_error unlink_impl(std::string api_path) override;
[[nodiscard]] auto unlink_impl(std::string api_path) -> api_error override;
api_error utimens_impl(std::string api_path, const struct timespec tv[2]) override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto utimens_impl(std::string api_path,
const struct timespec tv[2],
struct fuse_file_info *fi)
-> api_error override;
#else
[[nodiscard]] auto utimens_impl(std::string api_path,
const struct timespec tv[2])
-> api_error override;
#endif
api_error write_impl(std::string api_path, const char *buffer, size_t write_size,
off_t write_offset, struct fuse_file_info *fi,
std::size_t &bytes_written) override;
protected:
void notify_fuse_args_parsed(const std::vector<std::string> &args) override;
void notify_fuse_main_exit(int &ret) override;
int shutdown() override;
void update_accessed_time(const std::string &api_path);
[[nodiscard]] auto write_impl(std::string api_path, const char *buffer,
size_t write_size, off_t write_offset,
struct fuse_file_info *fi,
std::size_t &bytes_written)
-> api_error override;
public:
std::uint64_t get_directory_item_count(const std::string &api_path) const override;
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t override;
directory_item_list get_directory_items(const std::string &api_path) const override;
[[nodiscard]] auto get_directory_items(const std::string &api_path) const
-> directory_item_list override;
std::uint64_t get_file_size(const std::string &api_path) const override;
[[nodiscard]] auto get_file_size(const std::string &api_path) const
-> std::uint64_t override;
api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const override;
[[nodiscard]] auto get_item_meta(const std::string &api_path,
api_meta_map &meta) const
-> api_error override;
api_error get_item_meta(const std::string &api_path, const std::string &name,
std::string &value) const override;
[[nodiscard]] auto get_item_meta(const std::string &api_path,
const std::string &name,
std::string &value) const
-> api_error override;
std::uint64_t get_total_drive_space() const override;
[[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override;
std::uint64_t get_total_item_count() const override;
[[nodiscard]] auto get_total_item_count() const -> std::uint64_t override;
std::uint64_t get_used_drive_space() const override;
[[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override;
void get_volume_info(UINT64 &total_size, UINT64 &free_size,
std::string &volume_label) const override;
bool is_processing(const std::string &api_path) const override;
[[nodiscard]] auto is_processing(const std::string &api_path) const
-> bool override;
void populate_stat(const directory_item &di, struct stat &st) const override;
int rename_directory(const std::string &from_api_path, const std::string &to_api_path) override;
[[nodiscard]] auto rename_directory(const std::string &from_api_path,
const std::string &to_api_path)
-> int override;
int rename_file(const std::string &from_api_path, const std::string &to_api_path,
const bool &overwrite) override;
[[nodiscard]] auto rename_file(const std::string &from_api_path,
const std::string &to_api_path, bool overwrite)
-> int override;
void set_item_meta(const std::string &api_path, const std::string &key,
const std::string &value) override;
void update_directory_item(directory_item &di) const override;
};
} // namespace repertory

View File

@@ -0,0 +1,137 @@
/*
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_FUSE_FUSE_DRIVE_BASE_HPP_
#define INCLUDE_DRIVES_FUSE_FUSE_DRIVE_BASE_HPP_
#ifndef _WIN32
#include "drives/fuse/fuse_base.hpp"
#include "drives/fuse/i_fuse_drive.hpp"
namespace repertory {
class app_config;
class i_provider;
class fuse_drive_base : public fuse_base, public i_fuse_drive {
public:
explicit fuse_drive_base(app_config &config) : fuse_base(config) {}
~fuse_drive_base() override = default;
protected:
[[nodiscard]] auto access_impl(std::string api_path, int mask)
-> api_error override;
protected:
[[nodiscard]] auto check_access(const std::string &api_path, int mask) const
-> api_error;
[[nodiscard]] auto
check_and_perform(const std::string &api_path, int parent_mask,
const std::function<api_error(api_meta_map &meta)> &action)
-> api_error;
[[nodiscard]] auto get_current_gid() const -> gid_t;
[[nodiscard]] auto get_current_uid() const -> uid_t;
[[nodiscard]] auto get_effective_gid() const -> gid_t;
[[nodiscard]] auto get_effective_uid() const -> uid_t;
[[nodiscard]] static auto check_open_flags(int flags, int mask,
const api_error &fail_error)
-> api_error;
[[nodiscard]] auto check_owner(const api_meta_map &meta) const -> api_error;
[[nodiscard]] static auto check_readable(int flags,
const api_error &fail_error)
-> api_error;
[[nodiscard]] static auto check_writeable(int flags,
const api_error &fail_error)
-> api_error;
#ifdef __APPLE__
[[nodiscard]] static auto get_flags_from_meta(const api_meta_map &meta)
-> __uint32_t;
#endif // __APPLE__
[[nodiscard]] static auto get_gid_from_meta(const api_meta_map &meta)
-> gid_t;
[[nodiscard]] static auto get_mode_from_meta(const api_meta_map &meta)
-> mode_t;
static void get_timespec_from_meta(const api_meta_map &meta,
const std::string &name,
struct timespec &ts);
[[nodiscard]] static auto get_uid_from_meta(const api_meta_map &meta)
-> uid_t;
#ifdef __APPLE__
[[nodiscard]] auto parse_xattr_parameters(const char *name,
const uint32_t &position,
std::string &attribute_name,
const std::string &api_path)
-> api_error;
#else
[[nodiscard]] auto parse_xattr_parameters(const char *name,
std::string &attribute_name,
const std::string &api_path)
-> api_error;
#endif
#ifdef __APPLE__
[[nodiscard]] auto
parse_xattr_parameters(const char *name, const char *value, size_t size,
const uint32_t &position, std::string &attribute_name,
const std::string &api_path) -> api_error;
#else
[[nodiscard]] auto parse_xattr_parameters(const char *name, const char *value,
size_t size,
std::string &attribute_name,
const std::string &api_path)
-> api_error;
#endif
static void populate_stat(const std::string &api_path,
std::uint64_t size_or_count,
const api_meta_map &meta, bool directory,
i_provider &provider, struct stat *st);
static void set_timespec_from_meta(const api_meta_map &meta,
const std::string &name,
struct timespec &ts);
public:
[[nodiscard]] auto check_owner(const std::string &api_path) const
-> api_error override;
[[nodiscard]] auto check_parent_access(const std::string &api_path,
int mask) const -> api_error override;
};
} // namespace repertory
#endif // _WIN32
#endif // INCLUDE_DRIVES_FUSE_FUSE_DRIVE_BASE_HPP_

View File

@@ -1,26 +1,28 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_FUSE_I_FUSE_DRIVE_HPP_
#define INCLUDE_DRIVES_FUSE_I_FUSE_DRIVE_HPP_
#ifndef _WIN32
#include "common.hpp"
#include "types/repertory.hpp"
namespace repertory {
@@ -28,42 +30,59 @@ class i_fuse_drive {
INTERFACE_SETUP(i_fuse_drive);
public:
virtual api_error check_parent_access(const std::string &api_path, int mask) const = 0;
[[nodiscard]] virtual auto check_owner(const std::string &api_path) const
-> api_error = 0;
virtual std::uint64_t get_directory_item_count(const std::string &api_path) const = 0;
[[nodiscard]] virtual auto check_parent_access(const std::string &api_path,
int mask) const
-> api_error = 0;
virtual directory_item_list get_directory_items(const std::string &api_path) const = 0;
[[nodiscard]] virtual auto
get_directory_item_count(const std::string &api_path) const
-> std::uint64_t = 0;
virtual std::uint64_t get_file_size(const std::string &api_path) const = 0;
[[nodiscard]] virtual auto
get_directory_items(const std::string &api_path) const
-> directory_item_list = 0;
virtual api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const = 0;
[[nodiscard]] virtual auto get_file_size(const std::string &api_path) const
-> std::uint64_t = 0;
virtual api_error get_item_meta(const std::string &api_path, const std::string &name,
std::string &value) const = 0;
[[nodiscard]] virtual auto get_item_meta(const std::string &api_path,
api_meta_map &meta) const
-> api_error = 0;
virtual std::uint64_t get_total_drive_space() const = 0;
[[nodiscard]] virtual auto get_item_meta(const std::string &api_path,
const std::string &name,
std::string &value) const
-> api_error = 0;
virtual std::uint64_t get_total_item_count() const = 0;
[[nodiscard]] virtual auto get_total_drive_space() const -> std::uint64_t = 0;
virtual std::uint64_t get_used_drive_space() const = 0;
[[nodiscard]] virtual auto get_total_item_count() const -> std::uint64_t = 0;
[[nodiscard]] virtual auto get_used_drive_space() const -> std::uint64_t = 0;
virtual void get_volume_info(UINT64 &total_size, UINT64 &free_size,
std::string &volume_label) const = 0;
virtual bool is_processing(const std::string &api_path) const = 0;
[[nodiscard]] virtual auto is_processing(const std::string &api_path) const
-> bool = 0;
virtual void populate_stat(const directory_item &di, struct stat &st) const = 0;
virtual void populate_stat(const directory_item &di,
struct stat &st) const = 0;
virtual int rename_directory(const std::string &from_api_path,
const std::string &to_api_path) = 0;
[[nodiscard]] virtual auto rename_directory(const std::string &from_api_path,
const std::string &to_api_path)
-> int = 0;
virtual int rename_file(const std::string &from_api_path, const std::string &to_api_path,
const bool &overwrite) = 0;
[[nodiscard]] virtual auto rename_file(const std::string &from_api_path,
const std::string &to_api_path,
bool overwrite) -> int = 0;
virtual void set_item_meta(const std::string &api_path, const std::string &key,
virtual void set_item_meta(const std::string &api_path,
const std::string &key,
const std::string &value) = 0;
virtual void update_directory_item(directory_item &di) const = 0;
};
} // namespace repertory

View File

@@ -1,25 +1,27 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_FUSE_REMOTEFUSE_I_REMOTE_INSTANCE_HPP_
#define INCLUDE_DRIVES_FUSE_REMOTEFUSE_I_REMOTE_INSTANCE_HPP_
#include "common.hpp"
#include "drives/remote/i_remote_json.hpp"
#include "types/remote.hpp"
@@ -28,124 +30,179 @@ class i_remote_instance : public virtual i_remote_json {
INTERFACE_SETUP(i_remote_instance);
public:
virtual packet::error_type fuse_access(const char *path, const std::int32_t &mask) = 0;
[[nodiscard]] virtual auto fuse_access(const char *path,
const std::int32_t &mask)
-> packet::error_type = 0;
virtual packet::error_type fuse_chflags(const char *path, const std::uint32_t &flags) = 0;
[[nodiscard]] virtual auto fuse_chflags(const char *path, std::uint32_t flags)
-> packet::error_type = 0;
virtual packet::error_type fuse_chmod(const char *path, const remote::file_mode &mode) = 0;
[[nodiscard]] virtual auto fuse_chmod(const char *path,
const remote::file_mode &mode)
-> packet::error_type = 0;
virtual packet::error_type fuse_chown(const char *path, const remote::user_id &uid,
const remote::group_id &gid) = 0;
[[nodiscard]] virtual auto fuse_chown(const char *path,
const remote::user_id &uid,
const remote::group_id &gid)
-> packet::error_type = 0;
virtual packet::error_type fuse_create(const char *path, const remote::file_mode &mode,
const remote::open_flags &flags,
remote::file_handle &handle) = 0;
virtual packet::error_type fuse_destroy() = 0;
[[nodiscard]] virtual auto
fuse_create(const char *path, const remote::file_mode &mode,
const remote::open_flags &flags, remote::file_handle &handle)
-> packet::error_type = 0;
[[nodiscard]] virtual auto fuse_destroy() -> packet::error_type = 0;
/*virtual packet::error_type fuse_fallocate(const char *path, const std::int32_t &mode,
const remote::file_offset &offset,
const remote::file_offset &length,
const remote::file_offset &length,
const remote::file_handle &handle) = 0;*/
/*[[nodiscard]] virtual packet::error_type fuse_fallocate(const char *path,
const std::int32_t &mode, const remote::file_offset &offset, const
remote::file_offset &length, const remote::file_offset &length, const
remote::file_handle &handle) = 0;*/
virtual packet::error_type fuse_fgetattr(const char *path, remote::stat &st, bool &directory,
const remote::file_handle &handle) = 0;
[[nodiscard]] virtual auto fuse_fgetattr(const char *path, remote::stat &st,
bool &directory,
const remote::file_handle &handle)
-> packet::error_type = 0;
virtual packet::error_type fuse_fsetattr_x(const char *path, const remote::setattr_x &attr,
const remote::file_handle &handle) = 0;
[[nodiscard]] virtual auto fuse_fsetattr_x(const char *path,
const remote::setattr_x &attr,
const remote::file_handle &handle)
-> packet::error_type = 0;
virtual packet::error_type fuse_fsync(const char *path, const std::int32_t &datasync,
const remote::file_handle &handle) = 0;
[[nodiscard]] virtual auto fuse_fsync(const char *path,
const std::int32_t &datasync,
const remote::file_handle &handle)
-> packet::error_type = 0;
virtual packet::error_type fuse_ftruncate(const char *path, const remote::file_offset &size,
const remote::file_handle &handle) = 0;
[[nodiscard]] virtual auto fuse_ftruncate(const char *path,
const remote::file_offset &size,
const remote::file_handle &handle)
-> packet::error_type = 0;
virtual packet::error_type fuse_getattr(const char *path, remote::stat &st, bool &directory) = 0;
[[nodiscard]] virtual auto fuse_getattr(const char *path, remote::stat &st,
bool &directory)
-> packet::error_type = 0;
/*virtual packet::error_type fuse_getxattr(const char *path, const char *name, char *value,
const remote::file_size &size) = 0;
/*[[nodiscard]] virtual packet::error_type fuse_getxattr(const char *path,
const char *name, char *value, const remote::file_size &size) = 0;
virtual packet::error_type fuse_getxattrOSX(const char *path, const char *name, char *value,
const remote::file_size &size,
const std::uint32_t &position) = 0;*/
[[nodiscard]] virtual packet::error_type fuse_getxattrOSX(const char *path,
const char *name, char *value, const remote::file_size &size, std::uint32_t
position) = 0;*/
virtual packet::error_type fuse_getxtimes(const char *path, remote::file_time &bkuptime,
remote::file_time &crtime) = 0;
[[nodiscard]] virtual auto fuse_getxtimes(const char *path,
remote::file_time &bkuptime,
remote::file_time &crtime)
-> packet::error_type = 0;
virtual packet::error_type fuse_init() = 0;
[[nodiscard]] virtual auto fuse_init() -> packet::error_type = 0;
/*virtual packet::error_type fuse_listxattr(const char *path, char *buffer,
const remote::file_size &size) = 0;*/
[[nodiscard]] /*virtual packet::error_type fuse_listxattr(const char *path,
char *buffer, const remote::file_size &size) = 0;*/
virtual packet::error_type fuse_mkdir(const char *path, const remote::file_mode &mode) = 0;
[[nodiscard]] virtual auto
fuse_mkdir(const char *path, const remote::file_mode &mode)
-> packet::error_type = 0;
virtual packet::error_type fuse_open(const char *path, const remote::open_flags &flags,
remote::file_handle &handle) = 0;
[[nodiscard]] virtual auto fuse_open(const char *path,
const remote::open_flags &flags,
remote::file_handle &handle)
-> packet::error_type = 0;
virtual packet::error_type fuse_opendir(const char *path, remote::file_handle &handle) = 0;
[[nodiscard]] virtual auto fuse_opendir(const char *path,
remote::file_handle &handle)
-> packet::error_type = 0;
virtual packet::error_type fuse_read(const char *path, char *buffer,
[[nodiscard]] virtual auto fuse_read(const char *path, char *buffer,
const remote::file_size &readSize,
const remote::file_offset &readOffset,
const remote::file_handle &handle) = 0;
const remote::file_handle &handle)
-> packet::error_type = 0;
virtual packet::error_type fuse_readdir(const char *path, const remote::file_offset &offset,
const remote::file_handle &handle, std::string &itemPath) = 0;
[[nodiscard]] virtual auto
fuse_readdir(const char *path, const remote::file_offset &offset,
const remote::file_handle &handle, std::string &itemPath)
-> packet::error_type = 0;
virtual packet::error_type fuse_release(const char *path, const remote::file_handle &handle) = 0;
[[nodiscard]] virtual auto fuse_release(const char *path,
const remote::file_handle &handle)
-> packet::error_type = 0;
virtual packet::error_type fuse_releasedir(const char *path, const remote::file_handle &handle) = 0;
[[nodiscard]] virtual auto fuse_releasedir(const char *path,
const remote::file_handle &handle)
-> packet::error_type = 0;
// virtual packet::error_type fuse_removexattr(const char *path, const char *name) = 0;
//[[nodiscard]] virtual packet::error_type fuse_removexattr(const char *path,
// const char *name) =
// 0;
virtual packet::error_type fuse_rename(const char *from, const char *to) = 0;
[[nodiscard]] virtual auto fuse_rename(const char *from, const char *to)
-> packet::error_type = 0;
virtual packet::error_type fuse_rmdir(const char *path) = 0;
[[nodiscard]] virtual auto fuse_rmdir(const char *path)
-> packet::error_type = 0;
virtual packet::error_type fuse_setattr_x(const char *path, remote::setattr_x &attr) = 0;
[[nodiscard]] virtual auto fuse_setattr_x(const char *path,
remote::setattr_x &attr)
-> packet::error_type = 0;
virtual packet::error_type fuse_setbkuptime(const char *path, const remote::file_time &bkuptime) = 0;
[[nodiscard]] virtual auto fuse_setbkuptime(const char *path,
const remote::file_time &bkuptime)
-> packet::error_type = 0;
virtual packet::error_type fuse_setchgtime(const char *path, const remote::file_time &chgtime) = 0;
[[nodiscard]] virtual auto fuse_setchgtime(const char *path,
const remote::file_time &chgtime)
-> packet::error_type = 0;
virtual packet::error_type fuse_setcrtime(const char *path, const remote::file_time &crtime) = 0;
[[nodiscard]] virtual auto fuse_setcrtime(const char *path,
const remote::file_time &crtime)
-> packet::error_type = 0;
virtual packet::error_type fuse_setvolname(const char *volname) = 0;
[[nodiscard]] virtual auto fuse_setvolname(const char *volname)
-> packet::error_type = 0;
/*virtual packet::error_type fuse_setxattr(const char *path, const char *name,
const char *value, const remote::file_size &size,
const std::int32_t &flags) = 0;
virtual packet::error_type fuse_setxattr_osx(const char *path, const char *name,
const char *value, const remote::file_size &size,
const std::int32_t &flags,
const std::uint32_t &position) = 0;*/
/*[[nodiscard]] virtual packet::error_type fuse_setxattr(const char *path,
const char *name, const char *value, const remote::file_size &size, const
std::int32_t &flags) = 0;
[[nodiscard]] virtual packet::error_type fuse_setxattr_osx(const char *path,
const char *name, const char *value, const remote::file_size &size, const
std::int32_t &flags, std::uint32_t position) = 0;*/
virtual packet::error_type fuse_statfs(const char *path, const std::uint64_t &frsize,
remote::statfs &st) = 0;
[[nodiscard]] virtual auto fuse_statfs(const char *path, std::uint64_t frsize,
remote::statfs &st)
-> packet::error_type = 0;
virtual packet::error_type fuse_statfs_x(const char *path, const std::uint64_t &bsize,
remote::statfs_x &st) = 0;
[[nodiscard]] virtual auto
fuse_statfs_x(const char *path, std::uint64_t bsize, remote::statfs_x &st)
-> packet::error_type = 0;
virtual packet::error_type fuse_truncate(const char *path, const remote::file_offset &size) = 0;
[[nodiscard]] virtual auto fuse_truncate(const char *path,
const remote::file_offset &size)
-> packet::error_type = 0;
virtual packet::error_type fuse_unlink(const char *path) = 0;
[[nodiscard]] virtual auto fuse_unlink(const char *path)
-> packet::error_type = 0;
virtual packet::error_type fuse_utimens(const char *path, const remote::file_time *tv,
const std::uint64_t &op0, const std::uint64_t &op1) = 0;
[[nodiscard]] virtual auto fuse_utimens(const char *path,
const remote::file_time *tv,
std::uint64_t op0, std::uint64_t op1)
-> packet::error_type = 0;
virtual packet::error_type fuse_write(const char *path, const char *buffer,
[[nodiscard]] virtual auto fuse_write(const char *path, const char *buffer,
const remote::file_size &writeSize,
const remote::file_offset &writeOffset,
const remote::file_handle &handle) = 0;
const remote::file_handle &handle)
-> packet::error_type = 0;
virtual packet::error_type fuse_write_base64(const char *path, const char *buffer,
const remote::file_size &writeSize,
const remote::file_offset &writeOffset,
const remote::file_handle &handle) = 0;
[[nodiscard]] virtual auto fuse_write_base64(
const char *path, const char *buffer, const remote::file_size &writeSize,
const remote::file_offset &writeOffset, const remote::file_handle &handle)
-> packet::error_type = 0;
virtual void set_fuse_uid_gid(const remote::user_id &uid, const remote::group_id &gid) = 0;
virtual void set_fuse_uid_gid(const remote::user_id &uid,
const remote::group_id &gid) = 0;
};
typedef std::function<std::unique_ptr<i_remote_instance>()> remote_instance_factory;
using remote_instance_factory =
std::function<std::unique_ptr<i_remote_instance>()>;
} // namespace repertory::remote_fuse
#endif // INCLUDE_DRIVES_FUSE_REMOTEFUSE_I_REMOTE_INSTANCE_HPP_

View File

@@ -1,25 +1,27 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_CLIENT_HPP_
#define INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_CLIENT_HPP_
#include "common.hpp"
#include "comm/packet/packet_client.hpp"
#include "drives/fuse/remotefuse/i_remote_instance.hpp"
#include "events/event_system.hpp"
@@ -40,131 +42,183 @@ private:
remote::group_id gid_ = 0;
public:
packet::error_type fuse_access(const char *path, const std::int32_t &mask) override;
[[nodiscard]] auto fuse_access(const char *path, const std::int32_t &mask)
-> packet::error_type override;
packet::error_type fuse_chflags(const char *path, const std::uint32_t &flags) override;
[[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags)
-> packet::error_type override;
packet::error_type fuse_chmod(const char *path, const remote::file_mode &mode) override;
[[nodiscard]] auto fuse_chmod(const char *path, const remote::file_mode &mode)
-> packet::error_type override;
packet::error_type fuse_chown(const char *path, const remote::user_id &uid,
const remote::group_id &gid) override;
[[nodiscard]] auto fuse_chown(const char *path, const remote::user_id &uid,
const remote::group_id &gid)
-> packet::error_type override;
packet::error_type fuse_destroy() override;
[[nodiscard]] auto fuse_destroy() -> packet::error_type override;
/*packet::error_type fuse_fallocate(const char *path, const std::int32_t &mode,
const remote::file_offset &offset,
const remote::file_offset &length,
const remote::file_handle &handle) override ;*/
[[nodiscard]] /*packet::error_type fuse_fallocate(const char *path, const
std::int32_t &mode, const remote::file_offset &offset, const
remote::file_offset &length, const remote::file_handle
&handle) override ;*/
packet::error_type fuse_fgetattr(const char *path, remote::stat &st, bool &directory,
const remote::file_handle &handle) override;
[[nodiscard]] auto
fuse_fgetattr(const char *path, remote::stat &st, bool &directory,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_fsetattr_x(const char *path, const remote::setattr_x &attr,
const remote::file_handle &handle) override;
[[nodiscard]] auto fuse_fsetattr_x(const char *path,
const remote::setattr_x &attr,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_fsync(const char *path, const std::int32_t &datasync,
const remote::file_handle &handle) override;
[[nodiscard]] auto fuse_fsync(const char *path, const std::int32_t &datasync,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_ftruncate(const char *path, const remote::file_offset &size,
const remote::file_handle &handle) override;
[[nodiscard]] auto fuse_ftruncate(const char *path,
const remote::file_offset &size,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_getattr(const char *path, remote::stat &st, bool &directory) override;
[[nodiscard]] auto fuse_getattr(const char *path, remote::stat &st,
bool &directory)
-> packet::error_type override;
/*packet::error_type fuse_getxattr(const char *path, const char *name, char *value,
const remote::file_size &size) override ;
/*[[nodiscard]] packet::error_type fuse_getxattr(const char *path, const char
*name, char *value, const remote::file_size &size) override ;
packet::error_type fuse_getxattrOSX(const char *path, const char *name, char *value,
const remote::file_size &size,
const std::uint32_t &position) override ;*/
[[nodiscard]] packet::error_type fuse_getxattrOSX(const char *path, const char
*name, char *value, const remote::file_size &size, std::uint32_t position)
override ;*/
packet::error_type fuse_getxtimes(const char *path, remote::file_time &bkuptime,
remote::file_time &crtime) override;
[[nodiscard]] auto fuse_getxtimes(const char *path,
remote::file_time &bkuptime,
remote::file_time &crtime)
-> packet::error_type override;
packet::error_type fuse_init() override;
[[nodiscard]] auto fuse_init() -> packet::error_type override;
/*packet::error_type fuse_listxattr(const char *path, char *buffer,
const remote::file_size &size) override ;*/
/*[[nodiscard]] packet::error_type fuse_listxattr(const char *path, char
*buffer, const remote::file_size &size) override ;*/
packet::error_type fuse_mkdir(const char *path, const remote::file_mode &mode) override;
[[nodiscard]] auto fuse_mkdir(const char *path, const remote::file_mode &mode)
-> packet::error_type override;
packet::error_type fuse_opendir(const char *path, remote::file_handle &handle) override;
[[nodiscard]] auto fuse_opendir(const char *path, remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_create(const char *path, const remote::file_mode &mode,
const remote::open_flags &flags, remote::file_handle &handle) override;
[[nodiscard]] auto
fuse_create(const char *path, const remote::file_mode &mode,
const remote::open_flags &flags, remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_open(const char *path, const remote::open_flags &flags,
remote::file_handle &handle) override;
[[nodiscard]] auto fuse_open(const char *path,
const remote::open_flags &flags,
remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_read(const char *path, char *buffer, const remote::file_size &read_size,
[[nodiscard]] auto fuse_read(const char *path, char *buffer,
const remote::file_size &read_size,
const remote::file_offset &read_offset,
const remote::file_handle &handle) override;
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_rename(const char *from, const char *to) override;
[[nodiscard]] auto fuse_rename(const char *from, const char *to)
-> packet::error_type override;
packet::error_type fuse_readdir(const char *path, const remote::file_offset &offset,
const remote::file_handle &handle, std::string &item_path) override;
[[nodiscard]] auto
fuse_readdir(const char *path, const remote::file_offset &offset,
const remote::file_handle &handle, std::string &item_path)
-> packet::error_type override;
packet::error_type fuse_release(const char *path, const remote::file_handle &handle) override;
[[nodiscard]] auto fuse_release(const char *path,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_releasedir(const char *path, const remote::file_handle &handle) override;
[[nodiscard]] auto fuse_releasedir(const char *path,
const remote::file_handle &handle)
-> packet::error_type override;
/*packet::error_type fuse_removexattr(const char *path, const char *name) override ;*/
/*[[nodiscard]] packet::error_type fuse_removexattr(const char *path, const
* char *name) override
* ;*/
packet::error_type fuse_rmdir(const char *path) override;
[[nodiscard]] auto fuse_rmdir(const char *path)
-> packet::error_type override;
packet::error_type fuse_setattr_x(const char *path, remote::setattr_x &attr) override;
[[nodiscard]] auto fuse_setattr_x(const char *path, remote::setattr_x &attr)
-> packet::error_type override;
packet::error_type fuse_setbkuptime(const char *path, const remote::file_time &bkuptime) override;
[[nodiscard]] auto fuse_setbkuptime(const char *path,
const remote::file_time &bkuptime)
-> packet::error_type override;
packet::error_type fuse_setchgtime(const char *path, const remote::file_time &chgtime) override;
[[nodiscard]] auto fuse_setchgtime(const char *path,
const remote::file_time &chgtime)
-> packet::error_type override;
packet::error_type fuse_setcrtime(const char *path, const remote::file_time &crtime) override;
[[nodiscard]] auto fuse_setcrtime(const char *path,
const remote::file_time &crtime)
-> packet::error_type override;
packet::error_type fuse_setvolname(const char *volname) override;
[[nodiscard]] auto fuse_setvolname(const char *volname)
-> packet::error_type override;
/*packet::error_type fuse_setxattr(const char *path, const char *name, const char *value,
const remote::file_size &size,
const std::int32_t &flags) override ;
[[nodiscard]] /*packet::error_type fuse_setxattr(const char *path, const char
*name, const char *value, const remote::file_size &size, const std::int32_t
&flags) override ;
packet::error_type fuse_setxattr_osx(const char *path, const char *name, const char *value,
const remote::file_size &size, const std::int32_t &flags,
const std::uint32_t &position) override ;*/
[[nodiscard]] packet::error_type fuse_setxattr_osx(const char *path, const
char *name, const char *value, const remote::file_size &size, const
std::int32_t &flags, std::uint32_t position) override ;*/
packet::error_type fuse_statfs(const char *path, const std::uint64_t &frsize,
remote::statfs &st) override;
[[nodiscard]] auto
fuse_statfs(const char *path, std::uint64_t frsize, remote::statfs &st)
-> packet::error_type override;
packet::error_type fuse_statfs_x(const char *path, const std::uint64_t &bsize,
remote::statfs_x &st) override;
[[nodiscard]] auto fuse_statfs_x(const char *path, std::uint64_t bsize,
remote::statfs_x &st)
-> packet::error_type override;
packet::error_type fuse_truncate(const char *path, const remote::file_offset &size) override;
[[nodiscard]] auto fuse_truncate(const char *path,
const remote::file_offset &size)
-> packet::error_type override;
packet::error_type fuse_unlink(const char *path) override;
[[nodiscard]] auto fuse_unlink(const char *path)
-> packet::error_type override;
packet::error_type fuse_utimens(const char *path, const remote::file_time *tv,
const std::uint64_t &op0, const std::uint64_t &op1) override;
[[nodiscard]] auto fuse_utimens(const char *path, const remote::file_time *tv,
std::uint64_t op0, std::uint64_t op1)
-> packet::error_type override;
packet::error_type fuse_write(const char *path, const char *buffer,
[[nodiscard]] auto fuse_write(const char *path, const char *buffer,
const remote::file_size &write_size,
const remote::file_offset &write_offset,
const remote::file_handle &handle) override;
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_write_base64(const char *path, const char *buffer,
[[nodiscard]] auto fuse_write_base64(const char *path, const char *buffer,
const remote::file_size &write_size,
const remote::file_offset &write_offset,
const remote::file_handle &handle) override;
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type json_create_directory_snapshot(const std::string &path,
json &json_data) override;
[[nodiscard]] auto json_create_directory_snapshot(const std::string &path,
json &json_data)
-> packet::error_type override;
packet::error_type json_read_directory_snapshot(const std::string &path,
const remote::file_handle &handle,
const std::uint32_t &page,
json &json_data) override;
[[nodiscard]] auto json_read_directory_snapshot(
const std::string &path, const remote::file_handle &handle,
std::uint32_t page, json &json_data) -> packet::error_type override;
packet::error_type json_release_directory_snapshot(const std::string &path,
const remote::file_handle &handle) override;
[[nodiscard]] auto
json_release_directory_snapshot(const std::string &path,
const remote::file_handle &handle)
-> packet::error_type override;
void set_fuse_uid_gid(const remote::user_id &uid, const remote::group_id &gid) override;
void set_fuse_uid_gid(const remote::user_id &uid,
const remote::group_id &gid) override;
};
} // namespace remote_fuse
} // namespace repertory

View File

@@ -1,26 +1,29 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE_HPP_
#define INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE_HPP_
#ifndef _WIN32
#include "common.hpp"
#include "drives/fuse/fuse_base.hpp"
#include "drives/fuse/remotefuse/i_remote_instance.hpp"
#include "events/event_system.hpp"
@@ -32,223 +35,206 @@ class lock_data;
class server;
namespace remote_fuse {
class remote_fuse_drive final {
E_CONSUMER();
class remote_fuse_drive final : public fuse_base {
public:
remote_fuse_drive(app_config &config, lock_data &lock, remote_instance_factory factory);
remote_fuse_drive(app_config &config, remote_instance_factory factory,
lock_data &lock)
: fuse_base(config), factory_(std::move(factory)), lock_data_(lock) {}
~remote_fuse_drive() { E_CONSUMER_RELEASE(); }
~remote_fuse_drive() override = default;
private:
app_config &config_;
lock_data &lock_;
remote_instance_factory factory_;
std::string mount_location_;
lock_data &lock_data_;
std::shared_ptr<console_consumer> console_consumer_;
std::shared_ptr<logging_consumer> logging_consumer_;
std::shared_ptr<i_remote_instance> remote_instance_;
std::shared_ptr<server> server_;
bool was_mounted_ = false;
private:
static void shutdown(std::string mount_location);
void populate_stat(const remote::stat &r, bool directory, struct stat &st);
private:
class remote_fuse_impl final {
public:
static app_config *config_;
static lock_data *lock_;
static std::string *mount_location_;
static remote_instance_factory *factory_;
static std::unique_ptr<console_consumer> console_consumer_;
static std::unique_ptr<logging_consumer> logging_consumer_;
static std::unique_ptr<i_remote_instance> remote_instance_;
static std::unique_ptr<server> server_;
static std::optional<gid_t> forced_gid_;
static std::optional<uid_t> forced_uid_;
static std::optional<mode_t> forced_umask_;
static bool console_enabled_;
static bool was_mounted_;
public:
static void tear_down(const int &ret);
private:
static void populate_stat(const remote::stat &r, const bool &directory, struct stat &st);
public:
static int repertory_access(const char *path, int mask);
protected:
[[nodiscard]] auto access_impl(std::string api_path, int mask)
-> api_error override;
#ifdef __APPLE__
static int repertory_chflags(const char *path, uint32_t flags);
#endif
[[nodiscard]] auto chflags_impl(std::string api_path, uint32_t flags)
-> api_error override;
#endif // __APPLE__
static int repertory_chmod(const char *path, mode_t mode);
static int repertory_chown(const char *path, uid_t uid, gid_t gid);
static int repertory_create(const char *path, mode_t mode, struct fuse_file_info *fi);
static void repertory_destroy(void * /*ptr*/);
/*static int repertory_fallocate(const char *path, int mode, off_t offset, off_t length,
struct fuse_file_info *fi) ;*/
static int repertory_fgetattr(const char *path, struct stat *st, struct fuse_file_info *fi);
#ifdef __APPLE__
static int repertory_fsetattr_x(const char *path, struct setattr_x *attr,
struct fuse_file_info *fi);
#endif
static int repertory_fsync(const char *path, int datasync, struct fuse_file_info *fi);
static int repertory_ftruncate(const char *path, off_t size, struct fuse_file_info *fi);
static int repertory_getattr(const char *path, struct stat *st);
#ifdef __APPLE__
static int repertory_getxtimes(const char *path, struct timespec *bkuptime,
struct timespec *crtime);
#endif
static void *repertory_init(struct fuse_conn_info *conn);
static int repertory_mkdir(const char *path, mode_t mode);
static int repertory_open(const char *path, struct fuse_file_info *fi);
static int repertory_opendir(const char *path, struct fuse_file_info *fi);
static int repertory_read(const char *path, char *buffer, size_t readSize, off_t readOffset,
struct fuse_file_info *fi);
static int repertory_readdir(const char *path, void *buf, fuse_fill_dir_t fuseFillDir,
off_t offset, struct fuse_file_info *fi);
static int repertory_release(const char *path, struct fuse_file_info *fi);
static int repertory_releasedir(const char *path, struct fuse_file_info *fi);
static int repertory_rename(const char *from, const char *to);
static int repertory_rmdir(const char *path);
/*
#ifdef HAS_SETXATTR
#ifdef __APPLE__
static int repertory_getxattr(const char *path, const char *name, char *value, size_t size,
uint32_t position) ;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode,
struct fuse_file_info *fi)
-> api_error override;
#else
static int repertory_getxattr(const char *path, const char *name, char *value, size_t size) ;
[[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode)
-> api_error override;
#endif
static int repertory_listxattr(const char *path, char *buffer, size_t size) ;
static int repertory_removexattr(const char *path, const char *name) ;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid,
struct fuse_file_info *fi)
-> api_error override;
#else
[[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid)
-> api_error override;
#endif
[[nodiscard]] auto create_impl(std::string api_path, mode_t mode,
struct fuse_file_info *fi)
-> api_error override;
void destroy_impl(void * /*ptr*/) override;
[[nodiscard]] auto fgetattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info *fi)
-> api_error override;
#ifdef __APPLE__
static int repertory_setxattr(const char *path, const char *name, const char *value,
size_t size, int flags, uint32_t position) ;
[[nodiscard]] auto fsetattr_x_impl(std::string api_path,
struct setattr_x *attr,
struct fuse_file_info *fi)
-> api_error override;
#endif // __APPLE__
[[nodiscard]] auto fsync_impl(std::string api_path, int datasync,
struct fuse_file_info *fi)
-> api_error override;
#if FUSE_USE_VERSION < 30
[[nodiscard]] auto ftruncate_impl(std::string api_path, off_t size,
struct fuse_file_info *fi)
-> api_error override;
#endif
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto getattr_impl(std::string api_path, struct stat *st,
struct fuse_file_info *fi)
-> api_error override;
#else
static int repertory_setxattr(const char *path, const char *name, const char *value,
size_t size, int flags) ;
[[nodiscard]] auto getattr_impl(std::string api_path, struct stat *st)
-> api_error override;
#endif
#endif
*/
#ifdef __APPLE__
static int repertory_setattr_x(const char *path, struct setattr_x *attr);
[[nodiscard]] auto getxtimes_impl(std::string api_path,
struct timespec *bkuptime,
struct timespec *crtime)
-> api_error override;
#endif // __APPLE__
static int repertory_setbkuptime(const char *path, const struct timespec *bkuptime);
static int repertory_setchgtime(const char *path, const struct timespec *chgtime);
static int repertory_setcrtime(const char *path, const struct timespec *crtime);
static int repertory_setvolname(const char *volname);
static int repertory_statfs_x(const char *path, struct statfs *stbuf);
#if FUSE_USE_VERSION >= 30
auto init_impl(struct fuse_conn_info *conn, struct fuse_config *cfg)
-> void * override;
#else
static int repertory_statfs(const char *path, struct statvfs *stbuf);
auto init_impl(struct fuse_conn_info *conn) -> void * override;
#endif
static int repertory_truncate(const char *path, off_t size);
[[nodiscard]] auto mkdir_impl(std::string api_path, mode_t mode)
-> api_error override;
static int repertory_unlink(const char *path);
void notify_fuse_main_exit(int &ret) override;
static int repertory_utimens(const char *path, const struct timespec tv[2]);
[[nodiscard]] auto open_impl(std::string api_path, struct fuse_file_info *fi)
-> api_error override;
static int repertory_write(const char *path, const char *buffer, size_t writeSize,
off_t writeOffset, struct fuse_file_info *fi);
};
[[nodiscard]] auto opendir_impl(std::string api_path,
struct fuse_file_info *fi)
-> api_error override;
[[nodiscard]] auto read_impl(std::string api_path, char *buffer,
size_t read_size, off_t read_offset,
struct fuse_file_info *fi,
std::size_t &bytes_read) -> api_error override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto readdir_impl(std::string api_path, void *buf,
fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi,
fuse_readdir_flags flags)
-> api_error override;
#else
[[nodiscard]] auto readdir_impl(std::string api_path, void *buf,
fuse_fill_dir_t fuse_fill_dir, off_t offset,
struct fuse_file_info *fi)
-> api_error override;
#endif
[[nodiscard]] auto release_impl(std::string api_path,
struct fuse_file_info *fi)
-> api_error override;
[[nodiscard]] auto releasedir_impl(std::string api_path,
struct fuse_file_info *fi)
-> api_error override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto rename_impl(std::string from_api_path,
std::string to_api_path, unsigned int flags)
-> api_error override;
#else
[[nodiscard]] auto rename_impl(std::string from_api_path,
std::string to_api_path) -> api_error override;
#endif
[[nodiscard]] auto rmdir_impl(std::string api_path) -> api_error override;
private:
// clang-format off
struct fuse_operations fuse_ops_ {
.getattr = remote_fuse_impl::repertory_getattr,
.readlink = nullptr, // int (*readlink) (const char *, char *, size_t);
.getdir = nullptr, // int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t);
.mknod = nullptr, // int (*mknod) (const char *, mode_t, dev_t);
.mkdir = remote_fuse_impl::repertory_mkdir,
.unlink = remote_fuse_impl::repertory_unlink,
.rmdir = remote_fuse_impl::repertory_rmdir,
.symlink = nullptr, // int (*symlink) (const char *, const char *);
.rename = remote_fuse_impl::repertory_rename,
.link = nullptr, // int (*link) (const char *, const char *);
.chmod = remote_fuse_impl::repertory_chmod,
.chown = remote_fuse_impl::repertory_chown,
.truncate = remote_fuse_impl::repertory_truncate,
.utime = nullptr, // int (*utime) (const char *, struct utimbuf *);
.open = remote_fuse_impl::repertory_open,
.read = remote_fuse_impl::repertory_read,
.write = remote_fuse_impl::repertory_write,
#ifdef __APPLE__
.statfs = nullptr,
[[nodiscard]] auto setattr_x_impl(std::string api_path,
struct setattr_x *attr)
-> api_error override;
[[nodiscard]] auto setbkuptime_impl(std::string api_path,
const struct timespec *bkuptime)
-> api_error override;
[[nodiscard]] auto setchgtime_impl(std::string api_path,
const struct timespec *chgtime)
-> api_error override;
[[nodiscard]] auto setcrtime_impl(std::string api_path,
const struct timespec *crtime)
-> api_error override;
[[nodiscard]] virtual auto setvolname_impl(const char *volname)
-> api_error override;
[[nodiscard]] auto statfs_x_impl(std::string api_path, struct statfs *stbuf)
-> api_error override;
#else // __APPLE__
[[nodiscard]] auto statfs_impl(std::string api_path, struct statvfs *stbuf)
-> api_error override;
#endif // __APPLE__
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto truncate_impl(std::string api_path, off_t size,
struct fuse_file_info *fi)
-> api_error override;
#else
.statfs = remote_fuse_impl::repertory_statfs,
[[nodiscard]] auto truncate_impl(std::string api_path, off_t size)
-> api_error override;
#endif
.flush = nullptr, // int (*flush) (const char *, struct fuse_file_info *);
.release = remote_fuse_impl::repertory_release,
.fsync = remote_fuse_impl::repertory_fsync,
#if HAS_SETXATTR
.setxattr = nullptr, // remote_fuse_impl::repertory_setxattr,
.getxattr = nullptr, // remote_fuse_impl::repertory_getxattr,
.listxattr = nullptr, // remote_fuse_impl::repertory_listxattr,
.removexattr = nullptr, // remote_fuse_impl::repertory_removexattr,
[[nodiscard]] auto unlink_impl(std::string api_path) -> api_error override;
#if FUSE_USE_VERSION >= 30
[[nodiscard]] auto utimens_impl(std::string api_path,
const struct timespec tv[2],
struct fuse_file_info *fi)
-> api_error override;
#else
.setxattr = nullptr,
.getxattr = nullptr,
.listxattr = nullptr,
.removexattr = nullptr,
[[nodiscard]] auto utimens_impl(std::string api_path,
const struct timespec tv[2])
-> api_error override;
#endif
.opendir = remote_fuse_impl::repertory_opendir,
.readdir = remote_fuse_impl::repertory_readdir,
.releasedir = remote_fuse_impl::repertory_releasedir,
.fsyncdir = nullptr, // int (*fsyncdir) (const char *, int, struct fuse_file_info *);
.init = remote_fuse_impl::repertory_init,
.destroy = remote_fuse_impl::repertory_destroy,
.access = remote_fuse_impl::repertory_access,
.create = remote_fuse_impl::repertory_create,
.ftruncate = remote_fuse_impl::repertory_ftruncate,
.fgetattr = remote_fuse_impl::repertory_fgetattr,
.lock = nullptr, // int (*lock) (const char *, struct fuse_file_info *, int cmd, struct flock *);
.utimens = remote_fuse_impl::repertory_utimens,
.bmap = nullptr, // int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
.flag_nullpath_ok = 0,
.flag_nopath = 0,
.flag_utime_omit_ok = 1,
.flag_reserved = 0,
.ioctl = nullptr, // int (*ioctl) (const char *, int cmd, void *arg, struct fuse_file_info *, unsigned int flags, void *data);
.poll = nullptr, // int (*poll) (const char *, struct fuse_file_info *, struct fuse_pollhandle *ph, unsigned *reventsp);
.write_buf = nullptr, // int (*write_buf) (const char *, struct fuse_bufvec *buf, off_t off, struct fuse_file_info *);
.read_buf = nullptr, // int (*read_buf) (const char *, struct fuse_bufvec **bufp, size_t size, off_t off, struct fuse_file_info *);
.flock = nullptr, // int (*flock) (const char *, struct fuse_file_info *, int op);
.fallocate = nullptr // remote_fuse_impl::repertory_fallocate,
};
// clang-format on
public:
int mount(std::vector<std::string> drive_args);
static void display_options(int argc, char *argv[]);
static void display_version_information(int argc, char *argv[]);
[[nodiscard]] auto write_impl(std::string api_path, const char *buffer,
size_t write_size, off_t write_offset,
struct fuse_file_info *fi,
std::size_t &bytes_written)
-> api_error override;
};
} // namespace remote_fuse
} // namespace repertory

View File

@@ -1,101 +0,0 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE2_HPP_
#define INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE2_HPP_
#ifndef _WIN32
#if 0
#include "common.hpp"
#include "drives/fuse/fuse_base.hpp"
#include "drives/fuse/remotefuse/i_remote_instance.hpp"
#include "events/event_system.hpp"
namespace repertory {
class app_config;
class console_consumer;
class logging_consumer;
class lock_data;
class server;
namespace utils {
api_error to_api_error(packet::error_type e) { return api_error::success; }
} // namespace utils
namespace remote_fuse {
class remote_fuse_drive2 final : public fuse_base {
E_CONSUMER();
public:
~remote_fuse_drive2() override = default;
private:
std::unique_ptr<i_remote_instance> remote_instance_;
protected:
api_error access_impl(std::string api_path, int mask) override;
#ifdef __APPLE__
api_error chflags_impl(std::string api_path, uint32_t flags) override;
#endif // __APPLE__
api_error chmod_impl(std::string api_path, mode_t mode) override;
public:
api_error check_parent_access(const std::string &api_path, int mask) const override;
std::uint64_t get_directory_item_count(const std::string &api_path) const override;
directory_item_list get_directory_items(const std::string &api_path) const override;
std::uint64_t get_file_size(const std::string &api_path) const override;
api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const override;
api_error get_item_meta(const std::string &api_path, const std::string &name,
std::string &value) const override;
std::uint64_t get_total_drive_space() const override;
std::uint64_t get_total_item_count() const override;
std::uint64_t get_used_drive_space() const override;
void get_volume_info(UINT64 &total_size, UINT64 &free_size,
std::string &volume_label) const override;
bool is_processing(const std::string &api_path) const override;
void populate_stat(const directory_item &di, struct stat &st) const override;
int rename_directory(const std::string &from_api_path, const std::string &to_api_path) override;
int rename_file(const std::string &from_api_path, const std::string &to_api_path,
const bool &overwrite) override;
void set_item_meta(const std::string &api_path, const std::string &key,
const std::string &value) override;
void update_directory_item(directory_item &di) const override;
};
} // namespace remote_fuse
} // namespace repertory
#endif // 0
#endif // _WIN32
#endif // INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_FUSE_DRIVE2_HPP_

View File

@@ -1,26 +1,28 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_SERVER_HPP_
#define INCLUDE_DRIVES_FUSE_REMOTEFUSE_REMOTE_SERVER_HPP_
#ifndef _WIN32
#include "common.hpp"
#include "drives/directory_cache.hpp"
#include "drives/fuse/i_fuse_drive.hpp"
#include "drives/remote/remote_server_base.hpp"
@@ -31,220 +33,303 @@ class app_config;
namespace remote_fuse {
class remote_server final : public virtual remote_server_base<i_fuse_drive> {
public:
remote_server(app_config &config, i_fuse_drive &drive, const std::string &mount_location);
remote_server(app_config &config, i_fuse_drive &drive,
const std::string &mount_location);
private:
directory_cache directory_cache_;
private:
std::string construct_path(std::string path);
[[nodiscard]] auto construct_path(std::string path) -> std::string;
std::string construct_path(const std::wstring &path);
[[nodiscard]] auto construct_path(const std::wstring &path) -> std::string;
static std::string empty_as_zero(const json &data);
[[nodiscard]] static auto empty_as_zero(const json &data) -> std::string;
packet::error_type populate_file_info(const std::string &api_path, remote::file_info &file_info);
[[nodiscard]] auto populate_file_info(const std::string &api_path,
remote::file_info &file_info)
-> packet::error_type;
void populate_file_info(const std::string &api_path, const UINT64 &file_size,
const UINT32 &attributes, remote::file_info &file_info);
const UINT32 &attributes,
remote::file_info &file_info);
static void populate_stat(const struct stat &st1, remote::stat &st);
static void populate_stat(const struct stat64 &st1, remote::stat &st);
json &update_to_windows_format(json &item);
[[nodiscard]] auto update_to_windows_format(json &item) -> json &;
protected:
void delete_open_directory(void *dir) override;
public:
// FUSE Layer
packet::error_type fuse_access(const char *path, const std::int32_t &mask) override;
[[nodiscard]] auto fuse_access(const char *path, const std::int32_t &mask)
-> packet::error_type override;
packet::error_type fuse_chflags(const char *path, const std::uint32_t &flags) override;
[[nodiscard]] auto fuse_chflags(const char *path, std::uint32_t flags)
-> packet::error_type override;
packet::error_type fuse_chmod(const char *path, const remote::file_mode &mode) override;
[[nodiscard]] auto fuse_chmod(const char *path, const remote::file_mode &mode)
-> packet::error_type override;
packet::error_type fuse_chown(const char *path, const remote::user_id &uid,
const remote::group_id &gid) override;
[[nodiscard]] auto fuse_chown(const char *path, const remote::user_id &uid,
const remote::group_id &gid)
-> packet::error_type override;
packet::error_type fuse_create(const char *path, const remote::file_mode &mode,
const remote::open_flags &flags, remote::file_handle &handle) override;
[[nodiscard]] auto
fuse_create(const char *path, const remote::file_mode &mode,
const remote::open_flags &flags, remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_destroy() override;
[[nodiscard]] auto fuse_destroy() -> packet::error_type override;
/*packet::error_type fuse_fallocate(const char *path, const std::int32_t &mode,
const remote::file_offset &offset,
const remote::file_offset &length,
const remote::file_handle &handle) override ;*/
/*[[nodiscard]] packet::error_type fuse_fallocate(const char *path, const
std::int32_t &mode, const remote::file_offset &offset, const
remote::file_offset &length, const remote::file_handle &handle) override
;*/
packet::error_type fuse_fgetattr(const char *path, remote::stat &st, bool &directory,
const remote::file_handle &handle) override;
[[nodiscard]] auto fuse_fgetattr(const char *path, remote::stat &st,
bool &directory,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_fsetattr_x(const char *path, const remote::setattr_x &attr,
const remote::file_handle &handle) override;
[[nodiscard]] auto fuse_fsetattr_x(const char *path,
const remote::setattr_x &attr,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_fsync(const char *path, const std::int32_t &datasync,
const remote::file_handle &handle) override;
[[nodiscard]] auto fuse_fsync(const char *path, const std::int32_t &datasync,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_ftruncate(const char *path, const remote::file_offset &size,
const remote::file_handle &handle) override;
[[nodiscard]] auto fuse_ftruncate(const char *path,
const remote::file_offset &size,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_getattr(const char *path, remote::stat &st, bool &directory) override;
[[nodiscard]] auto fuse_getattr(const char *path, remote::stat &st,
bool &directory)
-> packet::error_type override;
/*packet::error_type fuse_getxattr(const char *path, const char *name, char *value,
const remote::file_size &size) override ;
/*[[nodiscard]] packet::error_type fuse_getxattr(const char *path, const char
*name, char *value, const remote::file_size &size) override ;
packet::error_type fuse_getxattrOSX(const char *path, const char *name, char *value,
const remote::file_size &size,
const std::uint32_t &position) override ;*/
[[nodiscard]] packet::error_type fuse_getxattrOSX(const char *path, const char
*name, char *value, const remote::file_size &size, std::uint32_t position)
override ;*/
packet::error_type fuse_getxtimes(const char *path, remote::file_time &bkuptime,
remote::file_time &crtime) override;
[[nodiscard]] auto fuse_getxtimes(const char *path,
remote::file_time &bkuptime,
remote::file_time &crtime)
-> packet::error_type override;
packet::error_type fuse_init() override;
[[nodiscard]] auto fuse_init() -> packet::error_type override;
/*packet::error_type fuse_listxattr(const char *path, char *buffer,
const remote::file_size &size) override ;*/
[[nodiscard]] /*packet::error_type fuse_listxattr(const char *path, char
*buffer, const remote::file_size &size) override ;*/
packet::error_type fuse_mkdir(const char *path, const remote::file_mode &mode) override;
[[nodiscard]] auto
fuse_mkdir(const char *path, const remote::file_mode &mode)
-> packet::error_type override;
packet::error_type fuse_open(const char *path, const remote::open_flags &flags,
remote::file_handle &handle) override;
[[nodiscard]] auto fuse_open(const char *path,
const remote::open_flags &flags,
remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_opendir(const char *path, remote::file_handle &handle) override;
[[nodiscard]] auto fuse_opendir(const char *path, remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_read(const char *path, char *buffer, const remote::file_size &read_size,
[[nodiscard]] auto fuse_read(const char *path, char *buffer,
const remote::file_size &read_size,
const remote::file_offset &read_offset,
const remote::file_handle &handle) override;
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_rename(const char *from, const char *to) override;
[[nodiscard]] auto fuse_rename(const char *from, const char *to)
-> packet::error_type override;
packet::error_type fuse_readdir(const char *path, const remote::file_offset &offset,
const remote::file_handle &handle, std::string &item_path) override;
[[nodiscard]] auto
fuse_readdir(const char *path, const remote::file_offset &offset,
const remote::file_handle &handle, std::string &item_path)
-> packet::error_type override;
packet::error_type fuse_release(const char *path, const remote::file_handle &handle) override;
[[nodiscard]] auto fuse_release(const char *path,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_releasedir(const char *path, const remote::file_handle &handle) override;
[[nodiscard]] auto fuse_releasedir(const char *path,
const remote::file_handle &handle)
-> packet::error_type override;
/*packet::error_type fuse_removexattr(const char *path, const char *name) override ;*/
/*[[nodiscard]] packet::error_type fuse_removexattr(const char *path, const
* char *name) override
* ;*/
packet::error_type fuse_rmdir(const char *path) override;
[[nodiscard]] auto fuse_rmdir(const char *path)
-> packet::error_type override;
packet::error_type fuse_setattr_x(const char *path, remote::setattr_x &attr) override;
[[nodiscard]] auto fuse_setattr_x(const char *path, remote::setattr_x &attr)
-> packet::error_type override;
packet::error_type fuse_setbkuptime(const char *path, const remote::file_time &bkuptime) override;
[[nodiscard]] auto fuse_setbkuptime(const char *path,
const remote::file_time &bkuptime)
-> packet::error_type override;
packet::error_type fuse_setchgtime(const char *path, const remote::file_time &chgtime) override;
[[nodiscard]] auto fuse_setchgtime(const char *path,
const remote::file_time &chgtime)
-> packet::error_type override;
packet::error_type fuse_setcrtime(const char *path, const remote::file_time &crtime) override;
[[nodiscard]] auto fuse_setcrtime(const char *path,
const remote::file_time &crtime)
-> packet::error_type override;
packet::error_type fuse_setvolname(const char *volname) override;
[[nodiscard]] auto fuse_setvolname(const char *volname)
-> packet::error_type override;
/*packet::error_type fuse_setxattr(const char *path, const char *name, const char *value,
const remote::file_size &size,
const std::int32_t &flags) override ;
/*[[nodiscard]] packet::error_type fuse_setxattr(const char *path, const char
*name, const char *value, const remote::file_size &size, const std::int32_t
&flags) override ;
packet::error_type fuse_setxattr_osx(const char *path, const char *name, const char *value,
const remote::file_size &size, const std::int32_t &flags,
const std::uint32_t &position) override ;*/
[[nodiscard]] packet::error_type fuse_setxattr_osx(const char *path, const
char *name, const char *value, const remote::file_size &size, const
std::int32_t &flags, std::uint32_t position) override ;*/
packet::error_type fuse_statfs(const char *path, const std::uint64_t &frsize,
remote::statfs &st) override;
[[nodiscard]] auto fuse_statfs(const char *path, std::uint64_t frsize,
remote::statfs &st)
-> packet::error_type override;
packet::error_type fuse_statfs_x(const char *path, const std::uint64_t &bsize,
remote::statfs_x &st) override;
[[nodiscard]] auto fuse_statfs_x(const char *path, std::uint64_t bsize,
remote::statfs_x &st)
-> packet::error_type override;
packet::error_type fuse_truncate(const char *path, const remote::file_offset &size) override;
[[nodiscard]] auto fuse_truncate(const char *path,
const remote::file_offset &size)
-> packet::error_type override;
packet::error_type fuse_unlink(const char *path) override;
[[nodiscard]] auto fuse_unlink(const char *path)
-> packet::error_type override;
packet::error_type fuse_utimens(const char *path, const remote::file_time *tv,
const std::uint64_t &op0, const std::uint64_t &op1) override;
[[nodiscard]] auto fuse_utimens(const char *path, const remote::file_time *tv,
std::uint64_t op0, std::uint64_t op1)
-> packet::error_type override;
packet::error_type fuse_write(const char *path, const char *buffer,
[[nodiscard]] auto fuse_write(const char *path, const char *buffer,
const remote::file_size &write_size,
const remote::file_offset &write_offset,
const remote::file_handle &handle) override;
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_write_base64(const char *path, const char *buffer,
[[nodiscard]] auto fuse_write_base64(const char *path, const char *buffer,
const remote::file_size &write_size,
const remote::file_offset &write_offset,
const remote::file_handle &handle) override;
const remote::file_handle &handle)
-> packet::error_type override;
void set_fuse_uid_gid(const remote::user_id &, const remote::group_id &) override {}
void set_fuse_uid_gid(const remote::user_id &,
const remote::group_id &) override {}
// JSON Layer
packet::error_type winfsp_get_dir_buffer(PVOID /*file_desc*/, PVOID *& /*ptr*/) override {
[[nodiscard]] auto winfsp_get_dir_buffer(PVOID /*file_desc*/,
PVOID *& /*ptr*/)
-> packet::error_type override {
return STATUS_INVALID_HANDLE;
}
packet::error_type json_create_directory_snapshot(const std::string &path,
json &jsonData) override;
[[nodiscard]] auto json_create_directory_snapshot(const std::string &path,
json &jsonData)
-> packet::error_type override;
packet::error_type json_read_directory_snapshot(const std::string &path,
const remote::file_handle &handle,
const std::uint32_t &page,
json &jsonData) override;
[[nodiscard]] auto json_read_directory_snapshot(
const std::string &path, const remote::file_handle &handle,
std::uint32_t page, json &jsonData) -> packet::error_type override;
packet::error_type json_release_directory_snapshot(const std::string &path,
const remote::file_handle &handle) override;
[[nodiscard]] auto
json_release_directory_snapshot(const std::string &path,
const remote::file_handle &handle)
-> packet::error_type override;
// WinFSP Layer
packet::error_type winfsp_can_delete(PVOID file_desc, PWSTR file_name) override;
[[nodiscard]] auto winfsp_can_delete(PVOID file_desc, PWSTR file_name)
-> packet::error_type override;
packet::error_type winfsp_cleanup(PVOID file_desc, PWSTR file_name, UINT32 flags,
BOOLEAN &wasClosed) override;
[[nodiscard]] auto winfsp_cleanup(PVOID file_desc, PWSTR file_name,
UINT32 flags, BOOLEAN &wasClosed)
-> packet::error_type override;
packet::error_type winfsp_close(PVOID file_desc) override;
[[nodiscard]] auto winfsp_close(PVOID file_desc)
-> packet::error_type override;
packet::error_type winfsp_create(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
UINT32 attributes, UINT64 /*allocation_size*/, PVOID *file_desc,
remote::file_info *file_info, std::string &normalized_name,
BOOLEAN &exists) override;
[[nodiscard]] auto
winfsp_create(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
UINT32 attributes, UINT64 /*allocation_size*/, PVOID *file_desc,
remote::file_info *file_info, std::string &normalized_name,
BOOLEAN &exists) -> packet::error_type override;
packet::error_type winfsp_flush(PVOID file_desc, remote::file_info *file_info) override;
[[nodiscard]] auto winfsp_flush(PVOID file_desc, remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_get_file_info(PVOID file_desc, remote::file_info *file_info) override;
[[nodiscard]] auto winfsp_get_file_info(PVOID file_desc,
remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes,
std::uint64_t * /*securityDescriptorSize*/,
std::wstring & /*strDescriptor*/) override;
[[nodiscard]] auto
winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes,
std::uint64_t * /*securityDescriptorSize*/,
std::wstring & /*strDescriptor*/)
-> packet::error_type override;
packet::error_type winfsp_get_volume_info(UINT64 &total_size, UINT64 &free_size,
std::string &volume_label) override;
[[nodiscard]] auto winfsp_get_volume_info(UINT64 &total_size,
UINT64 &free_size,
std::string &volume_label)
-> packet::error_type override;
packet::error_type winfsp_mounted(const std::wstring &location) override;
[[nodiscard]] auto winfsp_mounted(const std::wstring &location)
-> packet::error_type override;
packet::error_type winfsp_open(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
PVOID *file_desc, remote::file_info *file_info,
std::string &normalized_name) override;
[[nodiscard]] auto winfsp_open(PWSTR file_name, UINT32 create_options,
UINT32 granted_access, PVOID *file_desc,
remote::file_info *file_info,
std::string &normalized_name)
-> packet::error_type override;
packet::error_type winfsp_overwrite(PVOID file_desc, UINT32 attributes,
BOOLEAN replace_attributes, UINT64 /*allocation_size*/,
remote::file_info *file_info) override;
[[nodiscard]] auto winfsp_overwrite(PVOID file_desc, UINT32 attributes,
BOOLEAN replace_attributes,
UINT64 /*allocation_size*/,
remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
PUINT32 bytes_transferred) override;
[[nodiscard]] auto winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
UINT32 length, PUINT32 bytes_transferred)
-> packet::error_type override;
packet::error_type winfsp_read_directory(PVOID file_desc, PWSTR /*pattern*/, PWSTR marker,
json &itemList) override;
[[nodiscard]] auto winfsp_read_directory(PVOID file_desc, PWSTR /*pattern*/,
PWSTR marker, json &itemList)
-> packet::error_type override;
packet::error_type winfsp_rename(PVOID /*file_desc*/, PWSTR file_name, PWSTR new_file_name,
BOOLEAN replace_if_exists) override;
[[nodiscard]] auto winfsp_rename(PVOID /*file_desc*/, PWSTR file_name,
PWSTR new_file_name,
BOOLEAN replace_if_exists)
-> packet::error_type override;
packet::error_type winfsp_set_basic_info(PVOID file_desc, UINT32 attributes, UINT64 creation_time,
UINT64 last_access_time, UINT64 last_write_time,
UINT64 change_time,
remote::file_info *file_info) override;
[[nodiscard]] auto winfsp_set_basic_info(
PVOID file_desc, UINT32 attributes, UINT64 creation_time,
UINT64 last_access_time, UINT64 last_write_time, UINT64 change_time,
remote::file_info *file_info) -> packet::error_type override;
packet::error_type winfsp_set_file_size(PVOID file_desc, UINT64 newSize,
[[nodiscard]] auto winfsp_set_file_size(PVOID file_desc, UINT64 newSize,
BOOLEAN set_allocation_size,
remote::file_info *file_info) override;
remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_unmounted(const std::wstring &location) override;
[[nodiscard]] auto winfsp_unmounted(const std::wstring &location)
-> packet::error_type override;
packet::error_type winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
BOOLEAN write_to_end, BOOLEAN constrained_io,
PUINT32 bytes_transferred, remote::file_info *file_info) override;
[[nodiscard]] auto
winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
BOOLEAN write_to_end, BOOLEAN constrained_io,
PUINT32 bytes_transferred, remote::file_info *file_info)
-> packet::error_type override;
};
} // namespace remote_fuse
} // namespace repertory

View File

@@ -1,64 +0,0 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_I_OPEN_FILE_TABLE_HPP_
#define INCLUDE_DRIVES_I_OPEN_FILE_TABLE_HPP_
#include "common.hpp"
#include "types/repertory.hpp"
namespace repertory {
class i_provider;
class i_open_file_table {
INTERFACE_SETUP(i_open_file_table);
public:
typedef std::function<bool(i_open_file_table &oft, i_provider &provider)>
locked_operation_callback;
public:
virtual void close(const std::uint64_t &handle) = 0;
virtual bool contains_restore(const std::string &api_path) const = 0;
virtual bool evict_file(const std::string &api_path) = 0;
virtual void force_schedule_upload(const filesystem_item &fsi) = 0;
virtual directory_item_list get_directory_items(const std::string &api_path) const = 0;
virtual std::uint64_t get_open_count(const std::string &api_path) const = 0;
virtual bool get_open_file(const std::string &api_path, filesystem_item *&fsi) = 0;
virtual std::unordered_map<std::string, std::size_t> get_open_files() const = 0;
virtual bool has_no_open_file_handles() const = 0;
virtual api_error open(const filesystem_item &fsi, std::uint64_t &handle) = 0;
virtual bool perform_locked_operation(locked_operation_callback locked_operation) = 0;
virtual api_error set_item_meta(const std::string &api_path, const std::string &key,
const std::string &value) = 0;
virtual void update_directory_item(directory_item &di) const = 0;
};
} // namespace repertory
#endif // INCLUDE_DRIVES_I_OPEN_FILE_TABLE_HPP_

View File

@@ -1,751 +0,0 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_OPEN_FILE_TABLE_HPP_
#define INCLUDE_DRIVES_OPEN_FILE_TABLE_HPP_
#include "common.hpp"
#include "app_config.hpp"
#include "db/retry_db.hpp"
#include "download/i_download_manager.hpp"
#include "drives/i_open_file_table.hpp"
#include "providers/i_provider.hpp"
#include "types/repertory.hpp"
#include "utils/file_utils.hpp"
#include "utils/global_data.hpp"
#include "utils/native_file.hpp"
#include "utils/path_utils.hpp"
#include "utils/polling.hpp"
namespace repertory {
template <typename flags> class open_file_table final : public virtual i_open_file_table {
public:
open_file_table(i_provider &provider, const app_config &config, i_download_manager &dm)
: provider_(provider), config_(config), dm_(dm), retry_db_(config) {
// Set initial value for used cache space
global_data::instance().initialize_used_cache_space(
utils::file::calculate_used_space(config_.get_cache_directory(), false));
polling::instance().set_callback(
{"last_close_clear", false, [this] {
std::vector<std::string> keys;
unique_mutex_lock l(last_close_mutex_);
std::transform(last_close_lookup_.begin(), last_close_lookup_.end(),
std::back_inserter(keys), [](const auto &kv) { return kv.first; });
l.unlock();
for (const auto &key : keys) {
l.lock();
remove_if_expired(key, last_close_lookup_[key]);
l.unlock();
}
}});
}
~open_file_table() override { polling::instance().remove_callback("last_close_clear"); }
private:
struct open_file_info {
filesystem_item item;
api_meta_map meta;
};
private:
i_provider &provider_;
const app_config &config_;
i_download_manager &dm_;
retry_db retry_db_;
std::unordered_map<std::string, std::shared_ptr<open_file_info>> open_file_lookup_;
mutable std::recursive_mutex open_file_mutex_;
std::unordered_map<std::uint64_t, open_file_info *> open_handle_lookup_;
std::uint64_t next_handle_ = 1u;
bool stop_requested_ = false;
std::mutex retry_mutex_;
std::unique_ptr<std::thread> retry_thread_;
std::condition_variable retry_notify_;
std::mutex start_stop_mutex_;
std::mutex last_close_mutex_;
std::unordered_map<std::string, std::uint64_t> last_close_lookup_;
private:
api_error get_filesystem_item(const std::string &api_path, const bool &directory,
filesystem_item &fsi) {
auto ret = api_error::item_not_found;
const auto it = open_file_lookup_.find(api_path);
if (it != open_file_lookup_.end()) {
fsi = it->second->item;
ret = api_error::success;
} else {
ret = provider_.get_filesystem_item(api_path, directory, fsi);
}
return ret;
}
std::uint64_t get_next_handle() {
std::uint64_t ret = 0u;
while ((ret = next_handle_++) == 0u) {
}
return ret;
}
api_error handle_file_rename(const std::string &from_api_path, const std::string &to_api_path) {
auto ret = api_error::file_in_use;
if (dm_.pause_download(from_api_path)) {
if ((ret = provider_.rename_file(from_api_path, to_api_path)) == api_error::success) {
swap_renamed_items(from_api_path, to_api_path);
dm_.rename_download(from_api_path, to_api_path);
dm_.resume_download(to_api_path);
retry_db_.rename(from_api_path, to_api_path);
} else {
dm_.resume_download(from_api_path);
}
}
return ret;
}
void handle_file_upload(filesystem_item &fsi) {
fsi.changed = false;
handle_file_upload(&fsi);
}
void handle_file_upload(const filesystem_item *fsi) {
// Remove from retry queue, if present
retry_db_.remove(fsi->api_path);
// Upload file and add to retry queue on failure
auto nf = native_file::attach(fsi->handle);
nf->flush();
if (provider_.upload_file(fsi->api_path, fsi->source_path, fsi->encryption_token) !=
api_error::success) {
retry_db_.set(fsi->api_path);
event_system::instance().raise<failed_upload_queued>(fsi->api_path);
}
}
bool remove_if_expired(const std::string &api_path, const std::uint64_t &time) {
auto ret = false;
#ifdef _WIN32
const auto delay = std::chrono::minutes(config_.get_eviction_delay_mins());
const auto last_check = std::chrono::system_clock::from_time_t(time);
if ((ret = ((last_check + delay) <= std::chrono::system_clock::now())))
#else
if ((ret = ((time + ((config_.get_eviction_delay_mins() * 60L) * NANOS_PER_SECOND)) <=
utils::get_time_now())))
#endif
{
last_close_lookup_.erase(api_path);
}
return ret;
}
bool retry_delete_file(const std::string &file) {
auto deleted = false;
for (std::uint8_t i = 0u; not(deleted = utils::file::delete_file(file)) && (i < 100u); i++) {
std::this_thread::sleep_for(10ms);
}
return deleted;
}
void swap_renamed_items(std::string from_api_path, std::string to_api_path) {
const auto it = open_file_lookup_.find(from_api_path);
if (it != open_file_lookup_.end()) {
open_file_lookup_[to_api_path] = open_file_lookup_[from_api_path];
open_file_lookup_.erase(from_api_path);
auto &fsi = open_file_lookup_[to_api_path]->item;
fsi.api_path = to_api_path;
fsi.api_parent = utils::path::get_parent_api_path(to_api_path);
}
}
public:
bool has_no_open_file_handles() const override {
recur_mutex_lock l(open_file_mutex_);
return std::find_if(open_file_lookup_.cbegin(), open_file_lookup_.cend(), [](const auto &kv) {
return not kv.second->item.directory;
}) == open_file_lookup_.cend();
}
void close(const std::uint64_t &handle) override {
recur_mutex_lock l(open_file_mutex_);
const auto it = open_handle_lookup_.find(handle);
if (it != open_handle_lookup_.end()) {
auto *oi = it->second;
open_handle_lookup_.erase(handle);
auto &fsi = oi->item;
const auto was_changed = fsi.changed;
// Handle meta change
if (fsi.meta_changed) {
if (provider_.set_item_meta(fsi.api_path, oi->meta) == api_error::success) {
fsi.meta_changed = false;
} else {
event_system::instance().raise<repertory_exception>(
__FUNCTION__, "failed to set file meta: " + fsi.api_path);
}
}
// Handle source path change
if (not fsi.directory && fsi.source_path_changed) {
if (provider_.set_source_path(fsi.api_path, fsi.source_path) == api_error::success) {
fsi.source_path_changed = false;
} else {
event_system::instance().raise<repertory_exception>(
__FUNCTION__, "failed to set source path: " + fsi.api_path + "|" + fsi.source_path);
}
}
// Update last close time in lookup table
if (not fsi.directory) {
mutex_lock l2(last_close_mutex_);
last_close_lookup_[fsi.api_path] = utils::get_time_now();
}
// Handle file change
#ifdef __APPLE__
// Special handling for OS X - only upload if handle being closed is writable
if (not fsi.directory && was_changed && (fsi.open_data[handle] & O_ACCMODE))
#else
if (not fsi.directory && was_changed)
#endif
{
handle_file_upload(fsi);
}
// Close internal handle if no more open files
auto &od = fsi.open_data;
od.erase(handle);
event_system::instance().raise<filesystem_item_handle_closed>(
fsi.api_path, handle, fsi.source_path, fsi.directory, was_changed);
if (od.empty()) {
native_file::attach(fsi.handle)->close();
event_system::instance().raise<filesystem_item_closed>(fsi.api_path, fsi.source_path,
fsi.directory, was_changed);
open_file_lookup_.erase(fsi.api_path);
}
}
}
#ifdef _WIN32
void close_all(const std::string &api_path) {
recur_mutex_lock l(open_file_mutex_);
const auto it = open_file_lookup_.find(api_path);
if (it != open_file_lookup_.end()) {
auto *oi = it->second.get();
std::vector<std::uint64_t> handles;
for (const auto &kv : open_handle_lookup_) {
if (kv.second == oi) {
handles.emplace_back(kv.first);
}
}
while (!handles.empty()) {
close(handles.back());
handles.pop_back();
}
}
}
#endif // _WIN32
bool contains_restore(const std::string &api_path) const override {
return dm_.contains_restore(api_path);
}
api_error derive_file_size(const std::string &api_path, std::uint64_t &file_size) {
auto ret = api_error::success;
file_size = 0u;
if (provider_.is_file(api_path)) {
unique_recur_mutex_lock l(open_file_mutex_);
const auto it = open_file_lookup_.find(api_path);
if (it == open_file_lookup_.end()) {
l.unlock();
ret = provider_.get_file_size(api_path, file_size);
} else {
file_size = open_file_lookup_[api_path]->item.size;
}
}
return ret;
}
api_error derive_item_data(const std::string &api_path, api_meta_map &meta) {
auto ret = api_error::success;
meta.clear();
unique_recur_mutex_lock l(open_file_mutex_);
const auto it = open_file_lookup_.find(api_path);
if (it == open_file_lookup_.end()) {
l.unlock();
ret = provider_.get_item_meta(api_path, meta);
} else {
meta = open_file_lookup_[api_path]->meta;
}
return ret;
}
api_error derive_item_data(const directory_item &di, std::uint64_t &file_size,
api_meta_map &meta) {
return derive_item_data(di.api_path, di.directory, file_size, meta);
}
api_error derive_item_data(const std::string &api_path, const bool &directory,
std::uint64_t &file_size, api_meta_map &meta) {
auto ret = api_error::success;
meta.clear();
file_size = 0;
unique_recur_mutex_lock l(open_file_mutex_);
const auto it = open_file_lookup_.find(api_path);
if (it == open_file_lookup_.end()) {
l.unlock();
ret = provider_.get_item_meta(api_path, meta);
if ((ret == api_error::success) && not directory) {
ret = provider_.get_file_size(api_path, file_size);
}
} else {
meta = open_file_lookup_[api_path]->meta;
if (not directory) {
file_size = open_file_lookup_[api_path]->item.size;
}
}
return ret;
}
bool evict_file(const std::string &api_path) override {
auto ret = false;
auto allow_eviction = true;
// Ensure enough time has passed since file was closed
{
mutex_lock l(last_close_mutex_);
const auto it = last_close_lookup_.find(api_path);
if (it != last_close_lookup_.end()) {
allow_eviction = remove_if_expired(api_path, it->second);
}
}
if (allow_eviction) {
recur_mutex_lock l(open_file_mutex_);
// Ensure item is not in upload retry queue
if (not retry_db_.exists(api_path) && (get_open_count(api_path) == 0u)) {
// Ensure item is not currently downloading
if (not dm_.is_processing(api_path)) {
filesystem_item fsi{};
if (provider_.get_filesystem_item(api_path, false, fsi) == api_error::success) {
std::uint64_t file_size = 0u;
if ((ret = (utils::file::get_file_size(fsi.source_path, file_size) &&
retry_delete_file(fsi.source_path)))) {
global_data::instance().update_used_space(file_size, 0, true);
event_system::instance().raise<filesystem_item_evicted>(fsi.api_path,
fsi.source_path);
}
}
}
}
}
return ret;
}
void force_schedule_upload(const filesystem_item &fsi) override {
recur_mutex_lock l(open_file_mutex_);
filesystem_item *fsi_ptr = nullptr;
if (get_open_file(fsi.api_path, fsi_ptr)) {
handle_file_upload(*fsi_ptr);
} else {
handle_file_upload(&fsi);
}
}
directory_item_list get_directory_items(const std::string &api_path) const override {
directory_item_list list;
provider_.get_directory_items(api_path, list);
return list;
}
std::uint64_t get_open_count(const std::string &api_path) const override {
std::uint64_t ret = 0u;
recur_mutex_lock l(open_file_mutex_);
const auto it = open_file_lookup_.find(api_path);
if (it != open_file_lookup_.end()) {
ret = it->second->item.open_data.size();
}
return ret;
}
bool get_open_file(const std::string &api_path, filesystem_item *&fsi) override {
auto ret = false;
recur_mutex_lock l(open_file_mutex_);
const auto it = open_file_lookup_.find(api_path);
if (it != open_file_lookup_.end()) {
fsi = &it->second->item;
ret = true;
}
return ret;
}
bool get_open_file(const std::uint64_t &handle, filesystem_item *&fsi) {
auto ret = false;
recur_mutex_lock l(open_file_mutex_);
const auto it = open_handle_lookup_.find(handle);
if (it != open_handle_lookup_.end()) {
fsi = &it->second->item;
ret = true;
}
return ret;
}
std::unordered_map<std::string, std::size_t> get_open_files() const override {
std::unordered_map<std::string, std::size_t> ret;
unique_recur_mutex_lock l(open_file_mutex_);
for (const auto &kv : open_file_lookup_) {
ret.insert({kv.first, kv.second->item.open_data.size()});
}
l.unlock();
return ret;
}
api_error open(const filesystem_item &fsi, std::uint64_t &handle) override {
auto ret = api_error::success;
recur_mutex_lock l(open_file_mutex_);
if (open_file_lookup_.find(fsi.api_path) == open_file_lookup_.end()) {
api_meta_map meta;
if ((ret = provider_.get_item_meta(fsi.api_path, meta)) == api_error::success) {
auto oi = std::make_shared<open_file_info>();
oi->meta = meta;
oi->item = fsi;
oi->item.lock = std::make_shared<std::recursive_mutex>();
open_file_lookup_.insert({fsi.api_path, oi});
event_system::instance().raise<filesystem_item_opened>(
oi->item.api_path, oi->item.source_path, oi->item.directory);
}
}
if (ret == api_error::success) {
ret = Open(fsi.api_path, fsi.directory, utils::file::get_read_write_open_flags(), handle);
}
return ret;
}
api_error Open(const std::string &api_path, const bool &directory, const flags &f,
std::uint64_t &handle) {
auto ret = api_error::success;
recur_mutex_lock l(open_file_mutex_);
if (open_file_lookup_.find(api_path) == open_file_lookup_.end()) {
api_meta_map meta;
if ((ret = provider_.get_item_meta(api_path, meta)) == api_error::success) {
auto oi = std::make_shared<open_file_info>();
oi->meta = meta;
if ((ret = provider_.get_filesystem_item(api_path, directory, oi->item)) ==
api_error::success) {
open_file_lookup_.insert({api_path, oi});
event_system::instance().raise<filesystem_item_opened>(
oi->item.api_path, oi->item.source_path, oi->item.directory);
}
}
}
if (ret == api_error::success) {
auto *oi = open_file_lookup_[api_path].get();
auto &fsi = oi->item;
if (fsi.directory == directory) {
handle = get_next_handle();
fsi.open_data.insert({handle, f});
open_handle_lookup_.insert({handle, oi});
} else {
ret = directory ? api_error::file_exists : api_error::directory_exists;
}
}
return ret;
}
bool perform_locked_operation(locked_operation_callback locked_operation) override {
recur_mutex_lock l(open_file_mutex_);
return locked_operation(*this, provider_);
}
api_error remove_file(const std::string &api_path) {
recur_mutex_lock l(open_file_mutex_);
filesystem_item fsi{};
auto ret = api_error::file_in_use;
if ((get_open_count(api_path) == 0u) &&
((ret = provider_.get_filesystem_item(api_path, false, fsi)) == api_error::success) &&
((ret = provider_.remove_file(api_path)) == api_error::success)) {
std::uint64_t file_size = 0u;
utils::file::get_file_size(fsi.source_path, file_size);
if (retry_delete_file(fsi.source_path) && file_size) {
global_data::instance().update_used_space(file_size, 0, false);
}
}
return ret;
}
#ifdef HAS_SETXATTR
api_error remove_xattr_meta(const std::string &api_path, const std::string &name) {
auto ret = api_error::xattr_not_found;
if (utils::collection_excludes(META_USED_NAMES, name)) {
unique_recur_mutex_lock l(open_file_mutex_);
if (open_file_lookup_.find(api_path) == open_file_lookup_.end()) {
l.unlock();
ret = provider_.remove_item_meta(api_path, name);
} else if (open_file_lookup_[api_path]->meta.find(name) !=
open_file_lookup_[api_path]->meta.end()) {
open_file_lookup_[api_path]->item.meta_changed = true;
open_file_lookup_[api_path]->meta.erase(name);
ret = api_error::success;
}
}
return ret;
}
#endif
api_error rename_directory(const std::string &from_api_path, const std::string &to_api_path) {
unique_recur_mutex_lock l(open_file_mutex_);
auto ret = api_error::not_implemented;
if (provider_.is_rename_supported()) {
ret = api_error::directory_not_found;
// Ensure source directory exists
if (provider_.is_directory(from_api_path)) {
ret = api_error::directory_exists;
// Ensure destination directory does not exist
if (not provider_.is_directory(to_api_path)) {
ret = api_error::file_exists;
// Ensure destination is not a file
if (not provider_.is_file(from_api_path)) {
ret = api_error::directory_not_found;
// Ensure parent destination directory exists
directory_item_list list;
if (provider_.is_directory(utils::path::get_parent_api_path(to_api_path)) &&
((ret = provider_.create_directory_clone_source_meta(from_api_path, to_api_path)) ==
api_error::success) &&
((ret = provider_.get_directory_items(from_api_path, list)) ==
api_error::success)) {
// Rename all items - directories MUST BE returned first
for (std::size_t i = 0u; (ret == api_error::success) && (i < list.size()); i++) {
const auto &api_path = list[i].api_path;
if ((api_path != ".") && (api_path != "..")) {
const auto old_api_path = api_path;
const auto new_api_path = utils::path::create_api_path(utils::path::combine(
to_api_path, {old_api_path.substr(from_api_path.size())}));
if (list[i].directory) {
ret = rename_directory(old_api_path, new_api_path);
} else {
ret = rename_file(old_api_path, new_api_path);
}
}
}
if (ret == api_error::success) {
swap_renamed_items(from_api_path, to_api_path);
ret = provider_.remove_directory(from_api_path);
}
}
}
}
}
}
return ret;
}
api_error rename_file(const std::string &from_api_path, const std::string &to_api_path,
const bool &overwrite = true) {
auto ret = api_error::not_implemented;
if (provider_.is_rename_supported()) {
// Don't rename if paths are the same
if ((ret = (from_api_path == to_api_path) ? api_error::file_exists : api_error::success) ==
api_error::success) {
retry_db_.pause();
unique_recur_mutex_lock l(open_file_mutex_);
// Check allow overwrite if file exists
if (not overwrite && provider_.is_file(to_api_path)) {
l.unlock();
ret = api_error::file_exists;
} else {
// Don't rename if source does not exist
if ((ret = provider_.is_file(from_api_path)
? api_error::success
: api_error::item_not_found) == api_error::success) {
// Don't rename if destination file is downloading
if ((ret = dm_.is_processing(to_api_path) ? api_error::file_in_use
: api_error::success) == api_error::success) {
// Don't rename if destination file has open handles
ret = api_error::file_in_use;
if (get_open_count(to_api_path) == 0u) {
if (provider_.is_file(
to_api_path)) { // Handle destination file exists (should overwrite)
filesystem_item fsi{};
if ((ret = get_filesystem_item(to_api_path, false, fsi)) == api_error::success) {
ret = api_error::os_error;
std::uint64_t file_size = 0u;
if (utils::file::get_file_size(fsi.source_path, file_size)) {
ret = provider_.remove_file(to_api_path);
if ((ret == api_error::success) || (ret == api_error::item_not_found)) {
if (retry_delete_file(fsi.source_path) && file_size) {
global_data::instance().update_used_space(file_size, 0, false);
}
ret = handle_file_rename(from_api_path, to_api_path);
}
}
}
l.unlock();
} else if (provider_.is_directory(to_api_path)) { // Handle destination is directory
l.unlock();
ret = api_error::directory_exists;
} else if (provider_.is_directory(utils::path::get_parent_api_path(
to_api_path))) { // Handle rename if destination directory exists
ret = handle_file_rename(from_api_path, to_api_path);
l.unlock();
} else { // Destination directory not found
l.unlock();
ret = api_error::directory_not_found;
}
}
} else if (provider_.is_directory(from_api_path)) {
l.unlock();
ret = api_error::directory_exists;
}
}
}
retry_db_.resume();
}
}
return ret;
}
api_error set_item_meta(const std::string &api_path, const std::string &key,
const std::string &value) override {
unique_recur_mutex_lock l(open_file_mutex_);
if (open_file_lookup_.find(api_path) == open_file_lookup_.end()) {
l.unlock();
return provider_.set_item_meta(api_path, key, value);
}
if (open_file_lookup_[api_path]->meta[key] != value) {
open_file_lookup_[api_path]->item.meta_changed = true;
open_file_lookup_[api_path]->meta[key] = value;
}
return api_error::success;
}
api_error set_item_meta(const std::string &api_path, const api_meta_map &meta) {
auto ret = api_error::success;
auto it = meta.begin();
for (std::size_t i = 0u; (ret == api_error::success) && (i < meta.size()); i++) {
ret = set_item_meta(api_path, it->first, it->second);
it++;
}
return ret;
}
void start() {
mutex_lock start_stop_lock(start_stop_mutex_);
if (not retry_thread_) {
stop_requested_ = false;
retry_thread_ = std::make_unique<std::thread>([this] {
while (not stop_requested_) {
const auto processed = retry_db_.process_all([this](const std::string &api_path) -> bool {
auto success = false;
event_system::instance().raise<failed_upload_retry>(api_path);
unique_recur_mutex_lock open_file_lock(open_file_mutex_);
if (open_file_lookup_.find(api_path) == open_file_lookup_.end()) {
open_file_lock.unlock();
filesystem_item fsi{};
const auto res = provider_.get_filesystem_item(api_path, false, fsi);
if ((res == api_error::success) ||
((res == api_error::item_not_found) && provider_.is_file(api_path))) {
if (provider_.upload_file(api_path, fsi.source_path, fsi.encryption_token) ==
api_error::success) {
success = true;
}
}
// Remove deleted files
if (not success && not provider_.is_file(api_path)) {
success = true;
}
} else {
// File is open, so force re-upload on close
open_file_lookup_[api_path]->item.changed = true;
open_file_lock.unlock();
success = true;
}
return success;
});
if (not processed && not stop_requested_) {
unique_mutex_lock retryLock(retry_mutex_);
if (not stop_requested_) {
retry_notify_.wait_for(retryLock, 5s);
}
}
}
});
}
}
void stop() {
mutex_lock start_stop_lock(start_stop_mutex_);
if (retry_thread_) {
event_system::instance().raise<service_shutdown>("open_file_table");
stop_requested_ = true;
unique_mutex_lock retry_lock(retry_mutex_);
retry_notify_.notify_all();
retry_lock.unlock();
retry_thread_->join();
retry_thread_.reset();
}
}
void update_directory_item(directory_item &di) const override {
recur_mutex_lock l(open_file_mutex_);
const auto it = open_file_lookup_.find(di.api_path);
if (it != open_file_lookup_.end()) {
const auto &ofi = open_file_lookup_.at(di.api_path);
di.meta = ofi->meta;
if (not di.directory) {
di.size = ofi->item.size;
}
}
}
};
} // namespace repertory
#endif // INCLUDE_DRIVES_OPEN_FILE_TABLE_HPP_

View File

@@ -1,25 +1,27 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_REMOTE_I_REMOTEJSON_HPP_
#define INCLUDE_DRIVES_REMOTE_I_REMOTEJSON_HPP_
#ifndef INCLUDE_DRIVES_REMOTE_I_REMOTE_JSON_HPP_
#define INCLUDE_DRIVES_REMOTE_I_REMOTE_JSON_HPP_
#include "common.hpp"
#include "comm/packet/packet.hpp"
namespace repertory {
@@ -27,18 +29,19 @@ class i_remote_json {
INTERFACE_SETUP(i_remote_json);
public:
virtual packet::error_type json_create_directory_snapshot(const std::string &path,
json &json_data) = 0;
[[nodiscard]] virtual auto
json_create_directory_snapshot(const std::string &path, json &json_data)
-> packet::error_type = 0;
virtual packet::error_type json_read_directory_snapshot(const std::string &path,
const remote::file_handle &handle,
const std::uint32_t &page,
json &json_data) = 0;
[[nodiscard]] virtual auto json_read_directory_snapshot(
const std::string &path, const remote::file_handle &handle,
std::uint32_t page, json &json_data) -> packet::error_type = 0;
virtual packet::error_type
[[nodiscard]] virtual auto
json_release_directory_snapshot(const std::string &path,
const remote::file_handle &handle) = 0;
const remote::file_handle &handle)
-> packet::error_type = 0;
};
} // namespace repertory
#endif // INCLUDE_DRIVES_REMOTE_I_REMOTEJSON_HPP_
#endif // INCLUDE_DRIVES_REMOTE_I_REMOTE_JSON_HPP_

View File

@@ -1,25 +1,27 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_REMOTE_REMOTE_OPEN_FILE_TABLE_HPP_
#define INCLUDE_DRIVES_REMOTE_REMOTE_OPEN_FILE_TABLE_HPP_
#include "common.hpp"
#include "types/remote.hpp"
#include "types/repertory.hpp"
@@ -34,6 +36,7 @@ protected:
struct compat_open_info {
std::size_t count = 0u;
std::string client_id = "";
std::string path;
};
struct open_info {
@@ -45,11 +48,11 @@ protected:
private:
std::unordered_map<remote::file_handle, compat_open_info> compat_lookup_;
std::mutex compat_mutex_;
std::recursive_mutex compat_mutex_;
std::unordered_map<std::string, std::vector<void *>> directory_lookup_;
std::mutex directory_mutex_;
std::unordered_map<OSHandle, open_info> file_lookup_;
std::mutex file_mutex_;
std::recursive_mutex directory_mutex_;
std::unordered_map<native_handle, open_info> file_lookup_;
mutable std::recursive_mutex file_mutex_;
protected:
void add_directory(const std::string &client_id, void *dir);
@@ -59,36 +62,52 @@ protected:
virtual void delete_open_directory(void *dir) = 0;
#ifdef _WIN32
bool get_directory_buffer(const OSHandle &handle, PVOID *&buffer);
#endif
[[nodiscard]] auto get_directory_buffer(const native_handle &handle,
PVOID *&buffer) -> bool;
#endif // _WIN32
bool get_open_info(const OSHandle &handle, open_info &oi);
[[nodiscard]] auto get_open_file_path(const native_handle &handle)
-> std::string;
std::string get_open_file_path(const OSHandle &handle);
[[nodiscard]] auto get_open_info(const native_handle &handle, open_info &oi)
-> bool;
bool has_open_directory(const std::string &client_id, void *dir);
[[nodiscard]] auto has_open_directory(const std::string &client_id, void *dir)
-> bool;
int has_compat_open_info(const remote::file_handle &handle, const int &error_return);
[[nodiscard]] auto has_compat_open_info(const remote::file_handle &handle,
int error_return) -> int;
template <typename error_type>
error_type has_open_info(const OSHandle &handle, const error_type &error_return) {
mutex_lock file_lock(file_mutex_);
return ((file_lookup_.find(handle) == file_lookup_.end()) ? error_return : 0);
[[nodiscard]] auto has_open_info(const native_handle &handle,
const error_type &error_return)
-> error_type {
recur_mutex_lock file_lock(file_mutex_);
return ((file_lookup_.find(handle) == file_lookup_.end()) ? error_return
: 0);
}
void remove_all(const std::string &file_path);
void remove_compat_open_info(const remote::file_handle &handle);
bool remove_directory(const std::string &client_id, void *dir);
auto remove_directory(const std::string &client_id, void *dir) -> bool;
void remove_open_info(const OSHandle &handle);
void remove_open_info(const native_handle &handle);
void set_client_id(const OSHandle &handle, const std::string &client_id);
void set_client_id(const native_handle &handle, const std::string &client_id);
void set_compat_client_id(const remote::file_handle &handle, const std::string &client_id);
void set_compat_client_id(const remote::file_handle &handle,
const std::string &client_id);
void set_compat_open_info(const remote::file_handle &handle);
void set_compat_open_info(const remote::file_handle &handle,
const std::string &file_path);
void set_open_info(const OSHandle &handle, open_info oi);
void set_open_info(const native_handle &handle, open_info oi);
public:
[[nodiscard]] auto get_open_file_count(const std::string &file_path) const
-> std::size_t;
};
} // namespace repertory

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +1,28 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_WINFSP_I_WINFSP_DRIVE_HPP_
#define INCLUDE_DRIVES_WINFSP_I_WINFSP_DRIVE_HPP_
#ifdef _WIN32
#include "common.hpp"
#include "types/remote.hpp"
#include "types/repertory.hpp"
@@ -29,31 +31,43 @@ class i_winfsp_drive {
INTERFACE_SETUP(i_winfsp_drive);
public:
virtual std::uint64_t get_directory_item_count(const std::string &api_path) const = 0;
[[nodiscard]] virtual auto
get_directory_item_count(const std::string &api_path) const
-> std::uint64_t = 0;
virtual directory_item_list get_directory_items(const std::string &api_path) const = 0;
[[nodiscard]] virtual auto
get_directory_items(const std::string &api_path) const
-> directory_item_list = 0;
virtual std::uint64_t get_file_size(const std::string &api_path) const = 0;
[[nodiscard]] virtual auto get_file_size(const std::string &api_path) const
-> std::uint64_t = 0;
virtual api_error get_item_meta(const std::string &api_path, const std::string &name,
std::string &value) const = 0;
[[nodiscard]] virtual auto get_item_meta(const std::string &api_path,
const std::string &name,
std::string &value) const
-> api_error = 0;
virtual api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const = 0;
[[nodiscard]] virtual auto get_item_meta(const std::string &api_path,
api_meta_map &meta) const
-> api_error = 0;
virtual NTSTATUS get_security_by_name(PWSTR file_name, PUINT32 attributes,
PSECURITY_DESCRIPTOR descriptor,
std::uint64_t *descriptor_size) = 0;
[[nodiscard]] virtual auto
get_security_by_name(PWSTR file_name, PUINT32 attributes,
PSECURITY_DESCRIPTOR descriptor,
std::uint64_t *descriptor_size) -> NTSTATUS = 0;
virtual std::uint64_t get_total_drive_space() const = 0;
[[nodiscard]] virtual auto get_total_drive_space() const -> std::uint64_t = 0;
virtual std::uint64_t get_total_item_count() const = 0;
[[nodiscard]] virtual auto get_total_item_count() const -> std::uint64_t = 0;
virtual std::uint64_t get_used_drive_space() const = 0;
[[nodiscard]] virtual auto get_used_drive_space() const -> std::uint64_t = 0;
virtual void get_volume_info(UINT64 &total_size, UINT64 &free_size,
std::string &volume_label) const = 0;
virtual api_error populate_file_info(const std::string &api_path, remote::file_info &fi) = 0;
[[nodiscard]] virtual auto populate_file_info(const std::string &api_path,
remote::file_info &fi)
-> api_error = 0;
};
} // namespace repertory

View File

@@ -1,25 +1,27 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_I_REMOTE_INSTANCE_HPP_
#define INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_I_REMOTE_INSTANCE_HPP_
#include "common.hpp"
#include "drives/remote/i_remote_json.hpp"
namespace repertory::remote_winfsp {
@@ -27,68 +29,89 @@ class i_remote_instance : public virtual i_remote_json {
INTERFACE_SETUP(i_remote_instance);
public:
virtual packet::error_type winfsp_can_delete(PVOID fileDesc, PWSTR fileName) = 0;
virtual auto winfsp_can_delete(PVOID fileDesc, PWSTR fileName)
-> packet::error_type = 0;
virtual packet::error_type winfsp_cleanup(PVOID fileDesc, PWSTR fileName, UINT32 flags,
BOOLEAN &wasClosed) = 0;
virtual auto winfsp_cleanup(PVOID fileDesc, PWSTR fileName, UINT32 flags,
BOOLEAN &wasClosed) -> packet::error_type = 0;
virtual packet::error_type winfsp_close(PVOID fileDesc) = 0;
virtual auto winfsp_close(PVOID fileDesc) -> packet::error_type = 0;
virtual packet::error_type winfsp_create(PWSTR fileName, UINT32 createOptions,
UINT32 grantedAccess, UINT32 fileAttributes,
UINT64 allocationSize, PVOID *fileDesc,
remote::file_info *fileInfo, std::string &normalizedName,
BOOLEAN &exists) = 0;
virtual auto winfsp_create(PWSTR fileName, UINT32 createOptions,
UINT32 grantedAccess, UINT32 fileAttributes,
UINT64 allocationSize, PVOID *fileDesc,
remote::file_info *fileInfo,
std::string &normalizedName, BOOLEAN &exists)
-> packet::error_type = 0;
virtual packet::error_type winfsp_flush(PVOID fileDesc, remote::file_info *fileInfo) = 0;
virtual auto winfsp_flush(PVOID fileDesc, remote::file_info *fileInfo)
-> packet::error_type = 0;
virtual packet::error_type winfsp_get_dir_buffer(PVOID fileDesc, PVOID *&ptr) = 0;
virtual auto winfsp_get_dir_buffer(PVOID fileDesc, PVOID *&ptr)
-> packet::error_type = 0;
virtual packet::error_type winfsp_get_file_info(PVOID fileDesc, remote::file_info *fileInfo) = 0;
virtual auto winfsp_get_file_info(PVOID fileDesc, remote::file_info *fileInfo)
-> packet::error_type = 0;
virtual packet::error_type winfsp_get_security_by_name(PWSTR fileName, PUINT32 fileAttributes,
std::uint64_t *securityDescriptorSize,
std::wstring &strDescriptor) = 0;
virtual auto
winfsp_get_security_by_name(PWSTR fileName, PUINT32 fileAttributes,
std::uint64_t *securityDescriptorSize,
std::wstring &strDescriptor)
-> packet::error_type = 0;
virtual packet::error_type winfsp_get_volume_info(UINT64 &totalSize, UINT64 &freeSize,
std::string &volumeLabel) = 0;
virtual auto winfsp_get_volume_info(UINT64 &totalSize, UINT64 &freeSize,
std::string &volumeLabel)
-> packet::error_type = 0;
virtual packet::error_type winfsp_mounted(const std::wstring &location) = 0;
virtual auto winfsp_mounted(const std::wstring &location)
-> packet::error_type = 0;
virtual packet::error_type winfsp_open(PWSTR fileName, UINT32 createOptions, UINT32 grantedAccess,
PVOID *fileDesc, remote::file_info *fileInfo,
std::string &normalizedName) = 0;
virtual auto winfsp_open(PWSTR fileName, UINT32 createOptions,
UINT32 grantedAccess, PVOID *fileDesc,
remote::file_info *fileInfo,
std::string &normalizedName)
-> packet::error_type = 0;
virtual packet::error_type winfsp_overwrite(PVOID fileDesc, UINT32 fileAttributes,
BOOLEAN replaceFileAttributes, UINT64 allocationSize,
remote::file_info *fileInfo) = 0;
virtual auto winfsp_overwrite(PVOID fileDesc, UINT32 fileAttributes,
BOOLEAN replaceFileAttributes,
UINT64 allocationSize,
remote::file_info *fileInfo)
-> packet::error_type = 0;
virtual packet::error_type winfsp_read(PVOID fileDesc, PVOID buffer, UINT64 offset, UINT32 length,
PUINT32 bytesTransferred) = 0;
virtual auto winfsp_read(PVOID fileDesc, PVOID buffer, UINT64 offset,
UINT32 length, PUINT32 bytesTransferred)
-> packet::error_type = 0;
virtual packet::error_type winfsp_read_directory(PVOID fileDesc, PWSTR pattern, PWSTR marker,
json &itemList) = 0;
virtual auto winfsp_read_directory(PVOID fileDesc, PWSTR pattern,
PWSTR marker, json &itemList)
-> packet::error_type = 0;
virtual packet::error_type winfsp_rename(PVOID fileDesc, PWSTR fileName, PWSTR newFileName,
BOOLEAN replaceIfExists) = 0;
virtual auto winfsp_rename(PVOID fileDesc, PWSTR fileName, PWSTR newFileName,
BOOLEAN replaceIfExists) -> packet::error_type = 0;
virtual packet::error_type winfsp_set_basic_info(PVOID fileDesc, UINT32 fileAttributes,
UINT64 creationTime, UINT64 lastAccessTime,
UINT64 lastWriteTime, UINT64 changeTime,
remote::file_info *fileInfo) = 0;
virtual auto winfsp_set_basic_info(PVOID fileDesc, UINT32 fileAttributes,
UINT64 creationTime, UINT64 lastAccessTime,
UINT64 lastWriteTime, UINT64 changeTime,
remote::file_info *fileInfo)
-> packet::error_type = 0;
virtual packet::error_type winfsp_set_file_size(PVOID fileDesc, UINT64 newSize,
BOOLEAN setAllocationSize,
remote::file_info *fileInfo) = 0;
virtual auto winfsp_set_file_size(PVOID fileDesc, UINT64 newSize,
BOOLEAN setAllocationSize,
remote::file_info *fileInfo)
-> packet::error_type = 0;
virtual packet::error_type winfsp_unmounted(const std::wstring &location) = 0;
virtual auto winfsp_unmounted(const std::wstring &location)
-> packet::error_type = 0;
virtual packet::error_type winfsp_write(PVOID fileDesc, PVOID buffer, UINT64 offset,
UINT32 length, BOOLEAN writeToEndOfFile,
BOOLEAN constrainedIo, PUINT32 bytesTransferred,
remote::file_info *fileInfo) = 0;
virtual auto winfsp_write(PVOID fileDesc, PVOID buffer, UINT64 offset,
UINT32 length, BOOLEAN writeToEndOfFile,
BOOLEAN constrainedIo, PUINT32 bytesTransferred,
remote::file_info *fileInfo)
-> packet::error_type = 0;
};
typedef std::function<std::unique_ptr<i_remote_instance>()> remote_instance_factory;
using remote_instance_factory =
std::function<std::unique_ptr<i_remote_instance>()>;
} // namespace repertory::remote_winfsp
#endif // INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_I_REMOTE_INSTANCE_HPP_

View File

@@ -1,34 +1,37 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_CLIENT_HPP_
#define INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_CLIENT_HPP_
#include "common.hpp"
#include "comm/packet/packet.hpp"
#include "comm/packet/packet_client.hpp"
#include "drives/winfsp/remotewinfsp/i_remote_instance.hpp"
#include "drives/remote/remote_open_file_table.hpp"
#include "drives/winfsp/remotewinfsp/i_remote_instance.hpp"
namespace repertory {
class app_config;
namespace remote_winfsp {
class remote_client final : public remote_open_file_table, public virtual i_remote_instance {
class remote_client final : public remote_open_file_table,
public virtual i_remote_instance {
public:
explicit remote_client(const app_config &config);
@@ -40,84 +43,97 @@ private:
#ifdef _WIN32
#define to_handle(x) (x)
#else
static OSHandle to_handle(PVOID file_desc) {
return static_cast<OSHandle>(reinterpret_cast<std::uint64_t>(file_desc));
}
static auto to_handle(PVOID file_desc) -> native_handle;
#endif
protected:
void delete_open_directory(void * /*dir*/) override {}
public:
packet::error_type json_create_directory_snapshot(const std::string &path,
json &json_data) override;
auto json_create_directory_snapshot(const std::string &path, json &json_data)
-> packet::error_type override;
packet::error_type json_read_directory_snapshot(const std::string &path,
const remote::file_handle &handle,
const std::uint32_t &page,
json &json_data) override;
auto json_read_directory_snapshot(const std::string &path,
const remote::file_handle &handle,
std::uint32_t page, json &json_data)
-> packet::error_type override;
packet::error_type json_release_directory_snapshot(const std::string &path,
const remote::file_handle &handle) override;
auto json_release_directory_snapshot(const std::string &path,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type winfsp_can_delete(PVOID file_desc, PWSTR file_name) override;
auto winfsp_can_delete(PVOID file_desc, PWSTR file_name)
-> packet::error_type override;
packet::error_type winfsp_cleanup(PVOID file_desc, PWSTR file_name, UINT32 flags,
BOOLEAN &was_closed) override;
auto winfsp_cleanup(PVOID file_desc, PWSTR file_name, UINT32 flags,
BOOLEAN &was_closed) -> packet::error_type override;
packet::error_type winfsp_close(PVOID file_desc) override;
auto winfsp_close(PVOID file_desc) -> packet::error_type override;
packet::error_type winfsp_create(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
UINT32 attributes, UINT64 allocation_size, PVOID *file_desc,
remote::file_info *file_info, std::string &normalized_name,
BOOLEAN &exists) override;
auto winfsp_create(PWSTR file_name, UINT32 create_options,
UINT32 granted_access, UINT32 attributes,
UINT64 allocation_size, PVOID *file_desc,
remote::file_info *file_info, std::string &normalized_name,
BOOLEAN &exists) -> packet::error_type override;
packet::error_type winfsp_flush(PVOID file_desc, remote::file_info *file_info) override;
auto winfsp_flush(PVOID file_desc, remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_get_dir_buffer(PVOID file_desc, PVOID *&ptr) override;
auto winfsp_get_dir_buffer(PVOID file_desc, PVOID *&ptr)
-> packet::error_type override;
packet::error_type winfsp_get_file_info(PVOID file_desc, remote::file_info *file_info) override;
auto winfsp_get_file_info(PVOID file_desc, remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes,
std::uint64_t *descriptor_size,
std::wstring &string_descriptor) override;
auto winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes,
std::uint64_t *descriptor_size,
std::wstring &string_descriptor)
-> packet::error_type override;
packet::error_type winfsp_get_volume_info(UINT64 &total_size, UINT64 &free_size,
std::string &volume_label) override;
auto winfsp_get_volume_info(UINT64 &total_size, UINT64 &free_size,
std::string &volume_label)
-> packet::error_type override;
packet::error_type winfsp_mounted(const std::wstring &location) override;
auto winfsp_mounted(const std::wstring &location)
-> packet::error_type override;
packet::error_type winfsp_open(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
PVOID *file_desc, remote::file_info *file_info,
std::string &normalized_name) override;
auto winfsp_open(PWSTR file_name, UINT32 create_options,
UINT32 granted_access, PVOID *file_desc,
remote::file_info *file_info, std::string &normalized_name)
-> packet::error_type override;
packet::error_type winfsp_overwrite(PVOID file_desc, UINT32 attributes,
BOOLEAN replace_attributes, UINT64 allocation_size,
remote::file_info *file_info) override;
auto winfsp_overwrite(PVOID file_desc, UINT32 attributes,
BOOLEAN replace_attributes, UINT64 allocation_size,
remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
PUINT32 bytes_transferred) override;
auto winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
PUINT32 bytes_transferred) -> packet::error_type override;
packet::error_type winfsp_read_directory(PVOID file_desc, PWSTR pattern, PWSTR marker,
json &itemList) override;
auto winfsp_read_directory(PVOID file_desc, PWSTR pattern, PWSTR marker,
json &itemList) -> packet::error_type override;
packet::error_type winfsp_rename(PVOID file_desc, PWSTR file_name, PWSTR new_file_name,
BOOLEAN replace_if_exists) override;
auto winfsp_rename(PVOID file_desc, PWSTR file_name, PWSTR new_file_name,
BOOLEAN replace_if_exists) -> packet::error_type override;
packet::error_type winfsp_set_basic_info(PVOID file_desc, UINT32 attributes, UINT64 creation_time,
UINT64 last_access_time, UINT64 last_write_time,
UINT64 change_time,
remote::file_info *file_info) override;
auto winfsp_set_basic_info(PVOID file_desc, UINT32 attributes,
UINT64 creation_time, UINT64 last_access_time,
UINT64 last_write_time, UINT64 change_time,
remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_set_file_size(PVOID file_desc, UINT64 new_size,
BOOLEAN set_allocation_size,
remote::file_info *file_info) override;
auto winfsp_set_file_size(PVOID file_desc, UINT64 new_size,
BOOLEAN set_allocation_size,
remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_unmounted(const std::wstring &location) override;
auto winfsp_unmounted(const std::wstring &location)
-> packet::error_type override;
packet::error_type winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
BOOLEAN write_to_end, BOOLEAN constrained_io,
PUINT32 bytes_transferred, remote::file_info *file_info) override;
auto winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
BOOLEAN write_to_end, BOOLEAN constrained_io,
PUINT32 bytes_transferred, remote::file_info *file_info)
-> packet::error_type override;
};
} // namespace remote_winfsp
} // namespace repertory

View File

@@ -1,20 +1,23 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
// NOTE: Most of the WinFSP pass-through code has been modified from:
// https://github.com/billziss-gh/winfsp/blob/master/tst/passthrough-cpp/passthrough-cpp.cpp
@@ -22,7 +25,6 @@
#define INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_SERVER_HPP_
#ifdef _WIN32
#include "common.hpp"
#include "comm/packet/packet.hpp"
#include "drives/remote/remote_server_base.hpp"
#include "drives/winfsp/i_winfsp_drive.hpp"
@@ -32,207 +34,250 @@ class app_config;
namespace remote_winfsp {
class remote_server final : public virtual remote_server_base<i_winfsp_drive> {
public:
remote_server(app_config &config, i_winfsp_drive &drive, const std::string &mount_location)
: remote_server_base(config, drive, mount_location) {}
remote_server(app_config &config, i_winfsp_drive &drive,
const std::string &mount_location)
: remote_server_base(config, drive,
utils::string::to_lower(mount_location)) {}
private:
std::string construct_path(std::string path);
[[nodiscard]] auto construct_path(std::string path) -> std::string;
packet::error_type populate_file_info(const std::string &api_path, remote::file_info &file_info);
[[nodiscard]] auto populate_file_info(const std::string &api_path,
remote::file_info &file_info)
-> packet::error_type;
void populate_stat(const char *path, const bool &directory, remote::stat &st,
void populate_stat(const char *path, bool directory, remote::stat &st,
const struct _stat64 &st1);
public:
// FUSE Layer
packet::error_type fuse_access(const char *path, const std::int32_t &mask) override;
auto fuse_access(const char *path, const std::int32_t &mask)
-> packet::error_type override;
packet::error_type fuse_chflags(const char *path, const std::uint32_t &flags) override;
auto fuse_chflags(const char *path, std::uint32_t flags)
-> packet::error_type override;
packet::error_type fuse_chmod(const char *path, const remote::file_mode &mode) override;
auto fuse_chmod(const char *path, const remote::file_mode &mode)
-> packet::error_type override;
packet::error_type fuse_chown(const char *path, const remote::user_id &uid,
const remote::group_id &gid) override;
auto fuse_chown(const char *path, const remote::user_id &uid,
const remote::group_id &gid) -> packet::error_type override;
packet::error_type fuse_destroy() override;
auto fuse_destroy() -> packet::error_type override;
/*packet::error_type fuse_fallocate(const char *path, const std::int32_t &mode,
const remote::file_offset &offset,
const remote::file_offset &length,
const remote::file_handle &handle) override ;*/
/*packet::error_type fuse_fallocate(const char *path, const std::int32_t
&mode, const remote::file_offset &offset, const remote::file_offset
&length, const remote::file_handle &handle) override ;*/
packet::error_type fuse_fgetattr(const char *path, remote::stat &st, bool &directory,
const remote::file_handle &handle) override;
auto fuse_fgetattr(const char *path, remote::stat &st, bool &directory,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_fsetattr_x(const char *path, const remote::setattr_x &attr,
const remote::file_handle &handle) override;
auto fuse_fsetattr_x(const char *path, const remote::setattr_x &attr,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_fsync(const char *path, const std::int32_t &datasync,
const remote::file_handle &handle) override;
auto fuse_fsync(const char *path, const std::int32_t &datasync,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_ftruncate(const char *path, const remote::file_offset &size,
const remote::file_handle &handle) override;
auto fuse_ftruncate(const char *path, const remote::file_offset &size,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_getattr(const char *path, remote::stat &st, bool &directory) override;
auto fuse_getattr(const char *path, remote::stat &st, bool &directory)
-> packet::error_type override;
/*packet::error_type fuse_getxattr(const char *path, const char *name, char *value,
const remote::file_size &size) override ;
/*packet::error_type fuse_getxattr(const char *path, const char *name, char
*value, const remote::file_size &size) override ;
packet::error_type fuse_getxattrOSX(const char *path, const char *name, char *value,
const remote::file_size &size,
const std::uint32_t &position) override ;*/
packet::error_type fuse_getxattrOSX(const char *path, const char *name, char
*value, const remote::file_size &size, std::uint32_t position) override ;*/
packet::error_type fuse_getxtimes(const char *path, remote::file_time &bkuptime,
remote::file_time &crtime) override;
auto fuse_getxtimes(const char *path, remote::file_time &bkuptime,
remote::file_time &crtime) -> packet::error_type override;
packet::error_type fuse_init() override;
auto fuse_init() -> packet::error_type override;
/*packet::error_type fuse_listxattr(const char *path, char *buffer,
const remote::file_size &size) override ;*/
const remote::file_size &size) override
;*/
packet::error_type fuse_mkdir(const char *path, const remote::file_mode &mode) override;
auto fuse_mkdir(const char *path, const remote::file_mode &mode)
-> packet::error_type override;
packet::error_type fuse_opendir(const char *path, remote::file_handle &handle) override;
auto fuse_opendir(const char *path, remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_create(const char *path, const remote::file_mode &mode,
const remote::open_flags &flags,
remote::file_handle &handle) override;
auto fuse_create(const char *path, const remote::file_mode &mode,
const remote::open_flags &flags, remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_open(const char *path, const remote::open_flags &flags,
remote::file_handle &handle) override;
auto fuse_open(const char *path, const remote::open_flags &flags,
remote::file_handle &handle) -> packet::error_type override;
packet::error_type fuse_read(const char *path, char *buffer, const remote::file_size &read_size,
const remote::file_offset &read_offset,
const remote::file_handle &handle) override;
auto fuse_read(const char *path, char *buffer,
const remote::file_size &read_size,
const remote::file_offset &read_offset,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_rename(const char *from, const char *to) override;
auto fuse_rename(const char *from, const char *to)
-> packet::error_type override;
packet::error_type fuse_write(const char *path, const char *buffer,
const remote::file_size &write_size,
const remote::file_offset &write_offset,
const remote::file_handle &handle) override;
auto fuse_write(const char *path, const char *buffer,
const remote::file_size &write_size,
const remote::file_offset &write_offset,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_write_base64(const char *path, const char *buffer,
const remote::file_size &write_size,
const remote::file_offset &write_offset,
const remote::file_handle &handle) override;
auto fuse_write_base64(const char *path, const char *buffer,
const remote::file_size &write_size,
const remote::file_offset &write_offset,
const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_readdir(const char *path, const remote::file_offset &offset,
const remote::file_handle &handle,
std::string &item_path) override;
auto fuse_readdir(const char *path, const remote::file_offset &offset,
const remote::file_handle &handle, std::string &item_path)
-> packet::error_type override;
packet::error_type fuse_release(const char *path, const remote::file_handle &handle) override;
auto fuse_release(const char *path, const remote::file_handle &handle)
-> packet::error_type override;
packet::error_type fuse_releasedir(const char *path, const remote::file_handle &handle) override;
auto fuse_releasedir(const char *path, const remote::file_handle &handle)
-> packet::error_type override;
/*packet::error_type fuse_removexattr(const char *path, const char *name) override ;*/
/*packet::error_type fuse_removexattr(const char *path, const char *name)
* override ;*/
packet::error_type fuse_rmdir(const char *path) override;
auto fuse_rmdir(const char *path) -> packet::error_type override;
packet::error_type fuse_setattr_x(const char *path, remote::setattr_x &attr) override;
auto fuse_setattr_x(const char *path, remote::setattr_x &attr)
-> packet::error_type override;
packet::error_type fuse_setbkuptime(const char *path, const remote::file_time &bkuptime) override;
auto fuse_setbkuptime(const char *path, const remote::file_time &bkuptime)
-> packet::error_type override;
packet::error_type fuse_setchgtime(const char *path, const remote::file_time &chgtime) override;
auto fuse_setchgtime(const char *path, const remote::file_time &chgtime)
-> packet::error_type override;
packet::error_type fuse_setcrtime(const char *path, const remote::file_time &crtime) override;
auto fuse_setcrtime(const char *path, const remote::file_time &crtime)
-> packet::error_type override;
packet::error_type fuse_setvolname(const char *volname) override;
auto fuse_setvolname(const char *volname) -> packet::error_type override;
/*packet::error_type fuse_setxattr(const char *path, const char *name, const char *value,
const remote::file_size &size,
const std::int32_t &flags) override ;
/*packet::error_type fuse_setxattr(const char *path, const char *name, const
char *value, const remote::file_size &size, const std::int32_t &flags)
override ;
packet::error_type fuse_setxattr_osx(const char *path, const char *name, const char *value,
const remote::file_size &size, const std::int32_t &flags,
const std::uint32_t &position) override ;*/
packet::error_type fuse_setxattr_osx(const char *path, const char *name, const
char *value, const remote::file_size &size, const std::int32_t &flags,
std::uint32_t position) override ;*/
packet::error_type fuse_statfs(const char *path, const std::uint64_t &frsize,
remote::statfs &st) override;
auto fuse_statfs(const char *path, std::uint64_t frsize, remote::statfs &st)
-> packet::error_type override;
packet::error_type fuse_statfs_x(const char *path, const std::uint64_t &bsize,
remote::statfs_x &st) override;
auto fuse_statfs_x(const char *path, std::uint64_t bsize,
remote::statfs_x &st) -> packet::error_type override;
packet::error_type fuse_truncate(const char *path, const remote::file_offset &size) override;
auto fuse_truncate(const char *path, const remote::file_offset &size)
-> packet::error_type override;
packet::error_type fuse_unlink(const char *path) override;
auto fuse_unlink(const char *path) -> packet::error_type override;
packet::error_type fuse_utimens(const char *path, const remote::file_time *tv,
const std::uint64_t &op0, const std::uint64_t &op1) override;
auto fuse_utimens(const char *path, const remote::file_time *tv,
std::uint64_t op0, std::uint64_t op1)
-> packet::error_type override;
void set_fuse_uid_gid(const remote::user_id &, const remote::group_id &) override {}
void set_fuse_uid_gid(const remote::user_id &,
const remote::group_id &) override {}
// JSON Layer
packet::error_type json_create_directory_snapshot(const std::string &path,
json &json_data) override;
auto json_create_directory_snapshot(const std::string &path, json &json_data)
-> packet::error_type override;
packet::error_type json_read_directory_snapshot(const std::string &path,
const remote::file_handle &handle,
const std::uint32_t &page,
json &json_data) override;
auto json_read_directory_snapshot(const std::string &path,
const remote::file_handle &handle,
std::uint32_t page, json &json_data)
-> packet::error_type override;
packet::error_type json_release_directory_snapshot(const std::string &path,
const remote::file_handle &handle) override;
auto json_release_directory_snapshot(const std::string &path,
const remote::file_handle &handle)
-> packet::error_type override;
// WinFSP Layer
packet::error_type winfsp_can_delete(PVOID file_desc, PWSTR file_name) override;
auto winfsp_can_delete(PVOID file_desc, PWSTR file_name)
-> packet::error_type override;
packet::error_type winfsp_cleanup(PVOID file_desc, PWSTR file_name, UINT32 flags,
BOOLEAN &was_closed) override;
auto winfsp_cleanup(PVOID file_desc, PWSTR file_name, UINT32 flags,
BOOLEAN &was_closed) -> packet::error_type override;
packet::error_type winfsp_close(PVOID file_desc) override;
auto winfsp_close(PVOID file_desc) -> packet::error_type override;
packet::error_type winfsp_create(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
UINT32 attributes, UINT64 allocation_size, PVOID *file_desc,
remote::file_info *file_info, std::string &normalized_name,
BOOLEAN &exists) override;
auto winfsp_create(PWSTR file_name, UINT32 create_options,
UINT32 granted_access, UINT32 attributes,
UINT64 allocation_size, PVOID *file_desc,
remote::file_info *file_info, std::string &normalized_name,
BOOLEAN &exists) -> packet::error_type override;
packet::error_type winfsp_flush(PVOID file_desc, remote::file_info *file_info) override;
auto winfsp_flush(PVOID file_desc, remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_get_dir_buffer(PVOID file_desc, PVOID *&ptr) override;
auto winfsp_get_dir_buffer(PVOID file_desc, PVOID *&ptr)
-> packet::error_type override;
packet::error_type winfsp_get_file_info(PVOID file_desc, remote::file_info *file_info) override;
auto winfsp_get_file_info(PVOID file_desc, remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes,
std::uint64_t *descriptor_size,
std::wstring &string_descriptor) override;
auto winfsp_get_security_by_name(PWSTR file_name, PUINT32 attributes,
std::uint64_t *descriptor_size,
std::wstring &string_descriptor)
-> packet::error_type override;
packet::error_type winfsp_get_volume_info(UINT64 &total_size, UINT64 &free_size,
std::string &volume_label) override;
auto winfsp_get_volume_info(UINT64 &total_size, UINT64 &free_size,
std::string &volume_label)
-> packet::error_type override;
packet::error_type winfsp_mounted(const std::wstring &location) override;
auto winfsp_mounted(const std::wstring &location)
-> packet::error_type override;
packet::error_type winfsp_open(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
PVOID *file_desc, remote::file_info *file_info,
std::string &normalized_name) override;
auto winfsp_open(PWSTR file_name, UINT32 create_options,
UINT32 granted_access, PVOID *file_desc,
remote::file_info *file_info, std::string &normalized_name)
-> packet::error_type override;
packet::error_type winfsp_overwrite(PVOID file_desc, UINT32 attributes,
BOOLEAN replace_attributes, UINT64 allocation_size,
remote::file_info *file_info) override;
auto winfsp_overwrite(PVOID file_desc, UINT32 attributes,
BOOLEAN replace_attributes, UINT64 allocation_size,
remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
PUINT32 bytes_transferred) override;
auto winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
PUINT32 bytes_transferred) -> packet::error_type override;
packet::error_type winfsp_read_directory(PVOID file_desc, PWSTR pattern, PWSTR marker,
json &item_list) override;
auto winfsp_read_directory(PVOID file_desc, PWSTR pattern, PWSTR marker,
json &item_list) -> packet::error_type override;
packet::error_type winfsp_rename(PVOID file_desc, PWSTR file_name, PWSTR new_file_name,
BOOLEAN replace_if_exists) override;
auto winfsp_rename(PVOID file_desc, PWSTR file_name, PWSTR new_file_name,
BOOLEAN replace_if_exists) -> packet::error_type override;
packet::error_type winfsp_set_basic_info(PVOID file_desc, UINT32 attributes, UINT64 creation_time,
UINT64 last_access_time, UINT64 last_write_time,
UINT64 change_time,
remote::file_info *file_info) override;
auto winfsp_set_basic_info(PVOID file_desc, UINT32 attributes,
UINT64 creation_time, UINT64 last_access_time,
UINT64 last_write_time, UINT64 change_time,
remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_set_file_size(PVOID file_desc, UINT64 newSize,
BOOLEAN set_allocation_size,
remote::file_info *file_info) override;
auto winfsp_set_file_size(PVOID file_desc, UINT64 newSize,
BOOLEAN set_allocation_size,
remote::file_info *file_info)
-> packet::error_type override;
packet::error_type winfsp_unmounted(const std::wstring &location) override;
auto winfsp_unmounted(const std::wstring &location)
-> packet::error_type override;
packet::error_type winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
BOOLEAN write_to_end, BOOLEAN constrained_io,
PUINT32 bytes_transferred, remote::file_info *file_info) override;
auto winfsp_write(PVOID file_desc, PVOID buffer, UINT64 offset, UINT32 length,
BOOLEAN write_to_end, BOOLEAN constrained_io,
PUINT32 bytes_transferred, remote::file_info *file_info)
-> packet::error_type override;
};
} // namespace remote_winfsp
} // namespace repertory

View File

@@ -1,26 +1,28 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_WINFSP_DRIVE_HPP_
#define INCLUDE_DRIVES_WINFSP_REMOTEWINFSP_REMOTE_WINFSP_DRIVE_HPP_
#ifdef _WIN32
#include "common.hpp"
#include "drives/winfsp/remotewinfsp/i_remote_instance.hpp"
#include "events/event_system.hpp"
@@ -33,16 +35,16 @@ class remote_winfsp_drive final : public virtual FileSystemBase {
E_CONSUMER();
public:
remote_winfsp_drive(app_config &config, lock_data &lockData,
remote_instance_factory remoteInstanceFactory);
remote_winfsp_drive(app_config &config, remote_instance_factory factory,
lock_data &lock);
~remote_winfsp_drive() override { E_CONSUMER_RELEASE(); }
public:
class winfsp_service : virtual public Service {
public:
winfsp_service(lock_data &lock, remote_winfsp_drive &drive, std::vector<std::string> drive_args,
app_config &config);
winfsp_service(lock_data &lock, remote_winfsp_drive &drive,
std::vector<std::string> drive_args, app_config &config);
~winfsp_service() override = default;
@@ -54,9 +56,9 @@ public:
FileSystemHost host_;
protected:
NTSTATUS OnStart(ULONG, PWSTR *) override;
auto OnStart(ULONG, PWSTR *) -> NTSTATUS override;
NTSTATUS OnStop() override;
auto OnStop() -> NTSTATUS override;
};
private:
@@ -68,64 +70,76 @@ private:
std::string mount_location_;
private:
void PopulateFileInfo(const json &item, FSP_FSCTL_FILE_INFO &file_info);
void populate_file_info(const json &item, FSP_FSCTL_FILE_INFO &file_info);
static void SetFileInfo(FileInfo &dest, const remote::file_info &src);
static void set_file_info(FileInfo &dest, const remote::file_info &src);
public:
NTSTATUS CanDelete(PVOID file_node, PVOID file_desc, PWSTR file_name) override;
auto CanDelete(PVOID file_node, PVOID file_desc, PWSTR file_name)
-> NTSTATUS override;
VOID Cleanup(PVOID file_node, PVOID file_desc, PWSTR file_name, ULONG flags) override;
VOID Cleanup(PVOID file_node, PVOID file_desc, PWSTR file_name,
ULONG flags) override;
VOID Close(PVOID file_node, PVOID file_desc) override;
NTSTATUS Create(PWSTR file_name, UINT32 create_options, UINT32 granted_access, UINT32 attributes,
PSECURITY_DESCRIPTOR descriptor, UINT64 allocation_size, PVOID *file_node,
PVOID *file_desc, OpenFileInfo *ofi) override;
auto Create(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
UINT32 attributes, PSECURITY_DESCRIPTOR descriptor,
UINT64 allocation_size, PVOID *file_node, PVOID *file_desc,
OpenFileInfo *ofi) -> NTSTATUS override;
NTSTATUS Flush(PVOID file_node, PVOID file_desc, FileInfo *file_info) override;
auto Flush(PVOID file_node, PVOID file_desc, FileInfo *file_info)
-> NTSTATUS override;
NTSTATUS GetFileInfo(PVOID file_node, PVOID file_desc, FileInfo *file_info) override;
auto GetFileInfo(PVOID file_node, PVOID file_desc, FileInfo *file_info)
-> NTSTATUS override;
NTSTATUS GetSecurityByName(PWSTR file_name, PUINT32 attributes, PSECURITY_DESCRIPTOR descriptor,
SIZE_T *descriptor_size) override;
auto GetSecurityByName(PWSTR file_name, PUINT32 attributes,
PSECURITY_DESCRIPTOR descriptor,
SIZE_T *descriptor_size) -> NTSTATUS override;
NTSTATUS GetVolumeInfo(VolumeInfo *volume_info) override;
auto GetVolumeInfo(VolumeInfo *volume_info) -> NTSTATUS override;
NTSTATUS Init(PVOID host) override;
auto Init(PVOID host) -> NTSTATUS override;
int mount(const std::vector<std::string> &drive_args);
[[nodiscard]] auto mount(const std::vector<std::string> &drive_args) -> int;
NTSTATUS Mounted(PVOID host) override;
auto Mounted(PVOID host) -> NTSTATUS override;
NTSTATUS Open(PWSTR file_name, UINT32 create_options, UINT32 granted_access, PVOID *file_node,
PVOID *file_desc, OpenFileInfo *ofi) override;
auto Open(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
PVOID *file_node, PVOID *file_desc, OpenFileInfo *ofi)
-> NTSTATUS override;
NTSTATUS Overwrite(PVOID file_node, PVOID file_desc, UINT32 attributes,
BOOLEAN replace_attributes, UINT64 allocation_size,
FileInfo *file_info) override;
auto Overwrite(PVOID file_node, PVOID file_desc, UINT32 attributes,
BOOLEAN replace_attributes, UINT64 allocation_size,
FileInfo *file_info) -> NTSTATUS override;
NTSTATUS Read(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset, ULONG length,
PULONG bytes_transferred) override;
auto Read(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset,
ULONG length, PULONG bytes_transferred) -> NTSTATUS override;
NTSTATUS ReadDirectory(PVOID file_node, PVOID file_desc, PWSTR pattern, PWSTR marker,
PVOID buffer, ULONG buffer_length, PULONG bytes_transferred) override;
auto ReadDirectory(PVOID file_node, PVOID file_desc, PWSTR pattern,
PWSTR marker, PVOID buffer, ULONG buffer_length,
PULONG bytes_transferred) -> NTSTATUS override;
NTSTATUS Rename(PVOID file_node, PVOID file_desc, PWSTR file_name, PWSTR new_file_name,
BOOLEAN replace_if_exists) override;
auto Rename(PVOID file_node, PVOID file_desc, PWSTR file_name,
PWSTR new_file_name, BOOLEAN replace_if_exists)
-> NTSTATUS override;
NTSTATUS SetBasicInfo(PVOID file_node, PVOID file_desc, UINT32 attributes, UINT64 creation_time,
UINT64 last_access_time, UINT64 last_write_time, UINT64 change_time,
FileInfo *file_info) override;
auto SetBasicInfo(PVOID file_node, PVOID file_desc, UINT32 attributes,
UINT64 creation_time, UINT64 last_access_time,
UINT64 last_write_time, UINT64 change_time,
FileInfo *file_info) -> NTSTATUS override;
NTSTATUS SetFileSize(PVOID file_node, PVOID file_desc, UINT64 new_size,
BOOLEAN set_allocation_size, FileInfo *file_info) override;
auto SetFileSize(PVOID file_node, PVOID file_desc, UINT64 new_size,
BOOLEAN set_allocation_size, FileInfo *file_info)
-> NTSTATUS override;
VOID Unmounted(PVOID host) override;
NTSTATUS Write(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset, ULONG length,
BOOLEAN write_to_end, BOOLEAN constrained_io, PULONG bytes_transferred,
FileInfo *file_info) override;
auto Write(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset,
ULONG length, BOOLEAN write_to_end, BOOLEAN constrained_io,
PULONG bytes_transferred, FileInfo *file_info)
-> NTSTATUS override;
void shutdown() { ::GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); }

View File

@@ -1,40 +1,42 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Copyright <2018-2023> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_DRIVES_WINFSP_WINFSP_DRIVE_HPP_
#define INCLUDE_DRIVES_WINFSP_WINFSP_DRIVE_HPP_
#ifdef _WIN32
#include "common.hpp"
#include "download/download_manager.hpp"
#include "drives/eviction.hpp"
#include "drives/i_open_file_table.hpp"
#include "drives/open_file_table.hpp"
#include "drives/winfsp/i_winfsp_drive.hpp"
#include "drives/winfsp/remotewinfsp/remote_server.hpp"
#include "events/event_system.hpp"
#include "file_manager/file_manager.hpp"
#include "rpc/server/full_server.hpp"
namespace repertory {
class app_config;
class lock_data;
class i_provider;
class winfsp_drive final : public virtual i_winfsp_drive, public virtual FileSystemBase {
class winfsp_drive final : public virtual i_winfsp_drive,
public virtual FileSystemBase {
E_CONSUMER();
public:
@@ -45,8 +47,8 @@ public:
private:
class winfsp_service final : virtual public Service {
public:
winfsp_service(lock_data &lock, winfsp_drive &drive, std::vector<std::string> drive_args,
app_config &config);
winfsp_service(lock_data &lock, winfsp_drive &drive,
std::vector<std::string> drive_args, app_config &config);
~winfsp_service() override = default;
@@ -58,9 +60,9 @@ private:
app_config &config_;
protected:
NTSTATUS OnStart(ULONG, PWSTR *) override;
auto OnStart(ULONG, PWSTR *) -> NTSTATUS override;
NTSTATUS OnStop() override;
auto OnStop() -> NTSTATUS override;
};
private:
@@ -68,104 +70,128 @@ private:
app_config &config_;
lock_data &lock_;
std::unique_ptr<full_server> server_;
std::unique_ptr<open_file_table<open_file_data>> oft_;
std::unique_ptr<download_manager> download_manager_;
std::unique_ptr<file_manager> fm_;
std::unique_ptr<eviction> eviction_;
std::unique_ptr<remote_winfsp::remote_server> remote_server_;
private:
static std::string parse_mount_location(const std::wstring &mount_location);
static auto parse_mount_location(const std::wstring &mount_location)
-> std::string;
void populate_file_info(const std::string &api_path, const std::uint64_t &file_size,
const api_meta_map &meta, FSP_FSCTL_OPEN_FILE_INFO &ofi);
void populate_file_info(const std::string &api_path, std::uint64_t file_size,
const api_meta_map &meta,
FSP_FSCTL_OPEN_FILE_INFO &ofi);
void populate_file_info(const std::uint64_t &file_size, api_meta_map meta,
void populate_file_info(std::uint64_t file_size, api_meta_map meta,
FSP_FSCTL_FILE_INFO &fi);
static void set_file_info(remote::file_info &dest, const FSP_FSCTL_FILE_INFO &src);
static void set_file_info(remote::file_info &dest,
const FSP_FSCTL_FILE_INFO &src);
public:
NTSTATUS CanDelete(PVOID file_node, PVOID file_desc, PWSTR file_name) override;
auto CanDelete(PVOID file_node, PVOID file_desc, PWSTR file_name)
-> NTSTATUS override;
VOID Cleanup(PVOID file_node, PVOID file_desc, PWSTR file_name, ULONG flags) override;
VOID Cleanup(PVOID file_node, PVOID file_desc, PWSTR file_name,
ULONG flags) override;
VOID Close(PVOID file_node, PVOID file_desc) override;
NTSTATUS Create(PWSTR file_name, UINT32 create_options, UINT32 granted_access, UINT32 attributes,
PSECURITY_DESCRIPTOR descriptor, UINT64 allocation_size, PVOID *file_node,
PVOID *file_desc, OpenFileInfo *ofi) override;
auto Create(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
UINT32 attributes, PSECURITY_DESCRIPTOR descriptor,
UINT64 allocation_size, PVOID *file_node, PVOID *file_desc,
OpenFileInfo *ofi) -> NTSTATUS override;
NTSTATUS Flush(PVOID file_node, PVOID file_desc, FileInfo *file_info) override;
auto Flush(PVOID file_node, PVOID file_desc, FileInfo *file_info)
-> NTSTATUS override;
std::uint64_t get_directory_item_count(const std::string &api_path) const override;
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t override;
directory_item_list get_directory_items(const std::string &api_path) const override;
[[nodiscard]] auto get_directory_items(const std::string &api_path) const
-> directory_item_list override;
NTSTATUS GetFileInfo(PVOID file_node, PVOID file_desc, FileInfo *file_info) override;
auto GetFileInfo(PVOID file_node, PVOID file_desc, FileInfo *file_info)
-> NTSTATUS override;
std::uint64_t get_file_size(const std::string &api_path) const override;
[[nodiscard]] auto get_file_size(const std::string &api_path) const
-> std::uint64_t override;
api_error get_item_meta(const std::string &api_path, api_meta_map &meta) const override;
[[nodiscard]] auto get_item_meta(const std::string &api_path,
api_meta_map &meta) const
-> api_error override;
api_error get_item_meta(const std::string &api_path, const std::string &name,
std::string &value) const override;
[[nodiscard]] auto get_item_meta(const std::string &api_path,
const std::string &name,
std::string &value) const
-> api_error override;
NTSTATUS get_security_by_name(PWSTR file_name, PUINT32 attributes,
PSECURITY_DESCRIPTOR descriptor,
std::uint64_t *descriptor_size) override;
[[nodiscard]] auto get_security_by_name(PWSTR file_name, PUINT32 attributes,
PSECURITY_DESCRIPTOR descriptor,
std::uint64_t *descriptor_size)
-> NTSTATUS override;
NTSTATUS GetSecurityByName(PWSTR file_name, PUINT32 attributes, PSECURITY_DESCRIPTOR descriptor,
SIZE_T *descriptor_size) override;
auto GetSecurityByName(PWSTR file_name, PUINT32 attributes,
PSECURITY_DESCRIPTOR descriptor,
SIZE_T *descriptor_size) -> NTSTATUS override;
std::uint64_t get_total_drive_space() const override;
[[nodiscard]] auto get_total_drive_space() const -> std::uint64_t override;
std::uint64_t get_total_item_count() const override;
[[nodiscard]] auto get_total_item_count() const -> std::uint64_t override;
std::uint64_t get_used_drive_space() const override;
[[nodiscard]] auto get_used_drive_space() const -> std::uint64_t override;
void get_volume_info(UINT64 &total_size, UINT64 &free_size,
std::string &volume_label) const override;
NTSTATUS GetVolumeInfo(VolumeInfo *volume_info) override;
auto GetVolumeInfo(VolumeInfo *volume_info) -> NTSTATUS override;
NTSTATUS Init(PVOID host) override;
auto Init(PVOID host) -> NTSTATUS override;
int mount(const std::vector<std::string> &drive_args);
[[nodiscard]] auto mount(const std::vector<std::string> &drive_args) -> int;
NTSTATUS Mounted(PVOID host) override;
auto Mounted(PVOID host) -> NTSTATUS override;
NTSTATUS Open(PWSTR file_name, UINT32 create_options, UINT32 granted_access, PVOID *file_node,
PVOID *file_desc, OpenFileInfo *ofi) override;
auto Open(PWSTR file_name, UINT32 create_options, UINT32 granted_access,
PVOID *file_node, PVOID *file_desc, OpenFileInfo *ofi)
-> NTSTATUS override;
NTSTATUS Overwrite(PVOID file_node, PVOID file_desc, UINT32 attributes,
BOOLEAN replace_attributes, UINT64 allocation_size,
FileInfo *file_info) override;
auto Overwrite(PVOID file_node, PVOID file_desc, UINT32 attributes,
BOOLEAN replace_attributes, UINT64 allocation_size,
FileInfo *file_info) -> NTSTATUS override;
api_error populate_file_info(const std::string &api_path, remote::file_info &file_info) override;
[[nodiscard]] auto populate_file_info(const std::string &api_path,
remote::file_info &file_info)
-> api_error override;
NTSTATUS Read(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset, ULONG length,
PULONG bytes_transferred) override;
auto Read(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset,
ULONG length, PULONG bytes_transferred) -> NTSTATUS override;
NTSTATUS ReadDirectory(PVOID file_node, PVOID file_desc, PWSTR pattern, PWSTR marker,
PVOID buffer, ULONG bufferLength, PULONG bytes_transferred) override;
auto ReadDirectory(PVOID file_node, PVOID file_desc, PWSTR pattern,
PWSTR marker, PVOID buffer, ULONG bufferLength,
PULONG bytes_transferred) -> NTSTATUS override;
NTSTATUS Rename(PVOID file_node, PVOID file_desc, PWSTR file_name, PWSTR newFileName,
BOOLEAN replace_if_exists) override;
auto Rename(PVOID file_node, PVOID file_desc, PWSTR file_name,
PWSTR newFileName, BOOLEAN replace_if_exists)
-> NTSTATUS override;
NTSTATUS SetBasicInfo(PVOID file_node, PVOID file_desc, UINT32 attributes, UINT64 creation_time,
UINT64 last_access_time, UINT64 last_write_time, UINT64 change_time,
FileInfo *file_info) override;
auto SetBasicInfo(PVOID file_node, PVOID file_desc, UINT32 attributes,
UINT64 creation_time, UINT64 last_access_time,
UINT64 last_write_time, UINT64 change_time,
FileInfo *file_info) -> NTSTATUS override;
NTSTATUS SetFileSize(PVOID file_node, PVOID file_desc, UINT64 new_size,
BOOLEAN set_allocation_size, FileInfo *file_info) override;
auto SetFileSize(PVOID file_node, PVOID file_desc, UINT64 new_size,
BOOLEAN set_allocation_size, FileInfo *file_info)
-> NTSTATUS override;
VOID Unmounted(PVOID host) override;
NTSTATUS Write(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset, ULONG length,
BOOLEAN write_to_end, BOOLEAN constrained_io, PULONG bytes_transferred,
FileInfo *file_info) override;
auto Write(PVOID file_node, PVOID file_desc, PVOID buffer, UINT64 offset,
ULONG length, BOOLEAN write_to_end, BOOLEAN constrained_io,
PULONG bytes_transferred, FileInfo *file_info)
-> NTSTATUS override;
void shutdown() { ::GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); }
void shutdown();
static void display_options(int argc, char *argv[]) {}