initial commit
Some checks failed
BlockStorage/repertory_osx/pipeline/head There was a failure building this commit
BlockStorage/repertory_windows/pipeline/head This commit looks good
BlockStorage/repertory_linux_builds/pipeline/head This commit looks good

This commit is contained in:
2022-03-05 00:30:50 -06:00
commit 3ff46723b8
626 changed files with 178600 additions and 0 deletions

123
include/utils/Base64.hpp Normal file
View File

@ -0,0 +1,123 @@
#ifndef _MACARON_BASE64_H_
#define _MACARON_BASE64_H_
/**
* The MIT License (MIT)
* Copyright (c) 2016 tomykaira
*
* 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 <string>
#include <vector>
namespace macaron {
namespace Base64 {
static std::string Encode(const char *data, const size_t &len) {
static constexpr char sEncodingTable[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
size_t in_len = len;
std::string ret;
if (in_len > 0) {
size_t out_len = 4 * ((in_len + 2) / 3);
ret = std::string(out_len, '\0');
size_t i;
char *p = const_cast<char *>(ret.c_str());
for (i = 0; i < in_len - 2; i += 3) {
*p++ = sEncodingTable[(data[i] >> 2) & 0x3F];
*p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int)(data[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2) | ((int)(data[i + 2] & 0xC0) >> 6)];
*p++ = sEncodingTable[data[i + 2] & 0x3F];
}
if (i < in_len) {
*p++ = sEncodingTable[(data[i] >> 2) & 0x3F];
if (i == (in_len - 1)) {
*p++ = sEncodingTable[((data[i] & 0x3) << 4)];
*p++ = '=';
} else {
*p++ = sEncodingTable[((data[i] & 0x3) << 4) | ((int)(data[i + 1] & 0xF0) >> 4)];
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2)];
}
*p++ = '=';
}
}
return ret;
}
static std::string Encode(const std::string &data) { return Encode(&data[0], data.size()); }
static std::vector<char> Decode(const std::string &input) {
static constexpr unsigned char kDecodingTable[] = {
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62,
64, 64, 64, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64};
std::vector<char> out;
if (not input.empty()) {
size_t in_len = input.size();
if (in_len % 4 != 0)
throw std::runtime_error("Input data size is not a multiple of 4");
size_t out_len = in_len / 4 * 3;
if (input[in_len - 1] == '=')
out_len--;
if (input[in_len - 2] == '=')
out_len--;
out.resize(out_len);
for (size_t i = 0, j = 0; i < in_len;) {
uint32_t a = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t b = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t c = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t d = input[i] == '=' ? 0 & i++ : kDecodingTable[static_cast<int>(input[i++])];
uint32_t triple = (a << 3 * 6) + (b << 2 * 6) + (c << 1 * 6) + (d << 0 * 6);
if (j < out_len)
out[j++] = (triple >> 2 * 8) & 0xFF;
if (j < out_len)
out[j++] = (triple >> 1 * 8) & 0xFF;
if (j < out_len)
out[j++] = (triple >> 0 * 8) & 0xFF;
}
}
return out;
}
} // namespace Base64
} // namespace macaron
#endif /* _MACARON_BASE64_H_ */

119
include/utils/cli_utils.hpp Normal file
View File

@ -0,0 +1,119 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_CLI_UTILS_HPP_
#define INCLUDE_UTILS_CLI_UTILS_HPP_
#include "common.hpp"
#include "types/repertory.hpp"
namespace repertory::utils::cli {
typedef std::array<std::string, 2> option;
namespace options {
static const option check_version_option = {"-cv", "--check_version"};
static const option display_config_option = {"-dc", "--display_config"};
static const option data_directory_option = {"-dd", "--data_directory"};
static const option drive_information_option = {"-di", "--drive_information"};
static const option export_option = {"-ex", "--export"};
static const option export_all_option = {"-ea", "--export_all"};
#if defined(REPERTORY_ENABLE_S3)
static const option s3_option = {"-s3", "--s3"};
static const option name_option = {"-na", "--name"};
#endif // defined(REPERTORY_ENABLE_S3)
static const option generate_config_option = {"-gc", "--generate_config"};
static const option get_option = {"-get", "--get"};
static const option get_directory_items_option = {"-gdi", "--get_directory_items"};
static const option get_pinned_files_option = {"-gpf", "--get_pinned_files"};
static const option help_option = {"-h", "--help"};
static const option hidden_option = {"-hidden", "--hidden"};
static const option import_option = {"-im", "--import"};
static const option import_json_option = {"-ij", "--import_json"};
static const option open_files_option = {"-of", "--open_files"};
static const option pin_file_option = {"-pf", "--pin_file"};
static const option pinned_status_option = {"-ps", "--pinned_status"};
static const option password_option = {"-pw", "--password"};
#if defined(REPERTORY_ENABLE_SKYNET)
static const option skynet_option = {"-sk", "--skynet"};
static const option test_skynet_auth_option = {"-tsa", "--test_skynet_auth"};
#endif // defined(REPERTORY_ENABLE_SKYNET)
static const option remote_mount_option = {"-rm", "--remote_mount"};
static const option set_option = {"-set", "--set"};
static const option status_option = {"-status", "--status"};
static const option unmount_option = {"-unmount", "--unmount"};
static const option unpin_file_option = {"-uf", "--unpin_file"};
static const option user_option = {"-us", "--user"};
static const option version_option = {"-V", "--version"};
static const std::vector<option> option_list = {
check_version_option,
display_config_option,
data_directory_option,
drive_information_option,
export_option,
export_all_option,
#if defined(REPERTORY_ENABLE_S3)
s3_option,
name_option,
#endif // defined(REPERTORY_ENABLE_S3)
generate_config_option,
get_option,
get_directory_items_option,
get_pinned_files_option,
help_option,
hidden_option,
import_option,
import_json_option,
open_files_option,
password_option,
pin_file_option,
pinned_status_option,
#if defined(REPERTORY_ENABLE_SKYNET)
skynet_option,
test_skynet_auth_option,
#endif // defined(REPERTORY_ENABLE_SKYNET)
remote_mount_option,
set_option,
status_option,
unmount_option,
unpin_file_option,
user_option,
version_option,
};
} // namespace options
// Prototypes
void get_api_authentication_data(std::string &user, std::string &password, std::uint16_t &port,
const provider_type &pt, const std::string &data_directory);
provider_type get_provider_type_from_args(const int &argc, char *argv[]);
bool has_option(const int &argc, char *argv[], const std::string &option_name);
bool has_option(const int &argc, char *argv[], const option &opt);
std::vector<std::string> parse_option(const int &argc, char *argv[], const std::string &option_name,
std::uint8_t count);
exit_code parse_string_option(const int &argc, char **argv, const option &opt, std::string &value);
std::vector<std::string> parse_drive_options(const int &argc, char **argv, provider_type &pt,
std::string &data_directory);
} // namespace repertory::utils::cli
#endif // INCLUDE_UTILS_CLI_UTILS_HPP_

View File

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

View File

@ -0,0 +1,87 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_ENCRYPTING_READER_HPP_
#define INCLUDE_UTILS_ENCRYPTING_READER_HPP_
#include "common.hpp"
#include "utils/file_utils.hpp"
namespace repertory::utils::encryption {
class encrypting_reader final {
public:
encrypting_reader(const std::string &file_name, const std::string &source_path,
const bool &stop_requested, const std::string &token,
const size_t error_return = 0);
encrypting_reader(const encrypting_reader &r);
~encrypting_reader();
public:
typedef std::basic_iostream<char, std::char_traits<char>> iostream;
typedef std::basic_streambuf<char, std::char_traits<char>> streambuf;
private:
const CryptoPP::SecByteBlock key_;
const bool &stop_requested_;
const size_t error_return_;
std::unordered_map<std::size_t, std::vector<char>> chunk_buffers_;
std::string encrypted_file_name_;
std::size_t last_data_chunk_ = 0u;
std::size_t last_data_chunk_size_ = 0u;
std::uint64_t read_offset_ = 0u;
native_file_ptr source_file_;
std::uint64_t total_size_ = 0u;
private:
static const std::size_t header_size_;
static const std::size_t data_chunk_size_;
static const std::size_t encrypted_chunk_size_;
private:
size_t reader_function(char *buffer, size_t size, size_t nitems);
public:
static std::uint64_t calculate_decrypted_size(const std::uint64_t &total_size);
std::shared_ptr<iostream> create_iostream() const;
static constexpr const std::size_t &get_encrypted_chunk_size() { return encrypted_chunk_size_; }
static constexpr const std::size_t &get_data_chunk_size() { return data_chunk_size_; }
std::string get_encrypted_file_name() const { return encrypted_file_name_; }
std::size_t get_error_return() const { return error_return_; }
static constexpr const std::size_t &get_header_size() { return header_size_; }
const bool &get_stop_requested() const { return stop_requested_; }
std::uint64_t get_total_size() const { return total_size_; }
static size_t reader_function(char *buffer, size_t size, size_t nitems, void *instream) {
return reinterpret_cast<encrypting_reader *>(instream)->reader_function(buffer, size, nitems);
}
void set_read_position(const std::uint64_t &position) { read_offset_ = position; }
};
} // namespace repertory::utils::encryption
#endif // INCLUDE_UTILS_ENCRYPTING_READER_HPP_

View File

@ -0,0 +1,123 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_ENCRYPTION_HPP_
#define INCLUDE_UTILS_ENCRYPTION_HPP_
#include "common.hpp"
#include "types/repertory.hpp"
#include "utils/encrypting_reader.hpp"
namespace repertory::utils::encryption {
// Prototypes
api_error decrypt_file_name(const std::string &encryption_token, std::string &file_name);
CryptoPP::SecByteBlock generate_key(const std::string &encryption_token);
api_error read_encrypted_range(
const http_range &range, const CryptoPP::SecByteBlock &key,
const std::function<api_error(std::vector<char> &ct, const std::uint64_t &start_offset,
const std::uint64_t &end_offset)> &reader,
const std::uint64_t &total_size, std::vector<char> &data);
// Implementations
template <typename result>
static bool decrypt_data(const CryptoPP::SecByteBlock &key, const char *buffer,
const std::size_t &buffer_size, result &res) {
const auto header_size =
static_cast<std::uint32_t>(encrypting_reader::get_header_size());
if (buffer_size > header_size) {
CryptoPP::XChaCha20Poly1305::Decryption decryption;
CryptoPP::SecByteBlock iv(decryption.IVSize());
std::memcpy(&iv[0u], &buffer[0u], iv.size());
CryptoPP::SecByteBlock mac(decryption.DigestSize());
std::memcpy(&mac[0u], &buffer[iv.size()], mac.size());
decryption.SetKeyWithIV(key, key.size(), iv, iv.size());
const std::uint32_t size =
boost::endian::native_to_big(static_cast<std::uint32_t>(buffer_size));
res.resize(buffer_size - header_size);
return decryption.DecryptAndVerify(
reinterpret_cast<CryptoPP::byte *>(&res[0u]), &mac[0u], mac.size(), &iv[0u],
static_cast<int>(iv.size()), reinterpret_cast<const CryptoPP::byte *>(&size), sizeof(size),
reinterpret_cast<const CryptoPP::byte *>(&buffer[header_size]), res.size());
}
return false;
}
template <typename buffer, typename result>
static bool decrypt_data(const CryptoPP::SecByteBlock &key, const buffer &buf, result &res) {
return decrypt_data<result>(key, &buf[0u], buf.size(), res);
}
template <typename buffer, typename result>
static bool decrypt_data(const std::string &encryption_token, const buffer &buf, result &res) {
return decrypt_data<buffer, result>(generate_key(encryption_token), buf, res);
}
template <typename result>
static bool decrypt_data(const std::string &encryption_token, const char *buffer,
const std::size_t &buffer_size, result &res) {
return decrypt_data<result>(generate_key(encryption_token), buffer, buffer_size, res);
}
template <typename result>
static void encrypt_data(const CryptoPP::SecByteBlock &key, const char *buffer,
const std::size_t &buffer_size, result &res) {
CryptoPP::XChaCha20Poly1305::Encryption encryption;
CryptoPP::SecByteBlock iv(encryption.IVSize());
CryptoPP::OS_GenerateRandomBlock(false, iv, iv.size());
CryptoPP::SecByteBlock mac(encryption.DigestSize());
const std::uint32_t header_size =
static_cast<std::uint32_t>(encrypting_reader::get_header_size());
const std::uint32_t size =
boost::endian::native_to_big(static_cast<std::uint32_t>(buffer_size + header_size));
encryption.SetKeyWithIV(key, key.size(), iv, iv.size());
res.resize(buffer_size + header_size);
encryption.EncryptAndAuthenticate(reinterpret_cast<CryptoPP::byte *>(&res[header_size]), &mac[0u],
mac.size(), &iv[0u], static_cast<int>(iv.size()),
reinterpret_cast<const CryptoPP::byte *>(&size), sizeof(size),
reinterpret_cast<const CryptoPP::byte *>(buffer), buffer_size);
std::memcpy(&res[0u], &iv[0u], iv.size());
std::memcpy(&res[iv.size()], &mac[0u], mac.size());
}
template <typename result>
static void encrypt_data(const std::string &encryption_token, const char *buffer,
const std::size_t &buffer_size, result &res) {
return encrypt_data<result>(generate_key(encryption_token), buffer, buffer_size, res);
}
template <typename buffer, typename result>
static void encrypt_data(const std::string &encryption_token, const buffer &buf, result &res) {
return encrypt_data<result>(generate_key(encryption_token), &buf[0u], buf.size(), res);
}
template <typename buffer, typename result>
static void encrypt_data(const CryptoPP::SecByteBlock &key, const buffer &buf, result &res) {
return encrypt_data<result>(key, &buf[0u], buf.size(), res);
}
} // namespace repertory::utils::encryption
#endif // INCLUDE_UTILS_ENCRYPTION_HPP_

View File

@ -0,0 +1,106 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_FILE_UTILS_HPP_
#define INCLUDE_UTILS_FILE_UTILS_HPP_
#include "common.hpp"
#include "types/repertory.hpp"
#include "utils/native_file.hpp"
namespace repertory::utils::file {
// Prototypes
api_error assign_and_get_native_file(filesystem_item &fi, native_file_ptr &nf);
std::uint64_t calculate_used_space(std::string path, const bool &recursive);
void change_to_process_directory();
bool copy_directory_recursively(std::string from_path, std::string to_path);
bool copy_file(std::string from_path, std::string to_path);
bool create_full_directory_path(std::string path);
bool delete_directory(std::string path, const bool &recursive = false);
bool delete_directory_recursively(std::string path);
bool delete_file(std::string path);
std::string generate_sha256(const std::string &file_path);
std::uint64_t get_available_drive_space(const std::string &path);
std::deque<std::string> get_directory_files(std::string path, const bool &oldest_first,
const bool &recursive = false);
bool get_accessed_time(const std::string &path, std::uint64_t &accessed);
bool get_file_size(std::string path, std::uint64_t &file_size);
bool get_modified_time(const std::string &path, std::uint64_t &modified);
#ifdef _WIN32
static open_file_data get_read_write_open_flags() { return open_file_data{}; }
#else // _WIN32
static int get_read_write_open_flags() { return O_RDWR; }
#endif // _WIN32
bool is_directory(const std::string &path);
bool is_file(const std::string &path);
bool is_modified_date_older_than(const std::string &path, const std::chrono::hours &hours);
bool move_file(std::string from, std::string to);
std::vector<std::string> read_file_lines(const std::string &path);
api_error read_from_source(filesystem_item &fi, const std::size_t &read_size,
const std::uint64_t &read_offset, std::vector<char> &data);
template <typename t1, typename t2>
bool read_from_stream(t1 *input_file, t2 &buf, std::size_t to_read);
bool read_json_file(const std::string &path, json &data);
bool reset_modified_time(const std::string &path);
api_error truncate_source(filesystem_item &fi, const std::uint64_t &size);
bool write_json_file(const std::string &path, const json &j);
api_error write_to_source(filesystem_item &fi, const std::uint64_t &write_offset,
const std::vector<char> &data, std::size_t &bytes_written);
// template implementations
template <typename t1, typename t2>
bool read_from_stream(t1 *input_file, t2 &buf, std::size_t to_read) {
std::size_t offset = 0u;
do {
input_file->read((char *)&buf[offset], to_read);
to_read -= static_cast<std::size_t>(input_file->gcount());
offset += static_cast<std::size_t>(input_file->gcount());
} while (not input_file->fail() && (to_read > 0u));
return (to_read == 0u);
}
} // namespace repertory::utils::file
#endif // INCLUDE_UTILS_FILE_UTILS_HPP_

View File

@ -0,0 +1,68 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_GLOBAL_DATA_HPP_
#define INCLUDE_UTILS_GLOBAL_DATA_HPP_
#include "common.hpp"
namespace repertory {
class global_data final {
public:
global_data(const global_data &) = delete;
global_data(global_data &&) = delete;
global_data &operator=(const global_data &) = delete;
global_data &operator=(global_data &&) = delete;
private:
global_data() : used_cache_space_(0u), used_drive_space_(0u) {}
~global_data() = default;
private:
static global_data instance_;
public:
static global_data &instance() { return instance_; }
private:
std::atomic<std::uint64_t> used_cache_space_;
std::atomic<std::uint64_t> used_drive_space_;
public:
void decrement_used_drive_space(const std::uint64_t &val) { used_drive_space_ -= val; }
std::uint64_t get_used_cache_space() const { return used_cache_space_; }
std::uint64_t get_used_drive_space() const { return used_drive_space_; }
void increment_used_drive_space(const std::uint64_t &val) { used_drive_space_ += val; }
void initialize_used_cache_space(const std::uint64_t &val) { used_cache_space_ = val; }
void initialize_used_drive_space(const std::uint64_t &val) { used_drive_space_ = val; }
void update_used_space(const std::uint64_t &file_size, const std::uint64_t &new_file_size,
const bool &cache_only);
};
} // namespace repertory
#endif // INCLUDE_UTILS_GLOBAL_DATA_HPP_

View File

@ -0,0 +1,89 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_NATIVEFILE_HPP_
#define INCLUDE_UTILS_NATIVEFILE_HPP_
#include "common.hpp"
#include "types/repertory.hpp"
namespace repertory {
class native_file final {
public:
typedef std::shared_ptr<native_file> native_file_ptr;
public:
static native_file_ptr attach(OSHandle handle) {
return native_file_ptr(new native_file(handle));
}
static native_file_ptr clone(const native_file_ptr &nativeFile);
static api_error create_or_open(const std::string &source_path, native_file_ptr &nf);
static api_error open(const std::string &source_path, native_file_ptr &nf);
private:
explicit native_file(const OSHandle &handle) : handle_(handle) {}
public:
~native_file() = default;
private:
OSHandle handle_;
#ifdef _WIN32
std::recursive_mutex read_write_mutex_;
#endif
public:
bool allocate(const std::uint64_t &file_size);
void close();
bool copy_from(const native_file_ptr &source);
bool copy_from(const std::string &path);
void flush();
bool get_file_size(std::uint64_t &file_size);
OSHandle get_handle() { return handle_; }
#ifdef _WIN32
bool read_bytes(char *buffer, const std::size_t &read_size, const std::uint64_t &read_offset,
std::size_t &bytes_read);
#else
bool read_bytes(char *buffer, const std::size_t &read_size, const std::uint64_t &read_offset,
std::size_t &bytes_read);
#endif
bool truncate(const std::uint64_t &file_size);
#ifdef _WIN32
bool write_bytes(const char *buffer, const std::size_t &write_size,
const std::uint64_t &write_offset, std::size_t &bytes_written);
#else
bool write_bytes(const char *buffer, const std::size_t &write_size,
const std::uint64_t &write_offset, std::size_t &bytes_written);
#endif
};
typedef native_file::native_file_ptr native_file_ptr;
} // namespace repertory
#endif // INCLUDE_UTILS_NATIVEFILE_HPP_

105
include/utils/optional.h Normal file
View File

@ -0,0 +1,105 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_OPTIONAL_HPP_
#define INCLUDE_UTILS_OPTIONAL_HPP_
#if IS_DEBIAN9_DISTRO || !HAS_STD_OPTIONAL
#include <memory>
namespace std {
class bad_optional_access : std::runtime_error {
public:
bad_optional_access() : std::runtime_error("bad optional access") {}
};
template <typename t> class optional {
public:
optional() = default;
explicit optional(const t &v) : val_(new t(v)) {}
explicit optional(t &&v) noexcept : val_(new t(std::move(v))) {}
optional(const optional &o) noexcept : val_(o.has_value() ? new t(o.val_) : nullptr) {}
optional(optional &&o) noexcept : val_(o.has_value() ? std::move(o.val_) : nullptr) {}
private:
std::unique_ptr<t> val_;
public:
bool has_value() const { return (val_ != nullptr); }
t &value() {
if (not has_value()) {
throw bad_optional_access();
}
return *val_;
}
const t &value() const {
if (not has_value()) {
throw bad_optional_access();
}
return *val_;
}
optional &operator=(const t &v) {
if (&v != val_.get()) {
val_.reset(new t(v));
}
return *this;
}
optional &operator=(const optional &v) {
if (&v != this) {
val_.reset(new t(v.has_value() ? v.value() : nullptr));
}
return *this;
}
optional &operator=(t &&v) noexcept {
if (&v != val_.get()) {
val_.reset(new t(std::move(v)));
}
return *this;
}
optional &operator=(optional &&v) noexcept {
if (&v != this) {
val_ = std::move(v);
}
return *this;
}
bool operator==(const optional &v) {
return (&v == this) || ((has_value() && v.has_value()) && (*val_ == *v.val_));
}
bool operator==(const t &v) { return has_value() && (v == *val_); }
bool operator!=(const optional &v) {
return (has_value() != v.has_value) || ((has_value() && v.has_value()) && (*val_ != *v.val_));
}
bool operator!=(const t &v) { return not has_value() || (v != *val_); }
};
} // namespace std
#endif // IS_DEBIAN9_DISTRO || !HAS_STD_OPTIONAL
#endif // INCLUDE_UTILS_OPTIONAL_HPP_

View File

@ -0,0 +1,61 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_PATH_UTILS_HPP_
#define INCLUDE_UTILS_PATH_UTILS_HPP_
#include "common.hpp"
namespace repertory::utils::path {
#ifdef _WIN32
static const std::string directory_seperator = "\\";
static const std::string not_directory_seperator = "/";
#else
static const std::string directory_seperator = "/";
static const std::string not_directory_seperator = "\\";
#endif
// Prototypes
std::string absolute(std::string path);
std::string combine(std::string path, const std::vector<std::string> &paths);
std::string create_api_path(std::string path);
std::string finalize(std::string path);
std::string get_parent_api_path(const std::string &path);
#ifndef _WIN32
std::string get_parent_directory(std::string path);
#endif
bool is_ads_file_path(const std::string &path);
bool is_trash_directory(std::string path);
std::string remove_file_name(std::string path);
#ifndef _WIN32
std::string resolve(std::string path);
#endif
std::string strip_to_file_name(std::string path);
} // namespace repertory::utils::path
#endif // INCLUDE_UTILS_PATH_UTILS_HPP_

75
include/utils/polling.hpp Normal file
View File

@ -0,0 +1,75 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_POLLING_HPP_
#define INCLUDE_UTILS_POLLING_HPP_
#include "common.hpp"
namespace repertory {
class app_config;
class polling final {
public:
struct polling_item {
std::string name;
bool low_frequency;
std::function<void()> action;
};
public:
polling(const polling &) = delete;
polling(polling &&) = delete;
polling &operator=(const polling &) = delete;
polling &operator=(polling &&) = delete;
private:
polling() = default;
~polling() { stop(); }
private:
static polling instance_;
public:
static polling &instance() { return instance_; }
private:
app_config *config_ = nullptr;
std::unique_ptr<std::thread> high_frequency_thread_;
std::unordered_map<std::string, polling_item> items_;
std::unique_ptr<std::thread> low_frequency_thread_;
std::mutex mutex_;
std::condition_variable notify_;
std::mutex start_stop_mutex_;
bool stop_requested_ = false;
private:
void frequency_thread(std::function<std::uint32_t()> get_frequency_seconds, bool low_frequency);
public:
void remove_callback(const std::string &name);
void set_callback(const polling_item &item);
void start(app_config *config);
void stop();
};
} // namespace repertory
#endif // INCLUDE_UTILS_POLLING_HPP_

View File

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

View File

@ -0,0 +1,114 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_STRING_UTILS_HPP_
#define INCLUDE_UTILS_STRING_UTILS_HPP_
#include <string>
#include <vector>
#include <boost/dynamic_bitset.hpp>
namespace repertory::utils::string {
// Prototypes
bool begins_with(const std::string &str, const std::string &val);
bool contains(const std::string &str, const std::string &search);
bool ends_with(const std::string &str, const std::string &val);
std::string from_bool(const bool &val);
std::string from_double(const double &value);
std::string from_dynamic_bitset(const boost::dynamic_bitset<> &bitset);
std::string from_int32(const std::int32_t &val);
std::string from_int64(const std::int64_t &val);
std::string from_uint8(const std::uint8_t &val);
std::string from_uint16(const std::uint16_t &val);
std::string from_uint32(const std::uint32_t &val);
std::string from_uint64(const std::uint64_t &val);
std::wstring from_utf8(const std::string &str);
bool is_numeric(const std::string &s);
std::string join(const std::vector<std::string> &arr, const char &delim);
std::string &left_trim(std::string &s);
std::string &left_trim(std::string &s, const char &c);
std::string &replace(std::string &src, const char &character, const char &with);
std::string &replace(std::string &src, const std::string &find, const std::string &with,
size_t startPos = 0);
std::string replace_copy(std::string src, const char &character, const char &with);
std::string replace_copy(std::string src, const std::string &find, const std::string &with,
size_t startPos = 0);
std::string &right_trim(std::string &s);
std::string &right_trim(std::string &s, const char &c);
std::vector<std::string> split(const std::string &str, const char &delim,
const bool &should_trim = true);
bool to_bool(std::string val);
double to_double(const std::string &str);
boost::dynamic_bitset<> to_dynamic_bitset(const std::string &val);
std::string to_lower(std::string str);
std::int32_t to_int32(const std::string &val);
std::int64_t to_int64(const std::string &val);
std::uint8_t to_uint8(const std::string &val);
std::uint16_t to_uint16(const std::string &val);
std::uint32_t to_uint32(const std::string &val);
std::uint64_t to_uint64(const std::string &val);
std::string to_upper(std::string str);
const std::string &to_utf8(const std::string &str);
std::string to_utf8(const std::wstring &str);
std::string &trim(std::string &str);
std::string &trim(std::string &str, const char &c);
std::string trim_copy(std::string str);
std::string trim_copy(std::string str, const char &c);
} // namespace repertory::utils::string
#endif // INCLUDE_UTILS_STRING_UTILS_HPP_

View File

@ -0,0 +1,58 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_THROTTLE_HPP_
#define INCLUDE_UTILS_THROTTLE_HPP_
#include "common.hpp"
namespace repertory {
class throttle final {
public:
throttle() : max_size_(10u) {}
explicit throttle(const std::size_t &max_size) : max_size_(max_size) {}
public:
throttle(const throttle &) noexcept = delete;
throttle(throttle &&) noexcept = delete;
throttle &operator=(const throttle &) = delete;
throttle &operator=(throttle &&) = delete;
public:
~throttle() { shutdown(); }
private:
const std::size_t max_size_;
std::size_t count_ = 0u;
bool shutdown_ = false;
std::mutex mutex_;
std::condition_variable notify_;
public:
void decrement();
void increment_or_wait();
void reset();
void shutdown();
};
} // namespace repertory
#endif // INCLUDE_UTILS_THROTTLE_HPP_

49
include/utils/timeout.hpp Normal file
View File

@ -0,0 +1,49 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_TIMEOUT_HPP_
#define INCLUDE_UTILS_TIMEOUT_HPP_
#include "common.hpp"
namespace repertory {
class timeout final {
public:
timeout(const timeout &) noexcept = delete;
timeout(timeout &&) noexcept = delete;
timeout &operator=(const timeout &) noexcept = delete;
timeout &operator=(timeout &&) noexcept = delete;
public:
timeout(std::function<void()> timeout_callback,
const std::chrono::system_clock::duration &duration = 10s);
~timeout() { disable(); }
private:
bool timeout_killed_;
std::unique_ptr<std::thread> timeout_thread_;
std::mutex timeout_mutex_;
std::condition_variable timeout_notify_;
public:
void disable();
};
} // namespace repertory
#endif // INCLUDE_UTILS_TIMEOUT_HPP_

View File

@ -0,0 +1,71 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_UNIX_UNIX_UTILS_HPP_
#define INCLUDE_UTILS_UNIX_UNIX_UTILS_HPP_
#ifndef _WIN32
#include "common.hpp"
#include "types/remote.hpp"
#include "types/repertory.hpp"
namespace repertory::utils {
#if __linux__
static const std::array<std::string, 4u> attribute_namespaces = {
"security",
"system",
"trusted",
"user",
};
#endif
#if __APPLE__
template <typename t> std::uint64_t convert_to_uint64(const t *v);
#else
std::uint64_t convert_to_uint64(const pthread_t &t);
#endif
int get_last_error_code();
std::uint64_t get_thread_id();
bool is_uid_member_of_group(const uid_t &uid, const gid_t &gid);
void set_last_error_code(int error_code);
int translate_api_error(const api_error &e);
std::int32_t unix_error_to_windows(const int &e);
UINT64 unix_time_to_windows_time(const remote::file_time &ts);
void windows_create_to_unix(const UINT32 &create_options, const UINT32 &granted_access,
std::uint32_t &flags, remote::file_mode &mode);
remote::file_time windows_time_to_unix_time(const std::uint64_t &t);
// template implementations
#if __APPLE__
template <typename t> std::uint64_t convert_to_uint64(const t *v) {
return static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(v));
}
#endif
} // namespace repertory::utils
#endif // !_WIN32
#endif // INCLUDE_UTILS_UNIX_UNIX_UTILS_HPP_

143
include/utils/utils.hpp Normal file
View File

@ -0,0 +1,143 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_UTILS_HPP_
#define INCLUDE_UTILS_UTILS_HPP_
#include "common.hpp"
#include "types/remote.hpp"
#include "types/repertory.hpp"
#include "utils/unix/unix_utils.hpp"
#include "utils/windows/windows_utils.hpp"
namespace repertory::utils {
hastings api_currency_to_hastings(const api_currency &currency);
void calculate_allocation_size(const bool &directory, const std::uint64_t &file_size,
UINT64 allocation_size, std::string &allocation_meta_size);
std::size_t calculate_read_size(const uint64_t &total_size, const std::size_t &read_size,
const uint64_t &offset);
template <typename t> bool collection_excludes(t collection, const typename t::value_type &v);
template <typename t> bool collection_includes(t collection, const typename t::value_type &v);
int compare_version_strings(std::string version1, std::string version2);
std::uint64_t convert_api_date(const std::string &date);
CURL *create_curl();
std::string create_uuid_string();
std::string create_volume_label(const provider_type &pt);
template <typename t> t divide_with_ceiling(const t &n, const t &d);
download_type download_type_from_string(std::string type, const download_type &default_type);
std::string download_type_to_string(const download_type &type);
template <typename t> bool from_hex_string(const std::string &str, t &v);
std::string generate_random_string(const std::uint16_t &length);
std::string get_environment_variable(const std::string &variable);
std::uint64_t get_file_time_now();
void get_local_time_now(struct tm &localTime);
bool get_next_available_port(std::uint16_t first_port, std::uint16_t &available_port);
std::uint64_t get_time_now();
api_currency hastings_string_to_api_currency(const std::string &amount);
// bool parse_url(const std::string &url, HostConfig &hc);
template <typename t> t random_between(const t &begin, const t &end);
template <typename t> void remove_element_from(t &v, const typename t::value_type &value);
CURL *reset_curl(CURL *curl_handle);
bool retryable_action(const std::function<bool()> &action);
void spin_wait_for_mutex(std::function<bool()> complete, std::condition_variable &cv,
std::mutex &mtx, const std::string &txt = "");
void spin_wait_for_mutex(bool &complete, std::condition_variable &cv, std::mutex &mtx,
const std::string &txt = "");
template <typename t> std::string to_hex_string(const t &v);
// template implementations
template <typename t> bool collection_excludes(t collection, const typename t::value_type &v) {
return std::find(collection.begin(), collection.end(), v) == collection.end();
}
template <typename t> bool collection_includes(t collection, const typename t::value_type &v) {
return std::find(collection.begin(), collection.end(), v) != collection.end();
}
template <typename t> t divide_with_ceiling(const t &n, const t &d) {
return n ? (n / d) + (n % d != 0) : 0;
}
template <typename t> bool from_hex_string(const std::string &str, t &v) {
v.clear();
if (not(str.length() % 2u)) {
for (std::size_t i = 0u; i < str.length(); i += 2u) {
v.emplace_back(
static_cast<typename t::value_type>(strtol(str.substr(i, 2u).c_str(), nullptr, 16)));
}
return true;
}
return false;
}
template <typename t> t random_between(const t &begin, const t &end) {
srand(static_cast<unsigned int>(get_time_now()));
return begin + rand() % ((end + 1) - begin);
}
template <typename t> void remove_element_from(t &v, const typename t::value_type &value) {
v.erase(std::remove(v.begin(), v.end(), value), v.end());
}
template <typename t> std::string to_hex_string(const t &v) {
std::string ret;
for (const auto &v : v) {
char h[3] = {0};
#ifdef _WIN32
sprintf_s(&h[0], sizeof(h), "%x", static_cast<std::uint8_t>(v));
#else
sprintf(&h[0], "%x", static_cast<std::uint8_t>(v));
#endif
ret += ((strlen(h) == 1) ? std::string("0") + h : h);
}
return ret;
}
} // namespace repertory::utils
#endif // INCLUDE_UTILS_UTILS_HPP_

325
include/utils/uuid++.hh Normal file
View File

@ -0,0 +1,325 @@
/*
** MODIFIED BY <scott.e.graves@gmail.com>
** - Modifications for C++11
** - Memory leak avoidance
**
** OSSP uuid - Universally Unique Identifier
** Copyright (c) 2004-2008 Ralf S. Engelschall <rse@engelschall.com>
** Copyright (c) 2004-2008 The OSSP Project <http://www.ossp.org/>
**
** This file is part of OSSP uuid, a library for the generation
** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
**
** Permission to use, copy, modify, and distribute this software for
** any purpose with or without fee is hereby granted, provided that
** the above copyright notice and this permission notice appear in all
** copies.
**
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
**
** uuid++.hh: library C++ API definition
*/
#if __linux__
#ifndef __UUIDXX_HH__
#define __UUIDXX_HH__
#include <cstdarg>
#include <string>
#include <exception>
#include <vector>
#include <uuid.h>
namespace repertory {
/* UUID exception class */
class uuid_error_t : public virtual std::exception {
public:
uuid_error_t() : rc(UUID_RC_OK){};
explicit uuid_error_t(const uuid_rc_t &code) : rc(code) {}
private:
const uuid_rc_t rc;
public:
uuid_rc_t code() const { return rc; };
const char *what() const noexcept override {
static std::string ret;
if (ret.empty()) {
auto *p = uuid_error(rc);
ret = std::string(p, strlen(p));
free(p);
}
return ret.c_str();
}
};
/* UUID object class */
class uuid {
public:
/* construction & destruction */
/* standard constructor */
uuid() {
uuid_rc_t rc;
if ((rc = uuid_create(&ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
}
/* copy constructor */
uuid(const uuid &obj) {
/* Notice: the copy constructor is the same as the assignment
operator (with the object as the argument) below, except that
(1) no check for self-assignment is required, (2) no existing
internals have to be destroyed and (3) no return value is given back. */
uuid_rc_t rc;
if ((rc = uuid_clone(obj.ctx, &ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
}
/* import constructor */
explicit uuid(const uuid_t *obj) {
uuid_rc_t rc;
if (obj == nullptr)
throw uuid_error_t(UUID_RC_ARG);
if ((rc = uuid_clone(obj, &ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
}
/* import constructor */
explicit uuid(const std::vector<void *> &bin) {
uuid_rc_t rc;
if (bin.empty())
throw uuid_error_t(UUID_RC_ARG);
if ((rc = uuid_create(&ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
import(bin);
}
/* import constructor */
explicit uuid(const std::string &str) {
uuid_rc_t rc;
if (str.empty())
throw uuid_error_t(UUID_RC_ARG);
if ((rc = uuid_create(&ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
import(str);
}
/* move constructor */
uuid(uuid &&obj) noexcept : ctx(obj.ctx) {}
/* destructor */
~uuid() { uuid_destroy(ctx); }
private:
uuid_t *ctx = nullptr;
public:
/* copying & cloning */
/* copy assignment operator */
uuid &operator=(const uuid &obj) {
uuid_rc_t rc;
if (this != &obj) {
if ((rc = uuid_destroy(ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
if ((rc = uuid_clone(obj.ctx, &ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
}
return *this;
}
/* move assignment operator */
uuid &operator=(uuid &&obj) {
if (this != &obj) {
ctx = obj.ctx;
}
return *this;
}
/* import assignment operator */
uuid &operator=(const uuid_t *obj) {
uuid_rc_t rc;
if (obj == nullptr)
throw uuid_error_t(UUID_RC_ARG);
if ((rc = uuid_clone(obj, &ctx)) != UUID_RC_OK)
throw uuid_error_t(rc);
return *this;
}
/* import assignment operator */
uuid &operator=(const std::vector<void *> &bin) {
if (bin.empty())
throw uuid_error_t(UUID_RC_ARG);
import(bin);
return *this;
}
/* import assignment operator */
uuid &operator=(const std::string &str) {
if (str.empty())
throw uuid_error_t(UUID_RC_ARG);
import(str);
return *this;
}
/* regular method */
uuid clone() { return uuid(*this); }
/* content generation */
/* regular method */
void load(const std::string &name) {
uuid_rc_t rc;
if (name.empty())
throw uuid_error_t(UUID_RC_ARG);
if ((rc = uuid_load(ctx, &name[0])) != UUID_RC_OK)
throw uuid_error_t(rc);
}
/* regular method */
void make(unsigned int mode, ...) {
uuid_rc_t rc;
va_list ap;
va_start(ap, mode);
if ((mode & UUID_MAKE_V3) || (mode & UUID_MAKE_V5)) {
const uuid *ns = (const uuid *)va_arg(ap, const uuid *);
const char *name = (const char *)va_arg(ap, char *);
if (ns == nullptr || name == nullptr)
throw uuid_error_t(UUID_RC_ARG);
rc = uuid_make(ctx, mode, ns->ctx, name);
} else
rc = uuid_make(ctx, mode);
va_end(ap);
if (rc != UUID_RC_OK)
throw uuid_error_t(rc);
}
/* content comparison */
/* regular method */
int isnil() {
uuid_rc_t rc;
int rv;
if ((rc = uuid_isnil(ctx, &rv)) != UUID_RC_OK)
throw uuid_error_t(rc);
return rv;
}
/* regular method */
int compare(const uuid &obj) {
uuid_rc_t rc;
int rv;
if ((rc = uuid_compare(ctx, obj.ctx, &rv)) != UUID_RC_OK)
throw uuid_error_t(rc);
return rv;
}
/* comparison operator */
int operator==(const uuid &obj) { return (compare(obj) == 0); }
/* comparison operator */
int operator!=(const uuid &obj) { return (compare(obj) != 0); }
/* comparison operator */
int operator<(const uuid &obj) { return (compare(obj) < 0); }
/* comparison operator */
int operator<=(const uuid &obj) { return (compare(obj) <= 0); }
/* comparison operator */
int operator>(const uuid &obj) { return (compare(obj) > 0); }
/* comparison operator */
int operator>=(const uuid &obj) { return (compare(obj) >= 0); }
/* content importing & exporting */
/* regular method */
void import(const std::vector<void *> &bin) {
uuid_rc_t rc;
if ((rc = uuid_import(ctx, UUID_FMT_BIN, &bin[0], UUID_LEN_BIN)) != UUID_RC_OK)
throw uuid_error_t(rc);
}
/* regular method */
void import(const std::string &str) {
uuid_rc_t rc;
if ((rc = uuid_import(ctx, UUID_FMT_STR, &str[0], UUID_LEN_STR)) != UUID_RC_OK)
if ((rc = uuid_import(ctx, UUID_FMT_SIV, &str[0], UUID_LEN_SIV)) != UUID_RC_OK)
throw uuid_error_t(rc);
}
/* regular method */
std::vector<void *> binary() {
uuid_rc_t rc;
void *bin = nullptr;
if ((rc = uuid_export(ctx, UUID_FMT_BIN, &bin, nullptr)) != UUID_RC_OK)
throw uuid_error_t(rc);
std::vector<void *> data;
data.resize(UUID_LEN_BIN);
memcpy(&data[0], bin, UUID_LEN_BIN);
free(bin);
return data;
}
/* regular method */
std::string string() {
uuid_rc_t rc;
char *str = nullptr;
if ((rc = uuid_export(ctx, UUID_FMT_STR, (void **)&str, nullptr)) != UUID_RC_OK)
throw uuid_error_t(rc);
std::string data;
data.resize(UUID_LEN_STR + 1);
memcpy(&data[0], str, UUID_LEN_STR);
free(str);
return &data[0];
}
/* regular method */
std::string integer() {
uuid_rc_t rc;
char *str = nullptr;
if ((rc = uuid_export(ctx, UUID_FMT_SIV, (void **)&str, nullptr)) != UUID_RC_OK)
throw uuid_error_t(rc);
std::string data;
data.resize(UUID_LEN_SIV + 1);
memcpy(&data[0], str, UUID_LEN_SIV);
free(str);
return &data[0];
}
/* regular method */
std::string summary() {
uuid_rc_t rc;
char *txt = nullptr;
if ((rc = uuid_export(ctx, UUID_FMT_TXT, (void **)&txt, nullptr)) != UUID_RC_OK)
throw uuid_error_t(rc);
std::string data(txt, strlen(txt));
free(txt);
return data;
}
/* regular method */
unsigned long version() { return uuid_version(); }
};
} // namespace repertory
#endif /* __UUIDXX_HH__ */
#endif

View File

@ -0,0 +1,65 @@
/*
Copyright <2018-2022> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef INCLUDE_UTILS_WINDOWS_WINDOWS_UTILS_HPP_
#define INCLUDE_UTILS_WINDOWS_WINDOWS_UTILS_HPP_
#ifdef _WIN32
#include "common.hpp"
#include "types/remote.hpp"
#include "types/repertory.hpp"
namespace repertory::utils {
remote::file_time filetime_to_unix_time(const FILETIME &ft);
DWORD get_last_error_code();
const std::string &get_local_app_data_directory();
std::uint64_t get_accessed_time_from_meta(const api_meta_map &meta);
DWORD get_attributes_from_meta(const api_meta_map &meta);
std::uint64_t get_changed_time_from_meta(const api_meta_map &meta);
std::uint64_t get_creation_time_from_meta(const api_meta_map &meta);
std::uint64_t get_written_time_from_meta(const api_meta_map &meta);
std::uint64_t get_thread_id();
bool is_process_elevated();
int run_process_elevated(int argc, char *argv[]);
void set_last_error_code(DWORD errorCode);
NTSTATUS translate_api_error(const api_error &e);
int unix_access_mask_to_windows(std::int32_t mask);
int unix_open_flags_to_flags_and_perms(const remote::file_mode &mode, const remote::open_flags &flags,
std::int32_t &perms);
void unix_time_to_filetime(const remote::file_time &ts, FILETIME &ft);
remote::file_time time64_to_unix_time(const __time64_t &t);
} // namespace repertory::utils
#endif // _WIN32
#endif // INCLUDE_UTILS_WINDOWS_WINDOWS_UTILS_HPP_