712 lines
23 KiB
C++
712 lines
23 KiB
C++
#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)
|
|
{
|
|
}
|