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

Dependents:   mmain pop3demo

Files at this revision

API Documentation at this revision

Comitter:
hlipka
Date:
Tue Feb 01 21:17:03 2011 +0000
Parent:
2:3893c1aaee8d
Child:
4:850d9e9884fd
Commit message:
Now using UIDL as message ID, since the normal ID is not unique (between sessions). Also, now closes the session properly.

Changed in this revision

pop3.cpp Show annotated file Show diff for this revision Revisions of this file
pop3.h Show annotated file Show diff for this revision Revisions of this file
--- 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
--- a/pop3.h	Sat Jan 29 23:27:26 2011 +0000
+++ b/pop3.h	Tue Feb 01 21:17:03 2011 +0000
@@ -15,6 +15,10 @@
 {
     public:
         /**
+            the UIDL this message has on the server
+        */
+        string id;
+        /**
             the 'From:' header        
         */
         string from;
@@ -26,6 +30,7 @@
             the actual mail content, line by line
         */
         list<string> content;
+        
 };
 
 class Pop3CommandResponse;