bool CScenarioValidator::setScenarioToLoad( const std::string& filename, CScenarioValidator::TValues& values, std::string& md5, std::string& signature, bool checkMD5) { values.clear(); _Filename = filename; _Values.clear(); // open our input file NLMISC::CIFile inf; if (!inf.open(_Filename, true) ) { nlwarning("Can't load scenario %s", _Filename.c_str()); return false; } try { static const char * header = "---- Header\n"; static const char * slashheader = "---- /Header\n\n"; static const char * comment = "-- "; static const unsigned int headerLen = (unsigned int)strlen(header); static const unsigned int slasheaderLen = (unsigned int)strlen(slashheader); static const unsigned int commentLen = (unsigned int)strlen(comment); NLMISC::CSString tmp; tmp.resize( inf.getFileSize() ); inf.serialBuffer((uint8*)&tmp[0], (uint)tmp.size()); _ScenarioBody = tmp.replace("\r\n", "\n"); // Scenario without header if (_ScenarioBody.size() < headerLen ||_ScenarioBody.substr(0, headerLen) != header ) { md5 = ""; signature = ""; inf.close(); return true; } std::string::size_type endHeader = _ScenarioBody.find(slashheader, headerLen); if (endHeader == std::string::npos ) { inf.close(); return false; } std::string::size_type startHeader = headerLen; std::vector<std::string> lines; NLMISC::splitString( _ScenarioBody.substr(startHeader, endHeader - startHeader), "'\n", lines); std::vector<std::string>::const_iterator firstLine(lines.begin()), lastLine(lines.end()); std::vector<std::string> result; for (; firstLine != lastLine ; ++firstLine) { result.clear(); NLMISC::splitString(*firstLine, " = '", result); if (result.size() == 1) { result.push_back(""); } if (result.size() == 2) { if (result[0].find(comment) != std::string::npos) { //>result[1]"\\n" => "\n" NLMISC::CSString tmp = result[1]; tmp = tmp.replace("\\n", "\n"); values.push_back( std::make_pair( result[0].substr(commentLen), tmp)); } } } if (values.size() >=2 && values[0].first == "Version" && values[1].first == "Signature" && values[2].first == "HeaderMD5" && values[3].first =="BodyMD5") { std::string headerBodyMd5; std::string::size_type subHeader = _ScenarioBody.find("-- BodyMD5", startHeader); if (checkMD5) { std::string md5Id1 = NLMISC::getMD5((uint8*)(_ScenarioBody.data() + subHeader), (uint32)(endHeader - subHeader)).toString(); if (values[2].second != md5Id1 ) { return false; } std::string md5Id2 = NLMISC::getMD5((uint8*)(_ScenarioBody.data() + endHeader + slasheaderLen), (uint32)(_ScenarioBody.size() - (endHeader + slasheaderLen))).toString(); if (values[3].second != md5Id2) { return false; } } md5 = values[2].second; signature = values[1].second; } } catch(...) { _Values = values; nlwarning("Can't load scenario %s", _Filename.c_str()); return false; } _Values = values; // close the file inf.close(); return true; }
IFileAccess::TReturnCode CLoadFile::execute(CFileAccessManager& manager) { bool fileExists = NLMISC::CFile::fileExists(getBackupFileName(Filename)); if (!fileExists && checkFailureMode(MajorFailureIfFileNotExists)) { FailureReason = NLMISC::toString("MAJOR_FAILURE:LOAD: file '%s' doesn't not exist", Filename.c_str()); return MajorFailure; } CBackupMsgReceiveFile outMsg; outMsg.RequestId = RequestId; NLMISC::CIFile f; bool fileOpen = (fileExists && f.open(getBackupFileName(Filename))); bool fileRead = false; if (fileOpen) { outMsg.FileDescription.set(getBackupFileName(Filename)); // restore filename with the provided one for the response outMsg.FileDescription.FileName = Filename; try { H_AUTO(LoadFileSerial); outMsg.Data.invert(); f.serialBuffer( outMsg.Data.bufferToFill(outMsg.FileDescription.FileSize), outMsg.FileDescription.FileSize); outMsg.Data.invert(); fileRead = true; f.close(); } catch(const NLMISC::Exception &) { } } if (!fileRead && checkFailureMode(MajorFailureIfFileUnreaddable)) { FailureReason = NLMISC::toString("MAJOR_FAILURE:LOAD: can't %s file '%s'", (!fileOpen ? "open" : "read"), Filename.c_str()); return MajorFailure; } // outMsg.send(Requester); switch (Requester.RequesterType) { case TRequester::rt_service: { H_AUTO(CBackupMsgReceiveFile1); NLNET::CMessage msgOut("bs_file"); outMsg.serial(msgOut); NLNET::CUnifiedNetwork::getInstance()->send( Requester.ServiceId, msgOut ); } break; case TRequester::rt_layer3: { NLNET::CMessage msgOut("bs_file"); outMsg.serial(msgOut); Requester.Netbase->send(msgOut, Requester.From); } break; case TRequester::rt_module: { BS::CBackupServiceClientProxy bsc(Requester.ModuleProxy); bsc.loadFileResult(CBackupService::getInstance()->getBackupModule(), RequestId, outMsg.FileDescription.FileName, outMsg.FileDescription.FileTimeStamp, NLNET::TBinBuffer(outMsg.Data.buffer(), outMsg.Data.length())); } } // If the file read failed for any other reason than file not found then complain if (!fileRead && fileExists) { FailureReason = NLMISC::toString("MINOR_FAILURE:LOAD: can't %s file '%s'", (!fileOpen ? "open" : "read"), Filename.c_str()); return MinorFailure; } if (VerboseLog) { // We can assume that this is the only case where the file read failed that hasn't already been treated above if (!fileExists) { nldebug("Load file Failed (but MajorFailureIfFileUnreaddable==false): file '%s' doesn't not exist", Filename.c_str()); } else { nlinfo("Loaded file '%s'", Filename.c_str()); } } return Success; }