#include <vector>\r
#include "pthreadwrapper/thread.h"\r
\r
-#define FMS_VERSION "0.2.13"\r
+#define FMS_VERSION "0.2.14"\r
\r
// opens database and creates tables and initial inserts if necessary\r
void SetupDB();\r
// cleanup network on Windows\r
void ShutdownNetwork();\r
\r
-extern bool wantshutdown;\r
+extern volatile bool wantshutdown;\r
\r
#endif // _global_\r
void HandleMultiPartData(const std::string &contenttypeheader, char *data, const long datalen, std::map<std::string,std::string> &args);\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
+ const std::string CreateTrueFalseDropDown(const std::string &name, const std::string &selected);\r
\r
// replaces html control characters with elements (i.e. < becomes <)\r
const std::string SanitizeOutput(const std::string &input);\r
#define _homepage_\r
\r
#include "../ipagehandler.h"\r
+#include "../../idatabase.h"\r
\r
-class HomePage:public IPageHandler\r
+class HomePage:public IPageHandler,public IDatabase\r
{\r
public:\r
HomePage(const std::string &templatestr):IPageHandler(templatestr) {}\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
- const std::string CreateTrueFalseDropDown(const std::string &name, const std::string &selected);\r
-\r
};\r
\r
#endif // _localidentitiespage_\r
#include "../include/fmsservice.h"\r
#include "../include/global.h"\r
+#include "../include/logfile.h"\r
\r
#include <string>\r
\r
case SERVICE_CONTROL_SHUTDOWN: \r
ServiceStatus.dwWin32ExitCode = 0; \r
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; \r
+ LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"ControlHandler service got shutdown request");\r
wantshutdown=true;\r
break; \r
\r
ServiceStatus.dwCurrentState = SERVICE_RUNNING;\r
SetServiceStatus (hStatus, &ServiceStatus);\r
\r
+ LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"ServiceMain starting service");\r
+\r
MainFunction();\r
\r
+ LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"ServiceMain stopping service");\r
+\r
ServiceStatus.dwCurrentState=SERVICE_STOPPED;\r
SetServiceStatus(hStatus,&ServiceStatus);\r
\r
+ LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"ServiceMain returning");\r
+\r
return; \r
}\r
\r
\r
void IntroductionPuzzleInserter::CheckForNeededInsert()\r
{\r
- // select all local ids that aren't single use and that aren't currently inserting a puzzle\r
- SQLite3DB::Recordset rs=m_db->Query("SELECT LocalIdentityID FROM tblLocalIdentity WHERE SingleUse='false' AND InsertingPuzzle='false' AND PrivateKey IS NOT NULL AND PrivateKey <> '' ORDER BY LastInsertedPuzzle;");\r
+ // select all local ids that aren't single use and that aren't currently inserting a puzzle and are publishing a trust list\r
+ SQLite3DB::Recordset rs=m_db->Query("SELECT LocalIdentityID FROM tblLocalIdentity WHERE PublishTrustList='true' AND SingleUse='false' AND InsertingPuzzle='false' AND PrivateKey IS NOT NULL AND PrivateKey <> '' ORDER BY LastInsertedPuzzle;");\r
\r
while(!rs.AtEnd())\r
{\r
\r
now.SetToGMTime();\r
\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 DESC LIMIT 0,"+limitnum+";");\r
+ // select identities that aren't single use, are publishing a trust list, and have been seen today ( order by trust DESC and limit to limitnum )\r
+ st=m_db->Prepare("SELECT IdentityID FROM tblIdentity WHERE PublishTrustList='true' AND PublicKey IS NOT NULL AND PublicKey <> '' AND SingleUse='false' AND LastSeen>='"+now.Format("%Y-%m-%d")+"' ORDER BY LocalMessageTrust DESC LIMIT 0,"+limitnum+";");\r
st.Step();\r
\r
m_ids.clear();\r
#include <xmem.h>\r
#endif\r
\r
-bool wantshutdown=false;\r
+volatile bool wantshutdown=false;\r
\r
std::string CreateShortIdentityName(const std::string &name, const std::string &publickey)\r
{\r
{\r
\r
DateTime date;\r
+ std::string tempval="";\r
SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
\r
db->Open("fms.db3");\r
db->SetBusyTimeout(10000); // set timeout to 10 seconds\r
- //db->Execute("VACUUM;"); // not needed every startup\r
+\r
+ tempval="";\r
+ Option::Instance()->Get("VacuumOnStartup",tempval);\r
+ if(tempval=="true")\r
+ {\r
+ db->Execute("VACUUM;");\r
+ }\r
\r
db->Execute("CREATE TABLE IF NOT EXISTS tblDBVersion(\\r
Major INTEGER,\\r
st.Step();\r
st.Reset();\r
\r
+ st.Bind(0,"VacuumOnStartup");\r
+ st.Bind(1,"false");\r
+ st.Bind(2,"VACUUM the database every time FMS starts. This will defragment the free space in the database and create a smaller database file. Vacuuming the database can be CPU and disk intensive.");\r
+ st.Step();\r
+ st.Reset();\r
+\r
}\r
\r
void SetupLogFile()\r
\r
void Shutdown()\r
{\r
+\r
+ LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"FMS starting shutdown");\r
+\r
ThreadController::Instance()->ShutdownThreads();\r
\r
ShutdownNetwork();\r
}\r
}\r
\r
+const std::string IPageHandler::CreateTrueFalseDropDown(const std::string &name, const std::string &selected)\r
+{\r
+ std::string rval="";\r
+\r
+ rval+="<select name=\""+name+"\">";\r
+ rval+="<option value=\"true\"";\r
+ if(selected=="true")\r
+ {\r
+ rval+=" SELECTED";\r
+ }\r
+ rval+=">true</option>";\r
+ rval+="<option value=\"false\"";\r
+ if(selected=="false")\r
+ {\r
+ rval+=" SELECTED";\r
+ }\r
+ rval+=">false</option>";\r
+ rval+="</select>";\r
+\r
+ return rval;\r
+}\r
+\r
const bool IPageHandler::Handle(shttpd_arg *arg)\r
{\r
const char *uri=shttpd_get_env(arg,"REQUEST_URI");\r
const std::string HomePage::GeneratePage(const std::string &method, const std::map<std::string,std::string> &queryvars)\r
{\r
\r
+ std::string messagecountstr="";\r
+ std::string filecountstr="";\r
+\r
if(queryvars.find("formaction")!=queryvars.end() && (*queryvars.find("formaction")).second=="shutdown")\r
{\r
wantshutdown=true;\r
content+="</b><br>";\r
content+="Use these pages to administer your FMS installation.";\r
content+="</p>";\r
+\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT COUNT(*) FROM tblMessageInserts WHERE Inserted='false';");\r
+ st.Step();\r
+ if(st.RowReturned())\r
+ {\r
+ st.ResultText(0,messagecountstr);\r
+ }\r
+ content+="Messages waiting to be inserted:"+messagecountstr+"<br>";\r
+ st=m_db->Prepare("SELECT COUNT(*) FROM tblFileInserts WHERE Key IS NULL;");\r
+ st.Step();\r
+ if(st.RowReturned())\r
+ {\r
+ st.ResultText(0,filecountstr);\r
+ }\r
+ content+="Files waiting to be inserted:"+filecountstr+"<br>";\r
+\r
content+="<p class=\"paragraph\">";\r
content+="<form name=\"frmshutdown\" method=\"POST\">";\r
content+="<input type=\"hidden\" name=\"formaction\" value=\"shutdown\">";\r
content+="<input type=\"submit\" value=\"Shutdown FMS\">";\r
content+="</form>";\r
content+="</p>";\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
#include <xmem.h>\r
#endif\r
\r
-const std::string LocalIdentitiesPage::CreateTrueFalseDropDown(const std::string &name, const std::string &selected)\r
-{\r
- std::string rval="";\r
-\r
- rval+="<select name=\""+name+"\">";\r
- rval+="<option value=\"true\"";\r
- if(selected=="true")\r
- {\r
- rval+=" SELECTED";\r
- }\r
- rval+=">true</option>";\r
- rval+="<option value=\"false\"";\r
- if(selected=="false")\r
- {\r
- rval+=" SELECTED";\r
- }\r
- rval+=">false</option>";\r
- rval+="</select>";\r
-\r
- return rval;\r
-}\r
-\r
const std::string LocalIdentitiesPage::GeneratePage(const std::string &method, const std::map<std::string,std::string> &queryvars)\r
{\r
int count;\r
content+="<tr>";\r
content+="<td valign=\"top\"><input type=\"hidden\" name=\"option["+countstr+"]\" value=\""+option+"\">"+option+"</td>";\r
content+="<td valign=\"top\"><input type=\"hidden\" name=\"oldvalue["+countstr+"]\" value=\""+value+"\">";\r
- content+="<input type=\"text\" name=\"value["+countstr+"]\" value=\""+value+"\"></td>";\r
+\r
+ if(value!="true" && value!="false")\r
+ {\r
+ content+="<input type=\"text\" name=\"value["+countstr+"]\" value=\""+value+"\"></td>";\r
+ }\r
+ else\r
+ {\r
+ content+=CreateTrueFalseDropDown("value["+countstr+"]",value);\r
+ }\r
+\r
content+="<td valign=\"top\">"+description+"</td>";\r
content+="</tr>";\r
st.Step();\r
{\r
return false;\r
}\r
-}
\ No newline at end of file
+}\r
PThread::Sleep(1000);\r
}while(!wantshutdown);\r
\r
+ LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"FMS wants to shutdown");\r
+\r
Shutdown();\r
}\r
MessageXML xml;\r
int localidentityid=-1;\r
\r
- xml.SetMessageID(m_messageuuid);\r
- xml.SetSubject(m_subject);\r
- xml.SetBody(m_body);\r
- xml.SetReplyBoard(m_replyboardname);\r
- xml.SetDate(m_datetime.Format("%Y-%m-%d"));\r
- xml.SetTime(m_datetime.Format("%H:%M:%S"));\r
- \r
StripAdministrationBoards();\r
- for(std::vector<std::string>::iterator i=m_boards.begin(); i!=m_boards.end(); i++)\r
- {\r
- xml.AddBoard((*i));\r
- }\r
- \r
- for(std::map<long,std::string>::iterator j=m_inreplyto.begin(); j!=m_inreplyto.end(); j++)\r
- {\r
- xml.AddInReplyTo((*j).first,(*j).second);\r
- }\r
\r
- localidentityid=FindLocalIdentityID(m_fromname);\r
- if(localidentityid==-1)\r
+ if(m_boards.size()>0)\r
{\r
- return false;\r
- }\r
\r
- SQLite3DB::Statement st=m_db->Prepare("INSERT INTO tblMessageInserts(LocalIdentityID,MessageUUID,MessageXML) VALUES(?,?,?);");\r
- st.Bind(0,localidentityid);\r
- st.Bind(1,m_messageuuid);\r
- st.Bind(2,xml.GetXML());\r
- st.Step();\r
+ xml.SetMessageID(m_messageuuid);\r
+ xml.SetSubject(m_subject);\r
+ xml.SetBody(m_body);\r
+ xml.SetReplyBoard(m_replyboardname);\r
+ xml.SetDate(m_datetime.Format("%Y-%m-%d"));\r
+ xml.SetTime(m_datetime.Format("%H:%M:%S"));\r
+ \r
+ for(std::vector<std::string>::iterator i=m_boards.begin(); i!=m_boards.end(); i++)\r
+ {\r
+ xml.AddBoard((*i));\r
+ }\r
+ \r
+ for(std::map<long,std::string>::iterator j=m_inreplyto.begin(); j!=m_inreplyto.end(); j++)\r
+ {\r
+ xml.AddInReplyTo((*j).first,(*j).second);\r
+ }\r
\r
- // insert file attachments into database\r
- st=m_db->Prepare("INSERT INTO tblFileInserts(MessageUUID,FileName,Size,MimeType,Data) VALUES(?,?,?,?,?);");\r
- for(std::vector<fileattachment>::iterator i=m_fileattachments.begin(); i!=m_fileattachments.end(); i++)\r
- {\r
- st.Bind(0,m_messageuuid);\r
- st.Bind(1,(*i).m_filename);\r
- st.Bind(2,(long)(*i).m_data.size());\r
- st.Bind(3,(*i).m_mimetype);\r
- st.Bind(4,&((*i).m_data[0]),(*i).m_data.size());\r
+ localidentityid=FindLocalIdentityID(m_fromname);\r
+ if(localidentityid==-1)\r
+ {\r
+ return false;\r
+ }\r
+\r
+ SQLite3DB::Statement st=m_db->Prepare("INSERT INTO tblMessageInserts(LocalIdentityID,MessageUUID,MessageXML) VALUES(?,?,?);");\r
+ st.Bind(0,localidentityid);\r
+ st.Bind(1,m_messageuuid);\r
+ st.Bind(2,xml.GetXML());\r
st.Step();\r
- st.Reset();\r
- }\r
\r
- HandleChangeTrust();\r
+ // insert file attachments into database\r
+ st=m_db->Prepare("INSERT INTO tblFileInserts(MessageUUID,FileName,Size,MimeType,Data) VALUES(?,?,?,?,?);");\r
+ for(std::vector<fileattachment>::iterator i=m_fileattachments.begin(); i!=m_fileattachments.end(); i++)\r
+ {\r
+ st.Bind(0,m_messageuuid);\r
+ st.Bind(1,(*i).m_filename);\r
+ st.Bind(2,(long)(*i).m_data.size());\r
+ st.Bind(3,(*i).m_mimetype);\r
+ st.Bind(4,&((*i).m_data[0]),(*i).m_data.size());\r
+ st.Step();\r
+ st.Reset();\r
+ }\r
+\r
+ HandleChangeTrust();\r
+\r
+ }\r
\r
return true;\r
\r