Small library for reading mail messages via POP3. Currently doesn\'t return all header fields, and does only plain text authorization.
pop3.cpp
- Committer:
- hlipka
- Date:
- 2011-02-18
- Revision:
- 6:3e29a3a6f3bb
- Parent:
- 5:3182b4eda69b
File content as of revision 6:3e29a3a6f3bb:
/* * POP3 library * Copyright (c) 2010 Hendrik Lipka * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #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; } 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 (1!=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() { _closed=false; _stream=new TCPLineStream(_servername,110,"\r\n"); 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"); 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; }