updated build system

This commit is contained in:
2024-08-08 18:59:14 -05:00
parent 6e4ae2896b
commit 0b5efef569
30 changed files with 1162 additions and 474 deletions

View File

@ -178,7 +178,7 @@ encrypting_reader::encrypting_reader(
stop_requested_(stop_requested),
error_return_(error_return),
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
if (not source_file_) {
if (not *source_file_) {
throw std::runtime_error("file open failed|src|" +
std::string{source_path});
}
@ -190,16 +190,18 @@ encrypting_reader::encrypting_reader(
encrypted_file_name_ = utils::collection::to_hex_string(result);
if (relative_parent_path.has_value()) {
for (auto &&part : std::filesystem::path(relative_parent_path.value())) {
for (auto &&part :
utils::string::split(relative_parent_path.value(),
utils::path::directory_seperator, false)) {
utils::encryption::encrypt_data(
key_, reinterpret_cast<const unsigned char *>(part.string().c_str()),
strnlen(part.string().c_str(), part.string().size()), result);
key_, reinterpret_cast<const unsigned char *>(part.c_str()),
strnlen(part.c_str(), part.size()), result);
encrypted_file_path_ += '/' + utils::collection::to_hex_string(result);
}
encrypted_file_path_ += '/' + encrypted_file_name_;
}
auto file_size = source_file_.size();
auto file_size = source_file_->size();
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
@ -225,16 +227,15 @@ encrypting_reader::encrypting_reader(std::string_view encrypted_file_path,
stop_requested_(stop_requested),
error_return_(error_return),
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
if (not source_file_) {
if (not *source_file_) {
throw std::runtime_error("file open failed|src|" +
std::string{source_path});
}
encrypted_file_path_ = encrypted_file_path;
encrypted_file_name_ =
std::filesystem::path(encrypted_file_path_).filename().string();
encrypted_file_name_ = utils::path::strip_to_file_name(encrypted_file_path_);
auto file_size = source_file_.size();
auto file_size = source_file_->size();
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
@ -262,16 +263,15 @@ encrypting_reader::encrypting_reader(
stop_requested_(stop_requested),
error_return_(error_return),
source_file_(utils::file::file::open_or_create_file(source_path, true)) {
if (not source_file_) {
if (not *source_file_) {
throw std::runtime_error("file open failed|src|" +
std::string{source_path});
}
encrypted_file_path_ = encrypted_file_path;
encrypted_file_name_ =
std::filesystem::path(encrypted_file_path_).filename().string();
encrypted_file_name_ = utils::path::strip_to_file_name(encrypted_file_path_);
auto file_size = source_file_.size();
auto file_size = source_file_->size();
const auto total_chunks = utils::divide_with_ceiling(
file_size, static_cast<std::uint64_t>(data_chunk_size_));
@ -289,7 +289,7 @@ encrypting_reader::encrypting_reader(const encrypting_reader &reader)
stop_requested_(reader.stop_requested_),
error_return_(reader.error_return_),
source_file_(
utils::file::file::open_file(reader.source_file_.get_path(), true)),
utils::file::file::open_file(reader.source_file_->get_path(), true)),
chunk_buffers_(reader.chunk_buffers_),
encrypted_file_name_(reader.encrypted_file_name_),
encrypted_file_path_(reader.encrypted_file_path_),
@ -298,9 +298,9 @@ encrypting_reader::encrypting_reader(const encrypting_reader &reader)
last_data_chunk_size_(reader.last_data_chunk_size_),
read_offset_(reader.read_offset_),
total_size_(reader.total_size_) {
if (not source_file_) {
if (not *source_file_) {
throw std::runtime_error("file open failed|src|" +
source_file_.get_path().string());
source_file_->get_path());
}
}
@ -359,8 +359,8 @@ auto encrypting_reader::reader_function(char *buffer, size_t size,
chunk_buffer.resize(file_data.size() + encryption_header_size);
std::size_t bytes_read{};
if ((ret = source_file_.read(file_data, chunk * data_chunk_size_,
&bytes_read))) {
if ((ret = source_file_->read(file_data, chunk * data_chunk_size_,
&bytes_read))) {
utils::encryption::encrypt_data(iv_list_.at(chunk), key_, file_data,
chunk_buffer);
}

View File

@ -26,13 +26,129 @@
#include "utils/path.hpp"
#include "utils/string.hpp"
namespace {
[[nodiscard]] auto remove_directory_recursively(std::string_view path) -> bool {
#if defined(_WIN32)
WIN32_FIND_DATA fd{};
auto search = repertory::utils::path::combine(path, {"*.*"});
auto find = ::FindFirstFileA(search.c_str(), &fd);
if (find != INVALID_HANDLE_VALUE) {
auto res{true};
do {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if ((std::string(fd.cFileName) != ".") &&
(std::string(fd.cFileName) != "..")) {
res = remove_directory_recursively(
repertory::utils::path::combine(path, {fd.cFileName}));
}
} else {
res = repertory::utils::file::file(
repertory::utils::path::combine(path, {fd.cFileName}))
.remove();
}
} while (res && (::FindNextFileA(find, &fd) != 0));
::FindClose(find);
}
#else
auto *root = opendir(std::string{path}.c_str());
if (root != nullptr) {
auto res{true};
struct dirent *de{};
while (res && (de = readdir(root))) {
if (de->d_type == DT_DIR) {
if ((strcmp(de->d_name, ".") != 0) && (strcmp(de->d_name, "..") != 0)) {
res = remove_directory_recursively(
repertory::utils::path::combine(path, {de->d_name}));
}
} else {
res = repertory::utils::file::file(
repertory::utils::path::combine(path, {de->d_name}))
.remove();
}
}
closedir(root);
}
#endif
return repertory::utils::file::remove_directory(path, false);
}
} // namespace
namespace repertory::utils::file {
auto create_directories(std::string_view path) -> bool {
#if defined(_WIN32)
return is_directory(path) ||
(::SHCreateDirectory(
nullptr,
utils::string::from_utf8(utils::path::absolute(path)).c_str()) ==
ERROR_SUCCESS);
#else // !defined(_WIN32)
auto ret{true};
auto paths = utils::string::split(utils::path::absolute(path),
utils::path::directory_seperator, false);
std::string current_path;
for (std::size_t idx = 0U; ret && (idx < paths.size()); idx++) {
if (paths.at(idx).empty()) {
current_path = utils::path::directory_seperator;
continue;
}
current_path = utils::path::combine(current_path, {paths.at(idx)});
auto status = mkdir(current_path.c_str(), S_IRWXU);
ret = ((status == 0) || (errno == EEXIST));
}
return ret;
#endif
}
auto create_directories(std::wstring_view path) -> bool {
return create_directories(utils::string::to_utf8(path));
}
auto directory_exists_in_path(std::string_view path,
std::string_view sub_directory) -> bool {
return directory_exists_in_path_t<std::string>(path, sub_directory);
}
auto directory_exists_in_path(std::wstring_view path,
std::wstring_view sub_directory) -> bool {
return directory_exists_in_path_t<std::wstring>(path, sub_directory);
}
auto file_exists_in_path(std::string_view path,
std::string_view file_name) -> bool {
return file_exists_in_path_t<std::string>(path, file_name);
}
auto file_exists_in_path(std::wstring_view path,
std::wstring_view file_name) -> bool {
return file_exists_in_path_t<std::wstring>(path, file_name);
}
auto get_file_size(std::string_view path, std::uint64_t &file_size) -> bool {
auto abs_path = utils::path::absolute(path);
file_size = 0U;
#if defined(_WIN32)
struct _stat64 st {};
auto res = _stat64(std::string{path}.c_str(), &st);
if (res != 0) {
return false;
}
file_size = static_cast<std::uint64_t>(st.st_size);
#else // !defined(_WIN32)
std::error_code ec{};
file_size = std::filesystem::file_size(abs_path, ec);
return ec.value() == 0;
if (not ec) {
return false;
}
#endif // defined(_WIN32)
return true;
}
auto get_file_size(std::wstring_view path, std::uint64_t &file_size) -> bool {
@ -70,6 +186,23 @@ auto is_file(std::wstring_view path) -> bool {
return is_file(utils::string::to_utf8(path));
}
auto remove_directory(std::string_view path, bool recursive) -> bool {
auto abs_path = utils::path::absolute(path);
if (recursive) {
return remove_directory_recursively(abs_path);
}
#if defined(_WIN32)
return (not is_directory(abs_path) || ::RemoveDirectoryA(abs_path.c_str()));
#else // !defined(_WIN32)
return not is_directory(abs_path) || (rmdir(abs_path.c_str()) == 0);
#endif // defined(_WIN32)
}
auto remove_directory(std::wstring_view path, bool recursive) -> bool {
return remove_directory(utils::string::to_utf8(path), recursive);
}
#if defined(PROJECT_ENABLE_JSON)
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
auto read_json_file(std::string_view path, nlohmann::json &data,
@ -84,13 +217,13 @@ auto read_json_file(std::string_view path, nlohmann::json &data) -> bool {
try {
auto abs_path = utils::path::absolute(path);
auto file = file::open_file(abs_path);
if (not file) {
if (not *file) {
return false;
}
try {
data_buffer buffer{};
if (not file.read_all(buffer, 0U)) {
if (not file->read_all(buffer, 0U)) {
return false;
}
@ -141,7 +274,7 @@ auto write_json_file(std::string_view path,
try {
auto file = file::open_or_create_file(path);
if (not file.truncate()) {
if (not file->truncate()) {
throw std::runtime_error("failed to truncate file");
}
@ -153,13 +286,14 @@ auto write_json_file(std::string_view path,
utils::encryption::encrypt_data(
*password, reinterpret_cast<const unsigned char *>(str_data.c_str()),
str_data.size(), encrypted_data);
return file.write(encrypted_data, 0U);
return file->write(encrypted_data, 0U);
}
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
auto json_str = data.dump();
return file.write(reinterpret_cast<const unsigned char *>(json_str.c_str()),
json_str.size(), 0U);
return file->write(
reinterpret_cast<const unsigned char *>(json_str.c_str()),
json_str.size(), 0U);
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {

View File

@ -27,7 +27,8 @@
#include "utils/string.hpp"
namespace repertory::utils::file {
auto file::attach_file(native_handle handle, bool read_only) -> file {
auto file::attach_file(native_handle handle,
bool read_only) -> std::unique_ptr<i_file> {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
@ -36,13 +37,12 @@ auto file::attach_file(native_handle handle, bool read_only) -> file {
std::string path;
#if defined(_WIN32)
path.resize(MAX_PATH + 1);
path.resize(repertory::max_path_length + 1);
::GetFinalPathNameByHandleA(handle, path.data(),
static_cast<DWORD>(path.size()),
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
#else // !defined(_WIN32)
path.resize(PATH_MAX + 1);
path.resize(repertory::max_path_length + 1);
#if defined(__APPLE__)
fcntl(handle, F_GETPATH, source_path.data());
@ -63,54 +63,60 @@ auto file::attach_file(native_handle handle, bool read_only) -> file {
auto *ptr = fdopen(handle, read_only ? "rb" : "rb+");
#endif // defined(_WIN32)
return file{
return std::unique_ptr<i_file>(new file{
file_t{ptr},
utils::path::absolute(path),
};
read_only,
});
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
return {};
return nullptr;
}
auto file::open_file(std::filesystem::path path, bool read_only) -> file {
void file::open() {
if (not is_file(path_)) {
throw std::runtime_error("file not found: " + path_);
}
#if defined(_WIN32)
file_.reset(_fsopen(path_.c_str(), read_only_ ? "rb" : "rb+", _SH_DENYNO));
#else // !defined(_WIN32)
file_.reset(fopen(path_.c_str(), read_only_ ? "rb" : "rb+"));
#endif // defined(_WIN32)
}
auto file::open_file(std::string_view path,
bool read_only) -> std::unique_ptr<i_file> {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
auto *ptr = new file{
nullptr,
utils::path::absolute(path),
read_only,
};
auto new_file = std::unique_ptr<i_file>(ptr);
try {
path = utils::path::absolute(path.string());
if (not is_file(path.string())) {
throw std::runtime_error("file not found: " + path.string());
}
#if defined(_WIN32)
auto *ptr =
_fsopen(path.string().c_str(), read_only ? "rb" : "rb+", _SH_DENYNO);
#else // !defined(_WIN32)
auto *ptr = fopen(path.string().c_str(), read_only ? "rb" : "rb+");
#endif // defined(_WIN32)
return file{
file_t{ptr},
path,
};
ptr->open();
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
return {};
return new_file;
}
auto file::open_or_create_file(std::filesystem::path path,
bool read_only) -> file {
path = utils::path::absolute(path.string());
if (not utils::file::is_file(path.string())) {
auto file::open_or_create_file(std::string_view path,
bool read_only) -> std::unique_ptr<i_file> {
auto abs_path = utils::path::absolute(path);
if (not is_file(abs_path)) {
#if defined(_WIN32)
int old_mode{};
_umask_s(077, &old_mode);
@ -119,36 +125,44 @@ auto file::open_or_create_file(std::filesystem::path path,
#endif // defined(_WIN32)
#if defined(_WIN32)
auto *ptr = _fsopen(path.string().c_str(), "ab+", _SH_DENYNO);
auto *ptr = _fsopen(abs_path.c_str(), "ab+", _SH_DENYNO);
#else // !defined(_WIN32)
auto *ptr = fopen(path.string().c_str(), "ab+");
auto *ptr = fopen(abs_path.c_str(), "ab+");
#endif // defined(_WIN32)
if (ptr != nullptr) {
fclose(ptr);
}
#if defined(_WIN32)
_umask_s(old_mode, nullptr);
#else // !defined(_WIN32)
umask(old_mode);
#endif // defined(_WIN32)
if (ptr != nullptr) {
fclose(ptr);
}
}
return open_file(path, read_only);
return open_file(abs_path, read_only);
}
void file::close() {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
file_.reset();
}
void file::flush() {
auto file::exists() const -> bool {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
return is_file(path_);
}
void file::flush() const {
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
if (file_) {
@ -157,6 +171,10 @@ void file::flush() {
}
auto file::get_handle() const -> native_handle {
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
if (file_) {
#if defined(_WIN32)
return reinterpret_cast<native_handle>(
@ -169,12 +187,16 @@ auto file::get_handle() const -> native_handle {
return INVALID_HANDLE_VALUE;
}
auto file::move_to(std::filesystem::path new_path) -> bool {
auto file::move_to(std::string_view path) -> bool {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
new_path = utils::path::absolute(new_path.string());
auto abs_path = utils::path::absolute(path);
auto reopen{false};
if (file_) {
@ -182,19 +204,29 @@ auto file::move_to(std::filesystem::path new_path) -> bool {
close();
}
auto success{false};
#if defined(_WIN32)
success = !!::MoveFileExA(path_.c_str(), abs_path.c_str(),
MOVEFILE_REPLACE_EXISTING);
#else // !// defined(_WIN32)
std::error_code ec{};
std::filesystem::rename(path_, new_path, ec);
if (not ec) {
path_ = new_path;
if (reopen) {
*this = open_file(path_);
}
std::filesystem::rename(path_, abs_path, ec);
success = ec.value() == 0;
#endif // defined(_WIN32)
return true;
if (success) {
path_ = abs_path;
}
if (reopen) {
*this = open_file(path_);
try {
open();
return success;
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
}
return false;
@ -203,11 +235,11 @@ auto file::move_to(std::filesystem::path new_path) -> bool {
auto file::read_all(data_buffer &data, std::uint64_t offset,
std::size_t *total_read) -> bool {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
data_buffer buffer;
buffer.resize(65536U);
buffer.resize(read_buffer_size);
std::size_t current_read{};
while (read(reinterpret_cast<unsigned char *>(buffer.data()),
@ -237,7 +269,7 @@ auto file::read_all(data_buffer &data, std::uint64_t offset,
auto file::read(data_buffer &data, std::uint64_t offset,
std::size_t *total_read) -> bool {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
std::size_t bytes_read{};
@ -255,14 +287,14 @@ auto file::read(data_buffer &data, std::uint64_t offset,
auto file::read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
std::size_t *total_read) -> bool {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
#endif // defined(_WIN32)
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
if (total_read != nullptr) {
(*total_read) = 0U;
}
@ -298,18 +330,30 @@ auto file::read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
auto file::remove() -> bool {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
close();
if (not exists()) {
return true;
}
#if defined(_WIN32)
return !!::DeleteFileA(path_.c_str());
#else // !defined(_WIN32)
std::error_code ec{};
return std::filesystem::remove(path_, ec);
#endif // defined(_WIN32)
}
auto file::truncate(std::size_t size) -> bool {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
auto reopen{false};
@ -320,23 +364,34 @@ auto file::truncate(std::size_t size) -> bool {
std::error_code ec{};
std::filesystem::resize_file(path_, size, ec);
auto success{ec.value() == 0};
if (reopen) {
*this = open_file(path_);
try {
open();
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
success = false;
} catch (...) {
utils::error::handle_exception(function_name);
success = false;
}
}
return ec.value() == 0;
return success;
}
auto file::write(const unsigned char *data, std::size_t to_write,
std::size_t offset, std::size_t *total_written) -> bool {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
#endif // defined(_WIN32)
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
if (total_written != nullptr) {
(*total_written) = 0U;
}
@ -374,14 +429,14 @@ auto file::write(const unsigned char *data, std::size_t to_write,
}
auto file::size() const -> std::uint64_t {
#if defined(_WIN32)
recur_mutex_lock lock{mtx_};
#endif // defined(_WIN32)
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
#if defined(_WIN32)
recur_mutex_lock lock{*mtx_};
#endif // defined(_WIN32)
try {
if (file_) {
if (fseeko(file_.get(), 0, SEEK_END) == -1) {
@ -395,6 +450,13 @@ auto file::size() const -> std::uint64_t {
return static_cast<std::uint64_t>(size);
}
std::uint64_t size{};
if (not get_file_size(path_, size)) {
throw std::runtime_error("failed to get file size");
}
return size;
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {

View File

@ -0,0 +1,64 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/file.hpp"
namespace repertory::utils::file {
auto thread_file::attach_file(native_handle handle,
bool read_only) -> std::unique_ptr<i_file> {}
auto thread_file::open_file(std::string_view path,
bool read_only) -> std::unique_ptr<i_file> {}
auto thread_file::open_or_create_file(std::string_view path, bool read_only)
-> std::unique_ptr<i_file> {}
thread_file::thread_file(std::unique_ptr<i_file> file)
: file_(std::move(file)) {}
void thread_file::close() {}
void thread_file::flush() const {}
auto thread_file::move_to(std::string_view path) -> bool {}
auto thread_file::read_all(data_buffer &data, std::uint64_t offset,
std::size_t *total_read) -> bool {}
auto thread_file::read(data_buffer &data, std::uint64_t offset,
std::size_t *total_read) -> bool {}
auto thread_file::read(unsigned char *data, std::size_t to_read,
std::uint64_t offset, std::size_t *total_read) -> bool {}
auto thread_file::remove() -> bool {}
auto thread_file::truncate(std::size_t size) -> bool {}
auto thread_file::write(const unsigned char *data, std::size_t to_write,
std::size_t offset,
std::size_t *total_written) -> bool {}
auto thread_file::size() const -> std::uint64_t {}
auto thread_file::write(const data_buffer &data, std::uint64_t offset,
std::size_t *total_written) -> bool {}
} // namespace repertory::utils::file

View File

@ -23,18 +23,11 @@
#include "utils/common.hpp"
#include "utils/error.hpp"
#include "utils/file.hpp"
#include "utils/string.hpp"
#include "utils/unix.hpp"
namespace {
static const std::string directory_seperator_str{
repertory::utils::path::directory_seperator,
};
static const std::wstring directory_seperator_str_w{
repertory::utils::path::directory_seperator_w,
};
[[nodiscard]] auto resolve(std::string path) -> std::string {
#if defined(_WIN32)
if (repertory::utils::string::contains(path, "~") ||
@ -52,12 +45,17 @@ static const std::wstring directory_seperator_str_w{
#else // !defined (_WIN32)
if (repertory::utils::string::contains(path, "~")) {
std::string home{};
repertory::utils::use_getpwuid(getuid(), [&home](struct passwd *pw) {
home = (pw->pw_dir ? pw->pw_dir : "");
if (home.empty() || ((home == "/") && (getuid() != 0))) {
home = repertory::utils::path::combine("/home", {pw->pw_name});
}
});
auto res =
repertory::utils::use_getpwuid(getuid(), [&home](struct passwd *pw) {
home = (pw->pw_dir ? pw->pw_dir : "");
if (home.empty() ||
((home == repertory::utils::path::slash) && (getuid() != 0))) {
home = repertory::utils::path::combine("/home", {pw->pw_name});
}
});
if (res) {
throw std::runtime_error("failed to getpwuid: " + res.reason);
}
return repertory::utils::string::replace(path, "~", home);
}
@ -70,36 +68,44 @@ static const std::wstring directory_seperator_str_w{
namespace repertory::utils::path {
auto absolute(std::string_view path) -> std::string {
std::string abs_path{path};
abs_path = resolve(abs_path);
format_path(abs_path, directory_seperator, not_directory_seperator);
if (abs_path.empty()) {
return abs_path;
}
abs_path = finalize(resolve(abs_path));
#if defined(_WIN32)
if (not abs_path.empty() && ::PathIsRelativeA(abs_path.c_str())) {
std::string temp;
temp.resize(MAX_PATH + 1);
abs_path = _fullpath(temp.data(), abs_path.c_str(), MAX_PATH);
if (not utils::string::contains(abs_path, dot)) {
return abs_path;
}
std::string temp;
temp.resize(repertory::max_path_length + 1);
::GetFullPathNameA(abs_path.c_str(), static_cast<DWORD>(temp.size()),
temp.data(), nullptr);
#else // !defined(_WIN32)
if (not abs_path.empty() && (abs_path.at(0U) != '/')) {
auto found{false};
std::string tmp{abs_path};
do {
auto *res = realpath(tmp.c_str(), nullptr);
if (res != nullptr) {
abs_path = res + std::string{directory_seperator} +
abs_path.substr(tmp.size());
free(res);
found = true;
} else if (tmp == ".") {
found = true;
} else {
tmp = dirname(tmp.data());
}
} while (not found);
if (not utils::string::contains(abs_path, dot) ||
utils::string::begins_with(abs_path, slash)) {
return abs_path;
}
auto found{false};
std::string tmp{abs_path};
do {
auto *res = realpath(tmp.c_str(), nullptr);
if (res != nullptr) {
abs_path =
res + std::string{directory_seperator} + abs_path.substr(tmp.size());
free(res);
found = true;
} else if (tmp == dot) {
found = true;
} else {
tmp = dirname(tmp.data());
}
} while (not found);
#endif // defined(_WIN32)
return format_path(abs_path, directory_seperator, not_directory_seperator);
return finalize(abs_path);
}
auto absolute(std::wstring_view path) -> std::wstring {
@ -142,7 +148,7 @@ auto find_program_in_path(const std::string &name_without_extension)
for (auto &&extension : extension_list) {
auto exec_path = combine(
search_path, {name_without_extension + std::string{extension}});
if (std::filesystem::exists(exec_path)) {
if (utils::file::is_file(exec_path)) {
found_items[name_without_extension] = exec_path;
return exec_path;
}
@ -159,14 +165,16 @@ find_program_in_path(std::wstring_view name_without_extension) -> std::wstring {
}
auto get_parent_directory(std::string_view path) -> std::string {
auto ret = std::filesystem::path{path}.parent_path().string();
#if !defined(_WIN32)
if (ret == ".") {
ret = "/";
}
#endif // !defined(_WIN32)
auto abs_path = absolute(path);
return absolute(ret);
#if defined(_WIN32)
::PathRemoveFileSpecA(abs_path.data());
abs_path = abs_path.c_str();
#else // !defined(_WIN32)
abs_path = std::filesystem::path{abs_path}.parent_path().string();
#endif // defined(_WIN32)
return finalize(abs_path);
}
auto get_parent_directory(std::wstring_view path) -> std::wstring {
@ -175,13 +183,12 @@ auto get_parent_directory(std::wstring_view path) -> std::wstring {
}
auto is_trash_directory(std::string_view path) -> bool {
std::string dir_sep_t{get_directory_seperator<char>()};
auto trash_path = utils::string::to_lower(absolute(path));
return utils::string::begins_with(trash_path,
directory_seperator_str + ".trash-") ||
utils::string::begins_with(trash_path,
directory_seperator_str + ".trashes") ||
utils::string::begins_with(trash_path,
directory_seperator_str + "$recycle.bin");
return utils::string::begins_with(trash_path, dir_sep_t + ".trash-") ||
utils::string::begins_with(trash_path, dir_sep_t + ".trashes") ||
utils::string::begins_with(trash_path, dir_sep_t + "$recycle.bin");
}
auto is_trash_directory(std::wstring_view path) -> bool {
@ -191,8 +198,8 @@ auto is_trash_directory(std::wstring_view path) -> bool {
auto make_file_uri(std::string_view path) -> std::string {
auto abs_path = absolute(path);
#if defined(_WIN32)
utils::string::replace(abs_path, '\\', '/');
abs_path = '/' + abs_path;
utils::string::replace(abs_path, backslash, slash);
abs_path = std::string{slash} + abs_path;
#endif // defined(_WIN32)
return "file://" + abs_path;
}
@ -201,31 +208,11 @@ auto make_file_uri(std::wstring_view path) -> std::wstring {
return utils::string::from_utf8(make_file_uri(utils::string::to_utf8(path)));
}
auto remove_file_name(std::string_view path) -> std::string {
auto abs_path = absolute(path);
#if defined(_WIN32)
::PathRemoveFileSpecA(abs_path.data());
abs_path = abs_path.c_str();
#else // !defined(_WIN32)
if (abs_path != "/") {
auto idx{abs_path.size() - 1U};
while ((idx != 0U) && (abs_path.at(idx) != '/')) {
idx--;
}
abs_path = (idx > 0U) ? absolute(abs_path.substr(0U, idx)) : "/";
}
#endif // defined(_WIN32)
return abs_path;
}
auto strip_to_file_name(std::string path) -> std::string {
#if defined(_WIN32)
return ::PathFindFileNameA(path.c_str());
#else // !defined(_WIN32)
return utils::string::contains(path, "/") ? basename(path.data()) : path;
return utils::string::contains(path, slash) ? basename(path.data()) : path;
#endif // defined(_WIN32)
}

View File

@ -76,7 +76,7 @@ auto run_process_elevated(std::vector<const char *> args) -> int {
}
std::string full_path;
full_path.resize(MAX_PATH + 1);
full_path.resize(repertory::max_path_length + 1);
if (::GetModuleFileNameA(nullptr, full_path.data(), MAX_PATH)) {
SHELLEXECUTEINFOA sei{};