aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--SConstruct2
-rw-r--r--src/net/pop3/POP3Command.cpp228
-rw-r--r--src/net/pop3/POP3Folder.cpp52
-rw-r--r--src/net/pop3/POP3Message.cpp11
-rw-r--r--src/net/pop3/POP3Store.cpp56
-rw-r--r--tests/net/pop3/POP3CommandTest.cpp223
-rw-r--r--vmime/net/pop3/POP3Command.hpp118
-rw-r--r--vmime/net/pop3/POP3Store.hpp5
8 files changed, 621 insertions, 74 deletions
diff --git a/SConstruct b/SConstruct
index 93a79d16..d295a3ab 100644
--- a/SConstruct
+++ b/SConstruct
@@ -238,6 +238,7 @@ libvmime_messaging_proto_sources = [
[
'pop3',
[
+ 'net/pop3/POP3Command.cpp', 'net/pop3/POP3Command.hpp',
'net/pop3/POP3ServiceInfos.cpp', 'net/pop3/POP3ServiceInfos.hpp',
'net/pop3/POP3Store.cpp', 'net/pop3/POP3Store.hpp',
'net/pop3/POP3SStore.cpp', 'net/pop3/POP3SStore.hpp',
@@ -394,6 +395,7 @@ libvmimetest_sources = [
'tests/security/digest/md5Test.cpp',
'tests/security/digest/sha1Test.cpp',
# =============================== Net ================================
+ 'tests/net/pop3/POP3CommandTest.cpp',
'tests/net/pop3/POP3ResponseTest.cpp',
'tests/net/pop3/POP3UtilsTest.cpp',
'tests/net/imap/IMAPTagTest.cpp',
diff --git a/src/net/pop3/POP3Command.cpp b/src/net/pop3/POP3Command.cpp
new file mode 100644
index 00000000..4aef1e08
--- /dev/null
+++ b/src/net/pop3/POP3Command.cpp
@@ -0,0 +1,228 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 3 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Linking this library statically or dynamically with other modules is making
+// a combined work based on this library. Thus, the terms and conditions of
+// the GNU General Public License cover the whole combination.
+//
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+
+#include "vmime/net/pop3/POP3Command.hpp"
+
+#include "vmime/net/socket.hpp"
+
+#include "vmime/mailbox.hpp"
+#include "vmime/utility/outputStreamAdapter.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+POP3Command::POP3Command(const string& text)
+ : m_text(text)
+{
+}
+
+
+// static
+ref <POP3Command> POP3Command::CAPA()
+{
+ return createCommand("CAPA");
+}
+
+
+// static
+ref <POP3Command> POP3Command::NOOP()
+{
+ return createCommand("NOOP");
+}
+
+
+// static
+ref <POP3Command> POP3Command::AUTH(const string& mechName)
+{
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "AUTH " << mechName;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+ref <POP3Command> POP3Command::STLS()
+{
+ return createCommand("STLS");
+}
+
+
+// static
+ref <POP3Command> POP3Command::APOP(const string& username, const string& digest)
+{
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "APOP " << username << " " << digest;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+ref <POP3Command> POP3Command::USER(const string& username)
+{
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "USER " << username;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+ref <POP3Command> POP3Command::PASS(const string& password)
+{
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "PASS " << password;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+ref <POP3Command> POP3Command::STAT()
+{
+ return createCommand("STAT");
+}
+
+
+// static
+ref <POP3Command> POP3Command::LIST()
+{
+ return createCommand("LIST");
+}
+
+
+// static
+ref <POP3Command> POP3Command::LIST(const unsigned long msg)
+{
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "LIST " << msg;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+ref <POP3Command> POP3Command::UIDL()
+{
+ return createCommand("UIDL");
+}
+
+
+// static
+ref <POP3Command> POP3Command::UIDL(const unsigned long msg)
+{
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "UIDL " << msg;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+ref <POP3Command> POP3Command::DELE(const unsigned long msg)
+{
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "DELE " << msg;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+ref <POP3Command> POP3Command::RETR(const unsigned long msg)
+{
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "RETR " << msg;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+ref <POP3Command> POP3Command::TOP(const unsigned long msg, const unsigned long lines)
+{
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "TOP " << msg << " " << lines;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+ref <POP3Command> POP3Command::RSET()
+{
+ return createCommand("RSET");
+}
+
+
+// static
+ref <POP3Command> POP3Command::QUIT()
+{
+ return createCommand("QUIT");
+}
+
+
+// static
+ref <POP3Command> POP3Command::createCommand(const std::string& text)
+{
+ return vmime::create <POP3Command>(text);
+}
+
+
+const string POP3Command::getText() const
+{
+ return m_text;
+}
+
+
+void POP3Command::writeToSocket(ref <socket> sok)
+{
+ sok->send(m_text + "\r\n");
+}
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
diff --git a/src/net/pop3/POP3Folder.cpp b/src/net/pop3/POP3Folder.cpp
index e29d1360..46152f0e 100644
--- a/src/net/pop3/POP3Folder.cpp
+++ b/src/net/pop3/POP3Folder.cpp
@@ -31,6 +31,7 @@
#include "vmime/net/pop3/POP3Store.hpp"
#include "vmime/net/pop3/POP3Message.hpp"
+#include "vmime/net/pop3/POP3Command.hpp"
#include "vmime/net/pop3/POP3Response.hpp"
#include "vmime/net/pop3/POP3Utils.hpp"
@@ -130,7 +131,7 @@ void POP3Folder::open(const int mode, bool failIfModeIsNotAvailable)
}
else if (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX")
{
- store->sendRequest("STAT");
+ store->sendRequest(POP3Command::STAT());
ref <POP3Response> response =
POP3Response::readResponse(store->m_socket, store->m_timeoutHandler);
@@ -165,7 +166,7 @@ void POP3Folder::close(const bool expunge)
if (!expunge)
{
- store->sendRequest("RSET");
+ store->sendRequest(POP3Command::RSET());
POP3Response::readResponse(store->m_socket, store->m_timeoutHandler);
}
@@ -362,10 +363,7 @@ void POP3Folder::fetchMessages(std::vector <ref <message> >& msg, const int opti
if (options & FETCH_SIZE)
{
// Send the "LIST" command
- std::ostringstream command;
- command << "LIST";
-
- store->sendRequest(command.str());
+ store->sendRequest(POP3Command::LIST());
// Get the response
ref <POP3Response> response =
@@ -405,10 +403,7 @@ void POP3Folder::fetchMessages(std::vector <ref <message> >& msg, const int opti
if (options & FETCH_UID)
{
// Send the "UIDL" command
- std::ostringstream command;
- command << "UIDL";
-
- store->sendRequest(command.str());
+ store->sendRequest(POP3Command::UIDL());
// Get the response
ref <POP3Response> response =
@@ -457,12 +452,7 @@ void POP3Folder::fetchMessage(ref <message> msg, const int options)
if (options & FETCH_SIZE)
{
// Send the "LIST" command
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- command << "LIST " << msg->getNumber();
-
- store->sendRequest(command.str());
+ store->sendRequest(POP3Command::LIST(msg->getNumber()));
// Get the response
ref <POP3Response> response =
@@ -495,12 +485,7 @@ void POP3Folder::fetchMessage(ref <message> msg, const int options)
if (options & FETCH_UID)
{
// Send the "UIDL" command
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- command << "UIDL " << msg->getNumber();
-
- store->sendRequest(command.str());
+ store->sendRequest(POP3Command::UIDL(msg->getNumber()));
// Get the response
ref <POP3Response> response =
@@ -584,12 +569,7 @@ void POP3Folder::deleteMessage(const int num)
else if (!isOpen())
throw exceptions::illegal_state("Folder not open");
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- command << "DELE " << num;
-
- store->sendRequest(command.str());
+ store->sendRequest(POP3Command::DELE(num));
ref <POP3Response> response =
POP3Response::readResponse(store->m_socket, store->m_timeoutHandler);
@@ -635,12 +615,7 @@ void POP3Folder::deleteMessages(const int from, const int to)
for (int i = from ; i <= to2 ; ++i)
{
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- command << "DELE " << i;
-
- store->sendRequest(command.str());
+ store->sendRequest(POP3Command::DELE(i));
ref <POP3Response> response =
POP3Response::readResponse(store->m_socket, store->m_timeoutHandler);
@@ -688,12 +663,7 @@ void POP3Folder::deleteMessages(const std::vector <int>& nums)
for (std::vector <int>::const_iterator
it = nums.begin() ; it != nums.end() ; ++it)
{
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- command << "DELE " << (*it);
-
- store->sendRequest(command.str());
+ store->sendRequest(POP3Command::DELE(*it));
ref <POP3Response> response =
POP3Response::readResponse(store->m_socket, store->m_timeoutHandler);
@@ -790,7 +760,7 @@ void POP3Folder::status(int& count, int& unseen)
else if (!isOpen())
throw exceptions::illegal_state("Folder not open");
- store->sendRequest("STAT");
+ store->sendRequest(POP3Command::STAT());
ref <POP3Response> response =
POP3Response::readResponse(store->m_socket, store->m_timeoutHandler);
diff --git a/src/net/pop3/POP3Message.cpp b/src/net/pop3/POP3Message.cpp
index 9ad35ea9..b7494a71 100644
--- a/src/net/pop3/POP3Message.cpp
+++ b/src/net/pop3/POP3Message.cpp
@@ -28,6 +28,7 @@
#include "vmime/net/pop3/POP3Message.hpp"
+#include "vmime/net/pop3/POP3Command.hpp"
#include "vmime/net/pop3/POP3Response.hpp"
#include "vmime/net/pop3/POP3Folder.hpp"
#include "vmime/net/pop3/POP3Store.hpp"
@@ -139,12 +140,9 @@ void POP3Message::extract(utility::outputStream& os,
throw exceptions::partial_fetch_not_supported();
// Emit the "RETR" command
- std::ostringstream oss;
- oss << "RETR " << m_num;
-
ref <POP3Store> store = folder.constCast <POP3Folder>()->m_store.acquire();
- store->sendRequest(oss.str());
+ store->sendRequest(POP3Command::RETR(m_num));
try
{
@@ -198,12 +196,9 @@ void POP3Message::fetch(ref <POP3Folder> msgFolder, const int options)
// retrieve the whole header and not fields in particular.
// Emit the "TOP" command
- std::ostringstream oss;
- oss << "TOP " << m_num << " 0";
-
ref <POP3Store> store = folder->m_store.acquire();
- store->sendRequest(oss.str());
+ store->sendRequest(POP3Command::TOP(m_num, 0));
try
{
diff --git a/src/net/pop3/POP3Store.cpp b/src/net/pop3/POP3Store.cpp
index 9f1bfe0e..0efeec5f 100644
--- a/src/net/pop3/POP3Store.cpp
+++ b/src/net/pop3/POP3Store.cpp
@@ -29,6 +29,7 @@
#include "vmime/net/pop3/POP3Store.hpp"
#include "vmime/net/pop3/POP3Folder.hpp"
+#include "vmime/net/pop3/POP3Command.hpp"
#include "vmime/net/pop3/POP3Response.hpp"
#include "vmime/exception.hpp"
@@ -172,7 +173,7 @@ void POP3Store::connect()
// eg: C: <connection to server>
// --- S: +OK MailSite POP3 Server 5.3.4.0 Ready <[email protected]>
- ref <POP3Response> response = POP3Response::readResponse(m_socket, m_timeoutHandler);
+ ref <POP3Response> response = readResponse();
if (!response->isSuccess())
{
@@ -276,8 +277,8 @@ void POP3Store::authenticate(const messageId& randomMID)
md5->update(randomMID.generate() + password);
md5->finalize();
- sendRequest("APOP " + username + " " + md5->getHexDigest());
- response = POP3Response::readResponse(m_socket, m_timeoutHandler);
+ sendRequest(POP3Command::APOP(username, md5->getHexDigest()));
+ response = readResponse();
if (response->isSuccess())
{
@@ -305,8 +306,8 @@ void POP3Store::authenticate(const messageId& randomMID)
// Ensure connection is valid (cf. note above)
try
{
- sendRequest("NOOP");
- POP3Response::readResponse(m_socket, m_timeoutHandler);
+ sendRequest(POP3Command::NOOP());
+ readResponse();
}
catch (exceptions::socket_exception&)
{
@@ -334,8 +335,8 @@ void POP3Store::authenticate(const messageId& randomMID)
//
// C: PASS couic
// S: +OK vincent's maildrop has 2 messages (320 octets)
- sendRequest("USER " + username);
- response = POP3Response::readResponse(m_socket, m_timeoutHandler);
+ sendRequest(POP3Command::USER(username));
+ response = readResponse();
if (!response->isSuccess())
{
@@ -343,8 +344,8 @@ void POP3Store::authenticate(const messageId& randomMID)
throw exceptions::authentication_error(response->getFirstLine());
}
- sendRequest("PASS " + password);
- response = POP3Response::readResponse(m_socket, m_timeoutHandler);
+ sendRequest(POP3Command::PASS(password));
+ response = readResponse();
if (!response->isSuccess())
{
@@ -445,11 +446,11 @@ void POP3Store::authenticateSASL()
saslSession->init();
- sendRequest("AUTH " + mech->getName());
+ sendRequest(POP3Command::AUTH(mech->getName()));
for (bool cont = true ; cont ; )
{
- ref <POP3Response> response = POP3Response::readResponse(m_socket, m_timeoutHandler);
+ ref <POP3Response> response = readResponse();
switch (response->getCode())
{
@@ -476,7 +477,7 @@ void POP3Store::authenticateSASL()
(challenge, challengeLen, &resp, &respLen);
// Send response
- sendRequest(saslContext->encodeB64(resp, respLen));
+ m_socket->send(saslContext->encodeB64(resp, respLen) + "\r\n");
}
catch (exceptions::sasl_exception& e)
{
@@ -493,7 +494,7 @@ void POP3Store::authenticateSASL()
}
// Cancel SASL exchange
- sendRequest("*");
+ m_socket->sendRaw("*\r\n", 3);
}
catch (...)
{
@@ -535,9 +536,9 @@ void POP3Store::startTLS()
{
try
{
- sendRequest("STLS");
+ sendRequest(POP3Command::STLS());
- ref <POP3Response> response = POP3Response::readResponse(m_socket, m_timeoutHandler);
+ ref <POP3Response> response = readResponse();
if (!response->isSuccess())
throw exceptions::command_error("STLS", response->getFirstLine());
@@ -611,7 +612,8 @@ void POP3Store::internalDisconnect()
try
{
- sendRequest("QUIT");
+ sendRequest(POP3Command::QUIT());
+ readResponse();
}
catch (exception&)
{
@@ -632,10 +634,10 @@ void POP3Store::internalDisconnect()
void POP3Store::noop()
{
- sendRequest("NOOP");
+ sendRequest(POP3Command::NOOP());
ref <POP3Response> response =
- POP3Response::readResponse(m_socket, m_timeoutHandler);
+ readResponse();
if (!response->isSuccess())
throw exceptions::command_error("NOOP", response->getFirstLine());
@@ -644,7 +646,7 @@ void POP3Store::noop()
const std::vector <string> POP3Store::getCapabilities()
{
- sendRequest("CAPA");
+ sendRequest(POP3Command::CAPA());
ref <POP3Response> response =
POP3Response::readMultilineResponse(m_socket, m_timeoutHandler);
@@ -661,12 +663,18 @@ const std::vector <string> POP3Store::getCapabilities()
}
-void POP3Store::sendRequest(const string& buffer, const bool end)
+void POP3Store::sendRequest(ref <POP3Command> cmd)
{
- if (end)
- m_socket->send(buffer + "\r\n");
- else
- m_socket->send(buffer);
+ cmd->writeToSocket(m_socket);
+}
+
+
+ref <POP3Response> POP3Store::readResponse()
+{
+ ref <POP3Response> resp =
+ readResponse();
+
+ return resp;
}
diff --git a/tests/net/pop3/POP3CommandTest.cpp b/tests/net/pop3/POP3CommandTest.cpp
new file mode 100644
index 00000000..35a3629d
--- /dev/null
+++ b/tests/net/pop3/POP3CommandTest.cpp
@@ -0,0 +1,223 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 3 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Linking this library statically or dynamically with other modules is making
+// a combined work based on this library. Thus, the terms and conditions of
+// the GNU General Public License cover the whole combination.
+//
+
+#include "tests/testUtils.hpp"
+
+#include "vmime/net/pop3/POP3Command.hpp"
+
+
+using namespace vmime::net::pop3;
+
+
+VMIME_TEST_SUITE_BEGIN(POP3CommandTest)
+
+ VMIME_TEST_LIST_BEGIN
+ VMIME_TEST(testCreateCommand)
+ VMIME_TEST(testCreateCommandParams)
+ VMIME_TEST(testCAPA)
+ VMIME_TEST(testNOOP)
+ VMIME_TEST(testAUTH)
+ VMIME_TEST(testSTLS)
+ VMIME_TEST(testAPOP)
+ VMIME_TEST(testUSER)
+ VMIME_TEST(testPASS)
+ VMIME_TEST(testSTAT)
+ VMIME_TEST(testLIST)
+ VMIME_TEST(testLISTMessage)
+ VMIME_TEST(testUIDL)
+ VMIME_TEST(testUIDLMessage)
+ VMIME_TEST(testDELE)
+ VMIME_TEST(testRETR)
+ VMIME_TEST(testTOP)
+ VMIME_TEST(testRSET)
+ VMIME_TEST(testQUIT)
+ VMIME_TEST(testWriteToSocket)
+ VMIME_TEST_LIST_END
+
+
+ void testCreateCommand()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::createCommand("MY_COMMAND");
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "MY_COMMAND", cmd->getText());
+ }
+
+ void testCreateCommandParams()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::createCommand("MY_COMMAND param1 param2");
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "MY_COMMAND param1 param2", cmd->getText());
+ }
+
+ void testCAPA()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::CAPA();
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "CAPA", cmd->getText());
+ }
+
+ void testNOOP()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::NOOP();
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "NOOP", cmd->getText());
+ }
+
+ void testAUTH()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::AUTH("saslmechanism");
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "AUTH saslmechanism", cmd->getText());
+ }
+
+ void testSTLS()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::STLS();
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "STLS", cmd->getText());
+ }
+
+ void testAPOP()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::APOP("user", "digest");
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "APOP user digest", cmd->getText());
+ }
+
+ void testUSER()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::USER("user");
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "USER user", cmd->getText());
+ }
+
+ void testPASS()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::PASS("pass");
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "PASS pass", cmd->getText());
+ }
+
+ void testSTAT()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::STAT();
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "STAT", cmd->getText());
+ }
+
+ void testLIST()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::LIST();
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "LIST", cmd->getText());
+ }
+
+ void testLISTMessage()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::LIST(42);
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "LIST 42", cmd->getText());
+ }
+
+ void testUIDL()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::UIDL();
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "UIDL", cmd->getText());
+ }
+
+ void testUIDLMessage()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::UIDL(42);
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "UIDL 42", cmd->getText());
+ }
+
+ void testDELE()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::DELE(42);
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "DELE 42", cmd->getText());
+ }
+
+ void testRETR()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::RETR(42);
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "RETR 42", cmd->getText());
+ }
+
+ void testTOP()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::TOP(42, 567);
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "TOP 42 567", cmd->getText());
+ }
+
+ void testRSET()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::RSET();
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "RSET", cmd->getText());
+ }
+
+ void testQUIT()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::QUIT();
+
+ VASSERT_NOT_NULL("Not null", cmd);
+ VASSERT_EQ("Text", "QUIT", cmd->getText());
+ }
+
+ void testWriteToSocket()
+ {
+ vmime::ref <POP3Command> cmd = POP3Command::createCommand("MY_COMMAND param1 param2");
+
+ vmime::ref <testSocket> sok = vmime::create <testSocket>();
+ cmd->writeToSocket(sok);
+
+ vmime::string response;
+ sok->localReceive(response);
+
+ VASSERT_EQ("Sent buffer", "MY_COMMAND param1 param2\r\n", response);
+ }
+
+VMIME_TEST_SUITE_END
diff --git a/vmime/net/pop3/POP3Command.hpp b/vmime/net/pop3/POP3Command.hpp
new file mode 100644
index 00000000..68731661
--- /dev/null
+++ b/vmime/net/pop3/POP3Command.hpp
@@ -0,0 +1,118 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 3 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Linking this library statically or dynamically with other modules is making
+// a combined work based on this library. Thus, the terms and conditions of
+// the GNU General Public License cover the whole combination.
+//
+
+#ifndef VMIME_NET_POP3_POP3COMMAND_HPP_INCLUDED
+#define VMIME_NET_POP3_POP3COMMAND_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+
+#include "vmime/object.hpp"
+#include "vmime/base.hpp"
+
+
+namespace vmime {
+
+
+class mailbox;
+
+
+namespace net {
+
+
+class socket;
+class timeoutHandler;
+
+
+namespace pop3 {
+
+
+/** A POP3 command that will be sent to the server.
+ */
+class VMIME_EXPORT POP3Command : public object
+{
+ friend class vmime::creator;
+
+public:
+
+ static ref <POP3Command> CAPA();
+ static ref <POP3Command> NOOP();
+ static ref <POP3Command> AUTH(const string& mechName);
+ static ref <POP3Command> STLS();
+ static ref <POP3Command> APOP(const string& username, const string& digest);
+ static ref <POP3Command> USER(const string& username);
+ static ref <POP3Command> PASS(const string& password);
+ static ref <POP3Command> STAT();
+ static ref <POP3Command> LIST();
+ static ref <POP3Command> LIST(const unsigned long msg);
+ static ref <POP3Command> UIDL();
+ static ref <POP3Command> UIDL(const unsigned long msg);
+ static ref <POP3Command> DELE(const unsigned long msg);
+ static ref <POP3Command> RETR(const unsigned long msg);
+ static ref <POP3Command> TOP(const unsigned long msg, const unsigned long lines);
+ static ref <POP3Command> RSET();
+ static ref <POP3Command> QUIT();
+
+ /** Creates a new POP3 command with the specified text.
+ *
+ * @param text command text
+ * @return a new POP3Command object
+ */
+ static ref <POP3Command> createCommand(const string& text);
+
+ /** Sends this command to the specified socket.
+ *
+ * @param sok socket to which the command will be written
+ */
+ virtual void writeToSocket(ref <socket> sok);
+
+ /** Returns the full text of the command, including command name
+ * and parameters (if any).
+ *
+ * @return command text (eg. "LIST 42")
+ */
+ virtual const string getText() const;
+
+protected:
+
+ POP3Command(const string& text);
+ POP3Command(const POP3Command&);
+
+private:
+
+ string m_text;
+};
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+#endif // VMIME_NET_POP3_POP3COMMAND_HPP_INCLUDED
diff --git a/vmime/net/pop3/POP3Store.hpp b/vmime/net/pop3/POP3Store.hpp
index 2612b407..681a295e 100644
--- a/vmime/net/pop3/POP3Store.hpp
+++ b/vmime/net/pop3/POP3Store.hpp
@@ -48,6 +48,8 @@ namespace pop3 {
class POP3Folder;
+class POP3Command;
+class POP3Response;
/** POP3 store service.
@@ -98,7 +100,8 @@ private:
const std::vector <string> getCapabilities();
- void sendRequest(const string& buffer, const bool end = true);
+ void sendRequest(ref <POP3Command> cmd);
+ ref <POP3Response> readResponse();
void internalDisconnect();