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