/* */ #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 #include DHTAutoSaveCommand::DHTAutoSaveCommand(int32_t cuid, DownloadEngine* e, int32_t interval): TimeBasedCommand(cuid, e, interval), _localNode(0), _routingTable(0) {} DHTAutoSaveCommand::~DHTAutoSaveCommand() {} void DHTAutoSaveCommand::preProcess() { if(_e->_requestGroupMan->downloadFinished() || _e->isHaltRequested()) { save(); _exit = true; } } void DHTAutoSaveCommand::process() { save(); } void DHTAutoSaveCommand::save() { string dhtFile = _e->option->get(PREF_DHT_FILE_PATH); logger->info("Saving DHT routing table to %s.", dhtFile.c_str()); 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; } } } DHTNodes nodes; DHTBuckets buckets = _routingTable->getBuckets(); for(DHTBuckets::const_iterator i = buckets.begin(); i != buckets.end(); ++i) { const DHTBucketHandle& bucket = *i; DHTNodes goodNodes = bucket->getGoodNodes(); nodes.insert(nodes.end(), goodNodes.begin(), goodNodes.end()); } DHTRoutingTableSerializer serializer; serializer.setLocalNode(_localNode); serializer.setNodes(nodes); try { ofstream o(tempFile.c_str(), ios::out|ios::binary); o.exceptions(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(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 DHTNodeHandle& localNode) { _localNode = localNode; } void DHTAutoSaveCommand::setRoutingTable(const DHTRoutingTableHandle& routingTable) { _routingTable = routingTable; }