src/option.cpp\r
src/socketdefines.cpp\r
src/stringfunctions.cpp\r
+src/threadcontroller.cpp\r
src/uuidgenerator.cpp\r
src/db/sqlite3db.cpp\r
src/db/sqlite3recordset.cpp\r
src/freenet/identityrequester.cpp\r
src/freenet/identityxml.cpp\r
src/freenet/introductionpuzzleinserter.cpp\r
-src/freenet/introductionpuzzleremover.cpp\r
src/freenet/introductionpuzzlerequester.cpp\r
src/freenet/introductionpuzzlexml.cpp\r
src/freenet/messageinserter.cpp\r
src/freenet/messagelistxml.cpp\r
src/freenet/messagerequester.cpp\r
src/freenet/messagexml.cpp\r
+src/freenet/periodicdbmaintenance.cpp\r
src/freenet/trustlistinserter.cpp\r
src/freenet/trustlistrequester.cpp\r
src/freenet/trustlistxml.cpp\r
src/http/ipagehandler.cpp\r
src/http/pages/addpeerpage.cpp\r
src/http/pages/announceidentitypage.cpp\r
+src/http/pages/controlboardpage.cpp\r
src/http/pages/createidentitypage.cpp\r
src/http/pages/homepage.cpp\r
src/http/pages/localidentitiespage.cpp\r
src/pthreadwrapper/mutex.cpp\r
src/pthreadwrapper/runnable.cpp\r
src/pthreadwrapper/thread.cpp\r
+src/pthreadwrapper/threadedexecutor.cpp\r
src/xyssl/sha1.c\r
)\r
\r
void Add(const int seconds=0, const int minutes=0, const int hours=0, const int days=0, const int months=0, const int years=0);\r
\r
void Set(const int year=1970, const int month=1, const int day=1, const int hour=0, const int minute=0, const int second=0);\r
- void Set(const time_t &timet);\r
+ void SetT(const time_t &timet);\r
void Set(const struct tm *stm);\r
void Set(const std::string &datestring); // method only will work with a select few basic input formats\r
\r
void IIndexRequester<IDTYPE>::Process()\r
{\r
// max is the smaller of the config value or the total number of ids we will request from\r
- long max=m_maxrequests>m_ids.size() ? m_ids.size() : m_maxrequests;\r
+ typename std::map<IDTYPE,bool>::size_type max=m_maxrequests>m_ids.size() ? m_ids.size() : m_maxrequests;\r
\r
// try to keep up to max requests going\r
if(m_requesting.size()<max)\r
+++ /dev/null
-#ifndef _introductionpuzzleremover_\r
-#define _introductionpuzzleremover_\r
-\r
-#include "../idatabase.h"\r
-#include "../ilogger.h"\r
-#include "../datetime.h"\r
-#include "ifreenetregistrable.h"\r
-#include "iperiodicprocessor.h"\r
-\r
-/**\r
- \brief Removes stale IntroductionPuzzles from database\r
-*/\r
-class IntroductionPuzzleRemover:public IFreenetRegistrable,public IPeriodicProcessor,public IDatabase,public ILogger\r
-{\r
-public:\r
- IntroductionPuzzleRemover();\r
-\r
- void Process();\r
-\r
- void RegisterWithThread(FreenetMasterThread *thread);\r
-\r
-private:\r
-\r
- DateTime m_lastchecked;\r
-\r
-};\r
-\r
-#endif // _introductionpuzzleremover_\r
\r
class MessageListXML:public IFMSXMLDocument\r
{\r
+private:\r
+ struct message\r
+ {\r
+ message(const std::string &date, const long index, const std::vector<std::string> &boards):m_date(date),m_index(index),m_boards(boards) {}\r
+ std::string m_date;\r
+ long m_index;\r
+ std::vector<std::string> m_boards;\r
+ };\r
public:\r
MessageListXML();\r
\r
\r
void AddMessage(const std::string &date, const long index, const std::vector<std::string> boards);\r
\r
- const long MessageCount() { return m_messages.size(); }\r
+ const std::vector<message>::size_type MessageCount() { return m_messages.size(); }\r
std::string GetDate(const long index);\r
const long GetIndex(const long index);\r
std::vector<std::string> GetBoards(const long index);\r
\r
private:\r
- struct message\r
- {\r
- message(const std::string &date, const long index, const std::vector<std::string> &boards):m_date(date),m_index(index),m_boards(boards) {}\r
- std::string m_date;\r
- long m_index;\r
- std::vector<std::string> m_boards;\r
- };\r
-\r
void Initialize();\r
\r
std::vector<message> m_messages;\r
--- /dev/null
+#ifndef _periodicdbmaintenance_\r
+#define _periodicdbmaintenance_\r
+\r
+#include "../idatabase.h"\r
+#include "../ilogger.h"\r
+#include "../datetime.h"\r
+#include "ifreenetregistrable.h"\r
+#include "iperiodicprocessor.h"\r
+\r
+class PeriodicDBMaintenance:public IFreenetRegistrable,public IPeriodicProcessor,public IDatabase,public ILogger\r
+{\r
+public:\r
+ PeriodicDBMaintenance();\r
+\r
+ void Process();\r
+\r
+ void RegisterWithThread(FreenetMasterThread *thread);\r
+\r
+private:\r
+ void Do10MinuteMaintenance();\r
+ void Do30MinuteMaintenance();\r
+ void Do1HourMaintenance();\r
+ void Do6HourMaintenance();\r
+ void Do1DayMaintenance();\r
+\r
+ DateTime m_check10mins;\r
+ DateTime m_check30mins;\r
+ DateTime m_check1hour;\r
+ DateTime m_check6hours;\r
+ DateTime m_check1day;\r
+ \r
+};\r
+\r
+#endif // _periodicdbmaintenance_\r
\r
class TrustListXML:public IFMSXMLDocument,public ILogger\r
{\r
+private:\r
+ struct trust\r
+ {\r
+ trust(const std::string &identity, const long messagetrust, const long trustlisttrust):m_identity(identity),m_messagetrust(messagetrust),m_trustlisttrust(trustlisttrust) {}\r
+ std::string m_identity;\r
+ long m_messagetrust;\r
+ long m_trustlisttrust;\r
+ };\r
public:\r
TrustListXML();\r
\r
\r
void AddTrust(const std::string &identity, const long messagetrust, const long trustlisttrust);\r
\r
- const long TrustCount() { return m_trust.size(); }\r
+ const std::vector<trust>::size_type TrustCount() { return m_trust.size(); }\r
std::string GetIdentity(const long index);\r
long GetMessageTrust(const long index);\r
long GetTrustListTrust(const long index);\r
\r
private:\r
- struct trust\r
- {\r
- trust(const std::string &identity, const long messagetrust, const long trustlisttrust):m_identity(identity),m_messagetrust(messagetrust),m_trustlisttrust(trustlisttrust) {}\r
- std::string m_identity;\r
- long m_messagetrust;\r
- long m_trustlisttrust;\r
- };\r
-\r
void Initialize();\r
\r
std::vector<trust> m_trust;\r
//#include <zthread/Thread.h>\r
#include "pthreadwrapper/thread.h"\r
\r
-#define FMS_VERSION "0.1.8"\r
+#define FMS_VERSION "0.1.9"\r
\r
// opens database and creates tables and initial inserts if necessary\r
void SetupDB();\r
const bool Handle(shttpd_arg *arg);\r
\r
private:\r
- void HandlePost(shttpd_arg *arg);\r
- void HadleGet(shttpd_arg *arg);\r
virtual const bool WillHandleURI(const std::string &uri)=0;\r
virtual const std::string GeneratePage(const std::string &method, const std::map<std::string,std::string> &queryvars)=0;\r
\r
// converts from basename[#] query args into a vector where the vector pos is the index pos #\r
void CreateArgArray(const std::map<std::string,std::string> &vars, const std::string &basename, std::vector<std::string> &args);\r
\r
+ // replaces html control characters with elements (i.e. < becomes <)\r
+ const std::string SanitizeOutput(const std::string &input);\r
+\r
std::string m_template;\r
\r
};\r
--- /dev/null
+#ifndef _controlboardpage_\r
+#define _controlboardpage_\r
+\r
+#include "../ipagehandler.h"\r
+#include "../../idatabase.h"\r
+\r
+class ControlBoardPage:public IPageHandler,public IDatabase\r
+{\r
+public:\r
+ ControlBoardPage(const std::string &templatestr):IPageHandler(templatestr) {}\r
+\r
+private:\r
+ const bool WillHandleURI(const std::string &uri);\r
+ const std::string GeneratePage(const std::string &method, const std::map<std::string,std::string> &queryvars);\r
+};\r
+\r
+#endif // _controlboardpage_\r
\r
const bool ParseNNTPMessage(const std::string &nntpmessage);\r
\r
+ const bool PostedToAdministrationBoard() { return CheckForAdministrationBoard(m_boards); }\r
+\r
void StartFreenetInsert();\r
+ void HandleAdministrationMessage();\r
\r
private:\r
void Initialize();\r
+ // checks vector of boards for any special administration boards - if it finds one true is returned, otherwise false\r
+ const bool CheckForAdministrationBoard(const std::vector<std::string> &boards);\r
\r
long m_messageid;\r
std::string m_messageuuid;\r
//#include <zthread/ZThread.h>\r
//#include <zthread/ThreadedExecutor.h>\r
#include "../pthreadwrapper/runnable.h"\r
+#include "../pthreadwrapper/threadedexecutor.h"\r
\r
#include "../socketdefines.h"\r
\r
unsigned short m_listenport;\r
std::vector<SOCKET> m_listensockets;\r
//ZThread::ThreadedExecutor m_connections;\r
- std::vector<PThread::Thread *> m_connectionthreads;\r
+ //std::vector<PThread::Thread *> m_connectionthreads;\r
+ PThread::ThreadedExecutor m_connections;\r
\r
};\r
\r
class Guard;\r
class Runnable;\r
class Thread;\r
+ class ThreadedExecutor;\r
\r
} // namespace\r
\r
#include "pthreadwrapper/runnable.h"\r
#include "pthreadwrapper/thread.h"\r
#include "pthreadwrapper/singleton.h"\r
+#include "pthreadwrapper/threadedexecutor.h"\r
\r
#endif // _pthread_wrapper_\r
static void *EntryPoint(void *pthis);\r
\r
pthread_t m_thread;\r
+ int m_threadnum;\r
bool m_running; // thread (object) is currently running\r
bool m_cancelled;\r
Runnable *m_runnable; // actual object that is being run\r
--- /dev/null
+#ifndef _pthread_threadedexecutor_\r
+#define _pthread_threadedexecutor_\r
+\r
+#include "noncopyable.h"\r
+#include "runnable.h"\r
+#include <vector>\r
+\r
+namespace PThread\r
+{\r
+\r
+class ThreadedExecutor:public NonCopyable\r
+{\r
+public:\r
+ ThreadedExecutor() {}\r
+ ~ThreadedExecutor();\r
+\r
+ void Execute(Runnable *runnable);\r
+ \r
+ void Join();\r
+ void Cancel();\r
+\r
+private:\r
+ void CleanupFinished();\r
+ \r
+ std::vector<Thread *> m_threads;\r
+};\r
+\r
+}\r
+\r
+#endif // _pthread_threadedexecutor_\r
--- /dev/null
+#ifndef _threadcontroller_\r
+#define _threadcontroller_\r
+\r
+#include "pthreadwrapper/thread.h"\r
+#include "pthreadwrapper/singleton.h"\r
+\r
+class ThreadController:public PThread::Singleton<ThreadController>\r
+{\r
+public:\r
+ ThreadController():m_freenetthread(NULL),m_httpthread(NULL),m_nntpthread(NULL) {}\r
+ ~ThreadController();\r
+\r
+ void StartThreads();\r
+ void ShutdownThreads();\r
+ void RestartThreads();\r
+\r
+ void StartFreenetThread();\r
+ void StartHTTPThread();\r
+ void StartNNTPThread();\r
+\r
+ void ShutdownFreenetThread();\r
+ void ShutdownHTTPThread();\r
+ void ShutdownNNTPThread();\r
+\r
+private:\r
+ void ReadConfig();\r
+\r
+ bool m_startfreenet;\r
+ bool m_starthttp;\r
+ bool m_startnntp;\r
+\r
+ PThread::Thread *m_freenetthread;\r
+ PThread::Thread *m_httpthread;\r
+ PThread::Thread *m_nntpthread;\r
+\r
+};\r
+\r
+#endif // _threadcontroller_\r
{\r
std::vector<unsigned char>::size_type currentdatapos=0;\r
\r
+ //reserve space for encoded data 4*input/3\r
+ encoded.reserve((4L*data.size())/3L);\r
while(currentdatapos<data.size())\r
{\r
encoded.push_back(base64chars[(data[currentdatapos]>>2 & 0x3F)]);\r
std::string::size_type encodedpos=0;\r
unsigned char currentbyte=0;\r
\r
+ // reserve space for decoded data (encoded size*3/4)\r
+ if(encoded.size()>1)\r
+ {\r
+ data.reserve((encoded.size()*3)/4);\r
+ }\r
+\r
// loop while encoded pos fits in current size\r
while(encodedpos+3<encoded.size())\r
{\r
\r
DateTime::DateTime(const time_t &timet)\r
{\r
- Set(timet);\r
+ SetT(timet);\r
}\r
\r
DateTime::DateTime(const struct tm *stm)\r
Normalize();\r
}\r
\r
-void DateTime::Set(const time_t &timet)\r
+void DateTime::SetT(const time_t &timet)\r
{\r
m_timet=timet;\r
\r
{\r
int year,month,day,hour,minute,second;\r
std::vector<std::string> tokens;\r
- int vecpos;\r
+ std::vector<std::string>::size_type vecpos;\r
int tempint;\r
\r
year=month=day=hour=minute=second=-1;\r
m_parametercount=0;\r
m_resultcolumncount=0;\r
m_rowreturned=false;\r
+ m_lastinsertrowid=-1;\r
}\r
\r
Statement::Statement(sqlite3_stmt *statement)\r
m_parametercount=sqlite3_bind_parameter_count(m_statement);\r
m_resultcolumncount=sqlite3_column_count(m_statement);\r
m_rowreturned=false;\r
+ m_lastinsertrowid=-1;\r
\r
if(m_statement)\r
{\r
m_parametercount=0;\r
m_resultcolumncount=0;\r
m_rowreturned=false;\r
+ m_lastinsertrowid=-1;\r
*this=rhs;\r
}\r
\r
int FCPv2::FindOnReceiveBuffer(const char *text)\r
{\r
bool found;\r
- int i,j;\r
+ std::vector<char>::size_type i,j;\r
size_t tlen=strlen(text);\r
\r
if(m_receivebuffer.size()>=tlen)\r
va_list args;\r
const char *field;\r
const char *val;\r
- int bytecount=0;\r
+ std::vector<char>::size_type bytecount=0;\r
int i;\r
- int startlen;\r
+ std::vector<char>::size_type startlen;\r
\r
startlen=m_sendbuffer.size();\r
\r
\r
const int FCPv2::SendMessage(FCPMessage &message)\r
{\r
- int bytecount=0;\r
- int startlen;\r
+ std::vector<char>::size_type bytecount=0;\r
+ std::vector<char>::size_type startlen;\r
FCPMessage::iterator i;\r
\r
startlen=m_sendbuffer.size();\r
#include "../../include/freenet/introductionpuzzleinserter.h"\r
#include "../../include/freenet/identityintroductionrequester.h"\r
#include "../../include/freenet/introductionpuzzlerequester.h"\r
-#include "../../include/freenet/introductionpuzzleremover.h"\r
#include "../../include/freenet/identityintroductioninserter.h"\r
#include "../../include/freenet/trustlistinserter.h"\r
#include "../../include/freenet/trustlistrequester.h"\r
#include "../../include/freenet/messagerequester.h"\r
#include "../../include/freenet/messageinserter.h"\r
#include "../../include/freenet/messagelistinserter.h"\r
+#include "../../include/freenet/periodicdbmaintenance.h"\r
\r
//#include <zthread/Thread.h>\r
#include "../../include/pthreadwrapper/thread.h"\r
m_registrables.push_back(new IntroductionPuzzleInserter(&m_fcp));\r
m_registrables.push_back(new IdentityIntroductionRequester(&m_fcp));\r
m_registrables.push_back(new IntroductionPuzzleRequester(&m_fcp));\r
- m_registrables.push_back(new IntroductionPuzzleRemover());\r
m_registrables.push_back(new IdentityIntroductionInserter(&m_fcp));\r
m_registrables.push_back(new TrustListInserter(&m_fcp));\r
m_registrables.push_back(new TrustListRequester(&m_fcp));\r
m_registrables.push_back(new MessageRequester(&m_fcp));\r
m_registrables.push_back(new MessageInserter(&m_fcp));\r
m_registrables.push_back(new MessageListInserter(&m_fcp));\r
+ m_registrables.push_back(new PeriodicDBMaintenance());\r
\r
for(std::vector<IFreenetRegistrable *>::iterator i=m_registrables.begin(); i!=m_registrables.end(); i++)\r
{\r
\r
if(!td.Error())\r
{\r
- TiXmlElement *el;\r
TiXmlText *txt;\r
TiXmlHandle hnd(&td);\r
\r
\r
if(!td.Error())\r
{\r
- TiXmlElement *el;\r
TiXmlText *txt;\r
TiXmlHandle hnd(&td);\r
\r
+++ /dev/null
-#include "../../include/freenet/introductionpuzzleremover.h"\r
-\r
-#ifdef XMEM\r
- #include <xmem.h>\r
-#endif\r
-\r
-IntroductionPuzzleRemover::IntroductionPuzzleRemover()\r
-{\r
- m_lastchecked.SetToGMTime();\r
-}\r
-\r
-void IntroductionPuzzleRemover::Process()\r
-{\r
- DateTime now;\r
- DateTime date;\r
- now.SetToGMTime();\r
- date.SetToGMTime();\r
-\r
- // check once a day\r
- if(m_lastchecked<(now-1.0))\r
- {\r
-\r
- date.Add(0,0,0,-2);\r
-\r
- // delete all puzzles 2 or more days old\r
- m_db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day<='"+date.Format("%Y-%m-%d")+"';");\r
- m_db->Execute("DELETE FROM tblIntroductionPuzzleRequests WHERE Day<='"+date.Format("%Y-%m-%d")+"';");\r
-\r
- m_lastchecked=now;\r
- }\r
-}\r
-\r
-void IntroductionPuzzleRemover::RegisterWithThread(FreenetMasterThread *thread)\r
-{\r
- thread->RegisterPeriodicProcessor(this);\r
-}\r
{\r
DateTime now;\r
int id;\r
+ std::string limitnum="30";\r
+\r
+ // if we don't have an identity that we haven't seen yet, then set limit to 5\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT tblLocalIdentity.LocalIdentityID FROM tblLocalIdentity LEFT JOIN tblIdentity ON tblLocalIdentity.PublicKey=tblIdentity.PublicKey WHERE tblIdentity.IdentityID IS NULL;");\r
+ st.Step();\r
+ if(!st.RowReturned())\r
+ {\r
+ limitnum="5";\r
+ }\r
+ st.Finalize();\r
\r
now.SetToGMTime();\r
\r
- // select identities that aren't single use and have been seen today\r
- SQLite3DB::Statement st=m_db->Prepare("SELECT IdentityID FROM tblIdentity WHERE PublicKey IS NOT NULL AND PublicKey <> '' AND SingleUse='false' AND LastSeen>='"+now.Format("%Y-%m-%d")+"';");\r
+ // select identities that aren't single use and have been seen today ( order by trust DESC and limit to limitnum )\r
+ st=m_db->Prepare("SELECT IdentityID FROM tblIdentity WHERE PublicKey IS NOT NULL AND PublicKey <> '' AND SingleUse='false' AND LastSeen>='"+now.Format("%Y-%m-%d")+"' ORDER BY LocalMessageTrust LIMIT 0,"+limitnum+";");\r
st.Step();\r
\r
m_ids.clear();\r
\r
if(!td.Error())\r
{\r
- TiXmlElement *el;\r
TiXmlText *txt;\r
TiXmlHandle hnd(&td);\r
\r
MessageXML xml;\r
long identityid;\r
long index;\r
+ bool inserted=false;\r
\r
StringFunctions::Split(message["Identifier"],"|",idparts);\r
StringFunctions::Convert(message["DataLength"],datalength);\r
st.Bind(5,xml.GetMessageID());\r
st.Bind(6,GetBoardID(xml.GetReplyBoard()));\r
st.Bind(7,xml.GetBody());\r
- st.Step(true);\r
+ inserted=st.Step(true);\r
int messageid=st.GetLastInsertRowID();\r
\r
- st=m_db->Prepare("INSERT INTO tblMessageBoard(MessageID,BoardID) VALUES(?,?);");\r
- for(std::vector<std::string>::iterator i=boards.begin(); i!=boards.end(); i++)\r
+ if(inserted==true)\r
{\r
- st.Bind(0,messageid);\r
- st.Bind(1,GetBoardID((*i)));\r
- st.Step();\r
- st.Reset();\r
- }\r
- st.Finalize();\r
\r
- st=m_db->Prepare("INSERT INTO tblMessageReplyTo(MessageID,ReplyToMessageUUID,ReplyOrder) VALUES(?,?,?);");\r
- std::map<long,std::string> replyto=xml.GetInReplyTo();\r
- for(std::map<long,std::string>::iterator j=replyto.begin(); j!=replyto.end(); j++)\r
+ st=m_db->Prepare("INSERT INTO tblMessageBoard(MessageID,BoardID) VALUES(?,?);");\r
+ for(std::vector<std::string>::iterator i=boards.begin(); i!=boards.end(); i++)\r
+ {\r
+ st.Bind(0,messageid);\r
+ st.Bind(1,GetBoardID((*i)));\r
+ st.Step();\r
+ st.Reset();\r
+ }\r
+ st.Finalize();\r
+\r
+ st=m_db->Prepare("INSERT INTO tblMessageReplyTo(MessageID,ReplyToMessageUUID,ReplyOrder) VALUES(?,?,?);");\r
+ std::map<long,std::string> replyto=xml.GetInReplyTo();\r
+ for(std::map<long,std::string>::iterator j=replyto.begin(); j!=replyto.end(); j++)\r
+ {\r
+ st.Bind(0,messageid);\r
+ st.Bind(1,(*j).second);\r
+ st.Bind(2,(*j).first);\r
+ st.Step();\r
+ st.Reset();\r
+ }\r
+ st.Finalize();\r
+\r
+ m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageRequester::HandleAllData parsed Message XML file : "+message["Identifier"]);\r
+\r
+ }\r
+ else // couldn't insert - was already in database\r
{\r
- st.Bind(0,messageid);\r
- st.Bind(1,(*j).second);\r
- st.Bind(2,(*j).first);\r
- st.Step();\r
- st.Reset();\r
+ m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"MessageRequester::HandleAddData could not insert message into database. "+message["Identifier"]);\r
}\r
- st.Finalize();\r
-\r
- m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageRequester::HandleAllData parsed Message XML file : "+message["Identifier"]);\r
\r
}\r
else\r
m_fcp->SendMessage(message);\r
\r
m_requesting.push_back(requestid);\r
+\r
+ m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageRequester::StartRequest requesting "+message["Identifier"]);\r
}\r
\r
m_ids[requestid]=true;\r
if(!td.Error())\r
{\r
TiXmlHandle hnd(&td);\r
- TiXmlNode *node1;\r
TiXmlNode *node2;\r
TiXmlText *txt;\r
\r
--- /dev/null
+#include "../../include/freenet/periodicdbmaintenance.h"\r
+\r
+#ifdef XMEM\r
+ #include <xmem.h>\r
+#endif\r
+\r
+PeriodicDBMaintenance::PeriodicDBMaintenance()\r
+{\r
+ m_check10mins.SetToGMTime();\r
+ m_check30mins.SetToGMTime();\r
+ m_check1hour.SetToGMTime();\r
+ m_check6hours.SetToGMTime();\r
+ m_check1day.SetToGMTime();\r
+\r
+ // set back times so they will do their first maintenance soon ( within the next hour ) - stagger so not all run at once\r
+ m_check1hour.Add(0,-45);\r
+ m_check6hours.Add(0,0,-5);\r
+ m_check1day.Add(0,0,-23);\r
+\r
+}\r
+\r
+void PeriodicDBMaintenance::Do10MinuteMaintenance()\r
+{\r
+\r
+ m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"PeriodicDBMaintenance::Do10MinuteMaintenance");\r
+}\r
+\r
+void PeriodicDBMaintenance::Do30MinuteMaintenance()\r
+{\r
+\r
+ m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"PeriodicDBMaintenance::Do30MinuteMaintenance");\r
+}\r
+\r
+void PeriodicDBMaintenance::Do1HourMaintenance()\r
+{\r
+ // recalculate all trust levels - this is CPU instensive\r
+ // TODO - will probably have to change this to do 1 identity at a time as this locks that database for the duration\r
+ m_db->Execute("UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID);");\r
+\r
+ m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"PeriodicDBMaintenance::Do1HourMaintenance");\r
+}\r
+\r
+void PeriodicDBMaintenance::Do6HourMaintenance()\r
+{\r
+\r
+ m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"PeriodicDBMaintenance::Do6HourMaintenance");\r
+}\r
+\r
+void PeriodicDBMaintenance::Do1DayMaintenance()\r
+{\r
+ DateTime date;\r
+\r
+ // delete all puzzles 2 or more days old\r
+ date.SetToGMTime();\r
+ date.Add(0,0,0,-2);\r
+ m_db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day<='"+date.Format("%Y-%m-%d")+"';");\r
+ m_db->Execute("DELETE FROM tblIntroductionPuzzleRequests WHERE Day<='"+date.Format("%Y-%m-%d")+"';");\r
+\r
+ m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"PeriodicDBMaintenance::Do1DayMaintenance");\r
+\r
+}\r
+\r
+void PeriodicDBMaintenance::Process()\r
+{\r
+ DateTime now;\r
+ now.SetToGMTime();\r
+ \r
+ if(m_check10mins<=(now-((1.0/1440.0)*10.0)))\r
+ {\r
+ Do10MinuteMaintenance();\r
+ m_check10mins=now;\r
+ }\r
+ if(m_check30mins<=(now-((1.0/1440.0)*30.0)))\r
+ {\r
+ Do30MinuteMaintenance();\r
+ m_check30mins=now;\r
+ }\r
+ if(m_check1hour<=(now-(1.0/24.0)))\r
+ {\r
+ Do1HourMaintenance();\r
+ m_check1hour=now;\r
+ }\r
+ if(m_check6hours<=(now-(1.0/4.0)))\r
+ {\r
+ Do6HourMaintenance();\r
+ m_check6hours=now;\r
+ }\r
+ if(m_check1day<=(now-(1.0)))\r
+ {\r
+ Do1DayMaintenance();\r
+ m_check1day=now;\r
+ }\r
+\r
+}\r
+\r
+void PeriodicDBMaintenance::RegisterWithThread(FreenetMasterThread *thread)\r
+{\r
+ thread->RegisterPeriodicProcessor(this);\r
+}\r
{\r
DateTime date;\r
date.SetToGMTime();\r
- date.Add(0,0,-1);\r
+ int currentday=date.GetDay();\r
+ date.Add(0,0,-6);\r
+ // insert trust lists every 6 hours - if 6 hours ago was different day then set to midnight of current day to insert list today ASAP\r
+ if(currentday!=date.GetDay())\r
+ {\r
+ date.Set(date.GetYear(),date.GetMonth(),currentday);\r
+ }\r
SQLite3DB::Recordset rs=m_db->Query("SELECT LocalIdentityID, PrivateKey FROM tblLocalIdentity WHERE PrivateKey IS NOT NULL AND PrivateKey <> '' AND PublishTrustList='true' AND InsertingTrustList='false' AND (LastInsertedTrustList<='"+date.Format("%Y-%m-%d %H:%M:%S")+"' OR LastInsertedTrustList IS NULL);");\r
\r
if(rs.Empty()==false)\r
// select identities we want to query (we've seen them today and they are publishing trust list) - sort by their trust level (descending) with secondary sort on how long ago we saw them (ascending)\r
sql="SELECT IdentityID FROM tblIdentity ";\r
sql+="WHERE Name IS NOT NULL AND Name <> '' AND PublicKey IS NOT NULL AND PublicKey <> '' AND LastSeen>='"+date.Format("%Y-%m-%d")+"' AND PublishTrustList='true' AND LocalTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalTrustListTrust') AND ( PeerTrustListTrust IS NULL OR PeerTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerTrustListTrust') )";\r
- sql+="ORDER BY LocalMessageTrust+LocalTrustListTrust DESC, LastSeen;";\r
+ sql+="ORDER BY LocalTrustListTrust DESC, LastSeen;";\r
\r
SQLite3DB::Statement st=m_db->Prepare(sql);\r
st.Step();\r
db->Open("fms.db3");\r
db->SetBusyTimeout(10000); // set timeout to 10 seconds\r
db->Execute("VACUUM;");\r
+ \r
+ // TODO remove this - temp fix for problem in 0.1.8\r
+ db->Execute("DELETE FROM tblMessageBoard WHERE MessageID NOT IN (SELECT MessageID FROM tblMessage);");\r
+\r
+ db->Execute("CREATE TABLE IF NOT EXISTS tblDBVersion(\\r
+ Major INTEGER,\\r
+ Minor INTEGER\\r
+ );");\r
+\r
+ SQLite3DB::Statement st=db->Prepare("SELECT Major,Minor FROM tblDBVersion;");\r
+ st.Step();\r
+ if(st.RowReturned())\r
+ {\r
+ int major;\r
+ int minor;\r
+ st.ResultInt(0,major);\r
+ st.ResultInt(1,minor);\r
+ }\r
+ else\r
+ {\r
+ db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,0);");\r
+ }\r
\r
db->Execute("CREATE TABLE IF NOT EXISTS tblOption(\\r
Option TEXT UNIQUE,\\r
Inserted BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
);");\r
\r
+ db->Execute("CREATE TABLE IF NOT EXISTS tblAdministrationBoard(\\r
+ BoardID INTEGER UNIQUE,\\r
+ ModifyLocalMessageTrust INTEGER,\\r
+ ModifyLocalTrustListTrust INTEGER\\r
+ );");\r
+\r
// MessageInserter will insert a record into this temp table which the MessageListInserter will query for and insert a MessageList when needed\r
db->Execute("CREATE TEMPORARY TABLE IF NOT EXISTS tmpMessageListInsert(\\r
LocalIdentityID INTEGER,\\r
AND ( PeerTrustListTrust IS NULL OR PeerTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerTrustListTrust') ) \\r
GROUP BY TargetIdentityID;");\r
\r
+ /*\r
+ These peer trust calculations are too CPU intensive to be triggers - they were called every time a new trust list was processed\r
+ All trust levels will now be recalculated every hour in the PeriodicDBMaintenance class\r
+ */\r
+ // drop existing triggers\r
+ db->Execute("DROP TRIGGER IF EXISTS trgDeleteOntblPeerTrust;");\r
+ db->Execute("DROP TRIGGER IF EXISTS trgInsertOntblPeerTrust;");\r
+ db->Execute("DROP TRIGGER IF EXISTS trgUpdateOntblPeerTrust;");\r
+ db->Execute("DROP TRIGGER IF EXISTS trgUpdateLocalTrustLevels;");\r
+/*\r
// update PeerTrustLevel when deleting a record from tblPeerTrust\r
db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteOntblPeerTrust AFTER DELETE ON tblPeerTrust \\r
FOR EACH ROW \\r
BEGIN \\r
UPDATE tblIdentity SET PeerMessageTrust=(SELECT PeerMessageTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID), PeerTrustListTrust=(SELECT PeerTrustListTrust FROM vwCalculatedPeerTrust WHERE TargetIdentityID=IdentityID);\\r
END;");\r
+*/\r
\r
db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteMessage AFTER DELETE ON tblMessage \\r
FOR EACH ROW \\r
st.Reset();\r
\r
st.Bind(0,"MinLocalTrustListTrust");\r
- st.Bind(1,"50");\r
+ st.Bind(1,"51");\r
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
st.Step();\r
st.Reset();\r
#include "../../include/http/pages/announceidentitypage.h"\r
#include "../../include/http/pages/addpeerpage.h"\r
#include "../../include/http/pages/peertrustpage.h"\r
+#include "../../include/http/pages/controlboardpage.h"\r
\r
#include <iostream>\r
\r
m_pagehandlers.push_back(new AnnounceIdentityPage(templatestr));\r
m_pagehandlers.push_back(new AddPeerPage(templatestr));\r
m_pagehandlers.push_back(new PeerTrustPage(templatestr));\r
+ m_pagehandlers.push_back(new ControlBoardPage(templatestr));\r
// homepage must be last - catch all page handler\r
m_pagehandlers.push_back(new HomePage(templatestr));\r
\r
// we have all POST data (or it was 0 to begin with) - generate the page\r
if(mystate->m_indatalen==mystate->m_indatapos && mystate->m_outdata==NULL)\r
{\r
- //TODO parse POST data and any QUERY_STRING before generating page\r
+ //parse POST data and any QUERY_STRING before generating page\r
std::map<std::string,std::string> args;\r
std::vector<std::string> argparts;\r
\r
return false;\r
}\r
}\r
+\r
+const std::string IPageHandler::SanitizeOutput(const std::string &input)\r
+{\r
+ // must do & first because all other elements have & in them!\r
+ std::string output=StringFunctions::Replace(input,"&","&");\r
+ output=StringFunctions::Replace(output,"<","<");\r
+ output=StringFunctions::Replace(output,">",">");\r
+ output=StringFunctions::Replace(output,"\"",""");\r
+ output=StringFunctions::Replace(output," "," ");\r
+ return output;\r
+}\r
content+="<tr><td colspan=\"4\"><center>Type the answers of a few puzzles</td></tr>";\r
content+="<tr>";\r
\r
+ //TODO if we are already inserting a solution for an identity - we shouldn't select any puzzles that are older than the one we are inserting\r
+\r
date.SetToGMTime();\r
date.Add(0,0,0,-1);\r
SQLite3DB::Statement st=m_db->Prepare("SELECT UUID,Day,IdentityID FROM tblIntroductionPuzzleRequests WHERE UUID NOT IN (SELECT UUID FROM tblIdentityIntroductionInserts) AND UUID NOT IN (SELECT UUID FROM tblIntroductionPuzzleInserts) AND Day>='"+date.Format("%Y-%m-%d")+"' AND Found='true' ORDER BY IdentityID, Day DESC, RequestIndex DESC;");\r
--- /dev/null
+#include "../../../include/http/pages/controlboardpage.h"\r
+#include "../../../include/stringfunctions.h"\r
+#include "../../../include/datetime.h"\r
+\r
+#ifdef XMEM\r
+ #include <xmem.h>\r
+#endif\r
+\r
+const std::string ControlBoardPage::GeneratePage(const std::string &method, const std::map<std::string,std::string> &queryvars)\r
+{\r
+ std::string content="";\r
+ int boardid;\r
+ std::string boardidstr;\r
+ std::string boardname;\r
+ int changemessagetrust=0;\r
+ int changetrustlisttrust=0;\r
+ std::string changemessagetruststr;\r
+ std::string changetrustlisttruststr;\r
+\r
+ SQLite3DB::Statement st;\r
+\r
+ if(queryvars.find("formaction")!=queryvars.end())\r
+ {\r
+ if((*queryvars.find("formaction")).second=="remove" && queryvars.find("boardid")!=queryvars.end())\r
+ {\r
+ int boardid=0;\r
+ StringFunctions::Convert((*queryvars.find("boardid")).second,boardid);\r
+\r
+ st=m_db->Prepare("DELETE FROM tblAdministrationBoard WHERE BoardID=?;");\r
+ st.Bind(0,boardid);\r
+ st.Step();\r
+\r
+ st=m_db->Prepare("DELETE FROM tblBoard WHERE BoardID=?;");\r
+ st.Bind(0,boardid);\r
+ st.Step();\r
+\r
+ st=m_db->Prepare("DELETE FROM tblMessage WHERE MessageUUID IN (SELECT MessageUUID FROM tblMessage INNER JOIN tblMessageBoard ON tblMessage.MessageID=tblMessageBoard.MessageID WHERE BoardID=?);");\r
+ st.Bind(0,boardid);\r
+ st.Step();\r
+\r
+ st=m_db->Prepare("DELETE FROm tblMessageBoard WHERE BoardID=?;");\r
+ st.Bind(0,boardid);\r
+ st.Step();\r
+\r
+ }\r
+ if((*queryvars.find("formaction")).second=="addboard" && queryvars.find("boardname")!=queryvars.end() && (*queryvars.find("boardname")).second!="")\r
+ {\r
+ DateTime date;\r
+ date.SetToGMTime();\r
+ st=m_db->Prepare("INSERT INTO tblBoard(BoardName,DateAdded) VALUES(?,?);");\r
+ st.Bind(0,(*queryvars.find("boardname")).second);\r
+ st.Bind(1,date.Format("%Y-%m-%d %H:%M:%S"));\r
+ if(st.Step(true))\r
+ {\r
+ boardid=st.GetLastInsertRowID();\r
+ StringFunctions::Convert((*queryvars.find("changemessagetrust")).second,changemessagetrust);\r
+ StringFunctions::Convert((*queryvars.find("changetrustlisttrust")).second,changetrustlisttrust);\r
+\r
+ st=m_db->Prepare("INSERT INTO tblAdministrationBoard(BoardID,ModifyLocalMessageTrust,ModifyLocalTrustListTrust) VALUES(?,?,?);");\r
+ st.Bind(0,boardid);\r
+ st.Bind(1,changemessagetrust);\r
+ st.Bind(2,changetrustlisttrust);\r
+ st.Step();\r
+\r
+ }\r
+ }\r
+ }\r
+\r
+ content+="<h2>Control Boards</h2>";\r
+ content+="<p class=\"paragraph\">";\r
+ content+="These boards are special administration boards where sent messages will change the trust levels of the parent poster. These boards can not be used as regular boards, so make the name unique. The change in trust levels can be negative or positive, but keep in mind that the minimum trust level is 0 and the maximum trust level is 100. After the boards are created here, you may use your newreader to reply to a message to one or more of these boards, and the previous poster will have his trust levels changed as per the settings for that board.";\r
+ content+="</p>";\r
+\r
+ st=m_db->Prepare("SELECT tblBoard.BoardID,BoardName,ModifyLocalMessageTrust,ModifyLocalTrustListTrust FROM tblBoard INNER JOIN tblAdministrationBoard ON tblBoard.BoardID=tblAdministrationBoard.BoardID ORDER BY BoardName COLLATE NOCASE;");\r
+ st.Step();\r
+\r
+ content+="<table>";\r
+ content+="<tr><th>Board Name</th><th>Change Message Trust</th><th>Change Trust List Trust</th></tr>\r\n";\r
+ while(st.RowReturned())\r
+ {\r
+ st.ResultText(0,boardidstr);\r
+ st.ResultText(1,boardname);\r
+ st.ResultText(2,changemessagetruststr);\r
+ st.ResultText(3,changetrustlisttruststr);\r
+\r
+ content+="<tr>";\r
+ content+="<td>"+boardname+"</td>\r\n";\r
+ content+="<td>"+changemessagetruststr+"</td>\r\n";\r
+ content+="<td>"+changetrustlisttruststr+"</td>\r\n";\r
+ content+="<td>";\r
+ content+="<form name=\"frmremove\" method=\"POST\">";\r
+ content+="<input type=\"hidden\" name=\"formaction\" value=\"remove\">";\r
+ content+="<input type=\"hidden\" name=\"boardid\" value=\""+boardidstr+"\">";\r
+ content+="<input type=\"submit\" value=\"Remove\">";\r
+ content+="</form>";\r
+ content+="</td>";\r
+ content+="</tr>\r\n";\r
+ st.Step();\r
+ }\r
+\r
+ content+="<tr>";\r
+ content+="<td>";\r
+ content+="<form name=\"frmaddboard\" method=\"POST\">";\r
+ content+="<input type=\"hidden\" name=\"formaction\" value=\"addboard\">";\r
+ content+="<input type=\"text\" name=\"boardname\">";\r
+ content+="</td>\r\n<td>";\r
+ content+="<input type=\"text\" name=\"changemessagetrust\" size=\"2\" maxlength=\"3\">";\r
+ content+="</td>\r\n<td>";\r
+ content+="<input type=\"text\" name=\"changetrustlisttrust\" size=\"2\" maxlength=\"3\">";\r
+ content+="</td>\r\n<td>";\r
+ content+="<input type=\"submit\" value=\"Add\">";\r
+ content+="</form>";\r
+ content+="</td>\r\n";\r
+ content+="</tr>";\r
+ content+="</table>";\r
+\r
+ return "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"+StringFunctions::Replace(m_template,"[CONTENT]",content);\r
+}\r
+\r
+const bool ControlBoardPage::WillHandleURI(const std::string &uri)\r
+{\r
+ if(uri.find("controlboard.")!=std::string::npos)\r
+ {\r
+ return true;\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+}\r
std::string publickey;\r
std::string publishtrustlist;\r
std::string singleuse;\r
+ std::string keypart;\r
\r
st.ResultText(0,id);\r
st.ResultText(1,name);\r
st.ResultText(3,publishtrustlist);\r
st.ResultText(4,singleuse);\r
\r
+ if(publickey.size()>8)\r
+ {\r
+ keypart=publickey.substr(3,5);\r
+ }\r
+\r
content+="<tr>";\r
content+="<td><input type=\"checkbox\" name=\"chkidentityid["+countstr+"]\" value=\""+id+"\"></td>";\r
- content+="<td title=\""+publickey+"\">"+name+"</td>";\r
+ content+="<td title=\""+publickey+"\">"+SanitizeOutput(name+keypart)+"...</td>";\r
content+="<td>"+CreateTrueFalseDropDown("singleuse["+countstr+"]",singleuse)+"</td>";\r
content+="<td>"+CreateTrueFalseDropDown("publishtrustlist["+countstr+"]",publishtrustlist)+"</td>";\r
if(st.ResultNull(6))\r
std::string localtrustlisttrust;\r
std::string peertrustlisttrust;\r
std::string publickey;\r
+ std::string keypart="";\r
\r
StringFunctions::Convert(count,countstr);\r
\r
st.ResultText(5,peertrustlisttrust);\r
st.ResultText(6,publickey);\r
\r
+ if(publickey.size()>8)\r
+ {\r
+ keypart=publickey.substr(3,5);\r
+ }\r
+\r
content+="<tr>";\r
content+="<td title=\""+publickey+"\">";\r
content+="<input type=\"hidden\" name=\"identityid["+countstr+"]\" value=\""+identityid+"\">";\r
if(name!="")\r
{\r
- content+=name;\r
+ content+=SanitizeOutput(name+keypart)+"...";\r
}\r
else\r
{\r
\r
if(startrow>0 || startrow+rowsperpage<identitycount)\r
{\r
- int tempint;\r
std::string tempstr;\r
int cols=0;\r
\r
SetupDB();\r
SetupDefaultOptions();\r
\r
-\r
SetupLogFile();\r
\r
SetupNetwork();\r
Load(messageid);\r
}\r
\r
+const bool Message::CheckForAdministrationBoard(const std::vector<std::string> &boards)\r
+{\r
+ std::string name;\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT BoardName FROM tblBoard INNER JOIN tblAdministrationBoard ON tblBoard.BoardID=tblAdministrationBoard.BoardID;");\r
+ st.Step();\r
+ \r
+ while(st.RowReturned())\r
+ {\r
+ st.ResultText(0,name);\r
+\r
+ if(std::find(boards.begin(),boards.end(),name)!=boards.end())\r
+ {\r
+ return true;\r
+ }\r
+ \r
+ st.Step();\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
const std::string Message::GetNNTPArticleID() const\r
{\r
return "<"+m_messageuuid+"@freenetproject.org>";\r
return rval;\r
}\r
\r
+void Message::HandleAdministrationMessage()\r
+{\r
+ // only continue if this message was actually a reply to another message\r
+ if(m_inreplyto.size()>0)\r
+ {\r
+ int boardid=0;\r
+ std::string boardname="";\r
+ std::string identityname="";\r
+ int identityid;\r
+ int changemessagetrust=0;\r
+ int changetrustlisttrust=0;\r
+ int origmessagetrust=0;\r
+ int origtrustlisttrust=0;\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT tblBoard.BoardID,BoardName,ModifyLocalMessageTrust,ModifyLocalTrustListTrust FROM tblBoard INNER JOIN tblAdministrationBoard ON tblBoard.BoardID=tblAdministrationBoard.BoardID;");\r
+ st.Step();\r
+\r
+ while(st.RowReturned())\r
+ {\r
+ st.ResultInt(0,boardid);\r
+ st.ResultText(1,boardname);\r
+ st.ResultInt(2,changemessagetrust);\r
+ st.ResultInt(3,changetrustlisttrust);\r
+\r
+ if(std::find(m_boards.begin(),m_boards.end(),boardname)!=m_boards.end())\r
+ {\r
+ SQLite3DB::Statement origmess=m_db->Prepare("SELECT tblIdentity.IdentityID,tblIdentity.Name,tblIdentity.LocalMessageTrust,tblIdentity.LocalTrustListTrust FROM tblIdentity INNER JOIN tblMessage ON tblIdentity.IdentityID=tblMessage.IdentityID WHERE tblMessage.MessageUUID=?;");\r
+ origmess.Bind(0,m_inreplyto[0]);\r
+ origmess.Step();\r
+\r
+ if(origmess.RowReturned())\r
+ {\r
+ origmess.ResultInt(0,identityid);\r
+ origmess.ResultText(1,identityname);\r
+ origmess.ResultInt(2,origmessagetrust);\r
+ origmess.ResultInt(3,origtrustlisttrust);\r
+\r
+ origmessagetrust+=changemessagetrust;\r
+ origtrustlisttrust+=changetrustlisttrust;\r
+\r
+ if(origmessagetrust<0)\r
+ {\r
+ origmessagetrust=0;\r
+ }\r
+ if(origmessagetrust>100)\r
+ {\r
+ origmessagetrust=100;\r
+ }\r
+ if(origtrustlisttrust<0)\r
+ {\r
+ origtrustlisttrust=0;\r
+ }\r
+ if(origtrustlisttrust>100)\r
+ {\r
+ origtrustlisttrust=100;\r
+ }\r
+\r
+ // update new trust levels\r
+ SQLite3DB::Statement update=m_db->Prepare("UPDATE tblIdentity SET LocalMessageTrust=?, LocalTrustListTrust=? WHERE IdentityID=?;");\r
+ update.Bind(0,origmessagetrust);\r
+ update.Bind(1,origtrustlisttrust);\r
+ update.Bind(2,identityid);\r
+ update.Step();\r
+\r
+ // insert message to show what id was changed and what current levels are\r
+ int lastid=0;\r
+ std::string messagebody;\r
+ std::string messagetruststr="";\r
+ std::string trustlisttruststr="";\r
+ UUIDGenerator uuid;\r
+ DateTime now;\r
+ now.SetToGMTime();\r
+ StringFunctions::Convert(origmessagetrust,messagetruststr);\r
+ StringFunctions::Convert(origtrustlisttrust,trustlisttruststr);\r
+ messagebody="Trust Changed for "+identityname+"\r\n";\r
+ messagebody+="Local Message Trust : "+messagetruststr+"\r\n";\r
+ messagebody+="Local Trust List Trust : "+trustlisttruststr+"\r\n";\r
+ SQLite3DB::Statement insert=m_db->Prepare("INSERT INTO tblMessage(FromName,MessageDate,MessageTime,Subject,MessageUUID,ReplyBoardID,Body) VALUES('FMS',?,?,?,?,?,?);");\r
+ insert.Bind(0,now.Format("%Y-%m-%d"));\r
+ insert.Bind(1,now.Format("%H:%M:%S"));\r
+ insert.Bind(2,identityname+" Trust Changed");\r
+ insert.Bind(3,uuid.Generate());\r
+ insert.Bind(4,boardid);\r
+ insert.Bind(5,messagebody);\r
+ insert.Step(true);\r
+ lastid=insert.GetLastInsertRowID();\r
+\r
+ insert=m_db->Prepare("INSERT INTO tblMessageBoard(MessageID,BoardID) VALUES(?,?);");\r
+ insert.Bind(0,lastid);\r
+ insert.Bind(1,boardid);\r
+ insert.Step();\r
+\r
+ m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"Message::HandleAdministrationMessage updated "+identityname+" to "+messagetruststr+" , "+trustlisttruststr);\r
+\r
+ }\r
+ }\r
+\r
+ st.Step();\r
+ }\r
+ }\r
+\r
+}\r
+\r
void Message::Initialize()\r
{\r
m_messageid=-1;\r
\r
void Message::StartFreenetInsert()\r
{\r
+ //TODO if message was posted to one of the special administration boards - don't really insert it, but perform the action\r
MessageXML xml;\r
int localidentityid=-1;\r
\r
char buf[80];\r
if (!pszBoundary) // generate a new boundary delimeter\r
{\r
- ::srand(((unsigned)::time(NULL)) ^ (unsigned)this);\r
+ ::srand(((unsigned)::time(NULL)) ^ reinterpret_cast<unsigned>(this));\r
::sprintf(buf, "__=_Part_Boundary_%03d_%06d.%06d", ++s_nPartNumber, rand(), rand());\r
if (s_nPartNumber >= 9)\r
s_nPartNumber = 0;\r
std::ostringstream tempstr;\r
Board board;\r
bool validgroup=false;\r
- int tempint;\r
int lownum=-1;\r
int highnum=-1;\r
\r
\r
if(mess.ParseNNTPMessage(message))\r
{\r
- mess.StartFreenetInsert();\r
+ if(mess.PostedToAdministrationBoard()==true)\r
+ {\r
+ mess.HandleAdministrationMessage();\r
+ }\r
+ else\r
+ {\r
+ mess.StartFreenetInsert();\r
+ }\r
SendBufferedLine("240 Article received OK");\r
}\r
else\r
newsock=accept((*listeni),(struct sockaddr *)&addr,&addrlen);\r
LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_INFO,"NNTPListener::run NNTP client connected");\r
//m_connections.execute(new NNTPConnection(newsock));\r
- m_connectionthreads.push_back(new PThread::Thread(new NNTPConnection(newsock)));\r
+ //m_connectionthreads.push_back(new PThread::Thread(new NNTPConnection(newsock)));\r
+ m_connections.Execute(new NNTPConnection(newsock));\r
}\r
}\r
}\r
-\r
+/*\r
// check for any non-running connection threads that we can delete\r
for(std::vector<PThread::Thread *>::iterator i=m_connectionthreads.begin(); i!=m_connectionthreads.end(); )\r
{\r
i++;\r
}\r
}\r
+*/\r
\r
//}while(!ZThread::Thread::interrupted() && m_listensockets.size()>0);\r
}while(!IsCancelled() && m_listensockets.size()>0);\r
}\r
}\r
*/\r
+ /*\r
for(std::vector<PThread::Thread *>::iterator i=m_connectionthreads.begin(); i!=m_connectionthreads.end(); i++)\r
{\r
if((*i)->IsRunning())\r
}\r
delete (*i);\r
}\r
+ */\r
+ m_connections.Cancel();\r
+ m_connections.Join();\r
\r
for(listeni=m_listensockets.begin(); listeni!=m_listensockets.end(); listeni++)\r
{\r
m_running=false;\r
m_cancelled=false;\r
m_runnable=0;\r
+ m_threadnum=0;\r
}\r
\r
Thread::Thread(Runnable *runnable)\r
m_running=false;\r
m_cancelled=false;\r
m_runnable=runnable;\r
+ m_threadnum=0;\r
if(m_runnable)\r
{\r
m_runnable->m_thread=this;\r
((Thread *)pthis)->m_running=false;\r
((Thread *)pthis)->m_cancelled=false;\r
}\r
+ ((Thread *)pthis)->m_threadnum=0;\r
return NULL;\r
}\r
\r
void Thread::Start()\r
{\r
m_running=true;\r
- pthread_create(&m_thread,NULL,Thread::EntryPoint,this);\r
+ m_threadnum=pthread_create(&m_thread,NULL,Thread::EntryPoint,this);\r
}\r
\r
} // namespace\r
--- /dev/null
+#include "../../include/pthreadwrapper/threadedexecutor.h"\r
+\r
+#ifdef XMEM\r
+ #include <xmem.h>\r
+#endif\r
+\r
+namespace PThread\r
+{\r
+\r
+ThreadedExecutor::~ThreadedExecutor()\r
+{\r
+ for(std::vector<Thread *>::iterator i=m_threads.begin(); i!=m_threads.end(); i++)\r
+ {\r
+ (*i)->Cancel();\r
+ (*i)->Join();\r
+ delete (*i);\r
+ }\r
+}\r
+\r
+void ThreadedExecutor::Cancel()\r
+{\r
+ for(std::vector<Thread *>::iterator i=m_threads.begin(); i!=m_threads.end(); i++)\r
+ {\r
+ (*i)->Cancel(); \r
+ }\r
+}\r
+\r
+void ThreadedExecutor::CleanupFinished()\r
+{\r
+ for(std::vector<Thread *>::iterator i=m_threads.begin(); i!=m_threads.end(); )\r
+ {\r
+ if((*i)->IsRunning()==false)\r
+ {\r
+ delete (*i);\r
+ i=m_threads.erase(i);\r
+ }\r
+ else\r
+ {\r
+ i++;\r
+ }\r
+ }\r
+}\r
+\r
+void ThreadedExecutor::Execute(Runnable *runnable)\r
+{\r
+ CleanupFinished();\r
+ m_threads.push_back(new Thread(runnable)); \r
+}\r
+\r
+void ThreadedExecutor::Join()\r
+{\r
+ for(std::vector<Thread *>::iterator i=m_threads.begin(); i!=m_threads.end(); i++)\r
+ {\r
+ (*i)->Join();\r
+ }\r
+ CleanupFinished();\r
+}\r
+\r
+} // namespace\r
--- /dev/null
+#include "../include/threadcontroller.h"\r
+#include "../include/option.h"\r
+#include "../include/freenet/freenetmasterthread.h"\r
+#include "../include/nntp/nntplistener.h"\r
+#include "../include/http/httpthread.h"\r
+\r
+#ifdef XMEM\r
+ #include <xmem.h>\r
+#endif\r
+\r
+ThreadController::~ThreadController()\r
+{\r
+ ShutdownThreads();\r
+}\r
+\r
+void ThreadController::ReadConfig()\r
+{\r
+\r
+ std::string tempval="";\r
+ Option::Instance()->Get("StartFreenetUpdater",tempval);\r
+ if(tempval=="true")\r
+ {\r
+ m_startfreenet=true;\r
+ }\r
+ else\r
+ {\r
+ m_startfreenet=false;\r
+ }\r
+\r
+ tempval="";\r
+ Option::Instance()->Get("StartNNTP",tempval);\r
+ if(tempval=="true")\r
+ {\r
+ m_startnntp=true;\r
+ }\r
+ else\r
+ {\r
+ m_startnntp=false;\r
+ }\r
+\r
+ tempval="";\r
+ Option::Instance()->Get("StartHHTP",tempval);\r
+ if(tempval=="true")\r
+ {\r
+ m_starthttp=true;\r
+ }\r
+ else\r
+ {\r
+ m_starthttp=false;\r
+ }\r
+\r
+}\r
+\r
+void ThreadController::RestartThreads()\r
+{\r
+ ShutdownThreads();\r
+ StartThreads();\r
+}\r
+\r
+void ThreadController::ShutdownFreenetThread()\r
+{\r
+ if(m_freenetthread)\r
+ {\r
+ m_freenetthread->Cancel();\r
+ m_freenetthread->Join();\r
+ delete m_freenetthread;\r
+ m_freenetthread=NULL;\r
+ }\r
+}\r
+\r
+void ThreadController::ShutdownHTTPThread()\r
+{\r
+ if(m_httpthread)\r
+ {\r
+ m_httpthread->Cancel();\r
+ m_httpthread->Join();\r
+ delete m_httpthread;\r
+ m_httpthread=NULL;\r
+ }\r
+}\r
+\r
+void ThreadController::ShutdownNNTPThread()\r
+{\r
+ if(m_nntpthread)\r
+ {\r
+ m_nntpthread->Cancel();\r
+ m_nntpthread->Join();\r
+ delete m_nntpthread;\r
+ m_nntpthread=NULL;\r
+ }\r
+}\r
+\r
+void ThreadController::ShutdownThreads()\r
+{\r
+ ShutdownFreenetThread();\r
+ ShutdownNNTPThread();\r
+ ShutdownHTTPThread();\r
+}\r
+\r
+void ThreadController::StartFreenetThread()\r
+{\r
+ m_freenetthread=new PThread::Thread(new FreenetMasterThread());\r
+}\r
+\r
+void ThreadController::StartHTTPThread()\r
+{\r
+ m_httpthread=new PThread::Thread(new HTTPThread());\r
+}\r
+\r
+void ThreadController::StartNNTPThread()\r
+{\r
+ m_nntpthread=new PThread::Thread(new NNTPListener());\r
+}\r
+\r
+void ThreadController::StartThreads()\r
+{\r
+ ReadConfig();\r
+\r
+ if(m_startfreenet)\r
+ {\r
+ StartFreenetThread();\r
+ }\r
+ if(m_startnntp)\r
+ {\r
+ StartNNTPThread();\r
+ }\r
+ if(m_starthttp)\r
+ {\r
+ StartHTTPThread();\r
+ }\r
+}\r
+\r
.trust9 {background-color:#8aff97;}\r
.trust10 {background-color:#6dff9d;}\r
\r
+form { display:inline; }\r
+\r
</style>\r
</head>\r
\r
<li><a href="announceidentity.htm">Announce Identity</a></li>\r
<li><a href="addpeer.htm">Add Peer</a></li>\r
<li><a href="peertrust.htm">Peer Trust</a></li>\r
+ <li><a href="controlboard.htm">Control Boards</a></li>\r
</ul>\r
</div>\r
\r