diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d955e9..dc98a34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,9 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) else() set(SOLANACEAE_CLAMAV_STANDALONE OFF) endif() +message("II SOLANACEAE_CLAMAV_STANDALONE " ${SOLANACEAE_CLAMAV_STANDALONE}) + +option(SOLANACEAE_CLAMAV_BUILD_PLUGINS "Build the clamav plugins" ${SOLANACEAE_CLAMAV_STANDALONE}) if (SOLANACEAE_CLAMAV_STANDALONE) set(CMAKE_POSITION_INDEPENDENT_CODE ON) @@ -61,5 +64,8 @@ endif() # cmake setup end add_subdirectory(./src) -#add_subdirectory(./plugins) + +if (SOLANACEAE_CLAMAV_BUILD_PLUGINS) + add_subdirectory(./plugins) +endif() diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index bc28eaf..d9270b6 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -1,6 +1,5 @@ cmake_minimum_required(VERSION 3.24 FATAL_ERROR) - add_subdirectory(./solanaceae_util) #add_subdirectory(./solanaceae_plugin) @@ -9,6 +8,8 @@ add_subdirectory(./entt) add_subdirectory(./solanaceae_contact) add_subdirectory(./solanaceae_message3) +include(FetchContent) + # TODO: move to clamav.cmake find_package(PkgConfig QUIET) if (PKG_CONFIG_FOUND) @@ -21,7 +22,6 @@ if (PKG_CONFIG_FOUND) endif() if (NOT TARGET EXT_SOL::libclamav) - include(FetchContent) set(ENABLE_LIBCLAMAV_ONLY ON) set(ENABLE_APP OFF) set(ENABLE_TESTS OFF) @@ -38,3 +38,12 @@ if (NOT TARGET EXT_SOL::libclamav) add_library(EXT_SOL::libclamav ALIAS clamav) endif() +# TODO: rename when plugin lib is split +if (NOT TARGET solanaceae_plugin) + FetchContent_Declare(solanaceae_plugin + GIT_REPOSITORY https://github.com/Green-Sky/solanaceae_plugin.git + GIT_TAG master + ) + FetchContent_MakeAvailable(solanaceae_plugin) +endif() + diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt new file mode 100644 index 0000000..3c7aba4 --- /dev/null +++ b/plugins/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.24 FATAL_ERROR) + +add_library(plugin_clamav SHARED + ./plugin_clamav_module.cpp +) +target_compile_features(plugin_clamav PUBLIC cxx_std_17) +target_link_libraries(plugin_clamav PUBLIC + solanaceae_clamav + solanaceae_plugin +) + diff --git a/plugins/plugin_clamav_module.cpp b/plugins/plugin_clamav_module.cpp new file mode 100644 index 0000000..604085b --- /dev/null +++ b/plugins/plugin_clamav_module.cpp @@ -0,0 +1,65 @@ +#include + +#include +#include + +#include +#include + +#define RESOLVE_INSTANCE(x) static_cast(solana_api->resolveInstance(#x)) +#define PROVIDE_INSTANCE(x, p, v) solana_api->provideInstance(#x, p, static_cast(v)) + +static std::unique_ptr g_cavm = nullptr; + +extern "C" { + +SOLANA_PLUGIN_EXPORT const char* solana_plugin_get_name(void) { + return "ClamAVModule"; +} + +SOLANA_PLUGIN_EXPORT uint32_t solana_plugin_get_version(void) { + return SOLANA_PLUGIN_VERSION; +} + +SOLANA_PLUGIN_EXPORT uint32_t solana_plugin_start(struct SolanaAPI* solana_api) { + std::cout << "PLUGIN CAVM START()\n"; + + if (solana_api == nullptr) { + return 1; + } + + ConfigModelI* conf = nullptr; + + { // make sure required types are loaded + conf = RESOLVE_INSTANCE(ConfigModelI); + + if (conf == nullptr) { + std::cerr << "PLUGIN CAVM missing ConfigModelI\n"; + return 2; + } + } + + // static store, could be anywhere tho + // construct with fetched dependencies + g_cavm = std::make_unique(*conf); + + // register types + PROVIDE_INSTANCE(ClamAVModule, "ClamAVModule", g_cavm.get()); + + return 0; +} + +SOLANA_PLUGIN_EXPORT void solana_plugin_stop(void) { + std::cout << "PLUGIN CAVM STOP()\n"; + + g_cavm.reset(); +} + +SOLANA_PLUGIN_EXPORT void solana_plugin_tick(float delta) { + (void)delta; + //std::cout << "PLUGIN CAVM TICK()\n"; + //g_cavm->iterate(); +} + +} // extern C + diff --git a/src/solanaceae/clamav/clamav_module_async_wrapper.cpp b/src/solanaceae/clamav/clamav_module_async_wrapper.cpp index 7fd9e3f..6c0de02 100644 --- a/src/solanaceae/clamav/clamav_module_async_wrapper.cpp +++ b/src/solanaceae/clamav/clamav_module_async_wrapper.cpp @@ -1,5 +1,7 @@ #include "./clamav_module_async_wrapper.hpp" +#include + ClamAVModuleAsyncWrapper::ClamAVModuleAsyncWrapper(ClamAVModuleInterface& cavmi) : _cavmi(cavmi) { } @@ -7,6 +9,7 @@ std::future ClamAVModuleAsyncWrapper::scan return std::async( std::launch::async, [this](std::string inner_path) { + std::srand(5693); // TODO: optimize, clamav supports multi threading std::lock_guard lock_guard{_cavmi_mutex}; return _cavmi.scanFilePath(inner_path);