Initial
This commit is contained in:
711
nntp/NNTP.CPP
Normal file
711
nntp/NNTP.CPP
Normal file
@@ -0,0 +1,711 @@
|
||||
#include <nntp/nntp.hpp>
|
||||
#include <nntp/listitms.hpp>
|
||||
#include <nntp/grpitem.hpp>
|
||||
#include <nntp/header.hpp>
|
||||
#include <socket/hostent.hpp>
|
||||
#include <socket/servent.hpp>
|
||||
#include <common/systime.hpp>
|
||||
|
||||
bool NNTPClient::open(const String &hostName,const String &user,const String &password)
|
||||
{
|
||||
Block<String> responseLines;
|
||||
String strLastResponse;
|
||||
HostEnt hostEntry;
|
||||
ServEnt serverEntry;
|
||||
|
||||
if(isConnected())cancel();
|
||||
message(String("trying ")+hostName+String("..."));
|
||||
if(!mWSASystem.isInitialized()){message("WINSOCK initialization failure.");return false;}
|
||||
InternetAddress internetAddress(hostName);
|
||||
if(!internetAddress.isZero()){if(!hostEntry.hostByAddress(internetAddress)){message(String("no DNS entry for ")+hostName);return false;}}
|
||||
else if(!hostEntry.hostByName(hostName)){message(String("no DNS entry for ")+hostName);return false;}
|
||||
message(String("connect...")+String("'")+hostEntry.hostName()+String("' (")+(String)(hostEntry.addresses())[0]+String(")"));
|
||||
INETSocketAddress::internetAddress((hostEntry.addresses())[0]);
|
||||
if(!serverEntry.serviceByName("nntp","tcp")){message("cannot determine port number for nntp daemon.");return FALSE;}
|
||||
if(!mNNTPControl.create()){message("unable to create socket.");return FALSE;}
|
||||
INETSocketAddress::family(PF_INET);
|
||||
INETSocketAddress::port(serverEntry.port());
|
||||
if(!mNNTPControl.connect((INETSocketAddress&)*this)){message("unable to connect to nntp server");return FALSE;}
|
||||
if(!isConnected())return false;
|
||||
receiveStrings(responseLines);
|
||||
message(responseLines);
|
||||
if(responseLines.size())
|
||||
{
|
||||
strLastResponse=responseLines[responseLines.size()-1];
|
||||
if(isInResponse(strLastResponse.betweenString(0,' '),mNakConnectStrings))mNNTPControl.destroy();
|
||||
else if(!authenticate(user,password))mNNTPControl.destroy();
|
||||
}
|
||||
return mNNTPControl.isConnected();
|
||||
}
|
||||
|
||||
bool NNTPClient::open(const String &hostName)
|
||||
{
|
||||
Block<String> responseLines;
|
||||
String strLastResponse;
|
||||
HostEnt hostEntry;
|
||||
ServEnt serverEntry;
|
||||
|
||||
if(isConnected())cancel();
|
||||
message(String("trying ")+hostName+String("..."));
|
||||
if(!mWSASystem.isInitialized()){message("WINSOCK initialization failure.");return false;}
|
||||
InternetAddress internetAddress(hostName);
|
||||
if(!internetAddress.isZero()){if(!hostEntry.hostByAddress(internetAddress)){message(String("no DNS entry for ")+hostName);return false;}}
|
||||
else if(!hostEntry.hostByName(hostName)){message(String("no DNS entry for ")+hostName);return false;}
|
||||
message(String("connect...")+String("'")+hostEntry.hostName()+String("' (")+(String)(hostEntry.addresses())[0]+String(")"));
|
||||
INETSocketAddress::internetAddress((hostEntry.addresses())[0]);
|
||||
if(!serverEntry.serviceByName("nntp","tcp")){message("cannot determine port number for nntp daemon.");return false;}
|
||||
if(!mNNTPControl.create()){message("unable to create socket.");return false;}
|
||||
INETSocketAddress::family(PF_INET);
|
||||
INETSocketAddress::port(serverEntry.port());
|
||||
if(!mNNTPControl.connect((INETSocketAddress&)*this)){message("unable to connect to nntp server");return false;}
|
||||
if(!isConnected())return false;
|
||||
receiveStrings(responseLines);
|
||||
return mNNTPControl.isConnected();
|
||||
}
|
||||
|
||||
bool NNTPClient::quit(void)
|
||||
{
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[Quit];
|
||||
if(!putControlData(controlData,false))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
message(responseLine);
|
||||
if(!isInResponse(responseLine.betweenString(0,' '),mAckQuitResponseStrings))return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NNTPClient::slave(void)
|
||||
{
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[Slave];
|
||||
if(!putControlData(controlData,false))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
message(responseLine);
|
||||
if(!isInResponse(responseLine.betweenString(0,' '),mAckSlaveResponseStrings))return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NNTPClient::group(GroupItem &groupItem)
|
||||
{
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
if(!isConnected())return false;
|
||||
if(groupItem.groupName().isNull())return false;
|
||||
controlData.reserve(String::MaxString);
|
||||
::sprintf(controlData,"%s %s",(LPSTR)mNNTPCmds[Group],(LPSTR)groupItem.groupName());
|
||||
if(!putControlData(controlData,false))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
if(!isInResponse(responseLine.betweenString(0,' '),mAckGroupResponseStrings))return false;
|
||||
groupItem<<responseLine;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NNTPClient::list(void)
|
||||
{
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[List];
|
||||
if(!putControlData(controlData,false))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
message(responseLine);
|
||||
if(!isInResponse(responseLine.betweenString(0,' '),mAckListResponseStrings))return false;
|
||||
while(mNNTPControl.receive(responseLine))
|
||||
{
|
||||
if(mPeriod==responseLine)break;
|
||||
message(responseLine);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NNTPClient::authenticate(const String &user,const String &password)
|
||||
{
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
if(!isConnected())return false;
|
||||
if(user.isNull()||password.isNull())return false;
|
||||
message(String("AUTHENTICATING user '")+user+String("'"));
|
||||
controlData=mNNTPCmds[AuthInfoUser];
|
||||
controlData+=String(" ")+user;
|
||||
if(!putControlData(controlData,false))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
controlData=mNNTPCmds[AuthInfoPass];
|
||||
controlData+=String(" ")+password;
|
||||
if(!putControlData(controlData,false))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
message(responseLine);
|
||||
if(!isInResponse(responseLine.betweenString(0,' '),mAckAuthResponseStrings))return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NNTPClient::list(ListItems &listItems)
|
||||
{
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
listItems.remove();
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[List];
|
||||
if(!putControlData(controlData,false))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
message(responseLine);
|
||||
if(!isInResponse(responseLine.betweenString(0,' '),mAckListResponseStrings))return false;
|
||||
while(mNNTPControl.receive(responseLine))
|
||||
{
|
||||
if(mPeriod==responseLine)break;
|
||||
listItems+=responseLine;
|
||||
}
|
||||
return (listItems.size()?true:false);
|
||||
}
|
||||
|
||||
bool NNTPClient::article(DWORD articleNumber,Block<String> &articleText,String &messageID)
|
||||
{
|
||||
String controlData;
|
||||
bool returnCode;
|
||||
|
||||
::sprintf(controlData,"%s %ld",(LPSTR)mNNTPCmds[Article],articleNumber);
|
||||
returnCode=retrieveBlock(controlData,articleText,messageID,mAckArticleResponseStrings,mNackArticleResponseStrings);
|
||||
messageID=messageID.betweenString('<','>');
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
bool NNTPClient::article(const MsgID &msgID,Block<String> &articleText,String &messageID)
|
||||
{
|
||||
String controlData;
|
||||
|
||||
controlData=mNNTPCmds[Article]+mSpace+msgID;
|
||||
return retrieveBlock(controlData,articleText,messageID,mAckArticleResponseStrings,mNackArticleResponseStrings);
|
||||
}
|
||||
|
||||
bool NNTPClient::body(DWORD articleNumber,Block<String> &bodyText,String &messageID)
|
||||
{
|
||||
String controlData;
|
||||
|
||||
::sprintf(controlData,"%s %d",(LPSTR)mNNTPCmds[Body],articleNumber);
|
||||
return retrieveBlock(controlData,bodyText,messageID,mAckArticleResponseStrings,mNackArticleResponseStrings);
|
||||
}
|
||||
|
||||
bool NNTPClient::body(const MsgID &msgID,Block<String> &bodyText,String &messageID)
|
||||
{
|
||||
String controlData;
|
||||
|
||||
controlData=mNNTPCmds[Body];
|
||||
controlData+=mSpace+msgID;
|
||||
return retrieveBlock(controlData,bodyText,messageID,mAckArticleResponseStrings,mNackArticleResponseStrings);
|
||||
}
|
||||
|
||||
bool NNTPClient::head(DWORD articleNumber,Block<String> &headText,String &messageID)
|
||||
{
|
||||
String controlData;
|
||||
|
||||
::sprintf(controlData,"%s %ld",(LPSTR)mNNTPCmds[Head],articleNumber);
|
||||
return retrieveBlock(controlData,headText,mAckArticleResponseStrings,mNackArticleResponseStrings);
|
||||
}
|
||||
|
||||
bool NNTPClient::head(const MsgID &msgID,Block<String> &headText,String &messageID)
|
||||
{
|
||||
String controlData;
|
||||
|
||||
controlData=mNNTPCmds[Head]+mSpace+msgID;
|
||||
return retrieveBlock(controlData,headText,mAckArticleResponseStrings,mNackArticleResponseStrings);
|
||||
}
|
||||
|
||||
bool NNTPClient::stat(DWORD articleNumber,MsgID &msgID)
|
||||
{
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
if(!isConnected())return false;
|
||||
::sprintf(controlData,"%s %ld",(LPSTR)mNNTPCmds[Stat],articleNumber);
|
||||
if(!putControlData(controlData,false))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
if(isInResponse(responseLine.betweenString(0,' '),mNackArticleResponseStrings))return false;
|
||||
responseLine=responseLine.betweenString(' ',0);
|
||||
msgID=responseLine.betweenString(' ',0);
|
||||
return (!msgID.isNull());
|
||||
}
|
||||
|
||||
bool NNTPClient::stat(const MsgID &msgID,MsgID &msgFound)
|
||||
{
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[Stat]+mSpace+msgID;
|
||||
if(!putControlData(controlData,false))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
if(isInResponse(responseLine.betweenString(0,' '),mNackArticleResponseStrings))return false;
|
||||
responseLine=responseLine.betweenString(' ',0);
|
||||
msgFound=responseLine.betweenString(' ',0);
|
||||
return (!msgFound.isNull());
|
||||
}
|
||||
|
||||
bool NNTPClient::listGroup(const String &newsGroup,Block<String> &messageIDStrings)
|
||||
{
|
||||
DWORD responseLines(0L);
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
messageIDStrings.remove();
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[ListGroup];
|
||||
controlData+=mSpace;
|
||||
controlData+=newsGroup;
|
||||
if(!putControlData(controlData,false))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
if(isInResponse(responseLine.betweenString(0,' '),mNackGroupResponseStrings))return false;
|
||||
while(mNNTPControl.receive(responseLine))
|
||||
{
|
||||
if(mPeriod==responseLine&&1==responseLine.length())break;
|
||||
messageIDStrings.insert(&responseLine);
|
||||
}
|
||||
return (messageIDStrings.size()?true:false);
|
||||
}
|
||||
|
||||
bool NNTPClient::newNews(Block<String> &newsGroups,Block<String> &distributionGroups,Block<String> &messageIDStrings,const SystemTime &systemTime,WORD isGMT)
|
||||
{
|
||||
DWORD responseLines(0L);
|
||||
String controlData;
|
||||
String timeDateString;
|
||||
String responseLine;
|
||||
|
||||
messageIDStrings.remove();
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[NewNews];
|
||||
controlData+=mSpace;
|
||||
for(int itemIndex=0;itemIndex<newsGroups.size();itemIndex++)
|
||||
{
|
||||
controlData+=newsGroups[itemIndex];
|
||||
if(itemIndex+1<newsGroups.size())controlData+=mComma;
|
||||
}
|
||||
controlData+=mSpace;
|
||||
makeTimeDateString(timeDateString,systemTime);
|
||||
controlData+=timeDateString;
|
||||
if(isGMT)controlData+=" [GMT]";
|
||||
if(distributionGroups.size())
|
||||
{
|
||||
controlData+=mSpace+mLeftAngle;
|
||||
for(itemIndex=0;itemIndex<distributionGroups.size();itemIndex++)
|
||||
{
|
||||
controlData+=distributionGroups[itemIndex];
|
||||
if(itemIndex+1<distributionGroups.size())controlData+=mComma;
|
||||
}
|
||||
controlData+=mRightAngle;
|
||||
}
|
||||
if(!putControlData(controlData,false))return false;
|
||||
while(mNNTPControl.receive(responseLine))
|
||||
{
|
||||
if(mPeriod==responseLine&&1==responseLine.length())break;
|
||||
if(!responseLines++)
|
||||
{
|
||||
String responseString(responseLine.betweenString(0,' '));
|
||||
if(isInResponse(responseString,mAckNewNewsResponseStrings))continue;
|
||||
}
|
||||
messageIDStrings.insert(&responseLine);
|
||||
}
|
||||
return (messageIDStrings.size()?true:false);
|
||||
}
|
||||
|
||||
bool NNTPClient::simulateNewNews(const String &newsGroup,Block<String> &messageIDStrings,short pastDays)
|
||||
{
|
||||
String messageID;
|
||||
SystemTime systemTime;
|
||||
GroupItem groupItem;
|
||||
int badArticles(0);
|
||||
int goodArticles(0);
|
||||
int maxBadArticles(100);
|
||||
int maxGoodArticlesToOffsetBad(10);
|
||||
|
||||
messageIDStrings.remove();
|
||||
if(!isConnected())return false;
|
||||
daysPast(systemTime,pastDays);
|
||||
groupItem.groupName(newsGroup);
|
||||
group(groupItem);
|
||||
for(int articleIndex=groupItem.lastArticle();articleIndex>=groupItem.firstArticle();articleIndex--)
|
||||
{
|
||||
Block<String> headerText;
|
||||
head(articleIndex,headerText,messageID);
|
||||
if(!headerText.size())
|
||||
{
|
||||
String msgString;
|
||||
::sprintf(msgString,"article #:%d is not available, %d of %d",articleIndex,++badArticles,maxBadArticles);
|
||||
message(msgString);
|
||||
if(badArticles>=maxBadArticles)break;
|
||||
continue;
|
||||
}
|
||||
else goodArticles++;
|
||||
if(goodArticles>maxGoodArticlesToOffsetBad){badArticles=0;goodArticles=0;}
|
||||
Header articleHeader(headerText);
|
||||
message(String("examining ")+articleHeader.messageID()+String(", ")+articleHeader.date());
|
||||
if(articleHeader.systemTime()<systemTime)continue;
|
||||
messageIDStrings.insert(&articleHeader.messageID());
|
||||
}
|
||||
return (messageIDStrings.size()?true:false);
|
||||
}
|
||||
|
||||
bool NNTPClient::newNews(const String &newsGroup,Block<String> &messageIDStrings,short pastDays)
|
||||
{
|
||||
DWORD responseLines(0L);
|
||||
String controlData;
|
||||
String responseLine;
|
||||
String timeDateString;
|
||||
SystemTime systemTime;
|
||||
|
||||
messageIDStrings.remove();
|
||||
if(!isConnected())return false;
|
||||
daysPast(systemTime,pastDays);
|
||||
controlData=mNNTPCmds[NewNews];
|
||||
controlData+=mSpace;
|
||||
controlData+=newsGroup;
|
||||
makeTimeDateString(timeDateString,systemTime);
|
||||
controlData+=mSpace;
|
||||
controlData+=timeDateString;
|
||||
if(!putControlData(controlData))return false;
|
||||
while(mNNTPControl.receive(responseLine))
|
||||
{
|
||||
if(mPeriod==responseLine&&1==responseLine.length())break;
|
||||
if(!responseLines++)
|
||||
{
|
||||
String responseString(responseLine.betweenString(0,' '));
|
||||
if(isInResponse(responseString,mAckNewNewsResponseStrings))continue;
|
||||
}
|
||||
messageIDStrings.insert(&responseLine);
|
||||
}
|
||||
return (messageIDStrings.size()?true:false);
|
||||
}
|
||||
|
||||
bool NNTPClient::newGroups(ListItems &listItems,short pastDays)
|
||||
{
|
||||
SystemTime systemTime;
|
||||
Block<String> distributionGroups;
|
||||
|
||||
listItems.remove();
|
||||
daysPast(systemTime,pastDays);
|
||||
return newGroups(listItems,distributionGroups,systemTime,false);
|
||||
}
|
||||
|
||||
bool NNTPClient::newGroups(ListItems &listItems,Block<String> &distributionGroups,const SystemTime &systemTime,bool isGMT)
|
||||
{
|
||||
String controlData;
|
||||
String responseLine;
|
||||
String timeDateString;
|
||||
DWORD responseLines(0);
|
||||
|
||||
listItems.remove();
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[NewGroups];
|
||||
controlData+=mSpace;
|
||||
makeTimeDateString(timeDateString,systemTime);
|
||||
controlData+=timeDateString;
|
||||
if(isGMT)controlData+=" [GMT]";
|
||||
if(distributionGroups.size())
|
||||
{
|
||||
controlData+=mSpace+mLeftAngle;
|
||||
for(int itemIndex=0;itemIndex<distributionGroups.size();itemIndex++)
|
||||
{
|
||||
controlData+=distributionGroups[itemIndex];
|
||||
if(itemIndex+1<distributionGroups.size())controlData+=mComma;
|
||||
}
|
||||
controlData+=mRightAngle;
|
||||
}
|
||||
if(!putControlData(controlData,false))return false;
|
||||
while(mNNTPControl.receive(responseLine))
|
||||
{
|
||||
if(mPeriod==responseLine&&1==responseLine.length())break;
|
||||
if(!responseLines++)
|
||||
{
|
||||
String responseString(responseLine.betweenString(0,' '));
|
||||
if(isInResponse(responseString,mAckNewGroupsResponseStrings))continue;
|
||||
}
|
||||
listItems+=responseLine;
|
||||
}
|
||||
return (listItems.size()?true:false);
|
||||
}
|
||||
|
||||
bool NNTPClient::next(GroupIterator &groupIterator)
|
||||
{
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[Next];
|
||||
if(!putControlData(controlData))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
if(!isInResponse(responseLine.betweenString(0,' '),mAckNextResponseStrings))return false;
|
||||
groupIterator<<responseLine;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NNTPClient::last(GroupIterator &groupIterator)
|
||||
{
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[Last];
|
||||
if(!putControlData(controlData))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
if(!isInResponse(responseLine.betweenString(0,' '),mAckNextResponseStrings))return false;
|
||||
groupIterator<<responseLine;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NNTPClient::iHave(const MsgID &msgID)
|
||||
{
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[IHave]+mSpace+msgID;
|
||||
if(!putControlData(controlData))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
if(!isInResponse(responseLine.betweenString(0,' '),mAckIHaveResponseStrings))return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NNTPClient::xover(DWORD first,DWORD last,Block<String> &overview)
|
||||
{
|
||||
DWORD responseLines(0);
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
overview.remove();
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[XOver]+String(" ")+String().fromInt(first)+String("-")+String().fromInt(last);
|
||||
if(!putControlData(controlData))return false;
|
||||
while(mNNTPControl.receive(responseLine))
|
||||
{
|
||||
if(mPeriod==responseLine&&1==responseLine.length())break;
|
||||
if(!responseLines++)
|
||||
{
|
||||
String responseString(responseLine.betweenString(0,' '));
|
||||
if(isInResponse(responseString,mAckXOverResponseStrings))continue;
|
||||
}
|
||||
overview.insert(&responseLine);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NNTPClient::help(Block<String> &cmdLines)
|
||||
{
|
||||
DWORD responseLines(0);
|
||||
String controlData;
|
||||
String responseLine;
|
||||
|
||||
cmdLines.remove();
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[Help];
|
||||
if(!putControlData(controlData))return false;
|
||||
while(mNNTPControl.receive(responseLine))
|
||||
{
|
||||
if(mPeriod==responseLine&&1==responseLine.length())break;
|
||||
if(!responseLines++)
|
||||
{
|
||||
String responseString(responseLine.betweenString(0,' '));
|
||||
if(isInResponse(responseString,mAckHelpResponseStrings))continue;
|
||||
}
|
||||
cmdLines.insert(&responseLine);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NNTPClient::post(Block<String> &articleLines)
|
||||
{
|
||||
String responseLine;
|
||||
String controlData;
|
||||
String postString;
|
||||
int lineCount;
|
||||
|
||||
if(!isConnected())return false;
|
||||
controlData=mNNTPCmds[Post];
|
||||
if(!putControlData(controlData))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
responseLine=responseLine.betweenString(0,' ');
|
||||
if(!isInResponse(responseLine,mAckPostResponseStrings))return false;
|
||||
lineCount=articleLines.size();
|
||||
for(int lineIndex=0;lineIndex<lineCount;lineIndex++)
|
||||
{
|
||||
postString=articleLines[lineIndex];
|
||||
if(postString==mPeriod)postString+=mPeriod;
|
||||
if(!putControlData(articleLines[lineIndex]))return false;
|
||||
}
|
||||
if(!putControlData(mPeriod))return false;
|
||||
if(!mNNTPControl.receive(responseLine))return false;
|
||||
responseLine=responseLine.betweenString(0,' ');
|
||||
if(!isInResponse(responseLine,mAckPostResponseStrings))return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NNTPClient::retrieveBlock(const String &controlData,Block<String> &stringBlock,Block<String> &ackResponse,Block<String> &nackResponse)
|
||||
{
|
||||
String extraInfo;
|
||||
return retrieveBlock(controlData,stringBlock,extraInfo,ackResponse,nackResponse);
|
||||
}
|
||||
|
||||
bool NNTPClient::retrieveBlock(const String &controlData,Block<String> &stringBlock,String &extraInfo,Block<String> &ackResponse,Block<String> &nackResponse)
|
||||
{
|
||||
String responseLine;
|
||||
DWORD responseLines(0);
|
||||
|
||||
stringBlock.remove();
|
||||
if(!isConnected())return false;
|
||||
if(!putControlData(controlData,false))return false;
|
||||
while(mNNTPControl.receive(responseLine))
|
||||
{
|
||||
if(mPeriod==responseLine&&1==responseLine.length())break;
|
||||
if(!responseLines++)
|
||||
{
|
||||
String responseString(responseLine.betweenString(0,' '));
|
||||
extraInfo=responseLine.betweenString(' ','\0');
|
||||
if(nackResponse.size()&&isInResponse(responseString,nackResponse))break;
|
||||
if(ackResponse.size()&&isInResponse(responseString,ackResponse))continue;
|
||||
}
|
||||
stringBlock.insert(&responseLine);
|
||||
}
|
||||
return (stringBlock.size()?true:false);
|
||||
}
|
||||
|
||||
bool NNTPClient::putControlData(const String &stringData,bool waitForResponse)
|
||||
{
|
||||
if(!mNNTPControl.isConnected())return false;
|
||||
if(!mNNTPControl.send(stringData))
|
||||
{
|
||||
mNNTPControl.destroy();
|
||||
String errorString(String("error sending '")+stringData+String("' to NNTP server."));
|
||||
message(errorString);
|
||||
return false;
|
||||
}
|
||||
if(waitForResponse&&!getControlData())
|
||||
{
|
||||
mNNTPControl.destroy();
|
||||
String errorString(String("error reading result of '")+stringData+String("' command from NNTP server."));
|
||||
message(errorString);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NNTPClient::getControlData(void)
|
||||
{
|
||||
Block<String> responseStrings;
|
||||
mNNTPControl.receive(responseStrings);
|
||||
return responseStrings.size()?true:false;
|
||||
}
|
||||
|
||||
void NNTPClient::receiveStrings(WORD displayStrings)
|
||||
{
|
||||
Block<String> receiveStrings;
|
||||
|
||||
if(!mNNTPControl.isConnected())return;
|
||||
if(!mNNTPControl.receive(receiveStrings))return;
|
||||
if(!displayStrings||!receiveStrings.size())return;
|
||||
message(receiveStrings);
|
||||
}
|
||||
|
||||
void NNTPClient::receiveStrings(Block<String> &receiveStrings)
|
||||
{
|
||||
receiveStrings.remove();
|
||||
if(!mNNTPControl.isConnected())return;
|
||||
if(!mNNTPControl.receive(receiveStrings))return;
|
||||
if(!receiveStrings.size())return;
|
||||
message(receiveStrings);
|
||||
}
|
||||
|
||||
void NNTPClient::createCmds(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("XOVER"));
|
||||
}
|
||||
|
||||
bool NNTPClient::isInResponse(const String &responseString,Block<String> &responseStrings)
|
||||
{
|
||||
if(responseString.isNull())return false;
|
||||
for(int itemIndex=0;itemIndex<responseStrings.size();itemIndex++)
|
||||
if(responseString==responseStrings[itemIndex])return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void NNTPClient::createResponseStrings(void)
|
||||
{
|
||||
mAckArticleResponseStrings.insert(&String("220"));
|
||||
mAckArticleResponseStrings.insert(&String("221"));
|
||||
mAckArticleResponseStrings.insert(&String("222"));
|
||||
mAckArticleResponseStrings.insert(&String("223"));
|
||||
mNackArticleResponseStrings.insert(&String("412"));
|
||||
mNackArticleResponseStrings.insert(&String("420"));
|
||||
mNackArticleResponseStrings.insert(&String("423"));
|
||||
mNackArticleResponseStrings.insert(&String("430"));
|
||||
mNackArticleResponseStrings.insert(&String("480"));
|
||||
mAckSlaveResponseStrings.insert(&String("202"));
|
||||
mAckGroupResponseStrings.insert(&String("211"));
|
||||
mNackGroupResponseStrings.insert(&String("411"));
|
||||
mNackGroupResponseStrings.insert(&String("480"));
|
||||
mAckListResponseStrings.insert(&String("215"));
|
||||
mAckQuitResponseStrings.insert(&String("205"));
|
||||
mAckNewNewsResponseStrings.insert(&String("230"));
|
||||
mAckNextResponseStrings.insert(&String("223"));
|
||||
mAckNewGroupsResponseStrings.insert(&String("231"));
|
||||
mAckIHaveResponseStrings.insert(&String("335"));
|
||||
mAckHelpResponseStrings.insert(&String("100"));
|
||||
mAckPostResponseStrings.insert(&String("340"));
|
||||
mAckPostResponseStrings.insert(&String("240"));
|
||||
mAckAuthResponseStrings.insert(&String("281"));
|
||||
mAckXOverResponseStrings.insert(&String("224"));
|
||||
mNakConnectStrings.insert(&String("502"));
|
||||
mNakConnectStrings.insert(&String("400"));
|
||||
}
|
||||
|
||||
void NNTPClient::makeTimeDateString(String &timeDateString,const SystemTime &systemTime)
|
||||
{
|
||||
timeDateString.reserve(String::MaxString);
|
||||
::sprintf(timeDateString,"%02d%02d%02d %02d%02d%02d",
|
||||
systemTime.year()>2000?2000-systemTime.year():systemTime.year()-1900,
|
||||
systemTime.month(),
|
||||
systemTime.day(),
|
||||
systemTime.hour(),
|
||||
systemTime.minute(),
|
||||
systemTime.second());
|
||||
}
|
||||
|
||||
void NNTPClient::daysPast(SystemTime &systemTime,short pastDays)
|
||||
{
|
||||
systemTime.daysAdd360(-pastDays);
|
||||
systemTime.hour(0);
|
||||
systemTime.minute(0);
|
||||
systemTime.second(0);
|
||||
}
|
||||
|
||||
// virtual overloads
|
||||
void NNTPClient::message(String messageString)
|
||||
{
|
||||
}
|
||||
|
||||
void NNTPClient::message(Block<String> &messageStrings)
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user