/* */ #include "DHTAutoSaveCommand.h" #include "DHTRoutingTable.h" #include "DHTNode.h" #include "File.h" #include "DHTRoutingTableSerializer.h" #include "RecoverableException.h" #include "DownloadEngine.h" #include "Util.h" #include "DHTBucket.h" #include "RequestGroupMan.h" #include "prefs.h" #include "Option.h" #include "message.h" #include "Logger.h" #include #include #include namespace aria2 { DHTAutoSaveCommand::DHTAutoSaveCommand(int32_t cuid, DownloadEngine* e, time_t interval): TimeBasedCommand(cuid, e, interval) {} DHTAutoSaveCommand::~DHTAutoSaveCommand() {} void DHTAutoSaveCommand::preProcess() { if(_e->_requestGroupMan->downloadFinished() || _e->isHaltRequested()) { save(); _exit = true; } } void DHTAutoSaveCommand::process() { save(); } void DHTAutoSaveCommand::save() { std::string dhtFile = _e->option->get(PREF_DHT_FILE_PATH); logger->info("Saving DHT routing table to %s.", dhtFile.c_str()); std::string tempFile = dhtFile+"__temp"; { File f(tempFile); if(!f.isFile()) { File dir(f.getDirname()); if(!dir.exists()) { if(!dir.mkdirs()) { logger->info(EX_MAKE_DIR, dir.getPath().c_str(), strerror(errno)); return; } } else if(!dir.isDir()) { logger->info(EX_NOT_DIRECTORY, dir.getPath().c_str()); return; } } } std::deque > nodes; std::deque > buckets = _routingTable->getBuckets(); for(std::deque >::const_iterator i = buckets.begin(); i != buckets.end(); ++i) { const SharedHandle& bucket = *i; std::deque > goodNodes = bucket->getGoodNodes(); nodes.insert(nodes.end(), goodNodes.begin(), goodNodes.end()); } DHTRoutingTableSerializer serializer; serializer.setLocalNode(_localNode); serializer.setNodes(nodes); try { std::ofstream o(tempFile.c_str(), std::ios::out|std::ios::binary); o.exceptions(std::ios::failbit); serializer.serialize(o); if(!File(tempFile).renameTo(dhtFile)) { logger->error("Cannot move file from %s to %s.", tempFile.c_str(), dhtFile.c_str()); } } catch(std::ios::failure const& e) { logger->error("Failed to save DHT routing table to %s. cause:%s", tempFile.c_str(), strerror(errno)); } catch(RecoverableException* e) { logger->error("Exception caught while saving DHT routing table to %s", e, tempFile.c_str()); delete e; } } void DHTAutoSaveCommand::setLocalNode(const SharedHandle& localNode) { _localNode = localNode; } void DHTAutoSaveCommand::setRoutingTable(const SharedHandle& routingTable) { _routingTable = routingTable; } } // namespace aria2