version 0.2.11
authorSomeDude <SomeDude@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw>
Sun, 27 Apr 2008 12:14:00 +0000 (14:14 +0200)
committerDavid ‘Bombe’ Roden <bombe@freenetproject.org>
Sun, 27 Apr 2008 12:14:00 +0000 (14:14 +0200)
20 files changed:
CMakeLists.txt
include/freenet/fileinserter.h [new file with mode: 0644]
include/freenet/messagexml.h
include/global.h
include/http/pages/insertedfilespage.h [new file with mode: 0644]
include/message.h
readme.txt
src/db/sqlite3statement.cpp
src/freenet/boardlistxml.cpp
src/freenet/fileinserter.cpp [new file with mode: 0644]
src/freenet/freenetmasterthread.cpp
src/freenet/messageinserter.cpp
src/freenet/messagerequester.cpp
src/freenet/messagexml.cpp
src/freenet/siteinserter.cpp
src/global.cpp
src/http/httpthread.cpp
src/http/pages/insertedfilespage.cpp [new file with mode: 0644]
src/message.cpp
template.htm

index 3758251..ebff758 100644 (file)
@@ -28,6 +28,7 @@ src/freenet/boardlistinserter.cpp
 src/freenet/boardlistrequester.cpp\r
 src/freenet/boardlistxml.cpp\r
 src/freenet/fcpv2.cpp\r
+src/freenet/fileinserter.cpp\r
 src/freenet/freenetmasterthread.cpp\r
 src/freenet/freenetssk.cpp\r
 src/freenet/identityinserter.cpp\r
@@ -65,6 +66,7 @@ src/http/pages/controlboardpage.cpp
 src/http/pages/createidentitypage.cpp\r
 src/http/pages/execquerypage.cpp\r
 src/http/pages/homepage.cpp\r
+src/http/pages/insertedfilespage.cpp\r
 src/http/pages/localidentitiespage.cpp\r
 src/http/pages/optionspage.cpp\r
 src/http/pages/peerdetailspage.cpp\r
diff --git a/include/freenet/fileinserter.h b/include/freenet/fileinserter.h
new file mode 100644 (file)
index 0000000..efc105a
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _fileinserter_\r
+#define _fileinserter_\r
+\r
+#include "iindexinserter.h"\r
+\r
+class FileInserter:public IIndexInserter<long>\r
+{\r
+public:\r
+       FileInserter();\r
+       FileInserter(FCPv2 *fcp);\r
+\r
+private:\r
+       void Initialize();\r
+       const bool HandlePutSuccessful(FCPMessage &message);\r
+       const bool HandlePutFailed(FCPMessage &message);\r
+       void StartInsert(const long &fileinsertid);\r
+       void CheckForNeededInsert();\r
+\r
+};\r
+\r
+#endif // _fileinserter_\r
index 7daa842..71e6e65 100644 (file)
@@ -15,14 +15,22 @@ public:
        std::string GetXML();\r
        const bool ParseXML(const std::string &xml);\r
 \r
-       std::string GetDate()                                           { return m_date; }\r
-       std::string GetTime()                                           { return m_time; }\r
-       std::string GetSubject()                                        { return m_subject; }\r
-       std::string GetMessageID()                                      { return m_messageid; }\r
-       std::string GetReplyBoard()                                     { return m_replyboard; }\r
-       std::string GetBody()                                           { return m_body; }\r
-       std::vector<std::string> GetBoards()            { return m_boards; }\r
-       std::map<long,std::string> GetInReplyTo()       { return m_inreplyto; }\r
+       struct fileattachment\r
+       {\r
+               fileattachment(const std::string &key, const int size):m_key(key),m_size(size)  {}\r
+               std::string m_key;\r
+               int m_size;\r
+       };\r
+\r
+       std::string GetDate()                                                           { return m_date; }\r
+       std::string GetTime()                                                           { return m_time; }\r
+       std::string GetSubject()                                                        { return m_subject; }\r
+       std::string GetMessageID()                                                      { return m_messageid; }\r
+       std::string GetReplyBoard()                                                     { return m_replyboard; }\r
+       std::string GetBody()                                                           { return m_body; }\r
+       std::vector<std::string> GetBoards()                            { return m_boards; }\r
+       std::map<long,std::string> GetInReplyTo()                       { return m_inreplyto; }\r
+       std::vector<fileattachment> GetFileAttachments()        { return m_fileattachments; }\r
 \r
        void SetDate(const std::string &date)                                                           { m_date=date; }\r
        void SetTime(const std::string &time)                                                           { m_time=time; }\r
@@ -32,6 +40,7 @@ public:
        void SetBody(const std::string &body)                                                           { m_body=body; }\r
        void AddBoard(const std::string &board)                                                         { m_boards.push_back(board); }\r
        void AddInReplyTo(const long index, const std::string &messageid)       { m_inreplyto[index]=messageid; }\r
+       void AddFileAttachment(const std::string &key, const int size)          { m_fileattachments.push_back(fileattachment(key,size)); }\r
 \r
 private:\r
        void Initialize();\r
@@ -43,6 +52,7 @@ private:
        std::vector<std::string> m_boards;\r
        std::string m_replyboard;\r
        std::map<long,std::string> m_inreplyto;\r
+       std::vector<fileattachment> m_fileattachments;\r
        std::string m_body;\r
 \r
 };\r
index 6db0d86..59d9dd2 100644 (file)
@@ -5,7 +5,7 @@
 #include <vector>\r
 #include "pthreadwrapper/thread.h"\r
 \r
-#define FMS_VERSION    "0.2.10"\r
+#define FMS_VERSION    "0.2.11"\r
 \r
 // opens database and creates tables and initial inserts if necessary\r
 void SetupDB();\r
@@ -16,6 +16,7 @@ void ConvertDB0104To0105();
 void ConvertDB0105To0106();\r
 void ConvertDB0106To0107();\r
 void ConvertDB0107To0108();\r
+void ConvertDB0108To0109();\r
 // inserts default options into the database\r
 void SetupDefaultOptions();\r
 // opens logfile and sets it up\r
diff --git a/include/http/pages/insertedfilespage.h b/include/http/pages/insertedfilespage.h
new file mode 100644 (file)
index 0000000..c09e638
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _insertedfilespage_\r
+#define _insertedfilespage_\r
+\r
+#include "../ipagehandler.h"\r
+#include "../../idatabase.h"\r
+\r
+class InsertedFilesPage:public IPageHandler,public IDatabase\r
+{\r
+public:\r
+       InsertedFilesPage(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 // _insertedfilespage_\r
index 5aed3ed..625aa22 100644 (file)
@@ -59,6 +59,13 @@ private:
        void StripAdministrationBoards();       // removes administration boards from boards vector\r
        const int FindLocalIdentityID(const std::string &name);\r
 \r
+       struct fileattachment\r
+       {\r
+               fileattachment(const std::string &filename, const std::vector<unsigned char> &data):m_filename(filename),m_data(data)   {}\r
+               std::string m_filename;\r
+               std::vector<unsigned char> m_data;\r
+       };\r
+\r
        long m_messageid;\r
        bool m_addnewpostfromidentities;\r
        std::string m_messageuuid;\r
@@ -69,6 +76,7 @@ private:
        std::string m_fromname;\r
        std::vector<std::string> m_boards;\r
        std::map<long,std::string> m_inreplyto;\r
+       std::vector<fileattachment> m_fileattachments;\r
        long m_changemessagetrustonreply;\r
        long m_minlocalmessagetrust;\r
        long m_minlocaltrustlisttrust;\r
index be55508..133a0aa 100644 (file)
@@ -1,7 +1,7 @@
 COMPILING\r
 ---------\r
-Compiling FMS requires CMake, and pthreads.  Other required libraries are\r
-bundled with FMS.\r
+Compiling FMS requires CMake, pthreads and iconv if you want to do charset\r
+conversion.  Other required libraries are bundled with FMS.\r
 \r
 To compile, run these commands from the source directory:\r
 cmake .\r
@@ -51,10 +51,13 @@ is discarded when posting messages.
 \r
 POSTING MESSAGES\r
 ----------------\r
-Use must set your newsreader to use UTF-8 when posting messages.  Any non-text\r
-attachment to the message will be stripped.  Text attachments will be inlined\r
-with the message body.  Cross posting is fine, but remember that each identity\r
-can set a limit to the number of boards each message may be cross posted to.\r
+You must set your newsreader to use UTF-8 when posting messages.  Any non-text\r
+attachment to the message will be inserted as a regular file and the key added\r
+to the body of the message when received.  Keep the attachments small, as the\r
+message can't be inserted until all attachments are inserted.  Text attachments\r
+will be inlined with the message body.  Cross posting is fine, but remember\r
+that each identity can set a limit to the number of boards each message may be\r
+cross posted to.\r
 \r
 CONTROL BOARDS\r
 --------------\r
@@ -76,6 +79,12 @@ content.  The Freesite will be inserted once a day and contain your last 10
 posts and your trust list if you are publishing it.  The site will be inserted\r
 to a USK accessible via: USK@yourpublickey.../fms/0/\r
 \r
+You may add extra files to your Freesite by creating a file called identityname-\r
+files.txt that contains a list of files to add to the Freesite.  There should\r
+be one file per line, and the path to each file may be absolute or relative to\r
+the working directory, but you MUST use / as the path separator.  Files cannot\r
+be named index.htm, trustlist.htm, or files.htm.\r
+\r
 TRUST\r
 -----\r
 Trust is the most important element of FMS.  It determines which identities you\r
index 81df27a..fea3d76 100644 (file)
@@ -229,8 +229,24 @@ const bool Statement::ResultBlob(const int column, void *data, int &length)
        {\r
                //ZThread::Guard<ZThread::Mutex> g(DB::instance()->m_mutex);\r
                //PThread::Guard g(DB::Instance()->m_mutex);\r
-               data=(void *)sqlite3_column_blob(m_statement,column);\r
-               length=sqlite3_column_bytes(m_statement,column);\r
+               int bloblength=sqlite3_column_bytes(m_statement,column);\r
+               if(bloblength>length)\r
+               {\r
+                       bloblength=length;\r
+               }\r
+               if(bloblength<length)\r
+               {\r
+                       length=bloblength;\r
+               }\r
+               const void *blobptr=sqlite3_column_blob(m_statement,column);\r
+               if(blobptr)\r
+               {\r
+                       std::copy((unsigned char *)blobptr,(unsigned char *)blobptr+bloblength,(unsigned char *)data);\r
+               }\r
+               else\r
+               {\r
+                       length=0;\r
+               }\r
                return true;\r
        }\r
        else\r
index 117d25a..3de52f0 100644 (file)
@@ -61,7 +61,7 @@ std::string BoardListXML::GetXML()
        for(std::vector<board>::iterator i=m_boards.begin(); i!=m_boards.end(); i++)\r
        {\r
                std::string boardname=(*i).m_name;\r
-               StringFunctions::Convert(boardname,boardname);\r
+               StringFunctions::LowerCase(boardname,boardname);\r
                TiXmlElement *tr=new TiXmlElement("Board");\r
                tid->LinkEndChild(tr);\r
                tr->LinkEndChild(XMLCreateCDATAElement("Name",boardname));\r
diff --git a/src/freenet/fileinserter.cpp b/src/freenet/fileinserter.cpp
new file mode 100644 (file)
index 0000000..d8d2721
--- /dev/null
@@ -0,0 +1,106 @@
+#include "../../include/freenet/fileinserter.h"\r
+\r
+#ifdef XMEM\r
+       #include <xmem.h>\r
+#endif\r
+\r
+FileInserter::FileInserter()\r
+{\r
+       Initialize();\r
+}\r
+\r
+FileInserter::FileInserter(FCPv2 *fcp):IIndexInserter<long>(fcp)\r
+{\r
+       Initialize();\r
+}\r
+\r
+void FileInserter::CheckForNeededInsert()\r
+{\r
+       // only do 1 insert at a time\r
+       if(m_inserting.size()==0)\r
+       {\r
+               SQLite3DB::Statement st=m_db->Prepare("SELECT FileInsertID FROM tblFileInserts WHERE Key IS NULL;");\r
+               st.Step();\r
+               if(st.RowReturned())\r
+               {\r
+                       int id=-1;\r
+                       st.ResultInt(0,id);\r
+                       StartInsert(id);\r
+               }\r
+       }\r
+}\r
+\r
+const bool FileInserter::HandlePutFailed(FCPMessage &message)\r
+{\r
+       std::vector<std::string> idparts;\r
+       long fileinsertid;\r
+\r
+       StringFunctions::Split(message["Identifier"],"|",idparts);\r
+       StringFunctions::Convert(idparts[1],fileinsertid);\r
+\r
+       RemoveFromInsertList(fileinsertid);\r
+\r
+       m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"FileInserter::HandlePutFailed failed to insert "+message["Identifier"]);\r
+\r
+       return true;\r
+\r
+}\r
+\r
+const bool FileInserter::HandlePutSuccessful(FCPMessage &message)\r
+{\r
+       std::vector<std::string> idparts;\r
+       long fileinsertid;\r
+\r
+       StringFunctions::Split(message["Identifier"],"|",idparts);\r
+       StringFunctions::Convert(idparts[1],fileinsertid);\r
+\r
+       SQLite3DB::Statement st=m_db->Prepare("UPDATE tblFileInserts SET Key=?, Data=NULL WHERE FileInsertID=?;");\r
+       st.Bind(0,message["URI"]);\r
+       st.Bind(1,fileinsertid);\r
+       st.Step();\r
+\r
+       RemoveFromInsertList(fileinsertid);\r
+\r
+       return true;\r
+}\r
+\r
+void FileInserter::Initialize()\r
+{\r
+       m_fcpuniquename="FileInserter";\r
+}\r
+\r
+void FileInserter::StartInsert(const long &fileinsertid)\r
+{\r
+       FCPMessage message;\r
+       std::string fileinsertidstr="";\r
+       std::string sizestr="";\r
+       std::string filename="";\r
+       int datalen=-1;\r
+       std::vector<char> data;\r
+\r
+       StringFunctions::Convert(fileinsertid,fileinsertidstr);\r
+\r
+\r
+       SQLite3DB::Statement st=m_db->Prepare("SELECT FileName,Size,Data FROM tblFileInserts WHERE FileInsertID=?;");\r
+       st.Bind(0,fileinsertid);\r
+       st.Step();\r
+\r
+       st.ResultText(0,filename);\r
+       st.ResultInt(1,datalen);\r
+       data.resize(datalen,0);\r
+       st.ResultBlob(2,&data[0],datalen);\r
+       data.resize(datalen);\r
+\r
+       StringFunctions::Convert(data.size(),sizestr);\r
+\r
+       message.SetName("ClientPut");\r
+       message["URI"]="CHK@";\r
+       message["TargetFilename"]=filename;\r
+       message["Identifier"]=m_fcpuniquename+"|"+fileinsertidstr;\r
+       message["UploadFrom"]="direct";\r
+       message["DataLength"]=sizestr;\r
+       m_fcp->SendMessage(message);\r
+       m_fcp->SendRaw(&data[0],data.size());\r
+\r
+       m_inserting.push_back(fileinsertid);\r
+}\r
index db72906..73d26b6 100644 (file)
@@ -19,6 +19,7 @@
 #include "../../include/freenet/boardlistinserter.h"\r
 #include "../../include/freenet/boardlistrequester.h"\r
 #include "../../include/freenet/siteinserter.h"\r
+#include "../../include/freenet/fileinserter.h"\r
 \r
 #include "../../include/pthreadwrapper/thread.h"\r
 \r
@@ -281,6 +282,7 @@ void FreenetMasterThread::Setup()
        m_registrables.push_back(new BoardListInserter(&m_fcp));\r
        m_registrables.push_back(new BoardListRequester(&m_fcp));\r
        m_registrables.push_back(new SiteInserter(&m_fcp));\r
+       m_registrables.push_back(new FileInserter(&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
index 3d5af9a..b4e1ce4 100644 (file)
@@ -13,17 +13,29 @@ MessageInserter::MessageInserter(FCPv2 *fcp):IIndexInserter<std::string>(fcp)
 \r
 void MessageInserter::CheckForNeededInsert()\r
 {\r
+       bool didinsert=false;\r
        // only do 1 insert at a time\r
        if(m_inserting.size()==0)\r
        {\r
                SQLite3DB::Statement st=m_db->Prepare("SELECT MessageUUID FROM tblMessageInserts INNER JOIN tblLocalIdentity ON tblMessageInserts.LocalIdentityID=tblLocalIdentity.LocalIdentityID WHERE tblLocalIdentity.PrivateKey IS NOT NULL AND tblLocalIdentity.PrivateKey <> '' AND tblMessageInserts.Inserted='false';");\r
                st.Step();\r
 \r
-               if(st.RowReturned())\r
+               while(st.RowReturned() && m_inserting.size()==0)\r
                {\r
-                       std::string messageuuid;\r
+                       std::string messageuuid="";\r
                        st.ResultText(0,messageuuid);\r
-                       StartInsert(messageuuid);\r
+\r
+                       // make sure there are no uninserted files attached to this message\r
+                       SQLite3DB::Statement st2=m_db->Prepare("SELECT FileInsertID FROM tblFileInserts WHERE Key IS NULL AND MessageUUID=?;");\r
+                       st2.Bind(0,messageuuid);\r
+                       st2.Step();\r
+\r
+                       if(st2.RowReturned()==false)\r
+                       {\r
+                               StartInsert(messageuuid);\r
+                       }\r
+\r
+                       st.Step();\r
                }\r
        }\r
 }\r
@@ -59,6 +71,7 @@ const bool MessageInserter::HandlePutSuccessful(FCPMessage &message)
        int localidentityid;\r
        int index;\r
        std::vector<std::string> idparts;\r
+\r
        StringFunctions::Split(message["Identifier"],"|",idparts);\r
        StringFunctions::Convert(idparts[3],index);\r
        StringFunctions::Convert(idparts[2],localidentityid);\r
@@ -92,6 +105,12 @@ const bool MessageInserter::HandlePutSuccessful(FCPMessage &message)
                st2.Bind(1,xml.GetXML());\r
                st2.Bind(2,idparts[1]);\r
                st2.Step();\r
+\r
+               //update file insert MessageUUID as well\r
+               st2=m_db->Prepare("UPDATE tblFileInserts SET MessageUUID=? WHERE MessageUUID=?;");\r
+               st2.Bind(0,idparts[4]);\r
+               st2.Bind(1,idparts[1]);\r
+               st2.Step();\r
        }\r
 \r
        RemoveFromInsertList(idparts[1]);\r
@@ -145,9 +164,27 @@ void MessageInserter::StartInsert(const std::string &messageuuid)
                }\r
                StringFunctions::Convert(index,indexstr);\r
 \r
+               xmlfile.ParseXML(xml);\r
+\r
+               // add file attachments to xml - must do this before we change UUID\r
+               st=m_db->Prepare("SELECT Key, Size FROM tblFileInserts WHERE MessageUUID=?;");\r
+               st.Bind(0,xmlfile.GetMessageID());\r
+               st.Step();\r
+               while(st.RowReturned())\r
+               {\r
+                       std::string key="";\r
+                       int size;\r
+                       \r
+                       st.ResultText(0,key);\r
+                       st.ResultInt(1,size);\r
+\r
+                       xmlfile.AddFileAttachment(key,size);\r
+\r
+                       st.Step();\r
+               }\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
index c9b78bb..836d402 100644 (file)
@@ -206,6 +206,25 @@ const bool MessageRequester::HandleAllData(FCPMessage &message)
 \r
                if(validmessage && savetoboardcount>0)\r
                {\r
+                       std::string nntpbody="";\r
+                       nntpbody=xml.GetBody();\r
+\r
+                       //add file keys/sizes to body\r
+                       std::vector<MessageXML::fileattachment> fileattachments=xml.GetFileAttachments();\r
+                       if(fileattachments.size()>0)\r
+                       {\r
+                               nntpbody+="\r\nAttachments";\r
+                       }\r
+                       for(std::vector<MessageXML::fileattachment>::iterator i=fileattachments.begin(); i!=fileattachments.end(); i++)\r
+                       {\r
+                               std::string sizestr="0";\r
+                               StringFunctions::Convert((*i).m_size,sizestr);\r
+\r
+                               nntpbody+="\r\n"+(*i).m_key;\r
+                               nntpbody+="\r\n"+sizestr+" bytes";\r
+                               nntpbody+="\r\n";\r
+                       }\r
+\r
                        st=m_db->Prepare("INSERT INTO tblMessage(IdentityID,FromName,MessageDate,MessageTime,Subject,MessageUUID,ReplyBoardID,Body,MessageIndex) VALUES(?,?,?,?,?,?,?,?,?);");\r
                        st.Bind(0,identityid);\r
                        st.Bind(1,GetIdentityName(identityid));\r
@@ -214,7 +233,7 @@ const bool MessageRequester::HandleAllData(FCPMessage &message)
                        st.Bind(4,xml.GetSubject());\r
                        st.Bind(5,xml.GetMessageID());\r
                        st.Bind(6,GetBoardID(xml.GetReplyBoard(),GetIdentityName(identityid)));\r
-                       st.Bind(7,xml.GetBody());\r
+                       st.Bind(7,nntpbody);\r
                        st.Bind(8,index);\r
                        inserted=st.Step(true);\r
                        int messageid=st.GetLastInsertRowID();\r
index ec5946e..9652c76 100644 (file)
@@ -51,6 +51,20 @@ std::string MessageXML::GetXML()
                }\r
        }\r
 \r
+       // add attachemnt node if we have attachments\r
+       if(m_fileattachments.size()>0)\r
+       {\r
+               TiXmlElement *attachments=new TiXmlElement("Attachments");\r
+               tid->LinkEndChild(attachments);\r
+               for(std::vector<fileattachment>::iterator j=m_fileattachments.begin(); j!=m_fileattachments.end(); j++)\r
+               {\r
+                       TiXmlElement *f=new TiXmlElement("File");\r
+                       attachments->LinkEndChild(f);\r
+                       f->LinkEndChild(XMLCreateCDATAElement("Key",(*j).m_key));\r
+                       f->LinkEndChild(XMLCreateTextElement("Size",(*j).m_size));\r
+               }\r
+       }\r
+\r
        td.Accept(&tp);\r
        return std::string(tp.CStr());\r
 }\r
@@ -64,6 +78,7 @@ void MessageXML::Initialize()
        m_replyboard="";\r
        m_inreplyto.clear();\r
        m_body="";\r
+       m_fileattachments.clear();\r
 }\r
 \r
 const bool MessageXML::ParseXML(const std::string &xml)\r
@@ -158,6 +173,36 @@ const bool MessageXML::ParseXML(const std::string &xml)
                        node2=node2->NextSibling("Message");\r
                }\r
 \r
+               node2=hnd.FirstChild("Message").FirstChild("Attachments").FirstChild("File").ToNode();\r
+               while(node2)\r
+               {\r
+                       std::string key="";\r
+                       std::string sizestr="-1";\r
+                       int size=-1;\r
+\r
+                       TiXmlHandle hnd2(node2);\r
+\r
+                       txt=hnd2.FirstChild("Key").FirstChild().ToText();\r
+                       if(txt)\r
+                       {\r
+                               key=txt->ValueStr();\r
+                       }\r
+\r
+                       txt=hnd2.FirstChild("Size").FirstChild().ToText();\r
+                       if(txt)\r
+                       {\r
+                               sizestr=txt->ValueStr();\r
+                               StringFunctions::Convert(sizestr,size);\r
+                       }\r
+\r
+                       if(key!="" && size>0)\r
+                       {\r
+                               m_fileattachments.push_back(fileattachment(key,size));\r
+                       }\r
+\r
+                       node2=node2->NextSibling("File");\r
+               }\r
+\r
                return true;\r
        }\r
        else\r
index 9db9651..9ee3019 100644 (file)
@@ -113,7 +113,7 @@ std::string SiteInserter::GenerateLinks(const bool publishtrustlist, const bool
 \r
 void SiteInserter::GeneratePages(const long localidentityid, std::string &uskkey, std::map<std::string,std::string> &pages)\r
 {\r
-       SQLite3DB::Statement st=m_db->Prepare("SELECT Name, PrivateKey, PublishTrustList, PublishBoardList FROM tblLocalIdentity WHERE LocalIdentityID=?;");\r
+       SQLite3DB::Statement st=m_db->Prepare("SELECT Name, PrivateKey, PublishTrustList, PublishBoardList, FreesiteEdition FROM tblLocalIdentity WHERE LocalIdentityID=?;");\r
        st.Bind(0,localidentityid);\r
        st.Step();\r
 \r
@@ -182,6 +182,66 @@ void SiteInserter::GeneratePages(const long localidentityid, std::string &uskkey
                        LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_ERROR,"SiteInserter::GeneratePages unable to open "+filename+" or site-template.htm.");\r
                }\r
 \r
+               // get extra files that the user wants to add to the Freesite\r
+               filename=name+"-files.txt";\r
+               infile=fopen(filename.c_str(),"r+b");\r
+               if(infile)\r
+               {\r
+                       std::vector<std::string> files;\r
+\r
+                       fseek(infile,0,SEEK_END);\r
+                       long len=ftell(infile);\r
+                       fseek(infile,0,SEEK_SET);\r
+\r
+                       std::vector<unsigned char> data;\r
+                       data.resize(len);\r
+                       fread(&data[0],1,data.size(),infile);\r
+                       fclose(infile);\r
+\r
+                       // split on \r and \n - on systems with \r\n line endings there will be blank entries, but we'll just skip those\r
+                       std::string filecontent(data.begin(),data.end());\r
+                       StringFunctions::SplitMultiple(filecontent,"\r\n",files);\r
+\r
+                       for(std::vector<std::string>::iterator i=files.begin(); i!=files.end(); i++)\r
+                       {\r
+                               if((*i)!="" && (*i).find("index.htm")==std::string::npos && (*i).find("trustlist.htm")==std::string::npos && (*i).find("files.htm")==std::string::npos)\r
+                               {\r
+                                       filename=(*i);\r
+                                       infile=fopen(filename.c_str(),"r+b");\r
+                                       if(infile)\r
+                                       {\r
+                                               fseek(infile,0,SEEK_END);\r
+                                               len=ftell(infile);\r
+                                               fseek(infile,0,SEEK_SET);\r
+\r
+                                               data.resize(len);\r
+                                               fread(&data[0],1,data.size(),infile);\r
+                                               fclose(infile);\r
+\r
+                                               filecontent="";\r
+                                               filecontent.append(data.begin(),data.end());\r
+\r
+                                               // strip off path from filename\r
+                                               while(filename.find_first_of("/")!=std::string::npos)\r
+                                               {\r
+                                                       filename.erase(0,filename.find_first_of("/")+1);\r
+                                               }\r
+\r
+                                               if(filecontent.size()>0)\r
+                                               {\r
+                                                       pages[filename]=filecontent;\r
+                                               }\r
+\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"SiteInserter::GeneratePages could not include user file "+(*i));\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+               }\r
+\r
        }\r
 }\r
 \r
@@ -285,6 +345,8 @@ const bool SiteInserter::HandlePutFailed(FCPMessage &message)
 \r
        RemoveFromInsertList(localidentityid);\r
 \r
+       m_log->WriteLog(LogFile::LOGLEVEL_ERROR,"SiteInserter::HandlePutFailed failed to insert Freesite, Freenet error code : "+message["Code"]);\r
+\r
        return true;\r
 }\r
 \r
index 2dea27b..7e6d842 100644 (file)
@@ -101,13 +101,19 @@ void SetupDB()
                        major=1;\r
                        minor=8;\r
                }\r
+               if(major==1 && minor==8)\r
+               {\r
+                       ConvertDB0108To0109();\r
+                       major=1;\r
+                       minor=9;\r
+               }\r
        }\r
        else\r
        {\r
-               db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,8);");\r
+               db->Execute("INSERT INTO tblDBVersion(Major,Minor) VALUES(1,9);");\r
        }\r
 \r
-       db->Execute("UPDATE tblDBVersion SET Major=1, Minor=8;");\r
+       db->Execute("UPDATE tblDBVersion SET Major=1, Minor=9;");\r
 \r
        db->Execute("CREATE TABLE IF NOT EXISTS tblOption(\\r
                                Option                          TEXT UNIQUE,\\r
@@ -328,6 +334,15 @@ void SetupDB()
                                Inserted                        BOOL CHECK(Inserted IN('true','false')) DEFAULT 'false'\\r
                                );");\r
 \r
+       db->Execute("CREATE TABLE IF NOT EXISTS tblFileInserts(\\r
+                               FileInsertID            INTEGER PRIMARY KEY,\\r
+                               MessageUUID                     TEXT,\\r
+                               FileName                        TEXT,\\r
+                               Key                                     TEXT,\\r
+                               Size                            INTEGER,\\r
+                               Data                            BLOB\\r
+                               );");\r
+\r
        db->Execute("CREATE TABLE IF NOT EXISTS tblMessageListInserts(\\r
                                LocalIdentityID         INTEGER,\\r
                                Day                                     DATE,\\r
@@ -598,6 +613,20 @@ void ConvertDB0107To0108()
        db->Execute("UPDATE tblDBVersion SET Major=1, Minor=8;");\r
 }\r
 \r
+void ConvertDB0108To0109()\r
+{\r
+       SQLite3DB::DB *db=SQLite3DB::DB::Instance();\r
+       db->Execute("CREATE TABLE IF NOT EXISTS tblFileInserts(\\r
+                       FileInsertID            INTEGER PRIMARY KEY,\\r
+                       MessageUUID                     TEXT,\\r
+                       FileName                        TEXT,\\r
+                       Key                                     TEXT,\\r
+                       Size                            INTEGER,\\r
+                       Data                            BLOB\\r
+                       );");\r
+       db->Execute("UPDATE tblDBVersion SET Major=1, Minor=9;");\r
+}\r
+\r
 void SetupDefaultOptions()\r
 {\r
        // OptionValue should always be inserted as a string, even if the option really isn't a string - just to keep the field data type consistent\r
index 22fc930..4760f80 100644 (file)
@@ -14,6 +14,7 @@
 #include "../../include/http/pages/peermaintenancepage.h"\r
 #include "../../include/http/pages/execquerypage.h"\r
 #include "../../include/http/pages/boardspage.h"\r
+#include "../../include/http/pages/insertedfilespage.h"\r
 \r
 #include <iostream>\r
 \r
@@ -63,6 +64,7 @@ HTTPThread::HTTPThread()
        m_pagehandlers.push_back(new PeerMaintenancePage(templatestr));\r
        m_pagehandlers.push_back(new ExecQueryPage(templatestr));\r
        m_pagehandlers.push_back(new BoardsPage(templatestr));\r
+       m_pagehandlers.push_back(new InsertedFilesPage(templatestr));\r
        // homepage must be last - catch all page handler\r
        m_pagehandlers.push_back(new HomePage(templatestr));\r
 \r
diff --git a/src/http/pages/insertedfilespage.cpp b/src/http/pages/insertedfilespage.cpp
new file mode 100644 (file)
index 0000000..13abc3d
--- /dev/null
@@ -0,0 +1,48 @@
+#include "../../../include/http/pages/insertedfilespage.h"\r
+#include "../../../include/stringfunctions.h"\r
+#include "../../../include/option.h"\r
+\r
+#ifdef XMEM\r
+       #include <xmem.h>\r
+#endif\r
+\r
+const std::string InsertedFilesPage::GeneratePage(const std::string &method, const std::map<std::string,std::string> &queryvars)\r
+{\r
+       std::string content="<h2>Inserted Files</h2>";\r
+\r
+       SQLite3DB::Statement st=m_db->Prepare("SELECT Key,FileName,Size FROM tblFileInserts WHERE Key IS NOT NULL ORDER BY FileName");\r
+       st.Step();\r
+\r
+       std::string node="localhost";\r
+       Option::Instance()->Get("FCPHost",node);\r
+\r
+       while(st.RowReturned())\r
+       {\r
+               std::string key="";\r
+               std::string filename="";\r
+               std::string sizestr="";\r
+\r
+               st.ResultText(0,key);\r
+               st.ResultText(1,filename);\r
+               st.ResultText(2,sizestr);\r
+\r
+               content+="<a href=\"http://"+node+":8888/"+StringFunctions::UriEncode(key)+"\">"+SanitizeOutput(filename)+"</a> - "+sizestr+" bytes";\r
+               content+="<br>";\r
+\r
+               st.Step();\r
+       }\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 InsertedFilesPage::WillHandleURI(const std::string &uri)\r
+{\r
+       if(uri.find("insertedfiles.")!=std::string::npos)\r
+       {\r
+               return true;\r
+       }\r
+       else\r
+       {\r
+               return false;\r
+       }\r
+}\r
index d2693f5..5905021 100644 (file)
@@ -325,6 +325,7 @@ void Message::Initialize()
        m_fromname="";\r
        m_boards.clear();\r
        m_inreplyto.clear();\r
+       m_fileattachments.clear();\r
        m_changemessagetrustonreply=0;\r
        Option::Instance()->Get("ChangeMessageTrustOnReply",tempval);\r
        StringFunctions::Convert(tempval,m_changemessagetrustonreply);\r
@@ -694,6 +695,12 @@ const bool Message::ParseNNTPMessage(const std::string &nntpmessage)
 #endif\r
                        m_body+=bodypart;\r
                }\r
+               // add a binary file attachment\r
+               else if((*i)->GetName()!="" && (*i)->GetLength()>0 && (*i)->GetContent())\r
+               {\r
+                       std::vector<unsigned char> data((*i)->GetContent(),(*i)->GetContent()+(*i)->GetContentLength());\r
+                       m_fileattachments.push_back(fileattachment((*i)->GetName(),data));\r
+               }\r
        }\r
 \r
        return true;\r
@@ -735,6 +742,18 @@ const bool Message::StartFreenetInsert()
        st.Bind(2,xml.GetXML());\r
        st.Step();\r
 \r
+       // insert file attachments into database\r
+       st=m_db->Prepare("INSERT INTO tblFileInserts(MessageUUID,FileName,Size,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_data[0]),(*i).m_data.size());\r
+               st.Step();\r
+               st.Reset();\r
+       }\r
+\r
        HandleChangeTrust();\r
 \r
        return true;\r
index c35813c..7509afd 100644 (file)
@@ -238,6 +238,7 @@ td          { padding-left:5px; padding-right:5px; }
                        <li><a href="peertrust.htm">Peer Trust</a></li>\r
                        <li><a href="boards.htm">Boards</a></li>\r
                        <li><a href="controlboard.htm">Control Boards</a></li>\r
+                       <li><a href="insertedfiles.htm">Inserted Files</a></li>\r
                </ul>\r
                </div>\r
        \r