version 0.2.22
[fms.git] / src / global.cpp
index 2dea27b..872dfb7 100644 (file)
@@ -17,7 +17,7 @@
        #include <xmem.h>\r
 #endif\r
 \r
-bool wantshutdown=false;\r
+volatile bool wantshutdown=false;\r
 \r
 std::string CreateShortIdentityName(const std::string &name, const std::string &publickey)\r
 {\r
@@ -39,11 +39,18 @@ void SetupDB()
 {\r
 \r
        DateTime date;\r
+       std::string tempval="";\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;");               // not needed every startup\r
+\r
+       tempval="";\r
+       Option::Instance()->Get("VacuumOnStartup",tempval);\r
+       if(tempval=="true")\r
+       {\r
+               db->Execute("VACUUM;");\r
+       }\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblDBVersion(\\r
                                Major                           INTEGER,\\r
@@ -101,18 +108,45 @@ void SetupDB()
                        major=1;\r
                        minor=8;\r
                }\r
+               if(major==1 && minor==8)\r
+               {\r
+                       ConvertDB0108To0109();\r
+                       major=1;\r
+                       minor=9;\r
+               }\r
+               if(major==1 && minor==9)\r
+               {\r
+                       ConvertDB0109To0110();\r
+                       major=1;\r
+                       minor=10;\r
+               }\r
+               if(major==1 && minor==10)\r
+               {\r
+                       ConvertDB0110To0111();\r
+                       major=1;\r
+                       minor=11;\r
+               }\r
+               if(major==1 && minor==11)\r
+               {\r
+                       ConvertDB0111To0112();\r
+                       major=1;\r
+                       minor=12;\r
+               }\r
        }\r
        else\r
        {\r
-               db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,8);");\r
+               db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,12);");\r
        }\r
 \r
-       db->Execute("UPDATE tblDBVersion SET Major=1, Minor=8;");\r
+       db->Execute("UPDATE tblDBVersion SET Major=1, Minor=12;");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblOption(\\r
                                Option                          TEXT UNIQUE,\\r
                                OptionValue                     TEXT NOT NULL,\\r
-                               OptionDescription       TEXT\\r
+                               OptionDescription       TEXT,\\r
+                               Section                         TEXT,\\r
+                               SortOrder                       INTEGER,\\r
+                               ValidValues                     TEXT\\r
                                );");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\\r
@@ -131,12 +165,12 @@ void SetupDB()
                                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
                                LastInsertedFreesite    DATETIME,\\r
-                               DateCreated                             DATETIME\\r
+                               DateCreated                             DATETIME,\\r
+                               MinMessageDelay                 INTEGER DEFAULT 0,\\r
+                               MaxMessageDelay                 INTEGER DEFAULT 0\\r
                                );");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentityInserts(\\r
@@ -185,9 +219,8 @@ void SetupDB()
                                LocalTrustListTrust             INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
                                PeerTrustListTrust              INTEGER CHECK(PeerTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
                                AddedMethod                             TEXT,\\r
-                               MessageTrustComment             TEXT,\\r
-                               TrustListTrustComment   TEXT,\\r
-                               Hidden                                  BOOL CHECK(Hidden IN('true','false')) DEFAULT 'false'\\r
+                               Hidden                                  BOOL CHECK(Hidden IN('true','false')) DEFAULT 'false',\\r
+                               PurgeDate                               DATETIME\\r
                                );");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityRequests(\\r
@@ -267,7 +300,7 @@ void SetupDB()
                                );");\r
 \r
        db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('fms','Freenet Message System','2007-12-01 12:00:00','Initial Board');");\r
-       db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('freenet','Discussion about Freenet','2007-12-01 12:00:00','Initialt Board');");\r
+       db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('freenet','Discussion about Freenet','2007-12-01 12:00:00','Initial Board');");\r
        db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('public','Public discussion','2007-12-01 12:00:00','Initial Board');");\r
        db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('test','Test board','2007-12-01 12:00:00','Initial Board');");\r
 \r
@@ -325,7 +358,18 @@ void SetupDB()
                                InsertIndex                     INTEGER,\\r
                                MessageUUID                     TEXT UNIQUE,\\r
                                MessageXML                      TEXT,\\r
-                               Inserted                        BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
+                               Inserted                        BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false',\\r
+                               SendDate                        DATETIME\\r
+                               );");\r
+\r
+       db->Execute("CREATE TABLE IF NOT EXISTS tblFileInserts(\\r
+                               FileInsertID            INTEGER PRIMARY KEY,\\r
+                               MessageUUID                     TEXT,\\r
+                               FileName                        TEXT,\\r
+                               Key                                     TEXT,\\r
+                               Size                            INTEGER,\\r
+                               MimeType                        TEXT,\\r
+                               Data                            BLOB\\r
                                );");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblMessageListInserts(\\r
@@ -361,6 +405,11 @@ void SetupDB()
                                Date                            DATETIME\\r
                                );");\r
 \r
+       // A temporary table that will hold a local identity id of the last identity who was loaded in the trust list page\r
+       db->Execute("CREATE TEMPORARY TABLE IF NOT EXISTS tmpLocalIdentityPeerTrustPage(\\r
+                               LocalIdentityID         INTEGER\\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
@@ -381,6 +430,11 @@ void SetupDB()
                                AND ( PeerTrustListTrust IS NULL OR PeerTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerTrustListTrust') ) \\r
                                GROUP BY TargetIdentityID;");\r
 \r
+       db->Execute("CREATE VIEW IF NOT EXISTS vwIdentityStats AS \\r
+                               SELECT tblIdentity.IdentityID, COUNT(tblMessage.MessageID) AS MessageCount, MIN(tblMessage.MessageDate) AS FirstMessageDate, MAX(tblMessage.MessageDate) AS LastMessageDate \\r
+                               FROM tblIdentity LEFT JOIN tblMessage ON tblIdentity.IdentityID=tblMessage.IdentityID \\r
+                               GROUP BY tblIdentity.IdentityID;");\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
@@ -472,10 +526,24 @@ void SetupDB()
        date.SetToGMTime();\r
        // insert SomeDude's public key\r
        db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,LocalTrustListTrust,AddedMethod) VALUES('SSK@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw,iXez4j3qCpd596TxXiJgZyTq9o-CElEuJxm~jNNZAuA,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"',50,'Initial Identity');");\r
-       // insert Shadow Panther's public key\r
-       db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@~mimyB1kmH4f7Cgsd2wM2Qv2NxrZHRMM6IY8~7EWRVQ,fxTKkR0TYhgMYb-vEGAv55sMOxCGD2xhE4ZxWHxdPz4,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
+       // insert Shadow Panther's public key - haven't seen in a while - disabling for now\r
+       //db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@~mimyB1kmH4f7Cgsd2wM2Qv2NxrZHRMM6IY8~7EWRVQ,fxTKkR0TYhgMYb-vEGAv55sMOxCGD2xhE4ZxWHxdPz4,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
        // insert garfield's public key\r
        db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@T8l1IEGU4-PoASFzgc2GYhIgRzUvZsKdoQWeuLHuTmM,QLxAPfkGis8l5NafNpSCdbxzXhBlu9WL8svcqJw9Mpo,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
+       // insert alek's public key\r
+       db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@lTjeI6V0lQsktXqaqJ6Iwk4TdsHduQI54rdUpHfhGbg,0oTYfrxxx8OmdU1~60gqpf3781qzEicM4Sz97mJsBM4,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
+       // insert Luke771's public key\r
+       db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@mdXK~ZVlfTZhF1SLBrvZ--i0vOsOpa~w9wv~~psQ-04,gXonsXKc7aexKSO8Gt8Fwre4Qgmmbt2WueO7VzxNKkk,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
+       // insert falafel's public key\r
+       db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@IxVqeqM0LyYdTmYAf5z49SJZUxr7NtQkOqVYG0hvITw,RM2wnMn5zAufCMt5upkkgq25B1elfBAxc7htapIWg1c,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
+       // insert cptn_insano's public key\r
+       db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@bloE1LJ~qzSYUkU2nt7sB9kq060D4HTQC66pk5Q8NpA,DOOASUnp0kj6tOdhZJ-h5Tk7Ka50FSrUgsH7tCG1usU,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
+       // insert Flink's public key\r
+       db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@q2TtkNBOuuniyJ56~8NSopCs3ttwe5KlB31ugZtWmXA,6~PzIupS8YK7L6oFNpXGKJmHT2kBMDfwTg73nHdNur8,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
+       // insert Kane's public key\r
+       db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@Ofm~yZivDJ5Z2fSzZbMiLEUUQaIc0KHRdZMBTaPLO6I,WLm4s4hNbOOurJ6ijfOq4odz7-dN7uTUvYxJRwWnlMI,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
+       // inserts boardstat's public key\r
+       db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded,AddedMethod) VALUES('SSK@aYWBb6zo2AM13XCNhsmmRKMANEx6PG~C15CWjdZziKA,X1pAG4EIqR1gAiyGFVZ1iiw-uTlh460~rFACJ7ZHQXk,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"','Initial Identity');");\r
 \r
        // TODO remove sometime after 0.1.17\r
        FixCapitalBoardNames();\r
@@ -598,6 +666,111 @@ void ConvertDB0107To0108()
        db->Execute("UPDATE tblDBVersion SET Major=1, Minor=8;");\r
 }\r
 \r
+void ConvertDB0108To0109()\r
+{\r
+       SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
+       db->Execute("CREATE TABLE IF NOT EXISTS tblFileInserts(\\r
+                       FileInsertID            INTEGER PRIMARY KEY,\\r
+                       MessageUUID                     TEXT,\\r
+                       FileName                        TEXT,\\r
+                       Key                                     TEXT,\\r
+                       Size                            INTEGER,\\r
+                       Data                            BLOB\\r
+                       );");\r
+       db->Execute("UPDATE tblDBVersion SET Major=1, Minor=9;");\r
+}\r
+\r
+void ConvertDB0109To0110()\r
+{\r
+       SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
+       db->Execute("ALTER TABLE tblFileInserts ADD COLUMN MimeType TEXT;");\r
+       db->Execute("UPDATE tblDBVersion SET Major=1, Minor=10;");\r
+}\r
+\r
+void ConvertDB0110To0111()\r
+{\r
+       /*\r
+       Drop MessageTrustComment, TrustListTrustComment FROM tblIdentity\r
+\r
+       Drop InsertingMessageList, InsertingBoardList FROM tblLocalIdentity\r
+       Add MinMessageDelay, MaxMessageDelay to tblLocalIdentity Default 0\r
+\r
+       Add SendDate to tblMessageInserts\r
+       */\r
+       SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
+\r
+       db->Execute("ALTER TABLE tblMessageInserts ADD COLUMN SendDate DATETIME;");\r
+\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
+                               PublishFreesite                 BOOL CHECK(PublishFreesite IN('true','false')) DEFAULT 'false',\\r
+                               FreesiteEdition                 INTEGER,\\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
+                               LastInsertedBoardList   DATETIME,\\r
+                               LastInsertedMessageList DATETIME,\\r
+                               LastInsertedFreesite    DATETIME,\\r
+                               DateCreated                             DATETIME,\\r
+                               MinMessageDelay                 INTEGER DEFAULT 0,\\r
+                               MaxMessageDelay                 INTEGER DEFAULT 0\\r
+                               );");\r
+       db->Execute("INSERT INTO tblLocalIdentity SELECT LocalIdentityID,Name,PublicKey,PrivateKey,SingleUse,PublishTrustList,PublishBoardList,PublishFreesite,FreesiteEdition,InsertingIdentity,LastInsertedIdentity,InsertingPuzzle,LastInsertedPuzzle,InsertingTrustList,LastInsertedTrustList,LastInsertedBoardList,LastInsertedMessageList,LastInsertedFreesite,DateCreated,0,0 FROM tblLocalIdentityTemp;");\r
+       db->Execute("DROP TABLE IF EXISTS tblLocalIdentityTemp;");\r
+\r
+       db->Execute("CREATE TEMPORARY TABLE tblIdentityTemp AS SELECT * FROM tblIdentity;");\r
+       db->Execute("DROP TABLE IF EXISTS tblIdentity;");\r
+       db->Execute("CREATE TABLE IF NOT EXISTS tblIdentity(\\r
+                               IdentityID                              INTEGER PRIMARY KEY,\\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
+                               PublishBoardList                BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
+                               FreesiteEdition                 INTEGER,\\r
+                               DateAdded                               DATETIME,\\r
+                               LastSeen                                DATETIME,\\r
+                               LocalMessageTrust               INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
+                               PeerMessageTrust                INTEGER CHECK(PeerMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
+                               LocalTrustListTrust             INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
+                               PeerTrustListTrust              INTEGER CHECK(PeerTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
+                               AddedMethod                             TEXT,\\r
+                               Hidden                                  BOOL CHECK(Hidden IN('true','false')) DEFAULT 'false'\\r
+                               );");\r
+       db->Execute("INSERT INTO tblIdentity SELECT IdentityID,PublicKey,Name,SingleUse,PublishTrustList,PublishBoardList,FreesiteEdition,DateAdded,LastSeen,LocalMessageTrust,PeerMessageTrust,LocalTrustListTrust,PeerTrustListTrust,AddedMethod,Hidden FROM tblIdentityTemp;");\r
+       db->Execute("DROP TABLE IF EXISTS tblIdentityTemp;");\r
+\r
+       db->Execute("UPDATE tblDBVersion SET Major=1, Minor=11;");\r
+}\r
+\r
+void ConvertDB0111To0112()\r
+{\r
+       /*\r
+               Add Section, SortOrder, ValidValues to tblOption\r
+               Add PurgeDate to tblIdentity\r
+       */\r
+       SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
+\r
+       db->Execute("ALTER TABLE tblOption ADD COLUMN Section TEXT;");\r
+       db->Execute("ALTER TABLE tblOption ADD COLUMN SortOrder INTEGER;");\r
+       db->Execute("ALTER TABLE tblOption ADD COLUMN ValidValues TEXT;");\r
+\r
+       db->Execute("ALTER TABLE tblIdentity ADD COLUMN PurgeDate DATETIME;");\r
+\r
+       db->Execute("UPDATE tblDBVersion SET Major=1, Minor=12;");\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
@@ -605,6 +778,8 @@ void SetupDefaultOptions()
        std::ostringstream tempstr;     // must set tempstr to "" between db inserts\r
        SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
        SQLite3DB::Statement st=db->Prepare("INSERT INTO tblOption(Option,OptionValue,OptionDescription) VALUES(?,?,?);");\r
+       SQLite3DB::Statement upd=db->Prepare("UPDATE tblOption SET Section=?, SortOrder=?, ValidValues=? WHERE Option=?;");\r
+       int order=0;\r
 \r
        // LogLevel\r
        tempstr.str("");\r
@@ -614,6 +789,49 @@ void SetupDefaultOptions()
        st.Bind(2,"The maximum logging level that will be written to file.  0=Fatal Errors, 1=Errors, 2=Warnings, 3=Informational Messages, 4=Debug Messages.  Higher levels will include all messages from the previous levels.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Program");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2,"0|0 - Fatal Errors|1|1 - Errors|2|2 - Warnings|3|3 - Informational Messages|4|4 - Debug Messages");\r
+       upd.Bind(3,"LogLevel");\r
+       upd.Step();\r
+       upd.Reset();\r
+\r
+       st.Bind(0,"VacuumOnStartup");\r
+       st.Bind(1,"false");\r
+       st.Bind(2,"VACUUM the database every time FMS starts.  This will defragment the free space in the database and create a smaller database file.  Vacuuming the database can be CPU and disk intensive.");\r
+       st.Step();\r
+       st.Reset();\r
+       upd.Bind(0,"Program");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2,"true|true|false|false");\r
+       upd.Bind(3,"VacuumOnStartup");\r
+       upd.Step();\r
+       upd.Reset();\r
+\r
+       st.Bind(0,"MessageBase");\r
+       st.Bind(1,"fms");\r
+       st.Bind(2,"A unique string shared by all clients who want to communicate with each other.  This should not be changed unless you want to create your own separate communications network.");\r
+       st.Step();\r
+       st.Reset();\r
+       upd.Bind(0,"Program");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MessageBase");\r
+       upd.Step();\r
+       upd.Reset();\r
+\r
+       // StartNNTP\r
+       st.Bind(0,"StartNNTP");\r
+       st.Bind(1,"true");\r
+       st.Bind(2,"Start NNTP server.");\r
+       st.Step();\r
+       st.Reset();\r
+       upd.Bind(0,"NNTP Server");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2,"true|true|false|false");\r
+       upd.Bind(3,"StartNNTP");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        // NNTPListenPort\r
        st.Bind(0,"NNTPListenPort");\r
@@ -621,6 +839,12 @@ void SetupDefaultOptions()
        st.Bind(2,"The port that the NNTP service will listen for incoming connections.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"NNTP Server");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"NNTPListenPort");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        // NNTPBindAddresses\r
        st.Bind(0,"NNTPBindAddresses");\r
@@ -628,37 +852,60 @@ void SetupDefaultOptions()
        st.Bind(2,"A comma separated list of valid IPv4 or IPv6 addresses/hostnames that the NNTP service will try to bind to.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"NNTP Server");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"NNTPBindAddresses");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"NNTPAllowPost");\r
        st.Bind(1,"true");\r
        st.Bind(2,"Allow posting messages from NNTP.  Setting to false will make the newsgroups read only.");\r
        st.Step();\r
        st.Reset();\r
-\r
-       // StartNNTP\r
-       st.Bind(0,"StartNNTP");\r
-       st.Bind(1,"true");\r
-       st.Bind(2,"Start NNTP server.");\r
-       st.Step();\r
-       st.Reset();\r
+       upd.Bind(0,"NNTP Server");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2,"true|true|false|false");\r
+       upd.Bind(3,"NNTPAllowPost");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"StartHTTP");\r
        st.Bind(1,"true");\r
        st.Bind(2,"Start HTTP server.  WARNING: If you turn this off, you won't be able to access the administration pages.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"HTTP Server");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2,"true|true|false|false");\r
+       upd.Bind(3,"StartHTTP");\r
+       upd.Step();\r
+       upd.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
+       upd.Bind(0,"HTTP Server");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"HTTPListenPort");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"HTTPAccessControl");\r
        st.Bind(1,"-0.0.0.0/0,+127.0.0.1");\r
-       st.Bind(2,"Comma separated list of addresses and/or subnet masks that are allowed access to the administration pages.  Default is localhost only. + allows a host, - denies as host.");\r
+       st.Bind(2,"Comma separated list of addresses and/or subnet masks that are allowed access to the administration pages.  Default is localhost only. + allows a host, - denies a host.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"HTTP Server");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"HTTPAccessControl");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        // StartFreenetUpdater\r
        st.Bind(0,"StartFreenetUpdater");\r
@@ -666,6 +913,12 @@ void SetupDefaultOptions()
        st.Bind(2,"Set to true to start the Freenet Updater thread and connect to Freenet.  Set to false to prevent communication with Freenet.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Freenet Connection");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2,"true|true|false|false");\r
+       upd.Bind(3,"StartFreenetUpdater");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        // FCPHost\r
        st.Bind(0,"FCPHost");\r
@@ -673,6 +926,12 @@ void SetupDefaultOptions()
        st.Bind(2,"Host name or address of Freenet node.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Freenet Connection");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"FCPHost");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        // FCPPort\r
        st.Bind(0,"FCPPort");\r
@@ -680,126 +939,264 @@ void SetupDefaultOptions()
        st.Bind(2,"The port that Freenet is listening for FCP connections on.");\r
        st.Step();\r
        st.Reset();\r
-\r
-       st.Bind(0,"MessageBase");\r
-       st.Bind(1,"fms");\r
-       st.Bind(2,"A unique string shared by all clients who want to communicate with each other.  This should not be changed unless you want to create your own separate communications network.");\r
+       upd.Bind(0,"Freenet Connection");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"FCPPort");\r
+       upd.Step();\r
+       upd.Reset();\r
+\r
+       st.Bind(0,"FProxyPort");\r
+       st.Bind(1,"8888");\r
+       st.Bind(2,"The port that Freenet is listening for http connections on.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Freenet Connection");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"FProxyPort");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"MaxIdentityRequests");\r
        st.Bind(1,"5");\r
        st.Bind(2,"Maximum number of concurrent requests for new Identity xml files");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Requests");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MaxIdentityRequests");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"MaxIdentityIntroductionRequests");\r
        st.Bind(1,"5");\r
        st.Bind(2,"Maximum number of concurrent identities requesting IdentityIntroduction xml files.  Each identity may have multiple requests pending.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Requests");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MaxIdentityIntroductionRequests");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"MaxIntroductionPuzzleRequests");\r
        st.Bind(1,"5");\r
        st.Bind(2,"Maximum number of concurrent requests for new IntroductionPuzzle xml files");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Requests");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MaxIntroductionPuzzleRequests");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"MaxTrustListRequests");\r
        st.Bind(1,"5");\r
        st.Bind(2,"Maximum number of concurrent requests for new Trust Lists");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Requests");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MaxTrustListRequests");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"MaxMessageListRequests");\r
        st.Bind(1,"5");\r
        st.Bind(2,"Maximum number of concurrent requests for new Message Lists");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Requests");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MaxMessageListRequests");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"MaxMessageRequests");\r
        st.Bind(1,"20");\r
        st.Bind(2,"Maximum number of concurrent requests for new Messages");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Requests");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MaxMessageRequests");\r
+       upd.Step();\r
+       upd.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
+       upd.Bind(0,"Requests");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MaxBoardListRequests");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"MinLocalMessageTrust");\r
        st.Bind(1,"50");\r
        st.Bind(2,"Specifies a local message trust level that a peer must have before its messages will be downloaded.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Trust");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MinLocalMessageTrust");\r
+       upd.Step();\r
+       upd.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
+       upd.Bind(0,"Trust");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MinPeerMessageTrust");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"MinLocalTrustListTrust");\r
        st.Bind(1,"50");\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
+       upd.Bind(0,"Trust");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MinLocalTrustListTrust");\r
+       upd.Step();\r
+       upd.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
+       upd.Bind(0,"Trust");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MinPeerTrustListTrust");\r
+       upd.Step();\r
+       upd.Reset();\r
+\r
+       st.Bind(0,"LocalTrustOverridesPeerTrust");\r
+       st.Bind(1,"false");\r
+       st.Bind(2,"Set to true if you want your local trust levels to override the peer levels when determining which identities you will poll.");\r
+       st.Step();\r
+       st.Reset();\r
+       upd.Bind(0,"Trust");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2,"true|true|false|false");\r
+       upd.Bind(3,"LocalTrustOverridesPeerTrust");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"MessageDownloadMaxDaysBackward");\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
+       upd.Bind(0,"Messages");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MessageDownloadMaxDaysBackward");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"MessageListDaysBackward");\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
+       upd.Bind(0,"Messages");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MessageListDaysBackward");\r
+       upd.Step();\r
+       upd.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
+       upd.Bind(0,"Messages");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MaxPeerMessagesPerDay");\r
+       upd.Step();\r
+       upd.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
+       upd.Bind(0,"Messages");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"MaxBoardsPerMessage");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"SaveMessagesFromNewBoards");\r
        st.Bind(1,"true");\r
        st.Bind(2,"Set to true to automatically save messages posted to new boards.  Set to false to ignore messages to new boards.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Messages");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2,"true|true|false|false");\r
+       upd.Bind(3,"SaveMessagesFromNewBoards");\r
+       upd.Step();\r
+       upd.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
+       upd.Bind(0,"Messages");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"ChangeMessageTrustOnReply");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"AddNewPostFromIdentities");\r
        st.Bind(1,"false");\r
        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.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Messages");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2,"true|true|false|false");\r
+       upd.Bind(3,"AddNewPostFromIdentities");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
        st.Bind(0,"DeleteMessagesOlderThan");\r
        st.Bind(1,"180");\r
        st.Bind(2,"Automatically delete messages older than this many days.");\r
        st.Step();\r
        st.Reset();\r
+       upd.Bind(0,"Messages");\r
+       upd.Bind(1,order++);\r
+       upd.Bind(2);\r
+       upd.Bind(3,"DeleteMessagesOlderThan");\r
+       upd.Step();\r
+       upd.Reset();\r
 \r
 }\r
 \r
@@ -840,6 +1237,9 @@ void SetupNetwork()
 \r
 void Shutdown()\r
 {\r
+\r
+       LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"FMS starting shutdown");\r
+\r
        ThreadController::Instance()->ShutdownThreads();\r
 \r
        ShutdownNetwork();\r