/* Copyright (C) 2020-2021 Reiko Asakura. All Rights Reserved. Moonshine */ #include #include #include #include #include "config.h" #define CONFIG_FILE_PATH "ur0:/data/moonshine.ini" #define VAL_BUFFER_SIZE (0x20) typedef struct value_map { const char *ini_val; int val; } value_map; typedef struct key_map { const char *ini_key; int *key; value_map *map; int map_len; } key_map; int config_init(MoonshineConfig *config) { sceClibMemset(config, 0, sizeof(*config)); config->block_presence = MOONSHINE_CONFIG_BLOCK_HOMEBREW; config->block_status = MOONSHINE_CONFIG_BLOCK_HOMEBREW; return 0; } static int config_read_enum(const char *key, const char *val, key_map *kmap, int map_len) { for (int i = 0; i < map_len; i++) { if (sceClibStrncasecmp(key, kmap[i].ini_key, SCE_INI_FILE_PROCESSOR_KEY_BUFFER_SIZE) == 0) { for (int j = 0; j < kmap[i].map_len; j++) { if (sceClibStrncasecmp(val, kmap[i].map[j].ini_val, VAL_BUFFER_SIZE) == 0) { *kmap[i].key = kmap[i].map[j].val; SCE_DBG_LOG_INFO("Config read %s=%s", key, val); return 0; } } } } SCE_DBG_LOG_WARNING("Config skipped %s=%s", key, val); return -1; } int config_read(MoonshineConfig *config) { using namespace sce; int ret; SceIoStat stat; ret = sceIoGetstat(CONFIG_FILE_PATH, &stat); if (ret < 0) { SCE_DBG_LOG_ERROR("Failed to stat config file: 0x%08X", ret); return -1; } if (sceClibMemcmp(&stat.st_mtime, &config->time, sizeof(stat.st_mtime)) == 0) { SCE_DBG_LOG_INFO("Config already up to date"); return 0; } config_init(config); auto init_param = Ini::InitParameter(); auto ini_proc = Ini::IniFileProcessor(); ret = ini_proc.initialize(&init_param); if (ret < 0) { SCE_DBG_LOG_ERROR("Failed to initialise INI processor: 0x%08X", ret); return -1; } if (ini_proc.open(CONFIG_FILE_PATH, "r", 0) < 0) { SCE_DBG_LOG_ERROR("Failed to open config file: 0x%08X", ini_proc.getLastIoError()); return -1; } value_map vmap[3] = { {"none", MOONSHINE_CONFIG_BLOCK_NONE}, {"homebrew", MOONSHINE_CONFIG_BLOCK_HOMEBREW}, {"all", MOONSHINE_CONFIG_BLOCK_ALL}}; key_map kmap[2] = { {"block_presence", &config->block_presence, vmap, 3}, {"block_status", &config->block_status, vmap, 3}}; char key[SCE_INI_FILE_PROCESSOR_KEY_BUFFER_SIZE]; char val[VAL_BUFFER_SIZE]; while ((ret = ini_proc.parse(key, val, sizeof(val))) == SCE_OK) { config_read_enum(key, val, kmap, 2); } if (ret != SCE_INI_FILE_PROCESSOR_PARSE_COMPLETED) { SCE_DBG_LOG_ERROR("INI parse error: 0x%08X", ret); } ret = ini_proc.close(); if (ret < 0) { SCE_DBG_LOG_ERROR("Failed to close INI processor: 0x%08X", ret); } config->time = stat.st_mtime; return 0; }