v0.2.2 - Working on config setup

This commit is contained in:
Your Name
2025-09-05 19:48:49 -04:00
parent 6c10713e18
commit 9a29ea51e3
19 changed files with 2378 additions and 574 deletions

223
src/config.h Normal file
View File

@@ -0,0 +1,223 @@
#ifndef CONFIG_H
#define CONFIG_H
#include <sqlite3.h>
#include <time.h>
#include <stddef.h>
#include <cjson/cJSON.h>
// Configuration system constants
#define CONFIG_KEY_MAX_LENGTH 64
#define CONFIG_VALUE_MAX_LENGTH 512
#define CONFIG_DESCRIPTION_MAX_LENGTH 256
#define CONFIG_XDG_DIR_NAME "c-relay"
#define CONFIG_FILE_NAME "c_relay_config_event.json"
#define CONFIG_PRIVKEY_ENV "C_RELAY_CONFIG_PRIVKEY"
#define NOSTR_PUBKEY_HEX_LENGTH 64
#define NOSTR_PRIVKEY_HEX_LENGTH 64
#define NOSTR_EVENT_ID_HEX_LENGTH 64
#define NOSTR_SIGNATURE_HEX_LENGTH 128
// Protocol and implementation constants (hardcoded - should NOT be configurable)
#define SUBSCRIPTION_ID_MAX_LENGTH 64
#define CLIENT_IP_MAX_LENGTH 64
#define RELAY_NAME_MAX_LENGTH 128
#define RELAY_DESCRIPTION_MAX_LENGTH 1024
#define RELAY_URL_MAX_LENGTH 256
#define RELAY_CONTACT_MAX_LENGTH 128
#define RELAY_PUBKEY_MAX_LENGTH 65
#define DATABASE_PATH "db/c_nostr_relay.db"
// Default configuration values (used as fallbacks if database config fails)
#define DEFAULT_PORT 8888
#define DEFAULT_HOST "127.0.0.1"
#define MAX_CLIENTS 100
#define MAX_SUBSCRIPTIONS_PER_CLIENT 20
#define MAX_TOTAL_SUBSCRIPTIONS 5000
#define MAX_FILTERS_PER_SUBSCRIPTION 10
// Configuration types
typedef enum {
CONFIG_TYPE_SYSTEM = 0,
CONFIG_TYPE_USER = 1,
CONFIG_TYPE_RUNTIME = 2
} config_type_t;
// Configuration data types
typedef enum {
CONFIG_DATA_STRING = 0,
CONFIG_DATA_INTEGER = 1,
CONFIG_DATA_BOOLEAN = 2,
CONFIG_DATA_JSON = 3
} config_data_type_t;
// Configuration validation result
typedef enum {
CONFIG_VALID = 0,
CONFIG_INVALID_TYPE = 1,
CONFIG_INVALID_RANGE = 2,
CONFIG_INVALID_FORMAT = 3,
CONFIG_MISSING_REQUIRED = 4
} config_validation_result_t;
// Configuration entry structure
typedef struct {
char key[CONFIG_KEY_MAX_LENGTH];
char value[CONFIG_VALUE_MAX_LENGTH];
char description[CONFIG_DESCRIPTION_MAX_LENGTH];
config_type_t config_type;
config_data_type_t data_type;
int is_sensitive;
int requires_restart;
time_t created_at;
time_t updated_at;
} config_entry_t;
// Configuration manager state
typedef struct {
sqlite3* db;
sqlite3_stmt* get_config_stmt;
sqlite3_stmt* set_config_stmt;
sqlite3_stmt* log_change_stmt;
// Configuration loading status
int file_config_loaded;
int database_config_loaded;
time_t last_reload;
// XDG configuration directory
char config_dir_path[512];
char config_file_path[600];
} config_manager_t;
// Global configuration manager instance
extern config_manager_t g_config_manager;
// ================================
// CORE CONFIGURATION FUNCTIONS
// ================================
// Initialize configuration system
int init_configuration_system(void);
// Cleanup configuration system
void cleanup_configuration_system(void);
// Load configuration from all sources (file -> database -> defaults)
int load_configuration(void);
// Apply loaded configuration to global variables
int apply_configuration_to_globals(void);
// ================================
// DATABASE CONFIGURATION FUNCTIONS
// ================================
// Initialize database prepared statements
int init_config_database_statements(void);
// Get configuration value from database
int get_database_config(const char* key, char* value, size_t value_size);
// Set configuration value in database
int set_database_config(const char* key, const char* new_value, const char* changed_by);
// Load all configuration from database
int load_config_from_database(void);
// ================================
// FILE CONFIGURATION FUNCTIONS
// ================================
// Get XDG configuration directory path
int get_xdg_config_dir(char* path, size_t path_size);
// Check if configuration file exists
int config_file_exists(void);
// Load configuration from file
int load_config_from_file(void);
// Validate and apply Nostr configuration event
int validate_and_apply_config_event(const cJSON* event);
// Validate Nostr event structure
int validate_nostr_event_structure(const cJSON* event);
// Validate configuration tags array
int validate_config_tags(const cJSON* tags);
// Extract and apply configuration tags to database
int extract_and_apply_config_tags(const cJSON* tags);
// ================================
// CONFIGURATION ACCESS FUNCTIONS
// ================================
// Get configuration value (checks all sources: file -> database -> environment -> defaults)
const char* get_config_value(const char* key);
// Get configuration value as integer
int get_config_int(const char* key, int default_value);
// Get configuration value as boolean
int get_config_bool(const char* key, int default_value);
// Set configuration value (updates database)
int set_config_value(const char* key, const char* value);
// ================================
// CONFIGURATION VALIDATION
// ================================
// Validate configuration value
config_validation_result_t validate_config_value(const char* key, const char* value);
// Log validation error
void log_config_validation_error(const char* key, const char* value, const char* error);
// ================================
// UTILITY FUNCTIONS
// ================================
// Convert config type enum to string
const char* config_type_to_string(config_type_t type);
// Convert config data type enum to string
const char* config_data_type_to_string(config_data_type_t type);
// Convert string to config type enum
config_type_t string_to_config_type(const char* str);
// Convert string to config data type enum
config_data_type_t string_to_config_data_type(const char* str);
// Check if configuration key requires restart
int config_requires_restart(const char* key);
// ================================
// NOSTR EVENT GENERATION FUNCTIONS
// ================================
// Generate configuration file with valid Nostr event if it doesn't exist
int generate_config_file_if_missing(void);
// Create a valid Nostr configuration event from database values
cJSON* create_config_nostr_event(const char* privkey_hex);
// Generate a random private key (32 bytes as hex string)
int generate_random_privkey(char* privkey_hex, size_t buffer_size);
// Derive public key from private key (using secp256k1)
int derive_pubkey_from_privkey(const char* privkey_hex, char* pubkey_hex, size_t buffer_size);
// Create Nostr event ID (SHA256 of serialized event data)
int create_nostr_event_id(const cJSON* event, char* event_id_hex, size_t buffer_size);
// Sign Nostr event (using secp256k1 Schnorr signature)
int sign_nostr_event(const cJSON* event, const char* privkey_hex, char* signature_hex, size_t buffer_size);
// Write configuration event to file
int write_config_event_to_file(const cJSON* event);
#endif // CONFIG_H