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