aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/smtp/SMTPTransport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/smtp/SMTPTransport.cpp')
-rw-r--r--src/net/smtp/SMTPTransport.cpp420
1 files changed, 0 insertions, 420 deletions
diff --git a/src/net/smtp/SMTPTransport.cpp b/src/net/smtp/SMTPTransport.cpp
deleted file mode 100644
index 0020d010..00000000
--- a/src/net/smtp/SMTPTransport.cpp
+++ /dev/null
@@ -1,420 +0,0 @@
-//
-// VMime library (http://www.vmime.org)
-// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 3 of
-// the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// Linking this library statically or dynamically with other modules is making
-// a combined work based on this library. Thus, the terms and conditions of
-// the GNU General Public License cover the whole combination.
-//
-
-#include "vmime/config.hpp"
-
-
-#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP
-
-
-#include "vmime/net/smtp/SMTPTransport.hpp"
-#include "vmime/net/smtp/SMTPResponse.hpp"
-#include "vmime/net/smtp/SMTPCommand.hpp"
-#include "vmime/net/smtp/SMTPCommandSet.hpp"
-#include "vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp"
-#include "vmime/net/smtp/SMTPExceptions.hpp"
-
-#include "vmime/exception.hpp"
-#include "vmime/mailboxList.hpp"
-#include "vmime/message.hpp"
-
-#include "vmime/utility/filteredStream.hpp"
-#include "vmime/utility/stringUtils.hpp"
-#include "vmime/utility/outputStreamSocketAdapter.hpp"
-#include "vmime/utility/streamUtils.hpp"
-#include "vmime/utility/outputStreamAdapter.hpp"
-#include "vmime/utility/inputStreamStringAdapter.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace smtp {
-
-
-SMTPTransport::SMTPTransport(shared_ptr <session> sess, shared_ptr <security::authenticator> auth, const bool secured)
- : transport(sess, getInfosInstance(), auth), m_isSMTPS(secured), m_needReset(false)
-{
-}
-
-
-SMTPTransport::~SMTPTransport()
-{
- try
- {
- if (isConnected())
- disconnect();
- }
- catch (vmime::exception&)
- {
- // Ignore
- }
-}
-
-
-const string SMTPTransport::getProtocolName() const
-{
- return "smtp";
-}
-
-
-bool SMTPTransport::isSMTPS() const
-{
- return m_isSMTPS;
-}
-
-
-void SMTPTransport::connect()
-{
- if (isConnected())
- throw exceptions::already_connected();
-
- m_connection = make_shared <SMTPConnection>
- (dynamicCast <SMTPTransport>(shared_from_this()), getAuthenticator());
-
- try
- {
- m_connection->connect();
- }
- catch (std::exception&)
- {
- m_connection = null;
- throw;
- }
-}
-
-
-bool SMTPTransport::isConnected() const
-{
- return m_connection && m_connection->isConnected();
-}
-
-
-bool SMTPTransport::isSecuredConnection() const
-{
- if (m_connection == NULL)
- return false;
-
- return m_connection->isSecuredConnection();
-}
-
-
-shared_ptr <connectionInfos> SMTPTransport::getConnectionInfos() const
-{
- if (m_connection == NULL)
- return null;
-
- return m_connection->getConnectionInfos();
-}
-
-
-shared_ptr <SMTPConnection> SMTPTransport::getConnection()
-{
- return m_connection;
-}
-
-
-void SMTPTransport::disconnect()
-{
- if (!isConnected())
- throw exceptions::not_connected();
-
- m_connection->disconnect();
- m_connection = null;
-}
-
-
-void SMTPTransport::noop()
-{
- if (!isConnected())
- throw exceptions::not_connected();
-
- m_connection->sendRequest(SMTPCommand::NOOP());
-
- shared_ptr <SMTPResponse> resp = m_connection->readResponse();
-
- if (resp->getCode() != 250)
- {
- throw SMTPCommandError
- ("NOOP", resp->getText(), resp->getCode(), resp->getEnhancedCode());
- }
-}
-
-
-void SMTPTransport::sendEnvelope
- (const mailbox& expeditor, const mailboxList& recipients,
- const mailbox& sender, bool sendDATACommand,
- const size_t size)
-{
- // If no recipient/expeditor was found, throw an exception
- if (recipients.isEmpty())
- throw exceptions::no_recipient();
- else if (expeditor.isEmpty())
- throw exceptions::no_expeditor();
-
-
- const bool needReset = m_needReset;
- const bool hasPipelining = m_connection->hasExtension("PIPELINING") &&
- getInfos().getPropertyValue <bool>(getSession(),
- dynamic_cast <const SMTPServiceInfos&>(getInfos()).getProperties().PROPERTY_OPTIONS_PIPELINING);
-
- shared_ptr <SMTPResponse> resp;
- shared_ptr <SMTPCommandSet> commands = SMTPCommandSet::create(hasPipelining);
-
- // Emit a "RSET" command if we previously sent a message on this connection
- if (needReset)
- commands->addCommand(SMTPCommand::RSET());
-
- // Emit the "MAIL" command
- const bool hasSMTPUTF8 = m_connection->hasExtension("SMTPUTF8");
- const bool hasSize = m_connection->hasExtension("SIZE");
-
- if (!sender.isEmpty())
- commands->addCommand(SMTPCommand::MAIL(sender, hasSMTPUTF8, hasSize ? size : 0));
- else
- commands->addCommand(SMTPCommand::MAIL(expeditor, hasSMTPUTF8, hasSize ? size : 0));
-
- // Now, we will need to reset next time
- m_needReset = true;
-
- // Emit a "RCPT TO" command for each recipient
- for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i)
- {
- const mailbox& mbox = *recipients.getMailboxAt(i);
- commands->addCommand(SMTPCommand::RCPT(mbox, hasSMTPUTF8));
- }
-
- // Prepare sending of message data
- if (sendDATACommand)
- commands->addCommand(SMTPCommand::DATA());
-
- // Read response for "RSET" command
- if (needReset)
- {
- commands->writeToSocket(m_connection->getSocket());
-
- if ((resp = m_connection->readResponse())->getCode() != 250)
- {
- disconnect();
-
- throw SMTPCommandError
- (commands->getLastCommandSent()->getText(), resp->getText(),
- resp->getCode(), resp->getEnhancedCode());
- }
- }
-
- // Read response for "MAIL" command
- commands->writeToSocket(m_connection->getSocket());
-
- if ((resp = m_connection->readResponse())->getCode() != 250)
- {
- // SIZE extension: insufficient system storage
- if (resp->getCode() == 452)
- {
- disconnect();
-
- throw SMTPMessageSizeExceedsCurLimitsException
- (SMTPCommandError(commands->getLastCommandSent()->getText(), resp->getText(),
- resp->getCode(), resp->getEnhancedCode()));
- }
- // SIZE extension: message size exceeds fixed maximum message size
- else if (resp->getCode() == 552)
- {
- disconnect();
-
- throw SMTPMessageSizeExceedsMaxLimitsException
- (SMTPCommandError(commands->getLastCommandSent()->getText(), resp->getText(),
- resp->getCode(), resp->getEnhancedCode()));
- }
- // Other error
- else
- {
- disconnect();
-
- throw SMTPCommandError
- (commands->getLastCommandSent()->getText(), resp->getText(),
- resp->getCode(), resp->getEnhancedCode());
- }
- }
-
- // Read responses for "RCPT TO" commands
- for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i)
- {
- commands->writeToSocket(m_connection->getSocket());
-
- resp = m_connection->readResponse();
-
- if (resp->getCode() != 250 &&
- resp->getCode() != 251)
- {
- // SIZE extension: insufficient system storage
- if (resp->getCode() == 452)
- {
- disconnect();
-
- throw SMTPMessageSizeExceedsCurLimitsException
- (SMTPCommandError(commands->getLastCommandSent()->getText(), resp->getText(),
- resp->getCode(), resp->getEnhancedCode()));
- }
- // SIZE extension: message size exceeds fixed maximum message size
- else if (resp->getCode() == 552)
- {
- disconnect();
-
- throw SMTPMessageSizeExceedsMaxLimitsException
- (SMTPCommandError(commands->getLastCommandSent()->getText(), resp->getText(),
- resp->getCode(), resp->getEnhancedCode()));
- }
- // Other error
- else
- {
- disconnect();
-
- throw SMTPCommandError
- (commands->getLastCommandSent()->getText(), resp->getText(),
- resp->getCode(), resp->getEnhancedCode());
- }
- }
- }
-
- // Read response for "DATA" command
- if (sendDATACommand)
- {
- commands->writeToSocket(m_connection->getSocket());
-
- if ((resp = m_connection->readResponse())->getCode() != 354)
- {
- disconnect();
-
- throw SMTPCommandError
- (commands->getLastCommandSent()->getText(), resp->getText(),
- resp->getCode(), resp->getEnhancedCode());
- }
- }
-}
-
-
-void SMTPTransport::send
- (const mailbox& expeditor, const mailboxList& recipients,
- utility::inputStream& is, const size_t size,
- utility::progressListener* progress, const mailbox& sender)
-{
- if (!isConnected())
- throw exceptions::not_connected();
-
- // Send message envelope
- sendEnvelope(expeditor, recipients, sender, /* sendDATACommand */ true, size);
-
- // Send the message data
- // Stream copy with "\n." to "\n.." transformation
- utility::outputStreamSocketAdapter sos(*m_connection->getSocket());
- utility::dotFilteredOutputStream fos(sos);
-
- utility::bufferedStreamCopy(is, fos, size, progress);
-
- fos.flush();
-
- // Send end-of-data delimiter
- m_connection->getSocket()->send("\r\n.\r\n");
-
- shared_ptr <SMTPResponse> resp;
-
- if ((resp = m_connection->readResponse())->getCode() != 250)
- {
- disconnect();
-
- throw SMTPCommandError
- ("DATA", resp->getText(), resp->getCode(), resp->getEnhancedCode());
- }
-}
-
-
-void SMTPTransport::send
- (shared_ptr <vmime::message> msg, const mailbox& expeditor, const mailboxList& recipients,
- utility::progressListener* progress, const mailbox& sender)
-{
- if (!isConnected())
- throw exceptions::not_connected();
-
- // Generate the message with Internationalized Email support,
- // if this is supported by the SMTP server
- generationContext ctx(generationContext::getDefaultContext());
- ctx.setInternationalizedEmailSupport(m_connection->hasExtension("SMTPUTF8"));
-
- // If CHUNKING is not supported, generate the message to a temporary
- // buffer then use the send() method which takes an inputStream
- if (!m_connection->hasExtension("CHUNKING") ||
- !getInfos().getPropertyValue <bool>(getSession(),
- dynamic_cast <const SMTPServiceInfos&>(getInfos()).getProperties().PROPERTY_OPTIONS_CHUNKING))
-
- {
- std::ostringstream oss;
- utility::outputStreamAdapter ossAdapter(oss);
-
- msg->generate(ctx, ossAdapter);
-
- const string& str(oss.str());
-
- utility::inputStreamStringAdapter isAdapter(str);
-
- send(expeditor, recipients, isAdapter, str.length(), progress, sender);
- return;
- }
-
- // Send message envelope
- sendEnvelope(expeditor, recipients, sender,
- /* sendDATACommand */ false, msg->getGeneratedSize(ctx));
-
- // Send the message by chunks
- SMTPChunkingOutputStreamAdapter chunkStream(m_connection);
-
- msg->generate(ctx, chunkStream);
-
- chunkStream.flush();
-}
-
-
-
-// Service infos
-
-SMTPServiceInfos SMTPTransport::sm_infos(false);
-
-
-const serviceInfos& SMTPTransport::getInfosInstance()
-{
- return sm_infos;
-}
-
-
-const serviceInfos& SMTPTransport::getInfos() const
-{
- return sm_infos;
-}
-
-
-} // smtp
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP
-