version 0.3.20
[fms.git] / src / freenet / fmsversionrequester.cpp
1 #include "../../include/freenet/fmsversionrequester.h"\r
2 #include "../../include/freenet/fmsversionxml.h"\r
3 #include "../../include/option.h"\r
4 #include "../../include/stringfunctions.h"\r
5 \r
6 #include <Poco/Timestamp.h>\r
7 #include <Poco/Timespan.h>\r
8 \r
9 FMSVersionRequester::FMSVersionRequester()\r
10 {\r
11         Initialize();\r
12 }\r
13 \r
14 FMSVersionRequester::FMSVersionRequester(FCPv2 *fcp):IFCPConnected(fcp)\r
15 {\r
16         Initialize();\r
17 }\r
18 \r
19 const bool FMSVersionRequester::HandleAllData(FCPMessage &message)\r
20 {\r
21         std::vector<char> data;\r
22         long datalength;\r
23         FMSVersionXML xml;\r
24 \r
25         StringFunctions::Convert(message["DataLength"],datalength);\r
26 \r
27         // wait for all data to be received from connection\r
28         while(m_fcp->Connected() && m_fcp->ReceiveBufferSize()<datalength)\r
29         {\r
30                 m_fcp->Update(1);\r
31         }\r
32 \r
33         // if we got disconnected- return immediately\r
34         if(m_fcp->Connected()==false)\r
35         {\r
36                 return false;\r
37         }\r
38 \r
39         // receive the file\r
40         data.resize(datalength);\r
41         if(data.size()>0)\r
42         {\r
43                 m_fcp->ReceiveRaw(&data[0],datalength);\r
44         }\r
45 \r
46         // update latest edition #\r
47         std::vector<std::string> parts;\r
48         StringFunctions::Split(message["Identifier"],"/",parts);\r
49         if(parts.size()>2)\r
50         {\r
51                 std::string editionstr=parts[2];\r
52                 Option::Instance()->Set("FMSVersionEdition",editionstr);\r
53         }\r
54 \r
55         // parse file into xml and update the database\r
56         if(data.size()>0 && xml.ParseXML(std::string(data.begin(),data.end()))==true)\r
57         {\r
58 \r
59                 SQLite3DB::Statement st=m_db->Prepare("REPLACE INTO tblFMSVersion(Major,Minor,Release,Notes,Changes,PageKey,SourceKey) VALUES(?,?,?,?,?,?,?);");\r
60                 st.Bind(0,xml.GetMajor());\r
61                 st.Bind(1,xml.GetMinor());\r
62                 st.Bind(2,xml.GetRelease());\r
63                 st.Bind(3,xml.GetNotes());\r
64                 st.Bind(4,xml.GetChanges());\r
65                 st.Bind(5,xml.GetPageKey());\r
66                 st.Bind(6,xml.GetSourceKey());\r
67                 st.Step();\r
68 \r
69                 m_log->debug("FMSVersionRequester::HandleAllData parsed FMSVersion XML file : "+message["Identifier"]);\r
70         }\r
71         else\r
72         {\r
73                 m_log->error("FMSVersionRequester::HandleAllData error parsing FMSVersion XML file : "+message["Identifier"]);\r
74         }\r
75 \r
76         return true;\r
77 }\r
78 \r
79 const bool FMSVersionRequester::HandleGetFailed(FCPMessage &message)\r
80 {\r
81         std::vector<std::string> parts;\r
82         StringFunctions::Split(message["Identifier"],"/",parts);\r
83 \r
84         // fatal error - don't try to download again\r
85         if(message["Fatal"]=="true")\r
86         {\r
87                 if(parts.size()>2)\r
88                 {\r
89                         std::string editionstr=parts[2];\r
90                         Option::Instance()->Set("FMSVersionEdition",editionstr);\r
91                 }\r
92                 m_log->debug("FMSVersionRequester::HandleGetFailed Fatal GetFailed for "+message["Identifier"]);\r
93         }\r
94 \r
95         return true;\r
96 }\r
97 \r
98 const bool FMSVersionRequester::HandleMessage(FCPMessage &message)\r
99 {\r
100         if(message["Identifier"].find(m_fcpuniquename)==0)\r
101         {\r
102                 \r
103                 // ignore DataFound\r
104                 if(message.GetName()=="DataFound")\r
105                 {\r
106                         return true;\r
107                 }\r
108 \r
109                 if(message.GetName()=="AllData")\r
110                 {\r
111                         return HandleAllData(message);\r
112                 }\r
113 \r
114                 if(message.GetName()=="GetFailed")\r
115                 {\r
116                         return HandleGetFailed(message);\r
117                 }\r
118 \r
119                 if(message.GetName()=="IdentifierCollision")\r
120                 {\r
121                         return true;\r
122                 }\r
123 \r
124         }\r
125 \r
126         return false;   \r
127 }\r
128 \r
129 void FMSVersionRequester::Initialize()\r
130 {\r
131         m_fcpuniquename="FMSVersionRequester";\r
132         m_lastchecked=Poco::Timestamp();\r
133         m_lastchecked-=Poco::Timespan(0,6,0,0,0);\r
134 }\r
135 \r
136 void FMSVersionRequester::Process()\r
137 {\r
138         Poco::DateTime now;\r
139 \r
140         // check every 6 hours\r
141         if((m_lastchecked+Poco::Timespan(0,5,45,0,0))<=now)\r
142         {\r
143                 StartRequest();\r
144                 m_lastchecked=now;\r
145         }\r
146 }\r
147 \r
148 void FMSVersionRequester::RegisterWithThread(FreenetMasterThread *thread)\r
149 {\r
150         thread->RegisterFCPConnected(this);\r
151         thread->RegisterFCPMessageHandler(this);\r
152         thread->RegisterPeriodicProcessor(this);\r
153 }\r
154 \r
155 void FMSVersionRequester::StartRequest()\r
156 {\r
157         FCPMessage message;\r
158         std::string key="";\r
159         std::string editionstr="0";\r
160         int edition=0;\r
161         \r
162         Option::Instance()->Get("FMSVersionKey",key);\r
163         if(Option::Instance()->Get("FMSVersionEdition",editionstr))\r
164         {\r
165                 StringFunctions::Convert(editionstr,edition);\r
166                 edition++;\r
167                 StringFunctions::Convert(edition,editionstr);\r
168         }\r
169 \r
170         //start request\r
171         message.SetName("ClientGet");\r
172         message["URI"]=key+editionstr+"/FMSVersion.xml";\r
173         message["Identifier"]=m_fcpuniquename+"|"+message["URI"];\r
174         message["ReturnType"]="direct";\r
175         message["MaxSize"]="30000";             // 30K\r
176 \r
177         m_fcp->SendMessage(message);\r
178 \r
179 }\r