--- /dev/null
+#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
+#ifdef _WIN32\r
+ #include <winsock2.h>\r
+ #include <ws2tcpip.h>\r
+#else\r
+\r
+#endif\r
+\r
+#ifdef XMEM\r
+ #include <xmem.h>\r
+#endif\r
+\r
+NNTPListener::NNTPListener()\r
+{\r
+\r
+}\r
+\r
+NNTPListener::~NNTPListener()\r
+{\r
+\r
+}\r
+\r
+void NNTPListener::run()\r
+{\r
+ int rval;\r
+ struct fd_set readfs;\r
+ struct timeval tv;\r
+ std::vector<SOCKET>::iterator listeni;\r
+ SOCKET highsocket;\r
+\r
+ StartListen();\r
+\r
+ do\r
+ {\r
+ // reset values\r
+ highsocket=0;\r
+ tv.tv_sec=1;\r
+ tv.tv_usec=0;\r
+\r
+ // clear fd set\r
+ FD_ZERO(&readfs);\r
+\r
+ // put all listen sockets on the fd set\r
+ for(listeni=m_listensockets.begin(); listeni!=m_listensockets.end(); listeni++)\r
+ {\r
+ FD_SET((*listeni),&readfs);\r
+ if((*listeni)>highsocket)\r
+ {\r
+ highsocket=(*listeni);\r
+ }\r
+ }\r
+\r
+ // see if any connections are waiting\r
+ rval=select(highsocket+1,&readfs,0,0,&tv);\r
+\r
+ // check for new connections\r
+ if(rval>0)\r
+ {\r
+ for(listeni=m_listensockets.begin(); listeni!=m_listensockets.end(); listeni++)\r
+ {\r
+ if(FD_ISSET((*listeni),&readfs))\r
+ {\r
+ SOCKET newsock;\r
+ struct sockaddr_storage addr;\r
+ int 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
+ }\r
+ }\r
+ }\r
+\r
+ }while(!ZThread::Thread::interrupted() && 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
+ {\r
+ try\r
+ {\r
+ m_connections.interrupt();\r
+ }\r
+ catch(...)\r
+ {\r
+ }\r
+ m_connections.wait();\r
+ }\r
+\r
+}\r
+\r
+void NNTPListener::StartListen()\r
+{\r
+ \r
+ std::string bindaddresses;\r
+ std::vector<std::string> listenaddresses;\r
+ std::string nntpport;\r
+ if(Option::instance()->Get("NNTPListenPort",nntpport)==false)\r
+ {\r
+ nntpport="1119";\r
+ Option::instance()->Set("NNTPListenPort",nntpport);\r
+ }\r
+ if(Option::instance()->Get("NNTPBindAddresses",bindaddresses)==false)\r
+ {\r
+ bindaddresses="127.0.0.1";\r
+ Option::instance()->Set("NNTPBindAddresses",bindaddresses);\r
+ }\r
+ StringFunctions::Split(bindaddresses,",",listenaddresses);\r
+ \r
+ for(std::vector<std::string>::iterator i=listenaddresses.begin(); i!=listenaddresses.end(); i++)\r
+ {\r
+ SOCKET sock;\r
+ int rval;\r
+ struct addrinfo hint,*result,*current;\r
+ result=current=NULL;\r
+ memset(&hint,0,sizeof(hint));\r
+ hint.ai_socktype=SOCK_STREAM;\r
+ hint.ai_protocol=IPPROTO_TCP;\r
+ hint.ai_flags=AI_PASSIVE;\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
+ {\r
+ if(bind(sock,current->ai_addr,current->ai_addrlen)==0)\r
+ {\r
+ if(listen(sock,10)==0)\r
+ {\r
+ LogFile::instance()->WriteLog(LogFile::LOGLEVEL_INFO,"NNTPListener::StartListen started listening at "+(*i)+":"+nntpport);\r
+ m_listensockets.push_back(sock);\r
+ }\r
+ else\r
+ {\r
+ LogFile::instance()->WriteLog(LogFile::LOGLEVEL_ERROR,"NNTPListener::StartListen socket listen failed");\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 bind failed");\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 couldn't create socket");\r
+ }\r
+ }\r
+ }\r
+ if(result)\r
+ {\r
+ freeaddrinfo(result);\r
+ }\r
+ }\r
+ if(m_listensockets.size()==0)\r
+ {\r
+ LogFile::instance()->WriteLog(LogFile::LOGLEVEL_FATAL,"NNTPListener::StartListen couldn't start listening on any sockets");\r
+ }\r
+}\r