version 0.3.4
authorSomeDude <SomeDude@NuBL7aaJ6Cn4fB7GXFb9Zfi8w1FhPyW3oKgU9TweZMw>
Thu, 3 Jul 2008 17:45:00 +0000 (19:45 +0200)
committerDavid ‘Bombe’ Roden <bombe@freenetproject.org>
Thu, 3 Jul 2008 17:45:00 +0000 (19:45 +0200)
include/fmsapp.h
include/global.h
readme.txt
src/charsetconverter.cpp
src/fmsapp.cpp
src/http/httpthread.cpp
src/http/ipagehandler.cpp
src/http/pages/homepage.cpp
src/nntp/nntplistener.cpp
src/optionssetup.cpp

index dab56e1..ac2ef7d 100644 (file)
@@ -5,6 +5,8 @@
 \r
 #include <Poco/Util/ServerApplication.h>\r
 \r
 \r
 #include <Poco/Util/ServerApplication.h>\r
 \r
+#include <map>\r
+\r
 // main FMS application class\r
 class FMSApp:public Poco::Util::ServerApplication\r
 {\r
 // main FMS application class\r
 class FMSApp:public Poco::Util::ServerApplication\r
 {\r
@@ -24,8 +26,15 @@ private:
        void handleHelp(const std::string &name, const std::string &value);\r
        void displayHelp();\r
        void handleLogOption(const std::string &name, const std::string &value);\r
        void handleHelp(const std::string &name, const std::string &value);\r
        void displayHelp();\r
        void handleLogOption(const std::string &name, const std::string &value);\r
+       void handleShowOptions(const std::string &name, const std::string &value);\r
+       void showOptions();\r
+       void handleSetOption(const std::string &name, const std::string &value);\r
+       void setOptions();\r
 \r
        bool m_displayhelp;\r
 \r
        bool m_displayhelp;\r
+       bool m_showoptions;\r
+       bool m_setoption;\r
+       std::map<std::string,std::string> m_setoptions;\r
        std::string m_logtype;\r
 \r
        ThreadedExecutor m_threads;\r
        std::string m_logtype;\r
 \r
        ThreadedExecutor m_threads;\r
index bd580af..ce732de 100644 (file)
@@ -7,7 +7,7 @@
 \r
 #define VERSION_MAJOR          "0"\r
 #define VERSION_MINOR          "3"\r
 \r
 #define VERSION_MAJOR          "0"\r
 #define VERSION_MINOR          "3"\r
-#define VERSION_RELEASE                "3"\r
+#define VERSION_RELEASE                "4"\r
 #define FMS_VERSION                    VERSION_MAJOR"."VERSION_MINOR"."VERSION_RELEASE\r
 \r
 typedef Poco::ScopedLock<Poco::FastMutex> Guard;\r
 #define FMS_VERSION                    VERSION_MAJOR"."VERSION_MINOR"."VERSION_RELEASE\r
 \r
 typedef Poco::ScopedLock<Poco::FastMutex> Guard;\r
index 77ca276..3df7b4b 100644 (file)
@@ -39,6 +39,17 @@ argument when installing the service to set the service name to whatever you
 want.  You will need to manually start the service unless you change the\r
 startup type in the service properties.\r
 \r
 want.  You will need to manually start the service unless you change the\r
 startup type in the service properties.\r
 \r
+If you are experiencing a problem with FMS that you can't solve, and you've\r
+already rebooted your machine, restarted FMS, and have reproduced the problem\r
+with a brand new database, follow these instructions.  Set the logging option\r
+to trace and restart FMS.  Create a post on the fms group that contains the\r
+operating system you are using, along with a description of the problem, what\r
+you have tried already, if you are using a precompiled binary, the startup\r
+lines from the log file as well as the portion that corresponds to the problem\r
+you are experiencing, and any other information you have that pertains to the\r
+problem.  Make sure to anonymize any IP addresses, host names, subnet masks,\r
+and keys from the log that you don't want people to know about.\r
+\r
 EXITING\r
 -------\r
 To exit FMS running in console mode, press CTRL+C while at the console.  You\r
 EXITING\r
 -------\r
 To exit FMS running in console mode, press CTRL+C while at the console.  You\r
index b56eb2d..9e4ff6f 100644 (file)
@@ -57,6 +57,7 @@ const bool CharsetConverter::Convert(const std::string &input, std::string &outp
                char *outptr=&outvec[0];\r
                size_t insize=invec.size();\r
                size_t outsize=outvec.size();\r
                char *outptr=&outvec[0];\r
                size_t insize=invec.size();\r
                size_t outsize=outvec.size();\r
+\r
                size_t rval=0;\r
                \r
                rval=iconv(m_iconv,&inptr,&insize,&outptr,&outsize);\r
                size_t rval=0;\r
                \r
                rval=iconv(m_iconv,&inptr,&insize,&outptr,&outsize);\r
index 04562fc..99712c5 100644 (file)
@@ -9,6 +9,7 @@
 #include "../include/dbmaintenancethread.h"\r
 #include "../include/freenet/freenetmasterthread.h"\r
 #include "../include/threadwrapper/threadedexecutor.h"\r
 #include "../include/dbmaintenancethread.h"\r
 #include "../include/freenet/freenetmasterthread.h"\r
 #include "../include/threadwrapper/threadedexecutor.h"\r
+#include "../include/db/sqlite3db.h"\r
 \r
 #include <Poco/Util/HelpFormatter.h>\r
 #include <Poco/FileChannel.h>\r
 \r
 #include <Poco/Util/HelpFormatter.h>\r
 #include <Poco/FileChannel.h>\r
        #include <unistd.h>\r
 #endif\r
 \r
        #include <unistd.h>\r
 #endif\r
 \r
-//debug\r
-#include <Poco/ScopedLock.h>\r
-#include <Poco/Runnable.h>\r
-#include <Poco/Thread.h>\r
-#include <Poco/ThreadPool.h>\r
-#include "../include/threadwrapper/cancelablerunnable.h"\r
-#include "../include/threadwrapper/cancelablethread.h"\r
-\r
-Poco::FastMutex m1;\r
-class TestRunner:public CancelableRunnable\r
-{\r
-public:\r
-       void run()\r
-       {\r
-               do\r
-               {\r
-\r
-               }while(!IsCancelled());\r
-       }\r
-};\r
-\r
-FMSApp::FMSApp():m_displayhelp(false),m_logtype("file")\r
+FMSApp::FMSApp():m_displayhelp(false),m_showoptions(false),m_setoption(false),m_logtype("file")\r
 {\r
 \r
 }\r
 {\r
 \r
 }\r
@@ -54,8 +34,10 @@ void FMSApp::defineOptions(Poco::Util::OptionSet &options)
        ServerApplication::defineOptions(options);\r
 \r
        // add command line options here\r
        ServerApplication::defineOptions(options);\r
 \r
        // add command line options here\r
-       options.addOption(Poco::Util::Option("help","?","display help for command line arguments",false).repeatable(false).callback(Poco::Util::OptionCallback<FMSApp>(this,&FMSApp::handleHelp)));\r
-       options.addOption(Poco::Util::Option("log","l","select type of log output (file|stdout|stderr)",false,"type",true).repeatable(false).callback(Poco::Util::OptionCallback<FMSApp>(this,&FMSApp::handleLogOption)));\r
+       options.addOption(Poco::Util::Option("help","?","Display help for command line arguments.",false).repeatable(false).callback(Poco::Util::OptionCallback<FMSApp>(this,&FMSApp::handleHelp)));\r
+       options.addOption(Poco::Util::Option("log","l","Select type of log output (file|stdout|stderr).",false,"type",true).repeatable(false).callback(Poco::Util::OptionCallback<FMSApp>(this,&FMSApp::handleLogOption)));\r
+       options.addOption(Poco::Util::Option("showoptions","","Show all options that can be set and their current values.",false).repeatable(false).callback(Poco::Util::OptionCallback<FMSApp>(this,&FMSApp::handleShowOptions)));\r
+       options.addOption(Poco::Util::Option("setoption","","Set an option.  Values are not validated, so be sure to set them correctly.",false,"option=value",true).repeatable(true).callback(Poco::Util::OptionCallback<FMSApp>(this,&FMSApp::handleSetOption)));\r
 }\r
 \r
 void FMSApp::displayHelp()\r
 }\r
 \r
 void FMSApp::displayHelp()\r
@@ -82,6 +64,28 @@ void FMSApp::handleLogOption(const std::string &name, const std::string &value)
        }\r
 }\r
 \r
        }\r
 }\r
 \r
+void FMSApp::handleSetOption(const std::string &name, const std::string &value)\r
+{\r
+       std::vector<std::string> valueparts;\r
+       StringFunctions::Split(value,"=",valueparts);\r
+\r
+       if(valueparts.size()==2)\r
+       {\r
+               m_setoptions[valueparts[0]]=valueparts[1];\r
+       }\r
+       else\r
+       {\r
+               std::cout << "Expected option=value but found " << value << std::endl;\r
+       }\r
+\r
+       m_setoption=true;\r
+}\r
+\r
+void FMSApp::handleShowOptions(const std::string &name, const std::string &value)\r
+{\r
+       m_showoptions=true;\r
+}\r
+\r
 void FMSApp::initialize(Poco::Util::Application &self)\r
 {\r
        ServerApplication::initialize(self);\r
 void FMSApp::initialize(Poco::Util::Application &self)\r
 {\r
        ServerApplication::initialize(self);\r
@@ -131,7 +135,9 @@ void FMSApp::initializeLogger()
                }\r
        }\r
        \r
                }\r
        }\r
        \r
-       setLogger(Poco::Logger::create("logfile",formatter,initiallevel));\r
+       setLogger(Poco::Logger::create("logfile",formatter,Poco::Message::PRIO_INFORMATION));\r
+       Poco::Logger::get("logfile").information("LogLevel set to "+tempval);\r
+       Poco::Logger::get("logfile").setLevel(initiallevel);\r
 }\r
 \r
 int FMSApp::main(const std::vector<std::string> &args)\r
 }\r
 \r
 int FMSApp::main(const std::vector<std::string> &args)\r
@@ -142,7 +148,18 @@ int FMSApp::main(const std::vector<std::string> &args)
        // set working directory to program directory\r
        int rval=chdir(config().getString("application.dir").c_str());\r
 \r
        // set working directory to program directory\r
        int rval=chdir(config().getString("application.dir").c_str());\r
 \r
-       if(m_displayhelp==false)\r
+       if(m_displayhelp)\r
+       {\r
+       }\r
+       else if(m_showoptions)\r
+       {\r
+               showOptions();\r
+       }\r
+       else if(m_setoption)\r
+       {\r
+               setOptions();\r
+       }\r
+       else\r
        {\r
                logger().information("FMS startup v"FMS_VERSION);\r
 \r
        {\r
                logger().information("FMS startup v"FMS_VERSION);\r
 \r
@@ -155,7 +172,9 @@ int FMSApp::main(const std::vector<std::string> &args)
 \r
                waitForTerminationRequest();\r
 \r
 \r
                waitForTerminationRequest();\r
 \r
+               logger().trace("FMSApp::main cancelling threads");\r
                m_threads.Cancel();\r
                m_threads.Cancel();\r
+               logger().trace("FMSApp::main joining threads");\r
                m_threads.Join();\r
 \r
                logger().information("FMS shutdown");\r
                m_threads.Join();\r
 \r
                logger().information("FMS shutdown");\r
@@ -164,16 +183,52 @@ int FMSApp::main(const std::vector<std::string> &args)
        return FMSApp::EXIT_OK;\r
 }\r
 \r
        return FMSApp::EXIT_OK;\r
 }\r
 \r
+void FMSApp::setOptions()\r
+{\r
+       for(std::map<std::string,std::string>::iterator i=m_setoptions.begin(); i!=m_setoptions.end(); i++)\r
+       {\r
+               std::string tempval="";\r
+               if(Option::Instance()->Get((*i).first,tempval))\r
+               {\r
+                       Option::Instance()->Set((*i).first,(*i).second);\r
+                       std::cout << "Option " << (*i).first << " set to " << (*i).second << std::endl;\r
+               }\r
+               else\r
+               {\r
+                       std::cout << "Unknown option " << (*i).first << std::endl;\r
+               }\r
+       }\r
+}\r
+\r
+void FMSApp::showOptions()\r
+{\r
+       SQLite3DB::Statement st=SQLite3DB::DB::Instance()->Prepare("SELECT Option, OptionValue FROM tblOption;");\r
+       st.Step();\r
+       while(st.RowReturned())\r
+       {\r
+               std::string option="";\r
+               std::string optionvalue="";\r
+               st.ResultText(0,option);\r
+               st.ResultText(1,optionvalue);\r
+\r
+               std::cout << option << " = " << optionvalue << std::endl;\r
+\r
+               st.Step();\r
+       }\r
+}\r
+\r
 void FMSApp::StartThreads()\r
 {\r
        std::string tempval="";\r
 \r
        // always start the DB maintenance thread\r
 void FMSApp::StartThreads()\r
 {\r
        std::string tempval="";\r
 \r
        // always start the DB maintenance thread\r
+       logger().trace("FMSApp::StartThreads starting DBMaintenanceThread");\r
        m_threads.Start(new DBMaintenanceThread());\r
 \r
        Option::Instance()->Get("StartHTTP",tempval);\r
        if(tempval=="true")\r
        {\r
        m_threads.Start(new DBMaintenanceThread());\r
 \r
        Option::Instance()->Get("StartHTTP",tempval);\r
        if(tempval=="true")\r
        {\r
+               logger().trace("FMSApp::StartThreads starting HTTPThread");\r
                m_threads.Start(new HTTPThread());\r
        }\r
 \r
                m_threads.Start(new HTTPThread());\r
        }\r
 \r
@@ -181,6 +236,7 @@ void FMSApp::StartThreads()
        Option::Instance()->Get("StartNNTP",tempval);\r
        if(tempval=="true")\r
        {\r
        Option::Instance()->Get("StartNNTP",tempval);\r
        if(tempval=="true")\r
        {\r
+               logger().trace("FMSApp::StartThreads starting NNTPListener");\r
                m_threads.Start(new NNTPListener());\r
        }\r
 \r
                m_threads.Start(new NNTPListener());\r
        }\r
 \r
@@ -188,6 +244,7 @@ void FMSApp::StartThreads()
        Option::Instance()->Get("StartFreenetUpdater",tempval);\r
        if(tempval=="true")\r
        {\r
        Option::Instance()->Get("StartFreenetUpdater",tempval);\r
        if(tempval=="true")\r
        {\r
+               logger().trace("FMSApp::StartThreads starting FreenetMasterThread");\r
                m_threads.Start(new FreenetMasterThread());\r
        }\r
 \r
                m_threads.Start(new FreenetMasterThread());\r
        }\r
 \r
index ecc4cf5..89edc93 100644 (file)
@@ -19,49 +19,8 @@ HTTPThread::HTTPThread()
        std::string portstr;\r
        Option::Instance()->Get("HTTPListenPort",portstr);\r
        StringFunctions::Convert(portstr,m_listenport);\r
        std::string portstr;\r
        Option::Instance()->Get("HTTPListenPort",portstr);\r
        StringFunctions::Convert(portstr,m_listenport);\r
-\r
-       // push back page handlers\r
-       /*\r
-       m_pagehandlers.push_back(new ShowCaptchaPage());\r
-       m_pagehandlers.push_back(new OptionsPage(templatestr));\r
-       m_pagehandlers.push_back(new LocalIdentitiesPage(templatestr));\r
-       m_pagehandlers.push_back(new CreateIdentityPage(templatestr));\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
-       m_pagehandlers.push_back(new PeerDetailsPage(templatestr));\r
-       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
-       m_pagehandlers.push_back(new ConfirmPage(templatestr));\r
-       // homepage must be last - catch all page handler\r
-       m_pagehandlers.push_back(new HomePage(templatestr));\r
-       */\r
-       \r
 }\r
 \r
 }\r
 \r
-/*\r
-void HTTPThread::PageCallback(shttpd_arg *arg)\r
-{\r
-\r
-       HTTPThread *thread=(HTTPThread *)arg->user_data;\r
-\r
-       for(std::vector<IPageHandler *>::iterator i=thread->m_pagehandlers.begin(); i!=thread->m_pagehandlers.end(); )\r
-       {\r
-               if((*i)->Handle(arg)==true)\r
-               {\r
-                       i=thread->m_pagehandlers.end();\r
-               }\r
-               else\r
-               {\r
-                       i++;\r
-               }\r
-       }\r
-\r
-}\r
-*/\r
 void HTTPThread::run()\r
 {\r
        m_log->debug("HTTPThread::run thread started.");\r
 void HTTPThread::run()\r
 {\r
        m_log->debug("HTTPThread::run thread started.");\r
@@ -83,6 +42,12 @@ void HTTPThread::run()
        m_log->trace("Trying to stop HTTPServer");\r
        srv.stop();\r
        m_log->trace("Stopped HTTPServer");\r
        m_log->trace("Trying to stop HTTPServer");\r
        srv.stop();\r
        m_log->trace("Stopped HTTPServer");\r
+       \r
+       m_log->trace("Waiting for current HTTP requests to finish");\r
+       while(srv.currentConnections()>0)\r
+       {\r
+               Poco::Thread::sleep(500);\r
+       }\r
 \r
        m_log->debug("HTTPThread::run thread exiting.");\r
 \r
 \r
        m_log->debug("HTTPThread::run thread exiting.");\r
 \r
index b8bef90..53211b1 100644 (file)
@@ -72,6 +72,19 @@ void IPageHandler::CreateQueryVarMap(Poco::Net::HTTPServerRequest &request, std:
                vars[(*i).first]=(*i).second;\r
        }\r
 \r
                vars[(*i).first]=(*i).second;\r
        }\r
 \r
+       // for a POST method, the HTMLForm won't grab vars off the query string so we\r
+       // temporarily set the method to GET and parse with the HTMLForm again\r
+       if(request.getMethod()=="POST")\r
+       {\r
+               request.setMethod("GET");\r
+               Poco::Net::HTMLForm form1(request,request.stream(),mpp);\r
+               for(Poco::Net::HTMLForm::ConstIterator i=form1.begin(); i!=form1.end(); i++)\r
+               {\r
+                       vars[(*i).first]=(*i).second;\r
+               }\r
+               request.setMethod("POST");\r
+       }\r
+\r
        // get any multiparts\r
        std::map<std::string,std::string> mpvars=mpp.GetVars();\r
        for(std::map<std::string,std::string>::iterator i=mpvars.begin(); i!=mpvars.end(); i++)\r
        // get any multiparts\r
        std::map<std::string,std::string> mpvars=mpp.GetVars();\r
        for(std::map<std::string,std::string>::iterator i=mpvars.begin(); i!=mpvars.end(); i++)\r
index b295f45..a64efd2 100644 (file)
@@ -32,7 +32,7 @@ const std::string HomePage::GeneratePage(const std::string &method, const std::m
        content+="</b><br>";\r
 \r
        bool showgenericupdate=true;\r
        content+="</b><br>";\r
 \r
        bool showgenericupdate=true;\r
-       SQLite3DB::Statement st=m_db->Prepare("SELECT Major, Minor, Release, PageKey FROM tblFMSVersion ORDER BY Major DESC, Minor DESC, Release DESC;");\r
+       SQLite3DB::Statement st=m_db->Prepare("SELECT Major, Minor, Release, PageKey FROM tblFMSVersion ORDER BY Major DESC, Minor DESC, Release DESC LIMIT 1;");\r
        st.Step();\r
        if(st.RowReturned())\r
        {\r
        st.Step();\r
        if(st.RowReturned())\r
        {\r
@@ -58,7 +58,7 @@ const std::string HomePage::GeneratePage(const std::string &method, const std::m
 \r
        if(showgenericupdate)\r
        {\r
 \r
        if(showgenericupdate)\r
        {\r
-               content+="Check for new versions at the <a href=\"http://"+fcphost+":"+fproxyport+"/USK@0npnMrqZNKRCRoGojZV93UNHCMN-6UU3rRSAmP6jNLE,~BG-edFtdCC1cSH4O3BWdeIYa8Sw5DfyrSV-TKdO5ec,AQACAAE/fms/60/\">FMS Freesite</a><br>";\r
+               content+="Check for new versions at the <a href=\"http://"+fcphost+":"+fproxyport+"/USK@0npnMrqZNKRCRoGojZV93UNHCMN-6UU3rRSAmP6jNLE,~BG-edFtdCC1cSH4O3BWdeIYa8Sw5DfyrSV-TKdO5ec,AQACAAE/fms/63/\">FMS Freesite</a><br>";\r
        }\r
 \r
        content+="Use these pages to administer your FMS installation.";\r
        }\r
 \r
        content+="Use these pages to administer your FMS installation.";\r
index 2db0cfd..860da2c 100644 (file)
@@ -4,6 +4,8 @@
 #include "../../include/global.h"\r
 #include "../../include/stringfunctions.h"\r
 \r
 #include "../../include/global.h"\r
 #include "../../include/stringfunctions.h"\r
 \r
+#include <Poco/Net/SocketAddress.h>\r
+\r
 #include <cstring>\r
 \r
 #ifdef _WIN32\r
 #include <cstring>\r
 \r
 #ifdef _WIN32\r
@@ -133,18 +135,21 @@ void NNTPListener::StartListen()
                {\r
                        for(current=result; current!=NULL; current=current->ai_next)\r
                        {\r
                {\r
                        for(current=result; current!=NULL; current=current->ai_next)\r
                        {\r
+                               Poco::Net::SocketAddress sa(current->ai_addr,current->ai_addrlen);\r
+                               m_log->debug("NNTPListener::StartListen trying to create socket, bind, and listen on "+sa.toString());\r
+\r
                                sock=socket(current->ai_family,current->ai_socktype,current->ai_protocol);\r
                                if(sock!=INVALID_SOCKET)\r
                                {\r
                                        #ifndef _WIN32\r
                                        const char optval='1';\r
                                sock=socket(current->ai_family,current->ai_socktype,current->ai_protocol);\r
                                if(sock!=INVALID_SOCKET)\r
                                {\r
                                        #ifndef _WIN32\r
                                        const char optval='1';\r
-                                       setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&optval,1);\r
+                                       setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval));\r
                                        #endif\r
                                        if(bind(sock,current->ai_addr,current->ai_addrlen)==0)\r
                                        {\r
                                                if(listen(sock,10)==0)\r
                                                {\r
                                        #endif\r
                                        if(bind(sock,current->ai_addr,current->ai_addrlen)==0)\r
                                        {\r
                                                if(listen(sock,10)==0)\r
                                                {\r
-                                                       m_log->information("NNTPListener::StartListen started listening at "+(*i)+":"+nntpport);\r
+                                                       m_log->information("NNTPListener::StartListen started listening on "+sa.toString());\r
                                                        m_listensockets.push_back(sock);\r
                                                }\r
                                                else\r
                                                        m_listensockets.push_back(sock);\r
                                                }\r
                                                else\r
index e9fc7ce..b0bf701 100644 (file)
@@ -68,7 +68,7 @@ void SetupDefaultOptions()
        upd.Reset();\r
 \r
        st.Bind(0,"FMSVersionEdition");\r
        upd.Reset();\r
 \r
        st.Bind(0,"FMSVersionEdition");\r
-       st.Bind(1,"0");\r
+       st.Bind(1,"3");\r
        st.Step();\r
        upd.Bind(0,"Program");\r
        upd.Bind(1,order++);\r
        st.Step();\r
        upd.Bind(0,"Program");\r
        upd.Bind(1,order++);\r