This commit is contained in:
2024-08-29 14:39:18 -05:00
parent 92c0e4dabd
commit 272d9a1502
4 changed files with 146 additions and 119 deletions

View File

@ -72,13 +72,10 @@ encrypt_provider::encrypt_provider(app_config &config) : config_(config) {}
auto encrypt_provider::create_api_file( auto encrypt_provider::create_api_file(
const std::string &api_path, bool directory, const std::string &api_path, bool directory,
const std::string &source_path) -> api_file { const std::string &source_path) -> api_file {
#if defined(_WIN32) auto times = utils::file::get_times(source_path);
struct _stat64 buf {}; if (not times.has_value()) {
_stat64(source_path.c_str(), &buf); throw std::runtime_error("failed to get file times");
#else }
struct stat buf {};
stat(source_path.c_str(), &buf);
#endif
api_file file{}; api_file file{};
file.api_path = api_path; file.api_path = api_path;
@ -89,37 +86,10 @@ auto encrypt_provider::create_api_file(
: utils::encryption::encrypting_reader::calculate_encrypted_size( : utils::encryption::encrypting_reader::calculate_encrypted_size(
source_path); source_path);
file.source_path = source_path; file.source_path = source_path;
#if defined(__APPLE__) file.accessed_date = times->get(utils::file::time_type::accessed);
file.changed_date = buf.st_ctimespec.tv_nsec + file.changed_date = times->get(utils::file::time_type::modified);
(buf.st_ctimespec.tv_sec * utils::time::NANOS_PER_SECOND); file.creation_date = times->get(utils::file::time_type::created);
file.accessed_date = file.modified_date = times->get(utils::file::time_type::written);
buf.st_atimespec.tv_nsec +
(buf.st_atimespec.tv_sec * utils::time::NANOS_PER_SECOND);
file.creation_date =
buf.st_birthtimespec.tv_nsec +
(buf.st_birthtimespec.tv_sec * utils::time::NANOS_PER_SECOND);
file.modified_date =
buf.st_mtimespec.tv_nsec +
(buf.st_mtimespec.tv_sec * utils::time::NANOS_PER_SECOND);
#elif defined(_WIN32)
file.accessed_date = utils::time::windows_time_t_to_unix_time(buf.st_atime);
file.changed_date = utils::time::windows_time_t_to_unix_time(buf.st_mtime);
file.creation_date = utils::time::windows_time_t_to_unix_time(buf.st_ctime);
file.modified_date = utils::time::windows_time_t_to_unix_time(buf.st_mtime);
#else // !defined(_WIN32)
file.changed_date = static_cast<std::uint64_t>(
buf.st_mtim.tv_nsec +
(buf.st_mtim.tv_sec * utils::time::NANOS_PER_SECOND));
file.accessed_date = static_cast<std::uint64_t>(
buf.st_atim.tv_nsec +
(buf.st_atim.tv_sec * utils::time::NANOS_PER_SECOND));
file.creation_date = static_cast<std::uint64_t>(
buf.st_ctim.tv_nsec +
(buf.st_ctim.tv_sec * utils::time::NANOS_PER_SECOND));
file.modified_date = static_cast<std::uint64_t>(
buf.st_mtim.tv_nsec +
(buf.st_mtim.tv_sec * utils::time::NANOS_PER_SECOND));
#endif // defined(__APPLE__)
return file; return file;
} }

View File

@ -27,6 +27,35 @@
#include "utils/path.hpp" #include "utils/path.hpp"
namespace repertory::utils::file { namespace repertory::utils::file {
enum class time_type {
accessed,
created,
modified,
written,
};
struct file_times final {
std::uint64_t accessed{};
std::uint64_t created{};
std::uint64_t modified{};
std::uint64_t written{};
[[nodiscard]] auto get(time_type type) const -> std::uint64_t {
switch (type) {
case time_type::accessed:
return accessed;
case time_type::created:
return created;
case time_type::modified:
return modified;
case time_type::written:
return written;
}
throw std::runtime_error("type_type not supported") :
}
};
[[nodiscard]] inline auto [[nodiscard]] inline auto
directory_exists_in_path(std::string_view path, directory_exists_in_path(std::string_view path,
std::string_view sub_directory) -> bool; std::string_view sub_directory) -> bool;
@ -42,6 +71,18 @@ file_exists_in_path(std::string_view path, std::string_view file_name) -> bool;
file_exists_in_path(std::wstring_view path, file_exists_in_path(std::wstring_view path,
std::wstring_view file_name) -> bool; std::wstring_view file_name) -> bool;
[[nodiscard]] auto get_time(std::string_view path, time_type type) const
-> std::optional<std::uint64_t>;
[[nodiscard]] auto get_time(std::wstring_view path, time_type type) const
-> std::optional<std::uint64_t>;
[[nodiscard]] auto
get_times(std::string_view path) -> std::optional<file_times>;
[[nodiscard]] auto
get_times(std::wstring_view path) -> std::optional<file_times>;
#if defined(PROJECT_ENABLE_LIBDSM) #if defined(PROJECT_ENABLE_LIBDSM)
[[nodiscard]] auto [[nodiscard]] auto
smb_create_and_validate_relative_path(std::string_view smb_path, smb_create_and_validate_relative_path(std::string_view smb_path,
@ -77,13 +118,6 @@ smb_get_parent_path(std::string_view smb_path) -> std::string;
struct i_fs_item { struct i_fs_item {
using fs_item_t = std::unique_ptr<i_fs_item>; using fs_item_t = std::unique_ptr<i_fs_item>;
enum class time_types {
access,
creation,
modified,
write,
};
virtual ~i_fs_item() = default; virtual ~i_fs_item() = default;
[[nodiscard]] virtual auto copy_to(std::string_view to_path, [[nodiscard]] virtual auto copy_to(std::string_view to_path,
@ -98,7 +132,8 @@ struct i_fs_item {
[[nodiscard]] virtual auto get_path() const -> std::string = 0; [[nodiscard]] virtual auto get_path() const -> std::string = 0;
[[nodiscard]] virtual auto get_time(time_types type) const -> std::uint64_t; [[nodiscard]] virtual auto
get_time(time_type type) const -> std::optional<std::uint64_t>;
[[nodiscard]] virtual auto is_directory_item() const -> bool = 0; [[nodiscard]] virtual auto is_directory_item() const -> bool = 0;
@ -360,7 +395,8 @@ public:
return file_->get_read_buffer_size(); return file_->get_read_buffer_size();
} }
[[nodiscard]] auto get_time(time_types type) const -> std::uint64_t override { [[nodiscard]] auto
get_time(time_type type) const -> std::optional<std::uint64_t> override {
return file_->get_time(type); return file_->get_time(type);
} }
@ -479,7 +515,8 @@ public:
return file_->get_read_buffer_size(); return file_->get_read_buffer_size();
} }
[[nodiscard]] auto get_time(time_types type) const -> std::uint64_t override { [[nodiscard]] auto
get_time(time_type type) const -> std::optional<std::uint64_t> override {
return file_->get_time(type); return file_->get_time(type);
} }
@ -702,11 +739,12 @@ public:
return read_buffer_size; return read_buffer_size;
} }
[[nodiscard]] static auto get_time(smb_session *session, smb_tid tid, [[nodiscard]] static auto
std::string path, get_time(smb_session *session, smb_tid tid, std::string path,
time_types type) -> std::uint64_t; time_type type) -> std::optional<std::uint64_t>;
[[nodiscard]] auto get_time(time_types type) const -> std::uint64_t override { [[nodiscard]] auto
get_time(time_type type) const -> std::optional<std::uint64_t> override {
return get_time(session_.get(), tid_, path_, type); return get_time(session_.get(), tid_, path_, type);
} }
@ -838,7 +876,8 @@ public:
[[nodiscard]] auto get_path() const -> std::string override { return path_; } [[nodiscard]] auto get_path() const -> std::string override { return path_; }
[[nodiscard]] auto get_time(time_types type) const -> std::uint64_t override { [[nodiscard]] auto
get_time(time_type type) const -> std::optional<std::uint64_t> override {
return smb_file::get_time(session_.get(), tid_, path_, type); return smb_file::get_time(session_.get(), tid_, path_, type);
} }

View File

@ -28,6 +28,84 @@
#include "utils/time.hpp" #include "utils/time.hpp"
namespace repertory::utils::file { namespace repertory::utils::file {
auto get_time(std::string_view path,
time_type type) -> std::optional<std::uint64_t> {
auto times = get_times(path);
if (times.has_value()) {
return times->get(type);
}
return std::nullopt;
}
auto get_time(std::wstring_view path,
time_type type) -> std::optional<std::uint64_t> {
return get_time(utils::string::to_utf8(path), type);
}
auto get_times(std::string_view path) -> std::optional<file_times> {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
try {
#if defined(_WIN32)
struct _stat64 st {};
auto res = _stat64(std::string{path}.c_str(), &st);
#else // !defined(_WIN32)
struct stat st {};
auto res = stat(std::string{path}.c_str(), &st);
#endif // defined(_WIN32)
if (res != 0) {
throw std::runtime_error("failed to get file times|" + std::string{path} +
'|' + std::to_string(errno));
}
file_times ret{};
#if defined(_WIN32)
ret.accessed = utils::time::windows_time_t_to_unix_time(st.st_atime);
#else // !defined(_WIN32)
ret.accessed = static_cast<std::uint64_t>(
st.st_atim.tv_nsec + st.st_atim.tv_sec * utils::time::NANOS_PER_SECOND);
#endif // defined(_WIN32)
#if defined(_WIN32)
ret.created = utils::time::windows_time_t_to_unix_time(st.st_ctime);
#else // !defined(_WIN32)
ret.created = static_cast<std::uint64_t>(
st.st_ctim.tv_nsec + st.st_ctim.tv_sec * utils::time::NANOS_PER_SECOND);
#endif // defined(_WIN32)
#if defined(_WIN32)
ret.modified = utils::time::windows_time_t_to_unix_time(st.st_mtime);
#else // !defined(_WIN32)
ret.modified = static_cast<std::uint64_t>(
st.st_mtim.tv_nsec + st.st_mtim.tv_sec * utils::time::NANOS_PER_SECOND);
#endif // defined(_WIN32)
#if defined(_WIN32)
ret.written = utils::time::windows_time_t_to_unix_time(st.st_mtime);
#else // !defined(_WIN32)
ret.written = static_cast<std::uint64_t>(
st.st_mtim.tv_nsec + st.st_mtim.tv_sec * utils::time::NANOS_PER_SECOND);
#endif // defined(_WIN32)
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
return std::nullopt;
}
auto get_times(std::wstring_view path) -> std::optional<file_times> {
return get_times(utils::string::to_utf8(path));
}
auto i_fs_item::get_time(time_type type) const -> std::optional<std::uint64_t> {
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;
@ -58,66 +136,6 @@ auto i_file::read_all(data_buffer &data, std::uint64_t offset,
return false; return false;
} }
auto i_fs_item::get_time(time_types type) const -> std::uint64_t {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
try {
#if defined(_WIN32)
struct _stat64 st {};
_stat64(get_path().c_str(), &st);
#else // !defined(_WIN32)
struct stat st {};
stat(get_path().c_str(), &st);
#endif // defined(_WIN32)
switch (type) {
case time_types::access:
#if defined(_WIN32)
return utils::time::windows_time_t_to_unix_time(st.st_atime);
#else // !defined(_WIN32)
return static_cast<std::uint64_t>(st.st_atim.tv_nsec +
st.st_atim.tv_sec *
utils::time::NANOS_PER_SECOND);
#endif // defined(_WIN32)
case time_types::creation:
#if defined(_WIN32)
return utils::time::windows_time_t_to_unix_time(st.st_ctime);
#else // !defined(_WIN32)
return static_cast<std::uint64_t>(st.st_ctim.tv_nsec +
st.st_ctim.tv_sec *
utils::time::NANOS_PER_SECOND);
#endif // defined(_WIN32)
case time_types::modified:
#if defined(_WIN32)
return utils::time::windows_time_t_to_unix_time(st.st_mtime);
#else // !defined(_WIN32)
return static_cast<std::uint64_t>(st.st_mtim.tv_nsec +
st.st_mtim.tv_sec *
utils::time::NANOS_PER_SECOND);
#endif // defined(_WIN32)
case time_types::write:
#if defined(_WIN32)
return utils::time::windows_time_t_to_unix_time(st.st_mtime);
#else // !defined(_WIN32)
return static_cast<std::uint64_t>(st.st_mtim.tv_nsec +
st.st_mtim.tv_sec *
utils::time::NANOS_PER_SECOND);
#endif // defined(_WIN32)
}
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
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,

View File

@ -101,7 +101,7 @@ void smb_file::flush() const {
} }
auto smb_file::get_time(smb_session *session, smb_tid tid, std::string path, auto smb_file::get_time(smb_session *session, smb_tid tid, std::string path,
time_types type) -> std::uint64_t { time_type type) -> std::optional<std::uint64_t> {
static constexpr const std::string_view function_name{ static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__), static_cast<const char *>(__FUNCTION__),
}; };
@ -118,16 +118,16 @@ auto smb_file::get_time(smb_session *session, smb_tid tid, std::string path,
} }
switch (type) { switch (type) {
case time_types::access: case time_type::access:
return smb_stat_get(st.get(), SMB_STAT_ATIME); return smb_stat_get(st.get(), SMB_STAT_ATIME);
case time_types::creation: case time_type::creation:
return smb_stat_get(st.get(), SMB_STAT_CTIME); return smb_stat_get(st.get(), SMB_STAT_CTIME);
case time_types::modified: case time_type::modified:
return smb_stat_get(st.get(), SMB_STAT_MTIME); return smb_stat_get(st.get(), SMB_STAT_MTIME);
case time_types::write: case time_type::write:
return smb_stat_get(st.get(), SMB_STAT_WTIME); return smb_stat_get(st.get(), SMB_STAT_WTIME);
} }
} catch (const std::exception &e) { } catch (const std::exception &e) {
@ -136,7 +136,7 @@ auto smb_file::get_time(smb_session *session, smb_tid tid, std::string path,
utils::error::handle_exception(function_name); utils::error::handle_exception(function_name);
} }
return 0U; return std::nullopt;
} }
auto smb_file::is_symlink() const -> bool { auto smb_file::is_symlink() const -> bool {