#include "../include/freenet/freenetmasterthread.h"\r
#include "../include/nntp/nntplistener.h"\r
#include "../include/http/httpthread.h"\r
+#include "../include/threadcontroller.h"\r
\r
#ifdef _WIN32\r
#include <winsock2.h>\r
#include <xmem.h>\r
#endif\r
\r
+bool wantshutdown=false;\r
+\r
void SetupDB()\r
{\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
+ st.Finalize();\r
+ if(major==1 && minor==0)\r
+ {\r
+ ConvertDB0100To0101();\r
+ major=1;\r
+ minor=1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,1);");\r
+ }\r
+\r
+ db->Execute("UPDATE tblDBVersion SET Major=1, Minor=2;");\r
\r
db->Execute("CREATE TABLE IF NOT EXISTS tblOption(\\r
Option TEXT UNIQUE,\\r
db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\\r
LocalIdentityID INTEGER PRIMARY KEY,\\r
Name TEXT,\\r
- PublicKey TEXT,\\r
- PrivateKey TEXT,\\r
+ PublicKey TEXT UNIQUE,\\r
+ PrivateKey TEXT UNIQUE,\\r
SingleUse BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
PublishTrustList BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
PublishBoardList BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
DateAdded DATETIME\\r
);");\r
\r
- db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('fms','Freenet Message System','2007-12-01');");\r
- db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('freenet','Discussion about Freenet','2007-12-01');");\r
- db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('public','Public discussion','2007-12-01');");\r
- db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('test','Test board','2007-12-01');");\r
+ db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('fms','Freenet Message System','2007-12-01 12:00:00');");\r
+ db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('freenet','Discussion about Freenet','2007-12-01 12:00:00');");\r
+ db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('public','Public discussion','2007-12-01 12:00:00');");\r
+ db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('test','Test board','2007-12-01 12:00:00');");\r
\r
db->Execute("CREATE TABLE IF NOT EXISTS tblMessage(\\r
MessageID INTEGER PRIMARY KEY,\\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
+ db->Execute("CREATE TABLE IF NOT EXISTS tblBoardListInserts(\\r
+ LocalIdentityID INTEGER,\\r
+ Day DATE,\\r
+ InsertIndex INTEGER,\\r
+ Inserted BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
+ );");\r
+\r
+ db->Execute("CREATE TABLE IF NOT EXISTS tblBoardListRequests(\\r
+ IdentityID INTEGER,\\r
+ Day DATE,\\r
+ RequestIndex INTEGER,\\r
+ Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\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
);");\r
\r
// low / high / message count for each board\r
- db->Execute("DROP VIEW IF EXISTS vwBoardStats; \\r
- CREATE VIEW IF NOT EXISTS vwBoardStats AS \\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 OR MessageID IS NULL \\r
GROUP BY tblBoard.BoardID;");\r
\r
// calculates peer trust\r
- db->Execute("DROP VIEW IF EXISTS vwCalculatedPeerTrust; \\r
- CREATE VIEW IF NOT EXISTS vwCalculatedPeerTrust AS \\r
+ db->Execute("CREATE VIEW IF NOT EXISTS vwCalculatedPeerTrust AS \\r
SELECT TargetIdentityID, \\r
ROUND(SUM(MessageTrust*(LocalMessageTrust/100.0))/SUM(LocalMessageTrust/100.0),0) AS 'PeerMessageTrust', \\r
ROUND(SUM(TrustListTrust*(LocalTrustListTrust/100.0))/SUM(LocalTrustListTrust/100.0),0) AS 'PeerTrustListTrust' \\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 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=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
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
+ // insert SomeDude's public key\r
+ db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw,iXez4j3qCpd596TxXiJgZyTq9o-CElEuJxm~jNNZAuA,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');");\r
+ // insert Shadow Panther's public key\r
+ db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@~mimyB1kmH4f7Cgsd2wM2Qv2NxrZHRMM6IY8~7EWRVQ,fxTKkR0TYhgMYb-vEGAv55sMOxCGD2xhE4ZxWHxdPz4,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');");\r
+ // insert garfield's public key\r
+ db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@T8l1IEGU4-PoASFzgc2GYhIgRzUvZsKdoQWeuLHuTmM,QLxAPfkGis8l5NafNpSCdbxzXhBlu9WL8svcqJw9Mpo,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');");\r
\r
}\r
\r
+void ConvertDB0100To0101()\r
+{\r
+ // added unique constraint to public and private key\r
+ SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
+ db->Execute("CREATE TEMPORARY TABLE tblLocalIdentityTemp AS SELECT * FROM tblLocalIdentity;");\r
+ db->Execute("DROP TABLE IF EXISTS tblLocalIdentity;");\r
+ db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\\r
+ LocalIdentityID INTEGER PRIMARY KEY,\\r
+ Name TEXT,\\r
+ PublicKey TEXT UNIQUE,\\r
+ PrivateKey TEXT UNIQUE,\\r
+ SingleUse BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
+ PublishTrustList BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
+ PublishBoardList BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
+ InsertingIdentity BOOL CHECK(InsertingIdentity IN('true','false')) DEFAULT 'false',\\r
+ LastInsertedIdentity DATETIME,\\r
+ InsertingPuzzle BOOL CHECK(InsertingPuzzle IN('true','false')) DEFAULT 'false',\\r
+ LastInsertedPuzzle DATETIME,\\r
+ InsertingTrustList BOOL CHECK(InsertingTrustList IN('true','false')) DEFAULT 'false',\\r
+ LastInsertedTrustList DATETIME,\\r
+ InsertingBoardList BOOL CHECK(InsertingBoardList IN('true','false')) DEFAULT 'false',\\r
+ LastInsertedBoardList DATETIME,\\r
+ InsertingMessageList BOOL CHECK(InsertingMessageList IN('true','false')) DEFAULT 'false',\\r
+ LastInsertedMessageList DATETIME\\r
+ );");\r
+ db->Execute("INSERT INTO tblLocalIdentity SELECT * FROM tblLocalIdentityTemp;");\r
+ db->Execute("DROP TABLE IF EXISTS tblLocalIdentityTemp;");\r
+ db->Execute("UPDATE tblDBVersion SET Major=1, Minor=1;");\r
+}\r
+\r
void SetupDefaultOptions()\r
{\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
// 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.Reset();\r
\r
st.Bind(0,"MinPeerMessageTrust");\r
- st.Bind(1,"25");\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,"25");\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
st.Step();\r
st.Reset();\r
\r
+ st.Bind(0,"MaxPeerMessagesPerDay");\r
+ st.Bind(1,"200");\r
+ st.Bind(2,"The maximum number of messages you will download from each peer on a given day.");\r
+ st.Step();\r
+ st.Reset();\r
+\r
+ st.Bind(0,"MaxBoardListRequests");\r
+ st.Bind(1,"5");\r
+ st.Bind(2,"The maximum number of concurrent requests for new Board Lists. Set to 0 to disable.");\r
+ st.Step();\r
+ st.Reset();\r
+\r
+ st.Bind(0,"MaxBoardsPerMessage");\r
+ st.Bind(1,"8");\r
+ st.Bind(2,"The maximum number of boards a received message may be sent to. Boards over this limit will be ignored.");\r
+ st.Step();\r
+ st.Reset();\r
+\r
}\r
\r
void SetupLogFile()\r
#endif\r
}\r
\r
+void Shutdown()\r
+{\r
+ ThreadController::Instance()->ShutdownThreads();\r
+\r
+ ShutdownNetwork();\r
+\r
+ LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_INFO,"FMS shutdown");\r
+ LogFile::Instance()->WriteNewLine();\r
+}\r
+\r
void ShutdownNetwork()\r
{\r
#ifdef _WIN32\r
#endif\r
}\r
\r
+void SigHandler(int signum)\r
+{\r
+ Shutdown();\r
+ exit(0);\r
+}\r
+\r
+/*\r
void ShutdownThreads(std::vector<PThread::Thread *> &threads)\r
{\r
std::vector<PThread::Thread *>::iterator i;\r
for(i=threads.begin(); i!=threads.end(); i++)\r
{\r
-/* if((*i)->wait(1)==false)\r
- {\r
- try\r
- {\r
- (*i)->interrupt();\r
- }\r
- catch(...)\r
- {\r
- }\r
- }\r
- */\r
(*i)->Cancel();\r
}\r
\r
}\r
\r
}\r
+*/\r