version 0.2.10
[fms.git] / src / freenet / identityinserter.cpp
1 #include "../../include/freenet/identityinserter.h"\r
2 #include "../../include/freenet/identityxml.h"\r
3 #include "../../include/stringfunctions.h"\r
4 #include "../../include/option.h"\r
5 \r
6 #ifdef XMEM\r
7         #include <xmem.h>\r
8 #endif\r
9 \r
10 IdentityInserter::IdentityInserter()\r
11 {\r
12         Initialize();\r
13 }\r
14 \r
15 IdentityInserter::IdentityInserter(FCPv2 *fcp):IFCPConnected(fcp)\r
16 {\r
17         Initialize();\r
18 }\r
19 \r
20 void IdentityInserter::CheckForNeededInsert()\r
21 {\r
22         DateTime now;\r
23         DateTime date;\r
24         now.SetToGMTime();\r
25         date.SetToGMTime();\r
26         // set date to 1 hour back\r
27         date.Add(0,0,-1);\r
28 \r
29         // Because of importance of Identity.xml, if we are now at the next day we immediately want to insert identities so change the date back to 12:00 AM so we find all identities not inserted yet today\r
30         if(date.GetDay()!=now.GetDay())\r
31         {\r
32                 date=now;\r
33                 date.SetHour(0);\r
34                 date.SetMinute(0);\r
35                 date.SetSecond(0);\r
36         }\r
37 \r
38         SQLite3DB::Recordset rs=m_db->Query("SELECT LocalIdentityID FROM tblLocalIdentity WHERE PrivateKey IS NOT NULL AND PrivateKey <> '' AND InsertingIdentity='false' AND (LastInsertedIdentity<'"+date.Format("%Y-%m-%d %H:%M:%S")+"' OR LastInsertedIdentity IS NULL) ORDER BY LastInsertedIdentity;");\r
39         \r
40         if(rs.Empty()==false)\r
41         {\r
42                 StartInsert(rs.GetInt(0));\r
43         }\r
44 \r
45 }\r
46 \r
47 void IdentityInserter::FCPConnected()\r
48 {\r
49         m_db->Execute("UPDATE tblLocalIdentity SET InsertingIdentity='false';");\r
50 }\r
51 \r
52 \r
53 void IdentityInserter::FCPDisconnected()\r
54 {\r
55         \r
56 }\r
57 \r
58 const bool IdentityInserter::HandleMessage(FCPMessage &message)\r
59 {\r
60 \r
61         if(message["Identifier"].find("IdentityInserter")==0)\r
62         {\r
63                 DateTime now;\r
64                 std::vector<std::string> idparts;\r
65 \r
66                 now.SetToGMTime();\r
67                 StringFunctions::Split(message["Identifier"],"|",idparts);\r
68 \r
69                 // no action for URIGenerated\r
70                 if(message.GetName()=="URIGenerated")\r
71                 {\r
72                         return true;\r
73                 }\r
74 \r
75                 // no action for IdentifierCollision\r
76                 if(message.GetName()=="IdentifierCollision")\r
77                 {\r
78                         return true;\r
79                 }\r
80 \r
81                 if(message.GetName()=="PutSuccessful")\r
82                 {\r
83                         // a little hack here - if we just inserted index yesterday and it is now the next day - we would have inserted todays date not yesterdays as LastInsertedIdentity.\r
84                         // If this is the case, we will skip updating LastInsertedIdentity so that we can insert this identity again for today\r
85                         DateTime lastdate;\r
86                         lastdate.Set(idparts[4]);\r
87                         if(lastdate.GetDay()==now.GetDay())\r
88                         {\r
89                                 m_db->Execute("UPDATE tblLocalIdentity SET InsertingIdentity='false', LastInsertedIdentity='"+now.Format("%Y-%m-%d %H:%M:%S")+"' WHERE LocalIdentityID="+idparts[1]+";");\r
90                         }\r
91                         else\r
92                         {\r
93                                 m_db->Execute("UPDATE tblLocalIdentity SET InsertingIdentity='false' WHERE LocalIdentityID="+idparts[1]+";");\r
94                         }\r
95                         m_db->Execute("INSERT INTO tblLocalIdentityInserts(LocalIdentityID,Day,InsertIndex) VALUES("+idparts[1]+",'"+idparts[4]+"',"+idparts[2]+");");\r
96                         m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"IdentityInserter::HandleMessage inserted Identity xml");\r
97                         return true;\r
98                 }\r
99 \r
100                 if(message.GetName()=="PutFailed")\r
101                 {\r
102                         m_db->Execute("UPDATE tblLocalIdentity SET InsertingIdentity='false' WHERE LocalIdentityID="+idparts[1]+";");\r
103                         m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"IdentityInserter::HandleMessage failure inserting Identity xml.  Code="+message["Code"]+" Description="+message["CodeDescription"]);\r
104                         \r
105                         // if code 9 (collision), then insert index into inserted table\r
106                         if(message["Code"]=="9")\r
107                         {\r
108                                 m_db->Execute("INSERT INTO tblLocalIdentityInserts(LocalIdentityID,Day,InsertIndex) VALUES("+idparts[1]+",'"+idparts[4]+"',"+idparts[2]+");");\r
109                         }\r
110                         \r
111                         return true;\r
112                 }\r
113 \r
114         }\r
115 \r
116         return false;\r
117 \r
118 }\r
119 \r
120 void IdentityInserter::Initialize()\r
121 {\r
122         m_lastchecked.SetToGMTime();\r
123 }\r
124 \r
125 void IdentityInserter::Process()\r
126 {\r
127         DateTime now;\r
128         now.SetToGMTime();\r
129 \r
130         if(m_lastchecked<(now-(1.0/1440.0)))\r
131         {\r
132                 CheckForNeededInsert();\r
133                 m_lastchecked=now;\r
134         }\r
135 \r
136 }\r
137 \r
138 void IdentityInserter::RegisterWithThread(FreenetMasterThread *thread)\r
139 {\r
140         thread->RegisterFCPConnected(this);\r
141         thread->RegisterFCPMessageHandler(this);\r
142         thread->RegisterPeriodicProcessor(this);\r
143 }\r
144 \r
145 void IdentityInserter::StartInsert(const long localidentityid)\r
146 {\r
147         DateTime date;\r
148         std::string idstring;\r
149 \r
150         StringFunctions::Convert(localidentityid,idstring);\r
151         date.SetToGMTime();\r
152 \r
153         SQLite3DB::Recordset rs=m_db->Query("SELECT Name,PrivateKey,SingleUse,PublishTrustList,PublishBoardList,PublishFreesite,FreesiteEdition FROM tblLocalIdentity WHERE LocalIdentityID="+idstring+";");\r
154 \r
155         if(rs.Empty()==false)\r
156         {\r
157                 IdentityXML idxml;\r
158                 FCPMessage mess;\r
159                 DateTime now;\r
160                 std::string messagebase;\r
161                 std::string data;\r
162                 std::string datasizestr;\r
163                 std::string privatekey;\r
164                 long index=0;\r
165                 std::string indexstr;\r
166                 std::string singleuse="false";\r
167                 std::string publishtrustlist="false";\r
168                 std::string publishboardlist="false";\r
169                 std::string freesiteedition="";\r
170                 int edition=-1;\r
171 \r
172                 now.SetToGMTime();\r
173 \r
174                 SQLite3DB::Recordset rs2=m_db->Query("SELECT MAX(InsertIndex) FROM tblLocalIdentityInserts WHERE LocalIdentityID="+idstring+" AND Day='"+now.Format("%Y-%m-%d")+"';");\r
175                 if(rs2.Empty()==false)\r
176                 {\r
177                         if(rs2.GetField(0)==NULL)\r
178                         {\r
179                                 index=0;\r
180                         }\r
181                         else\r
182                         {\r
183                                 index=rs2.GetInt(0)+1;\r
184                         }\r
185                 }\r
186                 StringFunctions::Convert(index,indexstr);\r
187 \r
188                 Option::Instance()->Get("MessageBase",messagebase);\r
189 \r
190                 if(rs.GetField(0))\r
191                 {\r
192                         idxml.SetName(rs.GetField(0));\r
193                 }\r
194 \r
195                 if(rs.GetField(1))\r
196                 {\r
197                         privatekey=rs.GetField(1);\r
198                 }\r
199 \r
200                 if(rs.GetField(2))\r
201                 {\r
202                         singleuse=rs.GetField(2);\r
203                 }\r
204                 singleuse=="true" ? idxml.SetSingleUse(true) : idxml.SetSingleUse(false);\r
205 \r
206                 if(rs.GetField(3))\r
207                 {\r
208                         publishtrustlist=rs.GetField(3);\r
209                 }\r
210                 publishtrustlist=="true" ? idxml.SetPublishTrustList(true) : idxml.SetPublishTrustList(false);\r
211 \r
212                 if(rs.GetField(4))\r
213                 {\r
214                         publishboardlist=rs.GetField(4);\r
215                 }\r
216                 publishboardlist=="true" ? idxml.SetPublishBoardList(true) : idxml.SetPublishBoardList(false);\r
217 \r
218                 if(rs.GetField(5) && rs.GetField(6))\r
219                 {\r
220                         if(std::string(rs.GetField(5))=="true")\r
221                         {\r
222                                 freesiteedition=rs.GetField(6);\r
223                                 StringFunctions::Convert(freesiteedition,edition);\r
224                                 idxml.SetFreesiteEdition(edition);\r
225                         }\r
226                 }\r
227 \r
228                 data=idxml.GetXML();\r
229                 StringFunctions::Convert(data.size(),datasizestr);\r
230 \r
231                 mess.SetName("ClientPut");\r
232                 mess["URI"]=privatekey+messagebase+"|"+now.Format("%Y-%m-%d")+"|Identity|"+indexstr+".xml";\r
233                 mess["Identifier"]="IdentityInserter|"+idstring+"|"+indexstr+"|"+mess["URI"];\r
234                 mess["UploadFrom"]="direct";\r
235                 mess["DataLength"]=datasizestr;\r
236                 m_fcp->SendMessage(mess);\r
237                 m_fcp->SendRaw(data.c_str(),data.size());\r
238 \r
239                 m_db->Execute("UPDATE tblLocalIdentity SET InsertingIdentity='true' WHERE LocalIdentityID="+idstring+";");\r
240 \r
241         }\r
242 }\r