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

Dependents:   mmain pop3demo

Committer:
hlipka
Date:
Sat Jan 29 23:27:26 2011 +0000
Revision:
2:3893c1aaee8d
Parent:
1:f2b05d1c91be
Child:
3:37570217ae90
changed to use the TcpLineStream library - makes it simples and faster

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hlipka 1:f2b05d1c91be 1 #include "Timer.h"
hlipka 1:f2b05d1c91be 2
hlipka 1:f2b05d1c91be 3 #include "pop3.h"
hlipka 0:ec8a3cef200d 4 #include "dnsresolve.h"
hlipka 0:ec8a3cef200d 5
hlipka 1:f2b05d1c91be 6 using namespace mbed;
hlipka 1:f2b05d1c91be 7
hlipka 0:ec8a3cef200d 8 class Pop3CommandResponse
hlipka 0:ec8a3cef200d 9 {
hlipka 0:ec8a3cef200d 10 public:
hlipka 0:ec8a3cef200d 11 Pop3CommandResponse(string line);
hlipka 0:ec8a3cef200d 12 bool addLine(string line);
hlipka 0:ec8a3cef200d 13
hlipka 0:ec8a3cef200d 14 bool success;
hlipka 0:ec8a3cef200d 15 string responseLine;
hlipka 0:ec8a3cef200d 16 list<string> responseLines;
hlipka 0:ec8a3cef200d 17 };
hlipka 0:ec8a3cef200d 18
hlipka 0:ec8a3cef200d 19 Pop3::Pop3(const char* servername, const char* username, const char* password) {
hlipka 0:ec8a3cef200d 20 _username=username;
hlipka 0:ec8a3cef200d 21 _password=password;
hlipka 0:ec8a3cef200d 22 _servername=servername;
hlipka 2:3893c1aaee8d 23
hlipka 0:ec8a3cef200d 24 _closed=false;
hlipka 0:ec8a3cef200d 25
hlipka 2:3893c1aaee8d 26 _stream=new TCPLineStream(servername,110,"\r\n");
hlipka 2:3893c1aaee8d 27
hlipka 0:ec8a3cef200d 28 }
hlipka 0:ec8a3cef200d 29
hlipka 0:ec8a3cef200d 30 Pop3::~Pop3() {
hlipka 0:ec8a3cef200d 31 close();
hlipka 0:ec8a3cef200d 32 }
hlipka 0:ec8a3cef200d 33
hlipka 0:ec8a3cef200d 34 list<string> *Pop3::getMessages() {
hlipka 0:ec8a3cef200d 35 Pop3CommandResponse* pcr=sendCommandMultiResponse("LIST");
hlipka 0:ec8a3cef200d 36 if (!pcr->success) {
hlipka 0:ec8a3cef200d 37 delete pcr;
hlipka 0:ec8a3cef200d 38 return NULL;
hlipka 0:ec8a3cef200d 39 }
hlipka 0:ec8a3cef200d 40 list<string> *ids=new list<string>();
hlipka 0:ec8a3cef200d 41 list<string> lines=pcr->responseLines;
hlipka 0:ec8a3cef200d 42 list<string>::iterator it;
hlipka 0:ec8a3cef200d 43 for ( it=lines.begin() ; it != lines.end(); it++ ) {
hlipka 0:ec8a3cef200d 44 string line=*it;
hlipka 0:ec8a3cef200d 45 string id=line.substr(0,line.find(' '));
hlipka 0:ec8a3cef200d 46 ids->push_back(id);
hlipka 0:ec8a3cef200d 47 }
hlipka 0:ec8a3cef200d 48 delete pcr;
hlipka 0:ec8a3cef200d 49 return ids;
hlipka 0:ec8a3cef200d 50 }
hlipka 0:ec8a3cef200d 51
hlipka 0:ec8a3cef200d 52 Pop3Message* Pop3::getMessage(string id, bool getSig, bool deleteOnReceive) {
hlipka 0:ec8a3cef200d 53 Pop3CommandResponse* pcr=sendCommandMultiResponse(string("RETR ").append(id));
hlipka 0:ec8a3cef200d 54 if (!pcr->success) {
hlipka 0:ec8a3cef200d 55 delete pcr;
hlipka 0:ec8a3cef200d 56 return NULL;
hlipka 0:ec8a3cef200d 57 }
hlipka 0:ec8a3cef200d 58 Pop3Message *msg=new Pop3Message();
hlipka 0:ec8a3cef200d 59 list<string> lines=pcr->responseLines;
hlipka 0:ec8a3cef200d 60 list<string>::iterator it;
hlipka 0:ec8a3cef200d 61 for ( it=lines.begin() ; it != lines.end(); it++ ) {
hlipka 0:ec8a3cef200d 62 string line=*it;
hlipka 0:ec8a3cef200d 63 if (0==line.find("From: ")) {
hlipka 0:ec8a3cef200d 64 msg->from=line.substr(6);
hlipka 0:ec8a3cef200d 65 } else if (0==line.find("Subject: ")) {
hlipka 0:ec8a3cef200d 66 msg->subject=line.substr(9);
hlipka 0:ec8a3cef200d 67 } else if (0==line.length()) {
hlipka 0:ec8a3cef200d 68 break;
hlipka 0:ec8a3cef200d 69 }
hlipka 0:ec8a3cef200d 70 }
hlipka 0:ec8a3cef200d 71 for (/* use iterator from above - it start right at the content */ ; it != lines.end(); it++ ) {
hlipka 0:ec8a3cef200d 72 string line=*it;
hlipka 0:ec8a3cef200d 73 if (!getSig && 0==line.compare("-- "))
hlipka 0:ec8a3cef200d 74 break;
hlipka 0:ec8a3cef200d 75 msg->content.push_back(line);
hlipka 0:ec8a3cef200d 76 }
hlipka 0:ec8a3cef200d 77 delete pcr;
hlipka 0:ec8a3cef200d 78 if (deleteOnReceive)
hlipka 0:ec8a3cef200d 79 {
hlipka 1:f2b05d1c91be 80 deleteMessage(id);
hlipka 0:ec8a3cef200d 81 }
hlipka 0:ec8a3cef200d 82 return msg;
hlipka 0:ec8a3cef200d 83 }
hlipka 0:ec8a3cef200d 84
hlipka 0:ec8a3cef200d 85 bool Pop3::deleteMessage(string id) {
hlipka 0:ec8a3cef200d 86 Pop3CommandResponse* pcr=sendCommandMultiResponse(string("DELE ").append(id));
hlipka 0:ec8a3cef200d 87 if (!pcr->success) {
hlipka 0:ec8a3cef200d 88 delete pcr;
hlipka 0:ec8a3cef200d 89 return false;
hlipka 0:ec8a3cef200d 90 }
hlipka 0:ec8a3cef200d 91 delete pcr;
hlipka 0:ec8a3cef200d 92 return true;
hlipka 0:ec8a3cef200d 93 }
hlipka 0:ec8a3cef200d 94
hlipka 0:ec8a3cef200d 95
hlipka 0:ec8a3cef200d 96 Pop3CommandResponse* Pop3::sendCommand(string cmd) {
hlipka 0:ec8a3cef200d 97 // printf("send [%s]\n",cmd.c_str());
hlipka 2:3893c1aaee8d 98 _stream->sendLine(cmd);
hlipka 2:3893c1aaee8d 99 string r=_stream->readLine();
hlipka 0:ec8a3cef200d 100 return new Pop3CommandResponse(r);
hlipka 0:ec8a3cef200d 101 }
hlipka 0:ec8a3cef200d 102
hlipka 0:ec8a3cef200d 103 Pop3CommandResponse* Pop3::sendCommandMultiResponse(string cmd) {
hlipka 0:ec8a3cef200d 104 // first, send command
hlipka 0:ec8a3cef200d 105 // printf("send [%s]\n",cmd.c_str());
hlipka 2:3893c1aaee8d 106 _stream->sendLine(cmd);
hlipka 0:ec8a3cef200d 107 // read first response line -> contains status
hlipka 2:3893c1aaee8d 108 string r=_stream->readLine();
hlipka 0:ec8a3cef200d 109 // printf("response=[%s]\n",r.c_str());
hlipka 0:ec8a3cef200d 110 // create response object to collect remaining lines
hlipka 0:ec8a3cef200d 111 Pop3CommandResponse *pcr=new Pop3CommandResponse(r);
hlipka 0:ec8a3cef200d 112 if (!pcr->success)
hlipka 0:ec8a3cef200d 113 return pcr;
hlipka 0:ec8a3cef200d 114 // read other lines, stop when marker reached
hlipka 0:ec8a3cef200d 115 while (true) {
hlipka 2:3893c1aaee8d 116 r=_stream->readLine();
hlipka 0:ec8a3cef200d 117 if (pcr->addLine(r))
hlipka 0:ec8a3cef200d 118 break;
hlipka 0:ec8a3cef200d 119 }
hlipka 0:ec8a3cef200d 120 return pcr;
hlipka 0:ec8a3cef200d 121 }
hlipka 0:ec8a3cef200d 122
hlipka 0:ec8a3cef200d 123 bool Pop3::init() {
hlipka 2:3893c1aaee8d 124 if (!_stream->open())
hlipka 2:3893c1aaee8d 125 return NULL;
hlipka 0:ec8a3cef200d 126
hlipka 0:ec8a3cef200d 127 // read server banner
hlipka 2:3893c1aaee8d 128 string banner=_stream->readLine();
hlipka 0:ec8a3cef200d 129 // printf("banner=[%s]\n",banner.c_str());
hlipka 0:ec8a3cef200d 130
hlipka 0:ec8a3cef200d 131 Pop3CommandResponse pcr(banner);
hlipka 0:ec8a3cef200d 132 if (!pcr.success)
hlipka 0:ec8a3cef200d 133 return false;
hlipka 0:ec8a3cef200d 134
hlipka 0:ec8a3cef200d 135 // send username
hlipka 0:ec8a3cef200d 136 string cmd=string("user ").append(_username);
hlipka 0:ec8a3cef200d 137 Pop3CommandResponse *response=sendCommand(cmd);
hlipka 0:ec8a3cef200d 138
hlipka 0:ec8a3cef200d 139 if (!response->success) {
hlipka 0:ec8a3cef200d 140 delete response;
hlipka 0:ec8a3cef200d 141 return false;
hlipka 0:ec8a3cef200d 142 }
hlipka 0:ec8a3cef200d 143
hlipka 0:ec8a3cef200d 144 delete response;
hlipka 0:ec8a3cef200d 145
hlipka 0:ec8a3cef200d 146 // send password
hlipka 0:ec8a3cef200d 147 cmd=string("pass ").append(_password);
hlipka 0:ec8a3cef200d 148 response=sendCommand(cmd);
hlipka 0:ec8a3cef200d 149
hlipka 0:ec8a3cef200d 150 if (!response->success) {
hlipka 0:ec8a3cef200d 151 delete response;
hlipka 0:ec8a3cef200d 152 return false;
hlipka 0:ec8a3cef200d 153 }
hlipka 0:ec8a3cef200d 154
hlipka 0:ec8a3cef200d 155 delete response;
hlipka 0:ec8a3cef200d 156
hlipka 0:ec8a3cef200d 157 return true;
hlipka 0:ec8a3cef200d 158 }
hlipka 0:ec8a3cef200d 159
hlipka 0:ec8a3cef200d 160 void Pop3::close() {
hlipka 0:ec8a3cef200d 161 if (_closed)
hlipka 0:ec8a3cef200d 162 return;
hlipka 0:ec8a3cef200d 163
hlipka 0:ec8a3cef200d 164 Pop3CommandResponse *pcr=sendCommand("CLOSE");
hlipka 0:ec8a3cef200d 165 delete pcr;
hlipka 0:ec8a3cef200d 166
hlipka 2:3893c1aaee8d 167 if (NULL!=_stream) {
hlipka 2:3893c1aaee8d 168 _stream->close();
hlipka 2:3893c1aaee8d 169 delete _stream;
hlipka 2:3893c1aaee8d 170 _stream=NULL;
hlipka 0:ec8a3cef200d 171 }
hlipka 0:ec8a3cef200d 172
hlipka 0:ec8a3cef200d 173 _closed=true;
hlipka 0:ec8a3cef200d 174 }
hlipka 0:ec8a3cef200d 175
hlipka 0:ec8a3cef200d 176 Pop3CommandResponse::Pop3CommandResponse(string line) {
hlipka 0:ec8a3cef200d 177 if (0==line.find("+OK")) {
hlipka 0:ec8a3cef200d 178 success=true;
hlipka 0:ec8a3cef200d 179 responseLine=line.substr(4);
hlipka 0:ec8a3cef200d 180 } else if (0==line.find("-ERR")) {
hlipka 0:ec8a3cef200d 181 success=false;
hlipka 0:ec8a3cef200d 182 responseLine=line.substr(5);
hlipka 0:ec8a3cef200d 183 } else {
hlipka 0:ec8a3cef200d 184 success=false;
hlipka 0:ec8a3cef200d 185 }
hlipka 0:ec8a3cef200d 186
hlipka 0:ec8a3cef200d 187 }
hlipka 0:ec8a3cef200d 188
hlipka 0:ec8a3cef200d 189 bool Pop3CommandResponse::addLine(string line) {
hlipka 0:ec8a3cef200d 190 // last line is single dot only
hlipka 0:ec8a3cef200d 191 if (line.length()==1 && line.at(0)=='.')
hlipka 0:ec8a3cef200d 192 return true;
hlipka 0:ec8a3cef200d 193 // remove leading dot if any
hlipka 0:ec8a3cef200d 194 if (line.length()>0 && line.at(0)=='.')
hlipka 0:ec8a3cef200d 195 line=line.substr(1);
hlipka 0:ec8a3cef200d 196 responseLines.push_back(line);
hlipka 0:ec8a3cef200d 197 return false;
hlipka 0:ec8a3cef200d 198 }