#include #include #include #include #include #include #include #include struct ConnectionInfo { Socket *pSocketControl; String *pHost; String *pUser; String *pPassword; }; YProxyThread::YProxyThread() : mIsDebug(false) { consoleMessage("[YProxyThread::YProxyThread] Thread started"); mThreadHandler.setCallback(this,&YProxyThread::threadHandler); insertHandler(&mThreadHandler); mThreadName=getThreadName(); } 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(!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()) { mSocketControl.send("215 list of newsgroups follows"); mSocketControl.send("a.bsu.programming 00543 00501 y"); mSocketControl.send("a.bsu.religion 10125 10011 y"); mSocketControl.send("a.bsu.talk 10125 10011 y"); mSocketControl.send("abg.atari 10125 10011 y"); 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()) { mSocketControl.send("500 Unsupported"); } else if(mNNTPClient.isConnected()) { mNNTPClient.xover(first.toInt(),last.toInt(),overview); mSocketControl.send(String("224 Overview information follows ")); for(int index=0;index articleText; Block uuencodedLines; consoleMessage(String("[YProxyThread::handleArticle]")+NNTPCommands::getInstance().toString(NNTPCommands::Article)); if(isDebug()) { String selector; String messageID; DWORD articleNumber; selector=string.betweenString(' ','\0'); articleNumber=selector.toInt(); consoleMessage(String("220 ")+String().fromInt(articleNumber)+String(" <")+messageID+String(">")); mSocketControl.send(String("220 ")+String().fromInt(articleNumber)+String(" <")+messageID+String(">")); NewsDecoder::decode("d:\\work\\yproxy\\1392078.txt",uuencodedLines); for(int index=0;index').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()) { for(int index=0;index 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(">")); } for(int index=0;index 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(">")); } for(int index=0;index cmdLines; mNNTPClient.help(cmdLines); mSocketControl.send("100 help text follows"); for(int index=0;index'); 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)); // bool NNTPClient::newGroups(ListItems &listItems,Block &distributionGroups,const SystemTime &systemTime,bool isGMT) } void YProxyThread::handleNewNews(const String &string) { consoleMessage(String("[YProxyThread::handleNewNews]")+NNTPCommands::getInstance().toString(NNTPCommands::NewNews)); } void YProxyThread::handlePost(const String &string) { consoleMessage(String("[YProxyThread::handlePost]")+NNTPCommands::getInstance().toString(NNTPCommands::Post)); } void YProxyThread::handleQuit(const String &string) { consoleMessage(String("[YProxyThread::handleQuit]")+NNTPCommands::getInstance().toString(NNTPCommands::Quit)); mSocketControl.send("Goodbye."); } void YProxyThread::handleSlave(const String &string) { consoleMessage(String("[YProxyThread::handleSlave]")+NNTPCommands::getInstance().toString(NNTPCommands::Slave)); } void YProxyThread::handleStat(const String &string) { consoleMessage(String("[YProxyThread::handleStat]")+NNTPCommands::getInstance().toString(NNTPCommands::Stat)); } void YProxyThread::handleListGroup(const String &string) { consoleMessage(String("[YProxyThread::handleListGroup]")+NNTPCommands::getInstance().toString(NNTPCommands::ListGroup)); } void YProxyThread::handleAuthInfoUser(const String &string) { consoleMessage(String("[YProxyThread::handleAuthInfoUser]")+NNTPCommands::getInstance().toString(NNTPCommands::AuthInfoUser)); if(!mNNTPClient.isConnected())mSocketControl.send("500 Proxy is not connected to server"); else mSocketControl.send("300 Continue with password"); } void YProxyThread::handleAuthInfoPass(const String &string) { consoleMessage(String("[YProxyThread::handleAuthInfoPass]")+NNTPCommands::getInstance().toString(NNTPCommands::AuthInfoPass)); if(!mNNTPClient.isConnected())mSocketControl.send("500 Proxy is not connected to server"); else mSocketControl.send("202 user authenticated."); } //****************************************************************************************************** // virtual overloads void YProxyThread::consoleMessage(const String &message) { ::printf("Thread:%s %s\n",getThreadName().str(),message.str()); } void YProxyThread::message(String messageString) { } void YProxyThread::message(Block &messageStrings) { }