prepare for config resiliency

This commit is contained in:
tildearrow 2023-04-05 04:44:21 -05:00
parent 79b418c031
commit e6bac16a7a
3 changed files with 92 additions and 16 deletions

View file

@ -23,7 +23,10 @@
#include "../fileutils.h" #include "../fileutils.h"
#include <fmt/printf.h> #include <fmt/printf.h>
bool DivConfig::save(const char* path) { #define REDUNDANCY_NUM_ATTEMPTS 5
#define CHECK_BUF_SIZE 8192
bool DivConfig::save(const char* path, bool redundancy) {
logD("opening config for write: %s",path); logD("opening config for write: %s",path);
FILE* f=ps_fopen(path,"wb"); FILE* f=ps_fopen(path,"wb");
if (f==NULL) { if (f==NULL) {
@ -84,21 +87,94 @@ void DivConfig::parseLine(const char* line) {
} }
} }
bool DivConfig::loadFromFile(const char* path, bool createOnFail) { bool DivConfig::loadFromFile(const char* path, bool createOnFail, bool redundancy) {
char line[4096]; char line[4096];
logD("opening config for read: %s",path); logD("opening config for read: %s",path);
FILE* f=ps_fopen(path,"rb");
if (f==NULL) { FILE* f=NULL;
logD("config does not exist");
if (createOnFail) { if (redundancy) {
logI("creating default config."); unsigned char* readBuf=new unsigned char[CHECK_BUF_SIZE];
reportError(fmt::sprintf("Creating default config: %s",strerror(errno))); size_t readBufLen=0;
return save(path); for (int i=0; i<REDUNDANCY_NUM_ATTEMPTS; i++) {
} else { bool viable=false;
reportError(fmt::sprintf("COULD NOT LOAD CONFIG %s",strerror(errno))); if (i>0) {
return false; snprintf(line,4095,"%s.%d",path,i);
} else {
strncpy(line,path,4095);
}
logV("trying: %s",line);
// try to open config
f=ps_fopen(line,"rb");
// check whether we could open it
if (f==NULL) {
logV("fopen(): %s",strerror(errno));
continue;
}
// check whether there's something
while (!feof(f)) {
readBufLen=fread(readBuf,1,CHECK_BUF_SIZE,f);
if (ferror(f)) {
logV("fread(): %s",strerror(errno));
break;
}
for (size_t j=0; j<readBufLen; j++) {
if (readBuf[j]!='\r' && readBuf[j]!='\n' && readBuf[j]!=' ') {
viable=true;
break;
}
}
if (viable) break;
}
// there's something
if (viable) {
if (fseek(f,0,SEEK_SET)==-1) {
logV("fseek(): %s",strerror(errno));
viable=false;
} else {
break;
}
}
// close it (because there's nothing)
fclose(f);
f=NULL;
}
delete[] readBuf;
// we couldn't read at all
if (f==NULL) {
logD("config does not exist");
if (createOnFail) {
logI("creating default config.");
reportError(fmt::sprintf("Creating default config: %s",strerror(errno)));
return save(path,redundancy);
} else {
reportError(fmt::sprintf("COULD NOT LOAD CONFIG %s",strerror(errno)));
return false;
}
}
} else {
f=ps_fopen(path,"rb");
if (f==NULL) {
logD("config does not exist");
if (createOnFail) {
logI("creating default config.");
reportError(fmt::sprintf("Creating default config: %s",strerror(errno)));
return save(path);
} else {
reportError(fmt::sprintf("COULD NOT LOAD CONFIG %s",strerror(errno)));
return false;
}
} }
} }
logI("loading config."); logI("loading config.");
while (!feof(f)) { while (!feof(f)) {
if (fgets(line,4095,f)==NULL) { if (fgets(line,4095,f)==NULL) {

View file

@ -32,10 +32,10 @@ class DivConfig {
// config loading/saving // config loading/saving
bool loadFromMemory(const char* buf); bool loadFromMemory(const char* buf);
bool loadFromBase64(const char* buf); bool loadFromBase64(const char* buf);
bool loadFromFile(const char* path, bool createOnFail=true); bool loadFromFile(const char* path, bool createOnFail=true, bool redundancy=false);
String toString(); String toString();
String toBase64(); String toBase64();
bool save(const char* path); bool save(const char* path, bool redundancy=false);
// get the map // get the map
const std::map<String,String>& configMap(); const std::map<String,String>& configMap();

View file

@ -110,12 +110,12 @@ void DivEngine::initConfDir() {
bool DivEngine::saveConf() { bool DivEngine::saveConf() {
configFile=configPath+String(CONFIG_FILE); configFile=configPath+String(CONFIG_FILE);
return conf.save(configFile.c_str()); return conf.save(configFile.c_str(),true);
} }
bool DivEngine::loadConf() { bool DivEngine::loadConf() {
configFile=configPath+String(CONFIG_FILE); configFile=configPath+String(CONFIG_FILE);
return conf.loadFromFile(configFile.c_str()); return conf.loadFromFile(configFile.c_str(),true,true);
} }
bool DivEngine::getConfBool(String key, bool fallback) { bool DivEngine::getConfBool(String key, bool fallback) {