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