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