version 0.1.12
[fms.git] / src / global.cpp
index 0437eb4..0c6f913 100644 (file)
@@ -7,6 +7,7 @@
 #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
@@ -16,6 +17,8 @@
        #include <xmem.h>\r
 #endif\r
 \r
+bool wantshutdown=false;\r
+\r
 void SetupDB()\r
 {\r
 \r
@@ -25,6 +28,37 @@ void SetupDB()
        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
@@ -35,8 +69,8 @@ void SetupDB()
        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
@@ -138,10 +172,10 @@ void SetupDB()
                                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
@@ -197,6 +231,26 @@ void SetupDB()
                                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
@@ -220,6 +274,16 @@ void SetupDB()
                                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
@@ -248,6 +312,7 @@ void SetupDB()
                                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
@@ -278,6 +343,12 @@ void SetupDB()
                                        DELETE FROM tblTrustListInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
                                END;");\r
 \r
+       db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteBoard AFTER DELETE ON tblBoard \\r
+                               FOR EACH ROW \\r
+                               BEGIN \\r
+                                       DELETE FROM tblMessageBoard WHERE BoardID=old.BoardID;\\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
@@ -287,12 +358,46 @@ void SetupDB()
        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
+       // 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
@@ -425,7 +530,7 @@ void SetupDefaultOptions()
        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
@@ -448,6 +553,30 @@ void SetupDefaultOptions()
        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
+       st.Bind(0,"ChangeMessageTrustOnReply");\r
+       st.Bind(1,"0");\r
+       st.Bind(2,"How much the local message trust level of an identity should change when you reply to one of their messages.");\r
+       st.Step();\r
+       st.Reset();\r
+\r
 }\r
 \r
 void SetupLogFile()\r
@@ -485,6 +614,16 @@ void SetupNetwork()
 #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
@@ -492,22 +631,18 @@ void ShutdownNetwork()
 #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
@@ -566,3 +701,4 @@ void StartThreads(std::vector<PThread::Thread *> &threads)
        }\r
 \r
 }\r
+*/\r