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
13 #include <winsock2.h>
\r
20 bool wantshutdown=false;
\r
26 SQLite3DB::DB *db=SQLite3DB::DB::Instance();
\r
28 db->Open("fms.db3");
\r
29 db->SetBusyTimeout(10000); // set timeout to 10 seconds
\r
30 db->Execute("VACUUM;");
\r
32 // TODO remove this - temp fix for problem in 0.1.8
\r
33 db->Execute("DELETE FROM tblMessageBoard WHERE MessageID NOT IN (SELECT MessageID FROM tblMessage);");
\r
35 db->Execute("CREATE TABLE IF NOT EXISTS tblDBVersion(\
\r
40 SQLite3DB::Statement st=db->Prepare("SELECT Major,Minor FROM tblDBVersion;");
\r
42 if(st.RowReturned())
\r
46 st.ResultInt(0,major);
\r
47 st.ResultInt(1,minor);
\r
49 if(major==1 && minor==0)
\r
51 ConvertDB0100To0101();
\r
58 db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,1);");
\r
61 db->Execute("UPDATE tblDBVersion SET Major=1, Minor=2;");
\r
63 db->Execute("CREATE TABLE IF NOT EXISTS tblOption(\
\r
64 Option TEXT UNIQUE,\
\r
65 OptionValue TEXT NOT NULL,\
\r
66 OptionDescription TEXT\
\r
69 db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\
\r
70 LocalIdentityID INTEGER PRIMARY KEY,\
\r
72 PublicKey TEXT UNIQUE,\
\r
73 PrivateKey TEXT UNIQUE,\
\r
74 SingleUse BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\
\r
75 PublishTrustList BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\
\r
76 PublishBoardList BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\
\r
77 InsertingIdentity BOOL CHECK(InsertingIdentity IN('true','false')) DEFAULT 'false',\
\r
78 LastInsertedIdentity DATETIME,\
\r
79 InsertingPuzzle BOOL CHECK(InsertingPuzzle IN('true','false')) DEFAULT 'false',\
\r
80 LastInsertedPuzzle DATETIME,\
\r
81 InsertingTrustList BOOL CHECK(InsertingTrustList IN('true','false')) DEFAULT 'false',\
\r
82 LastInsertedTrustList DATETIME,\
\r
83 InsertingBoardList BOOL CHECK(InsertingBoardList IN('true','false')) DEFAULT 'false',\
\r
84 LastInsertedBoardList DATETIME,\
\r
85 InsertingMessageList BOOL CHECK(InsertingMessageList IN('true','false')) DEFAULT 'false',\
\r
86 LastInsertedMessageList DATETIME\
\r
89 db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentityInserts(\
\r
90 LocalIdentityID INTEGER,\
\r
92 InsertIndex INTEGER\
\r
95 db->Execute("CREATE TABLE IF NOT EXISTS tblTrustListInserts(\
\r
96 LocalIdentityID INTEGER,\
\r
98 InsertIndex INTEGER\
\r
101 db->Execute("CREATE TABLE IF NOT EXISTS tblTrustListRequests(\
\r
102 IdentityID INTEGER,\
\r
104 RequestIndex INTEGER,\
\r
105 Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\
\r
108 db->Execute("CREATE TABLE IF NOT EXISTS tblIntroductionPuzzleInserts(\
\r
110 LocalIdentityID INTEGER,\
\r
112 InsertIndex INTEGER,\
\r
116 PuzzleSolution TEXT,\
\r
117 FoundSolution BOOL CHECK(FoundSolution IN('true','false')) DEFAULT 'false'\
\r
120 db->Execute("CREATE TABLE IF NOT EXISTS tblIdentity(\
\r
121 IdentityID INTEGER PRIMARY KEY,\
\r
122 PublicKey TEXT UNIQUE,\
\r
124 SingleUse BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\
\r
125 PublishTrustList BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\
\r
126 PublishBoardList BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\
\r
127 DateAdded DATETIME,\
\r
128 LastSeen DATETIME,\
\r
129 LocalMessageTrust INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT 50,\
\r
130 PeerMessageTrust INTEGER CHECK(PeerMessageTrust BETWEEN 0 AND 100) DEFAULT 50,\
\r
131 LocalTrustListTrust INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT 50,\
\r
132 PeerTrustListTrust INTEGER CHECK(PeerTrustListTrust BETWEEN 0 AND 100) DEFAULT 50\
\r
135 db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityRequests(\
\r
136 IdentityID INTEGER,\
\r
138 RequestIndex INTEGER,\
\r
139 Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\
\r
142 db->Execute("CREATE TABLE IF NOT EXISTS tblIntroductionPuzzleRequests(\
\r
143 IdentityID INTEGER,\
\r
145 RequestIndex INTEGER,\
\r
146 Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false',\
\r
153 db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityIntroductionInserts(\
\r
154 LocalIdentityID INTEGER,\
\r
158 Inserted BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\
\r
161 db->Execute("CREATE TABLE IF NOT EXISTS tblPeerTrust(\
\r
162 IdentityID INTEGER,\
\r
163 TargetIdentityID INTEGER,\
\r
164 MessageTrust INTEGER CHECK(MessageTrust BETWEEN 0 AND 100),\
\r
165 TrustListTrust INTEGER CHECK(TrustListTrust BETWEEN 0 AND 100)\
\r
168 db->Execute("CREATE TABLE IF NOT EXISTS tblBoard(\
\r
169 BoardID INTEGER PRIMARY KEY,\
\r
170 BoardName TEXT UNIQUE,\
\r
171 BoardDescription TEXT,\
\r
172 DateAdded DATETIME\
\r
175 db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('fms','Freenet Message System','2007-12-01 12:00:00');");
\r
176 db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('freenet','Discussion about Freenet','2007-12-01 12:00:00');");
\r
177 db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('public','Public discussion','2007-12-01 12:00:00');");
\r
178 db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('test','Test board','2007-12-01 12:00:00');");
\r
180 db->Execute("CREATE TABLE IF NOT EXISTS tblMessage(\
\r
181 MessageID INTEGER PRIMARY KEY,\
\r
182 IdentityID INTEGER,\
\r
187 MessageUUID TEXT UNIQUE,\
\r
188 ReplyBoardID INTEGER,\
\r
192 db->Execute("CREATE TABLE IF NOT EXISTS tblMessageReplyTo(\
\r
193 MessageID INTEGER,\
\r
194 ReplyToMessageUUID TEXT,\
\r
195 ReplyOrder INTEGER\
\r
198 db->Execute("CREATE TABLE IF NOT EXISTS tblMessageBoard(\
\r
199 MessageID INTEGER,\
\r
203 db->Execute("CREATE TABLE IF NOT EXISTS tblMessageListRequests(\
\r
204 IdentityID INTEGER,\
\r
206 RequestIndex INTEGER,\
\r
207 Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\
\r
210 db->Execute("CREATE TABLE IF NOT EXISTS tblMessageRequests(\
\r
211 IdentityID INTEGER,\
\r
213 RequestIndex INTEGER,\
\r
214 FromMessageList BOOL CHECK(FromMessageList IN('true','false')) DEFAULT 'false',\
\r
215 Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\
\r
218 db->Execute("CREATE TABLE IF NOT EXISTS tblMessageInserts(\
\r
219 LocalIdentityID INTEGER,\
\r
221 InsertIndex INTEGER,\
\r
222 MessageUUID TEXT UNIQUE,\
\r
224 Inserted BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\
\r
227 db->Execute("CREATE TABLE IF NOT EXISTS tblMessageListInserts(\
\r
228 LocalIdentityID INTEGER,\
\r
230 InsertIndex INTEGER,\
\r
231 Inserted BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\
\r
234 db->Execute("CREATE TABLE IF NOT EXISTS tblAdministrationBoard(\
\r
235 BoardID INTEGER UNIQUE,\
\r
236 ModifyLocalMessageTrust INTEGER,\
\r
237 ModifyLocalTrustListTrust INTEGER\
\r
240 db->Execute("CREATE TABLE IF NOT EXISTS tblBoardListInserts(\
\r
241 LocalIdentityID INTEGER,\
\r
243 InsertIndex INTEGER,\
\r
244 Inserted BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\
\r
247 db->Execute("CREATE TABLE IF NOT EXISTS tblBoardListRequests(\
\r
248 IdentityID INTEGER,\
\r
250 RequestIndex INTEGER,\
\r
251 Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\
\r
254 // MessageInserter will insert a record into this temp table which the MessageListInserter will query for and insert a MessageList when needed
\r
255 db->Execute("CREATE TEMPORARY TABLE IF NOT EXISTS tmpMessageListInsert(\
\r
256 LocalIdentityID INTEGER,\
\r
260 // low / high / message count for each board
\r
261 db->Execute("CREATE VIEW IF NOT EXISTS vwBoardStats AS \
\r
262 SELECT tblBoard.BoardID AS 'BoardID', IFNULL(MIN(MessageID),0) AS 'LowMessageID', IFNULL(MAX(MessageID),0) AS 'HighMessageID', COUNT(MessageID) AS 'MessageCount' \
\r
263 FROM tblBoard LEFT JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID \
\r
264 WHERE MessageID>=0 OR MessageID IS NULL \
\r
265 GROUP BY tblBoard.BoardID;");
\r
267 // calculates peer trust
\r
268 db->Execute("CREATE VIEW IF NOT EXISTS vwCalculatedPeerTrust AS \
\r
269 SELECT TargetIdentityID, \
\r
270 ROUND(SUM(MessageTrust*(LocalMessageTrust/100.0))/SUM(LocalMessageTrust/100.0),0) AS 'PeerMessageTrust', \
\r
271 ROUND(SUM(TrustListTrust*(LocalTrustListTrust/100.0))/SUM(LocalTrustListTrust/100.0),0) AS 'PeerTrustListTrust' \
\r
272 FROM tblPeerTrust INNER JOIN tblIdentity ON tblPeerTrust.IdentityID=tblIdentity.IdentityID \
\r
273 WHERE LocalTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalTrustListTrust') \
\r
274 AND ( PeerTrustListTrust IS NULL OR PeerTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerTrustListTrust') ) \
\r
275 GROUP BY TargetIdentityID;");
\r
278 These peer trust calculations are too CPU intensive to be triggers - they were called every time a new trust list was processed
\r
279 All trust levels will now be recalculated every hour in the PeriodicDBMaintenance class
\r
281 // drop existing triggers
\r
282 db->Execute("DROP TRIGGER IF EXISTS trgDeleteOntblPeerTrust;");
\r
283 db->Execute("DROP TRIGGER IF EXISTS trgInsertOntblPeerTrust;");
\r
284 db->Execute("DROP TRIGGER IF EXISTS trgUpdateOntblPeerTrust;");
\r
285 db->Execute("DROP TRIGGER IF EXISTS trgUpdateLocalTrustLevels;");
\r
287 // update PeerTrustLevel when deleting a record from tblPeerTrust
\r
288 db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteOntblPeerTrust AFTER DELETE ON tblPeerTrust \
\r
291 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
294 // update PeerTrustLevel when inserting a record into tblPeerTrust
\r
295 db->Execute("CREATE TRIGGER IF NOT EXISTS trgInsertOntblPeerTrust AFTER INSERT ON tblPeerTrust \
\r
298 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
301 // update PeerTrustLevel when updating a record in tblPeerTrust
\r
302 db->Execute("CREATE TRIGGER IF NOT EXISTS trgUpdateOntblPeerTrust AFTER UPDATE ON tblPeerTrust \
\r
305 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
306 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
309 // 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
310 db->Execute("CREATE TRIGGER IF NOT EXISTS trgUpdateLocalTrustLevels AFTER UPDATE OF LocalMessageTrust,LocalTrustListTrust ON tblIdentity \
\r
313 UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID);\
\r
317 db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteMessage AFTER DELETE ON tblMessage \
\r
320 DELETE FROM tblMessageBoard WHERE tblMessageBoard.MessageID=old.MessageID;\
\r
321 DELETE FROM tblMessageReplyTo WHERE tblMessageReplyTo.MessageID=old.MessageID;\
\r
324 db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteIdentity AFTER DELETE ON tblIdentity \
\r
327 DELETE FROM tblIdentityRequests WHERE IdentityID=old.IdentityID;\
\r
328 DELETE FROM tblIntroductionPuzzleRequests WHERE IdentityID=old.IdentityID;\
\r
329 DELETE FROM tblMessageListRequests WHERE IdentityID=old.IdentityID;\
\r
330 DELETE FROM tblMessageRequests WHERE IdentityID=old.IdentityID;\
\r
331 DELETE FROM tblPeerTrust WHERE IdentityID=old.IdentityID;\
\r
332 DELETE FROM tblTrustListRequests WHERE IdentityID=old.IdentityID;\
\r
335 db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteLocalIdentity AFTER DELETE ON tblLocalIdentity \
\r
338 DELETE FROM tblIdentityIntroductionInserts WHERE LocalIdentityID=old.LocalIdentityID;\
\r
339 DELETE FROM tblIntroductionPuzzleInserts WHERE LocalIdentityID=old.LocalIdentityID;\
\r
340 DELETE FROM tblLocalIdentityInserts WHERE LocalIdentityID=old.LocalIdentityID;\
\r
341 DELETE FROM tblMessageInserts WHERE LocalIdentityID=old.LocalIdentityID;\
\r
342 DELETE FROM tblMessageListInserts WHERE LocalIdentityID=old.LocalIdentityID;\
\r
343 DELETE FROM tblTrustListInserts WHERE LocalIdentityID=old.LocalIdentityID;\
\r
346 db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteBoard AFTER DELETE ON tblBoard \
\r
349 DELETE FROM tblMessageBoard WHERE BoardID=old.BoardID;\
\r
352 // delete introduction puzzles that were half-way inserted
\r
353 db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day IS NULL AND InsertIndex IS NULL;");
\r
355 // delete stale introduction puzzles (2 or more days old)
\r
356 date.SetToGMTime();
\r
357 date.Add(0,0,0,-2);
\r
358 db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day<='"+date.Format("%Y-%m-%d")+"';");
\r
359 db->Execute("DELETE FROM tblIntroductionPuzzleRequests WHERE Day<='"+date.Format("%Y-%m-%d")+"';");
\r
361 date.SetToGMTime();
\r
362 // insert SomeDude's public key
\r
363 db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw,iXez4j3qCpd596TxXiJgZyTq9o-CElEuJxm~jNNZAuA,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');");
\r
364 // insert Shadow Panther's public key
\r
365 db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@~mimyB1kmH4f7Cgsd2wM2Qv2NxrZHRMM6IY8~7EWRVQ,fxTKkR0TYhgMYb-vEGAv55sMOxCGD2xhE4ZxWHxdPz4,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');");
\r
366 // insert garfield's public key
\r
367 db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@T8l1IEGU4-PoASFzgc2GYhIgRzUvZsKdoQWeuLHuTmM,QLxAPfkGis8l5NafNpSCdbxzXhBlu9WL8svcqJw9Mpo,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');");
\r
371 void ConvertDB0100To0101()
\r
373 // added unique constraint to public and private key
\r
374 SQLite3DB::DB *db=SQLite3DB::DB::Instance();
\r
375 db->Execute("CREATE TEMPORARY TABLE tblLocalIdentityTemp AS SELECT * FROM tblLocalIdentity;");
\r
376 db->Execute("DROP TABLE IF EXISTS tblLocalIdentity;");
\r
377 db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\
\r
378 LocalIdentityID INTEGER PRIMARY KEY,\
\r
380 PublicKey TEXT UNIQUE,\
\r
381 PrivateKey TEXT UNIQUE,\
\r
382 SingleUse BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\
\r
383 PublishTrustList BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\
\r
384 PublishBoardList BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\
\r
385 InsertingIdentity BOOL CHECK(InsertingIdentity IN('true','false')) DEFAULT 'false',\
\r
386 LastInsertedIdentity DATETIME,\
\r
387 InsertingPuzzle BOOL CHECK(InsertingPuzzle IN('true','false')) DEFAULT 'false',\
\r
388 LastInsertedPuzzle DATETIME,\
\r
389 InsertingTrustList BOOL CHECK(InsertingTrustList IN('true','false')) DEFAULT 'false',\
\r
390 LastInsertedTrustList DATETIME,\
\r
391 InsertingBoardList BOOL CHECK(InsertingBoardList IN('true','false')) DEFAULT 'false',\
\r
392 LastInsertedBoardList DATETIME,\
\r
393 InsertingMessageList BOOL CHECK(InsertingMessageList IN('true','false')) DEFAULT 'false',\
\r
394 LastInsertedMessageList DATETIME\
\r
396 db->Execute("INSERT INTO tblLocalIdentity SELECT * FROM tblLocalIdentityTemp;");
\r
397 db->Execute("DROP TABLE IF EXISTS tblLocalIdentityTemp;");
\r
398 db->Execute("UPDATE tblDBVersion SET Major=1, Minor=1;");
\r
401 void SetupDefaultOptions()
\r
403 // 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
405 std::ostringstream tempstr; // must set tempstr to "" between db inserts
\r
406 SQLite3DB::DB *db=SQLite3DB::DB::Instance();
\r
407 SQLite3DB::Statement st=db->Prepare("INSERT INTO tblOption(Option,OptionValue,OptionDescription) VALUES(?,?,?);");
\r
411 tempstr << LogFile::LOGLEVEL_DEBUG;
\r
412 st.Bind(0,"LogLevel");
\r
413 st.Bind(1,tempstr.str());
\r
414 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
419 st.Bind(0,"NNTPListenPort");
\r
421 st.Bind(2,"The port that the NNTP service will listen for incoming connections.");
\r
425 // NNTPBindAddresses
\r
426 st.Bind(0,"NNTPBindAddresses");
\r
427 st.Bind(1,"localhost");
\r
428 st.Bind(2,"A comma separated list of valid IPv4 or IPv6 addresses/hostnames that the NNTP service will try to bind to.");
\r
432 st.Bind(0,"NNTPAllowPost");
\r
434 st.Bind(2,"Allow posting messages from NNTP. Setting to false will make the newsgroups read only.");
\r
439 st.Bind(0,"StartNNTP");
\r
441 st.Bind(2,"Start NNTP server.");
\r
445 st.Bind(0,"StartHTTP");
\r
447 st.Bind(2,"Start HTTP server.");
\r
451 st.Bind(0,"HTTPListenPort");
\r
453 st.Bind(2,"Port HTTP server will listen on.");
\r
457 // StartFreenetUpdater
\r
458 st.Bind(0,"StartFreenetUpdater");
\r
460 st.Bind(2,"Start Freenet Updater thread.");
\r
465 st.Bind(0,"FCPHost");
\r
466 st.Bind(1,"127.0.0.1");
\r
467 st.Bind(2,"Host name or address of Freenet node.");
\r
472 st.Bind(0,"FCPPort");
\r
474 st.Bind(2,"The port that Freenet is listening for FCP connections on.");
\r
478 st.Bind(0,"MessageBase");
\r
480 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
484 st.Bind(0,"MaxIdentityRequests");
\r
486 st.Bind(2,"Maximum number of concurrent requests for new Identity xml files");
\r
490 st.Bind(0,"MaxIdentityIntroductionRequests");
\r
492 st.Bind(2,"Maximum number of concurrent identities requesting IdentityIntroduction xml files. Each identity may have multiple requests pending.");
\r
496 st.Bind(0,"MaxIntroductionPuzzleRequests");
\r
498 st.Bind(2,"Maximum number of concurrent requests for new IntroductionPuzzle xml files");
\r
502 st.Bind(0,"MaxTrustListRequests");
\r
504 st.Bind(2,"Maximum number of concurrent requests for new Trust Lists");
\r
508 st.Bind(0,"MaxMessageListRequests");
\r
510 st.Bind(2,"Maximum number of concurrent requests for new Message Lists");
\r
514 st.Bind(0,"MaxMessageRequests");
\r
516 st.Bind(2,"Maximum number of concurrent requests for new Messages");
\r
520 st.Bind(0,"MinLocalMessageTrust");
\r
522 st.Bind(2,"Specifies a local message trust level that a peer must have before its messages will be downloaded.");
\r
526 st.Bind(0,"MinPeerMessageTrust");
\r
528 st.Bind(2,"Specifies a peer message trust level that a peer must have before its messages will be downloaded.");
\r
532 st.Bind(0,"MinLocalTrustListTrust");
\r
534 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
538 st.Bind(0,"MinPeerTrustListTrust");
\r
540 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
544 st.Bind(0,"MessageDownloadMaxDaysBackward");
\r
546 st.Bind(2,"The maximum number of days backward that messages will be downloaded from each identity");
\r
550 st.Bind(0,"MessageListDaysBackward");
\r
552 st.Bind(2,"The number of days backward that messages you have inserted will appear in your MessageLists");
\r
556 st.Bind(0,"MaxPeerMessagesPerDay");
\r
558 st.Bind(2,"The maximum number of messages you will download from each peer on a given day.");
\r
562 st.Bind(0,"MaxBoardListRequests");
\r
564 st.Bind(2,"The maximum number of concurrent requests for new Board Lists. Set to 0 to disable.");
\r
568 st.Bind(0,"MaxBoardsPerMessage");
\r
570 st.Bind(2,"The maximum number of boards a received message may be sent to. Boards over this limit will be ignored.");
\r
574 st.Bind(0,"ChangeMessageTrustOnReply");
\r
576 st.Bind(2,"How much the local message trust level of an identity should change when you reply to one of their messages.");
\r
582 void SetupLogFile()
\r
585 std::string configval;
\r
588 date.SetToGMTime();
\r
590 LogFile::Instance()->SetFileName("fms-"+date.Format("%Y-%m-%d")+".log");
\r
591 LogFile::Instance()->OpenFile();
\r
592 LogFile::Instance()->SetWriteNewLine(true);
\r
593 LogFile::Instance()->SetWriteDate(true);
\r
594 LogFile::Instance()->SetWriteLogLevel(true);
\r
596 if(Option::Instance()->Get("LogLevel",configval)==false)
\r
599 Option::Instance()->Set("LogLevel",configval);
\r
601 if(StringFunctions::Convert(configval,loglevel)==false)
\r
603 loglevel=LogFile::LOGLEVEL_DEBUG;
\r
604 Option::Instance()->Set("LogLevel",loglevel);
\r
606 LogFile::Instance()->SetLogLevel((LogFile::LogLevel)loglevel);
\r
609 void SetupNetwork()
\r
613 WSAStartup(MAKEWORD(2,2),&wsadata);
\r
619 ThreadController::Instance()->ShutdownThreads();
\r
623 LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_INFO,"FMS shutdown");
\r
624 LogFile::Instance()->WriteNewLine();
\r
627 void ShutdownNetwork()
\r
634 void SigHandler(int signum)
\r
641 void ShutdownThreads(std::vector<PThread::Thread *> &threads)
\r
643 std::vector<PThread::Thread *>::iterator i;
\r
644 for(i=threads.begin(); i!=threads.end(); i++)
\r
649 for(i=threads.begin(); i!=threads.end(); i++)
\r
651 LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"ShutdownThreads waiting for thread to exit.");
\r
661 void StartThreads(std::vector<PThread::Thread *> &threads)
\r
663 std::string startfreenet;
\r
664 std::string startnntp;
\r
665 std::string starthttp;
\r
667 if(Option::Instance()->Get("StartFreenetUpdater",startfreenet)==false)
\r
669 startfreenet="true";
\r
670 Option::Instance()->Set("StartFreenetUpdater","true");
\r
673 if(Option::Instance()->Get("StartNNTP",startnntp)==false)
\r
676 Option::Instance()->Set("StartNNTP","true");
\r
679 if(Option::Instance()->Get("StartHTTP",starthttp)==false)
\r
682 Option::Instance()->Set("StartHTTP","true");
\r
685 if(startfreenet=="true")
\r
687 PThread::Thread *t=new PThread::Thread(new FreenetMasterThread());
\r
688 threads.push_back(t);
\r
691 if(startnntp=="true")
\r
693 PThread::Thread *t=new PThread::Thread(new NNTPListener());
\r
694 threads.push_back(t);
\r
697 if(starthttp=="true")
\r
699 PThread::Thread *t=new PThread::Thread(new HTTPThread());
\r
700 threads.push_back(t);
\r