Files
Work/yproxy/hold/YProxyThread.cpp
2024-08-07 09:16:27 -04:00

585 lines
17 KiB
C++

#include <yproxy/YProxyThread.hpp>
#include <yproxy/NNTPCommands.hpp>
#include <yproxy/NewsDecoder.hpp>
#include <nntp/listitms.hpp>
#include <nntp/grpitem.hpp>
#include <nntp/iterator.hpp>
#include <common/console.hpp>
#include <common/file.hpp>
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<listItems.size();index++)
mSocketControl.send(listItems[index].toString());
mSocketControl.send(".");
}
else
{
mSocketControl.send("500 Proxy is not connected to server");
}
}
void YProxyThread::handleGroup(const String &string)
{
String strGroup=string.betweenString(' ','\0');
consoleMessage(String("[YProxyThread::handleGroup]")+NNTPCommands::getInstance().toString(NNTPCommands::Group));
if(isDebug())
{
GroupItem groupItem(strGroup);
groupItem.articlesInGroup(3);
groupItem.firstArticle(1);
groupItem.lastArticle(3);
mSocketControl.send(String("211 ")+groupItem.toString());
}
else if(mNNTPClient.isConnected())
{
GroupItem groupItem(strGroup);
mNNTPClient.group(groupItem);
mSocketControl.send(String("211 ")+groupItem.toString());
}
else
{
mSocketControl.send("411 Proxy is not connected to server");
}
}
void YProxyThread::handleXOver(const String &string)
{
Block<String> 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<overview.size();index++)
mSocketControl.send(overview[index]);
mSocketControl.send(".");
}
else
{
mSocketControl.send("411 Proxy is not connected to server");
}
}
void YProxyThread::handleArticle(const String &string)
{
Block<String> articleText;
Block<String> 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<uuencodedLines.size();index++)
mSocketControl.send(uuencodedLines[index]);
}
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())
{
for(int index=0;index<uuencodedLines.size();index++)
mSocketControl.send(uuencodedLines[index]);
}
else
{
for(int index=0;index<articleText.size();index++)
mSocketControl.send(articleText[index]);
}
mSocketControl.send(".");
}
else
{
mSocketControl.send("500 Proxy is not connected to server");
}
}
void YProxyThread::handleBody(const String &string)
{
Block<String> 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.size();index++)
{
consoleMessage(articleText[index].isNull()?" ":articleText[index]);
if(articleText[index].isNull())mSocketControl.send(" ");
else mSocketControl.send(articleText[index]);
}
mSocketControl.send(".");
}
else
{
mSocketControl.send("500 Proxy is not connected to server");
}
}
void YProxyThread::handleHead(const String &string)
{
Block<String> 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<articleText.size();index++)
{
consoleMessage(articleText[index].isNull()?" ":articleText[index]);
if(articleText[index].isNull())mSocketControl.send(" ");
else mSocketControl.send(articleText[index]);
}
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<String> cmdLines;
mNNTPClient.help(cmdLines);
mSocketControl.send("100 help text follows");
for(int index=0;index<cmdLines.size();index++)
mSocketControl.send(cmdLines[index]);
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 <CR-LF>.<CR-LF>");
}
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<String> &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<String> &messageStrings)
{
}