eea0633477f6d423d609e0ff33f7aa4bd1fa12ee
[fms.git] / src / message.cpp
1 #include "../include/message.h"\r
2 #include "../include/nntp/mime/Mime.h"\r
3 #include "../include/uuidgenerator.h"\r
4 #include "../include/stringfunctions.h"\r
5 #include "../include/freenet/messagexml.h"\r
6 #include "../include/option.h"\r
7 \r
8 #include <algorithm>\r
9 \r
10 #ifdef XMEM\r
11         #include <xmem.h>\r
12 #endif\r
13 \r
14 Message::Message()\r
15 {\r
16         Initialize();\r
17 }\r
18 \r
19 Message::Message(const long messageid)\r
20 {\r
21         Load(messageid);\r
22 }\r
23 \r
24 const bool Message::CheckForAdministrationBoard(const std::vector<std::string> &boards)\r
25 {\r
26         std::string name;\r
27         SQLite3DB::Statement st=m_db->Prepare("SELECT BoardName FROM tblBoard INNER JOIN tblAdministrationBoard ON tblBoard.BoardID=tblAdministrationBoard.BoardID;");\r
28         st.Step();\r
29         \r
30         while(st.RowReturned())\r
31         {\r
32                 st.ResultText(0,name);\r
33 \r
34                 if(std::find(boards.begin(),boards.end(),name)!=boards.end())\r
35                 {\r
36                         return true;\r
37                 }\r
38                 \r
39                 st.Step();\r
40         }\r
41 \r
42         return false;\r
43 }\r
44 \r
45 const int Message::FindLocalIdentityID(const std::string &name)\r
46 {\r
47         SQLite3DB::Statement st=m_db->Prepare("SELECT LocalIdentityID FROM tblLocalIdentity WHERE Name=?;");\r
48         st.Bind(0,name);\r
49         st.Step();\r
50         if(st.RowReturned())\r
51         {\r
52                 int result=-1;\r
53                 st.ResultInt(0,result);\r
54                 return result;\r
55         }\r
56         else\r
57         {\r
58                 if(m_addnewpostfromidentities==true)\r
59                 {\r
60                         DateTime now;\r
61                         now.SetToGMTime();\r
62                         st=m_db->Prepare("INSERT INTO tblLocalIdentity(Name) VALUES(?);");\r
63                         st.Bind(0,name);\r
64                         st.Step(true);\r
65                         return st.GetLastInsertRowID();\r
66                 }\r
67                 else\r
68                 {\r
69                         return -1;\r
70                 }\r
71         }\r
72 }\r
73 \r
74 const std::string Message::GetNNTPArticleID() const\r
75 {\r
76         // old message - before 0.1.12 - doesn't have @domain so add @freenetproject.org\r
77         if(m_messageuuid.find("@")==std::string::npos)\r
78         {\r
79                 return "<"+m_messageuuid+"@freenetproject.org>";\r
80         }\r
81         else\r
82         {\r
83                 return "<"+m_messageuuid+">";\r
84         }\r
85 }\r
86 \r
87 const std::string Message::GetNNTPBody() const\r
88 {\r
89         return m_body;\r
90 }\r
91 \r
92 const std::string Message::GetNNTPHeaders() const\r
93 {\r
94         std::string rval("");\r
95 \r
96         rval+="From: "+m_fromname+"\r\n";\r
97         rval+="Newsgroups: ";\r
98         for(std::vector<std::string>::const_iterator i=m_boards.begin(); i!=m_boards.end(); i++)\r
99         {\r
100                 if(i!=m_boards.begin())\r
101                 {\r
102                         rval+=",";\r
103                 }\r
104                 rval+=(*i);\r
105         }\r
106         rval+="\r\n";\r
107         rval+="Subject: "+m_subject+"\r\n";\r
108         // format time as  : Wdy, DD Mon YY HH:MM:SS TIMEZONE\r
109         rval+="Date: "+m_datetime.Format("%a, %d %b %y %H:%M:%S -0000")+"\r\n";\r
110         if(m_inreplyto.size()>0)\r
111         {\r
112                 rval+="References: ";\r
113                 for(std::map<long,std::string>::const_reverse_iterator j=m_inreplyto.rbegin(); j!=m_inreplyto.rend(); j++)\r
114                 {\r
115                         if(j!=m_inreplyto.rend())\r
116                         {\r
117                                 rval+=" ";\r
118                         }\r
119                         // old message - before 0.1.12 - doesn't have @domain so add @freenetproject.org\r
120                         if((*j).second.find("@")==std::string::npos)\r
121                         {\r
122                                 rval+="<"+(*j).second+"@freenetproject.org>";\r
123                         }\r
124                         else\r
125                         {\r
126                                 rval+="<"+(*j).second+">";\r
127                         }\r
128                 }\r
129                 rval+="\r\n";\r
130         }\r
131         rval+="Followup-To: "+m_replyboardname+"\r\n";\r
132         rval+="Path: freenet\r\n";\r
133         rval+="Message-ID: "+GetNNTPArticleID()+"\r\n";\r
134         rval+="Content-Type: text/plain; charset=UTF-8\r\n";\r
135 \r
136         return rval;\r
137 }\r
138 \r
139 void Message::HandleAdministrationMessage()\r
140 {\r
141         // only continue if this message was actually a reply to another message\r
142         if(m_inreplyto.size()>0)\r
143         {\r
144                 int localidentityid=-1;\r
145                 int boardid=0;\r
146                 std::string boardname="";\r
147                 std::string identityname="";\r
148                 int identityid;\r
149                 int changemessagetrust=0;\r
150                 int changetrustlisttrust=0;\r
151                 int origmessagetrust=0;\r
152                 int origtrustlisttrust=0;\r
153                 SQLite3DB::Statement st=m_db->Prepare("SELECT tblBoard.BoardID,BoardName,ModifyLocalMessageTrust,ModifyLocalTrustListTrust FROM tblBoard INNER JOIN tblAdministrationBoard ON tblBoard.BoardID=tblAdministrationBoard.BoardID;");\r
154                 st.Step();\r
155 \r
156                 localidentityid=FindLocalIdentityID(m_fromname);\r
157 \r
158                 while(st.RowReturned() && localidentityid!=-1)\r
159                 {\r
160                         st.ResultInt(0,boardid);\r
161                         st.ResultText(1,boardname);\r
162                         st.ResultInt(2,changemessagetrust);\r
163                         st.ResultInt(3,changetrustlisttrust);\r
164 \r
165                         if(std::find(m_boards.begin(),m_boards.end(),boardname)!=m_boards.end())\r
166                         {\r
167                                 SQLite3DB::Statement origmess=m_db->Prepare("SELECT tblIdentity.IdentityID,tblIdentity.Name,tblIdentityTrust.LocalMessageTrust,tblIdentityTrust.LocalTrustListTrust FROM tblIdentity INNER JOIN tblMessage ON tblIdentity.IdentityID=tblMessage.IdentityID LEFT JOIN (SELECT IdentityID,LocalMessageTrust,LocalTrustListTrust FROM tblIdentityTrust WHERE LocalIdentityID=?) AS 'tblIdentityTrust' ON tblIdentity.IdentityID=tblIdentityTrust.IdentityID WHERE tblMessage.MessageUUID=?;");\r
168                                 origmess.Bind(0,localidentityid);\r
169                                 origmess.Bind(1,m_inreplyto[0]);\r
170                                 origmess.Step();\r
171 \r
172                                 if(origmess.RowReturned())\r
173                                 {\r
174                                         origmess.ResultInt(0,identityid);\r
175                                         origmess.ResultText(1,identityname);\r
176                                         if(origmess.ResultNull(2)==false)\r
177                                         {\r
178                                                 origmess.ResultInt(2,origmessagetrust);\r
179                                         }\r
180                                         else\r
181                                         {\r
182                                                 origmessagetrust=m_minlocalmessagetrust;\r
183                                         }\r
184                                         if(origmess.ResultNull(3)==false)\r
185                                         {\r
186                                                 origmess.ResultInt(3,origtrustlisttrust);\r
187                                         }\r
188                                         else\r
189                                         {\r
190                                                 origtrustlisttrust=m_minlocaltrustlisttrust;\r
191                                         }\r
192 \r
193                                         origmessagetrust+=changemessagetrust;\r
194                                         origtrustlisttrust+=changetrustlisttrust;\r
195 \r
196                                         origmessagetrust<0 ? origmessagetrust=0 : false;\r
197                                         origmessagetrust>100 ? origmessagetrust=100 : false;\r
198                                         origtrustlisttrust<0 ? origtrustlisttrust=0 : false;\r
199                                         origtrustlisttrust>100 ? origtrustlisttrust=100 : false;\r
200 \r
201                                         // make sure we have a record in tblIdentityTrust\r
202                                         SQLite3DB::Statement ins=m_db->Prepare("INSERT INTO tblIdentityTrust(LocalIdentityID,IdentityID) VALUES(?,?);");\r
203                                         ins.Bind(0,localidentityid);\r
204                                         ins.Bind(1,identityid);\r
205                                         ins.Step();\r
206 \r
207                                         // update new trust levels\r
208                                         SQLite3DB::Statement update=m_db->Prepare("UPDATE tblIdentityTrust SET LocalMessageTrust=?, LocalTrustListTrust=? WHERE IdentityID=? AND LocalIdentityID=?;");\r
209                                         update.Bind(0,origmessagetrust);\r
210                                         update.Bind(1,origtrustlisttrust);\r
211                                         update.Bind(2,identityid);\r
212                                         update.Bind(3,localidentityid);\r
213                                         update.Step();\r
214 \r
215                                         // insert message to show what id was changed and what current levels are\r
216                                         int lastid=0;\r
217                                         std::string messagebody;\r
218                                         std::string messagetruststr="";\r
219                                         std::string trustlisttruststr="";\r
220                                         UUIDGenerator uuid;\r
221                                         DateTime now;\r
222                                         now.SetToGMTime();\r
223                                         StringFunctions::Convert(origmessagetrust,messagetruststr);\r
224                                         StringFunctions::Convert(origtrustlisttrust,trustlisttruststr);\r
225                                         messagebody="Trust List of "+m_fromname+"\r\n";\r
226                                         messagebody="Trust Changed for "+identityname+"\r\n";\r
227                                         messagebody+="Local Message Trust : "+messagetruststr+"\r\n";\r
228                                         messagebody+="Local Trust List Trust : "+trustlisttruststr+"\r\n";\r
229                                         SQLite3DB::Statement insert=m_db->Prepare("INSERT INTO tblMessage(FromName,MessageDate,MessageTime,Subject,MessageUUID,ReplyBoardID,Body) VALUES('FMS',?,?,?,?,?,?);");\r
230                                         insert.Bind(0,now.Format("%Y-%m-%d"));\r
231                                         insert.Bind(1,now.Format("%H:%M:%S"));\r
232                                         insert.Bind(2,identityname+" Trust Changed");\r
233                                         insert.Bind(3,uuid.Generate());\r
234                                         insert.Bind(4,boardid);\r
235                                         insert.Bind(5,messagebody);\r
236                                         insert.Step(true);\r
237                                         lastid=insert.GetLastInsertRowID();\r
238 \r
239                                         insert=m_db->Prepare("INSERT INTO tblMessageBoard(MessageID,BoardID) VALUES(?,?);");\r
240                                         insert.Bind(0,lastid);\r
241                                         insert.Bind(1,boardid);\r
242                                         insert.Step();\r
243 \r
244                                         m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"Message::HandleAdministrationMessage updated "+identityname+" to "+messagetruststr+" , "+trustlisttruststr);\r
245 \r
246                                 }\r
247                         }\r
248 \r
249                         st.Step();\r
250                 }\r
251         }\r
252 \r
253 }\r
254 \r
255 void Message::HandleChangeTrust()\r
256 {\r
257         if(m_changemessagetrustonreply!=0 && m_inreplyto.size()>0)\r
258         {\r
259                 int localidentityid=FindLocalIdentityID(m_fromname);\r
260                 if(localidentityid!=-1)\r
261                 {\r
262                         // make sure we have a record in tblIdentityTrust\r
263                         SQLite3DB::Statement ins=m_db->Prepare("INSERT INTO tblIdentityTrust(LocalIdentityID,IdentityID) VALUES(?,?);");\r
264 \r
265                         SQLite3DB::Statement st=m_db->Prepare("SELECT tblIdentity.IdentityID,tblIdentityTrust.LocalMessageTrust FROM tblIdentity INNER JOIN tblMessage ON tblIdentity.IdentityID=tblMessage.IdentityID LEFT JOIN (SELECT IdentityID,LocalMessageTrust FROM tblIdentityTrust WHERE LocalIdentityID=?) AS 'tblIdentityTrust' ON tblIdentity.IdentityID=tblIdentityTrust.IdentityID WHERE tblMessage.MessageUUID=?;");\r
266                         st.Bind(0,localidentityid);\r
267                         st.Bind(1,m_inreplyto[0]);\r
268                         st.Step();\r
269                         if(st.RowReturned())\r
270                         {\r
271                                 int identityid=0;\r
272                                 int localmessagetrust=0;\r
273 \r
274                                 st.ResultInt(0,identityid);\r
275                                 if(st.ResultNull(1)==false)\r
276                                 {\r
277                                         st.ResultInt(1,localmessagetrust);\r
278                                 }\r
279                                 else\r
280                                 {\r
281                                         localmessagetrust=m_minlocalmessagetrust;\r
282                                 }\r
283 \r
284                                 localmessagetrust+=m_changemessagetrustonreply;\r
285                                 if(localmessagetrust<0)\r
286                                 {\r
287                                         localmessagetrust=0;\r
288                                 }\r
289                                 if(localmessagetrust>100)\r
290                                 {\r
291                                         localmessagetrust=100;\r
292                                 }\r
293 \r
294                                 ins.Bind(0,localidentityid);\r
295                                 ins.Bind(1,identityid);\r
296                                 ins.Step();\r
297 \r
298                                 SQLite3DB::Statement st2=m_db->Prepare("UPDATE tblIdentityTrust SET LocalMessageTrust=? WHERE IdentityID=? AND LocalIdentityID=?;");\r
299                                 st2.Bind(0,localmessagetrust);\r
300                                 st2.Bind(1,identityid);\r
301                                 st2.Bind(2,localidentityid);\r
302                                 st2.Step();\r
303 \r
304                         }\r
305                 }\r
306         }\r
307 }\r
308 \r
309 void Message::Initialize()\r
310 {\r
311         std::string tempval="";\r
312         m_messageid=-1;\r
313         m_messageuuid="";\r
314         m_subject="";\r
315         m_body="";\r
316         m_replyboardname="";\r
317         m_datetime.Set();\r
318         m_fromname="";\r
319         m_boards.clear();\r
320         m_inreplyto.clear();\r
321         m_changemessagetrustonreply=0;\r
322         Option::Instance()->Get("ChangeMessageTrustOnReply",tempval);\r
323         StringFunctions::Convert(tempval,m_changemessagetrustonreply);\r
324         Option::Instance()->Get("AddNewPostFromIdentities",tempval);\r
325         if(tempval=="true")\r
326         {\r
327                 m_addnewpostfromidentities=true;\r
328         }\r
329         else\r
330         {\r
331                 m_addnewpostfromidentities=false;\r
332         }\r
333         tempval="50";\r
334         Option::Instance()->Get("MinLocalMessageTrust",tempval);\r
335         StringFunctions::Convert(tempval,m_minlocalmessagetrust);\r
336         tempval="51";\r
337         Option::Instance()->Get("MinLocalTrustListTrust",tempval);\r
338         StringFunctions::Convert(tempval,m_minlocaltrustlisttrust);\r
339 }\r
340 \r
341 const bool Message::Load(const long messageid, const long boardid)\r
342 {\r
343         \r
344         Initialize();\r
345 \r
346         std::string sql;\r
347         \r
348         sql="SELECT tblMessage.MessageID, MessageUUID, Subject, Body, tblBoard.BoardName, MessageDate, MessageTime, FromName FROM tblMessage INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID INNER JOIN tblBoard ON tblMessage.ReplyBoardID=tblBoard.BoardID WHERE tblMessage.MessageID=?";\r
349         if(boardid!=-1)\r
350         {\r
351                 sql+=" AND tblMessageBoard.BoardID=?";\r
352         }\r
353         sql+=";";\r
354 \r
355         SQLite3DB::Statement st=m_db->Prepare(sql);\r
356         st.Bind(0,messageid);\r
357         if(boardid!=-1)\r
358         {\r
359                 st.Bind(1,boardid);\r
360         }\r
361         st.Step();\r
362 \r
363         if(st.RowReturned())\r
364         {\r
365                 std::string tempdate;\r
366                 std::string temptime;\r
367                 int tempint=-1;\r
368                 st.ResultInt(0,tempint);\r
369                 m_messageid=tempint;\r
370                 st.ResultText(1,m_messageuuid);\r
371                 st.ResultText(2,m_subject);\r
372                 st.ResultText(3,m_body);\r
373                 st.ResultText(4,m_replyboardname);\r
374                 st.ResultText(5,tempdate);\r
375                 st.ResultText(6,temptime);\r
376                 m_datetime.Set(tempdate + " " + temptime);\r
377                 st.ResultText(7,m_fromname);\r
378                 st.Finalize();\r
379 \r
380                 // strip off any \r\n in subject\r
381                 m_subject=StringFunctions::Replace(m_subject,"\r\n","");\r
382 \r
383                 // get board list\r
384                 st=m_db->Prepare("SELECT tblBoard.BoardName FROM tblBoard INNER JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID WHERE tblMessageBoard.MessageID=?;");\r
385                 st.Bind(0,messageid);\r
386                 st.Step();\r
387                 while(st.RowReturned())\r
388                 {\r
389                         std::string tempval;\r
390                         st.ResultText(0,tempval);\r
391                         m_boards.push_back(tempval);\r
392                         st.Step();\r
393                 }\r
394                 st.Finalize();\r
395 \r
396                 // get in reply to list\r
397                 st=m_db->Prepare("SELECT ReplyToMessageUUID, ReplyOrder FROM tblMessageReplyTo INNER JOIN tblMessage ON tblMessageReplyTo.MessageID=tblMessage.MessageID WHERE tblMessage.MessageID=?;");\r
398                 st.Bind(0,messageid);\r
399                 st.Step();\r
400                 while(st.RowReturned())\r
401                 {\r
402                         std::string tempval;\r
403                         int tempint;\r
404                         st.ResultText(0,tempval);\r
405                         st.ResultInt(1,tempint);\r
406                         m_inreplyto[tempint]=tempval;\r
407                         st.Step();\r
408                 }\r
409                 st.Finalize();\r
410 \r
411                 return true;\r
412         }\r
413         else\r
414         {\r
415                 return false;\r
416         }\r
417 \r
418 }\r
419 \r
420 const bool Message::Load(const std::string &messageuuid)\r
421 {\r
422 \r
423         std::string uuid=messageuuid;\r
424 \r
425         if(uuid.size()>0 && uuid[0]=='<')\r
426         {\r
427                 uuid.erase(0,1);\r
428         }\r
429         if(uuid.size()>0 && uuid[uuid.size()-1]=='>')\r
430         {\r
431                 uuid.erase(uuid.size()-1);\r
432         }\r
433         if(uuid.find("@freenetproject.org")!=std::string::npos)\r
434         {\r
435                 uuid.erase(uuid.find("@freenetproject.org"));\r
436         }\r
437 \r
438         SQLite3DB::Statement st=m_db->Prepare("SELECT MessageID FROM tblMessage WHERE MessageUUID=?;");\r
439         st.Bind(0,uuid);\r
440         st.Step();\r
441 \r
442         if(st.RowReturned())\r
443         {\r
444                 int messageid;\r
445                 st.ResultInt(0,messageid);\r
446 \r
447                 return Load(messageid);\r
448         }\r
449         else\r
450         {\r
451                 return false;\r
452         }\r
453 }\r
454 \r
455 const bool Message::LoadNext(const long messageid, const long boardid)\r
456 {\r
457         std::string sql="SELECT tblMessage.MessageID FROM tblMessage INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID WHERE tblMessage.MessageID>?";\r
458         if(boardid!=-1)\r
459         {\r
460                 sql+=" AND tblMessageBoard.BoardID=?";\r
461         }\r
462         sql+=";";\r
463 \r
464         SQLite3DB::Statement st=m_db->Prepare(sql);\r
465 \r
466         st.Bind(0,messageid);\r
467         if(boardid!=-1)\r
468         {\r
469                 st.Bind(1,boardid);\r
470         }\r
471         st.Step();\r
472 \r
473         if(st.RowReturned())\r
474         {\r
475                 int result;\r
476                 st.ResultInt(0,result);\r
477                 return Load(result,boardid);\r
478         }\r
479         else\r
480         {\r
481                 return false;\r
482         }\r
483 }\r
484 \r
485 const bool Message::LoadPrevious(const long messageid, const long boardid)\r
486 {\r
487         std::string sql="SELECT tblMessage.MessageID FROM tblMessage INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID WHERE tblMessage.MessageID<?";\r
488         if(boardid!=-1)\r
489         {\r
490                 sql+=" AND tblMessageBoard.BoardID=?";\r
491         }\r
492         sql+=" ORDER BY tblMessage.MessageID DESC;";\r
493 \r
494         SQLite3DB::Statement st=m_db->Prepare(sql);\r
495 \r
496         st.Bind(0,messageid);\r
497         if(boardid!=-1)\r
498         {\r
499                 st.Bind(1,boardid);\r
500         }\r
501         st.Step();\r
502 \r
503         if(st.RowReturned())\r
504         {\r
505                 int result;\r
506                 st.ResultInt(0,result);\r
507                 return Load(result,boardid);\r
508         }\r
509         else\r
510         {\r
511                 return false;\r
512         }\r
513 }\r
514 \r
515 const bool Message::ParseNNTPMessage(const std::string &nntpmessage)\r
516 {\r
517 \r
518         Initialize();\r
519 \r
520         UUIDGenerator uuid;\r
521         CMimeMessage mime;\r
522         mime.Load(nntpmessage.c_str(),nntpmessage.size());\r
523 \r
524         // get header info\r
525         // date is always set to now regardless of what message has\r
526         m_datetime.SetToGMTime();\r
527 \r
528         // messageuuid is always a unique id we generate regardless of message message-id\r
529         m_messageuuid=uuid.Generate();\r
530         \r
531         // get from\r
532         if(mime.GetFieldValue("From"))\r
533         {\r
534                 m_fromname=mime.GetFieldValue("From");\r
535                 // remove any path folding\r
536                 m_fromname=StringFunctions::Replace(m_fromname,"\r\n","");\r
537                 // strip off everything between () and <> and any whitespace\r
538                 std::string::size_type startpos=m_fromname.find("(");\r
539                 std::string::size_type endpos;\r
540                 if(startpos!=std::string::npos)\r
541                 {\r
542                         endpos=m_fromname.find(")",startpos);\r
543                         if(endpos!=std::string::npos)\r
544                         {\r
545                                 m_fromname.erase(startpos,(endpos-startpos)+1);\r
546                         }\r
547                 }\r
548                 startpos=m_fromname.find("<");\r
549                 if(startpos!=std::string::npos)\r
550                 {\r
551                         endpos=m_fromname.find(">",startpos);\r
552                         if(endpos!=std::string::npos)\r
553                         {\r
554                                 m_fromname.erase(startpos,(endpos-startpos)+1);\r
555                         }\r
556                 }\r
557                 m_fromname=StringFunctions::TrimWhitespace(m_fromname);\r
558 \r
559                 // trim off " from beginning and end\r
560                 if(m_fromname.size()>0 && m_fromname[0]=='\"')\r
561                 {\r
562                         m_fromname.erase(0,1);\r
563                 }\r
564                 if(m_fromname.size()>0 && m_fromname[m_fromname.size()-1]=='\"')\r
565                 {\r
566                         m_fromname.erase(m_fromname.size()-1,1);\r
567                 }\r
568 \r
569                 m_fromname=StringFunctions::TrimWhitespace(m_fromname);\r
570         }\r
571         else\r
572         {\r
573                 m_fromname="Anonymous";\r
574         }\r
575         // get boards posted to\r
576         if(mime.GetFieldValue("Newsgroups"))\r
577         {\r
578                 std::string temp=mime.GetFieldValue("Newsgroups");\r
579                 // remove any path folding\r
580                 temp=StringFunctions::Replace(temp,"\r\n","");\r
581                 std::vector<std::string> parts;\r
582                 StringFunctions::SplitMultiple(temp,", \t",parts);\r
583                 for(std::vector<std::string>::iterator i=parts.begin(); i!=parts.end(); i++)\r
584                 {\r
585                         (*i)=StringFunctions::Replace((*i),"<","");\r
586                         (*i)=StringFunctions::Replace((*i),">","");\r
587                         (*i)=StringFunctions::TrimWhitespace((*i));\r
588                         if((*i)!="")\r
589                         {\r
590                                 m_boards.push_back((*i));\r
591                         }\r
592                 }\r
593         }\r
594         // followup-to board - must be done after board vector populated\r
595         if(mime.GetFieldValue("Followup-To"))\r
596         {\r
597                 m_replyboardname=mime.GetFieldValue("Followup-To");\r
598                 // remove any path folding\r
599                 m_replyboardname=StringFunctions::Replace(m_replyboardname,"\r\n","");\r
600         }\r
601         else\r
602         {\r
603                 if(m_boards.size()>0)\r
604                 {\r
605                         m_replyboardname=m_boards[0];\r
606                 }\r
607         }\r
608         // subject\r
609         if(mime.GetFieldValue("Subject"))\r
610         {\r
611                 m_subject=mime.GetFieldValue("Subject");\r
612                 // remove any path folding\r
613                 m_subject=StringFunctions::Replace(m_subject,"\r\n","");\r
614         }\r
615         else\r
616         {\r
617                 m_subject="No Subject";\r
618         }\r
619         // references\r
620         if(mime.GetFieldValue("References"))\r
621         {\r
622                 std::string temp=mime.GetFieldValue("References");\r
623                 // remove any path folding\r
624                 temp=StringFunctions::Replace(temp,"\r\n","");\r
625                 std::vector<std::string> parts;\r
626                 int count=0;\r
627                 StringFunctions::SplitMultiple(temp,", \t",parts);\r
628                 for(std::vector<std::string>::reverse_iterator i=parts.rbegin(); i!=parts.rend(); i++)\r
629                 {\r
630                         // get rid of < and > and any whitespace\r
631                         (*i)=StringFunctions::Replace((*i),"<","");\r
632                         (*i)=StringFunctions::Replace((*i),">","");\r
633                         (*i)=StringFunctions::TrimWhitespace((*i));\r
634                         /*\r
635                         // erase @ and everything after\r
636                         if((*i).find("@")!=std::string::npos)\r
637                         {\r
638                                 (*i).erase((*i).find("@"));\r
639                         }\r
640                         */\r
641                         // only erase after @ if message is old type with @freenetproject.org\r
642                         if((*i).find("@freenetproject.org")!=std::string::npos)\r
643                         {\r
644                                 (*i).erase((*i).find("@"));\r
645                         }\r
646                         if((*i)!="")\r
647                         {\r
648                                 m_inreplyto[count++]=(*i);\r
649                         }\r
650                 }\r
651         }\r
652 \r
653         CMimeBody::CBodyList mbl;\r
654         mime.GetBodyPartList(mbl);\r
655 \r
656         // append all text parts of nntp message to body\r
657         for(CMimeBody::CBodyList::iterator i=mbl.begin(); i!=mbl.end(); i++)\r
658         {\r
659                 if((*i)->IsText() && (*i)->GetContent())\r
660                 {\r
661                         m_body+=(char *)(*i)->GetContent();\r
662                 }\r
663         }\r
664 \r
665         return true;\r
666 }\r
667 \r
668 const bool Message::StartFreenetInsert()\r
669 {\r
670 \r
671         MessageXML xml;\r
672         int localidentityid=-1;\r
673 \r
674         xml.SetMessageID(m_messageuuid);\r
675         xml.SetSubject(m_subject);\r
676         xml.SetBody(m_body);\r
677         xml.SetReplyBoard(m_replyboardname);\r
678         xml.SetDate(m_datetime.Format("%Y-%m-%d"));\r
679         xml.SetTime(m_datetime.Format("%H:%M:%S"));\r
680         \r
681         StripAdministrationBoards();\r
682         for(std::vector<std::string>::iterator i=m_boards.begin(); i!=m_boards.end(); i++)\r
683         {\r
684                 xml.AddBoard((*i));\r
685         }\r
686         \r
687         for(std::map<long,std::string>::iterator j=m_inreplyto.begin(); j!=m_inreplyto.end(); j++)\r
688         {\r
689                 xml.AddInReplyTo((*j).first,(*j).second);\r
690         }\r
691 \r
692 \r
693         // find identity to insert with\r
694         /*\r
695         SQLite3DB::Statement st=m_db->Prepare("SELECT LocalIdentityID FROM tblLocalIdentity WHERE Name=?;");\r
696         st.Bind(0,m_fromname);\r
697         st.Step();\r
698 \r
699         // couldn't find identity with this name - insert a new identity\r
700         if(!st.RowReturned())\r
701         {\r
702                 if(m_addnewpostfromidentities==true)\r
703                 {\r
704                         DateTime now;\r
705                         now.SetToGMTime();\r
706                         st=m_db->Prepare("INSERT INTO tblLocalIdentity(Name) VALUES(?);");\r
707                         st.Bind(0,m_fromname);\r
708                         st.Step(true);\r
709                         localidentityid=st.GetLastInsertRowID();\r
710                 }\r
711                 else\r
712                 {\r
713                         return false;\r
714                 }\r
715         }\r
716         else\r
717         {\r
718                 st.ResultInt(0,localidentityid);\r
719         }\r
720         */\r
721         localidentityid=FindLocalIdentityID(m_fromname);\r
722         if(localidentityid==-1)\r
723         {\r
724                 return false;\r
725         }\r
726 \r
727         SQLite3DB::Statement st=m_db->Prepare("INSERT INTO tblMessageInserts(LocalIdentityID,MessageUUID,MessageXML) VALUES(?,?,?);");\r
728         st.Bind(0,localidentityid);\r
729         st.Bind(1,m_messageuuid);\r
730         st.Bind(2,xml.GetXML());\r
731         st.Step();\r
732 \r
733         HandleChangeTrust();\r
734 \r
735         return true;\r
736 \r
737 }\r
738 \r
739 void Message::StripAdministrationBoards()\r
740 {\r
741         SQLite3DB::Statement st=m_db->Prepare("SELECT tblBoard.BoardID FROM tblBoard INNER JOIN tblAdministrationBoard ON tblBoard.BoardID=tblAdministrationBoard.BoardID WHERE BoardName=?;");\r
742         for(std::vector<std::string>::iterator i=m_boards.begin(); i!=m_boards.end(); )\r
743         {\r
744                 st.Bind(0,(*i));\r
745                 st.Step();\r
746                 if(st.RowReturned())\r
747                 {\r
748                         i=m_boards.erase(i);\r
749                 }\r
750                 else\r
751                 {\r
752                         i++;\r
753                 }\r
754                 st.Reset();\r
755         }\r
756 }\r