updated build system
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit

This commit is contained in:
Scott E. Graves 2024-10-19 11:10:36 -05:00
parent c72dec6369
commit 2fb53e34af
24 changed files with 1330 additions and 831 deletions

View File

@ -1,15 +1,15 @@
set(BINUTILS_VERSION 2.41) set(BINUTILS_VERSION 2.41)
set(BOOST_MAJOR_VERSION 1)
set(BOOST_MINOR_VERSION 85)
set(BOOST_PATCH_VERSION 0)
set(BOOST2_MAJOR_VERSION 1) set(BOOST2_MAJOR_VERSION 1)
set(BOOST2_MINOR_VERSION 76) set(BOOST2_MINOR_VERSION 76)
set(BOOST2_PATCH_VERSION 0) set(BOOST2_PATCH_VERSION 0)
set(BOOST_MAJOR_VERSION 1)
set(BOOST_MINOR_VERSION 85)
set(BOOST_PATCH_VERSION 0)
set(CPP_HTTPLIB_VERSION 0.16.3) set(CPP_HTTPLIB_VERSION 0.16.3)
set(CURL_VERSION 8.9.1)
set(CURL2_VERSION 8_9_1) set(CURL2_VERSION 8_9_1)
set(EXPAT_VERSION 2.6.2) set(CURL_VERSION 8.9.1)
set(EXPAT2_VERSION 2_6_2) set(EXPAT2_VERSION 2_6_2)
set(EXPAT_VERSION 2.6.2)
set(GCC_VERSION 14.2.0) set(GCC_VERSION 14.2.0)
set(GTEST_VERSION 1.15.2) set(GTEST_VERSION 1.15.2)
set(ICU_VERSION 75-1) set(ICU_VERSION 75-1)
@ -21,7 +21,7 @@ set(OPENSSL_VERSION 3.3.1)
set(PKG_CONFIG_VERSION 0.29.2) set(PKG_CONFIG_VERSION 0.29.2)
set(PUGIXML_VERSION 1.14) set(PUGIXML_VERSION 1.14)
set(SPDLOG_VERSION 1.14.1) set(SPDLOG_VERSION 1.14.1)
set(SQLITE_VERSION 3460100)
set(SQLITE2_VERSION 3.46.1) set(SQLITE2_VERSION 3.46.1)
set(SQLITE_VERSION 3460100)
set(STDUUID_VERSION 1.2.3) set(STDUUID_VERSION 1.2.3)
set(ZLIB_VERSION 1.3.1) set(ZLIB_VERSION 1.3.1)

View File

@ -57,6 +57,7 @@ private:
i_provider &provider_; i_provider &provider_;
private: private:
utils::db::sqlite::db3_t db_;
std::atomic<std::uint64_t> next_handle_{0U}; std::atomic<std::uint64_t> next_handle_{0U};
mutable std::recursive_mutex open_file_mtx_; mutable std::recursive_mutex open_file_mtx_;
std::unordered_map<std::string, std::shared_ptr<i_closeable_open_file>> std::unordered_map<std::string, std::shared_ptr<i_closeable_open_file>>
@ -68,8 +69,6 @@ private:
std::unique_ptr<std::thread> upload_thread_; std::unique_ptr<std::thread> upload_thread_;
private: private:
[[nodiscard]] auto create_db() const -> utils::db::sqlite::db3_t;
void close_timed_out_files(); void close_timed_out_files();
auto get_open_file_by_handle(std::uint64_t handle) const auto get_open_file_by_handle(std::uint64_t handle) const
@ -83,22 +82,12 @@ private:
std::shared_ptr<i_closeable_open_file> closeable_file) -> api_error; std::shared_ptr<i_closeable_open_file> closeable_file) -> api_error;
void queue_upload(const std::string &api_path, const std::string &source_path, void queue_upload(const std::string &api_path, const std::string &source_path,
bool no_lock, sqlite3 *db); bool no_lock);
void remove_resume(const std::string &api_path, void remove_upload(const std::string &api_path, bool no_lock);
const std::string &source_path, sqlite3 *db);
void remove_upload(const std::string &api_path, bool no_lock, sqlite3 *db);
[[nodiscard]] auto rename_directory(const std::string &from_api_path,
const std::string &to_api_path,
sqlite3 *db) -> api_error;
[[nodiscard]] auto rename_file(const std::string &from_api_path,
const std::string &to_api_path, bool overwrite,
sqlite3 *db) -> api_error;
void swap_renamed_items(std::string from_api_path, std::string to_api_path, void swap_renamed_items(std::string from_api_path, std::string to_api_path,
bool directory, sqlite3 *db); bool directory);
void upload_completed(const file_upload_completed &evt); void upload_completed(const file_upload_completed &evt);
@ -108,8 +97,7 @@ public:
[[nodiscard]] auto get_next_handle() -> std::uint64_t; [[nodiscard]] auto get_next_handle() -> std::uint64_t;
auto handle_file_rename(const std::string &from_api_path, auto handle_file_rename(const std::string &from_api_path,
const std::string &to_api_path, sqlite3 *db) const std::string &to_api_path) -> api_error;
-> api_error;
void queue_upload(const i_open_file &file) override; void queue_upload(const i_open_file &file) override;
@ -148,27 +136,27 @@ public:
[[nodiscard]] auto has_no_open_file_handles() const -> bool override; [[nodiscard]] auto has_no_open_file_handles() const -> bool override;
[[nodiscard]] auto is_processing(const std::string &api_path) const [[nodiscard]] auto
-> bool override; is_processing(const std::string &api_path) const -> bool override;
#if defined(PROJECT_TESTING) #if defined(PROJECT_TESTING)
[[nodiscard]] auto open(std::shared_ptr<i_closeable_open_file> of, [[nodiscard]] auto open(std::shared_ptr<i_closeable_open_file> of,
const open_file_data &ofd, std::uint64_t &handle, const open_file_data &ofd, std::uint64_t &handle,
std::shared_ptr<i_open_file> &file) -> api_error; std::shared_ptr<i_open_file> &file) -> api_error;
#endif #endif // defined(PROJECT_TESTING)
[[nodiscard]] auto open(const std::string &api_path, bool directory, [[nodiscard]] auto open(const std::string &api_path, bool directory,
const open_file_data &ofd, std::uint64_t &handle, const open_file_data &ofd, std::uint64_t &handle,
std::shared_ptr<i_open_file> &file) -> api_error; std::shared_ptr<i_open_file> &file) -> api_error;
[[nodiscard]] auto remove_file(const std::string &api_path) -> api_error; [[nodiscard]] auto remove_file(const std::string &api_path) -> api_error;
[[nodiscard]] auto rename_directory(const std::string &from_api_path, [[nodiscard]] auto
const std::string &to_api_path) rename_directory(const std::string &from_api_path,
-> api_error; const std::string &to_api_path) -> api_error;
[[nodiscard]] auto rename_file(const std::string &from_api_path, [[nodiscard]] auto rename_file(const std::string &from_api_path,
const std::string &to_api_path, bool overwrite) const std::string &to_api_path,
-> api_error; bool overwrite) -> api_error;
void start(); void start();

View File

@ -43,8 +43,8 @@
#include "utils/time.hpp" #include "utils/time.hpp"
namespace { namespace {
[[nodiscard]] auto create_resume_entry(const repertory::i_open_file &file) [[nodiscard]] auto
-> json { create_resume_entry(const repertory::i_open_file &file) -> json {
return { return {
{"chunk_size", file.get_chunk_size()}, {"chunk_size", file.get_chunk_size()},
{"path", file.get_api_path()}, {"path", file.get_api_path()},
@ -106,6 +106,10 @@ const std::map<std::string, std::string> sql_create_tables{
namespace repertory { namespace repertory {
file_manager::file_manager(app_config &config, i_provider &provider) file_manager::file_manager(app_config &config, i_provider &provider)
: config_(config), provider_(provider) { : config_(config), provider_(provider) {
db_ = utils::db::sqlite::create_db(
utils::path::combine(config_.get_data_directory(), {"file_manager.db"}),
sql_create_tables);
if (not provider_.is_direct_only()) { if (not provider_.is_direct_only()) {
E_SUBSCRIBE_EXACT(file_upload_completed, E_SUBSCRIBE_EXACT(file_upload_completed,
[this](const file_upload_completed &completed) { [this](const file_upload_completed &completed) {
@ -116,6 +120,7 @@ file_manager::file_manager(app_config &config, i_provider &provider)
file_manager::~file_manager() { file_manager::~file_manager() {
stop(); stop();
db_.reset();
E_CONSUMER_RELEASE(); E_CONSUMER_RELEASE();
} }
@ -170,38 +175,6 @@ void file_manager::close_timed_out_files() {
closeable_list.clear(); closeable_list.clear();
} }
auto file_manager::create_db() const -> utils::db::sqlite::db3_t {
auto db_path =
utils::path::combine(config_.get_data_directory(), {"file_manager.db"});
sqlite3 *db3{nullptr};
auto db_res =
sqlite3_open_v2(db_path.c_str(), &db3,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
if (db_res != SQLITE_OK) {
throw std::runtime_error("failed to open db|" + db_path + '|' +
std::to_string(db_res) + '|' +
sqlite3_errstr(db_res));
}
auto db = utils::db::sqlite::db3_t{
db3,
utils::db::sqlite::sqlite3_deleter(),
};
for (auto &&create_item : sql_create_tables) {
std::string err;
if (not utils::db::sqlite::execute_sql(*db, create_item.second, err)) {
db.reset();
throw std::runtime_error(err);
}
}
utils::db::sqlite::set_journal_mode(*db);
return db;
}
auto file_manager::create(const std::string &api_path, api_meta_map &meta, auto file_manager::create(const std::string &api_path, api_meta_map &meta,
open_file_data ofd, std::uint64_t &handle, open_file_data ofd, std::uint64_t &handle,
std::shared_ptr<i_open_file> &file) -> api_error { std::shared_ptr<i_open_file> &file) -> api_error {
@ -361,10 +334,8 @@ auto file_manager::get_stored_downloads() const -> std::vector<json> {
return {}; return {};
} }
auto db = create_db();
std::vector<json> ret; std::vector<json> ret;
auto result = utils::db::sqlite::db_select{*db.get(), resume_table}.go(); auto result = utils::db::sqlite::db_select{*db_, resume_table}.go();
while (result.has_row()) { while (result.has_row()) {
try { try {
std::optional<utils::db::sqlite::db_select::row> row; std::optional<utils::db::sqlite::db_select::row> row;
@ -385,8 +356,8 @@ auto file_manager::get_stored_downloads() const -> std::vector<json> {
} }
auto file_manager::handle_file_rename(const std::string &from_api_path, auto file_manager::handle_file_rename(const std::string &from_api_path,
const std::string &to_api_path, const std::string &to_api_path)
sqlite3 *db) -> api_error { -> api_error {
std::string source_path{}; std::string source_path{};
auto file_iter = open_file_lookup_.find(from_api_path); auto file_iter = open_file_lookup_.find(from_api_path);
if (file_iter != open_file_lookup_.end()) { if (file_iter != open_file_lookup_.end()) {
@ -399,7 +370,7 @@ auto file_manager::handle_file_rename(const std::string &from_api_path,
source_path = upload_lookup_.at(from_api_path)->get_source_path(); source_path = upload_lookup_.at(from_api_path)->get_source_path();
} }
} else { } else {
auto result = utils::db::sqlite::db_select{*db, upload_table} auto result = utils::db::sqlite::db_select{*db_, upload_table}
.column("source_path") .column("source_path")
.where("api_path") .where("api_path")
.equals(from_api_path) .equals(from_api_path)
@ -411,22 +382,22 @@ auto file_manager::handle_file_rename(const std::string &from_api_path,
} }
} }
remove_upload(from_api_path, true, db); remove_upload(from_api_path, true);
auto ret = provider_.rename_file(from_api_path, to_api_path); auto ret = provider_.rename_file(from_api_path, to_api_path);
if (ret != api_error::success) { if (ret != api_error::success) {
queue_upload(from_api_path, source_path, false, db); queue_upload(from_api_path, source_path, false);
return ret; return ret;
} }
swap_renamed_items(from_api_path, to_api_path, false, db); swap_renamed_items(from_api_path, to_api_path, false);
ret = source_path.empty() ret = source_path.empty()
? api_error::success ? api_error::success
: provider_.set_item_meta(to_api_path, META_SOURCE, source_path); : provider_.set_item_meta(to_api_path, META_SOURCE, source_path);
if (should_upload) { if (should_upload) {
queue_upload(to_api_path, source_path, false, db); queue_upload(to_api_path, source_path, false);
} }
return ret; return ret;
@ -447,9 +418,7 @@ auto file_manager::is_processing(const std::string &api_path) const -> bool {
} }
upload_lock.unlock(); upload_lock.unlock();
auto db = create_db(); utils::db::sqlite::db_select query{*db_, upload_table};
utils::db::sqlite::db_select query{*db.get(), upload_table};
if (query.where("api_path").equals(api_path).go().has_row()) { if (query.where("api_path").equals(api_path).go().has_row()) {
return true; return true;
}; };
@ -469,11 +438,10 @@ auto file_manager::open(const std::string &api_path, bool directory,
return open(api_path, directory, ofd, handle, file, nullptr); return open(api_path, directory, ofd, handle, file, nullptr);
} }
auto file_manager::open(const std::string &api_path, bool directory, auto file_manager::open(
const open_file_data &ofd, std::uint64_t &handle, const std::string &api_path, bool directory, const open_file_data &ofd,
std::shared_ptr<i_open_file> &file, std::uint64_t &handle, std::shared_ptr<i_open_file> &file,
std::shared_ptr<i_closeable_open_file> closeable_file) std::shared_ptr<i_closeable_open_file> closeable_file) -> api_error {
-> api_error {
const auto create_and_add_handle = const auto create_and_add_handle =
[&](std::shared_ptr<i_closeable_open_file> cur_file) { [&](std::shared_ptr<i_closeable_open_file> cur_file) {
handle = get_next_handle(); handle = get_next_handle();
@ -517,14 +485,11 @@ auto file_manager::open(const std::string &api_path, bool directory,
} }
void file_manager::queue_upload(const i_open_file &file) { void file_manager::queue_upload(const i_open_file &file) {
auto db = create_db(); return queue_upload(file.get_api_path(), file.get_source_path(), false);
return queue_upload(file.get_api_path(), file.get_source_path(), false,
db.get());
} }
void file_manager::queue_upload(const std::string &api_path, void file_manager::queue_upload(const std::string &api_path,
const std::string &source_path, bool no_lock, const std::string &source_path, bool no_lock) {
sqlite3 *db) {
if (provider_.is_direct_only()) { if (provider_.is_direct_only()) {
return; return;
} }
@ -533,10 +498,10 @@ void file_manager::queue_upload(const std::string &api_path,
if (not no_lock) { if (not no_lock) {
lock = std::make_unique<mutex_lock>(upload_mtx_); lock = std::make_unique<mutex_lock>(upload_mtx_);
} }
remove_upload(api_path, true, db); remove_upload(api_path, true);
auto result = auto result =
utils::db::sqlite::db_insert{*db, upload_table} utils::db::sqlite::db_insert{*db_, upload_table}
.or_replace() .or_replace()
.column_value("api_path", api_path) .column_value("api_path", api_path)
.column_value("date_time", .column_value("date_time",
@ -544,7 +509,7 @@ void file_manager::queue_upload(const std::string &api_path,
.column_value("source_path", source_path) .column_value("source_path", source_path)
.go(); .go();
if (result.ok()) { if (result.ok()) {
remove_resume(api_path, source_path, db); remove_resume(api_path, source_path);
event_system::instance().raise<file_upload_queued>(api_path, source_path); event_system::instance().raise<file_upload_queued>(api_path, source_path);
} else { } else {
event_system::instance().raise<file_upload_failed>( event_system::instance().raise<file_upload_failed>(
@ -570,10 +535,9 @@ auto file_manager::remove_file(const std::string &api_path) -> api_error {
close_all(api_path); close_all(api_path);
auto db = create_db(); remove_upload(api_path, true);
remove_upload(api_path, true, db.get());
auto result = utils::db::sqlite::db_delete{*db.get(), resume_table} auto result = utils::db::sqlite::db_delete{*db_, resume_table}
.where("api_path") .where("api_path")
.equals(api_path) .equals(api_path)
.go(); .go();
@ -599,13 +563,7 @@ auto file_manager::remove_file(const std::string &api_path) -> api_error {
void file_manager::remove_resume(const std::string &api_path, void file_manager::remove_resume(const std::string &api_path,
const std::string &source_path) { const std::string &source_path) {
auto db = create_db(); auto result = utils::db::sqlite::db_delete{*db_, resume_table}
return remove_resume(api_path, source_path, db.get());
}
void file_manager::remove_resume(const std::string &api_path,
const std::string &source_path, sqlite3 *db) {
auto result = utils::db::sqlite::db_delete{*db, resume_table}
.where("api_path") .where("api_path")
.equals(api_path) .equals(api_path)
.go(); .go();
@ -616,12 +574,10 @@ void file_manager::remove_resume(const std::string &api_path,
} }
void file_manager::remove_upload(const std::string &api_path) { void file_manager::remove_upload(const std::string &api_path) {
auto db = create_db(); remove_upload(api_path, false);
remove_upload(api_path, false, db.get());
} }
void file_manager::remove_upload(const std::string &api_path, bool no_lock, void file_manager::remove_upload(const std::string &api_path, bool no_lock) {
sqlite3 *db) {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
if (provider_.is_direct_only()) { if (provider_.is_direct_only()) {
@ -633,7 +589,7 @@ void file_manager::remove_upload(const std::string &api_path, bool no_lock,
lock = std::make_unique<mutex_lock>(upload_mtx_); lock = std::make_unique<mutex_lock>(upload_mtx_);
} }
auto result = utils::db::sqlite::db_delete{*db, upload_table} auto result = utils::db::sqlite::db_delete{*db_, upload_table}
.where("api_path") .where("api_path")
.equals(api_path) .equals(api_path)
.go(); .go();
@ -643,7 +599,7 @@ void file_manager::remove_upload(const std::string &api_path, bool no_lock,
"failed to remove from upload table"); "failed to remove from upload table");
} }
result = utils::db::sqlite::db_delete{*db, upload_active_table} result = utils::db::sqlite::db_delete{*db_, upload_active_table}
.where("api_path") .where("api_path")
.equals(api_path) .equals(api_path)
.go(); .go();
@ -670,13 +626,6 @@ void file_manager::remove_upload(const std::string &api_path, bool no_lock,
auto file_manager::rename_directory(const std::string &from_api_path, auto file_manager::rename_directory(const std::string &from_api_path,
const std::string &to_api_path) const std::string &to_api_path)
-> api_error { -> api_error {
auto db = create_db();
return rename_directory(from_api_path, to_api_path, db.get());
}
auto file_manager::rename_directory(const std::string &from_api_path,
const std::string &to_api_path, sqlite3 *db)
-> api_error {
if (not provider_.is_rename_supported()) { if (not provider_.is_rename_supported()) {
return api_error::not_implemented; return api_error::not_implemented;
} }
@ -732,9 +681,8 @@ auto file_manager::rename_directory(const std::string &from_api_path,
auto old_api_path = api_path; auto old_api_path = api_path;
auto new_api_path = utils::path::create_api_path(utils::path::combine( auto new_api_path = utils::path::create_api_path(utils::path::combine(
to_api_path, {old_api_path.substr(from_api_path.size())})); to_api_path, {old_api_path.substr(from_api_path.size())}));
res = list[i].directory res = list[i].directory ? rename_directory(old_api_path, new_api_path)
? rename_directory(old_api_path, new_api_path, db) : rename_file(old_api_path, new_api_path, false);
: rename_file(old_api_path, new_api_path, false, db);
} }
} }
@ -747,20 +695,13 @@ auto file_manager::rename_directory(const std::string &from_api_path,
return res; return res;
} }
swap_renamed_items(from_api_path, to_api_path, true, db); swap_renamed_items(from_api_path, to_api_path, true);
return api_error::success; return api_error::success;
} }
auto file_manager::rename_file(const std::string &from_api_path, auto file_manager::rename_file(const std::string &from_api_path,
const std::string &to_api_path, bool overwrite) const std::string &to_api_path,
-> api_error { bool overwrite) -> api_error {
auto db = create_db();
return rename_file(from_api_path, to_api_path, overwrite, db.get());
}
auto file_manager::rename_file(const std::string &from_api_path,
const std::string &to_api_path, bool overwrite,
sqlite3 *db) -> api_error {
if (not provider_.is_rename_supported()) { if (not provider_.is_rename_supported()) {
return api_error::not_implemented; return api_error::not_implemented;
} }
@ -828,7 +769,7 @@ auto file_manager::rename_file(const std::string &from_api_path,
} }
} }
return handle_file_rename(from_api_path, to_api_path, db); return handle_file_rename(from_api_path, to_api_path);
} }
void file_manager::start() { void file_manager::start() {
@ -849,8 +790,6 @@ void file_manager::start() {
return; return;
} }
auto db = create_db();
struct active_item final { struct active_item final {
std::string api_path; std::string api_path;
std::string source_path; std::string source_path;
@ -858,8 +797,7 @@ void file_manager::start() {
std::vector<active_item> active_items{}; std::vector<active_item> active_items{};
auto result = auto result = utils::db::sqlite::db_select{*db_, upload_active_table}.go();
utils::db::sqlite::db_select{*db.get(), upload_active_table}.go();
while (result.has_row()) { while (result.has_row()) {
try { try {
std::optional<utils::db::sqlite::db_select::row> row; std::optional<utils::db::sqlite::db_select::row> row;
@ -875,12 +813,11 @@ void file_manager::start() {
} }
for (auto &&active_item : active_items) { for (auto &&active_item : active_items) {
queue_upload(active_item.api_path, active_item.source_path, false, queue_upload(active_item.api_path, active_item.source_path, false);
db.get());
} }
active_items.clear(); active_items.clear();
result = utils::db::sqlite::db_select{*db.get(), resume_table}.go(); result = utils::db::sqlite::db_select{*db_, resume_table}.go();
if (not result.ok()) { if (not result.ok()) {
return; return;
} }
@ -999,8 +936,7 @@ void file_manager::store_resume(const i_open_file &file) {
return; return;
} }
auto db = create_db(); auto result = utils::db::sqlite::db_insert{*db_, resume_table}
auto result = utils::db::sqlite::db_insert{*db.get(), resume_table}
.or_replace() .or_replace()
.column_value("api_path", file.get_api_path()) .column_value("api_path", file.get_api_path())
.column_value("data", create_resume_entry(file).dump()) .column_value("data", create_resume_entry(file).dump())
@ -1018,8 +954,7 @@ void file_manager::store_resume(const i_open_file &file) {
} }
void file_manager::swap_renamed_items(std::string from_api_path, void file_manager::swap_renamed_items(std::string from_api_path,
std::string to_api_path, bool directory, std::string to_api_path, bool directory) {
sqlite3 *db) {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
auto file_iter = open_file_lookup_.find(from_api_path); auto file_iter = open_file_lookup_.find(from_api_path);
@ -1034,7 +969,7 @@ void file_manager::swap_renamed_items(std::string from_api_path,
return; return;
} }
auto result = utils::db::sqlite::db_update{*db, resume_table} auto result = utils::db::sqlite::db_update{*db_, resume_table}
.column_value("api_path", to_api_path) .column_value("api_path", to_api_path)
.where("api_path") .where("api_path")
.equals(from_api_path) .equals(from_api_path)
@ -1052,11 +987,9 @@ void file_manager::upload_completed(const file_upload_completed &evt) {
unique_mutex_lock upload_lock(upload_mtx_); unique_mutex_lock upload_lock(upload_mtx_);
if (not utils::string::to_bool(evt.get_cancelled().get<std::string>())) { if (not utils::string::to_bool(evt.get_cancelled().get<std::string>())) {
auto db = create_db();
auto err = api_error_from_string(evt.get_result().get<std::string>()); auto err = api_error_from_string(evt.get_result().get<std::string>());
if (err == api_error::success) { if (err == api_error::success) {
auto result = utils::db::sqlite::db_delete{*db.get(), upload_active_table} auto result = utils::db::sqlite::db_delete{*db_, upload_active_table}
.where("api_path") .where("api_path")
.equals(evt.get_api_path().get<std::string>()) .equals(evt.get_api_path().get<std::string>())
.go(); .go();
@ -1075,12 +1008,12 @@ void file_manager::upload_completed(const file_upload_completed &evt) {
not utils::file::file(evt.get_source().get<std::string>()).exists()) { not utils::file::file(evt.get_source().get<std::string>()).exists()) {
event_system::instance().raise<file_upload_not_found>( event_system::instance().raise<file_upload_not_found>(
evt.get_api_path(), evt.get_source()); evt.get_api_path(), evt.get_source());
remove_upload(evt.get_api_path(), true, db.get()); remove_upload(evt.get_api_path(), true);
} else { } else {
event_system::instance().raise<file_upload_retry>( event_system::instance().raise<file_upload_retry>(
evt.get_api_path(), evt.get_source(), err); evt.get_api_path(), evt.get_source(), err);
queue_upload(evt.get_api_path(), evt.get_source(), true, db.get()); queue_upload(evt.get_api_path(), evt.get_source(), true);
upload_notify_.wait_for(upload_lock, 5s); upload_notify_.wait_for(upload_lock, 5s);
} }
} }
@ -1092,8 +1025,6 @@ void file_manager::upload_completed(const file_upload_completed &evt) {
void file_manager::upload_handler() { void file_manager::upload_handler() {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
auto db = create_db();
while (not stop_requested_) { while (not stop_requested_) {
auto should_wait{true}; auto should_wait{true};
unique_mutex_lock upload_lock(upload_mtx_); unique_mutex_lock upload_lock(upload_mtx_);
@ -1103,7 +1034,7 @@ void file_manager::upload_handler() {
} }
if (upload_lookup_.size() < config_.get_max_upload_count()) { if (upload_lookup_.size() < config_.get_max_upload_count()) {
auto result = utils::db::sqlite::db_select{*db.get(), upload_table} auto result = utils::db::sqlite::db_select{*db_, upload_table}
.order_by("api_path", true) .order_by("api_path", true)
.limit(1) .limit(1)
.go(); .go();
@ -1121,7 +1052,7 @@ void file_manager::upload_handler() {
should_wait = false; should_wait = false;
event_system::instance().raise<file_upload_not_found>(api_path, event_system::instance().raise<file_upload_not_found>(api_path,
source_path); source_path);
remove_upload(api_path, true, db.get()); remove_upload(api_path, true);
} break; } break;
case api_error::success: { case api_error::success: {
@ -1129,13 +1060,13 @@ void file_manager::upload_handler() {
upload_lookup_[fsi.api_path] = upload_lookup_[fsi.api_path] =
std::make_unique<upload>(fsi, provider_); std::make_unique<upload>(fsi, provider_);
auto del_res = utils::db::sqlite::db_delete{*db.get(), upload_table} auto del_res = utils::db::sqlite::db_delete{*db_, upload_table}
.where("api_path") .where("api_path")
.equals(api_path) .equals(api_path)
.go(); .go();
if (del_res.ok()) { if (del_res.ok()) {
auto ins_res = auto ins_res =
utils::db::sqlite::db_insert{*db.get(), upload_active_table} utils::db::sqlite::db_insert{*db_, upload_active_table}
.column_value("api_path", api_path) .column_value("api_path", api_path)
.column_value("source_path", source_path) .column_value("source_path", source_path)
.go(); .go();
@ -1150,7 +1081,7 @@ void file_manager::upload_handler() {
default: { default: {
event_system::instance().raise<file_upload_retry>(api_path, event_system::instance().raise<file_upload_retry>(api_path,
source_path, res); source_path, res);
queue_upload(api_path, source_path, true, db.get()); queue_upload(api_path, source_path, true);
} break; } break;
} }
} }

View File

@ -1025,35 +1025,9 @@ auto encrypt_provider::start(api_item_added_callback /*api_item_added*/,
return false; return false;
} }
auto db_path = db_ = utils::db::sqlite::create_db(
utils::path::combine(config_.get_data_directory(), {"meta.db"}); utils::path::combine(config_.get_data_directory(), {"meta.db"}),
sql_create_tables);
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_name, "failed to open db|" + db_path +
'|' + std::to_string(res) +
'|' + sqlite3_errstr(res));
return false;
}
db_ = utils::db::sqlite::db3_t{
db3,
utils::db::sqlite::sqlite3_deleter(),
};
for (auto &&create : sql_create_tables) {
std::string err;
if (not utils::db::sqlite::execute_sql(*db_, create.second, err)) {
utils::error::raise_error(function_name, "failed to create table|" +
create.first + '|' + err);
db_.reset();
return false;
}
}
utils::db::sqlite::set_journal_mode(*db_);
const auto cfg = config_.get_encrypt_config(); const auto cfg = config_.get_encrypt_config();

View File

@ -34,25 +34,10 @@ namespace repertory {
meta_db::meta_db(const app_config &cfg) { meta_db::meta_db(const app_config &cfg) {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
auto db_path = utils::path::combine(cfg.get_data_directory(), {"meta.db"}); const std::map<std::string, std::string> sql_create_tables{
{
sqlite3 *db3{nullptr}; {"meta"},
auto res = {"CREATE TABLE IF NOT EXISTS "
sqlite3_open_v2(db_path.c_str(), &db3,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
if (res != SQLITE_OK) {
utils::error::raise_error(function_name, "failed to open db|" + db_path +
'|' + std::to_string(res) +
'|' + sqlite3_errstr(res));
return;
}
db_ = utils::db::sqlite::db3_t{
db3,
utils::db::sqlite::sqlite3_deleter(),
};
const auto *create = "CREATE TABLE IF NOT EXISTS "
"meta " "meta "
"(" "("
"api_path TEXT PRIMARY KEY ASC, " "api_path TEXT PRIMARY KEY ASC, "
@ -60,16 +45,13 @@ meta_db::meta_db(const app_config &cfg) {
"directory INTEGER, " "directory INTEGER, "
"pinned INTEGER, " "pinned INTEGER, "
"source_path TEXT" "source_path TEXT"
");"; ");"},
std::string err; },
if (not utils::db::sqlite::execute_sql(*db_, create, err)) { };
utils::error::raise_error(function_name,
"failed to create db|" + db_path + '|' + err);
db_.reset();
return;
}
utils::db::sqlite::set_journal_mode(*db_); db_ = utils::db::sqlite::create_db(
utils::path::combine(cfg.get_data_directory(), {"meta.db"}),
sql_create_tables);
} }
meta_db::~meta_db() { db_.reset(); } meta_db::~meta_db() { db_.reset(); }

View File

@ -92,7 +92,11 @@ template <typename val_t>
} }
if (fmt_val.empty()) { if (fmt_val.empty()) {
throw std::runtime_error("hex string is invalid|" + std::string{str}); throw utils::error::create_exception({
function_name,
"hex string is invalid",
str,
});
} }
if (fmt_val.length() % 2U) { if (fmt_val.length() % 2U) {
@ -107,9 +111,13 @@ template <typename val_t>
}); });
if (iter != fmt_val.end()) { if (iter != fmt_val.end()) {
auto invalid_idx{std::distance(fmt_val.begin(), iter)}; auto invalid_idx{std::distance(fmt_val.begin(), iter)};
throw std::range_error( throw std::range_error(utils::error::create_error_message({
"invalid character in hex string|" + std::to_string(invalid_idx) + function_name,
'|' + std::string(1U, str.at(invalid_idx)) + '|' + std::string{str}); "invalid character in hex string",
std::to_string(invalid_idx),
std::string(1U, str.at(invalid_idx)),
str,
}));
} }
val.resize(fmt_val.length() / 2U); val.resize(fmt_val.length() / 2U);

View File

@ -25,6 +25,8 @@
#include "utils/config.hpp" #include "utils/config.hpp"
#include "utils/error.hpp"
namespace repertory::utils::db::sqlite { namespace repertory::utils::db::sqlite {
using db_types_t = std::variant<std::int64_t, std::string>; using db_types_t = std::variant<std::int64_t, std::string>;
@ -44,6 +46,10 @@ struct sqlite3_statement_deleter final {
using db3_stmt_t = std::unique_ptr<sqlite3_stmt, sqlite3_statement_deleter>; using db3_stmt_t = std::unique_ptr<sqlite3_stmt, sqlite3_statement_deleter>;
[[nodiscard]] auto
create_db(std::string db_path,
const std::map<std::string, std::string> &sql_create_tables) -> db3_t;
[[nodiscard]] auto execute_sql(sqlite3 &db3, const std::string &sql, [[nodiscard]] auto execute_sql(sqlite3 &db3, const std::string &sql,
std::string &err) -> bool; std::string &err) -> bool;
@ -89,11 +95,16 @@ public:
template <typename data_type> template <typename data_type>
[[nodiscard]] auto get_value() const -> data_type { [[nodiscard]] auto get_value() const -> data_type {
REPERTORY_USES_FUNCTION_NAME();
return std::visit( return std::visit(
overloaded{ overloaded{
[](const data_type &value) -> data_type { return value; }, [](const data_type &value) -> data_type { return value; },
[](auto &&) -> data_type { [](auto &&) -> data_type {
throw std::runtime_error("data type not supported"); throw utils::error::create_exception({
function_name,
"data type not supported",
});
}, },
}, },
value_); value_);
@ -107,6 +118,8 @@ public:
template <typename ctx_t> class db_row final { template <typename ctx_t> class db_row final {
public: public:
db_row(std::shared_ptr<ctx_t> ctx) { db_row(std::shared_ptr<ctx_t> ctx) {
REPERTORY_USES_FUNCTION_NAME();
auto column_count = sqlite3_column_count(ctx->stmt.get()); auto column_count = sqlite3_column_count(ctx->stmt.get());
for (std::int32_t col = 0; col < column_count; col++) { for (std::int32_t col = 0; col < column_count; col++) {
std::string name{sqlite3_column_name(ctx->stmt.get(), col)}; std::string name{sqlite3_column_name(ctx->stmt.get(), col)};
@ -125,8 +138,11 @@ public:
} break; } break;
default: default:
throw std::runtime_error("column type not implemented|" + name + '|' + throw utils::error::create_exception({
std::to_string(column_type)); function_name,
"column type not implemented",
std::to_string(column_type),
});
} }
columns_[name] = db_column{col, name, value}; columns_[name] = db_column{col, name, value};

View File

@ -157,8 +157,8 @@ template <typename ctx_t, typename op_t> struct db_where_t final {
using action_t = std::variant<db_comp_data_t, n_t, db_where_t>; using action_t = std::variant<db_comp_data_t, n_t, db_where_t>;
[[nodiscard]] static auto dump(std::int32_t &idx, auto &&actions) [[nodiscard]] static auto dump(std::int32_t &idx,
-> std::string { auto &&actions) -> std::string {
std::stringstream stream; std::stringstream stream;
for (auto &&action : actions) { for (auto &&action : actions) {

View File

@ -25,6 +25,7 @@
#include "utils/config.hpp" #include "utils/config.hpp"
#include "utils/error.hpp"
#include "utils/hash.hpp" #include "utils/hash.hpp"
namespace repertory::utils::encryption { namespace repertory::utils::encryption {
@ -108,6 +109,8 @@ encrypt_data(const std::array<unsigned char,
const std::array<arr_t, arr_size> &key, const std::array<arr_t, arr_size> &key,
const unsigned char *buffer, std::size_t buffer_size, const unsigned char *buffer, std::size_t buffer_size,
result_t &res) { result_t &res) {
REPERTORY_USES_FUNCTION_NAME();
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_ABYTES> mac{}; std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_ABYTES> mac{};
const std::uint32_t size = boost::endian::native_to_big( const std::uint32_t size = boost::endian::native_to_big(
@ -121,7 +124,10 @@ encrypt_data(const std::array<unsigned char,
mac.data(), &mac_length, buffer, buffer_size, mac.data(), &mac_length, buffer, buffer_size,
reinterpret_cast<const unsigned char *>(&size), sizeof(size), nullptr, reinterpret_cast<const unsigned char *>(&size), sizeof(size), nullptr,
iv.data(), key.data()) != 0) { iv.data(), key.data()) != 0) {
throw std::runtime_error("encryption failed"); throw repertory::utils::error::create_exception({
function_name,
"encryption failed",
});
} }
std::memcpy(res.data(), iv.data(), iv.size()); std::memcpy(res.data(), iv.data(), iv.size());

View File

@ -25,6 +25,12 @@
#include "utils/config.hpp" #include "utils/config.hpp"
namespace repertory::utils::error { namespace repertory::utils::error {
[[nodiscard]] auto
create_error_message(std::vector<std::string_view> items) -> std::string;
[[nodiscard]] auto
create_exception(std::vector<std::string_view> items) -> std::runtime_error;
struct i_exception_handler { struct i_exception_handler {
virtual ~i_exception_handler() {} virtual ~i_exception_handler() {}
@ -48,17 +54,30 @@ protected:
struct iostream_exception_handler final : i_exception_handler { struct iostream_exception_handler final : i_exception_handler {
void handle_error(std::string_view function_name, void handle_error(std::string_view function_name,
std::string_view msg) const override { std::string_view msg) const override {
std::cerr << function_name << '|' << msg << std::endl; std::cerr << create_error_message({
function_name,
msg,
})
<< std::endl;
} }
void handle_exception(std::string_view function_name) const override { void handle_exception(std::string_view function_name) const override {
std::cerr << function_name << "|exception|unknown" << std::endl; std::cerr << create_error_message({
function_name,
"exception",
"unknown",
})
<< std::endl;
} }
void handle_exception(std::string_view function_name, void handle_exception(std::string_view function_name,
const std::exception &ex) const override { const std::exception &ex) const override {
std::cerr << function_name << "|exception|" std::cerr << create_error_message({
<< (ex.what() == nullptr ? "unknown" : ex.what()) << std::endl; function_name,
"exception",
(ex.what() == nullptr ? "unknown" : ex.what()),
})
<< std::endl;
} }
}; };
inline const iostream_exception_handler default_exception_handler{}; inline const iostream_exception_handler default_exception_handler{};
@ -66,15 +85,12 @@ inline const iostream_exception_handler default_exception_handler{};
extern std::atomic<const i_exception_handler *> exception_handler; extern std::atomic<const i_exception_handler *> exception_handler;
#if defined(PROJECT_ENABLE_TESTING) #if defined(PROJECT_ENABLE_TESTING)
[[nodiscard]] inline auto get_exception_handler() [[nodiscard]] inline auto
-> const i_exception_handler * { get_exception_handler() -> const i_exception_handler * {
return exception_handler; return exception_handler;
} }
#endif // defined(PROJECT_ENABLE_TESTING) #endif // defined(PROJECT_ENABLE_TESTING)
[[nodiscard]] auto create_error_message(std::vector<std::string_view> items)
-> std::string;
void handle_error(std::string_view function_name, std::string_view msg); void handle_error(std::string_view function_name, std::string_view msg);
void handle_exception(std::string_view function_name); void handle_exception(std::string_view function_name);

View File

@ -25,6 +25,8 @@
#include "utils/config.hpp" #include "utils/config.hpp"
#include "utils/error.hpp"
namespace repertory::utils::encryption { namespace repertory::utils::encryption {
using hash_256_t = std::array<unsigned char, 32U>; using hash_256_t = std::array<unsigned char, 32U>;
using hash_384_t = std::array<unsigned char, 48U>; using hash_384_t = std::array<unsigned char, 48U>;
@ -83,28 +85,39 @@ template <typename hash_t>
template <typename hash_t> template <typename hash_t>
auto create_hash_blake2b_t(const unsigned char *data, auto create_hash_blake2b_t(const unsigned char *data,
std::size_t data_size) -> hash_t { std::size_t data_size) -> hash_t {
REPERTORY_USES_FUNCTION_NAME();
hash_t hash{}; hash_t hash{};
crypto_generichash_blake2b_state state{}; crypto_generichash_blake2b_state state{};
auto res = crypto_generichash_blake2b_init(&state, nullptr, 0U, hash.size()); auto res = crypto_generichash_blake2b_init(&state, nullptr, 0U, hash.size());
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to initialize blake2b-" + throw utils::error::create_exception({
std::to_string(hash.size() * 8U) + "|" + function_name,
std::to_string(res)); "failed to initialize blake2b",
std::to_string(hash.size() * 8U),
std::to_string(res),
});
} }
res = crypto_generichash_blake2b_update(&state, data, data_size); res = crypto_generichash_blake2b_update(&state, data, data_size);
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to update blake2b-" + throw utils::error::create_exception({
std::to_string(hash.size() * 8U) + "|" + function_name,
std::to_string(res)); "failed to update blake2b",
std::to_string(hash.size() * 8U),
std::to_string(res),
});
} }
res = crypto_generichash_blake2b_final(&state, hash.data(), hash.size()); res = crypto_generichash_blake2b_final(&state, hash.data(), hash.size());
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to finalize blake2b-" + throw utils::error::create_exception({
std::to_string(hash.size() * 8U) + "|" + function_name,
std::to_string(res)); "failed to finalize blake2b",
std::to_string(hash.size() * 8U),
std::to_string(res),
});
} }
return hash; return hash;

View File

@ -24,6 +24,7 @@
#include "utils/config.hpp" #include "utils/config.hpp"
#include "utils/error.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
namespace repertory::utils::file { namespace repertory::utils::file {
@ -41,6 +42,8 @@ struct file_times final {
std::uint64_t written{}; std::uint64_t written{};
[[nodiscard]] auto get(time_type type) const -> std::uint64_t { [[nodiscard]] auto get(time_type type) const -> std::uint64_t {
REPERTORY_USES_FUNCTION_NAME();
switch (type) { switch (type) {
case time_type::accessed: case time_type::accessed:
return accessed; return accessed;
@ -52,7 +55,10 @@ struct file_times final {
return written; return written;
} }
throw std::runtime_error("type_type not supported"); throw utils::error::create_exception({
function_name,
"type_type not supported",
});
} }
}; };

View File

@ -34,10 +34,16 @@ void sqlite3_deleter::operator()(sqlite3 *db3) const {
return; return;
} }
utils::error::handle_error(function_name, "closing database handle"); std::string err_msg;
if (not execute_sql(*db3, "VACUUM;", err_msg)) {
utils::error::handle_error(function_name,
utils::error::create_error_message({
"failed to vacuum database",
err_msg,
}));
}
if (not utils::retry_action( if (not utils::retry_action([&db3]() -> bool {
[&db3]() -> bool {
auto res = sqlite3_close_v2(db3); auto res = sqlite3_close_v2(db3);
if (res == SQLITE_OK) { if (res == SQLITE_OK) {
return true; return true;
@ -51,8 +57,7 @@ void sqlite3_deleter::operator()(sqlite3 *db3) const {
(err_str == nullptr ? std::to_string(res) : err_str), (err_str == nullptr ? std::to_string(res) : err_str),
})); }));
return false; return false;
}, })) {
60U)) {
repertory::utils::error::handle_error(function_name, repertory::utils::error::handle_error(function_name,
"failed to close database"); "failed to close database");
} }
@ -71,8 +76,50 @@ auto db_column::get_value_as_json() const -> nlohmann::json {
} }
#endif // defined(PROJECT_ENABLE_JSON) #endif // defined(PROJECT_ENABLE_JSON)
auto execute_sql(sqlite3 &db3, const std::string &sql, std::string &err) auto create_db(std::string db_path,
-> bool { const std::map<std::string, std::string> &sql_create_tables)
-> db3_t {
REPERTORY_USES_FUNCTION_NAME();
sqlite3 *db_ptr{nullptr};
auto db_res =
sqlite3_open_v2(db_path.c_str(), &db_ptr,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
if (db_res != SQLITE_OK) {
const auto *msg = sqlite3_errstr(db_res);
throw utils::error::create_exception({
function_name,
"failed to open db",
db_path,
(msg == nullptr ? std::to_string(db_res) : msg),
});
}
auto db3 = db3_t{
db_ptr,
sqlite3_deleter(),
};
for (auto &&create_item : sql_create_tables) {
std::string err_msg;
if (not sqlite::execute_sql(*db3, create_item.second, err_msg)) {
db3.reset();
throw utils::error::create_exception({
function_name,
err_msg,
});
}
}
set_journal_mode(*db3);
return db3;
}
auto execute_sql(sqlite3 &db3, const std::string &sql,
std::string &err) -> bool {
REPERTORY_USES_FUNCTION_NAME();
char *err_msg{nullptr}; char *err_msg{nullptr};
auto res = sqlite3_exec(&db3, sql.c_str(), nullptr, nullptr, &err_msg); auto res = sqlite3_exec(&db3, sql.c_str(), nullptr, nullptr, &err_msg);
if (err_msg != nullptr) { if (err_msg != nullptr) {
@ -85,15 +132,20 @@ auto execute_sql(sqlite3 &db3, const std::string &sql, std::string &err)
return true; return true;
} }
err = "failed to execute sql|" + sql + "|" + std::to_string(res) + '|' + err = utils::error::create_error_message({
(err.empty() ? sqlite3_errstr(res) : err); function_name,
"failed to execute sql",
err,
sql,
});
return false; return false;
} }
void set_journal_mode(sqlite3 &db3) { void set_journal_mode(sqlite3 &db3) {
sqlite3_exec(&db3, sqlite3_exec(&db3,
"PRAGMA journal_mode = WAL;PRAGMA synchronous = NORMAL;PRAGMA " "PRAGMA journal_mode = WAL;PRAGMA synchronous = NORMAL;PRAGMA "
"auto_vacuum = FULL;", "auto_vacuum = NONE;",
nullptr, nullptr, nullptr); nullptr, nullptr, nullptr);
} }
} // namespace repertory::utils::db::sqlite } // namespace repertory::utils::db::sqlite

View File

@ -60,8 +60,13 @@ protected:
std::ios_base::openmode which = std::ios_base::out | std::ios_base::openmode which = std::ios_base::out |
std::ios_base::in) std::ios_base::in)
-> pos_type override { -> pos_type override {
REPERTORY_USES_FUNCTION_NAME();
if ((which & std::ios_base::in) != std::ios_base::in) { if ((which & std::ios_base::in) != std::ios_base::in) {
throw std::runtime_error("output is not supported"); throw utils::error::create_exception({
function_name,
"output is not supported",
});
} }
const auto set_position = [this](char *next) -> pos_type { const auto set_position = [this](char *next) -> pos_type {
@ -179,9 +184,14 @@ encrypting_reader::encrypting_reader(
stop_requested_(stop_requested), stop_requested_(stop_requested),
error_return_(error_return), error_return_(error_return),
source_file_(utils::file::file::open_or_create_file(source_path, true)) { source_file_(utils::file::file::open_or_create_file(source_path, true)) {
REPERTORY_USES_FUNCTION_NAME();
if (not *source_file_) { if (not *source_file_) {
throw std::runtime_error("file open failed|src|" + throw utils::error::create_exception({
std::string{source_path}); function_name,
"file open failed",
source_path,
});
} }
data_buffer result; data_buffer result;
@ -204,8 +214,11 @@ encrypting_reader::encrypting_reader(
auto opt_size = source_file_->size(); auto opt_size = source_file_->size();
if (not opt_size.has_value()) { if (not opt_size.has_value()) {
throw std::runtime_error("failed to get file size|" + throw utils::error::create_exception({
source_file_->get_path()); function_name,
"failed to get file size",
source_file_->get_path(),
});
} }
auto file_size = opt_size.value(); auto file_size = opt_size.value();
@ -233,9 +246,14 @@ encrypting_reader::encrypting_reader(std::string_view encrypted_file_path,
stop_requested_(stop_requested), stop_requested_(stop_requested),
error_return_(error_return), error_return_(error_return),
source_file_(utils::file::file::open_or_create_file(source_path, true)) { source_file_(utils::file::file::open_or_create_file(source_path, true)) {
REPERTORY_USES_FUNCTION_NAME();
if (not *source_file_) { if (not *source_file_) {
throw std::runtime_error("file open failed|src|" + throw utils::error::create_exception({
std::string{source_path}); function_name,
"file open failed",
source_path,
});
} }
encrypted_file_path_ = encrypted_file_path; encrypted_file_path_ = encrypted_file_path;
@ -243,8 +261,11 @@ encrypting_reader::encrypting_reader(std::string_view encrypted_file_path,
auto opt_size = source_file_->size(); auto opt_size = source_file_->size();
if (not opt_size.has_value()) { if (not opt_size.has_value()) {
throw std::runtime_error("failed to get file size|" + throw utils::error::create_exception({
source_file_->get_path()); function_name,
"failed to get file size",
source_file_->get_path(),
});
} }
auto file_size = opt_size.value(); auto file_size = opt_size.value();
@ -274,9 +295,14 @@ encrypting_reader::encrypting_reader(
stop_requested_(stop_requested), stop_requested_(stop_requested),
error_return_(error_return), error_return_(error_return),
source_file_(utils::file::file::open_or_create_file(source_path, true)) { source_file_(utils::file::file::open_or_create_file(source_path, true)) {
REPERTORY_USES_FUNCTION_NAME();
if (not *source_file_) { if (not *source_file_) {
throw std::runtime_error("file open failed|src|" + throw utils::error::create_exception({
std::string{source_path}); function_name,
"file open failed",
source_path,
});
} }
encrypted_file_path_ = encrypted_file_path; encrypted_file_path_ = encrypted_file_path;
@ -284,9 +310,12 @@ encrypting_reader::encrypting_reader(
auto opt_size = source_file_->size(); auto opt_size = source_file_->size();
if (not opt_size.has_value()) { if (not opt_size.has_value()) {
throw std::runtime_error("get file size failed|src|" + throw utils::error::create_exception({
source_file_->get_path() + '|' + function_name,
std::to_string(utils::get_last_error_code())); "get file size failed",
std::to_string(utils::get_last_error_code()),
source_file_->get_path(),
});
} }
auto file_size{opt_size.value()}; auto file_size{opt_size.value()};
@ -315,9 +344,15 @@ encrypting_reader::encrypting_reader(const encrypting_reader &reader)
last_data_chunk_size_(reader.last_data_chunk_size_), last_data_chunk_size_(reader.last_data_chunk_size_),
read_offset_(reader.read_offset_), read_offset_(reader.read_offset_),
total_size_(reader.total_size_) { total_size_(reader.total_size_) {
REPERTORY_USES_FUNCTION_NAME();
if (not *source_file_) { if (not *source_file_) {
throw std::runtime_error("file open failed|src|" + throw utils::error::create_exception({
source_file_->get_path()); function_name,
"file open failed",
std::to_string(utils::get_last_error_code()),
source_file_->get_path(),
});
} }
} }
@ -331,11 +366,16 @@ auto encrypting_reader::calculate_decrypted_size(std::uint64_t total_size)
auto encrypting_reader::calculate_encrypted_size(std::string_view source_path) auto encrypting_reader::calculate_encrypted_size(std::string_view source_path)
-> std::uint64_t { -> std::uint64_t {
REPERTORY_USES_FUNCTION_NAME();
auto opt_size = utils::file::file{source_path}.size(); auto opt_size = utils::file::file{source_path}.size();
if (not opt_size.has_value()) { if (not opt_size.has_value()) {
throw std::runtime_error("get file size failed|src|" + throw utils::error::create_exception({
std::string{source_path} + '|' + function_name,
std::to_string(utils::get_last_error_code())); "get file size failed",
std::to_string(utils::get_last_error_code()),
source_path,
});
} }
auto file_size{opt_size.value()}; auto file_size{opt_size.value()};

View File

@ -38,6 +38,11 @@ auto create_error_message(std::vector<std::string_view> items) -> std::string {
return stream.str(); return stream.str();
} }
auto create_exception(std::vector<std::string_view> items)
-> std::runtime_error {
return std::runtime_error(create_error_message(items));
}
void handle_error(std::string_view function_name, std::string_view msg) { void handle_error(std::string_view function_name, std::string_view msg) {
const i_exception_handler *handler{exception_handler}; const i_exception_handler *handler{exception_handler};
if (handler != nullptr) { if (handler != nullptr) {

View File

@ -51,15 +51,23 @@ auto change_to_process_directory() -> bool {
#else // !defined(__APPLE__) #else // !defined(__APPLE__)
auto res = readlink("/proc/self/exe", path.data(), path.size()); auto res = readlink("/proc/self/exe", path.data(), path.size());
if (res == -1) { if (res == -1) {
throw std::runtime_error("failed to readlink|" + path + '|' + throw utils::error::create_exception({
std::to_string(errno)); function_name,
"failed to readlink",
std::to_string(utils::get_last_error_code()),
path,
});
} }
#endif // defined(__APPLE__) #endif // defined(__APPLE__)
path = utils::path::get_parent_path(path); path = utils::path::get_parent_path(path);
res = chdir(path.c_str()); res = chdir(path.c_str());
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to chdir|" + path + '|' + throw utils::error::create_exception({
std::to_string(errno)); function_name,
"failed to chdir",
std::to_string(utils::get_last_error_code()),
path,
});
} }
#endif // defined(_WIN32) #endif // defined(_WIN32)
@ -105,10 +113,12 @@ auto get_free_drive_space(std::string_view path)
ULARGE_INTEGER li{}; ULARGE_INTEGER li{};
if (not ::GetDiskFreeSpaceEx(std::string{path}.c_str(), &li, nullptr, if (not ::GetDiskFreeSpaceEx(std::string{path}.c_str(), &li, nullptr,
nullptr)) { nullptr)) {
throw std::runtime_error("failed to get free disk space|" + throw utils::error::create_exception({
std::string{path} + '|' + function_name,
std::to_string(utils::get_last_error_code())); "failed to get free disk space",
} std::to_string(utils::get_last_error_code()),
path,
});
return li.QuadPart; return li.QuadPart;
#endif // defined(_WIN32) #endif // defined(_WIN32)
@ -116,9 +126,12 @@ auto get_free_drive_space(std::string_view path)
#if defined(__linux__) #if defined(__linux__)
struct statfs64 st {}; struct statfs64 st {};
if (statfs64(std::string{path}.c_str(), &st) != 0) { if (statfs64(std::string{path}.c_str(), &st) != 0) {
throw std::runtime_error("failed to get free disk space|" + throw utils::error::create_exception({
std::string{path} + '|' + function_name,
std::to_string(utils::get_last_error_code())); "failed to get free disk space",
std::to_string(utils::get_last_error_code()),
path,
});
} }
return st.f_bfree * static_cast<std::uint64_t>(st.f_bsize); return st.f_bfree * static_cast<std::uint64_t>(st.f_bsize);
@ -127,28 +140,33 @@ auto get_free_drive_space(std::string_view path)
#if defined(__APPLE__) #if defined(__APPLE__)
struct statvfs st {}; struct statvfs st {};
if (statvfs(path.c_str(), &st) != 0) { if (statvfs(path.c_str(), &st) != 0) {
throw std::runtime_error("failed to get free disk space|" + throw utils::error::create_exception({
std::string{path} + '|' + function_name,
std::to_string(utils::get_last_error_code())); "failed to get free disk space",
std::to_string(utils::get_last_error_code()),
path,
});
} }
return st.f_bfree * static_cast<std::uint64_t>(st.f_frsize); return st.f_bfree * static_cast<std::uint64_t>(st.f_frsize);
#endif // defined(__APPLE__) #endif // defined(__APPLE__)
} catch (const std::exception &e) { }
catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { }
catch (...) {
utils::error::handle_exception(function_name); utils::error::handle_exception(function_name);
} }
return std::nullopt; return std::nullopt;
} }
auto get_free_drive_space(std::wstring_view path) auto get_free_drive_space(
-> std::optional<std::uint64_t> { std::wstring_view path) -> std::optional<std::uint64_t> {
return get_free_drive_space(utils::string::to_utf8(path)); return get_free_drive_space(utils::string::to_utf8(path));
} }
auto get_time(std::string_view path, auto get_time(std::string_view path,
time_type type) -> std::optional<std::uint64_t> { time_type type) -> std::optional<std::uint64_t> {
auto times = get_times(path); auto times = get_times(path);
if (times.has_value()) { if (times.has_value()) {
@ -156,14 +174,14 @@ auto get_time(std::string_view path,
} }
return std::nullopt; return std::nullopt;
} }
auto get_time(std::wstring_view path, auto get_time(std::wstring_view path,
time_type type) -> std::optional<std::uint64_t> { time_type type) -> std::optional<std::uint64_t> {
return get_time(utils::string::to_utf8(path), type); return get_time(utils::string::to_utf8(path), type);
} }
auto get_times(std::string_view path) -> std::optional<file_times> { auto get_times(std::string_view path) -> std::optional<file_times> {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -182,18 +200,24 @@ auto get_times(std::string_view path) -> std::optional<file_times> {
if (res) { if (res) {
ret.accessed = ret.accessed =
utils::time::windows_file_time_to_unix_time(times.at(1U)); utils::time::windows_file_time_to_unix_time(times.at(1U));
ret.created = utils::time::windows_file_time_to_unix_time(times.at(0U)); ret.created =
utils::time::windows_file_time_to_unix_time(times.at(0U));
ret.modified = ret.modified =
utils::time::windows_file_time_to_unix_time(times.at(2U)); utils::time::windows_file_time_to_unix_time(times.at(2U));
ret.written = utils::time::windows_file_time_to_unix_time(times.at(2U)); ret.written =
utils::time::windows_file_time_to_unix_time(times.at(2U));
return ret; return ret;
} }
} }
struct _stat64 st {}; struct _stat64 st {};
if (_stat64(std::string{path}.c_str(), &st) != 0) { if (_stat64(std::string{path}.c_str(), &st) != 0) {
throw std::runtime_error("failed to get file times|" + std::string{path} + throw utils::error::create_exception({
'|' + std::to_string(errno)); function_name,
"failed to get file times",
std::to_string(utils::get_last_error_code()),
path,
});
} }
ret.accessed = utils::time::windows_time_t_to_unix_time(st.st_atime); ret.accessed = utils::time::windows_time_t_to_unix_time(st.st_atime);
@ -203,8 +227,12 @@ auto get_times(std::string_view path) -> std::optional<file_times> {
#else // !defined(_WIN32) #else // !defined(_WIN32)
struct stat64 st {}; struct stat64 st {};
if (stat64(std::string{path}.c_str(), &st) != 0) { if (stat64(std::string{path}.c_str(), &st) != 0) {
throw std::runtime_error("failed to get file times|" + std::string{path} + throw utils::error::create_exception({
'|' + std::to_string(errno)); function_name,
"failed to get file times",
std::to_string(utils::get_last_error_code()),
path,
});
} }
ret.accessed = static_cast<std::uint64_t>(st.st_atim.tv_nsec) + ret.accessed = static_cast<std::uint64_t>(st.st_atim.tv_nsec) +
@ -230,14 +258,14 @@ auto get_times(std::string_view path) -> std::optional<file_times> {
} }
return std::nullopt; return std::nullopt;
} }
auto get_times(std::wstring_view path) -> std::optional<file_times> { auto get_times(std::wstring_view path) -> std::optional<file_times> {
return get_times(utils::string::to_utf8(path)); return get_times(utils::string::to_utf8(path));
} }
auto get_total_drive_space(std::string_view path) auto get_total_drive_space(
-> std::optional<std::uint64_t> { std::string_view path) -> std::optional<std::uint64_t> {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -245,9 +273,12 @@ auto get_total_drive_space(std::string_view path)
ULARGE_INTEGER li{}; ULARGE_INTEGER li{};
if (not ::GetDiskFreeSpaceEx(std::string{path}.c_str(), nullptr, &li, if (not ::GetDiskFreeSpaceEx(std::string{path}.c_str(), nullptr, &li,
nullptr)) { nullptr)) {
throw std::runtime_error("failed to get total disk space|" + throw utils::error::create_exception({
std::string{path} + '|' + function_name,
std::to_string(utils::get_last_error_code())); "failed to get total disk space",
std::to_string(utils::get_last_error_code()),
path,
});
} }
return li.QuadPart; return li.QuadPart;
@ -256,9 +287,12 @@ auto get_total_drive_space(std::string_view path)
#if defined(__linux__) #if defined(__linux__)
struct statfs64 st {}; struct statfs64 st {};
if (statfs64(std::string{path}.c_str(), &st) != 0) { if (statfs64(std::string{path}.c_str(), &st) != 0) {
throw std::runtime_error("failed to get total disk space|" + throw utils::error::create_exception({
std::string{path} + '|' + function_name,
std::to_string(utils::get_last_error_code())); "failed to get total disk space",
std::to_string(utils::get_last_error_code()),
path,
});
} }
return st.f_blocks * static_cast<std::uint64_t>(st.f_bsize); return st.f_blocks * static_cast<std::uint64_t>(st.f_bsize);
@ -267,9 +301,12 @@ auto get_total_drive_space(std::string_view path)
#if defined(__APPLE__) #if defined(__APPLE__)
struct statvfs st {}; struct statvfs st {};
if (statvfs(path.c_str(), &st) != 0) { if (statvfs(path.c_str(), &st) != 0) {
throw std::runtime_error("failed to get total disk space|" + throw utils::error::create_exception({
std::string{path} + '|' + function_name,
std::to_string(utils::get_last_error_code())); "failed to get total disk space",
std::to_string(utils::get_last_error_code()),
path,
});
} }
return st.f_blocks * static_cast<std::uint64_t>(st.f_frsize); return st.f_blocks * static_cast<std::uint64_t>(st.f_frsize);
@ -281,19 +318,20 @@ auto get_total_drive_space(std::string_view path)
} }
return std::nullopt; return std::nullopt;
} }
auto get_total_drive_space(std::wstring_view path) auto get_total_drive_space(
-> std::optional<std::uint64_t> { std::wstring_view path) -> std::optional<std::uint64_t> {
return get_total_drive_space(utils::string::to_utf8(path)); return get_total_drive_space(utils::string::to_utf8(path));
} }
auto i_fs_item::get_time(time_type type) const -> std::optional<std::uint64_t> { auto i_fs_item::get_time(time_type type)
const -> std::optional<std::uint64_t> {
return utils::file::get_time(get_path(), type); return utils::file::get_time(get_path(), type);
} }
auto i_file::read_all(data_buffer &data, std::uint64_t offset, auto i_file::read_all(data_buffer & data, std::uint64_t offset,
std::size_t *total_read) -> bool { std::size_t * total_read) -> bool {
data_buffer buffer; data_buffer buffer;
buffer.resize(get_read_buffer_size()); buffer.resize(get_read_buffer_size());
@ -320,14 +358,14 @@ auto i_file::read_all(data_buffer &data, std::uint64_t offset,
} }
return false; return false;
} }
#if defined(PROJECT_ENABLE_JSON) #if defined(PROJECT_ENABLE_JSON)
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
auto read_json_file(std::string_view path, nlohmann::json &data, auto read_json_file(std::string_view path, nlohmann::json & data,
std::optional<std::string_view> password) -> bool { std::optional<std::string_view> password) -> bool {
#else // !defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #else // !defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
auto read_json_file(std::string_view path, nlohmann::json &data) -> bool { auto read_json_file(std::string_view path, nlohmann::json & data) -> bool {
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@ -376,13 +414,13 @@ auto read_json_file(std::string_view path, nlohmann::json &data) -> bool {
} }
return false; return false;
} }
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
auto write_json_file(std::string_view path, const nlohmann::json &data, auto write_json_file(std::string_view path, const nlohmann::json &data,
std::optional<std::string_view> password) -> bool { std::optional<std::string_view> password) -> bool {
#else // !defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #else // !defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
auto write_json_file(std::string_view path, auto write_json_file(std::string_view path,
const nlohmann::json &data) -> bool { const nlohmann::json &data) -> bool {
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
@ -390,7 +428,12 @@ auto write_json_file(std::string_view path,
try { try {
auto file = file::open_or_create_file(path); auto file = file::open_or_create_file(path);
if (not file->truncate()) { if (not file->truncate()) {
throw std::runtime_error("failed to truncate file"); throw utils::error::create_exception({
function_name,
"failed to truncate file",
std::to_string(utils::get_last_error_code()),
path,
});
} }
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
@ -399,7 +442,8 @@ auto write_json_file(std::string_view path,
data_buffer encrypted_data{}; data_buffer encrypted_data{};
utils::encryption::encrypt_data( utils::encryption::encrypt_data(
*password, reinterpret_cast<const unsigned char *>(str_data.c_str()), *password,
reinterpret_cast<const unsigned char *>(str_data.c_str()),
str_data.size(), encrypted_data); str_data.size(), encrypted_data);
return file->write(encrypted_data, 0U); return file->write(encrypted_data, 0U);
} }
@ -416,10 +460,10 @@ auto write_json_file(std::string_view path,
} }
return false; return false;
} }
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
auto read_json_file(std::wstring_view path, nlohmann::json &data, auto read_json_file(std::wstring_view path, nlohmann::json & data,
std::optional<std::wstring_view> password) -> bool { std::optional<std::wstring_view> password) -> bool {
if (password.has_value()) { if (password.has_value()) {
auto password_a = utils::string::to_utf8(*password); auto password_a = utils::string::to_utf8(*password);
@ -427,9 +471,9 @@ auto read_json_file(std::wstring_view path, nlohmann::json &data,
} }
return read_json_file(utils::string::to_utf8(path), data, std::nullopt); return read_json_file(utils::string::to_utf8(path), data, std::nullopt);
} }
auto write_json_file(std::wstring_view path, const nlohmann::json &data, auto write_json_file(std::wstring_view path, const nlohmann::json &data,
std::optional<std::wstring_view> password) -> bool { std::optional<std::wstring_view> password) -> bool {
if (password.has_value()) { if (password.has_value()) {
auto password_a = utils::string::to_utf8(*password); auto password_a = utils::string::to_utf8(*password);
@ -437,32 +481,38 @@ auto write_json_file(std::wstring_view path, const nlohmann::json &data,
} }
return write_json_file(utils::string::to_utf8(path), data, std::nullopt); return write_json_file(utils::string::to_utf8(path), data, std::nullopt);
} }
#else // !defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #else // !defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
auto read_json_file(std::wstring_view path, nlohmann::json &data) -> bool { auto read_json_file(std::wstring_view path, nlohmann::json & data) -> bool {
return read_json_file(utils::string::to_utf8(path), data); return read_json_file(utils::string::to_utf8(path), data);
} }
auto write_json_file(std::wstring_view path, auto write_json_file(std::wstring_view path,
const nlohmann::json &data) -> bool { const nlohmann::json &data) -> bool {
return write_json_file(utils::string::to_utf8(path), data); return write_json_file(utils::string::to_utf8(path), data);
} }
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
#endif // defined(PROJECT_ENABLE_JSON) #endif // defined(PROJECT_ENABLE_JSON)
#if defined(PROJECT_ENABLE_LIBDSM) #if defined(PROJECT_ENABLE_LIBDSM)
static constexpr const auto validate_smb_path = static constexpr const auto validate_smb_path =
[](std::string_view path) -> bool { [](std::string_view path) -> bool {
return (not utils::string::begins_with(path, "///") && return (not utils::string::begins_with(path, "///") &&
utils::string::begins_with(path, "//") && utils::string::begins_with(path, "//") &&
// not utils::string::contains(path, " ") && // not utils::string::contains(path, " ") &&
std::count(path.begin(), path.end(), '/') >= 3U); std::count(path.begin(), path.end(), '/') >= 3U);
}; };
auto smb_create_smb_path(std::string_view smb_path, auto smb_create_smb_path(std::string_view smb_path,
std::string_view rel_path) -> std::string { std::string_view rel_path) -> std::string {
REPERTORY_USES_FUNCTION_NAME();
if (not validate_smb_path(smb_path)) { if (not validate_smb_path(smb_path)) {
throw std::runtime_error("invalid smb path|" + std::string{smb_path}); throw utils::error::create_exception({
function_name,
"invalid smb path",
smb_path,
});
} }
std::string path{rel_path}; std::string path{rel_path};
@ -479,24 +529,37 @@ auto smb_create_smb_path(std::string_view smb_path,
path = "//" + utils::path::format_path(path, "/", "\\"); path = "//" + utils::path::format_path(path, "/", "\\");
if (not validate_smb_path(path)) { if (not validate_smb_path(path)) {
throw std::runtime_error("invalid smb path|" + std::string{path}); throw utils::error::create_exception({
function_name,
"invalid smb path",
path,
});
} }
return path; return path;
} }
auto smb_create_and_validate_relative_path( auto smb_create_and_validate_relative_path(
std::string_view smb_path, std::string_view path) -> std::string { std::string_view smb_path, std::string_view path) -> std::string {
REPERTORY_USES_FUNCTION_NAME();
if (not validate_smb_path(smb_path)) { if (not validate_smb_path(smb_path)) {
throw std::runtime_error("invalid smb path|" + std::string{smb_path}); throw utils::error::create_exception({
function_name,
"invalid smb path",
smb_path,
});
} }
std::string dir_path; std::string dir_path;
if (utils::string::begins_with(path, "//")) { if (utils::string::begins_with(path, "//")) {
if (not utils::file::smb_parent_is_same(smb_path, path)) { if (not utils::file::smb_parent_is_same(smb_path, path)) {
throw std::runtime_error("failed to validate path|" + throw utils::error::create_exception({
std::string{smb_path} + '|' + std::string{path} + function_name,
"|parent paths are not the same"); "failed to validate path",
"parent paths are not the same" smb_path,
path,
});
} }
return utils::file::smb_create_relative_path(path); return utils::file::smb_create_relative_path(path);
@ -504,11 +567,17 @@ auto smb_create_and_validate_relative_path(
return utils::file::smb_create_relative_path(std::string{smb_path} + '/' + return utils::file::smb_create_relative_path(std::string{smb_path} + '/' +
std::string{path}); std::string{path});
} }
auto smb_create_relative_path(std::string_view smb_path) -> std::string {
REPERTORY_USES_FUNCTION_NAME();
auto smb_create_relative_path(std::string_view smb_path) -> std::string {
if (not validate_smb_path(smb_path)) { if (not validate_smb_path(smb_path)) {
throw std::runtime_error("invalid smb path|" + std::string{smb_path}); throw utils::error::create_exception({
function_name,
"invalid smb path",
smb_path,
});
} }
std::string path{smb_path}; std::string path{smb_path};
@ -518,11 +587,17 @@ auto smb_create_relative_path(std::string_view smb_path) -> std::string {
auto parts = repertory::utils::string::split(path, '\\', false); auto parts = repertory::utils::string::split(path, '\\', false);
parts.erase(parts.begin(), std::next(parts.begin(), 2U)); parts.erase(parts.begin(), std::next(parts.begin(), 2U));
return "\\" + utils::string::join(parts, '\\'); return "\\" + utils::string::join(parts, '\\');
} }
auto smb_create_search_path(std::string_view smb_path) -> std::string {
REPERTORY_USES_FUNCTION_NAME();
auto smb_create_search_path(std::string_view smb_path) -> std::string {
if (not validate_smb_path(smb_path)) { if (not validate_smb_path(smb_path)) {
throw std::runtime_error("invalid smb path|" + std::string{smb_path}); throw utils::error::create_exception({
function_name,
"invalid smb path",
smb_path,
});
} }
std::string path{smb_path}; std::string path{smb_path};
@ -533,68 +608,102 @@ auto smb_create_search_path(std::string_view smb_path) -> std::string {
auto search_path = repertory::utils::string::join(parts, '\\'); auto search_path = repertory::utils::string::join(parts, '\\');
return search_path.empty() ? "\\*" : "\\" + search_path + "\\*"; return search_path.empty() ? "\\*" : "\\" + search_path + "\\*";
}
auto smb_get_parent_path(std::string_view smb_path) -> std::string {
if (not validate_smb_path(smb_path)) {
throw std::runtime_error("invalid smb path|" + std::string{smb_path});
} }
auto parts = repertory::utils::string::split(smb_path.substr(2U), '/', false); auto smb_get_parent_path(std::string_view smb_path) -> std::string {
REPERTORY_USES_FUNCTION_NAME();
if (not validate_smb_path(smb_path)) {
throw utils::error::create_exception({
function_name,
"invalid smb path",
smb_path,
});
}
auto parts =
repertory::utils::string::split(smb_path.substr(2U), '/', false);
if (parts.size() > 2U) { if (parts.size() > 2U) {
parts.erase(std::prev(parts.end()), parts.end()); parts.erase(std::prev(parts.end()), parts.end());
} }
auto parent_smb_path = "//" + utils::string::join(parts, '/'); auto parent_smb_path = "//" + utils::string::join(parts, '/');
if (not validate_smb_path(parent_smb_path)) { if (not validate_smb_path(parent_smb_path)) {
throw std::runtime_error("invalid smb path|" + parent_smb_path); throw utils::error::create_exception({
function_name,
"invalid parent smb path",
parent_smb_path,
});
} }
return parent_smb_path; return parent_smb_path;
}
auto smb_get_root_path(std::string_view smb_path) -> std::string {
if (not validate_smb_path(smb_path)) {
throw std::runtime_error("invalid smb path|" + std::string{smb_path});
} }
auto parts = repertory::utils::string::split(smb_path.substr(2U), '/', false); auto smb_get_root_path(std::string_view smb_path) -> std::string {
REPERTORY_USES_FUNCTION_NAME();
if (not validate_smb_path(smb_path)) {
throw utils::error::create_exception({
function_name,
"invalid smb path",
smb_path,
});
}
auto parts =
repertory::utils::string::split(smb_path.substr(2U), '/', false);
if (parts.size() > 2U) { if (parts.size() > 2U) {
parts.erase(std::next(parts.begin(), 2U), parts.end()); parts.erase(std::next(parts.begin(), 2U), parts.end());
} }
return "//" + utils::string::join(parts, '/'); return "//" + utils::string::join(parts, '/');
} }
auto smb_get_unc_path(std::string_view smb_path) -> std::string {
REPERTORY_USES_FUNCTION_NAME();
auto smb_get_unc_path(std::string_view smb_path) -> std::string {
if (not validate_smb_path(smb_path)) { if (not validate_smb_path(smb_path)) {
throw std::runtime_error("invalid smb path|" + std::string{smb_path}); throw utils::error::create_exception({
function_name,
"invalid smb path",
smb_path,
});
} }
std::string unc_path{smb_path}; std::string unc_path{smb_path};
utils::path::format_path(unc_path, "\\", "/"); utils::path::format_path(unc_path, "\\", "/");
return '\\' + unc_path; return '\\' + unc_path;
} }
auto smb_get_uri_path(std::string_view smb_path) -> std::string {
REPERTORY_USES_FUNCTION_NAME();
auto smb_get_uri_path(std::string_view smb_path) -> std::string {
if (not validate_smb_path(smb_path)) { if (not validate_smb_path(smb_path)) {
throw std::runtime_error("invalid smb path|" + std::string{smb_path}); throw utils::error::create_exception({
function_name,
"invalid smb path",
smb_path,
});
} }
return "smb:" + std::string{smb_path}; return "smb:" + std::string{smb_path};
} }
auto smb_get_uri_path(std::string_view smb_path, std::string_view user, auto smb_get_uri_path(std::string_view smb_path, std::string_view user,
std::string_view password) -> std::string { std::string_view password) -> std::string {
if (not validate_smb_path(smb_path)) { if (not validate_smb_path(smb_path)) {
throw std::runtime_error("invalid smb path|" + std::string{smb_path}); throw utils::error::create_exception({
function_name,
"invalid smb path",
smb_path,
});
} }
return "smb://" + std::string{user} + ':' + std::string{password} + '@' + return "smb://" + std::string{user} + ':' + std::string{password} + '@' +
std::string{smb_path.substr(2U)}; std::string{smb_path.substr(2U)};
} }
auto smb_parent_is_same(std::string_view smb_path1, auto smb_parent_is_same(std::string_view smb_path1,
std::string_view smb_path2) -> bool { std::string_view smb_path2) -> bool {
if (not(validate_smb_path(smb_path1) && validate_smb_path(smb_path2))) { if (not(validate_smb_path(smb_path1) && validate_smb_path(smb_path2))) {
return false; return false;
@ -612,6 +721,6 @@ auto smb_parent_is_same(std::string_view smb_path1,
return std::equal(parts1.begin(), std::next(parts1.begin(), 2U), return std::equal(parts1.begin(), std::next(parts1.begin(), 2U),
parts2.begin()); parts2.begin());
} }
#endif // defined(PROJECT_ENABLE_LIBDSM) #endif // defined(PROJECT_ENABLE_LIBDSM)
} // namespace repertory::utils::file } // namespace repertory::utils::file

View File

@ -23,6 +23,7 @@
#include "utils/common.hpp" #include "utils/common.hpp"
#include "utils/error.hpp" #include "utils/error.hpp"
#include "utils/string.hpp"
#include "utils/unix.hpp" #include "utils/unix.hpp"
#include "utils/windows.hpp" #include "utils/windows.hpp"
@ -32,6 +33,8 @@ auto traverse_directory(
std::function<bool(repertory::utils::file::directory)> directory_action, std::function<bool(repertory::utils::file::directory)> directory_action,
std::function<bool(repertory::utils::file::file)> file_action, std::function<bool(repertory::utils::file::file)> file_action,
repertory::stop_type *stop_requested) -> bool { repertory::stop_type *stop_requested) -> bool {
REPERTORY_USES_FUNCTION_NAME();
auto res{true}; auto res{true};
const auto is_stop_requested = [&stop_requested]() -> bool { const auto is_stop_requested = [&stop_requested]() -> bool {
@ -43,9 +46,12 @@ auto traverse_directory(
auto search = repertory::utils::path::combine(path, {"*.*"}); auto search = repertory::utils::path::combine(path, {"*.*"});
auto find = ::FindFirstFileA(search.c_str(), &fd); auto find = ::FindFirstFileA(search.c_str(), &fd);
if (find == INVALID_HANDLE_VALUE) { if (find == INVALID_HANDLE_VALUE) {
throw std::runtime_error( throw repertory::utils::error::create_exception({
"failed to open directory|" + std::string{path} + '|' + function_name,
std::to_string(repertory::utils::get_last_error_code())); "failed to open directory",
std::to_string(repertory::utils::get_last_error_code()),
path,
});
} }
do { do {
@ -67,9 +73,12 @@ auto traverse_directory(
#else // !defined(_WIN32) #else // !defined(_WIN32)
auto *root = opendir(std::string{path}.c_str()); auto *root = opendir(std::string{path}.c_str());
if (root == nullptr) { if (root == nullptr) {
throw std::runtime_error( throw repertory::utils::error::create_exception({
"failed to open directory|" + std::string{path} + '|' + function_name,
std::to_string(repertory::utils::get_last_error_code())); "failed to open directory",
std::to_string(repertory::utils::get_last_error_code()),
path,
});
} }
struct dirent *de{nullptr}; struct dirent *de{nullptr};
@ -94,14 +103,19 @@ auto traverse_directory(
} // namespace } // namespace
namespace repertory::utils::file { namespace repertory::utils::file {
auto directory::copy_to(std::string_view new_path, bool overwrite) const auto directory::copy_to(std::string_view new_path,
-> bool { bool overwrite) const -> bool {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
throw std::runtime_error("failed to copy directory|" + path_ + '|' + throw utils::error::create_exception({
std::string{new_path} + '+' + function_name,
std::to_string(overwrite) + "|not implemented"); "failed to copy directory",
"not implemented",
path_,
new_path,
utils::string::from_bool(overwrite),
});
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {
@ -157,9 +171,12 @@ auto directory::create_directory(std::string_view path) const
auto res = ::SHCreateDirectory(nullptr, auto res = ::SHCreateDirectory(nullptr,
utils::string::from_utf8(abs_path).c_str()); utils::string::from_utf8(abs_path).c_str());
if (res != ERROR_SUCCESS) { if (res != ERROR_SUCCESS) {
throw std::runtime_error("failed to create directory|" + throw utils::error::create_exception({
std::string{abs_path} + '|' + function_name,
std::to_string(res)); "failed to create directory",
std::to_string(res),
abs_path,
});
} }
#else // !defined(_WIN32) #else // !defined(_WIN32)
auto ret{true}; auto ret{true};
@ -194,7 +211,7 @@ auto directory::exists() const -> bool {
#if defined(_WIN32) #if defined(_WIN32)
return ::PathIsDirectoryA(path_.c_str()) != 0; return ::PathIsDirectoryA(path_.c_str()) != 0;
#else // !defined(_WIN32) #else // !defined(_WIN32)
struct stat64 st{}; struct stat64 st {};
return (stat64(path_.c_str(), &st) == 0 && S_ISDIR(st.st_mode)); return (stat64(path_.c_str(), &st) == 0 && S_ISDIR(st.st_mode));
#endif // defined(_WIN32) #endif // defined(_WIN32)
@ -247,8 +264,8 @@ auto directory::get_directories() const -> std::vector<fs_directory_t> {
return {}; return {};
} }
auto directory::create_file(std::string_view file_name, bool read_only) const auto directory::create_file(std::string_view file_name,
-> fs_file_t { bool read_only) const -> fs_file_t {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -360,8 +377,13 @@ auto directory::move_to(std::string_view new_path) -> bool {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
throw std::runtime_error("failed to move directory|" + path_ + '|' + throw utils::error::create_exception({
std::string{new_path} + "|not implemented"); function_name,
"failed to move directory",
"not implemented",
path_,
new_path,
});
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {
@ -383,7 +405,10 @@ auto directory::remove() -> bool {
#endif // defined(_WIN32) #endif // defined(_WIN32)
if (not ret) { if (not ret) {
utils::error::handle_error(function_name, utils::error::handle_error(function_name,
"failed to remove directory|" + path_); utils::error::create_error_message({
"failed to remove directory",
path_,
}));
} }
return ret; return ret;

View File

@ -33,7 +33,7 @@ namespace {
file_size = 0U; file_size = 0U;
#if defined(_WIN32) #if defined(_WIN32)
struct _stat64 st{}; struct _stat64 st {};
auto res = _stat64(std::string{path}.c_str(), &st); auto res = _stat64(std::string{path}.c_str(), &st);
if (res != 0) { if (res != 0) {
return false; return false;
@ -55,7 +55,7 @@ namespace {
return ((::PathFileExistsA(abs_path.c_str()) != 0) && return ((::PathFileExistsA(abs_path.c_str()) != 0) &&
(::PathIsDirectoryA(abs_path.c_str()) == 0)); (::PathIsDirectoryA(abs_path.c_str()) == 0));
#else // !defined(_WIN32) #else // !defined(_WIN32)
struct stat64 st{}; struct stat64 st {};
return (stat64(abs_path.c_str(), &st) == 0 && not S_ISDIR(st.st_mode)); return (stat64(abs_path.c_str(), &st) == 0 && not S_ISDIR(st.st_mode));
#endif // defined(_WIN32) #endif // defined(_WIN32)
} }
@ -112,8 +112,14 @@ namespace repertory::utils::file {
// } // }
void file::open() { void file::open() {
REPERTORY_USES_FUNCTION_NAME();
if (not is_file(path_)) { if (not is_file(path_)) {
throw std::runtime_error("file not found: " + path_); throw utils::error::create_exception({
function_name,
"file not found",
path_,
});
} }
#if defined(_WIN32) #if defined(_WIN32)
@ -150,8 +156,8 @@ auto file::open_file(std::string_view path, bool read_only) -> fs_file_t {
return new_file; return new_file;
} }
auto file::open_or_create_file(std::string_view path, bool read_only) auto file::open_or_create_file(std::string_view path,
-> fs_file_t { bool read_only) -> fs_file_t {
auto abs_path = utils::path::absolute(path); auto abs_path = utils::path::absolute(path);
if (not is_file(abs_path)) { if (not is_file(abs_path)) {
#if defined(_WIN32) #if defined(_WIN32)
@ -294,12 +300,20 @@ auto file::read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
try { try {
if (not file_) { if (not file_) {
throw std::runtime_error("file is not open for reading"); throw utils::error::create_exception({
function_name,
"file is not open for reading",
path_,
});
} }
if (fseeko(file_.get(), static_cast<std::int64_t>(offset), SEEK_SET) == if (fseeko(file_.get(), static_cast<std::int64_t>(offset), SEEK_SET) ==
-1) { -1) {
throw std::runtime_error("failed to seek before read"); throw utils::error::create_exception({
function_name,
"failed to seek before read",
path_,
});
} }
std::size_t bytes_read{0U}; std::size_t bytes_read{0U};
@ -307,7 +321,11 @@ auto file::read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
auto res = auto res =
fread(&data[bytes_read], 1U, to_read - bytes_read, file_.get()); fread(&data[bytes_read], 1U, to_read - bytes_read, file_.get());
if (not feof(file_.get()) && ferror(file_.get())) { if (not feof(file_.get()) && ferror(file_.get())) {
throw std::runtime_error("failed to read file bytes"); throw utils::error::create_exception({
function_name,
"failed to read file bytes",
path_,
});
} }
if (res == 0) { if (res == 0) {
@ -349,8 +367,12 @@ auto file::sha256() -> std::optional<std::string> {
crypto_hash_sha256_state state{}; crypto_hash_sha256_state state{};
auto res = crypto_hash_sha256_init(&state); auto res = crypto_hash_sha256_init(&state);
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to initialize sha256|" + throw utils::error::create_exception({
std::to_string(res)); function_name,
"failed to initialize sha256",
std::to_string(res),
path_,
});
} }
{ {
@ -367,8 +389,12 @@ auto file::sha256() -> std::optional<std::string> {
&state, reinterpret_cast<const unsigned char *>(buffer.data()), &state, reinterpret_cast<const unsigned char *>(buffer.data()),
bytes_read); bytes_read);
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to update sha256|" + throw utils::error::create_exception({
std::to_string(res)); function_name,
"failed to update sha256",
std::to_string(res),
path_,
});
} }
} }
} }
@ -376,8 +402,12 @@ auto file::sha256() -> std::optional<std::string> {
std::array<unsigned char, crypto_hash_sha256_BYTES> out{}; std::array<unsigned char, crypto_hash_sha256_BYTES> out{};
res = crypto_hash_sha256_final(&state, out.data()); res = crypto_hash_sha256_final(&state, out.data());
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to finalize sha256|" + throw utils::error::create_exception({
std::to_string(res)); function_name,
"failed to finalize sha256",
std::to_string(res),
path_,
});
} }
ret = utils::collection::to_hex_string(out); ret = utils::collection::to_hex_string(out);
@ -411,7 +441,10 @@ auto file::remove() -> bool {
#endif // defined(_WIN32) #endif // defined(_WIN32)
if (not ret) { if (not ret) {
utils::error::handle_error(function_name, utils::error::handle_error(function_name,
"failed to remove file|" + path_); utils::error::create_error_message({
"failed to remove file",
path_,
}));
} }
return ret; return ret;
@ -464,12 +497,20 @@ auto file::write(const unsigned char *data, std::size_t to_write,
try { try {
if (not file_) { if (not file_) {
throw std::runtime_error("file is not open for writing"); throw utils::error::create_exception({
function_name,
"file is not open for writing",
path_,
});
} }
auto res = fseeko(file_.get(), static_cast<std::int64_t>(offset), SEEK_SET); auto res = fseeko(file_.get(), static_cast<std::int64_t>(offset), SEEK_SET);
if (res == -1) { if (res == -1) {
throw std::runtime_error("failed to seek before write"); throw utils::error::create_exception({
function_name,
"failed to seek before write",
path_,
});
} }
std::size_t bytes_written{0U}; std::size_t bytes_written{0U};
@ -478,7 +519,11 @@ auto file::write(const unsigned char *data, std::size_t to_write,
fwrite(reinterpret_cast<const char *>(&data[bytes_written]), 1U, fwrite(reinterpret_cast<const char *>(&data[bytes_written]), 1U,
to_write - bytes_written, file_.get()); to_write - bytes_written, file_.get());
if (not feof(file_.get()) && ferror(file_.get())) { if (not feof(file_.get()) && ferror(file_.get())) {
throw std::runtime_error("failed to write file bytes"); throw utils::error::create_exception({
function_name,
"failed to write file bytes",
path_,
});
} }
if (written == 0U) { if (written == 0U) {
@ -510,12 +555,20 @@ auto file::size() const -> std::optional<std::uint64_t> {
try { try {
if (file_) { if (file_) {
if (fseeko(file_.get(), 0, SEEK_END) == -1) { if (fseeko(file_.get(), 0, SEEK_END) == -1) {
throw std::runtime_error("failed to seek"); throw utils::error::create_exception({
function_name,
"failed to seek",
path_,
});
} }
auto size = ftello(file_.get()); auto size = ftello(file_.get());
if (size == -1) { if (size == -1) {
throw std::runtime_error("failed to get position"); throw utils::error::create_exception({
function_name,
"failed to get position",
path_,
});
} }
return static_cast<std::uint64_t>(size); return static_cast<std::uint64_t>(size);
@ -523,7 +576,11 @@ auto file::size() const -> std::optional<std::uint64_t> {
std::uint64_t size{}; std::uint64_t size{};
if (not get_file_size(path_, size)) { if (not get_file_size(path_, size)) {
throw std::runtime_error("failed to get file size"); throw utils::error::create_exception({
function_name,
"failed to get file size",
path_,
});
} }
return size; return size;

View File

@ -50,8 +50,12 @@ auto smb_directory::open(std::string_view host, std::string_view user,
if (res != DSM_SUCCESS) { if (res != DSM_SUCCESS) {
res = inet_pton(AF_INET, std::string{host}.c_str(), &addr.sin_addr); res = inet_pton(AF_INET, std::string{host}.c_str(), &addr.sin_addr);
if (res != 1) { if (res != 1) {
throw std::runtime_error("failed to resolve host|" + std::string{host} + throw utils::error::create_exception({
'|' + std::to_string(errno)); function_name,
"failed to resolve host",
std::to_string(utils::get_last_error_code()),
host,
});
} }
} }
@ -59,8 +63,12 @@ auto smb_directory::open(std::string_view host, std::string_view user,
static_cast<std::uint32_t>(addr.sin_addr.s_addr), static_cast<std::uint32_t>(addr.sin_addr.s_addr),
SMB_TRANSPORT_TCP); SMB_TRANSPORT_TCP);
if (res != DSM_SUCCESS) { if (res != DSM_SUCCESS) {
throw std::runtime_error("failed to connect to host|" + throw utils::error::create_exception({
std::string{host} + '|' + std::to_string(res)); function_name,
"failed to connect to host",
std::to_string(res),
host,
});
} }
smb_session_set_creds(session.get(), std::string{host}.c_str(), smb_session_set_creds(session.get(), std::string{host}.c_str(),
@ -68,9 +76,13 @@ auto smb_directory::open(std::string_view host, std::string_view user,
std::string{password}.c_str()); std::string{password}.c_str());
res = smb_session_login(session.get()); res = smb_session_login(session.get());
if (res != DSM_SUCCESS) { if (res != DSM_SUCCESS) {
throw std::runtime_error("failed to logon to host|" + std::string{host} + throw utils::error::create_exception({
'|' + std::string{user} + '|' + function_name,
std::to_string(res)); "failed to logon to host",
std::to_string(res),
host,
user,
});
} }
auto share_name = utils::string::split(path, '/', false).at(0U); auto share_name = utils::string::split(path, '/', false).at(0U);
@ -78,9 +90,12 @@ auto smb_directory::open(std::string_view host, std::string_view user,
smb_tid tid{}; smb_tid tid{};
res = smb_tree_connect(session.get(), share_name.c_str(), &tid); res = smb_tree_connect(session.get(), share_name.c_str(), &tid);
if (res != DSM_SUCCESS) { if (res != DSM_SUCCESS) {
throw std::runtime_error("failed to connect to share|" + throw utils::error::create_exception({
std::string{share_name} + '|' + function_name,
std::to_string(res)); "failed to connect to share",
std::to_string(res),
share_name,
});
} }
return smb_directory_t{ return smb_directory_t{
@ -115,13 +130,22 @@ auto smb_directory::copy_to(std::string_view new_path,
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
// auto to_path = utils::path::absolute(new_path); // auto to_path = utils::path::absolute(new_path);
throw std::runtime_error("failed to copy directory|" + path_ + '|' + throw utils::error::create_exception({
std::string{new_path} + "|not implemented"); function_name,
"failed to copy directory",
"not implemented",
path_,
new_path,
});
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {
@ -136,7 +160,11 @@ auto smb_directory::count(bool recursive) const -> std::uint64_t {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
smb_stat_list_t list{ smb_stat_list_t list{
@ -149,8 +177,13 @@ auto smb_directory::count(bool recursive) const -> std::uint64_t {
return count; return count;
} }
throw std::runtime_error("failed to get directory count recursively|" + throw utils::error::create_exception({
path_ + "|not implemented"); function_name,
"failed to get directory count recursively",
"not implemented",
utils::string::from_bool(recursive),
path_,
});
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {
@ -166,7 +199,11 @@ auto smb_directory::create_directory(std::string_view path) const
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
auto dir = get_directory(path); auto dir = get_directory(path);
@ -178,8 +215,12 @@ auto smb_directory::create_directory(std::string_view path) const
session_.get(), tid_, session_.get(), tid_,
smb_create_and_validate_relative_path(path_, path).c_str()); smb_create_and_validate_relative_path(path_, path).c_str());
if (res != DSM_SUCCESS) { if (res != DSM_SUCCESS) {
throw std::runtime_error("failed to create directory|" + path_ + '/' + throw utils::error::create_exception({
std::string{path} + '|' + std::to_string(res)); function_name,
"failed to create directory",
std::to_string(res),
path_,
});
} }
return get_directory(path); return get_directory(path);
@ -198,14 +239,21 @@ auto smb_directory::create_file(std::string_view file_name,
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
auto fs_file = get_file(file_name); auto fs_file = get_file(file_name);
if (fs_file) { if (fs_file) {
if (not dynamic_cast<smb_file *>(fs_file.get())->open(read_only)) { if (not dynamic_cast<smb_file *>(fs_file.get())->open(read_only)) {
throw std::runtime_error("failed to open existing file|" + throw utils::error::create_exception({
std::string{file_name}); function_name,
"failed to open existing file",
file_name,
});
} }
return fs_file; return fs_file;
@ -243,7 +291,11 @@ auto smb_directory::exists() const -> bool {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
smb_stat_t st{ smb_stat_t st{
@ -271,7 +323,11 @@ auto smb_directory::get_directory(std::string_view path) const
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
auto rel_path = smb_create_and_validate_relative_path(path_, path); auto rel_path = smb_create_and_validate_relative_path(path_, path);
@ -280,12 +336,20 @@ auto smb_directory::get_directory(std::string_view path) const
smb_stat_deleter(), smb_stat_deleter(),
}; };
if (not st) { if (not st) {
throw std::runtime_error("failed to stat directory|" + rel_path); throw utils::error::create_exception({
function_name,
"failed to stat directory",
rel_path,
});
} }
bool is_dir{smb_stat_get(st.get(), SMB_STAT_ISDIR) != 0U}; bool is_dir{smb_stat_get(st.get(), SMB_STAT_ISDIR) != 0U};
if (not is_dir) { if (not is_dir) {
throw std::runtime_error("path is not a directory|" + rel_path); throw utils::error::create_exception({
function_name,
"path is not a directory",
rel_path,
});
} }
return smb_directory_t{ return smb_directory_t{
@ -311,7 +375,11 @@ auto smb_directory::get_directories() const -> std::vector<fs_directory_t> {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
smb_stat_list_t list{ smb_stat_list_t list{
smb_find(session_.get(), tid_, smb_create_search_path(path_).c_str()), smb_find(session_.get(), tid_, smb_create_search_path(path_).c_str()),
@ -319,7 +387,11 @@ auto smb_directory::get_directories() const -> std::vector<fs_directory_t> {
smb_stat_list_deleter(), smb_stat_list_deleter(),
}; };
if (not list) { if (not list) {
throw std::runtime_error("failed to get directory list|" + path_); throw utils::error::create_exception({
function_name,
"failed to get directory list",
path_,
});
} }
std::vector<fs_directory_t> ret{}; std::vector<fs_directory_t> ret{};
@ -370,7 +442,11 @@ auto smb_directory::get_file(std::string_view path) const -> fs_file_t {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
auto rel_path = smb_create_and_validate_relative_path(path_, path); auto rel_path = smb_create_and_validate_relative_path(path_, path);
@ -379,12 +455,20 @@ auto smb_directory::get_file(std::string_view path) const -> fs_file_t {
smb_stat_deleter(), smb_stat_deleter(),
}; };
if (not st) { if (not st) {
throw std::runtime_error("failed to stat file|" + rel_path); throw utils::error::create_exception({
function_name,
"failed to stat file",
rel_path,
});
} }
bool is_dir{smb_stat_get(st.get(), SMB_STAT_ISDIR) != 0U}; bool is_dir{smb_stat_get(st.get(), SMB_STAT_ISDIR) != 0U};
if (is_dir) { if (is_dir) {
throw std::runtime_error("path is not a file|" + rel_path); throw utils::error::create_exception({
function_name,
"path is not a file",
rel_path,
});
} }
return std::make_unique<smb_file>( return std::make_unique<smb_file>(
@ -404,7 +488,11 @@ auto smb_directory::get_files() const -> std::vector<fs_file_t> {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
smb_stat_list_t list{ smb_stat_list_t list{
@ -412,7 +500,11 @@ auto smb_directory::get_files() const -> std::vector<fs_file_t> {
smb_stat_list_deleter(), smb_stat_list_deleter(),
}; };
if (not list) { if (not list) {
throw std::runtime_error("failed to get file list|" + path_); throw utils::error::create_exception({
function_name,
"failed to get file list",
path_,
});
} }
std::vector<fs_file_t> ret{}; std::vector<fs_file_t> ret{};
@ -453,7 +545,11 @@ auto smb_directory::get_items() const -> std::vector<fs_item_t> {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
smb_stat_list_t list{ smb_stat_list_t list{
@ -461,7 +557,11 @@ auto smb_directory::get_items() const -> std::vector<fs_item_t> {
smb_stat_list_deleter(), smb_stat_list_deleter(),
}; };
if (not list) { if (not list) {
throw std::runtime_error("failed to get item list|" + path_); throw utils::error::create_exception({
function_name,
"failed to get item list",
path_,
});
} }
std::vector<fs_item_t> ret{}; std::vector<fs_item_t> ret{};
@ -530,7 +630,11 @@ auto smb_directory::is_symlink() const -> bool {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
} catch (const std::exception &e) { } catch (const std::exception &e) {
@ -547,11 +651,20 @@ auto smb_directory::move_to(std::string_view new_path) -> bool {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
throw std::runtime_error("failed to move directory|" + path_ + '|' + throw utils::error::create_exception({
std::string{new_path} + "|not implemented"); function_name,
"failed to move directory",
"not implemented",
path_,
new_path,
});
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {
@ -566,7 +679,11 @@ auto smb_directory::remove() -> bool {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
return utils::retry_action([this]() -> bool { return utils::retry_action([this]() -> bool {
@ -578,8 +695,12 @@ auto smb_directory::remove() -> bool {
auto res = smb_directory_rm(session_.get(), tid_, auto res = smb_directory_rm(session_.get(), tid_,
smb_create_relative_path(path_).c_str()); smb_create_relative_path(path_).c_str());
if (res != DSM_SUCCESS) { if (res != DSM_SUCCESS) {
throw std::runtime_error("failed to remove directory|" + path_ + '|' + throw utils::error::create_exception({
std::to_string(res)); function_name,
"failed to remove directory",
std::to_string(res),
path_,
});
} }
return true; return true;
@ -605,15 +726,23 @@ auto smb_directory::remove_recursively() -> bool {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
if (not exists()) { if (not exists()) {
return true; return true;
} }
throw std::runtime_error("failed to remove directory recursively|" + path_ + throw utils::error::create_exception({
"|not implemented"); function_name,
"failed to remove directory recursively",
"not implemented",
path_,
});
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {
@ -628,11 +757,19 @@ auto smb_directory::size(bool /* recursive */) const -> std::uint64_t {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
throw std::runtime_error("failed to get directory size|" + path_ + throw utils::error::create_exception({
"|not implemented"); function_name,
"failed to get directory size",
"not implemented",
path_,
});
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {

View File

@ -41,14 +41,23 @@ auto smb_file::copy_to(std::string_view new_path,
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
// auto to_path = utils::path::absolute(new_path); // auto to_path = utils::path::absolute(new_path);
throw std::runtime_error("failed to copy file|" + path_ + '|' + throw utils::error::create_exception({
std::string{new_path} + '|' + function_name,
std::to_string(overwrite) + "|not implemented"); "failed to copy file",
"not implemented",
std::to_string(overwrite),
path_,
new_path,
});
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {
@ -63,7 +72,11 @@ auto smb_file::exists() const -> bool {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
smb_stat_t st{ smb_stat_t st{
@ -89,8 +102,12 @@ void smb_file::flush() const {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
throw std::runtime_error("failed to flush file|" + path_ + throw utils::error::create_exception({
"|not implemented"); function_name,
"failed to flush file",
"not implemented",
path_,
});
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {
@ -104,7 +121,11 @@ auto smb_file::get_time(smb_session *session, smb_tid tid, std::string path,
try { try {
if (session == nullptr) { if (session == nullptr) {
throw std::runtime_error("session not found|" + path); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
auto rel_path = smb_create_relative_path(path); auto rel_path = smb_create_relative_path(path);
@ -113,7 +134,12 @@ auto smb_file::get_time(smb_session *session, smb_tid tid, std::string path,
smb_stat_deleter(), smb_stat_deleter(),
}; };
if (not st) { if (not st) {
throw std::runtime_error("failed to stat directory|" + rel_path); throw utils::error::create_exception({
function_name,
"failed to stat file",
"not implemented",
rel_path,
});
} }
switch (type) { switch (type) {
@ -143,7 +169,11 @@ auto smb_file::is_symlink() const -> bool {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
} catch (const std::exception &e) { } catch (const std::exception &e) {
@ -160,9 +190,13 @@ auto smb_file::move_to(std::string_view new_path) -> bool {
try { try {
if (utils::string::begins_with(new_path, "//")) { if (utils::string::begins_with(new_path, "//")) {
throw std::runtime_error("failed to move file|" + path_ + '|' + throw utils::error::create_exception({
std::string{new_path} + function_name,
"|new path must be in same share"); "failed to move file",
"new path must be in same share",
path_,
new_path,
});
} }
auto from_path = smb_create_relative_path(path_); auto from_path = smb_create_relative_path(path_);
@ -179,15 +213,23 @@ auto smb_file::move_to(std::string_view new_path) -> bool {
auto res = smb_tree_connect(session_.get(), share_name_.c_str(), &tid_); auto res = smb_tree_connect(session_.get(), share_name_.c_str(), &tid_);
if (res != DSM_SUCCESS) { if (res != DSM_SUCCESS) {
throw std::runtime_error("failed to connect to share|" + share_name_ + throw utils::error::create_exception({
'|' + std::to_string(res)); function_name,
"failed to connect to share",
path_std::to_string(res),
share_name_,
});
} }
res = smb_file_mv(session_.get(), tid_, from_path.c_str(), to_path.c_str()); res = smb_file_mv(session_.get(), tid_, from_path.c_str(), to_path.c_str());
if (res != DSM_SUCCESS) { if (res != DSM_SUCCESS) {
throw std::runtime_error("failed to move file|" + path_ + '|' + throw utils::error::create_exception({
from_path + '|' + to_path + '|' + function_name,
std::to_string(res)); "failed to move file",
path_std::to_string(res),
from_path,
to_path,
});
} }
path_ = smb_create_smb_path(path_, to_path); path_ = smb_create_smb_path(path_, to_path);
@ -221,17 +263,26 @@ auto smb_file::open(bool read_only) -> bool {
auto res = smb_tree_connect(session_.get(), share_name_.c_str(), &tid_); auto res = smb_tree_connect(session_.get(), share_name_.c_str(), &tid_);
if (res != DSM_SUCCESS) { if (res != DSM_SUCCESS) {
throw std::runtime_error("failed to connect to share|" + share_name_ + throw utils::error::create_exception({
'|' + std::to_string(res)); function_name,
"failed to connect to share",
path_std::to_string(res),
share_name_,
});
} }
smb_fd fd{}; smb_fd fd{};
res = smb_fopen(session_.get(), tid_, rel_path.c_str(), res = smb_fopen(session_.get(), tid_, rel_path.c_str(),
read_only ? SMB_MOD_RO : SMB_MOD_RW2, &fd); read_only ? SMB_MOD_RO : SMB_MOD_RW2, &fd);
if (res != DSM_SUCCESS) { if (res != DSM_SUCCESS) {
throw std::runtime_error("failed to open file|" + path_ + '|' + rel_path + throw utils::error::create_exception({
'|' + utils::string::from_bool(read_only) + '|' + function_name,
std::to_string(res)); "failed to open file",
utils::string::from_bool(read_only),
path_std::to_string(res),
path_,
rel_path,
});
} }
fd_ = fd; fd_ = fd;
@ -257,16 +308,24 @@ auto smb_file::read(unsigned char *data, std::size_t to_read,
} }
if (not fd_.has_value()) { if (not fd_.has_value()) {
throw std::runtime_error("failed to read file|" + path_ + throw utils::error::create_exception({
"|file not open"); function_name,
"failed to read file",
"file not open",
path_,
});
} }
auto res = smb_fseek(session_.get(), *fd_, static_cast<off_t>(offset), auto res = smb_fseek(session_.get(), *fd_, static_cast<off_t>(offset),
SMB_SEEK_SET); SMB_SEEK_SET);
if (res == -1) { if (res == -1) {
throw std::runtime_error("failed to seek file|" + path_ + '|' + throw utils::error::create_exception({
std::to_string(offset) + '|' + function_name,
std::to_string(res)); "failed to seek file",
std::to_string(res),
std::to_string(offset),
path_,
});
} }
std::size_t bytes_read{0U}; std::size_t bytes_read{0U};
@ -274,9 +333,14 @@ auto smb_file::read(unsigned char *data, std::size_t to_read,
res = smb_fread(session_.get(), *fd_, &data[bytes_read], res = smb_fread(session_.get(), *fd_, &data[bytes_read],
to_read - bytes_read); to_read - bytes_read);
if (res == -1) { if (res == -1) {
throw std::runtime_error("failed to read file|" + path_ + '|' + throw utils::error::create_exception({
std::to_string(to_read) + '|' + function_name,
std::to_string(res)); "failed to read file",
std::to_string(res),
std::to_string(offset),
std::to_string(to_read),
path_,
});
} }
if (res == 0) { if (res == 0) {
@ -314,17 +378,25 @@ auto smb_file::remove() -> bool {
try { try {
auto res = smb_tree_connect(session_.get(), share_name_.c_str(), &tid_); auto res = smb_tree_connect(session_.get(), share_name_.c_str(), &tid_);
if (res != DSM_SUCCESS) { if (res != DSM_SUCCESS) {
throw std::runtime_error("failed to connect to share|" + share_name_ + throw utils::error::create_exception({
'|' + std::to_string(res)); function_name,
"failed to connect to share",
path_std::to_string(res),
share_name_,
});
} }
auto rel_path = smb_create_relative_path(path_); auto rel_path = smb_create_relative_path(path_);
res = smb_file_rm(session_.get(), tid_, rel_path.c_str()); res = smb_file_rm(session_.get(), tid_, rel_path.c_str());
if (res != DSM_SUCCESS) { if (res != DSM_SUCCESS) {
throw std::runtime_error( throw utils::error::create_exception({
"failed to remove file|" + path_ + '|' + rel_path + '|' + function_name,
std::to_string(res) + '|' + "failed to remove file",
std::to_string(smb_session_get_nt_status(session_.get()))); std::to_string(res),
std::to_string(smb_session_get_nt_status(session_.get())),
path_,
rel_path,
});
} }
return true; return true;
@ -350,7 +422,11 @@ auto smb_file::size() const -> std::optional<std::uint64_t> {
try { try {
if (not session_) { if (not session_) {
throw std::runtime_error("session not found|" + path_); throw utils::error::create_exception({
function_name,
"session not found",
path_,
});
} }
auto rel_path = smb_create_relative_path(path_); auto rel_path = smb_create_relative_path(path_);
@ -359,7 +435,11 @@ auto smb_file::size() const -> std::optional<std::uint64_t> {
smb_stat_deleter(), smb_stat_deleter(),
}; };
if (not st) { if (not st) {
throw std::runtime_error("failed to stat directory|" + rel_path); throw utils::error::create_exception({
function_name,
"failed to stat directory",
rel_path,
});
} }
return smb_stat_get(st.get(), SMB_STAT_SIZE); return smb_stat_get(st.get(), SMB_STAT_SIZE);
@ -376,8 +456,13 @@ auto smb_file::truncate(std::size_t size) -> bool {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
throw std::runtime_error("failed to truncate file|" + path_ + '|' + throw utils::error::create_exception({
std::to_string(size) + "|not implemented"); function_name,
"failed to truncate file",
"not implemented",
std::to_string(size),
path_,
});
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::handle_exception(function_name, e); utils::error::handle_exception(function_name, e);
} catch (...) { } catch (...) {
@ -397,16 +482,24 @@ auto smb_file::write(const unsigned char *data, std::size_t to_write,
} }
if (not fd_.has_value()) { if (not fd_.has_value()) {
throw std::runtime_error("failed to write file|" + path_ + throw utils::error::create_exception({
"|file not open"); function_name,
"failed to write file",
"file not open",
path_,
});
} }
auto res = smb_fseek(session_.get(), *fd_, static_cast<off_t>(offset), auto res = smb_fseek(session_.get(), *fd_, static_cast<off_t>(offset),
SMB_SEEK_SET); SMB_SEEK_SET);
if (res == -1) { if (res == -1) {
throw std::runtime_error("failed to seek file|" + path_ + '|' + throw utils::error::create_exception({
std::to_string(offset) + '|' + function_name,
std::to_string(res)); "failed to seek file",
std::to_string(res),
std::to_string(offset),
path_,
});
} }
std::size_t bytes_written{0U}; std::size_t bytes_written{0U};
@ -415,9 +508,14 @@ auto smb_file::write(const unsigned char *data, std::size_t to_write,
const_cast<unsigned char *>(&data[bytes_written]), const_cast<unsigned char *>(&data[bytes_written]),
to_write - bytes_written); to_write - bytes_written);
if (res == -1) { if (res == -1) {
throw std::runtime_error("failed to write file|" + path_ + '|' + throw utils::error::create_exception({
std::to_string(to_write) + '|' + function_name,
std::to_string(res)); "failed to write file",
std::to_string(res),
std::to_string(offset),
std::to_string(to_write),
path_,
});
} }
if (res == 0) { if (res == 0) {

View File

@ -23,6 +23,8 @@
#include "utils/hash.hpp" #include "utils/hash.hpp"
#include "utils/error.hpp"
namespace repertory::utils::encryption { namespace repertory::utils::encryption {
auto create_hash_blake2b_256(std::string_view data) -> hash_256_t { auto create_hash_blake2b_256(std::string_view data) -> hash_256_t {
return create_hash_blake2b_t<hash_256_t>( return create_hash_blake2b_t<hash_256_t>(
@ -111,24 +113,36 @@ auto create_hash_sha512(const data_buffer &data) -> hash_512_t {
auto create_hash_sha512(const unsigned char *data, auto create_hash_sha512(const unsigned char *data,
std::size_t data_size) -> hash_512_t { std::size_t data_size) -> hash_512_t {
REPERTORY_USES_FUNCTION_NAME();
hash_512_t hash{}; hash_512_t hash{};
crypto_hash_sha512_state state{}; crypto_hash_sha512_state state{};
auto res = crypto_hash_sha512_init(&state); auto res = crypto_hash_sha512_init(&state);
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to initialize sha-512|" + throw utils::error::create_exception({
std::to_string(res)); function_name,
"failed to initialize sha-512",
std::to_string(res),
});
} }
res = crypto_hash_sha512_update(&state, data, data_size); res = crypto_hash_sha512_update(&state, data, data_size);
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to update sha-512|" + std::to_string(res)); throw utils::error::create_exception({
function_name,
"failed to update sha-512",
std::to_string(res),
});
} }
res = crypto_hash_sha512_final(&state, hash.data()); res = crypto_hash_sha512_final(&state, hash.data());
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to finalize sha-512|" + throw utils::error::create_exception({
std::to_string(res)); function_name,
"failed to finalize sha-512",
std::to_string(res),
});
} }
return hash; return hash;
@ -136,24 +150,36 @@ auto create_hash_sha512(const unsigned char *data,
auto create_hash_sha256(const unsigned char *data, auto create_hash_sha256(const unsigned char *data,
std::size_t data_size) -> hash_256_t { std::size_t data_size) -> hash_256_t {
REPERTORY_USES_FUNCTION_NAME();
hash_256_t hash{}; hash_256_t hash{};
crypto_hash_sha256_state state{}; crypto_hash_sha256_state state{};
auto res = crypto_hash_sha256_init(&state); auto res = crypto_hash_sha256_init(&state);
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to initialize sha-256|" + throw utils::error::create_exception({
std::to_string(res)); function_name,
"failed to initialize sha-256",
std::to_string(res),
});
} }
res = crypto_hash_sha256_update(&state, data, data_size); res = crypto_hash_sha256_update(&state, data, data_size);
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to update sha-256|" + std::to_string(res)); throw utils::error::create_exception({
function_name,
"failed to update sha-256",
std::to_string(res),
});
} }
res = crypto_hash_sha256_final(&state, hash.data()); res = crypto_hash_sha256_final(&state, hash.data());
if (res != 0) { if (res != 0) {
throw std::runtime_error("failed to finalize sha-256|" + throw utils::error::create_exception({
std::to_string(res)); function_name,
"failed to finalize sha-256",
std::to_string(res),
});
} }
return hash; return hash;

View File

@ -29,6 +29,8 @@
namespace { namespace {
[[nodiscard]] auto resolve(std::string path) -> std::string { [[nodiscard]] auto resolve(std::string path) -> std::string {
REPERTORY_USES_FUNCTION_NAME();
#if defined(_WIN32) #if defined(_WIN32)
if (repertory::utils::string::contains(path, "~\\")) { if (repertory::utils::string::contains(path, "~\\")) {
repertory::utils::string::replace(path, "~\\", "%USERPROFILE%\\"); repertory::utils::string::replace(path, "~\\", "%USERPROFILE%\\");
@ -63,7 +65,11 @@ namespace {
} }
}); });
if (res) { if (res) {
throw std::runtime_error("failed to getpwuid: " + res.reason); throw repertory::utils::error::create_exception({
function_name,
"failed to getpwuid",
res.reason,
});
} }
path = repertory::utils::string::replace(path, "~/", home + "/"); path = repertory::utils::string::replace(path, "~/", home + "/");

View File

@ -24,6 +24,7 @@
#include "utils/windows.hpp" #include "utils/windows.hpp"
#include "utils/com_init_wrapper.hpp" #include "utils/com_init_wrapper.hpp"
#include "utils/error.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
namespace repertory::utils { namespace repertory::utils {
@ -56,13 +57,13 @@ void create_console() {
std::wcin.clear(); std::wcin.clear();
} }
void free_console() { void free_console() { ::FreeConsole(); }
::FreeConsole();
}
auto get_last_error_code() -> DWORD { return ::GetLastError(); } auto get_last_error_code() -> DWORD { return ::GetLastError(); }
auto get_local_app_data_directory() -> const std::string & { auto get_local_app_data_directory() -> const std::string & {
REPERTORY_USES_FUNCTION_NAME();
static std::string app_data = ([]() -> std::string { static std::string app_data = ([]() -> std::string {
com_init_wrapper cw; com_init_wrapper cw;
PWSTR local_app_data{}; PWSTR local_app_data{};
@ -73,7 +74,10 @@ auto get_local_app_data_directory() -> const std::string & {
return ret; return ret;
} }
throw std::runtime_error("unable to detect local application data folder"); throw utils::error::create_exception({
function_name,
"unable to detect local application data folder",
});
})(); })();
return app_data; return app_data;

View File

@ -64,8 +64,8 @@ public:
void TearDown() override { db3.reset(); } void TearDown() override { db3.reset(); }
}; };
static void common_insert(sqlite3 &db, bool dump = false) { static void common_insert(sqlite3 &db3, bool dump = false) {
auto query = utils::db::sqlite::db_insert{db, "table"} auto query = utils::db::sqlite::db_insert{db3, "table"}
.column_value("column1", "test0") .column_value("column1", "test0")
.column_value("column2", "test1"); .column_value("column2", "test1");
if (dump) { if (dump) {
@ -76,9 +76,9 @@ static void common_insert(sqlite3 &db, bool dump = false) {
EXPECT_TRUE(res.ok()); EXPECT_TRUE(res.ok());
} }
static void common_select(sqlite3 &db, std::string value1, std::string value2, static void common_select(sqlite3 &db3, std::string value1, std::string value2,
bool dump = false) { bool dump = false) {
auto query = utils::db::sqlite::db_select{db, "table"}; auto query = utils::db::sqlite::db_select{db3, "table"};
if (dump) { if (dump) {
std::cout << query.dump() << std::endl; std::cout << query.dump() << std::endl;
} }
@ -113,9 +113,9 @@ static void common_select(sqlite3 &db, std::string value1, std::string value2,
EXPECT_EQ(std::size_t(1U), row_count); EXPECT_EQ(std::size_t(1U), row_count);
} }
static void common_delete(sqlite3 &db, bool dump = false) { static void common_delete(sqlite3 &db3, bool dump = false) {
{ {
auto query = utils::db::sqlite::db_delete{db, "table"}; auto query = utils::db::sqlite::db_delete{db3, "table"};
if (dump) { if (dump) {
std::cout << query.dump() << std::endl; std::cout << query.dump() << std::endl;
} }
@ -125,7 +125,7 @@ static void common_delete(sqlite3 &db, bool dump = false) {
} }
{ {
auto query = utils::db::sqlite::db_select{db, "table"}; auto query = utils::db::sqlite::db_select{db3, "table"};
auto res = query.go(); auto res = query.go();
EXPECT_TRUE(res.ok()); EXPECT_TRUE(res.ok());