version 0.2.22
[fms.git] / src / global.cpp
index 7889810..872dfb7 100644 (file)
@@ -17,7 +17,7 @@
        #include <xmem.h>\r
 #endif\r
 \r
        #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
 \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
 {\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
        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
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblDBVersion(\\r
                                Major                           INTEGER,\\r
@@ -95,18 +102,51 @@ void SetupDB()
                        major=1;\r
                        minor=7;\r
                }\r
                        major=1;\r
                        minor=7;\r
                }\r
+               if(major==1 && minor==7)\r
+               {\r
+                       ConvertDB0107To0108();\r
+                       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
        }\r
        else\r
        {\r
-               db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,7);");\r
+               db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,12);");\r
        }\r
 \r
        }\r
 \r
-       db->Execute("UPDATE tblDBVersion SET Major=1, Minor=7;");\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
 \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
                                );");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\\r
@@ -118,18 +158,19 @@ void SetupDB()
                                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
                                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
                                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
                                LastInsertedBoardList   DATETIME,\\r
-                               InsertingMessageList    BOOL CHECK(InsertingMessageList IN('true','false')) DEFAULT 'false',\\r
                                LastInsertedMessageList DATETIME,\\r
                                LastInsertedFreesite    DATETIME,\\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
                                );");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentityInserts(\\r
@@ -170,6 +211,7 @@ void SetupDB()
                                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
                                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
                                DateAdded                               DATETIME,\\r
                                LastSeen                                DATETIME,\\r
                                LocalMessageTrust               INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
@@ -177,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
                                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
                                );");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityRequests(\\r
@@ -259,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
                                );");\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
        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
@@ -317,7 +358,18 @@ void SetupDB()
                                InsertIndex                     INTEGER,\\r
                                MessageUUID                     TEXT UNIQUE,\\r
                                MessageXML                      TEXT,\\r
                                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
                                );");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblMessageListInserts(\\r
@@ -353,6 +405,11 @@ void SetupDB()
                                Date                            DATETIME\\r
                                );");\r
 \r
                                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
        // 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
@@ -373,6 +430,11 @@ void SetupDB()
                                AND ( PeerTrustListTrust IS NULL OR PeerTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerTrustListTrust') ) \\r
                                GROUP BY TargetIdentityID;");\r
 \r
                                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
        /*\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
@@ -420,6 +482,7 @@ void SetupDB()
                                        DELETE FROM tblMessageReplyTo WHERE tblMessageReplyTo.MessageID=old.MessageID;\\r
                                END;");\r
 \r
                                        DELETE FROM tblMessageReplyTo WHERE tblMessageReplyTo.MessageID=old.MessageID;\\r
                                END;");\r
 \r
+       db->Execute("DROP TRIGGER IF EXISTS trgDeleteIdentity;");\r
        db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteIdentity AFTER DELETE ON tblIdentity \\r
                                FOR EACH ROW \\r
                                BEGIN \\r
        db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteIdentity AFTER DELETE ON tblIdentity \\r
                                FOR EACH ROW \\r
                                BEGIN \\r
@@ -429,6 +492,7 @@ void SetupDB()
                                        DELETE FROM tblMessageRequests WHERE IdentityID=old.IdentityID;\\r
                                        DELETE FROM tblPeerTrust WHERE IdentityID=old.IdentityID;\\r
                                        DELETE FROM tblTrustListRequests 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
+                                       DELETE FROM tblIdentityTrust WHERE IdentityID=old.IdentityID;\\r
                                END;");\r
 \r
        db->Execute("DROP TRIGGER IF EXISTS trgDeleteLocalIdentity;");\r
                                END;");\r
 \r
        db->Execute("DROP TRIGGER IF EXISTS trgDeleteLocalIdentity;");\r
@@ -462,14 +526,31 @@ 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
        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 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
 \r
 \r
        // TODO remove sometime after 0.1.17\r
        FixCapitalBoardNames();\r
 \r
+       // run analyze - may speed up some queries\r
+       db->Execute("ANALYZE;");\r
+\r
 }\r
 \r
 void ConvertDB0100To0101()\r
 }\r
 \r
 void ConvertDB0100To0101()\r
@@ -576,6 +657,120 @@ void ConvertDB0106To0107()
        db->Execute("UPDATE tblDBVersion SET Major=1, Minor=7;");\r
 }\r
 \r
        db->Execute("UPDATE tblDBVersion SET Major=1, Minor=7;");\r
 }\r
 \r
+void ConvertDB0107To0108()\r
+{\r
+       // add FreesiteEdition to tblLocalIdentity and tblIdentity\r
+       SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
+       db->Execute("ALTER TABLE tblLocalIdentity ADD COLUMN FreesiteEdition INTEGER;");\r
+       db->Execute("ALTER TABLE tblIdentity ADD COLUMN FreesiteEdition INTEGER;");\r
+       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
 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
@@ -583,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
        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
 \r
        // LogLevel\r
        tempstr.str("");\r
@@ -592,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
        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
 \r
        // NNTPListenPort\r
        st.Bind(0,"NNTPListenPort");\r
@@ -599,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
        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
 \r
        // NNTPBindAddresses\r
        st.Bind(0,"NNTPBindAddresses");\r
@@ -606,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
        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
        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
 \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
 \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
 \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
        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
 \r
        // StartFreenetUpdater\r
        st.Bind(0,"StartFreenetUpdater");\r
@@ -644,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
        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
 \r
        // FCPHost\r
        st.Bind(0,"FCPHost");\r
@@ -651,6 +926,12 @@ void SetupDefaultOptions()
        st.Bind(2,"Host name or address of Freenet node.");\r
        st.Step();\r
        st.Reset();\r
        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
 \r
        // FCPPort\r
        st.Bind(0,"FCPPort");\r
@@ -658,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
        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
        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
 \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
 \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
 \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
 \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
 \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
 \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
 \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
 \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
 \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
 \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
 \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
 \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,"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
 \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
 \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
 \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
 \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
 \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
 \r
 }\r
 \r
@@ -818,6 +1237,9 @@ void SetupNetwork()
 \r
 void Shutdown()\r
 {\r
 \r
 void Shutdown()\r
 {\r
+\r
+       LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"FMS starting shutdown");\r
+\r
        ThreadController::Instance()->ShutdownThreads();\r
 \r
        ShutdownNetwork();\r
        ThreadController::Instance()->ShutdownThreads();\r
 \r
        ShutdownNetwork();\r