1 #include "../include/fmsapp.h"
\r
2 #include "../include/global.h"
\r
3 #include "../include/dbsetup.h"
\r
4 #include "../include/optionssetup.h"
\r
5 #include "../include/option.h"
\r
6 #include "../include/stringfunctions.h"
\r
7 #include "../include/http/httpthread.h"
\r
8 #include "../include/nntp/nntplistener.h"
\r
9 #include "../include/dbmaintenancethread.h"
\r
10 #include "../include/freenet/freenetmasterthread.h"
\r
11 #include "../include/threadwrapper/threadedexecutor.h"
\r
13 #include <Poco/Util/HelpFormatter.h>
\r
14 #include <Poco/FileChannel.h>
\r
15 #include <Poco/ConsoleChannel.h>
\r
16 #include <Poco/FormattingChannel.h>
\r
17 #include <Poco/PatternFormatter.h>
\r
27 #include <Poco/ScopedLock.h>
\r
28 #include <Poco/Runnable.h>
\r
29 #include <Poco/Thread.h>
\r
30 #include <Poco/ThreadPool.h>
\r
31 #include "../include/threadwrapper/cancelablerunnable.h"
\r
32 #include "../include/threadwrapper/cancelablethread.h"
\r
35 class TestRunner:public CancelableRunnable
\r
43 }while(!IsCancelled());
\r
47 FMSApp::FMSApp():m_displayhelp(false),m_logtype("file")
\r
52 void FMSApp::defineOptions(Poco::Util::OptionSet &options)
\r
54 ServerApplication::defineOptions(options);
\r
56 // add command line options here
\r
57 options.addOption(Poco::Util::Option("help","?","display help for command line arguments",false).repeatable(false).callback(Poco::Util::OptionCallback<FMSApp>(this,&FMSApp::handleHelp)));
\r
58 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
61 void FMSApp::displayHelp()
\r
63 Poco::Util::HelpFormatter helpFormatter(options());
\r
64 helpFormatter.setCommand(commandName());
\r
65 helpFormatter.setUsage("OPTIONS");
\r
66 helpFormatter.setHeader("The Freenet Message System.");
\r
67 helpFormatter.format(std::cout);
\r
70 void FMSApp::handleHelp(const std::string &name, const std::string &value)
\r
74 stopOptionsProcessing();
\r
77 void FMSApp::handleLogOption(const std::string &name, const std::string &value)
\r
79 if(value=="file" || value=="stdout" || value=="stderr")
\r
85 void FMSApp::initialize(Poco::Util::Application &self)
\r
87 ServerApplication::initialize(self);
\r
89 // set working directory to program directory
\r
90 int rval=chdir(config().getString("application.dir").c_str());
\r
93 SetupDefaultOptions();
\r
95 config().setString("application.logger","logfile");
\r
98 void FMSApp::initializeLogger()
\r
100 int initiallevel=Poco::Message::PRIO_TRACE;
\r
102 std::string tempval="";
\r
103 if(Option::Instance()->Get("LogLevel",tempval))
\r
105 StringFunctions::Convert(tempval,initiallevel);
\r
108 Poco::AutoPtr<Poco::FormattingChannel> formatter=new Poco::FormattingChannel(new Poco::PatternFormatter("%Y-%m-%d %H:%M:%S | %p | %t"));
\r
110 if(m_logtype=="file")
\r
112 Poco::AutoPtr<Poco::FileChannel> fc=new Poco::FileChannel("fms.log");
\r
113 fc->setProperty("rotation","daily"); // rotate log file daily
\r
114 fc->setProperty("times","utc"); // utc date/times for log entries
\r
115 fc->setProperty("archive","timestamp"); // add timestamp to old logs
\r
116 fc->setProperty("purgeCount","30"); // purge old logs after 30 logs have accumulated
\r
117 fc->setProperty("compress","true"); // gz compress old log files
\r
118 formatter->setChannel(fc);
\r
122 if(m_logtype=="stdout")
\r
124 Poco::AutoPtr<Poco::ConsoleChannel> cc=new Poco::ConsoleChannel(std::cout);
\r
125 formatter->setChannel(cc);
\r
129 Poco::AutoPtr<Poco::ConsoleChannel> cc=new Poco::ConsoleChannel(std::cerr);
\r
130 formatter->setChannel(cc);
\r
134 setLogger(Poco::Logger::create("logfile",formatter,initiallevel));
\r
137 int FMSApp::main(const std::vector<std::string> &args)
\r
140 // running as a daemon would reset the working directory to / before calling main
\r
141 // so we need to set the working directory again
\r
142 // set working directory to program directory
\r
143 int rval=chdir(config().getString("application.dir").c_str());
\r
145 if(m_displayhelp==false)
\r
147 logger().information("FMS startup v"FMS_VERSION);
\r
151 if(isInteractive()==true)
\r
153 std::cout << "FMS has been started." << std::endl << std::endl;
\r
156 waitForTerminationRequest();
\r
158 m_threads.Cancel();
\r
161 logger().information("FMS shutdown");
\r
164 return FMSApp::EXIT_OK;
\r
167 void FMSApp::StartThreads()
\r
169 std::string tempval="";
\r
171 // always start the DB maintenance thread
\r
172 m_threads.Start(new DBMaintenanceThread());
\r
174 Option::Instance()->Get("StartHTTP",tempval);
\r
175 if(tempval=="true")
\r
177 m_threads.Start(new HTTPThread());
\r
181 Option::Instance()->Get("StartNNTP",tempval);
\r
182 if(tempval=="true")
\r
184 m_threads.Start(new NNTPListener());
\r
188 Option::Instance()->Get("StartFreenetUpdater",tempval);
\r
189 if(tempval=="true")
\r
191 m_threads.Start(new FreenetMasterThread());
\r