#include "../include/db/sqlite3db.h"\r
#include "../include/freenet/freenetmasterthread.h"\r
#include "../include/nntp/nntplistener.h"\r
+#include "../include/http/httpthread.h"\r
\r
#ifdef _WIN32\r
#include <winsock2.h>\r
void SetupDB()\r
{\r
\r
- SQLite3DB::DB *db=SQLite3DB::DB::instance();\r
+ DateTime date;\r
+ SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
\r
db->Open("fms.db3");\r
db->SetBusyTimeout(10000); // set timeout to 10 seconds\r
db->Execute("VACUUM;");\r
+ \r
+ // TODO remove this - temp fix for problem in 0.1.8\r
+ db->Execute("DELETE FROM tblMessageBoard WHERE MessageID NOT IN (SELECT MessageID FROM tblMessage);");\r
+\r
+ db->Execute("CREATE TABLE IF NOT EXISTS tblDBVersion(\\r
+ Major INTEGER,\\r
+ Minor INTEGER\\r
+ );");\r
+\r
+ SQLite3DB::Statement st=db->Prepare("SELECT Major,Minor FROM tblDBVersion;");\r
+ st.Step();\r
+ if(st.RowReturned())\r
+ {\r
+ int major;\r
+ int minor;\r
+ st.ResultInt(0,major);\r
+ st.ResultInt(1,minor);\r
+ }\r
+ else\r
+ {\r
+ db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,0);");\r
+ }\r
\r
db->Execute("CREATE TABLE IF NOT EXISTS tblOption(\\r
Option TEXT UNIQUE,\\r
\r
db->Execute("CREATE TABLE IF NOT EXISTS tblIdentity(\\r
IdentityID INTEGER PRIMARY KEY,\\r
- PublicKey TEXT,\\r
+ PublicKey TEXT UNIQUE,\\r
Name TEXT,\\r
SingleUse BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
PublishTrustList BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
\r
db->Execute("CREATE TABLE IF NOT EXISTS tblMessageReplyTo(\\r
MessageID INTEGER,\\r
- ReplyToMessageUUID INTEGER,\\r
+ ReplyToMessageUUID TEXT,\\r
ReplyOrder INTEGER\\r
);");\r
\r
Inserted BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
);");\r
\r
+ db->Execute("CREATE TABLE IF NOT EXISTS tblAdministrationBoard(\\r
+ BoardID INTEGER UNIQUE,\\r
+ ModifyLocalMessageTrust INTEGER,\\r
+ ModifyLocalTrustListTrust INTEGER\\r
+ );");\r
+\r
+ // MessageInserter will insert a record into this temp table which the MessageListInserter will query for and insert a MessageList when needed\r
+ db->Execute("CREATE TEMPORARY TABLE IF NOT EXISTS tmpMessageListInsert(\\r
+ LocalIdentityID INTEGER,\\r
+ Date DATETIME\\r
+ );");\r
+\r
// low / high / message count for each board\r
db->Execute("CREATE VIEW IF NOT EXISTS vwBoardStats AS \\r
SELECT tblBoard.BoardID AS 'BoardID', IFNULL(MIN(MessageID),0) AS 'LowMessageID', IFNULL(MAX(MessageID),0) AS 'HighMessageID', COUNT(MessageID) AS 'MessageCount' \\r
FROM tblBoard LEFT JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID \\r
- WHERE MessageID>=0 \\r
+ WHERE MessageID>=0 OR MessageID IS NULL \\r
GROUP BY tblBoard.BoardID;");\r
\r
// calculates peer trust\r
ROUND(SUM(TrustListTrust*(LocalTrustListTrust/100.0))/SUM(LocalTrustListTrust/100.0),0) AS 'PeerTrustListTrust' \\r
FROM tblPeerTrust INNER JOIN tblIdentity ON tblPeerTrust.IdentityID=tblIdentity.IdentityID \\r
WHERE LocalTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalTrustListTrust') \\r
+ AND ( PeerTrustListTrust IS NULL OR PeerTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerTrustListTrust') ) \\r
GROUP BY TargetIdentityID;");\r
\r
+ /*\r
+ These peer trust calculations are too CPU intensive to be triggers - they were called every time a new trust list was processed\r
+ All trust levels will now be recalculated every hour in the PeriodicDBMaintenance class\r
+ */\r
+ // drop existing triggers\r
+ db->Execute("DROP TRIGGER IF EXISTS trgDeleteOntblPeerTrust;");\r
+ db->Execute("DROP TRIGGER IF EXISTS trgInsertOntblPeerTrust;");\r
+ db->Execute("DROP TRIGGER IF EXISTS trgUpdateOntblPeerTrust;");\r
+ db->Execute("DROP TRIGGER IF EXISTS trgUpdateLocalTrustLevels;");\r
+/*\r
// update PeerTrustLevel when deleting a record from tblPeerTrust\r
- db->Execute("CREATE TRIGGER trgDeleteOntblPeerTrust AFTER DELETE ON tblPeerTrust \\r
+ db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteOntblPeerTrust AFTER DELETE ON tblPeerTrust \\r
FOR EACH ROW \\r
BEGIN \\r
UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID) WHERE IdentityID=old.TargetIdentityID;\\r
END;");\r
\r
// update PeerTrustLevel when inserting a record into tblPeerTrust\r
- db->Execute("CREATE TRIGGER trgInsertOntblPeerTrust AFTER INSERT ON tblPeerTrust \\r
+ db->Execute("CREATE TRIGGER IF NOT EXISTS trgInsertOntblPeerTrust AFTER INSERT ON tblPeerTrust \\r
FOR EACH ROW \\r
BEGIN \\r
UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID) WHERE IdentityID=new.TargetIdentityID;\\r
END;");\r
\r
// update PeerTrustLevel when updating a record in tblPeerTrust\r
- db->Execute("CREATE TRIGGER trgUpdateOntblPeerTrust AFTER UPDATE ON tblPeerTrust \\r
+ db->Execute("CREATE TRIGGER IF NOT EXISTS trgUpdateOntblPeerTrust AFTER UPDATE ON tblPeerTrust \\r
FOR EACH ROW \\r
BEGIN \\r
UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID) WHERE IdentityID=old.TargetIdentityID;\\r
END;");\r
\r
// recalculate all Peer TrustLevels when updating Local TrustLevels on tblIdentity - doesn't really need to be all, but rather all identities the updated identity has a trust level for. It's easier to update everyone for now.\r
- db->Execute("CREATE TRIGGER trgUpdateLocalTrustLevels AFTER UPDATE OF LocalMessageTrust,LocalTrustListTrust ON tblIdentity \\r
+ db->Execute("CREATE TRIGGER IF NOT EXISTS trgUpdateLocalTrustLevels AFTER UPDATE OF LocalMessageTrust,LocalTrustListTrust ON tblIdentity \\r
FOR EACH ROW \\r
BEGIN \\r
UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID);\\r
END;");\r
+*/\r
+\r
+ db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteMessage AFTER DELETE ON tblMessage \\r
+ FOR EACH ROW \\r
+ BEGIN \\r
+ DELETE FROM tblMessageBoard WHERE tblMessageBoard.MessageID=old.MessageID;\\r
+ DELETE FROM tblMessageReplyTo WHERE tblMessageReplyTo.MessageID=old.MessageID;\\r
+ END;");\r
+\r
+ db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteIdentity AFTER DELETE ON tblIdentity \\r
+ FOR EACH ROW \\r
+ BEGIN \\r
+ DELETE FROM tblIdentityRequests WHERE IdentityID=old.IdentityID;\\r
+ DELETE FROM tblIntroductionPuzzleRequests WHERE IdentityID=old.IdentityID;\\r
+ DELETE FROM tblMessageListRequests WHERE IdentityID=old.IdentityID;\\r
+ DELETE FROM tblMessageRequests WHERE IdentityID=old.IdentityID;\\r
+ DELETE FROM tblPeerTrust WHERE IdentityID=old.IdentityID;\\r
+ DELETE FROM tblTrustListRequests WHERE IdentityID=old.IdentityID;\\r
+ END;");\r
+\r
+ db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteLocalIdentity AFTER DELETE ON tblLocalIdentity \\r
+ FOR EACH ROW \\r
+ BEGIN \\r
+ DELETE FROM tblIdentityIntroductionInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
+ DELETE FROM tblIntroductionPuzzleInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
+ DELETE FROM tblLocalIdentityInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
+ DELETE FROM tblMessageInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
+ DELETE FROM tblMessageListInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
+ DELETE FROM tblTrustListInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
+ END;");\r
\r
// delete introduction puzzles that were half-way inserted\r
db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day IS NULL AND InsertIndex IS NULL;");\r
\r
+ // delete stale introduction puzzles (2 or more days old)\r
+ date.SetToGMTime();\r
+ date.Add(0,0,0,-2);\r
+ db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day<='"+date.Format("%Y-%m-%d")+"';");\r
+ db->Execute("DELETE FROM tblIntroductionPuzzleRequests WHERE Day<='"+date.Format("%Y-%m-%d")+"';");\r
+\r
+ // insert SomeDude's public key\r
+ date.SetToGMTime();\r
+ db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw,iXez4j3qCpd596TxXiJgZyTq9o-CElEuJxm~jNNZAuA,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');");\r
+\r
}\r
\r
void SetupDefaultOptions()\r
// 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\r
\r
std::ostringstream tempstr; // must set tempstr to "" between db inserts\r
- SQLite3DB::DB *db=SQLite3DB::DB::instance();\r
+ SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
SQLite3DB::Statement st=db->Prepare("INSERT INTO tblOption(Option,OptionValue,OptionDescription) VALUES(?,?,?);");\r
\r
// LogLevel\r
// StartNNTP\r
st.Bind(0,"StartNNTP");\r
st.Bind(1,"true");\r
- st.Bind(2,"Start NNTP service.");\r
+ st.Bind(2,"Start NNTP server.");\r
+ st.Step();\r
+ st.Reset();\r
+\r
+ st.Bind(0,"StartHTTP");\r
+ st.Bind(1,"true");\r
+ st.Bind(2,"Start HTTP server.");\r
+ st.Step();\r
+ st.Reset();\r
+\r
+ st.Bind(0,"HTTPListenPort");\r
+ st.Bind(1,"8080");\r
+ st.Bind(2,"Port HTTP server will listen on.");\r
st.Step();\r
st.Reset();\r
\r
\r
// FCPHost\r
st.Bind(0,"FCPHost");\r
- st.Bind(1,"localhost");\r
+ st.Bind(1,"127.0.0.1");\r
st.Bind(2,"Host name or address of Freenet node.");\r
st.Step();\r
st.Reset();\r
st.Step();\r
st.Reset();\r
\r
+ st.Bind(0,"MinPeerMessageTrust");\r
+ st.Bind(1,"30");\r
+ st.Bind(2,"Specifies a peer message trust level that a peer must have before its messages will be downloaded.");\r
+ st.Step();\r
+ st.Reset();\r
+\r
st.Bind(0,"MinLocalTrustListTrust");\r
- st.Bind(1,"50");\r
+ st.Bind(1,"51");\r
st.Bind(2,"Specifies a local trust list trust level that a peer must have before its trust list will be included in the weighted average. Any peers below this number will be excluded from the results.");\r
st.Step();\r
st.Reset();\r
\r
+ st.Bind(0,"MinPeerTrustListTrust");\r
+ st.Bind(1,"30");\r
+ st.Bind(2,"Specifies a peer trust list trust level that a peer must have before its trust list will be included in the weighted average. Any peers below this number will be excluded from the results.");\r
+ st.Step();\r
+ st.Reset();\r
+\r
st.Bind(0,"MessageDownloadMaxDaysBackward");\r
- st.Bind(1,"3");\r
+ st.Bind(1,"5");\r
st.Bind(2,"The maximum number of days backward that messages will be downloaded from each identity");\r
st.Step();\r
st.Reset();\r
\r
st.Bind(0,"MessageListDaysBackward");\r
- st.Bind(1,"3");\r
+ st.Bind(1,"5");\r
st.Bind(2,"The number of days backward that messages you have inserted will appear in your MessageLists");\r
st.Step();\r
st.Reset();\r
\r
date.SetToGMTime();\r
\r
- LogFile::instance()->SetFileName("fms-"+date.Format("%Y-%m-%d")+".log");\r
- LogFile::instance()->OpenFile();\r
- LogFile::instance()->SetWriteNewLine(true);\r
- LogFile::instance()->SetWriteDate(true);\r
- LogFile::instance()->SetWriteLogLevel(true);\r
+ LogFile::Instance()->SetFileName("fms-"+date.Format("%Y-%m-%d")+".log");\r
+ LogFile::Instance()->OpenFile();\r
+ LogFile::Instance()->SetWriteNewLine(true);\r
+ LogFile::Instance()->SetWriteDate(true);\r
+ LogFile::Instance()->SetWriteLogLevel(true);\r
\r
- if(Option::instance()->Get("LogLevel",configval)==false)\r
+ if(Option::Instance()->Get("LogLevel",configval)==false)\r
{\r
configval="4";\r
- Option::instance()->Set("LogLevel",configval);\r
+ Option::Instance()->Set("LogLevel",configval);\r
}\r
if(StringFunctions::Convert(configval,loglevel)==false)\r
{\r
loglevel=LogFile::LOGLEVEL_DEBUG;\r
- Option::instance()->Set("LogLevel",loglevel);\r
+ Option::Instance()->Set("LogLevel",loglevel);\r
}\r
- LogFile::instance()->SetLogLevel((LogFile::LogLevel)loglevel);\r
+ LogFile::Instance()->SetLogLevel((LogFile::LogLevel)loglevel);\r
}\r
\r
void SetupNetwork()\r
#endif\r
}\r
\r
-void ShutdownThreads(std::vector<ZThread::Thread *> &threads)\r
+void ShutdownThreads(std::vector<PThread::Thread *> &threads)\r
{\r
- std::vector<ZThread::Thread *>::iterator i;\r
+ std::vector<PThread::Thread *>::iterator i;\r
for(i=threads.begin(); i!=threads.end(); i++)\r
{\r
- if((*i)->wait(1)==false)\r
+/* if((*i)->wait(1)==false)\r
{\r
try\r
{\r
{\r
}\r
}\r
+ */\r
+ (*i)->Cancel();\r
}\r
\r
for(i=threads.begin(); i!=threads.end(); i++)\r
{\r
- (*i)->wait();\r
+ LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"ShutdownThreads waiting for thread to exit.");\r
+ //(*i)->wait();\r
+ (*i)->Join();\r
delete (*i);\r
}\r
\r
\r
}\r
\r
-void StartThreads(std::vector<ZThread::Thread *> &threads)\r
+void StartThreads(std::vector<PThread::Thread *> &threads)\r
{\r
std::string startfreenet;\r
std::string startnntp;\r
+ std::string starthttp;\r
\r
- if(Option::instance()->Get("StartFreenetUpdater",startfreenet)==false)\r
+ if(Option::Instance()->Get("StartFreenetUpdater",startfreenet)==false)\r
{\r
startfreenet="true";\r
- Option::instance()->Set("StartFreenetUpdater","true");\r
+ Option::Instance()->Set("StartFreenetUpdater","true");\r
}\r
\r
- if(Option::instance()->Get("StartNNTP",startnntp)==false)\r
+ if(Option::Instance()->Get("StartNNTP",startnntp)==false)\r
{\r
startnntp="true";\r
- Option::instance()->Set("StartNNTP","true");\r
+ Option::Instance()->Set("StartNNTP","true");\r
+ }\r
+\r
+ if(Option::Instance()->Get("StartHTTP",starthttp)==false)\r
+ {\r
+ starthttp="true";\r
+ Option::Instance()->Set("StartHTTP","true");\r
}\r
\r
if(startfreenet=="true")\r
{\r
- ZThread::Thread *t=new ZThread::Thread(new FreenetMasterThread());\r
+ PThread::Thread *t=new PThread::Thread(new FreenetMasterThread());\r
threads.push_back(t);\r
}\r
\r
if(startnntp=="true")\r
{\r
- ZThread::Thread *t=new ZThread::Thread(new NNTPListener());\r
+ PThread::Thread *t=new PThread::Thread(new NNTPListener());\r
+ threads.push_back(t);\r
+ }\r
+\r
+ if(starthttp=="true")\r
+ {\r
+ PThread::Thread *t=new PThread::Thread(new HTTPThread());\r
threads.push_back(t);\r
}\r
\r