a3c811121ea2168cfa0f29159537870950fe75f1
[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 \r
11 #ifdef _WIN32\r
12         #include <winsock2.h>\r
13 #endif\r
14 \r
15 #ifdef XMEM\r
16         #include <xmem.h>\r
17 #endif\r
18 \r
19 void SetupDB()\r
20 {\r
21 \r
22         DateTime date;\r
23         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
24 \r
25         db->Open("fms.db3");\r
26         db->SetBusyTimeout(10000);              // set timeout to 10 seconds\r
27         db->Execute("VACUUM;");\r
28         \r
29         // TODO remove this - temp fix for problem in 0.1.8\r
30         db->Execute("DELETE FROM tblMessageBoard WHERE MessageID NOT IN (SELECT MessageID FROM tblMessage);");\r
31 \r
32         db->Execute("CREATE TABLE IF NOT EXISTS tblDBVersion(\\r
33                                 Major                           INTEGER,\\r
34                                 Minor                           INTEGER\\r
35                                 );");\r
36 \r
37         SQLite3DB::Statement st=db->Prepare("SELECT Major,Minor FROM tblDBVersion;");\r
38         st.Step();\r
39         if(st.RowReturned())\r
40         {\r
41                 int major;\r
42                 int minor;\r
43                 st.ResultInt(0,major);\r
44                 st.ResultInt(1,minor);\r
45         }\r
46         else\r
47         {\r
48                 db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,0);");\r
49         }\r
50 \r
51         db->Execute("CREATE TABLE IF NOT EXISTS tblOption(\\r
52                                 Option                          TEXT UNIQUE,\\r
53                                 OptionValue                     TEXT NOT NULL,\\r
54                                 OptionDescription       TEXT\\r
55                                 );");\r
56 \r
57         db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\\r
58                                 LocalIdentityID                 INTEGER PRIMARY KEY,\\r
59                                 Name                                    TEXT,\\r
60                                 PublicKey                               TEXT,\\r
61                                 PrivateKey                              TEXT,\\r
62                                 SingleUse                               BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
63                                 PublishTrustList                BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
64                                 PublishBoardList                BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
65                                 InsertingIdentity               BOOL CHECK(InsertingIdentity IN('true','false')) DEFAULT 'false',\\r
66                                 LastInsertedIdentity    DATETIME,\\r
67                                 InsertingPuzzle                 BOOL CHECK(InsertingPuzzle IN('true','false')) DEFAULT 'false',\\r
68                                 LastInsertedPuzzle              DATETIME,\\r
69                                 InsertingTrustList              BOOL CHECK(InsertingTrustList IN('true','false')) DEFAULT 'false',\\r
70                                 LastInsertedTrustList   DATETIME,\\r
71                                 InsertingBoardList              BOOL CHECK(InsertingBoardList IN('true','false')) DEFAULT 'false',\\r
72                                 LastInsertedBoardList   DATETIME,\\r
73                                 InsertingMessageList    BOOL CHECK(InsertingMessageList IN('true','false')) DEFAULT 'false',\\r
74                                 LastInsertedMessageList DATETIME\\r
75                                 );");\r
76 \r
77         db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentityInserts(\\r
78                                 LocalIdentityID         INTEGER,\\r
79                                 Day                                     DATE,\\r
80                                 InsertIndex                     INTEGER\\r
81                                 );");\r
82 \r
83         db->Execute("CREATE TABLE IF NOT EXISTS tblTrustListInserts(\\r
84                                 LocalIdentityID         INTEGER,\\r
85                                 Day                                     DATE,\\r
86                                 InsertIndex                     INTEGER\\r
87                                 );");\r
88 \r
89         db->Execute("CREATE TABLE IF NOT EXISTS tblTrustListRequests(\\r
90                                 IdentityID                      INTEGER,\\r
91                                 Day                                     DATE,\\r
92                                 RequestIndex            INTEGER,\\r
93                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
94                                 );");\r
95 \r
96         db->Execute("CREATE TABLE IF NOT EXISTS tblIntroductionPuzzleInserts(\\r
97                                 UUID                            TEXT UNIQUE,\\r
98                                 LocalIdentityID         INTEGER,\\r
99                                 Day                                     DATE,\\r
100                                 InsertIndex                     INTEGER,\\r
101                                 Type                            TEXT,\\r
102                                 MimeType                        TEXT,\\r
103                                 PuzzleData                      TEXT,\\r
104                                 PuzzleSolution          TEXT,\\r
105                                 FoundSolution           BOOL CHECK(FoundSolution IN('true','false')) DEFAULT 'false'\\r
106                                 );");\r
107 \r
108         db->Execute("CREATE TABLE IF NOT EXISTS tblIdentity(\\r
109                                 IdentityID                      INTEGER PRIMARY KEY,\\r
110                                 PublicKey                       TEXT UNIQUE,\\r
111                                 Name                            TEXT,\\r
112                                 SingleUse                       BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\\r
113                                 PublishTrustList        BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\\r
114                                 PublishBoardList        BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\\r
115                                 DateAdded                       DATETIME,\\r
116                                 LastSeen                        DATETIME,\\r
117                                 LocalMessageTrust       INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT 50,\\r
118                                 PeerMessageTrust        INTEGER CHECK(PeerMessageTrust BETWEEN 0 AND 100) DEFAULT 50,\\r
119                                 LocalTrustListTrust     INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT 50,\\r
120                                 PeerTrustListTrust      INTEGER CHECK(PeerTrustListTrust BETWEEN 0 AND 100) DEFAULT 50\\r
121                                 );");\r
122 \r
123         db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityRequests(\\r
124                                 IdentityID                      INTEGER,\\r
125                                 Day                                     DATE,\\r
126                                 RequestIndex            INTEGER,\\r
127                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
128                                 );");\r
129 \r
130         db->Execute("CREATE TABLE IF NOT EXISTS tblIntroductionPuzzleRequests(\\r
131                                 IdentityID                      INTEGER,\\r
132                                 Day                                     DATE,\\r
133                                 RequestIndex            INTEGER,\\r
134                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false',\\r
135                                 UUID                            TEXT UNIQUE,\\r
136                                 Type                            TEXT,\\r
137                                 MimeType                        TEXT,\\r
138                                 PuzzleData                      TEXT\\r
139                                 );");\r
140 \r
141         db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityIntroductionInserts(\\r
142                                 LocalIdentityID         INTEGER,\\r
143                                 Day                                     DATE,\\r
144                                 UUID                            TEXT UNIQUE,\\r
145                                 Solution                        TEXT,\\r
146                                 Inserted                        BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
147                                 );");\r
148 \r
149         db->Execute("CREATE TABLE IF NOT EXISTS tblPeerTrust(\\r
150                                 IdentityID                      INTEGER,\\r
151                                 TargetIdentityID        INTEGER,\\r
152                                 MessageTrust            INTEGER CHECK(MessageTrust BETWEEN 0 AND 100),\\r
153                                 TrustListTrust          INTEGER CHECK(TrustListTrust BETWEEN 0 AND 100)\\r
154                                 );");\r
155 \r
156         db->Execute("CREATE TABLE IF NOT EXISTS tblBoard(\\r
157                                 BoardID                         INTEGER PRIMARY KEY,\\r
158                                 BoardName                       TEXT UNIQUE,\\r
159                                 BoardDescription        TEXT,\\r
160                                 DateAdded                       DATETIME\\r
161                                 );");\r
162 \r
163         db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('fms','Freenet Message System','2007-12-01');");\r
164         db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('freenet','Discussion about Freenet','2007-12-01');");\r
165         db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('public','Public discussion','2007-12-01');");\r
166         db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('test','Test board','2007-12-01');");\r
167 \r
168         db->Execute("CREATE TABLE IF NOT EXISTS tblMessage(\\r
169                                 MessageID                       INTEGER PRIMARY KEY,\\r
170                                 IdentityID                      INTEGER,\\r
171                                 FromName                        TEXT,\\r
172                                 MessageDate                     DATE,\\r
173                                 MessageTime                     TIME,\\r
174                                 Subject                         TEXT,\\r
175                                 MessageUUID                     TEXT UNIQUE,\\r
176                                 ReplyBoardID            INTEGER,\\r
177                                 Body                            TEXT\\r
178                                 );");\r
179 \r
180         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageReplyTo(\\r
181                                 MessageID                       INTEGER,\\r
182                                 ReplyToMessageUUID      TEXT,\\r
183                                 ReplyOrder                      INTEGER\\r
184                                 );");\r
185 \r
186         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageBoard(\\r
187                                 MessageID                       INTEGER,\\r
188                                 BoardID                         INTEGER\\r
189                                 );");\r
190 \r
191         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageListRequests(\\r
192                                 IdentityID                      INTEGER,\\r
193                                 Day                                     DATE,\\r
194                                 RequestIndex            INTEGER,\\r
195                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
196                                 );");\r
197 \r
198         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageRequests(\\r
199                                 IdentityID                      INTEGER,\\r
200                                 Day                                     DATE,\\r
201                                 RequestIndex            INTEGER,\\r
202                                 FromMessageList         BOOL CHECK(FromMessageList IN('true','false')) DEFAULT 'false',\\r
203                                 Found                           BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\\r
204                                 );");\r
205 \r
206         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageInserts(\\r
207                                 LocalIdentityID         INTEGER,\\r
208                                 Day                                     DATE,\\r
209                                 InsertIndex                     INTEGER,\\r
210                                 MessageUUID                     TEXT UNIQUE,\\r
211                                 MessageXML                      TEXT,\\r
212                                 Inserted                        BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
213                                 );");\r
214 \r
215         db->Execute("CREATE TABLE IF NOT EXISTS tblMessageListInserts(\\r
216                                 LocalIdentityID         INTEGER,\\r
217                                 Day                                     DATE,\\r
218                                 InsertIndex                     INTEGER,\\r
219                                 Inserted                        BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
220                                 );");\r
221 \r
222         db->Execute("CREATE TABLE IF NOT EXISTS tblAdministrationBoard(\\r
223                                 BoardID                                         INTEGER UNIQUE,\\r
224                                 ModifyLocalMessageTrust         INTEGER,\\r
225                                 ModifyLocalTrustListTrust       INTEGER\\r
226                                 );");\r
227 \r
228         // MessageInserter will insert a record into this temp table which the MessageListInserter will query for and insert a MessageList when needed\r
229         db->Execute("CREATE TEMPORARY TABLE IF NOT EXISTS tmpMessageListInsert(\\r
230                                 LocalIdentityID         INTEGER,\\r
231                                 Date                            DATETIME\\r
232                                 );");\r
233 \r
234         // low / high / message count for each board\r
235         db->Execute("CREATE VIEW IF NOT EXISTS vwBoardStats AS \\r
236                                 SELECT tblBoard.BoardID AS 'BoardID', IFNULL(MIN(MessageID),0) AS 'LowMessageID', IFNULL(MAX(MessageID),0) AS 'HighMessageID', COUNT(MessageID) AS 'MessageCount' \\r
237                                 FROM tblBoard LEFT JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID \\r
238                                 WHERE MessageID>=0 OR MessageID IS NULL \\r
239                                 GROUP BY tblBoard.BoardID;");\r
240 \r
241         // calculates peer trust\r
242         db->Execute("CREATE VIEW IF NOT EXISTS vwCalculatedPeerTrust AS \\r
243                                 SELECT TargetIdentityID, \\r
244                                 ROUND(SUM(MessageTrust*(LocalMessageTrust/100.0))/SUM(LocalMessageTrust/100.0),0) AS 'PeerMessageTrust', \\r
245                                 ROUND(SUM(TrustListTrust*(LocalTrustListTrust/100.0))/SUM(LocalTrustListTrust/100.0),0) AS 'PeerTrustListTrust' \\r
246                                 FROM tblPeerTrust INNER JOIN tblIdentity ON tblPeerTrust.IdentityID=tblIdentity.IdentityID \\r
247                                 WHERE LocalTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalTrustListTrust') \\r
248                                 AND ( PeerTrustListTrust IS NULL OR PeerTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerTrustListTrust') ) \\r
249                                 GROUP BY TargetIdentityID;");\r
250 \r
251         /*\r
252                 These peer trust calculations are too CPU intensive to be triggers - they were called every time a new trust list was processed\r
253                 All trust levels will now be recalculated every hour in the PeriodicDBMaintenance class\r
254         */\r
255         // drop existing triggers\r
256         db->Execute("DROP TRIGGER IF EXISTS trgDeleteOntblPeerTrust;");\r
257         db->Execute("DROP TRIGGER IF EXISTS trgInsertOntblPeerTrust;");\r
258         db->Execute("DROP TRIGGER IF EXISTS trgUpdateOntblPeerTrust;");\r
259         db->Execute("DROP TRIGGER IF EXISTS trgUpdateLocalTrustLevels;");\r
260 /*\r
261         // update PeerTrustLevel when deleting a record from tblPeerTrust\r
262         db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteOntblPeerTrust AFTER DELETE ON tblPeerTrust \\r
263                                 FOR EACH ROW \\r
264                                 BEGIN \\r
265                                         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
266                                 END;");\r
267 \r
268         // update PeerTrustLevel when inserting a record into tblPeerTrust\r
269         db->Execute("CREATE TRIGGER IF NOT EXISTS trgInsertOntblPeerTrust AFTER INSERT ON tblPeerTrust \\r
270                                 FOR EACH ROW \\r
271                                 BEGIN \\r
272                                         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
273                                 END;");\r
274 \r
275         // update PeerTrustLevel when updating a record in tblPeerTrust\r
276         db->Execute("CREATE TRIGGER IF NOT EXISTS trgUpdateOntblPeerTrust AFTER UPDATE ON tblPeerTrust \\r
277                                 FOR EACH ROW \\r
278                                 BEGIN \\r
279                                         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
280                                         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
281                                 END;");\r
282 \r
283         // 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
284         db->Execute("CREATE TRIGGER IF NOT EXISTS trgUpdateLocalTrustLevels AFTER UPDATE OF LocalMessageTrust,LocalTrustListTrust ON tblIdentity \\r
285                                 FOR EACH ROW \\r
286                                 BEGIN \\r
287                                         UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID);\\r
288                                 END;");\r
289 */\r
290 \r
291         db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteMessage AFTER DELETE ON tblMessage \\r
292                                 FOR EACH ROW \\r
293                                 BEGIN \\r
294                                         DELETE FROM tblMessageBoard WHERE tblMessageBoard.MessageID=old.MessageID;\\r
295                                         DELETE FROM tblMessageReplyTo WHERE tblMessageReplyTo.MessageID=old.MessageID;\\r
296                                 END;");\r
297 \r
298         db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteIdentity AFTER DELETE ON tblIdentity \\r
299                                 FOR EACH ROW \\r
300                                 BEGIN \\r
301                                         DELETE FROM tblIdentityRequests WHERE IdentityID=old.IdentityID;\\r
302                                         DELETE FROM tblIntroductionPuzzleRequests WHERE IdentityID=old.IdentityID;\\r
303                                         DELETE FROM tblMessageListRequests WHERE IdentityID=old.IdentityID;\\r
304                                         DELETE FROM tblMessageRequests WHERE IdentityID=old.IdentityID;\\r
305                                         DELETE FROM tblPeerTrust WHERE IdentityID=old.IdentityID;\\r
306                                         DELETE FROM tblTrustListRequests WHERE IdentityID=old.IdentityID;\\r
307                                 END;");\r
308 \r
309         db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteLocalIdentity AFTER DELETE ON tblLocalIdentity \\r
310                                 FOR EACH ROW \\r
311                                 BEGIN \\r
312                                         DELETE FROM tblIdentityIntroductionInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
313                                         DELETE FROM tblIntroductionPuzzleInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
314                                         DELETE FROM tblLocalIdentityInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
315                                         DELETE FROM tblMessageInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
316                                         DELETE FROM tblMessageListInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
317                                         DELETE FROM tblTrustListInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
318                                 END;");\r
319 \r
320         // delete introduction puzzles that were half-way inserted\r
321         db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day IS NULL AND InsertIndex IS NULL;");\r
322 \r
323         // delete stale introduction puzzles (2 or more days old)\r
324         date.SetToGMTime();\r
325         date.Add(0,0,0,-2);\r
326         db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day<='"+date.Format("%Y-%m-%d")+"';");\r
327         db->Execute("DELETE FROM tblIntroductionPuzzleRequests WHERE Day<='"+date.Format("%Y-%m-%d")+"';");\r
328 \r
329         // insert SomeDude's public key\r
330         date.SetToGMTime();\r
331         db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw,iXez4j3qCpd596TxXiJgZyTq9o-CElEuJxm~jNNZAuA,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');");\r
332 \r
333 }\r
334 \r
335 void SetupDefaultOptions()\r
336 {\r
337         // 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
338 \r
339         std::ostringstream tempstr;     // must set tempstr to "" between db inserts\r
340         SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
341         SQLite3DB::Statement st=db->Prepare("INSERT INTO tblOption(Option,OptionValue,OptionDescription) VALUES(?,?,?);");\r
342 \r
343         // LogLevel\r
344         tempstr.str("");\r
345         tempstr << LogFile::LOGLEVEL_DEBUG;\r
346         st.Bind(0,"LogLevel");\r
347         st.Bind(1,tempstr.str());\r
348         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
349         st.Step();\r
350         st.Reset();\r
351 \r
352         // NNTPListenPort\r
353         st.Bind(0,"NNTPListenPort");\r
354         st.Bind(1,"1119");\r
355         st.Bind(2,"The port that the NNTP service will listen for incoming connections.");\r
356         st.Step();\r
357         st.Reset();\r
358 \r
359         // NNTPBindAddresses\r
360         st.Bind(0,"NNTPBindAddresses");\r
361         st.Bind(1,"localhost");\r
362         st.Bind(2,"A comma separated list of valid IPv4 or IPv6 addresses/hostnames that the NNTP service will try to bind to.");\r
363         st.Step();\r
364         st.Reset();\r
365 \r
366         st.Bind(0,"NNTPAllowPost");\r
367         st.Bind(1,"true");\r
368         st.Bind(2,"Allow posting messages from NNTP.  Setting to false will make the newsgroups read only.");\r
369         st.Step();\r
370         st.Reset();\r
371 \r
372         // StartNNTP\r
373         st.Bind(0,"StartNNTP");\r
374         st.Bind(1,"true");\r
375         st.Bind(2,"Start NNTP server.");\r
376         st.Step();\r
377         st.Reset();\r
378 \r
379         st.Bind(0,"StartHTTP");\r
380         st.Bind(1,"true");\r
381         st.Bind(2,"Start HTTP server.");\r
382         st.Step();\r
383         st.Reset();\r
384 \r
385         st.Bind(0,"HTTPListenPort");\r
386         st.Bind(1,"8080");\r
387         st.Bind(2,"Port HTTP server will listen on.");\r
388         st.Step();\r
389         st.Reset();\r
390 \r
391         // StartFreenetUpdater\r
392         st.Bind(0,"StartFreenetUpdater");\r
393         st.Bind(1,"true");\r
394         st.Bind(2,"Start Freenet Updater thread.");\r
395         st.Step();\r
396         st.Reset();\r
397 \r
398         // FCPHost\r
399         st.Bind(0,"FCPHost");\r
400         st.Bind(1,"127.0.0.1");\r
401         st.Bind(2,"Host name or address of Freenet node.");\r
402         st.Step();\r
403         st.Reset();\r
404 \r
405         // FCPPort\r
406         st.Bind(0,"FCPPort");\r
407         st.Bind(1,"9481");\r
408         st.Bind(2,"The port that Freenet is listening for FCP connections on.");\r
409         st.Step();\r
410         st.Reset();\r
411 \r
412         st.Bind(0,"MessageBase");\r
413         st.Bind(1,"fms");\r
414         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
415         st.Step();\r
416         st.Reset();\r
417 \r
418         st.Bind(0,"MaxIdentityRequests");\r
419         st.Bind(1,"5");\r
420         st.Bind(2,"Maximum number of concurrent requests for new Identity xml files");\r
421         st.Step();\r
422         st.Reset();\r
423 \r
424         st.Bind(0,"MaxIdentityIntroductionRequests");\r
425         st.Bind(1,"5");\r
426         st.Bind(2,"Maximum number of concurrent identities requesting IdentityIntroduction xml files.  Each identity may have multiple requests pending.");\r
427         st.Step();\r
428         st.Reset();\r
429 \r
430         st.Bind(0,"MaxIntroductionPuzzleRequests");\r
431         st.Bind(1,"5");\r
432         st.Bind(2,"Maximum number of concurrent requests for new IntroductionPuzzle xml files");\r
433         st.Step();\r
434         st.Reset();\r
435 \r
436         st.Bind(0,"MaxTrustListRequests");\r
437         st.Bind(1,"5");\r
438         st.Bind(2,"Maximum number of concurrent requests for new Trust Lists");\r
439         st.Step();\r
440         st.Reset();\r
441 \r
442         st.Bind(0,"MaxMessageListRequests");\r
443         st.Bind(1,"5");\r
444         st.Bind(2,"Maximum number of concurrent requests for new Message Lists");\r
445         st.Step();\r
446         st.Reset();\r
447 \r
448         st.Bind(0,"MaxMessageRequests");\r
449         st.Bind(1,"20");\r
450         st.Bind(2,"Maximum number of concurrent requests for new Messages");\r
451         st.Step();\r
452         st.Reset();\r
453 \r
454         st.Bind(0,"MinLocalMessageTrust");\r
455         st.Bind(1,"50");\r
456         st.Bind(2,"Specifies a local message trust level that a peer must have before its messages will be downloaded.");\r
457         st.Step();\r
458         st.Reset();\r
459 \r
460         st.Bind(0,"MinPeerMessageTrust");\r
461         st.Bind(1,"30");\r
462         st.Bind(2,"Specifies a peer message trust level that a peer must have before its messages will be downloaded.");\r
463         st.Step();\r
464         st.Reset();\r
465 \r
466         st.Bind(0,"MinLocalTrustListTrust");\r
467         st.Bind(1,"51");\r
468         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
469         st.Step();\r
470         st.Reset();\r
471 \r
472         st.Bind(0,"MinPeerTrustListTrust");\r
473         st.Bind(1,"30");\r
474         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
475         st.Step();\r
476         st.Reset();\r
477 \r
478         st.Bind(0,"MessageDownloadMaxDaysBackward");\r
479         st.Bind(1,"5");\r
480         st.Bind(2,"The maximum number of days backward that messages will be downloaded from each identity");\r
481         st.Step();\r
482         st.Reset();\r
483 \r
484         st.Bind(0,"MessageListDaysBackward");\r
485         st.Bind(1,"5");\r
486         st.Bind(2,"The number of days backward that messages you have inserted will appear in your MessageLists");\r
487         st.Step();\r
488         st.Reset();\r
489 \r
490 }\r
491 \r
492 void SetupLogFile()\r
493 {\r
494         DateTime date;\r
495         std::string configval;\r
496         int loglevel;\r
497 \r
498         date.SetToGMTime();\r
499 \r
500         LogFile::Instance()->SetFileName("fms-"+date.Format("%Y-%m-%d")+".log");\r
501         LogFile::Instance()->OpenFile();\r
502         LogFile::Instance()->SetWriteNewLine(true);\r
503         LogFile::Instance()->SetWriteDate(true);\r
504         LogFile::Instance()->SetWriteLogLevel(true);\r
505 \r
506         if(Option::Instance()->Get("LogLevel",configval)==false)\r
507         {\r
508                 configval="4";\r
509                 Option::Instance()->Set("LogLevel",configval);\r
510         }\r
511         if(StringFunctions::Convert(configval,loglevel)==false)\r
512         {\r
513                 loglevel=LogFile::LOGLEVEL_DEBUG;\r
514                 Option::Instance()->Set("LogLevel",loglevel);\r
515         }\r
516         LogFile::Instance()->SetLogLevel((LogFile::LogLevel)loglevel);\r
517 }\r
518 \r
519 void SetupNetwork()\r
520 {\r
521 #ifdef _WIN32\r
522         WSAData wsadata;\r
523         WSAStartup(MAKEWORD(2,2),&wsadata);\r
524 #endif\r
525 }\r
526 \r
527 void ShutdownNetwork()\r
528 {\r
529 #ifdef _WIN32\r
530         WSACleanup();\r
531 #endif\r
532 }\r
533 \r
534 void ShutdownThreads(std::vector<PThread::Thread *> &threads)\r
535 {\r
536         std::vector<PThread::Thread *>::iterator i;\r
537         for(i=threads.begin(); i!=threads.end(); i++)\r
538         {\r
539 /*              if((*i)->wait(1)==false)\r
540                 {\r
541                         try\r
542                         {\r
543                                 (*i)->interrupt();\r
544                         }\r
545                         catch(...)\r
546                         {\r
547                         }\r
548                 }\r
549                 */\r
550                 (*i)->Cancel();\r
551         }\r
552 \r
553         for(i=threads.begin(); i!=threads.end(); i++)\r
554         {\r
555                 LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"ShutdownThreads waiting for thread to exit.");\r
556                 //(*i)->wait();\r
557                 (*i)->Join();\r
558                 delete (*i);\r
559         }\r
560 \r
561         threads.clear();\r
562 \r
563 }\r
564 \r
565 void StartThreads(std::vector<PThread::Thread *> &threads)\r
566 {\r
567         std::string startfreenet;\r
568         std::string startnntp;\r
569         std::string starthttp;\r
570 \r
571         if(Option::Instance()->Get("StartFreenetUpdater",startfreenet)==false)\r
572         {\r
573                 startfreenet="true";\r
574                 Option::Instance()->Set("StartFreenetUpdater","true");\r
575         }\r
576 \r
577         if(Option::Instance()->Get("StartNNTP",startnntp)==false)\r
578         {\r
579                 startnntp="true";\r
580                 Option::Instance()->Set("StartNNTP","true");\r
581         }\r
582 \r
583         if(Option::Instance()->Get("StartHTTP",starthttp)==false)\r
584         {\r
585                 starthttp="true";\r
586                 Option::Instance()->Set("StartHTTP","true");\r
587         }\r
588 \r
589         if(startfreenet=="true")\r
590         {\r
591                 PThread::Thread *t=new PThread::Thread(new FreenetMasterThread());\r
592                 threads.push_back(t);\r
593         }\r
594 \r
595         if(startnntp=="true")\r
596         {\r
597                 PThread::Thread *t=new PThread::Thread(new NNTPListener());\r
598                 threads.push_back(t);\r
599         }\r
600 \r
601         if(starthttp=="true")\r
602         {\r
603                 PThread::Thread *t=new PThread::Thread(new HTTPThread());\r
604                 threads.push_back(t);\r
605         }\r
606 \r
607 }\r