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