version 0.2.8
[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 }\r
476 \r
477 void ConvertDB0100To0101()\r
478 {\r
479         // added unique constraint to public and private key\r
480         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
481         db->Execute("CREATE TEMPORARY TABLE tblLocalIdentityTemp AS SELECT * FROM tblLocalIdentity;");\r
482         db->Execute("DROP TABLE IF EXISTS tblLocalIdentity;");\r
483         db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\\r
484                                 LocalIdentityID                 INTEGER PRIMARY KEY,\\r
485                                 Name                                    TEXT,\\r
486                                 PublicKey                               TEXT UNIQUE,\\r
487                                 PrivateKey                              TEXT UNIQUE,\\r
488                                 SingleUse                               BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
489                                 PublishTrustList                BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
490                                 PublishBoardList                BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
491                                 InsertingIdentity               BOOL CHECK(InsertingIdentity IN('true','false')) DEFAULT 'false',\\r
492                                 LastInsertedIdentity    DATETIME,\\r
493                                 InsertingPuzzle                 BOOL CHECK(InsertingPuzzle IN('true','false')) DEFAULT 'false',\\r
494                                 LastInsertedPuzzle              DATETIME,\\r
495                                 InsertingTrustList              BOOL CHECK(InsertingTrustList IN('true','false')) DEFAULT 'false',\\r
496                                 LastInsertedTrustList   DATETIME,\\r
497                                 InsertingBoardList              BOOL CHECK(InsertingBoardList IN('true','false')) DEFAULT 'false',\\r
498                                 LastInsertedBoardList   DATETIME,\\r
499                                 InsertingMessageList    BOOL CHECK(InsertingMessageList IN('true','false')) DEFAULT 'false',\\r
500                                 LastInsertedMessageList DATETIME\\r
501                                 );");\r
502         db->Execute("INSERT INTO tblLocalIdentity SELECT * FROM tblLocalIdentityTemp;");\r
503         db->Execute("DROP TABLE IF EXISTS tblLocalIdentityTemp;");\r
504         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=1;");\r
505 }\r
506 \r
507 void ConvertDB0101To0103()\r
508 {\r
509         // remove default 50 from trust fields and set default to NULL\r
510         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
511         db->Execute("CREATE TEMPORARY TABLE tblIdentityTemp AS SELECT * FROM tblIdentity;");\r
512         db->Execute("DROP TABLE IF EXISTS tblIdentity;");\r
513         db->Execute("CREATE TABLE IF NOT EXISTS tblIdentity(\\r
514                                 IdentityID                      INTEGER PRIMARY KEY,\\r
515                                 PublicKey                       TEXT UNIQUE,\\r
516                                 Name                            TEXT,\\r
517                                 SingleUse                       BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
518                                 PublishTrustList        BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
519                                 PublishBoardList        BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
520                                 DateAdded                       DATETIME,\\r
521                                 LastSeen                        DATETIME,\\r
522                                 LocalMessageTrust       INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
523                                 PeerMessageTrust        INTEGER CHECK(PeerMessageTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
524                                 LocalTrustListTrust     INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL,\\r
525                                 PeerTrustListTrust      INTEGER CHECK(PeerTrustListTrust BETWEEN 0 AND 100) DEFAULT NULL\\r
526                                 );");\r
527         db->Execute("INSERT INTO tblIdentity SELECT * FROM tblIdentityTemp;");\r
528         db->Execute("DROP TABLE IF EXISTS tblIdentityTemp;");\r
529 \r
530         // add SaveReceivedMessages field to tblBoard\r
531         db->Execute("ALTER TABLE tblBoard ADD COLUMN SaveReceivedMessages       BOOL CHECK(SaveReceivedMessages IN('true','false')) DEFAULT 'true';");\r
532 \r
533         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=3;");\r
534 }\r
535 \r
536 void ConvertDB0103To0104()\r
537 {\r
538         // add MessageIndex to tblMessage\r
539         DateTime date;\r
540         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
541         db->Execute("ALTER TABLE tblMessage ADD COLUMN MessageIndex     INTEGER;");\r
542         db->Execute("CREATE UNIQUE INDEX IF NOT EXISTS idxMessageRequest ON tblMessageRequests(IdentityID,Day,RequestIndex);");\r
543         db->Execute("ALTER TABLE tblLocalIdentity ADD COLUMN DateCreated DATETIME;");\r
544         date.SetToGMTime();\r
545         db->Execute("UPDATE tblLocalIdentity SET DateCreated='"+date.Format("%Y-%m-%d %H:%M:%S")+"' WHERE DateCreated IS NULL;");\r
546         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=4;");\r
547 }\r
548 \r
549 void ConvertDB0104To0105()\r
550 {\r
551         // add AddedMethod, MessageTrustComment, TrustListTrustComment to tblIdentity\r
552         // add MessageTrustComment,TrustListTrustComment to tblPeerTrust\r
553         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
554         db->Execute("ALTER TABLE tblIdentity ADD COLUMN AddedMethod TEXT;");\r
555         db->Execute("ALTER TABLE tblIdentity ADD COLUMN MessageTrustComment TEXT;");\r
556         db->Execute("ALTER TABLE tblIdentity ADD COLUMN TrustListTrustComment TEXT;");\r
557         db->Execute("ALTER TABLE tblPeerTrust ADD COLUMN MessageTrustComment TEXT;");\r
558         db->Execute("ALTER TABLE tblPeerTrust ADD COLUMN TrustListTrustComment TEXT;");\r
559         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=5;");\r
560 }\r
561 \r
562 void ConvertDB0105To0106()\r
563 {\r
564         // add Publish Freesite\r
565         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
566         db->Execute("ALTER TABLE tblLocalIdentity ADD COLUMN PublishFreesite BOOL CHECK(PublishFreesite IN('true','false')) DEFAULT 'false';");\r
567         db->Execute("ALTER TABLE tblLocalIdentity ADD COLUMN LastInsertedFreesite DATETIME;");\r
568         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=6;");\r
569 }\r
570 \r
571 void ConvertDB0106To0107()\r
572 {\r
573         // add AddedMethod to tblBoard\r
574         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
575         db->Execute("ALTER TABLE tblBoard ADD COLUMN AddedMethod TEXT;");\r
576         db->Execute("ALTER TABLE tblIdentity ADD COLUMN Hidden BOOL CHECK(Hidden IN('true','false')) DEFAULT 'false';");\r
577         db->Execute("UPDATE tblIdentity SET Hidden='false' WHERE Hidden IS NULL;");\r
578         db->Execute("UPDATE tblDBVersion SET Major=1, Minor=7;");\r
579 }\r
580 \r
581 void SetupDefaultOptions()\r
582 {\r
583         // 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
584 \r
585         std::ostringstream tempstr;     // must set tempstr to "" between db inserts\r
586         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
587         SQLite3DB::Statement st=db->Prepare("INSERT INTO tblOption(Option,OptionValue,OptionDescription) VALUES(?,?,?);");\r
588 \r
589         // LogLevel\r
590         tempstr.str("");\r
591         tempstr << LogFile::LOGLEVEL_DEBUG;\r
592         st.Bind(0,"LogLevel");\r
593         st.Bind(1,tempstr.str());\r
594         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
595         st.Step();\r
596         st.Reset();\r
597 \r
598         // NNTPListenPort\r
599         st.Bind(0,"NNTPListenPort");\r
600         st.Bind(1,"1119");\r
601         st.Bind(2,"The port that the NNTP service will listen for incoming connections.");\r
602         st.Step();\r
603         st.Reset();\r
604 \r
605         // NNTPBindAddresses\r
606         st.Bind(0,"NNTPBindAddresses");\r
607         st.Bind(1,"localhost");\r
608         st.Bind(2,"A comma separated list of valid IPv4 or IPv6 addresses/hostnames that the NNTP service will try to bind to.");\r
609         st.Step();\r
610         st.Reset();\r
611 \r
612         st.Bind(0,"NNTPAllowPost");\r
613         st.Bind(1,"true");\r
614         st.Bind(2,"Allow posting messages from NNTP.  Setting to false will make the newsgroups read only.");\r
615         st.Step();\r
616         st.Reset();\r
617 \r
618         // StartNNTP\r
619         st.Bind(0,"StartNNTP");\r
620         st.Bind(1,"true");\r
621         st.Bind(2,"Start NNTP server.");\r
622         st.Step();\r
623         st.Reset();\r
624 \r
625         st.Bind(0,"StartHTTP");\r
626         st.Bind(1,"true");\r
627         st.Bind(2,"Start HTTP server.  WARNING: If you turn this off, you won't be able to access the administration pages.");\r
628         st.Step();\r
629         st.Reset();\r
630 \r
631         st.Bind(0,"HTTPListenPort");\r
632         st.Bind(1,"8080");\r
633         st.Bind(2,"Port HTTP server will listen on.");\r
634         st.Step();\r
635         st.Reset();\r
636 \r
637         st.Bind(0,"HTTPAccessControl");\r
638         st.Bind(1,"-0.0.0.0/0,+127.0.0.1");\r
639         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
640         st.Step();\r
641         st.Reset();\r
642 \r
643         // StartFreenetUpdater\r
644         st.Bind(0,"StartFreenetUpdater");\r
645         st.Bind(1,"true");\r
646         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
647         st.Step();\r
648         st.Reset();\r
649 \r
650         // FCPHost\r
651         st.Bind(0,"FCPHost");\r
652         st.Bind(1,"127.0.0.1");\r
653         st.Bind(2,"Host name or address of Freenet node.");\r
654         st.Step();\r
655         st.Reset();\r
656 \r
657         // FCPPort\r
658         st.Bind(0,"FCPPort");\r
659         st.Bind(1,"9481");\r
660         st.Bind(2,"The port that Freenet is listening for FCP connections on.");\r
661         st.Step();\r
662         st.Reset();\r
663 \r
664         st.Bind(0,"MessageBase");\r
665         st.Bind(1,"fms");\r
666         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
667         st.Step();\r
668         st.Reset();\r
669 \r
670         st.Bind(0,"MaxIdentityRequests");\r
671         st.Bind(1,"5");\r
672         st.Bind(2,"Maximum number of concurrent requests for new Identity xml files");\r
673         st.Step();\r
674         st.Reset();\r
675 \r
676         st.Bind(0,"MaxIdentityIntroductionRequests");\r
677         st.Bind(1,"5");\r
678         st.Bind(2,"Maximum number of concurrent identities requesting IdentityIntroduction xml files.  Each identity may have multiple requests pending.");\r
679         st.Step();\r
680         st.Reset();\r
681 \r
682         st.Bind(0,"MaxIntroductionPuzzleRequests");\r
683         st.Bind(1,"5");\r
684         st.Bind(2,"Maximum number of concurrent requests for new IntroductionPuzzle xml files");\r
685         st.Step();\r
686         st.Reset();\r
687 \r
688         st.Bind(0,"MaxTrustListRequests");\r
689         st.Bind(1,"5");\r
690         st.Bind(2,"Maximum number of concurrent requests for new Trust Lists");\r
691         st.Step();\r
692         st.Reset();\r
693 \r
694         st.Bind(0,"MaxMessageListRequests");\r
695         st.Bind(1,"5");\r
696         st.Bind(2,"Maximum number of concurrent requests for new Message Lists");\r
697         st.Step();\r
698         st.Reset();\r
699 \r
700         st.Bind(0,"MaxMessageRequests");\r
701         st.Bind(1,"20");\r
702         st.Bind(2,"Maximum number of concurrent requests for new Messages");\r
703         st.Step();\r
704         st.Reset();\r
705 \r
706         st.Bind(0,"MinLocalMessageTrust");\r
707         st.Bind(1,"50");\r
708         st.Bind(2,"Specifies a local message trust level that a peer must have before its messages will be downloaded.");\r
709         st.Step();\r
710         st.Reset();\r
711 \r
712         st.Bind(0,"MinPeerMessageTrust");\r
713         st.Bind(1,"30");\r
714         st.Bind(2,"Specifies a peer message trust level that a peer must have before its messages will be downloaded.");\r
715         st.Step();\r
716         st.Reset();\r
717 \r
718         st.Bind(0,"MinLocalTrustListTrust");\r
719         st.Bind(1,"50");\r
720         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
721         st.Step();\r
722         st.Reset();\r
723 \r
724         st.Bind(0,"MinPeerTrustListTrust");\r
725         st.Bind(1,"30");\r
726         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
727         st.Step();\r
728         st.Reset();\r
729 \r
730         st.Bind(0,"MessageDownloadMaxDaysBackward");\r
731         st.Bind(1,"5");\r
732         st.Bind(2,"The maximum number of days backward that messages will be downloaded from each identity");\r
733         st.Step();\r
734         st.Reset();\r
735 \r
736         st.Bind(0,"MessageListDaysBackward");\r
737         st.Bind(1,"5");\r
738         st.Bind(2,"The number of days backward that messages you have inserted will appear in your MessageLists");\r
739         st.Step();\r
740         st.Reset();\r
741 \r
742         st.Bind(0,"MaxPeerMessagesPerDay");\r
743         st.Bind(1,"200");\r
744         st.Bind(2,"The maximum number of messages you will download from each peer on a given day.");\r
745         st.Step();\r
746         st.Reset();\r
747 \r
748         st.Bind(0,"MaxBoardListRequests");\r
749         st.Bind(1,"5");\r
750         st.Bind(2,"The maximum number of concurrent requests for new Board Lists.  Set to 0 to disable.");\r
751         st.Step();\r
752         st.Reset();\r
753 \r
754         st.Bind(0,"MaxBoardsPerMessage");\r
755         st.Bind(1,"8");\r
756         st.Bind(2,"The maximum number of boards a received message may be sent to.  Boards over this limit will be ignored.");\r
757         st.Step();\r
758         st.Reset();\r
759 \r
760         st.Bind(0,"SaveMessagesFromNewBoards");\r
761         st.Bind(1,"true");\r
762         st.Bind(2,"Set to true to automatically save messages posted to new boards.  Set to false to ignore messages to new boards.");\r
763         st.Step();\r
764         st.Reset();\r
765 \r
766         st.Bind(0,"ChangeMessageTrustOnReply");\r
767         st.Bind(1,"0");\r
768         st.Bind(2,"How much the local message trust level of an identity should change when you reply to one of their messages.");\r
769         st.Step();\r
770         st.Reset();\r
771 \r
772         st.Bind(0,"AddNewPostFromIdentities");\r
773         st.Bind(1,"false");\r
774         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
775         st.Step();\r
776         st.Reset();\r
777 \r
778         st.Bind(0,"DeleteMessagesOlderThan");\r
779         st.Bind(1,"180");\r
780         st.Bind(2,"Automatically delete messages older than this many days.");\r
781         st.Step();\r
782         st.Reset();\r
783 \r
784 }\r
785 \r
786 void SetupLogFile()\r
787 {\r
788         DateTime date;\r
789         std::string configval;\r
790         int loglevel;\r
791 \r
792         date.SetToGMTime();\r
793 \r
794         LogFile::Instance()->SetFileName("fms-"+date.Format("%Y-%m-%d")+".log");\r
795         LogFile::Instance()->OpenFile();\r
796         LogFile::Instance()->SetWriteNewLine(true);\r
797         LogFile::Instance()->SetWriteDate(true);\r
798         LogFile::Instance()->SetWriteLogLevel(true);\r
799 \r
800         if(Option::Instance()->Get("LogLevel",configval)==false)\r
801         {\r
802                 configval="4";\r
803                 Option::Instance()->Set("LogLevel",configval);\r
804         }\r
805         if(StringFunctions::Convert(configval,loglevel)==false)\r
806         {\r
807                 loglevel=LogFile::LOGLEVEL_DEBUG;\r
808                 Option::Instance()->Set("LogLevel",loglevel);\r
809         }\r
810         LogFile::Instance()->SetLogLevel((LogFile::LogLevel)loglevel);\r
811 }\r
812 \r
813 void SetupNetwork()\r
814 {\r
815 #ifdef _WIN32\r
816         WSAData wsadata;\r
817         WSAStartup(MAKEWORD(2,2),&wsadata);\r
818 #endif\r
819 }\r
820 \r
821 void Shutdown()\r
822 {\r
823         ThreadController::Instance()->ShutdownThreads();\r
824 \r
825         ShutdownNetwork();\r
826 \r
827         LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_INFO,"FMS shutdown");\r
828         LogFile::Instance()->WriteNewLine();\r
829 }\r
830 \r
831 void ShutdownNetwork()\r
832 {\r
833 #ifdef _WIN32\r
834         WSACleanup();\r
835 #endif\r
836 }\r
837 \r
838 void SigHandler(int signum)\r
839 {\r
840         Shutdown();\r
841         exit(0);\r
842 }\r
843 \r
844 void FixCapitalBoardNames()\r
845 {\r
846         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
847 \r
848         SQLite3DB::Statement st=db->Prepare("SELECT BoardID,BoardName FROM tblBoard WHERE BoardID NOT IN (SELECT BoardID FROM tblAdministrationBoard);");\r
849         SQLite3DB::Statement st2=db->Prepare("SELECT BoardID FROM tblBoard WHERE BoardName=?;");\r
850         SQLite3DB::Statement del=db->Prepare("DELETE FROM tblBoard WHERE BoardID=?;");\r
851         SQLite3DB::Statement upd=db->Prepare("UPDATE tblBoard SET BoardName=? WHERE BoardID=?;");\r
852         SQLite3DB::Statement upd2=db->Prepare("UPDATE tblMessage SET ReplyBoardID=? WHERE ReplyBoardID=?;");\r
853         SQLite3DB::Statement upd3=db->Prepare("UPDATE tblMessageBoard SET BoardID=? WHERE BoardID=?;");\r
854 \r
855         st.Step();\r
856         while(st.RowReturned())\r
857         {\r
858                 int boardid=0;\r
859                 int newboardid=0;\r
860                 std::string name="";\r
861                 std::string lowername="";\r
862 \r
863                 st.ResultInt(0,boardid);\r
864                 st.ResultText(1,name);\r
865 \r
866                 lowername=name;\r
867                 StringFunctions::LowerCase(lowername,lowername);\r
868        \r
869                 if(name!=lowername)\r
870                 {\r
871                         st2.Bind(0,lowername);\r
872                         st2.Step();\r
873 \r
874                         if(st2.RowReturned())\r
875                         {\r
876                                 st2.ResultInt(0,newboardid);\r
877 \r
878                                 upd2.Bind(0,newboardid);\r
879                                 upd2.Bind(1,boardid);\r
880                                 upd2.Step();\r
881                                 upd2.Reset();\r
882 \r
883                                 upd3.Bind(0,newboardid);\r
884                                 upd3.Bind(1,boardid);\r
885                                 upd3.Step();\r
886                                 upd3.Reset();\r
887 \r
888                                 del.Bind(0,boardid);\r
889                                 del.Step();\r
890                                 del.Reset();\r
891                         }\r
892                         else\r
893                         {\r
894                                 upd.Bind(0,lowername);\r
895                                 upd.Bind(1,boardid);\r
896                                 upd.Step();\r
897                                 upd.Reset();\r
898                         }\r
899 \r
900                         st2.Reset();\r
901                 }\r
902        \r
903                 st.Step();\r
904         }\r
905 \r
906 }\r