summaryrefslogblamecommitdiff
path: root/config.cpp
blob: 6f0be9d53e6272648a03bdfcdc6179ba5d4ad021 (plain) (tree)













































































































                                                                                                            
/*
	Copyright (C) 2020-2021 Reiko Asakura. All Rights Reserved.

	Moonshine
*/

#include <ini_file_processor.h>
#include <kernel/iofilemgr_stat.h>
#include <kernel/libkernel.h>
#include <libdbg.h>

#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;
}