This commit is contained in:
2024-08-07 09:16:27 -04:00
parent fdfadd5c7e
commit 5f971cf684
5200 changed files with 731717 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
#include <yproxy/NNTPCommands.hpp>
NNTPCommands *NNTPCommands::smInstance=0;
NNTPCommands::NNTPCommand NNTPCommands::interpretCommand(const String &string)
{
for(int index=0;index<mNNTPCmds.size();index++)
{
if(!string.strncmp(mNNTPCmds[index]))return (NNTPCommand)index;
}
return InvalidCommand;
}
String NNTPCommands::toString(NNTPCommand command)
{
switch(command)
{
case XOver :
return "XOver";
case Article :
return "Article";
case Body :
return "Body";
case Group :
return "Group";
case Head :
return "Head";
case Help :
return "Help";
case IHave :
return "IHave";
case Last :
return "Last";
case List :
return "List";
case NewGroups :
return "NewGroups";
case NewNews :
return "NewNews";
case Next :
return "Next";
case Post :
return "Post";
case Quit :
return "Quit";
case Slave :
return "Slave";
case Stat :
return "Stat";
case ListGroup :
return "ListGroup";
case AuthInfoUser :
return "AuthInfoUser";
case AuthInfoPass :
return "AuthInfoPass";
case ModeReader :
return "ModeReader";
case InvalidCommand :
default :
return "InvalidCommand";
}
}
void NNTPCommands::buildCommands(void)
{
mNNTPCmds.insert(&String("ARTICLE"));
mNNTPCmds.insert(&String("BODY"));
mNNTPCmds.insert(&String("GROUP"));
mNNTPCmds.insert(&String("HEAD"));
mNNTPCmds.insert(&String("HELP"));
mNNTPCmds.insert(&String("IHAVE"));
mNNTPCmds.insert(&String("LAST"));
mNNTPCmds.insert(&String("LIST"));
mNNTPCmds.insert(&String("NEWGROUPS"));
mNNTPCmds.insert(&String("NEWNEWS"));
mNNTPCmds.insert(&String("NEXT"));
mNNTPCmds.insert(&String("POST"));
mNNTPCmds.insert(&String("QUIT"));
mNNTPCmds.insert(&String("SLAVE"));
mNNTPCmds.insert(&String("STAT"));
mNNTPCmds.insert(&String("LISTGROUP"));
mNNTPCmds.insert(&String("AUTHINFO USER"));
mNNTPCmds.insert(&String("AUTHINFO PASS"));
mNNTPCmds.insert(&String("AUTHINFO"));
mNNTPCmds.insert(&String("MODE READER"));
mNNTPCmds.insert(&String("XOVER"));
mNNTPCmds.insert(&String("INVALID"));
}

View File

@@ -0,0 +1,47 @@
#ifndef _YPROXY_NNTPCOMMANDS_HPP_
#define _YPROXY_NNTPCOMMANDS_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
#ifndef _COMMON_BLOCK_HPP_
#include <common/block.hpp>
#endif
class NNTPCommands
{
public:
typedef enum NNTPCommand{Article,Body,Group,Head,Help,IHave,Last,List,NewGroups,NewNews,
Next,Post,Quit,Slave,Stat,ListGroup,AuthInfoUser,AuthInfoPass,AuthInfo,ModeReader,XOver,InvalidCommand};
static NNTPCommands &getInstance(void);
NNTPCommand interpretCommand(const String &string);
String toString(NNTPCommand command);
private:
NNTPCommands();
virtual ~NNTPCommands();
void buildCommands(void);
Block<String> mNNTPCmds;
static NNTPCommands *smInstance;
};
inline
NNTPCommands::NNTPCommands()
{
buildCommands();
}
inline
NNTPCommands::~NNTPCommands()
{
}
inline
NNTPCommands &NNTPCommands::getInstance()
{
if(0==smInstance)smInstance=::new NNTPCommands();
return *smInstance;
}
#endif

View File

@@ -0,0 +1,75 @@
#include <yproxy/NewsDecoder.hpp>
#include <yproxy/ydecode.hpp>
#include <uuencode/uuencode.hpp>
#include <common/array.hpp>
bool NewsDecoder::decode(const String &pathFileName,Block<String> &uuencodedText)
{
Block<String> articleText;
String strLine;
File inFile;
uuencodedText.remove();
if(!inFile.open(pathFileName,"rb"))return false;
while(inFile.readLine(strLine))articleText.insert(&strLine);
inFile.close();
return decode(pathFileName,articleText,uuencodedText);
}
bool NewsDecoder::decode(const String &messageID,Block<String> &articleText,Block<String> &uuencodedLines)
{
Block<String> replaceBlock;
String pathImageFileName;
String pathTempFileName;
File outFile;
File inFile;
int beginIndex;
int endIndex;
int index;
Array<BYTE> bytes;
uuencodedLines.remove();
if(!isYEnc(articleText,beginIndex,endIndex))return false;
pathTempFileName=messageID+".yenc";
if(!outFile.open(pathTempFileName,"wb"))return false;
for(index=beginIndex;index<=endIndex;index++)outFile.writeLine(articleText[index]);
outFile.close();
YDecoder::decode(pathTempFileName,pathImageFileName,YDecoder::ForceDecode);
::unlink(pathTempFileName);
if(!inFile.open(pathImageFileName,"rb"))return false;
bytes.size(inFile.length());
inFile.read(&bytes[0],bytes.size());
if(!UUEncode::encode(bytes,pathImageFileName,replaceBlock))return false;
for(index=0;index<beginIndex;index++)uuencodedLines.insert(&articleText[index]);
for(index=0;index<replaceBlock.size();index++)uuencodedLines.insert(&replaceBlock[index]);
return uuencodedLines.size()?true:false;
}
bool NewsDecoder::isYEnc(Block<String> &articleText,int &beginIndex,int &endIndex)
{
int index;
beginIndex=-1;
endIndex=-1;
for(index=0;index<articleText.size();index++)
{
String &strLine=articleText[index];
if(strLine.substr(0,6)=="=ybegin")
{
beginIndex=index;
break;
}
}
if(-1==beginIndex)return false;
for(;index<articleText.size();index++)
{
String &strLine=articleText[index];
if(strLine.substr(0,4)=="=yend")
{
endIndex=index;
break;
}
}
return true;
}

View File

@@ -0,0 +1,21 @@
#ifndef _YPROXY_NEWSDECODER_HPP_
#define _YPROXY_NEWSDECODER_HPP_
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
#ifndef _COMMON_BLOCK_HPP_
#include <common/block.hpp>
#endif
#ifndef _COMMON_FILE_HPP_
#include <common/file.hpp>
#endif
class NewsDecoder
{
public:
static bool decode(const String &pathFileName,Block<String> &uuencodedText);
static bool decode(const String &messageID,Block<String> &articleText,Block<String> &uuencodedText);
private:
static bool isYEnc(Block<String> &articleText,int &beginIndex,int &endIndex);
};
#endif

View File

@@ -0,0 +1,58 @@
#include <yproxy/yProxyServer.hpp>
#include <socket/hostent.hpp>
#include <socket/servent.hpp>
#include <socket/inaddr.hpp>
String YProxyServer::smHostName="localhost";
bool YProxyServer::start(const String &remoteHost,const String &user,const String &password)
{
HostEnt hostEntry;
ServEnt serverEntry;
String stringData;
message(String("[YProxyServer::start]Trying host'")+smHostName+String("'..."));
if(!mWSASystem.isInitialized()){message("[YProxySever::start]WINSOCK initialization failure.");return FALSE;}
InternetAddress internetAddress(smHostName);
if(!internetAddress.isZero()){if(!hostEntry.hostByAddress(internetAddress)){message(String("[YProxyServer::start]no DNS entry for ")+smHostName);return FALSE;}}
else if(!hostEntry.hostByName(smHostName)){message(String("[YProxyServer::start]no DNS entry for ")+smHostName);return FALSE;}
message(String("[YProxyServer::start]connect...")+String("'")+hostEntry.hostName()+String("' (")+(String)(hostEntry.addresses())[0]+String(")"));
if(!serverEntry.serviceByName("nntp","tcp")){message("[YProxyServer::start]cannot determine port number for nntp session");return false;}
mINETSocketAddress.internetAddress((hostEntry.addresses())[0]);
mINETSocketAddress.family(PF_INET);
mINETSocketAddress.port(serverEntry.port());
while(TRUE)
{
INETSocketAddress internetSocketAddress;
message(String("[YProxyServer::start] host='")+(hostEntry.addresses())[0]+String("' port=")+String().fromInt(serverEntry.port()));
if(!mSocketControl.create()){message("[YProxyServer::start] socket initialization failure.");return FALSE;}
mSocketControl.reuseAddress();
if(!mSocketControl.bind(mINETSocketAddress)){message("[YProxyServer::start] bind failed");return FALSE;}
String strLocalHost((String)mINETSocketAddress.internetAddress());
message(String("[YProxyServer::start] waiting for connection on ")+strLocalHost+String(":")+String().fromInt(serverEntry.port()));
if(!mSocketControl.listen()){message("[YProxyServer::start] listen failed");return FALSE;}
mProxyThreads.insert(&SmartPointer<YProxyThread>());
PYProxyThread &yProxyThread=mProxyThreads[mProxyThreads.size()-1];
yProxyThread=::new YProxyThread();
yProxyThread.disposition(PointerDisposition::Delete);
yProxyThread->accept(mSocketControl,remoteHost,user,password);
}
message("[YProxyServer::start]terminating connection");
return TRUE;
}
// virtuals
void YProxyServer::acceptHandler(void)
{
}
void YProxyServer::stringHandler(const String &string)
{
message(String("[YProxyServer::stringHandler]Received:")+string);
}
void YProxyServer::message(const String &message)
{
::printf("%s\n",message.str());
}

View File

@@ -0,0 +1,66 @@
#ifndef _YPROXY_YPROXYSERVER_HPP_
#define _YPROXY_YPROXYSERVER_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_SMARTPOINTER_HPP_
#include <common/pointer.hpp>
#endif
#ifndef _YPROXY_YPROXYTHREAD_HPP_
#include <yproxy/YProxyThread.hpp>
#endif
#ifndef _SOCKET_SOCKET_HPP_
#include <socket/socket.hpp>
#endif
#ifndef _SOCKET_WSADATA_HPP_
#include <socket/wsadata.hpp>
#endif
#ifndef _SOCKET_INETSOCKETADDRESS_HPP_
#include <socket/intsaddr.hpp>
#endif
class YProxyServer
{
public:
YProxyServer();
virtual ~YProxyServer();
bool start(const String &remoteHost,const String &user,const String &password);
protected:
virtual void message(const String &message);
virtual void acceptHandler(void);
virtual void stringHandler(const String &string);
private:
typedef SmartPointer<YProxyThread> PYProxyThread;
enum{RecycleInterval=250};
YProxyServer(const YProxyServer &yProxyServer);
YProxyServer &operator=(const YProxyServer &yProxyServer);
static String smHostName;
Socket mSocketControl;
Socket mPortControl;
INETSocketAddress mINETSocketAddress;
WSASystem mWSASystem;
Block<PYProxyThread> mProxyThreads;
};
inline
YProxyServer::YProxyServer()
{
}
inline
YProxyServer::YProxyServer(const YProxyServer &/*yProxy*/)
{ // private
}
inline
YProxyServer::~YProxyServer()
{
}
inline
YProxyServer &YProxyServer::operator=(const YProxyServer &/*yProxy*/)
{ // private
return *this;
}
#endif

View File

@@ -0,0 +1,584 @@
#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)
{
}

View File

@@ -0,0 +1,70 @@
#ifndef _YPROXY_YPROXYTHREAD_HPP_
#define _YPROXY_YPROXYTHREAD_HPP_
#ifndef _SOCKET_SOCKET_HPP_
#include <socket/socket.hpp>
#endif
#ifndef _THREAD_MESSAGETHREAD_HPP_
#include <thread/mthread.hpp>
#endif
#ifndef _THREAD_EVENT_HPP_
#include <thread/event.hpp>
#endif
#ifndef _THREAD_THREADCALLBACK_HPP_
#include <thread/tcallbck.hpp>
#endif
#ifndef _NNTP_NNTPCLIENT_HPP_
#include <nntp/nntp.hpp>
#endif
class YProxyThread : private MessageThread
{
public:
YProxyThread();
virtual ~YProxyThread();
bool accept(Socket &socketControl,const String &host,const String &user,const String &password);
protected:
virtual void consoleMessage(const String &message);
virtual bool stringHandler(const String &string);
virtual void message(String message);
virtual void message(Block<String> &message);
private:
enum{AcceptMessage};
DWORD threadHandler(ThreadMessage &threadMessage);
void thAccept(ThreadMessage &threadMessage);
void sendConnectResponse(void);
void handleModeReader(const String &string);
void handleArticle(const String &string);
void handleBody(const String &string);
void handleGroup(const String &string);
void handleHead(const String &string);
void handleHelp(const String &string);
void handleIHave(const String &string);
void handleLast(const String &string);
void handleList(const String &string);
void handleNewGroups(const String &string);
void handleNewNews(const String &string);
void handleNext(const String &string);
void handlePost(const String &string);
void handleQuit(const String &string);
void handleSlave(const String &string);
void handleStat(const String &string);
void handleListGroup(const String &string);
void handleAuthInfoUser(const String &string);
void handleAuthInfoPass(const String &string);
void handleXOver(const String &string);
bool isDebug(void)const;
ThreadCallback<YProxyThread> mThreadHandler;
Socket mSocketControl;
Event mAcceptEvent;
String mThreadName;
NNTPClient mNNTPClient;
bool mIsDebug;
};
inline
bool YProxyThread::isDebug(void)const
{
return mIsDebug;
}
#endif

38
yproxy/hold/crc.cpp Normal file
View File

@@ -0,0 +1,38 @@
#include <yproxy/crc.hpp>
int CRC::crc_tab[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
}
;

55
yproxy/hold/crc.hpp Normal file
View File

@@ -0,0 +1,55 @@
#ifndef _YPROXY_CRC_HPP_
#define _YPROXY_CRC_HPP_
class CRC
{
public:
CRC();
virtual ~CRC();
void crcAdd(int c);
int getVal(void)const;
private:
static int crc_tab[256];
int mCRCVal;
long mCRCAnz;
};
inline
CRC::CRC()
: mCRCVal(-1L), mCRCAnz(0)
{
}
inline
CRC::~CRC()
{
}
inline
void CRC::crcAdd(int c)
{
unsigned long ch1,ch2,cc;
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
/* for (i = 0; i < size; i++) */
/* crccode = crc32Tab[(int) ((crccode) ^ (buf[i])) & 0xff] ^ */
/* (((crccode) >> 8) & 0x00FFFFFFL); */
/* return(crccode); */
cc= (c) & 0x000000ffL;
ch1=(mCRCVal ^ cc) & 0xffL;
ch1=crc_tab[ch1];
ch2=(mCRCVal>>8L) & 0xffffffL; // Correct version
mCRCVal=ch1 ^ ch2;
mCRCAnz++;
}
inline
int CRC::getVal(void)const
{
return mCRCVal;
}
#endif

22
yproxy/hold/main.cpp Normal file
View File

@@ -0,0 +1,22 @@
#include <common/windows.hpp>
#include <yproxy/YProxyServer.hpp>
#include <yproxy/NewsDecoder.hpp>
int main(int argc,char **argv)
{
YProxyServer yProxyServer;
yProxyServer.start("news-server.optonline.net","fusion","cygnus-x1");
return 0;
}
/*
#include <common/file.hpp>
File outFile;
Block<String> uuencodedLines;
NewsDecoder::decode("d:\\work\\yproxy\\1392078.txt",uuencodedLines);
outFile.open("1392078.uue","wb");
for(int index=0;index<uuencodedLines.size();index++)
outFile.writeLine(uuencodedLines[index]);
outFile.close();
*/

581
yproxy/hold/pdecode.cpp Normal file
View File

@@ -0,0 +1,581 @@
#include <common/windows.hpp>
#include <common/stdio.hpp>
#include <common/stdlib.hpp>
#include <common/finddata.hpp>
#include <yproxy/pdecode.hpp>
#include <yproxy/crc.hpp>
#include <io.h>
PureDecoder::PureDecoder()
: mErrors(0), mErrParts(0), mErrFiles(0), mDisplay(true), myBegin(0), myEnd(0), mAdResCrc(0), mAdResLen(0)
{
::memset(mAttName,0,sizeof(mAttName));
::memset(mAtText,0,sizeof(mAtText));
}
char *PureDecoder::ad_fgetscr(char * buffer, int maxlen, FILE * fp)
{
char * cp;
char * dp;
cp=fgets(buffer,maxlen,fp);
if(cp==NULL)return(NULL);
dp=strrchr(buffer,'\n'); // Eliminate CRLF
if (dp) *dp=0;
dp=strrchr(buffer,'\r');
if (dp) *dp=0;
return(cp);
}
unsigned long PureDecoder::hex_to_ulong(char * text)
{
unsigned long res;
unsigned char c;
if (text==NULL) return(-1);
res=0;
while(true)
{
c=*text; text++;
if ((c>='0')&(c<='9'))
{
res=(res<<4)+((long)(c-48) & 0x0F);
continue;
}
if ((c>='A')&(c<='F'))
{
res=(res<<4)+((long)(c-55) & 0x0F);
continue;
}
if ((c>='a')&(c<='f'))
{
res=(res<<4)+((long)(c-87) & 0x0F);
continue;
}
break;
}
return(res);
}
int PureDecoder::yDecode(FILE * fOut, FILE * fIn, long y_line, long y_size,int y_part)
{
unsigned char srcbuf[4100];
unsigned char desbuf[4100];
unsigned char * srcp;
unsigned char * desp;
int deslen;
int srclen;
unsigned char c;
int id;
char * cp;
long decolen;
unsigned long crc32;
char name[260];
int esize;
unsigned char * partbuf;
unsigned char * partptr;
long partsize;
long partfree;
long wlen;
long flen;
if(mDisplay)
{
display("yDecoder started...\r\n");
}
CRC crc;
decolen=0;
deslen=0;
desp=desbuf;
if(y_part) // This is a multipart message !
{
cp=ad_fgetscr((char*) srcbuf,4097,fIn); // fgets especially with ad_length
if (cp==NULL)
{
error("Unexpected eof in yEncoded file\r\n");
mErrors++;
return(1);
}
if(mDisplay)
{
String str;
::sprintf(str,"=ypart-line: %s\r\n",srcbuf);
display(str);
}
if (strncmp((char*) srcbuf,"=ypart ",7))
{
error("Missing =ypart line in yEncoded multipart message\r\n");
mErrors++;
return(2);
}
cp=strstr((char*)srcbuf,"end=");
if (cp==NULL)
{
error("Missing end= in yEncoded multipart message\r\n");
mErrors++;
return(2);
}
myEnd=atol(cp+4);
cp=strstr((char*)srcbuf,"begin=");
if (cp==NULL)
{
error("Missing begin= in yEncoded multipart message\r\n");
mErrors++;
return(2);
}
myBegin=atol(cp+6);
if(mDisplay)
{
String str;
::sprintf(str,"part-begin: %ld\r\n",myBegin);
display(str);
sprintf(str,"part-end : %ld\r\n",myEnd);
display(str);
}
partbuf=(unsigned char*)malloc(myEnd-myBegin+10); // Allocate a buffer for the part
partptr=partbuf;
partsize=myEnd-myBegin+1;
partfree=partsize;
}
loop:
cp=ad_fgetscr((char*) srcbuf,4097,fIn); // fgets especially with ad_length
if(cp==NULL)
{
error("Unexpected eof in yEncoded file\r\n");
mErrors++;
return(1);
}
if (strncmp((char*) srcbuf,"=yend ",6)==0)
{
if(mDisplay)
{
String str;
sprintf(str,"Endline (%d bytes): %s\r\n",decolen,srcbuf);
display(str);
}
goto end_of_file;
}
if (strncmp((char*) srcbuf,"=ybegin ",8)==0)
{
error("Unexpected =ybegin in yEncoded file\r\n");
mErrors++;
return(1);
}
srclen=strlen((char*)srcbuf);
if (srclen<y_line)
{
if(mDisplay)display("Last line.\r\n");
}
srcp=srcbuf;
loop2:
c=*srcp; srcp++;
if(c==0)
{
goto loop; // End of line reached
}
if(c=='=') // The escape character comes in
{
c=*srcp; srcp++;
if(c==0)return(2); // Last char cannot be escape char !
c=(unsigned char)(c-64);
}
c=(unsigned char)(c-42); // Subtract the secret number
*desp=c;
desp++;
deslen++;
decolen++;
// crc.crcAdd(c);
crc.crcAdd(c);
if (deslen>=4096)
{
if (y_part) // MultiPart --> to the partbuffer !
{
if (deslen>partfree)
{
error("Partial message corrupt: longer than (end-begin)!\r\n");
mErrors++;
return(11);
}
memcpy(partptr,desbuf,deslen);
partptr=partptr+deslen;
partfree=partfree-deslen;
}
else // Single part --> directly to target file
{
id=fwrite(desbuf,deslen,1,fOut);
if (id != 1)
{
String strError;
::sprintf(strError,"Error in writing decoded file (code=%d)\r\n",errno);
error(strError);
mErrors++;
return(3);
}
}
deslen=0;
desp=desbuf;
}
goto loop2;
end_of_file:
if (deslen>0) // Empty the last buffer
{
if (y_part)
{
if (deslen>partfree)
{
error("Partial message corrupt: longer than (end-begin)!\r\n");
mErrors++;
return(11);
}
memcpy(partptr,desbuf,deslen);
//partptr=partptr+deslen;
//partfree=partfree-deslen;
}
else // Single part --> directly to target file
{
id=fwrite(desbuf,deslen,1,fOut);
if (id != 1)
{
String strError;
::sprintf(strError,"Error in writing decoded file (code=%d)\r\n",errno);
error(strError);
mErrors++;
return(3);
}
}
}
cp=strstr((char*) srcbuf,"size="); // Compare the decoded size to the =yend size
if (cp)
{
esize=atoi(cp+5);
if (esize != decolen)
{
sprintf(name,"%s(size=%ld)",mAttName,decolen);
strcpy(mAttName,name);
String strError;
::sprintf(strError,"Corrupt yEnc binary - endsize mismatch (%s%s)\r\n",mAttName,mAtText);
error(strError);
mErrors++;
mErrFiles++;
return(0);
}
}
// Check the srcbuf for the CRC
if (y_part==0)
{
cp=strstr((char*)srcbuf,"crc32=");
if (cp)
{
crc32=hex_to_ulong((char*)(cp+6));
mAdResCrc=crc.getVal() ^ 0xFFFFFFFFl;
if (mDisplay)
{
String str;
sprintf(str,"Included CRC: $%08lx - calculated CRC: $%08lx\r\n",crc32,mAdResCrc);
display(str);
}
}
}
else
{
cp=strstr((char*)srcbuf,"pcrc32=");
if (cp)
{
crc32=hex_to_ulong((char*)(cp+7));
mAdResCrc=crc.getVal() ^ 0xFFFFFFFFl;
if (mDisplay)
{
String str;
sprintf(str,"Included CRC: $%08lx - calculated CRC: $%08lx\r\n",crc32,mAdResCrc);
display(str);
}
}
}
if (cp!=NULL)
{
if (crc32 != mAdResCrc)
{
sprintf(name,"%s(crc=%08lx)",mAttName,mAdResCrc);
strcpy(mAttName,name);
String strError;
::sprintf(strError,"Corrupt yEnc binary - CRC mismatch (%s%s)\r\n",mAttName,mAtText);
error(strError);
mErrors++;
mErrFiles++;
return(0);
}
}
if (y_part==0) // Single message
{
if ((y_part==0) & (decolen != y_size))
{
// eprint("Y-Decoder: Size mismatch - file corrupt.\r\n");
sprintf(name,"%s(len=%ld)",mAttName,decolen);
strcpy(mAttName,name);
String strError;
::sprintf(strError,"Corrupt yEnc binary - size mismatch (%s%s)\r\n",mAttName,mAtText);
error(strError);
mErrors++;
mErrFiles++;
return(0);
}
mAdResLen=decolen;
mAdResCrc=crc.getVal() ^ 0xFFFFFFFFl;
if(mDisplay)
{
String str;
sprintf(str,"yDecoder: Job done. %ld bytes written. CRC: $%08lx \r\n",decolen,mAdResCrc);
display(str);
}
return(0);
}
if ((y_part>0) & (decolen != (myEnd-myBegin+1)))
{
error("yDecoder: Part size mismatch - file corrupt.\r\n");
mErrors++;
mErrParts++;
return(6);
}
id=fseek(fOut,myBegin-1,0);
if(id)
{
String strError;
::sprintf(strError,"Cannot write a part (fseek failed) [reason:%d]\r\n",errno);
error(strError);
mErrors++;
return(12);
}
flen=decolen;
partptr=partbuf;
if (mDisplay)
{
String str;
sprintf(str,"Write part to target file (start: %ld, size: %ld)\r\n",myBegin-1,flen);
display(str);
}
while (flen>0)
{
wlen=flen;
if (wlen>8192) wlen=8192;
id=fwrite(partptr,wlen,1,fOut);
if (id != 1)
{
String strError;
::sprintf(strError,"Cannot write a part (fwrite failed) [reason:%d]\r\n",errno);
error(strError);
mErrors++;
return(12);
}
partptr=partptr+wlen;
flen=flen-wlen;
}
free(partbuf);
return(0);
}
int PureDecoder::AddPart(char * srcname,long y_begin, long y_end)
{
FILE * fSrc;
FILE * fDes;
char desname[260];
char line[1024];
long a,e;
int copyrest;
char * cp;
int resparts;
long flen;
if (mDisplay)
{
String str;
sprintf("AddPart (%s) [%ld - %ld]\r\n",srcname,y_begin,y_end);
display(str);
}
copyrest=0;
resparts=0;
sprintf(desname,"%s.des",srcname);
fSrc=fopen(srcname,"rb");
if (fSrc==NULL)
{
String strError;
::sprintf(strError,"AddPart: Part Info File not found (%s)\r\n",srcname);
error(strError);
mErrors++;
return(-1);
}
flen=filelength(fileno(fSrc));
if (flen==0) // Already complete
{
return(-9);
}
fDes=fopen(desname,"wb");
if(fDes==NULL)
{
String strError;
::sprintf(strError,"AddPart: Cannot create temporary part file (%s) [reason: %d]\r\n",desname,errno);
error(strError);
fclose(fSrc);
mErrors++;
return(-2);
}
loop:
cp=fgets(line,1000,fSrc);
if (cp==NULL) goto eof1;
cp=strrchr(line,'\n');
if (cp) *cp=0;
cp=strrchr(line,'\r');
if (cp) *cp=0;
// print("%s\r\n",line);
if (copyrest) // Analysis done - copy rest & done.
{
fprintf(fDes,"%s\r\n",line);
resparts++;
goto loop;
}
a=atol(line);
if (a==0)
{
String strError;
::sprintf(strError,"Corrupt part-info file (%s)\r\n",line);
error(strError);
mErrors++;
fclose(fSrc); fclose(fDes); return(-3);
}
cp=strchr(line,',');
if (cp==NULL)
{
String strError;
::sprintf(strError,"Corrupt part-info file (%s)\r\n",line);
error(strError);
mErrors++;
fclose(fSrc); fclose(fDes); return(-4);
}
e=atol(cp+1);
// print("a:%6d, e:%6d\r\n",a,e);
// ----- Case Analysis -----
// .............[yb--------ye] (The new, incoming block)
// 1...a****e (The old, missing block)
// 2...a********-----e (***) Newly written missing block
// 3...a********--------------****e
// .............[yb--------ye]
// 4............a-----e
// 5............a------------e
// 6............a-------------****e
// .............[yb--------ye]
// 7............................a***e
// .............[yb--------ye]
// 8................a----e
// 9................a---------****e
if (a<y_begin) // A previous section was missed
{
if (e<y_begin) // A previous section was missed entirely
{
// Case-1
fprintf(fDes,"%ld,%ld\r\n",a,e); // --> Keep that entry
resparts++;
goto loop;
}
if (e<=y_end) // Rduce the old section
{
// Case-2
fprintf(fDes,"%ld,%ld\r\n",a,y_begin-1); // --> Reduce that entry
resparts++;
goto loop;
}
// The new section is splitting the old missing section
// Case-3
fprintf(fDes,"%ld,%ld\r\n",a,y_begin-1); // --> First part
fprintf(fDes,"%ld,%ld\r\n",y_end+1,e); // --> First part
resparts++; resparts++;
goto loop;
}
if (a==y_begin) // New part matches this segment
{
if (e<y_end) // Just a smaller section was missed
{
// case 4
goto loop; // Skip this and analyse next
}
if (e==y_end) // This missing section was exactly -> remove it & done.
{
// case 5
copyrest=1; goto loop;
}
if (e>y_end) // The first part was found
{
// case-6
fprintf(fDes,"%ld,%ld\r\n",y_end+1,e); // Write the rest
resparts++;
copyrest=1; goto loop;
}
}
if (a>y_begin)
{
if (a>y_end) // the found section completely in front of this one.
{
// Case-7
fprintf(fDes,"%ld,%ld\r\n",a,e); // Rewrite it & copy the rest
resparts++;
copyrest=1; goto loop;
}
if (e<=y_end) // The section was completely found
{
// Case-8
goto loop; // Analyse the rest
}
// The first part of the missing section was found
// case-9
fprintf(fDes,"%ld,%ld\r\n",y_end+1,e); // Reduce it & copy the rest
resparts++;
copyrest=1; goto loop;
}
eof1:
fclose(fSrc); fclose(fDes);
remove(srcname);
rename(desname,srcname);
return(resparts);
}
// virtuals
void PureDecoder::error(const String &error)
{
::OutputDebugString(error.str());
}
void PureDecoder::display(const String &string)
{
::OutputDebugString(string.str());
}

41
yproxy/hold/pdecode.hpp Normal file
View File

@@ -0,0 +1,41 @@
#ifndef _YPROXY_PDECODE_HPP_
#define _YPROXY_PDECODE_HPP_
class PureDecoder
{
public:
PureDecoder();
int yDecode(FILE * fOut, FILE * fIn, long y_line, long y_size,int y_part);
protected:
virtual void error(const String &error);
virtual void display(const String &string);
private:
static char *ad_fgetscr(char * buffer, int maxlen, FILE * fp);
static unsigned long hex_to_ulong(char * text);
PureDecoder(const PureDecoder &pureDecoder);
PureDecoder &operator=(const PureDecoder &pureDecoder);
int AddPart(char * srcname,long y_begin, long y_end);
int mErrors;
int mErrParts;
int mErrFiles;
bool mDisplay;
long myBegin;
long myEnd;
char mAttName[260];
char mAtText[260];
unsigned long mAdResCrc;
unsigned long mAdResLen;
};
inline
PureDecoder::PureDecoder(const PureDecoder &pureDecoder)
{ // private
}
inline
PureDecoder &PureDecoder::operator=(const PureDecoder &pureDecoder)
{ // private
return *this;
}
#endif

124
yproxy/hold/ydecode.cpp Normal file
View File

@@ -0,0 +1,124 @@
#include <yproxy/ydecode.hpp>
#include <common/pathfnd.hpp>
#include <common/profile.hpp>
#include <common/console.hpp>
#include <common/file.hpp>
#include <common/array.hpp>
#include <yproxy/yheader.hpp>
#include <yproxy/pdecode.hpp>
bool YDecoder::isYEnc(const String &pathFileName)
{
YHeader yHeader;
String strLine;
File inFile;
bool haveHeader=false;
if(!inFile.open(pathFileName,"rb"))return false;
while(true)
{
if(!inFile.readLine(strLine))break;
if(yHeader.fromString(strLine))
{
haveHeader=true;
break;
}
}
if(!haveHeader)return false;
return true;
}
bool YDecoder::decode(const String &pathFileName,String &strPathImageFile,Method method)
{
File inFile;
File outFile;
String strLine;
YHeader yHeader;
PureDecoder pureDecoder;
String strPath;
bool haveHeader=false;
bool result=false;
Profile profile;
if(!inFile.open(pathFileName,"rb"))return false;
while(true)
{
if(!inFile.readLine(strLine))break;
if(yHeader.fromString(strLine))
{
haveHeader=true;
break;
}
}
if(!haveHeader)return false;
::unlink(strPath+yHeader.getName());
inFile.readLine(strLine);
strPath=pathFileName;
if(!Profile::makeDirectoryName(strPath))strPath=String();
else strPath+=String("\\");
outFile.open(strPath+yHeader.getName(),"w+b");
packFile(outFile,yHeader.getSize());
yHeader.setPart(0);
try
{
result=pureDecoder.yDecode(outFile.getFile(),inFile.getFile(),yHeader.getLine(),yHeader.getSize(),yHeader.getPart());
}
catch(...)
{
::printf("[YDecoder::decode] caught an exception decoding %s\n",pathFileName);
}
if(!result && AbortOnError==method)
{
outFile.close();
::unlink(strPath+yHeader.getName());
return false;
}
strPathImageFile=yHeader.getName();
outFile.close();
inFile.close();
return true;
}
void YDecoder::packFile(File &outFile,int byteCount)
{
Array<BYTE> bytes;
bytes.size(byteCount);
::memset(&bytes[0],255,byteCount);
outFile.write(&bytes[0],byteCount);
outFile.rewind();
}
/*
void main(int argc,char**argv)
{
FindData findData;
String strPathImageFile;
String strPath;
String strPattern;
String strSeparator("\\");
if(argc!=3)
{
::printf("USAGE: <directory> <filemask>\n");
::printf("(ie) ydecode ..\\news *.uue\n");
::printf("Hit CR to continue.");
String str;
gets(str);
return;
}
strPath=argv[1];
strPattern=argv[2];
::printf("%s%s%s\n",strPath.str(),strSeparator.str(),strPattern.str());
if(findData.findFirst(strPath+strSeparator+strPattern))
{
if(!YDecoder::decode(strPath+strSeparator+findData.fileName(),strPathImageFile))
::printf("Decode failed for %s\n",String(strPath+strSeparator+findData.fileName()).str());
else ::printf("Decoded %s->%s\n",String(strPath+strSeparator+findData.fileName()).str(),strPathImageFile.str());
while(findData.findNext())
{
if(!YDecoder::decode(strPath+strSeparator+findData.fileName(),strPathImageFile))
::printf("Decode failed for %s\n",String(strPath+strSeparator+findData.fileName()).str());
else ::printf("Decoded %s->%s\n",String(strPath+strSeparator+findData.fileName()).str(),strPathImageFile.str());
}
}
}
*/

17
yproxy/hold/ydecode.hpp Normal file
View File

@@ -0,0 +1,17 @@
#ifndef _YPROXY_YDECODE_HPP_
#define _YPROXY_YDECODE_HPP_
class File;
class String;
class YDecoder
{
public:
typedef enum Method{ForceDecode,AbortOnError};
static bool decode(const String &pathFileName,String &strPathImageFile,Method method=AbortOnError);
static bool isYEnc(const String &pathFileName);
private:
YDecoder(void);
static void packFile(File &outFile,int byteCount);
};
#endif

152
yproxy/hold/yheader.hpp Normal file
View File

@@ -0,0 +1,152 @@
#ifndef _YPROXY_YHEADER_HPP_
#define _YPROXY_YHEADER_HPP_
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
class YHeader
{
public:
YHeader();
YHeader(const String &name,int size,int line,int part);
virtual ~YHeader();
bool fromString(String strLine);
const String &getName(void)const;
void setName(const String &name);
int getSize(void)const;
void setSize(int size);
int getLine(void)const;
void setLine(int line);
int getPart(void)const;
void setPart(int part);
private:
String mName;
int mSize;
int mLine;
int mPart;
};
inline
YHeader::YHeader()
: mSize(0), mLine(0), mPart(0)
{
}
inline
YHeader::YHeader(const String &name,int size,int line,int part)
: mName(name), mSize(size), mLine(line), mPart(part)
{
}
inline
YHeader::~YHeader()
{
}
inline
bool YHeader::fromString(String strLine)
{
int pos;
if(-1==(pos=strLine.strpos("=ybegin ")))return false;
if(-1==(pos=strLine.strpos("name=")))return false;
setName(strLine.substr(pos).betweenString('=',0));
if(-1==(pos=strLine.strpos("size=")))return false;
setSize(strLine.substr(pos).betweenString('=',0).toInt());
if(-1==(pos=strLine.strpos("line=")))return false;
setLine(strLine.substr(pos).betweenString('=',0).toInt());
if(-1==(pos=strLine.strpos("part=")))return false;
setPart(strLine.substr(pos).betweenString('=',0).toInt());
return true;
/*
if (aDsp) print("\r\nTrigger: %s\r\n",line);
// Start of a section found
cp=strstr(line,"name=");
if (cp==NULL)
{
eprint("'name=' not found in =ybegin line. (%s)\r\n",line);
errors++;
goto loop; // Error - filename not found
}
strcpy(attname,cp+5); // Store the filename
*cp=0; // throw away the filename
cp=strstr(line,"size=");
if (cp==NULL)
{
eprint("'size=' not found in =ybegin line. (%s)\r\n",line);
errors++;
goto loop; // Error - size not found
}
y_size=atol(cp+5);
cp=strstr(line,"line=");
if (cp==NULL)
{
eprint("'line=' not found in =ybegin line. (%s)\r\n",line);
errors++;
goto loop; // Error - linelength not found
}
y_line=atol(cp+5);
y_part=0;
cp=strstr(line,"part="); // Check if this is a multipart message
if (cp)
{
y_part=atol(cp+5);
// if (y_part != 1) goto loop; // MUST start with the first part for proper decoding
}
*/
}
inline
const String &YHeader::getName(void)const
{
return mName;
}
inline
void YHeader::setName(const String &name)
{
mName=name;
}
inline
int YHeader::getSize(void)const
{
return mSize;
}
inline
void YHeader::setSize(int size)
{
mSize=size;
}
inline
int YHeader::getLine(void)const
{
return mLine;
}
inline
void YHeader::setLine(int line)
{
mLine=line;
}
inline
int YHeader::getPart(void)const
{
return mPart;
}
inline
void YHeader::setPart(int part)
{
mPart=part;
}
#endif