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