Small library for reading mail messages via POP3. Currently doesn\'t return all header fields, and does only plain text authorization.
Diff: pop3.cpp
- Revision:
- 3:37570217ae90
- Parent:
- 2:3893c1aaee8d
- Child:
- 4:850d9e9884fd
--- a/pop3.cpp Sat Jan 29 23:27:26 2011 +0000 +++ b/pop3.cpp Tue Feb 01 21:17:03 2011 +0000 @@ -1,198 +1,219 @@ -#include "Timer.h" - -#include "pop3.h" -#include "dnsresolve.h" - -using namespace mbed; - -class Pop3CommandResponse -{ - public: - Pop3CommandResponse(string line); - bool addLine(string line); - - bool success; - string responseLine; - list<string> responseLines; -}; - -Pop3::Pop3(const char* servername, const char* username, const char* password) { - _username=username; - _password=password; - _servername=servername; - - _closed=false; - - _stream=new TCPLineStream(servername,110,"\r\n"); - -} - -Pop3::~Pop3() { - close(); -} - -list<string> *Pop3::getMessages() { - Pop3CommandResponse* pcr=sendCommandMultiResponse("LIST"); - if (!pcr->success) { - delete pcr; - return NULL; - } - list<string> *ids=new list<string>(); - list<string> lines=pcr->responseLines; - list<string>::iterator it; - for ( it=lines.begin() ; it != lines.end(); it++ ) { - string line=*it; - string id=line.substr(0,line.find(' ')); - ids->push_back(id); - } - delete pcr; - return ids; -} - -Pop3Message* Pop3::getMessage(string id, bool getSig, bool deleteOnReceive) { - Pop3CommandResponse* pcr=sendCommandMultiResponse(string("RETR ").append(id)); - if (!pcr->success) { - delete pcr; - return NULL; - } - Pop3Message *msg=new Pop3Message(); - list<string> lines=pcr->responseLines; - list<string>::iterator it; - for ( it=lines.begin() ; it != lines.end(); it++ ) { - string line=*it; - if (0==line.find("From: ")) { - msg->from=line.substr(6); - } else if (0==line.find("Subject: ")) { - msg->subject=line.substr(9); - } else if (0==line.length()) { - break; - } - } - for (/* use iterator from above - it start right at the content */ ; it != lines.end(); it++ ) { - string line=*it; - if (!getSig && 0==line.compare("-- ")) - break; - msg->content.push_back(line); - } - delete pcr; - if (deleteOnReceive) - { - deleteMessage(id); - } - return msg; -} - -bool Pop3::deleteMessage(string id) { - Pop3CommandResponse* pcr=sendCommandMultiResponse(string("DELE ").append(id)); - if (!pcr->success) { - delete pcr; - return false; - } - delete pcr; - return true; -} - - -Pop3CommandResponse* Pop3::sendCommand(string cmd) { -// printf("send [%s]\n",cmd.c_str()); - _stream->sendLine(cmd); - string r=_stream->readLine(); - return new Pop3CommandResponse(r); -} - -Pop3CommandResponse* Pop3::sendCommandMultiResponse(string cmd) { - // first, send command -// printf("send [%s]\n",cmd.c_str()); - _stream->sendLine(cmd); - // read first response line -> contains status - string r=_stream->readLine(); -// printf("response=[%s]\n",r.c_str()); - // create response object to collect remaining lines - Pop3CommandResponse *pcr=new Pop3CommandResponse(r); - if (!pcr->success) - return pcr; - // read other lines, stop when marker reached - while (true) { - r=_stream->readLine(); - if (pcr->addLine(r)) - break; - } - return pcr; -} - -bool Pop3::init() { - if (!_stream->open()) - return NULL; - - // read server banner - string banner=_stream->readLine(); -// printf("banner=[%s]\n",banner.c_str()); - - Pop3CommandResponse pcr(banner); - if (!pcr.success) - return false; - - // send username - string cmd=string("user ").append(_username); - Pop3CommandResponse *response=sendCommand(cmd); - - if (!response->success) { - delete response; - return false; - } - - delete response; - - // send password - cmd=string("pass ").append(_password); - response=sendCommand(cmd); - - if (!response->success) { - delete response; - return false; - } - - delete response; - - return true; -} - -void Pop3::close() { - if (_closed) - return; - - Pop3CommandResponse *pcr=sendCommand("CLOSE"); - delete pcr; - - if (NULL!=_stream) { - _stream->close(); - delete _stream; - _stream=NULL; - } - - _closed=true; -} - -Pop3CommandResponse::Pop3CommandResponse(string line) { - if (0==line.find("+OK")) { - success=true; - responseLine=line.substr(4); - } else if (0==line.find("-ERR")) { - success=false; - responseLine=line.substr(5); - } else { - success=false; - } - -} - -bool Pop3CommandResponse::addLine(string line) { - // last line is single dot only - if (line.length()==1 && line.at(0)=='.') - return true; - // remove leading dot if any - if (line.length()>0 && line.at(0)=='.') - line=line.substr(1); - responseLines.push_back(line); - return false; +#include "Timer.h" + +#include "pop3.h" +#include "dnsresolve.h" + +using namespace mbed; + +class Pop3CommandResponse +{ + public: + Pop3CommandResponse(string line); + bool addLine(string line); + + bool success; + string responseLine; + list<string> responseLines; +}; + +Pop3::Pop3(const char* servername, const char* username, const char* password) { + _username=username; + _password=password; + _servername=servername; + + _closed=false; + + _stream=new TCPLineStream(servername,110,"\r\n"); + +} + +Pop3::~Pop3() { + close(); +} + +list<string> *Pop3::getMessages() { + Pop3CommandResponse* pcr=sendCommandMultiResponse("LIST"); + if (!pcr->success) { + delete pcr; + return NULL; + } + list<string> *ids=new list<string>(); + list<string> lines=pcr->responseLines; + list<string>::iterator it; + for ( it=lines.begin() ; it != lines.end(); it++ ) { + string line=*it; + string id=line.substr(0,line.find(' ')); + ids->push_back(id); + } + delete pcr; + return ids; +} + +Pop3Message* Pop3::getMessage(string id, bool getSig, bool deleteOnReceive) { + Pop3CommandResponse* pcr=sendCommand(string("UIDL ").append(id)); + if (!pcr->success) + { + delete pcr; + return NULL; + } + + char buf[74]; + int r=sscanf(pcr->responseLine.c_str(),"%*d %s",buf); + if (2!=r) + { + printf("can't recognize UIDL response: [%s]\n",pcr->responseLine.c_str()); + delete pcr; + return NULL; + } + string uid(buf); + delete pcr; + + pcr=sendCommandMultiResponse(string("RETR ").append(id)); + if (!pcr->success) { + delete pcr; + return NULL; + } + Pop3Message *msg=new Pop3Message(); + msg->id=uid; + list<string> lines=pcr->responseLines; + list<string>::iterator it; + for ( it=lines.begin() ; it != lines.end(); it++ ) { + string line=*it; + if (0==line.find("From: ")) { + msg->from=line.substr(6); + } else if (0==line.find("Subject: ")) { + msg->subject=line.substr(9); + } else if (0==line.length()) { + break; + } + } + for (/* use iterator from above - it start right at the content */ ; it != lines.end(); it++ ) { + string line=*it; + if (!getSig && 0==line.compare("-- ")) + break; + msg->content.push_back(line); + } + delete pcr; + if (deleteOnReceive) + { + deleteMessage(id); + } + return msg; +} + +bool Pop3::deleteMessage(string id) { + Pop3CommandResponse* pcr=sendCommand(string("DELE ").append(id)); +// printf("r=%s\n",pcr->responseLine.c_str()); + if (!pcr->success) { + delete pcr; + return false; + } + delete pcr; + return true; +} + + +Pop3CommandResponse* Pop3::sendCommand(string cmd) { +// printf("send [%s]\n",cmd.c_str()); + _stream->sendLine(cmd); + string r=_stream->readLine(); + return new Pop3CommandResponse(r); +} + +Pop3CommandResponse* Pop3::sendCommandMultiResponse(string cmd) { + // first, send command +// printf("send [%s]\n",cmd.c_str()); + _stream->sendLine(cmd); + // read first response line -> contains status + string r=_stream->readLine(); +// printf("response=[%s]\n",r.c_str()); + // create response object to collect remaining lines + Pop3CommandResponse *pcr=new Pop3CommandResponse(r); + if (!pcr->success) + return pcr; + // read other lines, stop when marker reached + while (true) { + r=_stream->readLine(); + if (pcr->addLine(r)) + break; + } + return pcr; +} + +bool Pop3::init() { + if (!_stream->open()) + return NULL; + + // read server banner + string banner=_stream->readLine(); +// printf("banner=[%s]\n",banner.c_str()); + + Pop3CommandResponse pcr(banner); + if (!pcr.success) + return false; + + // send username + string cmd=string("user ").append(_username); + Pop3CommandResponse *response=sendCommand(cmd); + + if (!response->success) { + delete response; + return false; + } + + delete response; + + // send password + cmd=string("pass ").append(_password); + response=sendCommand(cmd); + + if (!response->success) { + delete response; + return false; + } + + delete response; + + return true; +} + +void Pop3::close() { + if (_closed) + return; + + Pop3CommandResponse *pcr=sendCommand("QUIT"); +// printf("r=%s\n",pcr->responseLine.c_str()); + delete pcr; + + if (NULL!=_stream) { + _stream->close(); + delete _stream; + _stream=NULL; + } + + _closed=true; +} + +Pop3CommandResponse::Pop3CommandResponse(string line) { + if (0==line.find("+OK")) { + success=true; + responseLine=line.substr(4); + } else if (0==line.find("-ERR")) { + success=false; + responseLine=line.substr(5); + } else { + success=false; + } + +} + +bool Pop3CommandResponse::addLine(string line) { + // last line is single dot only + if (line.length()==1 && line.at(0)=='.') + return true; + // remove leading dot if any + if (line.length()>0 && line.at(0)=='.') + line=line.substr(1); + responseLines.push_back(line); + return false; } \ No newline at end of file