bool m_setoption;\r
std::map<std::string,std::string> m_setoptions;\r
std::string m_logtype;\r
+ std::string m_workingdirectory;\r
\r
ThreadedExecutor m_threads;\r
\r
\r
#include "iindexrequester.h"\r
\r
+#include <map>\r
+\r
class MessageListRequester:public IIndexRequester<long>\r
{\r
public:\r
void StartRedirectRequest(FCPMessage &message);\r
const bool HandleAllData(FCPMessage &message);\r
const bool HandleGetFailed(FCPMessage &message);\r
+ void GetBoardList(std::map<std::string,bool> &boards);\r
\r
bool m_localtrustoverrides;\r
+ bool m_savetonewboards;\r
\r
};\r
\r
\r
#define VERSION_MAJOR "0"\r
#define VERSION_MINOR "3"\r
-#define VERSION_RELEASE "5"\r
+#define VERSION_RELEASE "6"\r
#define FMS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_RELEASE\r
\r
typedef Poco::ScopedLock<Poco::FastMutex> Guard;\r
#include <unistd.h>\r
#endif\r
\r
-FMSApp::FMSApp():m_displayhelp(false),m_showoptions(false),m_setoption(false),m_logtype("file")\r
+FMSApp::FMSApp():m_displayhelp(false),m_showoptions(false),m_setoption(false),m_logtype("file"),m_workingdirectory("")\r
{\r
-\r
+ // get current working dir so we can go to it later\r
+ char wd[1024];\r
+ char *wdptr=NULL;\r
+ memset(wd,0,1024);\r
+ wdptr=getcwd(wd,1023);\r
+ if(wdptr)\r
+ {\r
+ m_workingdirectory=wdptr;\r
+ }\r
}\r
\r
void FMSApp::defineOptions(Poco::Util::OptionSet &options)\r
{\r
ServerApplication::initialize(self);\r
\r
- // set working directory to program directory\r
- int rval=chdir(config().getString("application.dir").c_str());\r
+ // set working directory - fall back on application.dir if working directory isn't set\r
+ if(m_workingdirectory=="")\r
+ {\r
+ m_workingdirectory=config().getString("application.dir");\r
+ }\r
+ int rval=chdir(m_workingdirectory.c_str());\r
\r
SetupDB();\r
SetupDefaultOptions();\r
\r
// running as a daemon would reset the working directory to / before calling main\r
// so we need to set the working directory again\r
- // set working directory to program directory\r
- int rval=chdir(config().getString("application.dir").c_str());\r
+ int rval=chdir(m_workingdirectory.c_str());\r
\r
if(m_displayhelp)\r
{\r
Initialize();\r
}\r
\r
+void MessageListRequester::GetBoardList(std::map<std::string,bool> &boards)\r
+{\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT BoardName, SaveReceivedMessages FROM tblBoard;");\r
+ st.Step();\r
+ while(st.RowReturned())\r
+ {\r
+ std::string boardname="";\r
+ std::string tempval="";\r
+ st.ResultText(0,boardname);\r
+ st.ResultText(1,tempval);\r
+\r
+ if(tempval=="true")\r
+ {\r
+ boards[boardname]=true;\r
+ }\r
+ else\r
+ {\r
+ boards[boardname]=false;\r
+ }\r
+\r
+ st.Step();\r
+ }\r
+}\r
+\r
const bool MessageListRequester::HandleAllData(FCPMessage &message)\r
{ \r
SQLite3DB::Statement st;\r
MessageListXML xml;\r
long identityid;\r
long index;\r
+ std::map<std::string,bool> boards; // list of boards and if we will save messages for that board or not\r
+ bool addmessage=false;\r
+ std::string boardsstr="";\r
+\r
+ GetBoardList(boards);\r
\r
StringFunctions::Split(message["Identifier"],"|",idparts);\r
StringFunctions::Convert(message["DataLength"],datalength);\r
SQLite3DB::Statement mst=m_db->Prepare("INSERT INTO tblMessageRequests(IdentityID,Day,RequestIndex,FromMessageList) VALUES(?,?,?,'true');");\r
for(long i=0; i<xml.MessageCount(); i++)\r
{\r
- st.Bind(0,identityid);\r
- st.Bind(1,xml.GetDate(i));\r
- st.Bind(2,xml.GetIndex(i));\r
- st.Step();\r
- if(st.RowReturned()==false)\r
+\r
+ // go through each board the message was posted to and see if we are saving messages to that board\r
+ // if the board isn't found, see if we are saving messages to new boards\r
+ boardsstr="";\r
+ addmessage=false;\r
+ std::vector<std::string> messageboards=xml.GetBoards(i);\r
+ for(std::vector<std::string>::iterator j=messageboards.begin(); j!=messageboards.end(); j++)\r
{\r
- mst.Bind(0,identityid);\r
- mst.Bind(1,xml.GetDate(i));\r
- mst.Bind(2,xml.GetIndex(i));\r
- mst.Step();\r
- mst.Reset();\r
+ if(boards.find((*j))!=boards.end())\r
+ {\r
+ if(boards[(*j)]==true)\r
+ {\r
+ addmessage=true;\r
+ }\r
+ }\r
+ else if(m_savetonewboards==true)\r
+ {\r
+ addmessage=true;\r
+ }\r
+ if(j!=messageboards.begin())\r
+ {\r
+ boardsstr+=", ";\r
+ }\r
+ boardsstr+=(*j);\r
+ }\r
+\r
+ if(addmessage==true)\r
+ {\r
+ st.Bind(0,identityid);\r
+ st.Bind(1,xml.GetDate(i));\r
+ st.Bind(2,xml.GetIndex(i));\r
+ st.Step();\r
+ if(st.RowReturned()==false)\r
+ {\r
+ mst.Bind(0,identityid);\r
+ mst.Bind(1,xml.GetDate(i));\r
+ mst.Bind(2,xml.GetIndex(i));\r
+ mst.Step();\r
+ mst.Reset();\r
+ }\r
+ st.Reset();\r
+ }\r
+ else\r
+ {\r
+ m_log->trace("MessageListRequester::HandleAllData will not download message posted to "+boardsstr);\r
}\r
- st.Reset();\r
}\r
\r
// insert external message indexes\r
{\r
if(xml.GetExternalType(i)=="Keyed")\r
{\r
- spk.Bind(0,xml.GetExternalIdentity(i));\r
- spk.Step();\r
- if(spk.RowReturned())\r
+ // go through each board the message was posted to and see if we are saving messages to that board\r
+ // if the board isn't found, see if we are saving messages to new boards\r
+ boardsstr="";\r
+ addmessage=false;\r
+ std::vector<std::string> messageboards=xml.GetExternalBoards(i);\r
+ for(std::vector<std::string>::iterator j=messageboards.begin(); j!=messageboards.end(); j++)\r
{\r
- int thisidentityid=0;\r
- spk.ResultInt(0,thisidentityid);\r
- mst.Bind(0,thisidentityid);\r
- mst.Bind(1,xml.GetExternalDate(i));\r
- mst.Bind(2,xml.GetExternalIndex(i));\r
- mst.Step();\r
- mst.Reset();\r
+ if(boards.find((*j))!=boards.end())\r
+ {\r
+ if(boards[(*j)]==true)\r
+ {\r
+ addmessage=true;\r
+ }\r
+ }\r
+ else if(m_savetonewboards==true)\r
+ {\r
+ addmessage=true;\r
+ }\r
+ if(j!=messageboards.begin())\r
+ {\r
+ boardsstr+=", ";\r
+ }\r
+ boardsstr+=(*j);\r
+ }\r
+\r
+ if(addmessage==true)\r
+ {\r
+ spk.Bind(0,xml.GetExternalIdentity(i));\r
+ spk.Step();\r
+ if(spk.RowReturned())\r
+ {\r
+ int thisidentityid=0;\r
+ spk.ResultInt(0,thisidentityid);\r
+ mst.Bind(0,thisidentityid);\r
+ mst.Bind(1,xml.GetExternalDate(i));\r
+ mst.Bind(2,xml.GetExternalIndex(i));\r
+ mst.Step();\r
+ mst.Reset();\r
+ }\r
+ spk.Reset();\r
+ }\r
+ else\r
+ {\r
+ m_log->trace("MessageListRequester::HandleAllData will not download external message posted to "+boardsstr+" from " + xml.GetExternalIdentity(i));\r
}\r
- spk.Reset();\r
}\r
}\r
\r
m_log->warning("Option MaxMessageListRequests is currently set at "+tempval+". This value might be incorrectly configured.");\r
}\r
\r
+ tempval="";\r
Option::Instance()->Get("LocalTrustOverridesPeerTrust",tempval);\r
if(tempval=="true")\r
{\r
m_localtrustoverrides=false;\r
}\r
\r
+ tempval="";\r
+ Option::Instance()->Get("SaveMessagesFromNewBoards",tempval);\r
+ if(tempval=="true")\r
+ {\r
+ m_savetonewboards=true;\r
+ }\r
+ else\r
+ {\r
+ m_savetonewboards=false;\r
+ }\r
+\r
}\r
\r
void MessageListRequester::PopulateIDList()\r
Poco::Net::MessageHeader::splitParameters(header["Content-Disposition"],disp,nvc);\r
name=nvc.get("name","");\r
\r
- Poco::StreamCopier sc;\r
- sc.copyToString(stream,data);\r
+ Poco::StreamCopier::copyToString(stream,data);\r
\r
vars[name]=data;\r
}\r
content+="</tr>";\r
content+="</table>";\r
content+="<p class=\"paragraph\">";\r
- content+="* If you uncheck this box, any new messages you download that are posted to this board will be discarded.";\r
+ content+="* If you uncheck this box, any new messages you download that are posted to this board will be discarded. When multiple local identities are used, it is best not to discard messages from any boards, as identifying which identities are the same person is much easier when their message lists are missing messages from the same boards.";\r
content+="</p>";\r
\r
return StringFunctions::Replace(m_template,"[CONTENT]",content);\r
content+="<h2>Execute Query</h2>";\r
content+="<form name=\"frmquery\" method=\"POST\">";\r
content+="<input type=\"hidden\" name=\"formaction\" value=\"execute\">";\r
- content+="<textarea name=\"query\" rows=\"10\" cols=\"80\">"+SanitizeOutput(query)+"</textarea>";\r
+ content+="<textarea name=\"query\" rows=\"10\" cols=\"80\">"+StringFunctions::Replace(query,"<","<")+"</textarea>";\r
content+="<input type=\"submit\" value=\"Execute Query\">";\r
content+="</form>";\r
\r
const bool IPAddressACL::Add(const std::string &aclentry)\r
{\r
bool allow=m_allowbydefault;\r
- int maskbits=0;\r
+ int maskbits=32;\r
std::string::size_type strpos=std::string::npos;\r
std::string entrystr=aclentry;\r
\r
\r
const std::string IPAddressACL::CreateMask(const int maskbits)\r
{\r
+/*\r
int bitsleft=maskbits;\r
- //int parts[4]={255,255,255,255};\r
int parts[4]={0,0,0,0};\r
std::ostringstream ipstr;\r
\r
- /*\r
- for(int i=3; i>=0; i--)\r
- {\r
- for(int b=0; b<8 && bitsleft>0; b++)\r
- {\r
- parts[i]-=pow((float)2,b);\r
- bitsleft--;\r
- }\r
- }\r
- */\r
for(int i=0; i<4; i++)\r
{\r
for(int b=7; b>=0 && bitsleft>0; b--)\r
bitsleft--;\r
}\r
}\r
+*/\r
+ int bits=maskbits;\r
+ bits>32 ? bits=32 : false;\r
+ bits<0 ? bits=0 : false;\r
+ int parts[4]={0,0,0,0};\r
+ std::ostringstream ipstr;\r
+\r
+ unsigned long maskval=(((unsigned long)pow((float)2,bits)-1) << (32-bits));\r
+\r
+ parts[0]=((maskval >> 24) & 0xff);\r
+ parts[1]=((maskval >> 16) & 0xff);\r
+ parts[2]=((maskval >> 8) & 0xff);\r
+ parts[3]=(maskval & 0xff);\r
\r
ipstr << parts[0] << "." << parts[1] << "." << parts[2] << "." << parts[3];\r
\r
//ip1.mask((*i).m_mask);\r
//ip2.mask((*i).m_mask);\r
\r
- ip1=MaskAddress(ip1,(*i).m_mask);\r
- ip2=MaskAddress(ip2,(*i).m_mask);\r
+ if(ip1.family()==Poco::Net::IPAddress::IPv4 && ip2.family()==Poco::Net::IPAddress::IPv4)\r
+ {\r
+ ip1=MaskAddress(ip1,(*i).m_mask);\r
+ ip2=MaskAddress(ip2,(*i).m_mask);\r
+ }\r
\r
if(ip1==ip2)\r
{\r
upd.Reset();\r
\r
st.Bind(0,"FMSVersionEdition");\r
- st.Bind(1,"3");\r
+ st.Bind(1,"7");\r
st.Step();\r
st.Reset();\r
upd.Bind(0,"Program");\r