updated build system
This commit is contained in:
@ -59,7 +59,6 @@ list(APPEND PROJECT_CFLAGS_LIST
|
|||||||
|
|
||||||
list(APPEND PROJECT_CXXFLAGS_LIST
|
list(APPEND PROJECT_CXXFLAGS_LIST
|
||||||
${PROJECT_COMMON_FLAG_LIST}
|
${PROJECT_COMMON_FLAG_LIST}
|
||||||
-fext-numeric-literals
|
|
||||||
-std=gnu++${CMAKE_CXX_STANDARD}
|
-std=gnu++${CMAKE_CXX_STANDARD}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,10 +21,13 @@ set(GTKMM_VERSION 3.0)
|
|||||||
set(ICU_VERSION 75-1)
|
set(ICU_VERSION 75-1)
|
||||||
set(JSON_VERSION 3.11.3)
|
set(JSON_VERSION 3.11.3)
|
||||||
set(LIBBITCOIN_SYSTEM_VERSION 3.8.0)
|
set(LIBBITCOIN_SYSTEM_VERSION 3.8.0)
|
||||||
|
set(LIBDSM_VERSION 0.4.3)
|
||||||
set(LIBEVENT_VERSION 2.1.12)
|
set(LIBEVENT_VERSION 2.1.12)
|
||||||
set(LIBJPEG_TURBO_VERSION 3.0.3)
|
set(LIBJPEG_TURBO_VERSION 3.0.3)
|
||||||
set(LIBPNG_VERSION 1.6.43)
|
set(LIBPNG_VERSION 1.6.43)
|
||||||
set(LIBSODIUM_VERSION 1.0.20)
|
set(LIBSODIUM_VERSION 1.0.20)
|
||||||
|
set(LIBTASN_VERSION 4.19.0)
|
||||||
|
set(LIBICONV_VERSION 1.17)
|
||||||
set(MESA_VERSION 23.3.3)
|
set(MESA_VERSION 23.3.3)
|
||||||
set(MINGW_VERSION 11.0.1)
|
set(MINGW_VERSION 11.0.1)
|
||||||
set(NANA_VERSION 1.7.4)
|
set(NANA_VERSION 1.7.4)
|
||||||
@ -41,6 +44,7 @@ set(SFML_VERSION 2.6.1)
|
|||||||
set(SPDLOG_VERSION 1.14.1)
|
set(SPDLOG_VERSION 1.14.1)
|
||||||
set(SQLITE_VERSION 3460000)
|
set(SQLITE_VERSION 3460000)
|
||||||
set(STDUUID_VERSION 1.2.3)
|
set(STDUUID_VERSION 1.2.3)
|
||||||
|
set(VLC_VERSION 3.0)
|
||||||
set(VORBIS_VERSION 1.3.7)
|
set(VORBIS_VERSION 1.3.7)
|
||||||
set(WXWIDGETS_VERSION 3.2.5)
|
set(WXWIDGETS_VERSION 3.2.5)
|
||||||
set(ZLIB_VERSION 1.3.1)
|
set(ZLIB_VERSION 1.3.1)
|
||||||
|
@ -10,6 +10,7 @@ RUN apk add \
|
|||||||
bash \
|
bash \
|
||||||
binutils \
|
binutils \
|
||||||
binutils-dev \
|
binutils-dev \
|
||||||
|
bison \
|
||||||
boost-dev \
|
boost-dev \
|
||||||
bzip2-static \
|
bzip2-static \
|
||||||
cmake \
|
cmake \
|
||||||
|
@ -10,6 +10,7 @@ RUN apk add \
|
|||||||
bash \
|
bash \
|
||||||
binutils \
|
binutils \
|
||||||
binutils-dev \
|
binutils-dev \
|
||||||
|
bison \
|
||||||
boost-dev \
|
boost-dev \
|
||||||
bzip2-static \
|
bzip2-static \
|
||||||
cmake \
|
cmake \
|
||||||
|
@ -1004,6 +1004,58 @@ RUN if [ -f "/3rd_party/sdl-${MY_SDL_VERSION}.tar.gz" ]; then \
|
|||||||
&& rm -r SDL-release-${MY_SDL_VERSION} \
|
&& rm -r SDL-release-${MY_SDL_VERSION} \
|
||||||
; fi
|
; fi
|
||||||
|
|
||||||
|
ARG LIBTASN_VERSION
|
||||||
|
ENV MY_LIBTASN_VERSION=${LIBTASN_VERSION}
|
||||||
|
RUN if [ -f "/3rd_party/libtasn1-${MY_LIBTASN_VERSION}.tar.gz" ]; then \
|
||||||
|
tar xvzf /3rd_party/libtasn1-${MY_LIBTASN_VERSION}.tar.gz \
|
||||||
|
&& cd libtasn1-${MY_LIBTASN_VERSION} \
|
||||||
|
&& ./configure \
|
||||||
|
--disable-doc \
|
||||||
|
--enable-static=yes \
|
||||||
|
--enable-shared=no \
|
||||||
|
--host=${MY_MINGW_PREFIX} \
|
||||||
|
--prefix=${MY_MINGW_DIR} \
|
||||||
|
&& make -j${MY_NUM_JOBS} \
|
||||||
|
&& make install \
|
||||||
|
&& cd ${MY_WORKDIR} \
|
||||||
|
&& rm -r libtasn1-${MY_LIBTASN_VERSION} \
|
||||||
|
; fi
|
||||||
|
|
||||||
|
ARG LIBICONV_VERSION
|
||||||
|
ENV MY_LIBICONV_VERSION=${LIBICONV_VERSION}
|
||||||
|
RUN if [ -f "/3rd_party/libiconv-${MY_LIBICONV_VERSION}.tar.gz" ]; then \
|
||||||
|
tar xvzf /3rd_party/libiconv-${MY_LIBICONV_VERSION}.tar.gz \
|
||||||
|
&& cd libiconv-${MY_LIBICONV_VERSION} \
|
||||||
|
&& ./configure \
|
||||||
|
--enable-static=yes \
|
||||||
|
--enable-shared=no \
|
||||||
|
--host=${MY_MINGW_PREFIX} \
|
||||||
|
--prefix=${MY_MINGW_DIR} \
|
||||||
|
&& make -j${MY_NUM_JOBS} \
|
||||||
|
&& make install \
|
||||||
|
&& cd ${MY_WORKDIR} \
|
||||||
|
&& rm -r libiconv-${MY_LIBICONV_VERSION} \
|
||||||
|
; fi
|
||||||
|
|
||||||
|
ARG LIBDSM_VERSION
|
||||||
|
ENV MY_LIBDSM_VERSION=${LIBDSM_VERSION}
|
||||||
|
RUN if [ -f "/3rd_party/libdsm-${MY_LIBDSM_VERSION}.tar.gz" ]; then \
|
||||||
|
tar xvxf /3rd_party/libdsm-${MY_LIBDSM_VERSION}.tar.gz \
|
||||||
|
&& cd libdsm-${MY_LIBDSM_VERSION} \
|
||||||
|
&& meson setup \
|
||||||
|
--cross-file ${MY_TOOLCHAIN_FILE_MESON} \
|
||||||
|
--prefix=${MY_MINGW_DIR} \
|
||||||
|
-Dbinaries=false \
|
||||||
|
-Ddefault_library=static \
|
||||||
|
_build \
|
||||||
|
&& meson compile \
|
||||||
|
-C _build \
|
||||||
|
&& meson install \
|
||||||
|
-C _build \
|
||||||
|
&& cd ${MY_WORKDIR} \
|
||||||
|
&& rm -r libdsm-${MY_LIBDSM_VERSION} \
|
||||||
|
; fi
|
||||||
|
|
||||||
RUN (mv ${MY_MINGW_DIR}/lib/*.dll ${MY_MINGW_DIR}/bin || echo "no dll's found") \
|
RUN (mv ${MY_MINGW_DIR}/lib/*.dll ${MY_MINGW_DIR}/bin || echo "no dll's found") \
|
||||||
&& chmod 0777 -R ${MY_MINGW_DIR} \
|
&& chmod 0777 -R ${MY_MINGW_DIR} \
|
||||||
&& rm -rf /3rd_party
|
&& rm -rf /3rd_party
|
||||||
|
@ -29,12 +29,6 @@ namespace repertory::utils::encryption {
|
|||||||
using reader_func = std::function<api_error(data_buffer &cypher_text,
|
using reader_func = std::function<api_error(data_buffer &cypher_text,
|
||||||
std::uint64_t start_offset,
|
std::uint64_t start_offset,
|
||||||
std::uint64_t end_offset)>;
|
std::uint64_t end_offset)>;
|
||||||
// Prototypes
|
|
||||||
[[nodiscard]] auto decrypt_file_path(std::string_view encryption_token,
|
|
||||||
std::string &file_path) -> api_error;
|
|
||||||
|
|
||||||
[[nodiscard]] auto decrypt_file_name(std::string_view encryption_token,
|
|
||||||
std::string &file_name) -> api_error;
|
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto
|
||||||
read_encrypted_range(const http_range &range,
|
read_encrypted_range(const http_range &range,
|
||||||
|
@ -30,43 +30,6 @@
|
|||||||
#include "utils/utils.hpp"
|
#include "utils/utils.hpp"
|
||||||
|
|
||||||
namespace repertory::utils::encryption {
|
namespace repertory::utils::encryption {
|
||||||
auto decrypt_file_path(std::string_view encryption_token,
|
|
||||||
std::string &file_path) -> api_error {
|
|
||||||
std::string decrypted_file_path{};
|
|
||||||
for (const auto &part : std::filesystem::path(file_path)) {
|
|
||||||
auto file_name = part.string();
|
|
||||||
if (file_name == "/") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto res = decrypt_file_name(encryption_token, file_name);
|
|
||||||
if (res != api_error::success) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
decrypted_file_path += '/' + file_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
file_path = decrypted_file_path;
|
|
||||||
return api_error::success;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto decrypt_file_name(std::string_view encryption_token,
|
|
||||||
std::string &file_name) -> api_error {
|
|
||||||
data_buffer buffer;
|
|
||||||
if (not utils::collection::from_hex_string(file_name, buffer)) {
|
|
||||||
return api_error::error;
|
|
||||||
}
|
|
||||||
|
|
||||||
file_name.clear();
|
|
||||||
if (not utils::encryption::decrypt_data(encryption_token, buffer,
|
|
||||||
file_name)) {
|
|
||||||
return api_error::decryption_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return api_error::success;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto read_encrypted_range(const http_range &range,
|
auto read_encrypted_range(const http_range &range,
|
||||||
const utils::encryption::hash_256_t &key,
|
const utils::encryption::hash_256_t &key,
|
||||||
reader_func reader, std::uint64_t total_size,
|
reader_func reader, std::uint64_t total_size,
|
||||||
|
@ -151,6 +151,10 @@ if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_ENABLE_WINFSP}" == "ON" ]; t
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_ENABLE_VLC}" == "ON" ]; then
|
||||||
|
rsync -av --progress ${PROJECT_3RD_PARTY_DIR}/vlc/ "${PROJECT_DIST_DIR}/vlc/"
|
||||||
|
fi
|
||||||
|
|
||||||
for PROJECT_DEPENDENCY in "${PROJECT_MINGW64_COPY_DEPENDENCIES[@]}"; do
|
for PROJECT_DEPENDENCY in "${PROJECT_MINGW64_COPY_DEPENDENCIES[@]}"; do
|
||||||
rsync -av --progress ${PROJECT_DEPENDENCY} "${PROJECT_DIST_DIR}/"
|
rsync -av --progress ${PROJECT_DEPENDENCY} "${PROJECT_DIST_DIR}/"
|
||||||
done
|
done
|
||||||
|
@ -222,6 +222,11 @@ else
|
|||||||
PROJECT_BUILD_SHARED_LIBS=ON
|
PROJECT_BUILD_SHARED_LIBS=ON
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${PROJECT_ENABLE_LIBDSM}" == "ON" ]; then
|
||||||
|
PROJECT_ENABLE_LIBICONV=ON
|
||||||
|
PROJECT_ENABLE_LIBTASN=ON
|
||||||
|
fi
|
||||||
|
|
||||||
PROJECT_CMAKE_OPTS="-DPROJECT_3RD_PARTY_DIR=${PROJECT_3RD_PARTY_DIR} ${PROJECT_CMAKE_OPTS}"
|
PROJECT_CMAKE_OPTS="-DPROJECT_3RD_PARTY_DIR=${PROJECT_3RD_PARTY_DIR} ${PROJECT_CMAKE_OPTS}"
|
||||||
PROJECT_CMAKE_OPTS="-DPROJECT_BUILD_ARCH=${PROJECT_BUILD_ARCH} ${PROJECT_CMAKE_OPTS}"
|
PROJECT_CMAKE_OPTS="-DPROJECT_BUILD_ARCH=${PROJECT_BUILD_ARCH} ${PROJECT_CMAKE_OPTS}"
|
||||||
PROJECT_CMAKE_OPTS="-DPROJECT_BUILD_DIR=${PROJECT_BUILD_DIR} ${PROJECT_CMAKE_OPTS}"
|
PROJECT_CMAKE_OPTS="-DPROJECT_BUILD_DIR=${PROJECT_BUILD_DIR} ${PROJECT_CMAKE_OPTS}"
|
||||||
|
@ -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::collection {
|
namespace repertory::utils::collection {
|
||||||
@ -69,24 +70,75 @@ inline auto includes(const col_t &collection,
|
|||||||
collection.end();
|
collection.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename val_t, typename string_t>
|
template <typename val_t>
|
||||||
[[nodiscard]] inline auto
|
[[nodiscard]] inline auto from_hex_string_t(std::string_view str,
|
||||||
from_hex_string_t(std::basic_string_view<typename string_t::value_type> str,
|
|
||||||
val_t &val) -> bool {
|
val_t &val) -> bool {
|
||||||
static constexpr const auto base16{16};
|
static constexpr const auto base16{16};
|
||||||
|
|
||||||
val.clear();
|
static constexpr const std::string_view function_name{
|
||||||
if (not(str.length() % 2U)) {
|
static_cast<const char *>(__FUNCTION__),
|
||||||
for (std::size_t i = 0U; i < str.length(); i += 2U) {
|
};
|
||||||
val.emplace_back(static_cast<typename val_t::value_type>(
|
|
||||||
std::strtol(string_t{str.substr(i, 2U)}.c_str(), nullptr, base16)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
val.clear();
|
||||||
|
|
||||||
|
std::string fmt_val{str};
|
||||||
|
utils::string::trim(fmt_val);
|
||||||
|
if (fmt_val.empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt_val = utils::string::to_lower(fmt_val);
|
||||||
|
if (utils::string::begins_with(fmt_val, "0x")) {
|
||||||
|
fmt_val = fmt_val.substr(2U);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fmt_val.empty()) {
|
||||||
|
throw std::runtime_error("hex string is invalid|" + std::string{str});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fmt_val.length() % 2U) {
|
||||||
|
fmt_val = '0' + fmt_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto iter = std::find_if_not(
|
||||||
|
fmt_val.begin(), fmt_val.end(), [](auto cur_char) -> bool {
|
||||||
|
auto check = static_cast<std::uint32_t>(cur_char);
|
||||||
|
return ((check >= 48U && check <= 57U) ||
|
||||||
|
(check >= 97U && check <= 102U));
|
||||||
|
});
|
||||||
|
if (iter != fmt_val.end()) {
|
||||||
|
auto invalid_idx{std::distance(fmt_val.begin(), iter)};
|
||||||
|
throw std::range_error(
|
||||||
|
"invalid character in hex string|" + std::to_string(invalid_idx) +
|
||||||
|
'|' + std::string(1U, str.at(invalid_idx)) + '|' + std::string{str});
|
||||||
|
}
|
||||||
|
|
||||||
|
val.resize(fmt_val.length() / 2U);
|
||||||
|
for (std::size_t idx = 0U; idx < fmt_val.length(); idx += 2U) {
|
||||||
|
val.at(idx / 2U) = static_cast<typename val_t::value_type>(
|
||||||
|
std::strtoul(fmt_val.substr(idx, 2U).c_str(), nullptr, base16));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
val.clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
template <typename val_t>
|
||||||
|
inline auto from_hex_string(std::string_view str, val_t &val) -> bool {
|
||||||
|
return from_hex_string_t<val_t>(str, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename val_t>
|
||||||
|
inline auto from_hex_string(std::wstring_view str, val_t &val) -> bool {
|
||||||
|
return from_hex_string_t<val_t>(utils::string::to_utf8(str), val);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename col_t>
|
template <typename col_t>
|
||||||
inline auto remove_element(col_t &collection,
|
inline auto remove_element(col_t &collection,
|
||||||
@ -96,16 +148,6 @@ inline auto remove_element(col_t &collection,
|
|||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename val_t>
|
|
||||||
inline auto from_hex_string(std::string_view str, val_t &val) -> bool {
|
|
||||||
return from_hex_string_t<val_t, std::string>(str, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename val_t>
|
|
||||||
inline auto from_hex_string(std::wstring_view str, val_t &val) -> bool {
|
|
||||||
return from_hex_string_t<val_t, std::wstring>(str, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename col_t>
|
template <typename col_t>
|
||||||
inline auto to_hex_string(const col_t &collection) -> std::string {
|
inline auto to_hex_string(const col_t &collection) -> std::string {
|
||||||
static_assert(sizeof(typename col_t::value_type) == 1U,
|
static_assert(sizeof(typename col_t::value_type) == 1U,
|
||||||
|
@ -165,6 +165,50 @@ extern "C" {
|
|||||||
#endif // defined(__cplusplus)
|
#endif // defined(__cplusplus)
|
||||||
#endif // defined(PROJECT_ENABLE_FZF)
|
#endif // defined(PROJECT_ENABLE_FZF)
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_LIBDSM)
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif // defined(__cplusplus)
|
||||||
|
#include "bdsm/bdsm.h"
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct netbios_ns_deleter final {
|
||||||
|
void operator()(netbios_ns *ns) {
|
||||||
|
if (ns != nullptr) {
|
||||||
|
netbios_ns_destroy(ns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using netbios_ns_t = std::unique_ptr<netbios_ns, netbios_ns_deleter>;
|
||||||
|
|
||||||
|
inline const auto smb_session_deleter = [](smb_session *session) {
|
||||||
|
if (session != nullptr) {
|
||||||
|
smb_session_destroy(session);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using smb_session_t = std::shared_ptr<smb_session>;
|
||||||
|
|
||||||
|
struct smb_stat_deleter final {
|
||||||
|
void operator()(smb_stat st) {
|
||||||
|
if (st != nullptr) {
|
||||||
|
smb_stat_destroy(st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using smb_stat_t = std::unique_ptr<smb_file, smb_stat_deleter>;
|
||||||
|
|
||||||
|
struct smb_stat_list_deleter final {
|
||||||
|
void operator()(smb_file *list) {
|
||||||
|
if (list != nullptr) {
|
||||||
|
smb_stat_list_destroy(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using smb_stat_list_t = std::unique_ptr<smb_file, smb_stat_list_deleter>;
|
||||||
|
#endif // defined(__cplusplus)
|
||||||
|
#endif // defined(PROJECT_ENABLE_LIBDSM)
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_LIBEVENT)
|
#if defined(PROJECT_ENABLE_LIBEVENT)
|
||||||
#include "event2/buffer.h"
|
#include "event2/buffer.h"
|
||||||
#include "event2/bufferevent.h"
|
#include "event2/bufferevent.h"
|
||||||
@ -173,20 +217,68 @@ extern "C" {
|
|||||||
#include "event2/util.h"
|
#include "event2/util.h"
|
||||||
#endif // defined(PROJECT_ENABLE_LIBEVENT)
|
#endif // defined(PROJECT_ENABLE_LIBEVENT)
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_LIBSODIUM)
|
||||||
|
#include "sodium.h"
|
||||||
|
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_SDL)
|
#if defined(PROJECT_ENABLE_SDL)
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "SDL_gamecontroller.h"
|
#include "SDL_gamecontroller.h"
|
||||||
#include "SDL_joystick.h"
|
#include "SDL_joystick.h"
|
||||||
#endif // defined(PROJECT_ENABLE_SDL)
|
#endif // defined(PROJECT_ENABLE_SDL)
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_LIBSODIUM)
|
|
||||||
#include "sodium.h"
|
|
||||||
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
|
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_SQLITE)
|
#if defined(PROJECT_ENABLE_SQLITE)
|
||||||
#include "sqlite3.h"
|
#include "sqlite3.h"
|
||||||
#endif // defined(PROJECT_ENABLE_SQLITE)
|
#endif // defined(PROJECT_ENABLE_SQLITE)
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_VLC)
|
||||||
|
#include <vlc/vlc.h>
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
[[nodiscard]] inline auto get_libvlc_error_msg() -> std::string {
|
||||||
|
const auto *msg = libvlc_errmsg();
|
||||||
|
return msg == nullptr ? "none" : msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vlc_deleter final {
|
||||||
|
void operator()(libvlc_instance_t *inst) {
|
||||||
|
if (inst != nullptr) {
|
||||||
|
libvlc_release(inst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using vlc_t = std::unique_ptr<libvlc_instance_t, vlc_deleter>;
|
||||||
|
|
||||||
|
struct vlc_media_deleter final {
|
||||||
|
void operator()(libvlc_media_t *media) {
|
||||||
|
if (media != nullptr) {
|
||||||
|
libvlc_media_release(media);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using vlc_media_t = std::unique_ptr<libvlc_media_t, vlc_media_deleter>;
|
||||||
|
|
||||||
|
struct vlc_media_list_deleter final {
|
||||||
|
void operator()(libvlc_media_list_t *media_list) {
|
||||||
|
if (media_list != nullptr) {
|
||||||
|
libvlc_media_list_release(media_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using vlc_media_list_t =
|
||||||
|
std::unique_ptr<libvlc_media_list_t, vlc_media_list_deleter>;
|
||||||
|
|
||||||
|
struct vlc_string_deleter final {
|
||||||
|
void operator()(char *str) {
|
||||||
|
if (str != nullptr) {
|
||||||
|
libvlc_free(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
using vlc_string_t = std::unique_ptr<char, vlc_string_deleter>;
|
||||||
|
#endif // defined(__cplusplus)
|
||||||
|
#endif // defined(PROJECT_ENABLE_VLC)
|
||||||
|
|
||||||
#if !defined(fstat64)
|
#if !defined(fstat64)
|
||||||
#define fstat64 fstat
|
#define fstat64 fstat
|
||||||
#endif // !defined(fstat64)
|
#endif // !defined(fstat64)
|
||||||
|
@ -34,7 +34,7 @@ class encrypting_reader final {
|
|||||||
public:
|
public:
|
||||||
encrypting_reader(std::string_view file_name, std::string_view source_path,
|
encrypting_reader(std::string_view file_name, std::string_view source_path,
|
||||||
stop_type &stop_requested, std::string_view token,
|
stop_type &stop_requested, std::string_view token,
|
||||||
std::optional<std::string_view> relative_parent_path,
|
std::optional<std::string> relative_parent_path,
|
||||||
std::size_t error_return = 0U);
|
std::size_t error_return = 0U);
|
||||||
|
|
||||||
encrypting_reader(std::string_view encrypted_file_path,
|
encrypting_reader(std::string_view encrypted_file_path,
|
||||||
|
@ -46,6 +46,12 @@ inline auto generate_key(
|
|||||||
default_create_hash<hash_t>()) -> hash_t;
|
default_create_hash<hash_t>()) -> hash_t;
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_BOOST)
|
#if defined(PROJECT_ENABLE_BOOST)
|
||||||
|
[[nodiscard]] auto decrypt_file_name(std::string_view encryption_token,
|
||||||
|
std::string &file_name) -> bool;
|
||||||
|
|
||||||
|
[[nodiscard]] auto decrypt_file_path(std::string_view encryption_token,
|
||||||
|
std::string &file_path) -> bool;
|
||||||
|
|
||||||
template <typename result_t, typename arr_t, std::size_t arr_size>
|
template <typename result_t, typename arr_t, std::size_t arr_size>
|
||||||
[[nodiscard]] inline auto decrypt_data(const std::array<arr_t, arr_size> &key,
|
[[nodiscard]] inline auto decrypt_data(const std::array<arr_t, arr_size> &key,
|
||||||
const unsigned char *buffer,
|
const unsigned char *buffer,
|
||||||
|
@ -25,31 +25,106 @@
|
|||||||
#include "utils/config.hpp"
|
#include "utils/config.hpp"
|
||||||
|
|
||||||
#include "utils/path.hpp"
|
#include "utils/path.hpp"
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace repertory::utils::file {
|
namespace repertory::utils::file {
|
||||||
struct i_file {
|
#if defined(PROJECT_ENABLE_LIBDSM)
|
||||||
|
[[nodiscard]] auto
|
||||||
|
smb_create_and_validate_relative_path(std::string_view smb_path,
|
||||||
|
std::string_view rel_path) -> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
smb_create_relative_path(std::string_view smb_path) -> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
smb_create_search_path(std::string_view smb_path) -> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
smb_create_smb_path(std::string_view smb_path,
|
||||||
|
std::string_view rel_path) -> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
smb_get_parent_path(std::string_view smb_path) -> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] auto smb_get_root_path(std::string_view smb_path) -> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] auto smb_get_unc_path(std::string_view smb_path) -> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] auto smb_get_uri_path(std::string_view smb_path) -> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] auto smb_get_uri_path(std::string_view smb_path,
|
||||||
|
std::string_view user,
|
||||||
|
std::string_view password) -> std::string;
|
||||||
|
|
||||||
|
[[nodiscard]] auto smb_parent_is_same(std::string_view smb_path1,
|
||||||
|
std::string_view smb_path2) -> bool;
|
||||||
|
#endif // defined(PROJECT_ENABLE_LIBDSM)
|
||||||
|
|
||||||
|
struct 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;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto exists() const -> bool = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto get_path() const -> std::string = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto
|
||||||
|
get_time(time_types type) const -> std::uint64_t = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto is_directory_item() const -> bool = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto move_to(std::string_view new_path) -> bool = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto move_to(std::wstring_view new_path) -> bool {
|
||||||
|
return move_to(utils::string::to_utf8(new_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto remove() -> bool = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
[[nodiscard]] virtual operator bool() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
i_fs_item() noexcept = default;
|
||||||
|
|
||||||
|
i_fs_item(const i_fs_item &) noexcept = default;
|
||||||
|
|
||||||
|
i_fs_item(i_fs_item &&) noexcept = default;
|
||||||
|
|
||||||
|
auto operator=(i_fs_item &&) noexcept -> i_fs_item & = default;
|
||||||
|
|
||||||
|
auto operator=(const i_fs_item &) noexcept -> i_fs_item & = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct i_file : public i_fs_item {
|
||||||
|
using fs_file_t = std::unique_ptr<i_file>;
|
||||||
|
|
||||||
virtual ~i_file() = default;
|
virtual ~i_file() = default;
|
||||||
|
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto exists() const -> bool = 0;
|
|
||||||
|
|
||||||
virtual void flush() const = 0;
|
virtual void flush() const = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_handle() const -> native_handle = 0;
|
[[nodiscard]] virtual auto get_handle() const -> native_handle = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_path() const -> std::string = 0;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_read_buffer_size() const -> std::uint32_t = 0;
|
[[nodiscard]] virtual auto get_read_buffer_size() const -> std::uint32_t = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] auto is_directory_item() const -> bool override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] virtual auto is_read_only() const -> bool = 0;
|
[[nodiscard]] virtual auto is_read_only() const -> bool = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto move_to(std::string_view new_path) -> bool = 0;
|
[[nodiscard]] virtual auto read(data_buffer &data, std::uint64_t offset,
|
||||||
|
std::size_t *total_read = nullptr) -> bool {
|
||||||
[[nodiscard]] virtual auto
|
return read(data.data(), data.size(), offset, total_read);
|
||||||
read(data_buffer &data, std::uint64_t offset,
|
}
|
||||||
std::size_t *total_read = nullptr) -> bool = 0;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto
|
||||||
read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
|
read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
|
||||||
@ -57,64 +132,59 @@ struct i_file {
|
|||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto
|
||||||
read_all(data_buffer &data, std::uint64_t offset,
|
read_all(data_buffer &data, std::uint64_t offset,
|
||||||
std::size_t *total_read = nullptr) -> bool = 0;
|
std::size_t *total_read = nullptr) -> bool;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto remove() -> bool = 0;
|
|
||||||
|
|
||||||
virtual auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t = 0;
|
virtual auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto size() const -> std::uint64_t = 0;
|
[[nodiscard]] virtual auto size() const -> std::uint64_t = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto truncate() -> bool = 0;
|
[[nodiscard]] virtual auto truncate() -> bool { return truncate(0U); }
|
||||||
|
|
||||||
[[nodiscard]] virtual auto truncate(std::size_t size) -> bool = 0;
|
[[nodiscard]] virtual auto truncate(std::size_t size) -> bool = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto
|
||||||
write(const data_buffer &data, std::uint64_t offset,
|
write(const data_buffer &data, std::uint64_t offset,
|
||||||
std::size_t *total_written = nullptr) -> bool = 0;
|
std::size_t *total_written = nullptr) -> bool {
|
||||||
|
return write(data.data(), data.size(), offset, total_written);
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] virtual auto
|
[[nodiscard]] virtual auto
|
||||||
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
|
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
|
||||||
std::size_t *total_written = nullptr) -> bool = 0;
|
std::size_t *total_written = nullptr) -> bool = 0;
|
||||||
|
|
||||||
public:
|
|
||||||
[[nodiscard]] virtual operator bool() const = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
i_file() noexcept = default;
|
i_file() noexcept = default;
|
||||||
|
|
||||||
i_file(const i_file &) noexcept = delete;
|
i_file(const i_file &) noexcept = default;
|
||||||
|
|
||||||
i_file(i_file &&) noexcept = delete;
|
i_file(i_file &&) noexcept = default;
|
||||||
|
|
||||||
auto operator=(i_file &&) noexcept -> i_file & = delete;
|
auto operator=(i_file &&) noexcept -> i_file & = default;
|
||||||
|
|
||||||
auto operator=(const i_file &) noexcept -> i_file & = delete;
|
auto operator=(const i_file &) noexcept -> i_file & = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
class file final : public i_file {
|
class file final : public i_file {
|
||||||
public:
|
public:
|
||||||
// [[nodiscard]] static auto
|
// [[nodiscard]] static auto
|
||||||
// attach_file(native_handle handle,
|
// attach_file(native_handle handle,
|
||||||
// bool read_only = false) -> std::unique_ptr<i_file>;
|
// bool read_only = false) -> fs_file_t;
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto open_file(std::string_view path,
|
||||||
open_file(std::string_view path,
|
bool read_only = false) -> fs_file_t;
|
||||||
bool read_only = false) -> std::unique_ptr<i_file>;
|
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto open_file(std::wstring_view path,
|
||||||
open_file(std::wstring_view path,
|
bool read_only = false) -> fs_file_t {
|
||||||
bool read_only = false) -> std::unique_ptr<i_file> {
|
|
||||||
return open_file(utils::string::to_utf8(path), read_only);
|
return open_file(utils::string::to_utf8(path), read_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto
|
||||||
open_or_create_file(std::string_view path,
|
open_or_create_file(std::string_view path,
|
||||||
bool read_only = false) -> std::unique_ptr<i_file>;
|
bool read_only = false) -> fs_file_t;
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto
|
||||||
open_or_create_file(std::wstring_view path,
|
open_or_create_file(std::wstring_view path,
|
||||||
bool read_only = false) -> std::unique_ptr<i_file> {
|
bool read_only = false) -> fs_file_t {
|
||||||
return open_or_create_file(utils::string::to_utf8(path), read_only);
|
return open_or_create_file(utils::string::to_utf8(path), read_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,23 +249,18 @@ public:
|
|||||||
return read_buffer_size;
|
return read_buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_time(time_types type) const -> std::uint64_t override;
|
||||||
|
|
||||||
[[nodiscard]] auto is_read_only() const -> bool override {
|
[[nodiscard]] auto is_read_only() const -> bool override {
|
||||||
return read_only_;
|
return read_only_;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
|
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto read(data_buffer &data, std::uint64_t offset,
|
|
||||||
std::size_t *total_read = nullptr) -> bool override;
|
|
||||||
|
|
||||||
[[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
|
[[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
|
||||||
std::uint64_t offset,
|
std::uint64_t offset,
|
||||||
std::size_t *total_read = nullptr) -> bool override;
|
std::size_t *total_read = nullptr) -> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
|
||||||
read_all(data_buffer &data, std::uint64_t offset,
|
|
||||||
std::size_t *total_read = nullptr) -> bool override;
|
|
||||||
|
|
||||||
[[nodiscard]] auto remove() -> bool override;
|
[[nodiscard]] auto remove() -> bool override;
|
||||||
|
|
||||||
auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t override {
|
auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t override {
|
||||||
@ -205,14 +270,8 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] auto size() const -> std::uint64_t override;
|
[[nodiscard]] auto size() const -> std::uint64_t override;
|
||||||
|
|
||||||
[[nodiscard]] auto truncate() -> bool override { return truncate(0U); }
|
|
||||||
|
|
||||||
[[nodiscard]] auto truncate(std::size_t size) -> bool override;
|
[[nodiscard]] auto truncate(std::size_t size) -> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
|
||||||
write(const data_buffer &data, std::uint64_t offset,
|
|
||||||
std::size_t *total_written = nullptr) -> bool override;
|
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto
|
||||||
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
|
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
|
||||||
std::size_t *total_written = nullptr) -> bool override;
|
std::size_t *total_written = nullptr) -> bool override;
|
||||||
@ -240,25 +299,25 @@ class thread_file final : public i_file {
|
|||||||
public:
|
public:
|
||||||
// [[nodiscard]] static auto
|
// [[nodiscard]] static auto
|
||||||
// attach_file(native_handle handle,
|
// attach_file(native_handle handle,
|
||||||
// bool read_only = false) -> std::unique_ptr<i_file>;
|
// bool read_only = false) -> fs_file_t;
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto attach_file(fs_file_t file) -> fs_file_t;
|
||||||
open_file(std::string_view path,
|
|
||||||
bool read_only = false) -> std::unique_ptr<i_file>;
|
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto open_file(std::string_view path,
|
||||||
open_file(std::wstring_view path,
|
bool read_only = false) -> fs_file_t;
|
||||||
bool read_only = false) -> std::unique_ptr<i_file> {
|
|
||||||
|
[[nodiscard]] static auto open_file(std::wstring_view path,
|
||||||
|
bool read_only = false) -> fs_file_t {
|
||||||
return open_file(utils::string::to_utf8(path), read_only);
|
return open_file(utils::string::to_utf8(path), read_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto
|
||||||
open_or_create_file(std::string_view path,
|
open_or_create_file(std::string_view path,
|
||||||
bool read_only = false) -> std::unique_ptr<i_file>;
|
bool read_only = false) -> fs_file_t;
|
||||||
|
|
||||||
[[nodiscard]] static auto
|
[[nodiscard]] static auto
|
||||||
open_or_create_file(std::wstring_view path,
|
open_or_create_file(std::wstring_view path,
|
||||||
bool read_only = false) -> std::unique_ptr<i_file> {
|
bool read_only = false) -> fs_file_t {
|
||||||
return open_or_create_file(utils::string::to_utf8(path), read_only);
|
return open_or_create_file(utils::string::to_utf8(path), read_only);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +330,7 @@ public:
|
|||||||
: file_(new file(utils::string::to_utf8(path))) {}
|
: file_(new file(utils::string::to_utf8(path))) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
thread_file(std::unique_ptr<i_file> file);
|
thread_file(fs_file_t file);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
thread_file(const thread_file &) = delete;
|
thread_file(const thread_file &) = delete;
|
||||||
@ -282,7 +341,7 @@ public:
|
|||||||
~thread_file() override { close(); }
|
~thread_file() override { close(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<i_file> file_;
|
fs_file_t file_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void close() override;
|
void close() override;
|
||||||
@ -303,23 +362,18 @@ 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 is_read_only() const -> bool override {
|
[[nodiscard]] auto is_read_only() const -> bool override {
|
||||||
return file_->is_read_only();
|
return file_->is_read_only();
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
|
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto read(data_buffer &data, std::uint64_t offset,
|
|
||||||
std::size_t *total_read = nullptr) -> bool override;
|
|
||||||
|
|
||||||
[[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
|
[[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
|
||||||
std::uint64_t offset,
|
std::uint64_t offset,
|
||||||
std::size_t *total_read = nullptr) -> bool override;
|
std::size_t *total_read = nullptr) -> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
|
||||||
read_all(data_buffer &data, std::uint64_t offset,
|
|
||||||
std::size_t *total_read = nullptr) -> bool override;
|
|
||||||
|
|
||||||
[[nodiscard]] auto remove() -> bool override;
|
[[nodiscard]] auto remove() -> bool override;
|
||||||
|
|
||||||
auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t override {
|
auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t override {
|
||||||
@ -328,14 +382,8 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] auto size() const -> std::uint64_t override;
|
[[nodiscard]] auto size() const -> std::uint64_t override;
|
||||||
|
|
||||||
[[nodiscard]] auto truncate() -> bool override { return truncate(0U); }
|
|
||||||
|
|
||||||
[[nodiscard]] auto truncate(std::size_t size) -> bool override;
|
[[nodiscard]] auto truncate(std::size_t size) -> bool override;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
|
||||||
write(const data_buffer &data, std::uint64_t offset,
|
|
||||||
std::size_t *total_written = nullptr) -> bool override;
|
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto
|
||||||
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
|
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
|
||||||
std::size_t *total_written = nullptr) -> bool override;
|
std::size_t *total_written = nullptr) -> bool override;
|
||||||
@ -356,6 +404,372 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct i_directory : public i_fs_item {
|
||||||
|
using fs_directory_t = std::unique_ptr<i_directory>;
|
||||||
|
using fs_file_t = i_file::fs_file_t;
|
||||||
|
|
||||||
|
virtual ~i_directory() = default;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto
|
||||||
|
count(bool recursive = false) const -> std::uint64_t = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto
|
||||||
|
create_directory(std::string_view path) const -> fs_directory_t = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto create_file(std::string_view file_name,
|
||||||
|
bool read_only) const -> fs_file_t = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] auto is_directory_item() const -> bool override { return true; }
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto
|
||||||
|
get_directory(std::string_view path) const -> fs_directory_t = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto
|
||||||
|
get_directories() const -> std::vector<fs_directory_t> = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto
|
||||||
|
get_file(std::string_view path) const -> fs_file_t = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto get_files() const -> std::vector<fs_file_t> = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto get_items() const -> std::vector<fs_item_t> = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto remove_recursively() -> bool = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto
|
||||||
|
size(bool recursive = false) const -> std::uint64_t = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
i_directory() noexcept = default;
|
||||||
|
|
||||||
|
i_directory(const i_directory &) noexcept = default;
|
||||||
|
|
||||||
|
i_directory(i_directory &&) noexcept = default;
|
||||||
|
|
||||||
|
auto operator=(i_directory &&) noexcept -> i_directory & = default;
|
||||||
|
|
||||||
|
auto operator=(const i_directory &) noexcept -> i_directory & = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class directory final : public i_directory {
|
||||||
|
public:
|
||||||
|
using directory_t = std::unique_ptr<directory>;
|
||||||
|
|
||||||
|
directory() noexcept = default;
|
||||||
|
|
||||||
|
directory(std::string_view path) : path_(utils::path::absolute(path)) {}
|
||||||
|
|
||||||
|
directory(std::wstring_view path)
|
||||||
|
: path_(utils::path::absolute(utils::string::to_utf8(path))) {}
|
||||||
|
|
||||||
|
directory(const directory &) noexcept = delete;
|
||||||
|
|
||||||
|
directory(directory &&move_dir) noexcept = default;
|
||||||
|
|
||||||
|
~directory() override = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string path_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
[[nodiscard]] auto
|
||||||
|
count(bool recursive = false) const -> std::uint64_t override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
create_directory(std::string_view path) const -> fs_directory_t override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_file(std::string_view file_name,
|
||||||
|
bool read_only) const -> fs_file_t override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto exists() const -> bool override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
get_directory(std::string_view path) const -> fs_directory_t override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
get_directories() const -> std::vector<fs_directory_t> override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
get_file(std::string_view path) const -> fs_file_t override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_files() const -> std::vector<fs_file_t> override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_items() const -> std::vector<fs_item_t> override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_path() const -> std::string override { return path_; }
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_time(time_types type) const -> std::uint64_t override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto remove() -> bool override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto remove_recursively() -> bool override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
size(bool recursive = false) const -> std::uint64_t override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
auto operator=(const directory &) noexcept -> directory & = delete;
|
||||||
|
|
||||||
|
auto operator=(directory &&move_dir) noexcept -> directory & = default;
|
||||||
|
|
||||||
|
[[nodiscard]] operator bool() const override { return exists(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_LIBDSM)
|
||||||
|
#define SMB_MOD_RW2 \
|
||||||
|
(SMB_MOD_READ | SMB_MOD_WRITE | SMB_MOD_READ_EXT | SMB_MOD_WRITE_EXT | \
|
||||||
|
SMB_MOD_READ_ATTR | SMB_MOD_WRITE_ATTR | SMB_MOD_READ_CTL)
|
||||||
|
|
||||||
|
class smb_file final : public i_file {
|
||||||
|
public:
|
||||||
|
smb_file() = default;
|
||||||
|
|
||||||
|
smb_file(std::uint64_t access_time, std::uint64_t creation_time,
|
||||||
|
std::optional<smb_fd> fd, std::uint64_t modified_time,
|
||||||
|
std::string path, smb_session_t session, std::string_view share_name,
|
||||||
|
smb_tid tid, std::uint64_t size, std::uint64_t write_time)
|
||||||
|
: access_time_(access_time),
|
||||||
|
creation_time_(creation_time),
|
||||||
|
fd_(std::move(fd)),
|
||||||
|
modified_time_(modified_time),
|
||||||
|
path_(std::move(path)),
|
||||||
|
session_(std::move(session)),
|
||||||
|
share_name_(share_name),
|
||||||
|
size_(size),
|
||||||
|
tid_(tid),
|
||||||
|
write_time_(write_time) {}
|
||||||
|
|
||||||
|
smb_file(const smb_file &) = delete;
|
||||||
|
|
||||||
|
smb_file(smb_file &&f) noexcept
|
||||||
|
: access_time_(f.access_time_),
|
||||||
|
creation_time_(f.creation_time_),
|
||||||
|
fd_(std::move(f.fd_)),
|
||||||
|
modified_time_(f.modified_time_),
|
||||||
|
path_(std::move(f.path_)),
|
||||||
|
read_buffer_size(f.get_read_buffer_size()),
|
||||||
|
read_only_(f.read_only_),
|
||||||
|
session_(std::move(f.session_)),
|
||||||
|
share_name_(std::move(f.share_name_)),
|
||||||
|
size_(f.size_),
|
||||||
|
tid_(f.tid_),
|
||||||
|
write_time_(f.write_time_) {}
|
||||||
|
|
||||||
|
~smb_file() override { close(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::uint64_t access_time_;
|
||||||
|
std::uint64_t creation_time_;
|
||||||
|
std::optional<smb_fd> fd_;
|
||||||
|
std::uint64_t modified_time_;
|
||||||
|
std::string path_;
|
||||||
|
std::atomic_uint32_t read_buffer_size{65536U};
|
||||||
|
bool read_only_;
|
||||||
|
smb_session_t session_;
|
||||||
|
std::string share_name_;
|
||||||
|
std::uint64_t size_;
|
||||||
|
smb_tid tid_;
|
||||||
|
std::uint64_t write_time_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void close() override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto exists() const -> bool override;
|
||||||
|
|
||||||
|
void flush() const override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_handle() const -> native_handle override {
|
||||||
|
return INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_path() const -> std::string override { return path_; }
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_read_buffer_size() const -> std::uint32_t override {
|
||||||
|
return read_buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_time(time_types type) const -> std::uint64_t override {
|
||||||
|
switch (type) {
|
||||||
|
case time_types::access:
|
||||||
|
return access_time_;
|
||||||
|
|
||||||
|
case time_types::creation:
|
||||||
|
return creation_time_;
|
||||||
|
|
||||||
|
case time_types::modified:
|
||||||
|
return modified_time_;
|
||||||
|
|
||||||
|
case time_types::write:
|
||||||
|
return write_time_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_unc_path() const -> std::string {
|
||||||
|
return smb_get_unc_path(path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_uri_path() const -> std::string {
|
||||||
|
return smb_get_uri_path(path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
get_uri_path(std::string_view user,
|
||||||
|
std::string_view password) const -> std::string {
|
||||||
|
return smb_get_uri_path(path_, user, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto is_read_only() const -> bool override {
|
||||||
|
return read_only_;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto open(bool read_only) -> bool;
|
||||||
|
|
||||||
|
[[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
|
||||||
|
std::uint64_t offset,
|
||||||
|
std::size_t *total_read = nullptr) -> bool override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto remove() -> bool override;
|
||||||
|
|
||||||
|
auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t override {
|
||||||
|
read_buffer_size = size;
|
||||||
|
return read_buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto size() const -> std::uint64_t override { return size_; }
|
||||||
|
|
||||||
|
[[nodiscard]] auto truncate(std::size_t size) -> bool override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
|
||||||
|
std::size_t *total_written = nullptr) -> bool override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
auto operator=(const smb_file &) noexcept -> smb_file & = delete;
|
||||||
|
|
||||||
|
auto operator=(smb_file &&move_file) noexcept -> smb_file & {
|
||||||
|
if (this != &move_file) {
|
||||||
|
access_time_ = move_file.access_time_;
|
||||||
|
creation_time_ = move_file.creation_time_;
|
||||||
|
fd_ = std::move(move_file.fd_);
|
||||||
|
modified_time_ = move_file.modified_time_;
|
||||||
|
path_ = std::move(move_file.path_);
|
||||||
|
read_buffer_size = move_file.get_read_buffer_size();
|
||||||
|
read_only_ = move_file.read_only_;
|
||||||
|
session_ = std::move(move_file.session_);
|
||||||
|
share_name_ = std::move(move_file.share_name_);
|
||||||
|
size_ = move_file.size_;
|
||||||
|
tid_ = move_file.tid_;
|
||||||
|
write_time_ = move_file.write_time_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] operator bool() const override { return fd_.has_value(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class smb_directory final : public i_directory {
|
||||||
|
public:
|
||||||
|
using smb_directory_t = std::unique_ptr<smb_directory>;
|
||||||
|
|
||||||
|
[[nodiscard]] static auto
|
||||||
|
open(std::string_view host, std::string_view user, std::string_view password,
|
||||||
|
std::string_view share_name) -> smb_directory_t;
|
||||||
|
|
||||||
|
[[nodiscard]] static auto
|
||||||
|
open(std::wstring_view host, std::wstring_view user,
|
||||||
|
std::wstring_view password,
|
||||||
|
std::wstring_view share_name) -> smb_directory_t;
|
||||||
|
|
||||||
|
public:
|
||||||
|
smb_directory() noexcept = default;
|
||||||
|
|
||||||
|
smb_directory(const smb_directory &) noexcept = delete;
|
||||||
|
|
||||||
|
smb_directory(smb_directory &&) noexcept = default;
|
||||||
|
|
||||||
|
~smb_directory() override = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
smb_directory(std::string path, smb_session_t session,
|
||||||
|
std::string_view share_name, smb_tid tid)
|
||||||
|
: path_(std::move(path)),
|
||||||
|
session_(std::move(session)),
|
||||||
|
share_name_(share_name),
|
||||||
|
tid_(tid) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string path_{};
|
||||||
|
smb_session_t session_{};
|
||||||
|
std::string share_name_{};
|
||||||
|
smb_tid tid_{};
|
||||||
|
|
||||||
|
public:
|
||||||
|
[[nodiscard]] auto
|
||||||
|
count(bool recursive = false) const -> std::uint64_t override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
create_directory(std::string_view path) const -> fs_directory_t override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto create_file(std::string_view file_name,
|
||||||
|
bool read_only) const -> fs_file_t override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto exists() const -> bool override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
get_directory(std::string_view path) const -> fs_directory_t override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
get_directories() const -> std::vector<fs_directory_t> override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
get_file(std::string_view path) const -> fs_file_t override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_files() const -> std::vector<fs_file_t> override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_items() const -> std::vector<fs_item_t> override;
|
||||||
|
|
||||||
|
[[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_unc_path() const -> std::string {
|
||||||
|
return smb_get_unc_path(path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_uri_path() const -> std::string {
|
||||||
|
return smb_get_uri_path(path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
get_uri_path(std::string_view user,
|
||||||
|
std::string_view password) const -> std::string {
|
||||||
|
return smb_get_uri_path(path_, user, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto remove() -> bool override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto remove_recursively() -> bool override;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
size(bool recursive = false) const -> std::uint64_t override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
auto operator=(const smb_directory &) noexcept -> smb_directory & = delete;
|
||||||
|
|
||||||
|
auto
|
||||||
|
operator=(smb_directory &&move_dir) noexcept -> smb_directory & = default;
|
||||||
|
|
||||||
|
[[nodiscard]] operator bool() const override { return session_ != nullptr; }
|
||||||
|
};
|
||||||
|
#endif // defined(PROJECT_ENABLE_LIBDSM)
|
||||||
|
|
||||||
[[nodiscard]] auto create_directories(std::string_view path) -> bool;
|
[[nodiscard]] auto create_directories(std::string_view path) -> bool;
|
||||||
|
|
||||||
[[nodiscard]] auto create_directories(std::wstring_view path) -> bool;
|
[[nodiscard]] auto create_directories(std::wstring_view path) -> bool;
|
||||||
|
@ -171,8 +171,7 @@ const std::size_t encrypting_reader::encrypted_chunk_size_ =
|
|||||||
encrypting_reader::encrypting_reader(
|
encrypting_reader::encrypting_reader(
|
||||||
std::string_view file_name, std::string_view source_path,
|
std::string_view file_name, std::string_view source_path,
|
||||||
stop_type &stop_requested, std::string_view token,
|
stop_type &stop_requested, std::string_view token,
|
||||||
std::optional<std::string_view> relative_parent_path,
|
std::optional<std::string> relative_parent_path, std::size_t error_return)
|
||||||
std::size_t error_return)
|
|
||||||
: key_(utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
: key_(utils::encryption::generate_key<utils::encryption::hash_256_t>(
|
||||||
token)),
|
token)),
|
||||||
stop_requested_(stop_requested),
|
stop_requested_(stop_requested),
|
||||||
|
67
support/src/utils/encryption.cpp
Normal file
67
support/src/utils/encryption.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
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/encryption.hpp"
|
||||||
|
|
||||||
|
#include "utils/collection.hpp"
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
|
||||||
|
|
||||||
|
namespace repertory::utils::encryption {
|
||||||
|
auto decrypt_file_path(std::string_view encryption_token,
|
||||||
|
std::string &file_path) -> bool {
|
||||||
|
std::string decrypted_file_path{};
|
||||||
|
for (const auto &part : std::filesystem::path(file_path)) {
|
||||||
|
auto file_name = part.string();
|
||||||
|
if (file_name == "/") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = decrypt_file_name(encryption_token, file_name);
|
||||||
|
if (not res) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
decrypted_file_path += '/' + file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_path = decrypted_file_path;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto decrypt_file_name(std::string_view encryption_token,
|
||||||
|
std::string &file_name) -> bool {
|
||||||
|
data_buffer buffer;
|
||||||
|
if (not utils::collection::from_hex_string(file_name, buffer)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_name.clear();
|
||||||
|
if (not utils::encryption::decrypt_data(encryption_token, buffer,
|
||||||
|
file_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace repertory::utils::encryption
|
||||||
|
|
||||||
|
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined (PROJECT_ENABLE_BOOST)
|
@ -77,10 +77,43 @@ namespace {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace repertory::utils::file {
|
namespace repertory::utils::file {
|
||||||
|
auto i_file::read_all(data_buffer &data, std::uint64_t offset,
|
||||||
|
std::size_t *total_read) -> bool {
|
||||||
|
data_buffer buffer;
|
||||||
|
buffer.resize(get_read_buffer_size());
|
||||||
|
|
||||||
|
std::size_t current_read{};
|
||||||
|
while (read(reinterpret_cast<unsigned char *>(buffer.data()),
|
||||||
|
buffer.size() * sizeof(data_buffer::value_type), offset,
|
||||||
|
¤t_read)) {
|
||||||
|
if (total_read != nullptr) {
|
||||||
|
*total_read += current_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_read != 0U) {
|
||||||
|
offset += current_read;
|
||||||
|
|
||||||
|
data.insert(
|
||||||
|
data.end(), buffer.begin(),
|
||||||
|
std::next(buffer.begin(),
|
||||||
|
static_cast<std::int64_t>(
|
||||||
|
current_read / sizeof(data_buffer::value_type))));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto create_directories(std::string_view path) -> bool {
|
auto create_directories(std::string_view path) -> bool {
|
||||||
|
if (is_directory(path)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
return is_directory(path) ||
|
return (::SHCreateDirectory(
|
||||||
(::SHCreateDirectory(
|
|
||||||
nullptr,
|
nullptr,
|
||||||
utils::string::from_utf8(utils::path::absolute(path)).c_str()) ==
|
utils::string::from_utf8(utils::path::absolute(path)).c_str()) ==
|
||||||
ERROR_SUCCESS);
|
ERROR_SUCCESS);
|
||||||
@ -332,4 +365,170 @@ auto write_json_file(std::wstring_view path,
|
|||||||
}
|
}
|
||||||
#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)
|
||||||
|
static constexpr const auto validate_smb_path =
|
||||||
|
[](std::string_view path) -> bool {
|
||||||
|
return (not utils::string::begins_with(path, "///") &&
|
||||||
|
utils::string::begins_with(path, "//") &&
|
||||||
|
not utils::string::contains(path, " ") &&
|
||||||
|
std::count(path.begin(), path.end(), '/') >= 3U);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto smb_create_smb_path(std::string_view smb_path,
|
||||||
|
std::string_view rel_path) -> std::string {
|
||||||
|
if (not validate_smb_path(smb_path)) {
|
||||||
|
throw std::runtime_error("invalid smb path|" + std::string{smb_path});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string path{rel_path};
|
||||||
|
utils::path::format_path(path, "/", "\\");
|
||||||
|
utils::string::left_trim(path, '/');
|
||||||
|
|
||||||
|
auto old_parts =
|
||||||
|
repertory::utils::string::split(smb_path.substr(2U), '/', false);
|
||||||
|
old_parts.erase(std::next(old_parts.begin(), 2U), old_parts.end());
|
||||||
|
|
||||||
|
auto new_parts = repertory::utils::string::split(path, '/', false);
|
||||||
|
old_parts.insert(old_parts.end(), new_parts.begin(), new_parts.end());
|
||||||
|
|
||||||
|
path = utils::string::join(old_parts, '/');
|
||||||
|
path = "//" + utils::path::format_path(path, "/", "\\");
|
||||||
|
|
||||||
|
if (not validate_smb_path(path)) {
|
||||||
|
throw std::runtime_error("invalid smb path|" + std::string{path});
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_create_and_validate_relative_path(
|
||||||
|
std::string_view smb_path, std::string_view path) -> std::string {
|
||||||
|
if (not validate_smb_path(smb_path)) {
|
||||||
|
throw std::runtime_error("invalid smb path|" + std::string{smb_path});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string dir_path;
|
||||||
|
if (utils::string::begins_with(path, "//")) {
|
||||||
|
if (not utils::file::smb_parent_is_same(smb_path, path)) {
|
||||||
|
throw std::runtime_error("failed to validate path|" +
|
||||||
|
std::string{smb_path} + '|' + std::string{path} +
|
||||||
|
"|parent paths are not the same");
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils::file::smb_create_relative_path(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils::file::smb_create_relative_path(std::string{smb_path} + '/' +
|
||||||
|
std::string{path});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_create_relative_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});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string path{smb_path};
|
||||||
|
utils::path::format_path(path, "\\", "/");
|
||||||
|
utils::string::left_trim(path, '\\');
|
||||||
|
|
||||||
|
auto parts = repertory::utils::string::split(path, '\\', false);
|
||||||
|
parts.erase(parts.begin(), std::next(parts.begin(), 2U));
|
||||||
|
return "\\" + utils::string::join(parts, '\\');
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_create_search_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});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string path{smb_path};
|
||||||
|
utils::string::left_trim(path, '/');
|
||||||
|
|
||||||
|
auto parts = repertory::utils::string::split(path, '/', false);
|
||||||
|
parts.erase(parts.begin(), std::next(parts.begin(), 2U));
|
||||||
|
|
||||||
|
auto search_path = repertory::utils::string::join(parts, '\\');
|
||||||
|
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);
|
||||||
|
if (parts.size() > 2U) {
|
||||||
|
parts.erase(std::prev(parts.end()), parts.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto parent_smb_path = "//" + utils::string::join(parts, '/');
|
||||||
|
if (not validate_smb_path(parent_smb_path)) {
|
||||||
|
throw std::runtime_error("invalid smb path|" + 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);
|
||||||
|
if (parts.size() > 2U) {
|
||||||
|
parts.erase(std::next(parts.begin(), 2U), parts.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
return "//" + utils::string::join(parts, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_get_unc_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});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string unc_path{smb_path};
|
||||||
|
utils::path::format_path(unc_path, "\\", "/");
|
||||||
|
return '\\' + unc_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_get_uri_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});
|
||||||
|
}
|
||||||
|
|
||||||
|
return "smb:" + std::string{smb_path};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_get_uri_path(std::string_view smb_path, std::string_view user,
|
||||||
|
std::string_view password) -> std::string {
|
||||||
|
if (not validate_smb_path(smb_path)) {
|
||||||
|
throw std::runtime_error("invalid smb path|" + std::string{smb_path});
|
||||||
|
}
|
||||||
|
|
||||||
|
return "smb://" + std::string{user} + ':' + std::string{password} + '@' +
|
||||||
|
std::string{smb_path.substr(2U)};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_parent_is_same(std::string_view smb_path1,
|
||||||
|
std::string_view smb_path2) -> bool {
|
||||||
|
if (not(validate_smb_path(smb_path1) && validate_smb_path(smb_path2))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto parts1 = utils::string::split(smb_path1.substr(2U), "/", false);
|
||||||
|
auto parts2 = utils::string::split(smb_path2.substr(2U), "/", false);
|
||||||
|
if (parts1.size() < 2U || parts2.size() < 2U) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parts2.at(1U).empty() || parts1.at(1U).empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::equal(parts1.begin(), std::next(parts1.begin(), 2U),
|
||||||
|
parts2.begin());
|
||||||
|
}
|
||||||
|
#endif // defined(PROJECT_ENABLE_LIBDSM)
|
||||||
} // namespace repertory::utils::file
|
} // namespace repertory::utils::file
|
||||||
|
@ -19,35 +19,37 @@
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include "test_common.hpp"
|
#include "utils/file.hpp"
|
||||||
|
|
||||||
#include "types/repertory.hpp"
|
namespace repertory::utils::file {
|
||||||
#include "utils/encrypting_reader.hpp"
|
auto directory::count(bool recursive) const -> std::uint64_t { return 0U; }
|
||||||
#include "utils/file_utils.hpp"
|
|
||||||
#include "utils/path.hpp"
|
|
||||||
|
|
||||||
namespace repertory {
|
auto directory::create_directory(std::string_view path) const
|
||||||
/* TEST(encrypting_reader, get_encrypted_file_name) {
|
-> fs_directory_t {}
|
||||||
const auto source_file_name = get_source_file_name();
|
|
||||||
ASSERT_TRUE(utils::file::retry_delete_file(source_file_name));
|
|
||||||
|
|
||||||
const auto token = std::string("moose");
|
auto directory::exists() const -> bool { return false; }
|
||||||
auto &source_file = create_random_file(source_file_name, 1024UL);
|
|
||||||
EXPECT_TRUE(source_file != nullptr);
|
|
||||||
if (source_file) {
|
|
||||||
stop_type stop_requested = false;
|
|
||||||
utils::encryption::encrypting_reader reader(
|
|
||||||
"test.dat", source_file_name, stop_requested, token, std::nullopt);
|
|
||||||
|
|
||||||
auto file_name = reader.get_encrypted_file_name();
|
auto directory::get_directory(std::string_view path) const -> fs_directory_t {
|
||||||
|
return {};
|
||||||
EXPECT_EQ(api_error::success,
|
|
||||||
utils::encryption::decrypt_file_name(token, file_name));
|
|
||||||
EXPECT_STREQ("test.dat", file_name.c_str());
|
|
||||||
|
|
||||||
source_file->close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_TRUE(utils::file::retry_delete_file(source_file_name));
|
auto directory::get_directories() const -> std::vector<fs_directory_t> {
|
||||||
} */
|
return {};
|
||||||
} // namespace repertory
|
}
|
||||||
|
|
||||||
|
auto directory::get_time(time_types type) const -> std::uint64_t {}
|
||||||
|
|
||||||
|
auto directory::get_file(std::string_view path) const -> fs_file_t {}
|
||||||
|
|
||||||
|
auto directory::get_files() const -> std::vector<fs_file_t> { return {}; }
|
||||||
|
|
||||||
|
auto directory::get_items() const -> std::vector<fs_item_t> { return {}; }
|
||||||
|
|
||||||
|
auto directory::move_to(std::string_view new_path) -> bool { return false; }
|
||||||
|
|
||||||
|
auto directory::remove() -> bool { return false; }
|
||||||
|
|
||||||
|
auto directory::remove_recursively() -> bool { return false; }
|
||||||
|
|
||||||
|
auto directory::size(bool recursive) const -> std::uint64_t { return 0U; }
|
||||||
|
} // namespace repertory::utils::file
|
@ -25,10 +25,11 @@
|
|||||||
#include "utils/error.hpp"
|
#include "utils/error.hpp"
|
||||||
#include "utils/path.hpp"
|
#include "utils/path.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
|
#include "utils/time.hpp"
|
||||||
|
|
||||||
namespace repertory::utils::file {
|
namespace repertory::utils::file {
|
||||||
// auto file::attach_file(native_handle handle,
|
// auto file::attach_file(native_handle handle,
|
||||||
// bool read_only) -> std::unique_ptr<i_file> {
|
// bool read_only) -> fs_file_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__),
|
||||||
// };
|
// };
|
||||||
@ -64,7 +65,7 @@ namespace repertory::utils::file {
|
|||||||
// auto *ptr = fdopen(handle, read_only ? "rb" : "rb+");
|
// auto *ptr = fdopen(handle, read_only ? "rb" : "rb+");
|
||||||
// #endif // defined(_WIN32)
|
// #endif // defined(_WIN32)
|
||||||
//
|
//
|
||||||
// return std::unique_ptr<i_file>(new file{
|
// return fs_file_t(new file{
|
||||||
// file_t{ptr},
|
// file_t{ptr},
|
||||||
// utils::path::absolute(path),
|
// utils::path::absolute(path),
|
||||||
// read_only,
|
// read_only,
|
||||||
@ -90,8 +91,7 @@ void file::open() {
|
|||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto file::open_file(std::string_view path,
|
auto file::open_file(std::string_view path, bool read_only) -> fs_file_t {
|
||||||
bool read_only) -> std::unique_ptr<i_file> {
|
|
||||||
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__),
|
||||||
};
|
};
|
||||||
@ -101,7 +101,7 @@ auto file::open_file(std::string_view path,
|
|||||||
utils::path::absolute(path),
|
utils::path::absolute(path),
|
||||||
read_only,
|
read_only,
|
||||||
};
|
};
|
||||||
auto new_file = std::unique_ptr<i_file>(ptr);
|
auto new_file = fs_file_t(ptr);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ptr->open();
|
ptr->open();
|
||||||
@ -115,7 +115,7 @@ auto file::open_file(std::string_view path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto file::open_or_create_file(std::string_view path,
|
auto file::open_or_create_file(std::string_view path,
|
||||||
bool read_only) -> std::unique_ptr<i_file> {
|
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)
|
||||||
@ -188,6 +188,68 @@ auto file::get_handle() const -> native_handle {
|
|||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto file::get_time(time_types type) const -> std::uint64_t {
|
||||||
|
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 defined(_WIN32)
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
struct stat st {};
|
||||||
|
stat(path_.c_str(), &st);
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case time_types::access:
|
||||||
|
#if defined(_WIN32)
|
||||||
|
break;
|
||||||
|
#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)
|
||||||
|
break;
|
||||||
|
#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)
|
||||||
|
break;
|
||||||
|
#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)
|
||||||
|
break;
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
auto file::move_to(std::string_view path) -> bool {
|
auto file::move_to(std::string_view path) -> bool {
|
||||||
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__),
|
||||||
@ -233,59 +295,6 @@ auto file::move_to(std::string_view path) -> bool {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
data_buffer buffer;
|
|
||||||
buffer.resize(read_buffer_size);
|
|
||||||
|
|
||||||
std::size_t current_read{};
|
|
||||||
while (read(reinterpret_cast<unsigned char *>(buffer.data()),
|
|
||||||
buffer.size() * sizeof(data_buffer::value_type), offset,
|
|
||||||
¤t_read)) {
|
|
||||||
if (total_read != nullptr) {
|
|
||||||
*total_read += current_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current_read != 0U) {
|
|
||||||
offset += current_read;
|
|
||||||
|
|
||||||
data.insert(
|
|
||||||
data.end(), buffer.begin(),
|
|
||||||
std::next(buffer.begin(),
|
|
||||||
static_cast<std::int64_t>(
|
|
||||||
current_read / sizeof(data_buffer::value_type))));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto file::read(data_buffer &data, std::uint64_t offset,
|
|
||||||
std::size_t *total_read) -> bool {
|
|
||||||
#if defined(_WIN32)
|
|
||||||
recur_mutex_lock lock{*mtx_};
|
|
||||||
#endif // defined(_WIN32)
|
|
||||||
|
|
||||||
std::size_t bytes_read{};
|
|
||||||
auto ret =
|
|
||||||
read(reinterpret_cast<unsigned char *>(data.data()),
|
|
||||||
data.size() * sizeof(data_buffer::value_type), offset, &bytes_read);
|
|
||||||
data.resize(bytes_read / sizeof(data_buffer::value_type));
|
|
||||||
|
|
||||||
if (total_read != nullptr) {
|
|
||||||
(*total_read) = bytes_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto file::read(unsigned char *data, std::size_t to_read, 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 {
|
std::size_t *total_read) -> bool {
|
||||||
static constexpr const std::string_view function_name{
|
static constexpr const std::string_view function_name{
|
||||||
@ -466,11 +475,4 @@ auto file::size() const -> std::uint64_t {
|
|||||||
|
|
||||||
return 0U;
|
return 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto file::write(const data_buffer &data, std::uint64_t offset,
|
|
||||||
std::size_t *total_written) -> bool {
|
|
||||||
return write(reinterpret_cast<const unsigned char *>(data.data()),
|
|
||||||
data.size() * sizeof(data_buffer::value_type), offset,
|
|
||||||
total_written);
|
|
||||||
}
|
|
||||||
} // namespace repertory::utils::file
|
} // namespace repertory::utils::file
|
||||||
|
610
support/src/utils/file_smb_directory.cpp
Normal file
610
support/src/utils/file_smb_directory.cpp
Normal file
@ -0,0 +1,610 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
|
||||||
|
#include "utils/error.hpp"
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_LIBDSM)
|
||||||
|
namespace repertory::utils::file {
|
||||||
|
auto smb_directory::open(std::string_view host, std::string_view user,
|
||||||
|
std::string_view password,
|
||||||
|
std::string_view share_name) -> smb_directory_t {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
smb_session_t session{smb_session_new(), smb_session_deleter};
|
||||||
|
netbios_ns_t ns{netbios_ns_new()};
|
||||||
|
|
||||||
|
sockaddr_in addr{};
|
||||||
|
|
||||||
|
auto res = netbios_ns_resolve(
|
||||||
|
ns.get(), std::string{host}.c_str(), NETBIOS_FILESERVER,
|
||||||
|
reinterpret_cast<std::uint32_t *>(&addr.sin_addr.s_addr));
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
res = inet_pton(AF_INET, std::string{host}.c_str(), &addr.sin_addr);
|
||||||
|
if (res != 1) {
|
||||||
|
throw std::runtime_error("failed to resolve host|" + std::string{host} +
|
||||||
|
'|' + std::to_string(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = smb_session_connect(session.get(), std::string{host}.c_str(),
|
||||||
|
static_cast<std::uint32_t>(addr.sin_addr.s_addr),
|
||||||
|
SMB_TRANSPORT_TCP);
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to connect to host|" +
|
||||||
|
std::string{host} + '|' + std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
smb_session_set_creds(session.get(), std::string{host}.c_str(),
|
||||||
|
std::string{user}.c_str(),
|
||||||
|
std::string{password}.c_str());
|
||||||
|
res = smb_session_login(session.get());
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to logon to host|" + std::string{host} +
|
||||||
|
'|' + std::string{user} + '|' +
|
||||||
|
std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
smb_tid tid{};
|
||||||
|
res =
|
||||||
|
smb_tree_connect(session.get(), std::string{share_name}.c_str(), &tid);
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to connect to share|" +
|
||||||
|
std::string{share_name} + '|' +
|
||||||
|
std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
return smb_directory_t{
|
||||||
|
new smb_directory{
|
||||||
|
"//" + std::string{host} + "/" + std::string{share_name},
|
||||||
|
session,
|
||||||
|
share_name,
|
||||||
|
tid,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::open(std::wstring_view host, std::wstring_view user,
|
||||||
|
std::wstring_view password,
|
||||||
|
std::wstring_view share_name) -> smb_directory_t {
|
||||||
|
return open(utils::string::to_utf8(host), utils::string::to_utf8(user),
|
||||||
|
utils::string::to_utf8(password),
|
||||||
|
utils::string::to_utf8(share_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::count(bool recursive) const -> std::uint64_t {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
smb_stat_list_t list{
|
||||||
|
smb_find(session_.get(), tid_, smb_create_search_path(path_).c_str())};
|
||||||
|
auto count = smb_stat_list_count(list.get());
|
||||||
|
|
||||||
|
if (not recursive) {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("failed to get directory count recursively|" +
|
||||||
|
path_ + "|not implemented");
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::create_directory(std::string_view path) const
|
||||||
|
-> fs_directory_t {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dir = get_directory(path);
|
||||||
|
if (dir) {
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = smb_directory_create(
|
||||||
|
session_.get(), tid_,
|
||||||
|
smb_create_and_validate_relative_path(path_, path).c_str());
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to create directory|" + path_ + '/' +
|
||||||
|
std::string{path} + '|' + std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_directory(path);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::create_file(std::string_view file_name,
|
||||||
|
bool read_only) const -> fs_file_t {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto fs_file = get_file(file_name);
|
||||||
|
if (fs_file) {
|
||||||
|
if (not dynamic_cast<smb_file *>(fs_file.get())->open(read_only)) {
|
||||||
|
throw std::runtime_error("failed to open existing file|" +
|
||||||
|
std::string{file_name});
|
||||||
|
}
|
||||||
|
|
||||||
|
return fs_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rel_path = smb_create_and_validate_relative_path(path_, file_name);
|
||||||
|
|
||||||
|
smb_fd fd{};
|
||||||
|
auto res =
|
||||||
|
smb_fopen(session_.get(), tid_, rel_path.c_str(), SMB_MOD_RW, &fd);
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
smb_fclose(session_.get(), fd);
|
||||||
|
|
||||||
|
res = smb_fopen(session_.get(), tid_, rel_path.c_str(),
|
||||||
|
read_only ? SMB_MOD_RO : SMB_MOD_RW2, &fd);
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
smb_stat_t st{smb_fstat(session_.get(), tid_, rel_path.c_str())};
|
||||||
|
if (not st) {
|
||||||
|
smb_fclose(session_.get(), fd);
|
||||||
|
throw std::runtime_error("failed to stat file|" + rel_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_unique<smb_file>(
|
||||||
|
smb_stat_get(st.get(), SMB_STAT_ATIME),
|
||||||
|
smb_stat_get(st.get(), SMB_STAT_CTIME), fd,
|
||||||
|
smb_stat_get(st.get(), SMB_STAT_MTIME),
|
||||||
|
smb_create_smb_path(path_, std::string{rel_path}), session_,
|
||||||
|
share_name_, smb_stat_get(st.get(), SMB_STAT_SIZE), tid_,
|
||||||
|
smb_stat_get(st.get(), SMB_STAT_WTIME));
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto smb_directory::exists() const -> bool {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
smb_stat_t st{smb_fstat(session_.get(), tid_,
|
||||||
|
smb_create_relative_path(path_).c_str())};
|
||||||
|
if (not st) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return smb_stat_get(st.get(), SMB_STAT_ISDIR) != 0U;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::get_directory(std::string_view path) const
|
||||||
|
-> fs_directory_t {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rel_path = smb_create_and_validate_relative_path(path_, path);
|
||||||
|
smb_stat_t st{smb_fstat(session_.get(), tid_, rel_path.c_str())};
|
||||||
|
if (not st) {
|
||||||
|
throw std::runtime_error("failed to stat directory|" + rel_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_dir{smb_stat_get(st.get(), SMB_STAT_ISDIR) != 0U};
|
||||||
|
if (not is_dir) {
|
||||||
|
throw std::runtime_error("path is not a directory|" + rel_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return smb_directory_t{
|
||||||
|
new smb_directory{
|
||||||
|
smb_create_smb_path(path_, rel_path),
|
||||||
|
session_,
|
||||||
|
share_name_,
|
||||||
|
tid_,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::get_directories() const -> std::vector<fs_directory_t> {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
smb_stat_list_t list{
|
||||||
|
smb_find(session_.get(), tid_, smb_create_search_path(path_).c_str())};
|
||||||
|
if (not list) {
|
||||||
|
throw std::runtime_error("failed to get directory list|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<fs_directory_t> ret{};
|
||||||
|
|
||||||
|
auto count = smb_stat_list_count(list.get());
|
||||||
|
for (std::size_t idx = 0U; idx < count; ++idx) {
|
||||||
|
auto st = smb_stat_list_at(list.get(), idx);
|
||||||
|
|
||||||
|
bool is_dir{smb_stat_get(st, SMB_STAT_ISDIR) != 0U};
|
||||||
|
if (not is_dir) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name{smb_stat_name(st)};
|
||||||
|
if (name == "." || name == "..") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.emplace_back(smb_directory_t{
|
||||||
|
new smb_directory{
|
||||||
|
smb_create_smb_path(path_, name),
|
||||||
|
session_,
|
||||||
|
share_name_,
|
||||||
|
tid_,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::get_file(std::string_view path) const -> fs_file_t {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rel_path = smb_create_and_validate_relative_path(path_, path);
|
||||||
|
smb_stat_t st{smb_fstat(session_.get(), tid_, rel_path.c_str())};
|
||||||
|
if (not st) {
|
||||||
|
throw std::runtime_error("failed to stat file|" + rel_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_dir{smb_stat_get(st.get(), SMB_STAT_ISDIR) != 0U};
|
||||||
|
if (is_dir) {
|
||||||
|
throw std::runtime_error("path is not a file|" + rel_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_unique<smb_file>(
|
||||||
|
smb_stat_get(st.get(), SMB_STAT_ATIME),
|
||||||
|
smb_stat_get(st.get(), SMB_STAT_CTIME), std::nullopt,
|
||||||
|
smb_stat_get(st.get(), SMB_STAT_MTIME),
|
||||||
|
smb_create_smb_path(path_, std::string{rel_path}), session_,
|
||||||
|
share_name_, smb_stat_get(st.get(), SMB_STAT_SIZE), tid_,
|
||||||
|
smb_stat_get(st.get(), SMB_STAT_WTIME));
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::get_files() const -> std::vector<fs_file_t> {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
smb_stat_list_t list{
|
||||||
|
smb_find(session_.get(), tid_, smb_create_search_path(path_).c_str())};
|
||||||
|
if (not list) {
|
||||||
|
throw std::runtime_error("failed to get file list|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<fs_file_t> ret{};
|
||||||
|
|
||||||
|
auto count = smb_stat_list_count(list.get());
|
||||||
|
for (std::size_t idx = 0U; idx < count; ++idx) {
|
||||||
|
auto st = smb_stat_list_at(list.get(), idx);
|
||||||
|
bool is_dir{smb_stat_get(st, SMB_STAT_ISDIR) != 0U};
|
||||||
|
if (is_dir) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name{smb_stat_name(st)};
|
||||||
|
ret.emplace_back(std::make_unique<smb_file>(
|
||||||
|
smb_stat_get(st, SMB_STAT_ATIME), smb_stat_get(st, SMB_STAT_CTIME),
|
||||||
|
std::nullopt, smb_stat_get(st, SMB_STAT_MTIME),
|
||||||
|
smb_create_smb_path(path_, name), session_, share_name_,
|
||||||
|
smb_stat_get(st, SMB_STAT_SIZE), tid_,
|
||||||
|
smb_stat_get(st, SMB_STAT_WTIME)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::get_items() const -> std::vector<fs_item_t> {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
smb_stat_list_t list{
|
||||||
|
smb_find(session_.get(), tid_, smb_create_search_path(path_).c_str())};
|
||||||
|
if (not list) {
|
||||||
|
throw std::runtime_error("failed to get item list|" + path_);
|
||||||
|
}
|
||||||
|
std::vector<fs_item_t> ret{};
|
||||||
|
|
||||||
|
auto count = smb_stat_list_count(list.get());
|
||||||
|
for (std::size_t idx = 0U; idx < count; ++idx) {
|
||||||
|
auto st = smb_stat_list_at(list.get(), idx);
|
||||||
|
|
||||||
|
bool is_dir{smb_stat_get(st, SMB_STAT_ISDIR) != 0U};
|
||||||
|
std::string name{smb_stat_name(st)};
|
||||||
|
|
||||||
|
if (is_dir) {
|
||||||
|
if (name == "." || name == "..") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.emplace_back(smb_directory_t{
|
||||||
|
new smb_directory{
|
||||||
|
path_ + '/' + name,
|
||||||
|
session_,
|
||||||
|
share_name_,
|
||||||
|
tid_,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.emplace_back(std::make_unique<smb_file>(
|
||||||
|
smb_stat_get(st, SMB_STAT_ATIME), smb_stat_get(st, SMB_STAT_CTIME),
|
||||||
|
std::nullopt, smb_stat_get(st, SMB_STAT_MTIME),
|
||||||
|
smb_create_smb_path(path_, name), session_, share_name_, tid_,
|
||||||
|
smb_stat_get(st, SMB_STAT_SIZE), smb_stat_get(st, SMB_STAT_WTIME)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::get_time(time_types type) const -> std::uint64_t {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rel_path = smb_create_relative_path(path_);
|
||||||
|
smb_stat_t st{smb_fstat(session_.get(), tid_, rel_path.c_str())};
|
||||||
|
if (not st) {
|
||||||
|
throw std::runtime_error("failed to stat directory|" + rel_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case time_types::access:
|
||||||
|
return smb_stat_get(st.get(), SMB_STAT_ATIME);
|
||||||
|
|
||||||
|
case time_types::creation:
|
||||||
|
return smb_stat_get(st.get(), SMB_STAT_CTIME);
|
||||||
|
|
||||||
|
case time_types::modified:
|
||||||
|
return smb_stat_get(st.get(), SMB_STAT_MTIME);
|
||||||
|
|
||||||
|
case time_types::write:
|
||||||
|
return smb_stat_get(st.get(), SMB_STAT_WTIME);
|
||||||
|
}
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::move_to(std::string_view new_path) -> bool {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("failed to move directory|" + path_ + '|' +
|
||||||
|
std::string{new_path} + "|not implemented");
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::remove() -> bool {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = smb_directory_rm(session_.get(), tid_,
|
||||||
|
smb_create_relative_path(path_).c_str());
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to remove directory|" + path_ + '|' +
|
||||||
|
std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::remove_recursively() -> bool {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("failed to remove directory recursively|" + path_ +
|
||||||
|
"|not implemented");
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_directory::size(bool /* recursive */) const -> std::uint64_t {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::runtime_error("failed to get directory size|" + path_ +
|
||||||
|
"|not implemented");
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} // namespace repertory::utils::file
|
||||||
|
|
||||||
|
#endif // defined(PROJECT_ENABLE_LIBDSM)
|
308
support/src/utils/file_smb_file.cpp
Normal file
308
support/src/utils/file_smb_file.cpp
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
|
||||||
|
#include "utils/error.hpp"
|
||||||
|
#include "utils/string.hpp"
|
||||||
|
|
||||||
|
#if defined(PROJECT_ENABLE_LIBDSM)
|
||||||
|
|
||||||
|
namespace repertory::utils::file {
|
||||||
|
void smb_file::close() {
|
||||||
|
if (fd_.has_value()) {
|
||||||
|
smb_fclose(session_.get(), *fd_);
|
||||||
|
fd_.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_file::exists() const -> bool {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not session_) {
|
||||||
|
throw std::runtime_error("session not found|" + path_);
|
||||||
|
}
|
||||||
|
|
||||||
|
smb_stat_t st{smb_fstat(session_.get(), tid_,
|
||||||
|
smb_create_relative_path(path_).c_str())};
|
||||||
|
if (not st) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return smb_stat_get(st.get(), SMB_STAT_ISDIR) == 0U;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void smb_file::flush() const {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
throw std::runtime_error("failed to flush file|" + path_ +
|
||||||
|
"|not implemented");
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_file::move_to(std::string_view new_path) -> bool {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (utils::string::begins_with(new_path, "//")) {
|
||||||
|
throw std::runtime_error("failed to move file|" + path_ + '|' +
|
||||||
|
std::string{new_path} +
|
||||||
|
"|new path must be in same share");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto from_path = smb_create_relative_path(path_);
|
||||||
|
auto to_path = smb_create_and_validate_relative_path(
|
||||||
|
utils::string::begins_with(new_path, "/") ? smb_get_root_path(path_)
|
||||||
|
: smb_get_parent_path(path_),
|
||||||
|
new_path);
|
||||||
|
|
||||||
|
auto was_open{false};
|
||||||
|
if (fd_.has_value()) {
|
||||||
|
close();
|
||||||
|
was_open = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = smb_tree_connect(session_.get(), share_name_.c_str(), &tid_);
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to connect to share|" + share_name_ +
|
||||||
|
'|' + std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
res = smb_file_mv(session_.get(), tid_, from_path.c_str(), to_path.c_str());
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to move file|" + path_ + '|' +
|
||||||
|
from_path + '|' + to_path + '|' +
|
||||||
|
std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
path_ = smb_create_smb_path(path_, to_path);
|
||||||
|
if (was_open) {
|
||||||
|
return open(read_only_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_file::open(bool read_only) -> bool {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (fd_.has_value()) {
|
||||||
|
if (read_only == read_only_) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rel_path = smb_create_relative_path(path_);
|
||||||
|
|
||||||
|
auto res = smb_tree_connect(session_.get(), share_name_.c_str(), &tid_);
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to connect to share|" + share_name_ +
|
||||||
|
'|' + std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
smb_fd fd{};
|
||||||
|
res = smb_fopen(session_.get(), tid_, rel_path.c_str(),
|
||||||
|
read_only ? SMB_MOD_RO : SMB_MOD_RW2, &fd);
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to open file|" + path_ + '|' + rel_path +
|
||||||
|
'|' + utils::string::from_bool(read_only) + '|' +
|
||||||
|
std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
fd_ = fd;
|
||||||
|
read_only_ = read_only;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_file::read(unsigned char *data, std::size_t to_read,
|
||||||
|
std::uint64_t offset, std::size_t *total_read) -> bool {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not fd_.has_value()) {
|
||||||
|
throw std::runtime_error("failed to read file|" + path_ +
|
||||||
|
"|file not open");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = smb_fseek(session_.get(), *fd_, static_cast<off_t>(offset),
|
||||||
|
SMB_SEEK_SET);
|
||||||
|
if (res == -1) {
|
||||||
|
throw std::runtime_error("failed to seek file|" + path_ + '|' +
|
||||||
|
std::to_string(offset) + '|' +
|
||||||
|
std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
res = smb_fread(session_.get(), *fd_, data, to_read);
|
||||||
|
if (res == -1) {
|
||||||
|
throw std::runtime_error("failed to read file|" + path_ + '|' +
|
||||||
|
std::to_string(to_read) + '|' +
|
||||||
|
std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total_read != nullptr) {
|
||||||
|
(*total_read) = static_cast<std::uint64_t>(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_file::remove() -> bool {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
close();
|
||||||
|
|
||||||
|
auto res = smb_tree_connect(session_.get(), share_name_.c_str(), &tid_);
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
throw std::runtime_error("failed to connect to share|" + share_name_ +
|
||||||
|
'|' + std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rel_path = smb_create_relative_path(path_);
|
||||||
|
res = smb_file_rm(session_.get(), tid_, rel_path.c_str());
|
||||||
|
if (res != DSM_SUCCESS) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"failed to remove file|" + path_ + '|' + rel_path + '|' +
|
||||||
|
std::to_string(res) + '|' +
|
||||||
|
std::to_string(smb_session_get_nt_status(session_.get())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_file::truncate(std::size_t size) -> bool {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
throw std::runtime_error("failed to truncate file|" + path_ + '|' +
|
||||||
|
std::to_string(size) + "|not implemented");
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto smb_file::write(const unsigned char *data, std::size_t to_write,
|
||||||
|
std::size_t offset, std::size_t *total_written) -> bool {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (not fd_.has_value()) {
|
||||||
|
throw std::runtime_error("failed to write file|" + path_ +
|
||||||
|
"|file not open");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = smb_fseek(session_.get(), *fd_, static_cast<off_t>(offset),
|
||||||
|
SMB_SEEK_SET);
|
||||||
|
if (res == -1) {
|
||||||
|
throw std::runtime_error("failed to seek file|" + path_ + '|' +
|
||||||
|
std::to_string(offset) + '|' +
|
||||||
|
std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
res = smb_fwrite(session_.get(), *fd_, const_cast<unsigned char *>(data),
|
||||||
|
to_write);
|
||||||
|
if (res == -1) {
|
||||||
|
throw std::runtime_error("failed to write file|" + path_ + '|' +
|
||||||
|
std::to_string(to_write) + '|' +
|
||||||
|
std::to_string(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total_written != nullptr) {
|
||||||
|
(*total_written) = static_cast<std::uint64_t>(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} // namespace repertory::utils::file
|
||||||
|
|
||||||
|
#endif // defined(PROJECT_ENABLE_LIBDSM)
|
@ -23,29 +23,26 @@
|
|||||||
|
|
||||||
namespace repertory::utils::file {
|
namespace repertory::utils::file {
|
||||||
// auto thread_file::attach_file(native_handle handle,
|
// auto thread_file::attach_file(native_handle handle,
|
||||||
// bool read_only) -> std::unique_ptr<i_file> {}
|
// bool read_only) -> fs_file_t {}
|
||||||
|
|
||||||
|
auto thread_file::attach_file(fs_file_t file) -> fs_file_t {}
|
||||||
|
|
||||||
auto thread_file::open_file(std::string_view path,
|
auto thread_file::open_file(std::string_view path,
|
||||||
bool read_only) -> std::unique_ptr<i_file> {}
|
bool read_only) -> fs_file_t {}
|
||||||
|
|
||||||
auto thread_file::open_or_create_file(std::string_view path, bool read_only)
|
auto thread_file::open_or_create_file(std::string_view path,
|
||||||
-> std::unique_ptr<i_file> {}
|
bool read_only) -> fs_file_t {}
|
||||||
|
|
||||||
thread_file::thread_file(std::unique_ptr<i_file> file)
|
thread_file::thread_file(fs_file_t file) : file_(std::move(file)) {}
|
||||||
: file_(std::move(file)) {}
|
|
||||||
|
|
||||||
void thread_file::close() {}
|
void thread_file::close() {}
|
||||||
|
|
||||||
void thread_file::flush() const {}
|
void thread_file::flush() const {}
|
||||||
|
|
||||||
|
auto thread_file::get_time(time_types type) const -> std::uint64_t {}
|
||||||
|
|
||||||
auto thread_file::move_to(std::string_view path) -> bool {}
|
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,
|
auto thread_file::read(unsigned char *data, std::size_t to_read,
|
||||||
std::uint64_t offset, std::size_t *total_read) -> bool {}
|
std::uint64_t offset, std::size_t *total_read) -> bool {}
|
||||||
|
|
||||||
@ -58,7 +55,4 @@ auto thread_file::write(const unsigned char *data, std::size_t to_write,
|
|||||||
std::size_t *total_written) -> bool {}
|
std::size_t *total_written) -> bool {}
|
||||||
|
|
||||||
auto thread_file::size() const -> std::uint64_t {}
|
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
|
} // namespace repertory::utils::file
|
||||||
|
250
support/test/src/utils/collection_test.cpp
Normal file
250
support/test/src/utils/collection_test.cpp
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
/*
|
||||||
|
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 "test.hpp"
|
||||||
|
|
||||||
|
namespace repertory {
|
||||||
|
TEST(utils_collection, excludes) {
|
||||||
|
auto data = {"cow", "moose", "dog", "chicken"};
|
||||||
|
EXPECT_FALSE(utils::collection::excludes(data, "chicken"));
|
||||||
|
EXPECT_FALSE(utils::collection::excludes(data, "cow"));
|
||||||
|
EXPECT_FALSE(utils::collection::excludes(data, "dog"));
|
||||||
|
EXPECT_FALSE(utils::collection::excludes(data, "moose"));
|
||||||
|
EXPECT_TRUE(utils::collection::excludes(data, "mouse"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(utils_collection, includes) {
|
||||||
|
auto data = {"cow", "moose", "dog", "chicken"};
|
||||||
|
EXPECT_FALSE(utils::collection::includes(data, "mice"));
|
||||||
|
EXPECT_TRUE(utils::collection::includes(data, "chicken"));
|
||||||
|
EXPECT_TRUE(utils::collection::includes(data, "cow"));
|
||||||
|
EXPECT_TRUE(utils::collection::includes(data, "dog"));
|
||||||
|
EXPECT_TRUE(utils::collection::includes(data, "moose"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(utils_collection, from_hex_string) {
|
||||||
|
{
|
||||||
|
auto data = "0xABCDEF10";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_TRUE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_EQ(4U, val.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = " 0xABCDEF10 ";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_TRUE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_EQ(4U, val.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = "ABCDEF10";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_TRUE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_EQ(4U, val.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = "ACDEF";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_TRUE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_EQ(3U, val.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = " ACDEF ";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_TRUE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_EQ(3U, val.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = "";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_TRUE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_TRUE(val.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = L"0xABCDEF10";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_TRUE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_EQ(4U, val.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = L" 0xABCDEF10 ";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_TRUE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_EQ(4U, val.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = L"ABCDEF10";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_TRUE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_EQ(4U, val.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = L"ACDEF";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_TRUE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_EQ(3U, val.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = L" ACDEF ";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_TRUE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_EQ(3U, val.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = L"";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_TRUE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_TRUE(val.empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(utils_collection, from_hex_string_fails) {
|
||||||
|
{
|
||||||
|
auto data = "ABCDEF1Z";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_FALSE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_TRUE(val.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = "ABC DEF1";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_FALSE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_TRUE(val.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = "0x";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_FALSE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_TRUE(val.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = " 0x ";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_FALSE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_TRUE(val.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = L"ABCDEF1Z";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_FALSE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_TRUE(val.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = L"ABC DEF1";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_FALSE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_TRUE(val.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = L"0x";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_FALSE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_TRUE(val.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data = L" 0x";
|
||||||
|
std::vector<std::uint8_t> val{};
|
||||||
|
EXPECT_FALSE(utils::collection::from_hex_string(data, val));
|
||||||
|
EXPECT_TRUE(val.empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(utils_collection, to_hex_string) {
|
||||||
|
{
|
||||||
|
std::array<std::int8_t, 2U> col{
|
||||||
|
static_cast<std::int8_t>(0xFF),
|
||||||
|
static_cast<std::int8_t>(0xEE),
|
||||||
|
};
|
||||||
|
|
||||||
|
auto str = utils::collection::to_hex_string(col);
|
||||||
|
EXPECT_STREQ("ffee", str.c_str());
|
||||||
|
|
||||||
|
auto w_str = utils::collection::to_hex_wstring(col);
|
||||||
|
EXPECT_STREQ(L"ffee", w_str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::array<std::uint8_t, 2U> col{
|
||||||
|
static_cast<std::uint8_t>(0xFF),
|
||||||
|
static_cast<std::uint8_t>(0xEE),
|
||||||
|
};
|
||||||
|
|
||||||
|
auto str = utils::collection::to_hex_string(col);
|
||||||
|
EXPECT_STREQ("ffee", str.c_str());
|
||||||
|
|
||||||
|
auto w_str = utils::collection::to_hex_wstring(col);
|
||||||
|
EXPECT_STREQ(L"ffee", w_str.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(utils_collection, remove_element) {
|
||||||
|
{
|
||||||
|
std::vector<std::uint8_t> col{
|
||||||
|
static_cast<std::uint8_t>(0xFF),
|
||||||
|
static_cast<std::uint8_t>(0xEE),
|
||||||
|
};
|
||||||
|
|
||||||
|
utils::collection::remove_element(col, 0xFF);
|
||||||
|
EXPECT_EQ(1U, col.size());
|
||||||
|
EXPECT_EQ(static_cast<std::uint8_t>(0xEE), col.at(0U));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::vector<std::uint8_t> col{
|
||||||
|
static_cast<std::uint8_t>(0xFF),
|
||||||
|
static_cast<std::uint8_t>(0xEE),
|
||||||
|
};
|
||||||
|
|
||||||
|
utils::collection::remove_element(col, 0xEE);
|
||||||
|
EXPECT_EQ(1U, col.size());
|
||||||
|
EXPECT_EQ(static_cast<std::uint8_t>(0xFF), col.at(0U));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::vector<std::uint8_t> col{
|
||||||
|
static_cast<std::uint8_t>(0xFF),
|
||||||
|
static_cast<std::uint8_t>(0xEE),
|
||||||
|
};
|
||||||
|
|
||||||
|
utils::collection::remove_element(col, 0xEF);
|
||||||
|
EXPECT_EQ(2U, col.size());
|
||||||
|
EXPECT_EQ(static_cast<std::uint8_t>(0xFF), col.at(0U));
|
||||||
|
EXPECT_EQ(static_cast<std::uint8_t>(0xEE), col.at(1U));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace repertory
|
@ -22,6 +22,7 @@
|
|||||||
#include "test.hpp"
|
#include "test.hpp"
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
|
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
TEST(utils_encrypting_reader, read_file_data) {
|
TEST(utils_encrypting_reader, read_file_data) {
|
||||||
const auto token = std::string("moose");
|
const auto token = std::string("moose");
|
||||||
|
@ -24,8 +24,8 @@
|
|||||||
#if defined(PROJECT_ENABLE_LIBSODIUM)
|
#if defined(PROJECT_ENABLE_LIBSODIUM)
|
||||||
|
|
||||||
namespace repertory {
|
namespace repertory {
|
||||||
static const std::string token{"moose"};
|
static constexpr const std::string_view token{"moose"};
|
||||||
static const std::wstring token_w{L"moose"};
|
static constexpr const std::wstring_view token_w{L"moose"};
|
||||||
|
|
||||||
TEST(utils_encryption, generate_key) {
|
TEST(utils_encryption, generate_key) {
|
||||||
auto key1 =
|
auto key1 =
|
||||||
@ -244,6 +244,39 @@ TEST(utils_encryption, decryption_failure) {
|
|||||||
std::string data;
|
std::string data;
|
||||||
EXPECT_FALSE(utils::encryption::decrypt_data(key, result, data));
|
EXPECT_FALSE(utils::encryption::decrypt_data(key, result, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(utils_encryption, decrypt_file_name) {
|
||||||
|
auto &source_file = test::create_random_file(
|
||||||
|
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
|
||||||
|
EXPECT_TRUE(source_file);
|
||||||
|
if (source_file) {
|
||||||
|
stop_type stop_requested{false};
|
||||||
|
utils::encryption::encrypting_reader reader(
|
||||||
|
"test.dat", source_file.get_path(), stop_requested, token,
|
||||||
|
std::nullopt);
|
||||||
|
|
||||||
|
auto file_name = reader.get_encrypted_file_name();
|
||||||
|
|
||||||
|
EXPECT_EQ(true, utils::encryption::decrypt_file_name(token, file_name));
|
||||||
|
EXPECT_STREQ("test.dat", file_name.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(utils_encryption, decrypt_file_path) {
|
||||||
|
auto &source_file = test::create_random_file(
|
||||||
|
8U * utils::encryption::encrypting_reader::get_data_chunk_size());
|
||||||
|
EXPECT_TRUE(source_file);
|
||||||
|
if (source_file) {
|
||||||
|
stop_type stop_requested{false};
|
||||||
|
utils::encryption::encrypting_reader reader(
|
||||||
|
"test.dat", source_file.get_path(), stop_requested, token, "moose/cow");
|
||||||
|
|
||||||
|
auto file_path = reader.get_encrypted_file_path();
|
||||||
|
|
||||||
|
EXPECT_EQ(true, utils::encryption::decrypt_file_path(token, file_path));
|
||||||
|
EXPECT_STREQ("/moose/cow/test.dat", file_path.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif // defined(PROJECT_ENABLE_BOOST)
|
#endif // defined(PROJECT_ENABLE_BOOST)
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
|
||||||
|
@ -140,4 +140,125 @@ TEST(utils_file, read_and_write_json_file_encrypted) {
|
|||||||
}
|
}
|
||||||
#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)
|
||||||
|
TEST(utils_file, smb_create_smb_path) {
|
||||||
|
auto path = "//server/share";
|
||||||
|
auto rel_path = "test/test.txt";
|
||||||
|
auto smb_path = utils::file::smb_create_smb_path(path, rel_path);
|
||||||
|
EXPECT_STREQ("//server/share/test/test.txt", smb_path.c_str());
|
||||||
|
|
||||||
|
rel_path = "/test/test.txt";
|
||||||
|
smb_path = utils::file::smb_create_smb_path(path, rel_path);
|
||||||
|
EXPECT_STREQ("//server/share/test/test.txt", smb_path.c_str());
|
||||||
|
|
||||||
|
rel_path = "test\\test.txt";
|
||||||
|
smb_path = utils::file::smb_create_smb_path(path, rel_path);
|
||||||
|
EXPECT_STREQ("//server/share/test/test.txt", smb_path.c_str());
|
||||||
|
|
||||||
|
rel_path = "\\test\\test.txt";
|
||||||
|
smb_path = utils::file::smb_create_smb_path(path, rel_path);
|
||||||
|
EXPECT_STREQ("//server/share/test/test.txt", smb_path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(utils_file, smb_create_relative_path) {
|
||||||
|
auto path = "//server/share/test.txt";
|
||||||
|
auto rel_path = utils::file::smb_create_relative_path(path);
|
||||||
|
EXPECT_STREQ("\\test.txt", rel_path.c_str());
|
||||||
|
|
||||||
|
path = "//server/share/test";
|
||||||
|
rel_path = utils::file::smb_create_relative_path(path);
|
||||||
|
EXPECT_STREQ("\\test", rel_path.c_str());
|
||||||
|
|
||||||
|
path = "//server/share/test/";
|
||||||
|
rel_path = utils::file::smb_create_relative_path(path);
|
||||||
|
EXPECT_STREQ("\\test", rel_path.c_str());
|
||||||
|
|
||||||
|
path = "//server/share/test/";
|
||||||
|
rel_path = utils::file::smb_create_relative_path(path);
|
||||||
|
EXPECT_STREQ("\\test", rel_path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(utils_file, smb_create_search_path) {
|
||||||
|
auto path = "//server/share";
|
||||||
|
auto search_path = utils::file::smb_create_search_path(path);
|
||||||
|
EXPECT_STREQ("\\*", search_path.c_str());
|
||||||
|
|
||||||
|
path = "//server/share/";
|
||||||
|
search_path = utils::file::smb_create_search_path(path);
|
||||||
|
EXPECT_STREQ("\\*", search_path.c_str());
|
||||||
|
|
||||||
|
path = "//server/share/folder";
|
||||||
|
search_path = utils::file::smb_create_search_path(path);
|
||||||
|
EXPECT_STREQ("\\folder\\*", search_path.c_str());
|
||||||
|
|
||||||
|
path = "//server/share/folder/";
|
||||||
|
search_path = utils::file::smb_create_search_path(path);
|
||||||
|
EXPECT_STREQ("\\folder\\*", search_path.c_str());
|
||||||
|
|
||||||
|
path = "//server/share/folder/next";
|
||||||
|
search_path = utils::file::smb_create_search_path(path);
|
||||||
|
EXPECT_STREQ("\\folder\\next\\*", search_path.c_str());
|
||||||
|
|
||||||
|
path = "//server/share/folder/next/";
|
||||||
|
search_path = utils::file::smb_create_search_path(path);
|
||||||
|
EXPECT_STREQ("\\folder\\next\\*", search_path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(utils_file, smb_parent_is_same) {
|
||||||
|
auto path1 = "//server/share";
|
||||||
|
auto path2 = "//server/share";
|
||||||
|
EXPECT_TRUE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
|
||||||
|
path1 = "//server/share/";
|
||||||
|
path2 = "//server/share/";
|
||||||
|
EXPECT_TRUE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
|
||||||
|
path1 = "//server/share/one";
|
||||||
|
path2 = "//server/share/two";
|
||||||
|
EXPECT_TRUE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(utils_file, smb_parent_is_not_same) {
|
||||||
|
auto path1 = "server/share";
|
||||||
|
auto path2 = "//server/share";
|
||||||
|
EXPECT_FALSE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
|
||||||
|
path1 = "server/share/";
|
||||||
|
path2 = "server/share/";
|
||||||
|
EXPECT_FALSE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
|
||||||
|
path1 = "//server1/share/one";
|
||||||
|
path2 = "//server/share/two";
|
||||||
|
EXPECT_FALSE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
|
||||||
|
path1 = "//server/share";
|
||||||
|
path2 = "//server/share2";
|
||||||
|
EXPECT_FALSE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
|
||||||
|
path1 = "//server/share/";
|
||||||
|
path2 = "//server/share2/";
|
||||||
|
EXPECT_FALSE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
|
||||||
|
path1 = "//server/share/one";
|
||||||
|
path2 = "//server/share2/two";
|
||||||
|
EXPECT_FALSE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
|
||||||
|
path1 = "//server";
|
||||||
|
path2 = "//server/share/two";
|
||||||
|
EXPECT_FALSE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
|
||||||
|
path1 = "//server/";
|
||||||
|
path2 = "//server/";
|
||||||
|
EXPECT_FALSE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
|
||||||
|
path1 = "//server";
|
||||||
|
path2 = "//server";
|
||||||
|
EXPECT_FALSE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
|
||||||
|
path1 = "// server/cow";
|
||||||
|
path2 = "// server/cow";
|
||||||
|
EXPECT_FALSE(utils::file::smb_parent_is_same(path1, path2));
|
||||||
|
}
|
||||||
|
#endif // defined(PROJECT_ENABLE_LIBDSM)
|
||||||
} // namespace repertory
|
} // namespace repertory
|
||||||
|
Reference in New Issue
Block a user