Compare commits
1 Commits
da1b5c6953
...
v2.0.1-rc
Author | SHA1 | Date | |
---|---|---|---|
1b8de3b097 |
@@ -244,6 +244,7 @@ wcast
|
||||
wconversion
|
||||
wdouble
|
||||
wduplicated
|
||||
wfloat
|
||||
wformat
|
||||
windres
|
||||
winfsp
|
||||
|
211
3rd_party/cpp-httplib/httplib.h
vendored
211
3rd_party/cpp-httplib/httplib.h
vendored
@@ -8,7 +8,7 @@
|
||||
#ifndef CPPHTTPLIB_HTTPLIB_H
|
||||
#define CPPHTTPLIB_HTTPLIB_H
|
||||
|
||||
#define CPPHTTPLIB_VERSION "0.14.0"
|
||||
#define CPPHTTPLIB_VERSION "0.14.2"
|
||||
|
||||
/*
|
||||
* Configuration
|
||||
@@ -247,7 +247,6 @@ using socket_t = int;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "crypt32.lib")
|
||||
#pragma comment(lib, "cryptui.lib")
|
||||
#endif
|
||||
#elif defined(CPPHTTPLIB_USE_CERTS_FROM_MACOSX_KEYCHAIN) && defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
@@ -331,7 +330,7 @@ struct scope_exit {
|
||||
explicit scope_exit(std::function<void(void)> &&f)
|
||||
: exit_function(std::move(f)), execute_on_destruction{true} {}
|
||||
|
||||
scope_exit(scope_exit &&rhs)
|
||||
scope_exit(scope_exit &&rhs) noexcept
|
||||
: exit_function(std::move(rhs.exit_function)),
|
||||
execute_on_destruction{rhs.execute_on_destruction} {
|
||||
rhs.release();
|
||||
@@ -385,6 +384,7 @@ public:
|
||||
DataSink &operator=(DataSink &&) = delete;
|
||||
|
||||
std::function<bool(const char *data, size_t data_len)> write;
|
||||
std::function<bool()> is_writable;
|
||||
std::function<void()> done;
|
||||
std::function<void(const Headers &trailer)> done_with_trailer;
|
||||
std::ostream os;
|
||||
@@ -395,7 +395,7 @@ private:
|
||||
explicit data_sink_streambuf(DataSink &sink) : sink_(sink) {}
|
||||
|
||||
protected:
|
||||
std::streamsize xsputn(const char *s, std::streamsize n) {
|
||||
std::streamsize xsputn(const char *s, std::streamsize n) override {
|
||||
sink_.write(s, static_cast<size_t>(n));
|
||||
return n;
|
||||
}
|
||||
@@ -873,15 +873,15 @@ private:
|
||||
bool routing(Request &req, Response &res, Stream &strm);
|
||||
bool handle_file_request(const Request &req, Response &res,
|
||||
bool head = false);
|
||||
bool dispatch_request(Request &req, Response &res, const Handlers &handlers);
|
||||
bool
|
||||
dispatch_request_for_content_reader(Request &req, Response &res,
|
||||
ContentReader content_reader,
|
||||
const HandlersForContentReader &handlers);
|
||||
bool dispatch_request(Request &req, Response &res,
|
||||
const Handlers &handlers) const;
|
||||
bool dispatch_request_for_content_reader(
|
||||
Request &req, Response &res, ContentReader content_reader,
|
||||
const HandlersForContentReader &handlers) const;
|
||||
|
||||
bool parse_request_line(const char *s, Request &req);
|
||||
bool parse_request_line(const char *s, Request &req) const;
|
||||
void apply_ranges(const Request &req, Response &res,
|
||||
std::string &content_type, std::string &boundary);
|
||||
std::string &content_type, std::string &boundary) const;
|
||||
bool write_response(Stream &strm, bool close_connection, const Request &req,
|
||||
Response &res);
|
||||
bool write_response_with_content(Stream &strm, bool close_connection,
|
||||
@@ -901,7 +901,7 @@ private:
|
||||
bool read_content_core(Stream &strm, Request &req, Response &res,
|
||||
ContentReceiver receiver,
|
||||
MultipartContentHeader multipart_header,
|
||||
ContentReceiver multipart_receiver);
|
||||
ContentReceiver multipart_receiver) const;
|
||||
|
||||
virtual bool process_and_close_socket(socket_t sock);
|
||||
|
||||
@@ -967,7 +967,7 @@ enum class Error {
|
||||
SSLPeerCouldBeClosed_,
|
||||
};
|
||||
|
||||
std::string to_string(const Error error);
|
||||
std::string to_string(Error error);
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const Error &obj);
|
||||
|
||||
@@ -1226,7 +1226,7 @@ public:
|
||||
void set_ca_cert_path(const std::string &ca_cert_file_path,
|
||||
const std::string &ca_cert_dir_path = std::string());
|
||||
void set_ca_cert_store(X509_STORE *ca_cert_store);
|
||||
X509_STORE *create_ca_cert_store(const char *ca_cert, std::size_t size);
|
||||
X509_STORE *create_ca_cert_store(const char *ca_cert, std::size_t size) const;
|
||||
#endif
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -1255,14 +1255,14 @@ protected:
|
||||
// Also, shutdown_ssl and close_socket should also NOT be called concurrently
|
||||
// with a DIFFERENT thread sending requests using that socket.
|
||||
virtual void shutdown_ssl(Socket &socket, bool shutdown_gracefully);
|
||||
void shutdown_socket(Socket &socket);
|
||||
void shutdown_socket(Socket &socket) const;
|
||||
void close_socket(Socket &socket);
|
||||
|
||||
bool process_request(Stream &strm, Request &req, Response &res,
|
||||
bool close_connection, Error &error);
|
||||
|
||||
bool write_content_with_provider(Stream &strm, const Request &req,
|
||||
Error &error);
|
||||
Error &error) const;
|
||||
|
||||
void copy_settings(const ClientImpl &rhs);
|
||||
|
||||
@@ -1353,7 +1353,8 @@ private:
|
||||
Result send_(Request &&req);
|
||||
|
||||
socket_t create_client_socket(Error &error) const;
|
||||
bool read_response_line(Stream &strm, const Request &req, Response &res);
|
||||
bool read_response_line(Stream &strm, const Request &req,
|
||||
Response &res) const;
|
||||
bool write_request(Stream &strm, Request &req, bool close_connection,
|
||||
Error &error);
|
||||
bool redirect(Request &req, Response &res, Error &error);
|
||||
@@ -1372,7 +1373,7 @@ private:
|
||||
const std::string &content_type);
|
||||
ContentProviderWithoutLength get_multipart_content_provider(
|
||||
const std::string &boundary, const MultipartFormDataItems &items,
|
||||
const MultipartFormDataProviderItems &provider_items);
|
||||
const MultipartFormDataProviderItems &provider_items) const;
|
||||
|
||||
std::string adjust_host_string(const std::string &host) const;
|
||||
|
||||
@@ -1685,7 +1686,7 @@ public:
|
||||
private:
|
||||
bool create_and_connect_socket(Socket &socket, Error &error) override;
|
||||
void shutdown_ssl(Socket &socket, bool shutdown_gracefully) override;
|
||||
void shutdown_ssl_impl(Socket &socket, bool shutdown_socket);
|
||||
void shutdown_ssl_impl(Socket &socket, bool shutdown_gracefully);
|
||||
|
||||
bool process_socket(const Socket &socket,
|
||||
std::function<bool(Stream &strm)> callback) override;
|
||||
@@ -2075,6 +2076,9 @@ std::string trim_copy(const std::string &s);
|
||||
void split(const char *b, const char *e, char d,
|
||||
std::function<void(const char *, const char *)> fn);
|
||||
|
||||
void split(const char *b, const char *e, char d, size_t m,
|
||||
std::function<void(const char *, const char *)> fn);
|
||||
|
||||
bool process_client_socket(socket_t sock, time_t read_timeout_sec,
|
||||
time_t read_timeout_usec, time_t write_timeout_sec,
|
||||
time_t write_timeout_usec,
|
||||
@@ -2151,7 +2155,7 @@ public:
|
||||
|
||||
class nocompressor : public compressor {
|
||||
public:
|
||||
virtual ~nocompressor() = default;
|
||||
~nocompressor() override = default;
|
||||
|
||||
bool compress(const char *data, size_t data_length, bool /*last*/,
|
||||
Callback callback) override;
|
||||
@@ -2161,7 +2165,7 @@ public:
|
||||
class gzip_compressor : public compressor {
|
||||
public:
|
||||
gzip_compressor();
|
||||
~gzip_compressor();
|
||||
~gzip_compressor() override;
|
||||
|
||||
bool compress(const char *data, size_t data_length, bool last,
|
||||
Callback callback) override;
|
||||
@@ -2174,7 +2178,7 @@ private:
|
||||
class gzip_decompressor : public decompressor {
|
||||
public:
|
||||
gzip_decompressor();
|
||||
~gzip_decompressor();
|
||||
~gzip_decompressor() override;
|
||||
|
||||
bool is_valid() const override;
|
||||
|
||||
@@ -2317,7 +2321,7 @@ inline std::string from_i_to_hex(size_t n) {
|
||||
|
||||
inline size_t to_utf8(int code, char *buff) {
|
||||
if (code < 0x0080) {
|
||||
buff[0] = (code & 0x7F);
|
||||
buff[0] = static_cast<char>(code & 0x7F);
|
||||
return 1;
|
||||
} else if (code < 0x0800) {
|
||||
buff[0] = static_cast<char>(0xC0 | ((code >> 6) & 0x1F));
|
||||
@@ -2583,16 +2587,23 @@ inline std::string trim_double_quotes_copy(const std::string &s) {
|
||||
|
||||
inline void split(const char *b, const char *e, char d,
|
||||
std::function<void(const char *, const char *)> fn) {
|
||||
return split(b, e, d, std::numeric_limits<size_t>::max(), fn);
|
||||
}
|
||||
|
||||
inline void split(const char *b, const char *e, char d, size_t m,
|
||||
std::function<void(const char *, const char *)> fn) {
|
||||
size_t i = 0;
|
||||
size_t beg = 0;
|
||||
size_t count = 1;
|
||||
|
||||
while (e ? (b + i < e) : (b[i] != '\0')) {
|
||||
if (b[i] == d) {
|
||||
if (b[i] == d && count < m) {
|
||||
auto r = trim(b, e, beg, i);
|
||||
if (r.first < r.second) {
|
||||
fn(&b[r.first], &b[r.second]);
|
||||
}
|
||||
beg = i + 1;
|
||||
count++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@@ -2683,9 +2694,7 @@ inline mmap::mmap(const char *path)
|
||||
,
|
||||
size_(0),
|
||||
addr_(nullptr) {
|
||||
if (!open(path)) {
|
||||
std::runtime_error("");
|
||||
}
|
||||
open(path);
|
||||
}
|
||||
|
||||
inline mmap::~mmap() { close(); }
|
||||
@@ -2974,7 +2983,7 @@ private:
|
||||
size_t read_buff_off_ = 0;
|
||||
size_t read_buff_content_size_ = 0;
|
||||
|
||||
static const size_t read_buff_size_ = 1024 * 4;
|
||||
static const size_t read_buff_size_ = 1024l * 4;
|
||||
};
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
@@ -3109,8 +3118,9 @@ socket_t create_socket(const std::string &host, const std::string &ip, int port,
|
||||
#ifndef _WIN32
|
||||
if (hints.ai_family == AF_UNIX) {
|
||||
const auto addrlen = host.length();
|
||||
if (addrlen > sizeof(sockaddr_un::sun_path))
|
||||
if (addrlen > sizeof(sockaddr_un::sun_path)) {
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
auto sock = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol);
|
||||
if (sock != INVALID_SOCKET) {
|
||||
@@ -3324,7 +3334,7 @@ inline socket_t create_client_socket(
|
||||
if (ip_from_if.empty()) {
|
||||
ip_from_if = intf;
|
||||
}
|
||||
if (!bind_ip_address(sock2, ip_from_if.c_str())) {
|
||||
if (!bind_ip_address(sock2, ip_from_if)) {
|
||||
error = Error::BindIPAddress;
|
||||
return false;
|
||||
}
|
||||
@@ -3486,7 +3496,7 @@ find_content_type(const std::string &path,
|
||||
|
||||
auto it = user_data.find(ext);
|
||||
if (it != user_data.end()) {
|
||||
return it->second.c_str();
|
||||
return it->second;
|
||||
}
|
||||
|
||||
using udl::operator""_t;
|
||||
@@ -3752,8 +3762,9 @@ inline bool gzip_decompressor::decompress(const char *data, size_t data_length,
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != Z_OK && ret != Z_STREAM_END)
|
||||
if (ret != Z_OK && ret != Z_STREAM_END) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} while (data_length > 0);
|
||||
|
||||
@@ -4069,7 +4080,7 @@ inline bool read_content_chunked(Stream &strm, T &x,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strcmp(line_reader.ptr(), "\r\n")) {
|
||||
if (strcmp(line_reader.ptr(), "\r\n") != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4085,7 +4096,7 @@ inline bool read_content_chunked(Stream &strm, T &x,
|
||||
return false;
|
||||
}
|
||||
|
||||
while (strcmp(line_reader.ptr(), "\r\n")) {
|
||||
while (strcmp(line_reader.ptr(), "\r\n") != 0) {
|
||||
if (line_reader.size() > CPPHTTPLIB_HEADER_MAX_LENGTH) {
|
||||
return false;
|
||||
}
|
||||
@@ -4241,6 +4252,8 @@ inline bool write_content(Stream &strm, const ContentProvider &content_provider,
|
||||
return ok;
|
||||
};
|
||||
|
||||
data_sink.is_writable = [&]() -> bool { return strm.is_writable(); };
|
||||
|
||||
while (offset < end_offset && !is_shutting_down()) {
|
||||
if (!strm.is_writable()) {
|
||||
error = Error::Write;
|
||||
@@ -4287,6 +4300,8 @@ write_content_without_length(Stream &strm,
|
||||
return ok;
|
||||
};
|
||||
|
||||
data_sink.is_writable = [&]() -> bool { return strm.is_writable(); };
|
||||
|
||||
data_sink.done = [&](void) { data_available = false; };
|
||||
|
||||
while (data_available && !is_shutting_down()) {
|
||||
@@ -4337,6 +4352,8 @@ write_content_chunked(Stream &strm, const ContentProvider &content_provider,
|
||||
return ok;
|
||||
};
|
||||
|
||||
data_sink.is_writable = [&]() -> bool { return strm.is_writable(); };
|
||||
|
||||
auto done_with_trailer = [&](const Headers *trailer) {
|
||||
if (!ok) {
|
||||
return;
|
||||
@@ -4438,8 +4455,9 @@ inline bool redirect(T &cli, Request &req, Response &res,
|
||||
req = new_req;
|
||||
res = new_res;
|
||||
|
||||
if (res.location.empty())
|
||||
if (res.location.empty()) {
|
||||
res.location = location;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -4534,8 +4552,9 @@ inline bool parse_range_header(const std::string &s, Ranges &ranges) try {
|
||||
auto len = static_cast<size_t>(m.length(1));
|
||||
auto all_valid_ranges = true;
|
||||
split(&s[pos], &s[pos + len], ',', [&](const char *b, const char *e) {
|
||||
if (!all_valid_ranges)
|
||||
if (!all_valid_ranges) {
|
||||
return;
|
||||
}
|
||||
static auto re_another_range = std::regex(R"(\s*(\d*)-(\d*))");
|
||||
std::cmatch cm;
|
||||
if (std::regex_match(b, e, cm, re_another_range)) {
|
||||
@@ -4922,8 +4941,9 @@ serialize_multipart_formdata(const MultipartFormDataItems &items,
|
||||
body += item.content + serialize_multipart_formdata_item_end();
|
||||
}
|
||||
|
||||
if (finish)
|
||||
if (finish) {
|
||||
body += serialize_multipart_formdata_finish(boundary);
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
@@ -5376,7 +5396,7 @@ inline std::string random_string(size_t length) {
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz";
|
||||
const size_t max_index = (sizeof(charset) - 1);
|
||||
return charset[repertory_rand<size_t>() % max_index];
|
||||
return charset[static_cast<size_t>(std::rand()) % max_index];
|
||||
};
|
||||
std::string str(length, 0);
|
||||
std::generate_n(str.begin(), length, randchar);
|
||||
@@ -5671,7 +5691,7 @@ inline SocketStream::SocketStream(socket_t sock, time_t read_timeout_sec,
|
||||
write_timeout_usec_(write_timeout_usec),
|
||||
read_buff_(read_buff_size_, 0) {}
|
||||
|
||||
inline SocketStream::~SocketStream() {}
|
||||
inline SocketStream::~SocketStream() = default;
|
||||
|
||||
inline bool SocketStream::is_readable() const {
|
||||
return select_read(sock_, read_timeout_sec_, read_timeout_usec_) > 0;
|
||||
@@ -5897,7 +5917,7 @@ inline Server::Server()
|
||||
#endif
|
||||
}
|
||||
|
||||
inline Server::~Server() {}
|
||||
inline Server::~Server() = default;
|
||||
|
||||
inline std::unique_ptr<detail::MatcherBase>
|
||||
Server::make_matcher(const std::string &pattern) {
|
||||
@@ -5909,66 +5929,60 @@ Server::make_matcher(const std::string &pattern) {
|
||||
}
|
||||
|
||||
inline Server &Server::Get(const std::string &pattern, Handler handler) {
|
||||
get_handlers_.push_back(
|
||||
std::make_pair(make_matcher(pattern), std::move(handler)));
|
||||
get_handlers_.emplace_back(make_matcher(pattern), std::move(handler));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Server &Server::Post(const std::string &pattern, Handler handler) {
|
||||
post_handlers_.push_back(
|
||||
std::make_pair(make_matcher(pattern), std::move(handler)));
|
||||
post_handlers_.emplace_back(make_matcher(pattern), std::move(handler));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Server &Server::Post(const std::string &pattern,
|
||||
HandlerWithContentReader handler) {
|
||||
post_handlers_for_content_reader_.push_back(
|
||||
std::make_pair(make_matcher(pattern), std::move(handler)));
|
||||
post_handlers_for_content_reader_.emplace_back(make_matcher(pattern),
|
||||
std::move(handler));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Server &Server::Put(const std::string &pattern, Handler handler) {
|
||||
put_handlers_.push_back(
|
||||
std::make_pair(make_matcher(pattern), std::move(handler)));
|
||||
put_handlers_.emplace_back(make_matcher(pattern), std::move(handler));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Server &Server::Put(const std::string &pattern,
|
||||
HandlerWithContentReader handler) {
|
||||
put_handlers_for_content_reader_.push_back(
|
||||
std::make_pair(make_matcher(pattern), std::move(handler)));
|
||||
put_handlers_for_content_reader_.emplace_back(make_matcher(pattern),
|
||||
std::move(handler));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Server &Server::Patch(const std::string &pattern, Handler handler) {
|
||||
patch_handlers_.push_back(
|
||||
std::make_pair(make_matcher(pattern), std::move(handler)));
|
||||
patch_handlers_.emplace_back(make_matcher(pattern), std::move(handler));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Server &Server::Patch(const std::string &pattern,
|
||||
HandlerWithContentReader handler) {
|
||||
patch_handlers_for_content_reader_.push_back(
|
||||
std::make_pair(make_matcher(pattern), std::move(handler)));
|
||||
patch_handlers_for_content_reader_.emplace_back(make_matcher(pattern),
|
||||
std::move(handler));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Server &Server::Delete(const std::string &pattern, Handler handler) {
|
||||
delete_handlers_.push_back(
|
||||
std::make_pair(make_matcher(pattern), std::move(handler)));
|
||||
delete_handlers_.emplace_back(make_matcher(pattern), std::move(handler));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Server &Server::Delete(const std::string &pattern,
|
||||
HandlerWithContentReader handler) {
|
||||
delete_handlers_for_content_reader_.push_back(
|
||||
std::make_pair(make_matcher(pattern), std::move(handler)));
|
||||
delete_handlers_for_content_reader_.emplace_back(make_matcher(pattern),
|
||||
std::move(handler));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Server &Server::Options(const std::string &pattern, Handler handler) {
|
||||
options_handlers_.push_back(
|
||||
std::make_pair(make_matcher(pattern), std::move(handler)));
|
||||
options_handlers_.emplace_back(make_matcher(pattern), std::move(handler));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -6116,9 +6130,7 @@ inline Server &Server::set_payload_max_length(size_t length) {
|
||||
|
||||
inline bool Server::bind_to_port(const std::string &host, int port,
|
||||
int socket_flags) {
|
||||
if (bind_internal(host, port, socket_flags) < 0)
|
||||
return false;
|
||||
return true;
|
||||
return bind_internal(host, port, socket_flags) >= 0;
|
||||
}
|
||||
inline int Server::bind_to_any_port(const std::string &host, int socket_flags) {
|
||||
return bind_internal(host, 0, socket_flags);
|
||||
@@ -6152,7 +6164,7 @@ inline void Server::stop() {
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Server::parse_request_line(const char *s, Request &req) {
|
||||
inline bool Server::parse_request_line(const char *s, Request &req) const {
|
||||
auto len = strlen(s);
|
||||
if (len < 2 || s[len - 2] != '\r' || s[len - 1] != '\n') {
|
||||
return false;
|
||||
@@ -6208,7 +6220,7 @@ inline bool Server::parse_request_line(const char *s, Request &req) {
|
||||
size_t count = 0;
|
||||
|
||||
detail::split(req.target.data(), req.target.data() + req.target.size(), '?',
|
||||
[&](const char *b, const char *e) {
|
||||
2, [&](const char *b, const char *e) {
|
||||
switch (count) {
|
||||
case 0:
|
||||
req.path = detail::decode_url(std::string(b, e), false);
|
||||
@@ -6433,10 +6445,11 @@ inline bool Server::read_content_with_content_receiver(
|
||||
std::move(multipart_receiver));
|
||||
}
|
||||
|
||||
inline bool Server::read_content_core(Stream &strm, Request &req, Response &res,
|
||||
ContentReceiver receiver,
|
||||
MultipartContentHeader multipart_header,
|
||||
ContentReceiver multipart_receiver) {
|
||||
inline bool
|
||||
Server::read_content_core(Stream &strm, Request &req, Response &res,
|
||||
ContentReceiver receiver,
|
||||
MultipartContentHeader multipart_header,
|
||||
ContentReceiver multipart_receiver) const {
|
||||
detail::MultipartFormDataParser multipart_form_data_parser;
|
||||
ContentReceiverWithProgress out;
|
||||
|
||||
@@ -6502,7 +6515,7 @@ inline bool Server::handle_file_request(const Request &req, Response &res,
|
||||
|
||||
if (detail::is_file(path)) {
|
||||
for (const auto &kv : entry.headers) {
|
||||
res.set_header(kv.first.c_str(), kv.second);
|
||||
res.set_header(kv.first, kv.second);
|
||||
}
|
||||
|
||||
auto mm = std::make_shared<detail::mmap>(path.c_str());
|
||||
@@ -6739,7 +6752,7 @@ inline bool Server::routing(Request &req, Response &res, Stream &strm) {
|
||||
}
|
||||
|
||||
inline bool Server::dispatch_request(Request &req, Response &res,
|
||||
const Handlers &handlers) {
|
||||
const Handlers &handlers) const {
|
||||
for (const auto &x : handlers) {
|
||||
const auto &matcher = x.first;
|
||||
const auto &handler = x.second;
|
||||
@@ -6754,7 +6767,7 @@ inline bool Server::dispatch_request(Request &req, Response &res,
|
||||
|
||||
inline void Server::apply_ranges(const Request &req, Response &res,
|
||||
std::string &content_type,
|
||||
std::string &boundary) {
|
||||
std::string &boundary) const {
|
||||
if (req.ranges.size() > 1) {
|
||||
boundary = detail::make_multipart_data_boundary();
|
||||
|
||||
@@ -6866,7 +6879,7 @@ inline void Server::apply_ranges(const Request &req, Response &res,
|
||||
|
||||
inline bool Server::dispatch_request_for_content_reader(
|
||||
Request &req, Response &res, ContentReader content_reader,
|
||||
const HandlersForContentReader &handlers) {
|
||||
const HandlersForContentReader &handlers) const {
|
||||
for (const auto &x : handlers) {
|
||||
const auto &matcher = x.first;
|
||||
const auto &handler = x.second;
|
||||
@@ -7125,8 +7138,9 @@ inline socket_t ClientImpl::create_client_socket(Error &error) const {
|
||||
// Check is custom IP specified for host_
|
||||
std::string ip;
|
||||
auto it = addr_map_.find(host_);
|
||||
if (it != addr_map_.end())
|
||||
if (it != addr_map_.end()) {
|
||||
ip = it->second;
|
||||
}
|
||||
|
||||
return detail::create_client_socket(
|
||||
host_, ip, port_, address_family_, tcp_nodelay_, socket_options_,
|
||||
@@ -7153,7 +7167,7 @@ inline void ClientImpl::shutdown_ssl(Socket & /*socket*/,
|
||||
socket_requests_are_from_thread_ == std::this_thread::get_id());
|
||||
}
|
||||
|
||||
inline void ClientImpl::shutdown_socket(Socket &socket) {
|
||||
inline void ClientImpl::shutdown_socket(Socket &socket) const {
|
||||
if (socket.sock == INVALID_SOCKET) {
|
||||
return;
|
||||
}
|
||||
@@ -7182,7 +7196,7 @@ inline void ClientImpl::close_socket(Socket &socket) {
|
||||
}
|
||||
|
||||
inline bool ClientImpl::read_response_line(Stream &strm, const Request &req,
|
||||
Response &res) {
|
||||
Response &res) const {
|
||||
std::array<char, 2048> buf{};
|
||||
|
||||
detail::stream_line_reader line_reader(strm, buf.data(), buf.size());
|
||||
@@ -7476,7 +7490,7 @@ inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) {
|
||||
} else {
|
||||
if (next_scheme == "https") {
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
SSLClient cli(next_host.c_str(), next_port);
|
||||
SSLClient cli(next_host, next_port);
|
||||
cli.copy_settings(*this);
|
||||
if (ca_cert_store_) {
|
||||
cli.set_ca_cert_store(ca_cert_store_);
|
||||
@@ -7486,7 +7500,7 @@ inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) {
|
||||
return false;
|
||||
#endif
|
||||
} else {
|
||||
ClientImpl cli(next_host.c_str(), next_port);
|
||||
ClientImpl cli(next_host, next_port);
|
||||
cli.copy_settings(*this);
|
||||
return detail::redirect(cli, req, res, path, location, error);
|
||||
}
|
||||
@@ -7495,7 +7509,7 @@ inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) {
|
||||
|
||||
inline bool ClientImpl::write_content_with_provider(Stream &strm,
|
||||
const Request &req,
|
||||
Error &error) {
|
||||
Error &error) const {
|
||||
auto is_shutting_down = []() { return false; };
|
||||
|
||||
if (req.is_chunked_content_provider_) {
|
||||
@@ -7843,13 +7857,14 @@ inline bool ClientImpl::process_request(Stream &strm, Request &req,
|
||||
|
||||
inline ContentProviderWithoutLength ClientImpl::get_multipart_content_provider(
|
||||
const std::string &boundary, const MultipartFormDataItems &items,
|
||||
const MultipartFormDataProviderItems &provider_items) {
|
||||
size_t cur_item = 0, cur_start = 0;
|
||||
const MultipartFormDataProviderItems &provider_items) const {
|
||||
size_t cur_item = 0;
|
||||
size_t cur_start = 0;
|
||||
// cur_item and cur_start are copied to within the std::function and maintain
|
||||
// state between successive calls
|
||||
return [&, cur_item, cur_start](size_t offset,
|
||||
DataSink &sink) mutable -> bool {
|
||||
if (!offset && items.size()) {
|
||||
if (!offset && !items.empty()) {
|
||||
sink.os << detail::serialize_multipart_formdata(items, boundary, false);
|
||||
return true;
|
||||
} else if (cur_item < provider_items.size()) {
|
||||
@@ -7866,8 +7881,9 @@ inline ContentProviderWithoutLength ClientImpl::get_multipart_content_provider(
|
||||
cur_sink.write = sink.write;
|
||||
cur_sink.done = [&]() { has_data = false; };
|
||||
|
||||
if (!provider_items[cur_item].provider(offset - cur_start, cur_sink))
|
||||
if (!provider_items[cur_item].provider(offset - cur_start, cur_sink)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!has_data) {
|
||||
sink.os << detail::serialize_multipart_formdata_item_end();
|
||||
@@ -7988,7 +8004,7 @@ inline Result ClientImpl::Get(const std::string &path, const Params ¶ms,
|
||||
}
|
||||
|
||||
std::string path_with_query = append_query_params(path, params);
|
||||
return Get(path_with_query.c_str(), headers, progress);
|
||||
return Get(path_with_query, headers, progress);
|
||||
}
|
||||
|
||||
inline Result ClientImpl::Get(const std::string &path, const Params ¶ms,
|
||||
@@ -8008,8 +8024,8 @@ inline Result ClientImpl::Get(const std::string &path, const Params ¶ms,
|
||||
}
|
||||
|
||||
std::string path_with_query = append_query_params(path, params);
|
||||
return Get(path_with_query.c_str(), headers, response_handler,
|
||||
content_receiver, progress);
|
||||
return Get(path_with_query, headers, response_handler, content_receiver,
|
||||
progress);
|
||||
}
|
||||
|
||||
inline Result ClientImpl::Head(const std::string &path) {
|
||||
@@ -8111,7 +8127,7 @@ inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
|
||||
const auto &content_type =
|
||||
detail::serialize_multipart_formdata_get_content_type(boundary);
|
||||
const auto &body = detail::serialize_multipart_formdata(items, boundary);
|
||||
return Post(path, headers, body, content_type.c_str());
|
||||
return Post(path, headers, body, content_type);
|
||||
}
|
||||
|
||||
inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
|
||||
@@ -8124,7 +8140,7 @@ inline Result ClientImpl::Post(const std::string &path, const Headers &headers,
|
||||
const auto &content_type =
|
||||
detail::serialize_multipart_formdata_get_content_type(boundary);
|
||||
const auto &body = detail::serialize_multipart_formdata(items, boundary);
|
||||
return Post(path, headers, body, content_type.c_str());
|
||||
return Post(path, headers, body, content_type);
|
||||
}
|
||||
|
||||
inline Result
|
||||
@@ -8508,10 +8524,11 @@ inline void ClientImpl::set_ca_cert_store(X509_STORE *ca_cert_store) {
|
||||
}
|
||||
|
||||
inline X509_STORE *ClientImpl::create_ca_cert_store(const char *ca_cert,
|
||||
std::size_t size) {
|
||||
std::size_t size) const {
|
||||
auto mem = BIO_new_mem_buf(ca_cert, static_cast<int>(size));
|
||||
if (!mem)
|
||||
if (!mem) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto inf = PEM_X509_INFO_read_bio(mem, nullptr, nullptr, nullptr);
|
||||
if (!inf) {
|
||||
@@ -8676,7 +8693,7 @@ inline SSLSocketStream::SSLSocketStream(socket_t sock, SSL *ssl,
|
||||
SSL_clear_mode(ssl, SSL_MODE_AUTO_RETRY);
|
||||
}
|
||||
|
||||
inline SSLSocketStream::~SSLSocketStream() {}
|
||||
inline SSLSocketStream::~SSLSocketStream() = default;
|
||||
|
||||
inline bool SSLSocketStream::is_readable() const {
|
||||
return detail::select_read(sock_, read_timeout_sec_, read_timeout_usec_) > 0;
|
||||
@@ -8898,7 +8915,7 @@ inline SSLClient::SSLClient(const std::string &host, int port,
|
||||
|
||||
detail::split(&host_[0], &host_[host_.size()], '.',
|
||||
[&](const char *b, const char *e) {
|
||||
host_components_.emplace_back(std::string(b, e));
|
||||
host_components_.emplace_back(b, e);
|
||||
});
|
||||
|
||||
if (!client_cert_path.empty() && !client_key_path.empty()) {
|
||||
@@ -8919,7 +8936,7 @@ inline SSLClient::SSLClient(const std::string &host, int port,
|
||||
|
||||
detail::split(&host_[0], &host_[host_.size()], '.',
|
||||
[&](const char *b, const char *e) {
|
||||
host_components_.emplace_back(std::string(b, e));
|
||||
host_components_.emplace_back(b, e);
|
||||
});
|
||||
|
||||
if (client_cert != nullptr && client_key != nullptr) {
|
||||
@@ -9197,8 +9214,8 @@ SSLClient::verify_host_with_subject_alt_name(X509 *server_cert) const {
|
||||
|
||||
auto type = GEN_DNS;
|
||||
|
||||
struct in6_addr addr6;
|
||||
struct in_addr addr;
|
||||
struct in6_addr addr6 {};
|
||||
struct in_addr addr {};
|
||||
size_t addr_len = 0;
|
||||
|
||||
#ifndef __MINGW32__
|
||||
@@ -9279,7 +9296,7 @@ inline bool SSLClient::check_host_name(const char *pattern,
|
||||
std::vector<std::string> pattern_components;
|
||||
detail::split(&pattern[0], &pattern[pattern_len], '.',
|
||||
[&](const char *b, const char *e) {
|
||||
pattern_components.emplace_back(std::string(b, e));
|
||||
pattern_components.emplace_back(b, e);
|
||||
});
|
||||
|
||||
if (host_components_.size() != pattern_components.size()) {
|
||||
@@ -9364,7 +9381,7 @@ inline Client::Client(const std::string &host, int port,
|
||||
: cli_(detail::make_unique<ClientImpl>(host, port, client_cert_path,
|
||||
client_key_path)) {}
|
||||
|
||||
inline Client::~Client() {}
|
||||
inline Client::~Client() = default;
|
||||
|
||||
inline bool Client::is_valid() const {
|
||||
return cli_ != nullptr && cli_->is_valid();
|
||||
|
24147
3rd_party/pugixml/src/pugixml.cpp
vendored
24147
3rd_party/pugixml/src/pugixml.cpp
vendored
File diff suppressed because it is too large
Load Diff
13300
3rd_party/sqlite/include/sqlite3.h
vendored
Normal file
13300
3rd_party/sqlite/include/sqlite3.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
252720
3rd_party/sqlite/src/sqlite3.c
vendored
Normal file
252720
3rd_party/sqlite/src/sqlite3.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@
|
||||
### Issues
|
||||
|
||||
* \#10 Address compiler warnings
|
||||
* \#11 Switch to SQLite over RocksDB
|
||||
|
||||
### Changes from v2.0.0-rc
|
||||
|
||||
@@ -14,10 +15,10 @@
|
||||
* Require `c++20`
|
||||
* Switched to Storj over Filebase for hosting binaries
|
||||
* Updated `boost` to v1.83.0
|
||||
* Updated `cpp-httplib` to v0.14.2
|
||||
* Updated `curl` to v8.4.0
|
||||
* Updated `libsodium` to v1.0.19
|
||||
* Updated `OpenSSL` to v3.1.4
|
||||
* Updated `rocksdb` to v8.6.7
|
||||
* Updated `OpenSSL` to v3.2.0
|
||||
|
||||
## 2.0.0-rc
|
||||
|
||||
|
546
CMakeLists.txt
546
CMakeLists.txt
@@ -1,273 +1,273 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
project(repertory)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
endif()
|
||||
|
||||
include(CheckIncludeFileCXX)
|
||||
include(CheckIncludeFiles)
|
||||
include(ExternalProject)
|
||||
|
||||
set(REPERTORY_MAJOR 2)
|
||||
set(REPERTORY_MINOR 0)
|
||||
set(REPERTORY_REV 1)
|
||||
set(REPERTORY_RELEASE_NUM 0)
|
||||
set(REPERTORY_RELEASE_ITER rc)
|
||||
set(REPERTORY_VERSION ${REPERTORY_MAJOR}.${REPERTORY_MINOR}.${REPERTORY_REV}-${REPERTORY_RELEASE_ITER})
|
||||
|
||||
include(cmake/arch_detection.cmake)
|
||||
include(cmake/os_detection.cmake)
|
||||
include(cmake/options.cmake)
|
||||
include(cmake/settings.cmake)
|
||||
include(cmake/flags.cmake)
|
||||
include(cmake/versions.cmake)
|
||||
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/cacert.pem")
|
||||
file(REMOVE ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/cacert.pem)
|
||||
endif()
|
||||
file(DOWNLOAD https://curl.haxx.se/ca/cacert.pem ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/cacert.pem)
|
||||
|
||||
unset(REPERTORY_GIT_REV CACHE)
|
||||
execute_process(
|
||||
COMMAND git rev-parse --short HEAD
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE REPERTORY_GIT_REV
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
if (UNIX)
|
||||
check_include_files(sys/xattr.h HAS_SETXATTR)
|
||||
if (HAS_SETXATTR)
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DHAS_SETXATTR)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (LINUX OR MINGW)
|
||||
if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
|
||||
message(FATAL_ERROR "Require at least gcc-8.0")
|
||||
endif()
|
||||
|
||||
set(ENV{PKG_CONFIG_PATH}
|
||||
"${EXTERNAL_BUILD_ROOT}/lib/pkgconfig:${EXTERNAL_BUILD_ROOT}/share/pkgconfig:$ENV{PKG_CONFIG_PATH}"
|
||||
)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
|
||||
if (NOT MINGW)
|
||||
include_directories(/usr/local/include)
|
||||
link_directories(
|
||||
/usr/local/lib
|
||||
/usr/local/lib64
|
||||
)
|
||||
endif()
|
||||
|
||||
if (REPERTORY_MUSL)
|
||||
find_library(LIBFUSE3 NO_CACHE NAMES libfuse3.a)
|
||||
else()
|
||||
if (NOT MINGW)
|
||||
find_library(LIBDL_LIBRARY NO_CACHE NAMES dl)
|
||||
find_library(LIBFUSE3 NO_CACHE NAMES fuse3)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (REPERTORY_MUSL OR MINGW)
|
||||
find_library(LIBPTHREAD_LIBRARY NO_CACHE NAMES libpthread.a)
|
||||
else()
|
||||
find_library(LIBPTHREAD_LIBRARY NO_CACHE NAMES pthread)
|
||||
endif()
|
||||
|
||||
if (LIBFUSE3 AND NOT MINGW)
|
||||
pkg_check_modules(LIBFUSE3 REQUIRED fuse3>=3.0.0)
|
||||
set(LIBFUSE3_LIBRARIES ${LIBFUSE3})
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DFUSE_USE_VERSION=30)
|
||||
endif()
|
||||
|
||||
if(NOT LIBFUSE3_LIBRARIES AND NOT MINGW)
|
||||
pkg_check_modules(LIBFUSE2 REQUIRED fuse>=2.9.0)
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DFUSE_USE_VERSION=29)
|
||||
endif()
|
||||
|
||||
if (NOT LIBPTHREAD_LIBRARY)
|
||||
message(FATAL_ERROR "'libpthread' not found")
|
||||
endif()
|
||||
|
||||
if (REPERTORY_MUSL)
|
||||
if (LIBFUSE3_LIBRARIES)
|
||||
set(LIBFUSE3_LIBRARIES libfuse3.a)
|
||||
else()
|
||||
set(LIBFUSE2_LIBRARIES libfuse.a)
|
||||
endif()
|
||||
|
||||
set(REPERTORY_LINK_LIBRARIES
|
||||
${REPERTORY_LINK_LIBRARIES}
|
||||
${LIBPTHREAD_LIBRARY}
|
||||
)
|
||||
else()
|
||||
if (NOT MINGW AND NOT LIBDL_LIBRARY)
|
||||
message(FATAL_ERROR "'libdl' not found")
|
||||
endif()
|
||||
|
||||
set(REPERTORY_LINK_LIBRARIES
|
||||
${REPERTORY_LINK_LIBRARIES}
|
||||
${LIBPTHREAD_LIBRARY}
|
||||
${LIBDL_LIBRARY}
|
||||
)
|
||||
endif()
|
||||
elseif (FREEBSD)
|
||||
message(FATAL_ERROR "FreeBSD is currently not supported")
|
||||
elseif (MACOS)
|
||||
set(CMAKE_OSX_ARCHITECTURES x86_64)
|
||||
|
||||
find_library(LIBDL_LIBRARY NO_CACHE NAMES dl)
|
||||
if (NOT LIBDL_LIBRARY)
|
||||
message(FATAL_ERROR "'libdl' not found")
|
||||
endif()
|
||||
|
||||
find_library(LIBPTHREAD_LIBRARY NO_CACHE NAMES pthread)
|
||||
if (NOT LIBPTHREAD_LIBRARY)
|
||||
message(FATAL_ERROR "'libpthread' not found")
|
||||
endif()
|
||||
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DFUSE_USE_VERSION=29 -DBOOST_ASIO_HAS_STD_STRING_VIEW)
|
||||
|
||||
include_directories(/usr/local/include)
|
||||
find_library(OSXFUSE NO_CACHE NAMES OSXFUSE)
|
||||
if (NOT OSXFUSE)
|
||||
message(FATAL_ERROR "FUSE for macOS not found (https://osxfuse.github.io/)")
|
||||
endif ()
|
||||
set(LIBFUSE2_LIBRARIES fuse)
|
||||
set(REPERTORY_LINK_LIBRARIES
|
||||
${REPERTORY_LINK_LIBRARIES}
|
||||
${LIBDL_LIBRARY}
|
||||
${LIBPTHREAD_LIBRARY}
|
||||
"-L/usr/local/lib"
|
||||
"-framework Foundation"
|
||||
"-framework AppKit"
|
||||
"-framework Security"
|
||||
"-framework SystemConfiguration"
|
||||
)
|
||||
elseif (MSVC)
|
||||
message(FATAL_ERROR "MSVC is currently not supported [MinGW-64 should be used]")
|
||||
endif()
|
||||
|
||||
if (MINGW)
|
||||
set(WINFSP_LIBRARY_BASENAME winfsp-x64)
|
||||
|
||||
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/3rd_party/winfsp-${WINFSP_VERSION}/inc)
|
||||
link_directories(${CMAKE_SOURCE_DIR}/3rd_party/winfsp-${WINFSP_VERSION}/lib)
|
||||
set(REPERTORY_LINK_LIBRARIES
|
||||
${REPERTORY_LINK_LIBRARIES}
|
||||
${WINFSP_LIBRARY_BASENAME}.lib
|
||||
mswsock
|
||||
)
|
||||
|
||||
set(REPERTORY_VER_FILEVERSION ${REPERTORY_MAJOR},${REPERTORY_MINOR},${REPERTORY_REV},${REPERTORY_RELEASE_NUM})
|
||||
set(REPERTORY_VER_FILEVERSION_STR ${REPERTORY_MAJOR}.${REPERTORY_MINOR}.${REPERTORY_REV}.${REPERTORY_RELEASE_NUM})
|
||||
set(REPERTORY_VER_PRODUCTVERSION ${REPERTORY_MAJOR},${REPERTORY_MINOR},${REPERTORY_REV},${REPERTORY_RELEASE_NUM})
|
||||
set(REPERTORY_VER_PRODUCTVERSION_STR ${REPERTORY_MAJOR}.${REPERTORY_MINOR}.${REPERTORY_REV}.${REPERTORY_RELEASE_NUM})
|
||||
set(REPERTORY_VER_PRERELEASE VS_FF_PRERELEASE)
|
||||
set(REPERTORY_VER_COMPANYNAME_STR "https://git.fifthgrid.com/blockstorage")
|
||||
set(REPERTORY_VER_LEGALCOPYRIGHT_STR "Copyright 2018-2023 <MIT License> <https://git.fifthgrid.com/blockstorage/repertory>")
|
||||
set(REPERTORY_VER_FILEDESCRIPTION_STR "Mount utility for Sia and S3")
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in ${CMAKE_CURRENT_SOURCE_DIR}/src/version.rc @ONLY)
|
||||
set(WINDOWS_VERSION_RC ${CMAKE_CURRENT_SOURCE_DIR}/src/version.rc)
|
||||
|
||||
set(REPERTORY_LINK_LIBRARIES
|
||||
${REPERTORY_LINK_LIBRARIES}
|
||||
advapi32${LIB_EXT}
|
||||
bcrypt${LIB_EXT}
|
||||
comdlg32${LIB_EXT}
|
||||
crypt32${LIB_EXT}
|
||||
gdi32${LIB_EXT}
|
||||
httpapi${LIB_EXT}
|
||||
kernel32${LIB_EXT}
|
||||
ncrypt${LIB_EXT}
|
||||
ole32${LIB_EXT}
|
||||
oleaut32${LIB_EXT}
|
||||
rpcrt4${LIB_EXT}
|
||||
secur32${LIB_EXT}
|
||||
shell32${LIB_EXT}
|
||||
shlwapi${LIB_EXT}
|
||||
user32${LIB_EXT}
|
||||
userenv${LIB_EXT}
|
||||
uuid${LIB_EXT}
|
||||
version${LIB_EXT}
|
||||
winhttp${LIB_EXT}
|
||||
wininet${LIB_EXT}
|
||||
winspool${LIB_EXT}
|
||||
ws2_32${LIB_EXT}
|
||||
)
|
||||
endif()
|
||||
|
||||
include_directories(SYSTEM
|
||||
${EXTERNAL_BUILD_ROOT}/include
|
||||
)
|
||||
|
||||
link_directories(
|
||||
${EXTERNAL_BUILD_ROOT}/lib
|
||||
)
|
||||
|
||||
include(cmake/zlib.cmake)
|
||||
include(cmake/openssl.cmake)
|
||||
include(cmake/curl.cmake)
|
||||
include(cmake/boost.cmake)
|
||||
include(cmake/rocksdb.cmake)
|
||||
include(cmake/libsodium.cmake)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/common.cpp.in ${CMAKE_CURRENT_SOURCE_DIR}/src/common.cpp @ONLY)
|
||||
|
||||
include_directories(include)
|
||||
include_directories(SYSTEM
|
||||
${Boost_INCLUDE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/cpp-httplib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/stduuid
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/json
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/pugixml/src
|
||||
${CURL_INCLUDE_DIRS}
|
||||
${LIBFUSE2_INCLUDE_DIRS}
|
||||
${LIBFUSE3_INCLUDE_DIRS}
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
${ROCKSDB_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(REPERTORY_LINK_LIBRARIES
|
||||
${ROCKSDB_LIBRARIES}
|
||||
${LIBFUSE2_LIBRARIES}
|
||||
${LIBFUSE3_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${CURL_LIBRARIES}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${LIBSODIUM_LIBRARIES}
|
||||
${REPERTORY_LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE REPERTORY_HEADERS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/*.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/*.hh
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/**/*.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/**/*.hh
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/**/*.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/pugixml/src/*.hpp
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE REPERTORY_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/**/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/pugixml/src/*.cpp
|
||||
)
|
||||
list(REMOVE_ITEM REPERTORY_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)
|
||||
|
||||
include(cmake/helpers.cmake)
|
||||
include(cmake/librepertory.cmake)
|
||||
include(cmake/repertory.cmake)
|
||||
include(cmake/unittests.cmake)
|
||||
include(cmake/install.cmake)
|
||||
|
||||
message(STATUS "Repertory Version: ${REPERTORY_VERSION}")
|
||||
message(STATUS "Git Revision: ${REPERTORY_GIT_REV}")
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
project(repertory)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
endif()
|
||||
|
||||
include(CheckIncludeFileCXX)
|
||||
include(CheckIncludeFiles)
|
||||
include(ExternalProject)
|
||||
|
||||
set(REPERTORY_MAJOR 2)
|
||||
set(REPERTORY_MINOR 0)
|
||||
set(REPERTORY_REV 1)
|
||||
set(REPERTORY_RELEASE_NUM 0)
|
||||
set(REPERTORY_RELEASE_ITER rc)
|
||||
set(REPERTORY_VERSION ${REPERTORY_MAJOR}.${REPERTORY_MINOR}.${REPERTORY_REV}-${REPERTORY_RELEASE_ITER})
|
||||
|
||||
include(cmake/arch_detection.cmake)
|
||||
include(cmake/os_detection.cmake)
|
||||
include(cmake/options.cmake)
|
||||
include(cmake/settings.cmake)
|
||||
include(cmake/flags.cmake)
|
||||
include(cmake/versions.cmake)
|
||||
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/cacert.pem")
|
||||
file(REMOVE ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/cacert.pem)
|
||||
endif()
|
||||
file(DOWNLOAD https://curl.haxx.se/ca/cacert.pem ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/cacert.pem)
|
||||
|
||||
unset(REPERTORY_GIT_REV CACHE)
|
||||
execute_process(
|
||||
COMMAND git rev-parse --short HEAD
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE REPERTORY_GIT_REV
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
if (UNIX)
|
||||
check_include_files(sys/xattr.h HAS_SETXATTR)
|
||||
if (HAS_SETXATTR)
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DHAS_SETXATTR)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (LINUX OR MINGW)
|
||||
if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
|
||||
message(FATAL_ERROR "Require at least gcc-8.0")
|
||||
endif()
|
||||
|
||||
set(ENV{PKG_CONFIG_PATH}
|
||||
"${EXTERNAL_BUILD_ROOT}/lib/pkgconfig:${EXTERNAL_BUILD_ROOT}/share/pkgconfig:$ENV{PKG_CONFIG_PATH}"
|
||||
)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
|
||||
if (NOT MINGW)
|
||||
include_directories(/usr/local/include)
|
||||
link_directories(
|
||||
/usr/local/lib
|
||||
/usr/local/lib64
|
||||
)
|
||||
endif()
|
||||
|
||||
if (REPERTORY_MUSL)
|
||||
find_library(LIBFUSE3 NO_CACHE NAMES libfuse3.a)
|
||||
else()
|
||||
if (NOT MINGW)
|
||||
find_library(LIBDL_LIBRARY NO_CACHE NAMES dl)
|
||||
find_library(LIBFUSE3 NO_CACHE NAMES fuse3)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (REPERTORY_MUSL OR MINGW)
|
||||
find_library(LIBPTHREAD_LIBRARY NO_CACHE NAMES libpthread.a)
|
||||
else()
|
||||
find_library(LIBPTHREAD_LIBRARY NO_CACHE NAMES pthread)
|
||||
endif()
|
||||
|
||||
if (LIBFUSE3 AND NOT MINGW)
|
||||
pkg_check_modules(LIBFUSE3 REQUIRED fuse3>=3.0.0)
|
||||
set(LIBFUSE3_LIBRARIES ${LIBFUSE3})
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DFUSE_USE_VERSION=30)
|
||||
endif()
|
||||
|
||||
if(NOT LIBFUSE3_LIBRARIES AND NOT MINGW)
|
||||
pkg_check_modules(LIBFUSE2 REQUIRED fuse>=2.9.0)
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DFUSE_USE_VERSION=29)
|
||||
endif()
|
||||
|
||||
if (NOT LIBPTHREAD_LIBRARY)
|
||||
message(FATAL_ERROR "'libpthread' not found")
|
||||
endif()
|
||||
|
||||
if (REPERTORY_MUSL)
|
||||
if (LIBFUSE3_LIBRARIES)
|
||||
set(LIBFUSE3_LIBRARIES libfuse3.a)
|
||||
else()
|
||||
set(LIBFUSE2_LIBRARIES libfuse.a)
|
||||
endif()
|
||||
|
||||
set(REPERTORY_LINK_LIBRARIES
|
||||
${REPERTORY_LINK_LIBRARIES}
|
||||
${LIBPTHREAD_LIBRARY}
|
||||
)
|
||||
else()
|
||||
if (NOT MINGW AND NOT LIBDL_LIBRARY)
|
||||
message(FATAL_ERROR "'libdl' not found")
|
||||
endif()
|
||||
|
||||
set(REPERTORY_LINK_LIBRARIES
|
||||
${REPERTORY_LINK_LIBRARIES}
|
||||
${LIBPTHREAD_LIBRARY}
|
||||
${LIBDL_LIBRARY}
|
||||
)
|
||||
endif()
|
||||
elseif (FREEBSD)
|
||||
message(FATAL_ERROR "FreeBSD is currently not supported")
|
||||
elseif (MACOS)
|
||||
set(CMAKE_OSX_ARCHITECTURES x86_64)
|
||||
|
||||
find_library(LIBDL_LIBRARY NO_CACHE NAMES dl)
|
||||
if (NOT LIBDL_LIBRARY)
|
||||
message(FATAL_ERROR "'libdl' not found")
|
||||
endif()
|
||||
|
||||
find_library(LIBPTHREAD_LIBRARY NO_CACHE NAMES pthread)
|
||||
if (NOT LIBPTHREAD_LIBRARY)
|
||||
message(FATAL_ERROR "'libpthread' not found")
|
||||
endif()
|
||||
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DFUSE_USE_VERSION=29 -DBOOST_ASIO_HAS_STD_STRING_VIEW)
|
||||
|
||||
include_directories(/usr/local/include)
|
||||
find_library(OSXFUSE NO_CACHE NAMES OSXFUSE)
|
||||
if (NOT OSXFUSE)
|
||||
message(FATAL_ERROR "FUSE for macOS not found (https://osxfuse.github.io/)")
|
||||
endif ()
|
||||
set(LIBFUSE2_LIBRARIES fuse)
|
||||
set(REPERTORY_LINK_LIBRARIES
|
||||
${REPERTORY_LINK_LIBRARIES}
|
||||
${LIBDL_LIBRARY}
|
||||
${LIBPTHREAD_LIBRARY}
|
||||
"-L/usr/local/lib"
|
||||
"-framework Foundation"
|
||||
"-framework AppKit"
|
||||
"-framework Security"
|
||||
"-framework SystemConfiguration"
|
||||
)
|
||||
elseif (MSVC)
|
||||
message(FATAL_ERROR "MSVC is currently not supported [MinGW-64 should be used]")
|
||||
endif()
|
||||
|
||||
if (MINGW)
|
||||
set(WINFSP_LIBRARY_BASENAME winfsp-x64)
|
||||
|
||||
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/3rd_party/winfsp-${WINFSP_VERSION}/inc)
|
||||
link_directories(${CMAKE_SOURCE_DIR}/3rd_party/winfsp-${WINFSP_VERSION}/lib)
|
||||
set(REPERTORY_LINK_LIBRARIES
|
||||
${REPERTORY_LINK_LIBRARIES}
|
||||
${WINFSP_LIBRARY_BASENAME}.lib
|
||||
mswsock
|
||||
)
|
||||
|
||||
set(REPERTORY_VER_FILEVERSION ${REPERTORY_MAJOR},${REPERTORY_MINOR},${REPERTORY_REV},${REPERTORY_RELEASE_NUM})
|
||||
set(REPERTORY_VER_FILEVERSION_STR ${REPERTORY_MAJOR}.${REPERTORY_MINOR}.${REPERTORY_REV}.${REPERTORY_RELEASE_NUM})
|
||||
set(REPERTORY_VER_PRODUCTVERSION ${REPERTORY_MAJOR},${REPERTORY_MINOR},${REPERTORY_REV},${REPERTORY_RELEASE_NUM})
|
||||
set(REPERTORY_VER_PRODUCTVERSION_STR ${REPERTORY_MAJOR}.${REPERTORY_MINOR}.${REPERTORY_REV}.${REPERTORY_RELEASE_NUM})
|
||||
set(REPERTORY_VER_PRERELEASE VS_FF_PRERELEASE)
|
||||
set(REPERTORY_VER_COMPANYNAME_STR "https://git.fifthgrid.com/blockstorage")
|
||||
set(REPERTORY_VER_LEGALCOPYRIGHT_STR "Copyright 2018-2023 <MIT License> <https://git.fifthgrid.com/blockstorage/repertory>")
|
||||
set(REPERTORY_VER_FILEDESCRIPTION_STR "Mount utility for Sia and S3")
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in ${CMAKE_CURRENT_SOURCE_DIR}/src/version.rc @ONLY)
|
||||
set(WINDOWS_VERSION_RC ${CMAKE_CURRENT_SOURCE_DIR}/src/version.rc)
|
||||
|
||||
set(REPERTORY_LINK_LIBRARIES
|
||||
${REPERTORY_LINK_LIBRARIES}
|
||||
advapi32${LIB_EXT}
|
||||
bcrypt${LIB_EXT}
|
||||
comdlg32${LIB_EXT}
|
||||
crypt32${LIB_EXT}
|
||||
gdi32${LIB_EXT}
|
||||
httpapi${LIB_EXT}
|
||||
kernel32${LIB_EXT}
|
||||
ncrypt${LIB_EXT}
|
||||
ole32${LIB_EXT}
|
||||
oleaut32${LIB_EXT}
|
||||
rpcrt4${LIB_EXT}
|
||||
secur32${LIB_EXT}
|
||||
shell32${LIB_EXT}
|
||||
shlwapi${LIB_EXT}
|
||||
user32${LIB_EXT}
|
||||
userenv${LIB_EXT}
|
||||
uuid${LIB_EXT}
|
||||
version${LIB_EXT}
|
||||
winhttp${LIB_EXT}
|
||||
wininet${LIB_EXT}
|
||||
winspool${LIB_EXT}
|
||||
ws2_32${LIB_EXT}
|
||||
)
|
||||
endif()
|
||||
|
||||
include_directories(SYSTEM
|
||||
${EXTERNAL_BUILD_ROOT}/include
|
||||
)
|
||||
|
||||
link_directories(
|
||||
${EXTERNAL_BUILD_ROOT}/lib
|
||||
)
|
||||
|
||||
include(cmake/zlib.cmake)
|
||||
include(cmake/openssl.cmake)
|
||||
include(cmake/curl.cmake)
|
||||
include(cmake/boost.cmake)
|
||||
include(cmake/libsodium.cmake)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/common.cpp.in ${CMAKE_CURRENT_SOURCE_DIR}/src/common.cpp @ONLY)
|
||||
|
||||
include_directories(include)
|
||||
include_directories(SYSTEM
|
||||
${Boost_INCLUDE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/cpp-httplib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/stduuid
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/json
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/pugixml/src
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/sqlite/include
|
||||
${CURL_INCLUDE_DIRS}
|
||||
${LIBFUSE2_INCLUDE_DIRS}
|
||||
${LIBFUSE3_INCLUDE_DIRS}
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set(REPERTORY_LINK_LIBRARIES
|
||||
${LIBFUSE2_LIBRARIES}
|
||||
${LIBFUSE3_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${CURL_LIBRARIES}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${LIBSODIUM_LIBRARIES}
|
||||
${REPERTORY_LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE REPERTORY_HEADERS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/*.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/*.hh
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/**/*.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/**/*.hh
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/**/*.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/pugixml/src/*.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/sqlite/include/*.h
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE REPERTORY_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/**/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/pugixml/src/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/sqlite/src/*.c
|
||||
)
|
||||
list(REMOVE_ITEM REPERTORY_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)
|
||||
|
||||
include(cmake/helpers.cmake)
|
||||
include(cmake/librepertory.cmake)
|
||||
include(cmake/repertory.cmake)
|
||||
include(cmake/unittests.cmake)
|
||||
include(cmake/install.cmake)
|
||||
|
||||
message(STATUS "Repertory Version: ${REPERTORY_VERSION}")
|
||||
message(STATUS "Git Revision: ${REPERTORY_GIT_REV}")
|
||||
|
@@ -16,13 +16,11 @@ on Windows.
|
||||
|
||||
* [Sia renterd](https://github.com/SiaFoundation/renterd/releases) v0.4.0+ for Sia support
|
||||
* Only 64-bit operating systems are supported
|
||||
* Linux requires the following dependencies:
|
||||
* `libfuse3`
|
||||
* Linux requires `fusermount3` or `repertory` must be manually compiled with `libfuse2` support
|
||||
* OS X requires the following dependency to be installed:
|
||||
* [FUSE for macOS v4.5.0](https://github.com/osxfuse/osxfuse/releases/download/macfuse-4.5.0/macfuse-4.5.0.dmg)
|
||||
* Windows requires the following dependencies to be installed:
|
||||
* [WinFSP 2023](https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi)
|
||||
* [Microsoft Visual C++ Redistributable for Visual Studio 2015, 2017 and 2019](https://aka.ms/vs/16/release/vc_redist.x64.exe)
|
||||
|
||||
## Supported Operating Systems
|
||||
|
||||
@@ -42,10 +40,9 @@ on Windows.
|
||||
* [libfuse](https://github.com/libfuse/libfuse)
|
||||
* [libsodium](https://doc.libsodium.org/)
|
||||
* [OpenSSL](https://www.openssl.org/)
|
||||
* [OSSP uuid](http://www.ossp.org/pkg/lib/uuid/)
|
||||
* [RocksDB](https://rocksdb.org/)
|
||||
* [ScPrime](https://scpri.me/)
|
||||
* [Sia Decentralized Cloud Storage](https://sia.tech/)
|
||||
* [SQLite](https://www.sqlite.org)
|
||||
* [stduuid](https://github.com/mariusbancila/stduuid)
|
||||
* [Storj](https://storj.io/)
|
||||
* [WinFSP - FUSE for Windows](https://github.com/billziss-gh/winfsp)
|
||||
@@ -80,4 +77,3 @@ mMH3segHBkRj0xJcfOxceRLj1a+ULIIR3xL/3f8s5Id25TDo/nqBoCvu5PeCpo6L
|
||||
9wIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
```
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "4")
|
||||
message(FATAL_ERROR "32-bit compilation is not supported")
|
||||
else()
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*|arm64.*|ARM64.*)")
|
||||
set(REPERTORY_UNIX_ARCH armv8-a)
|
||||
set(IS_ARM64 TRUE)
|
||||
else()
|
||||
set(REPERTORY_UNIX_ARCH x86-64)
|
||||
endif()
|
||||
endif()
|
||||
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "4")
|
||||
message(FATAL_ERROR "32-bit compilation is not supported")
|
||||
else()
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*|arm64.*|ARM64.*)")
|
||||
set(REPERTORY_UNIX_ARCH armv8-a)
|
||||
set(IS_ARM64 TRUE)
|
||||
else()
|
||||
set(REPERTORY_UNIX_ARCH x86-64)
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -1,97 +1,97 @@
|
||||
set(BOOST_VERSION ${BOOST_MAJOR_VERSION}.${BOOST_MINOR_VERSION}.${BOOST_REVISION})
|
||||
set(BOOST_VERSION2 ${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION}_${BOOST_REVISION})
|
||||
|
||||
set(BOOST_PROJECT_NAME boost_${BOOST_VERSION})
|
||||
set(BOOST_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${BOOST_PROJECT_NAME})
|
||||
|
||||
set(BOOST_ADDRESS_MODEL 64)
|
||||
|
||||
set(BOOST_DOWNLOAD_URL https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION2}.tar.gz)
|
||||
|
||||
if (IS_CLANG_COMPILER)
|
||||
set(BOOST_TOOLSET --with-toolset=clang)
|
||||
else ()
|
||||
set(BOOST_OPENSSL_DIR "--openssldir=${EXTERNAL_BUILD_ROOT}")
|
||||
endif()
|
||||
|
||||
if (IS_ARM64)
|
||||
set (BOOST_ARCH arm)
|
||||
else()
|
||||
set (BOOST_ARCH x86)
|
||||
endif()
|
||||
|
||||
set (BOOST_COMMON_ARGS
|
||||
${BOOST_OPENSSL_DIR}
|
||||
--prefix=${EXTERNAL_BUILD_ROOT}
|
||||
address-model=${BOOST_ADDRESS_MODEL}
|
||||
architecture=${BOOST_ARCH}
|
||||
cxxflags=-std=c++${CMAKE_CXX_STANDARD}
|
||||
cxxstd=${CMAKE_CXX_STANDARD}
|
||||
define=BOOST_ASIO_HAS_STD_STRING_VIEW
|
||||
define=BOOST_SYSTEM_NO_DEPRECATED
|
||||
link=static
|
||||
linkflags=-std=c++${CMAKE_CXX_STANDARD}
|
||||
threading=multi
|
||||
variant=${CMAKE_BUILD_TYPE_LOWER}
|
||||
-sZLIB_BINARY=zlibstatic${DEBUG_EXTRA}
|
||||
-sZLIB_LIBPATH="${EXTERNAL_BUILD_ROOT}/lib"
|
||||
-sZLIB_INCLUDE="${EXTERNAL_BUILD_ROOT}/include"
|
||||
)
|
||||
|
||||
if (MINGW)
|
||||
if (NOT CMAKE_HOST_WIN32)
|
||||
set(BOOST_COMMON_ARGS
|
||||
${BOOST_COMMON_ARGS}
|
||||
--user-config=./user-config.jam
|
||||
)
|
||||
endif()
|
||||
set(BOOST_TARGET_OS target-os=windows)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(boost_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
URL ${BOOST_DOWNLOAD_URL}
|
||||
PREFIX ${BOOST_BUILD_ROOT}
|
||||
BUILD_IN_SOURCE 1
|
||||
CONFIGURE_COMMAND
|
||||
cp -f ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/user-config.jam . &&
|
||||
./bootstrap.sh
|
||||
${BOOST_TOOLSET}
|
||||
${BOOST_TARGET_OS}
|
||||
--with-libraries=atomic,chrono,date_time,filesystem,random,regex,serialization,system,thread
|
||||
BUILD_COMMAND
|
||||
./b2
|
||||
${BOOST_COMMON_ARGS}
|
||||
${BOOST_TARGET_OS}
|
||||
INSTALL_COMMAND
|
||||
./b2
|
||||
${BOOST_COMMON_ARGS}
|
||||
${BOOST_TARGET_OS}
|
||||
install
|
||||
)
|
||||
|
||||
add_dependencies(boost_project openssl_project)
|
||||
|
||||
if (MINGW AND CMAKE_HOST_WIN32)
|
||||
set(BOOST_GCC_VERSION ${CMAKE_CXX_COMPILER_VERSION})
|
||||
string(REPLACE "." ";" BOOST_GCC_VERSION_LIST ${BOOST_GCC_VERSION})
|
||||
list(GET BOOST_GCC_VERSION_LIST 0 BOOST_GCC_MAJOR_VERSION)
|
||||
set(BOOST_LIB_EXTRA "-mgw${BOOST_GCC_MAJOR_VERSION}-mt${DEBUG_EXTRA2}-x64-${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION}")
|
||||
endif()
|
||||
|
||||
set(Boost_LIBRARIES
|
||||
libboost_system${BOOST_LIB_EXTRA}.a
|
||||
libboost_atomic${BOOST_LIB_EXTRA}.a
|
||||
libboost_chrono${BOOST_LIB_EXTRA}.a
|
||||
libboost_date_time${BOOST_LIB_EXTRA}.a
|
||||
libboost_filesystem${BOOST_LIB_EXTRA}.a
|
||||
libboost_random${BOOST_LIB_EXTRA}.a
|
||||
libboost_regex${BOOST_LIB_EXTRA}.a
|
||||
libboost_serialization${BOOST_LIB_EXTRA}.a
|
||||
libboost_thread${BOOST_LIB_EXTRA}.a
|
||||
)
|
||||
|
||||
add_dependencies(boost_project zlib_project)
|
||||
if (CMAKE_HOST_WIN32)
|
||||
include_directories(SYSTEM ${EXTERNAL_BUILD_ROOT}/include/boost-${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION})
|
||||
endif()
|
||||
set(BOOST_VERSION ${BOOST_MAJOR_VERSION}.${BOOST_MINOR_VERSION}.${BOOST_REVISION})
|
||||
set(BOOST_VERSION2 ${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION}_${BOOST_REVISION})
|
||||
|
||||
set(BOOST_PROJECT_NAME boost_${BOOST_VERSION})
|
||||
set(BOOST_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${BOOST_PROJECT_NAME})
|
||||
|
||||
set(BOOST_ADDRESS_MODEL 64)
|
||||
|
||||
set(BOOST_DOWNLOAD_URL https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION2}.tar.gz)
|
||||
|
||||
if (IS_CLANG_COMPILER)
|
||||
set(BOOST_TOOLSET --with-toolset=clang)
|
||||
else ()
|
||||
set(BOOST_OPENSSL_DIR "--openssldir=${EXTERNAL_BUILD_ROOT}")
|
||||
endif()
|
||||
|
||||
if (IS_ARM64)
|
||||
set (BOOST_ARCH arm)
|
||||
else()
|
||||
set (BOOST_ARCH x86)
|
||||
endif()
|
||||
|
||||
set (BOOST_COMMON_ARGS
|
||||
${BOOST_OPENSSL_DIR}
|
||||
--prefix=${EXTERNAL_BUILD_ROOT}
|
||||
address-model=${BOOST_ADDRESS_MODEL}
|
||||
architecture=${BOOST_ARCH}
|
||||
cxxflags=-std=c++${CMAKE_CXX_STANDARD}
|
||||
cxxstd=${CMAKE_CXX_STANDARD}
|
||||
define=BOOST_ASIO_HAS_STD_STRING_VIEW
|
||||
define=BOOST_SYSTEM_NO_DEPRECATED
|
||||
link=static
|
||||
linkflags=-std=c++${CMAKE_CXX_STANDARD}
|
||||
threading=multi
|
||||
variant=${CMAKE_BUILD_TYPE_LOWER}
|
||||
-sZLIB_BINARY=zlibstatic${DEBUG_EXTRA}
|
||||
-sZLIB_LIBPATH="${EXTERNAL_BUILD_ROOT}/lib"
|
||||
-sZLIB_INCLUDE="${EXTERNAL_BUILD_ROOT}/include"
|
||||
)
|
||||
|
||||
if (MINGW)
|
||||
if (NOT CMAKE_HOST_WIN32)
|
||||
set(BOOST_COMMON_ARGS
|
||||
${BOOST_COMMON_ARGS}
|
||||
--user-config=./user-config.jam
|
||||
)
|
||||
endif()
|
||||
set(BOOST_TARGET_OS target-os=windows)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(boost_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
URL ${BOOST_DOWNLOAD_URL}
|
||||
PREFIX ${BOOST_BUILD_ROOT}
|
||||
BUILD_IN_SOURCE 1
|
||||
CONFIGURE_COMMAND
|
||||
cp -f ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/user-config.jam . &&
|
||||
./bootstrap.sh
|
||||
${BOOST_TOOLSET}
|
||||
${BOOST_TARGET_OS}
|
||||
--with-libraries=atomic,chrono,date_time,filesystem,random,regex,serialization,system,thread
|
||||
BUILD_COMMAND
|
||||
./b2
|
||||
${BOOST_COMMON_ARGS}
|
||||
${BOOST_TARGET_OS}
|
||||
INSTALL_COMMAND
|
||||
./b2
|
||||
${BOOST_COMMON_ARGS}
|
||||
${BOOST_TARGET_OS}
|
||||
install
|
||||
)
|
||||
|
||||
add_dependencies(boost_project openssl_project)
|
||||
|
||||
if (MINGW AND CMAKE_HOST_WIN32)
|
||||
set(BOOST_GCC_VERSION ${CMAKE_CXX_COMPILER_VERSION})
|
||||
string(REPLACE "." ";" BOOST_GCC_VERSION_LIST ${BOOST_GCC_VERSION})
|
||||
list(GET BOOST_GCC_VERSION_LIST 0 BOOST_GCC_MAJOR_VERSION)
|
||||
set(BOOST_LIB_EXTRA "-mgw${BOOST_GCC_MAJOR_VERSION}-mt${DEBUG_EXTRA2}-x64-${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION}")
|
||||
endif()
|
||||
|
||||
set(Boost_LIBRARIES
|
||||
libboost_system${BOOST_LIB_EXTRA}.a
|
||||
libboost_atomic${BOOST_LIB_EXTRA}.a
|
||||
libboost_chrono${BOOST_LIB_EXTRA}.a
|
||||
libboost_date_time${BOOST_LIB_EXTRA}.a
|
||||
libboost_filesystem${BOOST_LIB_EXTRA}.a
|
||||
libboost_random${BOOST_LIB_EXTRA}.a
|
||||
libboost_regex${BOOST_LIB_EXTRA}.a
|
||||
libboost_serialization${BOOST_LIB_EXTRA}.a
|
||||
libboost_thread${BOOST_LIB_EXTRA}.a
|
||||
)
|
||||
|
||||
add_dependencies(boost_project zlib_project)
|
||||
if (CMAKE_HOST_WIN32)
|
||||
include_directories(SYSTEM ${EXTERNAL_BUILD_ROOT}/include/boost-${BOOST_MAJOR_VERSION}_${BOOST_MINOR_VERSION})
|
||||
endif()
|
||||
|
134
cmake/curl.cmake
134
cmake/curl.cmake
@@ -1,67 +1,67 @@
|
||||
set(CURL_PROJECT_NAME curl_${CURL_VERSION})
|
||||
set(CURL_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${CURL_PROJECT_NAME})
|
||||
|
||||
if (OPENSSL_ROOT_DIR)
|
||||
set(CURL_OPENSSL_EXTRA -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR})
|
||||
elseif(LINUX OR MINGW)
|
||||
set(CURL_OPENSSL_EXTRA -DOPENSSL_ROOT_DIR=${EXTERNAL_BUILD_ROOT})
|
||||
endif()
|
||||
|
||||
set(CURL_CMAKE_ARGS
|
||||
${CURL_OPENSSL_EXTRA}
|
||||
-DBUILD_CURL_EXE=OFF
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DBUILD_TESTING=OFF
|
||||
-DCMAKE_BUILD_TYPE=${EXTERNAL_BUILD_TYPE}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
|
||||
-DCMAKE_GENERATOR=${CMAKE_GENERATOR}
|
||||
-DCMAKE_INSTALL_PREFIX=${EXTERNAL_BUILD_ROOT}
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE}
|
||||
-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}
|
||||
-DCURL_CA_BUNDLE=./cacert.pem
|
||||
-DCURL_CA_FALLBACK=ON
|
||||
-DCURL_DISABLE_LDAP=ON
|
||||
-DCURL_STATICLIB=ON
|
||||
-DCURL_USE_LIBPSL=OFF
|
||||
-DCURL_USE_LIBSSH2=OFF
|
||||
-DCURL_ZLIB=OFF
|
||||
-DENABLE_THREADED_RESOLVER=ON
|
||||
-DOPENSSL_USE_STATIC_LIBS=ON
|
||||
-DUSE_LIBIDN2=OFF
|
||||
)
|
||||
|
||||
if (CMAKE_TOOLCHAIN_FILE)
|
||||
set(CURL_CMAKE_ARGS
|
||||
${CURL_CMAKE_ARGS}
|
||||
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (MINGW)
|
||||
set(CURL_CMAKE_ARGS
|
||||
${CURL_CMAKE_ARGS}
|
||||
-DCURL_USE_OPENSSL=OFF
|
||||
-DUSE_WIN32_CRYPTO=ON
|
||||
)
|
||||
else()
|
||||
set(CURL_CMAKE_ARGS
|
||||
${CURL_CMAKE_ARGS}
|
||||
-DCURL_USE_OPENSSL=ON
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(curl_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
URL https://github.com/curl/curl/archive/curl-${CURL_VERSION}.tar.gz
|
||||
PREFIX ${CURL_BUILD_ROOT}
|
||||
CMAKE_ARGS ${CURL_CMAKE_ARGS}
|
||||
)
|
||||
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DCURL_STATICLIB=ON -DCURL_DISABLE_LDAP=ON)
|
||||
|
||||
set(CURL_LIBRARIES libcurl${DEBUG_EXTRA2}${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
add_dependencies(curl_project
|
||||
openssl_project
|
||||
zlib_project
|
||||
)
|
||||
set(CURL_PROJECT_NAME curl_${CURL_VERSION})
|
||||
set(CURL_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${CURL_PROJECT_NAME})
|
||||
|
||||
if (OPENSSL_ROOT_DIR)
|
||||
set(CURL_OPENSSL_EXTRA -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR})
|
||||
elseif(LINUX OR MINGW)
|
||||
set(CURL_OPENSSL_EXTRA -DOPENSSL_ROOT_DIR=${EXTERNAL_BUILD_ROOT})
|
||||
endif()
|
||||
|
||||
set(CURL_CMAKE_ARGS
|
||||
${CURL_OPENSSL_EXTRA}
|
||||
-DBUILD_CURL_EXE=OFF
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DBUILD_TESTING=OFF
|
||||
-DCMAKE_BUILD_TYPE=${EXTERNAL_BUILD_TYPE}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
|
||||
-DCMAKE_GENERATOR=${CMAKE_GENERATOR}
|
||||
-DCMAKE_INSTALL_PREFIX=${EXTERNAL_BUILD_ROOT}
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE}
|
||||
-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}
|
||||
-DCURL_CA_BUNDLE=./cacert.pem
|
||||
-DCURL_CA_FALLBACK=ON
|
||||
-DCURL_DISABLE_LDAP=ON
|
||||
-DCURL_STATICLIB=ON
|
||||
-DCURL_USE_LIBPSL=OFF
|
||||
-DCURL_USE_LIBSSH2=OFF
|
||||
-DCURL_ZLIB=OFF
|
||||
-DENABLE_THREADED_RESOLVER=ON
|
||||
-DOPENSSL_USE_STATIC_LIBS=ON
|
||||
-DUSE_LIBIDN2=OFF
|
||||
)
|
||||
|
||||
if (CMAKE_TOOLCHAIN_FILE)
|
||||
set(CURL_CMAKE_ARGS
|
||||
${CURL_CMAKE_ARGS}
|
||||
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (MINGW)
|
||||
set(CURL_CMAKE_ARGS
|
||||
${CURL_CMAKE_ARGS}
|
||||
-DCURL_USE_OPENSSL=OFF
|
||||
-DUSE_WIN32_CRYPTO=ON
|
||||
)
|
||||
else()
|
||||
set(CURL_CMAKE_ARGS
|
||||
${CURL_CMAKE_ARGS}
|
||||
-DCURL_USE_OPENSSL=ON
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(curl_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
URL https://github.com/curl/curl/archive/curl-${CURL_VERSION}.tar.gz
|
||||
PREFIX ${CURL_BUILD_ROOT}
|
||||
CMAKE_ARGS ${CURL_CMAKE_ARGS}
|
||||
)
|
||||
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DCURL_STATICLIB=ON -DCURL_DISABLE_LDAP=ON)
|
||||
|
||||
set(CURL_LIBRARIES libcurl${DEBUG_EXTRA2}${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
add_dependencies(curl_project
|
||||
openssl_project
|
||||
zlib_project
|
||||
)
|
||||
|
@@ -1,103 +1,103 @@
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
set(IS_CLANG_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
if (UNIX OR MINGW)
|
||||
set(REPERTORY_COMMON_FLAG_LIST
|
||||
${REPERTORY_COMMON_FLAG_LIST}
|
||||
-D_FILE_OFFSET_BITS=64
|
||||
-march=${REPERTORY_UNIX_ARCH}
|
||||
-mtune=generic
|
||||
)
|
||||
|
||||
if (MINGW)
|
||||
set(REPERTORY_COMMON_FLAG_LIST
|
||||
${REPERTORY_COMMON_FLAG_LIST}
|
||||
-Wa,-mbig-obj
|
||||
-flarge-source-files
|
||||
)
|
||||
endif()
|
||||
|
||||
set(REPERTORY_COMMON_FLAG_LIST_DEBUG
|
||||
${REPERTORY_COMMON_FLAG_LIST_DEBUG}
|
||||
-DDEBUG
|
||||
-D_DEBUG
|
||||
-Og
|
||||
-fno-omit-frame-pointer
|
||||
-g
|
||||
-gdwarf-4
|
||||
)
|
||||
|
||||
set(REPERTORY_COMMON_FLAG_LIST_RELEASE
|
||||
${REPERTORY_COMMON_FLAG_LIST_RELEASE}
|
||||
-O3
|
||||
-DNDEBUG
|
||||
)
|
||||
|
||||
if (NOT IS_CLANG_COMPILER)
|
||||
set(REPERTORY_GCC_FLAGS
|
||||
-Wall
|
||||
-Wcast-align
|
||||
-Wconversion
|
||||
-Wdouble-promotion
|
||||
-Wduplicated-branches
|
||||
-Wduplicated-cond
|
||||
-Wextra
|
||||
-Wformat=2
|
||||
-Wlogical-op
|
||||
-Wmisleading-indentation
|
||||
-Wnull-dereference
|
||||
-Wpedantic
|
||||
-Wshadow
|
||||
-Wsign-conversion
|
||||
-Wunused
|
||||
)
|
||||
|
||||
set(REPERTORY_GCC_CXX_FLAGS
|
||||
-Wnon-virtual-dtor
|
||||
-Wold-style-cast
|
||||
-Woverloaded-virtual
|
||||
-Wuseless-cast
|
||||
)
|
||||
endif()
|
||||
|
||||
set(REPERTORY_C_FLAGS_LIST
|
||||
${REPERTORY_C_FLAGS_LIST}
|
||||
${REPERTORY_COMMON_FLAG_LIST}
|
||||
)
|
||||
|
||||
set(REPERTORY_CXX_FLAGS_LIST
|
||||
${REPERTORY_CXX_FLAGS_LIST}
|
||||
${REPERTORY_COMMON_FLAG_LIST}
|
||||
-std=c++${CMAKE_CXX_STANDARD}
|
||||
)
|
||||
endif()
|
||||
|
||||
list(JOIN REPERTORY_COMMON_FLAG_LIST_DEBUG " " REPERTORY_COMMON_FLAG_LIST_DEBUG)
|
||||
list(JOIN REPERTORY_COMMON_FLAG_LIST_RELEASE " " REPERTORY_COMMON_FLAG_LIST_RELEASE)
|
||||
|
||||
list(JOIN REPERTORY_CXX_FLAGS_LIST " " REPERTORY_CXX_FLAGS_LIST)
|
||||
list(JOIN REPERTORY_C_FLAGS_LIST " " REPERTORY_C_FLAGS_LIST)
|
||||
|
||||
list(JOIN REPERTORY_SHARED_LINKER_FLAGS_LIST " " REPERTORY_SHARED_LINKER_FLAGS_LIST)
|
||||
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${REPERTORY_CXX_FLAGS_LIST}")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${REPERTORY_C_FLAGS_LIST}")
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_DEBUG}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_DEBUG}")
|
||||
else()
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_RELEASE}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_RELEASE}")
|
||||
endif()
|
||||
|
||||
set (REPERTORY_CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_DEBUG}")
|
||||
set (REPERTORY_CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_DEBUG}")
|
||||
set (REPERTORY_CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_RELEASE}")
|
||||
set (REPERTORY_CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_RELEASE}")
|
||||
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${REPERTORY_SHARED_LINKER_FLAGS_LIST}")
|
||||
if (ALPINE_FOUND OR MINGW)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
|
||||
endif()
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
set(IS_CLANG_COMPILER TRUE)
|
||||
endif()
|
||||
|
||||
if (UNIX OR MINGW)
|
||||
set(REPERTORY_COMMON_FLAG_LIST
|
||||
${REPERTORY_COMMON_FLAG_LIST}
|
||||
-D_FILE_OFFSET_BITS=64
|
||||
-march=${REPERTORY_UNIX_ARCH}
|
||||
-mtune=generic
|
||||
)
|
||||
|
||||
if (MINGW)
|
||||
set(REPERTORY_COMMON_FLAG_LIST
|
||||
${REPERTORY_COMMON_FLAG_LIST}
|
||||
-Wa,-mbig-obj
|
||||
-flarge-source-files
|
||||
)
|
||||
endif()
|
||||
|
||||
set(REPERTORY_COMMON_FLAG_LIST_DEBUG
|
||||
${REPERTORY_COMMON_FLAG_LIST_DEBUG}
|
||||
-DDEBUG
|
||||
-D_DEBUG
|
||||
-Og
|
||||
-fno-omit-frame-pointer
|
||||
-g
|
||||
-gdwarf-4
|
||||
)
|
||||
|
||||
set(REPERTORY_COMMON_FLAG_LIST_RELEASE
|
||||
${REPERTORY_COMMON_FLAG_LIST_RELEASE}
|
||||
-O3
|
||||
-DNDEBUG
|
||||
)
|
||||
|
||||
if (NOT IS_CLANG_COMPILER)
|
||||
set(REPERTORY_GCC_FLAGS
|
||||
-Wall
|
||||
-Wcast-align
|
||||
-Wconversion
|
||||
-Wdouble-promotion
|
||||
-Wduplicated-branches
|
||||
-Wduplicated-cond
|
||||
-Wextra
|
||||
-Wformat=2
|
||||
-Wlogical-op
|
||||
-Wmisleading-indentation
|
||||
-Wnull-dereference
|
||||
-Wpedantic
|
||||
-Wshadow
|
||||
-Wsign-conversion
|
||||
-Wunused
|
||||
)
|
||||
|
||||
set(REPERTORY_GCC_CXX_FLAGS
|
||||
-Wnon-virtual-dtor
|
||||
-Wold-style-cast
|
||||
-Woverloaded-virtual
|
||||
-Wno-useless-cast
|
||||
)
|
||||
endif()
|
||||
|
||||
set(REPERTORY_C_FLAGS_LIST
|
||||
${REPERTORY_C_FLAGS_LIST}
|
||||
${REPERTORY_COMMON_FLAG_LIST}
|
||||
)
|
||||
|
||||
set(REPERTORY_CXX_FLAGS_LIST
|
||||
${REPERTORY_CXX_FLAGS_LIST}
|
||||
${REPERTORY_COMMON_FLAG_LIST}
|
||||
-std=c++${CMAKE_CXX_STANDARD}
|
||||
)
|
||||
endif()
|
||||
|
||||
list(JOIN REPERTORY_COMMON_FLAG_LIST_DEBUG " " REPERTORY_COMMON_FLAG_LIST_DEBUG)
|
||||
list(JOIN REPERTORY_COMMON_FLAG_LIST_RELEASE " " REPERTORY_COMMON_FLAG_LIST_RELEASE)
|
||||
|
||||
list(JOIN REPERTORY_CXX_FLAGS_LIST " " REPERTORY_CXX_FLAGS_LIST)
|
||||
list(JOIN REPERTORY_C_FLAGS_LIST " " REPERTORY_C_FLAGS_LIST)
|
||||
|
||||
list(JOIN REPERTORY_SHARED_LINKER_FLAGS_LIST " " REPERTORY_SHARED_LINKER_FLAGS_LIST)
|
||||
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${REPERTORY_CXX_FLAGS_LIST}")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${REPERTORY_C_FLAGS_LIST}")
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_DEBUG}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_DEBUG}")
|
||||
else()
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_RELEASE}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_RELEASE}")
|
||||
endif()
|
||||
|
||||
set (REPERTORY_CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_DEBUG}")
|
||||
set (REPERTORY_CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_DEBUG}")
|
||||
set (REPERTORY_CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_RELEASE}")
|
||||
set (REPERTORY_CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} ${REPERTORY_COMMON_FLAG_LIST_RELEASE}")
|
||||
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${REPERTORY_SHARED_LINKER_FLAGS_LIST}")
|
||||
if (ALPINE_FOUND OR MINGW)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++ -static")
|
||||
endif()
|
||||
|
@@ -1,62 +1,62 @@
|
||||
function(copy_support_files target)
|
||||
if (MINGW)
|
||||
add_custom_command(
|
||||
TARGET ${target}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_SOURCE_DIR}/3rd_party/winfsp-${WINFSP_VERSION}/bin/${WINFSP_LIBRARY_BASENAME}.dll
|
||||
${REPERTORY_OUTPUT_DIR}/${WINFSP_LIBRARY_BASENAME}.dll)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${target}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_SOURCE_DIR}/3rd_party/cacert.pem
|
||||
${REPERTORY_OUTPUT_DIR}/cacert.pem)
|
||||
endfunction(copy_support_files)
|
||||
|
||||
function(set_common_target_options name)
|
||||
target_compile_definitions(${name} PUBLIC ${REPERTORY_DEFINITIONS})
|
||||
|
||||
if (UNIX OR MINGW)
|
||||
target_compile_options(${name} PRIVATE
|
||||
${REPERTORY_GCC_CXX_FLAGS}
|
||||
${REPERTORY_GCC_FLAGS}
|
||||
)
|
||||
endif()
|
||||
|
||||
target_precompile_headers(${name} PRIVATE include/common.hpp)
|
||||
|
||||
if (MACOS)
|
||||
target_link_libraries(${name} PRIVATE -W1,-rpath,@executable_path)
|
||||
set_target_properties(${name} PROPERTIES COMPILE_FLAGS -fvisibility=hidden)
|
||||
endif()
|
||||
|
||||
if (UNIX OR MINGW)
|
||||
target_compile_options(${name} PRIVATE
|
||||
${REPERTORY_GCC_CXX_FLAGS}
|
||||
${REPERTORY_GCC_FLAGS}
|
||||
)
|
||||
endif()
|
||||
endfunction(set_common_target_options)
|
||||
|
||||
function(add_project_executable name sources)
|
||||
add_executable(${name}
|
||||
src/main.cpp
|
||||
${REPERTORY_HEADERS}
|
||||
${sources}
|
||||
)
|
||||
|
||||
set_common_target_options(${name})
|
||||
|
||||
add_dependencies(${name} librepertory)
|
||||
|
||||
if (REPERTORY_MUSL OR MINGW)
|
||||
set_property(TARGET ${name} PROPERTY LINK_SEARCH_START_STATIC 1)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${name} PRIVATE librepertory)
|
||||
|
||||
copy_support_files(${name})
|
||||
endfunction(add_project_executable)
|
||||
function(copy_support_files target)
|
||||
if (MINGW)
|
||||
add_custom_command(
|
||||
TARGET ${target}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_SOURCE_DIR}/3rd_party/winfsp-${WINFSP_VERSION}/bin/${WINFSP_LIBRARY_BASENAME}.dll
|
||||
${REPERTORY_OUTPUT_DIR}/${WINFSP_LIBRARY_BASENAME}.dll)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${target}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_SOURCE_DIR}/3rd_party/cacert.pem
|
||||
${REPERTORY_OUTPUT_DIR}/cacert.pem)
|
||||
endfunction(copy_support_files)
|
||||
|
||||
function(set_common_target_options name)
|
||||
target_compile_definitions(${name} PUBLIC ${REPERTORY_DEFINITIONS})
|
||||
|
||||
if (UNIX OR MINGW)
|
||||
target_compile_options(${name} PRIVATE
|
||||
${REPERTORY_GCC_CXX_FLAGS}
|
||||
${REPERTORY_GCC_FLAGS}
|
||||
)
|
||||
endif()
|
||||
|
||||
target_precompile_headers(${name} PRIVATE include/common.hpp)
|
||||
|
||||
if (MACOS)
|
||||
target_link_libraries(${name} PRIVATE -W1,-rpath,@executable_path)
|
||||
set_target_properties(${name} PROPERTIES COMPILE_FLAGS -fvisibility=hidden)
|
||||
endif()
|
||||
|
||||
if (UNIX OR MINGW)
|
||||
target_compile_options(${name} PRIVATE
|
||||
${REPERTORY_GCC_CXX_FLAGS}
|
||||
${REPERTORY_GCC_FLAGS}
|
||||
)
|
||||
endif()
|
||||
endfunction(set_common_target_options)
|
||||
|
||||
function(add_project_executable name sources)
|
||||
add_executable(${name}
|
||||
src/main.cpp
|
||||
${REPERTORY_HEADERS}
|
||||
${sources}
|
||||
)
|
||||
|
||||
set_common_target_options(${name})
|
||||
|
||||
add_dependencies(${name} librepertory)
|
||||
|
||||
if (REPERTORY_MUSL OR MINGW)
|
||||
set_property(TARGET ${name} PROPERTY LINK_SEARCH_START_STATIC 1)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${name} PRIVATE librepertory)
|
||||
|
||||
copy_support_files(${name})
|
||||
endfunction(add_project_executable)
|
||||
|
@@ -1,17 +1,17 @@
|
||||
if (UNIX)
|
||||
macro(install_symlink filepath sympath)
|
||||
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${filepath} ${sympath})")
|
||||
install(CODE "message(\"-- Created symlink: ${sympath} -> ${filepath}\")")
|
||||
endmacro(install_symlink)
|
||||
|
||||
install(TARGETS repertory RUNTIME DESTINATION share/repertory)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/cacert.pem RUNTIME DESTINATION share/repertory)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/CHANGELOG.md RUNTIME DESTINATION share/repertory)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/CONTRIBUTORS.md RUNTIME DESTINATION share/repertory)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md RUNTIME DESTINATION share/repertory)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.md RUNTIME DESTINATION share/repertory)
|
||||
if (LINUX)
|
||||
install_symlink(${CMAKE_INSTALL_PREFIX}/share/repertory/repertory ${CMAKE_INSTALL_PREFIX}/sbin/mount.repertory)
|
||||
install_symlink(${CMAKE_INSTALL_PREFIX}/share/repertory/repertory ${CMAKE_INSTALL_PREFIX}/sbin/repertory)
|
||||
endif()
|
||||
endif()
|
||||
if (UNIX)
|
||||
macro(install_symlink filepath sympath)
|
||||
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${filepath} ${sympath})")
|
||||
install(CODE "message(\"-- Created symlink: ${sympath} -> ${filepath}\")")
|
||||
endmacro(install_symlink)
|
||||
|
||||
install(TARGETS repertory RUNTIME DESTINATION share/repertory)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/cacert.pem RUNTIME DESTINATION share/repertory)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/CHANGELOG.md RUNTIME DESTINATION share/repertory)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/CONTRIBUTORS.md RUNTIME DESTINATION share/repertory)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md RUNTIME DESTINATION share/repertory)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.md RUNTIME DESTINATION share/repertory)
|
||||
if (LINUX)
|
||||
install_symlink(${CMAKE_INSTALL_PREFIX}/share/repertory/repertory ${CMAKE_INSTALL_PREFIX}/sbin/mount.repertory)
|
||||
install_symlink(${CMAKE_INSTALL_PREFIX}/share/repertory/repertory ${CMAKE_INSTALL_PREFIX}/sbin/repertory)
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -1,22 +1,21 @@
|
||||
if (EXISTS "${CMAKE_CURRENT_BINARY_DIR}/librepertory${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/librepertory${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
endif()
|
||||
|
||||
add_library(librepertory STATIC
|
||||
${REPERTORY_SOURCES}
|
||||
${REPERTORY_HEADERS}
|
||||
)
|
||||
|
||||
set_common_target_options(librepertory)
|
||||
|
||||
set_target_properties(librepertory PROPERTIES PREFIX "")
|
||||
target_link_libraries(librepertory PRIVATE ${REPERTORY_LINK_LIBRARIES})
|
||||
|
||||
add_dependencies(librepertory
|
||||
boost_project
|
||||
curl_project
|
||||
libsodium_project
|
||||
openssl_project
|
||||
rocksdb_project
|
||||
zlib_project
|
||||
)
|
||||
if (EXISTS "${CMAKE_CURRENT_BINARY_DIR}/librepertory${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/librepertory${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
endif()
|
||||
|
||||
add_library(librepertory STATIC
|
||||
${REPERTORY_SOURCES}
|
||||
${REPERTORY_HEADERS}
|
||||
)
|
||||
|
||||
set_common_target_options(librepertory)
|
||||
|
||||
set_target_properties(librepertory PROPERTIES PREFIX "")
|
||||
target_link_libraries(librepertory PRIVATE ${REPERTORY_LINK_LIBRARIES})
|
||||
|
||||
add_dependencies(librepertory
|
||||
boost_project
|
||||
curl_project
|
||||
libsodium_project
|
||||
openssl_project
|
||||
zlib_project
|
||||
)
|
||||
|
@@ -1,27 +1,27 @@
|
||||
set(LIBSODIUM_PROJECT_NAME libsodium_${LIBSODIUM_VERSION})
|
||||
set(LIBSODIUM_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${LIBSODIUM_PROJECT_NAME})
|
||||
set(LIBSODIUM_BUILD_TYPE ${EXTERNAL_BUILD_TYPE})
|
||||
|
||||
if (MINGW)
|
||||
set(LIBSODIUM_HOST --host=x86_64-w64-mingw32)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(libsodium_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
PREFIX ${LIBSODIUM_BUILD_ROOT}
|
||||
BUILD_IN_SOURCE 1
|
||||
URL https://github.com/jedisct1/libsodium/releases/download/${LIBSODIUM_VERSION}-RELEASE/libsodium-${LIBSODIUM_VERSION}.tar.gz
|
||||
CONFIGURE_COMMAND
|
||||
./configure
|
||||
${LIBSODIUM_HOST}
|
||||
--prefix=${EXTERNAL_BUILD_ROOT}
|
||||
--enable-shared=no
|
||||
--enable-static=yes
|
||||
--disable-asm
|
||||
BUILD_COMMAND make
|
||||
INSTALL_COMMAND make install
|
||||
)
|
||||
|
||||
set(LIBSODIUM_LIBRARIES libsodium.a)
|
||||
|
||||
add_dependencies(libsodium_project zlib_project)
|
||||
set(LIBSODIUM_PROJECT_NAME libsodium_${LIBSODIUM_VERSION})
|
||||
set(LIBSODIUM_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${LIBSODIUM_PROJECT_NAME})
|
||||
set(LIBSODIUM_BUILD_TYPE ${EXTERNAL_BUILD_TYPE})
|
||||
|
||||
if (MINGW)
|
||||
set(LIBSODIUM_HOST --host=x86_64-w64-mingw32)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(libsodium_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
PREFIX ${LIBSODIUM_BUILD_ROOT}
|
||||
BUILD_IN_SOURCE 1
|
||||
URL https://github.com/jedisct1/libsodium/releases/download/${LIBSODIUM_VERSION}-RELEASE/libsodium-${LIBSODIUM_VERSION}.tar.gz
|
||||
CONFIGURE_COMMAND
|
||||
./configure
|
||||
${LIBSODIUM_HOST}
|
||||
--prefix=${EXTERNAL_BUILD_ROOT}
|
||||
--enable-shared=no
|
||||
--enable-static=yes
|
||||
--disable-asm
|
||||
BUILD_COMMAND make
|
||||
INSTALL_COMMAND make install
|
||||
)
|
||||
|
||||
set(LIBSODIUM_LIBRARIES libsodium.a)
|
||||
|
||||
add_dependencies(libsodium_project zlib_project)
|
||||
|
@@ -1,16 +1,16 @@
|
||||
set(CMAKE_SYSTEM_NAME Windows)
|
||||
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
|
||||
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
|
||||
set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_PREFIX}-gfortran)
|
||||
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH
|
||||
/usr/${TOOLCHAIN_PREFIX}
|
||||
/usr/local/${TOOLCHAIN_PREFIX}
|
||||
)
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_SYSTEM_NAME Windows)
|
||||
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
|
||||
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
|
||||
set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_PREFIX}-gfortran)
|
||||
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH
|
||||
/usr/${TOOLCHAIN_PREFIX}
|
||||
/usr/local/${TOOLCHAIN_PREFIX}
|
||||
)
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
|
@@ -1,36 +1,36 @@
|
||||
if (IS_CLANG_COMPILER)
|
||||
set(OPENSSL_COMPILE_TYPE_EXTRA -clang)
|
||||
endif()
|
||||
|
||||
if (MACOS)
|
||||
set(OPENSSL_COMPILE_TYPE darwin64-x86_64-cc)
|
||||
elseif(IS_ARM64)
|
||||
set(OPENSSL_COMPILE_TYPE linux-aarch64${OPENSSL_COMPILE_TYPE_EXTRA})
|
||||
elseif(MINGW)
|
||||
if (CMAKE_TOOLCHAIN_FILE)
|
||||
set(OPENSSL_COMPILE_TYPE --cross-compile-prefix=x86_64-w64-mingw32- mingw64${OPENSSL_COMPILE_TYPE_EXTRA})
|
||||
else()
|
||||
set(OPENSSL_COMPILE_TYPE mingw64${OPENSSL_COMPILE_TYPE_EXTRA})
|
||||
endif()
|
||||
else()
|
||||
set(OPENSSL_COMPILE_TYPE linux-x86_64${OPENSSL_COMPILE_TYPE_EXTRA})
|
||||
endif()
|
||||
|
||||
set(OPENSSL_PROJECT_NAME openssl_${OPENSSL_VERSION})
|
||||
set(OPENSSL_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${OPENSSL_PROJECT_NAME})
|
||||
ExternalProject_Add(openssl_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
URL https://github.com/openssl/openssl/releases/download/openssl-${OPENSSL_VERSION}/openssl-${OPENSSL_VERSION}.tar.gz
|
||||
PREFIX ${OPENSSL_BUILD_ROOT}
|
||||
BUILD_IN_SOURCE 1
|
||||
CONFIGURE_COMMAND ./Configure no-shared ${OPENSSL_COMPILE_TYPE} --openssldir=${EXTERNAL_BUILD_ROOT}/ssl --prefix=${EXTERNAL_BUILD_ROOT}
|
||||
BUILD_COMMAND make -j1
|
||||
INSTALL_COMMAND make install
|
||||
)
|
||||
|
||||
set(OPENSSL_LIBRARIES
|
||||
${EXTERNAL_BUILD_ROOT}/lib/libssl.a
|
||||
${EXTERNAL_BUILD_ROOT}/lib/libcrypto.a
|
||||
)
|
||||
|
||||
add_dependencies(openssl_project zlib_project)
|
||||
if (IS_CLANG_COMPILER)
|
||||
set(OPENSSL_COMPILE_TYPE_EXTRA -clang)
|
||||
endif()
|
||||
|
||||
if (MACOS)
|
||||
set(OPENSSL_COMPILE_TYPE darwin64-x86_64-cc)
|
||||
elseif(IS_ARM64)
|
||||
set(OPENSSL_COMPILE_TYPE linux-aarch64${OPENSSL_COMPILE_TYPE_EXTRA})
|
||||
elseif(MINGW)
|
||||
if (CMAKE_TOOLCHAIN_FILE)
|
||||
set(OPENSSL_COMPILE_TYPE --cross-compile-prefix=x86_64-w64-mingw32- mingw64${OPENSSL_COMPILE_TYPE_EXTRA})
|
||||
else()
|
||||
set(OPENSSL_COMPILE_TYPE mingw64${OPENSSL_COMPILE_TYPE_EXTRA})
|
||||
endif()
|
||||
else()
|
||||
set(OPENSSL_COMPILE_TYPE linux-x86_64${OPENSSL_COMPILE_TYPE_EXTRA})
|
||||
endif()
|
||||
|
||||
set(OPENSSL_PROJECT_NAME openssl_${OPENSSL_VERSION})
|
||||
set(OPENSSL_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${OPENSSL_PROJECT_NAME})
|
||||
ExternalProject_Add(openssl_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
URL https://github.com/openssl/openssl/releases/download/openssl-${OPENSSL_VERSION}/openssl-${OPENSSL_VERSION}.tar.gz
|
||||
PREFIX ${OPENSSL_BUILD_ROOT}
|
||||
BUILD_IN_SOURCE 1
|
||||
CONFIGURE_COMMAND ./Configure no-shared ${OPENSSL_COMPILE_TYPE} --openssldir=${EXTERNAL_BUILD_ROOT}/ssl --prefix=${EXTERNAL_BUILD_ROOT}
|
||||
BUILD_COMMAND make -j1
|
||||
INSTALL_COMMAND make install
|
||||
)
|
||||
|
||||
set(OPENSSL_LIBRARIES
|
||||
${EXTERNAL_BUILD_ROOT}/lib/libssl.a
|
||||
${EXTERNAL_BUILD_ROOT}/lib/libcrypto.a
|
||||
)
|
||||
|
||||
add_dependencies(openssl_project zlib_project)
|
||||
|
@@ -1,11 +1,11 @@
|
||||
option(REPERTORY_ENABLE_TESTING "Enable testing" ON)
|
||||
|
||||
option(REPERTORY_ENABLE_S3 "Enable S3 mount support" OFF)
|
||||
if (REPERTORY_ENABLE_S3)
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DREPERTORY_ENABLE_S3)
|
||||
|
||||
option(REPERTORY_ENABLE_S3_TESTING "Enable S3 unit tests" OFF)
|
||||
if (REPERTORY_ENABLE_S3_TESTING)
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DREPERTORY_ENABLE_S3_TESTING)
|
||||
endif ()
|
||||
endif()
|
||||
option(REPERTORY_ENABLE_TESTING "Enable testing" ON)
|
||||
|
||||
option(REPERTORY_ENABLE_S3 "Enable S3 mount support" OFF)
|
||||
if (REPERTORY_ENABLE_S3)
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DREPERTORY_ENABLE_S3)
|
||||
|
||||
option(REPERTORY_ENABLE_S3_TESTING "Enable S3 unit tests" OFF)
|
||||
if (REPERTORY_ENABLE_S3_TESTING)
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DREPERTORY_ENABLE_S3_TESTING)
|
||||
endif ()
|
||||
endif()
|
||||
|
@@ -1,13 +1,13 @@
|
||||
if(UNIX AND NOT APPLE)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
set(FREEBSD TRUE)
|
||||
else()
|
||||
set(LINUX TRUE)
|
||||
endif()
|
||||
elseif(UNIX AND APPLE)
|
||||
set(MACOS TRUE)
|
||||
endif()
|
||||
|
||||
if (LINUX)
|
||||
find_file(ALPINE_FOUND alpine-release PATHS /etc)
|
||||
endif()
|
||||
if(UNIX AND NOT APPLE)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
set(FREEBSD TRUE)
|
||||
else()
|
||||
set(LINUX TRUE)
|
||||
endif()
|
||||
elseif(UNIX AND APPLE)
|
||||
set(MACOS TRUE)
|
||||
endif()
|
||||
|
||||
if (LINUX)
|
||||
find_file(ALPINE_FOUND alpine-release PATHS /etc)
|
||||
endif()
|
||||
|
@@ -1 +1 @@
|
||||
add_project_executable(repertory "${WINDOWS_VERSION_RC}")
|
||||
add_project_executable(repertory "${WINDOWS_VERSION_RC}")
|
||||
|
@@ -1,71 +0,0 @@
|
||||
set(ROCKSDB_PROJECT_NAME rocksdb_${ROCKSDB_VERSION})
|
||||
set(ROCKSDB_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${ROCKSDB_PROJECT_NAME})
|
||||
|
||||
set(ROCKSDB_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
if (MACOS)
|
||||
set(ROCKSDB_CMAKE_CXX_FLAGS "${ROCKSDB_CMAKE_CXX_FLAGS} -fvisibility=hidden")
|
||||
endif()
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(ROCKSDB_CMAKE_CXX_FLAGS "${ROCKSDB_CMAKE_CXX_FLAGS} -DXXH_NO_INLINE_HINTS")
|
||||
set(REPERTORY_DEFINITIONS "${REPERTORY_DEFINITIONS} -DXXH_NO_INLINE_HINTS")
|
||||
endif()
|
||||
|
||||
set(ROCKSDB_CMAKE_ARGS
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_CXX_FLAGS=${ROCKSDB_CMAKE_CXX_FLAGS}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
|
||||
-DCMAKE_GENERATOR=${CMAKE_GENERATOR}
|
||||
-DCMAKE_INSTALL_PREFIX=${EXTERNAL_BUILD_ROOT}
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE}
|
||||
-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}
|
||||
-DFAIL_ON_WARNINGS=OFF
|
||||
-DPORTABLE=1
|
||||
-DROCKSDB_BUILD_SHARED=OFF
|
||||
-DWITH_BENCHMARK_TOOLS=OFF
|
||||
-DWITH_GFLAGS=OFF
|
||||
-DWITH_LIBURING=OFF
|
||||
-DWITH_TESTS=OFF
|
||||
-DWITH_TOOLS=OFF
|
||||
)
|
||||
|
||||
if (MINGW)
|
||||
if (CMAKE_TOOLCHAIN_FILE)
|
||||
set(ROCKSDB_CMAKE_ARGS
|
||||
${ROCKSDB_CMAKE_ARGS}
|
||||
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(rocksdb_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
URL https://github.com/facebook/rocksdb/archive/v${ROCKSDB_VERSION}.tar.gz
|
||||
PREFIX ${ROCKSDB_BUILD_ROOT}
|
||||
CMAKE_ARGS ${ROCKSDB_CMAKE_ARGS}
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "Skipping install step."
|
||||
)
|
||||
|
||||
set(ROCKSDB_LIBRARIES ${ROCKSDB_BUILD_ROOT}/src/rocksdb_project-build/librocksdb.a)
|
||||
include_directories(SYSTEM ${ROCKSDB_BUILD_ROOT}/src/rocksdb_project/include)
|
||||
else()
|
||||
ExternalProject_Add(rocksdb_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
URL https://github.com/facebook/rocksdb/archive/v${ROCKSDB_VERSION}.tar.gz
|
||||
PREFIX ${ROCKSDB_BUILD_ROOT}
|
||||
CMAKE_ARGS ${ROCKSDB_CMAKE_ARGS}
|
||||
)
|
||||
|
||||
if (MACOS)
|
||||
set(ROCKSDB_LIBRARIES ${EXTERNAL_BUILD_ROOT}/lib/librocksdb.a)
|
||||
else()
|
||||
set(ROCKSDB_LIBRARIES librocksdb.a)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (LINUX OR MINGW)
|
||||
add_dependencies(rocksdb_project curl_project)
|
||||
endif()
|
||||
|
||||
add_dependencies(rocksdb_project zlib_project)
|
@@ -1,39 +1,39 @@
|
||||
if (ALPINE_FOUND)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE OFF)
|
||||
|
||||
set(REPERTORY_MUSL ON)
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DREPERTORY_MUSL)
|
||||
else()
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
set(CMAKE_COLOR_MAKEFILE OFF)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(DEBUG_EXTRA d)
|
||||
set(DEBUG_EXTRA2 -${DEBUG_EXTRA})
|
||||
set(DEBUG_EXTRA3 _${DEBUG_EXTRA})
|
||||
set(BOOST_DEBUG_EXTRA gd-)
|
||||
set(CMAKE_BUILD_TYPE_LOWER debug)
|
||||
else()
|
||||
set(CMAKE_BUILD_TYPE_LOWER release)
|
||||
endif()
|
||||
string(TOLOWER "${CMAKE_GENERATOR}" CMAKE_GENERATOR_LOWER)
|
||||
|
||||
set(REPERTORY_OUTPUT_DIR ${CMAKE_BINARY_DIR})
|
||||
|
||||
set(EXTERNAL_BUILD_ROOT ${CMAKE_BINARY_DIR}/external)
|
||||
set(EXTERNAL_BUILD_TYPE ${CMAKE_BUILD_TYPE})
|
||||
|
||||
if (UNIX OR MINGW)
|
||||
file(MAKE_DIRECTORY ${EXTERNAL_BUILD_ROOT}/lib)
|
||||
file(CREATE_LINK ${EXTERNAL_BUILD_ROOT}/lib ${EXTERNAL_BUILD_ROOT}/lib64 SYMBOLIC)
|
||||
endif()
|
||||
if (ALPINE_FOUND)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE OFF)
|
||||
|
||||
set(REPERTORY_MUSL ON)
|
||||
set(REPERTORY_DEFINITIONS ${REPERTORY_DEFINITIONS} -DREPERTORY_MUSL)
|
||||
else()
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
set(CMAKE_COLOR_MAKEFILE OFF)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(DEBUG_EXTRA d)
|
||||
set(DEBUG_EXTRA2 -${DEBUG_EXTRA})
|
||||
set(DEBUG_EXTRA3 _${DEBUG_EXTRA})
|
||||
set(BOOST_DEBUG_EXTRA gd-)
|
||||
set(CMAKE_BUILD_TYPE_LOWER debug)
|
||||
else()
|
||||
set(CMAKE_BUILD_TYPE_LOWER release)
|
||||
endif()
|
||||
string(TOLOWER "${CMAKE_GENERATOR}" CMAKE_GENERATOR_LOWER)
|
||||
|
||||
set(REPERTORY_OUTPUT_DIR ${CMAKE_BINARY_DIR})
|
||||
|
||||
set(EXTERNAL_BUILD_ROOT ${CMAKE_BINARY_DIR}/external)
|
||||
set(EXTERNAL_BUILD_TYPE ${CMAKE_BUILD_TYPE})
|
||||
|
||||
if (UNIX OR MINGW)
|
||||
file(MAKE_DIRECTORY ${EXTERNAL_BUILD_ROOT}/lib)
|
||||
file(CREATE_LINK ${EXTERNAL_BUILD_ROOT}/lib ${EXTERNAL_BUILD_ROOT}/lib64 SYMBOLIC)
|
||||
endif()
|
||||
|
@@ -1,66 +1,66 @@
|
||||
# Testing
|
||||
if (REPERTORY_ENABLE_TESTING)
|
||||
enable_testing()
|
||||
|
||||
set(GTEST_PROJECT_NAME gtest_${GTEST_VERSION})
|
||||
set(GTEST_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${GTEST_PROJECT_NAME})
|
||||
if (MACOS)
|
||||
set(GTEST_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
|
||||
set(GTEST_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
|
||||
else()
|
||||
set(GTEST_C_FLAGS ${CMAKE_C_FLAGS})
|
||||
set(GTEST_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
endif()
|
||||
ExternalProject_Add(gtest_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
URL https://github.com/google/googletest/archive/refs/tags/${GTEST_VERSION}.tar.gz
|
||||
PREFIX ${GTEST_BUILD_ROOT}
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_C_FLAGS=${GTEST_C_FLAGS}
|
||||
-DCMAKE_CXX_FLAGS=${GTEST_CXX_FLAGS}
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE}
|
||||
-DCMAKE_BUILD_TYPE=${EXTERNAL_BUILD_TYPE}
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "Skipping install step."
|
||||
)
|
||||
|
||||
set(GTEST_INCLUDE_DIRS
|
||||
${GTEST_BUILD_ROOT}/src/gtest_project/googletest/include
|
||||
${GTEST_BUILD_ROOT}/src/gtest_project/googlemock/include
|
||||
)
|
||||
|
||||
if(UNIX OR MINGW)
|
||||
set(GTEST_LIBRARIES
|
||||
${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/libgmock.a
|
||||
${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/libgtest.a
|
||||
${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/libgtest_main.a
|
||||
)
|
||||
endif()
|
||||
|
||||
file(GLOB_RECURSE UNITTEST_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/*.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/fixtures/*.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/mocks/*.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/utils/*.hpp
|
||||
)
|
||||
|
||||
add_project_executable(unittests "${UNITTEST_SOURCES}")
|
||||
add_dependencies(unittests
|
||||
gtest_project
|
||||
zlib_project
|
||||
)
|
||||
|
||||
target_compile_definitions(unittests PUBLIC
|
||||
GTEST_LINKED_AS_SHARED_LIBRARY=1
|
||||
REPERTORY_TESTING
|
||||
)
|
||||
target_include_directories(unittests PUBLIC
|
||||
${GTEST_INCLUDE_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests
|
||||
)
|
||||
target_link_libraries(unittests PRIVATE ${GTEST_LIBRARIES})
|
||||
|
||||
add_test(NAME AllTests COMMAND unittests WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
# Testing
|
||||
if (REPERTORY_ENABLE_TESTING)
|
||||
enable_testing()
|
||||
|
||||
set(GTEST_PROJECT_NAME gtest_${GTEST_VERSION})
|
||||
set(GTEST_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${GTEST_PROJECT_NAME})
|
||||
if (MACOS)
|
||||
set(GTEST_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
|
||||
set(GTEST_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
|
||||
else()
|
||||
set(GTEST_C_FLAGS ${CMAKE_C_FLAGS})
|
||||
set(GTEST_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
endif()
|
||||
ExternalProject_Add(gtest_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
URL https://github.com/google/googletest/archive/refs/tags/${GTEST_VERSION}.tar.gz
|
||||
PREFIX ${GTEST_BUILD_ROOT}
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_C_FLAGS=${GTEST_C_FLAGS}
|
||||
-DCMAKE_CXX_FLAGS=${GTEST_CXX_FLAGS}
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE}
|
||||
-DCMAKE_BUILD_TYPE=${EXTERNAL_BUILD_TYPE}
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "Skipping install step."
|
||||
)
|
||||
|
||||
set(GTEST_INCLUDE_DIRS
|
||||
${GTEST_BUILD_ROOT}/src/gtest_project/googletest/include
|
||||
${GTEST_BUILD_ROOT}/src/gtest_project/googlemock/include
|
||||
)
|
||||
|
||||
if(UNIX OR MINGW)
|
||||
set(GTEST_LIBRARIES
|
||||
${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/libgmock.a
|
||||
${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/libgtest.a
|
||||
${GTEST_BUILD_ROOT}/src/gtest_project-build/lib/libgtest_main.a
|
||||
)
|
||||
endif()
|
||||
|
||||
file(GLOB_RECURSE UNITTEST_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/*.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/fixtures/*.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/mocks/*.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/utils/*.hpp
|
||||
)
|
||||
|
||||
add_project_executable(unittests "${UNITTEST_SOURCES}")
|
||||
add_dependencies(unittests
|
||||
gtest_project
|
||||
zlib_project
|
||||
)
|
||||
|
||||
target_compile_definitions(unittests PUBLIC
|
||||
GTEST_LINKED_AS_SHARED_LIBRARY=1
|
||||
REPERTORY_TESTING
|
||||
)
|
||||
target_include_directories(unittests PUBLIC
|
||||
${GTEST_INCLUDE_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests
|
||||
)
|
||||
target_link_libraries(unittests PRIVATE ${GTEST_LIBRARIES})
|
||||
|
||||
add_test(NAME AllTests COMMAND unittests WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
|
@@ -1,11 +1,9 @@
|
||||
set(BOOST_MAJOR_VERSION 1)
|
||||
set(BOOST_MINOR_VERSION 83)
|
||||
set(BOOST_REVISION 0)
|
||||
set(CURL_VERSION 8_4_0)
|
||||
set(GTEST_VERSION v1.14.0)
|
||||
set(LIBSODIUM_VERSION 1.0.19)
|
||||
set(LIBUUID_VERSION 1.6.2)
|
||||
set(OPENSSL_VERSION 3.1.4)
|
||||
set(ROCKSDB_VERSION 8.6.7)
|
||||
set(WINFSP_VERSION 2.0)
|
||||
set(ZLIB_VERSION v1.3)
|
||||
set(BOOST_MAJOR_VERSION 1)
|
||||
set(BOOST_MINOR_VERSION 83)
|
||||
set(BOOST_REVISION 0)
|
||||
set(CURL_VERSION 8_5_0)
|
||||
set(GTEST_VERSION v1.14.0)
|
||||
set(LIBSODIUM_VERSION 1.0.19)
|
||||
set(OPENSSL_VERSION 3.2.0)
|
||||
set(WINFSP_VERSION 2.0)
|
||||
set(ZLIB_VERSION v1.3)
|
||||
|
@@ -1,31 +1,31 @@
|
||||
set(ZLIB_PROJECT_NAME zlib_${ZLIB_VERSION})
|
||||
set(ZLIB_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${ZLIB_PROJECT_NAME})
|
||||
set(ZLIB_CMAKE_ARGS
|
||||
-DCMAKE_BUILD_TYPE=${EXTERNAL_BUILD_TYPE}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
|
||||
-DCMAKE_GENERATOR=${CMAKE_GENERATOR}
|
||||
-DCMAKE_INSTALL_PREFIX=${EXTERNAL_BUILD_ROOT}
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE}
|
||||
-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}
|
||||
)
|
||||
|
||||
if (CMAKE_TOOLCHAIN_FILE)
|
||||
set(ZLIB_CMAKE_ARGS
|
||||
${ZLIB_CMAKE_ARGS}
|
||||
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(zlib_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
URL https://github.com/madler/zlib/archive/${ZLIB_VERSION}.tar.gz
|
||||
PREFIX ${ZLIB_BUILD_ROOT}
|
||||
CMAKE_ARGS ${ZLIB_CMAKE_ARGS}
|
||||
)
|
||||
|
||||
if(MINGW)
|
||||
set(ZLIB_LIBRARIES ${EXTERNAL_BUILD_ROOT}/lib/libzlibstatic${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
else()
|
||||
set(ZLIB_LIBRARIES ${EXTERNAL_BUILD_ROOT}/lib/libz${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
endif()
|
||||
set(ZLIB_PROJECT_NAME zlib_${ZLIB_VERSION})
|
||||
set(ZLIB_BUILD_ROOT ${EXTERNAL_BUILD_ROOT}/builds/${ZLIB_PROJECT_NAME})
|
||||
set(ZLIB_CMAKE_ARGS
|
||||
-DCMAKE_BUILD_TYPE=${EXTERNAL_BUILD_TYPE}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
|
||||
-DCMAKE_GENERATOR=${CMAKE_GENERATOR}
|
||||
-DCMAKE_INSTALL_PREFIX=${EXTERNAL_BUILD_ROOT}
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=${CMAKE_POSITION_INDEPENDENT_CODE}
|
||||
-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}
|
||||
)
|
||||
|
||||
if (CMAKE_TOOLCHAIN_FILE)
|
||||
set(ZLIB_CMAKE_ARGS
|
||||
${ZLIB_CMAKE_ARGS}
|
||||
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(zlib_project
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
URL https://github.com/madler/zlib/archive/${ZLIB_VERSION}.tar.gz
|
||||
PREFIX ${ZLIB_BUILD_ROOT}
|
||||
CMAKE_ARGS ${ZLIB_CMAKE_ARGS}
|
||||
)
|
||||
|
||||
if(MINGW)
|
||||
set(ZLIB_LIBRARIES ${EXTERNAL_BUILD_ROOT}/lib/libzlibstatic${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
else()
|
||||
set(ZLIB_LIBRARIES ${EXTERNAL_BUILD_ROOT}/lib/libz${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
endif()
|
||||
|
@@ -39,6 +39,9 @@ public:
|
||||
[[nodiscard]] static auto default_data_directory(const provider_type &prov)
|
||||
-> std::string;
|
||||
|
||||
[[nodiscard]] static auto default_remote_port(const provider_type &prov)
|
||||
-> std::uint16_t;
|
||||
|
||||
[[nodiscard]] static auto default_rpc_port(const provider_type &prov)
|
||||
-> std::uint16_t;
|
||||
|
||||
@@ -100,8 +103,8 @@ private:
|
||||
s3_config s3_config_;
|
||||
std::uint64_t version_ = REPERTORY_CONFIG_VERSION;
|
||||
std::string log_directory_;
|
||||
std::recursive_mutex read_write_mutex_;
|
||||
std::recursive_mutex remote_mount_mutex_;
|
||||
mutable std::recursive_mutex read_write_mutex_;
|
||||
mutable std::recursive_mutex remote_mount_mutex_;
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto load() -> bool;
|
||||
|
@@ -24,6 +24,8 @@
|
||||
|
||||
#include "comm/curl/multi_request.hpp"
|
||||
#include "comm/i_http_comm.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "events/events.hpp"
|
||||
#include "utils/encryption.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
@@ -196,7 +198,7 @@ public:
|
||||
CURLcode curl_code{};
|
||||
curl_request.get_result(curl_code, response_code);
|
||||
if (curl_code != CURLE_OK) {
|
||||
std::cout << curl_easy_strerror(curl_code) << std::endl;
|
||||
event_system::instance().raise<curl_error>(url, curl_code);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -225,6 +227,11 @@ public:
|
||||
stop_type &stop_requested) const
|
||||
-> bool override;
|
||||
|
||||
[[nodiscard]] auto make_request(const curl::requests::http_post &post_file,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const
|
||||
-> bool override;
|
||||
|
||||
[[nodiscard]] auto make_request(const curl::requests::http_put_file &put_file,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const
|
||||
|
49
include/comm/curl/requests/http_post.hpp
Normal file
49
include/comm/curl/requests/http_post.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
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_COMM_CURL_CURL_REQUESTS_HTTP_POST_HPP_
|
||||
#define INCLUDE_COMM_CURL_CURL_REQUESTS_HTTP_POST_HPP_
|
||||
|
||||
#include "comm/curl/requests/http_request_base.hpp"
|
||||
|
||||
namespace repertory::curl::requests {
|
||||
struct http_post final : http_request_base {
|
||||
http_post() = default;
|
||||
http_post(const http_post &) = default;
|
||||
http_post(http_post &&) = default;
|
||||
auto operator=(const http_post &) -> http_post & = default;
|
||||
auto operator=(http_post &&) -> http_post & = default;
|
||||
|
||||
~http_post() override;
|
||||
|
||||
std::optional<nlohmann::json> json;
|
||||
|
||||
[[nodiscard]] auto set_method(CURL *curl,
|
||||
stop_type & /*stop_requested*/) const
|
||||
-> bool override;
|
||||
|
||||
private:
|
||||
mutable curl_slist *headers{nullptr};
|
||||
mutable std::optional<std::string> json_str;
|
||||
};
|
||||
} // namespace repertory::curl::requests
|
||||
|
||||
#endif // INCLUDE_COMM_CURL_CURL_REQUESTS_HTTP_POST_HPP_
|
@@ -25,6 +25,7 @@
|
||||
#include "comm/curl/requests/http_delete.hpp"
|
||||
#include "comm/curl/requests/http_get.hpp"
|
||||
#include "comm/curl/requests/http_head.hpp"
|
||||
#include "comm/curl/requests/http_post.hpp"
|
||||
#include "comm/curl/requests/http_put_file.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
@@ -49,6 +50,11 @@ public:
|
||||
stop_type &stop_requested) const
|
||||
-> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto make_request(const curl::requests::http_post &post,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const
|
||||
-> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
make_request(const curl::requests::http_put_file &put_file,
|
||||
long &response_code, stop_type &stop_requested) const
|
||||
|
@@ -22,6 +22,32 @@
|
||||
#ifndef INCLUDE_COMMON_HPP_
|
||||
#define INCLUDE_COMMON_HPP_
|
||||
|
||||
#if defined(__GNUC__)
|
||||
// clang-format off
|
||||
#define REPERTORY_IGNORE_WARNINGS_ENABLE() \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wconversion\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdouble-promotion\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wduplicated-branches\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wfloat-conversion\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wnull-dereference\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wsign-conversion\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wunused-but-set-variable\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wuseless-cast\"")
|
||||
|
||||
#define REPERTORY_IGNORE_WARNINGS_DISABLE() \
|
||||
_Pragma("GCC diagnostic pop")
|
||||
#else
|
||||
#define REPERTORY_IGNORE_WARNINGS_ENABLE()
|
||||
#define REPERTORY_IGNORE_WARNINGS_DISABLE()
|
||||
#endif // defined(__GNUC__)
|
||||
// clang-format on
|
||||
|
||||
#ifdef __cplusplus
|
||||
REPERTORY_IGNORE_WARNINGS_ENABLE()
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
@@ -103,7 +129,7 @@ template <typename data_type>
|
||||
#include <curl/curl.h>
|
||||
#include <curl/multi.h>
|
||||
#include <json.hpp>
|
||||
#include <rocksdb/db.h>
|
||||
#include <sqlite3.h>
|
||||
#include <stduuid.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -124,6 +150,28 @@ template <typename data_type>
|
||||
#define CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
#include <httplib.h>
|
||||
|
||||
REPERTORY_IGNORE_WARNINGS_DISABLE()
|
||||
|
||||
struct sqlite3_deleter {
|
||||
void operator()(sqlite3 *db3) {
|
||||
if (db3 != nullptr) {
|
||||
sqlite3_close_v2(db3);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
using db3_t = std::unique_ptr<sqlite3, sqlite3_deleter>;
|
||||
|
||||
struct sqlite3_statement_deleter {
|
||||
void operator()(sqlite3_stmt *stmt) {
|
||||
if (stmt != nullptr) {
|
||||
sqlite3_finalize(stmt);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
using db3_stmt_t = std::unique_ptr<sqlite3_stmt, sqlite3_statement_deleter>;
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
using json = nlohmann::json;
|
||||
|
||||
@@ -356,17 +404,17 @@ enum {
|
||||
};
|
||||
|
||||
struct FSP_FSCTL_FILE_INFO {
|
||||
UINT32 FileAttributes;
|
||||
UINT32 ReparseTag;
|
||||
UINT64 AllocationSize;
|
||||
UINT64 FileSize;
|
||||
UINT64 CreationTime;
|
||||
UINT64 LastAccessTime;
|
||||
UINT64 LastWriteTime;
|
||||
UINT64 ChangeTime;
|
||||
UINT64 IndexNumber;
|
||||
UINT32 HardLinks;
|
||||
UINT32 EaSize;
|
||||
UINT32 FileAttributes{};
|
||||
UINT32 ReparseTag{};
|
||||
UINT64 AllocationSize{};
|
||||
UINT64 FileSize{};
|
||||
UINT64 CreationTime{};
|
||||
UINT64 LastAccessTime{};
|
||||
UINT64 LastWriteTime{};
|
||||
UINT64 ChangeTime{};
|
||||
UINT64 IndexNumber{};
|
||||
UINT32 HardLinks{};
|
||||
UINT32 EaSize{};
|
||||
};
|
||||
|
||||
using FileInfo = FSP_FSCTL_FILE_INFO;
|
||||
@@ -382,6 +430,13 @@ void repertory_init();
|
||||
void repertory_shutdown();
|
||||
} // namespace repertory
|
||||
|
||||
namespace {
|
||||
template <class... Ts> struct overloaded : Ts... {
|
||||
using Ts::operator()...;
|
||||
};
|
||||
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
|
||||
} // namespace
|
||||
|
||||
#define INTERFACE_SETUP(name) \
|
||||
public: \
|
||||
name(const name &) noexcept = delete; \
|
||||
@@ -395,4 +450,5 @@ protected: \
|
||||
public: \
|
||||
virtual ~name() = default
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // INCLUDE_COMMON_HPP_
|
||||
|
217
include/database/db_common.hpp
Normal file
217
include/database/db_common.hpp
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
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_DATABASE_DB_COMMON_HPP_
|
||||
#define INCLUDE_DATABASE_DB_COMMON_HPP_
|
||||
|
||||
#include "utils/error_utils.hpp"
|
||||
|
||||
namespace repertory::db {
|
||||
using db_types_t = std::variant<std::int64_t, std::string>;
|
||||
|
||||
struct comp_data_t final {
|
||||
std::string column_name;
|
||||
std::string op_type;
|
||||
db_types_t value;
|
||||
};
|
||||
|
||||
class db_column final {
|
||||
public:
|
||||
db_column() noexcept = default;
|
||||
db_column(const db_column &) = default;
|
||||
db_column(db_column &&column) noexcept = default;
|
||||
~db_column() = default;
|
||||
|
||||
auto operator=(const db_column &) -> db_column & = default;
|
||||
auto operator=(db_column &&) -> db_column & = default;
|
||||
|
||||
db_column(std::int32_t index, std::string name, db_types_t value) noexcept
|
||||
: index_(index), name_(std::move(name)), value_(std::move(value)) {}
|
||||
|
||||
private:
|
||||
std::int32_t index_{};
|
||||
std::string name_;
|
||||
db_types_t value_;
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto get_index() const -> std::int32_t { return index_; }
|
||||
|
||||
[[nodiscard]] auto get_name() const -> std::string { return name_; }
|
||||
|
||||
template <typename data_type>
|
||||
[[nodiscard]] auto get_value() const -> data_type {
|
||||
return std::visit(
|
||||
overloaded{
|
||||
[](const data_type &value) -> data_type { return value; },
|
||||
[](auto &&) -> data_type {
|
||||
throw std::runtime_error("data type not supported");
|
||||
},
|
||||
},
|
||||
value_);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_value_as_json() const -> nlohmann::json {
|
||||
return std::visit(
|
||||
overloaded{
|
||||
[this](std::int64_t value) -> auto {
|
||||
return nlohmann::json({{name_, value}});
|
||||
},
|
||||
[](auto &&value) -> auto { return nlohmann::json::parse(value); },
|
||||
},
|
||||
value_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename context_t> class db_row final {
|
||||
public:
|
||||
db_row(std::shared_ptr<context_t> context) {
|
||||
auto column_count = sqlite3_column_count(context->stmt.get());
|
||||
for (std::int32_t col = 0; col < column_count; col++) {
|
||||
std::string name{sqlite3_column_name(context->stmt.get(), col)};
|
||||
auto column_type = sqlite3_column_type(context->stmt.get(), col);
|
||||
|
||||
db_types_t value;
|
||||
switch (column_type) {
|
||||
case SQLITE_INTEGER: {
|
||||
value = sqlite3_column_int64(context->stmt.get(), col);
|
||||
} break;
|
||||
|
||||
case SQLITE_TEXT: {
|
||||
const auto *text = reinterpret_cast<const char *>(
|
||||
sqlite3_column_text(context->stmt.get(), col));
|
||||
value = std::string(text == nullptr ? "" : text);
|
||||
} break;
|
||||
|
||||
default:
|
||||
throw std::runtime_error("column type not implemented|" + name + '|' +
|
||||
std::to_string(column_type));
|
||||
}
|
||||
|
||||
columns_[name] = db_column{col, name, value};
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string, db_column> columns_;
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto get_columns() const -> std::vector<db_column> {
|
||||
std::vector<db_column> ret;
|
||||
for (const auto &item : columns_) {
|
||||
ret.push_back(item.second);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_column(std::int32_t index) const -> db_column {
|
||||
auto iter = std::find_if(columns_.begin(), columns_.end(),
|
||||
[&index](auto &&col) -> bool {
|
||||
return col.second.get_index() == index;
|
||||
});
|
||||
if (iter == columns_.end()) {
|
||||
throw std::out_of_range("");
|
||||
}
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_column(std::string name) const -> db_column {
|
||||
return columns_.at(name);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename context_t> struct db_result final {
|
||||
db_result(std::shared_ptr<context_t> context, std::int32_t res)
|
||||
: context_(std::move(context)), res_(res) {
|
||||
if (res == SQLITE_OK) {
|
||||
set_res(sqlite3_step(context_->stmt.get()), __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<context_t> context_;
|
||||
mutable std::int32_t res_;
|
||||
|
||||
private:
|
||||
void set_res(std::int32_t res, std::string function) const {
|
||||
if (res != SQLITE_OK && res != SQLITE_DONE && res != SQLITE_ROW) {
|
||||
utils::error::raise_error(function, "failed to step|" +
|
||||
std::to_string(res) + '|' +
|
||||
sqlite3_errstr(res));
|
||||
}
|
||||
res_ = res;
|
||||
}
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto ok() const -> bool {
|
||||
return res_ == SQLITE_DONE || res_ == SQLITE_ROW;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_error() const -> std::int32_t { return res_; }
|
||||
|
||||
[[nodiscard]] auto get_error_str() const -> std::string {
|
||||
return sqlite3_errstr(res_);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_row(std::optional<db_row<context_t>> &row) const
|
||||
-> bool {
|
||||
row.reset();
|
||||
if (has_row()) {
|
||||
row = db_row{context_};
|
||||
set_res(sqlite3_step(context_->stmt.get()), __FUNCTION__);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto has_row() const -> bool { return res_ == SQLITE_ROW; }
|
||||
|
||||
void next_row() const {
|
||||
if (has_row()) {
|
||||
set_res(sqlite3_step(context_->stmt.get()), __FUNCTION__);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline void set_journal_mode(sqlite3 &db3) {
|
||||
sqlite3_exec(&db3, "PRAGMA journal_mode = WAL;", nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline auto execute_sql(sqlite3 &db3, const std::string &sql,
|
||||
std::string &err) -> bool {
|
||||
char *err_msg{nullptr};
|
||||
auto res = sqlite3_exec(&db3, sql.c_str(), nullptr, nullptr, &err_msg);
|
||||
if (err_msg != nullptr) {
|
||||
err = err_msg;
|
||||
sqlite3_free(err_msg);
|
||||
err_msg = nullptr;
|
||||
}
|
||||
if (res != SQLITE_OK) {
|
||||
err = "failed to execute sql|" + sql + "|" + std::to_string(res) + '|' +
|
||||
(err.empty() ? sqlite3_errstr(res) : err);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace repertory::db
|
||||
|
||||
#endif // INCLUDE_DATABASE_DB_COMMON_HPP_
|
69
include/database/db_insert.hpp
Normal file
69
include/database/db_insert.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
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_DATABASE_DB_INSERT_HPP_
|
||||
#define INCLUDE_DATABASE_DB_INSERT_HPP_
|
||||
|
||||
#include "database/db_common.hpp"
|
||||
#include "utils/error_utils.hpp"
|
||||
|
||||
namespace repertory::db {
|
||||
class db_insert final {
|
||||
public:
|
||||
struct context final {
|
||||
context(sqlite3 &db3_, std::string table_name_)
|
||||
: db3(db3_), table_name(std::move(table_name_)) {}
|
||||
|
||||
sqlite3 &db3;
|
||||
std::string table_name;
|
||||
|
||||
bool or_replace{false};
|
||||
std::map<std::string, db_types_t> values{};
|
||||
db3_stmt_t stmt{nullptr};
|
||||
};
|
||||
|
||||
using row = db_row<context>;
|
||||
|
||||
public:
|
||||
db_insert(sqlite3 &db3, std::string table_name)
|
||||
: context_(std::make_shared<context>(db3, table_name)) {}
|
||||
|
||||
db_insert(std::shared_ptr<context> ctx) : context_(std::move(ctx)) {}
|
||||
|
||||
private:
|
||||
std::shared_ptr<context> context_;
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto or_replace() -> db_insert & {
|
||||
context_->or_replace = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto column_value(std::string column_name, db_types_t value)
|
||||
-> db_insert &;
|
||||
|
||||
[[nodiscard]] auto dump() const -> std::string;
|
||||
|
||||
[[nodiscard]] auto go() const -> db_result<context>;
|
||||
};
|
||||
} // namespace repertory::db
|
||||
|
||||
#endif // INCLUDE_DATABASE_DB_INSERT_HPP_
|
125
include/database/db_select.hpp
Normal file
125
include/database/db_select.hpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
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_DATABASE_DB_SELECT_HPP_
|
||||
#define INCLUDE_DATABASE_DB_SELECT_HPP_
|
||||
|
||||
#include "database/db_common.hpp"
|
||||
#include "utils/error_utils.hpp"
|
||||
|
||||
namespace repertory::db {
|
||||
class db_select final {
|
||||
public:
|
||||
struct context final {
|
||||
context(sqlite3 &db3_, std::string table_name_)
|
||||
: db3(db3_), table_name(std::move(table_name_)) {}
|
||||
|
||||
sqlite3 &db3;
|
||||
std::string table_name;
|
||||
|
||||
std::vector<comp_data_t> ands{};
|
||||
std::vector<std::string> columns{};
|
||||
std::map<std::string, std::string> count_columns{};
|
||||
bool delete_query{false};
|
||||
std::optional<std::int32_t> limit;
|
||||
std::optional<std::pair<std::string, bool>> order_by;
|
||||
db3_stmt_t stmt{nullptr};
|
||||
};
|
||||
|
||||
using row = db_row<context>;
|
||||
|
||||
public:
|
||||
db_select(sqlite3 &db3, std::string table_name)
|
||||
: context_(std::make_shared<context>(db3, table_name)) {}
|
||||
|
||||
db_select(std::shared_ptr<context> ctx) : context_(std::move(ctx)) {}
|
||||
|
||||
public:
|
||||
struct db_where final {
|
||||
db_where(std::shared_ptr<context> ctx, std::string column_name)
|
||||
: context_(std::move(ctx)), column_name_(std::move(column_name)) {}
|
||||
|
||||
public:
|
||||
struct db_where_next final {
|
||||
db_where_next(std::shared_ptr<context> ctx) : context_(std::move(ctx)) {}
|
||||
|
||||
private:
|
||||
std::shared_ptr<context> context_;
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto and_where(std::string column_name) const -> db_where {
|
||||
return db_where{context_, column_name};
|
||||
}
|
||||
|
||||
[[nodiscard]] auto dump() const -> std::string {
|
||||
return db_select{context_}.dump();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto go() const -> db_result<context> {
|
||||
return db_select{context_}.go();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto limit(std::int32_t value) const -> db_select {
|
||||
return db_select{context_}.limit(value);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto order_by(std::string column_name, bool ascending) const
|
||||
-> db_select {
|
||||
return db_select{context_}.order_by(column_name, ascending);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
std::shared_ptr<context> context_;
|
||||
std::string column_name_;
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto equals(db_types_t value) const -> db_where_next {
|
||||
context_->ands.emplace_back(comp_data_t{column_name_, "=", value});
|
||||
return db_where_next{context_};
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
std::shared_ptr<context> context_;
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto column(std::string column_name) -> db_select &;
|
||||
|
||||
[[nodiscard]] auto count(std::string column_name, std::string as_column_name)
|
||||
-> db_select &;
|
||||
|
||||
[[nodiscard]] auto delete_query() -> db_select &;
|
||||
|
||||
[[nodiscard]] auto dump() const -> std::string;
|
||||
|
||||
[[nodiscard]] auto go() const -> db_result<context>;
|
||||
|
||||
[[nodiscard]] auto limit(std::int32_t value) -> db_select &;
|
||||
|
||||
[[nodiscard]] auto order_by(std::string column_name, bool ascending)
|
||||
-> db_select &;
|
||||
|
||||
[[nodiscard]] auto where(std::string column_name) const -> db_where;
|
||||
};
|
||||
} // namespace repertory::db
|
||||
|
||||
#endif // INCLUDE_DATABASE_DB_SELECT_HPP_
|
@@ -33,16 +33,20 @@ public:
|
||||
|
||||
private:
|
||||
struct open_directory {
|
||||
directory_iterator *iterator;
|
||||
std::chrono::system_clock::time_point last_update =
|
||||
std::chrono::system_clock::now();
|
||||
directory_iterator *iterator{nullptr};
|
||||
std::chrono::system_clock::time_point last_update{
|
||||
std::chrono::system_clock::now()};
|
||||
};
|
||||
|
||||
public:
|
||||
directory_cache() : single_thread_service_base("directory_cache") {}
|
||||
|
||||
~directory_cache() override = default;
|
||||
|
||||
directory_cache(const directory_cache &) = delete;
|
||||
directory_cache(directory_cache &&) = delete;
|
||||
auto operator=(const directory_cache &) -> directory_cache & = delete;
|
||||
auto operator=(directory_cache &&) -> directory_cache & = delete;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, open_directory> directory_lookup_;
|
||||
std::recursive_mutex directory_mutex_;
|
||||
|
@@ -315,7 +315,7 @@ protected:
|
||||
return api_error::not_implemented;
|
||||
}
|
||||
|
||||
virtual void destroy_impl(void * /*ptr*/) { return; }
|
||||
virtual void destroy_impl(void * /*ptr*/);
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
fallocate_impl(std::string /*api_path*/, int /*mode*/, off_t /*offset*/,
|
||||
|
@@ -316,9 +316,6 @@ public:
|
||||
[[nodiscard]] auto is_processing(const std::string &api_path) const
|
||||
-> bool override;
|
||||
|
||||
void populate_stat(const directory_item &dir_item,
|
||||
struct stat &st) const override;
|
||||
|
||||
[[nodiscard]] auto rename_directory(const std::string &from_api_path,
|
||||
const std::string &to_api_path)
|
||||
-> int override;
|
||||
|
@@ -69,9 +69,6 @@ public:
|
||||
[[nodiscard]] virtual auto is_processing(const std::string &api_path) const
|
||||
-> bool = 0;
|
||||
|
||||
virtual void populate_stat(const directory_item &dir_item,
|
||||
struct stat &st) const = 0;
|
||||
|
||||
[[nodiscard]] virtual auto rename_directory(const std::string &from_api_path,
|
||||
const std::string &to_api_path)
|
||||
-> int = 0;
|
||||
|
@@ -112,14 +112,14 @@ public:
|
||||
-> packet::error_type = 0;
|
||||
|
||||
[[nodiscard]] virtual auto fuse_read(const char *path, char *buffer,
|
||||
const remote::file_size &readSize,
|
||||
const remote::file_offset &readOffset,
|
||||
const remote::file_size &read_size,
|
||||
const remote::file_offset &read_offset,
|
||||
const remote::file_handle &handle)
|
||||
-> packet::error_type = 0;
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
fuse_readdir(const char *path, const remote::file_offset &offset,
|
||||
const remote::file_handle &handle, std::string &itemPath)
|
||||
const remote::file_handle &handle, std::string &item_path)
|
||||
-> packet::error_type = 0;
|
||||
|
||||
[[nodiscard]] virtual auto fuse_release(const char *path,
|
||||
|
@@ -53,7 +53,8 @@ private:
|
||||
bool was_mounted_ = false;
|
||||
|
||||
private:
|
||||
void populate_stat(const remote::stat &r, bool directory, struct stat &st);
|
||||
void populate_stat(const remote::stat &r_stat, bool directory,
|
||||
struct stat &unix_st);
|
||||
|
||||
protected:
|
||||
[[nodiscard]] auto access_impl(std::string api_path, int mask)
|
||||
@@ -66,7 +67,7 @@ protected:
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
[[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode,
|
||||
struct fuse_file_info *fi)
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error override;
|
||||
#else
|
||||
[[nodiscard]] auto chmod_impl(std::string api_path, mode_t mode)
|
||||
@@ -75,7 +76,7 @@ protected:
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
[[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid,
|
||||
struct fuse_file_info *fi)
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error override;
|
||||
#else
|
||||
[[nodiscard]] auto chown_impl(std::string api_path, uid_t uid, gid_t gid)
|
||||
@@ -83,37 +84,38 @@ protected:
|
||||
#endif
|
||||
|
||||
[[nodiscard]] auto create_impl(std::string api_path, mode_t mode,
|
||||
struct fuse_file_info *fi)
|
||||
struct fuse_file_info *f_info)
|
||||
-> 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)
|
||||
[[nodiscard]] auto fgetattr_impl(std::string api_path, struct stat *unix_st,
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error override;
|
||||
|
||||
#ifdef __APPLE__
|
||||
[[nodiscard]] auto fsetattr_x_impl(std::string api_path,
|
||||
struct setattr_x *attr,
|
||||
struct fuse_file_info *fi)
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error override;
|
||||
#endif // __APPLE__
|
||||
|
||||
[[nodiscard]] auto fsync_impl(std::string api_path, int datasync,
|
||||
struct fuse_file_info *fi)
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error override;
|
||||
|
||||
#if FUSE_USE_VERSION < 30
|
||||
[[nodiscard]] auto ftruncate_impl(std::string api_path, off_t size,
|
||||
struct fuse_file_info *fi)
|
||||
struct fuse_file_info *f_info)
|
||||
-> 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)
|
||||
[[nodiscard]] auto getattr_impl(std::string api_path, struct stat *unix_st,
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error override;
|
||||
#else
|
||||
[[nodiscard]] auto getattr_impl(std::string api_path, struct stat *st)
|
||||
[[nodiscard]] auto getattr_impl(std::string api_path, struct stat *unix_st)
|
||||
-> api_error override;
|
||||
#endif
|
||||
|
||||
@@ -136,37 +138,38 @@ protected:
|
||||
|
||||
void notify_fuse_main_exit(int &ret) override;
|
||||
|
||||
[[nodiscard]] auto open_impl(std::string api_path, struct fuse_file_info *fi)
|
||||
[[nodiscard]] auto open_impl(std::string api_path,
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error override;
|
||||
|
||||
[[nodiscard]] auto opendir_impl(std::string api_path,
|
||||
struct fuse_file_info *fi)
|
||||
struct fuse_file_info *f_info)
|
||||
-> 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,
|
||||
struct fuse_file_info *f_info,
|
||||
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,
|
||||
struct fuse_file_info *f_info,
|
||||
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)
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error override;
|
||||
#endif
|
||||
|
||||
[[nodiscard]] auto release_impl(std::string api_path,
|
||||
struct fuse_file_info *fi)
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error override;
|
||||
|
||||
[[nodiscard]] auto releasedir_impl(std::string api_path,
|
||||
struct fuse_file_info *fi)
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error override;
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
@@ -210,7 +213,7 @@ protected:
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
[[nodiscard]] auto truncate_impl(std::string api_path, off_t size,
|
||||
struct fuse_file_info *fi)
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error override;
|
||||
#else
|
||||
[[nodiscard]] auto truncate_impl(std::string api_path, off_t size)
|
||||
@@ -222,7 +225,7 @@ protected:
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
[[nodiscard]] auto utimens_impl(std::string api_path,
|
||||
const struct timespec tv[2],
|
||||
struct fuse_file_info *fi)
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error override;
|
||||
#else
|
||||
[[nodiscard]] auto utimens_impl(std::string api_path,
|
||||
@@ -232,7 +235,7 @@ protected:
|
||||
|
||||
[[nodiscard]] auto write_impl(std::string api_path, const char *buffer,
|
||||
size_t write_size, off_t write_offset,
|
||||
struct fuse_file_info *fi,
|
||||
struct fuse_file_info *f_info,
|
||||
std::size_t &bytes_written)
|
||||
-> api_error override;
|
||||
};
|
||||
|
@@ -341,7 +341,7 @@ public:
|
||||
ret = this->winfsp_read(file_desc, buffer.data(), offset, length,
|
||||
&bytes_transferred);
|
||||
if (ret == STATUS_SUCCESS) {
|
||||
response.encode(static_cast<UINT32>(bytes_transferred));
|
||||
response.encode(bytes_transferred);
|
||||
if (bytes_transferred != 0U) {
|
||||
response.encode(buffer.data(), bytes_transferred);
|
||||
}
|
||||
@@ -1237,7 +1237,7 @@ public:
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
data_buffer buffer(static_cast<std::size_t>(write_size));
|
||||
data_buffer buffer(write_size);
|
||||
if ((ret = request->decode(buffer.data(), buffer.size())) == 0) {
|
||||
remote::file_offset write_offset{};
|
||||
DECODE_OR_RETURN(request, write_offset);
|
||||
@@ -1267,7 +1267,7 @@ public:
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
data_buffer buffer(static_cast<std::size_t>(write_size));
|
||||
data_buffer buffer(write_size);
|
||||
if ((ret = request->decode(buffer.data(), buffer.size())) == 0) {
|
||||
buffer = macaron::Base64::Decode(
|
||||
std::string(buffer.begin(), buffer.end()));
|
||||
|
@@ -60,6 +60,7 @@ using event_consumer = event_system::event_consumer;
|
||||
return ss; \
|
||||
})(d)
|
||||
#define E_STRING(t) t
|
||||
#define E_FROM_CURL_CODE(t) std::string(curl_easy_strerror(t))
|
||||
#define E_FROM_UINT8(t) std::to_string(t)
|
||||
#define E_FROM_UINT32(t) std::to_string(t)
|
||||
#define E_FROM_UINT64(t) std::to_string(t)
|
||||
|
@@ -28,145 +28,9 @@
|
||||
|
||||
namespace repertory {
|
||||
// clang-format off
|
||||
E_SIMPLE3(cache_file_processed, normal, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING,
|
||||
api_error, result, res, E_FROM_API_FILE_ERROR
|
||||
);
|
||||
|
||||
E_SIMPLE2(comm_auth_begin, normal, true,
|
||||
E_SIMPLE2(curl_error, normal, true,
|
||||
std::string, url, url, E_STRING,
|
||||
std::string, user, user, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_auth_end, normal, true,
|
||||
std::string, url, url, E_STRING,
|
||||
std::string, user, user, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32
|
||||
);
|
||||
|
||||
E_SIMPLE2(comm_auth_logout_begin, normal, true,
|
||||
std::string, url, url, E_STRING,
|
||||
std::string, user, user, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_auth_logout_end, normal, true,
|
||||
std::string, url, url, E_STRING,
|
||||
std::string, user, user, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32
|
||||
);
|
||||
|
||||
E_SIMPLE1(comm_del_begin, verbose, true,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_del_end, verbose, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(comm_get_begin, verbose, true,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_get_end, verbose, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(comm_get_range_begin, verbose, true,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_get_range_end, verbose, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(comm_get_raw_begin, verbose, true,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_get_raw_end, verbose, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(comm_post_begin, verbose, true,
|
||||
std::string, url, url, E_STRING,
|
||||
std::string, fields, fields, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_post_end, verbose, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, result, res, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(comm_duration, normal, true,
|
||||
std::string, url, url, E_STRING,
|
||||
std::string, duration, duration, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(comm_post_file_begin, debug, true,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_post_file_end, debug, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(comm_post_multi_part_file_begin, debug, true,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_post_multi_part_file_end, debug, true,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_tus_upload_begin, debug, true,
|
||||
std::string, file_name, fn, E_STRING,
|
||||
std::string, url, url, E_STRING,
|
||||
std::uint64_t, remain, rem, E_FROM_UINT64,
|
||||
std::uint64_t, offset, off, E_FROM_UINT64
|
||||
);
|
||||
|
||||
E_SIMPLE6(comm_tus_upload_end, debug, true,
|
||||
std::string, file_name, fn, E_STRING,
|
||||
std::string, url, url, E_STRING,
|
||||
std::uint64_t, remain, rem, E_FROM_UINT64,
|
||||
std::uint64_t, offset, OFF, E_FROM_UINT64,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32
|
||||
);
|
||||
|
||||
E_SIMPLE2(comm_tus_upload_create_begin, debug, true,
|
||||
std::string, file_name, fn, E_STRING,
|
||||
std::string, url, url, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE4(comm_tus_upload_create_end, debug, true,
|
||||
std::string, file_name, fn, E_STRING,
|
||||
std::string, url, url, E_STRING,
|
||||
CURLcode, curl, curl, E_FROM_INT32,
|
||||
int, http, http, E_FROM_INT32
|
||||
CURLcode, res, res, E_FROM_CURL_CODE
|
||||
);
|
||||
|
||||
E_SIMPLE3(debug_log, debug, true,
|
||||
@@ -341,9 +205,8 @@ E_SIMPLE2(file_upload_queued, normal, true,
|
||||
std::string, source, src, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE2(file_upload_removed, debug, true,
|
||||
std::string, api_path, ap, E_STRING,
|
||||
std::string, source, src, E_STRING
|
||||
E_SIMPLE1(file_upload_removed, debug, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE3(file_upload_retry, normal, true,
|
||||
|
@@ -93,7 +93,7 @@ E_SIMPLE3(download_stored_failed, error, true,
|
||||
std::string, error, err, E_STRING
|
||||
);
|
||||
|
||||
E_SIMPLE1(download_timeout, warn, true,
|
||||
E_SIMPLE1(item_timeout, normal, true,
|
||||
std::string, api_path, ap, E_STRING
|
||||
);
|
||||
// clang-format on
|
||||
|
@@ -133,6 +133,7 @@ public:
|
||||
mutable std::mutex io_thread_mtx_;
|
||||
std::condition_variable io_thread_notify_;
|
||||
std::deque<std::shared_ptr<io_item>> io_thread_queue_;
|
||||
bool removed_{false};
|
||||
|
||||
private:
|
||||
void file_io_thread();
|
||||
@@ -246,7 +247,8 @@ public:
|
||||
std::size_t end_chunk_index_inclusive,
|
||||
bool should_reset);
|
||||
|
||||
private:
|
||||
void set_modified();
|
||||
|
||||
void update_background_reader(std::size_t read_chunk);
|
||||
|
||||
protected:
|
||||
@@ -449,17 +451,14 @@ public:
|
||||
private:
|
||||
app_config &config_;
|
||||
i_provider &provider_;
|
||||
std::unique_ptr<rocksdb::DB> db_;
|
||||
|
||||
private:
|
||||
rocksdb::ColumnFamilyHandle *default_family_{};
|
||||
std::uint64_t next_handle_ = 0u;
|
||||
db3_t db_{nullptr};
|
||||
std::uint64_t next_handle_{0U};
|
||||
mutable std::recursive_mutex open_file_mtx_;
|
||||
std::unordered_map<std::string, std::shared_ptr<i_closeable_open_file>>
|
||||
open_file_lookup_;
|
||||
stop_type stop_requested_ = false;
|
||||
rocksdb::ColumnFamilyHandle *upload_family_{};
|
||||
rocksdb::ColumnFamilyHandle *upload_active_family_{};
|
||||
stop_type stop_requested_{false};
|
||||
std::unordered_map<std::string, std::unique_ptr<upload>> upload_lookup_;
|
||||
mutable std::mutex upload_mtx_;
|
||||
std::condition_variable upload_notify_;
|
||||
|
@@ -40,6 +40,9 @@ public:
|
||||
|
||||
[[nodiscard]] virtual auto get_filesystem_item() const -> filesystem_item = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_open_data() const
|
||||
-> std::map<std::uint64_t, open_file_data> = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_open_data(std::uint64_t handle) const
|
||||
-> open_file_data = 0;
|
||||
|
||||
@@ -91,9 +94,6 @@ public:
|
||||
[[nodiscard]] virtual auto get_handles() const
|
||||
-> std::vector<std::uint64_t> = 0;
|
||||
|
||||
[[nodiscard]] virtual auto get_open_data() const
|
||||
-> std::map<std::uint64_t, open_file_data> = 0;
|
||||
|
||||
[[nodiscard]] virtual auto is_complete() const -> bool = 0;
|
||||
|
||||
[[nodiscard]] virtual auto is_modified() const -> bool = 0;
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#define INCLUDE_PROVIDERS_BASE_PROVIDER_HPP_
|
||||
|
||||
#include "providers/i_provider.hpp"
|
||||
#include "providers/meta_db.hpp"
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
@@ -41,8 +42,7 @@ private:
|
||||
|
||||
private:
|
||||
api_item_added_callback api_item_added_;
|
||||
std::unique_ptr<rocksdb::DB> db_;
|
||||
std::string DB_NAME = "meta_db";
|
||||
std::unique_ptr<meta_db> db3_;
|
||||
i_file_manager *fm_{};
|
||||
|
||||
private:
|
||||
@@ -83,12 +83,12 @@ protected:
|
||||
return config_;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_db() -> meta_db & { return *db3_; }
|
||||
|
||||
[[nodiscard]] virtual auto
|
||||
get_directory_items_impl(const std::string &api_path,
|
||||
directory_item_list &list) const -> api_error = 0;
|
||||
|
||||
[[nodiscard]] auto get_db() const -> rocksdb::DB * { return db_.get(); }
|
||||
|
||||
[[nodiscard]] auto get_file_mgr() -> i_file_manager * { return fm_; }
|
||||
|
||||
[[nodiscard]] auto get_file_mgr() const -> const i_file_manager * {
|
||||
|
@@ -49,11 +49,7 @@ private:
|
||||
|
||||
private:
|
||||
app_config &config_;
|
||||
std::unique_ptr<rocksdb::DB> db_;
|
||||
rocksdb::ColumnFamilyHandle *dir_family_{};
|
||||
rocksdb::ColumnFamilyHandle *file_family_{};
|
||||
rocksdb::ColumnFamilyHandle *source_family_{};
|
||||
std::string DB_NAME = "meta_db";
|
||||
db3_t db_;
|
||||
|
||||
private:
|
||||
i_file_manager *fm_ = nullptr;
|
||||
|
83
include/providers/meta_db.hpp
Normal file
83
include/providers/meta_db.hpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
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_PROVIDERS_META_DB_HPP_
|
||||
#define INCLUDE_PROVIDERS_META_DB_HPP_
|
||||
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
|
||||
class meta_db final {
|
||||
public:
|
||||
meta_db(const app_config &cfg);
|
||||
~meta_db();
|
||||
|
||||
meta_db(const meta_db &) = delete;
|
||||
meta_db(meta_db &&) = delete;
|
||||
auto operator=(const meta_db &) -> meta_db & = delete;
|
||||
auto operator=(meta_db &&) -> meta_db & = delete;
|
||||
|
||||
private:
|
||||
db3_t db_;
|
||||
constexpr static const auto table_name = "meta";
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto update_item_meta(const std::string &api_path,
|
||||
api_meta_map meta) -> api_error;
|
||||
|
||||
public:
|
||||
[[nodiscard]] auto get_api_path(const std::string &source_path,
|
||||
std::string &api_path) -> api_error;
|
||||
|
||||
[[nodiscard]] auto get_api_path_list() -> std::vector<std::string>;
|
||||
|
||||
[[nodiscard]] auto get_item_meta(const std::string &api_path,
|
||||
api_meta_map &meta) -> api_error;
|
||||
|
||||
[[nodiscard]] auto get_item_meta(const std::string &api_path,
|
||||
const std::string &key,
|
||||
std::string &value) const -> api_error;
|
||||
|
||||
[[nodiscard]] auto get_pinned_files() const -> std::vector<std::string>;
|
||||
|
||||
[[nodiscard]] auto get_total_item_count() const -> std::uint64_t;
|
||||
|
||||
void remove_api_path(const std::string &api_path);
|
||||
|
||||
[[nodiscard]] auto remove_item_meta(const std::string &api_path,
|
||||
const std::string &key) -> api_error;
|
||||
|
||||
[[nodiscard]] auto rename_item_meta(const std::string &from_api_path,
|
||||
const std::string &to_api_path)
|
||||
-> api_error;
|
||||
|
||||
[[nodiscard]] auto set_item_meta(const std::string &api_path,
|
||||
const std::string &key,
|
||||
const std::string &value) -> api_error;
|
||||
|
||||
[[nodiscard]] auto set_item_meta(const std::string &api_path,
|
||||
const api_meta_map &meta) -> api_error;
|
||||
};
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_PROVIDERS_META_DB_HPP_
|
@@ -99,7 +99,7 @@ public:
|
||||
[[nodiscard]] auto is_online() const -> bool override;
|
||||
|
||||
[[nodiscard]] auto is_rename_supported() const -> bool override {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto read_file_bytes(const std::string &api_path,
|
||||
|
@@ -30,7 +30,6 @@ const std::string META_CHANGED = "changed";
|
||||
const std::string META_CREATION = "creation";
|
||||
const std::string META_DIRECTORY = "directory";
|
||||
const std::string META_GID = "gid";
|
||||
const std::string META_ID = "id";
|
||||
const std::string META_KEY = "key";
|
||||
const std::string META_MODE = "mode";
|
||||
const std::string META_MODIFIED = "modified";
|
||||
@@ -42,10 +41,10 @@ const std::string META_UID = "uid";
|
||||
const std::string META_WRITTEN = "written";
|
||||
|
||||
const std::vector<std::string> META_USED_NAMES = {
|
||||
META_ACCESSED, META_ATTRIBUTES, META_BACKUP, META_CHANGED, META_CREATION,
|
||||
META_DIRECTORY, META_GID, META_ID, META_KEY, META_MODE,
|
||||
META_MODIFIED, META_OSXFLAGS, META_PINNED, META_SIZE, META_SOURCE,
|
||||
META_UID, META_WRITTEN,
|
||||
META_ACCESSED, META_ATTRIBUTES, META_BACKUP, META_CHANGED,
|
||||
META_CREATION, META_DIRECTORY, META_GID, META_KEY,
|
||||
META_MODE, META_MODIFIED, META_OSXFLAGS, META_PINNED,
|
||||
META_SIZE, META_SOURCE, META_UID, META_WRITTEN,
|
||||
};
|
||||
|
||||
using api_meta_map = std::map<std::string, std::string>;
|
||||
|
@@ -26,6 +26,9 @@
|
||||
#include "utils/encrypting_reader.hpp"
|
||||
|
||||
namespace repertory::utils::encryption {
|
||||
using reader_func = std::function<api_error(data_buffer &cypher_text,
|
||||
std::uint64_t start_offset,
|
||||
std::uint64_t end_offset)>;
|
||||
// Prototypes
|
||||
[[nodiscard]] auto decrypt_file_path(const std::string &encryption_token,
|
||||
std::string &file_path) -> api_error;
|
||||
@@ -36,11 +39,10 @@ namespace repertory::utils::encryption {
|
||||
[[nodiscard]] auto generate_key(const std::string &encryption_token)
|
||||
-> key_type;
|
||||
|
||||
[[nodiscard]] auto read_encrypted_range(
|
||||
const http_range &range, const key_type &key,
|
||||
const std::function<api_error(data_buffer &ct, std::uint64_t start_offset,
|
||||
std::uint64_t end_offset)> &reader,
|
||||
std::uint64_t total_size, data_buffer &data) -> api_error;
|
||||
[[nodiscard]] auto read_encrypted_range(const http_range &range,
|
||||
const key_type &key, reader_func reader,
|
||||
std::uint64_t total_size,
|
||||
data_buffer &data) -> api_error;
|
||||
|
||||
// Implementations
|
||||
template <typename result>
|
||||
|
@@ -25,60 +25,60 @@
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory::utils::error {
|
||||
void raise_error(std::string_view function, std::string_view msg);
|
||||
void raise_error(std::string function, std::string_view msg);
|
||||
|
||||
void raise_error(std::string_view function, const api_error &e,
|
||||
void raise_error(std::string function, const api_error &err,
|
||||
std::string_view msg);
|
||||
|
||||
void raise_error(std::string_view function, const std::exception &e,
|
||||
void raise_error(std::string function, const std::exception &exception,
|
||||
std::string_view msg);
|
||||
|
||||
void raise_error(std::string_view function, std::int64_t e,
|
||||
std::string_view msg);
|
||||
void raise_error(std::string function, std::int64_t err, std::string_view msg);
|
||||
|
||||
void raise_error(std::string_view function, const json &e,
|
||||
std::string_view msg);
|
||||
void raise_error(std::string function, const json &err, std::string_view msg);
|
||||
|
||||
void raise_error(std::string_view function, const api_error &e,
|
||||
void raise_error(std::string function, const api_error &err,
|
||||
std::string_view file_path, std::string_view msg);
|
||||
|
||||
void raise_error(std::string_view function, std::int64_t e,
|
||||
void raise_error(std::string function, std::int64_t err,
|
||||
std::string_view file_path, std::string_view msg);
|
||||
|
||||
void raise_error(std::string_view function, const std::exception &e,
|
||||
void raise_error(std::string function, const std::exception &exception,
|
||||
std::string_view file_path, std::string_view msg);
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
const api_error &e, std::string_view msg);
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
const api_error &err, std::string_view msg);
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
const std::exception &e, std::string_view msg);
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
std::int64_t e, std::string_view msg);
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
const json &e, std::string_view msg);
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
std::string_view source_path, const api_error &e,
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
const std::exception &exception,
|
||||
std::string_view msg);
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
std::string_view source_path, std::int64_t e,
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
std::int64_t err, std::string_view msg);
|
||||
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
const json &err, std::string_view msg);
|
||||
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
std::string_view source_path, const api_error &err,
|
||||
std::string_view msg);
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
std::string_view source_path, const std::exception &e,
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
std::string_view source_path, std::int64_t err,
|
||||
std::string_view msg);
|
||||
|
||||
void raise_url_error(std::string_view function, std::string_view url,
|
||||
CURLcode e, std::string_view msg);
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
std::string_view source_path,
|
||||
const std::exception &exception,
|
||||
std::string_view msg);
|
||||
|
||||
void raise_url_error(std::string_view function, std::string_view url,
|
||||
std::string_view source_path, const std::exception &e,
|
||||
void raise_url_error(std::string function, std::string_view url, CURLcode err,
|
||||
std::string_view msg);
|
||||
|
||||
void raise_url_error(std::string function, std::string_view url,
|
||||
std::string_view source_path,
|
||||
const std::exception &exception, std::string_view msg);
|
||||
|
||||
} // namespace repertory::utils::error
|
||||
|
||||
#endif // INCLUDE_UTILS_ERROR_UTILS_HPP_
|
||||
|
@@ -28,7 +28,7 @@
|
||||
|
||||
namespace repertory::utils {
|
||||
#if __linux__
|
||||
inline const std::array<std::string, 4u> attribute_namespaces = {
|
||||
inline const std::array<std::string, 4U> attribute_namespaces = {
|
||||
"security",
|
||||
"system",
|
||||
"trusted",
|
||||
@@ -38,12 +38,12 @@ inline const std::array<std::string, 4u> attribute_namespaces = {
|
||||
|
||||
#if __APPLE__
|
||||
template <typename t>
|
||||
[[nodiscard]] auto convert_to_uint64(const t *v) -> std::uint64_t;
|
||||
[[nodiscard]] auto convert_to_uint64(const t *ptr) -> std::uint64_t;
|
||||
#else
|
||||
[[nodiscard]] auto convert_to_uint64(const pthread_t &t) -> std::uint64_t;
|
||||
[[nodiscard]] auto convert_to_uint64(const pthread_t &thread) -> std::uint64_t;
|
||||
#endif
|
||||
|
||||
[[nodiscard]] auto from_api_error(const api_error &e) -> int;
|
||||
[[nodiscard]] auto from_api_error(const api_error &err) -> int;
|
||||
|
||||
[[nodiscard]] auto get_last_error_code() -> int;
|
||||
|
||||
@@ -54,20 +54,20 @@ template <typename t>
|
||||
|
||||
void set_last_error_code(int error_code);
|
||||
|
||||
[[nodiscard]] auto to_api_error(int e) -> api_error;
|
||||
[[nodiscard]] auto to_api_error(int err) -> api_error;
|
||||
|
||||
[[nodiscard]] auto unix_error_to_windows(int e) -> std::int32_t;
|
||||
[[nodiscard]] auto unix_error_to_windows(int err) -> std::int32_t;
|
||||
|
||||
[[nodiscard]] auto unix_time_to_windows_time(const remote::file_time &ts)
|
||||
[[nodiscard]] auto unix_time_to_windows_time(const remote::file_time &file_time)
|
||||
-> UINT64;
|
||||
|
||||
void use_getpwuid(uid_t uid, std::function<void(struct passwd *pw)> fn);
|
||||
void use_getpwuid(uid_t uid, std::function<void(struct passwd *pass)> callback);
|
||||
|
||||
void windows_create_to_unix(const UINT32 &create_options,
|
||||
const UINT32 &granted_access, std::uint32_t &flags,
|
||||
remote::file_mode &mode);
|
||||
|
||||
[[nodiscard]] auto windows_time_to_unix_time(std::uint64_t t)
|
||||
[[nodiscard]] auto windows_time_to_unix_time(std::uint64_t win_time)
|
||||
-> remote::file_time;
|
||||
|
||||
// template implementations
|
||||
|
@@ -151,7 +151,7 @@ template <typename t>
|
||||
template <typename data_type>
|
||||
[[nodiscard]] auto random_between(const data_type &begin, const data_type &end)
|
||||
-> data_type {
|
||||
return begin + repertory_rand<data_type>() % ((end + 1) - begin);
|
||||
return begin + repertory_rand<data_type>() % ((end + data_type{1}) - begin);
|
||||
}
|
||||
|
||||
template <typename collection_t>
|
||||
|
@@ -12,6 +12,8 @@ if [ -z "${BUILD_ARCH}" ]; then
|
||||
BUILD_ARCH=64_bit
|
||||
fi
|
||||
|
||||
ln -sf ${SOURCE_DIR}/build/compile_commands.json ${SOURCE_DIR}/compile_commands.json
|
||||
|
||||
docker stop repertory_${NAME}
|
||||
docker rm repertory_${NAME}
|
||||
docker build -t repertory:${NAME} - < ${SOURCE_DIR}/docker/${BUILD_ARCH}/${NAME} &&
|
||||
|
@@ -41,6 +41,15 @@ cmake ../.. ${CMAKE_ADDITIONAL_OPTS} \
|
||||
-DREPERTORY_ENABLE_S3=ON \
|
||||
-DREPERTORY_ENABLE_S3_TESTING=ON || exit 1
|
||||
|
||||
pushd ..
|
||||
ln -sf ${BUILD_FOLDER}/compile_commands.json .
|
||||
ln -sf ${BUILD_FOLDER}/repertory${EXE_EXT} .
|
||||
ln -sf ${BUILD_FOLDER}/unittests${EXE_EXT} .
|
||||
if [ "${IS_MINGW}" == "1" ]; then
|
||||
ln -sf ${BUILD_FOLDER}/winfsp-x64.dll .
|
||||
fi
|
||||
popd
|
||||
|
||||
if [ "${BUILD_CLEAN}" == "clean" ]; then
|
||||
make clean
|
||||
fi
|
||||
|
@@ -28,52 +28,73 @@
|
||||
#include "utils/unix/unix_utils.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
namespace {
|
||||
constexpr const auto default_api_auth_size = 48U;
|
||||
constexpr const auto default_download_timeout_ces = 30U;
|
||||
constexpr const auto default_eviction_delay_mins = 10U;
|
||||
constexpr const auto default_high_freq_interval_secs = 30U;
|
||||
constexpr const auto default_low_freq_interval_secs = 60U * 60U;
|
||||
constexpr const auto default_max_cache_size_bytes =
|
||||
20ULL * 1024ULL * 1024ULL * 1024ULL;
|
||||
constexpr const auto default_max_upload_count = 5U;
|
||||
constexpr const auto default_min_download_timeout_secs = 5U;
|
||||
constexpr const auto default_online_check_retry_secs = 60U;
|
||||
constexpr const auto default_orphaned_file_retention_days = 15U;
|
||||
constexpr const auto default_read_ahead_count = 4U;
|
||||
constexpr const auto default_remote_client_pool_size = 10U;
|
||||
constexpr const auto default_remote_host_name_or_ip = "";
|
||||
constexpr const auto default_remote_max_connections = 20U;
|
||||
constexpr const auto default_remote_receive_timeout_secs = 120U;
|
||||
constexpr const auto default_remote_send_timeout_secs = 30U;
|
||||
constexpr const auto default_remote_token = "";
|
||||
constexpr const auto default_retry_read_count = 6U;
|
||||
constexpr const auto default_ring_buffer_file_size = 512U;
|
||||
constexpr const auto retry_save_count = 5U;
|
||||
} // namespace
|
||||
|
||||
namespace repertory {
|
||||
app_config::app_config(const provider_type &prov,
|
||||
const std::string &data_directory)
|
||||
: prov_(prov),
|
||||
api_auth_(utils::generate_random_string(48U)),
|
||||
api_auth_(utils::generate_random_string(default_api_auth_size)),
|
||||
api_port_(default_rpc_port(prov)),
|
||||
api_user_("repertory"),
|
||||
api_user_(REPERTORY),
|
||||
config_changed_(false),
|
||||
data_directory_(data_directory.empty()
|
||||
? default_data_directory(prov)
|
||||
: utils::path::absolute(data_directory)),
|
||||
download_timeout_secs_(30),
|
||||
download_timeout_secs_(default_download_timeout_ces),
|
||||
enable_chunk_downloader_timeout_(true),
|
||||
enable_comm_duration_events_(false),
|
||||
enable_drive_events_(false),
|
||||
enable_max_cache_size_(true),
|
||||
enable_max_cache_size_(false),
|
||||
#ifdef _WIN32
|
||||
enable_mount_manager_(false),
|
||||
#endif
|
||||
enable_remote_mount_(false),
|
||||
event_level_(event_level::normal),
|
||||
eviction_delay_mins_(30),
|
||||
eviction_delay_mins_(default_eviction_delay_mins),
|
||||
eviction_uses_accessed_time_(false),
|
||||
high_freq_interval_secs_(30),
|
||||
high_freq_interval_secs_(default_high_freq_interval_secs),
|
||||
is_remote_mount_(false),
|
||||
low_freq_interval_secs_(60 * 60),
|
||||
max_cache_size_bytes_(20 * 1024 * 1024 * 1024ULL),
|
||||
max_upload_count_(5U),
|
||||
min_download_timeout_secs_(5),
|
||||
online_check_retry_secs_(60),
|
||||
orphaned_file_retention_days_(15),
|
||||
low_freq_interval_secs_(default_low_freq_interval_secs),
|
||||
max_cache_size_bytes_(default_max_cache_size_bytes),
|
||||
max_upload_count_(default_max_upload_count),
|
||||
min_download_timeout_secs_(default_min_download_timeout_secs),
|
||||
online_check_retry_secs_(default_online_check_retry_secs),
|
||||
orphaned_file_retention_days_(default_orphaned_file_retention_days),
|
||||
preferred_download_type_(
|
||||
utils::download_type_to_string(download_type::fallback)),
|
||||
read_ahead_count_(4),
|
||||
remote_client_pool_size_(10),
|
||||
remote_host_name_or_ip_(""),
|
||||
remote_max_connections_(20),
|
||||
remote_port_((prov == provider_type::sia) ? 20000
|
||||
: (prov == provider_type::s3) ? 20001
|
||||
: (prov == provider_type::encrypt) ? 20002
|
||||
: 20003),
|
||||
remote_receive_timeout_secs_(120),
|
||||
remote_send_timeout_secs_(30),
|
||||
remote_token_(""),
|
||||
retry_read_count_(6),
|
||||
ring_buffer_file_size_(512) {
|
||||
read_ahead_count_(default_read_ahead_count),
|
||||
remote_client_pool_size_(default_remote_client_pool_size),
|
||||
remote_host_name_or_ip_(default_remote_host_name_or_ip),
|
||||
remote_max_connections_(default_remote_max_connections),
|
||||
remote_port_(default_remote_port(prov)),
|
||||
remote_receive_timeout_secs_(default_remote_receive_timeout_secs),
|
||||
remote_send_timeout_secs_(default_remote_send_timeout_secs),
|
||||
remote_token_(default_remote_token),
|
||||
retry_read_count_(default_retry_read_count),
|
||||
ring_buffer_file_size_(default_ring_buffer_file_size) {
|
||||
cache_directory_ = utils::path::combine(data_directory_, {"cache"});
|
||||
log_directory_ = utils::path::combine(data_directory_, {"logs"});
|
||||
|
||||
@@ -105,16 +126,26 @@ auto app_config::get_config_file_path() const -> std::string {
|
||||
auto app_config::default_agent_name(const provider_type &prov) -> std::string {
|
||||
static const std::array<std::string,
|
||||
static_cast<std::size_t>(provider_type::unknown)>
|
||||
PROVIDER_AGENT_NAMES = {"Sia-Agent", "", "", ""};
|
||||
PROVIDER_AGENT_NAMES = {
|
||||
"Sia-Agent",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
};
|
||||
|
||||
return PROVIDER_AGENT_NAMES[static_cast<std::size_t>(prov)];
|
||||
return PROVIDER_AGENT_NAMES.at(static_cast<std::size_t>(prov));
|
||||
}
|
||||
|
||||
auto app_config::default_api_port(const provider_type &prov) -> std::uint16_t {
|
||||
static const std::array<std::uint16_t,
|
||||
static_cast<std::size_t>(provider_type::unknown)>
|
||||
PROVIDER_API_PORTS = {9980U, 0U, 0U, 0U};
|
||||
return PROVIDER_API_PORTS[static_cast<std::size_t>(prov)];
|
||||
PROVIDER_API_PORTS = {
|
||||
9980U,
|
||||
0U,
|
||||
0U,
|
||||
0U,
|
||||
};
|
||||
return PROVIDER_API_PORTS.at(static_cast<std::size_t>(prov));
|
||||
}
|
||||
|
||||
auto app_config::default_data_directory(const provider_type &prov)
|
||||
@@ -137,16 +168,28 @@ auto app_config::default_data_directory(const provider_type &prov)
|
||||
return data_directory;
|
||||
}
|
||||
|
||||
auto app_config::default_remote_port(const provider_type &prov)
|
||||
-> std::uint16_t {
|
||||
static const std::array<std::uint16_t,
|
||||
static_cast<std::size_t>(provider_type::unknown)>
|
||||
PROVIDER_REMOTE_PORTS = {
|
||||
20000U,
|
||||
20010U,
|
||||
20100U,
|
||||
20001U,
|
||||
};
|
||||
return PROVIDER_REMOTE_PORTS.at(static_cast<std::size_t>(prov));
|
||||
}
|
||||
auto app_config::default_rpc_port(const provider_type &prov) -> std::uint16_t {
|
||||
static const std::array<std::uint16_t,
|
||||
static_cast<std::size_t>(provider_type::unknown)>
|
||||
PROVIDER_RPC_PORTS = {
|
||||
11101U,
|
||||
11102U,
|
||||
11103U,
|
||||
11104U,
|
||||
10000U,
|
||||
10010U,
|
||||
10100U,
|
||||
10002U,
|
||||
};
|
||||
return PROVIDER_RPC_PORTS[static_cast<std::size_t>(prov)];
|
||||
return PROVIDER_RPC_PORTS.at(static_cast<std::size_t>(prov));
|
||||
}
|
||||
|
||||
auto app_config::get_json() const -> json {
|
||||
@@ -289,7 +332,7 @@ auto app_config::get_provider_api_password(const provider_type &prov)
|
||||
#endif
|
||||
#endif
|
||||
auto lines = utils::file::read_file_lines(api_file);
|
||||
return lines.empty() ? "" : utils::string::trim(lines[0]);
|
||||
return lines.empty() ? "" : utils::string::trim(lines[0U]);
|
||||
}
|
||||
|
||||
auto app_config::get_provider_display_name(const provider_type &prov)
|
||||
@@ -302,7 +345,7 @@ auto app_config::get_provider_display_name(const provider_type &prov)
|
||||
"S3",
|
||||
"Encrypt",
|
||||
};
|
||||
return PROVIDER_DISPLAY_NAMES[static_cast<std::size_t>(prov)];
|
||||
return PROVIDER_DISPLAY_NAMES.at(static_cast<std::size_t>(prov));
|
||||
}
|
||||
|
||||
auto app_config::get_provider_name(const provider_type &prov) -> std::string {
|
||||
@@ -314,7 +357,7 @@ auto app_config::get_provider_name(const provider_type &prov) -> std::string {
|
||||
"s3",
|
||||
"encrypt",
|
||||
};
|
||||
return PROVIDER_NAMES[static_cast<std::size_t>(prov)];
|
||||
return PROVIDER_NAMES.at(static_cast<std::size_t>(prov));
|
||||
}
|
||||
|
||||
auto app_config::get_value_by_name(const std::string &name) -> std::string {
|
||||
@@ -332,16 +375,16 @@ auto app_config::get_value_by_name(const std::string &name) -> std::string {
|
||||
return std::to_string(get_chunk_downloader_timeout_secs());
|
||||
}
|
||||
if (name == "EnableChunkDownloaderTimeout") {
|
||||
return std::to_string(get_enable_chunk_download_timeout());
|
||||
return utils::string::from_bool(get_enable_chunk_download_timeout());
|
||||
}
|
||||
if (name == "GetEnableCommDurationEvents") {
|
||||
return std::to_string(get_enable_comm_duration_events());
|
||||
return utils::string::from_bool(get_enable_comm_duration_events());
|
||||
}
|
||||
if (name == "EnableDriveEvents") {
|
||||
return std::to_string(get_enable_drive_events());
|
||||
return utils::string::from_bool(get_enable_drive_events());
|
||||
}
|
||||
if (name == "EnableMaxCacheSize") {
|
||||
return std::to_string(get_enable_max_cache_size());
|
||||
return utils::string::from_bool(get_enable_max_cache_size());
|
||||
#ifdef _WIN32
|
||||
}
|
||||
if (name == "EnableMountManager") {
|
||||
@@ -361,7 +404,7 @@ auto app_config::get_value_by_name(const std::string &name) -> std::string {
|
||||
return std::to_string(get_eviction_delay_mins());
|
||||
}
|
||||
if (name == "EvictionUsesAccessedTime") {
|
||||
return std::to_string(get_eviction_uses_accessed_time());
|
||||
return utils::string::from_bool(get_eviction_uses_accessed_time());
|
||||
}
|
||||
if (name == "HighFreqIntervalSeconds") {
|
||||
return std::to_string(get_high_frequency_interval_secs());
|
||||
@@ -404,10 +447,10 @@ auto app_config::get_value_by_name(const std::string &name) -> std::string {
|
||||
return std::to_string(get_read_ahead_count());
|
||||
}
|
||||
if (name == "RemoteMount.EnableRemoteMount") {
|
||||
return std::to_string(get_enable_remote_mount());
|
||||
return utils::string::from_bool(get_enable_remote_mount());
|
||||
}
|
||||
if (name == "RemoteMount.IsRemoteMount") {
|
||||
return std::to_string(get_is_remote_mount());
|
||||
return utils::string::from_bool(get_is_remote_mount());
|
||||
}
|
||||
if (name == "RemoteMount.RemoteClientPoolSize") {
|
||||
return std::to_string(get_remote_client_pool_size());
|
||||
@@ -485,7 +528,8 @@ auto app_config::load() -> bool {
|
||||
stream << config_file.rdbuf();
|
||||
const auto json_text = stream.str();
|
||||
config_file.close();
|
||||
if ((ret = not json_text.empty())) {
|
||||
ret = not json_text.empty();
|
||||
if (ret) {
|
||||
const auto json_document = json::parse(json_text);
|
||||
|
||||
get_value(json_document, "ApiAuth", api_auth_, ret);
|
||||
@@ -650,8 +694,9 @@ void app_config::save() {
|
||||
config_changed_ = false;
|
||||
json data = get_json();
|
||||
auto success = false;
|
||||
for (auto i = 0; not success && (i < 5); i++) {
|
||||
if (not(success = utils::file::write_json_file(file_path, data))) {
|
||||
for (auto i = 0U; not success && (i < retry_save_count); i++) {
|
||||
success = utils::file::write_json_file(file_path, data);
|
||||
if (not success) {
|
||||
std::this_thread::sleep_for(1s);
|
||||
}
|
||||
}
|
||||
|
@@ -154,6 +154,16 @@ auto curl_comm::make_request(const curl::requests::http_head &head,
|
||||
head, response_code, stop_requested);
|
||||
}
|
||||
|
||||
auto curl_comm::make_request(const curl::requests::http_post &post,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const -> bool {
|
||||
return make_request(
|
||||
s3_config_.has_value()
|
||||
? create_host_config(s3_config_.value(), use_s3_path_style_)
|
||||
: host_config_.value_or(host_config{}),
|
||||
post, response_code, stop_requested);
|
||||
}
|
||||
|
||||
auto curl_comm::make_request(const curl::requests::http_put_file &put_file,
|
||||
long &response_code,
|
||||
stop_type &stop_requested) const -> bool {
|
||||
|
@@ -1,40 +1,45 @@
|
||||
/*
|
||||
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_UTILS_ROCKSDB_UTILS_HPP_
|
||||
#define INCLUDE_UTILS_ROCKSDB_UTILS_HPP_
|
||||
|
||||
namespace repertory {
|
||||
class app_config;
|
||||
|
||||
namespace utils::db {
|
||||
void create_rocksdb(const app_config &config, const std::string &name,
|
||||
std::unique_ptr<rocksdb::DB> &db);
|
||||
|
||||
void create_rocksdb(
|
||||
const app_config &config, const std::string &name,
|
||||
const std::vector<rocksdb::ColumnFamilyDescriptor> &families,
|
||||
std::vector<rocksdb::ColumnFamilyHandle *> &handles,
|
||||
std::unique_ptr<rocksdb::DB> &db);
|
||||
} // namespace utils::db
|
||||
} // namespace repertory
|
||||
|
||||
#endif // INCLUDE_UTILS_ROCKSDB_UTILS_HPP_
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
#include "comm/curl/requests/http_post.hpp"
|
||||
|
||||
namespace repertory::curl::requests {
|
||||
http_post::~http_post() {
|
||||
if (headers != nullptr) {
|
||||
curl_slist_free_all(headers);
|
||||
}
|
||||
}
|
||||
|
||||
auto http_post::set_method(CURL *curl, stop_type & /*stop_requested*/) const
|
||||
-> bool {
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
if (json.has_value()) {
|
||||
headers = curl_slist_append(headers, "content-type: application/json");
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
|
||||
json_str = json->dump();
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_str->c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, -1L);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace repertory::curl::requests
|
@@ -49,7 +49,11 @@ void repertory_init() {
|
||||
}
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
sqlite3_initialize();
|
||||
}
|
||||
|
||||
void repertory_shutdown() { curl_global_cleanup(); }
|
||||
void repertory_shutdown() {
|
||||
curl_global_cleanup();
|
||||
sqlite3_shutdown();
|
||||
}
|
||||
} // namespace repertory
|
||||
|
96
src/database/db_insert.cpp
Normal file
96
src/database/db_insert.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
#include "database/db_insert.hpp"
|
||||
|
||||
namespace repertory::db {
|
||||
auto db_insert::column_value(std::string column_name, db_types_t value)
|
||||
-> db_insert & {
|
||||
context_->values[column_name] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto db_insert::dump() const -> std::string {
|
||||
std::stringstream query;
|
||||
query << "INSERT ";
|
||||
if (context_->or_replace) {
|
||||
query << "OR REPLACE ";
|
||||
}
|
||||
query << "INTO \"" << context_->table_name << "\" (";
|
||||
|
||||
for (std::int32_t idx = 0;
|
||||
idx < static_cast<std::int32_t>(context_->values.size()); idx++) {
|
||||
if (idx > 0) {
|
||||
query << ", ";
|
||||
}
|
||||
query << '"' << std::next(context_->values.begin(), idx)->first << '"';
|
||||
}
|
||||
|
||||
query << ") VALUES (";
|
||||
for (std::int32_t idx = 0;
|
||||
idx < static_cast<std::int32_t>(context_->values.size()); idx++) {
|
||||
if (idx > 0) {
|
||||
query << ", ";
|
||||
}
|
||||
query << "?" << (idx + 1);
|
||||
}
|
||||
query << ");";
|
||||
|
||||
return query.str();
|
||||
}
|
||||
|
||||
auto db_insert::go() const -> db_result<context> {
|
||||
sqlite3_stmt *stmt_ptr{nullptr};
|
||||
auto query_str = dump();
|
||||
auto res = sqlite3_prepare_v2(&context_->db3, query_str.c_str(), -1,
|
||||
&stmt_ptr, nullptr);
|
||||
if (res != SQLITE_OK) {
|
||||
utils::error::raise_error(__FUNCTION__, "failed to prepare|" +
|
||||
std::to_string(res) + '|' +
|
||||
sqlite3_errstr(res));
|
||||
return {context_, res};
|
||||
}
|
||||
context_->stmt.reset(stmt_ptr);
|
||||
|
||||
for (std::int32_t idx = 0;
|
||||
idx < static_cast<std::int32_t>(context_->values.size()); idx++) {
|
||||
res = std::visit(
|
||||
overloaded{
|
||||
[this, &idx](std::int64_t data) -> std::int32_t {
|
||||
return sqlite3_bind_int64(context_->stmt.get(), idx + 1, data);
|
||||
},
|
||||
[this, &idx](const std::string &data) -> std::int32_t {
|
||||
return sqlite3_bind_text(context_->stmt.get(), idx + 1,
|
||||
data.c_str(), -1, nullptr);
|
||||
},
|
||||
},
|
||||
std::next(context_->values.begin(), idx)->second);
|
||||
if (res != SQLITE_OK) {
|
||||
utils::error::raise_error(__FUNCTION__, "failed to bind|" +
|
||||
std::to_string(res) + '|' +
|
||||
sqlite3_errstr(res));
|
||||
return {context_, res};
|
||||
}
|
||||
}
|
||||
|
||||
return {context_, res};
|
||||
}
|
||||
} // namespace repertory::db
|
173
src/database/db_select.cpp
Normal file
173
src/database/db_select.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
#include "database/db_select.hpp"
|
||||
|
||||
namespace repertory::db {
|
||||
|
||||
auto db_select::column(std::string column_name) -> db_select & {
|
||||
if (context_->delete_query) {
|
||||
throw std::runtime_error("columns may not be specified for delete");
|
||||
}
|
||||
|
||||
context_->columns.push_back(column_name);
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto db_select::count(std::string column_name, std::string as_column_name)
|
||||
-> db_select & {
|
||||
context_->count_columns[column_name] = as_column_name;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto db_select::delete_query() -> db_select & {
|
||||
if (not context_->columns.empty()) {
|
||||
throw std::runtime_error("columns must be empty for delete");
|
||||
}
|
||||
|
||||
context_->delete_query = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto db_select::dump() const -> std::string {
|
||||
std::stringstream query;
|
||||
query << (context_->delete_query ? "DELETE " : "SELECT ");
|
||||
if (not context_->delete_query) {
|
||||
bool has_column{false};
|
||||
if (context_->columns.empty()) {
|
||||
if (context_->count_columns.empty()) {
|
||||
query << "*";
|
||||
has_column = true;
|
||||
}
|
||||
} else {
|
||||
has_column = not context_->columns.empty();
|
||||
for (std::size_t idx = 0U; idx < context_->columns.size(); idx++) {
|
||||
if (idx > 0U) {
|
||||
query << ", ";
|
||||
}
|
||||
query << context_->columns.at(idx);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::int32_t idx = 0U;
|
||||
idx < static_cast<std::int32_t>(context_->count_columns.size());
|
||||
idx++) {
|
||||
if (has_column || idx > 0) {
|
||||
query << ", ";
|
||||
}
|
||||
query << "COUNT(\"";
|
||||
auto &count_column = *std::next(context_->count_columns.begin(), idx);
|
||||
query << count_column.first << "\") AS \"" << count_column.second << '"';
|
||||
}
|
||||
}
|
||||
query << " FROM \"" << context_->table_name << "\"";
|
||||
|
||||
if (not context_->ands.empty()) {
|
||||
query << " WHERE (";
|
||||
for (std::int32_t idx = 0;
|
||||
idx < static_cast<std::int32_t>(context_->ands.size()); idx++) {
|
||||
if (idx > 0) {
|
||||
query << " AND ";
|
||||
}
|
||||
|
||||
auto &item = context_->ands.at(static_cast<std::size_t>(idx));
|
||||
query << '"' << item.column_name << '"' << item.op_type << "?"
|
||||
<< (idx + 1);
|
||||
}
|
||||
query << ")";
|
||||
}
|
||||
|
||||
if (not context_->delete_query) {
|
||||
if (context_->order_by.has_value()) {
|
||||
query << " ORDER BY \"" << context_->order_by.value().first << "\" ";
|
||||
query << (context_->order_by.value().second ? "ASC" : "DESC");
|
||||
}
|
||||
|
||||
if (context_->limit.has_value()) {
|
||||
query << " LIMIT " << context_->limit.value();
|
||||
}
|
||||
}
|
||||
|
||||
query << ';';
|
||||
|
||||
return query.str();
|
||||
}
|
||||
|
||||
auto db_select::go() const -> db_result<context> {
|
||||
sqlite3_stmt *stmt_ptr{nullptr};
|
||||
auto query_str = dump();
|
||||
auto res = sqlite3_prepare_v2(&context_->db3, query_str.c_str(), -1,
|
||||
&stmt_ptr, nullptr);
|
||||
if (res != SQLITE_OK) {
|
||||
utils::error::raise_error(__FUNCTION__,
|
||||
"failed to prepare|" + std::to_string(res) + '|' +
|
||||
sqlite3_errstr(res) + '|' + query_str);
|
||||
return {context_, res};
|
||||
}
|
||||
context_->stmt.reset(stmt_ptr);
|
||||
|
||||
for (std::int32_t idx = 0;
|
||||
idx < static_cast<std::int32_t>(context_->ands.size()); idx++) {
|
||||
res = std::visit(
|
||||
overloaded{
|
||||
[this, &idx](std::int64_t data) -> std::int32_t {
|
||||
return sqlite3_bind_int64(context_->stmt.get(), idx + 1, data);
|
||||
},
|
||||
[this, &idx](const std::string &data) -> std::int32_t {
|
||||
return sqlite3_bind_text(context_->stmt.get(), idx + 1,
|
||||
data.c_str(), -1, nullptr);
|
||||
},
|
||||
},
|
||||
context_->ands.at(static_cast<std::size_t>(idx)).value);
|
||||
if (res != SQLITE_OK) {
|
||||
utils::error::raise_error(__FUNCTION__,
|
||||
"failed to bind|" + std::to_string(res) + '|' +
|
||||
sqlite3_errstr(res) + '|' + query_str);
|
||||
return {context_, res};
|
||||
}
|
||||
}
|
||||
|
||||
return {context_, res};
|
||||
}
|
||||
|
||||
auto db_select::limit(std::int32_t value) -> db_select & {
|
||||
if (context_->delete_query) {
|
||||
throw std::runtime_error("limit may not be specified for delete");
|
||||
}
|
||||
|
||||
context_->limit = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto db_select::order_by(std::string column_name, bool ascending)
|
||||
-> db_select & {
|
||||
if (context_->delete_query) {
|
||||
throw std::runtime_error("order_by may not be specified for delete");
|
||||
}
|
||||
|
||||
context_->order_by = {column_name, ascending};
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto db_select::where(std::string column_name) const -> db_where {
|
||||
return db_where{context_, column_name};
|
||||
}
|
||||
} // namespace repertory::db
|
@@ -54,10 +54,12 @@ auto directory_iterator::fill_buffer(const remote::file_offset &offset,
|
||||
}
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
if (filler_function(buffer, &item_name[0], pst, offset + 1,
|
||||
if (filler_function(buffer, item_name.data(), pst,
|
||||
static_cast<off_t>(offset + 1),
|
||||
FUSE_FILL_DIR_PLUS) != 0) {
|
||||
#else
|
||||
if (filler_function(buffer, &item_name[0], pst, offset + 1) != 0) {
|
||||
if (filler_function(buffer, item_name.data(), pst,
|
||||
static_cast<off_t>(offset + 1)) != 0) {
|
||||
#endif
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@@ -121,13 +123,14 @@ auto directory_iterator::get_json(std::size_t offset, json &item) -> int {
|
||||
|
||||
auto directory_iterator::get_next_directory_offset(
|
||||
const std::string &api_path) const -> std::size_t {
|
||||
const auto it = std::find_if(
|
||||
items_.begin(), items_.end(),
|
||||
[&api_path](const auto &di) -> bool { return api_path == di.api_path; });
|
||||
const auto iter = std::find_if(items_.begin(), items_.end(),
|
||||
[&api_path](const auto &dir_item) -> bool {
|
||||
return api_path == dir_item.api_path;
|
||||
});
|
||||
|
||||
return (it == items_.end())
|
||||
? 0
|
||||
: std::distance(items_.begin(), it) + std::size_t(1u);
|
||||
return (iter == items_.end()) ? 0U
|
||||
: static_cast<std::size_t>(
|
||||
std::distance(items_.begin(), iter) + 1);
|
||||
}
|
||||
|
||||
auto directory_iterator::operator=(const directory_iterator &iterator) noexcept
|
||||
|
@@ -41,12 +41,12 @@ auto eviction::check_minimum_requirements(const std::string &file_path)
|
||||
}
|
||||
|
||||
auto ret = false;
|
||||
if (file_size) {
|
||||
if (file_size != 0U) {
|
||||
std::uint64_t reference_time{};
|
||||
if ((ret =
|
||||
config_.get_eviction_uses_accessed_time()
|
||||
? utils::file::get_accessed_time(file_path, reference_time)
|
||||
: utils::file::get_modified_time(file_path, reference_time))) {
|
||||
ret = config_.get_eviction_uses_accessed_time()
|
||||
? utils::file::get_accessed_time(file_path, reference_time)
|
||||
: utils::file::get_modified_time(file_path, reference_time);
|
||||
if (ret) {
|
||||
#ifdef _WIN32
|
||||
const auto now = std::chrono::system_clock::now();
|
||||
const auto delay =
|
||||
@@ -57,7 +57,7 @@ auto eviction::check_minimum_requirements(const std::string &file_path)
|
||||
const auto now = utils::get_time_now();
|
||||
const auto delay =
|
||||
(config_.get_eviction_delay_mins() * 60L) * NANOS_PER_SECOND;
|
||||
ret = ((reference_time + delay) <= now);
|
||||
ret = ((reference_time + static_cast<std::uint64_t>(delay)) <= now);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "common.hpp"
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "drives/fuse/fuse_base.hpp"
|
||||
@@ -28,6 +29,7 @@
|
||||
#include "events/event_system.hpp"
|
||||
#include "events/events.hpp"
|
||||
#include "providers/i_provider.hpp"
|
||||
#include "utils/file_utils.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
@@ -160,6 +162,8 @@ void fuse_base::destroy_(void *ptr) {
|
||||
execute_void_callback(__FUNCTION__, [&]() { instance().destroy_impl(ptr); });
|
||||
}
|
||||
|
||||
void fuse_base::destroy_impl(void * /* ptr */) { repertory_shutdown(); }
|
||||
|
||||
void fuse_base::display_options(
|
||||
[[maybe_unused]] std::vector<const char *> args) {
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
@@ -176,7 +180,7 @@ void fuse_base::display_options(
|
||||
|
||||
void fuse_base::display_version_information(std::vector<const char *> args) {
|
||||
struct fuse_operations fuse_ops {};
|
||||
fuse_main(args.size(),
|
||||
fuse_main(static_cast<int>(args.size()),
|
||||
reinterpret_cast<char **>(const_cast<char **>(args.data())),
|
||||
&fuse_ops, nullptr);
|
||||
}
|
||||
@@ -312,6 +316,9 @@ auto fuse_base::init_(struct fuse_conn_info *conn) -> void * {
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
auto fuse_base::init_impl([[maybe_unused]] struct fuse_conn_info *conn,
|
||||
struct fuse_config *cfg) -> void * {
|
||||
utils::file::change_to_process_directory();
|
||||
repertory_init();
|
||||
|
||||
#ifdef __APPLE__
|
||||
conn->want |= FUSE_CAP_VOL_RENAME;
|
||||
conn->want |= FUSE_CAP_XTIMES;
|
||||
@@ -324,6 +331,9 @@ auto fuse_base::init_impl([[maybe_unused]] struct fuse_conn_info *conn,
|
||||
}
|
||||
#else
|
||||
auto fuse_base::init_impl(struct fuse_conn_info *conn) -> void * {
|
||||
utils::file::change_to_process_directory();
|
||||
repertory_init();
|
||||
|
||||
#ifdef __APPLE__
|
||||
conn->want |= FUSE_CAP_VOL_RENAME;
|
||||
conn->want |= FUSE_CAP_XTIMES;
|
||||
@@ -351,8 +361,9 @@ auto fuse_base::mount(std::vector<std::string> args) -> int {
|
||||
}
|
||||
|
||||
{
|
||||
struct fuse_args fa = FUSE_ARGS_INIT(static_cast<int>(fuse_argv.size()),
|
||||
(char **)&fuse_argv[0]);
|
||||
struct fuse_args fa = FUSE_ARGS_INIT(
|
||||
static_cast<int>(fuse_argv.size()),
|
||||
reinterpret_cast<char **>(const_cast<char **>(fuse_argv.data())));
|
||||
|
||||
char *mount_location{nullptr};
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
@@ -374,8 +385,10 @@ auto fuse_base::mount(std::vector<std::string> args) -> int {
|
||||
#if FUSE_USE_VERSION < 30
|
||||
umask(0);
|
||||
#endif
|
||||
ret = fuse_main(static_cast<int>(fuse_argv.size()), (char **)&fuse_argv[0],
|
||||
&fuse_ops_, this);
|
||||
ret = fuse_main(
|
||||
static_cast<int>(fuse_argv.size()),
|
||||
reinterpret_cast<char **>(const_cast<char **>(fuse_argv.data())),
|
||||
&fuse_ops_, this);
|
||||
notify_fuse_main_exit(ret);
|
||||
}
|
||||
|
||||
|
@@ -204,7 +204,7 @@ auto fuse_drive::create_impl(std::string api_path, mode_t mode,
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
void fuse_drive::destroy_impl(void * /* ptr */) {
|
||||
void fuse_drive::destroy_impl(void *ptr) {
|
||||
event_system::instance().raise<drive_unmount_pending>(get_mount_location());
|
||||
|
||||
remote_server_.reset();
|
||||
@@ -242,6 +242,8 @@ void fuse_drive::destroy_impl(void * /* ptr */) {
|
||||
if (not lock_data_.set_mount_state(false, "", -1)) {
|
||||
utils::error::raise_error(__FUNCTION__, "failed to set mount state");
|
||||
}
|
||||
|
||||
fuse_base::destroy_impl(ptr);
|
||||
}
|
||||
|
||||
auto fuse_drive::fallocate_impl(std::string /*api_path*/, int mode,
|
||||
@@ -519,7 +521,11 @@ auto fuse_drive::init_impl(struct fuse_conn_info *conn, struct fuse_config *cfg)
|
||||
#else
|
||||
void *fuse_drive::init_impl(struct fuse_conn_info *conn) {
|
||||
#endif
|
||||
utils::file::change_to_process_directory();
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
auto *ret = fuse_drive_base::init_impl(conn, cfg);
|
||||
#else
|
||||
auto *ret = fuse_drive_base::init_impl(conn);
|
||||
#endif
|
||||
|
||||
if (console_enabled_) {
|
||||
console_consumer_ = std::make_unique<console_consumer>();
|
||||
@@ -573,11 +579,7 @@ void *fuse_drive::init_impl(struct fuse_conn_info *conn) {
|
||||
fuse_exit(fuse_get_context()->fuse);
|
||||
}
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
return fuse_drive_base::init_impl(conn, cfg);
|
||||
#else
|
||||
return fuse_drive_base::init_impl(conn);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto fuse_drive::is_processing(const std::string &api_path) const -> bool {
|
||||
@@ -661,13 +663,6 @@ auto fuse_drive::opendir_impl(std::string api_path,
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
void fuse_drive::populate_stat(const directory_item &dir_item,
|
||||
struct stat &st) const {
|
||||
fuse_drive_base::populate_stat(dir_item.api_path, dir_item.size,
|
||||
dir_item.meta, dir_item.directory, provider_,
|
||||
&st);
|
||||
}
|
||||
|
||||
auto fuse_drive::read_impl(std::string api_path, char *buffer, size_t read_size,
|
||||
off_t read_offset, struct fuse_file_info *file_info,
|
||||
std::size_t &bytes_read) -> api_error {
|
||||
@@ -910,8 +905,8 @@ auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
|
||||
#endif
|
||||
const auto attribute_name_size = strlen(attribute_name.c_str()) + 1U;
|
||||
if (size >= attribute_name_size) {
|
||||
strncpy(&buffer[required_size], attribute_name.c_str(),
|
||||
attribute_name_size);
|
||||
std::memcpy(&buffer[required_size], attribute_name.data(),
|
||||
attribute_name_size);
|
||||
size -= attribute_name_size;
|
||||
} else {
|
||||
res = api_error::xattr_buffer_small;
|
||||
@@ -1203,11 +1198,10 @@ auto fuse_drive::statfs_impl(std::string /*api_path*/, struct statvfs *stbuf)
|
||||
|
||||
const auto total_bytes = provider_.get_total_drive_space();
|
||||
const auto total_used = provider_.get_used_drive_space();
|
||||
const auto used_blocks = utils::divide_with_ceiling(
|
||||
total_used, static_cast<std::uint64_t>(stbuf->f_frsize));
|
||||
const auto used_blocks =
|
||||
utils::divide_with_ceiling(total_used, stbuf->f_frsize);
|
||||
stbuf->f_files = 4294967295;
|
||||
stbuf->f_blocks = utils::divide_with_ceiling(
|
||||
total_bytes, static_cast<std::uint64_t>(stbuf->f_frsize));
|
||||
stbuf->f_blocks = utils::divide_with_ceiling(total_bytes, stbuf->f_frsize);
|
||||
stbuf->f_bavail = stbuf->f_bfree =
|
||||
stbuf->f_blocks == 0U ? 0 : (stbuf->f_blocks - used_blocks);
|
||||
stbuf->f_ffree = stbuf->f_favail =
|
||||
|
@@ -232,9 +232,9 @@ auto fuse_drive_base::get_mode_from_meta(const api_meta_map &meta) -> mode_t {
|
||||
void fuse_drive_base::get_timespec_from_meta(const api_meta_map &meta,
|
||||
const std::string &name,
|
||||
struct timespec &ts) {
|
||||
const auto t = utils::string::to_uint64(meta.at(name));
|
||||
ts.tv_nsec = t % NANOS_PER_SECOND;
|
||||
ts.tv_sec = t / NANOS_PER_SECOND;
|
||||
const auto meta_time = utils::string::to_int64(meta.at(name));
|
||||
ts.tv_nsec = meta_time % NANOS_PER_SECOND;
|
||||
ts.tv_sec = meta_time / NANOS_PER_SECOND;
|
||||
}
|
||||
|
||||
auto fuse_drive_base::get_uid_from_meta(const api_meta_map &meta) -> uid_t {
|
||||
@@ -305,21 +305,22 @@ void fuse_drive_base::populate_stat(const std::string &api_path,
|
||||
i_provider &provider, struct stat *st) {
|
||||
memset(st, 0, sizeof(struct stat));
|
||||
st->st_nlink =
|
||||
(directory
|
||||
? 2 + (size_or_count ? size_or_count
|
||||
: provider.get_directory_item_count(api_path))
|
||||
: 1);
|
||||
(directory ? 2 + (size_or_count == 0U
|
||||
? provider.get_directory_item_count(api_path)
|
||||
: size_or_count)
|
||||
: 1);
|
||||
if (directory) {
|
||||
st->st_blocks = 0;
|
||||
} else {
|
||||
st->st_size = size_or_count;
|
||||
static const auto block_size_stat = static_cast<std::uint64_t>(512u);
|
||||
static const auto block_size = static_cast<std::uint64_t>(4096u);
|
||||
st->st_size = static_cast<off_t>(size_or_count);
|
||||
static const auto block_size_stat = static_cast<std::uint64_t>(512U);
|
||||
static const auto block_size = static_cast<std::uint64_t>(4096U);
|
||||
const auto size = utils::divide_with_ceiling(
|
||||
static_cast<std::uint64_t>(st->st_size), block_size) *
|
||||
block_size;
|
||||
st->st_blocks = std::max(block_size / block_size_stat,
|
||||
utils::divide_with_ceiling(size, block_size_stat));
|
||||
st->st_blocks = static_cast<blkcnt_t>(
|
||||
std::max(block_size / block_size_stat,
|
||||
utils::divide_with_ceiling(size, block_size_stat)));
|
||||
}
|
||||
st->st_gid = get_gid_from_meta(meta);
|
||||
st->st_mode = (directory ? S_IFDIR : S_IFREG) | get_mode_from_meta(meta);
|
||||
@@ -344,9 +345,9 @@ void fuse_drive_base::populate_stat(const std::string &api_path,
|
||||
void fuse_drive_base::set_timespec_from_meta(const api_meta_map &meta,
|
||||
const std::string &name,
|
||||
struct timespec &ts) {
|
||||
const auto t = utils::string::to_uint64(meta.at(name));
|
||||
ts.tv_nsec = t % NANOS_PER_SECOND;
|
||||
ts.tv_sec = t / NANOS_PER_SECOND;
|
||||
const auto meta_time = utils::string::to_int64(meta.at(name));
|
||||
ts.tv_nsec = meta_time % NANOS_PER_SECOND;
|
||||
ts.tv_sec = meta_time / NANOS_PER_SECOND;
|
||||
}
|
||||
} // namespace repertory
|
||||
|
||||
|
@@ -40,7 +40,7 @@ auto remote_client::fuse_access(const char *path, const std::int32_t &mask)
|
||||
request.encode(path);
|
||||
request.encode(mask);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ auto remote_client::fuse_chflags(const char *path, std::uint32_t flags)
|
||||
request.encode(path);
|
||||
request.encode(flags);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ auto remote_client::fuse_chmod(const char *path, const remote::file_mode &mode)
|
||||
request.encode(path);
|
||||
request.encode(mode);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -72,12 +72,12 @@ auto remote_client::fuse_chown(const char *path, const remote::user_id &uid,
|
||||
request.encode(uid);
|
||||
request.encode(gid);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
auto remote_client::fuse_destroy() -> packet::error_type {
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, service_flags);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ std::int32_t &mode, const remote::file_offset &offset, const remote::file_offset
|
||||
request.encode(length);
|
||||
request.encode(handle);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags {};
|
||||
return packetClient_.send(__FUNCTION__, request, service_flags);
|
||||
}*/
|
||||
|
||||
@@ -105,12 +105,12 @@ auto remote_client::fuse_fgetattr(const char *path, remote::stat &st,
|
||||
request.encode(gid_);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
auto ret =
|
||||
packet_client_.send(__FUNCTION__, request, response, service_flags);
|
||||
if (ret == 0) {
|
||||
if ((ret = response.decode(st)) == 0) {
|
||||
std::uint8_t d = 0u;
|
||||
std::uint8_t d{};
|
||||
if ((ret = response.decode(d)) == 0) {
|
||||
directory = static_cast<bool>(d);
|
||||
}
|
||||
@@ -129,7 +129,7 @@ auto remote_client::fuse_fsetattr_x(const char *path,
|
||||
request.encode(attr);
|
||||
request.encode(handle);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ auto remote_client::fuse_fsync(const char *path, const std::int32_t &datasync,
|
||||
request.encode(datasync);
|
||||
request.encode(handle);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ auto remote_client::fuse_ftruncate(const char *path,
|
||||
request.encode(size);
|
||||
request.encode(handle);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ auto remote_client::fuse_getattr(const char *path, remote::stat &st,
|
||||
request.encode(gid_);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
auto ret =
|
||||
packet_client_.send(__FUNCTION__, request, response, service_flags);
|
||||
if (ret == 0) {
|
||||
@@ -188,7 +188,7 @@ packet request; request.encode(path); request.encode(name);
|
||||
request.encode(size);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags {};
|
||||
if ((ret = packetClient_.send(__FUNCTION__, request, response,
|
||||
service_flags)) == 0) { remote::file_size size2; if ((ret =
|
||||
response.decode(size2)) == 0) { if (size2 >
|
||||
@@ -211,7 +211,7 @@ packet::error_type ret = 0; if (size > std::numeric_limits<std::size_t>::max())
|
||||
request.encode(position);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags {};
|
||||
if ((ret = packetClient_.send(__FUNCTION__, request, response,
|
||||
service_flags)) == 0) { remote::file_size size2; if ((ret =
|
||||
response.decode(size2)) == 0) { if (size2 >
|
||||
@@ -233,7 +233,7 @@ auto remote_client::fuse_getxtimes(const char *path,
|
||||
request.encode(path);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
auto ret =
|
||||
packet_client_.send(__FUNCTION__, request, response, service_flags);
|
||||
if (ret == 0) {
|
||||
@@ -245,7 +245,7 @@ auto remote_client::fuse_getxtimes(const char *path,
|
||||
}
|
||||
|
||||
auto remote_client::fuse_init() -> packet::error_type {
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, service_flags);
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ std::numeric_limits<std::size_t>::max()) { ret = -ERANGE; } else { packet
|
||||
request; request.encode(path); request.encode(size);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags {};
|
||||
if ((ret = packetClient_.send(__FUNCTION__, request, response,
|
||||
service_flags)) == 0) { remote::file_size size2; if ((ret =
|
||||
response.decode(size2)) == 0) { if (size2 >
|
||||
@@ -276,7 +276,7 @@ auto remote_client::fuse_mkdir(const char *path, const remote::file_mode &mode)
|
||||
request.encode(path);
|
||||
request.encode(mode);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ auto remote_client::fuse_opendir(const char *path, remote::file_handle &handle)
|
||||
request.encode(path);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
auto ret =
|
||||
packet_client_.send(__FUNCTION__, request, response, service_flags);
|
||||
if (ret == 0) {
|
||||
@@ -306,7 +306,7 @@ auto remote_client::fuse_create(const char *path, const remote::file_mode &mode,
|
||||
request.encode(flags);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
auto ret =
|
||||
packet_client_.send(__FUNCTION__, request, response, service_flags);
|
||||
if (ret == 0) {
|
||||
@@ -324,7 +324,7 @@ auto remote_client::fuse_open(const char *path, const remote::open_flags &flags,
|
||||
request.encode(flags);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
auto ret =
|
||||
packet_client_.send(__FUNCTION__, request, response, service_flags);
|
||||
if (ret == 0) {
|
||||
@@ -346,11 +346,11 @@ auto remote_client::fuse_read(const char *path, char *buffer,
|
||||
request.encode(handle);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
auto ret =
|
||||
packet_client_.send(__FUNCTION__, request, response, service_flags);
|
||||
if (ret > 0) {
|
||||
memcpy(buffer, response.current_pointer(), ret);
|
||||
memcpy(buffer, response.current_pointer(), static_cast<std::size_t>(ret));
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -362,7 +362,7 @@ auto remote_client::fuse_rename(const char *from, const char *to)
|
||||
request.encode(from);
|
||||
request.encode(to);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -382,7 +382,7 @@ auto remote_client::fuse_write(const char *path, const char *buffer,
|
||||
request.encode(write_offset);
|
||||
request.encode(handle);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -402,7 +402,7 @@ auto remote_client::fuse_write_base64(const char *path, const char *buffer,
|
||||
request.encode(write_offset);
|
||||
request.encode(handle);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -416,7 +416,7 @@ auto remote_client::fuse_readdir(const char *path,
|
||||
request.encode(handle);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
auto ret =
|
||||
packet_client_.send(__FUNCTION__, request, response, service_flags);
|
||||
if (ret == 0) {
|
||||
@@ -433,7 +433,7 @@ auto remote_client::fuse_release(const char *path,
|
||||
request.encode(path);
|
||||
request.encode(handle);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -444,7 +444,7 @@ auto remote_client::fuse_releasedir(const char *path,
|
||||
request.encode(path);
|
||||
request.encode(handle);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -452,7 +452,7 @@ auto remote_client::fuse_releasedir(const char *path,
|
||||
char *name) override { packet request; request.encode(path);
|
||||
request.Encode(name);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags {};
|
||||
return packetClient_.send(__FUNCTION__, request, service_flags);
|
||||
}*/
|
||||
|
||||
@@ -460,7 +460,7 @@ auto remote_client::fuse_rmdir(const char *path) -> packet::error_type {
|
||||
packet request;
|
||||
request.encode(path);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -470,7 +470,7 @@ auto remote_client::fuse_setattr_x(const char *path, remote::setattr_x &attr)
|
||||
request.encode(path);
|
||||
request.encode(attr);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ auto remote_client::fuse_setbkuptime(const char *path,
|
||||
request.encode(path);
|
||||
request.encode(bkuptime);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -492,7 +492,7 @@ auto remote_client::fuse_setchgtime(const char *path,
|
||||
request.encode(path);
|
||||
request.encode(chgtime);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -503,7 +503,7 @@ auto remote_client::fuse_setcrtime(const char *path,
|
||||
request.encode(path);
|
||||
request.encode(crtime);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -511,7 +511,7 @@ auto remote_client::fuse_setvolname(const char *volname) -> packet::error_type {
|
||||
packet request;
|
||||
request.encode(volname);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -523,7 +523,7 @@ request; request.encode(path); request.encode(name); request.encode(size);
|
||||
request.encode(value, static_cast<std::size_t>(size));
|
||||
request.encode(flags);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags {};
|
||||
ret = packetClient_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -538,7 +538,7 @@ packet request; request.encode(path); request.Encode(name);
|
||||
request.Encode(size); request.encode(value, static_cast<std::size_t>(size));
|
||||
request.encode(flags); request.encode(position);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags {};
|
||||
ret = packetClient_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -552,7 +552,7 @@ auto remote_client::fuse_statfs(const char *path, std::uint64_t frsize,
|
||||
request.encode(frsize);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
auto ret =
|
||||
packet_client_.send(__FUNCTION__, request, response, service_flags);
|
||||
if (ret == 0) {
|
||||
@@ -569,7 +569,7 @@ auto remote_client::fuse_statfs_x(const char *path, std::uint64_t bsize,
|
||||
request.encode(bsize);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
auto ret =
|
||||
packet_client_.send(__FUNCTION__, request, response, service_flags);
|
||||
if (ret == 0) {
|
||||
@@ -586,7 +586,7 @@ auto remote_client::fuse_truncate(const char *path,
|
||||
request.encode(path);
|
||||
request.encode(size);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -594,7 +594,7 @@ auto remote_client::fuse_unlink(const char *path) -> packet::error_type {
|
||||
packet request;
|
||||
request.encode(path);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -607,7 +607,7 @@ auto remote_client::fuse_utimens(const char *path, const remote::file_time *tv,
|
||||
request.encode(op0);
|
||||
request.encode(op1);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
@@ -618,7 +618,7 @@ auto remote_client::json_create_directory_snapshot(const std::string &path,
|
||||
request.encode(path);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
auto ret =
|
||||
packet_client_.send(__FUNCTION__, request, response, service_flags);
|
||||
if (ret == 0) {
|
||||
@@ -637,7 +637,7 @@ auto remote_client::json_read_directory_snapshot(
|
||||
request.encode(page);
|
||||
|
||||
packet response;
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
auto ret =
|
||||
packet_client_.send(__FUNCTION__, request, response, service_flags);
|
||||
if (ret == 0) {
|
||||
@@ -654,7 +654,7 @@ auto remote_client::json_release_directory_snapshot(
|
||||
request.encode(path);
|
||||
request.encode(handle);
|
||||
|
||||
std::uint32_t service_flags = 0u;
|
||||
std::uint32_t service_flags{};
|
||||
return packet_client_.send(__FUNCTION__, request, service_flags);
|
||||
}
|
||||
|
||||
|
@@ -54,7 +54,7 @@ api_error remote_fuse_drive::chflags_impl(std::string api_path,
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
auto remote_fuse_drive::chmod_impl(std::string api_path, mode_t mode,
|
||||
struct fuse_file_info * /*fi*/)
|
||||
struct fuse_file_info * /*f_info*/)
|
||||
-> api_error {
|
||||
#else
|
||||
auto remote_fuse_drive::chmod_impl(std::string api_path, mode_t mode)
|
||||
@@ -66,7 +66,7 @@ auto remote_fuse_drive::chmod_impl(std::string api_path, mode_t mode)
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
auto remote_fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid,
|
||||
struct fuse_file_info * /*fi*/)
|
||||
struct fuse_file_info * /*f_info*/)
|
||||
-> api_error {
|
||||
#else
|
||||
auto remote_fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid)
|
||||
@@ -77,14 +77,15 @@ auto remote_fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid)
|
||||
}
|
||||
|
||||
auto remote_fuse_drive::create_impl(std::string api_path, mode_t mode,
|
||||
struct fuse_file_info *fi) -> api_error {
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error {
|
||||
return utils::to_api_error(remote_instance_->fuse_create(
|
||||
api_path.c_str(), static_cast<remote::file_mode>(mode),
|
||||
remote::create_open_flags(static_cast<std::uint32_t>(fi->flags)),
|
||||
fi->fh));
|
||||
remote::create_open_flags(static_cast<std::uint32_t>(f_info->flags)),
|
||||
f_info->fh));
|
||||
}
|
||||
|
||||
void remote_fuse_drive::destroy_impl(void * /*ptr*/) {
|
||||
void remote_fuse_drive::destroy_impl(void *ptr) {
|
||||
event_system::instance().raise<drive_unmount_pending>(get_mount_location());
|
||||
|
||||
if (server_) {
|
||||
@@ -107,17 +108,21 @@ void remote_fuse_drive::destroy_impl(void * /*ptr*/) {
|
||||
}
|
||||
|
||||
event_system::instance().raise<drive_unmounted>(get_mount_location());
|
||||
|
||||
fuse_base::destroy_impl(ptr);
|
||||
}
|
||||
|
||||
auto remote_fuse_drive::fgetattr_impl(std::string api_path, struct stat *st,
|
||||
struct fuse_file_info *fi) -> api_error {
|
||||
remote::stat r{};
|
||||
auto remote_fuse_drive::fgetattr_impl(std::string api_path,
|
||||
struct stat *unix_st,
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error {
|
||||
remote::stat r_stat{};
|
||||
auto directory = false;
|
||||
|
||||
const auto res =
|
||||
remote_instance_->fuse_fgetattr(api_path.c_str(), r, directory, fi->fh);
|
||||
const auto res = remote_instance_->fuse_fgetattr(api_path.c_str(), r_stat,
|
||||
directory, f_info->fh);
|
||||
if (res == 0) {
|
||||
populate_stat(r, directory, *st);
|
||||
populate_stat(r_stat, directory, *unix_st);
|
||||
}
|
||||
|
||||
return utils::to_api_error(res);
|
||||
@@ -126,7 +131,7 @@ auto remote_fuse_drive::fgetattr_impl(std::string api_path, struct stat *st,
|
||||
#ifdef __APPLE__
|
||||
api_error remote_fuse_drive::fsetattr_x_impl(std::string api_path,
|
||||
struct setattr_x *attr,
|
||||
struct fuse_file_info *fi) {
|
||||
struct fuse_file_info *f_info) {
|
||||
remote::setattr_x attributes{};
|
||||
attributes.valid = attr->valid;
|
||||
attributes.mode = attr->mode;
|
||||
@@ -144,41 +149,42 @@ api_error remote_fuse_drive::fsetattr_x_impl(std::string api_path,
|
||||
attributes.bkuptime =
|
||||
((attr->bkuptime.tv_sec * NANOS_PER_SECOND) + attr->bkuptime.tv_nsec);
|
||||
attributes.flags = attr->flags;
|
||||
return utils::to_api_error(
|
||||
remote_instance_->fuse_fsetattr_x(api_path.c_str(), attributes, fi->fh));
|
||||
return utils::to_api_error(remote_instance_->fuse_fsetattr_x(
|
||||
api_path.c_str(), attributes, f_info->fh));
|
||||
}
|
||||
#endif
|
||||
|
||||
auto remote_fuse_drive::fsync_impl(std::string api_path, int datasync,
|
||||
struct fuse_file_info *fi) -> api_error {
|
||||
struct fuse_file_info *f_info) -> api_error {
|
||||
|
||||
return utils::to_api_error(
|
||||
remote_instance_->fuse_fsync(api_path.c_str(), datasync, fi->fh));
|
||||
remote_instance_->fuse_fsync(api_path.c_str(), datasync, f_info->fh));
|
||||
}
|
||||
|
||||
#if FUSE_USE_VERSION < 30
|
||||
auto remote_fuse_drive::ftruncate_impl(std::string api_path, off_t size,
|
||||
struct fuse_file_info *fi) -> api_error {
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error {
|
||||
return utils::to_api_error(
|
||||
remote_instance_->fuse_ftruncate(api_path.c_str(), size, fi->fh));
|
||||
remote_instance_->fuse_ftruncate(api_path.c_str(), size, f_info->fh));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *st,
|
||||
struct fuse_file_info * /*fi*/)
|
||||
auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *unix_st,
|
||||
struct fuse_file_info * /*f_info*/)
|
||||
-> api_error {
|
||||
#else
|
||||
auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *st)
|
||||
auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *unix_st)
|
||||
-> api_error {
|
||||
#endif
|
||||
bool directory = false;
|
||||
remote::stat r{};
|
||||
remote::stat r_stat{};
|
||||
|
||||
const auto res =
|
||||
remote_instance_->fuse_getattr(api_path.c_str(), r, directory);
|
||||
remote_instance_->fuse_getattr(api_path.c_str(), r_stat, directory);
|
||||
if (res == 0) {
|
||||
populate_stat(r, directory, *st);
|
||||
populate_stat(r_stat, directory, *unix_st);
|
||||
}
|
||||
|
||||
return utils::to_api_error(res);
|
||||
@@ -214,7 +220,12 @@ auto remote_fuse_drive::init_impl(struct fuse_conn_info *conn,
|
||||
#else
|
||||
auto remote_fuse_drive::init_impl(struct fuse_conn_info *conn) -> void * {
|
||||
#endif
|
||||
utils::file::change_to_process_directory();
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
auto *ret = fuse_base::init_impl(conn, cfg);
|
||||
#else
|
||||
auto *ret = fuse_base::init_impl(conn);
|
||||
#endif
|
||||
|
||||
was_mounted_ = true;
|
||||
|
||||
if (console_enabled_) {
|
||||
@@ -241,11 +252,7 @@ auto remote_fuse_drive::init_impl(struct fuse_conn_info *conn) -> void * {
|
||||
event_system::instance().raise<drive_mounted>(get_mount_location());
|
||||
}
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
return fuse_base::init_impl(conn, cfg);
|
||||
#else
|
||||
return fuse_base::init_impl(conn);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto remote_fuse_drive::mkdir_impl(std::string api_path, mode_t mode)
|
||||
@@ -264,76 +271,88 @@ void remote_fuse_drive::notify_fuse_main_exit(int &ret) {
|
||||
}
|
||||
|
||||
auto remote_fuse_drive::open_impl(std::string api_path,
|
||||
struct fuse_file_info *fi) -> api_error {
|
||||
struct fuse_file_info *f_info) -> api_error {
|
||||
return utils::to_api_error(remote_instance_->fuse_open(
|
||||
api_path.c_str(), remote::create_open_flags(fi->flags), fi->fh));
|
||||
api_path.c_str(),
|
||||
remote::create_open_flags(static_cast<std::uint32_t>(f_info->flags)),
|
||||
f_info->fh));
|
||||
}
|
||||
|
||||
auto remote_fuse_drive::opendir_impl(std::string api_path,
|
||||
struct fuse_file_info *fi) -> api_error {
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error {
|
||||
|
||||
return utils::to_api_error(
|
||||
remote_instance_->fuse_opendir(api_path.c_str(), fi->fh));
|
||||
remote_instance_->fuse_opendir(api_path.c_str(), f_info->fh));
|
||||
}
|
||||
|
||||
void remote_fuse_drive::populate_stat(const remote::stat &r, bool directory,
|
||||
struct stat &st) {
|
||||
memset(&st, 0, sizeof(struct stat));
|
||||
void remote_fuse_drive::populate_stat(const remote::stat &r_stat,
|
||||
bool directory, struct stat &unix_st) {
|
||||
memset(&unix_st, 0, sizeof(struct stat));
|
||||
|
||||
#ifdef __APPLE__
|
||||
st.st_blksize = 0;
|
||||
unix_st.st_blksize = 0;
|
||||
|
||||
st.st_atimespec.tv_nsec = r.st_atimespec % NANOS_PER_SECOND;
|
||||
st.st_atimespec.tv_sec = r.st_atimespec / NANOS_PER_SECOND;
|
||||
unix_st.st_atimespec.tv_nsec = r_stat.st_atimespec % NANOS_PER_SECOND;
|
||||
unix_st.st_atimespec.tv_sec = r_stat.st_atimespec / NANOS_PER_SECOND;
|
||||
|
||||
st.st_birthtimespec.tv_nsec = r.st_birthtimespec % NANOS_PER_SECOND;
|
||||
st.st_birthtimespec.tv_sec = r.st_birthtimespec / NANOS_PER_SECOND;
|
||||
unix_st.st_birthtimespec.tv_nsec = r_stat.st_birthtimespec % NANOS_PER_SECOND;
|
||||
unix_st.st_birthtimespec.tv_sec = r_stat.st_birthtimespec / NANOS_PER_SECOND;
|
||||
|
||||
st.st_ctimespec.tv_nsec = r.st_ctimespec % NANOS_PER_SECOND;
|
||||
st.st_ctimespec.tv_sec = r.st_ctimespec / NANOS_PER_SECOND;
|
||||
unix_st.st_ctimespec.tv_nsec = r_stat.st_ctimespec % NANOS_PER_SECOND;
|
||||
unix_st.st_ctimespec.tv_sec = r_stat.st_ctimespec / NANOS_PER_SECOND;
|
||||
|
||||
st.st_mtimespec.tv_nsec = r.st_mtimespec % NANOS_PER_SECOND;
|
||||
st.st_mtimespec.tv_sec = r.st_mtimespec / NANOS_PER_SECOND;
|
||||
unix_st.st_mtimespec.tv_nsec = r_stat.st_mtimespec % NANOS_PER_SECOND;
|
||||
unix_st.st_mtimespec.tv_sec = r_stat.st_mtimespec / NANOS_PER_SECOND;
|
||||
|
||||
st.st_flags = r.st_flags;
|
||||
unix_st.st_flags = r_stat.st_flags;
|
||||
#else
|
||||
st.st_blksize = 4096;
|
||||
unix_st.st_blksize = 4096;
|
||||
|
||||
st.st_atim.tv_nsec = r.st_atimespec % NANOS_PER_SECOND;
|
||||
st.st_atim.tv_sec = r.st_atimespec / NANOS_PER_SECOND;
|
||||
unix_st.st_atim.tv_nsec =
|
||||
static_cast<suseconds_t>(r_stat.st_atimespec % NANOS_PER_SECOND);
|
||||
unix_st.st_atim.tv_sec =
|
||||
static_cast<suseconds_t>(r_stat.st_atimespec / NANOS_PER_SECOND);
|
||||
|
||||
st.st_ctim.tv_nsec = r.st_ctimespec % NANOS_PER_SECOND;
|
||||
st.st_ctim.tv_sec = r.st_ctimespec / NANOS_PER_SECOND;
|
||||
unix_st.st_ctim.tv_nsec =
|
||||
static_cast<suseconds_t>(r_stat.st_ctimespec % NANOS_PER_SECOND);
|
||||
unix_st.st_ctim.tv_sec =
|
||||
static_cast<suseconds_t>(r_stat.st_ctimespec / NANOS_PER_SECOND);
|
||||
|
||||
st.st_mtim.tv_nsec = r.st_mtimespec % NANOS_PER_SECOND;
|
||||
st.st_mtim.tv_sec = r.st_mtimespec / NANOS_PER_SECOND;
|
||||
unix_st.st_mtim.tv_nsec =
|
||||
static_cast<suseconds_t>(r_stat.st_mtimespec % NANOS_PER_SECOND);
|
||||
unix_st.st_mtim.tv_sec =
|
||||
static_cast<suseconds_t>(r_stat.st_mtimespec / NANOS_PER_SECOND);
|
||||
#endif
|
||||
if (not directory) {
|
||||
const auto block_size_stat = static_cast<std::uint64_t>(512u);
|
||||
const auto block_size = static_cast<std::uint64_t>(4096u);
|
||||
const auto size = utils::divide_with_ceiling(
|
||||
static_cast<std::uint64_t>(st.st_size), block_size) *
|
||||
block_size;
|
||||
st.st_blocks = std::max(block_size / block_size_stat,
|
||||
utils::divide_with_ceiling(size, block_size_stat));
|
||||
const auto block_size_stat = static_cast<std::uint64_t>(512U);
|
||||
const auto block_size = static_cast<std::uint64_t>(4096U);
|
||||
const auto size =
|
||||
utils::divide_with_ceiling(static_cast<std::uint64_t>(unix_st.st_size),
|
||||
block_size) *
|
||||
block_size;
|
||||
unix_st.st_blocks = static_cast<blkcnt_t>(
|
||||
std::max(block_size / block_size_stat,
|
||||
utils::divide_with_ceiling(size, block_size_stat)));
|
||||
}
|
||||
|
||||
st.st_gid = r.st_gid;
|
||||
st.st_mode = (directory ? S_IFDIR : S_IFREG) | r.st_mode;
|
||||
unix_st.st_gid = r_stat.st_gid;
|
||||
unix_st.st_mode = (directory ? S_IFDIR : S_IFREG) | r_stat.st_mode;
|
||||
|
||||
st.st_nlink = r.st_nlink;
|
||||
st.st_size = r.st_size;
|
||||
st.st_uid = r.st_uid;
|
||||
unix_st.st_nlink = r_stat.st_nlink;
|
||||
unix_st.st_size = static_cast<off_t>(r_stat.st_size);
|
||||
unix_st.st_uid = r_stat.st_uid;
|
||||
}
|
||||
|
||||
auto remote_fuse_drive::read_impl(std::string api_path, char *buffer,
|
||||
size_t read_size, off_t read_offset,
|
||||
struct fuse_file_info *fi,
|
||||
struct fuse_file_info *f_info,
|
||||
std::size_t &bytes_read) -> api_error {
|
||||
auto res = remote_instance_->fuse_read(api_path.c_str(), buffer, read_size,
|
||||
read_offset, fi->fh);
|
||||
auto res = remote_instance_->fuse_read(
|
||||
api_path.c_str(), buffer, read_size,
|
||||
static_cast<remote::file_offset>(read_offset), f_info->fh);
|
||||
if (res >= 0) {
|
||||
bytes_read = res;
|
||||
bytes_read = static_cast<size_t>(res);
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
@@ -343,19 +362,22 @@ auto remote_fuse_drive::read_impl(std::string api_path, char *buffer,
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
auto remote_fuse_drive::readdir_impl(std::string api_path, void *buf,
|
||||
fuse_fill_dir_t fuse_fill_dir,
|
||||
off_t offset, struct fuse_file_info *fi,
|
||||
off_t offset,
|
||||
struct fuse_file_info *f_info,
|
||||
fuse_readdir_flags /*flags*/)
|
||||
-> api_error {
|
||||
#else
|
||||
auto remote_fuse_drive::readdir_impl(std::string api_path, void *buf,
|
||||
fuse_fill_dir_t fuse_fill_dir,
|
||||
off_t offset, struct fuse_file_info *fi)
|
||||
off_t offset,
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error {
|
||||
#endif
|
||||
std::string item_path;
|
||||
int res = 0;
|
||||
while ((res = remote_instance_->fuse_readdir(api_path.c_str(), offset, fi->fh,
|
||||
item_path)) == 0) {
|
||||
while ((res = remote_instance_->fuse_readdir(
|
||||
api_path.c_str(), static_cast<remote::file_offset>(offset),
|
||||
f_info->fh, item_path)) == 0) {
|
||||
if ((item_path != ".") && (item_path != "..")) {
|
||||
item_path = utils::path::strip_to_file_name(item_path);
|
||||
}
|
||||
@@ -378,16 +400,17 @@ auto remote_fuse_drive::readdir_impl(std::string api_path, void *buf,
|
||||
}
|
||||
|
||||
auto remote_fuse_drive::release_impl(std::string api_path,
|
||||
struct fuse_file_info *fi) -> api_error {
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error {
|
||||
return utils::to_api_error(
|
||||
remote_instance_->fuse_release(api_path.c_str(), fi->fh));
|
||||
remote_instance_->fuse_release(api_path.c_str(), f_info->fh));
|
||||
}
|
||||
|
||||
auto remote_fuse_drive::releasedir_impl(std::string api_path,
|
||||
struct fuse_file_info *fi)
|
||||
struct fuse_file_info *f_info)
|
||||
-> api_error {
|
||||
return utils::to_api_error(
|
||||
remote_instance_->fuse_releasedir(api_path.c_str(), fi->fh));
|
||||
remote_instance_->fuse_releasedir(api_path.c_str(), f_info->fh));
|
||||
}
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
@@ -471,8 +494,8 @@ api_error remote_fuse_drive::statfs_x_impl(std::string api_path,
|
||||
stbuf->f_ffree = r.f_ffree;
|
||||
stbuf->f_files = r.f_files;
|
||||
stbuf->f_owner = getuid();
|
||||
strncpy(&stbuf->f_mntonname[0u], get_mount_location().c_str(), MNAMELEN);
|
||||
strncpy(&stbuf->f_mntfromname[0u], &r.f_mntfromname[0], MNAMELEN);
|
||||
strncpy(&stbuf->f_mntonname[0U], get_mount_location().c_str(), MNAMELEN);
|
||||
strncpy(&stbuf->f_mntfromname[0U], &r.f_mntfromname[0U], MNAMELEN);
|
||||
}
|
||||
} else {
|
||||
res = -errno;
|
||||
@@ -485,15 +508,16 @@ auto remote_fuse_drive::statfs_impl(std::string api_path, struct statvfs *stbuf)
|
||||
-> api_error {
|
||||
auto res = statvfs(config_.get_data_directory().c_str(), stbuf);
|
||||
if (res == 0) {
|
||||
remote::statfs r{};
|
||||
if ((res = remote_instance_->fuse_statfs(api_path.c_str(), stbuf->f_frsize,
|
||||
r)) == 0) {
|
||||
stbuf->f_blocks = r.f_blocks;
|
||||
stbuf->f_bavail = r.f_bavail;
|
||||
stbuf->f_bfree = r.f_bfree;
|
||||
stbuf->f_ffree = r.f_ffree;
|
||||
stbuf->f_favail = r.f_favail;
|
||||
stbuf->f_files = r.f_files;
|
||||
remote::statfs r_stat{};
|
||||
res = remote_instance_->fuse_statfs(api_path.c_str(), stbuf->f_frsize,
|
||||
r_stat);
|
||||
if (res == 0) {
|
||||
stbuf->f_blocks = r_stat.f_blocks;
|
||||
stbuf->f_bavail = r_stat.f_bavail;
|
||||
stbuf->f_bfree = r_stat.f_bfree;
|
||||
stbuf->f_ffree = r_stat.f_ffree;
|
||||
stbuf->f_favail = r_stat.f_favail;
|
||||
stbuf->f_files = r_stat.f_files;
|
||||
}
|
||||
} else {
|
||||
res = -errno;
|
||||
@@ -505,14 +529,14 @@ auto remote_fuse_drive::statfs_impl(std::string api_path, struct statvfs *stbuf)
|
||||
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
auto remote_fuse_drive::truncate_impl(std::string api_path, off_t size,
|
||||
struct fuse_file_info * /*fi*/)
|
||||
struct fuse_file_info * /*f_info*/)
|
||||
-> api_error {
|
||||
#else
|
||||
auto remote_fuse_drive::truncate_impl(std::string api_path, off_t size)
|
||||
-> api_error {
|
||||
#endif
|
||||
return utils::to_api_error(
|
||||
remote_instance_->fuse_truncate(api_path.c_str(), size));
|
||||
return utils::to_api_error(remote_instance_->fuse_truncate(
|
||||
api_path.c_str(), static_cast<remote::file_offset>(size)));
|
||||
}
|
||||
|
||||
auto remote_fuse_drive::unlink_impl(std::string api_path) -> api_error {
|
||||
@@ -522,31 +546,35 @@ auto remote_fuse_drive::unlink_impl(std::string api_path) -> api_error {
|
||||
#if FUSE_USE_VERSION >= 30
|
||||
auto remote_fuse_drive::utimens_impl(std::string api_path,
|
||||
const struct timespec tv[2],
|
||||
struct fuse_file_info * /*fi*/)
|
||||
struct fuse_file_info * /*f_info*/)
|
||||
-> api_error {
|
||||
#else
|
||||
auto remote_fuse_drive::utimens_impl(std::string api_path,
|
||||
const struct timespec tv[2]) -> api_error {
|
||||
#endif
|
||||
remote::file_time rtv[2u] = {0};
|
||||
if (tv) {
|
||||
rtv[0u] = tv[0u].tv_nsec + (tv[0u].tv_sec * NANOS_PER_SECOND);
|
||||
rtv[1u] = tv[1u].tv_nsec + (tv[1u].tv_sec * NANOS_PER_SECOND);
|
||||
remote::file_time rtv[2U] = {0};
|
||||
if (tv != nullptr) {
|
||||
rtv[0U] = static_cast<remote::file_time>(
|
||||
tv[0U].tv_nsec + (tv[0U].tv_sec * NANOS_PER_SECOND));
|
||||
rtv[1U] = static_cast<remote::file_time>(
|
||||
tv[1U].tv_nsec + (tv[1U].tv_sec * NANOS_PER_SECOND));
|
||||
}
|
||||
|
||||
return utils::to_api_error(remote_instance_->fuse_utimens(
|
||||
api_path.c_str(), rtv, tv ? tv[0u].tv_nsec : 0u,
|
||||
tv ? tv[1u].tv_nsec : 0u));
|
||||
api_path.c_str(), &rtv[0U],
|
||||
static_cast<std::uint64_t>(tv == nullptr ? 0 : tv[0U].tv_nsec),
|
||||
static_cast<std::uint64_t>(tv == nullptr ? 0 : tv[1U].tv_nsec)));
|
||||
}
|
||||
|
||||
auto remote_fuse_drive::write_impl(std::string api_path, const char *buffer,
|
||||
size_t write_size, off_t write_offset,
|
||||
struct fuse_file_info *fi,
|
||||
struct fuse_file_info *f_info,
|
||||
std::size_t &bytes_written) -> api_error {
|
||||
const auto res = remote_instance_->fuse_write(
|
||||
api_path.c_str(), buffer, write_size, write_offset, fi->fh);
|
||||
api_path.c_str(), buffer, write_size,
|
||||
static_cast<remote::file_offset>(write_offset), f_info->fh);
|
||||
if (res >= 0) {
|
||||
bytes_written = res;
|
||||
bytes_written = static_cast<std::size_t>(res);
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
|
@@ -157,14 +157,14 @@ void remote_server::populate_stat(const struct stat64 &st1, remote::stat &st) {
|
||||
#else
|
||||
st.st_flags = 0;
|
||||
|
||||
st.st_atimespec =
|
||||
st1.st_atim.tv_nsec + (st1.st_atim.tv_sec * NANOS_PER_SECOND);
|
||||
st.st_birthtimespec =
|
||||
st1.st_ctim.tv_nsec + (st1.st_ctim.tv_sec * NANOS_PER_SECOND);
|
||||
st.st_ctimespec =
|
||||
st1.st_ctim.tv_nsec + (st1.st_ctim.tv_sec * NANOS_PER_SECOND);
|
||||
st.st_mtimespec =
|
||||
st1.st_mtim.tv_nsec + (st1.st_mtim.tv_sec * NANOS_PER_SECOND);
|
||||
st.st_atimespec = static_cast<remote::file_time>(
|
||||
st1.st_atim.tv_nsec + (st1.st_atim.tv_sec * NANOS_PER_SECOND));
|
||||
st.st_birthtimespec = static_cast<remote::file_time>(
|
||||
st1.st_ctim.tv_nsec + (st1.st_ctim.tv_sec * NANOS_PER_SECOND));
|
||||
st.st_ctimespec = static_cast<remote::file_time>(
|
||||
st1.st_ctim.tv_nsec + (st1.st_ctim.tv_sec * NANOS_PER_SECOND));
|
||||
st.st_mtimespec = static_cast<remote::file_time>(
|
||||
st1.st_mtim.tv_nsec + (st1.st_mtim.tv_sec * NANOS_PER_SECOND));
|
||||
#endif
|
||||
st.st_blksize = static_cast<remote::block_size>(st1.st_blksize);
|
||||
st.st_blocks = static_cast<remote::block_count>(st1.st_blocks);
|
||||
@@ -337,8 +337,9 @@ auto remote_server::fuse_fsetattr_x(const char *path,
|
||||
if (res >= 0) {
|
||||
if (SETATTR_WANTS_SIZE(&attr)) {
|
||||
res = (handle == static_cast<std::uint64_t>(REPERTORY_INVALID_HANDLE))
|
||||
? truncate(file_path.c_str(), attr.size)
|
||||
: ftruncate(static_cast<native_handle>(handle), attr.size);
|
||||
? truncate(file_path.c_str(), static_cast<off_t>(attr.size))
|
||||
: ftruncate(static_cast<native_handle>(handle),
|
||||
static_cast<off_t>(attr.size));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,18 +366,20 @@ auto remote_server::fuse_fsetattr_x(const char *path,
|
||||
|
||||
if (res >= 0) {
|
||||
if (SETATTR_WANTS_MODTIME(&attr)) {
|
||||
struct timeval tv[2];
|
||||
struct timeval val[2];
|
||||
if (SETATTR_WANTS_ACCTIME(&attr)) {
|
||||
tv[0].tv_sec = attr.acctime / NANOS_PER_SECOND;
|
||||
tv[0].tv_usec = (attr.acctime % NANOS_PER_SECOND) / 1000;
|
||||
val[0U].tv_sec = static_cast<time_t>(attr.acctime / NANOS_PER_SECOND);
|
||||
val[0U].tv_usec =
|
||||
static_cast<time_t>((attr.acctime % NANOS_PER_SECOND) / 1000);
|
||||
} else {
|
||||
gettimeofday(&tv[0], nullptr);
|
||||
gettimeofday(&val[0U], nullptr);
|
||||
}
|
||||
|
||||
tv[1].tv_sec = attr.modtime / NANOS_PER_SECOND;
|
||||
tv[1].tv_usec = (attr.modtime % NANOS_PER_SECOND) / 1000;
|
||||
val[1U].tv_sec = static_cast<time_t>(attr.modtime / NANOS_PER_SECOND);
|
||||
val[1U].tv_usec =
|
||||
static_cast<time_t>((attr.modtime % NANOS_PER_SECOND) / 1000);
|
||||
|
||||
res = utimes(file_path.c_str(), tv);
|
||||
res = utimes(file_path.c_str(), &val[0U]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,7 +424,8 @@ auto remote_server::fuse_ftruncate(const char *path,
|
||||
|
||||
auto res = has_open_info(static_cast<native_handle>(handle), EBADF);
|
||||
if (res == 0) {
|
||||
res = ftruncate(static_cast<native_handle>(handle), size);
|
||||
res =
|
||||
ftruncate(static_cast<native_handle>(handle), static_cast<off_t>(size));
|
||||
}
|
||||
|
||||
auto ret = ((res < 0) ? -errno : 0);
|
||||
@@ -717,7 +721,8 @@ auto remote_server::fuse_rmdir(const char *path) -> packet::error_type {
|
||||
auto remote_server::fuse_setattr_x(const char *path, remote::setattr_x &attr)
|
||||
-> packet::error_type {
|
||||
const auto file_path = construct_path(path);
|
||||
auto ret = fuse_fsetattr_x(path, attr, REPERTORY_INVALID_HANDLE);
|
||||
auto ret = fuse_fsetattr_x(
|
||||
path, attr, static_cast<remote::file_handle>(REPERTORY_INVALID_HANDLE));
|
||||
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, file_path, ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -809,11 +814,9 @@ auto remote_server::fuse_statfs(const char *path, std::uint64_t frsize,
|
||||
|
||||
const auto total_bytes = drive_.get_total_drive_space();
|
||||
const auto total_used = drive_.get_used_drive_space();
|
||||
const auto used_blocks = utils::divide_with_ceiling(
|
||||
total_used, static_cast<std::uint64_t>(frsize));
|
||||
const auto used_blocks = utils::divide_with_ceiling(total_used, frsize);
|
||||
st.f_files = 4294967295;
|
||||
st.f_blocks = utils::divide_with_ceiling(total_bytes,
|
||||
static_cast<std::uint64_t>(frsize));
|
||||
st.f_blocks = utils::divide_with_ceiling(total_bytes, frsize);
|
||||
st.f_bavail = st.f_bfree = st.f_blocks ? (st.f_blocks - used_blocks) : 0;
|
||||
st.f_ffree = st.f_favail = st.f_files - drive_.get_total_item_count();
|
||||
|
||||
@@ -827,16 +830,15 @@ auto remote_server::fuse_statfs_x(const char *path, std::uint64_t bsize,
|
||||
|
||||
const auto total_bytes = drive_.get_total_drive_space();
|
||||
const auto total_used = drive_.get_used_drive_space();
|
||||
const auto used_blocks =
|
||||
utils::divide_with_ceiling(total_used, static_cast<std::uint64_t>(bsize));
|
||||
const auto used_blocks = utils::divide_with_ceiling(total_used, bsize);
|
||||
st.f_files = 4294967295;
|
||||
st.f_blocks = utils::divide_with_ceiling(total_bytes,
|
||||
static_cast<std::uint64_t>(bsize));
|
||||
st.f_blocks = utils::divide_with_ceiling(total_bytes, bsize);
|
||||
st.f_bavail = st.f_bfree = st.f_blocks ? (st.f_blocks - used_blocks) : 0;
|
||||
st.f_ffree = st.f_favail = st.f_files - drive_.get_total_item_count();
|
||||
strncpy(&st.f_mntfromname[0],
|
||||
std::memset(&st.f_mntfromname[0U], 0, sizeof(st.f_mntfromname));
|
||||
strncpy(&st.f_mntfromname[0U],
|
||||
(utils::create_volume_label(config_.get_provider_type())).c_str(),
|
||||
1024);
|
||||
sizeof(st.f_mntfromname) - 1U);
|
||||
|
||||
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, file_path, 0);
|
||||
return 0;
|
||||
@@ -846,7 +848,7 @@ auto remote_server::fuse_truncate(const char *path,
|
||||
const remote::file_offset &size)
|
||||
-> packet::error_type {
|
||||
const auto file_path = construct_path(path);
|
||||
const auto res = truncate(file_path.c_str(), size);
|
||||
const auto res = truncate(file_path.c_str(), static_cast<off_t>(size));
|
||||
auto ret = ((res < 0) ? -errno : 0);
|
||||
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, file_path, ret);
|
||||
return ret;
|
||||
@@ -867,22 +869,23 @@ auto remote_server::fuse_utimens(const char *path, const remote::file_time *tv,
|
||||
|
||||
struct timespec tv2[2] = {{0, 0}};
|
||||
if ((op0 == UTIME_NOW) || (op0 == UTIME_OMIT)) {
|
||||
tv2[0].tv_nsec = op0;
|
||||
tv2[0].tv_sec = 0;
|
||||
tv2[0U].tv_nsec = static_cast<time_t>(op0);
|
||||
tv2[0U].tv_sec = 0;
|
||||
} else {
|
||||
tv2[0].tv_nsec = tv[0] % NANOS_PER_SECOND;
|
||||
tv2[0].tv_sec = tv[0] / NANOS_PER_SECOND;
|
||||
tv2[0U].tv_nsec = static_cast<time_t>(tv[0U] % NANOS_PER_SECOND);
|
||||
tv2[0U].tv_sec = static_cast<time_t>(tv[0U] / NANOS_PER_SECOND);
|
||||
}
|
||||
|
||||
if ((op1 == UTIME_NOW) || (op1 == UTIME_OMIT)) {
|
||||
tv2[1].tv_nsec = op1;
|
||||
tv2[1].tv_sec = 0;
|
||||
tv2[1U].tv_nsec = static_cast<time_t>(op1);
|
||||
tv2[1U].tv_sec = 0;
|
||||
} else {
|
||||
tv2[1].tv_nsec = tv[1] % NANOS_PER_SECOND;
|
||||
tv2[1].tv_sec = tv[1] / NANOS_PER_SECOND;
|
||||
tv2[1U].tv_nsec = static_cast<time_t>(tv[1U] % NANOS_PER_SECOND);
|
||||
tv2[1U].tv_sec = static_cast<time_t>(tv[1U] / NANOS_PER_SECOND);
|
||||
}
|
||||
|
||||
const auto res = utimensat(0, file_path.c_str(), tv2, AT_SYMLINK_NOFOLLOW);
|
||||
const auto res =
|
||||
utimensat(0, file_path.c_str(), &tv2[0U], AT_SYMLINK_NOFOLLOW);
|
||||
auto ret = ((res < 0) ? -errno : 0);
|
||||
RAISE_REMOTE_FUSE_SERVER_EVENT(__FUNCTION__, file_path, ret);
|
||||
return ret;
|
||||
@@ -1025,10 +1028,10 @@ auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options,
|
||||
const auto file_path = construct_path(relative_path);
|
||||
exists = utils::file::is_file(file_path);
|
||||
|
||||
if (create_options & FILE_DIRECTORY_FILE) {
|
||||
if ((create_options & FILE_DIRECTORY_FILE) != 0U) {
|
||||
attributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||
} else {
|
||||
attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
|
||||
attributes &= static_cast<UINT32>(~FILE_ATTRIBUTE_DIRECTORY);
|
||||
}
|
||||
|
||||
if (not attributes) {
|
||||
@@ -1040,12 +1043,13 @@ auto remote_server::winfsp_create(PWSTR file_name, UINT32 create_options,
|
||||
utils::windows_create_to_unix(create_options, granted_access, flags, mode);
|
||||
|
||||
int res = 0;
|
||||
if (create_options & FILE_DIRECTORY_FILE) {
|
||||
if ((res = mkdir(file_path.c_str(), mode)) >= 0) {
|
||||
res = open(file_path.c_str(), flags);
|
||||
if ((create_options & FILE_DIRECTORY_FILE) != 0U) {
|
||||
res = mkdir(file_path.c_str(), mode);
|
||||
if (res >= 0) {
|
||||
res = open(file_path.c_str(), static_cast<int>(flags));
|
||||
}
|
||||
} else {
|
||||
res = open(file_path.c_str(), flags, mode);
|
||||
res = open(file_path.c_str(), static_cast<int>(flags), mode);
|
||||
}
|
||||
|
||||
if (res >= 0) {
|
||||
@@ -1155,9 +1159,9 @@ auto remote_server::winfsp_open(PWSTR file_name, UINT32 create_options,
|
||||
remote::file_mode mode{};
|
||||
std::uint32_t flags{};
|
||||
utils::windows_create_to_unix(create_options, granted_access, flags, mode);
|
||||
flags &= ~(O_CREAT);
|
||||
flags &= static_cast<std::uint32_t>(~O_CREAT);
|
||||
|
||||
auto res = open(file_path.c_str(), flags);
|
||||
auto res = open(file_path.c_str(), static_cast<int>(flags));
|
||||
if (res >= 0) {
|
||||
*file_desc = reinterpret_cast<PVOID>(res);
|
||||
set_open_info(res, open_info{0, "", nullptr, file_path});
|
||||
@@ -1209,8 +1213,9 @@ auto remote_server::winfsp_overwrite(PVOID file_desc, UINT32 attributes,
|
||||
}
|
||||
|
||||
if (set_attributes) {
|
||||
attributes &= ~(FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_NORMAL);
|
||||
if (not attributes) {
|
||||
attributes &= static_cast<UINT32>(
|
||||
~(FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_NORMAL));
|
||||
if (attributes == 0U) {
|
||||
attributes = FILE_ATTRIBUTE_NORMAL;
|
||||
}
|
||||
drive_.set_item_meta(api_path, META_ATTRIBUTES,
|
||||
@@ -1335,34 +1340,34 @@ auto remote_server::winfsp_set_basic_info(
|
||||
|
||||
const auto api_path = construct_api_path(file_path);
|
||||
api_meta_map meta;
|
||||
if (attributes) {
|
||||
if ((attributes & FILE_ATTRIBUTE_NORMAL) &&
|
||||
if (attributes != 0U) {
|
||||
if (((attributes & FILE_ATTRIBUTE_NORMAL) != 0U) &&
|
||||
(attributes != FILE_ATTRIBUTE_NORMAL)) {
|
||||
attributes &= ~(FILE_ATTRIBUTE_NORMAL);
|
||||
attributes &= static_cast<UINT32>(~(FILE_ATTRIBUTE_NORMAL));
|
||||
}
|
||||
drive_.set_item_meta(api_path, META_ATTRIBUTES,
|
||||
std::to_string(attributes));
|
||||
}
|
||||
|
||||
if (creation_time && (creation_time != 0xFFFFFFFFFFFFFFFF)) {
|
||||
if ((creation_time != 0U) && (creation_time != 0xFFFFFFFFFFFFFFFF)) {
|
||||
drive_.set_item_meta(
|
||||
api_path, META_CREATION,
|
||||
std::to_string(utils::windows_time_to_unix_time(creation_time)));
|
||||
}
|
||||
|
||||
if (last_access_time && (last_access_time != 0xFFFFFFFFFFFFFFFF)) {
|
||||
if ((last_access_time != 0U) && (last_access_time != 0xFFFFFFFFFFFFFFFF)) {
|
||||
drive_.set_item_meta(
|
||||
api_path, META_ACCESSED,
|
||||
std::to_string(utils::windows_time_to_unix_time(last_access_time)));
|
||||
}
|
||||
|
||||
if (last_write_time && (last_write_time != 0xFFFFFFFFFFFFFFFF)) {
|
||||
if ((last_write_time != 0U) && (last_write_time != 0xFFFFFFFFFFFFFFFF)) {
|
||||
drive_.set_item_meta(
|
||||
api_path, META_WRITTEN,
|
||||
std::to_string(utils::windows_time_to_unix_time(last_write_time)));
|
||||
}
|
||||
|
||||
if (change_time && (change_time != 0xFFFFFFFFFFFFFFFF)) {
|
||||
if ((change_time != 0U) && (change_time != 0xFFFFFFFFFFFFFFFF)) {
|
||||
drive_.set_item_meta(
|
||||
api_path, META_MODIFIED,
|
||||
std::to_string(utils::windows_time_to_unix_time(change_time)));
|
||||
@@ -1385,10 +1390,10 @@ auto remote_server::winfsp_set_file_size(PVOID file_desc, UINT64 new_size,
|
||||
auto ret =
|
||||
has_open_info(static_cast<native_handle>(handle), STATUS_INVALID_HANDLE);
|
||||
if (ret == STATUS_SUCCESS) {
|
||||
const auto res =
|
||||
set_allocation_size
|
||||
? 0
|
||||
: ftruncate(static_cast<native_handle>(handle), new_size);
|
||||
const auto res = set_allocation_size == 0U
|
||||
? ftruncate(static_cast<native_handle>(handle),
|
||||
static_cast<off_t>(new_size))
|
||||
: 0;
|
||||
ret = ((res < 0) ? utils::unix_error_to_windows(errno) : 0);
|
||||
if (ret == 0) {
|
||||
ret = populate_file_info(construct_api_path(get_open_file_path(
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -68,9 +68,8 @@ file_manager::open_file::open_file(
|
||||
fsi.source_path, not provider_.is_direct_only(), nf_));
|
||||
if (get_api_error() == api_error::success) {
|
||||
if (read_state.has_value()) {
|
||||
modified_ = true;
|
||||
mgr_.store_resume(*this);
|
||||
read_state_ = read_state.value();
|
||||
set_modified();
|
||||
} else if (fsi_.size > 0U) {
|
||||
read_state_.resize(static_cast<std::size_t>(utils::divide_with_ceiling(
|
||||
fsi_.size, chunk_size)),
|
||||
@@ -323,11 +322,7 @@ auto file_manager::open_file::native_operation(
|
||||
}
|
||||
|
||||
if (original_file_size != new_file_size) {
|
||||
if (not modified_) {
|
||||
mgr_.store_resume(*this);
|
||||
}
|
||||
modified_ = true;
|
||||
mgr_.remove_upload(get_api_path());
|
||||
set_modified();
|
||||
|
||||
fsi_.size = new_file_size;
|
||||
const auto now = std::to_string(utils::get_file_time_now());
|
||||
@@ -409,6 +404,10 @@ void file_manager::open_file::remove(std::uint64_t handle) {
|
||||
mgr_.queue_upload(*this);
|
||||
modified_ = false;
|
||||
}
|
||||
|
||||
if (removed_ && (get_open_file_count() == 0U)) {
|
||||
removed_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
auto file_manager::open_file::resize(std::uint64_t new_file_size) -> api_error {
|
||||
@@ -486,6 +485,18 @@ auto file_manager::open_file::close() -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
void file_manager::open_file::set_modified() {
|
||||
if (not modified_) {
|
||||
modified_ = true;
|
||||
mgr_.store_resume(*this);
|
||||
}
|
||||
|
||||
if (not removed_) {
|
||||
removed_ = true;
|
||||
mgr_.remove_upload(get_api_path());
|
||||
}
|
||||
}
|
||||
|
||||
void file_manager::open_file::update_background_reader(std::size_t read_chunk) {
|
||||
recur_mutex_lock reader_lock(file_mtx_);
|
||||
read_chunk_index_ = read_chunk;
|
||||
@@ -586,12 +597,7 @@ auto file_manager::open_file::write(std::uint64_t write_offset,
|
||||
return set_api_error(res);
|
||||
}
|
||||
|
||||
if (not modified_) {
|
||||
mgr_.store_resume(*this);
|
||||
}
|
||||
modified_ = true;
|
||||
mgr_.remove_upload(get_api_path());
|
||||
|
||||
set_modified();
|
||||
return api_error::success;
|
||||
}
|
||||
} // namespace repertory
|
||||
|
@@ -22,9 +22,9 @@
|
||||
#include "file_manager/file_manager.hpp"
|
||||
|
||||
namespace repertory {
|
||||
void file_manager::open_file_base::download::notify(const api_error &e) {
|
||||
void file_manager::open_file_base::download::notify(const api_error &err) {
|
||||
complete_ = true;
|
||||
error_ = e;
|
||||
error_ = err;
|
||||
unique_mutex_lock lock(mtx_);
|
||||
notify_.notify_all();
|
||||
}
|
||||
|
@@ -36,6 +36,6 @@ auto file_manager::open_file_base::io_item::get_result() -> api_error {
|
||||
}
|
||||
|
||||
notify_.wait(lock);
|
||||
return result_.value();
|
||||
return result_.value_or(api_error::error);
|
||||
}
|
||||
} // namespace repertory
|
||||
|
@@ -258,7 +258,8 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
|
||||
}
|
||||
|
||||
reset_timeout();
|
||||
if ((res = download_chunk(chunk)) == api_error::success) {
|
||||
res = download_chunk(chunk);
|
||||
if (res == api_error::success) {
|
||||
const auto to_read = std::min(
|
||||
static_cast<std::size_t>(chunk_size_ - read_offset), read_size);
|
||||
res = do_io([this, &buffer, &chunk, &data, read_offset,
|
||||
@@ -270,8 +271,10 @@ auto file_manager::ring_buffer_open_file::read(std::size_t read_size,
|
||||
? api_error::success
|
||||
: api_error::os_error;
|
||||
if (ret == api_error::success) {
|
||||
data.insert(data.end(), buffer.begin() + read_offset,
|
||||
buffer.begin() + read_offset + to_read);
|
||||
data.insert(data.end(),
|
||||
buffer.begin() + static_cast<std::int64_t>(read_offset),
|
||||
buffer.begin() +
|
||||
static_cast<std::int64_t>(read_offset + to_read));
|
||||
reset_timeout();
|
||||
}
|
||||
|
||||
|
@@ -27,10 +27,11 @@
|
||||
#include "utils/unix/unix_utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
using std::bind;
|
||||
|
||||
file_manager::upload::upload(filesystem_item fsi, i_provider &provider)
|
||||
: fsi_(fsi), provider_(provider) {
|
||||
thread_ =
|
||||
std::make_unique<std::thread>(std::bind(&upload::upload_thread, this));
|
||||
: fsi_(std::move(fsi)), provider_(provider) {
|
||||
thread_ = std::make_unique<std::thread>([this] { upload_thread(); });
|
||||
}
|
||||
|
||||
file_manager::upload::~upload() {
|
||||
|
@@ -166,13 +166,16 @@ auto lock_data::set_mount_state(bool active, const std::string &mount_location,
|
||||
}
|
||||
|
||||
auto lock_data::wait_for_lock(int fd, std::uint8_t retry_count) -> int {
|
||||
static constexpr const std::uint32_t max_sleep = 100U;
|
||||
|
||||
auto lock_status = EWOULDBLOCK;
|
||||
std::int16_t remain = retry_count * 100u;
|
||||
auto remain = static_cast<std::uint32_t>(retry_count * max_sleep);
|
||||
while ((remain > 0) && (lock_status == EWOULDBLOCK)) {
|
||||
if ((lock_status = flock(fd, LOCK_EX | LOCK_NB)) == -1) {
|
||||
if ((lock_status = errno) == EWOULDBLOCK) {
|
||||
const auto sleep_ms = utils::random_between(
|
||||
std::int16_t(1), std::min(remain, std::int16_t(100)));
|
||||
lock_status = flock(fd, LOCK_EX | LOCK_NB);
|
||||
if (lock_status == -1) {
|
||||
lock_status = errno;
|
||||
if (lock_status == EWOULDBLOCK) {
|
||||
auto sleep_ms = utils::random_between(1U, std::min(remain, max_sleep));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms));
|
||||
remain -= sleep_ms;
|
||||
}
|
||||
|
@@ -22,13 +22,15 @@
|
||||
#include "providers/base_provider.hpp"
|
||||
|
||||
#include "app_config.hpp"
|
||||
#include "database/db_common.hpp"
|
||||
#include "database/db_insert.hpp"
|
||||
#include "database/db_select.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "events/events.hpp"
|
||||
#include "file_manager/i_file_manager.hpp"
|
||||
#include "utils/file_utils.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
#include "utils/polling.hpp"
|
||||
#include "utils/rocksdb_utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
auto base_provider::create_api_file(std::string path, std::string key,
|
||||
@@ -202,7 +204,7 @@ auto base_provider::create_file(const std::string &api_path, api_meta_map &meta)
|
||||
stop_type stop_requested{false};
|
||||
res = upload_file(api_path, meta[META_SOURCE], stop_requested);
|
||||
if (res != api_error::success) {
|
||||
get_db()->Delete(rocksdb::WriteOptions(), api_path);
|
||||
db3_->remove_api_path(api_path);
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -224,26 +226,7 @@ auto base_provider::get_api_path_from_source(const std::string &source_path,
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
auto iterator = std::unique_ptr<rocksdb::Iterator>(
|
||||
db_->NewIterator(rocksdb::ReadOptions()));
|
||||
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
|
||||
std::string current_source_path{};
|
||||
if (get_item_meta(iterator->key().ToString(), META_SOURCE,
|
||||
current_source_path) != api_error::success) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current_source_path.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current_source_path == source_path) {
|
||||
api_path = iterator->key().ToString();
|
||||
return api_error::success;
|
||||
}
|
||||
}
|
||||
|
||||
return api_error::item_not_found;
|
||||
return db3_->get_api_path(source_path, api_path);
|
||||
}
|
||||
|
||||
auto base_provider::get_directory_items(const std::string &api_path,
|
||||
@@ -392,72 +375,21 @@ auto base_provider::get_filesystem_item_from_source_path(
|
||||
|
||||
auto base_provider::get_item_meta(const std::string &api_path,
|
||||
api_meta_map &meta) const -> api_error {
|
||||
std::string meta_value{};
|
||||
db_->Get(rocksdb::ReadOptions(), api_path, &meta_value);
|
||||
if (meta_value.empty()) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
try {
|
||||
meta = json::parse(meta_value).get<api_meta_map>();
|
||||
|
||||
return api_error::success;
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
|
||||
"failed to get item meta");
|
||||
}
|
||||
|
||||
return api_error::error;
|
||||
return db3_->get_item_meta(api_path, meta);
|
||||
}
|
||||
|
||||
auto base_provider::get_item_meta(const std::string &api_path,
|
||||
const std::string &key,
|
||||
std::string &value) const -> api_error {
|
||||
std::string meta_value{};
|
||||
db_->Get(rocksdb::ReadOptions(), api_path, &meta_value);
|
||||
if (meta_value.empty()) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
try {
|
||||
value = json::parse(meta_value)[key];
|
||||
return api_error::success;
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
|
||||
"failed to get item meta");
|
||||
}
|
||||
|
||||
return api_error::error;
|
||||
return db3_->get_item_meta(api_path, key, value);
|
||||
}
|
||||
|
||||
auto base_provider::get_pinned_files() const -> std::vector<std::string> {
|
||||
std::vector<std::string> ret{};
|
||||
|
||||
auto iterator = std::unique_ptr<rocksdb::Iterator>(
|
||||
db_->NewIterator(rocksdb::ReadOptions()));
|
||||
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
|
||||
std::string pinned{};
|
||||
if (get_item_meta(iterator->key().ToString(), META_PINNED, pinned) !=
|
||||
api_error::success) {
|
||||
continue;
|
||||
}
|
||||
if (pinned.empty() || not utils::string::to_bool(pinned)) {
|
||||
continue;
|
||||
}
|
||||
ret.emplace_back(iterator->key().ToString());
|
||||
}
|
||||
|
||||
return ret;
|
||||
return db3_->get_pinned_files();
|
||||
}
|
||||
|
||||
auto base_provider::get_total_item_count() const -> std::uint64_t {
|
||||
std::uint64_t ret{};
|
||||
auto iterator = std::unique_ptr<rocksdb::Iterator>(
|
||||
db_->NewIterator(rocksdb::ReadOptions()));
|
||||
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
|
||||
ret++;
|
||||
}
|
||||
return ret;
|
||||
return db3_->get_total_item_count();
|
||||
}
|
||||
|
||||
auto base_provider::get_used_drive_space() const -> std::uint64_t {
|
||||
@@ -499,31 +431,28 @@ void base_provider::remove_deleted_files() {
|
||||
}
|
||||
|
||||
std::vector<removed_item> removed_list{};
|
||||
auto iterator = std::unique_ptr<rocksdb::Iterator>(
|
||||
db_->NewIterator(rocksdb::ReadOptions()));
|
||||
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
|
||||
|
||||
for (const auto &api_path : db3_->get_api_path_list()) {
|
||||
api_meta_map meta{};
|
||||
if (get_item_meta(iterator->key().ToString(), meta) == api_error::success) {
|
||||
if (get_item_meta(api_path, meta) == api_error::success) {
|
||||
if (utils::string::to_bool(meta[META_DIRECTORY])) {
|
||||
bool exists{};
|
||||
if (is_directory(iterator->key().ToString(), exists) !=
|
||||
api_error::success) {
|
||||
if (is_directory(api_path, exists) != api_error::success) {
|
||||
continue;
|
||||
}
|
||||
if (not exists) {
|
||||
removed_list.emplace_back(
|
||||
removed_item{iterator->key().ToString(), true, ""});
|
||||
removed_list.emplace_back(removed_item{api_path, true, ""});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
bool exists{};
|
||||
if (is_file(iterator->key().ToString(), exists) != api_error::success) {
|
||||
if (is_file(api_path, exists) != api_error::success) {
|
||||
continue;
|
||||
}
|
||||
if (not exists) {
|
||||
removed_list.emplace_back(
|
||||
removed_item{iterator->key().ToString(), false, meta[META_SOURCE]});
|
||||
removed_item{api_path, false, meta[META_SOURCE]});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -560,7 +489,7 @@ void base_provider::remove_deleted_files() {
|
||||
}
|
||||
|
||||
if (fm_->evict_file(item.api_path)) {
|
||||
db_->Delete(rocksdb::WriteOptions(), item.api_path);
|
||||
db3_->remove_api_path(item.api_path);
|
||||
event_system::instance().raise<file_removed_externally>(
|
||||
item.api_path, item.source_path);
|
||||
}
|
||||
@@ -569,7 +498,7 @@ void base_provider::remove_deleted_files() {
|
||||
|
||||
for (const auto &item : removed_list) {
|
||||
if (item.directory) {
|
||||
db_->Delete(rocksdb::WriteOptions(), item.api_path);
|
||||
db3_->remove_api_path(item.api_path);
|
||||
event_system::instance().raise<directory_removed_externally>(
|
||||
item.api_path, item.source_path);
|
||||
}
|
||||
@@ -594,14 +523,7 @@ auto base_provider::remove_file(const std::string &api_path) -> api_error {
|
||||
¬ify_end]() -> api_error {
|
||||
api_meta_map meta{};
|
||||
auto res = get_item_meta(api_path, meta);
|
||||
|
||||
auto res2 = get_db()->Delete(rocksdb::WriteOptions(), api_path);
|
||||
if (not res2.ok()) {
|
||||
utils::error::raise_api_path_error(function_name, api_path, res2.code(),
|
||||
"failed to remove file");
|
||||
return notify_end(api_error::error);
|
||||
}
|
||||
|
||||
db3_->remove_api_path(api_path);
|
||||
return notify_end(res);
|
||||
};
|
||||
|
||||
@@ -658,101 +580,34 @@ auto base_provider::remove_directory(const std::string &api_path) -> api_error {
|
||||
return notify_end(res);
|
||||
}
|
||||
|
||||
auto status = get_db()->Delete(rocksdb::WriteOptions(), api_path);
|
||||
if (not status.ok()) {
|
||||
utils::error::raise_api_path_error(__FUNCTION__, api_path, status.code(),
|
||||
"failed to remove directory");
|
||||
return notify_end(api_error::error);
|
||||
}
|
||||
db3_->remove_api_path(api_path);
|
||||
|
||||
return notify_end(api_error::success);
|
||||
}
|
||||
|
||||
auto base_provider::remove_item_meta(const std::string &api_path,
|
||||
const std::string &key) -> api_error {
|
||||
api_meta_map meta{};
|
||||
auto res = get_item_meta(api_path, meta);
|
||||
if (res != api_error::success) {
|
||||
return res;
|
||||
}
|
||||
|
||||
meta.erase(key);
|
||||
|
||||
auto res2 = db_->Put(rocksdb::WriteOptions(), api_path, json(meta).dump());
|
||||
if (not res2.ok()) {
|
||||
utils::error::raise_api_path_error(__FUNCTION__, api_path, res2.code(),
|
||||
"failed to remove item meta");
|
||||
return api_error::error;
|
||||
}
|
||||
|
||||
return api_error::success;
|
||||
return db3_->remove_item_meta(api_path, key);
|
||||
}
|
||||
|
||||
auto base_provider::set_item_meta(const std::string &api_path,
|
||||
const std::string &key,
|
||||
const std::string &value) -> api_error {
|
||||
json meta_json{};
|
||||
std::string meta_value{};
|
||||
db_->Get(rocksdb::ReadOptions(), api_path, &meta_value);
|
||||
if (not meta_value.empty()) {
|
||||
try {
|
||||
meta_json = json::parse(meta_value);
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
|
||||
"failed to set item meta");
|
||||
return api_error::error;
|
||||
}
|
||||
}
|
||||
|
||||
meta_json[key] = value;
|
||||
|
||||
const auto res =
|
||||
db_->Put(rocksdb::WriteOptions(), api_path, meta_json.dump());
|
||||
if (not res.ok()) {
|
||||
utils::error::raise_api_path_error(__FUNCTION__, api_path, res.code(),
|
||||
"failed to set item meta");
|
||||
return api_error::error;
|
||||
}
|
||||
|
||||
return api_error::success;
|
||||
return db3_->set_item_meta(api_path, key, value);
|
||||
}
|
||||
|
||||
auto base_provider::set_item_meta(const std::string &api_path,
|
||||
const api_meta_map &meta) -> api_error {
|
||||
json meta_json{};
|
||||
std::string meta_value{};
|
||||
db_->Get(rocksdb::ReadOptions(), api_path, &meta_value);
|
||||
if (not meta_value.empty()) {
|
||||
try {
|
||||
meta_json = json::parse(meta_value);
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
|
||||
"failed to set item meta");
|
||||
return api_error::error;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &kv : meta) {
|
||||
meta_json[kv.first] = kv.second;
|
||||
}
|
||||
|
||||
const auto res =
|
||||
db_->Put(rocksdb::WriteOptions(), api_path, meta_json.dump());
|
||||
if (not res.ok()) {
|
||||
utils::error::raise_api_path_error(__FUNCTION__, api_path, res.code(),
|
||||
"failed to set item meta");
|
||||
return api_error::error;
|
||||
}
|
||||
|
||||
return api_error::success;
|
||||
return db3_->set_item_meta(api_path, meta);
|
||||
}
|
||||
|
||||
auto base_provider::start(api_item_added_callback api_item_added,
|
||||
i_file_manager *mgr) -> bool {
|
||||
utils::db::create_rocksdb(config_, DB_NAME, db_);
|
||||
|
||||
api_item_added_ = api_item_added;
|
||||
fm_ = mgr;
|
||||
|
||||
db3_ = std::make_unique<meta_db>(config_);
|
||||
|
||||
api_meta_map meta{};
|
||||
if (get_item_meta("/", meta) == api_error::item_not_found) {
|
||||
auto dir = create_api_file("/", "", 0U);
|
||||
@@ -789,7 +644,7 @@ auto base_provider::start(api_item_added_callback api_item_added,
|
||||
|
||||
void base_provider::stop() {
|
||||
polling::instance().remove_callback("check_deleted");
|
||||
db_.reset();
|
||||
db3_.reset();
|
||||
}
|
||||
|
||||
auto base_provider::upload_file(const std::string &api_path,
|
||||
|
@@ -21,6 +21,9 @@
|
||||
*/
|
||||
#include "providers/encrypt/encrypt_provider.hpp"
|
||||
|
||||
#include "database/db_common.hpp"
|
||||
#include "database/db_insert.hpp"
|
||||
#include "database/db_select.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "events/events.hpp"
|
||||
#include "platform/win32_platform.hpp"
|
||||
@@ -28,7 +31,37 @@
|
||||
#include "utils/encrypting_reader.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
#include "utils/polling.hpp"
|
||||
#include "utils/rocksdb_utils.hpp"
|
||||
|
||||
namespace {
|
||||
const std::string directory_table = "directory";
|
||||
const std::string file_table = "file";
|
||||
const std::string source_table = "source";
|
||||
const std::map<std::string, std::string> sql_create_tables = {
|
||||
{
|
||||
{directory_table},
|
||||
{"CREATE TABLE IF NOT EXISTS " + directory_table +
|
||||
"("
|
||||
"source_path TEXT PRIMARY KEY ASC, "
|
||||
"api_path TEXT"
|
||||
");"},
|
||||
},
|
||||
{
|
||||
{file_table},
|
||||
{"CREATE TABLE IF NOT EXISTS " + file_table +
|
||||
"("
|
||||
"source_path TEXT PRIMARY KEY ASC, "
|
||||
"data TEXT"
|
||||
");"},
|
||||
},
|
||||
{
|
||||
{source_table},
|
||||
{"CREATE TABLE IF NOT EXISTS " + source_table +
|
||||
"("
|
||||
"api_path TEXT PRIMARY KEY ASC, "
|
||||
"source_path TEXT"
|
||||
");"},
|
||||
}};
|
||||
} // namespace
|
||||
|
||||
namespace repertory {
|
||||
encrypt_provider::encrypt_provider(app_config &config) : config_(config) {}
|
||||
@@ -81,14 +114,14 @@ auto encrypt_provider::create_api_file(const std::string &api_path,
|
||||
file.modified_date =
|
||||
(static_cast<std::uint64_t>(ft.dwHighDateTime) << 32U) | ft.dwLowDateTime;
|
||||
#else
|
||||
file.changed_date =
|
||||
buf.st_mtim.tv_nsec + (buf.st_mtim.tv_sec * NANOS_PER_SECOND);
|
||||
file.accessed_date =
|
||||
buf.st_atim.tv_nsec + (buf.st_atim.tv_sec * NANOS_PER_SECOND);
|
||||
file.creation_date =
|
||||
buf.st_ctim.tv_nsec + (buf.st_ctim.tv_sec * NANOS_PER_SECOND);
|
||||
file.modified_date =
|
||||
buf.st_mtim.tv_nsec + (buf.st_mtim.tv_sec * NANOS_PER_SECOND);
|
||||
file.changed_date = static_cast<std::uint64_t>(
|
||||
buf.st_mtim.tv_nsec + (buf.st_mtim.tv_sec * NANOS_PER_SECOND));
|
||||
file.accessed_date = static_cast<std::uint64_t>(
|
||||
buf.st_atim.tv_nsec + (buf.st_atim.tv_sec * NANOS_PER_SECOND));
|
||||
file.creation_date = static_cast<std::uint64_t>(
|
||||
buf.st_ctim.tv_nsec + (buf.st_ctim.tv_sec * NANOS_PER_SECOND));
|
||||
file.modified_date = static_cast<std::uint64_t>(
|
||||
buf.st_mtim.tv_nsec + (buf.st_mtim.tv_sec * NANOS_PER_SECOND));
|
||||
#endif
|
||||
|
||||
return file;
|
||||
@@ -140,21 +173,33 @@ auto encrypt_provider::get_api_path_from_source(const std::string &source_path,
|
||||
std::string &api_path) const
|
||||
-> api_error {
|
||||
try {
|
||||
std::string api_path_data{};
|
||||
db_->Get(rocksdb::ReadOptions(), file_family_, source_path, &api_path_data);
|
||||
if (not api_path_data.empty()) {
|
||||
api_path = json::parse(api_path_data).at("api_path").get<std::string>();
|
||||
auto result = db::db_select{*db_, file_table}
|
||||
.column("data")
|
||||
.where("source_path")
|
||||
.equals(source_path)
|
||||
.go();
|
||||
std::optional<db::db_select::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
api_path = row->get_column("data")
|
||||
.get_value_as_json()
|
||||
.at("api_path")
|
||||
.get<std::string>();
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
std::string dir_api_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), dir_family_, source_path, &dir_api_path);
|
||||
if (dir_api_path.empty()) {
|
||||
return api_error::item_not_found;
|
||||
result = db::db_select{*db_, directory_table}
|
||||
.column("api_path")
|
||||
.where("source_path")
|
||||
.equals(source_path)
|
||||
.go();
|
||||
row.reset();
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
api_path = row->get_column("api_path").get_value<std::string>();
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
api_path = dir_api_path;
|
||||
return api_error::success;
|
||||
return api_error::item_not_found;
|
||||
|
||||
} catch (const std::exception &ex) {
|
||||
utils::error::raise_error(__FUNCTION__, ex, source_path,
|
||||
"failed to get api path from source path");
|
||||
@@ -165,15 +210,23 @@ auto encrypt_provider::get_api_path_from_source(const std::string &source_path,
|
||||
|
||||
auto encrypt_provider::get_directory_item_count(
|
||||
const std::string &api_path) const -> std::uint64_t {
|
||||
std::string source_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), source_family_, api_path, &source_path);
|
||||
if (source_path.empty()) {
|
||||
auto result = db::db_select{*db_, source_table}
|
||||
.column("source_path")
|
||||
.where("api_path")
|
||||
.equals(api_path)
|
||||
.go();
|
||||
std::optional<db::db_select::row> row;
|
||||
if (not(result.get_row(row) && row.has_value())) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
std::string dir_api_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), dir_family_, source_path, &dir_api_path);
|
||||
if (dir_api_path.empty()) {
|
||||
auto source_path = row->get_column("source_path").get_value<std::string>();
|
||||
result = db::db_select{*db_, directory_table}
|
||||
.column("api_path")
|
||||
.where("source_path")
|
||||
.equals(source_path)
|
||||
.go();
|
||||
if (not result.has_row()) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
@@ -206,15 +259,23 @@ auto encrypt_provider::get_directory_items(const std::string &api_path,
|
||||
return api_error::item_exists;
|
||||
}
|
||||
|
||||
std::string source_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), source_family_, api_path, &source_path);
|
||||
if (source_path.empty()) {
|
||||
auto result = db::db_select{*db_, source_table}
|
||||
.column("source_path")
|
||||
.where("api_path")
|
||||
.equals(api_path)
|
||||
.go();
|
||||
std::optional<db::db_select::row> row;
|
||||
if (not(result.get_row(row) && row.has_value())) {
|
||||
return api_error::directory_not_found;
|
||||
}
|
||||
auto source_path = row->get_column("source_path").get_value<std::string>();
|
||||
|
||||
std::string dir_api_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), dir_family_, source_path, &dir_api_path);
|
||||
if (dir_api_path.empty()) {
|
||||
result = db::db_select{*db_, directory_table}
|
||||
.column("api_path")
|
||||
.where("source_path")
|
||||
.equals(source_path)
|
||||
.go();
|
||||
if (not result.has_row()) {
|
||||
return api_error::directory_not_found;
|
||||
}
|
||||
|
||||
@@ -222,53 +283,69 @@ auto encrypt_provider::get_directory_items(const std::string &api_path,
|
||||
for (const auto &dir_entry :
|
||||
std::filesystem::directory_iterator(source_path)) {
|
||||
try {
|
||||
std::string entry_api_path{};
|
||||
std::string current_api_path{};
|
||||
if (dir_entry.is_directory()) {
|
||||
db_->Get(rocksdb::ReadOptions(), dir_family_,
|
||||
dir_entry.path().string(), &entry_api_path);
|
||||
if (entry_api_path.empty()) {
|
||||
result = db::db_select{*db_, directory_table}
|
||||
.column("api_path")
|
||||
.where("source_path")
|
||||
.equals(dir_entry.path().string())
|
||||
.go();
|
||||
row.reset();
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
current_api_path =
|
||||
row->get_column("api_path").get_value<std::string>();
|
||||
}
|
||||
if (current_api_path.empty()) {
|
||||
const auto cfg = config_.get_encrypt_config();
|
||||
for (const auto &child_dir_entry :
|
||||
std::filesystem::directory_iterator(dir_entry.path())) {
|
||||
if (process_directory_entry(child_dir_entry, cfg,
|
||||
entry_api_path)) {
|
||||
entry_api_path =
|
||||
utils::path::get_parent_api_path(entry_api_path);
|
||||
current_api_path)) {
|
||||
current_api_path =
|
||||
utils::path::get_parent_api_path(current_api_path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry_api_path.empty()) {
|
||||
if (current_api_path.empty()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::string api_path_data{};
|
||||
db_->Get(rocksdb::ReadOptions(), file_family_,
|
||||
dir_entry.path().string(), &api_path_data);
|
||||
result = db::db_select{*db_, file_table}
|
||||
.column("data")
|
||||
.where("source_path")
|
||||
.equals(dir_entry.path().string())
|
||||
.go();
|
||||
row.reset();
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
api_path_data = row->get_column("data").get_value<std::string>();
|
||||
}
|
||||
|
||||
if (api_path_data.empty()) {
|
||||
const auto cfg = config_.get_encrypt_config();
|
||||
if (not process_directory_entry(dir_entry, cfg, entry_api_path)) {
|
||||
if (not process_directory_entry(dir_entry, cfg, current_api_path)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
entry_api_path =
|
||||
current_api_path =
|
||||
json::parse(api_path_data).at("api_path").get<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
auto file = create_api_file(entry_api_path, dir_entry.is_directory(),
|
||||
auto file = create_api_file(current_api_path, dir_entry.is_directory(),
|
||||
dir_entry.path().string());
|
||||
|
||||
directory_item di{};
|
||||
di.api_parent = file.api_parent;
|
||||
di.api_path = file.api_path;
|
||||
di.directory = dir_entry.is_directory();
|
||||
di.resolved = true;
|
||||
di.size = file.file_size;
|
||||
create_item_meta(di.meta, di.directory, file);
|
||||
directory_item dir_item{};
|
||||
dir_item.api_parent = file.api_parent;
|
||||
dir_item.api_path = file.api_path;
|
||||
dir_item.directory = dir_entry.is_directory();
|
||||
dir_item.resolved = true;
|
||||
dir_item.size = file.file_size;
|
||||
create_item_meta(dir_item.meta, dir_item.directory, file);
|
||||
|
||||
list.emplace_back(std::move(di));
|
||||
list.emplace_back(std::move(dir_item));
|
||||
} catch (const std::exception &ex) {
|
||||
utils::error::raise_error(__FUNCTION__, ex, dir_entry.path().string(),
|
||||
"failed to process directory item");
|
||||
@@ -311,13 +388,18 @@ auto encrypt_provider::get_file(const std::string &api_path,
|
||||
return api_error::directory_exists;
|
||||
}
|
||||
|
||||
std::string source_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), source_family_, api_path, &source_path);
|
||||
if (source_path.empty()) {
|
||||
auto result = db::db_select{*db_, source_table}
|
||||
.column("source_path")
|
||||
.where("api_path")
|
||||
.equals(api_path)
|
||||
.go();
|
||||
std::optional<db::db_select::row> row;
|
||||
if (not(result.get_row(row) && row.has_value())) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
file = create_api_file(api_path, false, source_path);
|
||||
file = create_api_file(
|
||||
api_path, false, row->get_column("source_path").get_value<std::string>());
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
@@ -329,12 +411,26 @@ auto encrypt_provider::process_directory_entry(
|
||||
const auto relative_path = dir_entry.path().lexically_relative(cfg.path);
|
||||
|
||||
std::string api_path_data{};
|
||||
db_->Get(rocksdb::ReadOptions(), file_family_, dir_entry.path().string(),
|
||||
&api_path_data);
|
||||
auto result = db::db_select{*db_, file_table}
|
||||
.column("data")
|
||||
.where("source_path")
|
||||
.equals(dir_entry.path().string())
|
||||
.go();
|
||||
std::optional<db::db_select::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
api_path_data = row->get_column("data").get_value<std::string>();
|
||||
}
|
||||
|
||||
std::string api_parent{};
|
||||
db_->Get(rocksdb::ReadOptions(), dir_family_,
|
||||
dir_entry.path().parent_path().string(), &api_parent);
|
||||
result = db::db_select{*db_, directory_table}
|
||||
.column("api_path")
|
||||
.where("source_path")
|
||||
.equals(dir_entry.path().parent_path().string())
|
||||
.go();
|
||||
row.reset();
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
api_parent = row->get_column("api_path").get_value<std::string>();
|
||||
}
|
||||
|
||||
if (api_path_data.empty() || api_parent.empty()) {
|
||||
stop_type stop_requested = false;
|
||||
@@ -359,15 +455,31 @@ auto encrypt_provider::process_directory_entry(
|
||||
utils::path::combine(current_source_path, {part.string()});
|
||||
|
||||
std::string parent_api_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), dir_family_, current_source_path,
|
||||
&parent_api_path);
|
||||
result = db::db_select{*db_, directory_table}
|
||||
.column("api_path")
|
||||
.where("source_path")
|
||||
.equals(current_source_path)
|
||||
.go();
|
||||
row.reset();
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
parent_api_path =
|
||||
row->get_column("api_path").get_value<std::string>();
|
||||
}
|
||||
|
||||
if (parent_api_path.empty()) {
|
||||
parent_api_path = utils::path::create_api_path(
|
||||
current_encrypted_path + '/' + encrypted_parts[idx]);
|
||||
db_->Put(rocksdb::WriteOptions(), dir_family_, current_source_path,
|
||||
parent_api_path);
|
||||
db_->Put(rocksdb::WriteOptions(), source_family_, parent_api_path,
|
||||
current_source_path);
|
||||
|
||||
auto ins_res = db::db_insert{*db_, directory_table}
|
||||
.column_value("source_path", current_source_path)
|
||||
.column_value("api_path", parent_api_path)
|
||||
.go();
|
||||
// TODO handle error
|
||||
ins_res = db::db_insert{*db_, source_table}
|
||||
.column_value("api_path", parent_api_path)
|
||||
.column_value("source_path", current_source_path)
|
||||
.go();
|
||||
// TODO handle error
|
||||
event_system::instance().raise<filesystem_item_added>(
|
||||
parent_api_path,
|
||||
utils::path::get_parent_api_path(parent_api_path), true);
|
||||
@@ -393,10 +505,18 @@ auto encrypt_provider::process_directory_entry(
|
||||
{"iv_list", iv_list},
|
||||
{"original_file_size", dir_entry.file_size()},
|
||||
};
|
||||
db_->Put(rocksdb::WriteOptions(), file_family_,
|
||||
dir_entry.path().string(), data.dump());
|
||||
db_->Put(rocksdb::WriteOptions(), source_family_, api_path,
|
||||
dir_entry.path().string());
|
||||
auto ins_res =
|
||||
db::db_insert{*db_, file_table}
|
||||
.column_value("source_path", dir_entry.path().string())
|
||||
.column_value("data", data.dump())
|
||||
.go();
|
||||
// TODO handle error
|
||||
|
||||
ins_res = db::db_insert{*db_, source_table}
|
||||
.column_value("api_path", api_path)
|
||||
.column_value("source_path", dir_entry.path().string())
|
||||
.go();
|
||||
// TODO handle error
|
||||
event_system::instance().raise<filesystem_item_added>(
|
||||
api_path, api_parent, false);
|
||||
} else {
|
||||
@@ -437,13 +557,18 @@ auto encrypt_provider::get_file_list(api_file_list &list) const -> api_error {
|
||||
auto encrypt_provider::get_file_size(const std::string &api_path,
|
||||
std::uint64_t &file_size) const
|
||||
-> api_error {
|
||||
std::string source_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), source_family_, api_path, &source_path);
|
||||
if (source_path.empty()) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
try {
|
||||
auto result = db::db_select{*db_, source_table}
|
||||
.column("source_path")
|
||||
.where("api_path")
|
||||
.equals(api_path)
|
||||
.go();
|
||||
std::optional<db::db_select::row> row;
|
||||
if (not(result.get_row(row) && row.has_value())) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
auto source_path = row->get_column("source_path").get_value<std::string>();
|
||||
|
||||
file_size = utils::encryption::encrypting_reader::calculate_encrypted_size(
|
||||
source_path);
|
||||
return api_error::success;
|
||||
@@ -459,18 +584,30 @@ auto encrypt_provider::get_filesystem_item(const std::string &api_path,
|
||||
bool directory,
|
||||
filesystem_item &fsi) const
|
||||
-> api_error {
|
||||
std::string source_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), source_family_, api_path, &source_path);
|
||||
if (source_path.empty()) {
|
||||
auto result = db::db_select{*db_, source_table}
|
||||
.column("source_path")
|
||||
.where("api_path")
|
||||
.equals(api_path)
|
||||
.go();
|
||||
std::optional<db::db_select::row> row;
|
||||
if (not(result.get_row(row) && row.has_value())) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
auto source_path = row->get_column("source_path").get_value<std::string>();
|
||||
|
||||
if (directory) {
|
||||
std::string db_api_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), dir_family_, source_path, &db_api_path);
|
||||
if (db_api_path.empty()) {
|
||||
result = db::db_select{*db_, directory_table}
|
||||
.column("api_path")
|
||||
.where("source_path")
|
||||
.equals(source_path)
|
||||
.go();
|
||||
row.reset();
|
||||
if (not(result.get_row(row) && row.has_value())) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
auto db_api_path = row->get_column("api_path").get_value<std::string>();
|
||||
|
||||
fsi.api_parent = utils::path::get_parent_api_path(db_api_path);
|
||||
fsi.api_path = db_api_path;
|
||||
fsi.directory = true;
|
||||
@@ -479,14 +616,20 @@ auto encrypt_provider::get_filesystem_item(const std::string &api_path,
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
std::string api_path_data{};
|
||||
db_->Get(rocksdb::ReadOptions(), file_family_, source_path, &api_path_data);
|
||||
if (api_path_data.empty()) {
|
||||
result = db::db_select{*db_, file_table}
|
||||
.column("data")
|
||||
.where("source_path")
|
||||
.equals(source_path)
|
||||
.go();
|
||||
row.reset();
|
||||
if (not(result.get_row(row) && row.has_value())) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
auto data = json::parse(api_path_data);
|
||||
fsi.api_path = data["api_path"].get<std::string>();
|
||||
fsi.api_path = row->get_column("data")
|
||||
.get_value_as_json()
|
||||
.at("api_path")
|
||||
.get<std::string>();
|
||||
fsi.api_parent = utils::path::get_parent_api_path(fsi.api_path);
|
||||
fsi.directory = false;
|
||||
fsi.size = utils::encryption::encrypting_reader::calculate_encrypted_size(
|
||||
@@ -544,12 +687,18 @@ auto encrypt_provider::get_pinned_files() const -> std::vector<std::string> {
|
||||
|
||||
auto encrypt_provider::get_item_meta(const std::string &api_path,
|
||||
api_meta_map &meta) const -> api_error {
|
||||
std::string source_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), source_family_, api_path, &source_path);
|
||||
if (source_path.empty()) {
|
||||
auto result = db::db_select{*db_, source_table}
|
||||
.column("source_path")
|
||||
.where("api_path")
|
||||
.equals(api_path)
|
||||
.go();
|
||||
std::optional<db::db_select::row> row;
|
||||
if (not(result.get_row(row) && row.has_value())) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
auto source_path = row->get_column("source_path").get_value<std::string>();
|
||||
|
||||
bool exists{};
|
||||
auto res = is_directory(api_path, exists);
|
||||
if (res != api_error::success) {
|
||||
@@ -580,15 +729,16 @@ auto encrypt_provider::get_total_drive_space() const -> std::uint64_t {
|
||||
}
|
||||
|
||||
auto encrypt_provider::get_total_item_count() const -> std::uint64_t {
|
||||
std::uint64_t ret{};
|
||||
auto result =
|
||||
db::db_select{*db_, source_table}.count("api_path", "count").go();
|
||||
|
||||
auto iterator = std::unique_ptr<rocksdb::Iterator>(
|
||||
db_->NewIterator(rocksdb::ReadOptions(), source_family_));
|
||||
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
|
||||
ret++;
|
||||
std::optional<db::db_select::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
return static_cast<std::uint64_t>(
|
||||
row->get_column("count").get_value<std::int64_t>());
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0U;
|
||||
}
|
||||
|
||||
auto encrypt_provider::get_used_drive_space() const -> std::uint64_t {
|
||||
@@ -598,27 +748,37 @@ auto encrypt_provider::get_used_drive_space() const -> std::uint64_t {
|
||||
|
||||
auto encrypt_provider::is_directory(const std::string &api_path,
|
||||
bool &exists) const -> api_error {
|
||||
std::string source_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), source_family_, api_path, &source_path);
|
||||
if (source_path.empty()) {
|
||||
auto result = db::db_select{*db_, source_table}
|
||||
.column("source_path")
|
||||
.where("api_path")
|
||||
.equals(api_path)
|
||||
.go();
|
||||
std::optional<db::db_select::row> row;
|
||||
if (not(result.get_row(row) && row.has_value())) {
|
||||
exists = false;
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
exists = utils::file::is_directory(source_path);
|
||||
exists = utils::file::is_directory(
|
||||
row->get_column("source_path").get_value<std::string>());
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
auto encrypt_provider::is_file(const std::string &api_path, bool &exists) const
|
||||
-> api_error {
|
||||
std::string source_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), source_family_, api_path, &source_path);
|
||||
if (source_path.empty()) {
|
||||
auto result = db::db_select{*db_, source_table}
|
||||
.column("source_path")
|
||||
.where("api_path")
|
||||
.equals(api_path)
|
||||
.go();
|
||||
std::optional<db::db_select::row> row;
|
||||
if (not(result.get_row(row) && row.has_value())) {
|
||||
exists = false;
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
exists = utils::file::is_file(source_path);
|
||||
exists = utils::file::is_file(
|
||||
row->get_column("source_path").get_value<std::string>());
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
@@ -637,18 +797,33 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path,
|
||||
std::size_t size, std::uint64_t offset,
|
||||
data_buffer &data,
|
||||
stop_type &stop_requested) -> api_error {
|
||||
std::string source_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), source_family_, api_path, &source_path);
|
||||
auto result = db::db_select{*db_, source_table}
|
||||
.column("source_path")
|
||||
.where("api_path")
|
||||
.equals(api_path)
|
||||
.go();
|
||||
std::optional<db::db_select::row> row;
|
||||
if (not(result.get_row(row) && row.has_value())) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
auto source_path = row->get_column("source_path").get_value<std::string>();
|
||||
if (source_path.empty()) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
std::string api_path_data{};
|
||||
db_->Get(rocksdb::ReadOptions(), file_family_, source_path, &api_path_data);
|
||||
if (api_path_data.empty()) {
|
||||
result = db::db_select{*db_, file_table}
|
||||
.column("data")
|
||||
.where("source_path")
|
||||
.equals(source_path)
|
||||
.go();
|
||||
row.reset();
|
||||
if (not(result.get_row(row) && row.has_value())) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
auto file_data = row->get_column("data").get_value_as_json();
|
||||
|
||||
std::uint64_t file_size{};
|
||||
if (not utils::file::get_file_size(source_path, file_size)) {
|
||||
return api_error::os_error;
|
||||
@@ -662,7 +837,6 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path,
|
||||
|
||||
unique_recur_mutex_lock reader_lookup_lock(reader_lookup_mtx_);
|
||||
|
||||
auto file_data = json::parse(api_path_data);
|
||||
if (file_data.at("original_file_size").get<std::uint64_t>() != file_size) {
|
||||
const auto relative_path =
|
||||
std::filesystem::path(source_path).lexically_relative(cfg.path);
|
||||
@@ -676,10 +850,12 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path,
|
||||
|
||||
file_data["original_file_size"] = file_size;
|
||||
file_data["iv_list"] = iv_list;
|
||||
auto res = db_->Put(rocksdb::WriteOptions(), file_family_, source_path,
|
||||
file_data.dump());
|
||||
if (not res.ok()) {
|
||||
utils::error::raise_error(__FUNCTION__, res.code(), source_path,
|
||||
auto ins_res = db::db_insert{*db_, file_table}
|
||||
.column_value("source_path", source_path)
|
||||
.column_value("data", file_data.dump())
|
||||
.go();
|
||||
if (not ins_res.ok()) {
|
||||
utils::error::raise_error(__FUNCTION__, ins_res.get_error(), source_path,
|
||||
"failed to update meta db");
|
||||
return api_error::error;
|
||||
}
|
||||
@@ -727,26 +903,44 @@ void encrypt_provider::remove_deleted_files() {
|
||||
};
|
||||
|
||||
std::vector<removed_item> removed_list{};
|
||||
auto iterator = std::unique_ptr<rocksdb::Iterator>(
|
||||
db_->NewIterator(rocksdb::ReadOptions(), source_family_));
|
||||
for (iterator->SeekToFirst(); iterator->Valid(); iterator->Next()) {
|
||||
auto source_path = iterator->value().ToString();
|
||||
std::vector<db::db_select::row> row_list{};
|
||||
|
||||
auto result = db::db_select{*db_, source_table}.go();
|
||||
while (result.has_row()) {
|
||||
std::optional<db::db_select::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
row_list.push_back(row.value());
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &row : row_list) {
|
||||
auto source_path = row.get_column("source_path").get_value<std::string>();
|
||||
if (not std::filesystem::exists(source_path)) {
|
||||
auto api_path =
|
||||
utils::string::split(iterator->key().ToString(), '|', false)[1U];
|
||||
|
||||
std::string value{};
|
||||
db_->Get(rocksdb::ReadOptions(), file_family_, source_path, &value);
|
||||
|
||||
auto api_path = row.get_column("api_path").get_value<std::string>();
|
||||
result = db::db_select{*db_, file_table}
|
||||
.column("source_path")
|
||||
.where("source_path")
|
||||
.equals(source_path)
|
||||
.go();
|
||||
removed_list.emplace_back(
|
||||
removed_item{api_path, value.empty(), source_path});
|
||||
removed_item{api_path, not result.has_row(), source_path});
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &item : removed_list) {
|
||||
if (not item.directory) {
|
||||
db_->Delete(rocksdb::WriteOptions(), source_family_, item.api_path);
|
||||
db_->Delete(rocksdb::WriteOptions(), file_family_, item.source_path);
|
||||
auto del_res = db::db_select{*db_, source_table}
|
||||
.delete_query()
|
||||
.where("api_path")
|
||||
.equals(item.api_path)
|
||||
.go();
|
||||
// TODO handle error
|
||||
del_res = db::db_select{*db_, file_table}
|
||||
.delete_query()
|
||||
.where("source_path")
|
||||
.equals(item.source_path)
|
||||
.go();
|
||||
// TODO handle error
|
||||
event_system::instance().raise<file_removed_externally>(item.api_path,
|
||||
item.source_path);
|
||||
}
|
||||
@@ -754,8 +948,18 @@ void encrypt_provider::remove_deleted_files() {
|
||||
|
||||
for (const auto &item : removed_list) {
|
||||
if (item.directory) {
|
||||
db_->Delete(rocksdb::WriteOptions(), source_family_, item.api_path);
|
||||
db_->Delete(rocksdb::WriteOptions(), dir_family_, item.source_path);
|
||||
auto del_res = db::db_select{*db_, source_table}
|
||||
.delete_query()
|
||||
.where("api_path")
|
||||
.equals(item.api_path)
|
||||
.go();
|
||||
// TODO handle error
|
||||
del_res = db::db_select{*db_, directory_table}
|
||||
.delete_query()
|
||||
.where("source_path")
|
||||
.equals(item.source_path)
|
||||
.go();
|
||||
// TODO handle error
|
||||
event_system::instance().raise<directory_removed_externally>(
|
||||
item.api_path, item.source_path);
|
||||
}
|
||||
@@ -768,35 +972,64 @@ auto encrypt_provider::start(api_item_added_callback /*api_item_added*/,
|
||||
return false;
|
||||
}
|
||||
|
||||
auto families = std::vector<rocksdb::ColumnFamilyDescriptor>();
|
||||
families.emplace_back(rocksdb::kDefaultColumnFamilyName,
|
||||
rocksdb::ColumnFamilyOptions());
|
||||
families.emplace_back("dir", rocksdb::ColumnFamilyOptions());
|
||||
families.emplace_back("file", rocksdb::ColumnFamilyOptions());
|
||||
families.emplace_back("source", rocksdb::ColumnFamilyOptions());
|
||||
auto db_path =
|
||||
utils::path::combine(config_.get_data_directory(), {"meta.db3"});
|
||||
|
||||
auto handles = std::vector<rocksdb::ColumnFamilyHandle *>();
|
||||
sqlite3 *db3{nullptr};
|
||||
auto res =
|
||||
sqlite3_open_v2(db_path.c_str(), &db3,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
|
||||
if (res != SQLITE_OK) {
|
||||
utils::error::raise_error(__FUNCTION__, "failed to open db|" + db_path +
|
||||
'|' + std::to_string(res) +
|
||||
'|' + sqlite3_errstr(res));
|
||||
return false;
|
||||
}
|
||||
db_.reset(db3);
|
||||
|
||||
utils::db::create_rocksdb(config_, DB_NAME, families, handles, db_);
|
||||
for (const auto &create : sql_create_tables) {
|
||||
std::string err;
|
||||
if (not db::execute_sql(*db_, create.second, err)) {
|
||||
utils::error::raise_error(__FUNCTION__, "failed to create table|" +
|
||||
create.first + '|' + err);
|
||||
db_.reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t idx{};
|
||||
dir_family_ = handles[idx++];
|
||||
file_family_ = handles[idx++];
|
||||
source_family_ = handles[idx++];
|
||||
db::set_journal_mode(*db_);
|
||||
|
||||
const auto cfg = config_.get_encrypt_config();
|
||||
|
||||
std::string source_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), source_family_, "/", &source_path);
|
||||
if (source_path.empty()) {
|
||||
db_->Put(rocksdb::WriteOptions(), source_family_, "/", cfg.path);
|
||||
std::string source_path;
|
||||
auto result = db::db_select{*db_, source_table}
|
||||
.column("source_path")
|
||||
.where("api_path")
|
||||
.equals("/")
|
||||
.go();
|
||||
std::optional<db::db_select::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
source_path = row->get_column("source_path").get_value<std::string>();
|
||||
} else {
|
||||
auto ins_res = db::db_insert{*db_, source_table}
|
||||
.column_value("api_path", "/")
|
||||
.column_value("source_path", cfg.path)
|
||||
.go();
|
||||
// TODO error handling
|
||||
source_path = cfg.path;
|
||||
}
|
||||
|
||||
std::string dir_api_path{};
|
||||
db_->Get(rocksdb::ReadOptions(), dir_family_, source_path, &dir_api_path);
|
||||
if (dir_api_path.empty()) {
|
||||
db_->Put(rocksdb::WriteOptions(), dir_family_, source_path, "/");
|
||||
result = db::db_select{*db_, directory_table}
|
||||
.column("api_path")
|
||||
.where("source_path")
|
||||
.equals(source_path)
|
||||
.go();
|
||||
if (not result.has_row()) {
|
||||
auto ins_res = db::db_insert{*db_, directory_table}
|
||||
.column_value("source_path", source_path)
|
||||
.column_value("api_path", "/")
|
||||
.go();
|
||||
// TODO error handling
|
||||
}
|
||||
|
||||
polling::instance().set_callback({"check_deleted", polling::frequency::low,
|
||||
|
301
src/providers/meta_db.cpp
Normal file
301
src/providers/meta_db.cpp
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
#include "providers/meta_db.hpp"
|
||||
|
||||
#include "app_config.hpp"
|
||||
#include "database/db_common.hpp"
|
||||
#include "database/db_insert.hpp"
|
||||
#include "database/db_select.hpp"
|
||||
#include "utils/error_utils.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
meta_db::meta_db(const app_config &cfg) {
|
||||
auto db_path = utils::path::combine(cfg.get_data_directory(), {"meta.db3"});
|
||||
|
||||
sqlite3 *db3{nullptr};
|
||||
auto res =
|
||||
sqlite3_open_v2(db_path.c_str(), &db3,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
|
||||
if (res != SQLITE_OK) {
|
||||
utils::error::raise_error(__FUNCTION__, "failed to open db|" + db_path +
|
||||
'|' + std::to_string(res) +
|
||||
'|' + sqlite3_errstr(res));
|
||||
return;
|
||||
}
|
||||
db_.reset(db3);
|
||||
|
||||
const auto *create = "CREATE TABLE IF NOT EXISTS "
|
||||
"meta "
|
||||
"("
|
||||
"api_path TEXT PRIMARY KEY ASC, "
|
||||
"data TEXT, "
|
||||
"directory INTEGER, "
|
||||
"pinned INTEGER, "
|
||||
"source_path TEXT"
|
||||
");";
|
||||
std::string err;
|
||||
if (not db::execute_sql(*db_, create, err)) {
|
||||
utils::error::raise_error(__FUNCTION__,
|
||||
"failed to create db|" + db_path + '|' + err);
|
||||
db_.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
db::set_journal_mode(*db_);
|
||||
}
|
||||
|
||||
meta_db::~meta_db() { db_.reset(); }
|
||||
|
||||
auto meta_db::get_api_path(const std::string &source_path,
|
||||
std::string &api_path) -> api_error {
|
||||
auto result = db::db_select{*db_, table_name}
|
||||
.column("api_path")
|
||||
.where("source_path")
|
||||
.equals(source_path)
|
||||
.limit(1)
|
||||
.go();
|
||||
|
||||
std::optional<db::db_select::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
api_path = row->get_column("api_path").get_value<std::string>();
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
auto meta_db::get_api_path_list() -> std::vector<std::string> {
|
||||
std::vector<std::string> ret{};
|
||||
|
||||
auto result = db::db_select{*db_, table_name}.column("api_path").go();
|
||||
while (result.has_row()) {
|
||||
std::optional<db::db_select::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
ret.push_back(row->get_column("api_path").get_value<std::string>());
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto meta_db::get_item_meta(const std::string &api_path, api_meta_map &meta)
|
||||
-> api_error {
|
||||
auto result = db::db_select{*db_, table_name}
|
||||
.column("*")
|
||||
.where("api_path")
|
||||
.equals(api_path)
|
||||
.limit(1)
|
||||
.go();
|
||||
if (not result.has_row()) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
try {
|
||||
std::optional<db::db_select::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
meta = json::parse(row->get_column("data").get_value<std::string>())
|
||||
.get<api_meta_map>();
|
||||
meta[META_DIRECTORY] = utils::string::from_bool(
|
||||
row->get_column("directory").get_value<std::int64_t>() == 1);
|
||||
meta[META_PINNED] = utils::string::from_bool(
|
||||
row->get_column("pinned").get_value<std::int64_t>() == 1);
|
||||
meta[META_SOURCE] =
|
||||
row->get_column("source_path").get_value<std::string>();
|
||||
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
return api_error::item_not_found;
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
|
||||
"failed to get item meta");
|
||||
}
|
||||
|
||||
return api_error::error;
|
||||
}
|
||||
|
||||
auto meta_db::get_item_meta(const std::string &api_path, const std::string &key,
|
||||
std::string &value) const -> api_error {
|
||||
auto result = db::db_select{*db_, table_name}
|
||||
.column("*")
|
||||
.where("api_path")
|
||||
.equals(api_path)
|
||||
.limit(1)
|
||||
.go();
|
||||
if (not result.has_row()) {
|
||||
return api_error::item_not_found;
|
||||
}
|
||||
|
||||
try {
|
||||
std::optional<db::db_select::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
value =
|
||||
key == META_SOURCE
|
||||
? row->get_column("source_path").get_value<std::string>()
|
||||
: key == META_PINNED
|
||||
? utils::string::from_bool(
|
||||
row->get_column("pinned").get_value<std::int64_t>() == 1)
|
||||
: key == META_DIRECTORY
|
||||
? utils::string::from_bool(
|
||||
row->get_column("directory").get_value<std::int64_t>() == 1)
|
||||
: json::parse(
|
||||
row->get_column("data").get_value<std::string>())[key]
|
||||
.get<std::string>();
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
return api_error::item_not_found;
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::raise_api_path_error(__FUNCTION__, api_path, e,
|
||||
"failed to get item meta");
|
||||
}
|
||||
|
||||
return api_error::error;
|
||||
}
|
||||
|
||||
auto meta_db::get_pinned_files() const -> std::vector<std::string> {
|
||||
std::vector<std::string> ret{};
|
||||
|
||||
try {
|
||||
auto result = db::db_select{*db_, table_name}
|
||||
.column("api_path")
|
||||
.where("pinned")
|
||||
.equals(1)
|
||||
.go();
|
||||
while (result.has_row()) {
|
||||
std::optional<db::db_select::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
ret.emplace_back(row->get_column("api_path").get_value<std::string>());
|
||||
}
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::raise_error(__FUNCTION__, e, "failed to get pinned files");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto meta_db::get_total_item_count() const -> std::uint64_t {
|
||||
std::uint64_t ret{};
|
||||
|
||||
try {
|
||||
auto result =
|
||||
db::db_select{*db_, table_name}.count("api_path", "count").go();
|
||||
|
||||
std::optional<db::db_select::row> row;
|
||||
if (result.get_row(row) && row.has_value()) {
|
||||
ret = static_cast<std::uint64_t>(
|
||||
row->get_column("count").get_value<std::int64_t>());
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::raise_error(__FUNCTION__, e,
|
||||
"failed to get total item count");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void meta_db::remove_api_path(const std::string &api_path) {
|
||||
auto result = db::db_select{*db_, table_name}
|
||||
.delete_query()
|
||||
.where("api_path")
|
||||
.equals(api_path)
|
||||
.go();
|
||||
if (not result.ok()) {
|
||||
utils::error::raise_api_path_error(
|
||||
__FUNCTION__, api_path, result.get_error(), "failed to remove meta");
|
||||
}
|
||||
}
|
||||
|
||||
auto meta_db::remove_item_meta(const std::string &api_path,
|
||||
const std::string &key) -> api_error {
|
||||
api_meta_map meta{};
|
||||
auto res = get_item_meta(api_path, meta);
|
||||
if (res != api_error::success) {
|
||||
return res;
|
||||
}
|
||||
|
||||
meta.erase(key);
|
||||
return update_item_meta(api_path, meta);
|
||||
}
|
||||
|
||||
auto meta_db::rename_item_meta(const std::string &from_api_path,
|
||||
const std::string &to_api_path) -> api_error {
|
||||
api_meta_map meta{};
|
||||
auto res = get_item_meta(from_api_path, meta);
|
||||
if (res != api_error::success) {
|
||||
return res;
|
||||
}
|
||||
remove_api_path(from_api_path);
|
||||
|
||||
return update_item_meta(to_api_path, meta);
|
||||
}
|
||||
|
||||
auto meta_db::set_item_meta(const std::string &api_path, const std::string &key,
|
||||
const std::string &value) -> api_error {
|
||||
return set_item_meta(api_path, {{key, value}});
|
||||
}
|
||||
|
||||
auto meta_db::set_item_meta(const std::string &api_path,
|
||||
const api_meta_map &meta) -> api_error {
|
||||
api_meta_map existing_meta{};
|
||||
if (get_item_meta(api_path, existing_meta) != api_error::success) {
|
||||
// TODO handle error
|
||||
}
|
||||
|
||||
for (const auto &item : meta) {
|
||||
existing_meta[item.first] = item.second;
|
||||
}
|
||||
|
||||
return update_item_meta(api_path, existing_meta);
|
||||
}
|
||||
|
||||
auto meta_db::update_item_meta(const std::string &api_path, api_meta_map meta)
|
||||
-> api_error {
|
||||
auto directory = utils::string::to_bool(meta[META_DIRECTORY]);
|
||||
auto pinned = utils::string::to_bool(meta[META_PINNED]);
|
||||
auto source_path = meta[META_SOURCE];
|
||||
|
||||
meta.erase(META_DIRECTORY);
|
||||
meta.erase(META_PINNED);
|
||||
meta.erase(META_SOURCE);
|
||||
|
||||
auto result = db::db_insert{*db_, table_name}
|
||||
.or_replace()
|
||||
.column_value("api_path", api_path)
|
||||
.column_value("data", nlohmann::json(meta).dump())
|
||||
.column_value("directory", directory ? 1 : 0)
|
||||
.column_value("pinned", pinned ? 1 : 0)
|
||||
.column_value("source_path", source_path)
|
||||
.go();
|
||||
if (not result.ok()) {
|
||||
utils::error::raise_api_path_error(__FUNCTION__, api_path,
|
||||
result.get_error(),
|
||||
"failed to update item meta");
|
||||
return api_error::error;
|
||||
}
|
||||
|
||||
return api_error::success;
|
||||
}
|
||||
} // namespace repertory
|
@@ -36,7 +36,6 @@
|
||||
#include "utils/file_utils.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
#include "utils/polling.hpp"
|
||||
#include "utils/rocksdb_utils.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
|
@@ -31,7 +31,6 @@
|
||||
#include "utils/file_utils.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
#include "utils/polling.hpp"
|
||||
#include "utils/rocksdb_utils.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/utils.hpp"
|
||||
|
||||
@@ -576,10 +575,34 @@ auto sia_provider::remove_file_impl(const std::string &api_path) -> api_error {
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
auto sia_provider::rename_file(const std::string & /*from_api_path*/,
|
||||
const std::string & /*to_api_path*/)
|
||||
-> api_error {
|
||||
return api_error::not_implemented;
|
||||
auto sia_provider::rename_file(const std::string &from_api_path,
|
||||
const std::string &to_api_path) -> api_error {
|
||||
curl::requests::http_post post{};
|
||||
post.path = "/api/bus/objects/rename";
|
||||
post.json = nlohmann::json({
|
||||
{"from", from_api_path},
|
||||
{"to", to_api_path},
|
||||
{"mode", "single"},
|
||||
});
|
||||
|
||||
long response_code{};
|
||||
stop_type stop_requested{};
|
||||
if (not get_comm().make_request(post, response_code, stop_requested)) {
|
||||
utils::error::raise_api_path_error(
|
||||
__FUNCTION__, from_api_path + '|' + to_api_path, api_error::comm_error,
|
||||
"failed to rename file");
|
||||
return api_error::comm_error;
|
||||
}
|
||||
|
||||
if (response_code < http_error_codes::ok ||
|
||||
response_code >= http_error_codes::multiple_choices) {
|
||||
utils::error::raise_api_path_error(
|
||||
__FUNCTION__, from_api_path + '|' + to_api_path, response_code,
|
||||
"failed to rename file file");
|
||||
return api_error::comm_error;
|
||||
}
|
||||
|
||||
return get_db().rename_item_meta(from_api_path, to_api_path);
|
||||
}
|
||||
|
||||
auto sia_provider::start(api_item_added_callback api_item_added,
|
||||
|
@@ -104,8 +104,7 @@ protected:
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
reader_.set_read_position(
|
||||
static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(gptr())));
|
||||
reader_.set_read_position(reinterpret_cast<std::uintptr_t>(gptr()));
|
||||
|
||||
char c{};
|
||||
const auto res = encrypting_reader::reader_function(&c, 1U, 1U, &reader_);
|
||||
@@ -121,8 +120,7 @@ protected:
|
||||
return traits_type::eof();
|
||||
}
|
||||
|
||||
reader_.set_read_position(
|
||||
static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(gptr())));
|
||||
reader_.set_read_position(reinterpret_cast<std::uintptr_t>(gptr()));
|
||||
|
||||
const auto res = encrypting_reader::reader_function(
|
||||
ptr, 1U, static_cast<std::size_t>(count), &reader_);
|
||||
@@ -202,15 +200,15 @@ encrypting_reader::encrypting_reader(
|
||||
std::to_string(utils::get_last_error_code()));
|
||||
}
|
||||
|
||||
const auto total_chunks = static_cast<std::size_t>(utils::divide_with_ceiling(
|
||||
file_size, static_cast<std::uint64_t>(data_chunk_size_)));
|
||||
const auto total_chunks = utils::divide_with_ceiling(
|
||||
file_size, static_cast<std::uint64_t>(data_chunk_size_));
|
||||
total_size_ =
|
||||
file_size + (total_chunks * encrypting_reader::get_header_size());
|
||||
last_data_chunk_ = total_chunks - 1U;
|
||||
last_data_chunk_size_ = static_cast<std::size_t>(
|
||||
(file_size <= data_chunk_size_) ? file_size
|
||||
: (file_size % data_chunk_size_) == 0U ? data_chunk_size_
|
||||
: file_size % data_chunk_size_);
|
||||
last_data_chunk_size_ = (file_size <= data_chunk_size_) ? file_size
|
||||
: (file_size % data_chunk_size_) == 0U
|
||||
? data_chunk_size_
|
||||
: file_size % data_chunk_size_;
|
||||
iv_list_.resize(total_chunks);
|
||||
for (auto &iv : iv_list_) {
|
||||
randombytes_buf(iv.data(), iv.size());
|
||||
@@ -242,15 +240,15 @@ encrypting_reader::encrypting_reader(const std::string &encrypted_file_path,
|
||||
std::to_string(utils::get_last_error_code()));
|
||||
}
|
||||
|
||||
const auto total_chunks = static_cast<std::size_t>(utils::divide_with_ceiling(
|
||||
file_size, static_cast<std::uint64_t>(data_chunk_size_)));
|
||||
const auto total_chunks = utils::divide_with_ceiling(
|
||||
file_size, static_cast<std::uint64_t>(data_chunk_size_));
|
||||
total_size_ =
|
||||
file_size + (total_chunks * encrypting_reader::get_header_size());
|
||||
last_data_chunk_ = total_chunks - 1U;
|
||||
last_data_chunk_size_ = static_cast<std::size_t>(
|
||||
(file_size <= data_chunk_size_) ? file_size
|
||||
: (file_size % data_chunk_size_) == 0U ? data_chunk_size_
|
||||
: file_size % data_chunk_size_);
|
||||
last_data_chunk_size_ = (file_size <= data_chunk_size_) ? file_size
|
||||
: (file_size % data_chunk_size_) == 0U
|
||||
? data_chunk_size_
|
||||
: file_size % data_chunk_size_;
|
||||
iv_list_.resize(total_chunks);
|
||||
for (auto &iv : iv_list_) {
|
||||
randombytes_buf(iv.data(), iv.size());
|
||||
@@ -284,15 +282,15 @@ encrypting_reader::encrypting_reader(
|
||||
std::to_string(utils::get_last_error_code()));
|
||||
}
|
||||
|
||||
const auto total_chunks = static_cast<std::size_t>(utils::divide_with_ceiling(
|
||||
file_size, static_cast<std::uint64_t>(data_chunk_size_)));
|
||||
const auto total_chunks = utils::divide_with_ceiling(
|
||||
file_size, static_cast<std::uint64_t>(data_chunk_size_));
|
||||
total_size_ =
|
||||
file_size + (total_chunks * encrypting_reader::get_header_size());
|
||||
last_data_chunk_ = total_chunks - 1U;
|
||||
last_data_chunk_size_ = static_cast<std::size_t>(
|
||||
(file_size <= data_chunk_size_) ? file_size
|
||||
: (file_size % data_chunk_size_) == 0U ? data_chunk_size_
|
||||
: file_size % data_chunk_size_);
|
||||
last_data_chunk_size_ = (file_size <= data_chunk_size_) ? file_size
|
||||
: (file_size % data_chunk_size_) == 0U
|
||||
? data_chunk_size_
|
||||
: file_size % data_chunk_size_;
|
||||
iv_list_ = std::move(iv_list);
|
||||
}
|
||||
|
||||
@@ -332,8 +330,8 @@ auto encrypting_reader::calculate_encrypted_size(const std::string &source_path)
|
||||
std::to_string(utils::get_last_error_code()));
|
||||
}
|
||||
|
||||
const auto total_chunks = static_cast<std::size_t>(utils::divide_with_ceiling(
|
||||
file_size, static_cast<std::uint64_t>(data_chunk_size_)));
|
||||
const auto total_chunks = utils::divide_with_ceiling(
|
||||
file_size, static_cast<std::uint64_t>(data_chunk_size_));
|
||||
return file_size + (total_chunks * encrypting_reader::get_header_size());
|
||||
}
|
||||
|
||||
@@ -348,9 +346,8 @@ auto encrypting_reader::reader_function(char *buffer, size_t size,
|
||||
const auto read_size = static_cast<std::size_t>(std::min(
|
||||
static_cast<std::uint64_t>(size * nitems), total_size_ - read_offset_));
|
||||
|
||||
auto chunk = static_cast<std::size_t>(read_offset_ / encrypted_chunk_size_);
|
||||
auto chunk_offset =
|
||||
static_cast<std::size_t>(read_offset_ % encrypted_chunk_size_);
|
||||
auto chunk = read_offset_ / encrypted_chunk_size_;
|
||||
auto chunk_offset = read_offset_ % encrypted_chunk_size_;
|
||||
std::size_t total_read = 0u;
|
||||
|
||||
auto ret = false;
|
||||
@@ -378,8 +375,9 @@ auto encrypting_reader::reader_function(char *buffer, size_t size,
|
||||
}
|
||||
|
||||
auto &chunk_buffer = chunk_buffers_[chunk];
|
||||
const auto to_read =
|
||||
std::min(chunk_buffer.size() - chunk_offset, remain);
|
||||
const auto to_read = std::min(
|
||||
static_cast<std::size_t>(chunk_buffer.size() - chunk_offset),
|
||||
remain);
|
||||
std::memcpy(buffer + total_read, &chunk_buffer[chunk_offset], to_read);
|
||||
total_read += to_read;
|
||||
remain -= to_read;
|
||||
|
@@ -72,16 +72,16 @@ auto generate_key(const std::string &encryption_token) -> key_type {
|
||||
throw std::runtime_error("failed to initialize sha256|" +
|
||||
std::to_string(res));
|
||||
}
|
||||
|
||||
if ((res = crypto_hash_sha256_update(
|
||||
&state,
|
||||
reinterpret_cast<const unsigned char *>(encryption_token.c_str()),
|
||||
strnlen(encryption_token.c_str(), encryption_token.size()))) != 0) {
|
||||
res = crypto_hash_sha256_update(
|
||||
&state, reinterpret_cast<const unsigned char *>(encryption_token.c_str()),
|
||||
strnlen(encryption_token.c_str(), encryption_token.size()));
|
||||
if (res != 0) {
|
||||
throw std::runtime_error("failed to update sha256|" + std::to_string(res));
|
||||
}
|
||||
|
||||
key_type ret{};
|
||||
if ((res = crypto_hash_sha256_final(&state, ret.data())) != 0) {
|
||||
res = crypto_hash_sha256_final(&state, ret.data());
|
||||
if (res != 0) {
|
||||
throw std::runtime_error("failed to finalize sha256|" +
|
||||
std::to_string(res));
|
||||
}
|
||||
@@ -89,11 +89,9 @@ auto generate_key(const std::string &encryption_token) -> key_type {
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto read_encrypted_range(
|
||||
const http_range &range, const key_type &key,
|
||||
const std::function<api_error(data_buffer &ct, std::uint64_t start_offset,
|
||||
std::uint64_t end_offset)> &reader,
|
||||
std::uint64_t total_size, data_buffer &data) -> api_error {
|
||||
auto read_encrypted_range(const http_range &range, const key_type &key,
|
||||
reader_func reader, std::uint64_t total_size,
|
||||
data_buffer &data) -> api_error {
|
||||
const auto encrypted_chunk_size =
|
||||
utils::encryption::encrypting_reader::get_encrypted_chunk_size();
|
||||
const auto data_chunk_size =
|
||||
@@ -108,31 +106,33 @@ auto read_encrypted_range(
|
||||
auto source_offset = static_cast<std::size_t>(range.begin % data_chunk_size);
|
||||
|
||||
for (std::size_t chunk = start_chunk; chunk <= end_chunk; chunk++) {
|
||||
data_buffer ct;
|
||||
data_buffer cypher;
|
||||
const auto start_offset = chunk * encrypted_chunk_size;
|
||||
const auto end_offset = std::min(
|
||||
start_offset + (total_size - (chunk * data_chunk_size)) + header_size -
|
||||
1U,
|
||||
static_cast<std::uint64_t>(start_offset + encrypted_chunk_size - 1U));
|
||||
|
||||
const auto result = reader(ct, start_offset, end_offset);
|
||||
const auto result = reader(cypher, start_offset, end_offset);
|
||||
if (result != api_error::success) {
|
||||
return result;
|
||||
}
|
||||
|
||||
data_buffer source_buffer;
|
||||
if (not utils::encryption::decrypt_data(key, ct, source_buffer)) {
|
||||
if (not utils::encryption::decrypt_data(key, cypher, source_buffer)) {
|
||||
return api_error::decryption_error;
|
||||
}
|
||||
ct.clear();
|
||||
cypher.clear();
|
||||
|
||||
const auto data_size = static_cast<std::size_t>(std::min(
|
||||
remain, static_cast<std::uint64_t>(data_chunk_size - source_offset)));
|
||||
std::copy(source_buffer.begin() + source_offset,
|
||||
source_buffer.begin() + source_offset + data_size,
|
||||
std::copy(std::next(source_buffer.begin(),
|
||||
static_cast<std::int64_t>(source_offset)),
|
||||
std::next(source_buffer.begin(),
|
||||
static_cast<std::int64_t>(source_offset + data_size)),
|
||||
std::back_inserter(data));
|
||||
remain -= data_size;
|
||||
source_offset = 0u;
|
||||
source_offset = 0U;
|
||||
}
|
||||
|
||||
return api_error::success;
|
||||
|
@@ -26,147 +26,141 @@
|
||||
#include "types/repertory.hpp"
|
||||
|
||||
namespace repertory::utils::error {
|
||||
void raise_error(std::string_view function, std::string_view msg) {
|
||||
void raise_error(std::string function, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function), static_cast<std::string>(msg));
|
||||
function, static_cast<std::string>(msg));
|
||||
}
|
||||
|
||||
void raise_error(std::string_view function, const api_error &e,
|
||||
void raise_error(std::string function, const api_error &err,
|
||||
std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
static_cast<std::string>(msg) + "|err|" + api_error_to_string(e));
|
||||
function,
|
||||
static_cast<std::string>(msg) + "|err|" + api_error_to_string(err));
|
||||
}
|
||||
|
||||
void raise_error(std::string_view function, const std::exception &e,
|
||||
void raise_error(std::string function, const std::exception &exception,
|
||||
std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
function,
|
||||
static_cast<std::string>(msg) + "|err|" +
|
||||
(e.what() ? e.what() : "unknown error"));
|
||||
(exception.what() == nullptr ? "unknown error" : exception.what()));
|
||||
}
|
||||
|
||||
void raise_error(std::string_view function, const json &e,
|
||||
std::string_view msg) {
|
||||
void raise_error(std::string function, const json &err, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
static_cast<std::string>(msg) + "|err|" + e.dump(2));
|
||||
function, static_cast<std::string>(msg) + "|err|" + err.dump(2));
|
||||
}
|
||||
|
||||
void raise_error(std::string_view function, std::int64_t e,
|
||||
std::string_view msg) {
|
||||
void raise_error(std::string function, std::int64_t err, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
static_cast<std::string>(msg) + "|err|" + std::to_string(e));
|
||||
function, static_cast<std::string>(msg) + "|err|" + std::to_string(err));
|
||||
}
|
||||
|
||||
void raise_error(std::string_view function, const api_error &e,
|
||||
void raise_error(std::string function, const api_error &err,
|
||||
std::string_view file_path, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
function, static_cast<std::string>(msg) + "|sp|" +
|
||||
static_cast<std::string>(file_path) + "|err|" +
|
||||
api_error_to_string(err));
|
||||
}
|
||||
|
||||
void raise_error(std::string function, std::int64_t err,
|
||||
std::string_view file_path, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
function, static_cast<std::string>(msg) + "|sp|" +
|
||||
static_cast<std::string>(file_path) + "|err|" +
|
||||
std::to_string(err));
|
||||
}
|
||||
|
||||
void raise_error(std::string function, const std::exception &exception,
|
||||
std::string_view file_path, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
function,
|
||||
static_cast<std::string>(msg) + "|sp|" +
|
||||
static_cast<std::string>(file_path) + "|err|" +
|
||||
api_error_to_string(e));
|
||||
(exception.what() == nullptr ? "unknown error" : exception.what()));
|
||||
}
|
||||
|
||||
void raise_error(std::string_view function, std::int64_t e,
|
||||
std::string_view file_path, std::string_view msg) {
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
const api_error &err, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
static_cast<std::string>(msg) + "|sp|" +
|
||||
static_cast<std::string>(file_path) + "|err|" + std::to_string(e));
|
||||
function, static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|err|" +
|
||||
api_error_to_string(err));
|
||||
}
|
||||
|
||||
void raise_error(std::string_view function, const std::exception &e,
|
||||
std::string_view file_path, std::string_view msg) {
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
std::int64_t err, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
static_cast<std::string>(msg) + "|sp|" +
|
||||
static_cast<std::string>(file_path) + "|err|" +
|
||||
(e.what() ? e.what() : "unknown error"));
|
||||
function, static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|err|" +
|
||||
std::to_string(err));
|
||||
}
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
const api_error &e, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|err|" +
|
||||
api_error_to_string(e));
|
||||
}
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
std::int64_t e, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|err|" + std::to_string(e));
|
||||
}
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
const std::exception &e, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|err|" +
|
||||
(e.what() ? e.what() : "unknown error"));
|
||||
}
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
std::string_view source_path, const api_error &e,
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
const std::exception &exception,
|
||||
std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
function,
|
||||
static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|err|" +
|
||||
(exception.what() == nullptr ? "unknown error" : exception.what()));
|
||||
}
|
||||
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
std::string_view source_path, const api_error &err,
|
||||
std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
function, static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|sp|" +
|
||||
static_cast<std::string>(source_path) + "|err|" +
|
||||
api_error_to_string(err));
|
||||
}
|
||||
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
std::string_view source_path, std::int64_t err,
|
||||
std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
function, static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|sp|" +
|
||||
static_cast<std::string>(source_path) + "|err|" +
|
||||
std::to_string(err));
|
||||
}
|
||||
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
const json &err, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
function, static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|err|" + err.dump(2));
|
||||
}
|
||||
|
||||
void raise_api_path_error(std::string function, std::string_view api_path,
|
||||
std::string_view source_path,
|
||||
const std::exception &exception,
|
||||
std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
function,
|
||||
static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|sp|" +
|
||||
static_cast<std::string>(source_path) + "|err|" +
|
||||
api_error_to_string(e));
|
||||
(exception.what() == nullptr ? "unknown error" : exception.what()));
|
||||
}
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
std::string_view source_path, std::int64_t e,
|
||||
std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|sp|" +
|
||||
static_cast<std::string>(source_path) + "|err|" + std::to_string(e));
|
||||
}
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
const json &e, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|err|" + e.dump(2));
|
||||
}
|
||||
|
||||
void raise_api_path_error(std::string_view function, std::string_view api_path,
|
||||
std::string_view source_path, const std::exception &e,
|
||||
std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
static_cast<std::string>(msg) + "|ap|" +
|
||||
static_cast<std::string>(api_path) + "|sp|" +
|
||||
static_cast<std::string>(source_path) + "|err|" +
|
||||
(e.what() ? e.what() : "unknown error"));
|
||||
}
|
||||
|
||||
void raise_url_error(std::string_view function, std::string_view url,
|
||||
CURLcode e, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
static_cast<std::string>(msg) + "|url|" + static_cast<std::string>(url) +
|
||||
"|err|" + curl_easy_strerror(e));
|
||||
}
|
||||
|
||||
void raise_url_error(std::string_view function, std::string_view url,
|
||||
std::string_view source_path, const std::exception &e,
|
||||
void raise_url_error(std::string function, std::string_view url, CURLcode err,
|
||||
std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
static_cast<std::string>(function),
|
||||
function, static_cast<std::string>(msg) + "|url|" +
|
||||
static_cast<std::string>(url) + "|err|" +
|
||||
curl_easy_strerror(err));
|
||||
}
|
||||
|
||||
void raise_url_error(std::string function, std::string_view url,
|
||||
std::string_view source_path,
|
||||
const std::exception &exception, std::string_view msg) {
|
||||
event_system::instance().raise<repertory_exception>(
|
||||
function,
|
||||
static_cast<std::string>(msg) + "|url|" + static_cast<std::string>(url) +
|
||||
"|sp|" + static_cast<std::string>(source_path) + "|err|" +
|
||||
(e.what() ? e.what() : "unknown error"));
|
||||
(exception.what() == nullptr ? "unknown error" : exception.what()));
|
||||
}
|
||||
} // namespace repertory::utils::error
|
||||
|
@@ -539,7 +539,8 @@ auto is_modified_date_older_than(const std::string &path,
|
||||
return (std::chrono::system_clock::from_time_t(modified) + seconds) <
|
||||
std::chrono::system_clock::now();
|
||||
#else
|
||||
return (modified + (seconds.count() * NANOS_PER_SECOND)) <
|
||||
return (modified +
|
||||
static_cast<std::uint64_t>(seconds.count() * NANOS_PER_SECOND)) <
|
||||
utils::get_time_now();
|
||||
#endif
|
||||
}
|
||||
|
@@ -121,7 +121,7 @@ auto native_file::allocate(std::uint64_t file_size) -> bool {
|
||||
::SetEndOfFile(handle_));
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
return (fallocate(handle_, 0, 0, file_size) >= 0);
|
||||
return (fallocate(handle_, 0, 0, static_cast<off_t>(file_size)) >= 0);
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
return (ftruncate(handle_, file_size) >= 0);
|
||||
@@ -236,11 +236,11 @@ auto native_file::read_bytes(char *buffer, std::size_t read_size,
|
||||
auto native_file::read_bytes(char *buffer, std::size_t read_size,
|
||||
std::uint64_t read_offset, std::size_t &bytes_read)
|
||||
-> bool {
|
||||
bytes_read = 0u;
|
||||
bytes_read = 0U;
|
||||
ssize_t result = 0;
|
||||
do {
|
||||
result = pread64(handle_, &buffer[bytes_read], read_size - bytes_read,
|
||||
read_offset + bytes_read);
|
||||
static_cast<off_t>(read_offset + bytes_read));
|
||||
if (result > 0) {
|
||||
bytes_read += static_cast<size_t>(result);
|
||||
}
|
||||
@@ -257,7 +257,7 @@ auto native_file::truncate(std::uint64_t file_size) -> bool {
|
||||
return (::SetFilePointerEx(handle_, li, nullptr, FILE_BEGIN) &&
|
||||
::SetEndOfFile(handle_));
|
||||
#else
|
||||
return (ftruncate(handle_, file_size) >= 0);
|
||||
return (ftruncate(handle_, static_cast<off_t>(file_size)) >= 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -288,11 +288,12 @@ auto native_file::write_bytes(const char *buffer, std::size_t write_size,
|
||||
auto native_file::write_bytes(const char *buffer, std::size_t write_size,
|
||||
std::uint64_t write_offset,
|
||||
std::size_t &bytes_written) -> bool {
|
||||
bytes_written = 0;
|
||||
ssize_t result = 0;
|
||||
bytes_written = 0U;
|
||||
ssize_t result = 0U;
|
||||
do {
|
||||
result = pwrite64(handle_, &buffer[bytes_written],
|
||||
write_size - bytes_written, write_offset + bytes_written);
|
||||
result =
|
||||
pwrite64(handle_, &buffer[bytes_written], write_size - bytes_written,
|
||||
static_cast<off_t>(write_offset + bytes_written));
|
||||
if (result > 0) {
|
||||
bytes_written += static_cast<size_t>(result);
|
||||
}
|
||||
|
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
#include "utils/rocksdb_utils.hpp"
|
||||
|
||||
#include "app_config.hpp"
|
||||
#include "events/event_system.hpp"
|
||||
#include "types/startup_exception.hpp"
|
||||
#include "utils/error_utils.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
|
||||
namespace repertory::utils::db {
|
||||
void create_rocksdb(const app_config &config, const std::string &name,
|
||||
std::unique_ptr<rocksdb::DB> &db) {
|
||||
rocksdb::Options options{};
|
||||
options.create_if_missing = true;
|
||||
options.db_log_dir = config.get_log_directory();
|
||||
options.keep_log_file_num = 10;
|
||||
|
||||
rocksdb::DB *db_ptr{};
|
||||
const auto status = rocksdb::DB::Open(
|
||||
options, utils::path::combine(config.get_data_directory(), {name}),
|
||||
&db_ptr);
|
||||
if (status.ok()) {
|
||||
db.reset(db_ptr);
|
||||
} else {
|
||||
utils::error::raise_error(__FUNCTION__, status.ToString());
|
||||
throw startup_exception(status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void create_rocksdb(
|
||||
const app_config &config, const std::string &name,
|
||||
const std::vector<rocksdb::ColumnFamilyDescriptor> &families,
|
||||
std::vector<rocksdb::ColumnFamilyHandle *> &handles,
|
||||
std::unique_ptr<rocksdb::DB> &db) {
|
||||
rocksdb::Options options{};
|
||||
options.create_if_missing = true;
|
||||
options.create_missing_column_families = true;
|
||||
options.db_log_dir = config.get_log_directory();
|
||||
options.keep_log_file_num = 10;
|
||||
|
||||
rocksdb::DB *db_ptr{};
|
||||
const auto status = rocksdb::DB::Open(
|
||||
options, utils::path::combine(config.get_data_directory(), {name}),
|
||||
families, &handles, &db_ptr);
|
||||
if (status.ok()) {
|
||||
db.reset(db_ptr);
|
||||
} else {
|
||||
utils::error::raise_error(__FUNCTION__, status.ToString());
|
||||
throw startup_exception(status.ToString());
|
||||
}
|
||||
}
|
||||
} // namespace repertory::utils::db
|
@@ -28,13 +28,13 @@
|
||||
|
||||
namespace repertory::utils {
|
||||
#ifndef __APPLE__
|
||||
auto convert_to_uint64(const pthread_t &t) -> std::uint64_t {
|
||||
return static_cast<std::uint64_t>(t);
|
||||
auto convert_to_uint64(const pthread_t &thread) -> std::uint64_t {
|
||||
return static_cast<std::uint64_t>(thread);
|
||||
}
|
||||
#endif
|
||||
|
||||
auto from_api_error(const api_error &e) -> int {
|
||||
switch (e) {
|
||||
auto from_api_error(const api_error &err) -> int {
|
||||
switch (err) {
|
||||
case api_error::access_denied:
|
||||
return -EACCES;
|
||||
case api_error::bad_address:
|
||||
@@ -107,18 +107,16 @@ auto get_thread_id() -> std::uint64_t {
|
||||
}
|
||||
|
||||
auto is_uid_member_of_group(const uid_t &uid, const gid_t &gid) -> bool {
|
||||
static const auto function_name = __FUNCTION__;
|
||||
|
||||
std::vector<gid_t> groups{};
|
||||
use_getpwuid(uid, [&groups](struct passwd *pw) {
|
||||
use_getpwuid(uid, [&groups](struct passwd *pass) {
|
||||
int group_count{};
|
||||
if (getgrouplist(pw->pw_name, pw->pw_gid, nullptr, &group_count) < 0) {
|
||||
if (getgrouplist(pass->pw_name, pass->pw_gid, nullptr, &group_count) < 0) {
|
||||
groups.resize(static_cast<std::size_t>(group_count));
|
||||
#ifdef __APPLE__
|
||||
getgrouplist(pw->pw_name, pw->pw_gid,
|
||||
getgrouplist(pass->pw_name, pass->pw_gid,
|
||||
reinterpret_cast<int *>(groups.data()), &group_count);
|
||||
#else
|
||||
getgrouplist(pw->pw_name, pw->pw_gid, groups.data(), &group_count);
|
||||
getgrouplist(pass->pw_name, pass->pw_gid, groups.data(), &group_count);
|
||||
#endif
|
||||
}
|
||||
});
|
||||
@@ -126,8 +124,8 @@ auto is_uid_member_of_group(const uid_t &uid, const gid_t &gid) -> bool {
|
||||
return collection_includes(groups, gid);
|
||||
}
|
||||
|
||||
auto to_api_error(int e) -> api_error {
|
||||
switch (abs(e)) {
|
||||
auto to_api_error(int err) -> api_error {
|
||||
switch (abs(err)) {
|
||||
case 0:
|
||||
return api_error::success;
|
||||
case EBADF:
|
||||
@@ -196,8 +194,8 @@ auto to_api_error(int e) -> api_error {
|
||||
|
||||
void set_last_error_code(int error_code) { errno = error_code; }
|
||||
|
||||
auto unix_error_to_windows(int e) -> std::int32_t {
|
||||
switch (e) {
|
||||
auto unix_error_to_windows(int err) -> std::int32_t {
|
||||
switch (err) {
|
||||
case 0:
|
||||
return STATUS_SUCCESS;
|
||||
case EACCES:
|
||||
@@ -236,20 +234,21 @@ auto unix_error_to_windows(int e) -> std::int32_t {
|
||||
}
|
||||
}
|
||||
|
||||
auto unix_time_to_windows_time(const remote::file_time &ts) -> UINT64 {
|
||||
return (ts / 100ull) + 116444736000000000ull;
|
||||
auto unix_time_to_windows_time(const remote::file_time &file_time) -> UINT64 {
|
||||
return (file_time / 100ULL) + 116444736000000000ULL;
|
||||
}
|
||||
|
||||
void use_getpwuid(uid_t uid, std::function<void(struct passwd *pw)> fn) {
|
||||
void use_getpwuid(uid_t uid,
|
||||
std::function<void(struct passwd *pass)> callback) {
|
||||
static std::mutex mtx{};
|
||||
mutex_lock lock{mtx};
|
||||
auto *pw = getpwuid(uid);
|
||||
if (not pw) {
|
||||
auto *temp_pw = getpwuid(uid);
|
||||
if (temp_pw == nullptr) {
|
||||
utils::error::raise_error(__FUNCTION__, "'getpwuid' returned nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
fn(pw);
|
||||
callback(temp_pw);
|
||||
}
|
||||
|
||||
void windows_create_to_unix(const UINT32 &create_options,
|
||||
@@ -257,20 +256,20 @@ void windows_create_to_unix(const UINT32 &create_options,
|
||||
remote::file_mode &mode) {
|
||||
mode = S_IRUSR | S_IWUSR;
|
||||
flags = O_CREAT | O_RDWR;
|
||||
if (create_options & FILE_DIRECTORY_FILE) {
|
||||
if ((create_options & FILE_DIRECTORY_FILE) != 0U) {
|
||||
mode |= S_IXUSR;
|
||||
flags = O_DIRECTORY;
|
||||
}
|
||||
|
||||
if ((granted_access & GENERIC_EXECUTE) ||
|
||||
(granted_access & FILE_GENERIC_EXECUTE) ||
|
||||
(granted_access & FILE_EXECUTE)) {
|
||||
if (((granted_access & GENERIC_EXECUTE) != 0U) ||
|
||||
((granted_access & FILE_GENERIC_EXECUTE) != 0U) ||
|
||||
((granted_access & FILE_EXECUTE) != 0U)) {
|
||||
mode |= (S_IXUSR);
|
||||
}
|
||||
}
|
||||
|
||||
auto windows_time_to_unix_time(std::uint64_t t) -> remote::file_time {
|
||||
return (t - 116444736000000000ull) * 100ull;
|
||||
auto windows_time_to_unix_time(std::uint64_t win_time) -> remote::file_time {
|
||||
return (win_time - 116444736000000000ULL) * 100ULL;
|
||||
}
|
||||
} // namespace repertory::utils
|
||||
|
||||
|
@@ -30,7 +30,6 @@
|
||||
#include "utils/native_file.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include <limits>
|
||||
|
||||
namespace repertory::utils {
|
||||
void calculate_allocation_size(bool directory, std::uint64_t file_size,
|
||||
|
@@ -42,18 +42,18 @@ public:
|
||||
|
||||
const auto DEFAULT_SIA_CONFIG = "{\n"
|
||||
" \"ApiAuth\": \"\",\n"
|
||||
" \"ApiPort\": 11101,\n"
|
||||
" \"ApiPort\": 10000,\n"
|
||||
" \"ApiUser\": \"repertory\",\n"
|
||||
" \"ChunkDownloaderTimeoutSeconds\": 30,\n"
|
||||
" \"EnableChunkDownloaderTimeout\": true,\n"
|
||||
" \"EnableCommDurationEvents\": false,\n"
|
||||
" \"EnableDriveEvents\": false,\n"
|
||||
" \"EnableMaxCacheSize\": true,\n"
|
||||
" \"EnableMaxCacheSize\": false,\n"
|
||||
#ifdef _WIN32
|
||||
" \"EnableMountManager\": false,\n"
|
||||
#endif
|
||||
" \"EventLevel\": \"normal\",\n"
|
||||
" \"EvictionDelayMinutes\": 30,\n"
|
||||
" \"EvictionDelayMinutes\": 10,\n"
|
||||
" \"EvictionUsesAccessedTime\": false,\n"
|
||||
" \"HighFreqIntervalSeconds\": 30,\n"
|
||||
" \"HostConfig\": {\n"
|
||||
@@ -90,18 +90,18 @@ const auto DEFAULT_SIA_CONFIG = "{\n"
|
||||
|
||||
const auto DEFAULT_S3_CONFIG = "{\n"
|
||||
" \"ApiAuth\": \"\",\n"
|
||||
" \"ApiPort\": 11103,\n"
|
||||
" \"ApiPort\": 10100,\n"
|
||||
" \"ApiUser\": \"repertory\",\n"
|
||||
" \"ChunkDownloaderTimeoutSeconds\": 30,\n"
|
||||
" \"EnableChunkDownloaderTimeout\": true,\n"
|
||||
" \"EnableCommDurationEvents\": false,\n"
|
||||
" \"EnableDriveEvents\": false,\n"
|
||||
" \"EnableMaxCacheSize\": true,\n"
|
||||
" \"EnableMaxCacheSize\": false,\n"
|
||||
#ifdef _WIN32
|
||||
" \"EnableMountManager\": false,\n"
|
||||
#endif
|
||||
" \"EventLevel\": \"normal\",\n"
|
||||
" \"EvictionDelayMinutes\": 30,\n"
|
||||
" \"EvictionDelayMinutes\": 10,\n"
|
||||
" \"EvictionUsesAccessedTime\": false,\n"
|
||||
" \"HighFreqIntervalSeconds\": 30,\n"
|
||||
" \"LowFreqIntervalSeconds\": 3600,\n"
|
||||
@@ -117,7 +117,7 @@ const auto DEFAULT_S3_CONFIG = "{\n"
|
||||
" \"RemoteClientPoolSize\": 10,\n"
|
||||
" \"RemoteHostNameOrIp\": \"\",\n"
|
||||
" \"RemoteMaxConnections\": 20,\n"
|
||||
" \"RemotePort\": 20001,\n"
|
||||
" \"RemotePort\": 20100,\n"
|
||||
" \"RemoteReceiveTimeoutSeconds\": 120,\n"
|
||||
" \"RemoteSendTimeoutSeconds\": 30,\n"
|
||||
" \"RemoteToken\": \"\"\n"
|
||||
@@ -179,7 +179,7 @@ TEST_F(config_test, api_path) {
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_api_auth();
|
||||
EXPECT_EQ(48u, original_value.size());
|
||||
EXPECT_EQ(48U, original_value.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ TEST_F(config_test, api_auth) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, api_port) {
|
||||
std::uint16_t original_value;
|
||||
std::uint16_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_api_port();
|
||||
@@ -226,7 +226,7 @@ TEST_F(config_test, api_user) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, chunk_downloader_timeout_secs) {
|
||||
std::uint8_t original_value;
|
||||
std::uint8_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_chunk_downloader_timeout_secs();
|
||||
@@ -240,7 +240,7 @@ TEST_F(config_test, chunk_downloader_timeout_secs) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, enable_chunk_download_timeout) {
|
||||
bool original_value;
|
||||
bool original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_enable_chunk_download_timeout();
|
||||
@@ -254,7 +254,7 @@ TEST_F(config_test, enable_chunk_download_timeout) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, enable_comm_duration_events) {
|
||||
bool original_value;
|
||||
bool original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_enable_comm_duration_events();
|
||||
@@ -268,7 +268,7 @@ TEST_F(config_test, enable_comm_duration_events) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, enable_drive_events) {
|
||||
bool original_value;
|
||||
bool original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_enable_drive_events();
|
||||
@@ -282,7 +282,7 @@ TEST_F(config_test, enable_drive_events) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, enable_max_cache_size) {
|
||||
bool original_value;
|
||||
bool original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_enable_max_cache_size();
|
||||
@@ -324,7 +324,7 @@ TEST_F(config_test, event_level) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, eviction_delay_mins) {
|
||||
std::uint32_t original_value;
|
||||
std::uint32_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_eviction_delay_mins();
|
||||
@@ -338,7 +338,7 @@ TEST_F(config_test, eviction_delay_mins) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, eviction_uses_accessed_time) {
|
||||
bool original_value;
|
||||
bool original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_eviction_uses_accessed_time();
|
||||
@@ -353,7 +353,7 @@ TEST_F(config_test, eviction_uses_accessed_time) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, high_frequency_interval_secs) {
|
||||
std::uint8_t original_value;
|
||||
std::uint8_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_high_frequency_interval_secs();
|
||||
@@ -367,7 +367,7 @@ TEST_F(config_test, high_frequency_interval_secs) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, low_frequency_interval_secs) {
|
||||
std::uint32_t original_value;
|
||||
std::uint32_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_low_frequency_interval_secs();
|
||||
@@ -384,33 +384,33 @@ TEST_F(config_test, max_cache_size_bytes) {
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
config.set_max_cache_size_bytes(100 * 1024 * 1024);
|
||||
EXPECT_EQ(100u * 1024 * 1024, config.get_max_cache_size_bytes());
|
||||
EXPECT_EQ(100U * 1024 * 1024, config.get_max_cache_size_bytes());
|
||||
}
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
EXPECT_EQ(100u * 1024 * 1024, config.get_max_cache_size_bytes());
|
||||
EXPECT_EQ(100U * 1024 * 1024, config.get_max_cache_size_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(config_test, max_upload_count) {
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
config.set_max_upload_count(8u);
|
||||
EXPECT_EQ(std::uint8_t(8u), config.get_max_upload_count());
|
||||
config.set_max_upload_count(8U);
|
||||
EXPECT_EQ(std::uint8_t(8U), config.get_max_upload_count());
|
||||
}
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
EXPECT_EQ(std::uint8_t(8u), config.get_max_upload_count());
|
||||
EXPECT_EQ(std::uint8_t(8U), config.get_max_upload_count());
|
||||
}
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
config.set_max_upload_count(0u);
|
||||
EXPECT_EQ(std::uint8_t(1u), config.get_max_upload_count());
|
||||
config.set_max_upload_count(0U);
|
||||
EXPECT_EQ(std::uint8_t(1U), config.get_max_upload_count());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(config_test, online_check_retry_secs) {
|
||||
std::uint16_t original_value;
|
||||
std::uint16_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_online_check_retry_secs();
|
||||
@@ -432,7 +432,7 @@ TEST_F(config_test, online_check_retry_secs_minimum_value) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, orphaned_file_retention_days) {
|
||||
std::uint16_t original_value;
|
||||
std::uint16_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_orphaned_file_retention_days();
|
||||
@@ -462,7 +462,7 @@ TEST_F(config_test, orphaned_file_retention_days_maximum_value) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, read_ahead_count) {
|
||||
std::uint8_t original_value;
|
||||
std::uint8_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_read_ahead_count();
|
||||
@@ -567,11 +567,11 @@ TEST_F(config_test, default_agent_name) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, default_api_port) {
|
||||
EXPECT_EQ(9980u, app_config::default_api_port(provider_type::sia));
|
||||
EXPECT_EQ(9980U, app_config::default_api_port(provider_type::sia));
|
||||
}
|
||||
|
||||
TEST_F(config_test, default_data_directory) {
|
||||
const std::string data_directory[] = {
|
||||
const std::array<std::string, 1U> data_directory = {
|
||||
app_config::default_data_directory(provider_type::sia),
|
||||
};
|
||||
|
||||
@@ -592,7 +592,7 @@ TEST_F(config_test, default_data_directory) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, default_rpc_port) {
|
||||
EXPECT_EQ(11101u, app_config::default_rpc_port(provider_type::sia));
|
||||
EXPECT_EQ(10000U, app_config::default_rpc_port(provider_type::sia));
|
||||
}
|
||||
|
||||
TEST_F(config_test, get_provider_display_name) {
|
||||
@@ -613,7 +613,7 @@ TEST_F(config_test, get_version) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, enable_remote_mount) {
|
||||
bool original_value;
|
||||
bool original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_enable_remote_mount();
|
||||
@@ -627,7 +627,7 @@ TEST_F(config_test, enable_remote_mount) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, is_remote_mount) {
|
||||
bool original_value;
|
||||
bool original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_is_remote_mount();
|
||||
@@ -669,7 +669,7 @@ TEST_F(config_test, remote_host_name_or_ip) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, remote_port) {
|
||||
std::uint16_t original_value;
|
||||
std::uint16_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_remote_port();
|
||||
@@ -683,7 +683,7 @@ TEST_F(config_test, remote_port) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, remote_receive_timeout_secs) {
|
||||
std::uint16_t original_value;
|
||||
std::uint16_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_remote_receive_timeout_secs();
|
||||
@@ -697,7 +697,7 @@ TEST_F(config_test, remote_receive_timeout_secs) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, remote_send_timeout_secs) {
|
||||
std::uint16_t original_value;
|
||||
std::uint16_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_remote_send_timeout_secs();
|
||||
@@ -723,7 +723,7 @@ TEST_F(config_test, remote_token) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, remote_client_pool_size) {
|
||||
std::uint8_t original_value;
|
||||
std::uint8_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_remote_client_pool_size();
|
||||
@@ -749,7 +749,7 @@ TEST_F(config_test, remote_client_pool_size_minimum_value) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, remote_max_connections) {
|
||||
std::uint8_t original_value;
|
||||
std::uint8_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_remote_max_connections();
|
||||
@@ -775,7 +775,7 @@ TEST_F(config_test, remote_max_connections_minimum_value) {
|
||||
}
|
||||
|
||||
TEST_F(config_test, retry_read_count) {
|
||||
std::uint16_t original_value;
|
||||
std::uint16_t original_value{};
|
||||
{
|
||||
app_config config(provider_type::sia, "./data");
|
||||
original_value = config.get_retry_read_count();
|
||||
@@ -801,7 +801,7 @@ TEST_F(config_test, cache_timeout_seconds_minimum_value) {
|
||||
app_config config(provider_type::s3, "./data");
|
||||
EXPECT_FALSE(
|
||||
config.set_value_by_name("S3Config.CacheTimeoutSeconds", "1").empty());
|
||||
EXPECT_EQ(std::uint16_t(5u), config.get_s3_config().cache_timeout_secs);
|
||||
EXPECT_EQ(std::uint16_t(5U), config.get_s3_config().cache_timeout_secs);
|
||||
}
|
||||
}
|
||||
} // namespace repertory
|
||||
|
124
tests/database_test.cpp
Normal file
124
tests/database_test.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
#include "test_common.hpp"
|
||||
|
||||
#include "database/db_common.hpp"
|
||||
#include "database/db_insert.hpp"
|
||||
#include "database/db_select.hpp"
|
||||
#include "utils/path_utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
TEST(database, db_insert) {
|
||||
console_consumer consumer1;
|
||||
event_system::instance().start();
|
||||
{
|
||||
db3_t db3;
|
||||
{
|
||||
sqlite3 *db3_ptr{nullptr};
|
||||
auto res = sqlite3_open_v2(
|
||||
utils::path::absolute(
|
||||
utils::path::combine(get_test_dir(), {"test.db3"}))
|
||||
.c_str(),
|
||||
&db3_ptr, SQLITE_OPEN_READWRITE, nullptr);
|
||||
ASSERT_EQ(SQLITE_OK, res);
|
||||
ASSERT_TRUE(db3_ptr != nullptr);
|
||||
|
||||
db3.reset(db3_ptr);
|
||||
}
|
||||
|
||||
auto query = db::db_insert{*db3.get(), "table"}
|
||||
.column_value("column1", "test9")
|
||||
.column_value("column2", "test9");
|
||||
auto query_str = query.dump();
|
||||
std::cout << query_str << std::endl;
|
||||
EXPECT_STREQ(
|
||||
R"(INSERT INTO "table" ("column1", "column2") VALUES (?1, ?2);)",
|
||||
query_str.c_str());
|
||||
|
||||
query = db::db_insert{*db3.get(), "table"}
|
||||
.or_replace()
|
||||
.column_value("column1", "test1")
|
||||
.column_value("column2", "test2");
|
||||
query_str = query.dump();
|
||||
std::cout << query_str << std::endl;
|
||||
EXPECT_STREQ(
|
||||
R"(INSERT OR REPLACE INTO "table" ("column1", "column2") VALUES (?1, ?2);)",
|
||||
query_str.c_str());
|
||||
|
||||
auto res = query.go();
|
||||
EXPECT_TRUE(res.ok());
|
||||
EXPECT_FALSE(res.has_row());
|
||||
}
|
||||
|
||||
event_system::instance().stop();
|
||||
}
|
||||
|
||||
TEST(database, db_select) {
|
||||
console_consumer consumer1;
|
||||
event_system::instance().start();
|
||||
{
|
||||
db3_t db3;
|
||||
{
|
||||
sqlite3 *db3_ptr{nullptr};
|
||||
auto res = sqlite3_open_v2(
|
||||
utils::path::combine(get_test_dir(), {"test.db3"}).c_str(), &db3_ptr,
|
||||
SQLITE_OPEN_READWRITE, nullptr);
|
||||
ASSERT_EQ(SQLITE_OK, res);
|
||||
ASSERT_TRUE(db3_ptr != nullptr);
|
||||
|
||||
db3.reset(db3_ptr);
|
||||
}
|
||||
|
||||
auto query = db::db_select{*db3.get(), "table"}
|
||||
.where("column1")
|
||||
.equals("test1")
|
||||
.and_where("column2")
|
||||
.equals("test2");
|
||||
auto query_str = query.dump();
|
||||
std::cout << query_str << std::endl;
|
||||
EXPECT_STREQ(
|
||||
R"(SELECT * FROM "table" WHERE ("column1"=?1 AND "column2"=?2);)",
|
||||
query_str.c_str());
|
||||
auto res = query.go();
|
||||
|
||||
EXPECT_TRUE(res.ok());
|
||||
EXPECT_TRUE(res.has_row());
|
||||
std::size_t row_count{};
|
||||
while (res.has_row()) {
|
||||
std::optional<db::db_select::row> row;
|
||||
EXPECT_TRUE(res.get_row(row));
|
||||
EXPECT_TRUE(row.has_value());
|
||||
if (row.has_value()) {
|
||||
for (const auto &column : row.value().get_columns()) {
|
||||
std::cout << column.get_index() << ':';
|
||||
std::cout << column.get_name() << ':';
|
||||
std::cout << column.get_value<std::string>() << std::endl;
|
||||
}
|
||||
}
|
||||
++row_count;
|
||||
}
|
||||
EXPECT_EQ(std::size_t(1U), row_count);
|
||||
}
|
||||
|
||||
event_system::instance().stop();
|
||||
}
|
||||
} // namespace repertory
|
@@ -1 +1 @@
|
||||
test
|
||||
test
|
||||
|
@@ -1 +1 @@
|
||||
moose
|
||||
moose
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#include "utils/path_utils.hpp"
|
||||
|
||||
namespace repertory {
|
||||
static std::string get_source_file_name() {
|
||||
static auto get_source_file_name() -> std::string {
|
||||
return generate_test_file_name("./", "encrypting_reader");
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ TEST(encrypting_reader, get_encrypted_file_name) {
|
||||
ASSERT_TRUE(utils::file::retry_delete_file(source_file_name));
|
||||
|
||||
const auto token = std::string("moose");
|
||||
auto source_file = create_random_file(source_file_name, 1024ul);
|
||||
auto source_file = create_random_file(source_file_name, 1024UL);
|
||||
EXPECT_TRUE(source_file != nullptr);
|
||||
if (source_file) {
|
||||
stop_type stop_requested = false;
|
||||
@@ -64,20 +64,20 @@ TEST(encrypting_reader, file_data) {
|
||||
const auto token = std::string("moose");
|
||||
auto source_file = create_random_file(
|
||||
source_file_name,
|
||||
8u * utils::encryption::encrypting_reader::get_data_chunk_size());
|
||||
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
|
||||
EXPECT_TRUE(source_file != nullptr);
|
||||
if (source_file) {
|
||||
stop_type stop_requested = false;
|
||||
utils::encryption::encrypting_reader reader("test.dat", source_file_name,
|
||||
stop_requested, token);
|
||||
|
||||
for (std::uint8_t i = 0u; i < 8u; i++) {
|
||||
for (std::uint8_t i = 0U; i < 8U; i++) {
|
||||
data_buffer buffer(
|
||||
utils::encryption::encrypting_reader::get_encrypted_chunk_size());
|
||||
for (std::uint8_t j = 0u; j < 2u; j++) {
|
||||
EXPECT_EQ(buffer.size() / 2u,
|
||||
for (std::uint8_t j = 0U; j < 2U; j++) {
|
||||
EXPECT_EQ(buffer.size() / 2U,
|
||||
utils::encryption::encrypting_reader::reader_function(
|
||||
&buffer[(buffer.size() / 2u) * j], buffer.size() / 2u, 1u,
|
||||
&buffer[(buffer.size() / 2U) * j], buffer.size() / 2U, 1U,
|
||||
&reader));
|
||||
}
|
||||
|
||||
@@ -91,10 +91,10 @@ TEST(encrypting_reader, file_data) {
|
||||
std::size_t bytes_read{};
|
||||
data_buffer file_data(decrypted_data.size());
|
||||
EXPECT_TRUE(source_file->read_bytes(
|
||||
&file_data[0u], file_data.size(),
|
||||
file_data.data(), file_data.size(),
|
||||
utils::encryption::encrypting_reader::get_data_chunk_size() * i,
|
||||
bytes_read));
|
||||
EXPECT_EQ(0, std::memcmp(&file_data[0u], &decrypted_data[0u],
|
||||
EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(),
|
||||
file_data.size()));
|
||||
}
|
||||
|
||||
@@ -110,28 +110,30 @@ TEST(encrypting_reader, file_data_in_multiple_chunks) {
|
||||
const auto token = std::string("moose");
|
||||
auto source_file = create_random_file(
|
||||
source_file_name,
|
||||
8u * utils::encryption::encrypting_reader::get_data_chunk_size());
|
||||
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
|
||||
EXPECT_TRUE(source_file != nullptr);
|
||||
if (source_file) {
|
||||
stop_type stop_requested = false;
|
||||
utils::encryption::encrypting_reader reader("test.dat", source_file_name,
|
||||
stop_requested, token);
|
||||
|
||||
for (std::uint8_t i = 0u; i < 8u; i += 2u) {
|
||||
for (std::uint8_t i = 0U; i < 8U; i += 2U) {
|
||||
data_buffer buffer(
|
||||
utils::encryption::encrypting_reader::get_encrypted_chunk_size() *
|
||||
2u);
|
||||
2U);
|
||||
EXPECT_EQ(buffer.size(),
|
||||
utils::encryption::encrypting_reader::reader_function(
|
||||
&buffer[0u], buffer.size(), 1u, &reader));
|
||||
buffer.data(), buffer.size(), 1U, &reader));
|
||||
|
||||
for (std::uint8_t j = 0u; j < 2u; j++) {
|
||||
for (std::uint8_t j = 0U; j < 2U; j++) {
|
||||
data_buffer decrypted_data;
|
||||
const auto offset = (j * (buffer.size() / 2u));
|
||||
const auto offset = (j * (buffer.size() / 2U));
|
||||
EXPECT_TRUE(utils::encryption::decrypt_data(
|
||||
token,
|
||||
data_buffer(buffer.begin() + offset,
|
||||
buffer.begin() + offset + (buffer.size() / 2u)),
|
||||
data_buffer(
|
||||
std::next(buffer.begin(), static_cast<std::int64_t>(offset)),
|
||||
std::next(buffer.begin(), static_cast<std::int64_t>(
|
||||
offset + (buffer.size() / 2U)))),
|
||||
decrypted_data));
|
||||
|
||||
EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(),
|
||||
@@ -140,12 +142,12 @@ TEST(encrypting_reader, file_data_in_multiple_chunks) {
|
||||
std::size_t bytes_read{};
|
||||
data_buffer file_data(decrypted_data.size());
|
||||
EXPECT_TRUE(source_file->read_bytes(
|
||||
&file_data[0u], file_data.size(),
|
||||
file_data.data(), file_data.size(),
|
||||
(utils::encryption::encrypting_reader::get_data_chunk_size() * i) +
|
||||
(j *
|
||||
utils::encryption::encrypting_reader::get_data_chunk_size()),
|
||||
bytes_read));
|
||||
EXPECT_EQ(0, std::memcmp(&file_data[0u], &decrypted_data[0u],
|
||||
EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(),
|
||||
file_data.size()));
|
||||
}
|
||||
}
|
||||
@@ -163,7 +165,7 @@ TEST(encrypting_reader, file_data_as_stream) {
|
||||
const auto token = std::string("moose");
|
||||
auto source_file = create_random_file(
|
||||
source_file_name,
|
||||
8u * utils::encryption::encrypting_reader::get_data_chunk_size());
|
||||
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
|
||||
EXPECT_TRUE(source_file != nullptr);
|
||||
if (source_file) {
|
||||
stop_type stop_requested = false;
|
||||
@@ -177,15 +179,18 @@ TEST(encrypting_reader, file_data_as_stream) {
|
||||
EXPECT_FALSE(io_stream->seekg(0, std::ios_base::beg).fail());
|
||||
EXPECT_TRUE(io_stream->good());
|
||||
|
||||
for (std::uint8_t i = 0u; i < 8u; i++) {
|
||||
for (std::uint8_t i = 0U; i < 8U; i++) {
|
||||
data_buffer buffer(
|
||||
utils::encryption::encrypting_reader::get_encrypted_chunk_size());
|
||||
EXPECT_FALSE(io_stream->seekg(i * buffer.size()).fail());
|
||||
EXPECT_FALSE(
|
||||
io_stream->seekg(static_cast<std::streamoff>(i * buffer.size()))
|
||||
.fail());
|
||||
EXPECT_TRUE(io_stream->good());
|
||||
for (std::uint8_t j = 0u; j < 2u; j++) {
|
||||
for (std::uint8_t j = 0U; j < 2U; j++) {
|
||||
EXPECT_FALSE(
|
||||
io_stream
|
||||
->read(&buffer[(buffer.size() / 2u) * j], buffer.size() / 2u)
|
||||
->read(&buffer[(buffer.size() / 2U) * j],
|
||||
static_cast<std::streamsize>(buffer.size()) / 2U)
|
||||
.fail());
|
||||
EXPECT_TRUE(io_stream->good());
|
||||
}
|
||||
@@ -200,10 +205,10 @@ TEST(encrypting_reader, file_data_as_stream) {
|
||||
std::size_t bytes_read{};
|
||||
data_buffer file_data(decrypted_data.size());
|
||||
EXPECT_TRUE(source_file->read_bytes(
|
||||
&file_data[0u], file_data.size(),
|
||||
file_data.data(), file_data.size(),
|
||||
utils::encryption::encrypting_reader::get_data_chunk_size() * i,
|
||||
bytes_read));
|
||||
EXPECT_EQ(0, std::memcmp(&file_data[0u], &decrypted_data[0u],
|
||||
EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(),
|
||||
file_data.size()));
|
||||
}
|
||||
|
||||
@@ -233,20 +238,25 @@ TEST(encrypting_reader, file_data_in_multiple_chunks_as_stream) {
|
||||
EXPECT_FALSE(io_stream->seekg(0, std::ios_base::beg).fail());
|
||||
EXPECT_TRUE(io_stream->good());
|
||||
|
||||
for (std::uint8_t i = 0u; i < 8u; i += 2u) {
|
||||
for (std::uint8_t i = 0U; i < 8U; i += 2U) {
|
||||
data_buffer buffer(
|
||||
utils::encryption::encrypting_reader::get_encrypted_chunk_size() *
|
||||
2u);
|
||||
EXPECT_FALSE(io_stream->read(&buffer[0u], buffer.size()).fail());
|
||||
2U);
|
||||
EXPECT_FALSE(
|
||||
io_stream
|
||||
->read(buffer.data(), static_cast<std::streamsize>(buffer.size()))
|
||||
.fail());
|
||||
EXPECT_TRUE(io_stream->good());
|
||||
|
||||
for (std::uint8_t j = 0u; j < 2u; j++) {
|
||||
for (std::uint8_t j = 0U; j < 2U; j++) {
|
||||
data_buffer decrypted_data;
|
||||
const auto offset = (j * (buffer.size() / 2u));
|
||||
const auto offset = (j * (buffer.size() / 2U));
|
||||
EXPECT_TRUE(utils::encryption::decrypt_data(
|
||||
token,
|
||||
data_buffer(buffer.begin() + offset,
|
||||
buffer.begin() + offset + (buffer.size() / 2u)),
|
||||
data_buffer(
|
||||
std::next(buffer.begin(), static_cast<std::int64_t>(offset)),
|
||||
std::next(buffer.begin(), static_cast<std::int64_t>(
|
||||
offset + (buffer.size() / 2U)))),
|
||||
decrypted_data));
|
||||
|
||||
EXPECT_EQ(utils::encryption::encrypting_reader::get_data_chunk_size(),
|
||||
@@ -255,12 +265,12 @@ TEST(encrypting_reader, file_data_in_multiple_chunks_as_stream) {
|
||||
std::size_t bytes_read{};
|
||||
data_buffer file_data(decrypted_data.size());
|
||||
EXPECT_TRUE(source_file->read_bytes(
|
||||
&file_data[0u], file_data.size(),
|
||||
file_data.data(), file_data.size(),
|
||||
(utils::encryption::encrypting_reader::get_data_chunk_size() * i) +
|
||||
(j *
|
||||
utils::encryption::encrypting_reader::get_data_chunk_size()),
|
||||
bytes_read));
|
||||
EXPECT_EQ(0, std::memcmp(&file_data[0u], &decrypted_data[0u],
|
||||
EXPECT_EQ(0, std::memcmp(file_data.data(), decrypted_data.data(),
|
||||
file_data.size()));
|
||||
}
|
||||
}
|
||||
|
@@ -319,11 +319,9 @@ TEST(open_file, write_new_file) {
|
||||
return api_error::success;
|
||||
});
|
||||
|
||||
EXPECT_CALL(um, remove_upload)
|
||||
.Times(2)
|
||||
.WillRepeatedly([&fsi](const std::string &api_path) {
|
||||
EXPECT_EQ(fsi.api_path, api_path);
|
||||
});
|
||||
EXPECT_CALL(um, remove_upload).WillOnce([&fsi](const std::string &api_path) {
|
||||
EXPECT_EQ(fsi.api_path, api_path);
|
||||
});
|
||||
|
||||
EXPECT_CALL(um, queue_upload).WillOnce([&fsi](const i_open_file &cur_file) {
|
||||
EXPECT_EQ(fsi.api_path, cur_file.get_api_path());
|
||||
@@ -408,11 +406,9 @@ TEST(open_file, write_new_file_multiple_chunks) {
|
||||
return api_error::success;
|
||||
});
|
||||
|
||||
EXPECT_CALL(um, remove_upload)
|
||||
.Times(4)
|
||||
.WillRepeatedly([&fsi](const std::string &api_path) {
|
||||
EXPECT_EQ(fsi.api_path, api_path);
|
||||
});
|
||||
EXPECT_CALL(um, remove_upload).WillOnce([&fsi](const std::string &api_path) {
|
||||
EXPECT_EQ(fsi.api_path, api_path);
|
||||
});
|
||||
|
||||
EXPECT_CALL(um, queue_upload).WillOnce([&fsi](const i_open_file &cur_file) {
|
||||
EXPECT_EQ(fsi.api_path, cur_file.get_api_path());
|
||||
|
@@ -81,7 +81,7 @@ TEST(file_manager, can_start_and_stop) {
|
||||
}
|
||||
|
||||
event_system::instance().stop();
|
||||
EXPECT_TRUE(utils::file::delete_directory_recursively("./fm_test"));
|
||||
// EXPECT_TRUE(utils::file::delete_directory_recursively("./fm_test"));
|
||||
}
|
||||
|
||||
TEST(file_manager, can_create_and_close_file) {
|
||||
@@ -94,10 +94,13 @@ TEST(file_manager, can_create_and_close_file) {
|
||||
mock_provider mp;
|
||||
|
||||
EXPECT_CALL(mp, is_direct_only()).WillRepeatedly(Return(false));
|
||||
polling::instance().start(&cfg);
|
||||
|
||||
file_manager fm(cfg, mp);
|
||||
fm.start();
|
||||
|
||||
event_capture capture({
|
||||
"item_timeout",
|
||||
"filesystem_item_opened",
|
||||
"filesystem_item_handle_opened",
|
||||
"filesystem_item_handle_closed",
|
||||
@@ -184,12 +187,16 @@ TEST(file_manager, can_create_and_close_file) {
|
||||
|
||||
fm.close(handle);
|
||||
|
||||
EXPECT_EQ(std::size_t(0u), fm.get_open_file_count());
|
||||
EXPECT_EQ(std::size_t(1u), fm.get_open_file_count());
|
||||
EXPECT_EQ(std::size_t(0u), fm.get_open_handle_count());
|
||||
|
||||
capture.wait_for_empty();
|
||||
EXPECT_EQ(std::size_t(0u), fm.get_open_file_count());
|
||||
|
||||
fm.stop();
|
||||
}
|
||||
|
||||
polling::instance().stop();
|
||||
event_system::instance().stop();
|
||||
EXPECT_TRUE(utils::file::delete_directory_recursively("./fm_test"));
|
||||
}
|
||||
@@ -205,9 +212,12 @@ TEST(file_manager, can_open_and_close_file) {
|
||||
|
||||
EXPECT_CALL(mp, is_direct_only()).WillRepeatedly(Return(false));
|
||||
|
||||
polling::instance().start(&cfg);
|
||||
file_manager fm(cfg, mp);
|
||||
fm.start();
|
||||
|
||||
event_capture capture({
|
||||
"item_timeout",
|
||||
"filesystem_item_opened",
|
||||
"filesystem_item_handle_opened",
|
||||
"filesystem_item_handle_closed",
|
||||
@@ -293,12 +303,16 @@ TEST(file_manager, can_open_and_close_file) {
|
||||
|
||||
fm.close(handle);
|
||||
|
||||
EXPECT_EQ(std::size_t(0u), fm.get_open_file_count());
|
||||
EXPECT_EQ(std::size_t(1u), fm.get_open_file_count());
|
||||
EXPECT_EQ(std::size_t(0u), fm.get_open_handle_count());
|
||||
|
||||
capture.wait_for_empty();
|
||||
EXPECT_EQ(std::size_t(0u), fm.get_open_file_count());
|
||||
|
||||
fm.stop();
|
||||
}
|
||||
|
||||
polling::instance().stop();
|
||||
event_system::instance().stop();
|
||||
EXPECT_TRUE(utils::file::delete_directory_recursively("./fm_test"));
|
||||
}
|
||||
@@ -314,7 +328,9 @@ TEST(file_manager, can_open_and_close_multiple_handles_for_same_file) {
|
||||
|
||||
EXPECT_CALL(mp, is_direct_only()).WillRepeatedly(Return(false));
|
||||
|
||||
polling::instance().start(&cfg);
|
||||
file_manager fm(cfg, mp);
|
||||
fm.start();
|
||||
|
||||
{
|
||||
const auto source_path = utils::path::combine(
|
||||
@@ -362,12 +378,14 @@ TEST(file_manager, can_open_and_close_multiple_handles_for_same_file) {
|
||||
EXPECT_EQ(std::size_t(handles.size() - i), fm.get_open_handle_count());
|
||||
fm.close(handles[i]);
|
||||
}
|
||||
fm.stop();
|
||||
}
|
||||
|
||||
EXPECT_EQ(std::size_t(0u), fm.get_open_file_count());
|
||||
EXPECT_EQ(std::size_t(0u), fm.get_open_handle_count());
|
||||
}
|
||||
|
||||
polling::instance().stop();
|
||||
event_system::instance().stop();
|
||||
EXPECT_TRUE(utils::file::delete_directory_recursively("./fm_test"));
|
||||
}
|
||||
@@ -537,6 +555,7 @@ TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
|
||||
|
||||
EXPECT_CALL(mp, is_direct_only()).WillRepeatedly(Return(false));
|
||||
|
||||
polling::instance().start(&cfg);
|
||||
file_manager fm(cfg, mp);
|
||||
fm.start();
|
||||
|
||||
@@ -624,7 +643,8 @@ TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
|
||||
upload_file("/test_write_full_download.txt", source_path, _))
|
||||
.WillOnce(Return(api_error::success));
|
||||
|
||||
event_capture ec2({"file_upload_queued", "file_upload_completed"});
|
||||
event_capture ec2(
|
||||
{"item_timeout", "file_upload_queued", "file_upload_completed"});
|
||||
fm.close(handle);
|
||||
|
||||
ec2.wait_for_empty();
|
||||
@@ -637,6 +657,7 @@ TEST(file_manager, upload_occurs_after_write_if_fully_downloaded) {
|
||||
nf->close();
|
||||
}
|
||||
|
||||
polling::instance().stop();
|
||||
event_system::instance().stop();
|
||||
EXPECT_TRUE(utils::file::delete_directory_recursively("./fm_test"));
|
||||
}
|
||||
@@ -1315,6 +1336,9 @@ TEST(file_manager,
|
||||
EXPECT_CALL(mp, set_item_meta("/test_open.txt", META_SOURCE, _))
|
||||
.WillOnce(Return(api_error::success));
|
||||
|
||||
EXPECT_CALL(*non_writeable, has_handle(1)).WillOnce([]() -> bool {
|
||||
return true;
|
||||
});
|
||||
EXPECT_TRUE(fm.get_open_file(handle, true, f));
|
||||
EXPECT_NE(non_writeable.get(), f.get());
|
||||
EXPECT_EQ(std::size_t(1U), fm.get_open_file_count());
|
||||
@@ -1495,6 +1519,10 @@ TEST(file_manager, open_file_creates_source_path_if_empty) {
|
||||
#else
|
||||
EXPECT_EQ(api_error::success, fm.open(of, O_RDWR, handle, f));
|
||||
#endif
|
||||
EXPECT_CALL(*of, has_handle(1)).Times(2).WillRepeatedly([]() -> bool {
|
||||
return true;
|
||||
});
|
||||
|
||||
EXPECT_TRUE(fm.get_open_file(1U, true, f));
|
||||
EXPECT_EQ(std::size_t(1U), fm.get_open_file_count());
|
||||
EXPECT_TRUE(f);
|
||||
@@ -1546,6 +1574,8 @@ TEST(file_manager, open_file_first_file_handle_is_not_zero) {
|
||||
#else
|
||||
EXPECT_EQ(api_error::success, fm.open(of, O_RDWR, handle, f));
|
||||
#endif
|
||||
EXPECT_CALL(*of, has_handle(1)).WillOnce([]() -> bool { return true; });
|
||||
|
||||
EXPECT_TRUE(fm.get_open_file(1U, true, f));
|
||||
EXPECT_GT(handle, std::uint64_t(0U));
|
||||
}
|
||||
@@ -1702,8 +1732,8 @@ TEST(file_manager, file_is_closed_after_download_timeout) {
|
||||
const auto source_path = utils::path::combine(
|
||||
cfg.get_cache_directory(), {utils::create_uuid_string()});
|
||||
|
||||
event_consumer es("download_timeout", [](const event &e) {
|
||||
const auto &ee = dynamic_cast<const download_timeout &>(e);
|
||||
event_consumer es("item_timeout", [](const event &e) {
|
||||
const auto &ee = dynamic_cast<const item_timeout &>(e);
|
||||
EXPECT_STREQ("/test_download_timeout.txt",
|
||||
ee.get_api_path().get<std::string>().c_str());
|
||||
});
|
||||
@@ -1728,7 +1758,7 @@ TEST(file_manager, file_is_closed_after_download_timeout) {
|
||||
return api_error::success;
|
||||
});
|
||||
|
||||
event_capture ec({"download_timeout"});
|
||||
event_capture ec({"item_timeout"});
|
||||
|
||||
std::uint64_t handle{};
|
||||
std::shared_ptr<i_open_file> f;
|
||||
|
@@ -128,36 +128,36 @@ static void unlink_file_and_test(const std::string &file_path) {
|
||||
EXPECT_FALSE(utils::file::is_file(file_path));
|
||||
}
|
||||
|
||||
static void test_chmod(const std::string &api_path,
|
||||
static void test_chmod(const std::string & /* api_path */,
|
||||
const std::string &file_path) {
|
||||
std::cout << __FUNCTION__ << std::endl;
|
||||
EXPECT_EQ(0, chmod(file_path.c_str(), S_IRUSR | S_IWUSR));
|
||||
std::this_thread::sleep_for(SLEEP_SECONDS);
|
||||
|
||||
struct stat64 path_stat {};
|
||||
stat64(file_path.c_str(), &path_stat);
|
||||
struct stat64 unix_st {};
|
||||
stat64(file_path.c_str(), &unix_st);
|
||||
EXPECT_EQ(static_cast<std::uint32_t>(S_IRUSR | S_IWUSR),
|
||||
ACCESSPERMS & path_stat.st_mode);
|
||||
ACCESSPERMS & unix_st.st_mode);
|
||||
}
|
||||
|
||||
static void test_chown(const std::string &api_path,
|
||||
static void test_chown(const std::string & /* api_path */,
|
||||
const std::string &file_path) {
|
||||
std::cout << __FUNCTION__ << std::endl;
|
||||
EXPECT_EQ(0, chown(file_path.c_str(), -1, 0));
|
||||
EXPECT_EQ(0, chown(file_path.c_str(), static_cast<uid_t>(-1), 0));
|
||||
std::this_thread::sleep_for(SLEEP_SECONDS);
|
||||
|
||||
struct stat64 path_stat {};
|
||||
stat64(file_path.c_str(), &path_stat);
|
||||
EXPECT_EQ(0, path_stat.st_gid);
|
||||
struct stat64 unix_st {};
|
||||
stat64(file_path.c_str(), &unix_st);
|
||||
EXPECT_EQ(0U, unix_st.st_gid);
|
||||
|
||||
EXPECT_EQ(0, chown(file_path.c_str(), 0, -1));
|
||||
EXPECT_EQ(0, chown(file_path.c_str(), 0, static_cast<gid_t>(-1)));
|
||||
std::this_thread::sleep_for(SLEEP_SECONDS);
|
||||
|
||||
stat64(file_path.c_str(), &path_stat);
|
||||
EXPECT_EQ(0, path_stat.st_gid);
|
||||
stat64(file_path.c_str(), &unix_st);
|
||||
EXPECT_EQ(0U, unix_st.st_gid);
|
||||
}
|
||||
|
||||
static void test_mkdir(const std::string &api_path,
|
||||
static void test_mkdir(const std::string & /* api_path */,
|
||||
const std::string &directory_path) {
|
||||
std::cout << __FUNCTION__ << std::endl;
|
||||
EXPECT_EQ(0, mkdir(directory_path.c_str(),
|
||||
@@ -166,18 +166,18 @@ static void test_mkdir(const std::string &api_path,
|
||||
EXPECT_TRUE(utils::file::is_directory(directory_path));
|
||||
EXPECT_FALSE(utils::file::is_file(directory_path));
|
||||
|
||||
struct stat64 path_stat {};
|
||||
stat64(directory_path.c_str(), &path_stat);
|
||||
struct stat64 unix_st {};
|
||||
stat64(directory_path.c_str(), &unix_st);
|
||||
|
||||
EXPECT_EQ(getuid(), path_stat.st_uid);
|
||||
EXPECT_EQ(getgid(), path_stat.st_gid);
|
||||
EXPECT_EQ(getuid(), unix_st.st_uid);
|
||||
EXPECT_EQ(getgid(), unix_st.st_gid);
|
||||
|
||||
EXPECT_EQ(static_cast<std::uint32_t>(S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
|
||||
S_IXGRP),
|
||||
ACCESSPERMS & path_stat.st_mode);
|
||||
ACCESSPERMS & unix_st.st_mode);
|
||||
}
|
||||
|
||||
static void test_write_and_read(const std::string &api_path,
|
||||
static void test_write_and_read(const std::string & /* api_path */,
|
||||
const std::string &file_path) {
|
||||
std::cout << __FUNCTION__ << std::endl;
|
||||
auto fd =
|
||||
@@ -280,30 +280,27 @@ static void test_ftruncate(const std::string &file_path) {
|
||||
|
||||
#ifndef __APPLE__
|
||||
static void test_fallocate(const std::string &api_path,
|
||||
const std::string &file_path) {
|
||||
const std::string &file_path, i_provider &provider) {
|
||||
std::cout << __FUNCTION__ << std::endl;
|
||||
auto fd =
|
||||
auto file =
|
||||
open(file_path.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP);
|
||||
EXPECT_LE(1, fd);
|
||||
EXPECT_EQ(0, fallocate(fd, 0, 0, 16));
|
||||
EXPECT_LE(1, file);
|
||||
EXPECT_EQ(0, fallocate(file, 0, 0, 16));
|
||||
|
||||
std::uint64_t file_size{};
|
||||
EXPECT_TRUE(utils::file::get_file_size(file_path, file_size));
|
||||
EXPECT_EQ(16u, file_size);
|
||||
EXPECT_EQ(16U, file_size);
|
||||
|
||||
EXPECT_EQ(0, close(fd));
|
||||
EXPECT_EQ(0, close(file));
|
||||
|
||||
file_size = 0u;
|
||||
file_size = 0U;
|
||||
EXPECT_TRUE(utils::file::get_file_size(file_path, file_size));
|
||||
EXPECT_EQ(16u, file_size);
|
||||
EXPECT_EQ(16U, file_size);
|
||||
|
||||
// filesystem_item fsi{};
|
||||
// EXPECT_EQ(api_error::success,
|
||||
// provider.get_filesystem_item(api_path, false, fsi));
|
||||
|
||||
// file_size = 0u;
|
||||
// EXPECT_TRUE(utils::file::get_file_size(fsi.source_path, file_size));
|
||||
// EXPECT_EQ(16u, file_size);
|
||||
filesystem_item fsi{};
|
||||
EXPECT_EQ(api_error::success,
|
||||
provider.get_filesystem_item(api_path, false, fsi));
|
||||
EXPECT_EQ(16U, fsi.size);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -316,12 +313,12 @@ static void test_file_getattr(const std::string & /* api_path */,
|
||||
|
||||
EXPECT_EQ(0, close(fd));
|
||||
|
||||
struct stat64 st {};
|
||||
EXPECT_EQ(0, stat64(file_path.c_str(), &st));
|
||||
struct stat64 unix_st {};
|
||||
EXPECT_EQ(0, stat64(file_path.c_str(), &unix_st));
|
||||
EXPECT_EQ(static_cast<std::uint32_t>(S_IRUSR | S_IWUSR | S_IRGRP),
|
||||
ACCESSPERMS & st.st_mode);
|
||||
EXPECT_FALSE(S_ISDIR(st.st_mode));
|
||||
EXPECT_TRUE(S_ISREG(st.st_mode));
|
||||
ACCESSPERMS & unix_st.st_mode);
|
||||
EXPECT_FALSE(S_ISDIR(unix_st.st_mode));
|
||||
EXPECT_TRUE(S_ISREG(unix_st.st_mode));
|
||||
}
|
||||
|
||||
static void test_directory_getattr(const std::string & /* api_path */,
|
||||
@@ -330,17 +327,17 @@ static void test_directory_getattr(const std::string & /* api_path */,
|
||||
EXPECT_EQ(0, mkdir(directory_path.c_str(),
|
||||
S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP));
|
||||
|
||||
struct stat64 st {};
|
||||
EXPECT_EQ(0, stat64(directory_path.c_str(), &st));
|
||||
struct stat64 unix_st {};
|
||||
EXPECT_EQ(0, stat64(directory_path.c_str(), &unix_st));
|
||||
EXPECT_EQ(static_cast<std::uint32_t>(S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
|
||||
S_IXGRP),
|
||||
ACCESSPERMS & st.st_mode);
|
||||
EXPECT_TRUE(S_ISDIR(st.st_mode));
|
||||
EXPECT_FALSE(S_ISREG(st.st_mode));
|
||||
ACCESSPERMS & unix_st.st_mode);
|
||||
EXPECT_TRUE(S_ISDIR(unix_st.st_mode));
|
||||
EXPECT_FALSE(S_ISREG(unix_st.st_mode));
|
||||
}
|
||||
|
||||
static void
|
||||
test_write_operations_fail_if_read_only(const std::string &api_path,
|
||||
test_write_operations_fail_if_read_only(const std::string & /* api_path */,
|
||||
const std::string &file_path) {
|
||||
std::cout << __FUNCTION__ << std::endl;
|
||||
auto fd =
|
||||
@@ -418,13 +415,14 @@ static void test_xattr_listxattr(const std::string &file_path) {
|
||||
EXPECT_STREQ(attr.c_str(), val.c_str());
|
||||
|
||||
std::string data;
|
||||
auto size = listxattr(file_path.c_str(), &data[0u], 0u);
|
||||
auto size = listxattr(file_path.c_str(), data.data(), 0U);
|
||||
EXPECT_EQ(31, size);
|
||||
|
||||
data.resize(size);
|
||||
EXPECT_EQ(size, listxattr(file_path.c_str(), &data[0u], size));
|
||||
data.resize(static_cast<std::size_t>(size));
|
||||
EXPECT_EQ(size, listxattr(file_path.c_str(), data.data(),
|
||||
static_cast<std::size_t>(size)));
|
||||
|
||||
char *ptr = &data[0u];
|
||||
auto *ptr = data.data();
|
||||
EXPECT_STREQ("user.test_attr", ptr);
|
||||
|
||||
ptr += strlen(ptr) + 1;
|
||||
@@ -633,7 +631,7 @@ TEST(fuse_drive, all_tests) {
|
||||
#ifndef __APPLE__
|
||||
file_path = create_file_and_test(mount_location, "fallocate_file_test");
|
||||
test_fallocate(utils::path::create_api_path("fallocate_file_test"),
|
||||
file_path);
|
||||
file_path, *provider_ptr);
|
||||
unlink_file_and_test(file_path);
|
||||
#endif
|
||||
|
||||
|
@@ -39,52 +39,58 @@ public:
|
||||
: mount_location_(std::move(mount_location)) {}
|
||||
|
||||
private:
|
||||
const std::string mount_location_;
|
||||
std::string mount_location_;
|
||||
std::unordered_map<std::string, api_meta_map> meta_;
|
||||
|
||||
public:
|
||||
api_error check_owner(const std::string &) const override {
|
||||
auto check_owner(const std::string &) const -> api_error override {
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
api_error check_parent_access(const std::string &, int) const override {
|
||||
auto check_parent_access(const std::string &, int) const
|
||||
-> api_error override {
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
std::uint64_t get_directory_item_count(const std::string &) const override {
|
||||
auto get_directory_item_count(const std::string &) const
|
||||
-> std::uint64_t override {
|
||||
return 1;
|
||||
}
|
||||
|
||||
directory_item_list get_directory_items(const std::string &) const override {
|
||||
auto get_directory_items(const std::string &) const
|
||||
-> directory_item_list override {
|
||||
directory_item_list list{};
|
||||
|
||||
directory_item di{};
|
||||
di.api_path = ".";
|
||||
di.directory = true;
|
||||
di.size = 0;
|
||||
di.meta = {{META_ATTRIBUTES, "16"},
|
||||
{META_MODIFIED, std::to_string(utils::get_file_time_now())},
|
||||
{META_WRITTEN, std::to_string(utils::get_file_time_now())},
|
||||
{META_ACCESSED, std::to_string(utils::get_file_time_now())},
|
||||
{META_CREATION, std::to_string(utils::get_file_time_now())}};
|
||||
list.emplace_back(di);
|
||||
directory_item dir_item{};
|
||||
dir_item.api_path = ".";
|
||||
dir_item.directory = true;
|
||||
dir_item.size = 0;
|
||||
dir_item.meta = {
|
||||
{META_ATTRIBUTES, "16"},
|
||||
{META_MODIFIED, std::to_string(utils::get_file_time_now())},
|
||||
{META_WRITTEN, std::to_string(utils::get_file_time_now())},
|
||||
{META_ACCESSED, std::to_string(utils::get_file_time_now())},
|
||||
{META_CREATION, std::to_string(utils::get_file_time_now())}};
|
||||
list.emplace_back(dir_item);
|
||||
|
||||
di.api_path = "..";
|
||||
list.emplace_back(di);
|
||||
dir_item.api_path = "..";
|
||||
list.emplace_back(dir_item);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
std::uint64_t get_file_size(const std::string &) const override { return 0u; }
|
||||
auto get_file_size(const std::string &) const -> std::uint64_t override {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
api_error get_item_meta(const std::string &api_path,
|
||||
api_meta_map &meta) const override {
|
||||
auto get_item_meta(const std::string &api_path, api_meta_map &meta) const
|
||||
-> api_error override {
|
||||
meta = const_cast<mock_fuse_drive *>(this)->meta_[api_path];
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
api_error get_item_meta(const std::string &api_path, const std::string &name,
|
||||
std::string &value) const override {
|
||||
auto get_item_meta(const std::string &api_path, const std::string &name,
|
||||
std::string &value) const -> api_error override {
|
||||
value = const_cast<mock_fuse_drive *>(this)->meta_[api_path][name];
|
||||
if (value.empty()) {
|
||||
value = "0";
|
||||
@@ -92,13 +98,13 @@ public:
|
||||
return api_error::success;
|
||||
}
|
||||
|
||||
std::uint64_t get_total_drive_space() const override {
|
||||
return 100 * 1024 * 1024;
|
||||
auto get_total_drive_space() const -> std::uint64_t override {
|
||||
return 100ULL * 1024ULL * 1024ULL;
|
||||
}
|
||||
|
||||
std::uint64_t get_total_item_count() const override { return 0u; }
|
||||
auto get_total_item_count() const -> std::uint64_t override { return 0U; }
|
||||
|
||||
std::uint64_t get_used_drive_space() const override { return 0u; }
|
||||
auto get_used_drive_space() const -> std::uint64_t override { return 0U; }
|
||||
|
||||
void get_volume_info(UINT64 &total_size, UINT64 &free_size,
|
||||
std::string &volume_label) const override {
|
||||
@@ -107,10 +113,8 @@ public:
|
||||
volume_label = "TestVolumeLabel";
|
||||
}
|
||||
|
||||
void populate_stat(const directory_item &, struct stat &) const override {}
|
||||
|
||||
int rename_directory(const std::string &from_api_path,
|
||||
const std::string &to_api_path) override {
|
||||
auto rename_directory(const std::string &from_api_path,
|
||||
const std::string &to_api_path) -> int override {
|
||||
const auto from_file_path =
|
||||
utils::path::combine(mount_location_, {from_api_path});
|
||||
const auto to_file_path =
|
||||
@@ -118,8 +122,9 @@ public:
|
||||
return rename(from_file_path.c_str(), to_file_path.c_str());
|
||||
}
|
||||
|
||||
int rename_file(const std::string &from_api_path,
|
||||
const std::string &to_api_path, bool overwrite) override {
|
||||
auto rename_file(const std::string &from_api_path,
|
||||
const std::string &to_api_path, bool overwrite)
|
||||
-> int override {
|
||||
const auto from_file_path =
|
||||
utils::path::combine(mount_location_, {from_api_path});
|
||||
const auto to_file_path =
|
||||
@@ -138,7 +143,9 @@ public:
|
||||
return rename(from_file_path.c_str(), to_file_path.c_str());
|
||||
}
|
||||
|
||||
bool is_processing(const std::string &) const override { return false; }
|
||||
auto is_processing(const std::string &) const -> bool override {
|
||||
return false;
|
||||
}
|
||||
|
||||
void set_item_meta(const std::string &api_path, const std::string &key,
|
||||
const std::string &value) override {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user