1 #include "../../include/freenet/messagerequester.h"
\r
2 #include "../../include/freenet/messagexml.h"
\r
8 MessageRequester::MessageRequester()
\r
13 MessageRequester::MessageRequester(FCPv2 *fcp):IIndexRequester<std::string>(fcp)
\r
18 const long MessageRequester::GetBoardID(const std::string &boardname)
\r
20 SQLite3DB::Statement st=m_db->Prepare("SELECT BoardID FROM tblBoard WHERE BoardName=?;");
\r
21 st.Bind(0,boardname);
\r
24 if(st.RowReturned())
\r
27 st.ResultInt(0,boardid);
\r
34 st=m_db->Prepare("INSERT INTO tblBoard(BoardName,DateAdded) VALUES(?,?);");
\r
35 st.Bind(0,boardname);
\r
36 st.Bind(1,now.Format("%Y-%m-%d %H:%M:%S"));
\r
38 return st.GetLastInsertRowID();
\r
42 const std::string MessageRequester::GetIdentityName(const long identityid)
\r
44 SQLite3DB::Statement st=m_db->Prepare("SELECT Name,PublicKey FROM tblIdentity WHERE IdentityID=?;");
\r
45 st.Bind(0,identityid);
\r
47 if(st.RowReturned())
\r
49 std::vector<std::string> keyparts;
\r
52 st.ResultText(0,name);
\r
53 st.ResultText(1,key);
\r
55 StringFunctions::SplitMultiple(key,"@,",keyparts);
\r
57 if(keyparts.size()>1)
\r
59 return name+"@"+keyparts[1];
\r
63 return name+"@invalidpublickey";
\r
72 const bool MessageRequester::HandleAllData(FCPMessage &message)
\r
74 SQLite3DB::Statement st;
\r
75 std::vector<std::string> idparts;
\r
77 std::vector<char> data;
\r
82 StringFunctions::Split(message["Identifier"],"|",idparts);
\r
83 StringFunctions::Convert(message["DataLength"],datalength);
\r
84 StringFunctions::Convert(idparts[2],identityid);
\r
85 StringFunctions::Convert(idparts[4],index);
\r
87 // wait for all data to be received from connection
\r
88 while(m_fcp->Connected() && m_fcp->ReceiveBufferSize()<datalength)
\r
93 // if we got disconnected- return immediately
\r
94 if(m_fcp->Connected()==false)
\r
100 data.resize(datalength);
\r
101 m_fcp->ReceiveRaw(&data[0],datalength);
\r
103 // mark this index as received
\r
104 st=m_db->Prepare("UPDATE tblMessageRequests SET Found='true' WHERE IdentityID=? AND Day=? AND RequestIndex=?;");
\r
105 st.Bind(0,identityid);
\r
106 st.Bind(1,idparts[3]);
\r
111 // parse file into xml and update the database
\r
112 if(xml.ParseXML(std::string(data.begin(),data.end()))==true)
\r
114 std::vector<std::string> boards=xml.GetBoards();
\r
116 if(boards.size()<=0)
\r
118 m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData Message XML did not contain any boards! "+message["Identifier"]);
\r
121 if(xml.GetReplyBoard()=="")
\r
123 m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData Message XML did not contain a reply board! "+message["Identifier"]);
\r
127 st=m_db->Prepare("INSERT INTO tblMessage(IdentityID,FromName,MessageDate,MessageTime,Subject,MessageUUID,ReplyBoardID,Body) VALUES(?,?,?,?,?,?,?,?);");
\r
128 st.Bind(0,identityid);
\r
129 st.Bind(1,GetIdentityName(identityid));
\r
130 st.Bind(2,xml.GetDate());
\r
131 st.Bind(3,xml.GetTime());
\r
132 st.Bind(4,xml.GetSubject());
\r
133 st.Bind(5,xml.GetMessageID());
\r
134 st.Bind(6,GetBoardID(xml.GetReplyBoard()));
\r
135 st.Bind(7,xml.GetBody());
\r
137 int messageid=st.GetLastInsertRowID();
\r
139 st=m_db->Prepare("INSERT INTO tblMessageBoard(MessageID,BoardID) VALUES(?,?);");
\r
140 for(std::vector<std::string>::iterator i=boards.begin(); i!=boards.end(); i++)
\r
142 st.Bind(0,messageid);
\r
143 st.Bind(1,GetBoardID((*i)));
\r
149 st=m_db->Prepare("INSERT INTO tblMessageReplyTo(MessageID,ReplyToMessageUUID,ReplyOrder) VALUES(?,?,?);");
\r
150 std::map<long,std::string> replyto=xml.GetInReplyTo();
\r
151 for(std::map<long,std::string>::iterator j=replyto.begin(); j!=replyto.end(); j++)
\r
153 st.Bind(0,messageid);
\r
154 st.Bind(1,(*j).second);
\r
155 st.Bind(2,(*j).first);
\r
161 m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageRequester::HandleAllData parsed Message XML file : "+message["Identifier"]);
\r
166 m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData error parsing Message XML file : "+message["Identifier"]);
\r
169 RemoveFromRequestList(idparts[1]);
\r
174 const bool MessageRequester::HandleGetFailed(FCPMessage &message)
\r
177 SQLite3DB::Statement st;
\r
178 std::vector<std::string> idparts;
\r
179 std::string requestid;
\r
184 StringFunctions::Split(message["Identifier"],"|",idparts);
\r
185 requestid=idparts[1];
\r
186 StringFunctions::Convert(idparts[2],identityid);
\r
187 StringFunctions::Convert(idparts[4],index);
\r
189 // if this is a fatal error - insert index into database so we won't try to download this index again
\r
190 if(message["Fatal"]=="true")
\r
192 st=m_db->Prepare("UPDATE tblMessageRequests SET Found='true' WHERE IdentityID=? AND Day=? AND RequestIndex=?;");
\r
193 st.Bind(0,identityid);
\r
194 st.Bind(1,idparts[3]);
\r
199 m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleGetFailed fatal error requesting "+message["Identifier"]);
\r
202 // remove this identityid from request list
\r
203 RemoveFromRequestList(requestid);
\r
208 void MessageRequester::Initialize()
\r
210 m_fcpuniquename="MessageRequester";
\r
211 std::string tempval;
\r
212 Option::Instance()->Get("MaxMessageRequests",tempval);
\r
213 StringFunctions::Convert(tempval,m_maxrequests);
\r
214 if(m_maxrequests<1)
\r
217 m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"Option MaxMessageRequests is currently set at "+tempval+". It must be 1 or greater.");
\r
219 if(m_maxrequests>100)
\r
221 m_log->WriteLog(LogFile::LOGLEVEL_WARNING,"Option MaxMessageRequests is currently set at "+tempval+". This value might be incorrectly configured.");
\r
223 Option::Instance()->Get("MessageDownloadMaxDaysBackward",tempval);
\r
224 StringFunctions::Convert(tempval,m_maxdaysbackward);
\r
225 if(m_maxdaysbackward<0)
\r
227 m_maxdaysbackward=0;
\r
228 m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"Option MessageDownloadMaxDaysBackward is currently set at "+tempval+". It must be 0 or greater.");
\r
230 if(m_maxdaysbackward>30)
\r
232 m_log->WriteLog(LogFile::LOGLEVEL_WARNING,"Option MessageDownloadMaxDaysBackward is currently set at "+tempval+". This value might be incorrectly configured.");
\r
236 void MessageRequester::PopulateIDList()
\r
244 date.SetToGMTime();
\r
245 date.Add(0,0,0,-m_maxdaysbackward);
\r
247 sql="SELECT tblIdentity.IdentityID,Day,RequestIndex ";
\r
248 sql+="FROM tblMessageRequests INNER JOIN tblIdentity ON tblMessageRequests.IdentityID=tblIdentity.IdentityID ";
\r
249 sql+="WHERE tblIdentity.LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust') AND FromMessageList='true' AND Found='false' AND Day>='"+date.Format("%Y-%m-%d")+"' ";
\r
250 sql+="AND (tblIdentity.PeerMessageTrust IS NULL OR tblIdentity.PeerMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerMessageTrust')) ";
\r
253 SQLite3DB::Statement st=m_db->Prepare(sql);
\r
256 while(st.RowReturned())
\r
258 st.ResultText(0,val1);
\r
259 st.ResultText(1,val2);
\r
260 st.ResultText(2,val3);
\r
261 if(m_ids.find(val1+"*"+val2+"*"+val3)==m_ids.end())
\r
263 m_ids[val1+"*"+val2+"*"+val3]=false;
\r
270 void MessageRequester::StartRequest(const std::string &requestid)
\r
272 FCPMessage message;
\r
273 std::vector<std::string> parts;
\r
274 std::string tempval;
\r
277 std::string indexstr;
\r
278 std::string publickey;
\r
280 StringFunctions::Split(requestid,"*",parts);
\r
281 StringFunctions::Convert(parts[0],identityid);
\r
282 StringFunctions::Convert(parts[1],date);
\r
285 SQLite3DB::Statement st=m_db->Prepare("SELECT PublicKey FROM tblIdentity WHERE IdentityID=?;");
\r
286 st.Bind(0,identityid);
\r
289 if(st.RowReturned())
\r
291 st.ResultText(0,publickey);
\r
293 message.SetName("ClientGet");
\r
294 message["URI"]=publickey+m_messagebase+"|"+date+"|Message|"+indexstr+".xml";
\r
295 message["Identifier"]=m_fcpuniquename+"|"+requestid+"|"+parts[0]+"|"+parts[1]+"|"+parts[2]+"|"+message["URI"];
\r
296 message["ReturnType"]="direct";
\r
297 message["MaxSize"]="1000000"; // 1 MB
\r
299 m_fcp->SendMessage(message);
\r
301 m_requesting.push_back(requestid);
\r
304 m_ids[requestid]=true;
\r