diff options
Diffstat (limited to 'vmime-master/src/vmime/net/sendmail/sendmailTransport.cpp')
-rw-r--r-- | vmime-master/src/vmime/net/sendmail/sendmailTransport.cpp | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/vmime-master/src/vmime/net/sendmail/sendmailTransport.cpp b/vmime-master/src/vmime/net/sendmail/sendmailTransport.cpp new file mode 100644 index 0000000..7010fd8 --- /dev/null +++ b/vmime-master/src/vmime/net/sendmail/sendmailTransport.cpp @@ -0,0 +1,244 @@ +// +// 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_SENDMAIL + + +#include "vmime/net/sendmail/sendmailTransport.hpp" + +#include "vmime/exception.hpp" +#include "vmime/platform.hpp" +#include "vmime/message.hpp" +#include "vmime/mailboxList.hpp" + +#include "vmime/utility/filteredStream.hpp" +#include "vmime/utility/childProcess.hpp" + +#include "vmime/utility/streamUtils.hpp" + +#include "vmime/net/defaultConnectionInfos.hpp" + +#include "vmime/config.hpp" + + +// Helpers for service properties +#define GET_PROPERTY(type, prop) \ + (getInfos().getPropertyValue <type>(getSession(), \ + dynamic_cast <const sendmailServiceInfos&>(getInfos()).getProperties().prop)) +#define HAS_PROPERTY(prop) \ + (getInfos().hasProperty(getSession(), \ + dynamic_cast <const sendmailServiceInfos&>(getInfos()).getProperties().prop)) + + +namespace vmime { +namespace net { +namespace sendmail { + + +sendmailTransport::sendmailTransport( + const shared_ptr <session>& sess, + const shared_ptr <security::authenticator>& auth +) + : transport(sess, getInfosInstance(), auth), + m_connected(false) { + +} + + +sendmailTransport::~sendmailTransport() { + + try { + + if (isConnected()) { + disconnect(); + } + + } catch (...) { + + // Don't throw in destructor + } +} + + +const string sendmailTransport::getProtocolName() const { + + return "sendmail"; +} + + +void sendmailTransport::connect() { + + if (isConnected()) { + throw exceptions::already_connected(); + } + + // Use the specified path for 'sendmail' or a default one if no path is specified + m_sendmailPath = GET_PROPERTY(string, PROPERTY_BINPATH); + + m_connected = true; +} + + +bool sendmailTransport::isConnected() const { + + return m_connected; +} + + +bool sendmailTransport::isSecuredConnection() const { + + return false; +} + + +shared_ptr <connectionInfos> sendmailTransport::getConnectionInfos() const { + + return make_shared <defaultConnectionInfos>("localhost", static_cast <port_t>(0)); +} + + +void sendmailTransport::disconnect() { + + if (!isConnected()) { + throw exceptions::not_connected(); + } + + internalDisconnect(); +} + + +void sendmailTransport::internalDisconnect() { + + m_connected = false; +} + + +void sendmailTransport::noop() { + + // Do nothing +} + + +void sendmailTransport::send( + const mailbox& expeditor, + const mailboxList& recipients, + utility::inputStream& is, + const size_t size, + utility::progressListener* progress, + const mailbox& sender, + const dsnAttributes& /*dsnAttrs*/ +) { + + // If no recipient/expeditor was found, throw an exception + if (recipients.isEmpty()) { + throw exceptions::no_recipient(); + } else if (expeditor.isEmpty()) { + throw exceptions::no_expeditor(); + } + + // Construct the argument list + std::vector <string> args; + + args.push_back("-i"); + args.push_back("-f"); + + if (!sender.isEmpty()) { + args.push_back(expeditor.getEmail().generate()); + } else { + args.push_back(sender.getEmail().generate()); + } + + args.push_back("--"); + + for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) { + args.push_back(recipients.getMailboxAt(i)->getEmail().generate()); + } + + // Call sendmail + try { + internalSend(args, is, size, progress); + } catch (vmime::exception& e) { + throw exceptions::command_error("SEND", "", "sendmail failed", e); + } +} + + +void sendmailTransport::internalSend( + const std::vector <string>& args, + utility::inputStream& is, + const size_t size, + utility::progressListener* progress +) { + + const utility::file::path path = vmime::platform::getHandler()-> + getFileSystemFactory()->stringToPath(m_sendmailPath); + + shared_ptr <utility::childProcess> proc = + vmime::platform::getHandler()->getChildProcessFactory()->create(path); + + proc->start(args, utility::childProcess::FLAG_REDIRECT_STDIN); + + // Copy message data from input stream to output pipe + utility::outputStream& os = *(proc->getStdIn()); + + // Workaround for lame sendmail implementations that + // can't handle CRLF eoln sequences: we transform CRLF + // sequences into LF characters. + utility::CRLFToLFFilteredOutputStream fos(os); + + // TODO: remove 'Bcc:' field from message header + + utility::bufferedStreamCopy(is, fos, size, progress); + + // Wait for sendmail to exit + proc->waitForFinish(); +} + + +// Service infos + +sendmailServiceInfos sendmailTransport::sm_infos; + + +const serviceInfos& sendmailTransport::getInfosInstance() { + + return sm_infos; +} + + +const serviceInfos& sendmailTransport::getInfos() const { + + return sm_infos; +} + + +} // sendmail +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SENDMAIL + |