version 0.3.29
[fms.git] / src / nntp / nntplistener.cpp
index 7f6e469..a34fc15 100644 (file)
@@ -1,10 +1,13 @@
 #include "../../include/nntp/nntplistener.h"\r
 #include "../../include/nntp/nntpconnection.h"\r
 #include "../../include/option.h"\r
-#include "../../include/logfile.h"\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 <winsock2.h>\r
        #include <ws2tcpip.h>\r
@@ -27,7 +30,7 @@ NNTPListener::~NNTPListener()
 \r
 }\r
 \r
-void NNTPListener::Run()\r
+void NNTPListener::run()\r
 {\r
        int rval;\r
        fd_set readfs;\r
@@ -35,7 +38,9 @@ void NNTPListener::Run()
        std::vector<SOCKET>::iterator listeni;\r
        SOCKET highsocket;\r
 \r
-       LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPListener::run thread started.");\r
+       m_log->debug("NNTPListener::run thread started.");\r
+\r
+       LoadDatabase();\r
 \r
        StartListen();\r
 \r
@@ -73,63 +78,14 @@ void NNTPListener::Run()
                                        struct sockaddr_storage addr;\r
                                        socklen_t addrlen=sizeof(addr);\r
                                        newsock=accept((*listeni),(struct sockaddr *)&addr,&addrlen);\r
-                                       LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_INFO,"NNTPListener::run NNTP client connected");\r
-                                       //m_connections.execute(new NNTPConnection(newsock));\r
-                                       //m_connectionthreads.push_back(new PThread::Thread(new NNTPConnection(newsock)));\r
-                                       m_connections.Execute(new NNTPConnection(newsock));\r
+                                       m_log->information("NNTPListener::run NNTP client connected");\r
+                                       m_connections.Start(new NNTPConnection(newsock));\r
                                }\r
                        }\r
                }\r
-/*\r
-               // check for any non-running connection threads that we can delete\r
-               for(std::vector<PThread::Thread *>::iterator i=m_connectionthreads.begin(); i!=m_connectionthreads.end(); )\r
-               {\r
-                       if((*i)->IsRunning()==false)\r
-                       {\r
-                               delete (*i);\r
-                               i=m_connectionthreads.erase(i);\r
-                       }\r
-                       if(i!=m_connectionthreads.end())\r
-                       {\r
-                               i++;\r
-                       }\r
-               }\r
-*/\r
 \r
-       //}while(!ZThread::Thread::interrupted() && m_listensockets.size()>0);\r
        }while(!IsCancelled() && m_listensockets.size()>0);\r
 \r
-       // see if any threads are still running - just calling interrupt without check would cause assert in debug mode\r
-       /*\r
-       if(m_connections.wait(1)==false)\r
-       {\r
-               LogFile::instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPListener::run interrupting connection threads and waiting 60 seconds for exit.");\r
-               try\r
-               {\r
-                       m_connections.interrupt();\r
-               }\r
-               catch(...)\r
-               {\r
-                       LogFile::instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPListener::run caught unhandled exception.");\r
-               }\r
-               if(m_connections.wait(60000)==false)\r
-               {\r
-                       LogFile::instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPListener::run connection threads did not exit after 60 seconds.");\r
-               }\r
-       }\r
-       */\r
-       /*\r
-       for(std::vector<PThread::Thread *>::iterator i=m_connectionthreads.begin(); i!=m_connectionthreads.end(); i++)\r
-       {\r
-               if((*i)->IsRunning())\r
-               {\r
-                       LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPListener::Run waiting for connection thread to exit.");\r
-                       (*i)->Cancel();\r
-                       (*i)->Join();\r
-               }\r
-               delete (*i);\r
-       }\r
-       */\r
        m_connections.Cancel();\r
        m_connections.Join();\r
 \r
@@ -143,26 +99,29 @@ void NNTPListener::Run()
        }\r
        m_listensockets.clear();\r
 \r
-       LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_DEBUG,"NNTPListener::run thread exiting.");\r
+       m_log->debug("NNTPListener::run thread exiting.");\r
 \r
 }\r
 \r
 void NNTPListener::StartListen()\r
 {\r
        \r
-       std::string bindaddresses;\r
        std::vector<std::string> listenaddresses;\r
+       std::string bindaddresses;      \r
        std::string nntpport;\r
-       if(Option::Instance()->Get("NNTPListenPort",nntpport)==false)\r
+       Option option(m_db);\r
+\r
+       if(option.Get("NNTPListenPort",nntpport)==false)\r
        {\r
                nntpport="1119";\r
-               Option::Instance()->Set("NNTPListenPort",nntpport);\r
+               option.Set("NNTPListenPort",nntpport);\r
        }\r
-       if(Option::Instance()->Get("NNTPBindAddresses",bindaddresses)==false)\r
+       if(option.Get("NNTPBindAddresses",bindaddresses)==false)\r
        {\r
                bindaddresses="127.0.0.1";\r
-               Option::Instance()->Set("NNTPBindAddresses",bindaddresses);\r
+               option.Set("NNTPBindAddresses",bindaddresses);\r
        }\r
+\r
        StringFunctions::Split(bindaddresses,",",listenaddresses);\r
        \r
        for(std::vector<std::string>::iterator i=listenaddresses.begin(); i!=listenaddresses.end(); i++)\r
@@ -175,25 +134,47 @@ void NNTPListener::StartListen()
                hint.ai_socktype=SOCK_STREAM;\r
                hint.ai_protocol=IPPROTO_TCP;\r
                hint.ai_flags=AI_PASSIVE;\r
+\r
+               m_log->trace("NNTPListener::StartListen getting address info for "+(*i));\r
                \r
                rval=getaddrinfo((*i).c_str(),nntpport.c_str(),&hint,&result);\r
                if(rval==0)\r
                {\r
                        for(current=result; current!=NULL; current=current->ai_next)\r
                        {\r
-                               sock=socket(current->ai_family,current->ai_socktype,current->ai_protocol);\r
-                               if(sock!=INVALID_SOCKET)\r
+                               try\r
                                {\r
-                                       if(bind(sock,current->ai_addr,current->ai_addrlen)==0)\r
+                                       Poco::Net::SocketAddress sa(current->ai_addr,current->ai_addrlen);\r
+\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
-                                               if(listen(sock,10)==0)\r
+                                               #ifndef _WIN32\r
+                                               const char 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
-                                                       LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_INFO,"NNTPListener::StartListen started listening at "+(*i)+":"+nntpport);\r
-                                                       m_listensockets.push_back(sock);\r
+                                                       if(listen(sock,10)==0)\r
+                                                       {\r
+                                                               m_log->information("NNTPListener::StartListen started listening on "+sa.toString());\r
+                                                               m_listensockets.push_back(sock);\r
+                                                       }\r
+                                                       else\r
+                                                       {\r
+                                                               m_log->error("NNTPListener::StartListen socket listen failed on "+sa.toString());\r
+                                                               #ifdef _WIN32\r
+                                                               closesocket(sock);\r
+                                                               #else\r
+                                                               close(sock);\r
+                                                               #endif\r
+                                                       }\r
                                                }\r
                                                else\r
                                                {\r
-                                                       LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_ERROR,"NNTPListener::StartListen socket listen failed");\r
+                                                       m_log->error("NNTPListener::StartListen socket bind failed on "+sa.toString());\r
                                                        #ifdef _WIN32\r
                                                        closesocket(sock);\r
                                                        #else\r
@@ -203,17 +184,18 @@ void NNTPListener::StartListen()
                                        }\r
                                        else\r
                                        {\r
-                                               LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_ERROR,"NNTPListener::StartListen socket bind failed");\r
-                                               #ifdef _WIN32\r
-                                               closesocket(sock);\r
-                                               #else\r
-                                               close(sock);\r
-                                               #endif\r
+                                               m_log->error("NNTPListener::StartListen couldn't create socket on "+sa.toString());\r
                                        }\r
                                }\r
-                               else\r
+                               catch(Poco::Exception &e)\r
+                               {\r
+                                       m_log->error("NNTPListener::StartListen caught "+e.displayText());\r
+                                       continue;\r
+                               }\r
+                               catch(...)\r
                                {\r
-                                       LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_ERROR,"NNTPListener::StartListen couldn't create socket");\r
+                                       m_log->error("NNTPListener::StartListen caught unknown exception");\r
+                                       continue;\r
                                }\r
                        }\r
                }\r
@@ -224,6 +206,6 @@ void NNTPListener::StartListen()
        }\r
        if(m_listensockets.size()==0)\r
        {\r
-               LogFile::Instance()->WriteLog(LogFile::LOGLEVEL_FATAL,"NNTPListener::StartListen couldn't start listening on any sockets");\r
+               m_log->fatal("NNTPListener::StartListen couldn't start listening on any interfaces");\r
        }\r
 }\r