+#include "../../include/freenet/fmsversionrequester.h"\r
+#include "../../include/freenet/fmsversionxml.h"\r
+#include "../../include/option.h"\r
+#include "../../include/stringfunctions.h"\r
+\r
+#include <Poco/Timestamp.h>\r
+#include <Poco/Timespan.h>\r
+\r
+FMSVersionRequester::FMSVersionRequester()\r
+{\r
+ Initialize();\r
+}\r
+\r
+FMSVersionRequester::FMSVersionRequester(FCPv2 *fcp):IFCPConnected(fcp)\r
+{\r
+ Initialize();\r
+}\r
+\r
+const bool FMSVersionRequester::HandleAllData(FCPMessage &message)\r
+{\r
+ std::vector<char> data;\r
+ long datalength;\r
+ FMSVersionXML xml;\r
+\r
+ StringFunctions::Convert(message["DataLength"],datalength);\r
+\r
+ // wait for all data to be received from connection\r
+ while(m_fcp->Connected() && m_fcp->ReceiveBufferSize()<datalength)\r
+ {\r
+ m_fcp->Update(1);\r
+ }\r
+\r
+ // if we got disconnected- return immediately\r
+ if(m_fcp->Connected()==false)\r
+ {\r
+ return false;\r
+ }\r
+\r
+ // receive the file\r
+ data.resize(datalength);\r
+ m_fcp->ReceiveRaw(&data[0],datalength);\r
+\r
+ // update latest edition #\r
+ std::vector<std::string> parts;\r
+ StringFunctions::Split(message["Identifier"],"/",parts);\r
+ if(parts.size()>2)\r
+ {\r
+ std::string editionstr=parts[2];\r
+ Option::Instance()->Set("FMSVersionEdition",editionstr);\r
+ }\r
+\r
+ // parse file into xml and update the database\r
+ if(xml.ParseXML(std::string(data.begin(),data.end()))==true)\r
+ {\r
+\r
+ SQLite3DB::Statement st=m_db->Prepare("REPLACE INTO tblFMSVersion(Major,Minor,Release,Notes,Changes,PageKey,SourceKey) VALUES(?,?,?,?,?,?,?);");\r
+ st.Bind(0,xml.GetMajor());\r
+ st.Bind(1,xml.GetMinor());\r
+ st.Bind(2,xml.GetRelease());\r
+ st.Bind(3,xml.GetNotes());\r
+ st.Bind(4,xml.GetChanges());\r
+ st.Bind(5,xml.GetPageKey());\r
+ st.Bind(6,xml.GetSourceKey());\r
+ st.Step();\r
+\r
+ m_log->debug("FMSVersionRequester::HandleAllData parsed FMSVersion XML file : "+message["Identifier"]);\r
+ }\r
+ else\r
+ {\r
+ m_log->error("FMSVersionRequester::HandleAllData error parsing FMSVersion XML file : "+message["Identifier"]);\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+const bool FMSVersionRequester::HandleGetFailed(FCPMessage &message)\r
+{\r
+ std::vector<std::string> parts;\r
+ StringFunctions::Split(message["Identifier"],"/",parts);\r
+\r
+ // fatal error - don't try to download again\r
+ if(message["Fatal"]=="true")\r
+ {\r
+ if(parts.size()>2)\r
+ {\r
+ std::string editionstr=parts[2];\r
+ Option::Instance()->Set("FMSVersionEdition",editionstr);\r
+ }\r
+ m_log->debug("FMSVersionRequester::HandleGetFailed Fatal GetFailed for "+message["Identifier"]);\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+const bool FMSVersionRequester::HandleMessage(FCPMessage &message)\r
+{\r
+ if(message["Identifier"].find(m_fcpuniquename)==0)\r
+ {\r
+ \r
+ // ignore DataFound\r
+ if(message.GetName()=="DataFound")\r
+ {\r
+ return true;\r
+ }\r
+\r
+ if(message.GetName()=="AllData")\r
+ {\r
+ return HandleAllData(message);\r
+ }\r
+\r
+ if(message.GetName()=="GetFailed")\r
+ {\r
+ return HandleGetFailed(message);\r
+ }\r
+\r
+ if(message.GetName()=="IdentifierCollision")\r
+ {\r
+ return true;\r
+ }\r
+\r
+ }\r
+\r
+ return false; \r
+}\r
+\r
+void FMSVersionRequester::Initialize()\r
+{\r
+ m_fcpuniquename="FMSVersionRequester";\r
+ m_lastchecked=Poco::Timestamp();\r
+ m_lastchecked-=Poco::Timespan(0,6,0,0,0);\r
+}\r
+\r
+void FMSVersionRequester::Process()\r
+{\r
+ Poco::DateTime now;\r
+\r
+ // check every 6 hours\r
+ if((m_lastchecked+Poco::Timespan(0,5,45,0,0))<=now)\r
+ {\r
+ StartRequest();\r
+ m_lastchecked=now;\r
+ }\r
+}\r
+\r
+void FMSVersionRequester::RegisterWithThread(FreenetMasterThread *thread)\r
+{\r
+ thread->RegisterFCPConnected(this);\r
+ thread->RegisterFCPMessageHandler(this);\r
+ thread->RegisterPeriodicProcessor(this);\r
+}\r
+\r
+void FMSVersionRequester::StartRequest()\r
+{\r
+ FCPMessage message;\r
+ std::string key="";\r
+ std::string editionstr="0";\r
+ int edition=0;\r
+ \r
+ Option::Instance()->Get("FMSVersionKey",key);\r
+ if(Option::Instance()->Get("FMSVersionEdition",editionstr))\r
+ {\r
+ StringFunctions::Convert(editionstr,edition);\r
+ edition++;\r
+ StringFunctions::Convert(edition,editionstr);\r
+ }\r
+\r
+ //start request\r
+ message.SetName("ClientGet");\r
+ message["URI"]=key+editionstr+"/FMSVersion.xml";\r
+ message["Identifier"]=m_fcpuniquename+"|"+message["URI"];\r
+ message["ReturnType"]="direct";\r
+ message["MaxSize"]="30000"; // 30K\r
+\r
+ m_fcp->SendMessage(message);\r
+\r
+}\r