src/http/pages/announceidentitypage.cpp\r
src/http/pages/controlboardpage.cpp\r
src/http/pages/createidentitypage.cpp\r
+src/http/pages/execquerypage.cpp\r
src/http/pages/homepage.cpp\r
src/http/pages/localidentitiespage.cpp\r
src/http/pages/optionspage.cpp\r
virtual const int Count() { return m_rows; }\r
virtual const bool AtBeginning() { return m_currentrow==0; }\r
virtual const bool AtEnd() { return m_currentrow>=m_rows; }\r
+ virtual const int Cols() { return m_cols; }\r
\r
virtual const bool Next() { if(m_currentrow<m_rows) { m_currentrow++; return true; } else { return false; } }\r
virtual const bool Previous() { if(m_currentrow-1>=0) { m_currentrow--; return true; } else { return false; } }\r
//#include <zthread/Thread.h>\r
#include "pthreadwrapper/thread.h"\r
\r
-#define FMS_VERSION "0.1.11"\r
+#define FMS_VERSION "0.1.12"\r
\r
// opens database and creates tables and initial inserts if necessary\r
void SetupDB();\r
--- /dev/null
+#ifndef _execquerypage_\r
+#define _execquerypage_\r
+\r
+#include "../ipagehandler.h"\r
+#include "../../idatabase.h"\r
+\r
+class ExecQueryPage:public IPageHandler,public IDatabase\r
+{\r
+public:\r
+ ExecQueryPage(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
+\r
+#endif // _execquerypage_\r
const std::string GeneratePage(const std::string &method, const std::map<std::string,std::string> &queryvars);\r
\r
const std::string GetClassString(const std::string &trustlevel);\r
+ const std::string BuildQueryString(const long startrow, const std::string &namesearch, const std::string &sortby, const std::string &sortorder);\r
+ const std::string ReverseSort(const std::string &sortname, const std::string ¤tsortby, const std::string ¤tsortorder);\r
\r
};\r
\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
+ void HandleChangeTrust();\r
\r
long m_messageid;\r
std::string m_messageuuid;\r
std::string m_fromname;\r
std::vector<std::string> m_boards;\r
std::map<long,std::string> m_inreplyto;\r
+ long m_changemessagetrustonreply;\r
\r
};\r
\r
{\r
return false;\r
}\r
-}
\ No newline at end of file
+}\r
FCPMessage message;\r
std::string xmldata;\r
std::string xmldatasizestr;\r
- std::string privatekey;\r
+ std::string privatekey="";\r
+ std::string publickey="";\r
+ std::string keypart="";\r
\r
StringFunctions::Convert(localidentityid,idstring);\r
now.SetToGMTime();\r
}\r
StringFunctions::Convert(index,indexstr);\r
\r
- SQLite3DB::Recordset rs2=m_db->Query("SELECT PrivateKey FROM tblLocalIdentity WHERE LocalIdentityID="+idstring+";");\r
+ SQLite3DB::Recordset rs2=m_db->Query("SELECT PrivateKey,PublicKey FROM tblLocalIdentity WHERE LocalIdentityID="+idstring+";");\r
if(rs2.Empty()==false && rs2.GetField(0)!=NULL)\r
{\r
privatekey=rs2.GetField(0);\r
+ if(rs2.GetField(1))\r
+ {\r
+ publickey=rs2.GetField(1);\r
+ }\r
+ if(publickey.size()>=50)\r
+ {\r
+ // remove - and ~\r
+ keypart=StringFunctions::Replace(StringFunctions::Replace(publickey.substr(4,43),"-",""),"~","");\r
+ }\r
}\r
\r
Option::Instance()->Get("MessageBase",messagebase);\r
GenerateCaptcha(encodedpuzzle,solutionstring);\r
\r
xml.SetType("captcha");\r
- xml.SetUUID(uuid.Generate());\r
+ xml.SetUUID(uuid.Generate()+"@"+keypart);\r
xml.SetPuzzleData(encodedpuzzle);\r
xml.SetMimeType("image/bmp");\r
\r
// parse file into xml and update the database\r
if(xml.ParseXML(std::string(data.begin(),data.end()))==true)\r
{\r
+\r
+ // TODO - check if last part of UUID matches public key of identity who inserted it\r
+\r
st=m_db->Prepare("INSERT INTO tblIntroductionPuzzleRequests(IdentityID,Day,RequestIndex,Found,UUID,Type,MimeType,PuzzleData) VALUES(?,?,?,?,?,?,?,?);");\r
st.Bind(0,identityid);\r
st.Bind(1,idparts[4]);\r
\r
tid->LinkEndChild(XMLCreateTextElement("Type",m_type));\r
\r
- tid->LinkEndChild(XMLCreateTextElement("UUID",m_uuid));\r
+ tid->LinkEndChild(XMLCreateCDATAElement("UUID",m_uuid));\r
\r
tid->LinkEndChild(XMLCreateTextElement("MimeType",m_mimetype));\r
\r
#include "../../include/freenet/messageinserter.h"\r
+#include "../../include/freenet/messagexml.h"\r
\r
MessageInserter::MessageInserter()\r
{\r
{\r
SQLite3DB::Statement st=m_db->Prepare("INSERT INTO tblMessageInserts(LocalIdentityID,Day,InsertIndex,Inserted) VALUES(?,?,?,'true');");\r
st.Bind(0,localidentityid);\r
- st.Bind(1,idparts[5]);\r
+ st.Bind(1,idparts[6]);\r
st.Bind(2,index);\r
st.Step();\r
}\r
\r
const bool MessageInserter::HandlePutSuccessful(FCPMessage &message)\r
{\r
+ MessageXML xml;\r
DateTime date;\r
int localidentityid;\r
int index;\r
StringFunctions::Convert(idparts[2],localidentityid);\r
\r
SQLite3DB::Statement st=m_db->Prepare("UPDATE tblMessageInserts SET Day=?, InsertIndex=?, Inserted='true' WHERE MessageUUID=?;");\r
- st.Bind(0,idparts[5]);\r
+ st.Bind(0,idparts[6]);\r
st.Bind(1,index);\r
st.Bind(2,idparts[1]);\r
st.Step();\r
st.Bind(1,date.Format("%Y-%m-%d"));\r
st.Step();\r
\r
+ // update the messageuuid to the real messageuuid\r
+ st=m_db->Prepare("SELECT MessageXML FROM tblMessageInserts WHERE MessageUUID=?;");\r
+ st.Bind(0,idparts[1]);\r
+ st.Step();\r
+ if(st.RowReturned())\r
+ {\r
+ std::string xmldata="";\r
+ st.ResultText(0,xmldata);\r
+ xml.ParseXML(xmldata);\r
+ xml.SetMessageID(idparts[4]);\r
+\r
+ SQLite3DB::Statement st2=m_db->Prepare("UPDATE tblMessageInserts SET MessageUUID=?, MessageXML=? WHERE MessageUUID=?;");\r
+ st2.Bind(0,idparts[4]);\r
+ st2.Bind(1,xml.GetXML());\r
+ st2.Bind(2,idparts[1]);\r
+ st2.Step();\r
+ }\r
+\r
RemoveFromInsertList(idparts[1]);\r
\r
m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"MessageInserter::HandlePutSuccessful successfully inserted message "+message["Identifier"]);\r
\r
void MessageInserter::StartInsert(const std::string &messageuuid)\r
{\r
+ MessageXML xmlfile;\r
DateTime now;\r
now.SetToGMTime();\r
- SQLite3DB::Statement st=m_db->Prepare("SELECT MessageXML,PrivateKey,tblLocalIdentity.LocalIdentityID FROM tblMessageInserts INNER JOIN tblLocalIdentity ON tblMessageInserts.LocalIdentityID=tblLocalIdentity.LocalIdentityID WHERE MessageUUID=?;");\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT MessageXML,PrivateKey,tblLocalIdentity.LocalIdentityID,PublicKey FROM tblMessageInserts INNER JOIN tblLocalIdentity ON tblMessageInserts.LocalIdentityID=tblLocalIdentity.LocalIdentityID WHERE MessageUUID=?;");\r
st.Bind(0,messageuuid);\r
st.Step();\r
\r
std::string xml;\r
std::string xmlsizestr;\r
std::string privatekey;\r
+ std::string publickey;\r
FCPMessage message;\r
std::string indexstr;\r
int index=0;\r
st.ResultText(0,xml);\r
st.ResultText(1,privatekey);\r
st.ResultInt(2,localidentityid);\r
- StringFunctions::Convert(xml.size(),xmlsizestr);\r
+ st.ResultText(3,publickey);\r
StringFunctions::Convert(localidentityid,idstr);\r
\r
st=m_db->Prepare("SELECT MAX(InsertIndex) FROM tblMessageInserts WHERE Day=? AND LocalIdentityID=?;");\r
}\r
StringFunctions::Convert(index,indexstr);\r
\r
+ // recreate messageuuid in xml - UUID of message will not match entry in MessageInserts table until we successfully insert it\r
+ // see HandlePutSuccessful\r
+ xmlfile.ParseXML(xml);\r
+ // if we don't already have an @sskpart - add it\r
+ if(xmlfile.GetMessageID().find("@")==std::string::npos)\r
+ {\r
+ // remove - and ~ from publickey part\r
+ std::string publickeypart=StringFunctions::Replace(StringFunctions::Replace(publickey.substr(4,43),"-",""),"~","");\r
+ xmlfile.SetMessageID(xmlfile.GetMessageID()+"@"+publickeypart);\r
+ }\r
+ xml=xmlfile.GetXML();\r
+\r
+ StringFunctions::Convert(xml.size(),xmlsizestr);\r
+\r
message.SetName("ClientPut");\r
message["URI"]=privatekey+m_messagebase+"|"+now.Format("%Y-%m-%d")+"|Message|"+indexstr+".xml";\r
- message["Identifier"]=m_fcpuniquename+"|"+messageuuid+"|"+idstr+"|"+indexstr+"|"+message["URI"];\r
+ message["Identifier"]=m_fcpuniquename+"|"+messageuuid+"|"+idstr+"|"+indexstr+"|"+xmlfile.GetMessageID()+"|"+message["URI"];\r
message["UploadFrom"]="direct";\r
message["DataLength"]=xmlsizestr;\r
m_fcp->SendMessage(message);\r
boards[boards.size()-1]=xml.GetReplyBoard();\r
}\r
\r
+ // TODO make sure domain of message id match 43 characters of public key of identity (remove - and ~) - if not, discard message\r
+ // implement after 0.1.12 is released\r
+\r
st=m_db->Prepare("INSERT INTO tblMessage(IdentityID,FromName,MessageDate,MessageTime,Subject,MessageUUID,ReplyBoardID,Body) VALUES(?,?,?,?,?,?,?,?);");\r
st.Bind(0,identityid);\r
st.Bind(1,GetIdentityName(identityid));\r
tid->LinkEndChild(XMLCreateCDATAElement("Subject",m_subject));\r
tid->LinkEndChild(XMLCreateCDATAElement("MessageID",m_messageid));\r
tid->LinkEndChild(XMLCreateCDATAElement("ReplyBoard",m_replyboard));\r
- tid->LinkEndChild(XMLCreateCDATAElement("Body",m_body));\r
+ // a little hack because TinyXML doesn't handle ]]> inside a CDATA section - manually separate into multiple CDATA sections\r
+ // TinyXML still won't be able to parse past the 1st CDATA section, but other implementations might\r
+ tid->LinkEndChild(XMLCreateCDATAElement("Body",StringFunctions::Replace(m_body,"]]>","]]]]><![CDATA[>")));\r
\r
TiXmlElement *brds=new TiXmlElement("Boards");\r
tid->LinkEndChild(brds);\r
#include "../../include/freenet/periodicdbmaintenance.h"\r
+#include "../../include/stringfunctions.h"\r
\r
#ifdef XMEM\r
#include <xmem.h>\r
// delete trust lists from identities we aren't trusting anymore\r
m_db->Execute("DELETE FROM tblPeerTrust WHERE IdentityID NOT IN (SELECT IdentityID FROM tblIdentity WHERE (LocalTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinLocalTrustListTrust')) AND (PeerTrustListTrust IS NULL OR PeerTrustListTrust>=(SELECT OptionValue FROM tblOption WHERE Option='MinPeerTrustListTrust')));");\r
\r
+ // remove identityid from messages where the identity has been deleted\r
+ m_db->Execute("UPDATE tblMessage SET IdentityID=NULL WHERE IdentityID NOT IN (SELECT IdentityID FROM tblIdentity);");\r
+\r
+ // try to re-attach messages from identities that were previously deleted, but have been since re-added\r
+ // first get the names from messages that have a NULL IdentityID\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT FromName FROM tblMessage WHERE IdentityID IS NULL GROUP BY FromName;");\r
+ st.Step();\r
+ while(st.RowReturned())\r
+ {\r
+ std::string name="";\r
+ std::string publickey="";\r
+ int identityid=0;\r
+ st.ResultText(0,name);\r
+\r
+ std::vector<std::string> parts;\r
+ StringFunctions::Split(name,"@",parts);\r
+\r
+ // find identities with this name\r
+ SQLite3DB::Statement st2=m_db->Prepare("SELECT IdentityID,PublicKey FROM tblIdentity WHERE Name=?;");\r
+ st2.Bind(0,name);\r
+ st2.Step();\r
+ while(st2.RowReturned())\r
+ {\r
+ publickey="";\r
+ identityid=0;\r
+ st2.ResultText(1,publickey);\r
+ // check if public key matches 2nd part\r
+ if(parts.size()>1 && publickey.find(parts[1])==4)\r
+ {\r
+ // we have the identity - so update the messages table with the identityid\r
+ st2.ResultInt(0,identityid);\r
+\r
+ SQLite3DB::Statement st3=m_db->Prepare("UPDATE tblMessage SET IdentityID=? WHERE Name=? AND IdentityID IS NULL;");\r
+ st3.Bind(0,identityid);\r
+ st3.Bind(1,name);\r
+ st3.Step();\r
+ }\r
+ st2.Step();\r
+ }\r
+\r
+ st.Step();\r
+ }\r
+\r
}\r
\r
void PeriodicDBMaintenance::Process()\r
DELETE FROM tblTrustListInserts WHERE LocalIdentityID=old.LocalIdentityID;\\r
END;");\r
\r
+ db->Execute("CREATE TRIGGER IF NOT EXISTS trgDeleteBoard AFTER DELETE ON tblBoard \\r
+ FOR EACH ROW \\r
+ BEGIN \\r
+ DELETE FROM tblMessageBoard WHERE BoardID=old.BoardID;\\r
+ END;");\r
+\r
// delete introduction puzzles that were half-way inserted\r
db->Execute("DELETE FROM tblIntroductionPuzzleInserts WHERE Day IS NULL AND InsertIndex IS NULL;");\r
\r
st.Step();\r
st.Reset();\r
\r
+ st.Bind(0,"ChangeMessageTrustOnReply");\r
+ st.Bind(1,"0");\r
+ st.Bind(2,"How much the local message trust level of an identity should change when you reply to one of their messages.");\r
+ st.Step();\r
+ st.Reset();\r
+\r
}\r
\r
void SetupLogFile()\r
#include "../../include/http/pages/controlboardpage.h"\r
#include "../../include/http/pages/peerdetailspage.h"\r
#include "../../include/http/pages/peermaintenancepage.h"\r
+#include "../../include/http/pages/execquerypage.h"\r
\r
#include <iostream>\r
\r
StringFunctions::Convert(portstr,port);\r
\r
// set template\r
- templatestr="<html><head></head><body><a href=\"home.htm\">Home</a><br>[CONTENT]</body></html>";\r
+ templatestr="<html><head></head><body><a href=\"home.htm\">Home</a><br><h1>Could not find template.htm! Place in program directory and restart!</h1><br>[CONTENT]</body></html>";\r
FILE *infile=fopen("template.htm","r+b");\r
if(infile)\r
{\r
m_pagehandlers.push_back(new ControlBoardPage(templatestr));\r
m_pagehandlers.push_back(new PeerDetailsPage(templatestr));\r
m_pagehandlers.push_back(new PeerMaintenancePage(templatestr));\r
+ m_pagehandlers.push_back(new ExecQueryPage(templatestr));\r
// homepage must be last - catch all page handler\r
m_pagehandlers.push_back(new HomePage(templatestr));\r
\r
--- /dev/null
+#include "../../../include/http/pages/execquerypage.h"\r
+#include "../../../include/stringfunctions.h"\r
+\r
+#ifdef XMEM\r
+ #include <xmem.h>\r
+#endif\r
+\r
+const std::string ExecQueryPage::GeneratePage(const std::string &method, const std::map<std::string,std::string> &queryvars)\r
+{\r
+ std::string content="";\r
+\r
+ if(queryvars.find("formaction")!=queryvars.end() && (*queryvars.find("formaction")).second=="execute" && queryvars.find("query")!=queryvars.end() && (*queryvars.find("query")).second!="")\r
+ {\r
+ SQLite3DB::Recordset rs=m_db->Query((*queryvars.find("query")).second);\r
+\r
+ content+="<table>";\r
+ while(!rs.AtEnd())\r
+ {\r
+ content+="<tr>";\r
+ for(int i=0; i<rs.Cols(); i++)\r
+ {\r
+ content+="<td>";\r
+ if(rs.GetField(i))\r
+ {\r
+ content+=rs.GetField(i);\r
+ }\r
+ content+="</td>";\r
+ }\r
+ content+="</tr>";\r
+ rs.Next();\r
+ }\r
+ content+="</table>";\r
+ }\r
+\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\"></textarea>";\r
+ content+="<input type=\"submit\" value=\"Execute Query\">";\r
+ content+="</form>";\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 ExecQueryPage::WillHandleURI(const std::string &uri)\r
+{\r
+ if(uri.find("execquery.")!=std::string::npos)\r
+ {\r
+ return true;\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+}\r
{\r
return false;\r
}\r
-}
\ No newline at end of file
+}\r
#include <xmem.h>\r
#endif\r
\r
+const std::string PeerTrustPage::BuildQueryString(const long startrow, const std::string &namesearch, const std::string &sortby, const std::string &sortorder)\r
+{\r
+ std::string returnval="";\r
+ std::string tempval="";\r
+ \r
+ if(startrow>=0)\r
+ {\r
+ StringFunctions::Convert(startrow,tempval);\r
+ returnval+="startrow="+tempval;\r
+ }\r
+\r
+ if(namesearch!="")\r
+ {\r
+ if(returnval!="")\r
+ {\r
+ returnval+="&";\r
+ }\r
+ returnval+="namesearch="+namesearch;\r
+ }\r
+\r
+ if(sortby!="")\r
+ {\r
+ if(returnval!="")\r
+ {\r
+ returnval+="&";\r
+ }\r
+ returnval+="sortby="+sortby;\r
+ }\r
+\r
+ if(sortorder!="")\r
+ {\r
+ if(returnval!="")\r
+ {\r
+ returnval+="&";\r
+ }\r
+ returnval+="sortorder="+sortorder;\r
+ }\r
+\r
+ return returnval;\r
+\r
+}\r
+\r
const std::string PeerTrustPage::GeneratePage(const std::string &method, const std::map<std::string,std::string> &queryvars)\r
{\r
int count=0;\r
std::string startrowstr="0";\r
std::string namesearch="";\r
std::string sql;\r
+ std::string sortby="";\r
+ std::string sortorder="";\r
\r
StringFunctions::Convert(rowsperpage,rowsperpagestr);\r
\r
StringFunctions::Convert(startrow,startrowstr);\r
}\r
\r
+ // sort by\r
+ if(queryvars.find("sortby")!=queryvars.end())\r
+ {\r
+ sortby=(*queryvars.find("sortby")).second;\r
+ }\r
+ else\r
+ {\r
+ sortby="Name";\r
+ }\r
+\r
+ // sort order\r
+ if(queryvars.find("sortorder")!=queryvars.end())\r
+ {\r
+ sortorder=(*queryvars.find("sortorder")).second;\r
+ }\r
+ else\r
+ {\r
+ sortorder="ASC";\r
+ }\r
+\r
// if we are searching by name\r
if(queryvars.find("namesearch")!=queryvars.end())\r
{\r
}\r
\r
content+="<h2>Peer Trust</h2>";\r
- content+="Message Trust is how much you trust the identity to post good messages. Trust List Trust is how much weight you want the trust list of that identity to have when calculating the total. The local trust levels are set by you, and the peer trust levels are calculated by a weighted average using other identities trust lists.";\r
+ content+="Message Trust is how much you trust the identity to post good messages. Trust List Trust is how much weight you want the trust list of that identity to have when calculating the total. The local trust levels are set by you, and the peer trust levels are calculated by a weighted average using other identities' trust lists.";\r
content+="<div style=\"text-align:center;\">";\r
content+="<form name=\"frmsearch\" method=\"POST\" action=\"peertrust.htm\">";\r
content+="<input type=\"text\" name=\"namesearch\">";\r
content+="<input type=\"hidden\" name=\"formaction\" value=\"update\">";\r
content+="<input type=\"hidden\" name=\"startrow\" value=\""+startrowstr+"\">";\r
content+="<table>";\r
- content+="<tr><th>Name</th><th>Local Message Trust</th><th>Peer Message Trust</th><th>Local Trust List Trust</th><th>Peer Trust List Trust</th></tr>";\r
+ content+="<tr><th><a href=\"peertrust.htm?"+BuildQueryString(startrow,namesearch,"Name",ReverseSort("Name",sortby,sortorder))+"\">Name</a></th>";\r
+ content+="<th><a href=\"peertrust.htm?"+BuildQueryString(startrow,namesearch,"LocalMessageTrust",ReverseSort("LocalMessageTrust",sortby,sortorder))+"\">Local Message Trust</a></th>";\r
+ content+="<th><a href=\"peertrust.htm?"+BuildQueryString(startrow,namesearch,"PeerMessageTrust",ReverseSort("PeerMessageTrust",sortby,sortorder))+"\">Peer Message Trust</a></th>";\r
+ content+="<th><a href=\"peertrust.htm?"+BuildQueryString(startrow,namesearch,"LocalTrustListTrust",ReverseSort("LocalTrustListTrust",sortby,sortorder))+"\">Local Trust List Trust</a></th>";\r
+ content+="<th><a href=\"peertrust.htm?"+BuildQueryString(startrow,namesearch,"PeerTrustListTrust",ReverseSort("PeerTrustListTrust",sortby,sortorder))+"\">Peer Trust List Trust</a></th></tr>";\r
\r
// get count of identities we are showing\r
sql="SELECT COUNT(*) FROM tblIdentity";\r
{\r
sql+=" WHERE Name LIKE '%' || ? || '%'";\r
}\r
- sql+=" ORDER BY Name COLLATE NOCASE LIMIT "+startrowstr+","+rowsperpagestr+";";\r
+ sql+=" ORDER BY";\r
+ if(sortby=="Name")\r
+ {\r
+ sql+=" Name COLLATE NOCASE";\r
+ }\r
+ else\r
+ {\r
+ sql+=" "+sortby;\r
+ }\r
+ if(sortorder!="")\r
+ {\r
+ sql+=" "+sortorder;\r
+ }\r
+ sql+=" LIMIT "+startrowstr+","+rowsperpagestr+";";\r
st=m_db->Prepare(sql);\r
if(namesearch!="")\r
{\r
if(startrow>0)\r
{\r
StringFunctions::Convert(startrow-rowsperpage,tempstr);\r
- content+="<td colspan=\"2\" align=\"left\"><a href=\"peertrust.htm?startrow="+tempstr+"&namesearch="+namesearch+"\"><-- Previous Page</a></td>";\r
+ content+="<td colspan=\"2\" align=\"left\"><a href=\"peertrust.htm?"+BuildQueryString(startrow-rowsperpage,namesearch,sortby,sortorder)+"\"><-- Previous Page</a></td>";\r
cols+=2;\r
}\r
if(startrow+rowsperpage<identitycount)\r
{\r
- StringFunctions::Convert(startrow+rowsperpage,tempstr);\r
while(cols<3)\r
{\r
content+="<td></td>";\r
cols++;\r
}\r
- content+="<td colspan=\"2\" align=\"right\"><a href=\"peertrust.htm?startrow="+tempstr+"&namesearch="+namesearch+"\">Next Page --></a></td>";\r
+ content+="<td colspan=\"2\" align=\"right\"><a href=\"peertrust.htm?"+BuildQueryString(startrow+rowsperpage,namesearch,sortby,sortorder)+"\">Next Page --></a></td>";\r
}\r
content+="</tr>";\r
}\r
}\r
}\r
\r
+const std::string PeerTrustPage::ReverseSort(const std::string &sortname, const std::string ¤tsortby, const std::string ¤tsortorder)\r
+{\r
+ if(sortname==currentsortby)\r
+ {\r
+ if(currentsortorder=="ASC")\r
+ {\r
+ return "DESC";\r
+ }\r
+ else\r
+ {\r
+ return "ASC";\r
+ }\r
+ }\r
+ else\r
+ {\r
+ return currentsortorder;\r
+ }\r
+}\r
+\r
const bool PeerTrustPage::WillHandleURI(const std::string &uri)\r
{\r
if(uri.find("peertrust.")!=std::string::npos)\r
#include "../include/uuidgenerator.h"\r
#include "../include/stringfunctions.h"\r
#include "../include/freenet/messagexml.h"\r
+#include "../include/option.h"\r
\r
#include <algorithm>\r
\r
\r
const std::string Message::GetNNTPArticleID() const\r
{\r
- return "<"+m_messageuuid+"@freenetproject.org>";\r
+ // old message - before 0.1.12 - doesn't have @domain so add @freenetproject.org\r
+ if(m_messageuuid.find("@")==std::string::npos)\r
+ {\r
+ return "<"+m_messageuuid+"@freenetproject.org>";\r
+ }\r
+ else\r
+ {\r
+ return "<"+m_messageuuid+">";\r
+ }\r
}\r
\r
const std::string Message::GetNNTPBody() const\r
{\r
rval+=" ";\r
}\r
- rval+="<"+(*j).second+"@freenetproject.org>";\r
+ // old message - before 0.1.12 - doesn't have @domain so add @freenetproject.org\r
+ if((*j).second.find("@")==std::string::npos)\r
+ {\r
+ rval+="<"+(*j).second+"@freenetproject.org>";\r
+ }\r
+ else\r
+ {\r
+ rval+="<"+(*j).second+">";\r
+ }\r
}\r
rval+="\r\n";\r
}\r
\r
}\r
\r
+void Message::HandleChangeTrust()\r
+{\r
+ if(m_changemessagetrustonreply!=0 && m_inreplyto.size()>0)\r
+ {\r
+ SQLite3DB::Statement st=m_db->Prepare("SELECT tblIdentity.IdentityID,tblIdentity.LocalMessageTrust FROM tblIdentity INNER JOIN tblMessage ON tblIdentity.IdentityID=tblMessage.IdentityID WHERE tblMessage.MessageUUID=?;");\r
+ st.Bind(0,m_inreplyto[0]);\r
+ st.Step();\r
+ if(st.RowReturned())\r
+ {\r
+ int identityid=0;\r
+ int localmessagetrust=0;\r
+\r
+ st.ResultInt(0,identityid);\r
+ st.ResultInt(1,localmessagetrust);\r
+\r
+ localmessagetrust+=m_changemessagetrustonreply;\r
+ if(localmessagetrust<0)\r
+ {\r
+ localmessagetrust=0;\r
+ }\r
+ if(localmessagetrust>100)\r
+ {\r
+ localmessagetrust=100;\r
+ }\r
+\r
+ SQLite3DB::Statement st2=m_db->Prepare("UPDATE tblIdentity SET LocalMessageTrust=? WHERE IdentityID=?;");\r
+ st2.Bind(0,localmessagetrust);\r
+ st2.Bind(1,identityid);\r
+ st2.Step();\r
+\r
+ }\r
+ }\r
+}\r
+\r
void Message::Initialize()\r
{\r
+ std::string tempval="";\r
m_messageid=-1;\r
m_messageuuid="";\r
m_subject="";\r
m_fromname="";\r
m_boards.clear();\r
m_inreplyto.clear();\r
+ m_changemessagetrustonreply=0;\r
+ Option::Instance()->Get("ChangeMessageTrustOnReply",tempval);\r
+ StringFunctions::Convert(tempval,m_changemessagetrustonreply);\r
}\r
\r
const bool Message::Load(const long messageid, const long boardid)\r
\r
const bool Message::Load(const std::string &messageuuid)\r
{\r
+\r
+ std::string uuid=messageuuid;\r
+\r
+ if(uuid.size()>0 && uuid[0]=='<')\r
+ {\r
+ uuid.erase(0,1);\r
+ }\r
+ if(uuid.size()>0 && uuid[uuid.size()-1]=='>')\r
+ {\r
+ uuid.erase(uuid.size()-1);\r
+ }\r
+ if(uuid.find("@freenetproject.org")!=std::string::npos)\r
+ {\r
+ uuid.erase(uuid.find("@freenetproject.org"));\r
+ }\r
+\r
SQLite3DB::Statement st=m_db->Prepare("SELECT MessageID FROM tblMessage WHERE MessageUUID=?;");\r
- st.Bind(0,messageuuid);\r
+ st.Bind(0,uuid);\r
st.Step();\r
\r
if(st.RowReturned())\r
// get header info\r
// date is always set to now regardless of what message has\r
m_datetime.SetToGMTime();\r
+\r
// messageuuid is always a unique id we generate regardless of message message-id\r
m_messageuuid=uuid.Generate();\r
+ \r
// get from\r
if(mime.GetFieldValue("From"))\r
{\r
(*i)=StringFunctions::Replace((*i),"<","");\r
(*i)=StringFunctions::Replace((*i),">","");\r
(*i)=StringFunctions::TrimWhitespace((*i));\r
+ /*\r
// erase @ and everything after\r
if((*i).find("@")!=std::string::npos)\r
{\r
(*i).erase((*i).find("@"));\r
}\r
+ */\r
+ // only erase after @ if message is old type with @freenetproject.org\r
+ if((*i).find("@freenetproject.org")!=std::string::npos)\r
+ {\r
+ (*i).erase((*i).find("@"));\r
+ }\r
if((*i)!="")\r
{\r
m_inreplyto[count++]=(*i);\r
st.Bind(2,xml.GetXML());\r
st.Step();\r
\r
+ HandleChangeTrust();\r
+\r
}\r
messageuuid=command.m_arguments[0];\r
messageuuid=StringFunctions::Replace(messageuuid,"<","");\r
messageuuid=StringFunctions::Replace(messageuuid,">","");\r
+ /*\r
// get rid of @ and everything after\r
if(messageuuid.find("@")!=std::string::npos)\r
{\r
messageuuid.erase(messageuuid.find("@"));\r
}\r
+ */\r
}\r
// single article or range\r
else\r
{\r
line+=" ";\r
}\r
- line+="<"+(*i).second+"@freenetproject.org>";\r
+ line+="<"+(*i).second+">"; //+"@freenetproject.org>";\r
}\r
line+="\t";\r
}\r
else\r
{\r
articleid=command.m_arguments[0];\r
+ //strip off < and > and everthing after @\r
+ if(articleid.size()>0 && articleid[0]=='<')\r
+ {\r
+ articleid.erase(0,1);\r
+ }\r
+ if(articleid.size()>0 && articleid[articleid.size()-1]=='>')\r
+ {\r
+ articleid.erase(articleid.size()-1);\r
+ }\r
+ /*\r
+ if(articleid.size()>0 && articleid.find('@')!=std::string::npos)\r
+ {\r
+ articleid.erase(articleid.find('@'));\r
+ }\r
+ */\r
message.Load(articleid);\r
type=2;\r
}\r
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">\r
<head>\r
<title>FMS : Freenet Message System</title>\r
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />\r
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\r
<style type="text/css">\r
body {\r
background-color: #FFF;\r
\r
form { display:inline; }\r
\r
+th { padding-left:5px; padding-right:5px; }\r
+td { padding-left:5px; padding-right:5px; }\r
+\r
</style>\r
</head>\r
\r