Initialization and Cleanup Functions

#include <keychain/keychain_headers.h>

Overview

Library initialization and cleanup functions provide essential setup and teardown operations for the Keychain Core C API, including settings management and resource cleanup.

Library Lifecycle Functions

kc_gateway_init()

unsigned int kc_gateway_init(
    kc_settings_t** out_settings,
    const char* config_path,
    const unsigned int config_path_size
)

Initializes the Keychain library and creates a settings object from configuration file.

Parameters:

  • out_settings - Pointer to settings pointer (output, must be freed with kc_settings_destruct)

  • config_path - Path to configuration file (null-terminated string)

  • config_path_size - Length of config path string (excluding null terminator)

Returns: Error code (0 = success)

Example:

kc_settings_t* settings = NULL;
const char* config_file = "keychain.cfg";
unsigned int result = kc_gateway_init(&settings, config_file, strlen(config_file));
if (result != 0) {
    printf("Failed to initialize Keychain: error %u\n", result);
    return 1;
}

kc_gateway_init_with_defaults()

unsigned int kc_gateway_init_with_defaults(
    kc_settings_t** out_settings
)

Initializes the Keychain library with default settings.

Parameters:

  • out_settings - Pointer to settings pointer (output)

Returns: Error code (0 = success)

Example:

kc_settings_t* settings = NULL;
unsigned int result = kc_gateway_init_with_defaults(&settings);
if (result == 0) {
    printf("Keychain initialized with defaults\n");
}

kc_gateway_close()

unsigned int kc_gateway_close()

Cleans up static library resources and shuts down the Keychain library. Should be called once at application shutdown after all gateways are destructed.

Returns: Error code (0 = success)

Example:

// Clean up all gateways first
kc_gateway_destruct(&gateway);
kc_settings_destruct(&settings);

// Final library cleanup
unsigned int result = kc_gateway_close();
if (result == 0) {
    printf("Keychain library closed successfully\n");
}

Settings Management Functions

kc_settings_construct()

unsigned int kc_settings_construct(
    kc_settings_t** out_settings,
    const char* config_data,
    const unsigned int config_data_size
)

Constructs settings object from configuration data in memory.

Parameters:

  • out_settings - Pointer to settings pointer (output)

  • config_data - Configuration data as string

  • config_data_size - Length of configuration data

Returns: Error code (0 = success)

kc_settings_destruct()

unsigned int kc_settings_destruct(kc_settings_t** settings_ptr)

Destructs a settings object and frees its memory.

Parameters:

  • settings_ptr - Pointer to settings pointer (set to NULL on success)

Returns: Error code (0 = success)

kc_settings_get_property()

unsigned int kc_settings_get_property(
    const kc_settings_t* settings,
    const char* property_name,
    const unsigned int property_name_size,
    char** out_property_value,
    unsigned int* out_value_size
)

Gets a configuration property value from settings.

Parameters:

  • settings - Settings object

  • property_name - Name of property to retrieve

  • property_name_size - Length of property name

  • out_property_value - Pointer to property value string (output, caller must free)

  • out_value_size - Pointer to value string length (output)

Returns: Error code (0 = success)

kc_settings_set_property()

unsigned int kc_settings_set_property(
    kc_settings_t* settings,
    const char* property_name,
    const unsigned int property_name_size,
    const char* property_value,
    const unsigned int property_value_size
)

Sets a configuration property value in settings.

Parameters:

  • settings - Settings object

  • property_name - Name of property to set

  • property_name_size - Length of property name

  • property_value - New property value

  • property_value_size - Length of property value

Returns: Error code (0 = success)

Version Information Functions

kc_major_version()

unsigned int kc_major_version(unsigned int* out_major)

Gets the major version number of the Keychain library.

Parameters:

  • out_major - Pointer to major version number (output)

Returns: Error code (0 = success)

kc_minor_version()

unsigned int kc_minor_version(unsigned int* out_minor)

Gets the minor version number of the Keychain library.

Parameters:

  • out_minor - Pointer to minor version number (output)

Returns: Error code (0 = success)

kc_version_string()

unsigned int kc_version_string(
    char** out_version_string,
    unsigned int* out_string_size
)

Gets the full version string of the Keychain library.

Parameters:

  • out_version_string - Pointer to version string (output, caller must free)

  • out_string_size - Pointer to string length (output)

Returns: Error code (0 = success)

Usage Patterns

Complete Application Lifecycle

#include <keychain/keychain_headers.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    // 1. Initialize library
    kc_settings_t* settings = NULL;
    unsigned int result = kc_gateway_init(&settings, "keychain.cfg", 12);
    if (result != 0) {
        printf("Initialization failed: %u\n", result);
        return 1;
    }

    // 2. Create gateway
    kc_gateway_t* gateway = NULL;
    result = kc_gateway_construct(&gateway, settings);
    if (result != 0) {
        printf("Gateway creation failed: %u\n", result);
        kc_settings_destruct(&settings);
        kc_gateway_close();
        return 1;
    }

    // 3. Start operations
    result = kc_gateway_on_start(gateway);
    if (result != 0) {
        printf("Gateway start failed: %u\n", result);
        goto cleanup;
    }

    // 4. Application logic here
    printf("Keychain library is ready for operations\n");

    // ... perform keychain operations ...

cleanup:
    // 5. Stop operations
    kc_gateway_on_stop(gateway);

    // 6. Clean up gateway
    kc_gateway_destruct(&gateway);

    // 7. Clean up settings
    kc_settings_destruct(&settings);

    // 8. Final library cleanup
    kc_gateway_close();

    return 0;
}

Configuration Management

// Load and manage configuration settings
void demonstrate_settings_management() {
    kc_settings_t* settings = NULL;

    // Initialize with configuration file
    unsigned int result = kc_gateway_init(&settings, "app_config.cfg", 14);
    if (result != 0) {
        printf("Failed to load configuration\n");
        return;
    }

    // Get specific configuration properties
    char* server_url = NULL;
    unsigned int url_size = 0;
    result = kc_settings_get_property(settings, "server_url", 10, &server_url, &url_size);
    if (result == 0) {
        printf("Server URL: %s\n", server_url);
        kc_common_delete_buffer(&server_url);
    }

    // Set runtime configuration
    const char* new_timeout = "30000";
    result = kc_settings_set_property(settings, "timeout_ms", 10, new_timeout, 5);
    if (result == 0) {
        printf("Timeout updated\n");
    }

    // Cleanup
    kc_settings_destruct(&settings);
}

Version Checking

// Check library version compatibility
void check_version_compatibility() {
    unsigned int major = 0, minor = 0;
    char* version_string = NULL;
    unsigned int version_size = 0;

    // Get version components
    kc_major_version(&major);
    kc_minor_version(&minor);
    kc_version_string(&version_string, &version_size);

    printf("Keychain Core Version: %u.%u (%s)\n", major, minor, version_string);

    // Check minimum required version
    if (major < 3) {
        printf("ERROR: This application requires Keychain Core 3.0 or later\n");
        kc_common_delete_buffer(&version_string);
        exit(1);
    }

    printf("Version compatibility check passed\n");
    kc_common_delete_buffer(&version_string);
}

Error Handling During Initialization

// Robust initialization with error handling
int robust_initialization(const char* config_file) {
    kc_settings_t* settings = NULL;
    kc_gateway_t* gateway = NULL;
    unsigned int result;

    // Step 1: Library initialization
    result = kc_gateway_init(&settings, config_file, strlen(config_file));
    if (result != 0) {
        char* error_msg = NULL;
        unsigned int error_size = 0;
        kc_common_get_error_message(&error_msg, &error_size, result);
        printf("Library initialization failed: %s\n", error_msg);
        kc_common_delete_buffer(&error_msg);
        return -1;
    }

    // Step 2: Gateway creation
    result = kc_gateway_construct(&gateway, settings);
    if (result != 0) {
        char* error_msg = NULL;
        unsigned int error_size = 0;
        kc_common_get_error_message(&error_msg, &error_size, result);
        printf("Gateway creation failed: %s\n", error_msg);
        kc_common_delete_buffer(&error_msg);

        kc_settings_destruct(&settings);
        kc_gateway_close();
        return -1;
    }

    // Step 3: Start operations
    result = kc_gateway_on_start(gateway);
    if (result != 0) {
        char* error_msg = NULL;
        unsigned int error_size = 0;
        kc_common_get_error_message(&error_msg, &error_size, result);
        printf("Gateway start failed: %s\n", error_msg);
        kc_common_delete_buffer(&error_msg);

        kc_gateway_destruct(&gateway);
        kc_settings_destruct(&settings);
        kc_gateway_close();
        return -1;
    }

    printf("Keychain initialization completed successfully\n");

    // Store globals for later cleanup (in real application)
    // global_gateway = gateway;
    // global_settings = settings;

    return 0;
}

Configuration File Format

Example keychain.cfg file:

# Keychain Core Configuration File

[network]
server_url=https://keychain.example.com:8443
timeout_ms=30000
retry_count=3

[security]
security_level=HIGH
key_size=256
algorithm=ECDSA_P256_SHA256

[storage]
data_directory=/var/lib/keychain
backup_enabled=true
backup_interval=86400

[logging]
log_level=INFO
log_file=/var/log/keychain.log
max_log_size=10485760

[pki]
ca_cert_path=/etc/keychain/ca.pem
cert_validation=strict
crl_check=enabled

Memory Management

All functions that return allocated strings or objects require explicit cleanup:

// Proper memory management example
void proper_cleanup_example() {
    kc_settings_t* settings = NULL;
    char* version_string = NULL;
    char* property_value = NULL;
    unsigned int size = 0;

    // Initialize
    if (kc_gateway_init(&settings, "config.cfg", 10) == 0) {

        // Get version (allocates memory)
        if (kc_version_string(&version_string, &size) == 0) {
            printf("Version: %s\n", version_string);
            kc_common_delete_buffer(&version_string); // Free version string
        }

        // Get property (allocates memory)
        if (kc_settings_get_property(settings, "server_url", 10, &property_value, &size) == 0) {
            printf("Server: %s\n", property_value);
            kc_common_delete_buffer(&property_value); // Free property value
        }

        kc_settings_destruct(&settings); // Free settings object
    }

    kc_gateway_close(); // Final cleanup
}

Thread Safety

Initialization and cleanup functions are generally not thread-safe and should be called from a single thread during application startup and shutdown:

// Thread-safe initialization pattern
static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
static int initialized = 0;
static kc_settings_t* global_settings = NULL;

int thread_safe_init() {
    pthread_mutex_lock(&init_mutex);

    if (!initialized) {
        unsigned int result = kc_gateway_init(&global_settings, "config.cfg", 10);
        if (result == 0) {
            initialized = 1;
        }
        pthread_mutex_unlock(&init_mutex);
        return result;
    }

    pthread_mutex_unlock(&init_mutex);
    return 0; // Already initialized
}

See Also