version 0.3.29
[fms.git] / src / nntp / nntplistener.cpp
index 4d1c37d..a34fc15 100644 (file)
@@ -1,15 +1,19 @@
 #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
 #else\r
-\r
+       #include <netinet/in.h>  // gcc - IPPROTO_ consts\r
+       #include <netdb.h>       // gcc - addrinfo\r
 #endif\r
 \r
 #ifdef XMEM\r
@@ -29,11 +33,15 @@ NNTPListener::~NNTPListener()
 void NNTPListener::run()\r
 {\r
        int rval;\r
-       struct fd_set readfs;\r
+       fd_set readfs;\r
        struct timeval tv;\r
        std::vector<SOCKET>::iterator listeni;\r
        SOCKET highsocket;\r
 \r
+       m_log->debug("NNTPListener::run thread started.");\r
+\r
+       LoadDatabase();\r
+\r
        StartListen();\r
 \r
        do\r
@@ -68,47 +76,52 @@ void NNTPListener::run()
                                {\r
                                        SOCKET newsock;\r
                                        struct sockaddr_storage addr;\r
-                                       int addrlen=sizeof(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_log->information("NNTPListener::run NNTP client connected");\r
+                                       m_connections.Start(new NNTPConnection(newsock));\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
-       if(m_connections.wait(1)==false)\r
+       m_connections.Cancel();\r
+       m_connections.Join();\r
+\r
+       for(listeni=m_listensockets.begin(); listeni!=m_listensockets.end(); listeni++)\r
        {\r
-               try\r
-               {\r
-                       m_connections.interrupt();\r
-               }\r
-               catch(...)\r
-               {\r
-               }\r
-               m_connections.wait();\r
+               #ifdef _WIN32\r
+               closesocket((*listeni));\r
+               #else\r
+               close((*listeni));\r
+               #endif\r
        }\r
+       m_listensockets.clear();\r
+\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
@@ -121,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
@@ -149,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
@@ -170,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