diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ban.cpp | 17 | ||||
-rw-r--r-- | src/environment.cpp | 35 | ||||
-rw-r--r-- | src/filesys.cpp | 25 | ||||
-rw-r--r-- | src/filesys.h | 2 | ||||
-rw-r--r-- | src/map.cpp | 28 | ||||
-rw-r--r-- | src/mapgen.cpp | 17 | ||||
-rw-r--r-- | src/serverlist.cpp | 20 | ||||
-rw-r--r-- | src/settings.h | 21 | ||||
-rw-r--r-- | src/subgame.cpp | 5 |
9 files changed, 101 insertions, 69 deletions
diff --git a/src/ban.cpp b/src/ban.cpp index 75bae746f..f9d32b605 100644 --- a/src/ban.cpp +++ b/src/ban.cpp @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <set> #include "strfnd.h" #include "log.h" +#include "filesys.h" BanManager::BanManager(const std::string &banfilepath): m_banfilepath(banfilepath), @@ -76,20 +77,20 @@ void BanManager::save() { JMutexAutoLock lock(m_mutex); infostream<<"BanManager: saving to "<<m_banfilepath<<std::endl; - std::ofstream os(m_banfilepath.c_str(), std::ios::binary); - - if(os.good() == false) - { - infostream<<"BanManager: failed saving to "<<m_banfilepath<<std::endl; - throw SerializationError("BanManager::load(): Couldn't open file"); - } + std::ostringstream ss(std::ios_base::binary); for(std::map<std::string, std::string>::iterator i = m_ips.begin(); 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; } diff --git a/src/environment.cpp b/src/environment.cpp index 35983aaaf..eacc2a008 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -437,13 +437,13 @@ void ServerEnvironment::serializePlayers(const std::string &savedir) if(player->checkModified()) { // Open file and serialize - std::ofstream os(path.c_str(), std::ios_base::binary); - if(os.good() == false) + std::ostringstream ss(std::ios_base::binary); + player->serialize(ss); + if(!fs::safeWriteToFile(path, ss.str())) { - infostream<<"Failed to overwrite "<<path<<std::endl; + infostream<<"Failed to write "<<path<<std::endl; continue; } - player->serialize(os); saved_players.insert(player); } else { saved_players.insert(player); @@ -493,13 +493,13 @@ void ServerEnvironment::serializePlayers(const std::string &savedir) /*infostream<<"Saving player "<<player->getName()<<" to " <<path<<std::endl;*/ // Open file and serialize - std::ofstream os(path.c_str(), std::ios_base::binary); - if(os.good() == false) + std::ostringstream ss(std::ios_base::binary); + player->serialize(ss); + if(!fs::safeWriteToFile(path, ss.str())) { - infostream<<"Failed to overwrite "<<path<<std::endl; + infostream<<"Failed to write "<<path<<std::endl; continue; } - player->serialize(os); saved_players.insert(player); } } @@ -581,19 +581,20 @@ void ServerEnvironment::saveMeta(const std::string &savedir) std::string path = savedir + "/env_meta.txt"; // Open file and serialize - std::ofstream os(path.c_str(), std::ios_base::binary); - if(os.good() == false) - { - infostream<<"ServerEnvironment::saveMeta(): Failed to open " - <<path<<std::endl; - throw SerializationError("Couldn't save env meta"); - } + std::ostringstream ss(std::ios_base::binary); Settings args; args.setU64("game_time", m_game_time); args.setU64("time_of_day", getTimeOfDay()); - args.writeLines(os); - os<<"EnvArgsEnd\n"; + args.writeLines(ss); + 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) diff --git a/src/filesys.cpp b/src/filesys.cpp index 356d3018d..a1795c8ea 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <stdio.h> #include <string.h> #include <errno.h> +#include <sstream> +#include <fstream> #include "log.h" namespace fs @@ -684,5 +686,28 @@ std::string RemoveRelativePathComponents(std::string path) 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 diff --git a/src/filesys.h b/src/filesys.h index d0bf400c7..1b3659afe 100644 --- a/src/filesys.h +++ b/src/filesys.h @@ -98,6 +98,8 @@ std::string RemoveLastPathComponent(std::string path, // this does not resolve symlinks and check for existence of directories. std::string RemoveRelativePathComponents(std::string path); +bool safeWriteToFile(const std::string &path, const std::string &content); + }//fs #endif diff --git a/src/map.cpp b/src/map.cpp index da20b5b0e..331aa48d9 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -3490,20 +3490,21 @@ void ServerMap::saveMapMeta() createDirs(m_savedir); std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt"; - std::ofstream os(fullpath.c_str(), std::ios_base::binary); - if(os.good() == false) - { - infostream<<"ERROR: ServerMap::saveMapMeta(): " - <<"could not open"<<fullpath<<std::endl; - throw FileNotGoodException("Cannot open chunk metadata"); - } + std::ostringstream ss(std::ios_base::binary); Settings params; 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; } @@ -3574,11 +3575,12 @@ void ServerMap::saveSectorMeta(ServerMapSector *sector) createDirs(dir); std::string fullpath = dir + DIR_DELIM + "meta"; - std::ofstream o(fullpath.c_str(), std::ios_base::binary); - if(o.good() == false) - throw FileNotGoodException("Cannot open sector metafile"); + std::ostringstream ss(std::ios_base::binary); + + sector->serialize(ss, version); - sector->serialize(o, version); + if(!fs::safeWriteToFile(fullpath, ss.str())) + throw FileNotGoodException("Cannot write sector metafile"); sector->differs_from_disk = false; } diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 97d672b01..be65694aa 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapgen_v6.h" #include "mapgen_v7.h" #include "util/serialize.h" +#include "filesys.h" FlagDesc flagdesc_mapgen[] = { {"trees", MG_TREES}, @@ -756,24 +757,26 @@ bool DecoSchematic::loadSchematicFile() { 2 - Fixed messy never/always place; 0 probability is now never, 0xFF is always */ 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 - writeU16(os, 2); // version - writeV3S16(os, size); // schematic size + writeU32(ss, MTSCHEM_FILE_SIGNATURE); // signature + writeU16(ss, 2); // version + writeV3S16(ss, size); // schematic size std::vector<content_t> usednodes; int nodecount = size.X * size.Y * size.Z; build_nnlist_and_update_ids(schematic, nodecount, &usednodes); u16 numids = usednodes.size(); - writeU16(os, numids); // name count + writeU16(ss, numids); // name count 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 - MapNode::serializeBulk(os, SER_FMT_VER_HIGHEST_WRITE, schematic, + MapNode::serializeBulk(ss, SER_FMT_VER_HIGHEST_WRITE, schematic, nodecount, 2, 2, true); + + fs::safeWriteToFile(filename, ss.str()); } diff --git a/src/serverlist.cpp b/src/serverlist.cpp index bc09f6c0a..4db5f3ecd 100644 --- a/src/serverlist.cpp +++ b/src/serverlist.cpp @@ -105,13 +105,11 @@ bool deleteEntry (ServerListSpec server) } std::string path = ServerList::getFilePath(); - std::ofstream stream (path.c_str()); - if (stream.is_open()) - { - stream<<ServerList::serialize(serverlist); - return true; - } - return false; + std::ostringstream ss(std::ios_base::binary); + ss << ServerList::serialize(serverlist); + if (!fs::safeWriteToFile(path, ss.str())) + return false; + return true; } /* @@ -128,11 +126,9 @@ bool insert (ServerListSpec server) serverlist.insert(serverlist.begin(), server); std::string path = ServerList::getFilePath(); - std::ofstream stream (path.c_str()); - if (stream.is_open()) - { - stream<<ServerList::serialize(serverlist); - } + std::ostringstream ss(std::ios_base::binary); + ss << ServerList::serialize(serverlist); + fs::safeWriteToFile(path, ss.str()); return false; } diff --git a/src/settings.h b/src/settings.h index e7b49b6d7..a9e0faa40 100644 --- a/src/settings.h +++ b/src/settings.h @@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <list> #include <map> #include <set> +#include "filesys.h" enum ValueType { @@ -308,14 +309,7 @@ public: // Write stuff back { - std::ofstream os(filename); - if(os.good() == false) - { - errorstream<<"Error opening configuration file" - " for writing: \"" - <<filename<<"\""<<std::endl; - return false; - } + std::ostringstream ss(std::ios_base::binary); /* Write updated stuff @@ -324,7 +318,7 @@ public: i = objects.begin(); i != objects.end(); ++i) { - os<<(*i); + ss<<(*i); } /* @@ -340,7 +334,14 @@ public: std::string value = i->second; infostream<<"Adding \""<<name<<"\" = \""<<value<<"\"" <<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; } } diff --git a/src/subgame.cpp b/src/subgame.cpp index 7fee3899d..806d65934 100644 --- a/src/subgame.cpp +++ b/src/subgame.cpp @@ -241,8 +241,9 @@ bool initializeWorld(const std::string &path, const std::string &gameid) if(!fs::PathExists(worldmt_path)){ infostream<<"Creating world.mt ("<<worldmt_path<<")"<<std::endl; fs::CreateAllDirs(path); - std::ofstream of(worldmt_path.c_str(), std::ios::binary); - of<<"gameid = "<<gameid<<"\n"; + std::ostringstream ss(std::ios_base::binary); + ss<<"gameid = "<<gameid<<"\n"; + fs::safeWriteToFile(worldmt_path, ss.str()); } return true; } |