diff options
Diffstat (limited to 'vmime-master/src/vmime/net/pop3')
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 | 
