From ee580d19b7920904587e18d72a3465d52eab6204 Mon Sep 17 00:00:00 2001 From: SomeDude Date: Sat, 23 Feb 2008 13:26:00 +0100 Subject: [PATCH] version 0.1.13 --- CMakeLists.txt | 21 ++- include/freenet/messagerequester.h | 1 + include/freenet/trustlistxml.h | 1 + include/global.h | 3 +- include/http/pages/boardspage.h | 20 +++ include/message.h | 3 +- src/freenet/boardlistrequester.cpp | 2 +- src/freenet/introductionpuzzlerequester.cpp | 60 ++++++- src/freenet/messagelistrequester.cpp | 2 +- src/freenet/messagerequester.cpp | 155 ++++++++++++----- src/freenet/trustlistinserter.cpp | 18 +- src/freenet/trustlistrequester.cpp | 18 +- src/freenet/trustlistxml.cpp | 22 ++- src/global.cpp | 69 ++++++-- src/http/httpthread.cpp | 2 + src/http/ipagehandler.cpp | 4 +- src/http/pages/boardspage.cpp | 258 ++++++++++++++++++++++++++++ src/http/pages/homepage.cpp | 3 + src/http/pages/peertrustpage.cpp | 22 ++- src/logfile.cpp | 2 +- src/message.cpp | 59 +++++-- src/nntp/mime/Mime.cpp | 2 +- src/nntp/nntpconnection.cpp | 10 +- template.htm | 1 + 24 files changed, 666 insertions(+), 92 deletions(-) create mode 100644 include/http/pages/boardspage.h create mode 100644 src/http/pages/boardspage.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 455a73d..5f976ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,7 @@ src/http/identityexportxml.cpp src/http/ipagehandler.cpp src/http/pages/addpeerpage.cpp src/http/pages/announceidentitypage.cpp +src/http/pages/boardspage.cpp src/http/pages/controlboardpage.cpp src/http/pages/createidentitypage.cpp src/http/pages/execquerypage.cpp @@ -96,15 +97,31 @@ ADD_DEFINITIONS(-DTIXML_USE_STL) ADD_EXECUTABLE(fms ${FMS_SRC} ${FMS_PLATFORM_SRC}) -# For SQLite3 and shttpd +# link dl - For SQLite3 and shttpd - not for FreeBSD IF(CMAKE_COMPILER_IS_GNUCC) - TARGET_LINK_LIBRARIES(fms dl) + IF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + TARGET_LINK_LIBRARIES(fms dl) + ENDIF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") ENDIF(CMAKE_COMPILER_IS_GNUCC) +# add -lcompat only for FreeBSD +IF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + IF(CMAKE_COMPILER_IS_GNUCXX) + ADD_DEFINITIONS(-lcompat) + ENDIF(CMAKE_COMPILER_IS_GNUCXX) +ENDIF(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + +# link ws2_32 for Windows IF(WIN32) TARGET_LINK_LIBRARIES(fms ws2_32) ENDIF(WIN32) +# add -lxnet and -lsocket on solaris +IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") + ADD_DEFINITIONS(-lxnet -lsocket) +ENDIF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") + FIND_LIBRARY(SQLITE3_LIBRARY NAMES sqlite3 sqlite3_s) FIND_LIBRARY(TINYXML_LIBRARY NAMES tinyxml tinyxml_s) FIND_LIBRARY(PTHREADS_LIBRARY NAMES pthread pthreads pthreadvc2) diff --git a/include/freenet/messagerequester.h b/include/freenet/messagerequester.h index 353de7e..e840635 100644 --- a/include/freenet/messagerequester.h +++ b/include/freenet/messagerequester.h @@ -17,6 +17,7 @@ private: const bool HandleGetFailed(FCPMessage &message); const long GetBoardID(const std::string &boardname); + const bool SaveToBoard(const std::string &boardname); const std::string GetIdentityName(const long identityid); long m_maxdaysbackward; diff --git a/include/freenet/trustlistxml.h b/include/freenet/trustlistxml.h index ad09e60..ac16d1f 100644 --- a/include/freenet/trustlistxml.h +++ b/include/freenet/trustlistxml.h @@ -6,6 +6,7 @@ #include +// trust of -1 will mean NULL trust class TrustListXML:public IFMSXMLDocument,public ILogger { private: diff --git a/include/global.h b/include/global.h index d9a82e0..3abb065 100644 --- a/include/global.h +++ b/include/global.h @@ -5,11 +5,12 @@ //#include #include "pthreadwrapper/thread.h" -#define FMS_VERSION "0.1.12" +#define FMS_VERSION "0.1.13" // opens database and creates tables and initial inserts if necessary void SetupDB(); void ConvertDB0100To0101(); +void ConvertDB0101To0103(); // inserts default options into the database void SetupDefaultOptions(); // opens logfile and sets it up diff --git a/include/http/pages/boardspage.h b/include/http/pages/boardspage.h new file mode 100644 index 0000000..7f8ae92 --- /dev/null +++ b/include/http/pages/boardspage.h @@ -0,0 +1,20 @@ +#ifndef _boardspage_ +#define _boardspage_ + +#include "../ipagehandler.h" +#include "../../idatabase.h" + +class BoardsPage:public IPageHandler,public IDatabase +{ +public: + BoardsPage(const std::string &templatestr):IPageHandler(templatestr) {} + +private: + const bool WillHandleURI(const std::string &uri); + const std::string GeneratePage(const std::string &method, const std::map &queryvars); + + const std::string BuildQueryString(const long startrow, const std::string &boardsearch); + +}; + +#endif // _boardspage_ diff --git a/include/message.h b/include/message.h index 74c25d4..c99b96d 100644 --- a/include/message.h +++ b/include/message.h @@ -46,7 +46,7 @@ public: const bool PostedToAdministrationBoard() { return CheckForAdministrationBoard(m_boards); } - void StartFreenetInsert(); + const bool StartFreenetInsert(); void HandleAdministrationMessage(); private: @@ -56,6 +56,7 @@ private: void HandleChangeTrust(); long m_messageid; + bool m_addnewpostfromidentities; std::string m_messageuuid; std::string m_subject; std::string m_body; diff --git a/src/freenet/boardlistrequester.cpp b/src/freenet/boardlistrequester.cpp index 6b52a46..28ba901 100644 --- a/src/freenet/boardlistrequester.cpp +++ b/src/freenet/boardlistrequester.cpp @@ -173,7 +173,7 @@ void BoardListRequester::PopulateIDList() DateTime today; today.SetToGMTime(); - SQLite3DB::Statement st=m_db->Prepare("SELECT IdentityID FROM tblIdentity WHERE PublicKey IS NOT NULL AND PublicKey <> '' AND LastSeen>='"+today.Format("%Y-%m-%d")+"' AND LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust') AND PublishBoardList='true' ORDER BY LocalMessageTrust+LocalTrustListTrust DESC, LastSeen;"); + SQLite3DB::Statement st=m_db->Prepare("SELECT IdentityID FROM tblIdentity WHERE PublicKey IS NOT NULL AND PublicKey <> '' AND LastSeen>='"+today.Format("%Y-%m-%d")+"' AND (LocalMessageTrust IS NULL OR LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust')) AND (PeerMessageTrust IS NULL OR PeerMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerMessageTrust')) AND PublishBoardList='true' ORDER BY LocalMessageTrust+LocalTrustListTrust DESC, LastSeen;"); st.Step(); m_ids.clear(); diff --git a/src/freenet/introductionpuzzlerequester.cpp b/src/freenet/introductionpuzzlerequester.cpp index 03d4a41..1a24bd0 100644 --- a/src/freenet/introductionpuzzlerequester.cpp +++ b/src/freenet/introductionpuzzlerequester.cpp @@ -38,6 +38,7 @@ const bool IntroductionPuzzleRequester::HandleAllData(FCPMessage &message) IntroductionPuzzleXML xml; long identityid; long index; + bool validmessage=true; now.SetToGMTime(); StringFunctions::Split(message["Identifier"],"|",idparts); @@ -65,17 +66,64 @@ const bool IntroductionPuzzleRequester::HandleAllData(FCPMessage &message) if(xml.ParseXML(std::string(data.begin(),data.end()))==true) { - // TODO - check if last part of UUID matches public key of identity who inserted it + // check if last part of UUID matches first part of public key of identity who inserted it + st=m_db->Prepare("SELECT PublicKey FROM tblIdentity WHERE IdentityID=?;"); + st.Bind(0,identityid); + st.Step(); + if(st.RowReturned()) + { + std::vector uuidparts; + std::vector keyparts; + std::string keypart=""; + std::string publickey=""; + + st.ResultText(0,publickey); + + StringFunctions::SplitMultiple(publickey,"@,",keyparts); + StringFunctions::SplitMultiple(xml.GetUUID(),"@",uuidparts); + + if(uuidparts.size()>1 && keyparts.size()>1) + { + keypart=StringFunctions::Replace(StringFunctions::Replace(keyparts[1],"-",""),"~",""); + if(keypart!=uuidparts[1]) + { + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"IntroductionPuzzleRequester::HandleAllData UUID in IntroductionPuzzle doesn't match public key of identity : "+message["Identifier"]); + validmessage=false; + } + } + else + { + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"IntroductionPuzzleRequester::HandleAllData Error with identity's public key or UUID : "+message["Identifier"]); + validmessage=false; + } + + } + else + { + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"IntroductionPuzzleRequester::HandleAllData Error couldn't find identity : "+message["Identifier"]); + validmessage=false; + } st=m_db->Prepare("INSERT INTO tblIntroductionPuzzleRequests(IdentityID,Day,RequestIndex,Found,UUID,Type,MimeType,PuzzleData) VALUES(?,?,?,?,?,?,?,?);"); st.Bind(0,identityid); st.Bind(1,idparts[4]); st.Bind(2,index); - st.Bind(3,"true"); - st.Bind(4,xml.GetUUID()); - st.Bind(5,xml.GetType()); - st.Bind(6,xml.GetMimeType()); - st.Bind(7,xml.GetPuzzleData()); + if(validmessage) + { + st.Bind(3,"true"); + st.Bind(4,xml.GetUUID()); + st.Bind(5,xml.GetType()); + st.Bind(6,xml.GetMimeType()); + st.Bind(7,xml.GetPuzzleData()); + } + else + { + st.Bind(3,"false"); + st.Bind(4); + st.Bind(5); + st.Bind(6); + st.Bind(7); + } st.Step(); st.Finalize(); diff --git a/src/freenet/messagelistrequester.cpp b/src/freenet/messagelistrequester.cpp index c5ef11c..242d292 100644 --- a/src/freenet/messagelistrequester.cpp +++ b/src/freenet/messagelistrequester.cpp @@ -160,7 +160,7 @@ void MessageListRequester::PopulateIDList() date.SetToGMTime(); // select identities we want to query (we've seen them today) - sort by their trust level (descending) with secondary sort on how long ago we saw them (ascending) - SQLite3DB::Statement st=m_db->Prepare("SELECT IdentityID FROM tblIdentity WHERE PublicKey IS NOT NULL AND PublicKey <> '' AND LastSeen>='"+date.Format("%Y-%m-%d")+"' AND LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust') ORDER BY LocalMessageTrust+LocalTrustListTrust DESC, LastSeen;"); + SQLite3DB::Statement st=m_db->Prepare("SELECT IdentityID FROM tblIdentity WHERE PublicKey IS NOT NULL AND PublicKey <> '' AND LastSeen>='"+date.Format("%Y-%m-%d")+"' AND (LocalMessageTrust IS NULL OR LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust')) AND (PeerMessageTrust IS NULL OR PeerMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerMessageTrust')) ORDER BY LocalMessageTrust+LocalTrustListTrust DESC, LastSeen;"); st.Step(); m_ids.clear(); diff --git a/src/freenet/messagerequester.cpp b/src/freenet/messagerequester.cpp index 54b0d26..ac56c5c 100644 --- a/src/freenet/messagerequester.cpp +++ b/src/freenet/messagerequester.cpp @@ -81,6 +81,8 @@ const bool MessageRequester::HandleAllData(FCPMessage &message) long identityid; long index; bool inserted=false; + bool validmessage=true; + long savetoboardcount=0; StringFunctions::Split(message["Identifier"],"|",idparts); StringFunctions::Convert(message["DataLength"],datalength); @@ -115,6 +117,8 @@ const bool MessageRequester::HandleAllData(FCPMessage &message) if(xml.ParseXML(std::string(data.begin(),data.end()))==true) { std::vector boards=xml.GetBoards(); + std::map replyto=xml.GetInReplyTo(); + if(boards.size()>m_maxboardspermessage) { boards.resize(m_maxboardspermessage); @@ -130,61 +134,111 @@ const bool MessageRequester::HandleAllData(FCPMessage &message) m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData Message XML did not contain a reply board! "+message["Identifier"]); return true; } - - // make sure the reply board is on the board list - if not, replace the last element of boardswith the reply board + + // make sure the reply board is on the board list we are saving - if not, replace the last element of boards with the reply board if(xml.GetReplyBoard()!="" && std::find(boards.begin(),boards.end(),xml.GetReplyBoard())==boards.end() && boards.size()>0) { boards[boards.size()-1]=xml.GetReplyBoard(); } - // TODO make sure domain of message id match 43 characters of public key of identity (remove - and ~) - if not, discard message + // make sure domain of message id match 43 characters of public key of identity (remove - and ~) - if not, discard message // implement after 0.1.12 is released - - st=m_db->Prepare("INSERT INTO tblMessage(IdentityID,FromName,MessageDate,MessageTime,Subject,MessageUUID,ReplyBoardID,Body) VALUES(?,?,?,?,?,?,?,?);"); + st=m_db->Prepare("SELECT PublicKey FROM tblIdentity WHERE IdentityID=?;"); st.Bind(0,identityid); - st.Bind(1,GetIdentityName(identityid)); - st.Bind(2,xml.GetDate()); - st.Bind(3,xml.GetTime()); - st.Bind(4,xml.GetSubject()); - st.Bind(5,xml.GetMessageID()); - st.Bind(6,GetBoardID(xml.GetReplyBoard())); - st.Bind(7,xml.GetBody()); - inserted=st.Step(true); - int messageid=st.GetLastInsertRowID(); - - if(inserted==true) + st.Step(); + if(st.RowReturned()) { + std::vector uuidparts; + std::vector keyparts; + std::string keypart=""; + std::string publickey=""; - st=m_db->Prepare("INSERT INTO tblMessageBoard(MessageID,BoardID) VALUES(?,?);"); - for(std::vector::iterator i=boards.begin(); i!=boards.end(); i++) + st.ResultText(0,publickey); + + StringFunctions::SplitMultiple(publickey,"@,",keyparts); + StringFunctions::SplitMultiple(xml.GetMessageID(),"@",uuidparts); + + if(uuidparts.size()>1 && keyparts.size()>1) { - st.Bind(0,messageid); - st.Bind(1,GetBoardID((*i))); - st.Step(); - st.Reset(); + keypart=StringFunctions::Replace(StringFunctions::Replace(keyparts[1],"-",""),"~",""); + if(keypart!=uuidparts[1]) + { + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData MessageID in Message doesn't match public key of identity : "+message["Identifier"]); + validmessage=false; + } } - st.Finalize(); - - st=m_db->Prepare("INSERT INTO tblMessageReplyTo(MessageID,ReplyToMessageUUID,ReplyOrder) VALUES(?,?,?);"); - std::map replyto=xml.GetInReplyTo(); - for(std::map::iterator j=replyto.begin(); j!=replyto.end(); j++) + else { - st.Bind(0,messageid); - st.Bind(1,(*j).second); - st.Bind(2,(*j).first); - st.Step(); - st.Reset(); + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData Error with identity's public key or Message ID : "+message["Identifier"]); + validmessage=false; } - st.Finalize(); - - m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageRequester::HandleAllData parsed Message XML file : "+message["Identifier"]); - } - else // couldn't insert - was already in database + else { - //m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAddData could not insert message into database. "+message["Identifier"]); + m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAllData Error couldn't find identity : "+message["Identifier"]); + validmessage=false; } + // make sure we will at least save to 1 board before inserting message + savetoboardcount=0; + for(std::vector::iterator bi=boards.begin(); bi!=boards.end(); bi++) + { + if(SaveToBoard((*bi))) + { + savetoboardcount++; + } + } + + if(validmessage && savetoboardcount>0) + { + st=m_db->Prepare("INSERT INTO tblMessage(IdentityID,FromName,MessageDate,MessageTime,Subject,MessageUUID,ReplyBoardID,Body) VALUES(?,?,?,?,?,?,?,?);"); + st.Bind(0,identityid); + st.Bind(1,GetIdentityName(identityid)); + st.Bind(2,xml.GetDate()); + st.Bind(3,xml.GetTime()); + st.Bind(4,xml.GetSubject()); + st.Bind(5,xml.GetMessageID()); + st.Bind(6,GetBoardID(xml.GetReplyBoard())); + st.Bind(7,xml.GetBody()); + inserted=st.Step(true); + int messageid=st.GetLastInsertRowID(); + + if(inserted==true) + { + + st=m_db->Prepare("INSERT INTO tblMessageBoard(MessageID,BoardID) VALUES(?,?);"); + for(std::vector::iterator i=boards.begin(); i!=boards.end(); i++) + { + if(SaveToBoard((*i))) + { + st.Bind(0,messageid); + st.Bind(1,GetBoardID((*i))); + st.Step(); + st.Reset(); + } + } + st.Finalize(); + + st=m_db->Prepare("INSERT INTO tblMessageReplyTo(MessageID,ReplyToMessageUUID,ReplyOrder) VALUES(?,?,?);"); + for(std::map::iterator j=replyto.begin(); j!=replyto.end(); j++) + { + st.Bind(0,messageid); + st.Bind(1,(*j).second); + st.Bind(2,(*j).first); + st.Step(); + st.Reset(); + } + st.Finalize(); + + m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageRequester::HandleAllData parsed Message XML file : "+message["Identifier"]); + + } + else // couldn't insert - was already in database + { + //m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAddData could not insert message into database. "+message["Identifier"]); + } + + } // if validmessage } else { @@ -294,7 +348,8 @@ void MessageRequester::PopulateIDList() sql="SELECT tblIdentity.IdentityID,Day,RequestIndex "; sql+="FROM tblMessageRequests INNER JOIN tblIdentity ON tblMessageRequests.IdentityID=tblIdentity.IdentityID "; - sql+="WHERE tblIdentity.LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust') AND FromMessageList='true' AND Found='false' AND Day>='"+date.Format("%Y-%m-%d")+"' "; + sql+="WHERE (tblIdentity.LocalMessageTrust IS NULL OR tblIdentity.LocalMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalMessageTrust')) "; + sql+="AND FromMessageList='true' AND Found='false' AND Day>='"+date.Format("%Y-%m-%d")+"' "; sql+="AND (tblIdentity.PeerMessageTrust IS NULL OR tblIdentity.PeerMessageTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerMessageTrust')) "; sql+=";"; @@ -325,6 +380,28 @@ void MessageRequester::PopulateIDList() } +const bool MessageRequester::SaveToBoard(const std::string &boardname) +{ + bool save=true; + SQLite3DB::Statement st=m_db->Prepare("SELECT SaveReceivedMessages FROM tblBoard WHERE BoardName=?;"); + st.Bind(0,boardname); + st.Step(); + if(st.RowReturned()) + { + std::string val=""; + st.ResultText(0,val); + if(val=="true") + { + save=true; + } + else + { + save=false; + } + } + return save; +} + void MessageRequester::StartRequest(const std::string &requestid) { FCPMessage message; diff --git a/src/freenet/trustlistinserter.cpp b/src/freenet/trustlistinserter.cpp index 5f2fbb8..2d14f89 100644 --- a/src/freenet/trustlistinserter.cpp +++ b/src/freenet/trustlistinserter.cpp @@ -148,8 +148,22 @@ void TrustListInserter::StartInsert(const long localidentityid, const std::strin while(st.RowReturned()) { st.ResultText(0,publickey); - st.ResultInt(1,messagetrust); - st.ResultInt(2,trustlisttrust); + if(st.ResultNull(1)==false) + { + st.ResultInt(1,messagetrust); + } + else + { + messagetrust=-1; + } + if(st.ResultNull(2)==false) + { + st.ResultInt(2,trustlisttrust); + } + else + { + trustlisttrust=-1; + } xml.AddTrust(publickey,messagetrust,trustlisttrust); st.Step(); } diff --git a/src/freenet/trustlistrequester.cpp b/src/freenet/trustlistrequester.cpp index 3fd5d99..77b03b1 100644 --- a/src/freenet/trustlistrequester.cpp +++ b/src/freenet/trustlistrequester.cpp @@ -96,8 +96,22 @@ const bool TrustListRequester::HandleAllData(FCPMessage &message) //insert trust for this identity trustst.Bind(0,identityid); trustst.Bind(1,id); - trustst.Bind(2,xml.GetMessageTrust(i)); - trustst.Bind(3,xml.GetTrustListTrust(i)); + if(xml.GetMessageTrust(i)==-1) + { + trustst.Bind(2); + } + else + { + trustst.Bind(2,xml.GetMessageTrust(i)); + } + if(xml.GetTrustListTrust(i)==-1) + { + trustst.Bind(3); + } + else + { + trustst.Bind(3,xml.GetTrustListTrust(i)); + } trustst.Step(); trustst.Reset(); diff --git a/src/freenet/trustlistxml.cpp b/src/freenet/trustlistxml.cpp index c3e71db..d732105 100644 --- a/src/freenet/trustlistxml.cpp +++ b/src/freenet/trustlistxml.cpp @@ -73,8 +73,14 @@ std::string TrustListXML::GetXML() TiXmlElement *tr=new TiXmlElement("Trust"); tid->LinkEndChild(tr); tr->LinkEndChild(XMLCreateCDATAElement("Identity",(*i).m_identity)); - tr->LinkEndChild(XMLCreateTextElement("MessageTrustLevel",messagetrust)); - tr->LinkEndChild(XMLCreateTextElement("TrustListTrustLevel",trustlisttrust)); + if((*i).m_messagetrust>=0) + { + tr->LinkEndChild(XMLCreateTextElement("MessageTrustLevel",messagetrust)); + } + if((*i).m_trustlisttrust>=0) + { + tr->LinkEndChild(XMLCreateTextElement("TrustListTrustLevel",trustlisttrust)); + } } td.Accept(&tp); @@ -122,16 +128,22 @@ const bool TrustListXML::ParseXML(const std::string &xml) if(txt) { messagetruststr=txt->ValueStr(); - StringFunctions::Convert(messagetruststr,messagetrust); + if(messagetruststr!="") + { + StringFunctions::Convert(messagetruststr,messagetrust); + } } txt=hnd2.FirstChild("TrustListTrustLevel").FirstChild().ToText(); if(txt) { trustlisttruststr=txt->ValueStr(); - StringFunctions::Convert(trustlisttruststr,trustlisttrust); + if(trustlisttruststr!="") + { + StringFunctions::Convert(trustlisttruststr,trustlisttrust); + } } - if(identity!="" && messagetrust>=0 && messagetrust<=100 && trustlisttrust>=0 && trustlisttrust<=100) + if(identity!="" && messagetrust>=-1 && messagetrust<=100 && trustlisttrust>=-1 && trustlisttrust<=100) { // check so we don't add the same identity multiple times from a trust list if(std::find(m_foundkeys.begin(),m_foundkeys.end(),identity)==m_foundkeys.end()) diff --git a/src/global.cpp b/src/global.cpp index 0c6f913..5515e1a 100644 --- a/src/global.cpp +++ b/src/global.cpp @@ -52,13 +52,19 @@ void SetupDB() major=1; minor=1; } + if(major==1 && (minor==1 || minor==2)) + { + ConvertDB0101To0103(); + major=1; + minor=3; + } } else { db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,1);"); } - db->Execute("UPDATE tblDBVersion SET Major=1, Minor=2;"); + db->Execute("UPDATE tblDBVersion SET Major=1, Minor=3;"); db->Execute("CREATE TABLE IF NOT EXISTS tblOption(\ Option TEXT UNIQUE,\ @@ -126,10 +132,10 @@ void SetupDB() PublishBoardList BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\ DateAdded DATETIME,\ LastSeen DATETIME,\ - LocalMessageTrust INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT 50,\ - PeerMessageTrust INTEGER CHECK(PeerMessageTrust BETWEEN 0 AND 100) DEFAULT 50,\ - LocalTrustListTrust INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT 50,\ - PeerTrustListTrust INTEGER CHECK(PeerTrustListTrust BETWEEN 0 AND 100) DEFAULT 50\ + LocalMessageTrust INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\ + PeerMessageTrust INTEGER CHECK(PeerMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\ + LocalTrustListTrust INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL,\ + PeerTrustListTrust INTEGER CHECK(PeerTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL\ );"); db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityRequests(\ @@ -166,10 +172,11 @@ void SetupDB() );"); db->Execute("CREATE TABLE IF NOT EXISTS tblBoard(\ - BoardID INTEGER PRIMARY KEY,\ - BoardName TEXT UNIQUE,\ - BoardDescription TEXT,\ - DateAdded DATETIME\ + BoardID INTEGER PRIMARY KEY,\ + BoardName TEXT UNIQUE,\ + BoardDescription TEXT,\ + DateAdded DATETIME,\ + SaveReceivedMessages BOOL CHECK(SaveReceivedMessages IN('true','false')) DEFAULT 'true'\ );"); db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('fms','Freenet Message System','2007-12-01 12:00:00');"); @@ -265,10 +272,13 @@ void SetupDB() GROUP BY tblBoard.BoardID;"); // calculates peer trust + // do the (MessageTrust+1)*LocalTrustListTrust/(MessageTrust+1)/100.0 - so it MessageTrust or TrustListTrust is NULL, the calc will be NULL and it won't be included at all in the average + // need the +1 so that when the values are 0 the result is not 0 + db->Execute("DROP VIEW IF EXISTS vwCalculatedPeerTrust;"); db->Execute("CREATE VIEW IF NOT EXISTS vwCalculatedPeerTrust AS \ SELECT TargetIdentityID, \ - ROUND(SUM(MessageTrust*(LocalMessageTrust/100.0))/SUM(LocalMessageTrust/100.0),0) AS 'PeerMessageTrust', \ - ROUND(SUM(TrustListTrust*(LocalTrustListTrust/100.0))/SUM(LocalTrustListTrust/100.0),0) AS 'PeerTrustListTrust' \ + ROUND(SUM(MessageTrust*(LocalTrustListTrust/100.0))/SUM(((MessageTrust+1)*LocalTrustListTrust/(MessageTrust+1))/100.0),0) AS 'PeerMessageTrust', \ + ROUND(SUM(TrustListTrust*(LocalTrustListTrust/100.0))/SUM(((TrustListTrust+1)*LocalTrustListTrust/(TrustListTrust+1))/100.0),0) AS 'PeerTrustListTrust' \ FROM tblPeerTrust INNER JOIN tblIdentity ON tblPeerTrust.IdentityID=tblIdentity.IdentityID \ WHERE LocalTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalTrustListTrust') \ AND ( PeerTrustListTrust IS NULL OR PeerTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerTrustListTrust') ) \ @@ -360,7 +370,7 @@ void SetupDB() date.SetToGMTime(); // insert SomeDude's public key - db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw,iXez4j3qCpd596TxXiJgZyTq9o-CElEuJxm~jNNZAuA,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');"); + db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,LocalTrustListTrust) VALUES('SSK@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw,iXez4j3qCpd596TxXiJgZyTq9o-CElEuJxm~jNNZAuA,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"',51);"); // insert Shadow Panther's public key db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@~mimyB1kmH4f7Cgsd2wM2Qv2NxrZHRMM6IY8~7EWRVQ,fxTKkR0TYhgMYb-vEGAv55sMOxCGD2xhE4ZxWHxdPz4,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');"); // insert garfield's public key @@ -398,6 +408,35 @@ void ConvertDB0100To0101() db->Execute("UPDATE tblDBVersion SET Major=1, Minor=1;"); } +void ConvertDB0101To0103() +{ + // remove default 50 from trust fields and set default to NULL + SQLite3DB::DB *db=SQLite3DB::DB::Instance(); + db->Execute("CREATE TEMPORARY TABLE tblIdentityTemp AS SELECT * FROM tblIdentity;"); + db->Execute("DROP TABLE IF EXISTS tblIdentity;"); + db->Execute("CREATE TABLE IF NOT EXISTS tblIdentity(\ + IdentityID INTEGER PRIMARY KEY,\ + PublicKey TEXT UNIQUE,\ + Name TEXT,\ + SingleUse BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\ + PublishTrustList BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\ + PublishBoardList BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\ + DateAdded DATETIME,\ + LastSeen DATETIME,\ + LocalMessageTrust INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\ + PeerMessageTrust INTEGER CHECK(PeerMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\ + LocalTrustListTrust INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL,\ + PeerTrustListTrust INTEGER CHECK(PeerTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL\ + );"); + db->Execute("INSERT INTO tblIdentity SELECT * FROM tblIdentityTemp;"); + db->Execute("DROP TABLE IF EXISTS tblIdentityTemp;"); + + // add SaveReceivedMessages field to tblBoard + db->Execute("ALTER TABLE tblBoard ADD COLUMN SaveReceivedMessages BOOL CHECK(SaveReceivedMessages IN('true','false')) DEFAULT 'true';"); + + db->Execute("UPDATE tblDBVersion SET Major=1, Minor=3;"); +} + void SetupDefaultOptions() { // OptionValue should always be inserted as a string, even if the option really isn't a string - just to keep the field data type consistent @@ -577,6 +616,12 @@ void SetupDefaultOptions() st.Step(); st.Reset(); + st.Bind(0,"AddNewPostFromIdentities"); + st.Bind(1,"false"); + st.Bind(2,"Set to true to automatically create new identities when you send a message using a new name. If you set this to false, posting messages will fail until you manually create the identity."); + st.Step(); + st.Reset(); + } void SetupLogFile() diff --git a/src/http/httpthread.cpp b/src/http/httpthread.cpp index 6ad6ef9..a58044c 100644 --- a/src/http/httpthread.cpp +++ b/src/http/httpthread.cpp @@ -13,6 +13,7 @@ #include "../../include/http/pages/peerdetailspage.h" #include "../../include/http/pages/peermaintenancepage.h" #include "../../include/http/pages/execquerypage.h" +#include "../../include/http/pages/boardspage.h" #include @@ -58,6 +59,7 @@ HTTPThread::HTTPThread() m_pagehandlers.push_back(new PeerDetailsPage(templatestr)); m_pagehandlers.push_back(new PeerMaintenancePage(templatestr)); m_pagehandlers.push_back(new ExecQueryPage(templatestr)); + m_pagehandlers.push_back(new BoardsPage(templatestr)); // homepage must be last - catch all page handler m_pagehandlers.push_back(new HomePage(templatestr)); diff --git a/src/http/ipagehandler.cpp b/src/http/ipagehandler.cpp index f4ac20f..3565aab 100644 --- a/src/http/ipagehandler.cpp +++ b/src/http/ipagehandler.cpp @@ -12,7 +12,7 @@ void IPageHandler::CreateArgArray(const std::map &vars, { if((*i).first.find(basename)==0 && (*i).first.find("[")!=std::string::npos && (*i).first.find("]")!=std::string::npos) { - int index; + int index=0; std::string indexstr; std::string::size_type startpos; std::string::size_type endpos; @@ -82,7 +82,7 @@ const bool IPageHandler::Handle(shttpd_arg *arg) long len; StringFunctions::Convert(std::string(lenstr),len); mystate->m_indata=new char[len+1]; - mystate->m_indata[len]=NULL; + mystate->m_indata[len]='\0'; mystate->m_indatalen=len; mystate->m_indatapos=0; } diff --git a/src/http/pages/boardspage.cpp b/src/http/pages/boardspage.cpp new file mode 100644 index 0000000..8d10aa6 --- /dev/null +++ b/src/http/pages/boardspage.cpp @@ -0,0 +1,258 @@ +#include "../../../include/http/pages/boardspage.h" +#include "../../../include/stringfunctions.h" +#include "../../../include/datetime.h" + +#ifdef XMEM + #include +#endif + +const std::string BoardsPage::BuildQueryString(const long startrow, const std::string &boardsearch) +{ + std::string returnval=""; + std::string tempval=""; + + if(startrow>=0) + { + StringFunctions::Convert(startrow,tempval); + returnval+="startrow="+tempval; + } + + if(boardsearch!="") + { + if(returnval!="") + { + returnval+="&"; + } + returnval+="boardsearch="+boardsearch; + } + + return returnval; + +} + +const std::string BoardsPage::GeneratePage(const std::string &method, const std::map &queryvars) +{ + int boardcount=0; + std::string content=""; + int rownum=0; + int rowsperpage=25; + std::string rowsperpagestr="25"; + int startrow=0; + std::string startrowstr="0"; + std::string boardsearch=""; + std::string sql=""; + DateTime now; + now.SetToGMTime(); + + if(queryvars.find("formaction")!=queryvars.end()) + { + if((*queryvars.find("formaction")).second=="addboard" && queryvars.find("boardname")!=queryvars.end() && queryvars.find("boarddescription")!=queryvars.end()) + { + std::string boardname=""; + std::string boarddescription=""; + + boardname=(*queryvars.find("boardname")).second; + boarddescription=(*queryvars.find("boarddescription")).second; + + SQLite3DB::Statement addst=m_db->Prepare("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES(?,?,?);"); + addst.Bind(0,boardname); + addst.Bind(1,boarddescription); + addst.Bind(2,now.Format("%Y-%m-%d %H:%M:%S")); + addst.Step(); + } + if((*queryvars.find("formaction")).second=="update") + { + int boardid; + std::vector boardids; + std::vector olddescriptions; + std::vector descriptions; + std::vector oldsavemessages; + std::vector savemessages; + + CreateArgArray(queryvars,"boardid",boardids); + CreateArgArray(queryvars,"oldboarddescription",olddescriptions); + CreateArgArray(queryvars,"boarddescription",descriptions); + CreateArgArray(queryvars,"oldsavereceivedmessages",oldsavemessages); + CreateArgArray(queryvars,"savereceivedmessages",savemessages); + + olddescriptions.resize(boardids.size(),""); + descriptions.resize(boardids.size(),""); + oldsavemessages.resize(boardids.size(),""); + savemessages.resize(boardids.size(),""); + + SQLite3DB::Statement updatest=m_db->Prepare("UPDATE tblBoard SET BoardDescription=?, SaveReceivedMessages=? WHERE BoardID=?;"); + + for(int i=0; iPrepare(sql); + if(boardsearch!="") + { + st.Bind(0,boardsearch); + st.Bind(1,boardsearch); + } + st.Step(); + if(st.RowReturned()) + { + st.ResultInt(0,boardcount); + } + st.Finalize(); + + + sql="SELECT BoardID,BoardName,BoardDescription,SaveReceivedMessages FROM tblBoard WHERE BoardID NOT IN (SELECT BoardID FROM tblAdministrationBoard)"; + if(boardsearch!="") + { + sql+=" AND (BoardName LIKE '%' || ? || '%' OR BoardDescription LIKE '%' || ? || '%')"; + } + sql+=" ORDER BY BoardName COLLATE NOCASE"; + sql+=" LIMIT "+startrowstr+","+rowsperpagestr+";"; + + st=m_db->Prepare(sql); + if(boardsearch!="") + { + st.Bind(0,boardsearch); + st.Bind(1,boardsearch); + } + st.Step(); + + content+=""; + + content+=""; + content+=""; + content+=""; + + content+=""; + content+=""; + content+=""; + + content+=""; + content+=""; + content+=""; + content+=""; + while(st.RowReturned() && rownum"; + content+=""; + content+=""; + cols+=1; + } + if(startrow+rowsperpageNext Page -->"; + } + content+=""; + } + + content+=""; + content+=""; + content+=""; + content+="
"; + content+="
"; + content+="

NameDescriptionSave Received Messages
"; + content+=""; + content+=""; + content+=""; + content+="0 || startrow+rowsperpage0) + { + StringFunctions::Convert(startrow-rowsperpage,tempstr); + content+="<-- Previous Page
"; + + return "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"+StringFunctions::Replace(m_template,"[CONTENT]",content); +} + +const bool BoardsPage::WillHandleURI(const std::string &uri) +{ + if(uri.find("boards.")!=std::string::npos) + { + return true; + } + else + { + return false; + } +} diff --git a/src/http/pages/homepage.cpp b/src/http/pages/homepage.cpp index c89d92c..f305f30 100644 --- a/src/http/pages/homepage.cpp +++ b/src/http/pages/homepage.cpp @@ -16,6 +16,9 @@ const std::string HomePage::GeneratePage(const std::string &method, const std::m std::string content="

Home

"; content+="

"; + content+="FMS version "; + content+=FMS_VERSION; + content+="
"; content+="Use these pages to administer your FMS installation."; content+="

"; content+="

"; diff --git a/src/http/pages/peertrustpage.cpp b/src/http/pages/peertrustpage.cpp index 667595d..48a19e8 100644 --- a/src/http/pages/peertrustpage.cpp +++ b/src/http/pages/peertrustpage.cpp @@ -91,8 +91,22 @@ const std::string PeerTrustPage::GeneratePage(const std::string &method, const s StringFunctions::Convert(ltlt[i],localtrustlisttrust); StringFunctions::Convert(identityids[i],identityid); - update.Bind(0,localmessagetrust); - update.Bind(1,localtrustlisttrust); + if(lmt[i]!="") + { + update.Bind(0,localmessagetrust); + } + else + { + update.Bind(0); + } + if(ltlt[i]!="") + { + update.Bind(1,localtrustlisttrust); + } + else + { + update.Bind(1); + } update.Bind(2,identityid); update.Step(); update.Reset(); @@ -144,7 +158,7 @@ const std::string PeerTrustPage::GeneratePage(const std::string &method, const s content+="Message Trust is how much you trust the identity to post good messages. Trust List Trust is how much weight you want the trust list of that identity to have when calculating the total. The local trust levels are set by you, and the peer trust levels are calculated by a weighted average using other identities' trust lists."; content+="

"; content+="
"; - content+=""; + content+=""; content+=""; content+="
"; content+="
"; @@ -279,7 +293,7 @@ const std::string PeerTrustPage::GeneratePage(const std::string &method, const s content+=""; } - content+=""; + content+="
"; content+=""; content+=""; diff --git a/src/logfile.cpp b/src/logfile.cpp index 7e632f9..52d0452 100644 --- a/src/logfile.cpp +++ b/src/logfile.cpp @@ -75,7 +75,7 @@ void LogFile::WriteDate() struct tm *timeinfo=gmtime(&rawtime); strftime(m_datebuffer,99,"%Y-%m-%d %H:%M:%S : ",timeinfo); - m_datebuffer[99]=NULL; + m_datebuffer[99]='\0'; fputs(m_datebuffer,m_fileptr); } diff --git a/src/message.cpp b/src/message.cpp index 41add10..d8adc87 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -140,8 +140,22 @@ void Message::HandleAdministrationMessage() { origmess.ResultInt(0,identityid); origmess.ResultText(1,identityname); - origmess.ResultInt(2,origmessagetrust); - origmess.ResultInt(3,origtrustlisttrust); + if(origmess.ResultNull(2)==false) + { + origmess.ResultInt(2,origmessagetrust); + } + else + { + origmessagetrust=50; + } + if(origmess.ResultNull(3)==false) + { + origmess.ResultInt(3,origtrustlisttrust); + } + else + { + origtrustlisttrust=50; + } origmessagetrust+=changemessagetrust; origtrustlisttrust+=changetrustlisttrust; @@ -222,7 +236,14 @@ void Message::HandleChangeTrust() int localmessagetrust=0; st.ResultInt(0,identityid); - st.ResultInt(1,localmessagetrust); + if(st.ResultNull(1)==false) + { + st.ResultInt(1,localmessagetrust); + } + else + { + localmessagetrust=50; + } localmessagetrust+=m_changemessagetrustonreply; if(localmessagetrust<0) @@ -258,6 +279,15 @@ void Message::Initialize() m_changemessagetrustonreply=0; Option::Instance()->Get("ChangeMessageTrustOnReply",tempval); StringFunctions::Convert(tempval,m_changemessagetrustonreply); + Option::Instance()->Get("AddNewPostFromIdentities",tempval); + if(tempval=="true") + { + m_addnewpostfromidentities=true; + } + else + { + m_addnewpostfromidentities=false; + } } const bool Message::Load(const long messageid, const long boardid) @@ -587,7 +617,7 @@ const bool Message::ParseNNTPMessage(const std::string &nntpmessage) return true; } -void Message::StartFreenetInsert() +const bool Message::StartFreenetInsert() { MessageXML xml; @@ -618,12 +648,19 @@ void Message::StartFreenetInsert() // couldn't find identity with this name - insert a new identity if(!st.RowReturned()) { - DateTime now; - now.SetToGMTime(); - st=m_db->Prepare("INSERT INTO tblLocalIdentity(Name) VALUES(?);"); - st.Bind(0,m_fromname); - st.Step(true); - localidentityid=st.GetLastInsertRowID(); + if(m_addnewpostfromidentities==true) + { + DateTime now; + now.SetToGMTime(); + st=m_db->Prepare("INSERT INTO tblLocalIdentity(Name) VALUES(?);"); + st.Bind(0,m_fromname); + st.Step(true); + localidentityid=st.GetLastInsertRowID(); + } + else + { + return false; + } } else { @@ -638,4 +675,6 @@ void Message::StartFreenetInsert() HandleChangeTrust(); + return true; + } diff --git a/src/nntp/mime/Mime.cpp b/src/nntp/mime/Mime.cpp index 89de9f1..d925590 100644 --- a/src/nntp/mime/Mime.cpp +++ b/src/nntp/mime/Mime.cpp @@ -475,7 +475,7 @@ list::iterator CMimeHeader::FindField(const char* pszFieldName) #include #else #if !defined(__APPLE__) && !defined(__DARWIN__) - #ifndef __FreeBSD__ + #if !defined(__FreeBSD__) && !defined(solaris) && !defined(__sun) #include #else #include diff --git a/src/nntp/nntpconnection.cpp b/src/nntp/nntpconnection.cpp index 078c1c3..fa35f4f 100644 --- a/src/nntp/nntpconnection.cpp +++ b/src/nntp/nntpconnection.cpp @@ -786,9 +786,15 @@ void NNTPConnection::HandlePostedMessage(const std::string &message) } else { - mess.StartFreenetInsert(); + if(mess.StartFreenetInsert()) + { + SendBufferedLine("240 Article received OK"); + } + else + { + SendBufferedLine("441 Posting failed. Make sure the identity you are sending with exists!"); + } } - SendBufferedLine("240 Article received OK"); } else { diff --git a/template.htm b/template.htm index 157b1b2..1320715 100644 --- a/template.htm +++ b/template.htm @@ -224,6 +224,7 @@ td { padding-left:5px; padding-right:5px; }
  • Add Peer
  • Peer Maintenance
  • Peer Trust
  • +
  • Boards
  • Control Boards
  • -- 2.7.4