version 0.2.11
[fms.git] / src / global.cpp
1 #include "../include/global.h"\r
2 #include "../include/datetime.h"\r
3 #include "../include/logfile.h"\r
4 #include "../include/option.h"\r
5 #include "../include/stringfunctions.h"\r
6 #include "../include/db/sqlite3db.h"\r
7 #include "../include/freenet/freenetmasterthread.h"\r
8 #include "../include/nntp/nntplistener.h"\r
9 #include "../include/http/httpthread.h"\r
10 #include "../include/threadcontroller.h"\r
11 \r
12 #ifdef _WIN32\r
13         #include <winsock2.h>\r
14 #endif\r
15 \r
16 #ifdef XMEM\r
17         #include <xmem.h>\r
18 #endif\r
19 \r
20 bool wantshutdown=false;\r
21 \r
22 std::string CreateShortIdentityName(const std::string &name, const std::string &publickey)\r
23 {\r
24         std::string result="";\r
25         std::vector<std::string> keyparts;\r
26 \r
27         StringFunctions::SplitMultiple(publickey,"@,",keyparts);\r
28 \r
29         result+=name;\r
30         if(keyparts.size()>1 && keyparts[1].size()>8)\r
31         {\r
32                 result+="@"+keyparts[1].substr(0,4)+"...";\r
33         }\r
34 \r
35         return result;\r
36 }\r
37 \r
38 void SetupDB()\r
39 {\r
40 \r
41         DateTime date;\r
42         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
43 \r
44         db->Open("fms.db3");\r
45         db->SetBusyTimeout(10000);              // set timeout to 10 seconds\r
46         //db->Execute("VACUUM;");               // not needed every startup\r
47 \r
48         db->Execute("CREATE TABLE IF NOT EXISTS tblDBVersion(\\r
49                                 Major                           INTEGER,\\r
50                                 Minor                           INTEGER\\r
51                                 );");\r
52 \r
53         SQLite3DB::Statement st=db->Prepare("SELECT Major,Minor FROM tblDBVersion;");\r
54         st.Step();\r
55         if(st.RowReturned())\r
56         {\r
57                 int major;\r
58                 int minor;\r
59                 st.ResultInt(0,major);\r
60                 st.ResultInt(1,minor);\r
61                 st.Finalize();\r
62                 if(major==1 && minor==0)\r
63                 {\r
64                         ConvertDB0100To0101();\r
65                         major=1;\r
66                         minor=1;\r
67                 }\r
68                 if(major==1 && (minor==1 || minor==2))\r
69                 {\r
70                         ConvertDB0101To0103();\r
71                         major=1;\r
72                         minor=3;\r
73                 }\r
74                 if(major==1 && minor==3)\r
75                 {\r
76                         ConvertDB0103To0104();\r
77                         major=1;\r
78                         minor=4;\r
79                 }\r
80                 if(major==1 && minor==4)\r
81                 {\r
82                         ConvertDB0104To0105();\r
83                         major=1;\r
84                         minor=5;\r
85                 }\r
86                 if(major==1 && minor==5)\r
87                 {\r
88                         ConvertDB0105To0106();\r
89                         major=1;\r
90                         minor=6;\r
91                 }\r
92                 if(major==1 && minor==6)\r
93                 {\r
94                         ConvertDB0106To0107();\r
95                         major=1;\r
96                         minor=7;\r
97                 }\r
98                 if(major==1 && minor==7)\r
99                 {\r
100                         ConvertDB0107To0108();\r
101                         major=1;\r
102                         minor=8;\r
103                 }\r
104                 if(major==1 && minor==8)\r
105                 {\r
106                         ConvertDB0108To0109();\r
107                         major=1;\r
108                         minor=9;\r
109                 }\r
110         }\r
111         else\r
112         {\r
113                 db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,9);");\r
114         }\r
115 \r
116         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=9;");\r
117 \r
118         db->Execute("CREATE TABLE IF NOT EXISTS tblOption(\\r
119                                 Option                          TEXT UNIQUE,\\r
120                                 OptionValue                     TEXT NOT NULL,\\r
121                                 OptionDescription       TEXT\\r
122                                 );");\r
123 \r
124         db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\\r
125                                 LocalIdentityID                 INTEGER PRIMARY KEY,\\r
126                                 Name                                    TEXT,\\r
127                                 PublicKey                               TEXT UNIQUE,\\r
128                                 PrivateKey                              TEXT UNIQUE,\\r
129                                 SingleUse                               BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
130                                 PublishTrustList                BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
131                                 PublishBoardList                BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
132                                 PublishFreesite                 BOOL CHECK(PublishFreesite IN('true','false')) DEFAULT 'false',\\r
133                                 FreesiteEdition                 INTEGER,\\r
134                                 InsertingIdentity               BOOL CHECK(InsertingIdentity IN('true','false')) DEFAULT 'false',\\r
135                                 LastInsertedIdentity    DATETIME,\\r
136                                 InsertingPuzzle                 BOOL CHECK(InsertingPuzzle IN('true','false')) DEFAULT 'false',\\r
137                                 LastInsertedPuzzle              DATETIME,\\r
138                                 InsertingTrustList              BOOL CHECK(InsertingTrustList IN('true','false')) DEFAULT 'false',\\r
139                                 LastInsertedTrustList   DATETIME,\\r
140                                 InsertingBoardList              BOOL CHECK(InsertingBoardList IN('true','false')) DEFAULT 'false',\\r
141                                 LastInsertedBoardList   DATETIME,\\r
142                                 InsertingMessageList    BOOL CHECK(InsertingMessageList IN('true','false')) DEFAULT 'false',\\r
143                                 LastInsertedMessageList DATETIME,\\r
144                                 LastInsertedFreesite    DATETIME,\\r
145                                 DateCreated                             DATETIME\\r
146                                 );");\r
147 \r
148         db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentityInserts(\\r
149                                 LocalIdentityID         INTEGER,\\r
150                                 Day                                     DATE,\\r
151                                 InsertIndex                     INTEGER\\r
152                                 );");\r
153 \r
154         db->Execute("CREATE TABLE IF NOT EXISTS tblTrustListInserts(\\r
155                                 LocalIdentityID         INTEGER,\\r
156                                 Day                                     DATE,\\r
157                                 InsertIndex                     INTEGER\\r
158                                 );");\r
159 \r
160         db->Execute("CREATE TABLE IF NOT EXISTS tblTrustListRequests(\\r
161                                 IdentityID                      INTEGER,\\r
162                                 Day                                     DATE,\\r
163                                 RequestIndex            INTEGER,\\r
164                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
165                                 );");\r
166 \r
167         db->Execute("CREATE TABLE IF NOT EXISTS tblIntroductionPuzzleInserts(\\r
168                                 UUID                            TEXT UNIQUE,\\r
169                                 LocalIdentityID         INTEGER,\\r
170                                 Day                                     DATE,\\r
171                                 InsertIndex                     INTEGER,\\r
172                                 Type                            TEXT,\\r
173                                 MimeType                        TEXT,\\r
174                                 PuzzleData                      TEXT,\\r
175                                 PuzzleSolution          TEXT,\\r
176                                 FoundSolution           BOOL CHECK(FoundSolution IN('true','false')) DEFAULT 'false'\\r
177                                 );");\r
178 \r
179         db->Execute("CREATE TABLE IF NOT EXISTS tblIdentity(\\r
180                                 IdentityID                              INTEGER PRIMARY KEY,\\r
181                                 PublicKey                               TEXT UNIQUE,\\r
182                                 Name                                    TEXT,\\r
183                                 SingleUse                               BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
184                                 PublishTrustList                BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
185                                 PublishBoardList                BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
186                                 FreesiteEdition                 INTEGER,\\r
187                                 DateAdded                               DATETIME,\\r
188                                 LastSeen                                DATETIME,\\r
189                                 LocalMessageTrust               INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
190                                 PeerMessageTrust                INTEGER CHECK(PeerMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
191                                 LocalTrustListTrust             INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
192                                 PeerTrustListTrust              INTEGER CHECK(PeerTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
193                                 AddedMethod                             TEXT,\\r
194                                 MessageTrustComment             TEXT,\\r
195                                 TrustListTrustComment   TEXT,\\r
196                                 Hidden                                  BOOL CHECK(Hidden IN('true','false')) DEFAULT 'false'\\r
197                                 );");\r
198 \r
199         db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityRequests(\\r
200                                 IdentityID                      INTEGER,\\r
201                                 Day                                     DATE,\\r
202                                 RequestIndex            INTEGER,\\r
203                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
204                                 );");\r
205 \r
206         db->Execute("CREATE TABLE IF NOT EXISTS tblIntroductionPuzzleRequests(\\r
207                                 IdentityID                      INTEGER,\\r
208                                 Day                                     DATE,\\r
209                                 RequestIndex            INTEGER,\\r
210                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false',\\r
211                                 UUID                            TEXT UNIQUE,\\r
212                                 Type                            TEXT,\\r
213                                 MimeType                        TEXT,\\r
214                                 PuzzleData                      TEXT\\r
215                                 );");\r
216 \r
217         db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityIntroductionInserts(\\r
218                                 LocalIdentityID         INTEGER,\\r
219                                 Day                                     DATE,\\r
220                                 UUID                            TEXT UNIQUE,\\r
221                                 Solution                        TEXT,\\r
222                                 Inserted                        BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
223                                 );");\r
224 \r
225         db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityTrust(\\r
226                                 LocalIdentityID                 INTEGER,\\r
227                                 IdentityID                              INTEGER,\\r
228                                 LocalMessageTrust               INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
229                                 MessageTrustComment             TEXT,\\r
230                                 LocalTrustListTrust             INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
231                                 TrustListTrustComment   TEXT\\r
232                                 );");\r
233 \r
234         db->Execute("CREATE UNIQUE INDEX IF NOT EXISTS idxIdentityTrust_IDs ON tblIdentityTrust(LocalIdentityID,IdentityID);");\r
235 \r
236         db->Execute("CREATE TRIGGER IF NOT EXISTS trgInsertOnIdentityTrust AFTER INSERT ON tblIdentityTrust \\r
237                                 FOR EACH ROW \\r
238                                 BEGIN \\r
239                                         UPDATE tblIdentity SET LocalMessageTrust=(SELECT MAX(LocalMessageTrust) FROM tblIdentityTrust WHERE tblIdentityTrust.IdentityID=new.IdentityID GROUP BY tblIdentityTrust.IdentityID), LocalTrustListTrust=(SELECT MAX(LocalTrustListTrust) FROM tblIdentityTrust WHERE tblIdentityTrust.IdentityID=new.IdentityID GROUP BY tblIdentityTrust.IdentityID) WHERE tblIdentity.IdentityID=new.IdentityID; \\r
240                                 END;");\r
241 \r
242         db->Execute("CREATE TRIGGER IF NOT EXISTS trgUpdateOnIdentityTrust AFTER UPDATE OF LocalMessageTrust,LocalTrustListTrust ON tblIdentityTrust \\r
243                                 FOR EACH ROW \\r
244                                 BEGIN \\r
245                                         UPDATE tblIdentity SET LocalMessageTrust=(SELECT MAX(LocalMessageTrust) FROM tblIdentityTrust WHERE tblIdentityTrust.IdentityID=new.IdentityID GROUP BY tblIdentityTrust.IdentityID), LocalTrustListTrust=(SELECT MAX(LocalTrustListTrust) FROM tblIdentityTrust WHERE tblIdentityTrust.IdentityID=new.IdentityID GROUP BY tblIdentityTrust.IdentityID) WHERE tblIdentity.IdentityID=new.IdentityID; \\r
246                                 END;");\r
247 \r
248         db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteOnIdentityTrust AFTER DELETE ON tblIdentityTrust \\r
249                                 FOR EACH ROW \\r
250                                 BEGIN \\r
251                                         UPDATE tblIdentity SET LocalMessageTrust=(SELECT MAX(LocalMessageTrust) FROM tblIdentityTrust WHERE tblIdentityTrust.IdentityID=old.IdentityID GROUP BY tblIdentityTrust.IdentityID), LocalTrustListTrust=(SELECT MAX(LocalTrustListTrust) FROM tblIdentityTrust WHERE tblIdentityTrust.IdentityID=old.IdentityID GROUP BY tblIdentityTrust.IdentityID) WHERE tblIdentity.IdentityID=old.IdentityID; \\r
252                                 END;");\r
253 \r
254         db->Execute("CREATE TABLE IF NOT EXISTS tblPeerTrust(\\r
255                                 IdentityID                              INTEGER,\\r
256                                 TargetIdentityID                INTEGER,\\r
257                                 MessageTrust                    INTEGER CHECK(MessageTrust BETWEEN 0 AND 100),\\r
258                                 TrustListTrust                  INTEGER CHECK(TrustListTrust BETWEEN 0 AND 100),\\r
259                                 MessageTrustComment             TEXT,\\r
260                                 TrustListTrustComment   TEXT\\r
261                                 );");\r
262 \r
263         db->Execute("CREATE INDEX IF NOT EXISTS idxPeerTrust_IdentityID ON tblPeerTrust (IdentityID);");\r
264         db->Execute("CREATE INDEX IF NOT EXISTS idxPeerTrust_TargetIdentityID ON tblPeerTrust (TargetIdentityID);");\r
265 \r
266         db->Execute("CREATE TABLE IF NOT EXISTS tblBoard(\\r
267                                 BoardID                                 INTEGER PRIMARY KEY,\\r
268                                 BoardName                               TEXT UNIQUE,\\r
269                                 BoardDescription                TEXT,\\r
270                                 DateAdded                               DATETIME,\\r
271                                 SaveReceivedMessages    BOOL CHECK(SaveReceivedMessages IN('true','false')) DEFAULT 'true',\\r
272                                 AddedMethod                             TEXT\\r
273                                 );");\r
274 \r
275         db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('fms','Freenet Message System','2007-12-01 12:00:00','Initial Board');");\r
276         db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('freenet','Discussion about Freenet','2007-12-01 12:00:00','Initialt Board');");\r
277         db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('public','Public discussion','2007-12-01 12:00:00','Initial Board');");\r
278         db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded,AddedMethod) VALUES('test','Test board','2007-12-01 12:00:00','Initial Board');");\r
279 \r
280         db->Execute("CREATE TABLE IF NOT EXISTS tblMessage(\\r
281                                 MessageID                       INTEGER PRIMARY KEY,\\r
282                                 IdentityID                      INTEGER,\\r
283                                 FromName                        TEXT,\\r
284                                 MessageDate                     DATE,\\r
285                                 MessageTime                     TIME,\\r
286                                 Subject                         TEXT,\\r
287                                 MessageUUID                     TEXT UNIQUE,\\r
288                                 ReplyBoardID            INTEGER,\\r
289                                 Body                            TEXT,\\r
290                                 MessageIndex            INTEGER\\r
291                                 );");\r
292 \r
293         db->Execute("CREATE INDEX IF NOT EXISTS idxMessage_IdentityID ON tblMessage (IdentityID);");\r
294 \r
295         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageReplyTo(\\r
296                                 MessageID                       INTEGER,\\r
297                                 ReplyToMessageUUID      TEXT,\\r
298                                 ReplyOrder                      INTEGER\\r
299                                 );");\r
300 \r
301         db->Execute("CREATE INDEX IF NOT EXISTS idxMessageReplyTo_MessageID ON tblMessageReplyTo (MessageID);");\r
302 \r
303         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageBoard(\\r
304                                 MessageID                       INTEGER,\\r
305                                 BoardID                         INTEGER\\r
306                                 );");\r
307 \r
308         db->Execute("CREATE INDEX IF NOT EXISTS idxMessageBoard_MessageID ON tblMessageBoard (MessageID);");\r
309         db->Execute("CREATE INDEX IF NOT EXISTS idxMessageBoard_BoardID ON tblMessageBoard (BoardID);");\r
310 \r
311         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageListRequests(\\r
312                                 IdentityID                      INTEGER,\\r
313                                 Day                                     DATE,\\r
314                                 RequestIndex            INTEGER,\\r
315                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
316                                 );");\r
317 \r
318         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageRequests(\\r
319                                 IdentityID                      INTEGER,\\r
320                                 Day                                     DATE,\\r
321                                 RequestIndex            INTEGER,\\r
322                                 FromMessageList         BOOL CHECK(FromMessageList IN('true','false')) DEFAULT 'false',\\r
323                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
324                                 );");\r
325 \r
326         db->Execute("CREATE UNIQUE INDEX IF NOT EXISTS idxMessageRequest ON tblMessageRequests(IdentityID,Day,RequestIndex);");\r
327 \r
328         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageInserts(\\r
329                                 LocalIdentityID         INTEGER,\\r
330                                 Day                                     DATE,\\r
331                                 InsertIndex                     INTEGER,\\r
332                                 MessageUUID                     TEXT UNIQUE,\\r
333                                 MessageXML                      TEXT,\\r
334                                 Inserted                        BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
335                                 );");\r
336 \r
337         db->Execute("CREATE TABLE IF NOT EXISTS tblFileInserts(\\r
338                                 FileInsertID            INTEGER PRIMARY KEY,\\r
339                                 MessageUUID                     TEXT,\\r
340                                 FileName                        TEXT,\\r
341                                 Key                                     TEXT,\\r
342                                 Size                            INTEGER,\\r
343                                 Data                            BLOB\\r
344                                 );");\r
345 \r
346         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageListInserts(\\r
347                                 LocalIdentityID         INTEGER,\\r
348                                 Day                                     DATE,\\r
349                                 InsertIndex                     INTEGER,\\r
350                                 Inserted                        BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
351                                 );");\r
352 \r
353         db->Execute("CREATE TABLE IF NOT EXISTS tblAdministrationBoard(\\r
354                                 BoardID                                         INTEGER UNIQUE,\\r
355                                 ModifyLocalMessageTrust         INTEGER,\\r
356                                 ModifyLocalTrustListTrust       INTEGER\\r
357                                 );");\r
358 \r
359         db->Execute("CREATE TABLE IF NOT EXISTS tblBoardListInserts(\\r
360                                 LocalIdentityID         INTEGER,\\r
361                                 Day                                     DATE,\\r
362                                 InsertIndex                     INTEGER,\\r
363                                 Inserted                        BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
364                                 );");\r
365 \r
366         db->Execute("CREATE TABLE IF NOT EXISTS tblBoardListRequests(\\r
367                                 IdentityID                      INTEGER,\\r
368                                 Day                                     DATE,\\r
369                                 RequestIndex            INTEGER,\\r
370                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
371                                 );");   \r
372 \r
373         // MessageInserter will insert a record into this temp table which the MessageListInserter will query for and insert a MessageList when needed\r
374         db->Execute("CREATE TEMPORARY TABLE IF NOT EXISTS tmpMessageListInsert(\\r
375                                 LocalIdentityID         INTEGER,\\r
376                                 Date                            DATETIME\\r
377                                 );");\r
378 \r
379         // low / high / message count for each board\r
380         db->Execute("CREATE VIEW IF NOT EXISTS vwBoardStats AS \\r
381                                 SELECT tblBoard.BoardID AS 'BoardID', IFNULL(MIN(MessageID),0) AS 'LowMessageID', IFNULL(MAX(MessageID),0) AS 'HighMessageID', COUNT(MessageID) AS 'MessageCount' \\r
382                                 FROM tblBoard LEFT JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID \\r
383                                 WHERE MessageID>=0 OR MessageID IS NULL \\r
384                                 GROUP BY tblBoard.BoardID;");\r
385 \r
386         // calculates peer trust\r
387         // do the (MessageTrust+1)*LocalTrustListTrust/(MessageTrust+1)/100.0 - so if MessageTrust or TrustListTrust is NULL, the calc will be NULL and it won't be included at all in the average\r
388         // need the +1 so that when the values are 0 the result is not 0\r
389         db->Execute("DROP VIEW IF EXISTS vwCalculatedPeerTrust;");\r
390         db->Execute("CREATE VIEW IF NOT EXISTS vwCalculatedPeerTrust AS \\r
391                                 SELECT TargetIdentityID, \\r
392                                 ROUND(SUM(MessageTrust*(LocalTrustListTrust/100.0))/SUM(((MessageTrust+1)*LocalTrustListTrust/(MessageTrust+1))/100.0),0) AS 'PeerMessageTrust', \\r
393                                 ROUND(SUM(TrustListTrust*(LocalTrustListTrust/100.0))/SUM(((TrustListTrust+1)*LocalTrustListTrust/(TrustListTrust+1))/100.0),0) AS 'PeerTrustListTrust' \\r
394                                 FROM tblPeerTrust INNER JOIN tblIdentity ON tblPeerTrust.IdentityID=tblIdentity.IdentityID \\r
395                                 WHERE LocalTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalTrustListTrust') \\r
396                                 AND ( PeerTrustListTrust IS NULL OR PeerTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerTrustListTrust') ) \\r
397                                 GROUP BY TargetIdentityID;");\r
398 \r
399         /*\r
400                 These peer trust calculations are too CPU intensive to be triggers - they were called every time a new trust list was processed\r
401                 All trust levels will now be recalculated every hour in the PeriodicDBMaintenance class\r
402         */\r
403         // drop existing triggers\r
404         db->Execute("DROP TRIGGER IF EXISTS trgDeleteOntblPeerTrust;");\r
405         db->Execute("DROP TRIGGER IF EXISTS trgInsertOntblPeerTrust;");\r
406         db->Execute("DROP TRIGGER IF EXISTS trgUpdateOntblPeerTrust;");\r
407         db->Execute("DROP TRIGGER IF EXISTS trgUpdateLocalTrustLevels;");\r
408 /*\r
409         // update PeerTrustLevel when deleting a record from tblPeerTrust\r
410         db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteOntblPeerTrust AFTER DELETE ON tblPeerTrust \\r
411                                 FOR EACH ROW \\r
412                                 BEGIN \\r
413                                         UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID) WHERE IdentityID=old.TargetIdentityID;\\r
414                                 END;");\r
415 \r
416         // update PeerTrustLevel when inserting a record into tblPeerTrust\r
417         db->Execute("CREATE TRIGGER IF NOT EXISTS trgInsertOntblPeerTrust AFTER INSERT ON tblPeerTrust \\r
418                                 FOR EACH ROW \\r
419                                 BEGIN \\r
420                                         UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID) WHERE IdentityID=new.TargetIdentityID;\\r
421                                 END;");\r
422 \r
423         // update PeerTrustLevel when updating a record in tblPeerTrust\r
424         db->Execute("CREATE TRIGGER IF NOT EXISTS trgUpdateOntblPeerTrust AFTER UPDATE ON tblPeerTrust \\r
425                                 FOR EACH ROW \\r
426                                 BEGIN \\r
427                                         UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=old.TargetIdentityID) WHERE IdentityID=old.TargetIdentityID;\\r
428                                         UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=new.TargetIdentityID) WHERE IdentityID=new.TargetIdentityID;\\r
429                                 END;");\r
430 \r
431         // recalculate all Peer TrustLevels when updating Local TrustLevels on tblIdentity - doesn't really need to be all, but rather all identities the updated identity has a trust level for.  It's easier to update everyone for now.\r
432         db->Execute("CREATE TRIGGER IF NOT EXISTS trgUpdateLocalTrustLevels AFTER UPDATE OF LocalMessageTrust,LocalTrustListTrust ON tblIdentity \\r
433                                 FOR EACH ROW \\r
434                                 BEGIN \\r
435                                         UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID);\\r
436                                 END;");\r
437 */\r
438 \r
439         db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteMessage AFTER DELETE ON tblMessage \\r
440                                 FOR EACH ROW \\r
441                                 BEGIN \\r
442                                         DELETE FROM tblMessageBoard WHERE tblMessageBoard.MessageID=old.MessageID;\\r
443                                         DELETE FROM tblMessageReplyTo WHERE tblMessageReplyTo.MessageID=old.MessageID;\\r
444                                 END;");\r
445 \r
446         db->Execute("DROP TRIGGER IF EXISTS trgDeleteIdentity;");\r
447         db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteIdentity AFTER DELETE ON tblIdentity \\r
448                                 FOR EACH ROW \\r
449                                 BEGIN \\r
450                                         DELETE FROM tblIdentityRequests WHERE IdentityID=old.IdentityID;\\r
451                                         DELETE FROM tblIntroductionPuzzleRequests WHERE IdentityID=old.IdentityID;\\r
452                                         DELETE FROM tblMessageListRequests WHERE IdentityID=old.IdentityID;\\r
453                                         DELETE FROM tblMessageRequests WHERE IdentityID=old.IdentityID;\\r
454                                         DELETE FROM tblPeerTrust WHERE IdentityID=old.IdentityID;\\r
455                                         DELETE FROM tblTrustListRequests WHERE IdentityID=old.IdentityID;\\r
456                                         DELETE FROM tblIdentityTrust WHERE IdentityID=old.IdentityID;\\r
457                                 END;");\r
458 \r
459         db->Execute("DROP TRIGGER IF EXISTS trgDeleteLocalIdentity;");\r
460         db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteLocalIdentity AFTER DELETE ON tblLocalIdentity \\r
461                                 FOR EACH ROW \\r
462                                 BEGIN \\r
463                                         DELETE FROM tblIdentityIntroductionInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
464                                         DELETE FROM tblIntroductionPuzzleInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
465                                         DELETE FROM tblLocalIdentityInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
466                                         DELETE FROM tblMessageInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
467                                         DELETE FROM tblMessageListInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
468                                         DELETE FROM tblTrustListInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
469                                         DELETE FROM tblIdentityTrust WHERE LocalIdentityID=old.LocalIdentityID;\\r
470                                 END;");\r
471 \r
472         db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteBoard AFTER DELETE ON tblBoard \\r
473                                 FOR EACH ROW \\r
474                                 BEGIN \\r
475                                         DELETE FROM tblMessageBoard WHERE BoardID=old.BoardID;\\r
476                                 END;");\r
477 \r
478         // delete introduction puzzles that were half-way inserted\r
479         db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day IS NULL AND InsertIndex IS NULL;");\r
480 \r
481         // delete stale introduction puzzles (2 or more days old)\r
482         date.SetToGMTime();\r
483         date.Add(0,0,0,-2);\r
484         db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day<='"+date.Format("%Y-%m-%d")+"';");\r
485         db->Execute("DELETE FROM tblIntroductionPuzzleRequests WHERE Day<='"+date.Format("%Y-%m-%d")+"';");\r
486 \r
487         date.SetToGMTime();\r
488         // insert SomeDude's public key\r
489         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
490         // insert Shadow Panther's public key\r
491         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
492         // insert garfield's public key\r
493         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
494 \r
495         // TODO remove sometime after 0.1.17\r
496         FixCapitalBoardNames();\r
497 \r
498         // run analyze - may speed up some queries\r
499         db->Execute("ANALYZE;");\r
500 \r
501 }\r
502 \r
503 void ConvertDB0100To0101()\r
504 {\r
505         // added unique constraint to public and private key\r
506         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
507         db->Execute("CREATE TEMPORARY TABLE tblLocalIdentityTemp AS SELECT * FROM tblLocalIdentity;");\r
508         db->Execute("DROP TABLE IF EXISTS tblLocalIdentity;");\r
509         db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\\r
510                                 LocalIdentityID                 INTEGER PRIMARY KEY,\\r
511                                 Name                                    TEXT,\\r
512                                 PublicKey                               TEXT UNIQUE,\\r
513                                 PrivateKey                              TEXT UNIQUE,\\r
514                                 SingleUse                               BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
515                                 PublishTrustList                BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
516                                 PublishBoardList                BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
517                                 InsertingIdentity               BOOL CHECK(InsertingIdentity IN('true','false')) DEFAULT 'false',\\r
518                                 LastInsertedIdentity    DATETIME,\\r
519                                 InsertingPuzzle                 BOOL CHECK(InsertingPuzzle IN('true','false')) DEFAULT 'false',\\r
520                                 LastInsertedPuzzle              DATETIME,\\r
521                                 InsertingTrustList              BOOL CHECK(InsertingTrustList IN('true','false')) DEFAULT 'false',\\r
522                                 LastInsertedTrustList   DATETIME,\\r
523                                 InsertingBoardList              BOOL CHECK(InsertingBoardList IN('true','false')) DEFAULT 'false',\\r
524                                 LastInsertedBoardList   DATETIME,\\r
525                                 InsertingMessageList    BOOL CHECK(InsertingMessageList IN('true','false')) DEFAULT 'false',\\r
526                                 LastInsertedMessageList DATETIME\\r
527                                 );");\r
528         db->Execute("INSERT INTO tblLocalIdentity SELECT * FROM tblLocalIdentityTemp;");\r
529         db->Execute("DROP TABLE IF EXISTS tblLocalIdentityTemp;");\r
530         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=1;");\r
531 }\r
532 \r
533 void ConvertDB0101To0103()\r
534 {\r
535         // remove default 50 from trust fields and set default to NULL\r
536         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
537         db->Execute("CREATE TEMPORARY TABLE tblIdentityTemp AS SELECT * FROM tblIdentity;");\r
538         db->Execute("DROP TABLE IF EXISTS tblIdentity;");\r
539         db->Execute("CREATE TABLE IF NOT EXISTS tblIdentity(\\r
540                                 IdentityID                      INTEGER PRIMARY KEY,\\r
541                                 PublicKey                       TEXT UNIQUE,\\r
542                                 Name                            TEXT,\\r
543                                 SingleUse                       BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
544                                 PublishTrustList        BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
545                                 PublishBoardList        BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
546                                 DateAdded                       DATETIME,\\r
547                                 LastSeen                        DATETIME,\\r
548                                 LocalMessageTrust       INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
549                                 PeerMessageTrust        INTEGER CHECK(PeerMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
550                                 LocalTrustListTrust     INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
551                                 PeerTrustListTrust      INTEGER CHECK(PeerTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL\\r
552                                 );");\r
553         db->Execute("INSERT INTO tblIdentity SELECT * FROM tblIdentityTemp;");\r
554         db->Execute("DROP TABLE IF EXISTS tblIdentityTemp;");\r
555 \r
556         // add SaveReceivedMessages field to tblBoard\r
557         db->Execute("ALTER TABLE tblBoard ADD COLUMN SaveReceivedMessages       BOOL CHECK(SaveReceivedMessages IN('true','false')) DEFAULT 'true';");\r
558 \r
559         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=3;");\r
560 }\r
561 \r
562 void ConvertDB0103To0104()\r
563 {\r
564         // add MessageIndex to tblMessage\r
565         DateTime date;\r
566         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
567         db->Execute("ALTER TABLE tblMessage ADD COLUMN MessageIndex     INTEGER;");\r
568         db->Execute("CREATE UNIQUE INDEX IF NOT EXISTS idxMessageRequest ON tblMessageRequests(IdentityID,Day,RequestIndex);");\r
569         db->Execute("ALTER TABLE tblLocalIdentity ADD COLUMN DateCreated DATETIME;");\r
570         date.SetToGMTime();\r
571         db->Execute("UPDATE tblLocalIdentity SET DateCreated='"+date.Format("%Y-%m-%d %H:%M:%S")+"' WHERE DateCreated IS NULL;");\r
572         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=4;");\r
573 }\r
574 \r
575 void ConvertDB0104To0105()\r
576 {\r
577         // add AddedMethod, MessageTrustComment, TrustListTrustComment to tblIdentity\r
578         // add MessageTrustComment,TrustListTrustComment to tblPeerTrust\r
579         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
580         db->Execute("ALTER TABLE tblIdentity ADD COLUMN AddedMethod TEXT;");\r
581         db->Execute("ALTER TABLE tblIdentity ADD COLUMN MessageTrustComment TEXT;");\r
582         db->Execute("ALTER TABLE tblIdentity ADD COLUMN TrustListTrustComment TEXT;");\r
583         db->Execute("ALTER TABLE tblPeerTrust ADD COLUMN MessageTrustComment TEXT;");\r
584         db->Execute("ALTER TABLE tblPeerTrust ADD COLUMN TrustListTrustComment TEXT;");\r
585         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=5;");\r
586 }\r
587 \r
588 void ConvertDB0105To0106()\r
589 {\r
590         // add Publish Freesite\r
591         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
592         db->Execute("ALTER TABLE tblLocalIdentity ADD COLUMN PublishFreesite BOOL CHECK(PublishFreesite IN('true','false')) DEFAULT 'false';");\r
593         db->Execute("ALTER TABLE tblLocalIdentity ADD COLUMN LastInsertedFreesite DATETIME;");\r
594         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=6;");\r
595 }\r
596 \r
597 void ConvertDB0106To0107()\r
598 {\r
599         // add AddedMethod to tblBoard\r
600         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
601         db->Execute("ALTER TABLE tblBoard ADD COLUMN AddedMethod TEXT;");\r
602         db->Execute("ALTER TABLE tblIdentity ADD COLUMN Hidden BOOL CHECK(Hidden IN('true','false')) DEFAULT 'false';");\r
603         db->Execute("UPDATE tblIdentity SET Hidden='false' WHERE Hidden IS NULL;");\r
604         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=7;");\r
605 }\r
606 \r
607 void ConvertDB0107To0108()\r
608 {\r
609         // add FreesiteEdition to tblLocalIdentity and tblIdentity\r
610         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
611         db->Execute("ALTER TABLE tblLocalIdentity ADD COLUMN FreesiteEdition INTEGER;");\r
612         db->Execute("ALTER TABLE tblIdentity ADD COLUMN FreesiteEdition INTEGER;");\r
613         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=8;");\r
614 }\r
615 \r
616 void ConvertDB0108To0109()\r
617 {\r
618         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
619         db->Execute("CREATE TABLE IF NOT EXISTS tblFileInserts(\\r
620                         FileInsertID            INTEGER PRIMARY KEY,\\r
621                         MessageUUID                     TEXT,\\r
622                         FileName                        TEXT,\\r
623                         Key                                     TEXT,\\r
624                         Size                            INTEGER,\\r
625                         Data                            BLOB\\r
626                         );");\r
627         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=9;");\r
628 }\r
629 \r
630 void SetupDefaultOptions()\r
631 {\r
632         // 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
633 \r
634         std::ostringstream tempstr;     // must set tempstr to "" between db inserts\r
635         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
636         SQLite3DB::Statement st=db->Prepare("INSERT INTO tblOption(Option,OptionValue,OptionDescription) VALUES(?,?,?);");\r
637 \r
638         // LogLevel\r
639         tempstr.str("");\r
640         tempstr << LogFile::LOGLEVEL_DEBUG;\r
641         st.Bind(0,"LogLevel");\r
642         st.Bind(1,tempstr.str());\r
643         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
644         st.Step();\r
645         st.Reset();\r
646 \r
647         // NNTPListenPort\r
648         st.Bind(0,"NNTPListenPort");\r
649         st.Bind(1,"1119");\r
650         st.Bind(2,"The port that the NNTP service will listen for incoming connections.");\r
651         st.Step();\r
652         st.Reset();\r
653 \r
654         // NNTPBindAddresses\r
655         st.Bind(0,"NNTPBindAddresses");\r
656         st.Bind(1,"localhost");\r
657         st.Bind(2,"A comma separated list of valid IPv4 or IPv6 addresses/hostnames that the NNTP service will try to bind to.");\r
658         st.Step();\r
659         st.Reset();\r
660 \r
661         st.Bind(0,"NNTPAllowPost");\r
662         st.Bind(1,"true");\r
663         st.Bind(2,"Allow posting messages from NNTP.  Setting to false will make the newsgroups read only.");\r
664         st.Step();\r
665         st.Reset();\r
666 \r
667         // StartNNTP\r
668         st.Bind(0,"StartNNTP");\r
669         st.Bind(1,"true");\r
670         st.Bind(2,"Start NNTP server.");\r
671         st.Step();\r
672         st.Reset();\r
673 \r
674         st.Bind(0,"StartHTTP");\r
675         st.Bind(1,"true");\r
676         st.Bind(2,"Start HTTP server.  WARNING: If you turn this off, you won't be able to access the administration pages.");\r
677         st.Step();\r
678         st.Reset();\r
679 \r
680         st.Bind(0,"HTTPListenPort");\r
681         st.Bind(1,"8080");\r
682         st.Bind(2,"Port HTTP server will listen on.");\r
683         st.Step();\r
684         st.Reset();\r
685 \r
686         st.Bind(0,"HTTPAccessControl");\r
687         st.Bind(1,"-0.0.0.0/0,+127.0.0.1");\r
688         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
689         st.Step();\r
690         st.Reset();\r
691 \r
692         // StartFreenetUpdater\r
693         st.Bind(0,"StartFreenetUpdater");\r
694         st.Bind(1,"true");\r
695         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
696         st.Step();\r
697         st.Reset();\r
698 \r
699         // FCPHost\r
700         st.Bind(0,"FCPHost");\r
701         st.Bind(1,"127.0.0.1");\r
702         st.Bind(2,"Host name or address of Freenet node.");\r
703         st.Step();\r
704         st.Reset();\r
705 \r
706         // FCPPort\r
707         st.Bind(0,"FCPPort");\r
708         st.Bind(1,"9481");\r
709         st.Bind(2,"The port that Freenet is listening for FCP connections on.");\r
710         st.Step();\r
711         st.Reset();\r
712 \r
713         st.Bind(0,"MessageBase");\r
714         st.Bind(1,"fms");\r
715         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
716         st.Step();\r
717         st.Reset();\r
718 \r
719         st.Bind(0,"MaxIdentityRequests");\r
720         st.Bind(1,"5");\r
721         st.Bind(2,"Maximum number of concurrent requests for new Identity xml files");\r
722         st.Step();\r
723         st.Reset();\r
724 \r
725         st.Bind(0,"MaxIdentityIntroductionRequests");\r
726         st.Bind(1,"5");\r
727         st.Bind(2,"Maximum number of concurrent identities requesting IdentityIntroduction xml files.  Each identity may have multiple requests pending.");\r
728         st.Step();\r
729         st.Reset();\r
730 \r
731         st.Bind(0,"MaxIntroductionPuzzleRequests");\r
732         st.Bind(1,"5");\r
733         st.Bind(2,"Maximum number of concurrent requests for new IntroductionPuzzle xml files");\r
734         st.Step();\r
735         st.Reset();\r
736 \r
737         st.Bind(0,"MaxTrustListRequests");\r
738         st.Bind(1,"5");\r
739         st.Bind(2,"Maximum number of concurrent requests for new Trust Lists");\r
740         st.Step();\r
741         st.Reset();\r
742 \r
743         st.Bind(0,"MaxMessageListRequests");\r
744         st.Bind(1,"5");\r
745         st.Bind(2,"Maximum number of concurrent requests for new Message Lists");\r
746         st.Step();\r
747         st.Reset();\r
748 \r
749         st.Bind(0,"MaxMessageRequests");\r
750         st.Bind(1,"20");\r
751         st.Bind(2,"Maximum number of concurrent requests for new Messages");\r
752         st.Step();\r
753         st.Reset();\r
754 \r
755         st.Bind(0,"MinLocalMessageTrust");\r
756         st.Bind(1,"50");\r
757         st.Bind(2,"Specifies a local message trust level that a peer must have before its messages will be downloaded.");\r
758         st.Step();\r
759         st.Reset();\r
760 \r
761         st.Bind(0,"MinPeerMessageTrust");\r
762         st.Bind(1,"30");\r
763         st.Bind(2,"Specifies a peer message trust level that a peer must have before its messages will be downloaded.");\r
764         st.Step();\r
765         st.Reset();\r
766 \r
767         st.Bind(0,"MinLocalTrustListTrust");\r
768         st.Bind(1,"50");\r
769         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
770         st.Step();\r
771         st.Reset();\r
772 \r
773         st.Bind(0,"MinPeerTrustListTrust");\r
774         st.Bind(1,"30");\r
775         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
776         st.Step();\r
777         st.Reset();\r
778 \r
779         st.Bind(0,"MessageDownloadMaxDaysBackward");\r
780         st.Bind(1,"5");\r
781         st.Bind(2,"The maximum number of days backward that messages will be downloaded from each identity");\r
782         st.Step();\r
783         st.Reset();\r
784 \r
785         st.Bind(0,"MessageListDaysBackward");\r
786         st.Bind(1,"5");\r
787         st.Bind(2,"The number of days backward that messages you have inserted will appear in your MessageLists");\r
788         st.Step();\r
789         st.Reset();\r
790 \r
791         st.Bind(0,"MaxPeerMessagesPerDay");\r
792         st.Bind(1,"200");\r
793         st.Bind(2,"The maximum number of messages you will download from each peer on a given day.");\r
794         st.Step();\r
795         st.Reset();\r
796 \r
797         st.Bind(0,"MaxBoardListRequests");\r
798         st.Bind(1,"5");\r
799         st.Bind(2,"The maximum number of concurrent requests for new Board Lists.  Set to 0 to disable.");\r
800         st.Step();\r
801         st.Reset();\r
802 \r
803         st.Bind(0,"MaxBoardsPerMessage");\r
804         st.Bind(1,"8");\r
805         st.Bind(2,"The maximum number of boards a received message may be sent to.  Boards over this limit will be ignored.");\r
806         st.Step();\r
807         st.Reset();\r
808 \r
809         st.Bind(0,"SaveMessagesFromNewBoards");\r
810         st.Bind(1,"true");\r
811         st.Bind(2,"Set to true to automatically save messages posted to new boards.  Set to false to ignore messages to new boards.");\r
812         st.Step();\r
813         st.Reset();\r
814 \r
815         st.Bind(0,"ChangeMessageTrustOnReply");\r
816         st.Bind(1,"0");\r
817         st.Bind(2,"How much the local message trust level of an identity should change when you reply to one of their messages.");\r
818         st.Step();\r
819         st.Reset();\r
820 \r
821         st.Bind(0,"AddNewPostFromIdentities");\r
822         st.Bind(1,"false");\r
823         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
824         st.Step();\r
825         st.Reset();\r
826 \r
827         st.Bind(0,"DeleteMessagesOlderThan");\r
828         st.Bind(1,"180");\r
829         st.Bind(2,"Automatically delete messages older than this many days.");\r
830         st.Step();\r
831         st.Reset();\r
832 \r
833 }\r
834 \r
835 void SetupLogFile()\r
836 {\r
837         DateTime date;\r
838         std::string configval;\r
839         int loglevel;\r
840 \r
841         date.SetToGMTime();\r
842 \r
843         LogFile::Instance()->SetFileName("fms-"+date.Format("%Y-%m-%d")+".log");\r
844         LogFile::Instance()->OpenFile();\r
845         LogFile::Instance()->SetWriteNewLine(true);\r
846         LogFile::Instance()->SetWriteDate(true);\r
847         LogFile::Instance()->SetWriteLogLevel(true);\r
848 \r
849         if(Option::Instance()->Get("LogLevel",configval)==false)\r
850         {\r
851                 configval="4";\r
852                 Option::Instance()->Set("LogLevel",configval);\r
853         }\r
854         if(StringFunctions::Convert(configval,loglevel)==false)\r
855         {\r
856                 loglevel=LogFile::LOGLEVEL_DEBUG;\r
857                 Option::Instance()->Set("LogLevel",loglevel);\r
858         }\r
859         LogFile::Instance()->SetLogLevel((LogFile::LogLevel)loglevel);\r
860 }\r
861 \r
862 void SetupNetwork()\r
863 {\r
864 #ifdef _WIN32\r
865         WSAData wsadata;\r
866         WSAStartup(MAKEWORD(2,2),&wsadata);\r
867 #endif\r
868 }\r
869 \r
870 void Shutdown()\r
871 {\r
872         ThreadController::Instance()->ShutdownThreads();\r
873 \r
874         ShutdownNetwork();\r
875 \r
876         LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_INFO,"FMS shutdown");\r
877         LogFile::Instance()->WriteNewLine();\r
878 }\r
879 \r
880 void ShutdownNetwork()\r
881 {\r
882 #ifdef _WIN32\r
883         WSACleanup();\r
884 #endif\r
885 }\r
886 \r
887 void SigHandler(int signum)\r
888 {\r
889         Shutdown();\r
890         exit(0);\r
891 }\r
892 \r
893 void FixCapitalBoardNames()\r
894 {\r
895         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
896 \r
897         SQLite3DB::Statement st=db->Prepare("SELECT BoardID,BoardName FROM tblBoard WHERE BoardID NOT IN (SELECT BoardID FROM tblAdministrationBoard);");\r
898         SQLite3DB::Statement st2=db->Prepare("SELECT BoardID FROM tblBoard WHERE BoardName=?;");\r
899         SQLite3DB::Statement del=db->Prepare("DELETE FROM tblBoard WHERE BoardID=?;");\r
900         SQLite3DB::Statement upd=db->Prepare("UPDATE tblBoard SET BoardName=? WHERE BoardID=?;");\r
901         SQLite3DB::Statement upd2=db->Prepare("UPDATE tblMessage SET ReplyBoardID=? WHERE ReplyBoardID=?;");\r
902         SQLite3DB::Statement upd3=db->Prepare("UPDATE tblMessageBoard SET BoardID=? WHERE BoardID=?;");\r
903 \r
904         st.Step();\r
905         while(st.RowReturned())\r
906         {\r
907                 int boardid=0;\r
908                 int newboardid=0;\r
909                 std::string name="";\r
910                 std::string lowername="";\r
911 \r
912                 st.ResultInt(0,boardid);\r
913                 st.ResultText(1,name);\r
914 \r
915                 lowername=name;\r
916                 StringFunctions::LowerCase(lowername,lowername);\r
917        \r
918                 if(name!=lowername)\r
919                 {\r
920                         st2.Bind(0,lowername);\r
921                         st2.Step();\r
922 \r
923                         if(st2.RowReturned())\r
924                         {\r
925                                 st2.ResultInt(0,newboardid);\r
926 \r
927                                 upd2.Bind(0,newboardid);\r
928                                 upd2.Bind(1,boardid);\r
929                                 upd2.Step();\r
930                                 upd2.Reset();\r
931 \r
932                                 upd3.Bind(0,newboardid);\r
933                                 upd3.Bind(1,boardid);\r
934                                 upd3.Step();\r
935                                 upd3.Reset();\r
936 \r
937                                 del.Bind(0,boardid);\r
938                                 del.Step();\r
939                                 del.Reset();\r
940                         }\r
941                         else\r
942                         {\r
943                                 upd.Bind(0,lowername);\r
944                                 upd.Bind(1,boardid);\r
945                                 upd.Step();\r
946                                 upd.Reset();\r
947                         }\r
948 \r
949                         st2.Reset();\r
950                 }\r
951        \r
952                 st.Step();\r
953         }\r
954 \r
955 }\r