@@ -381,6 +381,72 @@ bool ArgsManager::IsArgSet(const std::string& strArg) const
381381 return !ArgsManagerHelper::Get (*this , strArg).isNull ();
382382}
383383
384+ static fs::path GetSettingsFile (bool temp = false )
385+ {
386+ return fs::absolute (temp ? " settings.json.tmp" : " settings.json" , GetDataDir (/* net_specific= */ true ));
387+ }
388+
389+ bool ArgsManager::ReadSettingsFile ()
390+ {
391+ fsbridge::ifstream file;
392+ fs::path filepath = GetSettingsFile (/* temp= */ false );
393+ file.open (filepath);
394+ if (!file.is_open ()) return true ; // Ok for file not to exist.
395+
396+ util::SettingsValue in;
397+ if (!in.read (std::string{std::istreambuf_iterator<char >(file), std::istreambuf_iterator<char >()})) {
398+ LogPrintf (" Error: Unable to parse settings file %s\n " , filepath.string ());
399+ return false ;
400+ }
401+ if (file.fail ()) {
402+ LogPrintf (" Error reading settings file %s\n " , filepath.string ());
403+ return false ;
404+ }
405+ file.close ();
406+
407+ if (!in.isObject ()) {
408+ LogPrintf (" Error: Settings file %s is not in expected key-value format.\n " , filepath.string ());
409+ return false ;
410+ }
411+
412+ LOCK (cs_args);
413+ m_settings.rw_settings .clear ();
414+ const std::vector<std::string>& keys = in.getKeys ();
415+ const std::vector<UniValue>& values = in.getValues ();
416+ for (size_t i = 0 ; i < keys.size (); ++i) {
417+ m_settings.rw_settings .emplace (keys[i], values[i]);
418+ }
419+ return true ;
420+ }
421+
422+ bool ArgsManager::WriteSettingsFile () const
423+ {
424+ util::SettingsValue out (util::SettingsValue::VOBJ);
425+ {
426+ LOCK (cs_args);
427+ for (const auto & value : m_settings.rw_settings ) {
428+ out.__pushKV (value.first , value.second );
429+ }
430+ }
431+
432+ fsbridge::ofstream file;
433+ fs::path filepath_tmp = GetSettingsFile (/* temp= */ true );
434+ file.open (filepath_tmp);
435+ if (file.fail ()) {
436+ LogPrintf (" Error: Unable to open settings file %s for writing\n " , filepath_tmp.string ());
437+ return false ;
438+ }
439+ file << out.write (/* prettyIndent= */ 1 , /* indentLevel= */ 4 ) << std::endl;
440+ file.close ();
441+
442+ fs::path filepath = GetSettingsFile (/* temp= */ false );
443+ if (!RenameOver (filepath_tmp, filepath)) {
444+ LogPrintf (" Error: Unable to rename settings file %s to %s\n " , filepath_tmp.string (), filepath.string ());
445+ return false ;
446+ }
447+ return true ;
448+ }
449+
384450bool ArgsManager::IsArgNegated (const std::string& strArg) const
385451{
386452 return ArgsManagerHelper::Get (*this , strArg).isFalse ();
0 commit comments