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
56 db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,1);");
\r
59 db->Execute("CREATE TABLE IF NOT EXISTS tblOption(\
\r
60 Option TEXT UNIQUE,\
\r
61 OptionValue TEXT NOT NULL,\
\r
62 OptionDescription TEXT\
\r
65 db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\
\r
66 LocalIdentityID INTEGER PRIMARY KEY,\
\r
68 PublicKey TEXT UNIQUE,\
\r
69 PrivateKey TEXT UNIQUE,\
\r
70 SingleUse BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\
\r
71 PublishTrustList BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\
\r
72 PublishBoardList BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\
\r
73 InsertingIdentity BOOL CHECK(InsertingIdentity IN('true','false')) DEFAULT 'false',\
\r
74 LastInsertedIdentity DATETIME,\
\r
75 InsertingPuzzle BOOL CHECK(InsertingPuzzle IN('true','false')) DEFAULT 'false',\
\r
76 LastInsertedPuzzle DATETIME,\
\r
77 InsertingTrustList BOOL CHECK(InsertingTrustList IN('true','false')) DEFAULT 'false',\
\r
78 LastInsertedTrustList DATETIME,\
\r
79 InsertingBoardList BOOL CHECK(InsertingBoardList IN('true','false')) DEFAULT 'false',\
\r
80 LastInsertedBoardList DATETIME,\
\r
81 InsertingMessageList BOOL CHECK(InsertingMessageList IN('true','false')) DEFAULT 'false',\
\r
82 LastInsertedMessageList DATETIME\
\r
85 db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentityInserts(\
\r
86 LocalIdentityID INTEGER,\
\r
88 InsertIndex INTEGER\
\r
91 db->Execute("CREATE TABLE IF NOT EXISTS tblTrustListInserts(\
\r
92 LocalIdentityID INTEGER,\
\r
94 InsertIndex INTEGER\
\r
97 db->Execute("CREATE TABLE IF NOT EXISTS tblTrustListRequests(\
\r
98 IdentityID INTEGER,\
\r
100 RequestIndex INTEGER,\
\r
101 Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\
\r
104 db->Execute("CREATE TABLE IF NOT EXISTS tblIntroductionPuzzleInserts(\
\r
106 LocalIdentityID INTEGER,\
\r
108 InsertIndex INTEGER,\
\r
112 PuzzleSolution TEXT,\
\r
113 FoundSolution BOOL CHECK(FoundSolution IN('true','false')) DEFAULT 'false'\
\r
116 db->Execute("CREATE TABLE IF NOT EXISTS tblIdentity(\
\r
117 IdentityID INTEGER PRIMARY KEY,\
\r
118 PublicKey TEXT UNIQUE,\
\r
120 SingleUse BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\
\r
121 PublishTrustList BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\
\r
122 PublishBoardList BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\
\r
123 DateAdded DATETIME,\
\r
124 LastSeen DATETIME,\
\r
125 LocalMessageTrust INTEGER CHECK(LocalMessageTrust BETWEEN 0 AND 100) DEFAULT 50,\
\r
126 PeerMessageTrust INTEGER CHECK(PeerMessageTrust BETWEEN 0 AND 100) DEFAULT 50,\
\r
127 LocalTrustListTrust INTEGER CHECK(LocalTrustListTrust BETWEEN 0 AND 100) DEFAULT 50,\
\r
128 PeerTrustListTrust INTEGER CHECK(PeerTrustListTrust BETWEEN 0 AND 100) DEFAULT 50\
\r
131 db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityRequests(\
\r
132 IdentityID INTEGER,\
\r
134 RequestIndex INTEGER,\
\r
135 Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\
\r
138 db->Execute("CREATE TABLE IF NOT EXISTS tblIntroductionPuzzleRequests(\
\r
139 IdentityID INTEGER,\
\r
141 RequestIndex INTEGER,\
\r
142 Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false',\
\r
149 db->Execute("CREATE TABLE IF NOT EXISTS tblIdentityIntroductionInserts(\
\r
150 LocalIdentityID INTEGER,\
\r
154 Inserted BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\
\r
157 db->Execute("CREATE TABLE IF NOT EXISTS tblPeerTrust(\
\r
158 IdentityID INTEGER,\
\r
159 TargetIdentityID INTEGER,\
\r
160 MessageTrust INTEGER CHECK(MessageTrust BETWEEN 0 AND 100),\
\r
161 TrustListTrust INTEGER CHECK(TrustListTrust BETWEEN 0 AND 100)\
\r
164 db->Execute("CREATE TABLE IF NOT EXISTS tblBoard(\
\r
165 BoardID INTEGER PRIMARY KEY,\
\r
166 BoardName TEXT UNIQUE,\
\r
167 BoardDescription TEXT,\
\r
168 DateAdded DATETIME\
\r
171 db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('fms','Freenet Message System','2007-12-01');");
\r
172 db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('freenet','Discussion about Freenet','2007-12-01');");
\r
173 db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('public','Public discussion','2007-12-01');");
\r
174 db->Execute("INSERT INTO tblBoard(BoardName,BoardDescription,DateAdded) VALUES('test','Test board','2007-12-01');");
\r
176 db->Execute("CREATE TABLE IF NOT EXISTS tblMessage(\
\r
177 MessageID INTEGER PRIMARY KEY,\
\r
178 IdentityID INTEGER,\
\r
183 MessageUUID TEXT UNIQUE,\
\r
184 ReplyBoardID INTEGER,\
\r
188 db->Execute("CREATE TABLE IF NOT EXISTS tblMessageReplyTo(\
\r
189 MessageID INTEGER,\
\r
190 ReplyToMessageUUID TEXT,\
\r
191 ReplyOrder INTEGER\
\r
194 db->Execute("CREATE TABLE IF NOT EXISTS tblMessageBoard(\
\r
195 MessageID INTEGER,\
\r
199 db->Execute("CREATE TABLE IF NOT EXISTS tblMessageListRequests(\
\r
200 IdentityID INTEGER,\
\r
202 RequestIndex INTEGER,\
\r
203 Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\
\r
206 db->Execute("CREATE TABLE IF NOT EXISTS tblMessageRequests(\
\r
207 IdentityID INTEGER,\
\r
209 RequestIndex INTEGER,\
\r
210 FromMessageList BOOL CHECK(FromMessageList IN('true','false')) DEFAULT 'false',\
\r
211 Found BOOL CHECK(Found IN('true','false')) DEFAULT 'false'\
\r
214 db->Execute("CREATE TABLE IF NOT EXISTS tblMessageInserts(\
\r
215 LocalIdentityID INTEGER,\
\r
217 InsertIndex INTEGER,\
\r
218 MessageUUID TEXT UNIQUE,\
\r
220 Inserted BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\
\r
223 db->Execute("CREATE TABLE IF NOT EXISTS tblMessageListInserts(\
\r
224 LocalIdentityID INTEGER,\
\r
226 InsertIndex INTEGER,\
\r
227 Inserted BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\
\r
230 db->Execute("CREATE TABLE IF NOT EXISTS tblAdministrationBoard(\
\r
231 BoardID INTEGER UNIQUE,\
\r
232 ModifyLocalMessageTrust INTEGER,\
\r
233 ModifyLocalTrustListTrust INTEGER\
\r
236 // MessageInserter will insert a record into this temp table which the MessageListInserter will query for and insert a MessageList when needed
\r
237 db->Execute("CREATE TEMPORARY TABLE IF NOT EXISTS tmpMessageListInsert(\
\r
238 LocalIdentityID INTEGER,\
\r
242 // low / high / message count for each board
\r
243 db->Execute("CREATE VIEW IF NOT EXISTS vwBoardStats AS \
\r
244 SELECT tblBoard.BoardID AS 'BoardID', IFNULL(MIN(MessageID),0) AS 'LowMessageID', IFNULL(MAX(MessageID),0) AS 'HighMessageID', COUNT(MessageID) AS 'MessageCount' \
\r
245 FROM tblBoard LEFT JOIN tblMessageBoard ON tblBoard.BoardID=tblMessageBoard.BoardID \
\r
246 WHERE MessageID>=0 OR MessageID IS NULL \
\r
247 GROUP BY tblBoard.BoardID;");
\r
249 // calculates peer trust
\r
250 db->Execute("CREATE VIEW IF NOT EXISTS vwCalculatedPeerTrust AS \
\r
251 SELECT TargetIdentityID, \
\r
252 ROUND(SUM(MessageTrust*(LocalMessageTrust/100.0))/SUM(LocalMessageTrust/100.0),0) AS 'PeerMessageTrust', \
\r
253 ROUND(SUM(TrustListTrust*(LocalTrustListTrust/100.0))/SUM(LocalTrustListTrust/100.0),0) AS 'PeerTrustListTrust' \
\r
254 FROM tblPeerTrust INNER JOIN tblIdentity ON tblPeerTrust.IdentityID=tblIdentity.IdentityID \
\r
255 WHERE LocalTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalTrustListTrust') \
\r
256 AND ( PeerTrustListTrust IS NULL OR PeerTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerTrustListTrust') ) \
\r
257 GROUP BY TargetIdentityID;");
\r
260 These peer trust calculations are too CPU intensive to be triggers - they were called every time a new trust list was processed
\r
261 All trust levels will now be recalculated every hour in the PeriodicDBMaintenance class
\r
263 // drop existing triggers
\r
264 db->Execute("DROP TRIGGER IF EXISTS trgDeleteOntblPeerTrust;");
\r
265 db->Execute("DROP TRIGGER IF EXISTS trgInsertOntblPeerTrust;");
\r
266 db->Execute("DROP TRIGGER IF EXISTS trgUpdateOntblPeerTrust;");
\r
267 db->Execute("DROP TRIGGER IF EXISTS trgUpdateLocalTrustLevels;");
\r
269 // update PeerTrustLevel when deleting a record from tblPeerTrust
\r
270 db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteOntblPeerTrust AFTER DELETE ON tblPeerTrust \
\r
273 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
276 // update PeerTrustLevel when inserting a record into tblPeerTrust
\r
277 db->Execute("CREATE TRIGGER IF NOT EXISTS trgInsertOntblPeerTrust AFTER INSERT ON tblPeerTrust \
\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
283 // update PeerTrustLevel when updating a record in tblPeerTrust
\r
284 db->Execute("CREATE TRIGGER IF NOT EXISTS trgUpdateOntblPeerTrust AFTER UPDATE ON tblPeerTrust \
\r
287 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
288 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
291 // 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
292 db->Execute("CREATE TRIGGER IF NOT EXISTS trgUpdateLocalTrustLevels AFTER UPDATE OF LocalMessageTrust,LocalTrustListTrust ON tblIdentity \
\r
295 UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID);\
\r
299 db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteMessage AFTER DELETE ON tblMessage \
\r
302 DELETE FROM tblMessageBoard WHERE tblMessageBoard.MessageID=old.MessageID;\
\r
303 DELETE FROM tblMessageReplyTo WHERE tblMessageReplyTo.MessageID=old.MessageID;\
\r
306 db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteIdentity AFTER DELETE ON tblIdentity \
\r
309 DELETE FROM tblIdentityRequests WHERE IdentityID=old.IdentityID;\
\r
310 DELETE FROM tblIntroductionPuzzleRequests WHERE IdentityID=old.IdentityID;\
\r
311 DELETE FROM tblMessageListRequests WHERE IdentityID=old.IdentityID;\
\r
312 DELETE FROM tblMessageRequests WHERE IdentityID=old.IdentityID;\
\r
313 DELETE FROM tblPeerTrust WHERE IdentityID=old.IdentityID;\
\r
314 DELETE FROM tblTrustListRequests WHERE IdentityID=old.IdentityID;\
\r
317 db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteLocalIdentity AFTER DELETE ON tblLocalIdentity \
\r
320 DELETE FROM tblIdentityIntroductionInserts WHERE LocalIdentityID=old.LocalIdentityID;\
\r
321 DELETE FROM tblIntroductionPuzzleInserts WHERE LocalIdentityID=old.LocalIdentityID;\
\r
322 DELETE FROM tblLocalIdentityInserts WHERE LocalIdentityID=old.LocalIdentityID;\
\r
323 DELETE FROM tblMessageInserts WHERE LocalIdentityID=old.LocalIdentityID;\
\r
324 DELETE FROM tblMessageListInserts WHERE LocalIdentityID=old.LocalIdentityID;\
\r
325 DELETE FROM tblTrustListInserts WHERE LocalIdentityID=old.LocalIdentityID;\
\r
328 // delete introduction puzzles that were half-way inserted
\r
329 db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day IS NULL AND InsertIndex IS NULL;");
\r
331 // delete stale introduction puzzles (2 or more days old)
\r
332 date.SetToGMTime();
\r
333 date.Add(0,0,0,-2);
\r
334 db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day<='"+date.Format("%Y-%m-%d")+"';");
\r
335 db->Execute("DELETE FROM tblIntroductionPuzzleRequests WHERE Day<='"+date.Format("%Y-%m-%d")+"';");
\r
337 date.SetToGMTime();
\r
338 // insert SomeDude's public key
\r
339 db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw,iXez4j3qCpd596TxXiJgZyTq9o-CElEuJxm~jNNZAuA,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');");
\r
340 // insert Shadow Panther's public key
\r
341 db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@~mimyB1kmH4f7Cgsd2wM2Qv2NxrZHRMM6IY8~7EWRVQ,fxTKkR0TYhgMYb-vEGAv55sMOxCGD2xhE4ZxWHxdPz4,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');");
\r
342 // insert garfield's public key
\r
343 db->Execute("INSERT INTO tblIdentity(PublicKey,DateAdded) VALUES('SSK@T8l1IEGU4-PoASFzgc2GYhIgRzUvZsKdoQWeuLHuTmM,QLxAPfkGis8l5NafNpSCdbxzXhBlu9WL8svcqJw9Mpo,AQACAAE/','"+date.Format("%Y-%m-%d %H:%M:%S")+"');");
\r
347 void ConvertDB0100To0101()
\r
349 // added unique constraint to public and private key
\r
350 SQLite3DB::DB *db=SQLite3DB::DB::Instance();
\r
351 db->Execute("CREATE TEMPORARY TABLE tblLocalIdentityTemp AS SELECT * FROM tblLocalIdentity;");
\r
352 db->Execute("DROP TABLE IF EXISTS tblLocalIdentity;");
\r
353 db->Execute("CREATE TABLE IF NOT EXISTS tblLocalIdentity(\
\r
354 LocalIdentityID INTEGER PRIMARY KEY,\
\r
356 PublicKey TEXT UNIQUE,\
\r
357 PrivateKey TEXT UNIQUE,\
\r
358 SingleUse BOOL CHECK(SingleUse IN('true','false')) DEFAULT 'false',\
\r
359 PublishTrustList BOOL CHECK(PublishTrustList IN('true','false')) DEFAULT 'false',\
\r
360 PublishBoardList BOOL CHECK(PublishBoardList IN('true','false')) DEFAULT 'false',\
\r
361 InsertingIdentity BOOL CHECK(InsertingIdentity IN('true','false')) DEFAULT 'false',\
\r
362 LastInsertedIdentity DATETIME,\
\r
363 InsertingPuzzle BOOL CHECK(InsertingPuzzle IN('true','false')) DEFAULT 'false',\
\r
364 LastInsertedPuzzle DATETIME,\
\r
365 InsertingTrustList BOOL CHECK(InsertingTrustList IN('true','false')) DEFAULT 'false',\
\r
366 LastInsertedTrustList DATETIME,\
\r
367 InsertingBoardList BOOL CHECK(InsertingBoardList IN('true','false')) DEFAULT 'false',\
\r
368 LastInsertedBoardList DATETIME,\
\r
369 InsertingMessageList BOOL CHECK(InsertingMessageList IN('true','false')) DEFAULT 'false',\
\r
370 LastInsertedMessageList DATETIME\
\r
372 db->Execute("INSERT INTO tblLocalIdentity SELECT * FROM tblLocalIdentityTemp;");
\r
373 db->Execute("DROP TABLE IF EXISTS tblLocalIdentityTemp;");
\r
374 db->Execute("UPDATE tblDBVersion SET Major=1, Minor=1;");
\r
377 void SetupDefaultOptions()
\r
379 // 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
381 std::ostringstream tempstr; // must set tempstr to "" between db inserts
\r
382 SQLite3DB::DB *db=SQLite3DB::DB::Instance();
\r
383 SQLite3DB::Statement st=db->Prepare("INSERT INTO tblOption(Option,OptionValue,OptionDescription) VALUES(?,?,?);");
\r
387 tempstr << LogFile::LOGLEVEL_DEBUG;
\r
388 st.Bind(0,"LogLevel");
\r
389 st.Bind(1,tempstr.str());
\r
390 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
395 st.Bind(0,"NNTPListenPort");
\r
397 st.Bind(2,"The port that the NNTP service will listen for incoming connections.");
\r
401 // NNTPBindAddresses
\r
402 st.Bind(0,"NNTPBindAddresses");
\r
403 st.Bind(1,"localhost");
\r
404 st.Bind(2,"A comma separated list of valid IPv4 or IPv6 addresses/hostnames that the NNTP service will try to bind to.");
\r
408 st.Bind(0,"NNTPAllowPost");
\r
410 st.Bind(2,"Allow posting messages from NNTP. Setting to false will make the newsgroups read only.");
\r
415 st.Bind(0,"StartNNTP");
\r
417 st.Bind(2,"Start NNTP server.");
\r
421 st.Bind(0,"StartHTTP");
\r
423 st.Bind(2,"Start HTTP server.");
\r
427 st.Bind(0,"HTTPListenPort");
\r
429 st.Bind(2,"Port HTTP server will listen on.");
\r
433 // StartFreenetUpdater
\r
434 st.Bind(0,"StartFreenetUpdater");
\r
436 st.Bind(2,"Start Freenet Updater thread.");
\r
441 st.Bind(0,"FCPHost");
\r
442 st.Bind(1,"127.0.0.1");
\r
443 st.Bind(2,"Host name or address of Freenet node.");
\r
448 st.Bind(0,"FCPPort");
\r
450 st.Bind(2,"The port that Freenet is listening for FCP connections on.");
\r
454 st.Bind(0,"MessageBase");
\r
456 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
460 st.Bind(0,"MaxIdentityRequests");
\r
462 st.Bind(2,"Maximum number of concurrent requests for new Identity xml files");
\r
466 st.Bind(0,"MaxIdentityIntroductionRequests");
\r
468 st.Bind(2,"Maximum number of concurrent identities requesting IdentityIntroduction xml files. Each identity may have multiple requests pending.");
\r
472 st.Bind(0,"MaxIntroductionPuzzleRequests");
\r
474 st.Bind(2,"Maximum number of concurrent requests for new IntroductionPuzzle xml files");
\r
478 st.Bind(0,"MaxTrustListRequests");
\r
480 st.Bind(2,"Maximum number of concurrent requests for new Trust Lists");
\r
484 st.Bind(0,"MaxMessageListRequests");
\r
486 st.Bind(2,"Maximum number of concurrent requests for new Message Lists");
\r
490 st.Bind(0,"MaxMessageRequests");
\r
492 st.Bind(2,"Maximum number of concurrent requests for new Messages");
\r
496 st.Bind(0,"MinLocalMessageTrust");
\r
498 st.Bind(2,"Specifies a local message trust level that a peer must have before its messages will be downloaded.");
\r
502 st.Bind(0,"MinPeerMessageTrust");
\r
504 st.Bind(2,"Specifies a peer message trust level that a peer must have before its messages will be downloaded.");
\r
508 st.Bind(0,"MinLocalTrustListTrust");
\r
510 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
514 st.Bind(0,"MinPeerTrustListTrust");
\r
516 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
520 st.Bind(0,"MessageDownloadMaxDaysBackward");
\r
522 st.Bind(2,"The maximum number of days backward that messages will be downloaded from each identity");
\r
526 st.Bind(0,"MessageListDaysBackward");
\r
528 st.Bind(2,"The number of days backward that messages you have inserted will appear in your MessageLists");
\r
532 st.Bind(0,"MaxPeerMessagesPerDay");
\r
534 st.Bind(2,"The maximum number of messages you will download from each peer on a given day.");
\r
540 void SetupLogFile()
\r
543 std::string configval;
\r
546 date.SetToGMTime();
\r
548 LogFile::Instance()->SetFileName("fms-"+date.Format("%Y-%m-%d")+".log");
\r
549 LogFile::Instance()->OpenFile();
\r
550 LogFile::Instance()->SetWriteNewLine(true);
\r
551 LogFile::Instance()->SetWriteDate(true);
\r
552 LogFile::Instance()->SetWriteLogLevel(true);
\r
554 if(Option::Instance()->Get("LogLevel",configval)==false)
\r
557 Option::Instance()->Set("LogLevel",configval);
\r
559 if(StringFunctions::Convert(configval,loglevel)==false)
\r
561 loglevel=LogFile::LOGLEVEL_DEBUG;
\r
562 Option::Instance()->Set("LogLevel",loglevel);
\r
564 LogFile::Instance()->SetLogLevel((LogFile::LogLevel)loglevel);
\r
567 void SetupNetwork()
\r
571 WSAStartup(MAKEWORD(2,2),&wsadata);
\r
577 ThreadController::Instance()->ShutdownThreads();
\r
581 LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_INFO,"FMS shutdown");
\r
582 LogFile::Instance()->WriteNewLine();
\r
585 void ShutdownNetwork()
\r
592 void SigHandler(int signum)
\r
599 void ShutdownThreads(std::vector<PThread::Thread *> &threads)
\r
601 std::vector<PThread::Thread *>::iterator i;
\r
602 for(i=threads.begin(); i!=threads.end(); i++)
\r
607 for(i=threads.begin(); i!=threads.end(); i++)
\r
609 LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"ShutdownThreads waiting for thread to exit.");
\r
619 void StartThreads(std::vector<PThread::Thread *> &threads)
\r
621 std::string startfreenet;
\r
622 std::string startnntp;
\r
623 std::string starthttp;
\r
625 if(Option::Instance()->Get("StartFreenetUpdater",startfreenet)==false)
\r
627 startfreenet="true";
\r
628 Option::Instance()->Set("StartFreenetUpdater","true");
\r
631 if(Option::Instance()->Get("StartNNTP",startnntp)==false)
\r
634 Option::Instance()->Set("StartNNTP","true");
\r
637 if(Option::Instance()->Get("StartHTTP",starthttp)==false)
\r
640 Option::Instance()->Set("StartHTTP","true");
\r
643 if(startfreenet=="true")
\r
645 PThread::Thread *t=new PThread::Thread(new FreenetMasterThread());
\r
646 threads.push_back(t);
\r
649 if(startnntp=="true")
\r
651 PThread::Thread *t=new PThread::Thread(new NNTPListener());
\r
652 threads.push_back(t);
\r
655 if(starthttp=="true")
\r
657 PThread::Thread *t=new PThread::Thread(new HTTPThread());
\r
658 threads.push_back(t);
\r