#include #include #include #include #include #include #include #include #include struct ConnectionInfo { Socket *pSocketControl; String *pHost; String *pUser; String *pPassword; }; YProxyThread::YProxyThread() : mProfile("ydebug.ini","unset"), mIsDebug(false) { String strDebug; mProfile.readProfileString("SETTINGS","DEBUG",strDebug); strDebug.lower(); mIsDebug=strDebug=="true"?true:false; consoleMessage("[YProxyThread::YProxyThread] Thread started"); mThreadHandler.setCallback(this,&YProxyThread::threadHandler); insertHandler(&mThreadHandler); } YProxyThread::~YProxyThread() { } bool YProxyThread::accept(Socket &socketControl,const String &host,const String &user,const String &password) { ConnectionInfo *pConnectionInfo=::new ConnectionInfo(); pConnectionInfo->pHost=::new String(host); pConnectionInfo->pUser=::new String(user); pConnectionInfo->pPassword=::new String(password); pConnectionInfo->pSocketControl=&socketControl; ThreadMessage threadMessage(ThreadMessage::TM_USER,AcceptMessage,(DWORD)pConnectionInfo); postMessage(threadMessage); message("[YProxyThread::accept] Waiting for bind."); mAcceptEvent.waitEvent(); return true; } DWORD YProxyThread::threadHandler(ThreadMessage &threadMessage) { switch(threadMessage.message()) { case ThreadMessage::TM_VOID : break; case ThreadMessage::TM_CREATE : break; case ThreadMessage::TM_DESTROY : break; case ThreadMessage::TM_USER : switch(threadMessage.userDataOne()) { case AcceptMessage : thAccept(threadMessage); break; } break; } return 0; } void YProxyThread::thAccept(ThreadMessage &threadMessage) { INETSocketAddress inetSocketAddress; String stringData; ConnectionInfo *pConnectionInfo=(ConnectionInfo*)threadMessage.userDataTwo(); Socket &socketControl=*pConnectionInfo->pSocketControl; String user=*pConnectionInfo->pUser; String password=*pConnectionInfo->pPassword; String host=*pConnectionInfo->pHost; ::delete pConnectionInfo->pUser; ::delete pConnectionInfo->pPassword; ::delete pConnectionInfo->pHost; ::delete pConnectionInfo; if(!socketControl.accept(mSocketControl,inetSocketAddress))return; if(!mIsDebug && !mNNTPClient.open(host,user,password)) { mSocketControl.send("400 Service not available"); consoleMessage(String("[YProxyThread::accept] Unable to connect to news server")+inetSocketAddress.internetAddress().toString()); mSocketControl.destroy(); return; } mSocketControl.setDontLinger(); consoleMessage(String("[YProxyThread::accept]Service started from ")+inetSocketAddress.internetAddress().toString()); consoleMessage("[YProxyThread::accept]Socket is bound "); mAcceptEvent.setEvent(); sendConnectResponse(); while(true) { if(!mSocketControl.isOkay()) { consoleMessage("[YProxyThread::thAccept] socket error, closing connection."); break; } if(mSocketControl.receive(stringData)) { if(stringData.isNull())continue; consoleMessage(String("[YProxyThread::thAccept] Received '")+stringData+String("'")); if(!stringHandler(stringData))break; } else { consoleMessage("[YProxyThread::thAccept] connection dropped."); break; } } mSocketControl.destroy(); } void YProxyThread::sendConnectResponse() { consoleMessage("[YProxyThread::sendConnectResponse] sending connection response."); mSocketControl.send("200 YProxy v1.00 copyright(c) 2002 Diversified Software Solutions."); if(!mNNTPClient.isConnected())consoleMessage("[YProxyThread::sendConnectResponse] Proxy is not connected to server."); } // virtuals bool YProxyThread::stringHandler(const String &string) { bool returnCode=true; switch(NNTPCommands::getInstance().interpretCommand(string)) { case NNTPCommands::Article : handleArticle(string); break; case NNTPCommands::Body : handleBody(string); break; case NNTPCommands::Group : handleGroup(string); break; case NNTPCommands::Head : handleHead(string); break; case NNTPCommands::Help : handleHelp(string); break; case NNTPCommands::IHave : handleIHave(string); break; case NNTPCommands::Last : handleLast(string); break; case NNTPCommands::List : handleList(string); break; case NNTPCommands::NewGroups : handleNewGroups(string); break; case NNTPCommands::NewNews : handleNewNews(string); break; case NNTPCommands::Next : handleNext(string); break; case NNTPCommands::Post : handlePost(string); break; case NNTPCommands::Quit : handleQuit(string); returnCode=false; break; case NNTPCommands::Slave : handleSlave(string); break; case NNTPCommands::Stat : handleStat(string); break; case NNTPCommands::ListGroup : handleListGroup(string); break; case NNTPCommands::AuthInfoUser : handleAuthInfoUser(string); break; case NNTPCommands::AuthInfoPass : handleAuthInfoPass(string); break; case NNTPCommands::ModeReader : handleModeReader(string); break; case NNTPCommands::XOver : handleXOver(string); break; case NNTPCommands::InvalidCommand : consoleMessage(NNTPCommands::getInstance().toString(NNTPCommands::InvalidCommand)+String(" '")+string+String("'")); break; } return returnCode; } // ***************************************************************************************************** // command handlers void YProxyThread::handleModeReader(const String &string) { consoleMessage(String("[YProxyThread::handleModeReader]")+NNTPCommands::getInstance().toString(NNTPCommands::ModeReader)); mSocketControl.send("200 OK"); } void YProxyThread::handleList(const String &string) { consoleMessage(String("[YProxyThread::handleList]")+NNTPCommands::getInstance().toString(NNTPCommands::List)); if(isDebug()) { Block list; mProfile.readProfileBlock(String("LIST"),list,Profile::NoAssign); mSocketControl.send("215 list of newsgroups follows"); mSocketControl.send(list); mSocketControl.send("."); } else if(mNNTPClient.isConnected()) { ListItems listItems; mNNTPClient.list(listItems); mSocketControl.send("215 list of newsgroups follows"); for(int index=0;index overview; String first; String last; consoleMessage(String("[YProxyThread::handleXOver]")+NNTPCommands::getInstance().toString(NNTPCommands::XOver)); first=string.betweenString(' ','-'); last=string.betweenString('-','\0'); if(isDebug()) { Block xoverKeys; Block xoverList; mProfile.readProfileBlock(String("XOVER"),xoverKeys,Profile::NoAssign); for(int index=0;index groupingList; mProfile.readProfileBlock(xoverKeys[index],groupingList,Profile::NoAssign); xoverList+=groupingList; } mSocketControl.send(String("224 Overview information follows ")); mSocketControl.send(xoverList); mSocketControl.send("."); } else if(mNNTPClient.isConnected()) { mNNTPClient.xover(first.toInt(),last.toInt(),overview); mSocketControl.send(String("224 Overview information follows ")); mSocketControl.send(overview); mSocketControl.send("."); } else { mSocketControl.send("411 Proxy is not connected to server"); } } void YProxyThread::handleArticle(const String &string) { Block articleText; Block uuencodedLines; consoleMessage(String("[YProxyThread::handleArticle]")+NNTPCommands::getInstance().toString(NNTPCommands::Article)); if(isDebug()) { DWORD articleNumber; String strPathFileName; String strProfile; String selector; String messageID; articleNumber=0; selector=string.betweenString(' ','\0'); if(selector.betweenString('<','>').length())selector=selector.betweenString('<','>'); else articleNumber=selector.toInt(); mProfile.readProfileString(String("ARTICLES"),selector,strProfile); strPathFileName=strProfile.betweenString(0,';'); messageID=strProfile.betweenString(';',0); consoleMessage(String("220 ")+String().fromInt(articleNumber)+String(" <")+messageID+String(">")); mSocketControl.send(String("220 ")+String().fromInt(articleNumber)+String(" <")+messageID+String(">")); NewsDecoder::decode(strPathFileName,uuencodedLines); mSocketControl.send(uuencodedLines); } else if(mNNTPClient.isConnected()) { String selector; String messageID; selector=string.betweenString(' ','\0'); if(selector.betweenString('<','>').length()) { MsgID msgID=selector.betweenString('<','>'); mNNTPClient.article(msgID,articleText,messageID); consoleMessage(String("220 ")+String().fromInt(0)+String(" <")+messageID+String(">")); mSocketControl.send(String("220 ")+String().fromInt(0)+String(" <")+messageID+String(">")); NewsDecoder::decode(messageID,articleText,uuencodedLines); } else { DWORD articleNumber=selector.toInt(); mNNTPClient.article(articleNumber,articleText,messageID); consoleMessage(String("220 ")+String().fromInt(articleNumber)+String(" <")+messageID+String(">")); mSocketControl.send(String("220 ")+String().fromInt(articleNumber)+String(" <")+messageID+String(">")); NewsDecoder::decode(String().fromInt(articleNumber),articleText,uuencodedLines); } if(uuencodedLines.size())mSocketControl.send(uuencodedLines); else mSocketControl.send(articleText); mSocketControl.send("."); } else { mSocketControl.send("500 Proxy is not connected to server"); } } void YProxyThread::handleBody(const String &string) { Block articleText; consoleMessage(String("[YProxyThread::handleBody]")+NNTPCommands::getInstance().toString(NNTPCommands::Body)); if(isDebug()) { consoleMessage("YProxyThread::handleBody] No debug version."); } else if(mNNTPClient.isConnected()) { String selector; String messageID; selector=string.betweenString(' ','\0'); if(selector.betweenString('<','>').length()) { MsgID msgID=selector.betweenString('<','>'); mNNTPClient.body(msgID,articleText,messageID); mSocketControl.send(String("220 ")+String().fromInt(0)+String(" <")+messageID+String(">")); } else { DWORD articleNumber=selector.toInt(); mNNTPClient.body(articleNumber,articleText,messageID); mSocketControl.send(String("220 ")+String().fromInt(articleNumber)+String(" <")+messageID+String(">")); } mSocketControl.send(articleText); mSocketControl.send("."); } else { mSocketControl.send("500 Proxy is not connected to server"); } } void YProxyThread::handleHead(const String &string) { Block articleText; consoleMessage(String("[YProxyThread::handleHead]")+NNTPCommands::getInstance().toString(NNTPCommands::Head)); if(isDebug()) { consoleMessage("YProxyThread::handleHead] No debug version."); } else if(mNNTPClient.isConnected()) { String selector; String messageID; selector=string.betweenString(' ','\0'); if(selector.betweenString('<','>').length()) { MsgID msgID=selector.betweenString('<','>'); mNNTPClient.head(msgID,articleText,messageID); mSocketControl.send(String("220 ")+String().fromInt(0)+String(" <")+messageID+String(">")); } else { DWORD articleNumber=selector.toInt(); mNNTPClient.head(articleNumber,articleText,messageID); mSocketControl.send(String("220 ")+String().fromInt(articleNumber)+String(" <")+messageID+String(">")); } mSocketControl.send(articleText); mSocketControl.send("."); } else { mSocketControl.send("500 Proxy is not connected to server"); } } void YProxyThread::handleHelp(const String &string) { consoleMessage(String("[YProxyThread::handleHelp]")+NNTPCommands::getInstance().toString(NNTPCommands::Help)); if(isDebug()) { mSocketControl.send("100 help text follows"); mSocketControl.send("YProxy v1.00 prototype"); mSocketControl.send("."); } else if(mNNTPClient.isConnected()) { Block cmdLines; mNNTPClient.help(cmdLines); mSocketControl.send("100 help text follows"); mSocketControl.send(cmdLines); mSocketControl.send("."); } else { mSocketControl.send("500 Proxy is not connected to server"); } } void YProxyThread::handleIHave(const String &string) { String messageID; consoleMessage(String("[YProxyThread::handleIHave]")+NNTPCommands::getInstance().toString(NNTPCommands::IHave)); messageID=string.betweenString('<','>'); if(isDebug()) { mSocketControl.send("435 article not wanted - do not send it"); } else if(mNNTPClient.isConnected()) { if(!mNNTPClient.iHave(messageID))mSocketControl.send("435 article not wanted - do not send it"); else mSocketControl.send("335 send article to be transferred. End with ."); } else { mSocketControl.send("500 Proxy is not connected to server"); } } void YProxyThread::handleNext(const String &string) { consoleMessage(String("[YProxyThread::handleNext]")+NNTPCommands::getInstance().toString(NNTPCommands::Next)); consoleMessage(String("[YProxyThread::handleLast]")+NNTPCommands::getInstance().toString(NNTPCommands::Last)); if(isDebug()) { } else if(mNNTPClient.isConnected()) { GroupIterator groupIterator; if(!mNNTPClient.next(groupIterator)) mSocketControl.send(String("223 ")+groupIterator.toString()); else mSocketControl.send("420 no current article has been selected"); } else { mSocketControl.send("500 Proxy is not connected to server"); } } void YProxyThread::handleLast(const String &string) { consoleMessage(String("[YProxyThread::handleLast]")+NNTPCommands::getInstance().toString(NNTPCommands::Last)); if(isDebug()) { } else if(mNNTPClient.isConnected()) { GroupIterator groupIterator; if(!mNNTPClient.last(groupIterator)) mSocketControl.send(String("223 ")+groupIterator.toString()); else mSocketControl.send("420 no current article has been selected"); } else { mSocketControl.send("500 Proxy is not connected to server"); } } void YProxyThread::handleNewGroups(const String &string) { // "NEWGROUPS 030305 024721 " consoleMessage(String("[YProxyThread::handleNewGroups]")+NNTPCommands::getInstance().toString(NNTPCommands::NewGroups)); if(isDebug()) { } else if(mNNTPClient.isConnected()) { ListItems listItems; Block distributionGroups; SystemTime systemTime; mNNTPClient.newGroups(listItems,distributionGroups,systemTime,true); mSocketControl.send("232 list of newsgroups follows"); for(int index=0;index &messageStrings) { }