#include #include #include POPClient::POPClient(void) : mSpace(" "), mIsLoggedIn(FALSE) { createCmds(); createStats(); } POPClient::~POPClient() { } BOOL POPClient::open(const String &hostName) { HostEnt hostEntry; ServEnt serverEntry; Block responseLines; INETSocketAddress internetSocketAddress; if(hostName.isNull())return FALSE; if(mPOPControl.isConnected())mPOPControl.closeSocket(); message(String("trying ")+hostName+String("...")); if(!mWSASystem.isInitialized()){message("WINSOCK initialization failure.");return FALSE;} InternetAddress internetAddress(hostName); if(!internetAddress.isZero()){if(!hostEntry.hostByAddress(internetAddress)){return FALSE;}} else if(!hostEntry.hostByName(hostName)){return FALSE;} 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(")")); internetSocketAddress.internetAddress((hostEntry.addresses())[0]); if(serverEntry.serviceByName("pop3","tcp")) { if(!mPOPControl.openSocket()){message("unable to create socket.");return FALSE;} internetSocketAddress.family(PF_INET); internetSocketAddress.port(serverEntry.port()); } else { if(!mPOPControl.openSocket()){message("unable to create socket.");return FALSE;} internetSocketAddress.family(PF_INET); internetSocketAddress.port(htons(POPPort)); } if(!mPOPControl.connect(internetSocketAddress)){message("unable to connect to pop3 server");return FALSE;} mPOPControl.getSocketName(internetSocketAddress); if(!mPOPControl.isConnected())return FALSE; // if(!mPOPControl.receive(responseLines)) //||!responseLines.size()||! if(!mPOPControl.receive(responseLines)||!isInAckResponse(responseLines)) { mPOPControl.closeSocket(); return FALSE; } return TRUE; } BOOL POPClient::quit(void) { Block responseLines; if(!isConnected())return FALSE; isLoggedIn(FALSE); if(!putControlData(mPOPCmds[Quit],FALSE))return FALSE; mPOPControl.receive(responseLines); mPOPControl.closeSocket(); return TRUE; } BOOL POPClient::authenticate(const String &user,const String &password) { Block responseLines; if(!isConnected())return FALSE; if(!putControlData(mPOPCmds[User]+String(" ")+user,FALSE))return FALSE; if(!mPOPControl.receive(responseLines))return FALSE; if(!isInAckResponse(responseLines))return FALSE; if(!putControlData(mPOPCmds[Pass]+String(" ")+password,FALSE))return FALSE; if(!mPOPControl.receive(responseLines))return FALSE; if(!isInAckResponse(responseLines))return FALSE; isLoggedIn(TRUE); return TRUE; } BOOL POPClient::stat(WORD &messages,WORD &octets) { Block responseLines; String strItem; if(!isConnected()||!isLoggedIn())return FALSE; if(!putControlData(mPOPCmds[Stat],FALSE))return FALSE; if(!mPOPControl.receive(responseLines))return FALSE; if(!isInAckResponse(responseLines))return FALSE; strItem=responseLines[0].betweenString(' ',' '); messages=::atoi((char*)strItem); strItem=responseLines[0].betweenString(' ',0); strItem=strItem.betweenString(' ',0); octets=::atoi((char*)strItem); return TRUE; } BOOL POPClient::retrieve(WORD msgNum,Block &messageLines) { Block responseLines; String strMsg; if(!isConnected()||!isLoggedIn())return FALSE; ::sprintf(strMsg,"%d",msgNum); if(!putControlData(mPOPCmds[Retr]+String(" ")+strMsg,FALSE))return FALSE; if(!mPOPControl.receive(responseLines))return FALSE; if(!isInAckResponse(responseLines))return FALSE; return TRUE; } void POPClient::createStats(void) { mPOPStatus.insert(&String("+OK")); mPOPStatus.insert(&String("-ERR")); } void POPClient::createCmds(void) { mPOPCmds.remove(); mPOPCmds.insert(&String("QUIT")); mPOPCmds.insert(&String("USER")); mPOPCmds.insert(&String("PASS")); mPOPCmds.insert(&String("STAT")); mPOPCmds.insert(&String("RETR")); } WORD POPClient::putControlData(const String &stringData,WORD waitForResponse) { if(!mPOPControl.isConnected())return FALSE; if(!mPOPControl.send(stringData)) { mPOPControl.closeSocket(); String errorString(String("error sending '")+stringData+String("' to POP server.")); message(errorString); errorString+="\n"; ::OutputDebugString(errorString); return FALSE; } if(waitForResponse&&!getControlData()) { mPOPControl.closeSocket(); String errorString(String("error reading result of '")+stringData+String("' command from NNTP server.")); message(errorString); errorString+="\n"; ::OutputDebugString(errorString); return FALSE; } return TRUE; } WORD POPClient::getControlData(void) { Block responseStrings; mPOPControl.receive(responseStrings); return responseStrings.size(); } BOOL POPClient::isInAckResponse(Block &responseLines) { if(!responseLines.size())return FALSE; if(responseLines[0].substr(0,2)==mPOPStatus[Ok])return TRUE; return FALSE; } BOOL POPClient::isInNakResponse(Block &responseLines) { if(!responseLines.size())return FALSE; if(responseLines[0].substr(0,3)==mPOPStatus[Error])return TRUE; return FALSE; } // virtuals void POPClient::message(const String &messageString) { ::OutputDebugString(messageString+String("\n")); } void POPClient::message(Block &messageStrings) { for(int itemIndex=0;itemIndex