aboutsummaryrefslogtreecommitdiff
path: root/vmime-master/src/vmime/net/pop3
diff options
context:
space:
mode:
authorWojtek Kosior <wk@koszkonutek-tmp.pl.eu.org>2021-04-30 00:33:56 +0200
committerWojtek Kosior <wk@koszkonutek-tmp.pl.eu.org>2021-04-30 00:33:56 +0200
commitaa4d426b4d3527d7e166df1a05058c9a4a0f6683 (patch)
tree4ff17ce8b89a2321b9d0ed4bcfc37c447bcb6820 /vmime-master/src/vmime/net/pop3
downloadsmtps-and-pop3s-console-program-master.tar.gz
smtps-and-pop3s-console-program-master.zip
initial/final commitHEADmaster
Diffstat (limited to 'vmime-master/src/vmime/net/pop3')
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Command.cpp267
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Command.hpp123
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Connection.cpp737
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Connection.hpp132
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Folder.cpp822
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Folder.hpp179
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3FolderStatus.cpp88
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3FolderStatus.hpp75
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Message.cpp283
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Message.hpp124
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Response.cpp504
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Response.hpp194
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3SStore.cpp82
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3SStore.hpp74
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3ServiceInfos.cpp142
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3ServiceInfos.hpp91
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Store.cpp262
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Store.hpp120
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Utils.cpp135
-rw-r--r--vmime-master/src/vmime/net/pop3/POP3Utils.hpp92
-rw-r--r--vmime-master/src/vmime/net/pop3/pop3.hpp35
21 files changed, 4561 insertions, 0 deletions
diff --git a/vmime-master/src/vmime/net/pop3/POP3Command.cpp b/vmime-master/src/vmime/net/pop3/POP3Command.cpp
new file mode 100644
index 0000000..0e79888
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Command.cpp
@@ -0,0 +1,267 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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/pop3/POP3Connection.hpp"
+#include "vmime/net/pop3/POP3Store.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, const string& traceText)
+ : m_text(text),
+ m_traceText(traceText) {
+
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::CAPA() {
+
+ return createCommand("CAPA");
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::NOOP() {
+
+ return createCommand("NOOP");
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::AUTH(const string& mechName) {
+
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "AUTH " << mechName;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::AUTH(const string& mechName, const string& initialResponse) {
+
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "AUTH " << mechName << " " << initialResponse;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::STLS() {
+
+ return createCommand("STLS");
+}
+
+
+// static
+shared_ptr <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
+shared_ptr <POP3Command> POP3Command::USER(const string& username) {
+
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "USER " << username;
+
+ std::ostringstream trace;
+ trace.imbue(std::locale::classic());
+ trace << "USER {username}";
+
+ return createCommand(cmd.str(), trace.str());
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::PASS(const string& password) {
+
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "PASS " << password;
+
+ std::ostringstream trace;
+ trace.imbue(std::locale::classic());
+ trace << "PASS {password}";
+
+ return createCommand(cmd.str(), trace.str());
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::STAT() {
+
+ return createCommand("STAT");
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::LIST() {
+
+ return createCommand("LIST");
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::LIST(const unsigned long msg) {
+
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "LIST " << msg;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::UIDL() {
+
+ return createCommand("UIDL");
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::UIDL(const unsigned long msg) {
+
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "UIDL " << msg;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::DELE(const unsigned long msg) {
+
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "DELE " << msg;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::RETR(const unsigned long msg) {
+
+ std::ostringstream cmd;
+ cmd.imbue(std::locale::classic());
+ cmd << "RETR " << msg;
+
+ return createCommand(cmd.str());
+}
+
+
+// static
+shared_ptr <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
+shared_ptr <POP3Command> POP3Command::RSET() {
+
+ return createCommand("RSET");
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::QUIT() {
+
+ return createCommand("QUIT");
+}
+
+
+// static
+shared_ptr <POP3Command> POP3Command::createCommand(
+ const string& text,
+ const string& traceText
+) {
+
+ if (traceText.empty()) {
+ return shared_ptr <POP3Command>(new POP3Command(text, text));
+ } else {
+ return shared_ptr <POP3Command>(new POP3Command(text, traceText));
+ }
+}
+
+
+const string POP3Command::getText() const {
+
+ return m_text;
+}
+
+
+const string POP3Command::getTraceText() const {
+
+ return m_traceText;
+}
+
+
+void POP3Command::send(const shared_ptr <POP3Connection>& conn) {
+
+ conn->getSocket()->send(m_text + "\r\n");
+
+ if (conn->getTracer()) {
+ conn->getTracer()->traceSend(m_traceText);
+ }
+}
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
diff --git a/vmime-master/src/vmime/net/pop3/POP3Command.hpp b/vmime-master/src/vmime/net/pop3/POP3Command.hpp
new file mode 100644
index 0000000..06a61b9
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Command.hpp
@@ -0,0 +1,123 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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 {
+namespace pop3 {
+
+
+class POP3Connection;
+
+
+/** A POP3 command that will be sent to the server.
+ */
+class VMIME_EXPORT POP3Command : public object {
+
+public:
+
+ static shared_ptr <POP3Command> CAPA();
+ static shared_ptr <POP3Command> NOOP();
+ static shared_ptr <POP3Command> AUTH(const string& mechName);
+ static shared_ptr <POP3Command> AUTH(const string& mechName, const string& initialResponse);
+ static shared_ptr <POP3Command> STLS();
+ static shared_ptr <POP3Command> APOP(const string& username, const string& digest);
+ static shared_ptr <POP3Command> USER(const string& username);
+ static shared_ptr <POP3Command> PASS(const string& password);
+ static shared_ptr <POP3Command> STAT();
+ static shared_ptr <POP3Command> LIST();
+ static shared_ptr <POP3Command> LIST(const unsigned long msg);
+ static shared_ptr <POP3Command> UIDL();
+ static shared_ptr <POP3Command> UIDL(const unsigned long msg);
+ static shared_ptr <POP3Command> DELE(const unsigned long msg);
+ static shared_ptr <POP3Command> RETR(const unsigned long msg);
+ static shared_ptr <POP3Command> TOP(const unsigned long msg, const unsigned long lines);
+ static shared_ptr <POP3Command> RSET();
+ static shared_ptr <POP3Command> QUIT();
+
+ /** Creates a new POP3 command with the specified text.
+ *
+ * @param text command text
+ * @param traceText trace text (if empty, command text is used)
+ * @return a new POP3Command object
+ */
+ static shared_ptr <POP3Command> createCommand(const string& text, const string& traceText = "");
+
+ /** Sends this command over the specified connection.
+ *
+ * @param conn connection onto which the command will be sent
+ */
+ virtual void send(const shared_ptr <POP3Connection>& conn);
+
+ /** 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;
+
+ /** Returns the full text of the command, suitable for outputing
+ * to the tracer.
+ *
+ * @return trace text (eg. "USER myusername")
+ */
+ virtual const string getTraceText() const;
+
+protected:
+
+ POP3Command(const string& text, const string& traceText);
+ POP3Command(const POP3Command&);
+
+private:
+
+ string m_text;
+ string m_traceText;
+};
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+#endif // VMIME_NET_POP3_POP3COMMAND_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/net/pop3/POP3Connection.cpp b/vmime-master/src/vmime/net/pop3/POP3Connection.cpp
new file mode 100644
index 0000000..749f7ef
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Connection.cpp
@@ -0,0 +1,737 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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/POP3Connection.hpp"
+#include "vmime/net/pop3/POP3Store.hpp"
+
+#include "vmime/exception.hpp"
+#include "vmime/platform.hpp"
+
+#include "vmime/security/digest/messageDigestFactory.hpp"
+
+#include "vmime/net/defaultConnectionInfos.hpp"
+
+#if VMIME_HAVE_SASL_SUPPORT
+ #include "vmime/security/sasl/SASLContext.hpp"
+#endif // VMIME_HAVE_SASL_SUPPORT
+
+#if VMIME_HAVE_TLS_SUPPORT
+ #include "vmime/net/tls/TLSSession.hpp"
+ #include "vmime/net/tls/TLSSecuredConnectionInfos.hpp"
+#endif // VMIME_HAVE_TLS_SUPPORT
+
+
+
+// Helpers for service properties
+#define GET_PROPERTY(type, prop) \
+ (m_store.lock()->getInfos().getPropertyValue <type>(getSession(), \
+ dynamic_cast <const POP3ServiceInfos&>(m_store.lock()->getInfos()).getProperties().prop))
+#define HAS_PROPERTY(prop) \
+ (m_store.lock()->getInfos().hasProperty(getSession(), \
+ dynamic_cast <const POP3ServiceInfos&>(m_store.lock()->getInfos()).getProperties().prop))
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+
+POP3Connection::POP3Connection(
+ const shared_ptr <POP3Store>& store,
+ const shared_ptr <security::authenticator>& auth
+)
+ : m_store(store),
+ m_auth(auth),
+ m_socket(null),
+ m_timeoutHandler(null),
+ m_authenticated(false),
+ m_secured(false),
+ m_capabilitiesFetched(false) {
+
+ static int connectionId = 0;
+
+ if (store->getTracerFactory()) {
+ m_tracer = store->getTracerFactory()->create(store, ++connectionId);
+ }
+}
+
+
+POP3Connection::~POP3Connection() {
+
+ try {
+
+ if (isConnected()) {
+ disconnect();
+ } else if (m_socket) {
+ internalDisconnect();
+ }
+
+ } catch (...) {
+
+ // Don't throw in destructor
+ }
+}
+
+
+void POP3Connection::connect() {
+
+ if (isConnected()) {
+ throw exceptions::already_connected();
+ }
+
+ const string address = GET_PROPERTY(string, PROPERTY_SERVER_ADDRESS);
+ const port_t port = GET_PROPERTY(port_t, PROPERTY_SERVER_PORT);
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ // Create the time-out handler
+ if (store->getTimeoutHandlerFactory()) {
+ m_timeoutHandler = store->getTimeoutHandlerFactory()->create();
+ }
+
+ // Create and connect the socket
+ m_socket = store->getSocketFactory()->create(m_timeoutHandler);
+ m_socket->setTracer(m_tracer);
+
+#if VMIME_HAVE_TLS_SUPPORT
+ if (store->isPOP3S()) { // dedicated port/POP3S
+
+ shared_ptr <tls::TLSSession> tlsSession = tls::TLSSession::create
+ (store->getCertificateVerifier(),
+ store->getSession()->getTLSProperties());
+
+ shared_ptr <tls::TLSSocket> tlsSocket =
+ tlsSession->getSocket(m_socket);
+
+ m_socket = tlsSocket;
+
+ m_secured = true;
+ m_cntInfos = make_shared <tls::TLSSecuredConnectionInfos>(address, port, tlsSession, tlsSocket);
+ } else
+#endif // VMIME_HAVE_TLS_SUPPORT
+ {
+ m_cntInfos = make_shared <defaultConnectionInfos>(address, port);
+ }
+
+ m_socket->connect(address, port);
+
+ // Connection
+ //
+ // eg: C: <connection to server>
+ // --- S: +OK MailSite POP3 Server 5.3.4.0 Ready <36938848.1056800841.634@somewhere.com>
+
+ shared_ptr <POP3Response> response = POP3Response::readResponse(
+ dynamicCast <POP3Connection>(shared_from_this())
+ );
+
+ if (!response->isSuccess()) {
+
+ internalDisconnect();
+ throw exceptions::connection_greeting_error(response->getFirstLine());
+ }
+
+#if VMIME_HAVE_TLS_SUPPORT
+ // Setup secured connection, if requested
+ const bool tls = HAS_PROPERTY(PROPERTY_CONNECTION_TLS)
+ && GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS);
+ const bool tlsRequired = HAS_PROPERTY(PROPERTY_CONNECTION_TLS_REQUIRED)
+ && GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS_REQUIRED);
+
+ if (!store->isPOP3S() && tls) { // only if not POP3S
+
+ try {
+
+ startTLS();
+
+ // Non-fatal error
+ } catch (exceptions::command_error&) {
+
+ if (tlsRequired) {
+ throw;
+ } else {
+ // TLS is not required, so don't bother
+ }
+
+ // Fatal error
+ } catch (...) {
+ throw;
+ }
+ }
+#endif // VMIME_HAVE_TLS_SUPPORT
+
+ // Start authentication process
+ authenticate(messageId(response->getText()));
+}
+
+
+void POP3Connection::disconnect() {
+
+ if (!isConnected()) {
+ throw exceptions::not_connected();
+ }
+
+ internalDisconnect();
+}
+
+
+void POP3Connection::internalDisconnect() {
+
+ if (m_socket) {
+
+ if (m_socket->isConnected()) {
+
+ try {
+
+ POP3Command::QUIT()->send(dynamicCast <POP3Connection>(shared_from_this()));
+ POP3Response::readResponse(dynamicCast <POP3Connection>(shared_from_this()));
+
+ } catch (exception&) {
+
+ // Not important
+ }
+
+ m_socket->disconnect();
+ }
+
+ m_socket = null;
+ }
+
+ m_timeoutHandler = null;
+
+ m_authenticated = false;
+ m_secured = false;
+
+ m_cntInfos = null;
+}
+
+
+void POP3Connection::authenticate(const messageId& randomMID) {
+
+ getAuthenticator()->setService(m_store.lock());
+
+#if VMIME_HAVE_SASL_SUPPORT
+ // First, try SASL authentication
+ if (GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL)) {
+
+ try {
+
+ authenticateSASL();
+
+ m_authenticated = true;
+ return;
+
+ } catch (exceptions::authentication_error&) {
+
+ if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL_FALLBACK)) {
+
+ // Can't fallback on APOP/normal authentication
+ internalDisconnect();
+ throw;
+
+ } else {
+
+ // Ignore, will try APOP/normal authentication
+ }
+
+ } catch (exception&) {
+
+ internalDisconnect();
+ throw;
+ }
+ }
+#endif // VMIME_HAVE_SASL_SUPPORT
+
+ // Secured authentication with APOP (if requested and if available)
+ //
+ // eg: C: APOP vincent <digest>
+ // --- S: +OK vincent is a valid mailbox
+
+ const string username = getAuthenticator()->getUsername();
+ const string password = getAuthenticator()->getPassword();
+
+ shared_ptr <POP3Connection> conn = dynamicCast <POP3Connection>(shared_from_this());
+ shared_ptr <POP3Response> response;
+
+ if (GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP)) {
+
+ if (randomMID.getLeft().length() != 0 &&
+ randomMID.getRight().length() != 0) {
+
+ // <digest> is the result of MD5 applied to "<message-id>password"
+ shared_ptr <security::digest::messageDigest> md5 =
+ security::digest::messageDigestFactory::getInstance()->create("md5");
+
+ md5->update(randomMID.generate() + password);
+ md5->finalize();
+
+ POP3Command::APOP(username, md5->getHexDigest())->send(conn);
+ response = POP3Response::readResponse(conn);
+
+ if (response->isSuccess()) {
+
+ m_authenticated = true;
+ return;
+
+ } else {
+
+ // Some servers close the connection after an unsuccessful APOP
+ // command, so the fallback may not always work...
+ //
+ // S: +OK Qpopper (version 4.0.5) at xxx starting. <30396.1126730747@xxx>
+ // C: APOP plop c5e0a87d088ec71d60e32692d4c5bdf4
+ // S: -ERR [AUTH] Password supplied for "plop" is incorrect.
+ // S: +OK Pop server at xxx signing off.
+ // [Connection closed by foreign host.]
+
+ if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP_FALLBACK)) {
+
+ // Can't fallback on basic authentication
+ internalDisconnect();
+ throw exceptions::authentication_error(response->getFirstLine());
+ }
+
+ // Ensure connection is valid (cf. note above)
+ try {
+
+ POP3Command::NOOP()->send(conn);
+ POP3Response::readResponse(conn);
+
+ } catch (exceptions::socket_exception&) {
+
+ internalDisconnect();
+ throw exceptions::authentication_error(response->getFirstLine());
+ }
+ }
+
+ } else {
+
+ // APOP not supported
+ if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP_FALLBACK)) {
+
+ // Can't fallback on basic authentication
+ internalDisconnect();
+ throw exceptions::authentication_error("APOP not supported");
+ }
+ }
+ }
+
+ // Basic authentication
+ //
+ // eg: C: USER vincent
+ // --- S: +OK vincent is a valid mailbox
+ //
+ // C: PASS couic
+ // S: +OK vincent's maildrop has 2 messages (320 octets)
+ POP3Command::USER(username)->send(conn);
+ response = POP3Response::readResponse(conn);
+
+ if (!response->isSuccess()) {
+
+ internalDisconnect();
+ throw exceptions::authentication_error(response->getFirstLine());
+ }
+
+ POP3Command::PASS(password)->send(conn);
+ response = POP3Response::readResponse(conn);
+
+ if (!response->isSuccess()) {
+
+ internalDisconnect();
+ throw exceptions::authentication_error(response->getFirstLine());
+ }
+
+ m_authenticated = true;
+}
+
+
+#if VMIME_HAVE_SASL_SUPPORT
+
+void POP3Connection::authenticateSASL() {
+
+ if (!dynamicCast <security::sasl::SASLAuthenticator>(getAuthenticator())) {
+ throw exceptions::authentication_error("No SASL authenticator available.");
+ }
+
+ std::vector <string> capa = getCapabilities();
+ std::vector <string> saslMechs;
+
+ for (unsigned int i = 0 ; i < capa.size() ; ++i) {
+
+ const string& x = capa[i];
+
+ // C: CAPA
+ // S: +OK List of capabilities follows
+ // S: LOGIN-DELAY 0
+ // S: PIPELINING
+ // S: UIDL
+ // S: ...
+ // S: SASL DIGEST-MD5 CRAM-MD5 <-----
+ // S: EXPIRE NEVER
+ // S: ...
+
+ if (x.length() > 5 &&
+ (x[0] == 'S' || x[0] == 's') &&
+ (x[1] == 'A' || x[1] == 'a') &&
+ (x[2] == 'S' || x[2] == 's') &&
+ (x[3] == 'L' || x[3] == 'l') &&
+ (x[4] == ' ' || x[4] == '\t')) {
+
+ const string list(x.begin() + 5, x.end());
+
+ std::istringstream iss(list);
+ iss.imbue(std::locale::classic());
+
+ string mech;
+
+ while (iss >> mech) {
+ saslMechs.push_back(mech);
+ }
+ }
+ }
+
+ if (saslMechs.empty()) {
+ throw exceptions::authentication_error("No SASL mechanism available.");
+ }
+
+ std::vector <shared_ptr <security::sasl::SASLMechanism> > mechList;
+
+ shared_ptr <security::sasl::SASLContext> saslContext =
+ security::sasl::SASLContext::create();
+
+ for (unsigned int i = 0 ; i < saslMechs.size() ; ++i) {
+
+ try {
+ mechList.push_back(saslContext->createMechanism(saslMechs[i]));
+ } catch (exceptions::no_such_mechanism&) {
+ // Ignore mechanism
+ }
+ }
+
+ if (mechList.empty()) {
+ throw exceptions::authentication_error("No SASL mechanism available.");
+ }
+
+ // Try to suggest a mechanism among all those supported
+ shared_ptr <security::sasl::SASLMechanism> suggestedMech =
+ saslContext->suggestMechanism(mechList);
+
+ if (!suggestedMech) {
+ throw exceptions::authentication_error("Unable to suggest SASL mechanism.");
+ }
+
+ // Allow application to choose which mechanisms to use
+ mechList = dynamicCast <security::sasl::SASLAuthenticator>(getAuthenticator())->
+ getAcceptableMechanisms(mechList, suggestedMech);
+
+ if (mechList.empty()) {
+ throw exceptions::authentication_error("No SASL mechanism available.");
+ }
+
+ // Try each mechanism in the list in turn
+ for (unsigned int i = 0 ; i < mechList.size() ; ++i) {
+
+ shared_ptr <security::sasl::SASLMechanism> mech = mechList[i];
+
+ shared_ptr <security::sasl::SASLSession> saslSession =
+ saslContext->createSession("pop3", getAuthenticator(), mech);
+
+ saslSession->init();
+
+ shared_ptr <POP3Command> authCmd;
+
+ if (saslSession->getMechanism()->hasInitialResponse()) {
+
+ byte_t* initialResp = 0;
+ size_t initialRespLen = 0;
+
+ saslSession->evaluateChallenge(NULL, 0, &initialResp, &initialRespLen);
+
+ string encodedInitialResp(saslContext->encodeB64(initialResp, initialRespLen));
+ delete [] initialResp;
+
+ if (encodedInitialResp.empty()) {
+ authCmd = POP3Command::AUTH(mech->getName(), "=");
+ } else {
+ authCmd = POP3Command::AUTH(mech->getName(), encodedInitialResp);
+ }
+
+ } else {
+
+ authCmd = POP3Command::AUTH(mech->getName());
+ }
+
+ authCmd->send(dynamicCast <POP3Connection>(shared_from_this()));
+
+ for (bool cont = true ; cont ; ) {
+
+ shared_ptr <POP3Response> response =
+ POP3Response::readResponse(dynamicCast <POP3Connection>(shared_from_this()));
+
+ switch (response->getCode()) {
+
+ case POP3Response::CODE_OK: {
+
+ m_socket = saslSession->getSecuredSocket(m_socket);
+ return;
+ }
+
+ case POP3Response::CODE_READY: {
+
+ byte_t* challenge = 0;
+ size_t challengeLen = 0;
+
+ byte_t* resp = 0;
+ size_t respLen = 0;
+
+ try {
+
+ // Extract challenge
+ saslContext->decodeB64(response->getText(), &challenge, &challengeLen);
+
+ // Prepare response
+ saslSession->evaluateChallenge(challenge, challengeLen, &resp, &respLen);
+
+ // Send response
+ const string respB64 = saslContext->encodeB64(resp, respLen) + "\r\n";
+ m_socket->sendRaw(utility::stringUtils::bytesFromString(respB64), respB64.length());
+
+ if (m_tracer) {
+ m_tracer->traceSendBytes(respB64.length() - 2, "SASL exchange");
+ }
+
+ } catch (exceptions::sasl_exception& e) {
+
+ if (challenge) {
+ delete [] challenge;
+ challenge = NULL;
+ }
+
+ if (resp) {
+ delete [] resp;
+ resp = NULL;
+ }
+
+ // Cancel SASL exchange
+ m_socket->send("*\r\n");
+
+ if (m_tracer) {
+ m_tracer->traceSend("*");
+ }
+
+ } catch (...) {
+
+ if (challenge) {
+ delete [] challenge;
+ }
+
+ if (resp) {
+ delete [] resp;
+ }
+
+ throw;
+ }
+
+ if (challenge) {
+ delete [] challenge;
+ }
+
+ if (resp) {
+ delete [] resp;
+ }
+
+ break;
+ }
+
+ default:
+
+ cont = false;
+ break;
+ }
+ }
+ }
+
+ throw exceptions::authentication_error("Could not authenticate using SASL: all mechanisms failed.");
+}
+
+#endif // VMIME_HAVE_SASL_SUPPORT
+
+
+#if VMIME_HAVE_TLS_SUPPORT
+
+void POP3Connection::startTLS() {
+
+ try {
+
+ POP3Command::STLS()->send(dynamicCast <POP3Connection>(shared_from_this()));
+
+ shared_ptr <POP3Response> response =
+ POP3Response::readResponse(dynamicCast <POP3Connection>(shared_from_this()));
+
+ if (!response->isSuccess()) {
+ throw exceptions::command_error("STLS", response->getFirstLine());
+ }
+
+ shared_ptr <tls::TLSSession> tlsSession = tls::TLSSession::create(
+ m_store.lock()->getCertificateVerifier(),
+ m_store.lock()->getSession()->getTLSProperties()
+ );
+
+ shared_ptr <tls::TLSSocket> tlsSocket = tlsSession->getSocket(m_socket);
+
+ tlsSocket->handshake();
+
+ m_socket = tlsSocket;
+
+ m_secured = true;
+ m_cntInfos = make_shared <tls::TLSSecuredConnectionInfos>(
+ m_cntInfos->getHost(), m_cntInfos->getPort(), tlsSession, tlsSocket
+ );
+
+ // " Once TLS has been started, the client MUST discard cached
+ // information about server capabilities and SHOULD re-issue
+ // the CAPA command. This is necessary to protect against
+ // man-in-the-middle attacks which alter the capabilities list
+ // prior to STLS. " (RFC-2595)
+ invalidateCapabilities();
+
+ } catch (exceptions::command_error&) {
+
+ // Non-fatal error
+ throw;
+
+ } catch (exception&) {
+
+ // Fatal error
+ internalDisconnect();
+ throw;
+ }
+}
+
+#endif // VMIME_HAVE_TLS_SUPPORT
+
+
+const std::vector <string> POP3Connection::getCapabilities() {
+
+ if (!m_capabilitiesFetched) {
+ fetchCapabilities();
+ }
+
+ return m_capabilities;
+}
+
+
+void POP3Connection::invalidateCapabilities() {
+
+ m_capabilities.clear();
+ m_capabilitiesFetched = false;
+}
+
+
+void POP3Connection::fetchCapabilities() {
+
+ POP3Command::CAPA()->send(dynamicCast <POP3Connection>(shared_from_this()));
+
+ shared_ptr <POP3Response> response =
+ POP3Response::readMultilineResponse(dynamicCast <POP3Connection>(shared_from_this()));
+
+ std::vector <string> res;
+
+ if (response->isSuccess()) {
+
+ for (size_t i = 0, n = response->getLineCount() ; i < n ; ++i) {
+ res.push_back(response->getLineAt(i));
+ }
+ }
+
+ m_capabilities = res;
+ m_capabilitiesFetched = true;
+}
+
+
+bool POP3Connection::isConnected() const {
+
+ return m_socket && m_socket->isConnected() && m_authenticated;
+}
+
+
+bool POP3Connection::isSecuredConnection() const {
+
+ return m_secured;
+}
+
+
+shared_ptr <connectionInfos> POP3Connection::getConnectionInfos() const {
+
+ return m_cntInfos;
+}
+
+
+shared_ptr <POP3Store> POP3Connection::getStore() {
+
+ return m_store.lock();
+}
+
+
+shared_ptr <session> POP3Connection::getSession() {
+
+ return m_store.lock()->getSession();
+}
+
+
+shared_ptr <socket> POP3Connection::getSocket() {
+
+ return m_socket;
+}
+
+
+shared_ptr <tracer> POP3Connection::getTracer() {
+
+ return m_tracer;
+}
+
+
+shared_ptr <timeoutHandler> POP3Connection::getTimeoutHandler() {
+
+ return m_timeoutHandler;
+}
+
+
+shared_ptr <security::authenticator> POP3Connection::getAuthenticator() {
+
+ return m_auth;
+}
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
diff --git a/vmime-master/src/vmime/net/pop3/POP3Connection.hpp b/vmime-master/src/vmime/net/pop3/POP3Connection.hpp
new file mode 100644
index 0000000..26b3f3c
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Connection.hpp
@@ -0,0 +1,132 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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_POP3CONNECTION_HPP_INCLUDED
+#define VMIME_NET_POP3_POP3CONNECTION_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+
+#include "vmime/messageId.hpp"
+
+#include "vmime/net/socket.hpp"
+#include "vmime/net/timeoutHandler.hpp"
+#include "vmime/net/session.hpp"
+#include "vmime/net/connectionInfos.hpp"
+#include "vmime/net/tracer.hpp"
+
+#include "vmime/net/pop3/POP3Command.hpp"
+#include "vmime/net/pop3/POP3Response.hpp"
+
+#include "vmime/security/authenticator.hpp"
+
+
+namespace vmime {
+namespace net {
+
+
+class socket;
+class timeoutHandler;
+
+
+namespace pop3 {
+
+
+class POP3Store;
+
+
+/** Manage connection to a POP3 server.
+ */
+class VMIME_EXPORT POP3Connection : public object, public enable_shared_from_this <POP3Connection> {
+
+public:
+
+ POP3Connection(
+ const shared_ptr <POP3Store>& store,
+ const shared_ptr <security::authenticator>& auth
+ );
+
+ virtual ~POP3Connection();
+
+
+ virtual void connect();
+ virtual bool isConnected() const;
+ virtual void disconnect();
+
+ bool isSecuredConnection() const;
+ shared_ptr <connectionInfos> getConnectionInfos() const;
+
+ virtual shared_ptr <POP3Store> getStore();
+ virtual shared_ptr <socket> getSocket();
+ virtual shared_ptr <timeoutHandler> getTimeoutHandler();
+ virtual shared_ptr <security::authenticator> getAuthenticator();
+ virtual shared_ptr <session> getSession();
+ virtual shared_ptr <tracer> getTracer();
+
+private:
+
+ void authenticate(const messageId& randomMID);
+#if VMIME_HAVE_SASL_SUPPORT
+ void authenticateSASL();
+#endif // VMIME_HAVE_SASL_SUPPORT
+
+#if VMIME_HAVE_TLS_SUPPORT
+ void startTLS();
+#endif // VMIME_HAVE_TLS_SUPPORT
+
+ void fetchCapabilities();
+ void invalidateCapabilities();
+ const std::vector <string> getCapabilities();
+
+ void internalDisconnect();
+
+
+ weak_ptr <POP3Store> m_store;
+
+ shared_ptr <security::authenticator> m_auth;
+ shared_ptr <socket> m_socket;
+ shared_ptr <timeoutHandler> m_timeoutHandler;
+ shared_ptr <tracer> m_tracer;
+
+ bool m_authenticated;
+ bool m_secured;
+
+ shared_ptr <connectionInfos> m_cntInfos;
+
+ std::vector <string> m_capabilities;
+ bool m_capabilitiesFetched;
+};
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+#endif // VMIME_NET_POP3_POP3CONNECTION_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/net/pop3/POP3Folder.cpp b/vmime-master/src/vmime/net/pop3/POP3Folder.cpp
new file mode 100644
index 0000000..b69a483
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Folder.cpp
@@ -0,0 +1,822 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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/POP3Folder.hpp"
+
+#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/POP3FolderStatus.hpp"
+
+#include "vmime/net/pop3/POP3Utils.hpp"
+
+#include "vmime/exception.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+POP3Folder::POP3Folder(
+ const folder::path& path,
+ const shared_ptr <POP3Store>& store
+)
+ : m_store(store),
+ m_path(path),
+ m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()),
+ m_mode(-1),
+ m_open(false) {
+
+ store->registerFolder(this);
+}
+
+
+POP3Folder::~POP3Folder() {
+
+ try {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ if (store) {
+
+ if (m_open) {
+ close(false);
+ }
+
+ store->unregisterFolder(this);
+
+ } else if (m_open) {
+
+ onClose();
+ }
+
+ } catch (...) {
+
+ // Don't throw in destructor
+ }
+}
+
+
+int POP3Folder::getMode() const {
+
+ if (!isOpen()) {
+ throw exceptions::illegal_state("Folder not open");
+ }
+
+ return m_mode;
+}
+
+
+const folderAttributes POP3Folder::getAttributes() {
+
+ folderAttributes attribs;
+
+ if (m_path.isEmpty()) {
+ attribs.setType(folderAttributes::TYPE_CONTAINS_FOLDERS);
+ } else if (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX") {
+ attribs.setType(folderAttributes::TYPE_CONTAINS_MESSAGES);
+ attribs.setSpecialUse(folderAttributes::SPECIALUSE_INBOX);
+ } else {
+ throw exceptions::folder_not_found();
+ }
+
+ attribs.setFlags(0);
+
+ return attribs;
+}
+
+
+const folder::path::component POP3Folder::getName() const {
+
+ return m_name;
+}
+
+
+const folder::path POP3Folder::getFullPath() const {
+
+ return m_path;
+}
+
+
+void POP3Folder::open(const int mode, bool failIfModeIsNotAvailable) {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store disconnected");
+ }
+
+ if (m_path.isEmpty()) {
+
+ if (mode != MODE_READ_ONLY && failIfModeIsNotAvailable) {
+ throw exceptions::operation_not_supported();
+ }
+
+ m_open = true;
+ m_mode = mode;
+
+ m_messageCount = 0;
+
+ } else if (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX") {
+
+ POP3Command::STAT()->send(store->getConnection());
+
+ shared_ptr <POP3Response> response = POP3Response::readResponse(store->getConnection());
+
+ if (!response->isSuccess()) {
+ throw exceptions::command_error("STAT", response->getFirstLine());
+ }
+
+ std::istringstream iss(response->getText());
+ iss.imbue(std::locale::classic());
+ iss >> m_messageCount;
+
+ if (iss.fail()) {
+ throw exceptions::invalid_response("STAT", response->getFirstLine());
+ }
+
+ m_open = true;
+ m_mode = mode;
+
+ } else {
+
+ throw exceptions::folder_not_found();
+ }
+}
+
+
+void POP3Folder::close(const bool expunge) {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store disconnected");
+ }
+
+ if (!isOpen()) {
+ throw exceptions::illegal_state("Folder not open");
+ }
+
+ if (!expunge) {
+ POP3Command::RSET()->send(store->getConnection());
+ POP3Response::readResponse(store->getConnection());
+ }
+
+ m_open = false;
+ m_mode = -1;
+
+ onClose();
+}
+
+
+void POP3Folder::onClose() {
+
+ for (MessageMap::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) {
+ (*it).first->onFolderClosed();
+ }
+
+ m_messages.clear();
+}
+
+
+void POP3Folder::create(const folderAttributes& /* attribs */) {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+void POP3Folder::destroy() {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+bool POP3Folder::exists() {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store disconnected");
+ }
+
+ return m_path.isEmpty() || (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX");
+}
+
+
+bool POP3Folder::isOpen() const {
+
+ return m_open;
+}
+
+
+shared_ptr <message> POP3Folder::getMessage(const size_t num) {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store disconnected");
+ } else if (!isOpen()) {
+ throw exceptions::illegal_state("Folder not open");
+ } else if (num < 1 || num > m_messageCount) {
+ throw exceptions::message_not_found();
+ }
+
+ return make_shared <POP3Message>(dynamicCast <POP3Folder>(shared_from_this()), num);
+}
+
+
+std::vector <shared_ptr <message> > POP3Folder::getMessages(const messageSet& msgs) {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store disconnected");
+ } else if (!isOpen()) {
+ throw exceptions::illegal_state("Folder not open");
+ }
+
+ if (msgs.isNumberSet()) {
+
+ const std::vector <size_t> numbers = POP3Utils::messageSetToNumberList(msgs, m_messageCount);
+
+ std::vector <shared_ptr <message> > messages;
+ shared_ptr <POP3Folder> thisFolder(dynamicCast <POP3Folder>(shared_from_this()));
+
+ for (std::vector <size_t>::const_iterator it = numbers.begin() ; it != numbers.end() ; ++it) {
+
+ if (*it < 1|| *it > m_messageCount) {
+ throw exceptions::message_not_found();
+ }
+
+ messages.push_back(make_shared <POP3Message>(thisFolder, *it));
+ }
+
+ return messages;
+
+ } else {
+
+ throw exceptions::operation_not_supported();
+ }
+}
+
+
+size_t POP3Folder::getMessageCount() {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store disconnected");
+ } else if (!isOpen()) {
+ throw exceptions::illegal_state("Folder not open");
+ }
+
+ return m_messageCount;
+}
+
+
+shared_ptr <folder> POP3Folder::getFolder(const folder::path::component& name) {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store disconnected");
+ }
+
+ return shared_ptr <POP3Folder>(new POP3Folder(m_path / name, store));
+}
+
+
+std::vector <shared_ptr <folder> > POP3Folder::getFolders(const bool /* recursive */) {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store disconnected");
+ }
+
+ if (m_path.isEmpty()) {
+
+ std::vector <shared_ptr <folder> > v;
+ v.push_back(shared_ptr <POP3Folder>(new POP3Folder(folder::path::component("INBOX"), store)));
+ return v;
+
+ } else {
+
+ std::vector <shared_ptr <folder> > v;
+ return v;
+ }
+}
+
+
+void POP3Folder::fetchMessages(
+ std::vector <shared_ptr <message> >& msg,
+ const fetchAttributes& options,
+ utility::progressListener* progress
+) {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store disconnected");
+ } else if (!isOpen()) {
+ throw exceptions::illegal_state("Folder not open");
+ }
+
+ if (msg.empty()) {
+ return;
+ }
+
+ const size_t total = msg.size();
+ size_t current = 0;
+
+ if (progress) {
+ progress->start(total);
+ }
+
+ for (std::vector <shared_ptr <message> >::iterator it = msg.begin() ;
+ it != msg.end() ; ++it) {
+
+ dynamicCast <POP3Message>(*it)->fetch(
+ dynamicCast <POP3Folder>(shared_from_this()),
+ options
+ );
+
+ if (progress) {
+ progress->progress(++current, total);
+ }
+ }
+
+ if (options.has(fetchAttributes::SIZE)) {
+
+ // Send the "LIST" command
+ POP3Command::LIST()->send(store->getConnection());
+
+ // Get the response
+ shared_ptr <POP3Response> response =
+ POP3Response::readMultilineResponse(store->getConnection());
+
+ if (response->isSuccess()) {
+
+ // C: LIST
+ // S: +OK
+ // S: 1 47548
+ // S: 2 12653
+ // S: .
+ std::map <size_t, string> result;
+ POP3Utils::parseMultiListOrUidlResponse(response, result);
+
+ for (std::vector <shared_ptr <message> >::iterator it = msg.begin() ;
+ it != msg.end() ; ++it) {
+
+ shared_ptr <POP3Message> m = dynamicCast <POP3Message>(*it);
+
+ std::map <size_t, string>::const_iterator x = result.find(m->m_num);
+
+ if (x != result.end()) {
+
+ size_t size = 0;
+
+ std::istringstream iss((*x).second);
+ iss.imbue(std::locale::classic());
+ iss >> size;
+
+ m->m_size = size;
+ }
+ }
+ }
+ }
+
+ if (options.has(fetchAttributes::UID)) {
+
+ // Send the "UIDL" command
+ POP3Command::UIDL()->send(store->getConnection());
+
+ // Get the response
+ shared_ptr <POP3Response> response =
+ POP3Response::readMultilineResponse(store->getConnection());
+
+ if (response->isSuccess()) {
+
+ // C: UIDL
+ // S: +OK
+ // S: 1 whqtswO00WBw418f9t5JxYwZ
+ // S: 2 QhdPYR:00WBw1Ph7x7
+ // S: .
+ std::map <size_t, string> result;
+ POP3Utils::parseMultiListOrUidlResponse(response, result);
+
+ for (std::vector <shared_ptr <message> >::iterator it = msg.begin() ;
+ it != msg.end() ; ++it) {
+
+ shared_ptr <POP3Message> m = dynamicCast <POP3Message>(*it);
+
+ std::map <size_t, string>::const_iterator x = result.find(m->m_num);
+
+ if (x != result.end()) {
+ m->m_uid = (*x).second;
+ }
+ }
+ }
+ }
+
+ if (progress) {
+ progress->stop(total);
+ }
+}
+
+
+void POP3Folder::fetchMessage(const shared_ptr <message>& msg, const fetchAttributes& options) {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store disconnected");
+ } else if (!isOpen()) {
+ throw exceptions::illegal_state("Folder not open");
+ }
+
+ dynamicCast <POP3Message>(msg)->fetch(
+ dynamicCast <POP3Folder>(shared_from_this()),
+ options
+ );
+
+ if (options.has(fetchAttributes::SIZE)) {
+
+ // Send the "LIST" command
+ POP3Command::LIST(msg->getNumber())->send(store->getConnection());
+
+ // Get the response
+ shared_ptr <POP3Response> response =
+ POP3Response::readResponse(store->getConnection());
+
+ if (response->isSuccess()) {
+
+ string responseText = response->getText();
+
+ // C: LIST 2
+ // S: +OK 2 4242
+ string::iterator it = responseText.begin();
+
+ while (it != responseText.end() && (*it == ' ' || *it == '\t')) ++it;
+ while (it != responseText.end() && !(*it == ' ' || *it == '\t')) ++it;
+ while (it != responseText.end() && (*it == ' ' || *it == '\t')) ++it;
+
+ if (it != responseText.end()) {
+
+ size_t size = 0;
+
+ std::istringstream iss(string(it, responseText.end()));
+ iss.imbue(std::locale::classic());
+ iss >> size;
+
+ dynamicCast <POP3Message>(msg)->m_size = size;
+ }
+ }
+ }
+
+ if (options.has(fetchAttributes::UID)) {
+
+ // Send the "UIDL" command
+ POP3Command::UIDL(msg->getNumber())->send(store->getConnection());
+
+ // Get the response
+ shared_ptr <POP3Response> response =
+ POP3Response::readResponse(store->getConnection());
+
+ if (response->isSuccess()) {
+
+ string responseText = response->getText();
+
+ // C: UIDL 2
+ // S: +OK 2 QhdPYR:00WBw1Ph7x7
+ string::iterator it = responseText.begin();
+
+ while (it != responseText.end() && (*it == ' ' || *it == '\t')) ++it;
+ while (it != responseText.end() && !(*it == ' ' || *it == '\t')) ++it;
+ while (it != responseText.end() && (*it == ' ' || *it == '\t')) ++it;
+
+ if (it != responseText.end()) {
+ dynamicCast <POP3Message>(msg)->m_uid = string(it, responseText.end());
+ }
+ }
+ }
+}
+
+
+std::vector <shared_ptr <message> > POP3Folder::getAndFetchMessages(
+ const messageSet& msgs,
+ const fetchAttributes& attribs
+) {
+
+ if (msgs.isEmpty()) {
+ return std::vector <shared_ptr <message> >();
+ }
+
+ std::vector <shared_ptr <message> > messages = getMessages(msgs);
+ fetchMessages(messages, attribs);
+
+ return messages;
+}
+
+
+int POP3Folder::getFetchCapabilities() const {
+
+ return fetchAttributes::ENVELOPE |
+ fetchAttributes::CONTENT_INFO |
+ fetchAttributes::SIZE |
+ fetchAttributes::FULL_HEADER |
+ fetchAttributes::UID |
+ fetchAttributes::IMPORTANCE;
+}
+
+
+shared_ptr <folder> POP3Folder::getParent() {
+
+ if (m_path.isEmpty()) {
+ return null;
+ } else {
+ return shared_ptr <POP3Folder>(new POP3Folder(m_path.getParent(), m_store.lock()));
+ }
+}
+
+
+shared_ptr <const store> POP3Folder::getStore() const {
+
+ return m_store.lock();
+}
+
+
+shared_ptr <store> POP3Folder::getStore() {
+
+ return m_store.lock();
+}
+
+
+void POP3Folder::registerMessage(POP3Message* msg) {
+
+ m_messages.insert(MessageMap::value_type(msg, msg->getNumber()));
+}
+
+
+void POP3Folder::unregisterMessage(POP3Message* msg) {
+
+ m_messages.erase(msg);
+}
+
+
+void POP3Folder::onStoreDisconnected() {
+
+ m_store.reset();
+}
+
+
+void POP3Folder::deleteMessages(const messageSet& msgs) {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ const std::vector <size_t> nums = POP3Utils::messageSetToNumberList(msgs, m_messageCount);
+
+ if (nums.empty()) {
+ throw exceptions::invalid_argument();
+ }
+
+ if (!store) {
+ throw exceptions::illegal_state("Store disconnected");
+ } else if (!isOpen()) {
+ throw exceptions::illegal_state("Folder not open");
+ }
+
+ for (std::vector <size_t>::const_iterator
+ it = nums.begin() ; it != nums.end() ; ++it) {
+
+ POP3Command::DELE(*it)->send(store->getConnection());
+
+ shared_ptr <POP3Response> response =
+ POP3Response::readResponse(store->getConnection());
+
+ if (!response->isSuccess()) {
+ throw exceptions::command_error("DELE", response->getFirstLine());
+ }
+ }
+
+ // Sort message list
+ std::vector <size_t> list;
+
+ list.resize(nums.size());
+ std::copy(nums.begin(), nums.end(), list.begin());
+
+ std::sort(list.begin(), list.end());
+
+ // Update local flags
+ for (std::map <POP3Message*, size_t>::iterator it =
+ m_messages.begin() ; it != m_messages.end() ; ++it) {
+
+ POP3Message* msg = (*it).first;
+
+ if (std::binary_search(list.begin(), list.end(), msg->getNumber())) {
+ msg->m_deleted = true;
+ }
+ }
+
+ // Notify message flags changed
+ shared_ptr <events::messageChangedEvent> event =
+ make_shared <events::messageChangedEvent>(
+ dynamicCast <folder>(shared_from_this()),
+ events::messageChangedEvent::TYPE_FLAGS,
+ list
+ );
+
+ notifyMessageChanged(event);
+}
+
+
+void POP3Folder::setMessageFlags(
+ const messageSet& /* msgs */,
+ const int /* flags */,
+ const int /* mode */
+) {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+void POP3Folder::rename(const folder::path& /* newPath */) {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+messageSet POP3Folder::addMessage(
+ const shared_ptr <vmime::message>& /* msg */,
+ const int /* flags */,
+ vmime::datetime* /* date */,
+ utility::progressListener* /* progress */
+) {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+messageSet POP3Folder::addMessage(
+ utility::inputStream& /* is */,
+ const size_t /* size */,
+ const int /* flags */,
+ vmime::datetime* /* date */,
+ utility::progressListener* /* progress */
+) {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+messageSet POP3Folder::copyMessages(
+ const folder::path& /* dest */,
+ const messageSet& /* msgs */
+) {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+void POP3Folder::status(size_t& count, size_t& unseen) {
+
+ count = 0;
+ unseen = 0;
+
+ shared_ptr <folderStatus> status = getStatus();
+
+ count = status->getMessageCount();
+ unseen = status->getUnseenCount();
+
+ m_messageCount = count;
+}
+
+
+shared_ptr <folderStatus> POP3Folder::getStatus() {
+
+ shared_ptr <POP3Store> store = m_store.lock();
+
+ if (!store) {
+ throw exceptions::illegal_state("Store disconnected");
+ }
+
+ POP3Command::STAT()->send(store->getConnection());
+
+ shared_ptr <POP3Response> response =
+ POP3Response::readResponse(store->getConnection());
+
+ if (!response->isSuccess()) {
+ throw exceptions::command_error("STAT", response->getFirstLine());
+ }
+
+
+ size_t count = 0;
+
+ std::istringstream iss(response->getText());
+ iss.imbue(std::locale::classic());
+ iss >> count;
+
+ shared_ptr <POP3FolderStatus> status = make_shared <POP3FolderStatus>();
+
+ status->setMessageCount(count);
+ status->setUnseenCount(count);
+
+ // Update local message count
+ if (m_messageCount != count) {
+
+ const size_t oldCount = m_messageCount;
+
+ m_messageCount = count;
+
+ if (count > oldCount) {
+
+ std::vector <size_t> nums;
+ nums.resize(count - oldCount);
+
+ for (size_t i = oldCount + 1, j = 0 ; i <= count ; ++i, ++j) {
+ nums[j] = i;
+ }
+
+ // Notify message count changed
+ shared_ptr <events::messageCountEvent> event =
+ make_shared <events::messageCountEvent>(
+ dynamicCast <folder>(shared_from_this()),
+ events::messageCountEvent::TYPE_ADDED,
+ nums
+ );
+
+ notifyMessageCount(event);
+
+ // Notify folders with the same path
+ for (std::list <POP3Folder*>::iterator it = store->m_folders.begin() ;
+ it != store->m_folders.end() ; ++it) {
+
+ if ((*it) != this && (*it)->getFullPath() == m_path) {
+
+ (*it)->m_messageCount = count;
+
+ shared_ptr <events::messageCountEvent> event =
+ make_shared <events::messageCountEvent>(
+ dynamicCast <folder>((*it)->shared_from_this()),
+ events::messageCountEvent::TYPE_ADDED,
+ nums
+ );
+
+ (*it)->notifyMessageCount(event);
+ }
+ }
+ }
+ }
+
+ return status;
+}
+
+
+void POP3Folder::expunge() {
+
+ // Not supported by POP3 protocol (deleted messages are automatically
+ // expunged at the end of the session...).
+}
+
+
+std::vector <size_t> POP3Folder::getMessageNumbersStartingOnUID(const message::uid& /* uid */) {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
diff --git a/vmime-master/src/vmime/net/pop3/POP3Folder.hpp b/vmime-master/src/vmime/net/pop3/POP3Folder.hpp
new file mode 100644
index 0000000..73e29f9
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Folder.hpp
@@ -0,0 +1,179 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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_POP3FOLDER_HPP_INCLUDED
+#define VMIME_NET_POP3_POP3FOLDER_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+
+#include <vector>
+#include <map>
+
+#include "vmime/types.hpp"
+
+#include "vmime/net/folder.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+class POP3Store;
+class POP3Message;
+
+
+/** POP3 folder implementation.
+ */
+class VMIME_EXPORT POP3Folder : public folder {
+
+private:
+
+ friend class POP3Store;
+ friend class POP3Message;
+
+ POP3Folder(const POP3Folder&);
+ POP3Folder(const folder::path& path, const shared_ptr <POP3Store>& store);
+
+public:
+
+ ~POP3Folder();
+
+ int getMode() const;
+
+ const folderAttributes getAttributes();
+
+ const folder::path::component getName() const;
+ const folder::path getFullPath() const;
+
+ void open(const int mode, bool failIfModeIsNotAvailable = false);
+ void close(const bool expunge);
+ void create(const folderAttributes& attribs);
+
+ bool exists();
+
+ void destroy();
+
+ bool isOpen() const;
+
+ shared_ptr <message> getMessage(const size_t num);
+ std::vector <shared_ptr <message> > getMessages(const messageSet& msgs);
+
+ size_t getMessageCount();
+
+ shared_ptr <folder> getFolder(const folder::path::component& name);
+ std::vector <shared_ptr <folder> > getFolders(const bool recursive = false);
+
+ void rename(const folder::path& newPath);
+
+ void deleteMessages(const messageSet& msgs);
+
+ void setMessageFlags(
+ const messageSet& msgs,
+ const int flags,
+ const int mode = message::FLAG_MODE_SET
+ );
+
+ messageSet addMessage(
+ const shared_ptr <vmime::message>& msg,
+ const int flags = -1,
+ vmime::datetime* date = NULL,
+ utility::progressListener* progress = NULL
+ );
+
+ messageSet addMessage(
+ utility::inputStream& is,
+ const size_t size,
+ const int flags = -1,
+ vmime::datetime* date = NULL,
+ utility::progressListener* progress = NULL
+ );
+
+ messageSet copyMessages(const folder::path& dest, const messageSet& msgs);
+
+ void status(size_t& count, size_t& unseen);
+ shared_ptr <folderStatus> getStatus();
+
+ void expunge();
+
+ shared_ptr <folder> getParent();
+
+ shared_ptr <const store> getStore() const;
+ shared_ptr <store> getStore();
+
+
+ void fetchMessages(
+ std::vector <shared_ptr <message> >& msg,
+ const fetchAttributes& options,
+ utility::progressListener* progress = NULL
+ );
+
+ void fetchMessage(const shared_ptr <message>& msg, const fetchAttributes& options);
+
+ std::vector <shared_ptr <message> > getAndFetchMessages(
+ const messageSet& msgs,
+ const fetchAttributes& attribs
+ );
+
+ int getFetchCapabilities() const;
+
+ std::vector <size_t> getMessageNumbersStartingOnUID(const message::uid& uid);
+
+private:
+
+ void registerMessage(POP3Message* msg);
+ void unregisterMessage(POP3Message* msg);
+
+ void onStoreDisconnected();
+
+ void onClose();
+
+
+ weak_ptr <POP3Store> m_store;
+
+ folder::path m_path;
+ folder::path::component m_name;
+
+ int m_mode;
+ bool m_open;
+
+ size_t m_messageCount;
+
+ typedef std::map <POP3Message*, size_t> MessageMap;
+ MessageMap m_messages;
+};
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+#endif // VMIME_NET_POP3_POP3FOLDER_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/net/pop3/POP3FolderStatus.cpp b/vmime-master/src/vmime/net/pop3/POP3FolderStatus.cpp
new file mode 100644
index 0000000..9f2c49f
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3FolderStatus.cpp
@@ -0,0 +1,88 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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/POP3FolderStatus.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+POP3FolderStatus::POP3FolderStatus()
+ : m_count(0),
+ m_unseen(0) {
+
+}
+
+
+POP3FolderStatus::POP3FolderStatus(const POP3FolderStatus& other)
+ : folderStatus(),
+ m_count(other.m_count),
+ m_unseen(other.m_unseen) {
+
+}
+
+
+size_t POP3FolderStatus::getMessageCount() const {
+
+ return m_count;
+}
+
+
+size_t POP3FolderStatus::getUnseenCount() const {
+
+ return m_unseen;
+}
+
+
+void POP3FolderStatus::setMessageCount(const size_t count) {
+
+ m_count = count;
+}
+
+
+void POP3FolderStatus::setUnseenCount(const size_t unseen) {
+
+ m_unseen = unseen;
+}
+
+
+shared_ptr <folderStatus> POP3FolderStatus::clone() const {
+
+ return make_shared <POP3FolderStatus>(*this);
+}
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
diff --git a/vmime-master/src/vmime/net/pop3/POP3FolderStatus.hpp b/vmime-master/src/vmime/net/pop3/POP3FolderStatus.hpp
new file mode 100644
index 0000000..0ce413e
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3FolderStatus.hpp
@@ -0,0 +1,75 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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_POP3FOLDERSTATUS_HPP_INCLUDED
+#define VMIME_NET_POP3_POP3FOLDERSTATUS_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+
+#include "vmime/net/folderStatus.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+/** Holds the status of a POP3 folder.
+ */
+class VMIME_EXPORT POP3FolderStatus : public folderStatus {
+
+public:
+
+ POP3FolderStatus();
+ POP3FolderStatus(const POP3FolderStatus& other);
+
+ // Inherited from folderStatus
+ size_t getMessageCount() const;
+ size_t getUnseenCount() const;
+
+ shared_ptr <folderStatus> clone() const;
+
+
+ void setMessageCount(const size_t count);
+ void setUnseenCount(const size_t unseen);
+
+private:
+
+ size_t m_count;
+ size_t m_unseen;
+};
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+#endif // VMIME_NET_POP3_POP3FOLDERSTATUS_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/net/pop3/POP3Message.cpp b/vmime-master/src/vmime/net/pop3/POP3Message.cpp
new file mode 100644
index 0000000..8d6b7f5
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Message.cpp
@@ -0,0 +1,283 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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/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"
+
+#include "vmime/utility/outputStreamAdapter.hpp"
+#include "vmime/utility/outputStreamStringAdapter.hpp"
+
+#include <sstream>
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+POP3Message::POP3Message(
+ const shared_ptr <POP3Folder>& folder,
+ const size_t num
+)
+ : m_folder(folder),
+ m_num(num),
+ m_size(-1),
+ m_deleted(false) {
+
+ folder->registerMessage(this);
+}
+
+
+POP3Message::~POP3Message() {
+
+ try {
+
+ shared_ptr <POP3Folder> folder = m_folder.lock();
+
+ if (folder) {
+ folder->unregisterMessage(this);
+ }
+
+ } catch (...) {
+
+ // Don't throw in destructor
+ }
+}
+
+
+void POP3Message::onFolderClosed() {
+
+ m_folder.reset();
+}
+
+
+size_t POP3Message::getNumber() const {
+
+ return m_num;
+}
+
+
+const message::uid POP3Message::getUID() const {
+
+ return m_uid;
+}
+
+
+size_t POP3Message::getSize() const {
+
+ if (m_size == static_cast <size_t>(-1)) {
+ throw exceptions::unfetched_object();
+ }
+
+ return m_size;
+}
+
+
+bool POP3Message::isExpunged() const {
+
+ return false;
+}
+
+
+int POP3Message::getFlags() const {
+
+ int flags = 0;
+
+ if (m_deleted) {
+ flags |= FLAG_DELETED;
+ }
+
+ return flags;
+}
+
+
+shared_ptr <const messageStructure> POP3Message::getStructure() const {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+shared_ptr <messageStructure> POP3Message::getStructure() {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+shared_ptr <const header> POP3Message::getHeader() const {
+
+ if (!m_header) {
+ throw exceptions::unfetched_object();
+ }
+
+ return m_header;
+}
+
+
+void POP3Message::extract(
+ utility::outputStream& os,
+ utility::progressListener* progress,
+ const size_t start,
+ const size_t length,
+ const bool /* peek */
+) const {
+
+ shared_ptr <const POP3Folder> folder = m_folder.lock();
+
+ if (!folder) {
+ throw exceptions::illegal_state("Folder closed");
+ } else if (!folder->getStore()) {
+ throw exceptions::illegal_state("Store disconnected");
+ }
+
+ if (start != 0 && length != static_cast <size_t>(-1)) {
+ throw exceptions::partial_fetch_not_supported();
+ }
+
+ // Emit the "RETR" command
+ shared_ptr <POP3Store> store = folder->m_store.lock();
+
+ POP3Command::RETR(m_num)->send(store->getConnection());
+
+ try {
+
+ POP3Response::readLargeResponse(
+ store->getConnection(), os, progress,
+ m_size == static_cast <size_t>(-1) ? 0 : m_size
+ );
+
+ } catch (exceptions::command_error& e) {
+
+ throw exceptions::command_error("RETR", e.response());
+ }
+}
+
+
+void POP3Message::extractPart(
+ const shared_ptr <const messagePart>& /* p */,
+ utility::outputStream& /* os */,
+ utility::progressListener* /* progress */,
+ const size_t /* start */,
+ const size_t /* length */,
+ const bool /* peek */
+) const {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+void POP3Message::fetchPartHeader(const shared_ptr <messagePart>& /* p */) {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+void POP3Message::fetch(
+ const shared_ptr <POP3Folder>& msgFolder,
+ const fetchAttributes& options
+) {
+
+ shared_ptr <POP3Folder> folder = m_folder.lock();
+
+ if (folder != msgFolder) {
+ throw exceptions::folder_not_found();
+ }
+
+ // STRUCTURE and FLAGS attributes are not supported by POP3
+ if (options.has(fetchAttributes::STRUCTURE | fetchAttributes::FLAGS)) {
+ throw exceptions::operation_not_supported();
+ }
+
+ // Check for the real need to fetch the full header
+ static const int optionsRequiringHeader =
+ fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO |
+ fetchAttributes::FULL_HEADER | fetchAttributes::IMPORTANCE;
+
+ if (!options.has(optionsRequiringHeader)) {
+ return;
+ }
+
+ // No need to differenciate between ENVELOPE, CONTENT_INFO, ...
+ // since POP3 only permits to retrieve the whole header and not
+ // fields in particular.
+
+ // Emit the "TOP" command
+ shared_ptr <POP3Store> store = folder->m_store.lock();
+
+ POP3Command::TOP(m_num, 0)->send(store->getConnection());
+
+ try {
+
+ string buffer;
+ utility::outputStreamStringAdapter bufferStream(buffer);
+
+ POP3Response::readLargeResponse(
+ store->getConnection(),
+ bufferStream, /* progress */ NULL, /* predictedSize */ 0
+ );
+
+ m_header = make_shared <header>();
+ m_header->parse(buffer);
+
+ } catch (exceptions::command_error& e) {
+
+ throw exceptions::command_error("TOP", e.response());
+ }
+}
+
+
+void POP3Message::setFlags(const int /* flags */, const int /* mode */) {
+
+ throw exceptions::operation_not_supported();
+}
+
+
+shared_ptr <vmime::message> POP3Message::getParsedMessage() {
+
+ std::ostringstream oss;
+ utility::outputStreamAdapter os(oss);
+
+ extract(os);
+
+ shared_ptr <vmime::message> msg = make_shared <vmime::message>();
+ msg->parse(oss.str());
+
+ return msg;
+}
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
diff --git a/vmime-master/src/vmime/net/pop3/POP3Message.hpp b/vmime-master/src/vmime/net/pop3/POP3Message.hpp
new file mode 100644
index 0000000..3d6dc92
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Message.hpp
@@ -0,0 +1,124 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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_POP3MESSAGE_HPP_INCLUDED
+#define VMIME_NET_POP3_POP3MESSAGE_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+
+#include "vmime/net/message.hpp"
+#include "vmime/net/folder.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+class POP3Folder;
+
+
+/** POP3 message implementation.
+ */
+class VMIME_EXPORT POP3Message : public message {
+
+private:
+
+ friend class POP3Folder;
+
+ POP3Message(const POP3Message&);
+
+public:
+
+ POP3Message(const shared_ptr <POP3Folder>& folder, const size_t num);
+
+ ~POP3Message();
+
+
+ size_t getNumber() const;
+
+ const uid getUID() const;
+
+ size_t getSize() const;
+
+ bool isExpunged() const;
+
+ shared_ptr <const messageStructure> getStructure() const;
+ shared_ptr <messageStructure> getStructure();
+
+ shared_ptr <const header> getHeader() const;
+
+ int getFlags() const;
+ void setFlags(const int flags, const int mode = FLAG_MODE_SET);
+
+ void extract(
+ utility::outputStream& os,
+ utility::progressListener* progress = NULL,
+ const size_t start = 0,
+ const size_t length = -1,
+ const bool peek = false
+ ) const;
+
+ void extractPart(
+ const shared_ptr <const messagePart>& p,
+ utility::outputStream& os,
+ utility::progressListener* progress = NULL,
+ const size_t start = 0,
+ const size_t length = -1,
+ const bool peek = false
+ ) const;
+
+ void fetchPartHeader(const shared_ptr <messagePart>& p);
+
+ shared_ptr <vmime::message> getParsedMessage();
+
+private:
+
+ void fetch(const shared_ptr <POP3Folder>& folder, const fetchAttributes& options);
+
+ void onFolderClosed();
+
+ weak_ptr <POP3Folder> m_folder;
+ size_t m_num;
+ uid m_uid;
+ size_t m_size;
+
+ bool m_deleted;
+
+ shared_ptr <header> m_header;
+};
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+#endif // VMIME_NET_POP3_POP3MESSAGE_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/net/pop3/POP3Response.cpp b/vmime-master/src/vmime/net/pop3/POP3Response.cpp
new file mode 100644
index 0000000..725841e
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Response.cpp
@@ -0,0 +1,504 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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/POP3Response.hpp"
+#include "vmime/net/pop3/POP3Connection.hpp"
+
+#include "vmime/platform.hpp"
+
+#include "vmime/utility/stringUtils.hpp"
+#include "vmime/utility/filteredStream.hpp"
+#include "vmime/utility/stringUtils.hpp"
+#include "vmime/utility/inputStreamSocketAdapter.hpp"
+
+#include "vmime/net/socket.hpp"
+#include "vmime/net/timeoutHandler.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+POP3Response::POP3Response(
+ const shared_ptr <socket>& sok,
+ const shared_ptr <timeoutHandler>& toh,
+ const shared_ptr <tracer>& tracer
+)
+ : m_socket(sok),
+ m_timeoutHandler(toh),
+ m_tracer(tracer) {
+
+}
+
+
+// static
+shared_ptr <POP3Response> POP3Response::readResponse(
+ const shared_ptr <POP3Connection>& conn
+) {
+
+ shared_ptr <POP3Response> resp = shared_ptr <POP3Response>(
+ new POP3Response(conn->getSocket(), conn->getTimeoutHandler(), conn->getTracer())
+ );
+
+ string buffer;
+ resp->readResponseImpl(buffer, /* multiLine */ false);
+
+ resp->m_firstLine = buffer;
+ resp->m_code = getResponseCode(buffer);
+ stripResponseCode(buffer, resp->m_text);
+
+ if (resp->m_tracer) {
+ resp->m_tracer->traceReceive(buffer);
+ }
+
+ return resp;
+}
+
+
+// static
+shared_ptr <POP3Response> POP3Response::readMultilineResponse(
+ const shared_ptr <POP3Connection>& conn
+) {
+
+ shared_ptr <POP3Response> resp = shared_ptr <POP3Response>(
+ new POP3Response(conn->getSocket(), conn->getTimeoutHandler(), conn->getTracer())
+ );
+
+ string buffer;
+ resp->readResponseImpl(buffer, /* multiLine */ true);
+
+ string firstLine, nextLines;
+ stripFirstLine(buffer, nextLines, &firstLine);
+
+ resp->m_firstLine = firstLine;
+ resp->m_code = getResponseCode(firstLine);
+ stripResponseCode(firstLine, resp->m_text);
+
+ std::istringstream iss(nextLines);
+ string line;
+
+ if (resp->m_tracer) {
+ resp->m_tracer->traceReceive(firstLine);
+ }
+
+ while (std::getline(iss, line, '\n')) {
+
+ line = utility::stringUtils::trim(line);
+ resp->m_lines.push_back(line);
+
+ if (resp->m_tracer) {
+ resp->m_tracer->traceReceive(line);
+ }
+ }
+
+ if (resp->m_tracer) {
+ resp->m_tracer->traceReceive(".");
+ }
+
+ return resp;
+}
+
+
+// static
+shared_ptr <POP3Response> POP3Response::readLargeResponse(
+ const shared_ptr <POP3Connection>& conn,
+ utility::outputStream& os,
+ utility::progressListener* progress,
+ const size_t predictedSize
+) {
+
+ shared_ptr <POP3Response> resp = shared_ptr <POP3Response>(
+ new POP3Response(conn->getSocket(), conn->getTimeoutHandler(), conn->getTracer())
+ );
+
+ string firstLine;
+ const size_t length = resp->readResponseImpl(firstLine, os, progress, predictedSize);
+
+ resp->m_firstLine = firstLine;
+ resp->m_code = getResponseCode(firstLine);
+ stripResponseCode(firstLine, resp->m_text);
+
+ if (resp->m_tracer) {
+ resp->m_tracer->traceReceive(firstLine);
+ resp->m_tracer->traceReceiveBytes(length - firstLine.length());
+ resp->m_tracer->traceReceive(".");
+ }
+
+ return resp;
+}
+
+
+bool POP3Response::isSuccess() const {
+
+ return m_code == CODE_OK;
+}
+
+
+const string POP3Response::getFirstLine() const {
+
+ return m_firstLine;
+}
+
+
+POP3Response::ResponseCode POP3Response::getCode() const {
+
+ return m_code;
+}
+
+
+const string POP3Response::getText() const {
+
+ return m_text;
+}
+
+
+const string POP3Response::getLineAt(const size_t pos) const {
+
+ return m_lines[pos];
+}
+
+
+size_t POP3Response::getLineCount() const {
+
+ return m_lines.size();
+}
+
+
+void POP3Response::readResponseImpl(string& buffer, const bool multiLine) {
+
+ bool foundTerminator = false;
+
+ if (m_timeoutHandler) {
+ m_timeoutHandler->resetTimeOut();
+ }
+
+ buffer.clear();
+
+ char last1 = '\0', last2 = '\0';
+
+ for ( ; !foundTerminator ; ) {
+
+ // Check whether the time-out delay is elapsed
+ if (m_timeoutHandler && m_timeoutHandler->isTimeOut()) {
+
+ if (!m_timeoutHandler->handleTimeOut()) {
+ throw exceptions::operation_timed_out();
+ }
+
+ m_timeoutHandler->resetTimeOut();
+ }
+
+ // Receive data from the socket
+ string receiveBuffer;
+ m_socket->receive(receiveBuffer);
+
+ if (receiveBuffer.empty()) { // buffer is empty
+
+ if (m_socket->getStatus() & socket::STATUS_WANT_WRITE) {
+ m_socket->waitForWrite();
+ } else {
+ m_socket->waitForRead();
+ }
+
+ continue;
+ }
+
+ // We have received data: reset the time-out counter
+ if (m_timeoutHandler) {
+ m_timeoutHandler->resetTimeOut();
+ }
+
+ // Check for transparent characters: '\n..' becomes '\n.'
+ const char first = receiveBuffer[0];
+
+ if (first == '.' && last2 == '\n' && last1 == '.') {
+
+ receiveBuffer.erase(receiveBuffer.begin());
+
+ } else if (receiveBuffer.length() >= 2 && first == '.' &&
+ receiveBuffer[1] == '.' && last1 == '\n') {
+
+ receiveBuffer.erase(receiveBuffer.begin());
+ }
+
+ for (size_t trans ;
+ string::npos != (trans = receiveBuffer.find("\n..")) ; ) {
+
+ receiveBuffer.replace(trans, 3, "\n.");
+ }
+
+ last1 = receiveBuffer[receiveBuffer.length() - 1];
+ last2 = static_cast <char>((receiveBuffer.length() >= 2) ? receiveBuffer[receiveBuffer.length() - 2] : 0);
+
+ // Append the data to the response buffer
+ buffer += receiveBuffer;
+
+ // Check for terminator string (and strip it if present)
+ foundTerminator = checkTerminator(buffer, multiLine);
+
+ // If there is an error (-ERR) when executing a command that
+ // requires a multi-line response, the error response will
+ // include only one line, so we stop waiting for a multi-line
+ // terminator and check for a "normal" one.
+ if (multiLine &&
+ !foundTerminator &&
+ buffer.length() >= 4 && buffer[0] == '-') {
+
+ foundTerminator = checkTerminator(buffer, false);
+ }
+ }
+}
+
+
+size_t POP3Response::readResponseImpl(
+ string& firstLine,
+ utility::outputStream& os,
+ utility::progressListener* progress,
+ const size_t predictedSize
+) {
+
+ size_t current = 0, total = predictedSize;
+
+ string temp;
+ bool codeDone = false;
+
+ if (progress) {
+ progress->start(total);
+ }
+
+ if (m_timeoutHandler) {
+ m_timeoutHandler->resetTimeOut();
+ }
+
+ utility::inputStreamSocketAdapter sis(*m_socket);
+ utility::stopSequenceFilteredInputStream <5> sfis1(sis, "\r\n.\r\n");
+ utility::stopSequenceFilteredInputStream <3> sfis2(sfis1, "\n.\n");
+ utility::dotFilteredInputStream dfis(sfis2); // "\n.." --> "\n."
+
+ utility::inputStream& is = dfis;
+
+ while (!is.eof()) {
+
+ // Check whether the time-out delay is elapsed
+ if (m_timeoutHandler && m_timeoutHandler->isTimeOut()) {
+
+ if (!m_timeoutHandler->handleTimeOut()) {
+ throw exceptions::operation_timed_out();
+ }
+ }
+
+ // Receive data from the socket
+ byte_t buffer[65536];
+ const size_t read = is.read(buffer, sizeof(buffer));
+
+ if (read == 0) { // buffer is empty
+
+ if (m_socket->getStatus() & socket::STATUS_WANT_WRITE) {
+ m_socket->waitForWrite();
+ } else if (m_socket->getStatus() & socket::STATUS_WANT_READ) {
+ m_socket->waitForRead();
+ } else {
+ // Input stream needs more bytes to continue, but there
+ // is enough data into socket buffer. Do not waitForRead(),
+ // just retry read()ing on the stream.
+ }
+
+ continue;
+ }
+
+ // We have received data: reset the time-out counter
+ if (m_timeoutHandler) {
+ m_timeoutHandler->resetTimeOut();
+ }
+
+ // Notify progress
+ current += read;
+
+ if (progress) {
+ total = std::max(total, current);
+ progress->progress(current, total);
+ }
+
+ // If we don't have extracted the response code yet
+ if (!codeDone) {
+
+ vmime::utility::stringUtils::appendBytesToString(temp, buffer, read);
+
+ string responseData;
+
+ if (stripFirstLine(temp, responseData, &firstLine) == true) {
+
+ if (getResponseCode(firstLine) != CODE_OK) {
+ throw exceptions::command_error("?", firstLine);
+ }
+
+ codeDone = true;
+
+ os.write(responseData.data(), responseData.length());
+ temp.clear();
+
+ continue;
+ }
+
+ } else {
+
+ // Inject the data into the output stream
+ os.write(buffer, read);
+ }
+ }
+
+ if (progress) {
+ progress->stop(total);
+ }
+
+ return current;
+}
+
+
+// static
+bool POP3Response::stripFirstLine(
+ const string& buffer,
+ string& result,
+ string* firstLine
+) {
+
+ const size_t end = buffer.find('\n');
+
+ if (end != string::npos) {
+
+ if (firstLine) {
+ *firstLine = utility::stringUtils::trim(buffer.substr(0, end));
+ }
+
+ result = buffer.substr(end + 1);
+
+ return true;
+
+ } else {
+
+ if (firstLine) {
+ *firstLine = utility::stringUtils::trim(buffer);
+ }
+
+ result = "";
+
+ return false;
+ }
+}
+
+
+// static
+POP3Response::ResponseCode POP3Response::getResponseCode(const string& buffer) {
+
+ if (buffer.length() >= 2) {
+
+ // +[space]
+ if (buffer[0] == '+' &&
+ (buffer[1] == ' ' || buffer[1] == '\t')) {
+
+ return CODE_READY;
+ }
+
+ // +OK
+ if (buffer.length() >= 3) {
+
+ if (buffer[0] == '+' &&
+ (buffer[1] == 'O' || buffer[1] == 'o') &&
+ (buffer[2] == 'K' || buffer[1] == 'k')) {
+
+ return CODE_OK;
+ }
+ }
+ }
+
+ // -ERR or whatever
+ return CODE_ERR;
+}
+
+
+// static
+void POP3Response::stripResponseCode(const string& buffer, string& result) {
+
+ const size_t pos = buffer.find_first_of(" \t");
+
+ if (pos != string::npos) {
+ result = buffer.substr(pos + 1);
+ } else {
+ result = buffer;
+ }
+}
+
+
+// static
+bool POP3Response::checkTerminator(string& buffer, const bool multiLine) {
+
+ // Multi-line response
+ if (multiLine) {
+
+ static const string term1("\r\n.\r\n");
+ static const string term2("\n.\n");
+
+ return checkOneTerminator(buffer, term1) ||
+ checkOneTerminator(buffer, term2);
+
+ // Normal response
+ } else {
+
+ static const string term1("\r\n");
+ static const string term2("\n");
+
+ return checkOneTerminator(buffer, term1) ||
+ checkOneTerminator(buffer, term2);
+ }
+
+ return false;
+}
+
+
+// static
+bool POP3Response::checkOneTerminator(string& buffer, const string& term) {
+
+ if (buffer.length() >= term.length() &&
+ std::equal(buffer.end() - term.length(), buffer.end(), term.begin())) {
+
+ buffer.erase(buffer.end() - term.length(), buffer.end());
+ return true;
+ }
+
+ return false;
+}
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
diff --git a/vmime-master/src/vmime/net/pop3/POP3Response.hpp b/vmime-master/src/vmime/net/pop3/POP3Response.hpp
new file mode 100644
index 0000000..69f8d5d
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Response.hpp
@@ -0,0 +1,194 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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_SMTP_POP3RESPONSE_HPP_INCLUDED
+#define VMIME_NET_SMTP_POP3RESPONSE_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+
+#include "vmime/object.hpp"
+#include "vmime/base.hpp"
+
+#include "vmime/utility/outputStream.hpp"
+#include "vmime/utility/progressListener.hpp"
+
+#include "vmime/net/socket.hpp"
+#include "vmime/net/tracer.hpp"
+
+
+namespace vmime {
+namespace net {
+
+
+class timeoutHandler;
+
+
+namespace pop3 {
+
+
+class POP3Connection;
+
+
+/** A POP3 response, as sent by the server.
+ */
+class VMIME_EXPORT POP3Response : public object {
+
+public:
+
+ /** Possible response codes. */
+ enum ResponseCode {
+ CODE_OK = 0,
+ CODE_READY,
+ CODE_ERR
+ };
+
+
+ /** Receive and parse a POP3 response from the
+ * specified connection.
+ *
+ * @param conn connection from which to read
+ * @return POP3 response
+ * @throws exceptions::operation_timed_out if no data
+ * has been received within the granted time
+ */
+ static shared_ptr <POP3Response> readResponse(const shared_ptr <POP3Connection>& conn);
+
+ /** Receive and parse a multiline POP3 response from
+ * the specified connection.
+ *
+ * @param conn connection from which to read
+ * @return POP3 response
+ * @throws exceptions::operation_timed_out if no data
+ * has been received within the granted time
+ */
+ static shared_ptr <POP3Response> readMultilineResponse(const shared_ptr <POP3Connection>& conn);
+
+ /** Receive and parse a large POP3 response (eg. message data)
+ * from the specified connection.
+ *
+ * @param conn connection from which to read
+ * @param os output stream to which response data will be written
+ * @param progress progress listener (can be NULL)
+ * @param predictedSize estimated size of response data (in bytes)
+ * @return POP3 response
+ * @throws exceptions::operation_timed_out if no data
+ * has been received within the granted time
+ */
+ static shared_ptr <POP3Response> readLargeResponse(
+ const shared_ptr <POP3Connection>& conn,
+ utility::outputStream& os,
+ utility::progressListener* progress,
+ const size_t predictedSize
+ );
+
+
+ /** Returns whether the response is successful ("OK").
+ *
+ * @return true if the response if successful, false otherwise
+ */
+ bool isSuccess() const;
+
+ /** Return the POP3 response code.
+ *
+ * @return response code
+ */
+ ResponseCode getCode() const;
+
+ /** Return the POP3 response text (first line).
+ *
+ * @return response text
+ */
+ const string getText() const;
+
+ /** Return the first POP3 response line.
+ *
+ * @return first response line
+ */
+ const string getFirstLine() const;
+
+ /** Return the response line at the specified position.
+ *
+ * @param pos line index
+ * @return line at the specified index
+ */
+ const string getLineAt(const size_t pos) const;
+
+ /** Return the number of lines in the response.
+ *
+ * @return number of lines in the response
+ */
+ size_t getLineCount() const;
+
+private:
+
+ POP3Response(
+ const shared_ptr <socket>& sok,
+ const shared_ptr <timeoutHandler>& toh,
+ const shared_ptr <tracer>& tracer
+ );
+
+ void readResponseImpl(string& buffer, const bool multiLine);
+
+ size_t readResponseImpl(
+ string& firstLine,
+ utility::outputStream& os,
+ utility::progressListener* progress,
+ const size_t predictedSize
+ );
+
+
+ static bool stripFirstLine(const string& buffer, string& result, string* firstLine);
+
+ static ResponseCode getResponseCode(const string& buffer);
+
+ static void stripResponseCode(const string& buffer, string& result);
+
+ static bool checkTerminator(string& buffer, const bool multiLine);
+ static bool checkOneTerminator(string& buffer, const string& term);
+
+
+ shared_ptr <socket> m_socket;
+ shared_ptr <timeoutHandler> m_timeoutHandler;
+ shared_ptr <tracer> m_tracer;
+
+ string m_firstLine;
+ ResponseCode m_code;
+ string m_text;
+
+ std::vector <string> m_lines;
+};
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+#endif // VMIME_NET_SMTP_POP3RESPONSE_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/net/pop3/POP3SStore.cpp b/vmime-master/src/vmime/net/pop3/POP3SStore.cpp
new file mode 100644
index 0000000..81a50bc
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3SStore.cpp
@@ -0,0 +1,82 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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/POP3SStore.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+POP3SStore::POP3SStore(
+ const shared_ptr <session>& sess,
+ const shared_ptr <security::authenticator>& auth
+)
+ : POP3Store(sess, auth, true) {
+
+}
+
+
+POP3SStore::~POP3SStore() {
+
+}
+
+
+const string POP3SStore::getProtocolName() const {
+
+ return "pop3s";
+}
+
+
+
+// Service infos
+
+POP3ServiceInfos POP3SStore::sm_infos(true);
+
+
+const serviceInfos& POP3SStore::getInfosInstance() {
+
+ return sm_infos;
+}
+
+
+const serviceInfos& POP3SStore::getInfos() const {
+
+ return sm_infos;
+}
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
diff --git a/vmime-master/src/vmime/net/pop3/POP3SStore.hpp b/vmime-master/src/vmime/net/pop3/POP3SStore.hpp
new file mode 100644
index 0000000..76a6ee1
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3SStore.hpp
@@ -0,0 +1,74 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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_POP3SSTORE_HPP_INCLUDED
+#define VMIME_NET_POP3_POP3SSTORE_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+
+#include "vmime/net/pop3/POP3Store.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+/** POP3S store service.
+ */
+class VMIME_EXPORT POP3SStore : public POP3Store {
+
+public:
+
+ POP3SStore(
+ const shared_ptr <session>& sess,
+ const shared_ptr <security::authenticator>& auth
+ );
+
+ ~POP3SStore();
+
+ const string getProtocolName() const;
+
+ static const serviceInfos& getInfosInstance();
+ const serviceInfos& getInfos() const;
+
+private:
+
+ static POP3ServiceInfos sm_infos;
+};
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+#endif // VMIME_NET_POP3_POP3SSTORE_HPP_INCLUDED
+
diff --git a/vmime-master/src/vmime/net/pop3/POP3ServiceInfos.cpp b/vmime-master/src/vmime/net/pop3/POP3ServiceInfos.cpp
new file mode 100644
index 0000000..4deee74
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3ServiceInfos.cpp
@@ -0,0 +1,142 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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/POP3ServiceInfos.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+POP3ServiceInfos::POP3ServiceInfos(const bool pop3s)
+ : m_pop3s(pop3s) {
+
+}
+
+
+const string POP3ServiceInfos::getPropertyPrefix() const {
+
+ if (m_pop3s) {
+ return "store.pop3s.";
+ } else {
+ return "store.pop3.";
+ }
+}
+
+
+const POP3ServiceInfos::props& POP3ServiceInfos::getProperties() const {
+
+ static props pop3Props = {
+ // POP3-specific options
+ property("options.apop", serviceInfos::property::TYPE_BOOLEAN, "true"),
+ property("options.apop.fallback", serviceInfos::property::TYPE_BOOLEAN, "true"),
+#if VMIME_HAVE_SASL_SUPPORT
+ property("options.sasl", serviceInfos::property::TYPE_BOOLEAN, "true"),
+ property("options.sasl.fallback", serviceInfos::property::TYPE_BOOLEAN, "true"),
+#endif // VMIME_HAVE_SASL_SUPPORT
+
+ // Common properties
+ property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED),
+ property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED),
+
+#if VMIME_HAVE_TLS_SUPPORT
+ property(serviceInfos::property::CONNECTION_TLS),
+ property(serviceInfos::property::CONNECTION_TLS_REQUIRED),
+#endif // VMIME_HAVE_TLS_SUPPORT
+
+ property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
+ property(serviceInfos::property::SERVER_PORT, "110"),
+ };
+
+ static props pop3sProps = {
+
+ // POP3-specific options
+ property("options.apop", serviceInfos::property::TYPE_BOOLEAN, "true"),
+ property("options.apop.fallback", serviceInfos::property::TYPE_BOOLEAN, "true"),
+#if VMIME_HAVE_SASL_SUPPORT
+ property("options.sasl", serviceInfos::property::TYPE_BOOLEAN, "true"),
+ property("options.sasl.fallback", serviceInfos::property::TYPE_BOOLEAN, "true"),
+#endif // VMIME_HAVE_SASL_SUPPORT
+
+ // Common properties
+ property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED),
+ property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED),
+
+#if VMIME_HAVE_TLS_SUPPORT
+ property(serviceInfos::property::CONNECTION_TLS),
+ property(serviceInfos::property::CONNECTION_TLS_REQUIRED),
+#endif // VMIME_HAVE_TLS_SUPPORT
+
+ property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
+ property(serviceInfos::property::SERVER_PORT, "995"),
+ };
+
+ return m_pop3s ? pop3sProps : pop3Props;
+}
+
+
+const std::vector <serviceInfos::property> POP3ServiceInfos::getAvailableProperties() const {
+
+ std::vector <property> list;
+ const props& p = getProperties();
+
+ // POP3-specific options
+ list.push_back(p.PROPERTY_OPTIONS_APOP);
+ list.push_back(p.PROPERTY_OPTIONS_APOP_FALLBACK);
+#if VMIME_HAVE_SASL_SUPPORT
+ list.push_back(p.PROPERTY_OPTIONS_SASL);
+ list.push_back(p.PROPERTY_OPTIONS_SASL_FALLBACK);
+#endif // VMIME_HAVE_SASL_SUPPORT
+
+ // Common properties
+ list.push_back(p.PROPERTY_AUTH_USERNAME);
+ list.push_back(p.PROPERTY_AUTH_PASSWORD);
+
+#if VMIME_HAVE_TLS_SUPPORT
+ if (!m_pop3s) {
+ list.push_back(p.PROPERTY_CONNECTION_TLS);
+ list.push_back(p.PROPERTY_CONNECTION_TLS_REQUIRED);
+ }
+#endif // VMIME_HAVE_TLS_SUPPORT
+
+ list.push_back(p.PROPERTY_SERVER_ADDRESS);
+ list.push_back(p.PROPERTY_SERVER_PORT);
+
+ return list;
+}
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
diff --git a/vmime-master/src/vmime/net/pop3/POP3ServiceInfos.hpp b/vmime-master/src/vmime/net/pop3/POP3ServiceInfos.hpp
new file mode 100644
index 0000000..590a6be
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3ServiceInfos.hpp
@@ -0,0 +1,91 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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_POP3SERVICEINFOS_HPP_INCLUDED
+#define VMIME_NET_POP3_POP3SERVICEINFOS_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+
+#include "vmime/net/serviceInfos.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+/** Information about POP3 service.
+ */
+class VMIME_EXPORT POP3ServiceInfos : public serviceInfos {
+
+public:
+
+ POP3ServiceInfos(const bool pop3s);
+
+ struct props {
+ // POP3-specific options
+ serviceInfos::property PROPERTY_OPTIONS_APOP;
+ serviceInfos::property PROPERTY_OPTIONS_APOP_FALLBACK;
+#if VMIME_HAVE_SASL_SUPPORT
+ serviceInfos::property PROPERTY_OPTIONS_SASL;
+ serviceInfos::property PROPERTY_OPTIONS_SASL_FALLBACK;
+#endif // VMIME_HAVE_SASL_SUPPORT
+
+ // Common properties
+ serviceInfos::property PROPERTY_AUTH_USERNAME;
+ serviceInfos::property PROPERTY_AUTH_PASSWORD;
+
+#if VMIME_HAVE_TLS_SUPPORT
+ serviceInfos::property PROPERTY_CONNECTION_TLS;
+ serviceInfos::property PROPERTY_CONNECTION_TLS_REQUIRED;
+#endif // VMIME_HAVE_TLS_SUPPORT
+
+ serviceInfos::property PROPERTY_SERVER_ADDRESS;
+ serviceInfos::property PROPERTY_SERVER_PORT;
+ };
+
+ const props& getProperties() const;
+
+ const string getPropertyPrefix() const;
+ const std::vector <serviceInfos::property> getAvailableProperties() const;
+
+private:
+
+ const bool m_pop3s;
+};
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+#endif // VMIME_NET_POP3_POP3SERVICEINFOS_HPP_INCLUDED
+
diff --git a/vmime-master/src/vmime/net/pop3/POP3Store.cpp b/vmime-master/src/vmime/net/pop3/POP3Store.cpp
new file mode 100644
index 0000000..b06640f
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Store.cpp
@@ -0,0 +1,262 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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/POP3Store.hpp"
+#include "vmime/net/pop3/POP3Folder.hpp"
+#include "vmime/net/pop3/POP3Command.hpp"
+#include "vmime/net/pop3/POP3Response.hpp"
+
+#include "vmime/exception.hpp"
+
+#include <algorithm>
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+POP3Store::POP3Store(
+ const shared_ptr <session>& sess,
+ const shared_ptr <security::authenticator>& auth,
+ const bool secured
+)
+ : store(sess, getInfosInstance(), auth),
+ m_isPOP3S(secured) {
+
+}
+
+
+POP3Store::~POP3Store() {
+
+ try {
+
+ if (isConnected()) {
+ disconnect();
+ }
+
+ } catch (...) {
+
+ // Don't throw in destructor
+ }
+}
+
+
+const string POP3Store::getProtocolName() const {
+
+ return "pop3";
+}
+
+
+shared_ptr <folder> POP3Store::getDefaultFolder() {
+
+ if (!isConnected()) {
+ throw exceptions::illegal_state("Not connected");
+ }
+
+ return shared_ptr <POP3Folder>(
+ new POP3Folder(
+ folder::path(folder::path::component("INBOX")),
+ dynamicCast <POP3Store>(shared_from_this())
+ )
+ );
+}
+
+
+shared_ptr <folder> POP3Store::getRootFolder() {
+
+ if (!isConnected()) {
+ throw exceptions::illegal_state("Not connected");
+ }
+
+ return shared_ptr <POP3Folder>(
+ new POP3Folder(
+ folder::path(),
+ dynamicCast <POP3Store>(shared_from_this())
+ )
+ );
+}
+
+
+shared_ptr <folder> POP3Store::getFolder(const folder::path& path) {
+
+ if (!isConnected()) {
+ throw exceptions::illegal_state("Not connected");
+ }
+
+ return shared_ptr <POP3Folder>(
+ new POP3Folder(
+ path,
+ dynamicCast <POP3Store>(shared_from_this())
+ )
+ );
+}
+
+
+bool POP3Store::isValidFolderName(const folder::path::component& /* name */) const {
+
+ return true;
+}
+
+
+void POP3Store::connect() {
+
+ if (isConnected()) {
+ throw exceptions::already_connected();
+ }
+
+ m_connection = make_shared <POP3Connection>(
+ dynamicCast <POP3Store>(shared_from_this()), getAuthenticator()
+ );
+
+ m_connection->connect();
+}
+
+
+bool POP3Store::isPOP3S() const {
+
+ return m_isPOP3S;
+}
+
+
+bool POP3Store::isConnected() const {
+
+ return m_connection && m_connection->isConnected();
+}
+
+
+bool POP3Store::isSecuredConnection() const {
+
+ if (!m_connection) {
+ return false;
+ }
+
+ return m_connection->isSecuredConnection();
+}
+
+
+shared_ptr <connectionInfos> POP3Store::getConnectionInfos() const {
+
+ if (!m_connection) {
+ return null;
+ }
+
+ return m_connection->getConnectionInfos();
+}
+
+
+shared_ptr <POP3Connection> POP3Store::getConnection() {
+
+ return m_connection;
+}
+
+
+void POP3Store::disconnect() {
+
+ if (!isConnected()) {
+ throw exceptions::not_connected();
+ }
+
+ for (std::list <POP3Folder*>::iterator it = m_folders.begin() ;
+ it != m_folders.end() ; ++it) {
+
+ (*it)->onStoreDisconnected();
+ }
+
+ m_folders.clear();
+
+
+ m_connection->disconnect();
+ m_connection = null;
+}
+
+
+void POP3Store::noop() {
+
+ if (!m_connection) {
+ throw exceptions::not_connected();
+ }
+
+ POP3Command::NOOP()->send(m_connection);
+
+ shared_ptr <POP3Response> response = POP3Response::readResponse(m_connection);
+
+ if (!response->isSuccess()) {
+ throw exceptions::command_error("NOOP", response->getFirstLine());
+ }
+}
+
+
+void POP3Store::registerFolder(POP3Folder* folder) {
+
+ m_folders.push_back(folder);
+}
+
+
+void POP3Store::unregisterFolder(POP3Folder* folder) {
+
+ std::list <POP3Folder*>::iterator it = std::find(m_folders.begin(), m_folders.end(), folder);
+
+ if (it != m_folders.end()) {
+ m_folders.erase(it);
+ }
+}
+
+
+int POP3Store::getCapabilities() const {
+
+ return CAPABILITY_DELETE_MESSAGE;
+}
+
+
+
+// Service infos
+
+POP3ServiceInfos POP3Store::sm_infos(false);
+
+
+const serviceInfos& POP3Store::getInfosInstance() {
+
+ return sm_infos;
+}
+
+
+const serviceInfos& POP3Store::getInfos() const {
+
+ return sm_infos;
+}
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
diff --git a/vmime-master/src/vmime/net/pop3/POP3Store.hpp b/vmime-master/src/vmime/net/pop3/POP3Store.hpp
new file mode 100644
index 0000000..140a1ab
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Store.hpp
@@ -0,0 +1,120 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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_POP3STORE_HPP_INCLUDED
+#define VMIME_NET_POP3_POP3STORE_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+
+#include "vmime/net/store.hpp"
+
+#include "vmime/net/pop3/POP3ServiceInfos.hpp"
+#include "vmime/net/pop3/POP3Connection.hpp"
+
+#include "vmime/utility/stream.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+class POP3Folder;
+class POP3Command;
+class POP3Response;
+
+
+/** POP3 store service.
+ */
+class VMIME_EXPORT POP3Store : public store {
+
+ friend class POP3Folder;
+ friend class POP3Message;
+
+public:
+
+ POP3Store(
+ const shared_ptr <session>& sess,
+ const shared_ptr <security::authenticator>& auth,
+ const bool secured = false
+ );
+
+ ~POP3Store();
+
+ const string getProtocolName() const;
+
+ shared_ptr <folder> getDefaultFolder();
+ shared_ptr <folder> getRootFolder();
+ shared_ptr <folder> getFolder(const folder::path& path);
+
+ bool isValidFolderName(const folder::path::component& name) const;
+
+ static const serviceInfos& getInfosInstance();
+ const serviceInfos& getInfos() const;
+
+ void connect();
+ bool isConnected() const;
+ void disconnect();
+
+ void noop();
+
+ int getCapabilities() const;
+
+ bool isSecuredConnection() const;
+ shared_ptr <connectionInfos> getConnectionInfos() const;
+ shared_ptr <POP3Connection> getConnection();
+
+ bool isPOP3S() const;
+
+private:
+
+ shared_ptr <POP3Connection> m_connection;
+
+
+ void registerFolder(POP3Folder* folder);
+ void unregisterFolder(POP3Folder* folder);
+
+ std::list <POP3Folder*> m_folders;
+
+
+ const bool m_isPOP3S;
+
+
+ // Service infos
+ static POP3ServiceInfos sm_infos;
+};
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+#endif // VMIME_NET_POP3_POP3STORE_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/net/pop3/POP3Utils.cpp b/vmime-master/src/vmime/net/pop3/POP3Utils.cpp
new file mode 100644
index 0000000..b38161e
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Utils.cpp
@@ -0,0 +1,135 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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/POP3Utils.hpp"
+#include "vmime/net/pop3/POP3Response.hpp"
+
+#include <sstream>
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+// static
+void POP3Utils::parseMultiListOrUidlResponse(
+ const shared_ptr <POP3Response>& response,
+ std::map <size_t, string>& result
+) {
+
+ std::map <size_t, string> ids;
+
+ for (size_t i = 0, n = response->getLineCount() ; i < n ; ++i) {
+
+ string line = response->getLineAt(i);
+ string::iterator it = line.begin();
+
+ while (it != line.end() && (*it == ' ' || *it == '\t')) {
+ ++it;
+ }
+
+ if (it != line.end()) {
+
+ size_t number = 0;
+
+ while (it != line.end() && (*it >= '0' && *it <= '9')) {
+ number = (number * 10) + (*it - '0');
+ ++it;
+ }
+
+ while (it != line.end() && !(*it == ' ' || *it == '\t')) ++it;
+ while (it != line.end() && (*it == ' ' || *it == '\t')) ++it;
+
+ if (it != line.end()) {
+ result.insert(std::map <size_t, string>::value_type(number, string(it, line.end())));
+ }
+ }
+ }
+}
+
+
+
+class POP3MessageSetEnumerator : public messageSetEnumerator {
+
+public:
+
+ POP3MessageSetEnumerator(const size_t msgCount)
+ : m_msgCount(msgCount) {
+
+ }
+
+ void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) {
+
+ size_t last = range.getLast();
+
+ if (last == size_t(-1)) {
+ last = m_msgCount;
+ }
+
+ for (size_t i = range.getFirst() ; i <= last ; ++i) {
+ list.push_back(i);
+ }
+ }
+
+ void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& /* range */) {
+
+ // Not supported
+ }
+
+public:
+
+ std::vector <size_t> list;
+
+private:
+
+ size_t m_msgCount;
+};
+
+
+// static
+const std::vector <size_t> POP3Utils::messageSetToNumberList(
+ const messageSet& msgs,
+ const size_t msgCount
+) {
+
+ POP3MessageSetEnumerator en(msgCount);
+ msgs.enumerate(en);
+
+ return en.list;
+}
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
diff --git a/vmime-master/src/vmime/net/pop3/POP3Utils.hpp b/vmime-master/src/vmime/net/pop3/POP3Utils.hpp
new file mode 100644
index 0000000..09d15d5
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/POP3Utils.hpp
@@ -0,0 +1,92 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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_POP3UTILS_HPP_INCLUDED
+#define VMIME_NET_POP3_POP3UTILS_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+
+#include <map>
+
+#include "vmime/types.hpp"
+
+#include "vmime/net/messageSet.hpp"
+
+
+namespace vmime {
+namespace net {
+namespace pop3 {
+
+
+class POP3Response;
+
+
+class VMIME_EXPORT POP3Utils {
+
+public:
+
+ /** Parse a response of type ([integer] [string] \n)*.
+ * This is used in LIST or UIDL commands:
+ *
+ * C: UIDL
+ * S: +OK
+ * S: 1 whqtswO00WBw418f9t5JxYwZ
+ * S: 2 QhdPYR:00WBw1Ph7x7
+ * S: .
+ *
+ * @param response raw response string as returned by the server
+ * @param result points to an associative array which maps a message
+ * number to its corresponding data (either UID or size)
+ */
+ static void parseMultiListOrUidlResponse(
+ const shared_ptr <POP3Response>& response,
+ std::map <size_t, string>& result
+ );
+
+ /** Returns a list of message numbers given a message set.
+ *
+ * @param msgs message set
+ * @param msgCount number of messages in folder
+ * @return list of message numbers
+ */
+ static const std::vector <size_t> messageSetToNumberList(
+ const messageSet& msgs,
+ const size_t msgCount
+ );
+};
+
+
+} // pop3
+} // net
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
+
+#endif // VMIME_NET_POP3_POP3UTILS_HPP_INCLUDED
+
diff --git a/vmime-master/src/vmime/net/pop3/pop3.hpp b/vmime-master/src/vmime/net/pop3/pop3.hpp
new file mode 100644
index 0000000..ced3a97
--- /dev/null
+++ b/vmime-master/src/vmime/net/pop3/pop3.hpp
@@ -0,0 +1,35 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
+//
+// 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_POP3_HPP_INCLUDED
+#define VMIME_NET_POP3_POP3_HPP_INCLUDED
+
+
+#include "vmime/net/pop3/POP3Folder.hpp"
+#include "vmime/net/pop3/POP3FolderStatus.hpp"
+#include "vmime/net/pop3/POP3Message.hpp"
+#include "vmime/net/pop3/POP3Store.hpp"
+#include "vmime/net/pop3/POP3SStore.hpp"
+
+
+#endif // VMIME_NET_POP3_POP3_HPP_INCLUDED