basic POC functionality established for peer module loading
							parent
							
								
									448dc0cdfd
								
							
						
					
					
						commit
						7b29824e40
					
				| 
						 | 
				
			
			@ -170,74 +170,7 @@ extern "C" {
 | 
			
		|||
 */
 | 
			
		||||
#define DPM_VERSION "0.1.0"
 | 
			
		||||
 | 
			
		||||
// If we're building in standalone mode, add support for standalone execution
 | 
			
		||||
// If we're building in standalone mode, include the standalone implementations
 | 
			
		||||
#ifdef BUILD_STANDALONE
 | 
			
		||||
 | 
			
		||||
// Declare, but don't define the standalone implementations
 | 
			
		||||
// These will be defined in the main file through the DPM_STANDALONE_IMPL macro
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Helper macro to create a standalone main function for modules
 | 
			
		||||
 *
 | 
			
		||||
 * This macro defines a main() function that initializes the module and
 | 
			
		||||
 * processes command-line arguments to execute commands directly.
 | 
			
		||||
 */
 | 
			
		||||
#define DPM_MODULE_STANDALONE_MAIN() \
 | 
			
		||||
extern "C" void dpm_log(int level, const char* message) { \
 | 
			
		||||
const char* level_str; \
 | 
			
		||||
switch (level) { \
 | 
			
		||||
case 0: level_str = "FATAL"; break; \
 | 
			
		||||
case 1: level_str = "ERROR"; break; \
 | 
			
		||||
case 2: level_str = "WARN"; break; \
 | 
			
		||||
case 3: level_str = "INFO"; break; \
 | 
			
		||||
case 4: level_str = "DEBUG"; break; \
 | 
			
		||||
default: level_str = "UNKNOWN"; break; \
 | 
			
		||||
} \
 | 
			
		||||
std::cout << "[" << level_str << "] " << message << std::endl; \
 | 
			
		||||
} \
 | 
			
		||||
extern "C" void dpm_con(int level, const char* message) { \
 | 
			
		||||
const char* level_str; \
 | 
			
		||||
switch (level) { \
 | 
			
		||||
case 0: level_str = "FATAL"; break; \
 | 
			
		||||
case 1: level_str = "ERROR"; break; \
 | 
			
		||||
case 2: level_str = "WARN"; break; \
 | 
			
		||||
case 3: level_str = "INFO"; break; \
 | 
			
		||||
case 4: level_str = "DEBUG"; break; \
 | 
			
		||||
default: level_str = "UNKNOWN"; break; \
 | 
			
		||||
} \
 | 
			
		||||
std::cout << "[" << level_str << "] " << message << std::endl; \
 | 
			
		||||
} \
 | 
			
		||||
extern "C" const char* dpm_get_config(const char* section, const char* key) { \
 | 
			
		||||
if (!section || !key) return nullptr; \
 | 
			
		||||
\
 | 
			
		||||
/* Create environment variable name in format SECTION_KEY */ \
 | 
			
		||||
std::string env_name = std::string(section) + "_" + std::string(key); \
 | 
			
		||||
\
 | 
			
		||||
/* Check if environment variable exists */ \
 | 
			
		||||
const char* env_value = getenv(env_name.c_str()); \
 | 
			
		||||
return env_value; /* Will be null if env var doesn't exist */ \
 | 
			
		||||
} \
 | 
			
		||||
extern "C" void dpm_set_logging_level(int level) { \
 | 
			
		||||
std::cout << "[INFO] Verbosity level ignored, as all standalone executions have maximum verbosity" << std::endl; \
 | 
			
		||||
} \
 | 
			
		||||
extern "C" const char* dpm_get_module_path(void) { \
 | 
			
		||||
/* Get from environment variable or use default */ \
 | 
			
		||||
const char* env_path = getenv("DPM_MODULE_PATH"); \
 | 
			
		||||
return env_path ? env_path : "/usr/lib/dpm/modules/"; \
 | 
			
		||||
} \
 | 
			
		||||
int main(int argc, char** argv) { \
 | 
			
		||||
/* Default to "help" if no command is provided */ \
 | 
			
		||||
const char* command = "help"; \
 | 
			
		||||
\
 | 
			
		||||
/* If arguments are provided, use the first as command */ \
 | 
			
		||||
if (argc > 1) { \
 | 
			
		||||
command = argv[1]; \
 | 
			
		||||
/* Shift arguments for the command handler but keep the original argc count */ \
 | 
			
		||||
argv++; \
 | 
			
		||||
argc--; \
 | 
			
		||||
} \
 | 
			
		||||
\
 | 
			
		||||
return dpm_module_execute(command, argc, argv); \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "StandaloneModuleImpl.hpp"
 | 
			
		||||
#endif // BUILD_STANDALONE
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,121 @@
 | 
			
		|||
/**
 | 
			
		||||
 * @file StandaloneModuleImpl.hpp
 | 
			
		||||
 * @brief Standalone implementations for DPM modules
 | 
			
		||||
 *
 | 
			
		||||
 * Provides implementations of core DPM functions for standalone module builds,
 | 
			
		||||
 * allowing modules to be compiled and run independently of the main DPM system
 | 
			
		||||
 * for testing and development purposes.
 | 
			
		||||
 *
 | 
			
		||||
 * @copyright Copyright (c) 2025 SILO GROUP LLC
 | 
			
		||||
 * @author Chris Punches <chris.punches@silogroup.org>
 | 
			
		||||
 *
 | 
			
		||||
 * Part of the Dark Horse Linux Package Manager (DPM)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * For bug reports or contributions, please contact the dhlp-contributors
 | 
			
		||||
 * mailing list at: https://lists.darkhorselinux.org/mailman/listinfo/dhlp-contributors
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
 | 
			
		||||
// All implementations must be inline to prevent multiple definition errors when included in multiple files
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Standalone implementation of dpm_log
 | 
			
		||||
 */
 | 
			
		||||
inline void dpm_log(int level, const char* message) {
 | 
			
		||||
    const char* level_str;
 | 
			
		||||
    switch (level) {
 | 
			
		||||
        case 0: level_str = "FATAL"; break;
 | 
			
		||||
        case 1: level_str = "ERROR"; break;
 | 
			
		||||
        case 2: level_str = "WARN"; break;
 | 
			
		||||
        case 3: level_str = "INFO"; break;
 | 
			
		||||
        case 4: level_str = "DEBUG"; break;
 | 
			
		||||
        default: level_str = "UNKNOWN"; break;
 | 
			
		||||
    }
 | 
			
		||||
    std::cout << "[" << level_str << "] " << message << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Standalone implementation of dpm_con
 | 
			
		||||
 */
 | 
			
		||||
inline void dpm_con(int level, const char* message) {
 | 
			
		||||
    const char* level_str;
 | 
			
		||||
    switch (level) {
 | 
			
		||||
        case 0: level_str = "FATAL"; break;
 | 
			
		||||
        case 1: level_str = "ERROR"; break;
 | 
			
		||||
        case 2: level_str = "WARN"; break;
 | 
			
		||||
        case 3: level_str = "INFO"; break;
 | 
			
		||||
        case 4: level_str = "DEBUG"; break;
 | 
			
		||||
        default: level_str = "UNKNOWN"; break;
 | 
			
		||||
    }
 | 
			
		||||
    std::cout << "[" << level_str << "] " << message << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Standalone implementation of dpm_get_config
 | 
			
		||||
 */
 | 
			
		||||
inline const char* dpm_get_config(const char* section, const char* key) {
 | 
			
		||||
    if (!section || !key) return nullptr;
 | 
			
		||||
 | 
			
		||||
    // Create environment variable name in format SECTION_KEY
 | 
			
		||||
    std::string env_name = std::string(section) + "_" + std::string(key);
 | 
			
		||||
 | 
			
		||||
    // Check if environment variable exists
 | 
			
		||||
    const char* env_value = getenv(env_name.c_str());
 | 
			
		||||
    return env_value; // Will be null if env var doesn't exist
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Standalone implementation of dpm_set_logging_level
 | 
			
		||||
 */
 | 
			
		||||
inline void dpm_set_logging_level(int level) {
 | 
			
		||||
    std::cout << "[INFO] Verbosity level ignored, as all standalone executions have maximum verbosity" << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Standalone implementation of dpm_get_module_path
 | 
			
		||||
 */
 | 
			
		||||
inline const char* dpm_get_module_path(void) {
 | 
			
		||||
    // Get from environment variable or use default
 | 
			
		||||
    const char* env_path = getenv("DPM_MODULE_PATH");
 | 
			
		||||
    return env_path ? env_path : "/usr/lib/dpm/modules/";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Standalone module main function
 | 
			
		||||
 *
 | 
			
		||||
 * Provides a main() function for standalone module builds that
 | 
			
		||||
 * initializes the environment and routes to the module's execute function.
 | 
			
		||||
 */
 | 
			
		||||
#define DPM_MODULE_STANDALONE_MAIN() \
 | 
			
		||||
int main(int argc, char** argv) { \
 | 
			
		||||
    /* Default to "help" if no command is provided */ \
 | 
			
		||||
    const char* command = "help"; \
 | 
			
		||||
    \
 | 
			
		||||
    /* If arguments are provided, use the first as command */ \
 | 
			
		||||
    if (argc > 1) { \
 | 
			
		||||
        command = argv[1]; \
 | 
			
		||||
        /* Shift arguments for the command handler but keep the original argc count */ \
 | 
			
		||||
        argv++; \
 | 
			
		||||
        argc--; \
 | 
			
		||||
    } \
 | 
			
		||||
    \
 | 
			
		||||
    return dpm_module_execute(command, argc, argv); \
 | 
			
		||||
}
 | 
			
		||||
/* End of file */
 | 
			
		||||
| 
						 | 
				
			
			@ -157,10 +157,10 @@ class ConfigManager {
 | 
			
		|||
        bool hasConfigKey(const char* section, const char* key) const;
 | 
			
		||||
 | 
			
		||||
        // getter for _module_path
 | 
			
		||||
        void setModulePath(const std::string& module_path);
 | 
			
		||||
        void setModulePath(const char * module_path);
 | 
			
		||||
 | 
			
		||||
        // setter for _module_path
 | 
			
		||||
        std::string getModulePath() const;
 | 
			
		||||
        const char * getModulePath() const;
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,8 @@ enum Command {
 | 
			
		|||
    CMD_UNKNOWN,     /**< Unknown or unsupported command */
 | 
			
		||||
    CMD_HELP,        /**< Display help information */
 | 
			
		||||
    CMD_CHECKSUM,    /**< Verify package checksums */
 | 
			
		||||
    CMD_SIGNATURE    /**< Verify package signatures */
 | 
			
		||||
    CMD_SIGNATURE,   /**< Verify package signatures */
 | 
			
		||||
    CMD_CHECK        /**< Check build module integration */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -85,3 +86,15 @@ int cmd_unknown(const char* command, int argc, char** argv);
 | 
			
		|||
 * @return The corresponding Command enum value
 | 
			
		||||
 */
 | 
			
		||||
Command parse_command(const char* cmd_str);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Handler for the check command
 | 
			
		||||
 *
 | 
			
		||||
 * Checks if the build module can be loaded. This validates that the integration
 | 
			
		||||
 * between the verify module and build module is working correctly.
 | 
			
		||||
 *
 | 
			
		||||
 * @param argc Number of arguments
 | 
			
		||||
 * @param argv Array of arguments
 | 
			
		||||
 * @return 0 on success, non-zero on failure
 | 
			
		||||
 */
 | 
			
		||||
int cmd_check(int argc, char** argv);
 | 
			
		||||
| 
						 | 
				
			
			@ -196,6 +196,7 @@ int cmd_help(int argc, char** argv) {
 | 
			
		|||
    dpm_con(LOG_INFO, "");
 | 
			
		||||
    dpm_con(LOG_INFO, "  checksum   - Verify checksums of installed packages");
 | 
			
		||||
    dpm_con(LOG_INFO, "  signature  - Verify signatures of installed packages");
 | 
			
		||||
    dpm_con(LOG_INFO, "  check      - Check build module integration");
 | 
			
		||||
    dpm_con(LOG_INFO, "  help       - Display this help message");
 | 
			
		||||
    dpm_con(LOG_INFO, "");
 | 
			
		||||
    dpm_con(LOG_INFO, "Usage: dpm verify <command>");
 | 
			
		||||
| 
						 | 
				
			
			@ -227,6 +228,30 @@ Command parse_command(const char* cmd_str) {
 | 
			
		|||
    else if (strcmp(cmd_str, "signature") == 0) {
 | 
			
		||||
        return CMD_SIGNATURE;
 | 
			
		||||
    }
 | 
			
		||||
    else if (strcmp(cmd_str, "check") == 0) {
 | 
			
		||||
        return CMD_CHECK;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CMD_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cmd_check(int argc, char** argv) {
 | 
			
		||||
    dpm_log(LOG_INFO, "Checking build module integration...");
 | 
			
		||||
 | 
			
		||||
    void* module_handle = nullptr;
 | 
			
		||||
    int result = check_and_load_build_module(module_handle);
 | 
			
		||||
 | 
			
		||||
    if (result != 0) {
 | 
			
		||||
        dpm_log(LOG_ERROR, "Failed to load build module.");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dpm_log(LOG_INFO, "Successfully loaded build module.");
 | 
			
		||||
 | 
			
		||||
    // Clean up
 | 
			
		||||
    if (module_handle) {
 | 
			
		||||
        dlclose(module_handle);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -85,6 +85,9 @@ extern "C" int dpm_module_execute(const char* command, int argc, char** argv) {
 | 
			
		|||
        case CMD_SIGNATURE:
 | 
			
		||||
            return cmd_signature(argc, argv);
 | 
			
		||||
 | 
			
		||||
        case CMD_CHECK:
 | 
			
		||||
            return cmd_check(argc, argv);
 | 
			
		||||
 | 
			
		||||
        case CMD_HELP:
 | 
			
		||||
            return cmd_help(argc, argv);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -321,10 +321,10 @@ bool ConfigManager::getConfigBool(const char* section, const char* key, bool def
 | 
			
		|||
    return defaultValue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ConfigManager::setModulePath(const std::string& module_path) {
 | 
			
		||||
void ConfigManager::setModulePath(const char * module_path) {
 | 
			
		||||
    _module_path = module_path;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ConfigManager::getModulePath() const {
 | 
			
		||||
    return _module_path;
 | 
			
		||||
const char * ConfigManager::getModulePath() const {
 | 
			
		||||
    return _module_path.c_str();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -129,8 +129,6 @@ int main( int argc, char* argv[] )
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        g_config_manager.setModulePath(module_path);
 | 
			
		||||
 | 
			
		||||
        // create a module loader object with the determined path
 | 
			
		||||
        ModuleLoader loader(module_path);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -165,6 +163,8 @@ int main( int argc, char* argv[] )
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g_config_manager.setModulePath(module_path.c_str());
 | 
			
		||||
 | 
			
		||||
    // create a module loader object with the determined path
 | 
			
		||||
    ModuleLoader loader(module_path);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -123,7 +123,7 @@ extern "C" void dpm_set_logging_level(int level) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
extern "C" const char* dpm_get_module_path(void) {
 | 
			
		||||
    static std::string module_path;
 | 
			
		||||
    static const char * module_path;
 | 
			
		||||
    module_path = g_config_manager.getModulePath();
 | 
			
		||||
    return module_path.c_str();
 | 
			
		||||
    return module_path;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue