Small library for reading mail messages via POP3. Currently doesn\'t return all header fields, and does only plain text authorization.

Dependents:   mmain pop3demo

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