Dont write directly to files but rather write and copy a tmp file
parent
c8930850e3
commit
d718b0b34e
17
src/ban.cpp
17
src/ban.cpp
|
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "strfnd.h"
|
#include "strfnd.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "filesys.h"
|
||||||
|
|
||||||
BanManager::BanManager(const std::string &banfilepath):
|
BanManager::BanManager(const std::string &banfilepath):
|
||||||
m_banfilepath(banfilepath),
|
m_banfilepath(banfilepath),
|
||||||
|
@ -76,20 +77,20 @@ void BanManager::save()
|
||||||
{
|
{
|
||||||
JMutexAutoLock lock(m_mutex);
|
JMutexAutoLock lock(m_mutex);
|
||||||
infostream<<"BanManager: saving to "<<m_banfilepath<<std::endl;
|
infostream<<"BanManager: saving to "<<m_banfilepath<<std::endl;
|
||||||
std::ofstream os(m_banfilepath.c_str(), std::ios::binary);
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
|
|
||||||
if(os.good() == false)
|
|
||||||
{
|
|
||||||
infostream<<"BanManager: failed saving to "<<m_banfilepath<<std::endl;
|
|
||||||
throw SerializationError("BanManager::load(): Couldn't open file");
|
|
||||||
}
|
|
||||||
|
|
||||||
for(std::map<std::string, std::string>::iterator
|
for(std::map<std::string, std::string>::iterator
|
||||||
i = m_ips.begin();
|
i = m_ips.begin();
|
||||||
i != m_ips.end(); i++)
|
i != m_ips.end(); i++)
|
||||||
{
|
{
|
||||||
os<<i->first<<"|"<<i->second<<"\n";
|
ss << i->first << "|" << i->second << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!fs::safeWriteToFile(m_banfilepath, ss.str())) {
|
||||||
|
infostream<<"BanManager: failed saving to "<<m_banfilepath<<std::endl;
|
||||||
|
throw SerializationError("BanManager::load(): Couldn't write file");
|
||||||
|
}
|
||||||
|
|
||||||
m_modified = false;
|
m_modified = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -437,13 +437,13 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
|
||||||
if(player->checkModified())
|
if(player->checkModified())
|
||||||
{
|
{
|
||||||
// Open file and serialize
|
// Open file and serialize
|
||||||
std::ofstream os(path.c_str(), std::ios_base::binary);
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
if(os.good() == false)
|
player->serialize(ss);
|
||||||
|
if(!fs::safeWriteToFile(path, ss.str()))
|
||||||
{
|
{
|
||||||
infostream<<"Failed to overwrite "<<path<<std::endl;
|
infostream<<"Failed to write "<<path<<std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
player->serialize(os);
|
|
||||||
saved_players.insert(player);
|
saved_players.insert(player);
|
||||||
} else {
|
} else {
|
||||||
saved_players.insert(player);
|
saved_players.insert(player);
|
||||||
|
@ -493,13 +493,13 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
|
||||||
/*infostream<<"Saving player "<<player->getName()<<" to "
|
/*infostream<<"Saving player "<<player->getName()<<" to "
|
||||||
<<path<<std::endl;*/
|
<<path<<std::endl;*/
|
||||||
// Open file and serialize
|
// Open file and serialize
|
||||||
std::ofstream os(path.c_str(), std::ios_base::binary);
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
if(os.good() == false)
|
player->serialize(ss);
|
||||||
|
if(!fs::safeWriteToFile(path, ss.str()))
|
||||||
{
|
{
|
||||||
infostream<<"Failed to overwrite "<<path<<std::endl;
|
infostream<<"Failed to write "<<path<<std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
player->serialize(os);
|
|
||||||
saved_players.insert(player);
|
saved_players.insert(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -581,19 +581,20 @@ void ServerEnvironment::saveMeta(const std::string &savedir)
|
||||||
std::string path = savedir + "/env_meta.txt";
|
std::string path = savedir + "/env_meta.txt";
|
||||||
|
|
||||||
// Open file and serialize
|
// Open file and serialize
|
||||||
std::ofstream os(path.c_str(), std::ios_base::binary);
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
if(os.good() == false)
|
|
||||||
{
|
|
||||||
infostream<<"ServerEnvironment::saveMeta(): Failed to open "
|
|
||||||
<<path<<std::endl;
|
|
||||||
throw SerializationError("Couldn't save env meta");
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings args;
|
Settings args;
|
||||||
args.setU64("game_time", m_game_time);
|
args.setU64("game_time", m_game_time);
|
||||||
args.setU64("time_of_day", getTimeOfDay());
|
args.setU64("time_of_day", getTimeOfDay());
|
||||||
args.writeLines(os);
|
args.writeLines(ss);
|
||||||
os<<"EnvArgsEnd\n";
|
ss<<"EnvArgsEnd\n";
|
||||||
|
|
||||||
|
if(!fs::safeWriteToFile(path, ss.str()))
|
||||||
|
{
|
||||||
|
infostream<<"ServerEnvironment::saveMeta(): Failed to write "
|
||||||
|
<<path<<std::endl;
|
||||||
|
throw SerializationError("Couldn't save env meta");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerEnvironment::loadMeta(const std::string &savedir)
|
void ServerEnvironment::loadMeta(const std::string &savedir)
|
||||||
|
|
|
@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <fstream>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
namespace fs
|
namespace fs
|
||||||
|
@ -684,5 +686,28 @@ std::string RemoveRelativePathComponents(std::string path)
|
||||||
return path.substr(0, pos);
|
return path.substr(0, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool safeWriteToFile(const std::string &path, const std::string &content)
|
||||||
|
{
|
||||||
|
std::string tmp_file = path + ".~mt";
|
||||||
|
|
||||||
|
// Write to a tmp file
|
||||||
|
std::ofstream os(tmp_file.c_str(), std::ios::binary);
|
||||||
|
if (!os.good())
|
||||||
|
return false;
|
||||||
|
os << content;
|
||||||
|
os.flush();
|
||||||
|
os.close();
|
||||||
|
if (os.fail())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Copy file
|
||||||
|
#ifdef _WIN32
|
||||||
|
remove(path.c_str());
|
||||||
|
return (rename(tmp_file.c_str(), path.c_str()) == 0);
|
||||||
|
#else
|
||||||
|
return (rename(tmp_file.c_str(), path.c_str()) == 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace fs
|
} // namespace fs
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,8 @@ std::string RemoveLastPathComponent(std::string path,
|
||||||
// this does not resolve symlinks and check for existence of directories.
|
// this does not resolve symlinks and check for existence of directories.
|
||||||
std::string RemoveRelativePathComponents(std::string path);
|
std::string RemoveRelativePathComponents(std::string path);
|
||||||
|
|
||||||
|
bool safeWriteToFile(const std::string &path, const std::string &content);
|
||||||
|
|
||||||
}//fs
|
}//fs
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
28
src/map.cpp
28
src/map.cpp
|
@ -3490,20 +3490,21 @@ void ServerMap::saveMapMeta()
|
||||||
createDirs(m_savedir);
|
createDirs(m_savedir);
|
||||||
|
|
||||||
std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt";
|
std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt";
|
||||||
std::ofstream os(fullpath.c_str(), std::ios_base::binary);
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
if(os.good() == false)
|
|
||||||
{
|
|
||||||
infostream<<"ERROR: ServerMap::saveMapMeta(): "
|
|
||||||
<<"could not open"<<fullpath<<std::endl;
|
|
||||||
throw FileNotGoodException("Cannot open chunk metadata");
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings params;
|
Settings params;
|
||||||
|
|
||||||
m_emerge->setParamsToSettings(¶ms);
|
m_emerge->setParamsToSettings(¶ms);
|
||||||
params.writeLines(os);
|
params.writeLines(ss);
|
||||||
|
|
||||||
os<<"[end_of_params]\n";
|
ss<<"[end_of_params]\n";
|
||||||
|
|
||||||
|
if(!fs::safeWriteToFile(fullpath, ss.str()))
|
||||||
|
{
|
||||||
|
infostream<<"ERROR: ServerMap::saveMapMeta(): "
|
||||||
|
<<"could not write "<<fullpath<<std::endl;
|
||||||
|
throw FileNotGoodException("Cannot save chunk metadata");
|
||||||
|
}
|
||||||
|
|
||||||
m_map_metadata_changed = false;
|
m_map_metadata_changed = false;
|
||||||
}
|
}
|
||||||
|
@ -3574,11 +3575,12 @@ void ServerMap::saveSectorMeta(ServerMapSector *sector)
|
||||||
createDirs(dir);
|
createDirs(dir);
|
||||||
|
|
||||||
std::string fullpath = dir + DIR_DELIM + "meta";
|
std::string fullpath = dir + DIR_DELIM + "meta";
|
||||||
std::ofstream o(fullpath.c_str(), std::ios_base::binary);
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
if(o.good() == false)
|
|
||||||
throw FileNotGoodException("Cannot open sector metafile");
|
|
||||||
|
|
||||||
sector->serialize(o, version);
|
sector->serialize(ss, version);
|
||||||
|
|
||||||
|
if(!fs::safeWriteToFile(fullpath, ss.str()))
|
||||||
|
throw FileNotGoodException("Cannot write sector metafile");
|
||||||
|
|
||||||
sector->differs_from_disk = false;
|
sector->differs_from_disk = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "mapgen_v6.h"
|
#include "mapgen_v6.h"
|
||||||
#include "mapgen_v7.h"
|
#include "mapgen_v7.h"
|
||||||
#include "util/serialize.h"
|
#include "util/serialize.h"
|
||||||
|
#include "filesys.h"
|
||||||
|
|
||||||
FlagDesc flagdesc_mapgen[] = {
|
FlagDesc flagdesc_mapgen[] = {
|
||||||
{"trees", MG_TREES},
|
{"trees", MG_TREES},
|
||||||
|
@ -756,24 +757,26 @@ bool DecoSchematic::loadSchematicFile() {
|
||||||
2 - Fixed messy never/always place; 0 probability is now never, 0xFF is always
|
2 - Fixed messy never/always place; 0 probability is now never, 0xFF is always
|
||||||
*/
|
*/
|
||||||
void DecoSchematic::saveSchematicFile(INodeDefManager *ndef) {
|
void DecoSchematic::saveSchematicFile(INodeDefManager *ndef) {
|
||||||
std::ofstream os(filename.c_str(), std::ios_base::binary);
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
|
|
||||||
writeU32(os, MTSCHEM_FILE_SIGNATURE); // signature
|
writeU32(ss, MTSCHEM_FILE_SIGNATURE); // signature
|
||||||
writeU16(os, 2); // version
|
writeU16(ss, 2); // version
|
||||||
writeV3S16(os, size); // schematic size
|
writeV3S16(ss, size); // schematic size
|
||||||
|
|
||||||
std::vector<content_t> usednodes;
|
std::vector<content_t> usednodes;
|
||||||
int nodecount = size.X * size.Y * size.Z;
|
int nodecount = size.X * size.Y * size.Z;
|
||||||
build_nnlist_and_update_ids(schematic, nodecount, &usednodes);
|
build_nnlist_and_update_ids(schematic, nodecount, &usednodes);
|
||||||
|
|
||||||
u16 numids = usednodes.size();
|
u16 numids = usednodes.size();
|
||||||
writeU16(os, numids); // name count
|
writeU16(ss, numids); // name count
|
||||||
for (int i = 0; i != numids; i++)
|
for (int i = 0; i != numids; i++)
|
||||||
os << serializeString(ndef->get(usednodes[i]).name); // node names
|
ss << serializeString(ndef->get(usednodes[i]).name); // node names
|
||||||
|
|
||||||
// compressed bulk node data
|
// compressed bulk node data
|
||||||
MapNode::serializeBulk(os, SER_FMT_VER_HIGHEST_WRITE, schematic,
|
MapNode::serializeBulk(ss, SER_FMT_VER_HIGHEST_WRITE, schematic,
|
||||||
nodecount, 2, 2, true);
|
nodecount, 2, 2, true);
|
||||||
|
|
||||||
|
fs::safeWriteToFile(filename, ss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -105,13 +105,11 @@ bool deleteEntry (ServerListSpec server)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string path = ServerList::getFilePath();
|
std::string path = ServerList::getFilePath();
|
||||||
std::ofstream stream (path.c_str());
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
if (stream.is_open())
|
ss << ServerList::serialize(serverlist);
|
||||||
{
|
if (!fs::safeWriteToFile(path, ss.str()))
|
||||||
stream<<ServerList::serialize(serverlist);
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -128,11 +126,9 @@ bool insert (ServerListSpec server)
|
||||||
serverlist.insert(serverlist.begin(), server);
|
serverlist.insert(serverlist.begin(), server);
|
||||||
|
|
||||||
std::string path = ServerList::getFilePath();
|
std::string path = ServerList::getFilePath();
|
||||||
std::ofstream stream (path.c_str());
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
if (stream.is_open())
|
ss << ServerList::serialize(serverlist);
|
||||||
{
|
fs::safeWriteToFile(path, ss.str());
|
||||||
stream<<ServerList::serialize(serverlist);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include "filesys.h"
|
||||||
|
|
||||||
enum ValueType
|
enum ValueType
|
||||||
{
|
{
|
||||||
|
@ -308,14 +309,7 @@ public:
|
||||||
|
|
||||||
// Write stuff back
|
// Write stuff back
|
||||||
{
|
{
|
||||||
std::ofstream os(filename);
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
if(os.good() == false)
|
|
||||||
{
|
|
||||||
errorstream<<"Error opening configuration file"
|
|
||||||
" for writing: \""
|
|
||||||
<<filename<<"\""<<std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Write updated stuff
|
Write updated stuff
|
||||||
|
@ -324,7 +318,7 @@ public:
|
||||||
i = objects.begin();
|
i = objects.begin();
|
||||||
i != objects.end(); ++i)
|
i != objects.end(); ++i)
|
||||||
{
|
{
|
||||||
os<<(*i);
|
ss<<(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -340,7 +334,14 @@ public:
|
||||||
std::string value = i->second;
|
std::string value = i->second;
|
||||||
infostream<<"Adding \""<<name<<"\" = \""<<value<<"\""
|
infostream<<"Adding \""<<name<<"\" = \""<<value<<"\""
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
os<<name<<" = "<<value<<"\n";
|
ss<<name<<" = "<<value<<"\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!fs::safeWriteToFile(filename, ss.str()))
|
||||||
|
{
|
||||||
|
errorstream<<"Error writing configuration file: \""
|
||||||
|
<<filename<<"\""<<std::endl;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -241,8 +241,9 @@ bool initializeWorld(const std::string &path, const std::string &gameid)
|
||||||
if(!fs::PathExists(worldmt_path)){
|
if(!fs::PathExists(worldmt_path)){
|
||||||
infostream<<"Creating world.mt ("<<worldmt_path<<")"<<std::endl;
|
infostream<<"Creating world.mt ("<<worldmt_path<<")"<<std::endl;
|
||||||
fs::CreateAllDirs(path);
|
fs::CreateAllDirs(path);
|
||||||
std::ofstream of(worldmt_path.c_str(), std::ios::binary);
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
of<<"gameid = "<<gameid<<"\n";
|
ss<<"gameid = "<<gameid<<"\n";
|
||||||
|
fs::safeWriteToFile(worldmt_path, ss.str());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue