aboutsummaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2013-12-29 10:02:12 +0100
committerVincent Richard <[email protected]>2013-12-29 10:02:12 +0100
commit152c6bed75598a6ca5efb7914701157270155833 (patch)
tree8faced1d75a45c819630323da256248415992ed0 /src/net
parentMerge branch 'master' of https://github.com/kisli/vmime (diff)
downloadvmime-152c6bed75598a6ca5efb7914701157270155833.tar.gz
vmime-152c6bed75598a6ca5efb7914701157270155833.zip
Merged source and header files in directory structure. Got rid of SConstruct build.
Diffstat (limited to 'src/net')
-rw-r--r--src/net/builtinServices.inl76
-rw-r--r--src/net/defaultConnectionInfos.cpp60
-rw-r--r--src/net/events.cpp166
-rw-r--r--src/net/fetchAttributes.cpp95
-rw-r--r--src/net/folder.cpp127
-rw-r--r--src/net/imap/IMAPConnection.cpp814
-rw-r--r--src/net/imap/IMAPFolder.cpp1511
-rw-r--r--src/net/imap/IMAPFolderStatus.cpp307
-rw-r--r--src/net/imap/IMAPMessage.cpp649
-rw-r--r--src/net/imap/IMAPMessagePart.cpp161
-rw-r--r--src/net/imap/IMAPMessagePartContentHandler.cpp216
-rw-r--r--src/net/imap/IMAPMessageStructure.cpp94
-rw-r--r--src/net/imap/IMAPSStore.cpp79
-rw-r--r--src/net/imap/IMAPServiceInfos.cpp137
-rw-r--r--src/net/imap/IMAPStore.cpp267
-rw-r--r--src/net/imap/IMAPTag.cpp122
-rw-r--r--src/net/imap/IMAPUtils.cpp758
-rw-r--r--src/net/maildir/format/courierMaildirFormat.cpp542
-rw-r--r--src/net/maildir/format/kmailMaildirFormat.cpp320
-rw-r--r--src/net/maildir/maildirFolder.cpp1254
-rw-r--r--src/net/maildir/maildirFolderStatus.cpp88
-rw-r--r--src/net/maildir/maildirFormat.cpp109
-rw-r--r--src/net/maildir/maildirMessage.cpp369
-rw-r--r--src/net/maildir/maildirMessagePart.cpp155
-rw-r--r--src/net/maildir/maildirMessageStructure.cpp98
-rw-r--r--src/net/maildir/maildirServiceInfos.cpp77
-rw-r--r--src/net/maildir/maildirStore.cpp272
-rw-r--r--src/net/maildir/maildirUtils.cpp273
-rw-r--r--src/net/message.cpp150
-rw-r--r--src/net/messageSet.cpp369
-rw-r--r--src/net/pop3/POP3Command.cpp230
-rw-r--r--src/net/pop3/POP3Connection.cpp675
-rw-r--r--src/net/pop3/POP3Folder.cpp729
-rw-r--r--src/net/pop3/POP3FolderStatus.cpp88
-rw-r--r--src/net/pop3/POP3Message.cpp250
-rw-r--r--src/net/pop3/POP3Response.cpp428
-rw-r--r--src/net/pop3/POP3SStore.cpp79
-rw-r--r--src/net/pop3/POP3ServiceInfos.cpp143
-rw-r--r--src/net/pop3/POP3Store.cpp240
-rw-r--r--src/net/pop3/POP3Utils.cpp114
-rw-r--r--src/net/sendmail/sendmailServiceInfos.cpp78
-rw-r--r--src/net/sendmail/sendmailTransport.cpp230
-rw-r--r--src/net/service.cpp152
-rw-r--r--src/net/serviceFactory.cpp145
-rw-r--r--src/net/serviceInfos.cpp167
-rw-r--r--src/net/serviceRegistration.inl98
-rw-r--r--src/net/session.cpp158
-rw-r--r--src/net/smtp/SMTPChunkingOutputStreamAdapter.cpp145
-rw-r--r--src/net/smtp/SMTPCommand.cpp214
-rw-r--r--src/net/smtp/SMTPCommandSet.cpp144
-rw-r--r--src/net/smtp/SMTPConnection.cpp618
-rw-r--r--src/net/smtp/SMTPExceptions.cpp151
-rw-r--r--src/net/smtp/SMTPResponse.cpp334
-rw-r--r--src/net/smtp/SMTPSTransport.cpp79
-rw-r--r--src/net/smtp/SMTPServiceInfos.cpp146
-rw-r--r--src/net/smtp/SMTPTransport.cpp420
-rw-r--r--src/net/tls/TLSProperties.cpp44
-rw-r--r--src/net/tls/TLSSecuredConnectionInfos.cpp72
-rw-r--r--src/net/tls/TLSSession.cpp48
-rw-r--r--src/net/tls/TLSSocket.cpp44
-rw-r--r--src/net/tls/gnutls/TLSProperties_GnuTLS.cpp113
-rw-r--r--src/net/tls/gnutls/TLSSession_GnuTLS.cpp300
-rw-r--r--src/net/tls/gnutls/TLSSocket_GnuTLS.cpp490
-rw-r--r--src/net/tls/openssl/OpenSSLInitializer.cpp142
-rw-r--r--src/net/tls/openssl/TLSProperties_OpenSSL.cpp112
-rw-r--r--src/net/tls/openssl/TLSSession_OpenSSL.cpp135
-rw-r--r--src/net/tls/openssl/TLSSocket_OpenSSL.cpp601
-rw-r--r--src/net/transport.cpp236
68 files changed, 0 insertions, 18307 deletions
diff --git a/src/net/builtinServices.inl b/src/net/builtinServices.inl
deleted file mode 100644
index 9225ff30..00000000
--- a/src/net/builtinServices.inl
+++ /dev/null
@@ -1,76 +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 registration helpers
-#include "src/net/serviceRegistration.inl"
-
-
-#ifndef VMIME_BUILDING_DOC
-
-
-#if VMIME_HAVE_MESSAGING_PROTO_POP3
- #include "vmime/net/pop3/POP3Store.hpp"
- REGISTER_SERVICE(pop3::POP3Store, pop3, TYPE_STORE);
-
- #if VMIME_HAVE_TLS_SUPPORT
- #include "vmime/net/pop3/POP3SStore.hpp"
- REGISTER_SERVICE(pop3::POP3SStore, pop3s, TYPE_STORE);
- #endif // VMIME_HAVE_TLS_SUPPORT
-#endif
-
-
-#if VMIME_HAVE_MESSAGING_PROTO_SMTP
- #include "vmime/net/smtp/SMTPTransport.hpp"
- REGISTER_SERVICE(smtp::SMTPTransport, smtp, TYPE_TRANSPORT);
-
- #if VMIME_HAVE_TLS_SUPPORT
- #include "vmime/net/smtp/SMTPSTransport.hpp"
- REGISTER_SERVICE(smtp::SMTPSTransport, smtps, TYPE_TRANSPORT);
- #endif // VMIME_HAVE_TLS_SUPPORT
-#endif
-
-
-#if VMIME_HAVE_MESSAGING_PROTO_IMAP
- #include "vmime/net/imap/IMAPStore.hpp"
- REGISTER_SERVICE(imap::IMAPStore, imap, TYPE_STORE);
-
- #if VMIME_HAVE_TLS_SUPPORT
- #include "vmime/net/imap/IMAPSStore.hpp"
- REGISTER_SERVICE(imap::IMAPSStore, imaps, TYPE_STORE);
- #endif // VMIME_HAVE_TLS_SUPPORT
-#endif
-
-
-#if VMIME_HAVE_MESSAGING_PROTO_MAILDIR
- #include "vmime/net/maildir/maildirStore.hpp"
- REGISTER_SERVICE(maildir::maildirStore, maildir, TYPE_STORE);
-#endif
-
-#if VMIME_HAVE_MESSAGING_PROTO_SENDMAIL
- #include "vmime/net/sendmail/sendmailTransport.hpp"
- REGISTER_SERVICE(sendmail::sendmailTransport, sendmail, TYPE_TRANSPORT);
-#endif
-
-
-#endif // VMIME_BUILDING_DOC
diff --git a/src/net/defaultConnectionInfos.cpp b/src/net/defaultConnectionInfos.cpp
deleted file mode 100644
index 335e8f6f..00000000
--- a/src/net/defaultConnectionInfos.cpp
+++ /dev/null
@@ -1,60 +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
-
-
-#include "vmime/net/defaultConnectionInfos.hpp"
-
-
-namespace vmime {
-namespace net {
-
-
-defaultConnectionInfos::defaultConnectionInfos(const string& host, const port_t port)
- : m_host(host), m_port(port)
-{
-}
-
-
-const string defaultConnectionInfos::getHost() const
-{
- return m_host;
-}
-
-
-port_t defaultConnectionInfos::getPort() const
-{
- return m_port;
-}
-
-
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES
-
diff --git a/src/net/events.cpp b/src/net/events.cpp
deleted file mode 100644
index a19e1738..00000000
--- a/src/net/events.cpp
+++ /dev/null
@@ -1,166 +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
-
-
-#include "vmime/net/events.hpp"
-#include "vmime/net/folder.hpp"
-
-#include <algorithm>
-
-
-namespace vmime {
-namespace net {
-namespace events {
-
-
-//
-// event
-//
-
-event::event()
-{
-}
-
-
-event::~event()
-{
-}
-
-
-//
-// messageCountEvent
-//
-
-const char* messageCountEvent::EVENT_CLASS = "messageCountEvent";
-
-
-messageCountEvent::messageCountEvent
- (shared_ptr <folder> folder, const Types type, const std::vector <int>& nums)
- : m_folder(folder), m_type(type)
-{
- m_nums.resize(nums.size());
- std::copy(nums.begin(), nums.end(), m_nums.begin());
-}
-
-
-shared_ptr <folder> messageCountEvent::getFolder() const { return (m_folder); }
-messageCountEvent::Types messageCountEvent::getType() const { return (m_type); }
-const std::vector <int>& messageCountEvent::getNumbers() const { return (m_nums); }
-
-
-void messageCountEvent::dispatch(messageCountListener* listener)
-{
- if (m_type == TYPE_ADDED)
- listener->messagesAdded(dynamicCast <messageCountEvent>(shared_from_this()));
- else
- listener->messagesRemoved(dynamicCast <messageCountEvent>(shared_from_this()));
-}
-
-
-const char* messageCountEvent::getClass() const
-{
- return EVENT_CLASS;
-}
-
-
-//
-// messageChangedEvent
-//
-
-const char* messageChangedEvent::EVENT_CLASS = "messageChangedEvent";
-
-
-messageChangedEvent::messageChangedEvent
- (shared_ptr <folder> folder, const Types type, const std::vector <int>& nums)
- : m_folder(folder), m_type(type)
-{
- m_nums.resize(nums.size());
- std::copy(nums.begin(), nums.end(), m_nums.begin());
-}
-
-
-shared_ptr <folder> messageChangedEvent::getFolder() const { return (m_folder); }
-messageChangedEvent::Types messageChangedEvent::getType() const { return (m_type); }
-const std::vector <int>& messageChangedEvent::getNumbers() const { return (m_nums); }
-
-
-void messageChangedEvent::dispatch(messageChangedListener* listener)
-{
- listener->messageChanged(dynamicCast <messageChangedEvent>(shared_from_this()));
-}
-
-
-const char* messageChangedEvent::getClass() const
-{
- return EVENT_CLASS;
-}
-
-
-//
-// folderEvent
-//
-
-const char* folderEvent::EVENT_CLASS = "folderEvent";
-
-
-folderEvent::folderEvent
- (shared_ptr <folder> folder, const Types type,
- const utility::path& oldPath, const utility::path& newPath)
- : m_folder(folder), m_type(type), m_oldPath(oldPath), m_newPath(newPath)
-{
-}
-
-
-shared_ptr <folder> folderEvent::getFolder() const { return (m_folder); }
-folderEvent::Types folderEvent::getType() const { return (m_type); }
-
-
-void folderEvent::dispatch(folderListener* listener)
-{
- switch (m_type)
- {
- case TYPE_CREATED: listener->folderCreated(dynamicCast <folderEvent>(shared_from_this())); break;
- case TYPE_RENAMED: listener->folderRenamed(dynamicCast <folderEvent>(shared_from_this())); break;
- case TYPE_DELETED: listener->folderDeleted(dynamicCast <folderEvent>(shared_from_this())); break;
- }
-}
-
-
-const char* folderEvent::getClass() const
-{
- return EVENT_CLASS;
-}
-
-
-} // events
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES
-
diff --git a/src/net/fetchAttributes.cpp b/src/net/fetchAttributes.cpp
deleted file mode 100644
index 85a41b8c..00000000
--- a/src/net/fetchAttributes.cpp
+++ /dev/null
@@ -1,95 +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
-
-
-#include "vmime/net/fetchAttributes.hpp"
-
-#include "vmime/utility/stringUtils.hpp"
-
-#include <algorithm>
-
-
-namespace vmime {
-namespace net {
-
-
-fetchAttributes::fetchAttributes()
- : m_predefinedAttribs(0)
-{
-}
-
-
-fetchAttributes::fetchAttributes(const int attribs)
- : m_predefinedAttribs(attribs)
-{
-}
-
-
-fetchAttributes::fetchAttributes(const fetchAttributes& attribs)
- : object()
-{
- m_predefinedAttribs = attribs.m_predefinedAttribs;
- m_headers = attribs.m_headers;
-}
-
-
-void fetchAttributes::add(const int attribs)
-{
- m_predefinedAttribs = attribs;
-}
-
-
-void fetchAttributes::add(const string& header)
-{
- m_headers.push_back(utility::stringUtils::toLower(header));
-}
-
-
-bool fetchAttributes::has(const int attribs) const
-{
- return (m_predefinedAttribs & attribs) != 0;
-}
-
-
-bool fetchAttributes::has(const string& header) const
-{
- return std::find(m_headers.begin(), m_headers.end(), utility::stringUtils::toLower(header)) != m_headers.end();
-}
-
-
-const std::vector <string> fetchAttributes::getHeaderFields() const
-{
- return m_headers;
-}
-
-
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES
diff --git a/src/net/folder.cpp b/src/net/folder.cpp
deleted file mode 100644
index 1d6f3140..00000000
--- a/src/net/folder.cpp
+++ /dev/null
@@ -1,127 +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
-
-
-#include "vmime/net/folder.hpp"
-
-#include <algorithm>
-
-
-namespace vmime {
-namespace net {
-
-
-void folder::addMessageChangedListener(events::messageChangedListener* l)
-{
- m_messageChangedListeners.push_back(l);
-}
-
-
-void folder::removeMessageChangedListener(events::messageChangedListener* l)
-{
- std::remove(m_messageChangedListeners.begin(), m_messageChangedListeners.end(), l);
-}
-
-
-void folder::notifyMessageChanged(shared_ptr <events::messageChangedEvent> event)
-{
- for (std::list <events::messageChangedListener*>::iterator
- it = m_messageChangedListeners.begin() ; it != m_messageChangedListeners.end() ; ++it)
- {
- event->dispatch(*it);
- }
-}
-
-
-void folder::addMessageCountListener(events::messageCountListener* l)
-{
- m_messageCountListeners.push_back(l);
-}
-
-
-void folder::removeMessageCountListener(events::messageCountListener* l)
-{
- std::remove(m_messageCountListeners.begin(), m_messageCountListeners.end(), l);
-}
-
-
-void folder::notifyMessageCount(shared_ptr <events::messageCountEvent> event)
-{
- for (std::list <events::messageCountListener*>::iterator
- it = m_messageCountListeners.begin() ; it != m_messageCountListeners.end() ; ++it)
- {
- event->dispatch(*it);
- }
-}
-
-
-void folder::addFolderListener(events::folderListener* l)
-{
- m_folderListeners.push_back(l);
-}
-
-
-void folder::removeFolderListener(events::folderListener* l)
-{
- std::remove(m_folderListeners.begin(), m_folderListeners.end(), l);
-}
-
-
-void folder::notifyFolder(shared_ptr <events::folderEvent> event)
-{
- for (std::list <events::folderListener*>::iterator
- it = m_folderListeners.begin() ; it != m_folderListeners.end() ; ++it)
- {
- event->dispatch(*it);
- }
-}
-
-
-void folder::notifyEvent(shared_ptr <events::event> event)
-{
- if (event->getClass() == events::messageCountEvent::EVENT_CLASS)
- {
- notifyMessageCount(dynamicCast <events::messageCountEvent>(event));
- }
- else if (event->getClass() == events::messageChangedEvent::EVENT_CLASS)
- {
- notifyMessageChanged(dynamicCast <events::messageChangedEvent>(event));
- }
- else if (event->getClass() == events::folderEvent::EVENT_CLASS)
- {
- notifyFolder(dynamicCast <events::folderEvent>(event));
- }
-}
-
-
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES
-
diff --git a/src/net/imap/IMAPConnection.cpp b/src/net/imap/IMAPConnection.cpp
deleted file mode 100644
index 234c2b6a..00000000
--- a/src/net/imap/IMAPConnection.cpp
+++ /dev/null
@@ -1,814 +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_IMAP
-
-
-#include "vmime/net/imap/IMAPTag.hpp"
-#include "vmime/net/imap/IMAPConnection.hpp"
-#include "vmime/net/imap/IMAPUtils.hpp"
-#include "vmime/net/imap/IMAPStore.hpp"
-
-#include "vmime/exception.hpp"
-#include "vmime/platform.hpp"
-
-#include "vmime/utility/stringUtils.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
-
-#include <sstream>
-
-
-// Helpers for service properties
-#define GET_PROPERTY(type, prop) \
- (m_store.lock()->getInfos().getPropertyValue <type>(getSession(), \
- dynamic_cast <const IMAPServiceInfos&>(m_store.lock()->getInfos()).getProperties().prop))
-#define HAS_PROPERTY(prop) \
- (m_store.lock()->getInfos().hasProperty(getSession(), \
- dynamic_cast <const IMAPServiceInfos&>(m_store.lock()->getInfos()).getProperties().prop))
-
-
-namespace vmime {
-namespace net {
-namespace imap {
-
-
-IMAPConnection::IMAPConnection(shared_ptr <IMAPStore> store, shared_ptr <security::authenticator> auth)
- : m_store(store), m_auth(auth), m_socket(null), m_parser(null), m_tag(null),
- m_hierarchySeparator('\0'), m_state(STATE_NONE), m_timeoutHandler(null),
- m_secured(false), m_firstTag(true), m_capabilitiesFetched(false), m_noModSeq(false)
-{
-}
-
-
-IMAPConnection::~IMAPConnection()
-{
- try
- {
- if (isConnected())
- disconnect();
- else if (m_socket)
- internalDisconnect();
- }
- catch (vmime::exception&)
- {
- // Ignore
- }
-}
-
-
-void IMAPConnection::connect()
-{
- if (isConnected())
- throw exceptions::already_connected();
-
- m_state = STATE_NONE;
- m_hierarchySeparator = '\0';
-
- const string address = GET_PROPERTY(string, PROPERTY_SERVER_ADDRESS);
- const port_t port = GET_PROPERTY(port_t, PROPERTY_SERVER_PORT);
-
- shared_ptr <IMAPStore> 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);
-
-#if VMIME_HAVE_TLS_SUPPORT
- if (store->isIMAPS()) // dedicated port/IMAPS
- {
- 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);
-
-
- m_tag = make_shared <IMAPTag>();
- m_parser = make_shared <IMAPParser>(m_tag, m_socket, m_timeoutHandler);
-
-
- setState(STATE_NON_AUTHENTICATED);
-
-
- // Connection greeting
- //
- // eg: C: <connection to server>
- // --- S: * OK mydomain.org IMAP4rev1 v12.256 server ready
-
- std::auto_ptr <IMAPParser::greeting> greet(m_parser->readGreeting());
- bool needAuth = false;
-
- if (greet->resp_cond_bye())
- {
- internalDisconnect();
- throw exceptions::connection_greeting_error(greet->getErrorLog());
- }
- else if (greet->resp_cond_auth()->condition() != IMAPParser::resp_cond_auth::PREAUTH)
- {
- needAuth = true;
- }
-
- if (greet->resp_cond_auth()->resp_text()->resp_text_code() &&
- greet->resp_cond_auth()->resp_text()->resp_text_code()->capability_data())
- {
- processCapabilityResponseData(greet->resp_cond_auth()->resp_text()->resp_text_code()->capability_data());
- }
-
-#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->isIMAPS() && tls) // only if not IMAPS
- {
- try
- {
- startTLS();
- }
- // Non-fatal error
- catch (exceptions::command_error&)
- {
- if (tlsRequired)
- {
- m_state = STATE_NONE;
- throw;
- }
- else
- {
- // TLS is not required, so don't bother
- }
- }
- // Fatal error
- catch (...)
- {
- m_state = STATE_NONE;
- throw;
- }
- }
-#endif // VMIME_HAVE_TLS_SUPPORT
-
- // Authentication
- if (needAuth)
- {
- try
- {
- authenticate();
- }
- catch (...)
- {
- m_state = STATE_NONE;
- throw;
- }
- }
-
- // Get the hierarchy separator character
- initHierarchySeparator();
-
- // Switch to state "Authenticated"
- setState(STATE_AUTHENTICATED);
-}
-
-
-void IMAPConnection::authenticate()
-{
- getAuthenticator()->setService(m_store.lock());
-
-#if VMIME_HAVE_SASL_SUPPORT
- // First, try SASL authentication
- if (GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL))
- {
- try
- {
- authenticateSASL();
- return;
- }
- catch (exceptions::authentication_error& e)
- {
- if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL_FALLBACK))
- {
- // Can't fallback on normal authentication
- internalDisconnect();
- throw e;
- }
- else
- {
- // Ignore, will try normal authentication
- }
- }
- catch (exception& e)
- {
- internalDisconnect();
- throw e;
- }
- }
-#endif // VMIME_HAVE_SASL_SUPPORT
-
- // Normal authentication
- const string username = getAuthenticator()->getUsername();
- const string password = getAuthenticator()->getPassword();
-
- send(true, "LOGIN " + IMAPUtils::quoteString(username)
- + " " + IMAPUtils::quoteString(password), true);
-
- std::auto_ptr <IMAPParser::response> resp(m_parser->readResponse());
-
- if (resp->isBad())
- {
- internalDisconnect();
- throw exceptions::command_error("LOGIN", resp->getErrorLog());
- }
- else if (resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- internalDisconnect();
- throw exceptions::authentication_error(resp->getErrorLog());
- }
-
- // Server capabilities may change when logged in
- if (!processCapabilityResponseData(resp.get()))
- invalidateCapabilities();
-}
-
-
-#if VMIME_HAVE_SASL_SUPPORT
-
-void IMAPConnection::authenticateSASL()
-{
- if (!dynamicCast <security::sasl::SASLAuthenticator>(getAuthenticator()))
- throw exceptions::authentication_error("No SASL authenticator available.");
-
- const std::vector <string> capa = getCapabilities();
- std::vector <string> saslMechs;
-
- for (unsigned int i = 0 ; i < capa.size() ; ++i)
- {
- const string& x = capa[i];
-
- if (x.length() > 5 &&
- (x[0] == 'A' || x[0] == 'a') &&
- (x[1] == 'U' || x[1] == 'u') &&
- (x[2] == 'T' || x[2] == 't') &&
- (x[3] == 'H' || x[3] == 'h') &&
- x[4] == '=')
- {
- saslMechs.push_back(string(x.begin() + 5, x.end()));
- }
- }
-
- 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 =
- make_shared <security::sasl::SASLContext>();
-
- 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("imap", getAuthenticator(), mech);
-
- saslSession->init();
-
- send(true, "AUTHENTICATE " + mech->getName(), true);
-
- for (bool cont = true ; cont ; )
- {
- std::auto_ptr <IMAPParser::response> resp(m_parser->readResponse());
-
- if (resp->response_done() &&
- resp->response_done()->response_tagged() &&
- resp->response_done()->response_tagged()->resp_cond_state()->
- status() == IMAPParser::resp_cond_state::OK)
- {
- m_socket = saslSession->getSecuredSocket(m_socket);
- return;
- }
- else
- {
- std::vector <IMAPParser::continue_req_or_response_data*>
- respDataList = resp->continue_req_or_response_data();
-
- string response;
- bool hasResponse = false;
-
- for (unsigned int i = 0 ; i < respDataList.size() ; ++i)
- {
- if (respDataList[i]->continue_req())
- {
- response = respDataList[i]->continue_req()->resp_text()->text();
- hasResponse = true;
- break;
- }
- }
-
- if (!hasResponse)
- {
- cont = false;
- continue;
- }
-
- byte_t* challenge = 0;
- size_t challengeLen = 0;
-
- byte_t* resp = 0;
- size_t respLen = 0;
-
- try
- {
- // Extract challenge
- saslContext->decodeB64(response, &challenge, &challengeLen);
-
- // Prepare response
- saslSession->evaluateChallenge
- (challenge, challengeLen, &resp, &respLen);
-
- // Send response
- send(false, saslContext->encodeB64(resp, respLen), true);
-
- // Server capabilities may change when logged in
- invalidateCapabilities();
- }
- catch (exceptions::sasl_exception& e)
- {
- if (challenge)
- {
- delete [] challenge;
- challenge = NULL;
- }
-
- if (resp)
- {
- delete [] resp;
- resp = NULL;
- }
-
- // Cancel SASL exchange
- send(false, "*", true);
- }
- catch (...)
- {
- if (challenge)
- delete [] challenge;
-
- if (resp)
- delete [] resp;
-
- throw;
- }
-
- if (challenge)
- delete [] challenge;
-
- if (resp)
- delete [] resp;
- }
- }
- }
-
- throw exceptions::authentication_error
- ("Could not authenticate using SASL: all mechanisms failed.");
-}
-
-#endif // VMIME_HAVE_SASL_SUPPORT
-
-
-#if VMIME_HAVE_TLS_SUPPORT
-
-void IMAPConnection::startTLS()
-{
- try
- {
- send(true, "STARTTLS", true);
-
- std::auto_ptr <IMAPParser::response> resp(m_parser->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error
- ("STARTTLS", resp->getErrorLog(), "bad response");
- }
-
- 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_timeoutHandler);
-
- m_socket = tlsSocket;
- m_parser->setSocket(m_socket);
-
- 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
- // CAPABILITY command. This is necessary to protect against
- // man-in-the-middle attacks which alter the capabilities list prior
- // to STARTTLS. " (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> IMAPConnection::getCapabilities()
-{
- if (!m_capabilitiesFetched)
- fetchCapabilities();
-
- return m_capabilities;
-}
-
-
-bool IMAPConnection::hasCapability(const string& capa)
-{
- if (!m_capabilitiesFetched)
- fetchCapabilities();
-
- const string normCapa = utility::stringUtils::toUpper(capa);
-
- for (size_t i = 0, n = m_capabilities.size() ; i < n ; ++i)
- {
- if (m_capabilities[i] == normCapa)
- return true;
- }
-
- return false;
-}
-
-
-void IMAPConnection::invalidateCapabilities()
-{
- m_capabilities.clear();
- m_capabilitiesFetched = false;
-}
-
-
-void IMAPConnection::fetchCapabilities()
-{
- send(true, "CAPABILITY", true);
-
- std::auto_ptr <IMAPParser::response> resp(m_parser->readResponse());
-
- if (resp->response_done()->response_tagged()->
- resp_cond_state()->status() == IMAPParser::resp_cond_state::OK)
- {
- processCapabilityResponseData(resp.get());
- }
-}
-
-
-bool IMAPConnection::processCapabilityResponseData(const IMAPParser::response* resp)
-{
- const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList =
- resp->continue_req_or_response_data();
-
- for (size_t i = 0 ; i < respDataList.size() ; ++i)
- {
- if (respDataList[i]->response_data() == NULL)
- continue;
-
- const IMAPParser::capability_data* capaData =
- respDataList[i]->response_data()->capability_data();
-
- if (capaData == NULL)
- continue;
-
- processCapabilityResponseData(capaData);
- return true;
- }
-
- return false;
-}
-
-
-void IMAPConnection::processCapabilityResponseData(const IMAPParser::capability_data* capaData)
-{
- std::vector <string> res;
-
- std::vector <IMAPParser::capability*> caps = capaData->capabilities();
-
- for (unsigned int j = 0 ; j < caps.size() ; ++j)
- {
- if (caps[j]->auth_type())
- res.push_back("AUTH=" + caps[j]->auth_type()->name());
- else
- res.push_back(utility::stringUtils::toUpper(caps[j]->atom()->value()));
- }
-
- m_capabilities = res;
- m_capabilitiesFetched = true;
-}
-
-
-shared_ptr <security::authenticator> IMAPConnection::getAuthenticator()
-{
- return m_auth;
-}
-
-
-bool IMAPConnection::isConnected() const
-{
- return (m_socket && m_socket->isConnected() &&
- (m_state == STATE_AUTHENTICATED || m_state == STATE_SELECTED));
-}
-
-
-bool IMAPConnection::isSecuredConnection() const
-{
- return m_secured;
-}
-
-
-shared_ptr <connectionInfos> IMAPConnection::getConnectionInfos() const
-{
- return m_cntInfos;
-}
-
-
-void IMAPConnection::disconnect()
-{
- if (!isConnected())
- throw exceptions::not_connected();
-
- internalDisconnect();
-}
-
-
-void IMAPConnection::internalDisconnect()
-{
- if (isConnected())
- {
- send(true, "LOGOUT", true);
-
- m_socket->disconnect();
- m_socket = null;
- }
-
- m_timeoutHandler = null;
-
- m_state = STATE_LOGOUT;
-
- m_secured = false;
- m_cntInfos = null;
-}
-
-
-void IMAPConnection::initHierarchySeparator()
-{
- send(true, "LIST \"\" \"\"", true);
-
- std::auto_ptr <IMAPParser::response> resp(m_parser->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- internalDisconnect();
- throw exceptions::command_error("LIST", resp->getErrorLog(), "bad response");
- }
-
- const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList =
- resp->continue_req_or_response_data();
-
- bool found = false;
-
- for (unsigned int i = 0 ; !found && i < respDataList.size() ; ++i)
- {
- if (respDataList[i]->response_data() == NULL)
- continue;
-
- const IMAPParser::mailbox_data* mailboxData =
- static_cast <const IMAPParser::response_data*>
- (respDataList[i]->response_data())->mailbox_data();
-
- if (mailboxData == NULL || mailboxData->type() != IMAPParser::mailbox_data::LIST)
- continue;
-
- if (mailboxData->mailbox_list()->quoted_char() != '\0')
- {
- m_hierarchySeparator = mailboxData->mailbox_list()->quoted_char();
- found = true;
- }
- }
-
- if (!found) // default
- m_hierarchySeparator = '/';
-}
-
-
-void IMAPConnection::send(bool tag, const string& what, bool end)
-{
- if (tag && !m_firstTag)
- ++(*m_tag);
-
-#if VMIME_DEBUG
- std::ostringstream oss;
-
- if (tag)
- {
- oss << string(*m_tag);
- oss << " ";
- }
-
- oss << what;
-
- if (end)
- oss << "\r\n";
-
- m_socket->send(oss.str());
-#else
- if (tag)
- {
- m_socket->send(*m_tag);
- m_socket->send(" ");
- }
-
- m_socket->send(what);
-
- if (end)
- {
- m_socket->send("\r\n");
- }
-#endif
-
- if (tag)
- m_firstTag = false;
-}
-
-
-void IMAPConnection::sendRaw(const byte_t* buffer, const size_t count)
-{
- m_socket->sendRaw(buffer, count);
-}
-
-
-IMAPParser::response* IMAPConnection::readResponse(IMAPParser::literalHandler* lh)
-{
- return (m_parser->readResponse(lh));
-}
-
-
-IMAPConnection::ProtocolStates IMAPConnection::state() const
-{
- return (m_state);
-}
-
-
-void IMAPConnection::setState(const ProtocolStates state)
-{
- m_state = state;
-}
-
-
-char IMAPConnection::hierarchySeparator() const
-{
- return (m_hierarchySeparator);
-}
-
-
-shared_ptr <const IMAPStore> IMAPConnection::getStore() const
-{
- return m_store.lock();
-}
-
-
-shared_ptr <IMAPStore> IMAPConnection::getStore()
-{
- return m_store.lock();
-}
-
-
-shared_ptr <session> IMAPConnection::getSession()
-{
- return m_store.lock()->getSession();
-}
-
-
-shared_ptr <const socket> IMAPConnection::getSocket() const
-{
- return m_socket;
-}
-
-
-bool IMAPConnection::isMODSEQDisabled() const
-{
- return m_noModSeq;
-}
-
-
-void IMAPConnection::disableMODSEQ()
-{
- m_noModSeq = true;
-}
-
-
-} // imap
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
-
diff --git a/src/net/imap/IMAPFolder.cpp b/src/net/imap/IMAPFolder.cpp
deleted file mode 100644
index fb98887c..00000000
--- a/src/net/imap/IMAPFolder.cpp
+++ /dev/null
@@ -1,1511 +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_IMAP
-
-
-#include "vmime/net/imap/IMAPFolder.hpp"
-
-#include "vmime/net/imap/IMAPStore.hpp"
-#include "vmime/net/imap/IMAPParser.hpp"
-#include "vmime/net/imap/IMAPMessage.hpp"
-#include "vmime/net/imap/IMAPUtils.hpp"
-#include "vmime/net/imap/IMAPConnection.hpp"
-#include "vmime/net/imap/IMAPFolderStatus.hpp"
-
-#include "vmime/message.hpp"
-
-#include "vmime/exception.hpp"
-
-#include "vmime/utility/outputStreamAdapter.hpp"
-
-#include <algorithm>
-#include <sstream>
-
-
-namespace vmime {
-namespace net {
-namespace imap {
-
-
-IMAPFolder::IMAPFolder(const folder::path& path, shared_ptr <IMAPStore> store, const int type, const int flags)
- : m_store(store), m_connection(store->connection()), m_path(path),
- m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()), m_mode(-1),
- m_open(false), m_type(type), m_flags(flags)
-{
- store->registerFolder(this);
-
- m_status = make_shared <IMAPFolderStatus>();
-}
-
-
-IMAPFolder::~IMAPFolder()
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (store)
- {
- if (m_open)
- close(false);
-
- store->unregisterFolder(this);
- }
- else if (m_open)
- {
- m_connection = null;
- onClose();
- }
-}
-
-
-int IMAPFolder::getMode() const
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- return (m_mode);
-}
-
-
-int IMAPFolder::getType()
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- // Root folder
- if (m_path.isEmpty())
- {
- return (TYPE_CONTAINS_FOLDERS);
- }
- else
- {
- if (m_type == TYPE_UNDEFINED)
- testExistAndGetType();
-
- return (m_type);
- }
-}
-
-
-int IMAPFolder::getFlags()
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- // Root folder
- if (m_path.isEmpty())
- {
- return (FLAG_CHILDREN | FLAG_NO_OPEN);
- }
- else
- {
- if (m_flags == FLAG_UNDEFINED)
- testExistAndGetType();
-
- return (m_flags);
- }
-}
-
-
-const folder::path::component IMAPFolder::getName() const
-{
- return (m_name);
-}
-
-
-const folder::path IMAPFolder::getFullPath() const
-{
- return (m_path);
-}
-
-
-void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable)
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
-
- // Ensure this folder is not already open in the same session
- for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ;
- it != store->m_folders.end() ; ++it)
- {
- if ((*it) != this && (*it)->getFullPath() == m_path)
- throw exceptions::folder_already_open();
- }
-
- // Open a connection for this folder
- shared_ptr <IMAPConnection> connection =
- make_shared <IMAPConnection>(store, store->getAuthenticator());
-
- try
- {
- connection->connect();
-
- // Emit the "SELECT" command
- //
- // Example: C: A142 SELECT INBOX
- // S: * 172 EXISTS
- // S: * 1 RECENT
- // S: * OK [UNSEEN 12] Message 12 is first unseen
- // S: * OK [UIDVALIDITY 3857529045] UIDs valid
- // S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
- // S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited
- // S: A142 OK [READ-WRITE] SELECT completed
-
- std::ostringstream oss;
-
- if (mode == MODE_READ_ONLY)
- oss << "EXAMINE ";
- else
- oss << "SELECT ";
-
- oss << IMAPUtils::quoteString(IMAPUtils::pathToString
- (connection->hierarchySeparator(), getFullPath()));
-
- if (m_connection->hasCapability("CONDSTORE"))
- oss << " (CONDSTORE)";
-
- connection->send(true, oss.str(), true);
-
- // Read the response
- std::auto_ptr <IMAPParser::response> resp(connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("SELECT",
- resp->getErrorLog(), "bad response");
- }
-
- const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList =
- resp->continue_req_or_response_data();
-
- for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
- it = respDataList.begin() ; it != respDataList.end() ; ++it)
- {
- if ((*it)->response_data() == NULL)
- {
- throw exceptions::command_error("SELECT",
- resp->getErrorLog(), "invalid response");
- }
-
- const IMAPParser::response_data* responseData = (*it)->response_data();
-
- // OK Untagged responses: UNSEEN, PERMANENTFLAGS, UIDVALIDITY (optional)
- if (responseData->resp_cond_state())
- {
- const IMAPParser::resp_text_code* code =
- responseData->resp_cond_state()->resp_text()->resp_text_code();
-
- if (code != NULL)
- {
- switch (code->type())
- {
- case IMAPParser::resp_text_code::NOMODSEQ:
-
- connection->disableMODSEQ();
- break;
-
- default:
-
- break;
- }
- }
- }
- // Untagged responses: FLAGS, EXISTS, RECENT (required)
- else if (responseData->mailbox_data())
- {
- switch (responseData->mailbox_data()->type())
- {
- default: break;
-
- case IMAPParser::mailbox_data::FLAGS:
- {
- m_type = IMAPUtils::folderTypeFromFlags
- (responseData->mailbox_data()->mailbox_flag_list());
-
- m_flags = IMAPUtils::folderFlagsFromFlags
- (responseData->mailbox_data()->mailbox_flag_list());
-
- break;
- }
-
- }
- }
- }
-
- processStatusUpdate(resp.get());
-
- // Check for access mode (read-only or read-write)
- const IMAPParser::resp_text_code* respTextCode = resp->response_done()->
- response_tagged()->resp_cond_state()->resp_text()->resp_text_code();
-
- if (respTextCode)
- {
- const int openMode =
- (respTextCode->type() == IMAPParser::resp_text_code::READ_WRITE)
- ? MODE_READ_WRITE : MODE_READ_ONLY;
-
- if (failIfModeIsNotAvailable &&
- mode == MODE_READ_WRITE && openMode == MODE_READ_ONLY)
- {
- throw exceptions::operation_not_supported();
- }
- }
-
-
- m_connection = connection;
- m_open = true;
- m_mode = mode;
- }
- catch (std::exception&)
- {
- throw;
- }
-}
-
-
-void IMAPFolder::close(const bool expunge)
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
-
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- shared_ptr <IMAPConnection> oldConnection = m_connection;
-
- // Emit the "CLOSE" command to expunge messages marked
- // as deleted (this is fastest than "EXPUNGE")
- if (expunge)
- {
- if (m_mode == MODE_READ_ONLY)
- throw exceptions::operation_not_supported();
-
- oldConnection->send(true, "CLOSE", true);
- }
-
- // Close this folder connection
- oldConnection->disconnect();
-
- // Now use default store connection
- m_connection = m_store.lock()->connection();
-
- m_open = false;
- m_mode = -1;
-
- m_status = make_shared <IMAPFolderStatus>();
-
- onClose();
-}
-
-
-void IMAPFolder::onClose()
-{
- for (std::vector <IMAPMessage*>::iterator it = m_messages.begin() ;
- it != m_messages.end() ; ++it)
- {
- (*it)->onFolderClosed();
- }
-
- m_messages.clear();
-}
-
-
-void IMAPFolder::create(const int type)
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (isOpen())
- throw exceptions::illegal_state("Folder is open");
- else if (exists())
- throw exceptions::illegal_state("Folder already exists");
- else if (!store->isValidFolderName(m_name))
- throw exceptions::invalid_folder_name();
-
- // Emit the "CREATE" command
- //
- // Example: C: A003 CREATE owatagusiam/
- // S: A003 OK CREATE completed
- // C: A004 CREATE owatagusiam/blurdybloop
- // S: A004 OK CREATE completed
-
- string mailbox = IMAPUtils::pathToString
- (m_connection->hierarchySeparator(), getFullPath());
-
- if (type & TYPE_CONTAINS_FOLDERS)
- mailbox += m_connection->hierarchySeparator();
-
- std::ostringstream oss;
- oss << "CREATE " << IMAPUtils::quoteString(mailbox);
-
- m_connection->send(true, oss.str(), true);
-
-
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("CREATE",
- resp->getErrorLog(), "bad response");
- }
-
- // Notify folder created
- shared_ptr <events::folderEvent> event =
- make_shared <events::folderEvent>
- (dynamicCast <folder>(shared_from_this()),
- events::folderEvent::TYPE_CREATED, m_path, m_path);
-
- notifyFolder(event);
-}
-
-
-void IMAPFolder::destroy()
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
-
- if (isOpen())
- throw exceptions::illegal_state("Folder is open");
-
- const string mailbox = IMAPUtils::pathToString
- (m_connection->hierarchySeparator(), getFullPath());
-
- std::ostringstream oss;
- oss << "DELETE " << IMAPUtils::quoteString(mailbox);
-
- m_connection->send(true, oss.str(), true);
-
-
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("DELETE",
- resp->getErrorLog(), "bad response");
- }
-
- // Notify folder deleted
- shared_ptr <events::folderEvent> event =
- make_shared <events::folderEvent>
- (dynamicCast <folder>(shared_from_this()),
- events::folderEvent::TYPE_DELETED, m_path, m_path);
-
- notifyFolder(event);
-}
-
-
-bool IMAPFolder::exists()
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!isOpen() && !store)
- throw exceptions::illegal_state("Store disconnected");
-
- return (testExistAndGetType() != TYPE_UNDEFINED);
-}
-
-
-int IMAPFolder::testExistAndGetType()
-{
- m_type = TYPE_UNDEFINED;
-
- // To test whether a folder exists, we simple list it using
- // the "LIST" command, and there should be one unique mailbox
- // with this name...
- //
- // Eg. Test whether '/foo/bar' exists
- //
- // C: a005 list "" foo/bar
- // S: * LIST (\NoSelect) "/" foo/bar
- // S: a005 OK LIST completed
- //
- // ==> OK, exists
- //
- // Test whether '/foo/bar/zap' exists
- //
- // C: a005 list "" foo/bar/zap
- // S: a005 OK LIST completed
- //
- // ==> NO, does not exist
-
- std::ostringstream oss;
- oss << "LIST \"\" ";
- oss << IMAPUtils::quoteString(IMAPUtils::pathToString
- (m_connection->hierarchySeparator(), getFullPath()));
-
- m_connection->send(true, oss.str(), true);
-
-
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("LIST",
- resp->getErrorLog(), "bad response");
- }
-
- // Check whether the result mailbox list contains this folder
- const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList =
- resp->continue_req_or_response_data();
-
- for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
- it = respDataList.begin() ; it != respDataList.end() ; ++it)
- {
- if ((*it)->response_data() == NULL)
- {
- throw exceptions::command_error("LIST",
- resp->getErrorLog(), "invalid response");
- }
-
- const IMAPParser::mailbox_data* mailboxData =
- (*it)->response_data()->mailbox_data();
-
- // We are only interested in responses of type "LIST"
- if (mailboxData != NULL && mailboxData->type() == IMAPParser::mailbox_data::LIST)
- {
- // Get the folder type/flags at the same time
- m_type = IMAPUtils::folderTypeFromFlags
- (mailboxData->mailbox_list()->mailbox_flag_list());
-
- m_flags = IMAPUtils::folderFlagsFromFlags
- (mailboxData->mailbox_list()->mailbox_flag_list());
- }
- }
-
- return (m_type);
-}
-
-
-bool IMAPFolder::isOpen() const
-{
- return (m_open);
-}
-
-
-shared_ptr <message> IMAPFolder::getMessage(const int num)
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- if (num < 1 || num > m_status->getMessageCount())
- throw exceptions::message_not_found();
-
- return make_shared <IMAPMessage>(dynamicCast <IMAPFolder>(shared_from_this()), num);
-}
-
-
-std::vector <shared_ptr <message> > IMAPFolder::getMessages(const messageSet& msgs)
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- if (msgs.isEmpty())
- return std::vector <shared_ptr <message> >();
-
- std::vector <shared_ptr <message> > messages;
-
- if (msgs.isNumberSet())
- {
- const std::vector <int> numbers = IMAPUtils::messageSetToNumberList(msgs);
-
- shared_ptr <IMAPFolder> thisFolder = dynamicCast <IMAPFolder>(shared_from_this());
-
- for (std::vector <int>::const_iterator it = numbers.begin() ; it != numbers.end() ; ++it)
- messages.push_back(make_shared <IMAPMessage>(thisFolder, *it));
- }
- else if (msgs.isUIDSet())
- {
- // C: . UID FETCH uuuu1,uuuu2,uuuu3 UID
- // S: * nnnn1 FETCH (UID uuuu1)
- // S: * nnnn2 FETCH (UID uuuu2)
- // S: * nnnn3 FETCH (UID uuuu3)
- // S: . OK UID FETCH completed
-
- // Prepare command and arguments
- std::ostringstream cmd;
- cmd.imbue(std::locale::classic());
-
- cmd << "UID FETCH " << IMAPUtils::messageSetToSequenceSet(msgs) << " UID";
-
- // Send the request
- m_connection->send(true, cmd.str(), true);
-
- // Get the response
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("UID FETCH ... UID", resp->getErrorLog(), "bad response");
- }
-
- // Process the response
- const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList =
- resp->continue_req_or_response_data();
-
- for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
- it = respDataList.begin() ; it != respDataList.end() ; ++it)
- {
- if ((*it)->response_data() == NULL)
- {
- throw exceptions::command_error("UID FETCH ... UID",
- resp->getErrorLog(), "invalid response");
- }
-
- const IMAPParser::message_data* messageData =
- (*it)->response_data()->message_data();
-
- // We are only interested in responses of type "FETCH"
- if (messageData == NULL || messageData->type() != IMAPParser::message_data::FETCH)
- continue;
-
- // Get Process fetch response for this message
- const int msgNum = static_cast <int>(messageData->number());
- message::uid msgUID;
-
- // Find UID in message attributes
- const std::vector <IMAPParser::msg_att_item*> atts = messageData->msg_att()->items();
-
- for (std::vector <IMAPParser::msg_att_item*>::const_iterator
- it = atts.begin() ; it != atts.end() ; ++it)
- {
- if ((*it)->type() == IMAPParser::msg_att_item::UID)
- {
- msgUID = (*it)->unique_id()->value();
- break;
- }
- }
-
- if (!msgUID.empty())
- {
- shared_ptr <IMAPFolder> thisFolder = dynamicCast <IMAPFolder>(shared_from_this());
- messages.push_back(make_shared <IMAPMessage>(thisFolder, msgNum, msgUID));
- }
- }
- }
-
- return messages;
-}
-
-
-int IMAPFolder::getMessageCount()
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- return m_status->getMessageCount();
-}
-
-
-vmime_uint32 IMAPFolder::getUIDValidity() const
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- return m_status->getUIDValidity();
-}
-
-
-vmime_uint64 IMAPFolder::getHighestModSequence() const
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- return m_status->getHighestModSeq();
-}
-
-
-shared_ptr <folder> IMAPFolder::getFolder(const folder::path::component& name)
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
-
- return make_shared <IMAPFolder>(m_path / name, store);
-}
-
-
-std::vector <shared_ptr <folder> > IMAPFolder::getFolders(const bool recursive)
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!isOpen() && !store)
- throw exceptions::illegal_state("Store disconnected");
-
- // Eg. List folders in '/foo/bar'
- //
- // C: a005 list "foo/bar" *
- // S: * LIST (\NoSelect) "/" foo/bar
- // S: * LIST (\NoInferiors) "/" foo/bar/zap
- // S: a005 OK LIST completed
-
- std::ostringstream oss;
- oss << "LIST ";
-
- const string pathString = IMAPUtils::pathToString
- (m_connection->hierarchySeparator(), getFullPath());
-
- if (recursive)
- {
- oss << IMAPUtils::quoteString(pathString);
- oss << " *";
- }
- else
- {
- if (pathString.empty()) // don't add sep for root folder
- oss << "\"\"";
- else
- oss << IMAPUtils::quoteString(pathString + m_connection->hierarchySeparator());
-
- oss << " %";
- }
-
- m_connection->send(true, oss.str(), true);
-
-
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("LIST", resp->getErrorLog(), "bad response");
- }
-
- const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList =
- resp->continue_req_or_response_data();
-
-
- std::vector <shared_ptr <folder> > v;
-
- for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
- it = respDataList.begin() ; it != respDataList.end() ; ++it)
- {
- if ((*it)->response_data() == NULL)
- {
- throw exceptions::command_error("LIST",
- resp->getErrorLog(), "invalid response");
- }
-
- const IMAPParser::mailbox_data* mailboxData =
- (*it)->response_data()->mailbox_data();
-
- if (mailboxData == NULL || mailboxData->type() != IMAPParser::mailbox_data::LIST)
- continue;
-
- // Get folder path
- const class IMAPParser::mailbox* mailbox =
- mailboxData->mailbox_list()->mailbox();
-
- folder::path path = IMAPUtils::stringToPath
- (mailboxData->mailbox_list()->quoted_char(), mailbox->name());
-
- if (recursive || m_path.isDirectParentOf(path))
- {
- // Append folder to list
- const class IMAPParser::mailbox_flag_list* mailbox_flag_list =
- mailboxData->mailbox_list()->mailbox_flag_list();
-
- v.push_back(make_shared <IMAPFolder>(path, store,
- IMAPUtils::folderTypeFromFlags(mailbox_flag_list),
- IMAPUtils::folderFlagsFromFlags(mailbox_flag_list)));
- }
- }
-
- return (v);
-}
-
-
-void IMAPFolder::fetchMessages(std::vector <shared_ptr <message> >& msg, const fetchAttributes& options,
- utility::progressListener* progress)
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- // Build message numbers list
- std::vector <int> list;
- list.reserve(msg.size());
-
- std::map <int, shared_ptr <IMAPMessage> > numberToMsg;
-
- for (std::vector <shared_ptr <message> >::iterator it = msg.begin() ; it != msg.end() ; ++it)
- {
- list.push_back((*it)->getNumber());
- numberToMsg[(*it)->getNumber()] = dynamicCast <IMAPMessage>(*it);
- }
-
- // Send the request
- const string command = IMAPUtils::buildFetchRequest
- (m_connection, messageSet::byNumber(list), options);
-
- m_connection->send(true, command, true);
-
- // Get the response
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("FETCH",
- resp->getErrorLog(), "bad response");
- }
-
- const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList =
- resp->continue_req_or_response_data();
-
- const size_t total = msg.size();
- size_t current = 0;
-
- if (progress)
- progress->start(total);
-
- try
- {
- for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
- it = respDataList.begin() ; it != respDataList.end() ; ++it)
- {
- if ((*it)->response_data() == NULL)
- {
- throw exceptions::command_error("FETCH",
- resp->getErrorLog(), "invalid response");
- }
-
- const IMAPParser::message_data* messageData =
- (*it)->response_data()->message_data();
-
- // We are only interested in responses of type "FETCH"
- if (messageData == NULL || messageData->type() != IMAPParser::message_data::FETCH)
- continue;
-
- // Process fetch response for this message
- const int num = static_cast <int>(messageData->number());
-
- std::map <int, shared_ptr <IMAPMessage> >::iterator msg = numberToMsg.find(num);
-
- if (msg != numberToMsg.end())
- {
- (*msg).second->processFetchResponse(options, messageData);
-
- if (progress)
- progress->progress(++current, total);
- }
- }
- }
- catch (...)
- {
- if (progress)
- progress->stop(total);
-
- throw;
- }
-
- if (progress)
- progress->stop(total);
-
- processStatusUpdate(resp.get());
-}
-
-
-void IMAPFolder::fetchMessage(shared_ptr <message> msg, const fetchAttributes& options)
-{
- std::vector <shared_ptr <message> > msgs;
- msgs.push_back(msg);
-
- fetchMessages(msgs, options, /* progress */ NULL);
-}
-
-
-int IMAPFolder::getFetchCapabilities() const
-{
- return fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO |
- fetchAttributes::STRUCTURE | fetchAttributes::FLAGS |
- fetchAttributes::SIZE | fetchAttributes::FULL_HEADER |
- fetchAttributes::UID | fetchAttributes::IMPORTANCE;
-}
-
-
-shared_ptr <folder> IMAPFolder::getParent()
-{
- if (m_path.isEmpty())
- return null;
- else
- return make_shared <IMAPFolder>(m_path.getParent(), m_store.lock());
-}
-
-
-shared_ptr <const store> IMAPFolder::getStore() const
-{
- return m_store.lock();
-}
-
-
-shared_ptr <store> IMAPFolder::getStore()
-{
- return m_store.lock();
-}
-
-
-void IMAPFolder::registerMessage(IMAPMessage* msg)
-{
- m_messages.push_back(msg);
-}
-
-
-void IMAPFolder::unregisterMessage(IMAPMessage* msg)
-{
- std::vector <IMAPMessage*>::iterator it =
- std::find(m_messages.begin(), m_messages.end(), msg);
-
- if (it != m_messages.end())
- m_messages.erase(it);
-}
-
-
-void IMAPFolder::onStoreDisconnected()
-{
- m_store.reset();
-}
-
-
-void IMAPFolder::deleteMessages(const messageSet& msgs)
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (msgs.isEmpty())
- throw exceptions::invalid_argument();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
- else if (m_mode == MODE_READ_ONLY)
- throw exceptions::illegal_state("Folder is read-only");
-
- // Build the request text
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- if (msgs.isUIDSet())
- command << "UID STORE " << IMAPUtils::messageSetToSequenceSet(msgs);
- else
- command << "STORE " << IMAPUtils::messageSetToSequenceSet(msgs);
-
- command << " +FLAGS (\\Deleted)";
-
- // Send the request
- m_connection->send(true, command.str(), true);
-
- // Get the response
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("STORE",
- resp->getErrorLog(), "bad response");
- }
-
- processStatusUpdate(resp.get());
-}
-
-
-void IMAPFolder::setMessageFlags(const messageSet& msgs, const int flags, const int mode)
-{
- // Build the request text
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- if (msgs.isUIDSet())
- command << "UID STORE " << IMAPUtils::messageSetToSequenceSet(msgs);
- else
- command << "STORE " << IMAPUtils::messageSetToSequenceSet(msgs);
-
- switch (mode)
- {
- case message::FLAG_MODE_ADD: command << " +FLAGS "; break;
- case message::FLAG_MODE_REMOVE: command << " -FLAGS "; break;
- default:
- case message::FLAG_MODE_SET: command << " FLAGS "; break;
- }
-
- const string flagList = IMAPUtils::messageFlagList(flags);
-
- if (!flagList.empty())
- {
- command << flagList;
-
- // Send the request
- m_connection->send(true, command.str(), true);
-
- // Get the response
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("STORE",
- resp->getErrorLog(), "bad response");
- }
-
- processStatusUpdate(resp.get());
- }
-}
-
-
-void IMAPFolder::addMessage(shared_ptr <vmime::message> msg, const int flags,
- vmime::datetime* date, utility::progressListener* progress)
-{
- std::ostringstream oss;
- utility::outputStreamAdapter ossAdapter(oss);
-
- msg->generate(ossAdapter);
-
- const string& str = oss.str();
- utility::inputStreamStringAdapter strAdapter(str);
-
- addMessage(strAdapter, str.length(), flags, date, progress);
-}
-
-
-void IMAPFolder::addMessage(utility::inputStream& is, const size_t size, const int flags,
- vmime::datetime* date, utility::progressListener* progress)
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
- else if (m_mode == MODE_READ_ONLY)
- throw exceptions::illegal_state("Folder is read-only");
-
- // Build the request text
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- command << "APPEND " << IMAPUtils::quoteString(IMAPUtils::pathToString
- (m_connection->hierarchySeparator(), getFullPath())) << ' ';
-
- const string flagList = IMAPUtils::messageFlagList(flags);
-
- if (flags != message::FLAG_UNDEFINED && !flagList.empty())
- {
- command << flagList;
- command << ' ';
- }
-
- if (date != NULL)
- {
- command << IMAPUtils::dateTime(*date);
- command << ' ';
- }
-
- command << '{' << size << '}';
-
- // Send the request
- m_connection->send(true, command.str(), true);
-
- // Get the response
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- bool ok = false;
- const std::vector <IMAPParser::continue_req_or_response_data*>& respList
- = resp->continue_req_or_response_data();
-
- for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
- it = respList.begin() ; !ok && (it != respList.end()) ; ++it)
- {
- if ((*it)->continue_req())
- ok = true;
- }
-
- if (!ok)
- {
- throw exceptions::command_error("APPEND",
- resp->getErrorLog(), "bad response");
- }
-
- // Send message data
- const size_t total = size;
- size_t current = 0;
-
- if (progress)
- progress->start(total);
-
- const size_t blockSize = std::min(is.getBlockSize(),
- static_cast <size_t>(m_connection->getSocket()->getBlockSize()));
-
- std::vector <byte_t> vbuffer(blockSize);
- byte_t* buffer = &vbuffer.front();
-
- while (!is.eof())
- {
- // Read some data from the input stream
- const size_t read = is.read(buffer, sizeof(buffer));
- current += read;
-
- // Put read data into socket output stream
- m_connection->sendRaw(buffer, read);
-
- // Notify progress
- if (progress)
- progress->progress(current, total);
- }
-
- m_connection->send(false, "", true);
-
- if (progress)
- progress->stop(total);
-
- // Get the response
- std::auto_ptr <IMAPParser::response> finalResp(m_connection->readResponse());
-
- if (finalResp->isBad() || finalResp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("APPEND",
- resp->getErrorLog(), "bad response");
- }
-
- processStatusUpdate(resp.get());
-}
-
-
-void IMAPFolder::expunge()
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
- else if (m_mode == MODE_READ_ONLY)
- throw exceptions::illegal_state("Folder is read-only");
-
- // Send the request
- m_connection->send(true, "EXPUNGE", true);
-
- // Get the response
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("EXPUNGE",
- resp->getErrorLog(), "bad response");
- }
-
- processStatusUpdate(resp.get());
-}
-
-
-void IMAPFolder::rename(const folder::path& newPath)
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (m_path.isEmpty() || newPath.isEmpty())
- throw exceptions::illegal_operation("Cannot rename root folder");
- else if (m_path.getSize() == 1 && m_name.getBuffer() == "INBOX")
- throw exceptions::illegal_operation("Cannot rename 'INBOX' folder");
- else if (!store->isValidFolderName(newPath.getLastComponent()))
- throw exceptions::invalid_folder_name();
-
- // Build the request text
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- command << "RENAME ";
- command << IMAPUtils::quoteString(IMAPUtils::pathToString
- (m_connection->hierarchySeparator(), getFullPath())) << " ";
- command << IMAPUtils::quoteString(IMAPUtils::pathToString
- (m_connection->hierarchySeparator(), newPath));
-
- // Send the request
- m_connection->send(true, command.str(), true);
-
- // Get the response
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("RENAME",
- resp->getErrorLog(), "bad response");
- }
-
- // Notify folder renamed
- folder::path oldPath(m_path);
-
- m_path = newPath;
- m_name = newPath.getLastComponent();
-
- shared_ptr <events::folderEvent> event =
- make_shared <events::folderEvent>
- (dynamicCast <folder>(shared_from_this()),
- events::folderEvent::TYPE_RENAMED, oldPath, newPath);
-
- notifyFolder(event);
-
- // Notify sub-folders
- for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ;
- it != store->m_folders.end() ; ++it)
- {
- if ((*it) != this && oldPath.isParentOf((*it)->getFullPath()))
- {
- folder::path oldPath((*it)->m_path);
-
- (*it)->m_path.renameParent(oldPath, newPath);
-
- shared_ptr <events::folderEvent> event =
- make_shared <events::folderEvent>
- (dynamicCast <folder>((*it)->shared_from_this()),
- events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path);
-
- (*it)->notifyFolder(event);
- }
- }
-
- processStatusUpdate(resp.get());
-}
-
-
-void IMAPFolder::copyMessages(const folder::path& dest, const messageSet& set)
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- // Build the request text
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- command << "COPY " << IMAPUtils::messageSetToSequenceSet(set) << " ";
- command << IMAPUtils::quoteString(IMAPUtils::pathToString
- (m_connection->hierarchySeparator(), dest));
-
- // Send the request
- m_connection->send(true, command.str(), true);
-
- // Get the response
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("COPY",
- resp->getErrorLog(), "bad response");
- }
-
- processStatusUpdate(resp.get());
-}
-
-
-void IMAPFolder::status(int& count, int& unseen)
-{
- count = 0;
- unseen = 0;
-
- shared_ptr <folderStatus> status = getStatus();
-
- count = status->getMessageCount();
- unseen = status->getUnseenCount();
-}
-
-
-shared_ptr <folderStatus> IMAPFolder::getStatus()
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
-
- // Build the request text
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- command << "STATUS ";
- command << IMAPUtils::quoteString(IMAPUtils::pathToString
- (m_connection->hierarchySeparator(), getFullPath()));
- command << " (";
-
- command << "MESSAGES" << ' ' << "UNSEEN" << ' ' << "UIDNEXT" << ' ' << "UIDVALIDITY";
-
- if (m_connection->hasCapability("CONDSTORE"))
- command << ' ' << "HIGHESTMODSEQ";
-
- command << ")";
-
- // Send the request
- m_connection->send(true, command.str(), true);
-
- // Get the response
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("STATUS",
- resp->getErrorLog(), "bad response");
- }
-
- const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList =
- resp->continue_req_or_response_data();
-
- for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
- it = respDataList.begin() ; it != respDataList.end() ; ++it)
- {
- if ((*it)->response_data() != NULL)
- {
- const IMAPParser::response_data* responseData = (*it)->response_data();
-
- if (responseData->mailbox_data() &&
- responseData->mailbox_data()->type() == IMAPParser::mailbox_data::STATUS)
- {
- shared_ptr <IMAPFolderStatus> status = make_shared <IMAPFolderStatus>();
- status->updateFromResponse(responseData->mailbox_data());
-
- m_status->updateFromResponse(responseData->mailbox_data());
-
- return status;
- }
- }
- }
-
- throw exceptions::command_error("STATUS",
- resp->getErrorLog(), "invalid response");
-}
-
-
-void IMAPFolder::noop()
-{
- shared_ptr <IMAPStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
-
- m_connection->send(true, "NOOP", true);
-
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("NOOP", resp->getErrorLog());
- }
-
- processStatusUpdate(resp.get());
-}
-
-
-std::vector <int> IMAPFolder::getMessageNumbersStartingOnUID(const message::uid& uid)
-{
- std::vector<int> v;
-
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- command << "SEARCH UID " << uid << ":*";
-
- // Send the request
- m_connection->send(true, command.str(), true);
-
- // Get the response
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() ||
- resp->response_done()->response_tagged()->resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("SEARCH",
- resp->getErrorLog(), "bad response");
- }
-
- const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList = resp->continue_req_or_response_data();
-
- for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
- it = respDataList.begin() ; it != respDataList.end() ; ++it)
- {
- if ((*it)->response_data() == NULL)
- {
- throw exceptions::command_error("SEARCH",
- resp->getErrorLog(), "invalid response");
- }
-
- const IMAPParser::mailbox_data* mailboxData =
- (*it)->response_data()->mailbox_data();
-
- // We are only interested in responses of type "SEARCH"
- if (mailboxData == NULL ||
- mailboxData->type() != IMAPParser::mailbox_data::SEARCH)
- {
- continue;
- }
-
- for (std::vector <IMAPParser::nz_number*>::const_iterator
- it = mailboxData->search_nz_number_list().begin() ;
- it != mailboxData->search_nz_number_list().end();
- ++it)
- {
- v.push_back((*it)->value());
- }
- }
-
- processStatusUpdate(resp.get());
-
- return v;
-}
-
-
-void IMAPFolder::processStatusUpdate(const IMAPParser::response* resp)
-{
- std::vector <shared_ptr <events::event> > events;
-
- shared_ptr <IMAPFolderStatus> oldStatus = vmime::clone(m_status);
- int expungedMessageCount = 0;
-
- // Process tagged response
- if (resp->response_done() && resp->response_done()->response_tagged() &&
- resp->response_done()->response_tagged()
- ->resp_cond_state()->resp_text()->resp_text_code())
- {
- const IMAPParser::resp_text_code* code =
- resp->response_done()->response_tagged()
- ->resp_cond_state()->resp_text()->resp_text_code();
-
- m_status->updateFromResponse(code);
- }
-
- // Process untagged responses
- for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
- it = resp->continue_req_or_response_data().begin() ;
- it != resp->continue_req_or_response_data().end() ; ++it)
- {
- if ((*it)->response_data() && (*it)->response_data()->resp_cond_state() &&
- (*it)->response_data()->resp_cond_state()->resp_text()->resp_text_code())
- {
- const IMAPParser::resp_text_code* code =
- (*it)->response_data()->resp_cond_state()->resp_text()->resp_text_code();
-
- m_status->updateFromResponse(code);
- }
- else if ((*it)->response_data() && (*it)->response_data()->mailbox_data())
- {
- m_status->updateFromResponse((*it)->response_data()->mailbox_data());
- }
- else if ((*it)->response_data() && (*it)->response_data()->message_data())
- {
- const IMAPParser::message_data* msgData = (*it)->response_data()->message_data();
- const int msgNumber = msgData->number();
-
- if ((*it)->response_data()->message_data()->type() == IMAPParser::message_data::FETCH)
- {
- // Message changed
- for (std::vector <IMAPMessage*>::iterator mit =
- m_messages.begin() ; mit != m_messages.end() ; ++mit)
- {
- if ((*mit)->getNumber() == msgNumber)
- (*mit)->processFetchResponse(/* options */ 0, msgData);
- }
-
- events.push_back(make_shared <events::messageChangedEvent>
- (dynamicCast <folder>(shared_from_this()),
- events::messageChangedEvent::TYPE_FLAGS,
- std::vector <int>(1, msgNumber)));
- }
- else if ((*it)->response_data()->message_data()->type() == IMAPParser::message_data::EXPUNGE)
- {
- // A message has been expunged, renumber messages
- for (std::vector <IMAPMessage*>::iterator jt =
- m_messages.begin() ; jt != m_messages.end() ; ++jt)
- {
- if ((*jt)->getNumber() == msgNumber)
- (*jt)->setExpunged();
- else if ((*jt)->getNumber() > msgNumber)
- (*jt)->renumber((*jt)->getNumber() - 1);
- }
-
- events.push_back(make_shared <events::messageCountEvent>
- (dynamicCast <folder>(shared_from_this()),
- events::messageCountEvent::TYPE_REMOVED,
- std::vector <int>(1, msgNumber)));
-
- expungedMessageCount++;
- }
- }
- }
-
- // New messages arrived
- if (m_status->getMessageCount() > oldStatus->getMessageCount() - expungedMessageCount)
- {
- std::vector <int> newMessageNumbers;
-
- for (int msgNumber = oldStatus->getMessageCount() - expungedMessageCount ;
- msgNumber <= m_status->getMessageCount() ; ++msgNumber)
- {
- newMessageNumbers.push_back(msgNumber);
- }
-
- events.push_back(make_shared <events::messageCountEvent>
- (dynamicCast <folder>(shared_from_this()),
- events::messageCountEvent::TYPE_ADDED,
- newMessageNumbers));
- }
-
- // Dispatch notifications
- for (std::vector <shared_ptr <events::event> >::iterator evit =
- events.begin() ; evit != events.end() ; ++evit)
- {
- notifyEvent(*evit);
- }
-}
-
-
-} // imap
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
-
diff --git a/src/net/imap/IMAPFolderStatus.cpp b/src/net/imap/IMAPFolderStatus.cpp
deleted file mode 100644
index c78a40f3..00000000
--- a/src/net/imap/IMAPFolderStatus.cpp
+++ /dev/null
@@ -1,307 +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_IMAP
-
-
-#include "vmime/net/imap/IMAPFolderStatus.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace imap {
-
-
-IMAPFolderStatus::IMAPFolderStatus()
- : m_count(0),
- m_unseen(0),
- m_recent(0),
- m_uidValidity(0),
- m_uidNext(0),
- m_highestModSeq(0)
-{
-}
-
-
-IMAPFolderStatus::IMAPFolderStatus(const IMAPFolderStatus& other)
- : folderStatus(),
- m_count(other.m_count),
- m_unseen(other.m_unseen),
- m_recent(other.m_recent),
- m_uidValidity(other.m_uidValidity),
- m_uidNext(other.m_uidNext),
- m_highestModSeq(other.m_highestModSeq)
-{
-}
-
-
-unsigned int IMAPFolderStatus::getMessageCount() const
-{
- return m_count;
-}
-
-
-unsigned int IMAPFolderStatus::getUnseenCount() const
-{
- return m_unseen;
-}
-
-
-unsigned int IMAPFolderStatus::getRecentCount() const
-{
- return m_recent;
-}
-
-
-vmime_uint32 IMAPFolderStatus::getUIDValidity() const
-{
- return m_uidValidity;
-}
-
-
-vmime_uint32 IMAPFolderStatus::getUIDNext() const
-{
- return m_uidNext;
-}
-
-
-vmime_uint64 IMAPFolderStatus::getHighestModSeq() const
-{
- return m_highestModSeq;
-}
-
-
-shared_ptr <folderStatus> IMAPFolderStatus::clone() const
-{
- return make_shared <IMAPFolderStatus>(*this);
-}
-
-
-bool IMAPFolderStatus::updateFromResponse(const IMAPParser::mailbox_data* resp)
-{
- bool changed = false;
-
- if (resp->type() == IMAPParser::mailbox_data::STATUS)
- {
- const IMAPParser::status_att_list* statusAttList = resp->status_att_list();
-
- for (std::vector <IMAPParser::status_att_val*>::const_iterator
- jt = statusAttList->values().begin() ; jt != statusAttList->values().end() ; ++jt)
- {
- switch ((*jt)->type())
- {
- case IMAPParser::status_att_val::MESSAGES:
- {
- const unsigned int count =
- static_cast <unsigned int>((*jt)->value_as_number()->value());
-
- if (m_count != count)
- {
- m_count = count;
- changed = true;
- }
-
- break;
- }
- case IMAPParser::status_att_val::UNSEEN:
- {
- const unsigned int unseen =
- static_cast <unsigned int>((*jt)->value_as_number()->value());
-
- if (m_unseen != unseen)
- {
- m_unseen = unseen;
- changed = true;
- }
-
- break;
- }
- case IMAPParser::status_att_val::RECENT:
- {
- const unsigned int recent =
- static_cast <unsigned int>((*jt)->value_as_number()->value());
-
- if (m_recent != recent)
- {
- m_recent = recent;
- changed = true;
- }
-
- break;
- }
- case IMAPParser::status_att_val::UIDNEXT:
- {
- const vmime_uint32 uidNext =
- static_cast <vmime_uint32>((*jt)->value_as_number()->value());
-
- if (m_uidNext != uidNext)
- {
- m_uidNext = uidNext;
- changed = true;
- }
-
- break;
- }
- case IMAPParser::status_att_val::UIDVALIDITY:
- {
- const vmime_uint32 uidValidity =
- static_cast <vmime_uint32>((*jt)->value_as_number()->value());
-
- if (m_uidValidity != uidValidity)
- {
- m_uidValidity = uidValidity;
- changed = true;
- }
-
- break;
- }
- case IMAPParser::status_att_val::HIGHESTMODSEQ:
- {
- const vmime_uint64 highestModSeq =
- static_cast <vmime_uint64>((*jt)->value_as_mod_sequence_value()->value());
-
- if (m_highestModSeq != highestModSeq)
- {
- m_highestModSeq = highestModSeq;
- changed = true;
- }
-
- break;
- }
-
- }
- }
- }
- else if (resp->type() == IMAPParser::mailbox_data::EXISTS)
- {
- const unsigned int count =
- static_cast <unsigned int>(resp->number()->value());
-
- if (m_count != count)
- {
- m_count = count;
- changed = true;
- }
- }
- else if (resp->type() == IMAPParser::mailbox_data::RECENT)
- {
- const unsigned int recent =
- static_cast <unsigned int>(resp->number()->value());
-
- if (m_recent != recent)
- {
- m_recent = recent;
- changed = true;
- }
- }
-
- return changed;
-}
-
-
-bool IMAPFolderStatus::updateFromResponse(const IMAPParser::resp_text_code* resp)
-{
- bool changed = false;
-
- switch (resp->type())
- {
- case IMAPParser::resp_text_code::UIDVALIDITY:
- {
- const vmime_uint32 uidValidity =
- static_cast <vmime_uint32>(resp->nz_number()->value());
-
- if (m_uidValidity != uidValidity)
- {
- m_uidValidity = uidValidity;
- changed = true;
- }
-
- break;
- }
- case IMAPParser::resp_text_code::UIDNEXT:
- {
- const vmime_uint32 uidNext =
- static_cast <vmime_uint32>(resp->nz_number()->value());
-
- if (m_uidNext != uidNext)
- {
- m_uidNext = uidNext;
- changed = true;
- }
-
- break;
- }
- case IMAPParser::resp_text_code::UNSEEN:
- {
- const unsigned int unseen =
- static_cast <unsigned int>(resp->nz_number()->value());
-
- if (m_unseen != unseen)
- {
- m_unseen = unseen;
- changed = true;
- }
-
- break;
- }
- case IMAPParser::resp_text_code::HIGHESTMODSEQ:
- {
- const vmime_uint64 highestModSeq =
- static_cast <vmime_uint64>(resp->mod_sequence_value()->value());
-
- if (m_highestModSeq != highestModSeq)
- {
- m_highestModSeq = highestModSeq;
- changed = true;
- }
-
- break;
- }
- case IMAPParser::resp_text_code::NOMODSEQ:
- {
- if (m_highestModSeq != 0)
- {
- m_highestModSeq = 0;
- changed = true;
- }
-
- break;
- }
- default:
-
- break;
- }
-
- return changed;
-}
-
-
-} // imap
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
diff --git a/src/net/imap/IMAPMessage.cpp b/src/net/imap/IMAPMessage.cpp
deleted file mode 100644
index c11aafc2..00000000
--- a/src/net/imap/IMAPMessage.cpp
+++ /dev/null
@@ -1,649 +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_IMAP
-
-
-#include "vmime/net/imap/IMAPParser.hpp"
-#include "vmime/net/imap/IMAPMessage.hpp"
-#include "vmime/net/imap/IMAPFolder.hpp"
-#include "vmime/net/imap/IMAPFolderStatus.hpp"
-#include "vmime/net/imap/IMAPStore.hpp"
-#include "vmime/net/imap/IMAPConnection.hpp"
-#include "vmime/net/imap/IMAPUtils.hpp"
-#include "vmime/net/imap/IMAPMessageStructure.hpp"
-#include "vmime/net/imap/IMAPMessagePart.hpp"
-#include "vmime/net/imap/IMAPMessagePartContentHandler.hpp"
-
-#include "vmime/utility/outputStreamAdapter.hpp"
-
-#include <sstream>
-#include <iterator>
-#include <typeinfo>
-
-
-namespace vmime {
-namespace net {
-namespace imap {
-
-
-#ifndef VMIME_BUILDING_DOC
-
-//
-// IMAPMessage_literalHandler
-//
-
-class IMAPMessage_literalHandler : public IMAPParser::literalHandler
-{
-public:
-
- IMAPMessage_literalHandler(utility::outputStream& os, utility::progressListener* progress)
- : m_os(os), m_progress(progress)
- {
- }
-
- target* targetFor(const IMAPParser::component& comp, const int /* data */)
- {
- if (typeid(comp) == typeid(IMAPParser::msg_att_item))
- {
- const int type = static_cast
- <const IMAPParser::msg_att_item&>(comp).type();
-
- if (type == IMAPParser::msg_att_item::BODY_SECTION ||
- type == IMAPParser::msg_att_item::RFC822_TEXT)
- {
- return new targetStream(m_progress, m_os);
- }
- }
-
- return (NULL);
- }
-
-private:
-
- utility::outputStream& m_os;
- utility::progressListener* m_progress;
-};
-
-#endif // VMIME_BUILDING_DOC
-
-
-
-//
-// IMAPMessage
-//
-
-
-IMAPMessage::IMAPMessage(shared_ptr <IMAPFolder> folder, const int num)
- : m_folder(folder), m_num(num), m_size(-1U), m_flags(FLAG_UNDEFINED),
- m_expunged(false), m_modseq(0), m_structure(null)
-{
- folder->registerMessage(this);
-}
-
-
-IMAPMessage::IMAPMessage(shared_ptr <IMAPFolder> folder, const int num, const uid& uid)
- : m_folder(folder), m_num(num), m_size(-1), m_flags(FLAG_UNDEFINED),
- m_expunged(false), m_uid(uid), m_modseq(0), m_structure(null)
-{
- folder->registerMessage(this);
-}
-
-
-IMAPMessage::~IMAPMessage()
-{
- shared_ptr <IMAPFolder> folder = m_folder.lock();
-
- if (folder)
- folder->unregisterMessage(this);
-}
-
-
-void IMAPMessage::onFolderClosed()
-{
- m_folder.reset();
-}
-
-
-int IMAPMessage::getNumber() const
-{
- return (m_num);
-}
-
-
-const message::uid IMAPMessage::getUID() const
-{
- return m_uid;
-}
-
-
-vmime_uint64 IMAPMessage::getModSequence() const
-{
- return m_modseq;
-}
-
-
-size_t IMAPMessage::getSize() const
-{
- if (m_size == -1U)
- throw exceptions::unfetched_object();
-
- return (m_size);
-}
-
-
-bool IMAPMessage::isExpunged() const
-{
- return (m_expunged);
-}
-
-
-int IMAPMessage::getFlags() const
-{
- if (m_flags == FLAG_UNDEFINED)
- throw exceptions::unfetched_object();
-
- return (m_flags);
-}
-
-
-shared_ptr <const messageStructure> IMAPMessage::getStructure() const
-{
- if (m_structure == NULL)
- throw exceptions::unfetched_object();
-
- return m_structure;
-}
-
-
-shared_ptr <messageStructure> IMAPMessage::getStructure()
-{
- if (m_structure == NULL)
- throw exceptions::unfetched_object();
-
- return m_structure;
-}
-
-
-shared_ptr <const header> IMAPMessage::getHeader() const
-{
- if (m_header == NULL)
- throw exceptions::unfetched_object();
-
- return (m_header);
-}
-
-
-void IMAPMessage::extract
- (utility::outputStream& os,
- utility::progressListener* progress,
- const size_t start, const size_t length,
- const bool peek) const
-{
- shared_ptr <const IMAPFolder> folder = m_folder.lock();
-
- if (!folder)
- throw exceptions::folder_not_found();
-
- extractImpl(null, os, progress, start, length,
- EXTRACT_HEADER | EXTRACT_BODY | (peek ? EXTRACT_PEEK : 0));
-}
-
-
-void IMAPMessage::extractPart
- (shared_ptr <const messagePart> p,
- utility::outputStream& os,
- utility::progressListener* progress,
- const size_t start, const size_t length,
- const bool peek) const
-{
- shared_ptr <const IMAPFolder> folder = m_folder.lock();
-
- if (!folder)
- throw exceptions::folder_not_found();
-
- extractImpl(p, os, progress, start, length,
- EXTRACT_HEADER | EXTRACT_BODY | (peek ? EXTRACT_PEEK : 0));
-}
-
-
-void IMAPMessage::fetchPartHeader(shared_ptr <messagePart> p)
-{
- shared_ptr <IMAPFolder> folder = m_folder.lock();
-
- if (!folder)
- throw exceptions::folder_not_found();
-
- std::ostringstream oss;
- utility::outputStreamAdapter ossAdapter(oss);
-
- extractImpl(p, ossAdapter, NULL, 0, -1, EXTRACT_HEADER | EXTRACT_PEEK);
-
- dynamicCast <IMAPMessagePart>(p)->getOrCreateHeader().parse(oss.str());
-}
-
-
-void IMAPMessage::fetchPartHeaderForStructure(shared_ptr <messageStructure> str)
-{
- for (size_t i = 0, n = str->getPartCount() ; i < n ; ++i)
- {
- shared_ptr <messagePart> part = str->getPartAt(i);
-
- // Fetch header of current part
- fetchPartHeader(part);
-
- // Fetch header of sub-parts
- fetchPartHeaderForStructure(part->getStructure());
- }
-}
-
-
-void IMAPMessage::extractImpl
- (shared_ptr <const messagePart> p,
- utility::outputStream& os,
- utility::progressListener* progress,
- const size_t start, const size_t length,
- const int extractFlags) const
-{
- shared_ptr <const IMAPFolder> folder = m_folder.lock();
-
- IMAPMessage_literalHandler literalHandler(os, progress);
-
- // Construct section identifier
- std::ostringstream section;
- section.imbue(std::locale::classic());
-
- if (p != NULL)
- {
- shared_ptr <const IMAPMessagePart> currentPart = dynamicCast <const IMAPMessagePart>(p);
- std::vector <int> numbers;
-
- numbers.push_back(currentPart->getNumber());
- currentPart = currentPart->getParent();
-
- while (currentPart != NULL)
- {
- numbers.push_back(currentPart->getNumber());
- currentPart = currentPart->getParent();
- }
-
- numbers.erase(numbers.end() - 1);
-
- for (std::vector <int>::reverse_iterator it = numbers.rbegin() ; it != numbers.rend() ; ++it)
- {
- if (it != numbers.rbegin()) section << ".";
- section << (*it + 1);
- }
- }
-
- // Build the request text
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- if (m_uid.empty())
- command << "FETCH " << m_num << " BODY";
- else
- command << "UID FETCH " << m_uid << " BODY";
-
- /*
- BODY[] header + body
- BODY.PEEK[] header + body (peek)
- BODY[HEADER] header
- BODY.PEEK[HEADER] header (peek)
- BODY[TEXT] body
- BODY.PEEK[TEXT] body (peek)
- */
-
- if (extractFlags & EXTRACT_PEEK)
- command << ".PEEK";
-
- command << "[";
-
- if (section.str().empty())
- {
- // header + body
- if ((extractFlags & EXTRACT_HEADER) && (extractFlags & EXTRACT_BODY))
- command << "";
- // body only
- else if (extractFlags & EXTRACT_BODY)
- command << "TEXT";
- // header only
- else if (extractFlags & EXTRACT_HEADER)
- command << "HEADER";
- }
- else
- {
- command << section.str();
-
- // header + body
- if ((extractFlags & EXTRACT_HEADER) && (extractFlags & EXTRACT_BODY))
- throw exceptions::operation_not_supported();
- // body only
- else if (extractFlags & EXTRACT_BODY)
- command << ".TEXT";
- // header only
- else if (extractFlags & EXTRACT_HEADER)
- command << ".MIME"; // "MIME" not "HEADER" for parts
- }
-
- command << "]";
-
- if (start != 0 || length != static_cast <size_t>(-1))
- command << "<" << start << "." << length << ">";
-
- // Send the request
- constCast <IMAPFolder>(folder)->m_connection->send(true, command.str(), true);
-
- // Get the response
- std::auto_ptr <IMAPParser::response> resp
- (constCast <IMAPFolder>(folder)->m_connection->readResponse(&literalHandler));
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("FETCH",
- resp->getErrorLog(), "bad response");
- }
-
-
- if (extractFlags & EXTRACT_BODY)
- {
- // TODO: update the flags (eg. flag "\Seen" may have been set)
- }
-}
-
-
-int IMAPMessage::processFetchResponse
- (const fetchAttributes& options, const IMAPParser::message_data* msgData)
-{
- shared_ptr <IMAPFolder> folder = m_folder.lock();
-
- // Get message attributes
- const std::vector <IMAPParser::msg_att_item*> atts = msgData->msg_att()->items();
- int changes = 0;
-
- for (std::vector <IMAPParser::msg_att_item*>::const_iterator
- it = atts.begin() ; it != atts.end() ; ++it)
- {
- switch ((*it)->type())
- {
- case IMAPParser::msg_att_item::FLAGS:
- {
- int flags = IMAPUtils::messageFlagsFromFlags((*it)->flag_list());
-
- if (m_flags != flags)
- {
- m_flags = flags;
- changes |= events::messageChangedEvent::TYPE_FLAGS;
- }
-
- break;
- }
- case IMAPParser::msg_att_item::UID:
- {
- m_uid = (*it)->unique_id()->value();
- break;
- }
- case IMAPParser::msg_att_item::MODSEQ:
- {
- m_modseq = (*it)->mod_sequence_value()->value();
- break;
- }
- case IMAPParser::msg_att_item::ENVELOPE:
- {
- if (!options.has(fetchAttributes::FULL_HEADER))
- {
- const IMAPParser::envelope* env = (*it)->envelope();
- shared_ptr <vmime::header> hdr = getOrCreateHeader();
-
- // Date
- hdr->Date()->setValue(env->env_date()->value());
-
- // Subject
- text subject;
- text::decodeAndUnfold(env->env_subject()->value(), &subject);
-
- hdr->Subject()->setValue(subject);
-
- // From
- mailboxList from;
- IMAPUtils::convertAddressList(*(env->env_from()), from);
-
- if (!from.isEmpty())
- hdr->From()->setValue(*(from.getMailboxAt(0)));
-
- // To
- mailboxList to;
- IMAPUtils::convertAddressList(*(env->env_to()), to);
-
- hdr->To()->setValue(to.toAddressList());
-
- // Sender
- mailboxList sender;
- IMAPUtils::convertAddressList(*(env->env_sender()), sender);
-
- if (!sender.isEmpty())
- hdr->Sender()->setValue(*(sender.getMailboxAt(0)));
-
- // Reply-to
- mailboxList replyTo;
- IMAPUtils::convertAddressList(*(env->env_reply_to()), replyTo);
-
- if (!replyTo.isEmpty())
- hdr->ReplyTo()->setValue(*(replyTo.getMailboxAt(0)));
-
- // Cc
- mailboxList cc;
- IMAPUtils::convertAddressList(*(env->env_cc()), cc);
-
- if (!cc.isEmpty())
- hdr->Cc()->setValue(cc);
-
- // Bcc
- mailboxList bcc;
- IMAPUtils::convertAddressList(*(env->env_bcc()), bcc);
-
- if (!bcc.isEmpty())
- hdr->Bcc()->setValue(bcc);
- }
-
- break;
- }
- case IMAPParser::msg_att_item::BODY_STRUCTURE:
- {
- m_structure = make_shared <IMAPMessageStructure>((*it)->body());
- break;
- }
- case IMAPParser::msg_att_item::RFC822_HEADER:
- {
- getOrCreateHeader()->parse((*it)->nstring()->value());
- break;
- }
- case IMAPParser::msg_att_item::RFC822_SIZE:
- {
- m_size = static_cast <size_t>((*it)->number()->value());
- break;
- }
- case IMAPParser::msg_att_item::BODY_SECTION:
- {
- if (!options.has(fetchAttributes::FULL_HEADER))
- {
- if ((*it)->section()->section_text1() &&
- (*it)->section()->section_text1()->type()
- == IMAPParser::section_text::HEADER_FIELDS)
- {
- header tempHeader;
- tempHeader.parse((*it)->nstring()->value());
-
- vmime::header& hdr = *getOrCreateHeader();
- std::vector <shared_ptr <headerField> > fields = tempHeader.getFieldList();
-
- for (std::vector <shared_ptr <headerField> >::const_iterator jt = fields.begin() ;
- jt != fields.end() ; ++jt)
- {
- hdr.appendField(vmime::clone(*jt));
- }
- }
- }
-
- break;
- }
- case IMAPParser::msg_att_item::INTERNALDATE:
- case IMAPParser::msg_att_item::RFC822:
- case IMAPParser::msg_att_item::RFC822_TEXT:
- case IMAPParser::msg_att_item::BODY:
- {
- break;
- }
-
- }
- }
-
- return changes;
-}
-
-
-shared_ptr <header> IMAPMessage::getOrCreateHeader()
-{
- if (m_header != NULL)
- return (m_header);
- else
- return (m_header = make_shared <header>());
-}
-
-
-void IMAPMessage::setFlags(const int flags, const int mode)
-{
- shared_ptr <IMAPFolder> folder = m_folder.lock();
-
- if (!folder)
- throw exceptions::folder_not_found();
-
- if (!m_uid.empty())
- folder->setMessageFlags(messageSet::byUID(m_uid), flags, mode);
- else
- folder->setMessageFlags(messageSet::byNumber(m_num), flags, mode);
-}
-
-
-void IMAPMessage::constructParsedMessage
- (shared_ptr <bodyPart> parentPart, shared_ptr <messageStructure> str, int level)
-{
- if (level == 0)
- {
- shared_ptr <messagePart> part = str->getPartAt(0);
-
- // Copy header
- shared_ptr <const header> hdr = part->getHeader();
- parentPart->getHeader()->copyFrom(*hdr);
-
- // Initialize body
- parentPart->getBody()->setContents
- (make_shared <IMAPMessagePartContentHandler>
- (dynamicCast <IMAPMessage>(shared_from_this()),
- part, parentPart->getBody()->getEncoding()));
-
- constructParsedMessage(parentPart, part->getStructure(), 1);
- }
- else
- {
- for (size_t i = 0, n = str->getPartCount() ; i < n ; ++i)
- {
- shared_ptr <messagePart> part = str->getPartAt(i);
-
- shared_ptr <bodyPart> childPart = make_shared <bodyPart>();
-
- // Copy header
- shared_ptr <const header> hdr = part->getHeader();
- childPart->getHeader()->copyFrom(*hdr);
-
- // Initialize body
- childPart->getBody()->setContents
- (make_shared <IMAPMessagePartContentHandler>
- (dynamicCast <IMAPMessage>(shared_from_this()),
- part, childPart->getBody()->getEncoding()));
-
- // Add child part
- parentPart->getBody()->appendPart(childPart);
-
- // Construct sub parts
- constructParsedMessage(childPart, part->getStructure(), ++level);
- }
- }
-}
-
-
-shared_ptr <vmime::message> IMAPMessage::getParsedMessage()
-{
- // Fetch structure
- shared_ptr <messageStructure> structure;
-
- try
- {
- structure = getStructure();
- }
- catch (exceptions::unfetched_object&)
- {
- std::vector <shared_ptr <message> > msgs;
- msgs.push_back(dynamicCast <IMAPMessage>(shared_from_this()));
-
- m_folder.lock()->fetchMessages
- (msgs, fetchAttributes(fetchAttributes::STRUCTURE), /* progress */ NULL);
-
- structure = getStructure();
- }
-
- // Fetch header for each part
- fetchPartHeaderForStructure(structure);
-
- // Construct message from structure
- shared_ptr <vmime::message> msg = make_shared <vmime::message>();
-
- constructParsedMessage(msg, structure);
-
- return msg;
-}
-
-
-void IMAPMessage::renumber(const int number)
-{
- m_num = number;
-}
-
-
-void IMAPMessage::setExpunged()
-{
- m_expunged = true;
-}
-
-
-} // imap
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
-
diff --git a/src/net/imap/IMAPMessagePart.cpp b/src/net/imap/IMAPMessagePart.cpp
deleted file mode 100644
index eed885dc..00000000
--- a/src/net/imap/IMAPMessagePart.cpp
+++ /dev/null
@@ -1,161 +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_IMAP
-
-
-#include "vmime/net/imap/IMAPMessagePart.hpp"
-#include "vmime/net/imap/IMAPMessageStructure.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace imap {
-
-
-IMAPMessagePart::IMAPMessagePart(shared_ptr <IMAPMessagePart> parent, const int number, const IMAPParser::body_type_mpart* mpart)
- : m_parent(parent), m_header(null), m_number(number), m_size(0)
-{
- m_mediaType = vmime::mediaType
- ("multipart", mpart->media_subtype()->value());
-}
-
-
-IMAPMessagePart::IMAPMessagePart(shared_ptr <IMAPMessagePart> parent, const int number, const IMAPParser::body_type_1part* part)
- : m_parent(parent), m_header(null), m_number(number), m_size(0)
-{
- if (part->body_type_text())
- {
- m_mediaType = vmime::mediaType
- ("text", part->body_type_text()->
- media_text()->media_subtype()->value());
-
- m_size = part->body_type_text()->body_fields()->body_fld_octets()->value();
- }
- else if (part->body_type_msg())
- {
- m_mediaType = vmime::mediaType
- ("message", part->body_type_msg()->
- media_message()->media_subtype()->value());
- }
- else
- {
- m_mediaType = vmime::mediaType
- (part->body_type_basic()->media_basic()->media_type()->value(),
- part->body_type_basic()->media_basic()->media_subtype()->value());
-
- m_size = part->body_type_basic()->body_fields()->body_fld_octets()->value();
- }
-
- m_structure = null;
-}
-
-
-shared_ptr <const messageStructure> IMAPMessagePart::getStructure() const
-{
- if (m_structure != NULL)
- return m_structure;
- else
- return IMAPMessageStructure::emptyStructure();
-}
-
-
-shared_ptr <messageStructure> IMAPMessagePart::getStructure()
-{
- if (m_structure != NULL)
- return m_structure;
- else
- return IMAPMessageStructure::emptyStructure();
-}
-
-
-shared_ptr <const IMAPMessagePart> IMAPMessagePart::getParent() const
-{
- return m_parent.lock();
-}
-
-
-const mediaType& IMAPMessagePart::getType() const
-{
- return m_mediaType;
-}
-
-
-size_t IMAPMessagePart::getSize() const
-{
- return m_size;
-}
-
-
-int IMAPMessagePart::getNumber() const
-{
- return m_number;
-}
-
-
-shared_ptr <const header> IMAPMessagePart::getHeader() const
-{
- if (m_header == NULL)
- throw exceptions::unfetched_object();
- else
- return m_header;
-}
-
-
-// static
-shared_ptr <IMAPMessagePart> IMAPMessagePart::create
- (shared_ptr <IMAPMessagePart> parent, const int number, const IMAPParser::body* body)
-{
- if (body->body_type_mpart())
- {
- shared_ptr <IMAPMessagePart> part = make_shared <IMAPMessagePart>(parent, number, body->body_type_mpart());
- part->m_structure = make_shared <IMAPMessageStructure>(part, body->body_type_mpart()->list());
-
- return part;
- }
- else
- {
- return make_shared <IMAPMessagePart>(parent, number, body->body_type_1part());
- }
-}
-
-
-header& IMAPMessagePart::getOrCreateHeader()
-{
- if (m_header != NULL)
- return *m_header;
- else
- return *(m_header = make_shared <header>());
-}
-
-
-} // imap
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
-
diff --git a/src/net/imap/IMAPMessagePartContentHandler.cpp b/src/net/imap/IMAPMessagePartContentHandler.cpp
deleted file mode 100644
index 1f53f082..00000000
--- a/src/net/imap/IMAPMessagePartContentHandler.cpp
+++ /dev/null
@@ -1,216 +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_IMAP
-
-
-#include "vmime/net/imap/IMAPMessagePartContentHandler.hpp"
-#include "vmime/net/imap/IMAPFolder.hpp"
-#include "vmime/net/imap/IMAPConnection.hpp"
-#include "vmime/net/imap/IMAPFolderStatus.hpp"
-#include "vmime/net/imap/IMAPStore.hpp"
-
-#include "vmime/utility/outputStreamAdapter.hpp"
-#include "vmime/utility/inputStreamStringProxyAdapter.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace imap {
-
-
-IMAPMessagePartContentHandler::IMAPMessagePartContentHandler
- (shared_ptr <IMAPMessage> msg, shared_ptr <messagePart> part, const vmime::encoding& encoding)
- : m_message(msg), m_part(part), m_encoding(encoding)
-{
-}
-
-
-shared_ptr <contentHandler> IMAPMessagePartContentHandler::clone() const
-{
- return make_shared <IMAPMessagePartContentHandler>
- (constCast <IMAPMessage>(m_message.lock()),
- constCast <messagePart>(m_part.lock()),
- m_encoding);
-}
-
-
-void IMAPMessagePartContentHandler::generate
- (utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength) const
-{
- shared_ptr <IMAPMessage> msg = constCast <IMAPMessage>(m_message.lock());
- shared_ptr <messagePart> part = constCast <messagePart>(m_part.lock());
-
- // Data is already encoded
- if (isEncoded())
- {
- // The data is already encoded but the encoding specified for
- // the generation is different from the current one. We need
- // to re-encode data: decode from input buffer to temporary
- // buffer, and then re-encode to output stream...
- if (m_encoding != enc)
- {
- // Extract part contents to temporary buffer
- std::ostringstream oss;
- utility::outputStreamAdapter tmp(oss);
-
- msg->extractPart(part, tmp, NULL);
-
- // Decode to another temporary buffer
- utility::inputStreamStringProxyAdapter in(oss.str());
-
- std::ostringstream oss2;
- utility::outputStreamAdapter tmp2(oss2);
-
- shared_ptr <utility::encoder::encoder> theDecoder = m_encoding.getEncoder();
- theDecoder->decode(in, tmp2);
-
- // Reencode to output stream
- string str = oss2.str();
- utility::inputStreamStringAdapter tempIn(str);
-
- shared_ptr <utility::encoder::encoder> theEncoder = enc.getEncoder();
- theEncoder->getProperties()["maxlinelength"] = maxLineLength;
- theEncoder->getProperties()["text"] = (m_contentType.getType() == mediaTypes::TEXT);
-
- theEncoder->encode(tempIn, os);
- }
- // No encoding to perform
- else
- {
- msg->extractPart(part, os);
- }
- }
- // Need to encode data before
- else
- {
- // Extract part contents to temporary buffer
- std::ostringstream oss;
- utility::outputStreamAdapter tmp(oss);
-
- msg->extractPart(part, tmp, NULL);
-
- // Encode temporary buffer to output stream
- shared_ptr <utility::encoder::encoder> theEncoder = enc.getEncoder();
- theEncoder->getProperties()["maxlinelength"] = maxLineLength;
- theEncoder->getProperties()["text"] = (m_contentType.getType() == mediaTypes::TEXT);
-
- utility::inputStreamStringAdapter is(oss.str());
-
- theEncoder->encode(is, os);
- }
-}
-
-
-void IMAPMessagePartContentHandler::extract
- (utility::outputStream& os, utility::progressListener* progress) const
-{
- shared_ptr <IMAPMessage> msg = constCast <IMAPMessage>(m_message.lock());
- shared_ptr <messagePart> part = constCast <messagePart>(m_part.lock());
-
- // No decoding to perform
- if (!isEncoded())
- {
- msg->extractImpl(part, os, progress, 0, -1, IMAPMessage::EXTRACT_BODY);
- }
- // Need to decode data
- else
- {
- // Extract part contents to temporary buffer
- std::ostringstream oss;
- utility::outputStreamAdapter tmp(oss);
-
- msg->extractImpl(part, tmp, NULL, 0, -1, IMAPMessage::EXTRACT_BODY);
-
- // Encode temporary buffer to output stream
- utility::inputStreamStringAdapter is(oss.str());
- utility::progressListenerSizeAdapter plsa(progress, getLength());
-
- shared_ptr <utility::encoder::encoder> theDecoder = m_encoding.getEncoder();
- theDecoder->decode(is, os, &plsa);
- }
-}
-
-
-void IMAPMessagePartContentHandler::extractRaw
- (utility::outputStream& os, utility::progressListener* progress) const
-{
- shared_ptr <IMAPMessage> msg = constCast <IMAPMessage>(m_message.lock());
- shared_ptr <messagePart> part = constCast <messagePart>(m_part.lock());
-
- msg->extractPart(part, os, progress);
-}
-
-
-size_t IMAPMessagePartContentHandler::getLength() const
-{
- return m_part.lock()->getSize();
-}
-
-
-bool IMAPMessagePartContentHandler::isEncoded() const
-{
- return m_encoding != NO_ENCODING;
-}
-
-
-const vmime::encoding& IMAPMessagePartContentHandler::getEncoding() const
-{
- return m_encoding;
-}
-
-
-bool IMAPMessagePartContentHandler::isEmpty() const
-{
- return getLength() == 0;
-}
-
-
-bool IMAPMessagePartContentHandler::isBuffered() const
-{
- return true;
-}
-
-
-void IMAPMessagePartContentHandler::setContentTypeHint(const mediaType& type)
-{
- m_contentType = type;
-}
-
-
-const mediaType IMAPMessagePartContentHandler::getContentTypeHint() const
-{
- return m_contentType;
-}
-
-
-} // imap
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
-
diff --git a/src/net/imap/IMAPMessageStructure.cpp b/src/net/imap/IMAPMessageStructure.cpp
deleted file mode 100644
index 8dc333e9..00000000
--- a/src/net/imap/IMAPMessageStructure.cpp
+++ /dev/null
@@ -1,94 +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_IMAP
-
-
-#include "vmime/net/imap/IMAPMessageStructure.hpp"
-#include "vmime/net/imap/IMAPMessagePart.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace imap {
-
-
-IMAPMessageStructure::IMAPMessageStructure()
-{
-}
-
-
-IMAPMessageStructure::IMAPMessageStructure(const IMAPParser::body* body)
-{
- m_parts.push_back(IMAPMessagePart::create(null, 0, body));
-}
-
-
-IMAPMessageStructure::IMAPMessageStructure(shared_ptr <IMAPMessagePart> parent, const std::vector <IMAPParser::body*>& list)
-{
- int number = 0;
-
- for (std::vector <IMAPParser::body*>::const_iterator
- it = list.begin() ; it != list.end() ; ++it, ++number)
- {
- m_parts.push_back(IMAPMessagePart::create(parent, number, *it));
- }
-}
-
-
-shared_ptr <const messagePart> IMAPMessageStructure::getPartAt(const size_t x) const
-{
- return m_parts[x];
-}
-
-
-shared_ptr <messagePart> IMAPMessageStructure::getPartAt(const size_t x)
-{
- return m_parts[x];
-}
-
-
-size_t IMAPMessageStructure::getPartCount() const
-{
- return m_parts.size();
-}
-
-
-// static
-shared_ptr <IMAPMessageStructure> IMAPMessageStructure::emptyStructure()
-{
- static shared_ptr <IMAPMessageStructure> emptyStructure = make_shared <IMAPMessageStructure>();
- return emptyStructure;
-}
-
-
-} // imap
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
-
diff --git a/src/net/imap/IMAPSStore.cpp b/src/net/imap/IMAPSStore.cpp
deleted file mode 100644
index c9e64f5b..00000000
--- a/src/net/imap/IMAPSStore.cpp
+++ /dev/null
@@ -1,79 +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_IMAP
-
-
-#include "vmime/net/imap/IMAPSStore.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace imap {
-
-
-IMAPSStore::IMAPSStore(shared_ptr <session> sess, shared_ptr <security::authenticator> auth)
- : IMAPStore(sess, auth, true)
-{
-}
-
-
-IMAPSStore::~IMAPSStore()
-{
-}
-
-
-const string IMAPSStore::getProtocolName() const
-{
- return "imaps";
-}
-
-
-
-// Service infos
-
-IMAPServiceInfos IMAPSStore::sm_infos(true);
-
-
-const serviceInfos& IMAPSStore::getInfosInstance()
-{
- return sm_infos;
-}
-
-
-const serviceInfos& IMAPSStore::getInfos() const
-{
- return sm_infos;
-}
-
-
-} // imap
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
-
diff --git a/src/net/imap/IMAPServiceInfos.cpp b/src/net/imap/IMAPServiceInfos.cpp
deleted file mode 100644
index 46dbc2e1..00000000
--- a/src/net/imap/IMAPServiceInfos.cpp
+++ /dev/null
@@ -1,137 +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_IMAP
-
-
-#include "vmime/net/imap/IMAPServiceInfos.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace imap {
-
-
-IMAPServiceInfos::IMAPServiceInfos(const bool imaps)
- : m_imaps(imaps)
-{
-}
-
-
-const string IMAPServiceInfos::getPropertyPrefix() const
-{
- if (m_imaps)
- return "store.imaps.";
- else
- return "store.imap.";
-}
-
-
-const IMAPServiceInfos::props& IMAPServiceInfos::getProperties() const
-{
- static props imapProps =
- {
- // IMAP-specific options
-#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, "143"),
- };
-
- static props imapsProps =
- {
- // IMAP-specific options
-#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, "993"),
- };
-
- return m_imaps ? imapsProps : imapProps;
-}
-
-
-const std::vector <serviceInfos::property> IMAPServiceInfos::getAvailableProperties() const
-{
- std::vector <property> list;
- const props& p = getProperties();
-
- // IMAP-specific options
-#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_imaps)
- {
- 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;
-}
-
-
-} // imap
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
-
diff --git a/src/net/imap/IMAPStore.cpp b/src/net/imap/IMAPStore.cpp
deleted file mode 100644
index a1a8c9ca..00000000
--- a/src/net/imap/IMAPStore.cpp
+++ /dev/null
@@ -1,267 +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_IMAP
-
-
-#include "vmime/net/imap/IMAPStore.hpp"
-#include "vmime/net/imap/IMAPFolder.hpp"
-#include "vmime/net/imap/IMAPConnection.hpp"
-#include "vmime/net/imap/IMAPFolderStatus.hpp"
-
-#include "vmime/exception.hpp"
-#include "vmime/platform.hpp"
-
-#include <map>
-
-
-namespace vmime {
-namespace net {
-namespace imap {
-
-
-IMAPStore::IMAPStore(shared_ptr <session> sess, shared_ptr <security::authenticator> auth, const bool secured)
- : store(sess, getInfosInstance(), auth), m_connection(null), m_isIMAPS(secured)
-{
-}
-
-
-IMAPStore::~IMAPStore()
-{
- try
- {
- if (isConnected())
- disconnect();
- }
- catch (vmime::exception&)
- {
- // Ignore
- }
-}
-
-
-const string IMAPStore::getProtocolName() const
-{
- return "imap";
-}
-
-
-shared_ptr <folder> IMAPStore::getRootFolder()
-{
- if (!isConnected())
- throw exceptions::illegal_state("Not connected");
-
- return make_shared <IMAPFolder>
- (folder::path(),
- dynamicCast <IMAPStore>(shared_from_this()));
-}
-
-
-shared_ptr <folder> IMAPStore::getDefaultFolder()
-{
- if (!isConnected())
- throw exceptions::illegal_state("Not connected");
-
- return make_shared <IMAPFolder>
- (folder::path::component("INBOX"),
- dynamicCast <IMAPStore>(shared_from_this()));
-}
-
-
-shared_ptr <folder> IMAPStore::getFolder(const folder::path& path)
-{
- if (!isConnected())
- throw exceptions::illegal_state("Not connected");
-
- return make_shared <IMAPFolder>
- (path, dynamicCast <IMAPStore>(shared_from_this()));
-}
-
-
-bool IMAPStore::isValidFolderName(const folder::path::component& /* name */) const
-{
- return true;
-}
-
-
-void IMAPStore::connect()
-{
- if (isConnected())
- throw exceptions::already_connected();
-
- m_connection = make_shared <IMAPConnection>
- (dynamicCast <IMAPStore>(shared_from_this()), getAuthenticator());
-
- try
- {
- m_connection->connect();
- }
- catch (std::exception&)
- {
- m_connection = null;
- throw;
- }
-}
-
-
-bool IMAPStore::isConnected() const
-{
- return (m_connection && m_connection->isConnected());
-}
-
-
-bool IMAPStore::isIMAPS() const
-{
- return m_isIMAPS;
-}
-
-
-bool IMAPStore::isSecuredConnection() const
-{
- if (m_connection == NULL)
- return false;
-
- return m_connection->isSecuredConnection();
-}
-
-
-shared_ptr <connectionInfos> IMAPStore::getConnectionInfos() const
-{
- if (m_connection == NULL)
- return null;
-
- return m_connection->getConnectionInfos();
-}
-
-
-shared_ptr <IMAPConnection> IMAPStore::getConnection()
-{
- return m_connection;
-}
-
-
-void IMAPStore::disconnect()
-{
- if (!isConnected())
- throw exceptions::not_connected();
-
- for (std::list <IMAPFolder*>::iterator it = m_folders.begin() ;
- it != m_folders.end() ; ++it)
- {
- (*it)->onStoreDisconnected();
- }
-
- m_folders.clear();
-
-
- m_connection->disconnect();
-
- m_connection = null;
-}
-
-
-void IMAPStore::noop()
-{
- if (!isConnected())
- throw exceptions::not_connected();
-
- m_connection->send(true, "NOOP", true);
-
- std::auto_ptr <IMAPParser::response> resp(m_connection->readResponse());
-
- if (resp->isBad() || resp->response_done()->response_tagged()->
- resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
- {
- throw exceptions::command_error("NOOP", resp->getErrorLog());
- }
-
-
- for (std::list <IMAPFolder*>::iterator it = m_folders.begin() ;
- it != m_folders.end() ; ++it)
- {
- if ((*it)->isOpen())
- (*it)->noop();
- }
-}
-
-
-shared_ptr <IMAPConnection> IMAPStore::connection()
-{
- return (m_connection);
-}
-
-
-void IMAPStore::registerFolder(IMAPFolder* folder)
-{
- m_folders.push_back(folder);
-}
-
-
-void IMAPStore::unregisterFolder(IMAPFolder* folder)
-{
- std::list <IMAPFolder*>::iterator it = std::find(m_folders.begin(), m_folders.end(), folder);
- if (it != m_folders.end()) m_folders.erase(it);
-}
-
-
-int IMAPStore::getCapabilities() const
-{
- return (CAPABILITY_CREATE_FOLDER |
- CAPABILITY_RENAME_FOLDER |
- CAPABILITY_ADD_MESSAGE |
- CAPABILITY_COPY_MESSAGE |
- CAPABILITY_DELETE_MESSAGE |
- CAPABILITY_PARTIAL_FETCH |
- CAPABILITY_MESSAGE_FLAGS |
- CAPABILITY_EXTRACT_PART);
-}
-
-
-
-// Service infos
-
-IMAPServiceInfos IMAPStore::sm_infos(false);
-
-
-const serviceInfos& IMAPStore::getInfosInstance()
-{
- return sm_infos;
-}
-
-
-const serviceInfos& IMAPStore::getInfos() const
-{
- return sm_infos;
-}
-
-
-} // imap
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
-
diff --git a/src/net/imap/IMAPTag.cpp b/src/net/imap/IMAPTag.cpp
deleted file mode 100644
index 14d12788..00000000
--- a/src/net/imap/IMAPTag.cpp
+++ /dev/null
@@ -1,122 +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_IMAP
-
-
-#include "vmime/net/imap/IMAPTag.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace imap {
-
-
-const int IMAPTag::sm_maxNumber = 52 * 10 * 10 * 10;
-
-
-IMAPTag::IMAPTag(const int number)
- : m_number(number)
-{
- m_tag.resize(4);
- generate();
-}
-
-
-IMAPTag::IMAPTag(const IMAPTag& tag)
- : object(), m_number(tag.m_number)
-{
- m_tag.resize(4);
- generate();
-}
-
-
-IMAPTag::IMAPTag()
- : m_number(1)
-{
- m_tag.resize(4);
- generate();
-}
-
-
-IMAPTag& IMAPTag::operator++()
-{
- ++m_number;
-
- if (m_number >= sm_maxNumber)
- m_number = 1;
-
- generate();
-
- return (*this);
-}
-
-
-const IMAPTag IMAPTag::operator++(int)
-{
- IMAPTag old(*this);
- operator++();
- return (old);
-}
-
-
-int IMAPTag::maximumNumber() const
-{
- return sm_maxNumber - 1;
-}
-
-
-int IMAPTag::number() const
-{
- return (m_number);
-}
-
-
-IMAPTag::operator string() const
-{
- return (m_tag);
-}
-
-
-void IMAPTag::generate()
-{
- static const char prefixChars[53] =
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
- m_tag[0] = prefixChars[m_number / 1000];
- m_tag[1] = static_cast <char>('0' + (m_number % 1000) / 100);
- m_tag[2] = static_cast <char>('0' + (m_number % 100) / 10);
- m_tag[3] = static_cast <char>('0' + m_number % 10);
-}
-
-
-} // imap
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
-
diff --git a/src/net/imap/IMAPUtils.cpp b/src/net/imap/IMAPUtils.cpp
deleted file mode 100644
index ff81ce71..00000000
--- a/src/net/imap/IMAPUtils.cpp
+++ /dev/null
@@ -1,758 +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_IMAP
-
-
-#include "vmime/net/imap/IMAPUtils.hpp"
-#include "vmime/net/imap/IMAPStore.hpp"
-
-#include "vmime/net/message.hpp"
-#include "vmime/net/folder.hpp"
-
-#include <sstream>
-#include <iterator>
-#include <algorithm>
-
-
-namespace vmime {
-namespace net {
-namespace imap {
-
-
-// static
-const string IMAPUtils::quoteString(const string& text)
-{
- //
- // ATOM_CHAR ::= <any CHAR except atom_specials>
- //
- // atom_specials ::= "(" / ")" / "{" / SPACE / CTL /
- // list_wildcards / quoted_specials
- //
- // list_wildcards ::= "%" / "*"
- //
- // quoted_specials ::= <"> / "\"
- //
- // CHAR ::= <any 7-bit US-ASCII character except NUL,
- // 0x01 - 0x7f>
- //
- // CTL ::= <any ASCII control character and DEL,
- // 0x00 - 0x1f, 0x7f>
- //
-
- bool needQuoting = text.empty();
-
- for (string::const_iterator it = text.begin() ;
- !needQuoting && it != text.end() ; ++it)
- {
- const unsigned char c = *it;
-
- switch (c)
- {
- case '(':
- case ')':
- case '{':
- case 0x20: // SPACE
- case '%':
- case '*':
- case '"':
- case '\\':
-
- needQuoting = true;
- break;
-
- default:
-
- if (c <= 0x1f || c >= 0x7f)
- needQuoting = true;
- }
- }
-
- if (needQuoting)
- {
- string quoted;
- quoted.reserve((text.length() * 3) / 2 + 2);
-
- quoted += '"';
-
- for (string::const_iterator it = text.begin() ; it != text.end() ; ++it)
- {
- const unsigned char c = *it;
-
- if (c == '\\' || c == '"')
- quoted += '\\';
-
- quoted += c;
- }
-
- quoted += '"';
-
- return (quoted);
- }
- else
- {
- return (text);
- }
-}
-
-
-const string IMAPUtils::pathToString
- (const char hierarchySeparator, const folder::path& path)
-{
- string result;
-
- for (size_t i = 0 ; i < path.getSize() ; ++i)
- {
- if (i > 0) result += hierarchySeparator;
- result += toModifiedUTF7(hierarchySeparator, path[i]);
- }
-
- return (result);
-}
-
-
-const folder::path IMAPUtils::stringToPath
- (const char hierarchySeparator, const string& str)
-{
- folder::path result;
- string::const_iterator begin = str.begin();
-
- for (string::const_iterator it = str.begin() ; it != str.end() ; ++it)
- {
- if (*it == hierarchySeparator)
- {
- result /= fromModifiedUTF7(string(begin, it));
- begin = it + 1;
- }
- }
-
- if (begin != str.end())
- {
- result /= fromModifiedUTF7(string(begin, str.end()));
- }
-
- return (result);
-}
-
-
-const string IMAPUtils::toModifiedUTF7
- (const char hierarchySeparator, const folder::path::component& text)
-{
- // We will replace the hierarchy separator with an equivalent
- // UTF-7 sequence, so we compute it here...
- const char base64alphabet[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,=";
-
- const unsigned int hs = static_cast <unsigned int>(static_cast <unsigned char>(hierarchySeparator));
-
- string hsUTF7;
- hsUTF7.resize(3);
-
- hsUTF7[0] = base64alphabet[0];
- hsUTF7[1] = base64alphabet[(hs & 0xF0) >> 4];
- hsUTF7[2] = base64alphabet[(hs & 0x0F) << 2];
-
- // iconv() is buggy with UTF-8 to UTF-7 conversion, so we do it "by hand".
- // This code is largely inspired from "imap/utf7.c", in mutt 1.4.
- // Copyright (C) 2000 Edmund Grimley Evans <[email protected]>
-
- // WARNING: This may throw "exceptions::charset_conv_error"
- const string cvt = text.getConvertedText(charset(charsets::UTF_8));
-
- // In the worst case we convert 2 chars to 7 chars.
- // For example: "\x10&\x10&..." -> "&ABA-&-&ABA-&-...".
- string out;
- out.reserve((cvt.length() / 2) * 7 + 6);
-
- int b = 0, k = 0;
- bool base64 = false;
-
- size_t remaining = cvt.length();
-
- for (size_t i = 0, len = cvt.length() ; i < len ; )
- {
- const unsigned char c = cvt[i];
-
- // Replace hierarchy separator with an equivalent UTF-7 Base64 sequence
- if (!base64 && c == hierarchySeparator)
- {
- out += "&" + hsUTF7 + "-";
-
- ++i;
- --remaining;
- continue;
- }
-
- size_t n = 0;
- int ch = 0;
-
- if (c < 0x80)
- ch = c, n = 0;
- else if (c < 0xc2)
- return "";
- else if (c < 0xe0)
- ch = c & 0x1f, n = 1;
- else if (c < 0xf0)
- ch = c & 0x0f, n = 2;
- else if (c < 0xf8)
- ch = c & 0x07, n = 3;
- else if (c < 0xfc)
- ch = c & 0x03, n = 4;
- else if (c < 0xfe)
- ch = c & 0x01, n = 5;
- else
- return "";
-
- if (n > remaining)
- return ""; // error
-
- ++i;
- --remaining;
-
- for (size_t j = 0 ; j < n ; j++)
- {
- if ((cvt[i + j] & 0xc0) != 0x80)
- return ""; // error
-
- ch = (ch << 6) | (cvt[i + j] & 0x3f);
- }
-
- if (n > 1 && !(ch >> (n * 5 + 1)))
- return ""; // error
-
- i += n;
- remaining -= n;
-
- if (ch < 0x20 || ch >= 0x7f)
- {
- if (!base64)
- {
- out += '&';
- base64 = true;
- b = 0;
- k = 10;
- }
-
- if (ch & ~0xffff)
- ch = 0xfffe;
-
- out += base64alphabet[b | ch >> k];
-
- k -= 6;
-
- for ( ; k >= 0 ; k -= 6)
- out += base64alphabet[(ch >> k) & 0x3f];
-
- b = (ch << (-k)) & 0x3f;
- k += 16;
- }
- else
- {
- if (base64)
- {
- if (k > 10)
- out += base64alphabet[b];
-
- out += '-';
- base64 = false;
- }
-
- out += static_cast <char>(ch);
-
- if (ch == '&')
- out += '-';
- }
- }
-
- if (base64)
- {
- if (k > 10)
- out += base64alphabet[b];
-
- out += '-';
- }
-
- return (out);
-}
-
-
-const folder::path::component IMAPUtils::fromModifiedUTF7(const string& text)
-{
- // Transcode from modified UTF-7 (RFC-2060).
- string out;
- out.reserve(text.length());
-
- bool inB64sequence = false;
- unsigned char prev = 0;
-
- for (string::const_iterator it = text.begin() ; it != text.end() ; ++it)
- {
- const unsigned char c = *it;
-
- switch (c)
- {
- // Start of Base64 sequence
- case '&':
- {
- if (!inB64sequence)
- {
- inB64sequence = true;
- out += '+';
- }
- else
- {
- out += '&';
- }
-
- break;
- }
- // End of Base64 sequence (or "&-" --> "&")
- case '-':
- {
- if (inB64sequence && prev == '&')
- out += '&';
- else
- out += '-';
-
- inB64sequence = false;
- break;
- }
- // ',' is used instead of '/' in modified Base64
- case ',':
- {
- out += (inB64sequence ? '/' : ',');
- break;
- }
- default:
- {
- out += c;
- break;
- }
-
- }
-
- prev = c;
- }
-
- // Store it as UTF-8 by default
- string cvt;
- charset::convert(out, cvt,
- charset(charsets::UTF_7), charset(charsets::UTF_8));
-
- return (folder::path::component(cvt, charset(charsets::UTF_8)));
-}
-
-
-int IMAPUtils::folderTypeFromFlags(const IMAPParser::mailbox_flag_list* list)
-{
- // Get folder type
- int type = folder::TYPE_CONTAINS_MESSAGES | folder::TYPE_CONTAINS_FOLDERS;
- const std::vector <IMAPParser::mailbox_flag*>& flags = list->flags();
-
- for (std::vector <IMAPParser::mailbox_flag*>::const_iterator it = flags.begin() ;
- it != flags.end() ; ++it)
- {
- if ((*it)->type() == IMAPParser::mailbox_flag::NOSELECT)
- type &= ~folder::TYPE_CONTAINS_MESSAGES;
- }
-
- if (type & folder::TYPE_CONTAINS_MESSAGES)
- type &= ~folder::TYPE_CONTAINS_FOLDERS;
-
- return (type);
-}
-
-
-int IMAPUtils::folderFlagsFromFlags(const IMAPParser::mailbox_flag_list* list)
-{
- // Get folder flags
- int folderFlags = folder::FLAG_CHILDREN;
- const std::vector <IMAPParser::mailbox_flag*>& flags = list->flags();
-
- for (std::vector <IMAPParser::mailbox_flag*>::const_iterator it = flags.begin() ;
- it != flags.end() ; ++it)
- {
- if ((*it)->type() == IMAPParser::mailbox_flag::NOSELECT)
- folderFlags |= folder::FLAG_NO_OPEN;
- else if ((*it)->type() == IMAPParser::mailbox_flag::NOINFERIORS)
- folderFlags &= ~folder::FLAG_CHILDREN;
- }
-
- return (folderFlags);
-}
-
-
-int IMAPUtils::messageFlagsFromFlags(const IMAPParser::flag_list* list)
-{
- const std::vector <IMAPParser::flag*>& flagList = list->flags();
- int flags = 0;
-
- for (std::vector <IMAPParser::flag*>::const_iterator
- it = flagList.begin() ; it != flagList.end() ; ++it)
- {
- switch ((*it)->type())
- {
- case IMAPParser::flag::ANSWERED:
- flags |= message::FLAG_REPLIED;
- break;
- case IMAPParser::flag::FLAGGED:
- flags |= message::FLAG_MARKED;
- break;
- case IMAPParser::flag::DELETED:
- flags |= message::FLAG_DELETED;
- break;
- case IMAPParser::flag::SEEN:
- flags |= message::FLAG_SEEN;
- break;
- case IMAPParser::flag::DRAFT:
- flags |= message::FLAG_DRAFT;
- break;
-
- default:
- //case IMAPParser::flag::UNKNOWN:
- break;
- }
- }
-
- return (flags);
-}
-
-
-const string IMAPUtils::messageFlagList(const int flags)
-{
- std::vector <string> flagList;
-
- if (flags & message::FLAG_REPLIED) flagList.push_back("\\Answered");
- if (flags & message::FLAG_MARKED) flagList.push_back("\\Flagged");
- if (flags & message::FLAG_DELETED) flagList.push_back("\\Deleted");
- if (flags & message::FLAG_SEEN) flagList.push_back("\\Seen");
- if (flags & message::FLAG_DRAFT) flagList.push_back("\\Draft");
-
- if (!flagList.empty())
- {
- std::ostringstream res;
- res.imbue(std::locale::classic());
-
- res << "(";
-
- if (flagList.size() >= 2)
- {
- std::copy(flagList.begin(), flagList.end() - 1,
- std::ostream_iterator <string>(res, " "));
- }
-
- res << *(flagList.end() - 1) << ")";
-
- return (res.str());
- }
-
- return "";
-}
-
-
-// static
-const string IMAPUtils::dateTime(const vmime::datetime& date)
-{
- std::ostringstream res;
- res.imbue(std::locale::classic());
-
- // date_time ::= <"> date_day_fixed "-" date_month "-" date_year
- // SPACE time SPACE zone <">
- //
- // time ::= 2digit ":" 2digit ":" 2digit
- // ;; Hours minutes seconds
- // zone ::= ("+" / "-") 4digit
- // ;; Signed four-digit value of hhmm representing
- // ;; hours and minutes west of Greenwich
- res << '"';
-
- // Date
- if (date.getDay() < 10) res << ' ';
- res << date.getDay();
-
- res << '-';
-
- static const char* monthNames[12] =
- { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
- res << monthNames[std::min(std::max(date.getMonth() - 1, 0), 11)];
-
- res << '-';
-
- if (date.getYear() < 10) res << '0';
- if (date.getYear() < 100) res << '0';
- if (date.getYear() < 1000) res << '0';
- res << date.getYear();
-
- res << ' ';
-
- // Time
- if (date.getHour() < 10) res << '0';
- res << date.getHour() << ':';
-
- if (date.getMinute() < 10) res << '0';
- res << date.getMinute() << ':';
-
- if (date.getSecond() < 10) res << '0';
- res << date.getSecond();
-
- res << ' ';
-
- // Zone
- const int zs = (date.getZone() < 0 ? -1 : 1);
- const int zh = (date.getZone() * zs) / 60;
- const int zm = (date.getZone() * zs) % 60;
-
- res << (zs < 0 ? '-' : '+');
-
- if (zh < 10) res << '0';
- res << zh;
-
- if (zm < 10) res << '0';
- res << zm;
-
- res << '"';
-
-
- return (res.str());
-}
-
-
-// static
-const string IMAPUtils::buildFetchRequest
- (shared_ptr <IMAPConnection> cnt, const messageSet& msgs, const fetchAttributes& options)
-{
- // Example:
- // C: A654 FETCH 2:4 (FLAGS BODY[HEADER.FIELDS (DATE FROM)])
- // S: * 2 FETCH ....
- // S: * 3 FETCH ....
- // S: * 4 FETCH ....
- // S: A654 OK FETCH completed
-
- std::vector <string> items;
-
- if (options.has(fetchAttributes::SIZE))
- items.push_back("RFC822.SIZE");
-
- if (options.has(fetchAttributes::FLAGS))
- items.push_back("FLAGS");
-
- if (options.has(fetchAttributes::STRUCTURE))
- items.push_back("BODYSTRUCTURE");
-
- if (options.has(fetchAttributes::UID))
- {
- items.push_back("UID");
-
- // Also fetch MODSEQ if CONDSTORE is supported
- if (cnt->hasCapability("CONDSTORE") && !cnt->isMODSEQDisabled())
- items.push_back("MODSEQ");
- }
-
- if (options.has(fetchAttributes::FULL_HEADER))
- items.push_back("RFC822.HEADER");
- else
- {
- if (options.has(fetchAttributes::ENVELOPE))
- items.push_back("ENVELOPE");
-
- std::vector <string> headerFields;
-
- if (options.has(fetchAttributes::CONTENT_INFO))
- headerFields.push_back("CONTENT_TYPE");
-
- if (options.has(fetchAttributes::IMPORTANCE))
- {
- headerFields.push_back("IMPORTANCE");
- headerFields.push_back("X-PRIORITY");
- }
-
- // Also add custom header fields to fetch, if any
- const std::vector <string> customHeaderFields = options.getHeaderFields();
- std::copy(customHeaderFields.begin(), customHeaderFields.end(), std::back_inserter(headerFields));
-
- if (!headerFields.empty())
- {
- string list;
-
- for (std::vector <string>::iterator it = headerFields.begin() ;
- it != headerFields.end() ; ++it)
- {
- if (it != headerFields.begin())
- list += " ";
-
- list += *it;
- }
-
- items.push_back("BODY[HEADER.FIELDS (" + list + ")]");
- }
- }
-
- // Build the request text
- std::ostringstream command;
- command.imbue(std::locale::classic());
-
- if (msgs.isUIDSet())
- command << "UID FETCH " << messageSetToSequenceSet(msgs) << " (";
- else
- command << "FETCH " << messageSetToSequenceSet(msgs) << " (";
-
- for (std::vector <string>::const_iterator it = items.begin() ;
- it != items.end() ; ++it)
- {
- if (it != items.begin()) command << " ";
- command << *it;
- }
-
- command << ")";
-
- return command.str();
-}
-
-
-// static
-void IMAPUtils::convertAddressList
- (const IMAPParser::address_list& src, mailboxList& dest)
-{
- for (std::vector <IMAPParser::address*>::const_iterator
- it = src.addresses().begin() ; it != src.addresses().end() ; ++it)
- {
- const IMAPParser::address& addr = **it;
-
- text name;
- text::decodeAndUnfold(addr.addr_name()->value(), &name);
-
- string email = addr.addr_mailbox()->value()
- + "@" + addr.addr_host()->value();
-
- dest.appendMailbox(make_shared <mailbox>(name, email));
- }
-}
-
-
-
-class IMAPUIDMessageSetEnumerator : public messageSetEnumerator
-{
-public:
-
- IMAPUIDMessageSetEnumerator()
- : m_first(true)
- {
- }
-
- void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range)
- {
- if (!m_first)
- m_oss << ",";
-
- if (range.getFirst() == range.getLast())
- m_oss << range.getFirst();
- else
- m_oss << range.getFirst() << ":" << range.getLast();
-
- m_first = false;
- }
-
- void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& range)
- {
- if (!m_first)
- m_oss << ",";
-
- if (range.getFirst() == range.getLast())
- m_oss << range.getFirst();
- else
- m_oss << range.getFirst() << ":" << range.getLast();
-
- m_first = false;
- }
-
- const std::string str() const
- {
- return m_oss.str();
- }
-
-private:
-
- std::ostringstream m_oss;
- bool m_first;
-};
-
-
-class IMAPMessageSetEnumerator : public messageSetEnumerator
-{
-public:
-
- void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range)
- {
- for (int i = range.getFirst(), last = range.getLast() ; i <= last ; ++i)
- m_list.push_back(i);
- }
-
- void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& /* range */)
- {
- // Not used
- }
-
- const std::vector <int>& list() const
- {
- return m_list;
- }
-
-public:
-
- std::vector <int> m_list;
-};
-
-
-
-// static
-const string IMAPUtils::messageSetToSequenceSet(const messageSet& msgs)
-{
- IMAPUIDMessageSetEnumerator en;
- msgs.enumerate(en);
-
- return en.str();
-}
-
-
-// static
-const std::vector <int> IMAPUtils::messageSetToNumberList(const messageSet& msgs)
-{
- IMAPMessageSetEnumerator en;
- msgs.enumerate(en);
-
- return en.list();
-}
-
-
-} // imap
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
-
diff --git a/src/net/maildir/format/courierMaildirFormat.cpp b/src/net/maildir/format/courierMaildirFormat.cpp
deleted file mode 100644
index 6d460d5e..00000000
--- a/src/net/maildir/format/courierMaildirFormat.cpp
+++ /dev/null
@@ -1,542 +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_MAILDIR
-
-
-#include "vmime/net/maildir/format/courierMaildirFormat.hpp"
-
-#include "vmime/net/maildir/maildirStore.hpp"
-#include "vmime/net/maildir/maildirUtils.hpp"
-
-#include "vmime/platform.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace maildir {
-namespace format {
-
-
-courierMaildirFormat::courierMaildirFormat(shared_ptr <context> ctx)
- : maildirFormat(ctx)
-{
-}
-
-
-const string courierMaildirFormat::getName() const
-{
- return "courier";
-}
-
-
-void courierMaildirFormat::createFolder(const folder::path& path)
-{
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- if (!fsf->isValidPath(folderPathToFileSystemPath(path, ROOT_DIRECTORY)))
- throw exceptions::invalid_folder_name();
-
- shared_ptr <utility::file> rootDir = fsf->create
- (folderPathToFileSystemPath(path, ROOT_DIRECTORY));
-
- shared_ptr <utility::file> newDir = fsf->create
- (folderPathToFileSystemPath(path, NEW_DIRECTORY));
- shared_ptr <utility::file> tmpDir = fsf->create
- (folderPathToFileSystemPath(path, TMP_DIRECTORY));
- shared_ptr <utility::file> curDir = fsf->create
- (folderPathToFileSystemPath(path, CUR_DIRECTORY));
-
- rootDir->createDirectory(true);
-
- newDir->createDirectory(false);
- tmpDir->createDirectory(false);
- curDir->createDirectory(false);
-
- shared_ptr <utility::file> maildirFile = fsf->create
- (folderPathToFileSystemPath(path, ROOT_DIRECTORY)
- / utility::file::path::component("maildirfolder"));
-
- maildirFile->createFile();
-}
-
-
-void courierMaildirFormat::destroyFolder(const folder::path& path)
-{
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- // Recursively delete directories of subfolders
- const std::vector <folder::path> folders = listFolders(path, true);
-
- for (std::vector <folder::path>::size_type i = 0, n = folders.size() ; i < n ; ++i)
- {
- maildirUtils::recursiveFSDelete(fsf->create
- (folderPathToFileSystemPath(folders[i], ROOT_DIRECTORY)));
- }
-
- // Recursively delete the directory of this folder
- maildirUtils::recursiveFSDelete(fsf->create
- (folderPathToFileSystemPath(path, ROOT_DIRECTORY)));
-}
-
-
-void courierMaildirFormat::renameFolder
- (const folder::path& oldPath, const folder::path& newPath)
-{
- const std::vector <folder::path> folders = listFolders(oldPath, true);
-
- for (std::vector <folder::path>::size_type i = 0, n = folders.size() ; i < n ; ++i)
- {
- const folder::path folderOldPath = folders[i];
-
- folder::path folderNewPath = folderOldPath;
- folderNewPath.renameParent(oldPath, newPath);
-
- renameFolderImpl(folderOldPath, folderNewPath);
- }
-
- renameFolderImpl(oldPath, newPath);
-}
-
-
-void courierMaildirFormat::renameFolderImpl
- (const folder::path& oldPath, const folder::path& newPath)
-{
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- const utility::file::path oldFSPath =
- folderPathToFileSystemPath(oldPath, ROOT_DIRECTORY);
-
- const utility::file::path newFSPath =
- folderPathToFileSystemPath(newPath, ROOT_DIRECTORY);
-
- shared_ptr <utility::file> rootDir = fsf->create(oldFSPath);
- rootDir->rename(newFSPath);
-}
-
-
-bool courierMaildirFormat::folderExists(const folder::path& path) const
-{
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- shared_ptr <utility::file> rootDir = fsf->create
- (folderPathToFileSystemPath(path, ROOT_DIRECTORY));
-
- shared_ptr <utility::file> newDir = fsf->create
- (folderPathToFileSystemPath(path, NEW_DIRECTORY));
- shared_ptr <utility::file> tmpDir = fsf->create
- (folderPathToFileSystemPath(path, TMP_DIRECTORY));
- shared_ptr <utility::file> curDir = fsf->create
- (folderPathToFileSystemPath(path, CUR_DIRECTORY));
-
- shared_ptr <utility::file> maildirFile = fsf->create
- (folderPathToFileSystemPath(path, ROOT_DIRECTORY)
- / utility::file::path::component("maildirfolder"));
-
- bool exists = rootDir->exists() && rootDir->isDirectory() &&
- newDir->exists() && newDir->isDirectory() &&
- tmpDir->exists() && tmpDir->isDirectory() &&
- curDir->exists() && curDir->isDirectory();
-
- // If this is not the root folder, then a file named "maildirfolder"
- // must also be present in the directory
- if (!path.isRoot())
- exists = exists && maildirFile->exists() && maildirFile->isFile();
-
- return exists;
-}
-
-
-bool courierMaildirFormat::folderHasSubfolders(const folder::path& path) const
-{
- std::vector <string> dirs;
- return listDirectories(path, dirs, true);
-}
-
-
-const utility::file::path courierMaildirFormat::folderPathToFileSystemPath
- (const folder::path& path, const DirectoryType type) const
-{
- // Virtual folder "/MyFolder/SubFolder" corresponds to physical
- // directory "[store root]/.MyFolder.SubFolder"
- utility::file::path fsPath = getContext()->getStore()->getFileSystemPath();
-
- if (!path.isRoot())
- {
- string folderComp;
-
- for (size_t i = 0, n = path.getSize() ; i < n ; ++i)
- folderComp += "." + toModifiedUTF7(path[i]);
-
- fsPath /= utility::file::path::component(folderComp);
- }
-
- // Last component
- switch (type)
- {
- case ROOT_DIRECTORY:
-
- // Nothing to add
- break;
-
- case NEW_DIRECTORY:
-
- fsPath /= NEW_DIR;
- break;
-
- case CUR_DIRECTORY:
-
- fsPath /= CUR_DIR;
- break;
-
- case TMP_DIRECTORY:
-
- fsPath /= TMP_DIR;
- break;
-
- case CONTAINER_DIRECTORY:
-
- // Not used
- break;
- }
-
- return fsPath;
-}
-
-
-const std::vector <folder::path> courierMaildirFormat::listFolders
- (const folder::path& root, const bool recursive) const
-{
- // First, list directories
- std::vector <string> dirs;
- listDirectories(root, dirs, false);
-
- // Then, map directories to folders
- std::vector <folder::path> folders;
-
- for (std::vector <string>::size_type i = 0, n = dirs.size() ; i < n ; ++i)
- {
- const string dir = dirs[i].substr(1) + ".";
- folder::path path;
-
- for (size_t pos = dir.find("."), prev = 0 ;
- pos != string::npos ; prev = pos + 1, pos = dir.find(".", pos + 1))
- {
- const string comp = dir.substr(prev, pos - prev);
- path /= fromModifiedUTF7(comp);
- }
-
- if (recursive || path.getSize() == root.getSize() + 1)
- folders.push_back(path);
- }
-
- return folders;
-}
-
-
-bool courierMaildirFormat::listDirectories(const folder::path& root,
- std::vector <string>& dirs, const bool onlyTestForExistence) const
-{
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- shared_ptr <utility::file> rootDir = fsf->create
- (getContext()->getStore()->getFileSystemPath());
-
- if (rootDir->exists())
- {
- // To speed up things, and if we are not searching in root folder,
- // search for directories with a common prefix
- string base;
-
- if (!root.isRoot())
- {
- for (size_t i = 0, n = root.getSize() ; i < n ; ++i)
- base += "." + toModifiedUTF7(root[i]);
- }
-
- // Enumerate directories
- shared_ptr <utility::fileIterator> it = rootDir->getFiles();
-
- while (it->hasMoreElements())
- {
- shared_ptr <utility::file> file = it->nextElement();
-
- if (isSubfolderDirectory(*file))
- {
- const string dir = file->getFullPath().getLastComponent().getBuffer();
-
- if (base.empty() || (dir.length() > base.length() && dir.substr(0, base.length()) == base))
- {
- dirs.push_back(dir);
-
- if (onlyTestForExistence)
- return true;
- }
- }
- }
- }
- else
- {
- // No sub-folder
- }
-
- std::sort(dirs.begin(), dirs.end());
-
- return !dirs.empty();
-}
-
-
-// static
-bool courierMaildirFormat::isSubfolderDirectory(const utility::file& file)
-{
- // A directory which names starts with '.' may be a subfolder
- if (file.isDirectory() &&
- file.getFullPath().getLastComponent().getBuffer().length() >= 1 &&
- file.getFullPath().getLastComponent().getBuffer()[0] == '.')
- {
- return true;
- }
-
- return false;
-}
-
-
-// static
-const string courierMaildirFormat::toModifiedUTF7(const folder::path::component& text)
-{
- // From http://www.courier-mta.org/?maildir.html:
- //
- // Folder names can contain any Unicode character, except for control
- // characters. US-ASCII characters, U+0x0020 - U+0x007F, except for the
- // period, forward-slash, and ampersand characters (U+0x002E, U+0x002F,
- // and U+0x0026) represent themselves. The ampersand is represented by
- // the two character sequence "&-". The period, forward slash, and non
- // US-ASCII Unicode characters are represented using the UTF-7 character
- // set, and encoded with a modified form of base64-encoding.
- //
- // The "&" character starts the modified base64-encoded sequence; the
- // sequence is terminated by the "-" character. The sequence of 16-bit
- // Unicode characters is written in big-endian order, and encoded using
- // the base64-encoding method described in section 5.2 of RFC 1521, with
- // the following modifications:
- //
- // * The "=" padding character is omitted. When decoding, an incomplete
- // 16-bit character is discarded.
- //
- // * The comma character, "," is used in place of the "/" character in
- // the base64 alphabet.
- //
- // For example, the word "Resume" with both "e"s being the e-acute
- // character, U+0x00e9, is encoded as "R&AOk-sum&AOk-" (so a folder of
- // that name would be a maildir subdirectory called ".R&AOk-sum&AOk-").
- //
-
- // Transcode path component to UTF-7 charset.
- // WARNING: This may throw "exceptions::charset_conv_error"
- const string cvt = text.getConvertedText(charset(charsets::UTF_7));
-
- // Transcode to modified UTF-7 (RFC-2060).
- string out;
- out.reserve((cvt.length() * 3) / 2);
-
- bool inB64sequence = false;
-
- for (string::const_iterator it = cvt.begin() ; it != cvt.end() ; ++it)
- {
- const unsigned char c = *it;
-
- switch (c)
- {
- // Beginning of Base64 sequence: replace '+' with '&'
- case '+':
- {
- if (!inB64sequence)
- {
- inB64sequence = true;
- out += '&';
- }
- else
- {
- out += '+';
- }
-
- break;
- }
- // End of Base64 sequence
- case '-':
- {
- inB64sequence = false;
- out += '-';
- break;
- }
- // ',' is used instead of '/' in modified Base64,
- // and simply UTF7-encoded out of a Base64 sequence
- case '/':
- {
- if (inB64sequence)
- out += ',';
- else
- out += "&Lw-";
-
- break;
- }
- // Encode period (should not happen in a Base64 sequence)
- case '.':
- {
- out += "&Lg-";
- break;
- }
- // '&' (0x26) is represented by the two-octet sequence "&-"
- case '&':
- {
- if (!inB64sequence)
- out += "&-";
- else
- out += '&';
-
- break;
- }
- default:
- {
- out += c;
- break;
- }
-
- }
- }
-
- return out;
-}
-
-
-// static
-const folder::path::component courierMaildirFormat::fromModifiedUTF7(const string& text)
-{
- // Transcode from modified UTF-7
- string out;
- out.reserve(text.length());
-
- bool inB64sequence = false;
- unsigned char prev = 0;
-
- for (string::const_iterator it = text.begin() ; it != text.end() ; ++it)
- {
- const unsigned char c = *it;
-
- switch (c)
- {
- // Start of Base64 sequence
- case '&':
- {
- if (!inB64sequence)
- {
- inB64sequence = true;
- out += '+';
- }
- else
- {
- out += '&';
- }
-
- break;
- }
- // End of Base64 sequence (or "&-" --> "&")
- case '-':
- {
- if (inB64sequence && prev == '&')
- out += '&';
- else
- out += '-';
-
- inB64sequence = false;
- break;
- }
- // ',' is used instead of '/' in modified Base64
- case ',':
- {
- out += (inB64sequence ? '/' : ',');
- break;
- }
- default:
- {
- out += c;
- break;
- }
-
- }
-
- prev = c;
- }
-
- // Store it as UTF-8 by default
- string cvt;
- charset::convert(out, cvt,
- charset(charsets::UTF_7), charset(charsets::UTF_8));
-
- return (folder::path::component(cvt, charset(charsets::UTF_8)));
-}
-
-
-bool courierMaildirFormat::supports() const
-{
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- shared_ptr <utility::file> rootDir = fsf->create
- (getContext()->getStore()->getFileSystemPath());
-
- if (rootDir->exists())
- {
- // Try to find a file named "maildirfolder", which indicates
- // the Maildir is in Courier format
- shared_ptr <utility::fileIterator> it = rootDir->getFiles();
-
- while (it->hasMoreElements())
- {
- shared_ptr <utility::file> file = it->nextElement();
-
- if (isSubfolderDirectory(*file))
- {
- shared_ptr <utility::file> folderFile = fsf->create
- (file->getFullPath() / utility::file::path::component("maildirfolder"));
-
- if (folderFile->exists() && folderFile->isFile())
- return true;
- }
- }
- }
-
- return false;
-}
-
-
-} // format
-} // maildir
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR
-
diff --git a/src/net/maildir/format/kmailMaildirFormat.cpp b/src/net/maildir/format/kmailMaildirFormat.cpp
deleted file mode 100644
index 975752a5..00000000
--- a/src/net/maildir/format/kmailMaildirFormat.cpp
+++ /dev/null
@@ -1,320 +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_MAILDIR
-
-
-#include "vmime/net/maildir/format/kmailMaildirFormat.hpp"
-
-#include "vmime/net/maildir/maildirStore.hpp"
-#include "vmime/net/maildir/maildirUtils.hpp"
-
-#include "vmime/platform.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace maildir {
-namespace format {
-
-
-kmailMaildirFormat::kmailMaildirFormat(shared_ptr <context> ctx)
- : maildirFormat(ctx)
-{
-}
-
-
-const string kmailMaildirFormat::getName() const
-{
- return "kmail";
-}
-
-
-void kmailMaildirFormat::createFolder(const folder::path& path)
-{
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- if (!fsf->isValidPath(folderPathToFileSystemPath(path, ROOT_DIRECTORY)))
- throw exceptions::invalid_folder_name();
-
- shared_ptr <utility::file> rootDir = fsf->create
- (folderPathToFileSystemPath(path, ROOT_DIRECTORY));
-
- shared_ptr <utility::file> newDir = fsf->create
- (folderPathToFileSystemPath(path, NEW_DIRECTORY));
- shared_ptr <utility::file> tmpDir = fsf->create
- (folderPathToFileSystemPath(path, TMP_DIRECTORY));
- shared_ptr <utility::file> curDir = fsf->create
- (folderPathToFileSystemPath(path, CUR_DIRECTORY));
-
- rootDir->createDirectory(true);
-
- newDir->createDirectory(false);
- tmpDir->createDirectory(false);
- curDir->createDirectory(false);
-}
-
-
-void kmailMaildirFormat::destroyFolder(const folder::path& path)
-{
- // Delete 'folder' and '.folder.directory' directories
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- maildirUtils::recursiveFSDelete(fsf->create
- (folderPathToFileSystemPath(path, ROOT_DIRECTORY))); // root
-
- maildirUtils::recursiveFSDelete(fsf->create
- (folderPathToFileSystemPath(path, CONTAINER_DIRECTORY))); // container
-}
-
-
-bool kmailMaildirFormat::folderExists(const folder::path& path) const
-{
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- shared_ptr <utility::file> rootDir = fsf->create
- (folderPathToFileSystemPath(path, ROOT_DIRECTORY));
-
- shared_ptr <utility::file> newDir = fsf->create
- (folderPathToFileSystemPath(path, NEW_DIRECTORY));
- shared_ptr <utility::file> tmpDir = fsf->create
- (folderPathToFileSystemPath(path, TMP_DIRECTORY));
- shared_ptr <utility::file> curDir = fsf->create
- (folderPathToFileSystemPath(path, CUR_DIRECTORY));
-
- return rootDir->exists() && rootDir->isDirectory() &&
- newDir->exists() && newDir->isDirectory() &&
- tmpDir->exists() && tmpDir->isDirectory() &&
- curDir->exists() && curDir->isDirectory();
-}
-
-
-const utility::file::path kmailMaildirFormat::folderPathToFileSystemPath
- (const folder::path& path, const DirectoryType type) const
-{
- // Root path
- utility::file::path fsPath = getContext()->getStore()->getFileSystemPath();
-
- const size_t pathSize = path.getSize();
- const size_t count = (type == CONTAINER_DIRECTORY
- ? pathSize : (pathSize >= 1 ? pathSize - 1 : 0));
-
- // Parent folders
- for (size_t i = 0 ; i < count ; ++i)
- {
- utility::file::path::component comp(path[i]);
-
- // TODO: may not work with all encodings...
- comp.setBuffer("." + comp.getBuffer() + ".directory");
-
- fsPath /= comp;
- }
-
- // Last component
- if (path.getSize() != 0 && type != CONTAINER_DIRECTORY)
- {
- fsPath /= path.getLastComponent();
-
- switch (type)
- {
- case ROOT_DIRECTORY:
-
- // Nothing to add
- break;
-
- case NEW_DIRECTORY:
-
- fsPath /= NEW_DIR;
- break;
-
- case CUR_DIRECTORY:
-
- fsPath /= CUR_DIR;
- break;
-
- case TMP_DIRECTORY:
-
- fsPath /= TMP_DIR;
- break;
-
- case CONTAINER_DIRECTORY:
-
- // Can't happen...
- break;
- }
- }
-
- return fsPath;
-}
-
-
-const std::vector <folder::path> kmailMaildirFormat::listFolders
- (const folder::path& root, const bool recursive) const
-{
- std::vector <folder::path> list;
- listFoldersImpl(list, root, recursive);
-
- return list;
-}
-
-
-void kmailMaildirFormat::listFoldersImpl
- (std::vector <folder::path>& list, const folder::path& root, const bool recursive) const
-{
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- shared_ptr <utility::file> rootDir = fsf->create(folderPathToFileSystemPath(root,
- root.isEmpty() ? ROOT_DIRECTORY : CONTAINER_DIRECTORY));
-
- if (rootDir->exists())
- {
- shared_ptr <utility::fileIterator> it = rootDir->getFiles();
-
- while (it->hasMoreElements())
- {
- shared_ptr <utility::file> file = it->nextElement();
-
- if (isSubfolderDirectory(*file))
- {
- const utility::path subPath =
- root / file->getFullPath().getLastComponent();
-
- list.push_back(subPath);
-
- if (recursive)
- listFoldersImpl(list, subPath, true);
- }
- }
- }
- else
- {
- // No sub-folder
- }
-}
-
-
-// static
-bool kmailMaildirFormat::isSubfolderDirectory(const utility::file& file)
-{
- // A directory which name does not start with '.' is listed as a sub-folder
- if (file.isDirectory() &&
- file.getFullPath().getLastComponent().getBuffer().length() >= 1 &&
- file.getFullPath().getLastComponent().getBuffer()[0] != '.')
- {
- return true;
- }
-
- return false;
-}
-
-
-void kmailMaildirFormat::renameFolder(const folder::path& oldPath, const folder::path& newPath)
-{
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- shared_ptr <utility::file> rootDir = fsf->create
- (folderPathToFileSystemPath(oldPath, ROOT_DIRECTORY));
- shared_ptr <utility::file> contDir = fsf->create
- (folderPathToFileSystemPath(oldPath, CONTAINER_DIRECTORY));
-
- try
- {
- const utility::file::path newRootPath =
- folderPathToFileSystemPath(newPath, ROOT_DIRECTORY);
- const utility::file::path newContPath =
- folderPathToFileSystemPath(newPath, CONTAINER_DIRECTORY);
-
- rootDir->rename(newRootPath);
-
- // Container directory may not exist, so ignore error when trying to rename it
- try
- {
- contDir->rename(newContPath);
- }
- catch (exceptions::filesystem_exception& e)
- {
- // Ignore
- }
- }
- catch (exceptions::filesystem_exception& e)
- {
- // Revert to old location
- const utility::file::path rootPath =
- folderPathToFileSystemPath(oldPath, ROOT_DIRECTORY);
- const utility::file::path contPath =
- folderPathToFileSystemPath(oldPath, CONTAINER_DIRECTORY);
-
- try
- {
- rootDir->rename(rootPath);
- contDir->rename(contPath);
- }
- catch (exceptions::filesystem_exception& e)
- {
- // Ignore (not recoverable)
- }
-
- throw;
- }
-}
-
-
-bool kmailMaildirFormat::folderHasSubfolders(const folder::path& path) const
-{
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- shared_ptr <utility::file> rootDir = fsf->create
- (folderPathToFileSystemPath(path, CONTAINER_DIRECTORY));
-
- shared_ptr <utility::fileIterator> it = rootDir->getFiles();
-
- while (it->hasMoreElements())
- {
- shared_ptr <utility::file> file = it->nextElement();
-
- if (isSubfolderDirectory(*file))
- return true;
- }
-
- return false;
-}
-
-
-bool kmailMaildirFormat::supports() const
-{
- // This is the default
- return true;
-}
-
-
-} // format
-} // maildir
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR
-
diff --git a/src/net/maildir/maildirFolder.cpp b/src/net/maildir/maildirFolder.cpp
deleted file mode 100644
index 660178ff..00000000
--- a/src/net/maildir/maildirFolder.cpp
+++ /dev/null
@@ -1,1254 +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_MAILDIR
-
-
-#include "vmime/net/maildir/maildirFolder.hpp"
-
-#include "vmime/net/maildir/maildirStore.hpp"
-#include "vmime/net/maildir/maildirMessage.hpp"
-#include "vmime/net/maildir/maildirUtils.hpp"
-#include "vmime/net/maildir/maildirFormat.hpp"
-#include "vmime/net/maildir/maildirFolderStatus.hpp"
-
-#include "vmime/message.hpp"
-
-#include "vmime/exception.hpp"
-#include "vmime/platform.hpp"
-
-#include "vmime/utility/outputStreamAdapter.hpp"
-#include "vmime/utility/inputStreamStringAdapter.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace maildir {
-
-
-maildirFolder::maildirFolder(const folder::path& path, shared_ptr <maildirStore> store)
- : m_store(store), m_path(path),
- m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()),
- m_mode(-1), m_open(false), m_unreadMessageCount(0), m_messageCount(0)
-{
- store->registerFolder(this);
-}
-
-
-maildirFolder::~maildirFolder()
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (store)
- {
- if (m_open)
- close(false);
-
- store->unregisterFolder(this);
- }
- else if (m_open)
- {
- close(false);
- }
-}
-
-
-void maildirFolder::onStoreDisconnected()
-{
- m_store.reset();
-}
-
-
-int maildirFolder::getMode() const
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- return (m_mode);
-}
-
-
-int maildirFolder::getType()
-{
- if (m_path.isEmpty())
- return (TYPE_CONTAINS_FOLDERS);
- else
- return (TYPE_CONTAINS_FOLDERS | TYPE_CONTAINS_MESSAGES);
-}
-
-
-int maildirFolder::getFlags()
-{
- int flags = 0;
-
- if (m_store.lock()->getFormat()->folderHasSubfolders(m_path))
- flags |= FLAG_CHILDREN; // Contains at least one sub-folder
-
- return (flags);
-}
-
-
-const folder::path::component maildirFolder::getName() const
-{
- return (m_name);
-}
-
-
-const folder::path maildirFolder::getFullPath() const
-{
- return (m_path);
-}
-
-
-void maildirFolder::open(const int mode, bool /* failIfModeIsNotAvailable */)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (isOpen())
- throw exceptions::illegal_state("Folder is already open");
- else if (!exists())
- throw exceptions::illegal_state("Folder does not exist");
-
- scanFolder();
-
- m_open = true;
- m_mode = mode;
-}
-
-
-void maildirFolder::close(const bool expunge)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
-
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- if (expunge)
- this->expunge();
-
- m_open = false;
- m_mode = -1;
-
- onClose();
-}
-
-
-void maildirFolder::onClose()
-{
- for (std::vector <maildirMessage*>::iterator it = m_messages.begin() ;
- it != m_messages.end() ; ++it)
- {
- (*it)->onFolderClosed();
- }
-
- m_messages.clear();
-}
-
-
-void maildirFolder::registerMessage(maildirMessage* msg)
-{
- m_messages.push_back(msg);
-}
-
-
-void maildirFolder::unregisterMessage(maildirMessage* msg)
-{
- std::vector <maildirMessage*>::iterator it =
- std::find(m_messages.begin(), m_messages.end(), msg);
-
- if (it != m_messages.end())
- m_messages.erase(it);
-}
-
-
-void maildirFolder::create(const int /* type */)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (isOpen())
- throw exceptions::illegal_state("Folder is open");
- else if (exists())
- throw exceptions::illegal_state("Folder already exists");
- else if (!store->isValidFolderName(m_name))
- throw exceptions::invalid_folder_name();
-
- // Create directory on file system
- try
- {
- store->getFormat()->createFolder(m_path);
- }
- catch (exceptions::filesystem_exception& e)
- {
- throw exceptions::command_error("CREATE", "", "File system exception", e);
- }
-
- // Notify folder created
- shared_ptr <events::folderEvent> event =
- make_shared <events::folderEvent>
- (dynamicCast <folder>(shared_from_this()),
- events::folderEvent::TYPE_CREATED, m_path, m_path);
-
- notifyFolder(event);
-}
-
-
-void maildirFolder::destroy()
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (isOpen())
- throw exceptions::illegal_state("Folder is open");
-
- // Delete folder
- try
- {
- store->getFormat()->destroyFolder(m_path);
- }
- catch (std::exception&)
- {
- // Ignore exception: anyway, we can't recover from this...
- }
-
- // Notify folder deleted
- shared_ptr <events::folderEvent> event =
- make_shared <events::folderEvent>
- (dynamicCast <folder>(shared_from_this()),
- events::folderEvent::TYPE_DELETED, m_path, m_path);
-
- notifyFolder(event);
-}
-
-
-bool maildirFolder::exists()
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- return store->getFormat()->folderExists(m_path);
-}
-
-
-bool maildirFolder::isOpen() const
-{
- return (m_open);
-}
-
-
-void maildirFolder::scanFolder()
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- try
- {
- m_messageCount = 0;
- m_unreadMessageCount = 0;
-
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- utility::file::path newDirPath = store->getFormat()->folderPathToFileSystemPath
- (m_path, maildirFormat::NEW_DIRECTORY);
- shared_ptr <utility::file> newDir = fsf->create(newDirPath);
-
- utility::file::path curDirPath = store->getFormat()->folderPathToFileSystemPath
- (m_path, maildirFormat::CUR_DIRECTORY);
- shared_ptr <utility::file> curDir = fsf->create(curDirPath);
-
- // New received messages (new/)
- shared_ptr <utility::fileIterator> nit = newDir->getFiles();
- std::vector <utility::file::path::component> newMessageFilenames;
-
- while (nit->hasMoreElements())
- {
- shared_ptr <utility::file> file = nit->nextElement();
-
- if (maildirUtils::isMessageFile(*file))
- newMessageFilenames.push_back(file->getFullPath().getLastComponent());
- }
-
- // Current messages (cur/)
- shared_ptr <utility::fileIterator> cit = curDir->getFiles();
- std::vector <utility::file::path::component> curMessageFilenames;
-
- while (cit->hasMoreElements())
- {
- shared_ptr <utility::file> file = cit->nextElement();
-
- if (maildirUtils::isMessageFile(*file))
- curMessageFilenames.push_back(file->getFullPath().getLastComponent());
- }
-
- // Update/delete existing messages (found in previous scan)
- for (unsigned int i = 0 ; i < m_messageInfos.size() ; ++i)
- {
- messageInfos& msgInfos = m_messageInfos[i];
-
- // NOTE: the flags may have changed (eg. moving from 'new' to 'cur'
- // may imply the 'S' flag) and so the filename. That's why we use
- // "maildirUtils::messageIdComparator" to compare only the 'unique'
- // portion of the filename...
-
- if (msgInfos.type == messageInfos::TYPE_CUR)
- {
- const std::vector <utility::file::path::component>::iterator pos =
- std::find_if(curMessageFilenames.begin(), curMessageFilenames.end(),
- maildirUtils::messageIdComparator(msgInfos.path));
-
- // If we cannot find this message in the 'cur' directory,
- // it means it has been deleted (and expunged).
- if (pos == curMessageFilenames.end())
- {
- msgInfos.type = messageInfos::TYPE_DELETED;
- }
- // Otherwise, update its information.
- else
- {
- msgInfos.path = *pos;
- curMessageFilenames.erase(pos);
- }
- }
- }
-
- m_messageInfos.reserve(m_messageInfos.size()
- + newMessageFilenames.size() + curMessageFilenames.size());
-
- // Add new messages from 'new': we are responsible to move the files
- // from the 'new' directory to the 'cur' directory, and append them
- // to our message list.
- for (std::vector <utility::file::path::component>::const_iterator
- it = newMessageFilenames.begin() ; it != newMessageFilenames.end() ; ++it)
- {
- const utility::file::path::component newFilename =
- maildirUtils::buildFilename(maildirUtils::extractId(*it), 0);
-
- // Move messages from 'new' to 'cur'
- shared_ptr <utility::file> file = fsf->create(newDirPath / *it);
- file->rename(curDirPath / newFilename);
-
- // Append to message list
- messageInfos msgInfos;
- msgInfos.path = newFilename;
-
- if (maildirUtils::extractFlags(msgInfos.path) & message::FLAG_DELETED)
- msgInfos.type = messageInfos::TYPE_DELETED;
- else
- msgInfos.type = messageInfos::TYPE_CUR;
-
- m_messageInfos.push_back(msgInfos);
- }
-
- // Add new messages from 'cur': the files have already been moved
- // from 'new' to 'cur'. Just append them to our message list.
- for (std::vector <utility::file::path::component>::const_iterator
- it = curMessageFilenames.begin() ; it != curMessageFilenames.end() ; ++it)
- {
- // Append to message list
- messageInfos msgInfos;
- msgInfos.path = *it;
-
- if (maildirUtils::extractFlags(msgInfos.path) & message::FLAG_DELETED)
- msgInfos.type = messageInfos::TYPE_DELETED;
- else
- msgInfos.type = messageInfos::TYPE_CUR;
-
- m_messageInfos.push_back(msgInfos);
- }
-
- // Update message count
- int unreadMessageCount = 0;
-
- for (std::vector <messageInfos>::const_iterator
- it = m_messageInfos.begin() ; it != m_messageInfos.end() ; ++it)
- {
- if ((maildirUtils::extractFlags((*it).path) & message::FLAG_SEEN) == 0)
- ++unreadMessageCount;
- }
-
- m_unreadMessageCount = unreadMessageCount;
- m_messageCount = m_messageInfos.size();
- }
- catch (exceptions::filesystem_exception&)
- {
- // Should not happen...
- }
-}
-
-
-shared_ptr <message> maildirFolder::getMessage(const int num)
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- if (num < 1 || num > m_messageCount)
- throw exceptions::message_not_found();
-
- return make_shared <maildirMessage>
- (dynamicCast <maildirFolder>(shared_from_this()), num);
-}
-
-
-std::vector <shared_ptr <message> > maildirFolder::getMessages(const messageSet& msgs)
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- if (msgs.isNumberSet())
- {
- const std::vector <int> numbers = maildirUtils::messageSetToNumberList(msgs);
-
- std::vector <shared_ptr <message> > messages;
- shared_ptr <maildirFolder> thisFolder = dynamicCast <maildirFolder>(shared_from_this());
-
- for (std::vector <int>::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 <maildirMessage>(thisFolder, *it));
- }
-
- return messages;
- }
- else
- {
- throw exceptions::operation_not_supported();
- }
-}
-
-
-int maildirFolder::getMessageCount()
-{
- return (m_messageCount);
-}
-
-
-shared_ptr <folder> maildirFolder::getFolder(const folder::path::component& name)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
-
- return make_shared <maildirFolder>(m_path / name, store);
-}
-
-
-std::vector <shared_ptr <folder> > maildirFolder::getFolders(const bool recursive)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!isOpen() && !store)
- throw exceptions::illegal_state("Store disconnected");
-
- std::vector <shared_ptr <folder> > list;
-
- listFolders(list, recursive);
-
- return (list);
-}
-
-
-void maildirFolder::listFolders(std::vector <shared_ptr <folder> >& list, const bool recursive)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- try
- {
- std::vector <folder::path> pathList =
- store->getFormat()->listFolders(m_path, recursive);
-
- list.reserve(pathList.size());
-
- for (std::vector <folder::path>::size_type i = 0, n = pathList.size() ; i < n ; ++i)
- {
- shared_ptr <maildirFolder> subFolder =
- make_shared <maildirFolder>(pathList[i], store);
-
- list.push_back(subFolder);
- }
- }
- catch (exceptions::filesystem_exception& e)
- {
- throw exceptions::command_error("LIST", "", "", e);
- }
-}
-
-
-void maildirFolder::rename(const folder::path& newPath)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (m_path.isEmpty() || newPath.isEmpty())
- throw exceptions::illegal_operation("Cannot rename root folder");
- else if (!store->isValidFolderName(newPath.getLastComponent()))
- throw exceptions::invalid_folder_name();
-
- // Rename the directory on the file system
- try
- {
- store->getFormat()->renameFolder(m_path, newPath);
- }
- catch (vmime::exception& e)
- {
- throw exceptions::command_error("RENAME", "", "", e);
- }
-
- // Notify folder renamed
- folder::path oldPath(m_path);
-
- m_path = newPath;
- m_name = newPath.getLastComponent();
-
- shared_ptr <events::folderEvent> event =
- make_shared <events::folderEvent>
- (dynamicCast <folder>(shared_from_this()),
- events::folderEvent::TYPE_RENAMED, oldPath, newPath);
-
- notifyFolder(event);
-
- // Notify folders with the same path
- for (std::list <maildirFolder*>::iterator it = store->m_folders.begin() ;
- it != store->m_folders.end() ; ++it)
- {
- if ((*it) != this && (*it)->getFullPath() == oldPath)
- {
- (*it)->m_path = newPath;
- (*it)->m_name = newPath.getLastComponent();
-
- shared_ptr <events::folderEvent> event =
- make_shared <events::folderEvent>
- (dynamicCast <folder>((*it)->shared_from_this()),
- events::folderEvent::TYPE_RENAMED, oldPath, newPath);
-
- (*it)->notifyFolder(event);
- }
- else if ((*it) != this && oldPath.isParentOf((*it)->getFullPath()))
- {
- folder::path oldPath((*it)->m_path);
-
- (*it)->m_path.renameParent(oldPath, newPath);
-
- shared_ptr <events::folderEvent> event =
- make_shared <events::folderEvent>
- (dynamicCast <folder>((*it)->shared_from_this()),
- events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path);
-
- (*it)->notifyFolder(event);
- }
- }
-}
-
-
-void maildirFolder::deleteMessages(const messageSet& msgs)
-{
- // Mark messages as deleted
- setMessageFlags(msgs, message::FLAG_DELETED, message::FLAG_MODE_ADD);
-}
-
-
-void maildirFolder::setMessageFlags
- (const messageSet& msgs, const int flags, const int mode)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
- else if (m_mode == MODE_READ_ONLY)
- throw exceptions::illegal_state("Folder is read-only");
-
- if (msgs.isNumberSet())
- {
- const std::vector <int> nums = maildirUtils::messageSetToNumberList(msgs);
-
- // Change message flags
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- utility::file::path curDirPath = store->getFormat()->
- folderPathToFileSystemPath(m_path, maildirFormat::CUR_DIRECTORY);
-
- for (std::vector <int>::const_iterator it =
- nums.begin() ; it != nums.end() ; ++it)
- {
- const int num = *it - 1;
-
- try
- {
- const utility::file::path::component path = m_messageInfos[num].path;
- shared_ptr <utility::file> file = fsf->create(curDirPath / path);
-
- int newFlags = maildirUtils::extractFlags(path);
-
- switch (mode)
- {
- case message::FLAG_MODE_ADD: newFlags |= flags; break;
- case message::FLAG_MODE_REMOVE: newFlags &= ~flags; break;
- default:
- case message::FLAG_MODE_SET: newFlags = flags; break;
- }
-
- const utility::file::path::component newPath = maildirUtils::buildFilename
- (maildirUtils::extractId(path), newFlags);
-
- file->rename(curDirPath / newPath);
-
- if (flags & message::FLAG_DELETED)
- m_messageInfos[num].type = messageInfos::TYPE_DELETED;
- else
- m_messageInfos[num].type = messageInfos::TYPE_CUR;
-
- m_messageInfos[num].path = newPath;
- }
- catch (exceptions::filesystem_exception& e)
- {
- // Ignore (not important)
- }
- }
-
- // Update local flags
- switch (mode)
- {
- case message::FLAG_MODE_ADD:
- {
- for (std::vector <maildirMessage*>::iterator it =
- m_messages.begin() ; it != m_messages.end() ; ++it)
- {
- if (std::binary_search(nums.begin(), nums.end(), (*it)->getNumber()) &&
- (*it)->m_flags != message::FLAG_UNDEFINED)
- {
- (*it)->m_flags |= flags;
- }
- }
-
- break;
- }
- case message::FLAG_MODE_REMOVE:
- {
- for (std::vector <maildirMessage*>::iterator it =
- m_messages.begin() ; it != m_messages.end() ; ++it)
- {
- if (std::binary_search(nums.begin(), nums.end(), (*it)->getNumber()) &&
- (*it)->m_flags != message::FLAG_UNDEFINED)
- {
- (*it)->m_flags &= ~flags;
- }
- }
-
- break;
- }
- default:
- case message::FLAG_MODE_SET:
- {
- for (std::vector <maildirMessage*>::iterator it =
- m_messages.begin() ; it != m_messages.end() ; ++it)
- {
- if (std::binary_search(nums.begin(), nums.end(), (*it)->getNumber()) &&
- (*it)->m_flags != message::FLAG_UNDEFINED)
- {
- (*it)->m_flags = flags;
- }
- }
-
- break;
- }
-
- }
-
- // Notify message flags changed
- shared_ptr <events::messageChangedEvent> event =
- make_shared <events::messageChangedEvent>
- (dynamicCast <folder>(shared_from_this()),
- events::messageChangedEvent::TYPE_FLAGS, nums);
-
- notifyMessageChanged(event);
-
- // TODO: notify other folders with the same path
- }
- else
- {
- throw exceptions::operation_not_supported();
- }
-}
-
-
-void maildirFolder::addMessage(shared_ptr <vmime::message> msg, const int flags,
- vmime::datetime* date, utility::progressListener* progress)
-{
- std::ostringstream oss;
- utility::outputStreamAdapter ossAdapter(oss);
-
- msg->generate(ossAdapter);
-
- const string& str = oss.str();
- utility::inputStreamStringAdapter strAdapter(str);
-
- addMessage(strAdapter, str.length(), flags, date, progress);
-}
-
-
-void maildirFolder::addMessage(utility::inputStream& is, const size_t size,
- const int flags, vmime::datetime* /* date */, utility::progressListener* progress)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
- else if (m_mode == MODE_READ_ONLY)
- throw exceptions::illegal_state("Folder is read-only");
-
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- utility::file::path tmpDirPath = store->getFormat()->
- folderPathToFileSystemPath(m_path,maildirFormat::TMP_DIRECTORY);
- utility::file::path dstDirPath = store->getFormat()->
- folderPathToFileSystemPath(m_path,
- flags == message::FLAG_RECENT ?
- maildirFormat::NEW_DIRECTORY :
- maildirFormat::CUR_DIRECTORY);
-
- const utility::file::path::component filename =
- maildirUtils::buildFilename(maildirUtils::generateId(),
- ((flags == message::FLAG_UNDEFINED) ? 0 : flags));
-
- try
- {
- shared_ptr <utility::file> tmpDir = fsf->create(tmpDirPath);
- tmpDir->createDirectory(true);
- }
- catch (exceptions::filesystem_exception&)
- {
- // Don't throw now, it will fail later...
- }
-
- try
- {
- shared_ptr <utility::file> curDir = fsf->create(dstDirPath);
- curDir->createDirectory(true);
- }
- catch (exceptions::filesystem_exception&)
- {
- // Don't throw now, it will fail later...
- }
-
- // Actually add the message
- copyMessageImpl(tmpDirPath, dstDirPath, filename, is, size, progress);
-
- // Append the message to the cache list
- messageInfos msgInfos;
- msgInfos.path = filename;
- msgInfos.type = messageInfos::TYPE_CUR;
-
- m_messageInfos.push_back(msgInfos);
- m_messageCount++;
-
- if ((flags == message::FLAG_UNDEFINED) || !(flags & message::FLAG_SEEN))
- m_unreadMessageCount++;
-
- // Notification
- std::vector <int> nums;
- nums.push_back(m_messageCount);
-
- 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 <maildirFolder*>::iterator it = store->m_folders.begin() ;
- it != store->m_folders.end() ; ++it)
- {
- if ((*it) != this && (*it)->getFullPath() == m_path)
- {
- (*it)->m_messageCount = m_messageCount;
- (*it)->m_unreadMessageCount = m_unreadMessageCount;
-
- (*it)->m_messageInfos.resize(m_messageInfos.size());
- std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin());
-
- shared_ptr <events::messageCountEvent> event =
- make_shared <events::messageCountEvent>
- (dynamicCast <folder>((*it)->shared_from_this()),
- events::messageCountEvent::TYPE_ADDED, nums);
-
- (*it)->notifyMessageCount(event);
- }
- }
-}
-
-
-void maildirFolder::copyMessageImpl(const utility::file::path& tmpDirPath,
- const utility::file::path& dstDirPath,
- const utility::file::path::component& filename,
- utility::inputStream& is, const size_t size,
- utility::progressListener* progress)
-{
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- shared_ptr <utility::file> file = fsf->create(tmpDirPath / filename);
-
- if (progress)
- progress->start(size);
-
- // First, write the message into 'tmp'...
- try
- {
- file->createFile();
-
- shared_ptr <utility::fileWriter> fw = file->getFileWriter();
- shared_ptr <utility::outputStream> os = fw->getOutputStream();
-
- byte_t buffer[65536];
- size_t total = 0;
-
- while (!is.eof())
- {
- const size_t read = is.read(buffer, sizeof(buffer));
-
- if (read != 0)
- {
- os->write(buffer, read);
- total += read;
- }
-
- if (progress)
- progress->progress(total, size);
- }
-
- os->flush();
- }
- catch (exception& e)
- {
- if (progress)
- progress->stop(size);
-
- // Delete temporary file
- try
- {
- shared_ptr <utility::file> file = fsf->create(tmpDirPath / filename);
- file->remove();
- }
- catch (exceptions::filesystem_exception&)
- {
- // Ignore
- }
-
- throw exceptions::command_error("ADD", "", "", e);
- }
-
- // ...then, move it to 'cur'
- try
- {
- file->rename(dstDirPath / filename);
- }
- catch (exception& e)
- {
- if (progress)
- progress->stop(size);
-
- // Delete temporary file
- try
- {
- file->remove();
- shared_ptr <utility::file> file = fsf->create(dstDirPath / filename);
- file->remove();
- }
- catch (exceptions::filesystem_exception&)
- {
- // Ignore
- }
-
- throw exceptions::command_error("ADD", "", "", e);
- }
-
- if (progress)
- progress->stop(size);
-}
-
-
-void maildirFolder::copyMessages(const folder::path& dest, const messageSet& msgs)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- utility::file::path curDirPath = store->getFormat()->folderPathToFileSystemPath
- (m_path, maildirFormat::CUR_DIRECTORY);
-
- utility::file::path destCurDirPath = store->getFormat()->
- folderPathToFileSystemPath(dest, maildirFormat::CUR_DIRECTORY);
- utility::file::path destTmpDirPath = store->getFormat()->
- folderPathToFileSystemPath(dest, maildirFormat::TMP_DIRECTORY);
-
- // Create destination directories
- try
- {
- shared_ptr <utility::file> destTmpDir = fsf->create(destTmpDirPath);
- destTmpDir->createDirectory(true);
- }
- catch (exceptions::filesystem_exception&)
- {
- // Don't throw now, it will fail later...
- }
-
- try
- {
- shared_ptr <utility::file> destCurDir = fsf->create(destCurDirPath);
- destCurDir->createDirectory(true);
- }
- catch (exceptions::filesystem_exception&)
- {
- // Don't throw now, it will fail later...
- }
-
- // Copy messages
- const std::vector <int> nums = maildirUtils::messageSetToNumberList(msgs);
-
- try
- {
- for (std::vector <int>::const_iterator it =
- nums.begin() ; it != nums.end() ; ++it)
- {
- const int num = *it;
- const messageInfos& msg = m_messageInfos[num - 1];
- const int flags = maildirUtils::extractFlags(msg.path);
-
- const utility::file::path::component filename =
- maildirUtils::buildFilename(maildirUtils::generateId(), flags);
-
- shared_ptr <utility::file> file = fsf->create(curDirPath / msg.path);
- shared_ptr <utility::fileReader> fr = file->getFileReader();
- shared_ptr <utility::inputStream> is = fr->getInputStream();
-
- copyMessageImpl(destTmpDirPath, destCurDirPath,
- filename, *is, file->getLength(), NULL);
- }
- }
- catch (exception& e)
- {
- notifyMessagesCopied(dest);
- throw exceptions::command_error("COPY", "", "", e);
- }
-
- notifyMessagesCopied(dest);
-}
-
-
-void maildirFolder::notifyMessagesCopied(const folder::path& dest)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- for (std::list <maildirFolder*>::iterator it = store->m_folders.begin() ;
- it != store->m_folders.end() ; ++it)
- {
- if ((*it) != this && (*it)->getFullPath() == dest)
- {
- // We only need to update the first folder we found as calling
- // status() will notify all the folders with the same path.
- int count, unseen;
- (*it)->status(count, unseen);
-
- return;
- }
- }
-}
-
-
-void maildirFolder::status(int& count, int& unseen)
-{
- count = 0;
- unseen = 0;
-
- shared_ptr <folderStatus> status = getStatus();
-
- count = status->getMessageCount();
- unseen = status->getUnseenCount();
-}
-
-
-shared_ptr <folderStatus> maildirFolder::getStatus()
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- const int oldCount = m_messageCount;
-
- scanFolder();
-
- shared_ptr <maildirFolderStatus> status = make_shared <maildirFolderStatus>();
-
- status->setMessageCount(m_messageCount);
- status->setUnseenCount(m_unreadMessageCount);
-
- // Notify message count changed (new messages)
- if (m_messageCount > oldCount)
- {
- std::vector <int> nums;
- nums.reserve(m_messageCount - oldCount);
-
- for (int i = oldCount + 1, j = 0 ; i <= m_messageCount ; ++i, ++j)
- nums[j] = i;
-
- 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 <maildirFolder*>::iterator it = store->m_folders.begin() ;
- it != store->m_folders.end() ; ++it)
- {
- if ((*it) != this && (*it)->getFullPath() == m_path)
- {
- (*it)->m_messageCount = m_messageCount;
- (*it)->m_unreadMessageCount = m_unreadMessageCount;
-
- (*it)->m_messageInfos.resize(m_messageInfos.size());
- std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin());
-
- 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 maildirFolder::expunge()
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
- else if (m_mode == MODE_READ_ONLY)
- throw exceptions::illegal_state("Folder is read-only");
-
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- utility::file::path curDirPath = store->getFormat()->
- folderPathToFileSystemPath(m_path, maildirFormat::CUR_DIRECTORY);
-
- std::vector <int> nums;
- int unreadCount = 0;
-
- for (int num = 1 ; num <= m_messageCount ; ++num)
- {
- messageInfos& infos = m_messageInfos[num - 1];
-
- if (infos.type == messageInfos::TYPE_DELETED)
- {
- nums.push_back(num);
-
- for (std::vector <maildirMessage*>::iterator it =
- m_messages.begin() ; it != m_messages.end() ; ++it)
- {
- if ((*it)->m_num == num)
- (*it)->m_expunged = true;
- else if ((*it)->m_num > num)
- (*it)->m_num--;
- }
-
- if (maildirUtils::extractFlags(infos.path) & message::FLAG_SEEN)
- ++unreadCount;
-
- // Delete file from file system
- try
- {
- shared_ptr <utility::file> file = fsf->create(curDirPath / infos.path);
- file->remove();
- }
- catch (exceptions::filesystem_exception& e)
- {
- // Ignore (not important)
- }
- }
- }
-
- if (!nums.empty())
- {
- for (std::vector <int>::size_type i = nums.size() ; i != 0 ; --i)
- m_messageInfos.erase(m_messageInfos.begin() + (i - 1));
- }
-
- m_messageCount -= nums.size();
- m_unreadMessageCount -= unreadCount;
-
- // Notify message expunged
- shared_ptr <events::messageCountEvent> event =
- make_shared <events::messageCountEvent>
- (dynamicCast <folder>(shared_from_this()),
- events::messageCountEvent::TYPE_REMOVED, nums);
-
- notifyMessageCount(event);
-
- // Notify folders with the same path
- for (std::list <maildirFolder*>::iterator it = store->m_folders.begin() ;
- it != store->m_folders.end() ; ++it)
- {
- if ((*it) != this && (*it)->getFullPath() == m_path)
- {
- (*it)->m_messageCount = m_messageCount;
- (*it)->m_unreadMessageCount = m_unreadMessageCount;
-
- (*it)->m_messageInfos.resize(m_messageInfos.size());
- std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin());
-
- shared_ptr <events::messageCountEvent> event =
- make_shared <events::messageCountEvent>
- (dynamicCast <folder>((*it)->shared_from_this()),
- events::messageCountEvent::TYPE_REMOVED, nums);
-
- (*it)->notifyMessageCount(event);
- }
- }
-}
-
-
-shared_ptr <folder> maildirFolder::getParent()
-{
- if (m_path.isEmpty())
- return null;
- else
- return make_shared <maildirFolder>(m_path.getParent(), m_store.lock());
-}
-
-
-shared_ptr <const store> maildirFolder::getStore() const
-{
- return m_store.lock();
-}
-
-
-shared_ptr <store> maildirFolder::getStore()
-{
- return m_store.lock();
-}
-
-
-void maildirFolder::fetchMessages(std::vector <shared_ptr <message> >& msg,
- const fetchAttributes& options, utility::progressListener* progress)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- const size_t total = msg.size();
- size_t current = 0;
-
- if (progress)
- progress->start(total);
-
- shared_ptr <maildirFolder> thisFolder = dynamicCast <maildirFolder>(shared_from_this());
-
- for (std::vector <shared_ptr <message> >::iterator it = msg.begin() ;
- it != msg.end() ; ++it)
- {
- dynamicCast <maildirMessage>(*it)->fetch(thisFolder, options);
-
- if (progress)
- progress->progress(++current, total);
- }
-
- if (progress)
- progress->stop(total);
-}
-
-
-void maildirFolder::fetchMessage(shared_ptr <message> msg, const fetchAttributes& options)
-{
- shared_ptr <maildirStore> store = m_store.lock();
-
- if (!store)
- throw exceptions::illegal_state("Store disconnected");
- else if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- dynamicCast <maildirMessage>(msg)->fetch
- (dynamicCast <maildirFolder>(shared_from_this()), options);
-}
-
-
-int maildirFolder::getFetchCapabilities() const
-{
- return fetchAttributes::ENVELOPE | fetchAttributes::STRUCTURE |
- fetchAttributes::CONTENT_INFO | fetchAttributes::FLAGS |
- fetchAttributes::SIZE | fetchAttributes::FULL_HEADER |
- fetchAttributes::UID | fetchAttributes::IMPORTANCE;
-}
-
-
-const utility::file::path maildirFolder::getMessageFSPath(const int number) const
-{
- utility::file::path curDirPath = m_store.lock()->getFormat()->
- folderPathToFileSystemPath(m_path, maildirFormat::CUR_DIRECTORY);
-
- return (curDirPath / m_messageInfos[number - 1].path);
-}
-
-
-std::vector <int> maildirFolder::getMessageNumbersStartingOnUID(const message::uid& /* uid */)
-{
- throw exceptions::operation_not_supported();
-}
-
-
-} // maildir
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR
-
diff --git a/src/net/maildir/maildirFolderStatus.cpp b/src/net/maildir/maildirFolderStatus.cpp
deleted file mode 100644
index 9ee84dba..00000000
--- a/src/net/maildir/maildirFolderStatus.cpp
+++ /dev/null
@@ -1,88 +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_MAILDIR
-
-
-#include "vmime/net/maildir/maildirFolderStatus.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace maildir {
-
-
-maildirFolderStatus::maildirFolderStatus()
- : m_count(0),
- m_unseen(0)
-{
-}
-
-
-maildirFolderStatus::maildirFolderStatus(const maildirFolderStatus& other)
- : folderStatus(),
- m_count(other.m_count),
- m_unseen(other.m_unseen)
-{
-}
-
-
-unsigned int maildirFolderStatus::getMessageCount() const
-{
- return m_count;
-}
-
-
-unsigned int maildirFolderStatus::getUnseenCount() const
-{
- return m_unseen;
-}
-
-
-void maildirFolderStatus::setMessageCount(const unsigned int count)
-{
- m_count = count;
-}
-
-
-void maildirFolderStatus::setUnseenCount(const unsigned int unseen)
-{
- m_unseen = unseen;
-}
-
-
-shared_ptr <folderStatus> maildirFolderStatus::clone() const
-{
- return make_shared <maildirFolderStatus>(*this);
-}
-
-
-} // maildir
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR
diff --git a/src/net/maildir/maildirFormat.cpp b/src/net/maildir/maildirFormat.cpp
deleted file mode 100644
index f7a3c8fe..00000000
--- a/src/net/maildir/maildirFormat.cpp
+++ /dev/null
@@ -1,109 +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_MAILDIR
-
-
-#include "vmime/net/maildir/maildirFormat.hpp"
-#include "vmime/net/maildir/maildirStore.hpp"
-
-#include "vmime/net/maildir/format/kmailMaildirFormat.hpp"
-#include "vmime/net/maildir/format/courierMaildirFormat.hpp"
-
-#include "vmime/utility/file.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace maildir {
-
-
-const utility::file::path::component maildirFormat::TMP_DIR("tmp", vmime::charset(vmime::charsets::US_ASCII));
-const utility::file::path::component maildirFormat::CUR_DIR("cur", vmime::charset(vmime::charsets::US_ASCII));
-const utility::file::path::component maildirFormat::NEW_DIR("new", vmime::charset(vmime::charsets::US_ASCII));
-
-
-//
-// maildirFormat::context
-//
-
-maildirFormat::context::context(shared_ptr <maildirStore> store)
- : m_store(store)
-{
-}
-
-
-shared_ptr <maildirStore> maildirFormat::context::getStore() const
-{
- return constCast <maildirStore>(m_store.lock());
-}
-
-
-//
-// maildirFormat
-//
-
-maildirFormat::maildirFormat(shared_ptr <context> ctx)
- : m_context(ctx)
-{
-}
-
-
-shared_ptr <maildirFormat::context> maildirFormat::getContext()
-{
- return m_context;
-}
-
-
-shared_ptr <const maildirFormat::context> maildirFormat::getContext() const
-{
- return m_context;
-}
-
-
-// static
-shared_ptr <maildirFormat> maildirFormat::detect(shared_ptr <maildirStore> store)
-{
- shared_ptr <context> ctx = make_shared <context>(store);
-
- // Try Courier format
- shared_ptr <maildirFormat> fmt = make_shared <format::courierMaildirFormat>(ctx);
-
- if (fmt->supports())
- return fmt;
-
- // Default is KMail format
- return make_shared <format::kmailMaildirFormat>(ctx);
-}
-
-
-} // maildir
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR
-
diff --git a/src/net/maildir/maildirMessage.cpp b/src/net/maildir/maildirMessage.cpp
deleted file mode 100644
index a14f067e..00000000
--- a/src/net/maildir/maildirMessage.cpp
+++ /dev/null
@@ -1,369 +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_MAILDIR
-
-
-#include "vmime/net/maildir/maildirMessage.hpp"
-#include "vmime/net/maildir/maildirMessagePart.hpp"
-#include "vmime/net/maildir/maildirMessageStructure.hpp"
-#include "vmime/net/maildir/maildirFolder.hpp"
-#include "vmime/net/maildir/maildirUtils.hpp"
-#include "vmime/net/maildir/maildirStore.hpp"
-
-#include "vmime/message.hpp"
-
-#include "vmime/exception.hpp"
-#include "vmime/platform.hpp"
-
-#include "vmime/utility/outputStreamAdapter.hpp"
-#include "vmime/utility/stringUtils.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace maildir {
-
-
-maildirMessage::maildirMessage(shared_ptr <maildirFolder> folder, const int num)
- : m_folder(folder), m_num(num), m_size(-1), m_flags(FLAG_UNDEFINED),
- m_expunged(false), m_structure(null)
-{
- folder->registerMessage(this);
-}
-
-
-maildirMessage::~maildirMessage()
-{
- shared_ptr <maildirFolder> folder = m_folder.lock();
-
- if (folder)
- folder->unregisterMessage(this);
-}
-
-
-void maildirMessage::onFolderClosed()
-{
- m_folder.reset();
-}
-
-
-int maildirMessage::getNumber() const
-{
- return (m_num);
-}
-
-
-const message::uid maildirMessage::getUID() const
-{
- return (m_uid);
-}
-
-
-size_t maildirMessage::getSize() const
-{
- if (m_size == static_cast <size_t>(-1))
- throw exceptions::unfetched_object();
-
- return (m_size);
-}
-
-
-bool maildirMessage::isExpunged() const
-{
- return (m_expunged);
-}
-
-
-shared_ptr <const messageStructure> maildirMessage::getStructure() const
-{
- if (m_structure == NULL)
- throw exceptions::unfetched_object();
-
- return m_structure;
-}
-
-
-shared_ptr <messageStructure> maildirMessage::getStructure()
-{
- if (m_structure == NULL)
- throw exceptions::unfetched_object();
-
- return m_structure;
-}
-
-
-shared_ptr <const header> maildirMessage::getHeader() const
-{
- if (m_header == NULL)
- throw exceptions::unfetched_object();
-
- return (m_header);
-}
-
-
-int maildirMessage::getFlags() const
-{
- if (m_flags == FLAG_UNDEFINED)
- throw exceptions::unfetched_object();
-
- return (m_flags);
-}
-
-
-void maildirMessage::setFlags(const int flags, const int mode)
-{
- shared_ptr <maildirFolder> folder = m_folder.lock();
-
- if (!folder)
- throw exceptions::folder_not_found();
-
- folder->setMessageFlags(messageSet::byNumber(m_num), flags, mode);
-}
-
-
-void maildirMessage::extract(utility::outputStream& os,
- utility::progressListener* progress, const size_t start,
- const size_t length, const bool peek) const
-{
- extractImpl(os, progress, 0, m_size, start, length, peek);
-}
-
-
-void maildirMessage::extractPart(shared_ptr <const messagePart> p, utility::outputStream& os,
- utility::progressListener* progress, const size_t start,
- const size_t length, const bool peek) const
-{
- shared_ptr <const maildirMessagePart> mp = dynamicCast <const maildirMessagePart>(p);
-
- extractImpl(os, progress, mp->getBodyParsedOffset(), mp->getBodyParsedLength(),
- start, length, peek);
-}
-
-
-void maildirMessage::extractImpl(utility::outputStream& os, utility::progressListener* progress,
- const size_t start, const size_t length, const size_t partialStart, const size_t partialLength,
- const bool /* peek */) const
-{
- shared_ptr <const maildirFolder> folder = m_folder.lock();
-
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- const utility::file::path path = folder->getMessageFSPath(m_num);
- shared_ptr <utility::file> file = fsf->create(path);
-
- shared_ptr <utility::fileReader> reader = file->getFileReader();
- shared_ptr <utility::inputStream> is = reader->getInputStream();
-
- is->skip(start + partialStart);
-
- byte_t buffer[8192];
- size_t remaining = (partialLength == static_cast <size_t>(-1)
- ? length : std::min(partialLength, length));
-
- const size_t total = remaining;
- size_t current = 0;
-
- if (progress)
- progress->start(total);
-
- while (!is->eof() && remaining > 0)
- {
- const size_t read = is->read(buffer, std::min(remaining, sizeof(buffer)));
-
- remaining -= read;
- current += read;
-
- os.write(buffer, read);
-
- if (progress)
- progress->progress(current, total);
- }
-
- if (progress)
- progress->stop(total);
-
- // TODO: mark as read unless 'peek' is set
-}
-
-
-void maildirMessage::fetchPartHeader(shared_ptr <messagePart> p)
-{
- shared_ptr <maildirFolder> folder = m_folder.lock();
-
- shared_ptr <maildirMessagePart> mp = dynamicCast <maildirMessagePart>(p);
-
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- const utility::file::path path = folder->getMessageFSPath(m_num);
- shared_ptr <utility::file> file = fsf->create(path);
-
- shared_ptr <utility::fileReader> reader = file->getFileReader();
- shared_ptr <utility::inputStream> is = reader->getInputStream();
-
- is->skip(mp->getHeaderParsedOffset());
-
- byte_t buffer[1024];
- size_t remaining = mp->getHeaderParsedLength();
-
- string contents;
- contents.reserve(remaining);
-
- while (!is->eof() && remaining > 0)
- {
- const size_t read = is->read(buffer, std::min(remaining, sizeof(buffer)));
-
- remaining -= read;
-
- vmime::utility::stringUtils::appendBytesToString(contents, buffer, read);
- }
-
- mp->getOrCreateHeader().parse(contents);
-}
-
-
-void maildirMessage::fetch(shared_ptr <maildirFolder> msgFolder, const fetchAttributes& options)
-{
- shared_ptr <maildirFolder> folder = m_folder.lock();
-
- if (folder != msgFolder)
- throw exceptions::folder_not_found();
-
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- const utility::file::path path = folder->getMessageFSPath(m_num);
- shared_ptr <utility::file> file = fsf->create(path);
-
- if (options.has(fetchAttributes::FLAGS))
- m_flags = maildirUtils::extractFlags(path.getLastComponent());
-
- if (options.has(fetchAttributes::SIZE))
- m_size = file->getLength();
-
- if (options.has(fetchAttributes::UID))
- m_uid = maildirUtils::extractId(path.getLastComponent()).getBuffer();
-
- if (options.has(fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO |
- fetchAttributes::FULL_HEADER | fetchAttributes::STRUCTURE |
- fetchAttributes::IMPORTANCE))
- {
- string contents;
-
- shared_ptr <utility::fileReader> reader = file->getFileReader();
- shared_ptr <utility::inputStream> is = reader->getInputStream();
-
- // Need whole message contents for structure
- if (options.has(fetchAttributes::STRUCTURE))
- {
- byte_t buffer[16384];
-
- contents.reserve(file->getLength());
-
- while (!is->eof())
- {
- const size_t read = is->read(buffer, sizeof(buffer));
- vmime::utility::stringUtils::appendBytesToString(contents, buffer, read);
- }
- }
- // Need only header
- else
- {
- byte_t buffer[1024];
-
- contents.reserve(4096);
-
- while (!is->eof())
- {
- const size_t read = is->read(buffer, sizeof(buffer));
- vmime::utility::stringUtils::appendBytesToString(contents, buffer, read);
-
- const size_t sep1 = contents.rfind("\r\n\r\n");
- const size_t sep2 = contents.rfind("\n\n");
-
- if (sep1 != string::npos)
- {
- contents.erase(contents.begin() + sep1 + 4, contents.end());
- break;
- }
- else if (sep2 != string::npos)
- {
- contents.erase(contents.begin() + sep2 + 2, contents.end());
- break;
- }
- }
- }
-
- vmime::message msg;
- msg.parse(contents);
-
- // Extract structure
- if (options.has(fetchAttributes::STRUCTURE))
- {
- m_structure = make_shared <maildirMessageStructure>(shared_ptr <maildirMessagePart>(), msg);
- }
-
- // Extract some header fields or whole header
- if (options.has(fetchAttributes::ENVELOPE |
- fetchAttributes::CONTENT_INFO |
- fetchAttributes::FULL_HEADER |
- fetchAttributes::IMPORTANCE))
- {
- getOrCreateHeader()->copyFrom(*(msg.getHeader()));
- }
- }
-}
-
-
-shared_ptr <header> maildirMessage::getOrCreateHeader()
-{
- if (m_header != NULL)
- return (m_header);
- else
- return (m_header = make_shared <header>());
-}
-
-
-shared_ptr <vmime::message> maildirMessage::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;
-}
-
-
-} // maildir
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR
-
diff --git a/src/net/maildir/maildirMessagePart.cpp b/src/net/maildir/maildirMessagePart.cpp
deleted file mode 100644
index 6ae085c9..00000000
--- a/src/net/maildir/maildirMessagePart.cpp
+++ /dev/null
@@ -1,155 +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_MAILDIR
-
-
-#include "vmime/net/maildir/maildirMessagePart.hpp"
-#include "vmime/net/maildir/maildirMessageStructure.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace maildir {
-
-
-maildirMessagePart::maildirMessagePart(shared_ptr <maildirMessagePart> parent, const int number, const bodyPart& part)
- : m_parent(parent), m_header(null), m_number(number)
-{
- m_headerParsedOffset = part.getHeader()->getParsedOffset();
- m_headerParsedLength = part.getHeader()->getParsedLength();
-
- m_bodyParsedOffset = part.getBody()->getParsedOffset();
- m_bodyParsedLength = part.getBody()->getParsedLength();
-
- m_size = part.getBody()->getContents()->getLength();
-
- m_mediaType = part.getBody()->getContentType();
-}
-
-
-maildirMessagePart::~maildirMessagePart()
-{
-}
-
-
-void maildirMessagePart::initStructure(const bodyPart& part)
-{
- if (part.getBody()->getPartList().size() == 0)
- m_structure = null;
- else
- {
- m_structure = make_shared <maildirMessageStructure>
- (dynamicCast <maildirMessagePart>(shared_from_this()),
- part.getBody()->getPartList());
- }
-}
-
-
-shared_ptr <const messageStructure> maildirMessagePart::getStructure() const
-{
- if (m_structure != NULL)
- return m_structure;
- else
- return maildirMessageStructure::emptyStructure();
-}
-
-
-shared_ptr <messageStructure> maildirMessagePart::getStructure()
-{
- if (m_structure != NULL)
- return m_structure;
- else
- return maildirMessageStructure::emptyStructure();
-}
-
-
-const mediaType& maildirMessagePart::getType() const
-{
- return m_mediaType;
-}
-
-
-size_t maildirMessagePart::getSize() const
-{
- return m_size;
-}
-
-
-int maildirMessagePart::getNumber() const
-{
- return m_number;
-}
-
-
-shared_ptr <const header> maildirMessagePart::getHeader() const
-{
- if (m_header == NULL)
- throw exceptions::unfetched_object();
- else
- return m_header;
-}
-
-
-header& maildirMessagePart::getOrCreateHeader()
-{
- if (m_header != NULL)
- return *m_header;
- else
- return *(m_header = make_shared <header>());
-}
-
-
-size_t maildirMessagePart::getHeaderParsedOffset() const
-{
- return m_headerParsedOffset;
-}
-
-
-size_t maildirMessagePart::getHeaderParsedLength() const
-{
- return m_headerParsedLength;
-}
-
-
-size_t maildirMessagePart::getBodyParsedOffset() const
-{
- return m_bodyParsedOffset;
-}
-
-
-size_t maildirMessagePart::getBodyParsedLength() const
-{
- return m_bodyParsedLength;
-}
-
-
-} // maildir
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR
diff --git a/src/net/maildir/maildirMessageStructure.cpp b/src/net/maildir/maildirMessageStructure.cpp
deleted file mode 100644
index f3b7cf59..00000000
--- a/src/net/maildir/maildirMessageStructure.cpp
+++ /dev/null
@@ -1,98 +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_MAILDIR
-
-
-#include "vmime/net/maildir/maildirMessageStructure.hpp"
-#include "vmime/net/maildir/maildirMessagePart.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace maildir {
-
-
-shared_ptr <maildirMessageStructure> maildirMessageStructure::m_emptyStructure = make_shared <maildirMessageStructure>();
-
-
-maildirMessageStructure::maildirMessageStructure()
-{
-}
-
-
-maildirMessageStructure::maildirMessageStructure(shared_ptr <maildirMessagePart> parent, const bodyPart& part)
-{
- shared_ptr <maildirMessagePart> mpart = make_shared <maildirMessagePart>(parent, 0, part);
- mpart->initStructure(part);
-
- m_parts.push_back(mpart);
-}
-
-
-maildirMessageStructure::maildirMessageStructure(shared_ptr <maildirMessagePart> parent, const std::vector <shared_ptr <const vmime::bodyPart> >& list)
-{
- for (unsigned int i = 0 ; i < list.size() ; ++i)
- {
- shared_ptr <maildirMessagePart> mpart = make_shared <maildirMessagePart>(parent, i, *list[i]);
- mpart->initStructure(*list[i]);
-
- m_parts.push_back(mpart);
- }
-}
-
-
-shared_ptr <const messagePart> maildirMessageStructure::getPartAt(const size_t x) const
-{
- return m_parts[x];
-}
-
-
-shared_ptr <messagePart> maildirMessageStructure::getPartAt(const size_t x)
-{
- return m_parts[x];
-}
-
-
-size_t maildirMessageStructure::getPartCount() const
-{
- return m_parts.size();
-}
-
-
-// static
-shared_ptr <maildirMessageStructure> maildirMessageStructure::emptyStructure()
-{
- return m_emptyStructure;
-}
-
-
-} // maildir
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR
diff --git a/src/net/maildir/maildirServiceInfos.cpp b/src/net/maildir/maildirServiceInfos.cpp
deleted file mode 100644
index 974a0c21..00000000
--- a/src/net/maildir/maildirServiceInfos.cpp
+++ /dev/null
@@ -1,77 +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_MAILDIR
-
-
-#include "vmime/net/maildir/maildirServiceInfos.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace maildir {
-
-
-maildirServiceInfos::maildirServiceInfos()
-{
-}
-
-
-const string maildirServiceInfos::getPropertyPrefix() const
-{
- return "store.maildir.";
-}
-
-
-const maildirServiceInfos::props& maildirServiceInfos::getProperties() const
-{
- static props maildirProps =
- {
- property(serviceInfos::property::SERVER_ROOTPATH, serviceInfos::property::FLAG_REQUIRED)
- };
-
- return maildirProps;
-}
-
-
-const std::vector <serviceInfos::property> maildirServiceInfos::getAvailableProperties() const
-{
- std::vector <property> list;
- const props& p = getProperties();
-
- list.push_back(p.PROPERTY_SERVER_ROOTPATH);
-
- return list;
-}
-
-
-} // maildir
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR
-
diff --git a/src/net/maildir/maildirStore.cpp b/src/net/maildir/maildirStore.cpp
deleted file mode 100644
index 87e733e2..00000000
--- a/src/net/maildir/maildirStore.cpp
+++ /dev/null
@@ -1,272 +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_MAILDIR
-
-
-#include "vmime/net/maildir/maildirStore.hpp"
-
-#include "vmime/net/maildir/maildirFolder.hpp"
-#include "vmime/net/maildir/maildirFormat.hpp"
-
-#include "vmime/exception.hpp"
-#include "vmime/platform.hpp"
-
-#include "vmime/net/defaultConnectionInfos.hpp"
-
-
-// Helpers for service properties
-#define GET_PROPERTY(type, prop) \
- (getInfos().getPropertyValue <type>(getSession(), \
- dynamic_cast <const maildirServiceInfos&>(getInfos()).getProperties().prop))
-#define HAS_PROPERTY(prop) \
- (getInfos().hasProperty(getSession(), \
- dynamic_cast <const maildirServiceInfos&>(getInfos()).getProperties().prop))
-
-
-namespace vmime {
-namespace net {
-namespace maildir {
-
-
-maildirStore::maildirStore(shared_ptr <session> sess, shared_ptr <security::authenticator> auth)
- : store(sess, getInfosInstance(), auth), m_connected(false)
-{
-}
-
-
-maildirStore::~maildirStore()
-{
- try
- {
- if (isConnected())
- disconnect();
- }
- catch (vmime::exception&)
- {
- // Ignore
- }
-}
-
-
-const string maildirStore::getProtocolName() const
-{
- return "maildir";
-}
-
-
-shared_ptr <folder> maildirStore::getRootFolder()
-{
- if (!isConnected())
- throw exceptions::illegal_state("Not connected");
-
- return make_shared <maildirFolder>
- (folder::path(),
- dynamicCast <maildirStore>(shared_from_this()));
-}
-
-
-shared_ptr <folder> maildirStore::getDefaultFolder()
-{
- if (!isConnected())
- throw exceptions::illegal_state("Not connected");
-
- return make_shared <maildirFolder>
- (folder::path::component("inbox"),
- dynamicCast <maildirStore>(shared_from_this()));
-}
-
-
-shared_ptr <folder> maildirStore::getFolder(const folder::path& path)
-{
- if (!isConnected())
- throw exceptions::illegal_state("Not connected");
-
- return make_shared <maildirFolder>
- (path, dynamicCast <maildirStore>(shared_from_this()));
-}
-
-
-bool maildirStore::isValidFolderName(const folder::path::component& name) const
-{
- if (!platform::getHandler()->getFileSystemFactory()->isValidPathComponent(name))
- return false;
-
- const string& buf = name.getBuffer();
-
- // Name cannot start/end with spaces
- if (utility::stringUtils::trim(buf) != buf)
- return false;
-
- // Name cannot start with '.'
- const size_t length = buf.length();
- int pos = 0;
-
- while ((pos < length) && (buf[pos] == '.'))
- ++pos;
-
- return (pos == 0);
-}
-
-
-void maildirStore::connect()
-{
- if (isConnected())
- throw exceptions::already_connected();
-
- // Get root directory
- shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
-
- m_fsPath = fsf->stringToPath(GET_PROPERTY(string, PROPERTY_SERVER_ROOTPATH));
-
- shared_ptr <utility::file> rootDir = fsf->create(m_fsPath);
-
- // Try to create the root directory if it does not exist
- if (!(rootDir->exists() && rootDir->isDirectory()))
- {
- try
- {
- rootDir->createDirectory();
- }
- catch (exceptions::filesystem_exception& e)
- {
- throw exceptions::connection_error("Cannot create root directory.", e);
- }
- }
-
- m_format = maildirFormat::detect(dynamicCast <maildirStore>(shared_from_this()));
-
- m_connected = true;
-}
-
-
-bool maildirStore::isConnected() const
-{
- return (m_connected);
-}
-
-
-bool maildirStore::isSecuredConnection() const
-{
- return false;
-}
-
-
-shared_ptr <connectionInfos> maildirStore::getConnectionInfos() const
-{
- return make_shared <defaultConnectionInfos>("localhost", static_cast <port_t>(0));
-}
-
-
-void maildirStore::disconnect()
-{
- for (std::list <maildirFolder*>::iterator it = m_folders.begin() ;
- it != m_folders.end() ; ++it)
- {
- (*it)->onStoreDisconnected();
- }
-
- m_folders.clear();
-
- m_connected = false;
-}
-
-
-void maildirStore::noop()
-{
- // Nothing to do.
-}
-
-
-shared_ptr <maildirFormat> maildirStore::getFormat()
-{
- return m_format;
-}
-
-
-shared_ptr <const maildirFormat> maildirStore::getFormat() const
-{
- return m_format;
-}
-
-
-void maildirStore::registerFolder(maildirFolder* folder)
-{
- m_folders.push_back(folder);
-}
-
-
-void maildirStore::unregisterFolder(maildirFolder* folder)
-{
- std::list <maildirFolder*>::iterator it = std::find(m_folders.begin(), m_folders.end(), folder);
- if (it != m_folders.end()) m_folders.erase(it);
-}
-
-
-const utility::path& maildirStore::getFileSystemPath() const
-{
- return (m_fsPath);
-}
-
-
-int maildirStore::getCapabilities() const
-{
- return (CAPABILITY_CREATE_FOLDER |
- CAPABILITY_RENAME_FOLDER |
- CAPABILITY_ADD_MESSAGE |
- CAPABILITY_COPY_MESSAGE |
- CAPABILITY_DELETE_MESSAGE |
- CAPABILITY_PARTIAL_FETCH |
- CAPABILITY_MESSAGE_FLAGS |
- CAPABILITY_EXTRACT_PART);
-}
-
-
-
-// Service infos
-
-maildirServiceInfos maildirStore::sm_infos;
-
-
-const serviceInfos& maildirStore::getInfosInstance()
-{
- return sm_infos;
-}
-
-
-const serviceInfos& maildirStore::getInfos() const
-{
- return sm_infos;
-}
-
-
-} // maildir
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR
-
diff --git a/src/net/maildir/maildirUtils.cpp b/src/net/maildir/maildirUtils.cpp
deleted file mode 100644
index 77aac715..00000000
--- a/src/net/maildir/maildirUtils.cpp
+++ /dev/null
@@ -1,273 +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_MAILDIR
-
-
-#include "vmime/net/maildir/maildirUtils.hpp"
-#include "vmime/net/maildir/maildirStore.hpp"
-
-#include "vmime/utility/random.hpp"
-#include "vmime/platform.hpp"
-
-#include "vmime/exception.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace maildir {
-
-
-bool maildirUtils::isMessageFile(const utility::file& file)
-{
- // Ignore files which name begins with '.'
- if (file.isFile() &&
- file.getFullPath().getLastComponent().getBuffer().length() >= 1 &&
- file.getFullPath().getLastComponent().getBuffer()[0] != '.')
- {
- return (true);
- }
-
- return (false);
-}
-
-
-// NOTE ABOUT ID/FLAGS SEPARATOR
-// -----------------------------
-// In the maildir specification, the character ':' is used to separate
-// the unique identifier and the message flags.
-//
-// On Windows (and particularly FAT file systems), ':' is not allowed
-// in a filename, so we use a dash ('-') instead. This is the solution
-// used by Mutt/Win32, so we also use it here.
-//
-// To be compatible between implementations, we check for both
-// characters when reading file names.
-
-
-const utility::file::path::component maildirUtils::extractId
- (const utility::file::path::component& filename)
-{
- size_t sep = filename.getBuffer().rfind(':'); // try colon
-
- if (sep == string::npos)
- {
- sep = filename.getBuffer().rfind('-'); // try dash (Windows)
- if (sep == string::npos) return (filename);
- }
-
- return (utility::path::component
- (string(filename.getBuffer().begin(), filename.getBuffer().begin() + sep)));
-}
-
-
-int maildirUtils::extractFlags(const utility::file::path::component& comp)
-{
- size_t sep = comp.getBuffer().rfind(':'); // try colon
-
- if (sep == string::npos)
- {
- sep = comp.getBuffer().rfind('-'); // try dash (Windows)
- if (sep == string::npos) return 0;
- }
-
- const string flagsString(comp.getBuffer().begin() + sep + 1, comp.getBuffer().end());
- const size_t count = flagsString.length();
-
- int flags = 0;
-
- for (size_t i = 0 ; i < count ; ++i)
- {
- switch (flagsString[i])
- {
- case 'R': case 'r': flags |= message::FLAG_REPLIED; break;
- case 'S': case 's': flags |= message::FLAG_SEEN; break;
- case 'T': case 't': flags |= message::FLAG_DELETED; break;
- case 'F': case 'f': flags |= message::FLAG_MARKED; break;
- case 'P': case 'p': flags |= message::FLAG_PASSED; break;
- case 'D': case 'd': flags |= message::FLAG_DRAFT; break;
- }
- }
-
- return (flags);
-}
-
-
-const utility::file::path::component maildirUtils::buildFlags(const int flags)
-{
- string str;
- str.reserve(8);
-
- str += "2,";
-
- if (flags & message::FLAG_MARKED) str += "F";
- if (flags & message::FLAG_PASSED) str += "P";
- if (flags & message::FLAG_REPLIED) str += "R";
- if (flags & message::FLAG_SEEN) str += "S";
- if (flags & message::FLAG_DELETED) str += "T";
- if (flags & message::FLAG_DRAFT) str += "D";
-
- return (utility::file::path::component(str));
-}
-
-
-const utility::file::path::component maildirUtils::buildFilename
- (const utility::file::path::component& id, const int flags)
-{
- if (flags == message::FLAG_RECENT)
- return id;
- else
- return (buildFilename(id, buildFlags(flags)));
-}
-
-
-const utility::file::path::component maildirUtils::buildFilename
- (const utility::file::path::component& id,
- const utility::file::path::component& flags)
-{
-#if VMIME_PLATFORM_IS_WINDOWS
- static const char DELIMITER[] = "-";
-#else
- static const char DELIMITER[] = ":";
-#endif
-
- return utility::path::component(id.getBuffer() + DELIMITER + flags.getBuffer());
-}
-
-
-const utility::file::path::component maildirUtils::generateId()
-{
- std::ostringstream oss;
- oss.imbue(std::locale::classic());
-
- oss << utility::random::getTime();
- oss << ".";
- oss << utility::random::getProcess();
- oss << ".";
- oss << utility::random::getString(6);
- oss << ".";
- oss << platform::getHandler()->getHostName();
-
- return (utility::file::path::component(oss.str()));
-}
-
-
-void maildirUtils::recursiveFSDelete(shared_ptr <utility::file> dir)
-{
- shared_ptr <utility::fileIterator> files = dir->getFiles();
-
- // First, delete files and subdirectories in this directory
- while (files->hasMoreElements())
- {
- shared_ptr <utility::file> file = files->nextElement();
-
- if (file->isDirectory())
- {
- maildirUtils::recursiveFSDelete(file);
- }
- else
- {
- try
- {
- file->remove();
- }
- catch (exceptions::filesystem_exception&)
- {
- // Ignore
- }
- }
- }
-
- // Then, delete this (empty) directory
- try
- {
- dir->remove();
- }
- catch (exceptions::filesystem_exception&)
- {
- // Ignore
- }
-}
-
-
-
-class maildirMessageSetEnumerator : public messageSetEnumerator
-{
-public:
-
- void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range)
- {
- for (int i = range.getFirst(), last = range.getLast() ; i <= last ; ++i)
- list.push_back(i);
- }
-
- void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& /* range */)
- {
- // Not supported
- }
-
-public:
-
- std::vector <int> list;
-};
-
-
-// static
-const std::vector <int> maildirUtils::messageSetToNumberList(const messageSet& msgs)
-{
- maildirMessageSetEnumerator en;
- msgs.enumerate(en);
-
- return en.list;
-}
-
-
-
-//
-// messageIdComparator
-//
-
-maildirUtils::messageIdComparator::messageIdComparator
- (const utility::file::path::component& comp)
- : m_comp(maildirUtils::extractId(comp))
-{
-}
-
-
-bool maildirUtils::messageIdComparator::operator()
- (const utility::file::path::component& other) const
-{
- return (m_comp == maildirUtils::extractId(other));
-}
-
-
-} // maildir
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR
-
diff --git a/src/net/message.cpp b/src/net/message.cpp
deleted file mode 100644
index 6765e73c..00000000
--- a/src/net/message.cpp
+++ /dev/null
@@ -1,150 +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
-
-
-#include "vmime/net/message.hpp"
-
-#include <sstream>
-
-
-namespace vmime {
-namespace net {
-
-
-shared_ptr <const messagePart> messagePart::getPartAt(const size_t pos) const
-{
- return getStructure()->getPartAt(pos);
-}
-
-
-shared_ptr <messagePart> messagePart::getPartAt(const size_t pos)
-{
- return getStructure()->getPartAt(pos);
-}
-
-
-size_t messagePart::getPartCount() const
-{
- return getStructure()->getPartCount();
-}
-
-
-
-// message::uid
-
-
-message::uid::uid()
-{
-}
-
-
-message::uid::uid(const string& uid)
- : m_str(uid)
-{
-}
-
-
-message::uid::uid(const unsigned long uid)
-{
- std::ostringstream oss;
- oss.imbue(std::locale::classic());
- oss << uid;
-
- m_str = oss.str();
-}
-
-
-message::uid::uid(const char* uid)
- : m_str(uid)
-{
-}
-
-
-message::uid::uid(const uid& other)
-{
- m_str = other.m_str;
-}
-
-
-message::uid& message::uid::operator=(const uid& other)
-{
- m_str = other.m_str;
- return *this;
-}
-
-
-message::uid& message::uid::operator=(const string& uid)
-{
- m_str = uid;
- return *this;
-}
-
-
-message::uid& message::uid::operator=(const unsigned long uid)
-{
- std::ostringstream oss;
- oss.imbue(std::locale::classic());
- oss << uid;
-
- m_str = oss.str();
-
- return *this;
-}
-
-
-message::uid::operator string() const
-{
- return m_str;
-}
-
-
-bool message::uid::empty() const
-{
- return m_str.empty();
-}
-
-
-bool message::uid::operator==(const uid& other) const
-{
- return m_str == other.m_str;
-}
-
-
-std::ostream& operator<<(std::ostream& os, const message::uid& uid)
-{
- os << static_cast <string>(uid);
- return os;
-}
-
-
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES
-
diff --git a/src/net/messageSet.cpp b/src/net/messageSet.cpp
deleted file mode 100644
index 2939042e..00000000
--- a/src/net/messageSet.cpp
+++ /dev/null
@@ -1,369 +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/net/messageSet.hpp"
-
-#include <iterator>
-#include <algorithm>
-#include <typeinfo>
-
-
-namespace vmime {
-namespace net {
-
-
-// messageRange
-
-messageRange::messageRange()
-{
-}
-
-
-messageRange::~messageRange()
-{
-}
-
-
-// numberMessageRange
-
-numberMessageRange::numberMessageRange(const int number)
- : m_first(number), m_last(number)
-{
- if (number < 1)
- throw std::invalid_argument("number");
-}
-
-
-numberMessageRange::numberMessageRange(const int first, const int last)
- : m_first(first), m_last(last)
-{
- if (first < 1)
- throw std::invalid_argument("first");
- else if (last != -1 && last < first)
- throw std::invalid_argument("last");
-}
-
-
-numberMessageRange::numberMessageRange(const numberMessageRange& other)
- : messageRange(), m_first(other.m_first), m_last(other.m_last)
-{
-}
-
-
-int numberMessageRange::getFirst() const
-{
- return m_first;
-}
-
-
-int numberMessageRange::getLast() const
-{
- return m_last;
-}
-
-
-void numberMessageRange::enumerate(messageSetEnumerator& en) const
-{
- en.enumerateNumberMessageRange(*this);
-}
-
-
-messageRange* numberMessageRange::clone() const
-{
- return new numberMessageRange(*this);
-}
-
-
-// UIDMessageRange
-
-UIDMessageRange::UIDMessageRange(const message::uid& uid)
- : m_first(uid), m_last(uid)
-{
-}
-
-
-UIDMessageRange::UIDMessageRange(const message::uid& first, const message::uid& last)
- : m_first(first), m_last(last)
-{
-}
-
-
-UIDMessageRange::UIDMessageRange(const UIDMessageRange& other)
- : messageRange(), m_first(other.m_first), m_last(other.m_last)
-{
-}
-
-
-const message::uid UIDMessageRange::getFirst() const
-{
- return m_first;
-}
-
-
-const message::uid UIDMessageRange::getLast() const
-{
- return m_last;
-}
-
-
-void UIDMessageRange::enumerate(messageSetEnumerator& en) const
-{
- en.enumerateUIDMessageRange(*this);
-}
-
-
-messageRange* UIDMessageRange::clone() const
-{
- return new UIDMessageRange(*this);
-}
-
-
-// messageSet
-
-
-messageSet::messageSet()
-{
-}
-
-
-messageSet::messageSet(const messageSet& other)
- : object()
-{
- m_ranges.resize(other.m_ranges.size());
-
- for (size_t i = 0, n = other.m_ranges.size() ; i < n ; ++i)
- m_ranges[i] = other.m_ranges[i]->clone();
-}
-
-
-messageSet::~messageSet()
-{
- for (size_t i = 0, n = m_ranges.size() ; i < n ; ++i)
- delete m_ranges[i];
-}
-
-
-// static
-messageSet messageSet::byNumber(const int number)
-{
- messageSet set;
- set.m_ranges.push_back(new numberMessageRange(number));
-
- return set;
-}
-
-
-// static
-messageSet messageSet::byNumber(const int first, const int last)
-{
- messageSet set;
- set.m_ranges.push_back(new numberMessageRange(first, last));
-
- return set;
-}
-
-
-// static
-messageSet messageSet::byNumber(const std::vector <int>& numbers)
-{
- // Sort a copy of the list
- std::vector <int> sortedNumbers;
-
- sortedNumbers.resize(numbers.size());
-
- std::copy(numbers.begin(), numbers.end(), sortedNumbers.begin());
- std::sort(sortedNumbers.begin(), sortedNumbers.end());
-
- // Build the set by detecting ranges of continuous numbers
- int previous = -1, rangeStart = -1;
- messageSet set;
-
- for (std::vector <int>::const_iterator it = sortedNumbers.begin() ;
- it != sortedNumbers.end() ; ++it)
- {
- const int current = *it;
-
- if (current == previous)
- continue; // skip duplicates
-
- if (previous == -1)
- {
- previous = current;
- rangeStart = current;
- }
- else
- {
- if (current == previous + 1)
- {
- previous = current;
- }
- else
- {
- set.m_ranges.push_back(new numberMessageRange(rangeStart, previous));
-
- previous = current;
- rangeStart = current;
- }
- }
- }
-
- set.m_ranges.push_back(new numberMessageRange(rangeStart, previous));
-
- return set;
-}
-
-
-// static
-messageSet messageSet::byUID(const message::uid& uid)
-{
- messageSet set;
- set.m_ranges.push_back(new UIDMessageRange(uid));
-
- return set;
-}
-
-
-messageSet messageSet::byUID(const message::uid& first, const message::uid& last)
-{
- messageSet set;
- set.m_ranges.push_back(new UIDMessageRange(first, last));
-
- return set;
-}
-
-
-messageSet messageSet::byUID(const std::vector <message::uid>& uids)
-{
- std::vector <vmime_uint32> numericUIDs;
-
- for (size_t i = 0, n = uids.size() ; i < n ; ++i)
- {
- const string uid = uids[i];
- int numericUID = 0;
-
- const char* p = uid.c_str();
-
- for ( ; *p >= '0' && *p <= '9' ; ++p)
- numericUID = (numericUID * 10) + (*p - '0');
-
- if (*p != '\0')
- {
- messageSet set;
-
- // Non-numeric UID, fall back to plain UID list (single-UID ranges)
- for (size_t i = 0, n = uids.size() ; i < n ; ++i)
- set.m_ranges.push_back(new UIDMessageRange(uids[i]));
-
- return set;
- }
-
- numericUIDs.push_back(numericUID);
- }
-
- // Sort a copy of the list
- std::vector <vmime_uint32> sortedUIDs;
-
- sortedUIDs.resize(numericUIDs.size());
-
- std::copy(numericUIDs.begin(), numericUIDs.end(), sortedUIDs.begin());
- std::sort(sortedUIDs.begin(), sortedUIDs.end());
-
- // Build the set by detecting ranges of continuous numbers
- vmime_uint32 previous = -1U, rangeStart = -1U;
- messageSet set;
-
- for (std::vector <vmime_uint32>::const_iterator it = sortedUIDs.begin() ;
- it != sortedUIDs.end() ; ++it)
- {
- const vmime_uint32 current = *it;
-
- if (current == previous)
- continue; // skip duplicates
-
- if (previous == -1U)
- {
- previous = current;
- rangeStart = current;
- }
- else
- {
- if (current == previous + 1)
- {
- previous = current;
- }
- else
- {
- set.m_ranges.push_back(new UIDMessageRange
- (utility::stringUtils::toString(rangeStart),
- utility::stringUtils::toString(previous)));
-
- previous = current;
- rangeStart = current;
- }
- }
- }
-
- set.m_ranges.push_back(new UIDMessageRange
- (utility::stringUtils::toString(rangeStart),
- utility::stringUtils::toString(previous)));
-
- return set;
-}
-
-
-void messageSet::addRange(const messageRange& range)
-{
- if (!m_ranges.empty() && typeid(*m_ranges[0]) != typeid(range))
- throw std::invalid_argument("range");
-
- m_ranges.push_back(range.clone());
-}
-
-
-void messageSet::enumerate(messageSetEnumerator& en) const
-{
- for (size_t i = 0, n = m_ranges.size() ; i < n ; ++i)
- m_ranges[i]->enumerate(en);
-}
-
-
-bool messageSet::isEmpty() const
-{
- return m_ranges.empty();
-}
-
-
-bool messageSet::isNumberSet() const
-{
- return !isEmpty() && dynamic_cast <numberMessageRange*>(m_ranges[0]) != NULL;
-}
-
-
-bool messageSet::isUIDSet() const
-{
- return !isEmpty() && dynamic_cast <UIDMessageRange*>(m_ranges[0]) != NULL;
-}
-
-
-} // net
-} // vmime
diff --git a/src/net/pop3/POP3Command.cpp b/src/net/pop3/POP3Command.cpp
deleted file mode 100644
index 6fe301ce..00000000
--- a/src/net/pop3/POP3Command.cpp
+++ /dev/null
@@ -1,230 +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_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)
- : m_text(text)
-{
-}
-
-
-// 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::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;
-
- return createCommand(cmd.str());
-}
-
-
-// static
-shared_ptr <POP3Command> POP3Command::PASS(const string& password)
-{
- std::ostringstream cmd;
- cmd.imbue(std::locale::classic());
- cmd << "PASS " << password;
-
- return createCommand(cmd.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)
-{
- return shared_ptr <POP3Command>(new POP3Command(text));
-}
-
-
-const string POP3Command::getText() const
-{
- return m_text;
-}
-
-
-void POP3Command::send(shared_ptr <POP3Connection> conn)
-{
- conn->getSocket()->send(m_text + "\r\n");
-}
-
-
-} // pop3
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
diff --git a/src/net/pop3/POP3Connection.cpp b/src/net/pop3/POP3Connection.cpp
deleted file mode 100644
index 5fa923f4..00000000
--- a/src/net/pop3/POP3Connection.cpp
+++ /dev/null
@@ -1,675 +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_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(shared_ptr <POP3Store> store, 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)
-{
-}
-
-
-POP3Connection::~POP3Connection()
-{
- try
- {
- if (isConnected())
- disconnect();
- else if (m_socket)
- internalDisconnect();
- }
- catch (vmime::exception&)
- {
- // Ignore
- }
-}
-
-
-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);
-
-#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 <[email protected]>
-
- 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& e)
- {
- if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL_FALLBACK))
- {
- // Can't fallback on APOP/normal authentication
- internalDisconnect();
- throw e;
- }
- else
- {
- // Ignore, will try APOP/normal authentication
- }
- }
- catch (exception& e)
- {
- internalDisconnect();
- throw e;
- }
- }
-#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);
- 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 =
- make_shared <security::sasl::SASLContext>();
-
- 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();
-
- POP3Command::AUTH(mech->getName())->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
- m_socket->send(saslContext->encodeB64(resp, respLen) + "\r\n");
- }
- 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");
- }
- 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_timeoutHandler);
-
- 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 <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/src/net/pop3/POP3Folder.cpp b/src/net/pop3/POP3Folder.cpp
deleted file mode 100644
index 096de8af..00000000
--- a/src/net/pop3/POP3Folder.cpp
+++ /dev/null
@@ -1,729 +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_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, 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()
-{
- shared_ptr <POP3Store> store = m_store.lock();
-
- if (store)
- {
- if (m_open)
- close(false);
-
- store->unregisterFolder(this);
- }
- else if (m_open)
- {
- onClose();
- }
-}
-
-
-int POP3Folder::getMode() const
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- return (m_mode);
-}
-
-
-int POP3Folder::getType()
-{
- if (!isOpen())
- throw exceptions::illegal_state("Folder not open");
-
- if (m_path.isEmpty())
- return (TYPE_CONTAINS_FOLDERS);
- else if (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX")
- return (TYPE_CONTAINS_MESSAGES);
- else
- throw exceptions::folder_not_found();
-}
-
-
-int POP3Folder::getFlags()
-{
- return (0);
-}
-
-
-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 >> 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 int /* type */)
-{
- 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 int 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 <int> numbers = POP3Utils::messageSetToNumberList(msgs);
-
- std::vector <shared_ptr <message> > messages;
- shared_ptr <POP3Folder> thisFolder(dynamicCast <POP3Folder>(shared_from_this()));
-
- for (std::vector <int>::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();
- }
-}
-
-
-int 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 make_shared <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(make_shared <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");
-
- 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 <int, 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 <int, string>::const_iterator x = result.find(m->m_num);
-
- if (x != result.end())
- {
- size_t size = 0;
-
- std::istringstream iss((*x).second);
- 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 <int, 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 <int, 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(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 >> 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());
- }
- }
- }
-}
-
-
-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 make_shared <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 <int> nums = POP3Utils::messageSetToNumberList(msgs);
-
- 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 <int>::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 <int> 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*, int>::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();
-}
-
-
-void POP3Folder::addMessage
- (shared_ptr <vmime::message> /* msg */, const int /* flags */,
- vmime::datetime* /* date */, utility::progressListener* /* progress */)
-{
- throw exceptions::operation_not_supported();
-}
-
-
-void POP3Folder::addMessage
- (utility::inputStream& /* is */, const size_t /* size */, const int /* flags */,
- vmime::datetime* /* date */, utility::progressListener* /* progress */)
-{
- throw exceptions::operation_not_supported();
-}
-
-
-void POP3Folder::copyMessages(const folder::path& /* dest */, const messageSet& /* msgs */)
-{
- throw exceptions::operation_not_supported();
-}
-
-
-void POP3Folder::status(int& count, int& unseen)
-{
- count = 0;
- unseen = 0;
-
- shared_ptr <folderStatus> status = getStatus();
-
- count = status->getMessageCount();
- unseen = status->getUnseenCount();
-}
-
-
-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());
-
-
- unsigned int count = 0;
-
- std::istringstream iss(response->getText());
- iss >> count;
-
- shared_ptr <POP3FolderStatus> status = make_shared <POP3FolderStatus>();
-
- status->setMessageCount(count);
- status->setUnseenCount(count);
-
- // Update local message count
- if (m_messageCount != count)
- {
- const int oldCount = m_messageCount;
-
- m_messageCount = count;
-
- if (count > oldCount)
- {
- std::vector <int> nums;
- nums.reserve(count - oldCount);
-
- for (int 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 <int> 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/src/net/pop3/POP3FolderStatus.cpp b/src/net/pop3/POP3FolderStatus.cpp
deleted file mode 100644
index 944379ac..00000000
--- a/src/net/pop3/POP3FolderStatus.cpp
+++ /dev/null
@@ -1,88 +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_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)
-{
-}
-
-
-unsigned int POP3FolderStatus::getMessageCount() const
-{
- return m_count;
-}
-
-
-unsigned int POP3FolderStatus::getUnseenCount() const
-{
- return m_unseen;
-}
-
-
-void POP3FolderStatus::setMessageCount(const unsigned int count)
-{
- m_count = count;
-}
-
-
-void POP3FolderStatus::setUnseenCount(const unsigned int 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/src/net/pop3/POP3Message.cpp b/src/net/pop3/POP3Message.cpp
deleted file mode 100644
index 08523611..00000000
--- a/src/net/pop3/POP3Message.cpp
+++ /dev/null
@@ -1,250 +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_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(shared_ptr <POP3Folder> folder, const int num)
- : m_folder(folder), m_num(num), m_size(-1), m_deleted(false)
-{
- folder->registerMessage(this);
-}
-
-
-POP3Message::~POP3Message()
-{
- shared_ptr <POP3Folder> folder = m_folder.lock();
-
- if (folder)
- folder->unregisterMessage(this);
-}
-
-
-void POP3Message::onFolderClosed()
-{
- m_folder.reset();
-}
-
-
-int 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 = FLAG_RECENT;
-
- 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 == NULL)
- 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 = constCast <POP3Folder>(folder)->m_store.lock();
-
- POP3Command::RETR(m_num)->send(store->getConnection());
-
- try
- {
- POP3Response::readLargeResponse
- (store->getConnection(), os, progress, m_size);
- }
- catch (exceptions::command_error& e)
- {
- throw exceptions::command_error("RETR", e.response());
- }
-}
-
-
-void POP3Message::extractPart
- (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(shared_ptr <messagePart> /* p */)
-{
- throw exceptions::operation_not_supported();
-}
-
-
-void POP3Message::fetch(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/src/net/pop3/POP3Response.cpp b/src/net/pop3/POP3Response.cpp
deleted file mode 100644
index 1dc5ee76..00000000
--- a/src/net/pop3/POP3Response.cpp
+++ /dev/null
@@ -1,428 +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_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(shared_ptr <socket> sok, shared_ptr <timeoutHandler> toh)
- : m_socket(sok), m_timeoutHandler(toh)
-{
-}
-
-
-// static
-shared_ptr <POP3Response> POP3Response::readResponse(shared_ptr <POP3Connection> conn)
-{
- shared_ptr <POP3Response> resp = shared_ptr <POP3Response>
- (new POP3Response(conn->getSocket(), conn->getTimeoutHandler()));
-
- string buffer;
- resp->readResponseImpl(buffer, /* multiLine */ false);
-
- resp->m_firstLine = buffer;
- resp->m_code = getResponseCode(buffer);
- stripResponseCode(buffer, resp->m_text);
-
- return resp;
-}
-
-
-// static
-shared_ptr <POP3Response> POP3Response::readMultilineResponse(shared_ptr <POP3Connection> conn)
-{
- shared_ptr <POP3Response> resp = shared_ptr <POP3Response>
- (new POP3Response(conn->getSocket(), conn->getTimeoutHandler()));
-
- 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;
-
- while (std::getline(iss, line, '\n'))
- resp->m_lines.push_back(utility::stringUtils::trim(line));
-
- return resp;
-}
-
-
-// static
-shared_ptr <POP3Response> POP3Response::readLargeResponse
- (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()));
-
- string firstLine;
- resp->readResponseImpl(firstLine, os, progress, predictedSize);
-
- resp->m_firstLine = firstLine;
- resp->m_code = getResponseCode(firstLine);
- stripResponseCode(firstLine, resp->m_text);
-
- 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
- {
- platform::getHandler()->wait();
- 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);
- }
- }
-}
-
-
-void 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())
- {
-#if 0 // not supported
- // Check for possible cancellation
- if (progress && progress->cancel())
- throw exceptions::operation_cancelled();
-#endif
-
- // 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
- {
- platform::getHandler()->wait();
- 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);
-}
-
-
-// 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/src/net/pop3/POP3SStore.cpp b/src/net/pop3/POP3SStore.cpp
deleted file mode 100644
index f1c3da74..00000000
--- a/src/net/pop3/POP3SStore.cpp
+++ /dev/null
@@ -1,79 +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_POP3
-
-
-#include "vmime/net/pop3/POP3SStore.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace pop3 {
-
-
-POP3SStore::POP3SStore(shared_ptr <session> sess, 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/src/net/pop3/POP3ServiceInfos.cpp b/src/net/pop3/POP3ServiceInfos.cpp
deleted file mode 100644
index 4760d4f2..00000000
--- a/src/net/pop3/POP3ServiceInfos.cpp
+++ /dev/null
@@ -1,143 +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_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/src/net/pop3/POP3Store.cpp b/src/net/pop3/POP3Store.cpp
deleted file mode 100644
index e6e95b1b..00000000
--- a/src/net/pop3/POP3Store.cpp
+++ /dev/null
@@ -1,240 +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_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(shared_ptr <session> sess, shared_ptr <security::authenticator> auth, const bool secured)
- : store(sess, getInfosInstance(), auth), m_isPOP3S(secured)
-{
-}
-
-
-POP3Store::~POP3Store()
-{
- try
- {
- if (isConnected())
- disconnect();
- }
- catch (vmime::exception&)
- {
- // Ignore
- }
-}
-
-
-const string POP3Store::getProtocolName() const
-{
- return "pop3";
-}
-
-
-shared_ptr <folder> POP3Store::getDefaultFolder()
-{
- if (!isConnected())
- throw exceptions::illegal_state("Not connected");
-
- return make_shared <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 make_shared <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 make_shared <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());
-
- try
- {
- m_connection->connect();
- }
- catch (std::exception&)
- {
- m_connection = null;
- throw;
- }
-}
-
-
-bool POP3Store::isPOP3S() const
-{
- return m_isPOP3S;
-}
-
-
-bool POP3Store::isConnected() const
-{
- return m_connection && m_connection->isConnected();
-}
-
-
-bool POP3Store::isSecuredConnection() const
-{
- if (m_connection == NULL)
- return false;
-
- return m_connection->isSecuredConnection();
-}
-
-
-shared_ptr <connectionInfos> POP3Store::getConnectionInfos() const
-{
- if (m_connection == NULL)
- 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/src/net/pop3/POP3Utils.cpp b/src/net/pop3/POP3Utils.cpp
deleted file mode 100644
index 7ba65fff..00000000
--- a/src/net/pop3/POP3Utils.cpp
+++ /dev/null
@@ -1,114 +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_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(shared_ptr <POP3Response> response, std::map <int, string>& result)
-{
- std::map <int, 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())
- {
- int 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 <int, string>::value_type(number, string(it, line.end())));
- }
- }
- }
-}
-
-
-
-class POP3MessageSetEnumerator : public messageSetEnumerator
-{
-public:
-
- void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range)
- {
- for (int i = range.getFirst(), last = range.getLast() ; i <= last ; ++i)
- list.push_back(i);
- }
-
- void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& /* range */)
- {
- // Not supported
- }
-
-public:
-
- std::vector <int> list;
-};
-
-
-// static
-const std::vector <int> POP3Utils::messageSetToNumberList(const messageSet& msgs)
-{
- POP3MessageSetEnumerator en;
- msgs.enumerate(en);
-
- return en.list;
-}
-
-
-} // pop3
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3
-
diff --git a/src/net/sendmail/sendmailServiceInfos.cpp b/src/net/sendmail/sendmailServiceInfos.cpp
deleted file mode 100644
index 21cac00c..00000000
--- a/src/net/sendmail/sendmailServiceInfos.cpp
+++ /dev/null
@@ -1,78 +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_SENDMAIL
-
-
-#include "vmime/net/sendmail/sendmailServiceInfos.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace sendmail {
-
-
-sendmailServiceInfos::sendmailServiceInfos()
-{
-}
-
-
-const string sendmailServiceInfos::getPropertyPrefix() const
-{
- return "transport.sendmail.";
-}
-
-
-const sendmailServiceInfos::props& sendmailServiceInfos::getProperties() const
-{
- static props sendmailProps =
- {
- // Path to sendmail (override default)
- property("binpath", serviceInfos::property::TYPE_STRING, string(VMIME_SENDMAIL_PATH))
- };
-
- return sendmailProps;
-}
-
-
-const std::vector <serviceInfos::property> sendmailServiceInfos::getAvailableProperties() const
-{
- std::vector <property> list;
- const props& p = getProperties();
-
- list.push_back(p.PROPERTY_BINPATH);
-
- return list;
-}
-
-
-} // sendmail
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SENDMAIL
-
diff --git a/src/net/sendmail/sendmailTransport.cpp b/src/net/sendmail/sendmailTransport.cpp
deleted file mode 100644
index 8ef18e3b..00000000
--- a/src/net/sendmail/sendmailTransport.cpp
+++ /dev/null
@@ -1,230 +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_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(shared_ptr <session> sess, shared_ptr <security::authenticator> auth)
- : transport(sess, getInfosInstance(), auth), m_connected(false)
-{
-}
-
-
-sendmailTransport::~sendmailTransport()
-{
- try
- {
- if (isConnected())
- disconnect();
- }
- catch (vmime::exception&)
- {
- // Ignore
- }
-}
-
-
-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)
-{
- // 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
-
diff --git a/src/net/service.cpp b/src/net/service.cpp
deleted file mode 100644
index c52ba592..00000000
--- a/src/net/service.cpp
+++ /dev/null
@@ -1,152 +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
-
-
-#include "vmime/net/service.hpp"
-
-#include "vmime/platform.hpp"
-
-#if VMIME_HAVE_SASL_SUPPORT
- #include "vmime/security/sasl/defaultSASLAuthenticator.hpp"
-#else
- #include "vmime/security/defaultAuthenticator.hpp"
-#endif // VMIME_HAVE_SASL_SUPPORT
-
-#if VMIME_HAVE_TLS_SUPPORT
- #include "vmime/security/cert/defaultCertificateVerifier.hpp"
-#endif // VMIME_HAVE_TLS_SUPPORT
-
-
-namespace vmime {
-namespace net {
-
-
-service::service(shared_ptr <session> sess, const serviceInfos& /* infos */,
- shared_ptr <security::authenticator> auth)
- : m_session(sess), m_auth(auth)
-{
- if (!auth)
- {
-#if VMIME_HAVE_SASL_SUPPORT
- m_auth = make_shared
- <security::sasl::defaultSASLAuthenticator>();
-#else
- m_auth = make_shared
- <security::defaultAuthenticator>();
-#endif // VMIME_HAVE_SASL_SUPPORT
- }
-
-#if VMIME_HAVE_TLS_SUPPORT
- m_certVerifier = make_shared <security::cert::defaultCertificateVerifier>();
-#endif // VMIME_HAVE_TLS_SUPPORT
-
- m_socketFactory = platform::getHandler()->getSocketFactory();
-}
-
-
-service::~service()
-{
-}
-
-
-shared_ptr <const session> service::getSession() const
-{
- return (m_session);
-}
-
-
-shared_ptr <session> service::getSession()
-{
- return (m_session);
-}
-
-
-shared_ptr <const security::authenticator> service::getAuthenticator() const
-{
- return (m_auth);
-}
-
-
-shared_ptr <security::authenticator> service::getAuthenticator()
-{
- return (m_auth);
-}
-
-
-void service::setAuthenticator(shared_ptr <security::authenticator> auth)
-{
- m_auth = auth;
-}
-
-
-#if VMIME_HAVE_TLS_SUPPORT
-
-void service::setCertificateVerifier(shared_ptr <security::cert::certificateVerifier> cv)
-{
- m_certVerifier = cv;
-}
-
-
-shared_ptr <security::cert::certificateVerifier> service::getCertificateVerifier()
-{
- return m_certVerifier;
-}
-
-#endif // VMIME_HAVE_TLS_SUPPORT
-
-
-void service::setSocketFactory(shared_ptr <socketFactory> sf)
-{
- m_socketFactory = sf;
-}
-
-
-shared_ptr <socketFactory> service::getSocketFactory()
-{
- return m_socketFactory;
-}
-
-
-void service::setTimeoutHandlerFactory(shared_ptr <timeoutHandlerFactory> thf)
-{
- m_toHandlerFactory = thf;
-}
-
-
-shared_ptr <timeoutHandlerFactory> service::getTimeoutHandlerFactory()
-{
- return m_toHandlerFactory;
-}
-
-
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES
-
diff --git a/src/net/serviceFactory.cpp b/src/net/serviceFactory.cpp
deleted file mode 100644
index 98aee646..00000000
--- a/src/net/serviceFactory.cpp
+++ /dev/null
@@ -1,145 +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
-
-
-#include "vmime/net/serviceFactory.hpp"
-#include "vmime/net/service.hpp"
-
-#include "vmime/exception.hpp"
-
-#include "src/net/builtinServices.inl"
-
-
-namespace vmime {
-namespace net {
-
-
-serviceFactory::serviceFactory()
-{
-}
-
-
-serviceFactory::~serviceFactory()
-{
-}
-
-
-shared_ptr <serviceFactory> serviceFactory::getInstance()
-{
- static serviceFactory instance;
- return shared_ptr <serviceFactory>(&instance, noop_shared_ptr_deleter <serviceFactory>());
-}
-
-
-shared_ptr <service> serviceFactory::create
- (shared_ptr <session> sess, const string& protocol,
- shared_ptr <security::authenticator> auth)
-{
- return (getServiceByProtocol(protocol)->create(sess, auth));
-}
-
-
-shared_ptr <service> serviceFactory::create
- (shared_ptr <session> sess, const utility::url& u,
- shared_ptr <security::authenticator> auth)
-{
- shared_ptr <service> serv = create(sess, u.getProtocol(), auth);
-
- sess->getProperties()[serv->getInfos().getPropertyPrefix() + "server.address"] = u.getHost();
-
- if (u.getPort() != utility::url::UNSPECIFIED_PORT)
- sess->getProperties()[serv->getInfos().getPropertyPrefix() + "server.port"] = u.getPort();
-
- // Path portion of the URL is used to point a specific folder (empty = root).
- // In maildir, this is used to point to the root of the message repository.
- if (!u.getPath().empty())
- sess->getProperties()[serv->getInfos().getPropertyPrefix() + "server.rootpath"] = u.getPath();
-
- if (!u.getUsername().empty())
- {
- sess->getProperties()[serv->getInfos().getPropertyPrefix() + "auth.username"] = u.getUsername();
- sess->getProperties()[serv->getInfos().getPropertyPrefix() + "auth.password"] = u.getPassword();
- }
-
- return (serv);
-}
-
-
-shared_ptr <const serviceFactory::registeredService> serviceFactory::getServiceByProtocol(const string& protocol) const
-{
- const string name(utility::stringUtils::toLower(protocol));
-
- for (std::vector <shared_ptr <registeredService> >::const_iterator it = m_services.begin() ;
- it != m_services.end() ; ++it)
- {
- if ((*it)->getName() == name)
- return (*it);
- }
-
- return null;
-}
-
-
-size_t serviceFactory::getServiceCount() const
-{
- return (m_services.size());
-}
-
-
-shared_ptr <const serviceFactory::registeredService> serviceFactory::getServiceAt(const size_t pos) const
-{
- return (m_services[pos]);
-}
-
-
-const std::vector <shared_ptr <const serviceFactory::registeredService> > serviceFactory::getServiceList() const
-{
- std::vector <shared_ptr <const registeredService> > res;
-
- for (std::vector <shared_ptr <registeredService> >::const_iterator it = m_services.begin() ;
- it != m_services.end() ; ++it)
- {
- res.push_back(*it);
- }
-
- return (res);
-}
-
-
-void serviceFactory::registerService(shared_ptr <registeredService> reg)
-{
- m_services.push_back(reg);
-}
-
-
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES
-
diff --git a/src/net/serviceInfos.cpp b/src/net/serviceInfos.cpp
deleted file mode 100644
index 8de0529e..00000000
--- a/src/net/serviceInfos.cpp
+++ /dev/null
@@ -1,167 +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
-
-
-#include "vmime/net/serviceInfos.hpp"
-
-
-namespace vmime {
-namespace net {
-
-
-// Common properties
-const serviceInfos::property serviceInfos::property::SERVER_ADDRESS
- ("server.address", serviceInfos::property::TYPE_STRING);
-
-const serviceInfos::property serviceInfos::property::SERVER_PORT
- ("server.port", serviceInfos::property::TYPE_INTEGER);
-
-const serviceInfos::property serviceInfos::property::SERVER_ROOTPATH
- ("server.rootpath", serviceInfos::property::TYPE_STRING);
-
-const serviceInfos::property serviceInfos::property::AUTH_USERNAME
- ("auth.username", serviceInfos::property::TYPE_STRING);
-
-const serviceInfos::property serviceInfos::property::AUTH_PASSWORD
- ("auth.password", serviceInfos::property::TYPE_STRING);
-
-#if VMIME_HAVE_TLS_SUPPORT
-
-const serviceInfos::property serviceInfos::property::CONNECTION_TLS
- ("connection.tls", serviceInfos::property::TYPE_BOOLEAN, "false");
-
-const serviceInfos::property serviceInfos::property::CONNECTION_TLS_REQUIRED
- ("connection.tls.required", serviceInfos::property::TYPE_BOOLEAN, "false");
-
-#endif // VMIME_HAVE_TLS_SUPPORT
-
-
-
-// serviceInfos
-
-serviceInfos::serviceInfos()
-{
-}
-
-
-serviceInfos::serviceInfos(const serviceInfos&)
-{
-}
-
-
-serviceInfos& serviceInfos::operator=(const serviceInfos&)
-{
- return (*this);
-}
-
-
-serviceInfos::~serviceInfos()
-{
-}
-
-
-bool serviceInfos::hasProperty(shared_ptr <session> s, const property& p) const
-{
- return s->getProperties().hasProperty(getPropertyPrefix() + p.getName());
-}
-
-
-
-// serviceInfos::property
-
-serviceInfos::property::property
- (const string& name, const Types type,
- const string& defaultValue, const int flags)
- : m_name(name), m_defaultValue(defaultValue),
- m_type(type), m_flags(flags)
-{
-}
-
-
-serviceInfos::property::property
- (const property& p, const int addFlags, const int removeFlags)
-{
- m_name = p.m_name;
- m_type = p.m_type;
- m_defaultValue = p.m_defaultValue;
- m_flags = (p.m_flags | addFlags) & ~removeFlags;
-}
-
-
-serviceInfos::property::property
- (const property& p, const string& newDefaultValue,
- const int addFlags, const int removeFlags)
-{
- m_name = p.m_name;
- m_type = p.m_type;
- m_defaultValue = newDefaultValue;
- m_flags = (p.m_flags | addFlags) & ~removeFlags;
-}
-
-
-serviceInfos::property& serviceInfos::property::operator=(const property& p)
-{
- m_name = p.m_name;
- m_type = p.m_type;
- m_defaultValue = p.m_defaultValue;
- m_flags = p.m_flags;
-
- return (*this);
-}
-
-
-const string& serviceInfos::property::getName() const
-{
- return (m_name);
-}
-
-
-const string& serviceInfos::property::getDefaultValue() const
-{
- return (m_defaultValue);
-}
-
-
-serviceInfos::property::Types serviceInfos::property::getType() const
-{
- return (m_type);
-}
-
-
-int serviceInfos::property::getFlags() const
-{
- return (m_flags);
-}
-
-
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES
-
diff --git a/src/net/serviceRegistration.inl b/src/net/serviceRegistration.inl
deleted file mode 100644
index 2366fe01..00000000
--- a/src/net/serviceRegistration.inl
+++ /dev/null
@@ -1,98 +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/net/serviceFactory.hpp"
-
-
-#ifndef VMIME_BUILDING_DOC
-
-
-namespace vmime {
-namespace net {
-
-
-template <class S>
-class registeredServiceImpl : public serviceFactory::registeredService
-{
-public:
-
- registeredServiceImpl(const string& name, const int type)
- : m_type(type), m_name(name), m_servInfos(S::getInfosInstance())
- {
- }
-
- shared_ptr <service> create
- (shared_ptr <session> sess,
- shared_ptr <security::authenticator> auth) const
- {
- return make_shared <S>(sess, auth);
- }
-
- const serviceInfos& getInfos() const
- {
- return (m_servInfos);
- }
-
- const string& getName() const
- {
- return (m_name);
- }
-
- int getType() const
- {
- return (m_type);
- }
-
-private:
-
- const int m_type;
- const string m_name;
- const serviceInfos& m_servInfos;
-};
-
-
-// Basic service registerer
-template <class S>
-class serviceRegisterer
-{
-public:
-
- serviceRegisterer(const string& protocol, const service::Type type)
- {
- serviceFactory::getInstance()->registerService
- (make_shared <registeredServiceImpl <S> >(protocol, type));
- }
-};
-
-
-} // net
-} // vmime
-
-
-#define REGISTER_SERVICE(p_class, p_name, p_type) \
- vmime::net::serviceRegisterer <vmime::net::p_class> \
- p_name(#p_name, vmime::net::service::p_type)
-
-
-#endif // VMIME_BUILDING_DOC
-
diff --git a/src/net/session.cpp b/src/net/session.cpp
deleted file mode 100644
index 36b9f2c3..00000000
--- a/src/net/session.cpp
+++ /dev/null
@@ -1,158 +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
-
-
-#include "vmime/net/session.hpp"
-#include "vmime/net/serviceFactory.hpp"
-
-#include "vmime/net/store.hpp"
-#include "vmime/net/transport.hpp"
-
-
-namespace vmime {
-namespace net {
-
-
-session::session()
- : m_tlsProps(make_shared <tls::TLSProperties>())
-{
-}
-
-
-session::session(const session& sess)
- : object(), m_props(sess.m_props),
- m_tlsProps(make_shared <tls::TLSProperties>(*sess.m_tlsProps))
-{
-}
-
-
-session::session(const propertySet& props)
- : m_props(props), m_tlsProps(make_shared <tls::TLSProperties>())
-{
-}
-
-
-session::~session()
-{
-}
-
-
-shared_ptr <transport> session::getTransport(shared_ptr <security::authenticator> auth)
-{
- return (getTransport(m_props["transport.protocol"], auth));
-}
-
-
-shared_ptr <transport> session::getTransport
- (const string& protocol, shared_ptr <security::authenticator> auth)
-{
- shared_ptr <session> sess(dynamicCast <session>(shared_from_this()));
- shared_ptr <service> sv = serviceFactory::getInstance()->create(sess, protocol, auth);
-
- if (!sv || sv->getType() != service::TYPE_TRANSPORT)
- return null;
-
- return dynamicCast <transport>(sv);
-}
-
-
-shared_ptr <transport> session::getTransport
- (const utility::url& url, shared_ptr <security::authenticator> auth)
-{
- shared_ptr <session> sess(dynamicCast <session>(shared_from_this()));
- shared_ptr <service> sv = serviceFactory::getInstance()->create(sess, url, auth);
-
- if (!sv || sv->getType() != service::TYPE_TRANSPORT)
- return null;
-
- return dynamicCast <transport>(sv);
-}
-
-
-shared_ptr <store> session::getStore(shared_ptr <security::authenticator> auth)
-{
- return (getStore(m_props["store.protocol"], auth));
-}
-
-
-shared_ptr <store> session::getStore
- (const string& protocol, shared_ptr <security::authenticator> auth)
-{
- shared_ptr <session> sess(dynamicCast <session>(shared_from_this()));
- shared_ptr <service> sv = serviceFactory::getInstance()->create(sess, protocol, auth);
-
- if (!sv || sv->getType() != service::TYPE_STORE)
- return null;
-
- return dynamicCast <store>(sv);
-}
-
-
-shared_ptr <store> session::getStore
- (const utility::url& url, shared_ptr <security::authenticator> auth)
-{
- shared_ptr <session> sess(dynamicCast <session>(shared_from_this()));
- shared_ptr <service> sv = serviceFactory::getInstance()->create(sess, url, auth);
-
- if (!sv || sv->getType() != service::TYPE_STORE)
- return null;
-
- return dynamicCast <store>(sv);
-}
-
-
-const propertySet& session::getProperties() const
-{
- return (m_props);
-}
-
-
-propertySet& session::getProperties()
-{
- return (m_props);
-}
-
-
-void session::setTLSProperties(shared_ptr <tls::TLSProperties> tlsProps)
-{
- m_tlsProps = make_shared <tls::TLSProperties>(*tlsProps);
-}
-
-
-shared_ptr <tls::TLSProperties> session::getTLSProperties() const
-{
- return m_tlsProps;
-}
-
-
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES
-
diff --git a/src/net/smtp/SMTPChunkingOutputStreamAdapter.cpp b/src/net/smtp/SMTPChunkingOutputStreamAdapter.cpp
deleted file mode 100644
index 69f63bc9..00000000
--- a/src/net/smtp/SMTPChunkingOutputStreamAdapter.cpp
+++ /dev/null
@@ -1,145 +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/SMTPChunkingOutputStreamAdapter.hpp"
-
-#include "vmime/net/smtp/SMTPConnection.hpp"
-#include "vmime/net/smtp/SMTPTransport.hpp"
-
-#include <algorithm>
-
-
-namespace vmime {
-namespace net {
-namespace smtp {
-
-
-SMTPChunkingOutputStreamAdapter::SMTPChunkingOutputStreamAdapter(shared_ptr <SMTPConnection> conn)
- : m_connection(conn), m_bufferSize(0), m_chunkCount(0)
-{
-}
-
-
-void SMTPChunkingOutputStreamAdapter::sendChunk
- (const byte_t* const data, const size_t count, const bool last)
-{
- if (count == 0 && !last)
- {
- // Nothing to send
- return;
- }
-
- // Send this chunk
- m_connection->sendRequest(SMTPCommand::BDAT(count, last));
- m_connection->getSocket()->sendRaw(data, count);
-
- ++m_chunkCount;
-
- // If PIPELINING is not supported, read one response for this BDAT command
- if (!m_connection->hasExtension("PIPELINING"))
- {
- shared_ptr <SMTPResponse> resp = m_connection->readResponse();
-
- if (resp->getCode() != 250)
- {
- m_connection->getTransport()->disconnect();
- throw exceptions::command_error("BDAT", resp->getText());
- }
- }
- // If PIPELINING is supported, read one response for each chunk (ie. number
- // of BDAT commands issued) after the last chunk has been sent
- else if (last)
- {
- bool invalidReply = false;
- shared_ptr <SMTPResponse> resp;
-
- for (unsigned int i = 0 ; i < m_chunkCount ; ++i)
- {
- resp = m_connection->readResponse();
-
- if (resp->getCode() != 250)
- invalidReply = true;
- }
-
- if (invalidReply)
- {
- m_connection->getTransport()->disconnect();
- throw exceptions::command_error("BDAT", resp->getText());
- }
- }
-}
-
-
-void SMTPChunkingOutputStreamAdapter::writeImpl
- (const byte_t* const data, const size_t count)
-{
- const byte_t* curData = data;
- size_t curCount = count;
-
- while (curCount != 0)
- {
- // Fill the buffer
- const size_t remaining = sizeof(m_buffer) - m_bufferSize;
- const size_t bytesToCopy = std::min(remaining, curCount);
-
- std::copy(data, data + bytesToCopy, m_buffer + m_bufferSize);
-
- m_bufferSize += bytesToCopy;
- curData += bytesToCopy;
- curCount -= bytesToCopy;
-
- // If the buffer is full, send this chunk
- if (m_bufferSize >= sizeof(m_buffer))
- {
- sendChunk(m_buffer, m_bufferSize, /* last */ false);
- m_bufferSize = 0;
- }
- }
-}
-
-
-void SMTPChunkingOutputStreamAdapter::flush()
-{
- sendChunk(m_buffer, m_bufferSize, /* last */ true);
- m_bufferSize = 0;
-}
-
-
-size_t SMTPChunkingOutputStreamAdapter::getBlockSize()
-{
- return sizeof(m_buffer);
-}
-
-
-} // smtp
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP
diff --git a/src/net/smtp/SMTPCommand.cpp b/src/net/smtp/SMTPCommand.cpp
deleted file mode 100644
index 949ab0c1..00000000
--- a/src/net/smtp/SMTPCommand.cpp
+++ /dev/null
@@ -1,214 +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/SMTPCommand.hpp"
-
-#include "vmime/net/socket.hpp"
-
-#include "vmime/mailbox.hpp"
-#include "vmime/utility/outputStreamAdapter.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace smtp {
-
-
-SMTPCommand::SMTPCommand(const string& text)
- : m_text(text)
-{
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::EHLO(const string& hostname)
-{
- std::ostringstream cmd;
- cmd.imbue(std::locale::classic());
- cmd << "EHLO " << hostname;
-
- return createCommand(cmd.str());
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::HELO(const string& hostname)
-{
- std::ostringstream cmd;
- cmd.imbue(std::locale::classic());
- cmd << "HELO " << hostname;
-
- return createCommand(cmd.str());
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::AUTH(const string& mechName)
-{
- std::ostringstream cmd;
- cmd.imbue(std::locale::classic());
- cmd << "AUTH " << mechName;
-
- return createCommand(cmd.str());
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::STARTTLS()
-{
- return createCommand("STARTTLS");
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::MAIL(const mailbox& mbox, const bool utf8)
-{
- return MAIL(mbox, utf8, 0);
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::MAIL(const mailbox& mbox, const bool utf8, const size_t size)
-{
- std::ostringstream cmd;
- cmd.imbue(std::locale::classic());
- cmd << "MAIL FROM:<";
-
- if (utf8)
- {
- cmd << mbox.getEmail().toText().getConvertedText(vmime::charsets::UTF_8);
- }
- else
- {
- vmime::utility::outputStreamAdapter cmd2(cmd);
- mbox.getEmail().generate(cmd2);
- }
-
- cmd << ">";
-
- if (utf8)
- cmd << " SMTPUTF8";
-
- if (size != 0)
- cmd << " SIZE=" << size;
-
- return createCommand(cmd.str());
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::RCPT(const mailbox& mbox, const bool utf8)
-{
- std::ostringstream cmd;
- cmd.imbue(std::locale::classic());
- cmd << "RCPT TO:<";
-
- if (utf8)
- {
- cmd << mbox.getEmail().toText().getConvertedText(vmime::charsets::UTF_8);
- }
- else
- {
- vmime::utility::outputStreamAdapter cmd2(cmd);
- mbox.getEmail().generate(cmd2);
- }
-
- cmd << ">";
-
- return createCommand(cmd.str());
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::RSET()
-{
- return createCommand("RSET");
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::DATA()
-{
- return createCommand("DATA");
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::BDAT(const size_t chunkSize, const bool last)
-{
- std::ostringstream cmd;
- cmd.imbue(std::locale::classic());
- cmd << "BDAT " << chunkSize;
-
- if (last)
- cmd << " LAST";
-
- return createCommand(cmd.str());
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::NOOP()
-{
- return createCommand("NOOP");
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::QUIT()
-{
- return createCommand("QUIT");
-}
-
-
-// static
-shared_ptr <SMTPCommand> SMTPCommand::createCommand(const string& text)
-{
- return shared_ptr <SMTPCommand>(new SMTPCommand(text));
-}
-
-
-const string SMTPCommand::getText() const
-{
- return m_text;
-}
-
-
-void SMTPCommand::writeToSocket(shared_ptr <socket> sok)
-{
- sok->send(m_text + "\r\n");
-}
-
-
-} // smtp
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP
diff --git a/src/net/smtp/SMTPCommandSet.cpp b/src/net/smtp/SMTPCommandSet.cpp
deleted file mode 100644
index 3e03427c..00000000
--- a/src/net/smtp/SMTPCommandSet.cpp
+++ /dev/null
@@ -1,144 +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/SMTPCommandSet.hpp"
-
-#include "vmime/net/socket.hpp"
-
-#include "vmime/mailbox.hpp"
-
-#include <stdexcept>
-
-
-namespace vmime {
-namespace net {
-namespace smtp {
-
-
-SMTPCommandSet::SMTPCommandSet(const bool pipeline)
- : SMTPCommand(""), m_pipeline(pipeline),
- m_started(false), m_lastCommandSent()
-{
-}
-
-
-// static
-shared_ptr <SMTPCommandSet> SMTPCommandSet::create(const bool pipeline)
-{
- return shared_ptr <SMTPCommandSet>(new SMTPCommandSet(pipeline));
-}
-
-
-void SMTPCommandSet::addCommand(shared_ptr <SMTPCommand> cmd)
-{
- if (m_started)
- {
- throw std::runtime_error("Could not add command to pipeline: "
- "one or more commands have already been sent to the server.");
- }
-
- m_commands.push_back(cmd);
-}
-
-
-void SMTPCommandSet::writeToSocket(shared_ptr <socket> sok)
-{
- if (m_pipeline)
- {
- if (!m_started)
- {
- // Send all commands at once
- for (std::list <shared_ptr <SMTPCommand> >::const_iterator it = m_commands.begin() ;
- it != m_commands.end() ; ++it)
- {
- shared_ptr <SMTPCommand> cmd = *it;
- cmd->writeToSocket(sok);
- }
- }
-
- if (!m_commands.empty())
- {
- // Advance the pointer to last command sent
- shared_ptr <SMTPCommand> cmd = m_commands.front();
- m_commands.pop_front();
-
- m_lastCommandSent = cmd;
- }
- }
- else
- {
- if (!m_commands.empty())
- {
- // Send only one command
- shared_ptr <SMTPCommand> cmd = m_commands.front();
- m_commands.pop_front();
-
- cmd->writeToSocket(sok);
-
- m_lastCommandSent = cmd;
- }
- }
-
- m_started = true;
-}
-
-
-const string SMTPCommandSet::getText() const
-{
- std::ostringstream cmd;
- cmd.imbue(std::locale::classic());
-
- for (std::list <shared_ptr <SMTPCommand> >::const_iterator it = m_commands.begin() ;
- it != m_commands.end() ; ++it)
- {
- cmd << (*it)->getText() << "\r\n";
- }
-
- return cmd.str();
-}
-
-
-bool SMTPCommandSet::isFinished() const
-{
- return (m_pipeline && m_started) || (m_commands.size() == 0 && m_started);
-}
-
-
-shared_ptr <SMTPCommand> SMTPCommandSet::getLastCommandSent() const
-{
- return m_lastCommandSent;
-}
-
-
-} // smtp
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP
diff --git a/src/net/smtp/SMTPConnection.cpp b/src/net/smtp/SMTPConnection.cpp
deleted file mode 100644
index 26be25db..00000000
--- a/src/net/smtp/SMTPConnection.cpp
+++ /dev/null
@@ -1,618 +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/SMTPConnection.hpp"
-#include "vmime/net/smtp/SMTPTransport.hpp"
-#include "vmime/net/smtp/SMTPExceptions.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_transport.lock()->getInfos().getPropertyValue <type>(getSession(), \
- dynamic_cast <const SMTPServiceInfos&>(m_transport.lock()->getInfos()).getProperties().prop))
-#define HAS_PROPERTY(prop) \
- (m_transport.lock()->getInfos().hasProperty(getSession(), \
- dynamic_cast <const SMTPServiceInfos&>(m_transport.lock()->getInfos()).getProperties().prop))
-
-
-namespace vmime {
-namespace net {
-namespace smtp {
-
-
-
-SMTPConnection::SMTPConnection(shared_ptr <SMTPTransport> transport, shared_ptr <security::authenticator> auth)
- : m_transport(transport), m_auth(auth), m_socket(null), m_timeoutHandler(null),
- m_authenticated(false), m_secured(false), m_extendedSMTP(false)
-{
-}
-
-
-SMTPConnection::~SMTPConnection()
-{
- try
- {
- if (isConnected())
- disconnect();
- else if (m_socket)
- internalDisconnect();
- }
- catch (vmime::exception&)
- {
- // Ignore
- }
-}
-
-
-void SMTPConnection::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 <SMTPTransport> transport = m_transport.lock();
-
- // Create the time-out handler
- if (transport->getTimeoutHandlerFactory())
- m_timeoutHandler = transport->getTimeoutHandlerFactory()->create();
-
- // Create and connect the socket
- m_socket = transport->getSocketFactory()->create(m_timeoutHandler);
-
-#if VMIME_HAVE_TLS_SUPPORT
- if (transport->isSMTPS()) // dedicated port/SMTPS
- {
- shared_ptr <tls::TLSSession> tlsSession = tls::TLSSession::create
- (transport->getCertificateVerifier(),
- transport->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: 220 smtp.domain.com Service ready
-
- shared_ptr <SMTPResponse> resp;
-
- if ((resp = readResponse())->getCode() != 220)
- {
- internalDisconnect();
- throw exceptions::connection_greeting_error(resp->getText());
- }
-
- // Identification
- helo();
-
-#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 (!transport->isSMTPS() && tls) // only if not SMTPS
- {
- 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;
- }
-
- // Must reissue a EHLO command [RFC-2487, 5.2]
- helo();
- }
-#endif // VMIME_HAVE_TLS_SUPPORT
-
- // Authentication
- if (GET_PROPERTY(bool, PROPERTY_OPTIONS_NEEDAUTH))
- authenticate();
- else
- m_authenticated = true;
-}
-
-
-void SMTPConnection::helo()
-{
- // First, try Extended SMTP (ESMTP)
- //
- // eg: C: EHLO thismachine.ourdomain.com
- // S: 250-smtp.theserver.com
- // S: 250-AUTH CRAM-MD5 DIGEST-MD5
- // S: 250-PIPELINING
- // S: 250 SIZE 2555555555
-
- sendRequest(SMTPCommand::EHLO(platform::getHandler()->getHostName()));
-
- shared_ptr <SMTPResponse> resp;
-
- if ((resp = readResponse())->getCode() != 250)
- {
- // Next, try "Basic" SMTP
- //
- // eg: C: HELO thismachine.ourdomain.com
- // S: 250 OK
-
- sendRequest(SMTPCommand::HELO(platform::getHandler()->getHostName()));
-
- if ((resp = readResponse())->getCode() != 250)
- {
- internalDisconnect();
- throw exceptions::connection_greeting_error(resp->getLastLine().getText());
- }
-
- m_extendedSMTP = false;
- m_extensions.clear();
- }
- else
- {
- m_extendedSMTP = true;
- m_extensions.clear();
-
- // Get supported extensions from SMTP response
- // One extension per line, format is: EXT PARAM1 PARAM2...
- for (size_t i = 1, n = resp->getLineCount() ; i < n ; ++i)
- {
- const string line = resp->getLineAt(i).getText();
- std::istringstream iss(line);
-
- string ext;
- iss >> ext;
-
- std::vector <string> params;
- string param;
-
- // Special case: some servers send "AUTH=MECH [MECH MECH...]"
- if (ext.length() >= 5 && utility::stringUtils::toUpper(ext.substr(0, 5)) == "AUTH=")
- {
- params.push_back(utility::stringUtils::toUpper(ext.substr(5)));
- ext = "AUTH";
- }
-
- while (iss >> param)
- params.push_back(utility::stringUtils::toUpper(param));
-
- m_extensions[ext] = params;
- }
- }
-}
-
-
-bool SMTPConnection::hasExtension
- (const std::string& extName, std::vector <string>* params) const
-{
- std::map <string, std::vector <string> >::const_iterator
- it = m_extensions.find(extName);
-
- if (it != m_extensions.end())
- {
- if (params)
- *params = (*it).second;
-
- return true;
- }
- else
- {
- return false;
- }
-}
-
-
-void SMTPConnection::authenticate()
-{
- if (!m_extendedSMTP)
- {
- internalDisconnect();
- throw exceptions::command_error("AUTH", "ESMTP not supported.");
- }
-
- getAuthenticator()->setService(m_transport.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& e)
- {
- if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL_FALLBACK))
- {
- // Can't fallback on normal authentication
- internalDisconnect();
- throw e;
- }
- else
- {
- // Ignore, will try normal authentication
- }
- }
- catch (exception& e)
- {
- internalDisconnect();
- throw e;
- }
- }
-#endif // VMIME_HAVE_SASL_SUPPORT
-
- // No other authentication method is possible
- throw exceptions::authentication_error("All authentication methods failed");
-}
-
-
-
-#if VMIME_HAVE_SASL_SUPPORT
-
-void SMTPConnection::authenticateSASL()
-{
- if (!dynamicCast <security::sasl::SASLAuthenticator>(getAuthenticator()))
- throw exceptions::authentication_error("No SASL authenticator available.");
-
- // Obtain SASL mechanisms supported by server from ESMTP extensions
- std::vector <string> saslMechs;
- hasExtension("AUTH", &saslMechs);
-
- 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 =
- make_shared <security::sasl::SASLContext>();
-
- 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("smtp", getAuthenticator(), mech);
-
- saslSession->init();
-
- sendRequest(SMTPCommand::AUTH(mech->getName()));
-
- for (bool cont = true ; cont ; )
- {
- shared_ptr <SMTPResponse> response = readResponse();
-
- switch (response->getCode())
- {
- case 235:
- {
- m_socket = saslSession->getSecuredSocket(m_socket);
- return;
- }
- case 334:
- {
- 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
- m_socket->send(saslContext->encodeB64(resp, respLen) + "\r\n");
- }
- 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");
- }
- 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 SMTPConnection::startTLS()
-{
- try
- {
- sendRequest(SMTPCommand::STARTTLS());
-
- shared_ptr <SMTPResponse> resp = readResponse();
-
- if (resp->getCode() != 220)
- {
- throw SMTPCommandError("STARTTLS", resp->getText(),
- resp->getCode(), resp->getEnhancedCode());
- }
-
- shared_ptr <tls::TLSSession> tlsSession = tls::TLSSession::create
- (getTransport()->getCertificateVerifier(),
- getTransport()->getSession()->getTLSProperties());
-
- shared_ptr <tls::TLSSocket> tlsSocket =
- tlsSession->getSocket(m_socket);
-
- tlsSocket->handshake(m_timeoutHandler);
-
- m_socket = tlsSocket;
-
- m_secured = true;
- m_cntInfos = make_shared <tls::TLSSecuredConnectionInfos>
- (m_cntInfos->getHost(), m_cntInfos->getPort(), tlsSession, tlsSocket);
- }
- catch (exceptions::command_error&)
- {
- // Non-fatal error
- throw;
- }
- catch (exception&)
- {
- // Fatal error
- internalDisconnect();
- throw;
- }
-}
-
-#endif // VMIME_HAVE_TLS_SUPPORT
-
-
-void SMTPConnection::disconnect()
-{
- if (!isConnected())
- throw exceptions::not_connected();
-
- internalDisconnect();
-}
-
-
-void SMTPConnection::internalDisconnect()
-{
- try
- {
- sendRequest(SMTPCommand::QUIT());
- readResponse();
- }
- catch (exception&)
- {
- // Not important
- }
-
- m_socket->disconnect();
- m_socket = null;
-
- m_timeoutHandler = null;
-
- m_authenticated = false;
- m_extendedSMTP = false;
-
- m_secured = false;
- m_cntInfos = null;
-}
-
-
-void SMTPConnection::sendRequest(shared_ptr <SMTPCommand> cmd)
-{
- cmd->writeToSocket(m_socket);
-}
-
-
-shared_ptr <SMTPResponse> SMTPConnection::readResponse()
-{
- shared_ptr <SMTPResponse> resp = SMTPResponse::readResponse
- (m_socket, m_timeoutHandler, m_responseState);
-
- m_responseState = resp->getCurrentState();
-
- return resp;
-}
-
-
-bool SMTPConnection::isConnected() const
-{
- return m_socket && m_socket->isConnected() && m_authenticated;
-}
-
-
-bool SMTPConnection::isSecuredConnection() const
-{
- return m_secured;
-}
-
-
-shared_ptr <connectionInfos> SMTPConnection::getConnectionInfos() const
-{
- return m_cntInfos;
-}
-
-
-shared_ptr <SMTPTransport> SMTPConnection::getTransport()
-{
- return m_transport.lock();
-}
-
-
-shared_ptr <session> SMTPConnection::getSession()
-{
- return m_transport.lock()->getSession();
-}
-
-
-shared_ptr <socket> SMTPConnection::getSocket()
-{
- return m_socket;
-}
-
-
-shared_ptr <timeoutHandler> SMTPConnection::getTimeoutHandler()
-{
- return m_timeoutHandler;
-}
-
-
-shared_ptr <security::authenticator> SMTPConnection::getAuthenticator()
-{
- return m_auth;
-}
-
-
-} // smtp
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP
diff --git a/src/net/smtp/SMTPExceptions.cpp b/src/net/smtp/SMTPExceptions.cpp
deleted file mode 100644
index 0c3112c0..00000000
--- a/src/net/smtp/SMTPExceptions.cpp
+++ /dev/null
@@ -1,151 +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/SMTPExceptions.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace smtp {
-
-
-//
-// SMTPCommandError
-//
-
-SMTPCommandError::SMTPCommandError
- (const string& command, const string& response,
- const string& desc, const int statusCode,
- const SMTPResponse::enhancedStatusCode& extendedStatusCode,
- const exception& other)
- : command_error(command, response, desc, other),
- m_status(statusCode), m_exStatus(extendedStatusCode)
-{
-}
-
-
-SMTPCommandError::SMTPCommandError
- (const string& command, const string& response,
- const int statusCode, const SMTPResponse::enhancedStatusCode& extendedStatusCode,
- const exception& other)
- : command_error(command, response, "", other),
- m_status(statusCode), m_exStatus(extendedStatusCode)
-{
-}
-
-
-SMTPCommandError::~SMTPCommandError() throw()
-{
-}
-
-
-int SMTPCommandError::statusCode() const
-{
- return m_status;
-}
-
-
-const SMTPResponse::enhancedStatusCode SMTPCommandError::extendedStatusCode() const
-{
- return m_exStatus;
-}
-
-
-exception* SMTPCommandError::clone() const
-{
- return new SMTPCommandError(*this);
-}
-
-
-const char* SMTPCommandError::name() const throw()
-{
- return "SMTPCommandError";
-}
-
-
-//
-// SMTPMessageSizeExceedsMaxLimitsException
-//
-
-SMTPMessageSizeExceedsMaxLimitsException::SMTPMessageSizeExceedsMaxLimitsException(const exception& other)
- : net_exception("Message size exceeds maximum server limits (permanent error).", other)
-{
-}
-
-
-SMTPMessageSizeExceedsMaxLimitsException::~SMTPMessageSizeExceedsMaxLimitsException() throw()
-{
-}
-
-
-exception* SMTPMessageSizeExceedsMaxLimitsException::clone() const
-{
- return new SMTPMessageSizeExceedsMaxLimitsException(*this);
-}
-
-
-const char* SMTPMessageSizeExceedsMaxLimitsException::name() const throw()
-{
- return "SMTPMessageSizeExceedsMaxLimitsException";
-}
-
-
-//
-// SMTPMessageSizeExceedsCurLimitsException
-//
-
-SMTPMessageSizeExceedsCurLimitsException::SMTPMessageSizeExceedsCurLimitsException(const exception& other)
- : net_exception("Message size exceeds current server limits (temporary storage error).", other)
-{
-}
-
-
-SMTPMessageSizeExceedsCurLimitsException::~SMTPMessageSizeExceedsCurLimitsException() throw()
-{
-}
-
-
-exception* SMTPMessageSizeExceedsCurLimitsException::clone() const
-{
- return new SMTPMessageSizeExceedsCurLimitsException(*this);
-}
-
-
-const char* SMTPMessageSizeExceedsCurLimitsException::name() const throw()
-{
- return "SMTPMessageSizeExceedsCurLimitsException";
-}
-
-
-} // smtp
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP
diff --git a/src/net/smtp/SMTPResponse.cpp b/src/net/smtp/SMTPResponse.cpp
deleted file mode 100644
index f7980351..00000000
--- a/src/net/smtp/SMTPResponse.cpp
+++ /dev/null
@@ -1,334 +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/SMTPResponse.hpp"
-
-#include "vmime/platform.hpp"
-#include "vmime/utility/stringUtils.hpp"
-
-#include "vmime/net/socket.hpp"
-#include "vmime/net/timeoutHandler.hpp"
-
-#include <cctype>
-
-
-namespace vmime {
-namespace net {
-namespace smtp {
-
-
-SMTPResponse::SMTPResponse(shared_ptr <socket> sok, shared_ptr <timeoutHandler> toh, const state& st)
- : m_socket(sok), m_timeoutHandler(toh),
- m_responseBuffer(st.responseBuffer), m_responseContinues(false)
-{
-}
-
-
-SMTPResponse::SMTPResponse(const SMTPResponse&)
- : vmime::object()
-{
- // Not used
-}
-
-
-int SMTPResponse::getCode() const
-{
- const int firstCode = m_lines[0].getCode();
-
- for (unsigned int i = 1 ; i < m_lines.size() ; ++i)
- {
- // All response codes returned must be equal
- // or else this in an error...
- if (m_lines[i].getCode() != firstCode)
- return 0;
- }
-
- return firstCode;
-}
-
-
-const SMTPResponse::enhancedStatusCode SMTPResponse::getEnhancedCode() const
-{
- return m_lines[m_lines.size() - 1].getEnhancedCode();
-}
-
-
-const string SMTPResponse::getText() const
-{
- string text = m_lines[0].getText();
-
- for (unsigned int i = 1 ; i < m_lines.size() ; ++i)
- {
- text += '\n';
- text += m_lines[i].getText();
- }
-
- return text;
-}
-
-
-// static
-shared_ptr <SMTPResponse> SMTPResponse::readResponse
- (shared_ptr <socket> sok, shared_ptr <timeoutHandler> toh, const state& st)
-{
- shared_ptr <SMTPResponse> resp = shared_ptr <SMTPResponse>(new SMTPResponse(sok, toh, st));
-
- resp->readResponse();
-
- return resp;
-}
-
-
-void SMTPResponse::readResponse()
-{
- responseLine line = getNextResponse();
- m_lines.push_back(line);
-
- while (m_responseContinues)
- {
- line = getNextResponse();
- m_lines.push_back(line);
- }
-}
-
-
-const string SMTPResponse::readResponseLine()
-{
- string currentBuffer = m_responseBuffer;
-
- if (m_timeoutHandler)
- m_timeoutHandler->resetTimeOut();
-
- while (true)
- {
- // Get a line from the response buffer
- const size_t lineEnd = currentBuffer.find_first_of('\n');
-
- if (lineEnd != string::npos)
- {
- size_t actualLineEnd = lineEnd;
-
- if (actualLineEnd != 0 && currentBuffer[actualLineEnd - 1] == '\r') // CRLF case
- actualLineEnd--;
-
- const string line(currentBuffer.begin(), currentBuffer.begin() + actualLineEnd);
-
- currentBuffer.erase(currentBuffer.begin(), currentBuffer.begin() + lineEnd + 1);
- m_responseBuffer = currentBuffer;
-
- return line;
- }
-
- // 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
- {
- platform::getHandler()->wait();
- continue;
- }
-
- currentBuffer += receiveBuffer;
- }
-}
-
-
-const SMTPResponse::responseLine SMTPResponse::getNextResponse()
-{
- string line = readResponseLine();
-
- const int code = extractResponseCode(line);
- string text;
-
- m_responseContinues = (line.length() >= 4 && line[3] == '-');
-
- if (line.length() > 4)
- text = utility::stringUtils::trim(line.substr(4));
- else
- text = "";
-
- return responseLine(code, text, extractEnhancedCode(text));
-}
-
-
-// static
-int SMTPResponse::extractResponseCode(const string& response)
-{
- int code = 0;
-
- if (response.length() >= 3)
- {
- code = (response[0] - '0') * 100
- + (response[1] - '0') * 10
- + (response[2] - '0');
- }
-
- return code;
-}
-
-
-// static
-const SMTPResponse::enhancedStatusCode SMTPResponse::extractEnhancedCode(const string& responseText)
-{
- enhancedStatusCode enhCode;
-
- std::istringstream iss(responseText);
-
- if (std::isdigit(iss.peek()))
- {
- iss >> enhCode.klass;
-
- if (iss.get() == '.' && std::isdigit(iss.peek()))
- {
- iss >> enhCode.subject;
-
- if (iss.get() == '.' && std::isdigit(iss.peek()))
- {
- iss >> enhCode.detail;
- return enhCode;
- }
- }
- }
-
- return enhancedStatusCode(); // no enhanced code found
-}
-
-
-const SMTPResponse::responseLine SMTPResponse::getLineAt(const size_t pos) const
-{
- return m_lines[pos];
-}
-
-
-size_t SMTPResponse::getLineCount() const
-{
- return m_lines.size();
-}
-
-
-const SMTPResponse::responseLine SMTPResponse::getLastLine() const
-{
- return m_lines[m_lines.size() - 1];
-}
-
-
-const SMTPResponse::state SMTPResponse::getCurrentState() const
-{
- state st;
- st.responseBuffer = m_responseBuffer;
-
- return st;
-}
-
-
-
-// SMTPResponse::responseLine
-
-SMTPResponse::responseLine::responseLine(const int code, const string& text, const enhancedStatusCode& enhCode)
- : m_code(code), m_text(text), m_enhCode(enhCode)
-{
-}
-
-
-void SMTPResponse::responseLine::setCode(const int code)
-{
- m_code = code;
-}
-
-
-int SMTPResponse::responseLine::getCode() const
-{
- return m_code;
-}
-
-
-void SMTPResponse::responseLine::setEnhancedCode(const enhancedStatusCode& enhCode)
-{
- m_enhCode = enhCode;
-}
-
-
-const SMTPResponse::enhancedStatusCode SMTPResponse::responseLine::getEnhancedCode() const
-{
- return m_enhCode;
-}
-
-
-void SMTPResponse::responseLine::setText(const string& text)
-{
- m_text = text;
-}
-
-
-const string SMTPResponse::responseLine::getText() const
-{
- return m_text;
-}
-
-
-
-// SMTPResponse::enhancedStatusCode
-
-
-SMTPResponse::enhancedStatusCode::enhancedStatusCode()
- : klass(0), subject(0), detail(0)
-{
-}
-
-
-SMTPResponse::enhancedStatusCode::enhancedStatusCode(const enhancedStatusCode& enhCode)
- : klass(enhCode.klass), subject(enhCode.subject), detail(enhCode.detail)
-{
-}
-
-
-std::ostream& operator<<(std::ostream& os, const SMTPResponse::enhancedStatusCode& code)
-{
- os << code.klass << '.' << code.subject << '.' << code.detail;
- return os;
-}
-
-
-} // smtp
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP
-
diff --git a/src/net/smtp/SMTPSTransport.cpp b/src/net/smtp/SMTPSTransport.cpp
deleted file mode 100644
index ab64d49d..00000000
--- a/src/net/smtp/SMTPSTransport.cpp
+++ /dev/null
@@ -1,79 +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/SMTPSTransport.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace smtp {
-
-
-SMTPSTransport::SMTPSTransport(shared_ptr <session> sess, shared_ptr <security::authenticator> auth)
- : SMTPTransport(sess, auth, true)
-{
-}
-
-
-SMTPSTransport::~SMTPSTransport()
-{
-}
-
-
-const string SMTPSTransport::getProtocolName() const
-{
- return "smtps";
-}
-
-
-
-// Service infos
-
-SMTPServiceInfos SMTPSTransport::sm_infos(true);
-
-
-const serviceInfos& SMTPSTransport::getInfosInstance()
-{
- return sm_infos;
-}
-
-
-const serviceInfos& SMTPSTransport::getInfos() const
-{
- return sm_infos;
-}
-
-
-} // smtp
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP
-
diff --git a/src/net/smtp/SMTPServiceInfos.cpp b/src/net/smtp/SMTPServiceInfos.cpp
deleted file mode 100644
index 532bb8b8..00000000
--- a/src/net/smtp/SMTPServiceInfos.cpp
+++ /dev/null
@@ -1,146 +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/SMTPServiceInfos.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace smtp {
-
-
-SMTPServiceInfos::SMTPServiceInfos(const bool smtps)
- : m_smtps(smtps)
-{
-}
-
-
-const string SMTPServiceInfos::getPropertyPrefix() const
-{
- if (m_smtps)
- return "transport.smtps.";
- else
- return "transport.smtp.";
-}
-
-
-const SMTPServiceInfos::props& SMTPServiceInfos::getProperties() const
-{
- static props smtpProps =
- {
- // SMTP-specific options
- property("options.need-authentication", serviceInfos::property::TYPE_BOOLEAN, "false"),
-#if VMIME_HAVE_SASL_SUPPORT
- property("options.sasl", serviceInfos::property::TYPE_BOOLEAN, "true"),
- property("options.sasl.fallback", serviceInfos::property::TYPE_BOOLEAN, "false"),
-#endif // VMIME_HAVE_SASL_SUPPORT
-
- property("options.pipelining", serviceInfos::property::TYPE_BOOLEAN, "true"),
- property("options.chunking", serviceInfos::property::TYPE_BOOLEAN, "true"),
-
- // 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, "25"),
- };
-
- static props smtpsProps =
- {
- // SMTP-specific options
- property("options.need-authentication", serviceInfos::property::TYPE_BOOLEAN, "false"),
-#if VMIME_HAVE_SASL_SUPPORT
- property("options.sasl", serviceInfos::property::TYPE_BOOLEAN, "true"),
- property("options.sasl.fallback", serviceInfos::property::TYPE_BOOLEAN, "false"),
-#endif // VMIME_HAVE_SASL_SUPPORT
-
- property("options.pipelining", serviceInfos::property::TYPE_BOOLEAN, "true"),
- property("options.chunking", serviceInfos::property::TYPE_BOOLEAN, "true"),
-
- // 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, "465"),
- };
-
- return m_smtps ? smtpsProps : smtpProps;
-}
-
-
-const std::vector <serviceInfos::property> SMTPServiceInfos::getAvailableProperties() const
-{
- std::vector <property> list;
- const props& p = getProperties();
-
- // SMTP-specific options
- list.push_back(p.PROPERTY_OPTIONS_NEEDAUTH);
-#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_smtps)
- {
- 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;
-}
-
-
-} // smtp
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP
-
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
-
diff --git a/src/net/tls/TLSProperties.cpp b/src/net/tls/TLSProperties.cpp
deleted file mode 100644
index 1986db79..00000000
--- a/src/net/tls/TLSProperties.cpp
+++ /dev/null
@@ -1,44 +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_TLS_SUPPORT
-
-
-#include "vmime/net/tls/TLSProperties.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace tls {
-
-
-} // tls
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
-
diff --git a/src/net/tls/TLSSecuredConnectionInfos.cpp b/src/net/tls/TLSSecuredConnectionInfos.cpp
deleted file mode 100644
index 4856e9af..00000000
--- a/src/net/tls/TLSSecuredConnectionInfos.cpp
+++ /dev/null
@@ -1,72 +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_TLS_SUPPORT
-
-
-#include "vmime/net/tls/TLSSecuredConnectionInfos.hpp"
-#include "vmime/net/tls/TLSSession.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace tls {
-
-
-TLSSecuredConnectionInfos::TLSSecuredConnectionInfos
- (const string& host, const port_t port,
- shared_ptr <TLSSession> tlsSession, shared_ptr <TLSSocket> tlsSocket)
- : m_host(host), m_port(port),
- m_tlsSession(tlsSession), m_tlsSocket(tlsSocket)
-{
-}
-
-
-const string TLSSecuredConnectionInfos::getHost() const
-{
- return m_host;
-}
-
-
-port_t TLSSecuredConnectionInfos::getPort() const
-{
- return m_port;
-}
-
-
-shared_ptr <const security::cert::certificateChain> TLSSecuredConnectionInfos::getPeerCertificates() const
-{
- return m_tlsSocket->getPeerCertificates();
-}
-
-
-} // tls
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
-
diff --git a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
deleted file mode 100644
index a46f07ca..00000000
--- a/src/net/tls/TLSSession.cpp
+++ /dev/null
@@ -1,48 +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_TLS_SUPPORT
-
-
-#include "vmime/net/tls/TLSSession.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace tls {
-
-
-TLSSession::TLSSession()
-{
-}
-
-
-} // tls
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
diff --git a/src/net/tls/TLSSocket.cpp b/src/net/tls/TLSSocket.cpp
deleted file mode 100644
index 0419a571..00000000
--- a/src/net/tls/TLSSocket.cpp
+++ /dev/null
@@ -1,44 +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_TLS_SUPPORT
-
-
-#include "vmime/net/tls/TLSSocket.hpp"
-
-
-namespace vmime {
-namespace net {
-namespace tls {
-
-
-} // tls
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
-
diff --git a/src/net/tls/gnutls/TLSProperties_GnuTLS.cpp b/src/net/tls/gnutls/TLSProperties_GnuTLS.cpp
deleted file mode 100644
index 36ab7d7a..00000000
--- a/src/net/tls/gnutls/TLSProperties_GnuTLS.cpp
+++ /dev/null
@@ -1,113 +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_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS
-
-
-#include "vmime/base.hpp"
-#include "vmime/net/tls/gnutls/TLSProperties_GnuTLS.hpp"
-
-#include <gnutls/gnutls.h>
-#if GNUTLS_VERSION_NUMBER < 0x030000
-#include <gnutls/extra.h>
-#endif
-
-
-namespace vmime {
-namespace net {
-namespace tls {
-
-
-TLSProperties::TLSProperties()
- : m_data(make_shared <TLSProperties_GnuTLS>())
-{
- setCipherSuite(CIPHERSUITE_DEFAULT);
-}
-
-
-TLSProperties::TLSProperties(const TLSProperties& props)
- : object(),
- m_data(make_shared <TLSProperties_GnuTLS>())
-{
- *dynamicCast <TLSProperties_GnuTLS>(m_data) = *dynamicCast <TLSProperties_GnuTLS>(props.m_data);
-}
-
-
-void TLSProperties::setCipherSuite(const GenericCipherSuite cipherSuite)
-{
- switch (cipherSuite)
- {
- case CIPHERSUITE_HIGH:
-
- setCipherSuite("SECURE256:%SSL3_RECORD_VERSION");
- break;
-
- case CIPHERSUITE_MEDIUM:
-
- setCipherSuite("SECURE128:%SSL3_RECORD_VERSION");
- break;
-
- case CIPHERSUITE_LOW:
-
- setCipherSuite("NORMAL:%SSL3_RECORD_VERSION");
- break;
-
- default:
- case CIPHERSUITE_DEFAULT:
-
- setCipherSuite("NORMAL:%SSL3_RECORD_VERSION");
- break;
- }
-}
-
-
-void TLSProperties::setCipherSuite(const string& cipherSuite)
-{
- dynamicCast <TLSProperties_GnuTLS>(m_data)->cipherSuite = cipherSuite;
-}
-
-
-const string TLSProperties::getCipherSuite() const
-{
- return dynamicCast <TLSProperties_GnuTLS>(m_data)->cipherSuite;
-}
-
-
-
-TLSProperties_GnuTLS& TLSProperties_GnuTLS::operator=(const TLSProperties_GnuTLS& other)
-{
- cipherSuite = other.cipherSuite;
-
- return *this;
-}
-
-
-} // tls
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS
diff --git a/src/net/tls/gnutls/TLSSession_GnuTLS.cpp b/src/net/tls/gnutls/TLSSession_GnuTLS.cpp
deleted file mode 100644
index 1c520ed1..00000000
--- a/src/net/tls/gnutls/TLSSession_GnuTLS.cpp
+++ /dev/null
@@ -1,300 +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_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS
-
-
-#include <gnutls/gnutls.h>
-#if GNUTLS_VERSION_NUMBER < 0x030000
-#include <gnutls/extra.h>
-#endif
-
-
-// Dependency on gcrypt is not needed since GNU TLS version 2.12.
-// See here: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=638651
-#if GNUTLS_VERSION_NUMBER <= 0x020b00
-# define VMIME_GNUTLS_NEEDS_GCRYPT 1
-#endif
-
-#if VMIME_HAVE_PTHREAD
-# include <pthread.h>
-# if VMIME_GNUTLS_NEEDS_GCRYPT
-# include <gcrypt.h>
-# endif
-# include <errno.h>
-#endif // VMIME_HAVE_PTHREAD
-
-#include "vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp"
-#include "vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp"
-#include "vmime/net/tls/gnutls/TLSProperties_GnuTLS.hpp"
-
-#include "vmime/exception.hpp"
-
-
-// Enable GnuTLS debugging by defining GNUTLS_DEBUG
-//#define GNUTLS_DEBUG 1
-
-
-#include <sstream>
-#include <iomanip>
-
-#if VMIME_DEBUG && GNUTLS_DEBUG
- #include <iostream>
-#endif // VMIME_DEBUG && GNUTLS_DEBUG
-
-
-#if VMIME_HAVE_PTHREAD && VMIME_GNUTLS_NEEDS_GCRYPT && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL)
-extern "C"
-{
- GCRY_THREAD_OPTION_PTHREAD_IMPL;
-}
-#endif // VMIME_HAVE_PTHREAD && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL
-
-
-namespace vmime {
-namespace net {
-namespace tls {
-
-
-#ifndef VMIME_BUILDING_DOC
-
-// Initialize GNU TLS library
-struct TLSGlobal
-{
- TLSGlobal()
- {
-#if VMIME_HAVE_PTHREAD && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL)
- #if VMIME_GNUTLS_NEEDS_GCRYPT
- gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
- #endif // VMIME_GNUTLS_NEEDS_GCRYPT
-#endif // VMIME_HAVE_PTHREAD && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL
-
- gnutls_global_init();
- //gnutls_global_init_extra();
-
-#if VMIME_DEBUG && GNUTLS_DEBUG
- gnutls_global_set_log_function(TLSLogFunc);
- gnutls_global_set_log_level(10);
-#endif // VMIME_DEBUG && GNUTLS_DEBUG
-
- gnutls_anon_allocate_client_credentials(&anonCred);
- gnutls_certificate_allocate_credentials(&certCred);
- }
-
- ~TLSGlobal()
- {
- gnutls_anon_free_client_credentials(anonCred);
- gnutls_certificate_free_credentials(certCred);
-
- gnutls_global_deinit();
- }
-
-#if VMIME_DEBUG && GNUTLS_DEBUG
-
- static void TLSLogFunc(int level, const char *str)
- {
- std::cerr << "GNUTLS: [" << level << "] " << str << std::endl;
- }
-
-#endif // VMIME_DEBUG && GNUTLS_DEBUG
-
-
- gnutls_anon_client_credentials anonCred;
- gnutls_certificate_credentials certCred;
-};
-
-static TLSGlobal g_gnutlsGlobal;
-
-
-#endif // VMIME_BUILDING_DOC
-
-
-
-// static
-shared_ptr <TLSSession> TLSSession::create(shared_ptr <security::cert::certificateVerifier> cv, shared_ptr <TLSProperties> props)
-{
- return make_shared <TLSSession_GnuTLS>(cv, props);
-}
-
-
-TLSSession_GnuTLS::TLSSession_GnuTLS(shared_ptr <security::cert::certificateVerifier> cv, shared_ptr <TLSProperties> props)
- : m_certVerifier(cv), m_props(props)
-{
- int res;
-
- m_gnutlsSession = new gnutls_session;
-
- if (gnutls_init(m_gnutlsSession, GNUTLS_CLIENT) != 0)
- throw std::bad_alloc();
-
- // Sets some default priority on the ciphers, key exchange methods,
- // macs and compression methods.
-#ifdef VMIME_HAVE_GNUTLS_PRIORITY_FUNCS
- gnutls_dh_set_prime_bits(*m_gnutlsSession, 128);
-
- if ((res = gnutls_priority_set_direct
- (*m_gnutlsSession, m_props->getCipherSuite().c_str(), NULL)) != 0)
- {
- throwTLSException("gnutls_priority_set_direct", res);
- }
-
-#else // !VMIME_HAVE_GNUTLS_PRIORITY_FUNCS
-
- gnutls_set_default_priority(*m_gnutlsSession);
-
- // Sets the priority on the certificate types supported by gnutls.
- // Priority is higher for types specified before others. After
- // specifying the types you want, you must append a 0.
- const int certTypePriority[] = { GNUTLS_CRT_X509, 0 };
-
- res = gnutls_certificate_type_set_priority
- (*m_gnutlsSession, certTypePriority);
-
- if (res < 0)
- {
- throwTLSException
- ("gnutls_certificate_type_set_priority", res);
- }
-
- // Sets the priority on the protocol types
- const int protoPriority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
-
- res = gnutls_protocol_set_priority(*m_gnutlsSession, protoPriority);
-
- if (res < 0)
- {
- throwTLSException
- ("gnutls_certificate_type_set_priority", res);
- }
-
- // Priority on the ciphers
- const int cipherPriority[] =
- {
- GNUTLS_CIPHER_ARCFOUR_128,
- GNUTLS_CIPHER_3DES_CBC,
- GNUTLS_CIPHER_AES_128_CBC,
- GNUTLS_CIPHER_AES_256_CBC,
- GNUTLS_CIPHER_ARCFOUR_40,
- GNUTLS_CIPHER_RC2_40_CBC,
- GNUTLS_CIPHER_DES_CBC,
- 0
- };
-
- gnutls_cipher_set_priority(*m_gnutlsSession, cipherPriority);
-
- // Priority on MACs
- const int macPriority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0};
-
- gnutls_mac_set_priority(*m_gnutlsSession, macPriority);
-
- // Priority on key exchange methods
- const int kxPriority[] =
- {
- GNUTLS_KX_RSA,
- GNUTLS_KX_DHE_DSS,
- GNUTLS_KX_DHE_RSA,
- GNUTLS_KX_ANON_DH,
- GNUTLS_KX_SRP,
- GNUTLS_KX_RSA_EXPORT,
- GNUTLS_KX_SRP_RSA,
- GNUTLS_KX_SRP_DSS,
- 0
- };
-
- gnutls_kx_set_priority(*m_gnutlsSession, kxPriority);
-
- // Priority on compression methods
- const int compressionPriority[] =
- {
- GNUTLS_COMP_ZLIB,
- //GNUTLS_COMP_LZO,
- GNUTLS_COMP_NULL,
- 0
- };
-
- gnutls_compression_set_priority(*m_gnutlsSession, compressionPriority);
-
-#endif // !VMIME_HAVE_GNUTLS_PRIORITY_FUNCS
-
- // Initialize credentials
- gnutls_credentials_set(*m_gnutlsSession,
- GNUTLS_CRD_ANON, g_gnutlsGlobal.anonCred);
-
- gnutls_credentials_set(*m_gnutlsSession,
- GNUTLS_CRD_CERTIFICATE, g_gnutlsGlobal.certCred);
-}
-
-
-TLSSession_GnuTLS::TLSSession_GnuTLS(const TLSSession_GnuTLS&)
- : TLSSession()
-{
- // Not used
-}
-
-
-TLSSession_GnuTLS::~TLSSession_GnuTLS()
-{
- if (m_gnutlsSession)
- {
- gnutls_deinit(*m_gnutlsSession);
-
- delete m_gnutlsSession;
- m_gnutlsSession = NULL;
- }
-}
-
-
-shared_ptr <TLSSocket> TLSSession_GnuTLS::getSocket(shared_ptr <socket> sok)
-{
- return TLSSocket::wrap(dynamicCast <TLSSession>(shared_from_this()), sok);
-}
-
-
-shared_ptr <security::cert::certificateVerifier> TLSSession_GnuTLS::getCertificateVerifier()
-{
- return m_certVerifier;
-}
-
-
-void TLSSession_GnuTLS::throwTLSException(const string& fname, const int code)
-{
- std::ostringstream msg;
-
- msg << fname + "() returned code ";
- msg << std::hex << code;
- msg << ": ";
- msg << gnutls_strerror(code);
-
- throw exceptions::tls_exception(msg.str());
-}
-
-
-} // tls
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS
diff --git a/src/net/tls/gnutls/TLSSocket_GnuTLS.cpp b/src/net/tls/gnutls/TLSSocket_GnuTLS.cpp
deleted file mode 100644
index 5a90565b..00000000
--- a/src/net/tls/gnutls/TLSSocket_GnuTLS.cpp
+++ /dev/null
@@ -1,490 +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_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS
-
-
-#include <gnutls/gnutls.h>
-#include <gnutls/x509.h>
-
-#include "vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp"
-#include "vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp"
-
-#include "vmime/platform.hpp"
-
-#include "vmime/security/cert/X509Certificate.hpp"
-
-#include "vmime/utility/stringUtils.hpp"
-
-#include <cstring>
-
-
-namespace vmime {
-namespace net {
-namespace tls {
-
-
-// static
-shared_ptr <TLSSocket> TLSSocket::wrap(shared_ptr <TLSSession> session, shared_ptr <socket> sok)
-{
- return make_shared <TLSSocket_GnuTLS>
- (dynamicCast <TLSSession_GnuTLS>(session), sok);
-}
-
-
-TLSSocket_GnuTLS::TLSSocket_GnuTLS(shared_ptr <TLSSession_GnuTLS> session, shared_ptr <socket> sok)
- : m_session(session), m_wrapped(sok), m_connected(false),
- m_handshaking(false), m_ex(NULL), m_status(0)
-{
- gnutls_transport_set_ptr(*m_session->m_gnutlsSession, this);
-
- gnutls_transport_set_push_function(*m_session->m_gnutlsSession, gnutlsPushFunc);
- gnutls_transport_set_pull_function(*m_session->m_gnutlsSession, gnutlsPullFunc);
-}
-
-
-TLSSocket_GnuTLS::~TLSSocket_GnuTLS()
-{
- if (m_ex)
- {
- delete m_ex;
- m_ex = NULL;
- }
-
- try
- {
- disconnect();
- }
- catch (...)
- {
- // Don't throw exception in destructor
- }
-}
-
-
-void TLSSocket_GnuTLS::connect(const string& address, const port_t port)
-{
- m_wrapped->connect(address, port);
-
- handshake(null);
-
- m_connected = true;
-}
-
-
-void TLSSocket_GnuTLS::disconnect()
-{
- if (m_connected)
- {
- gnutls_bye(*m_session->m_gnutlsSession, GNUTLS_SHUT_RDWR);
-
- m_wrapped->disconnect();
-
- m_connected = false;
- }
-}
-
-
-bool TLSSocket_GnuTLS::isConnected() const
-{
- return m_wrapped->isConnected() && m_connected;
-}
-
-
-size_t TLSSocket_GnuTLS::getBlockSize() const
-{
- return 16384; // 16 KB
-}
-
-
-const string TLSSocket_GnuTLS::getPeerName() const
-{
- return m_wrapped->getPeerName();
-}
-
-
-const string TLSSocket_GnuTLS::getPeerAddress() const
-{
- return m_wrapped->getPeerAddress();
-}
-
-
-void TLSSocket_GnuTLS::receive(string& buffer)
-{
- const size_t size = receiveRaw(m_buffer, sizeof(m_buffer));
- buffer = utility::stringUtils::makeStringFromBytes(m_buffer, size);
-}
-
-
-void TLSSocket_GnuTLS::send(const string& buffer)
-{
- sendRaw(reinterpret_cast <const byte_t*>(buffer.data()), buffer.length());
-}
-
-
-void TLSSocket_GnuTLS::send(const char* str)
-{
- sendRaw(reinterpret_cast <const byte_t*>(str), ::strlen(str));
-}
-
-
-size_t TLSSocket_GnuTLS::receiveRaw(byte_t* buffer, const size_t count)
-{
- m_status &= ~STATUS_WOULDBLOCK;
-
- const ssize_t ret = gnutls_record_recv
- (*m_session->m_gnutlsSession,
- buffer, static_cast <size_t>(count));
-
- if (m_ex)
- internalThrow();
-
- if (ret < 0)
- {
- if (ret == GNUTLS_E_AGAIN)
- {
- m_status |= STATUS_WOULDBLOCK;
- return 0;
- }
-
- TLSSession_GnuTLS::throwTLSException("gnutls_record_recv", static_cast <int>(ret));
- }
-
- return static_cast <size_t>(ret);
-}
-
-
-void TLSSocket_GnuTLS::sendRaw(const byte_t* buffer, const size_t count)
-{
- ssize_t ret = gnutls_record_send
- (*m_session->m_gnutlsSession,
- buffer, static_cast <size_t>(count));
-
- if (m_ex)
- internalThrow();
-
- if (ret < 0)
- {
- if (ret == GNUTLS_E_AGAIN)
- {
- m_status |= STATUS_WOULDBLOCK;
- return;
- }
-
- TLSSession_GnuTLS::throwTLSException("gnutls_record_send", static_cast <int>(ret));
- }
-}
-
-
-size_t TLSSocket_GnuTLS::sendRawNonBlocking(const byte_t* buffer, const size_t count)
-{
- ssize_t ret = gnutls_record_send
- (*m_session->m_gnutlsSession,
- buffer, static_cast <size_t>(count));
-
- if (m_ex)
- internalThrow();
-
- if (ret < 0)
- {
- if (ret == GNUTLS_E_AGAIN)
- {
- m_status |= STATUS_WOULDBLOCK;
- return 0;
- }
-
- TLSSession_GnuTLS::throwTLSException("gnutls_record_send", static_cast <int>(ret));
- }
-
- return static_cast <size_t>(ret);
-}
-
-
-unsigned int TLSSocket_GnuTLS::getStatus() const
-{
- return m_status | m_wrapped->getStatus();
-}
-
-
-void TLSSocket_GnuTLS::handshake(shared_ptr <timeoutHandler> toHandler)
-{
- if (toHandler)
- toHandler->resetTimeOut();
-
- // Start handshaking process
- m_handshaking = true;
- m_toHandler = toHandler;
-
- try
- {
- while (true)
- {
- const int ret = gnutls_handshake(*m_session->m_gnutlsSession);
-
- if (m_ex)
- internalThrow();
-
- if (ret < 0)
- {
- if (ret == GNUTLS_E_AGAIN ||
- ret == GNUTLS_E_INTERRUPTED)
- {
- // Non-fatal error
- platform::getHandler()->wait();
- }
- else
- {
- TLSSession_GnuTLS::throwTLSException("gnutls_handshake", ret);
- }
- }
- else
- {
- // Successful handshake
- break;
- }
- }
- }
- catch (...)
- {
- m_handshaking = false;
- m_toHandler = null;
-
- throw;
- }
-
- m_handshaking = false;
- m_toHandler = null;
-
- // Verify server's certificate(s)
- shared_ptr <security::cert::certificateChain> certs = getPeerCertificates();
-
- if (certs == NULL)
- throw exceptions::tls_exception("No peer certificate.");
-
- m_session->getCertificateVerifier()->verify(certs, getPeerName());
-
- m_connected = true;
-}
-
-
-ssize_t TLSSocket_GnuTLS::gnutlsPushFunc
- (gnutls_transport_ptr trspt, const void* data, size_t len)
-{
- TLSSocket_GnuTLS* sok = reinterpret_cast <TLSSocket_GnuTLS*>(trspt);
-
- try
- {
- sok->m_wrapped->sendRaw
- (reinterpret_cast <const byte_t*>(data), len);
- }
- catch (exception& e)
- {
- // Workaround for bad behaviour when throwing C++ exceptions
- // from C functions (GNU TLS)
- sok->m_ex = e.clone();
- return -1;
- }
-
- return len;
-}
-
-
-ssize_t TLSSocket_GnuTLS::gnutlsPullFunc
- (gnutls_transport_ptr trspt, void* data, size_t len)
-{
- TLSSocket_GnuTLS* sok = reinterpret_cast <TLSSocket_GnuTLS*>(trspt);
-
- try
- {
- // Workaround for cross-platform asynchronous handshaking:
- // gnutls_handshake() only returns GNUTLS_E_AGAIN if recv()
- // returns -1 and errno is set to EGAIN...
- if (sok->m_handshaking)
- {
- while (true)
- {
- const ssize_t ret = static_cast <ssize_t>
- (sok->m_wrapped->receiveRaw
- (reinterpret_cast <byte_t*>(data), len));
-
- if (ret == 0)
- {
- // No data available yet
- platform::getHandler()->wait();
- }
- else
- {
- return ret;
- }
-
- // Check whether the time-out delay is elapsed
- if (sok->m_toHandler && sok->m_toHandler->isTimeOut())
- {
- if (!sok->m_toHandler->handleTimeOut())
- throw exceptions::operation_timed_out();
-
- sok->m_toHandler->resetTimeOut();
- }
- }
- }
- else
- {
- const ssize_t n = static_cast <ssize_t>
- (sok->m_wrapped->receiveRaw
- (reinterpret_cast <byte_t*>(data), len));
-
- if (n == 0 && sok->m_wrapped->getStatus() & socket::STATUS_WOULDBLOCK)
- return GNUTLS_E_AGAIN;
-
- return n;
- }
- }
- catch (exception& e)
- {
- // Workaround for bad behaviour when throwing C++ exceptions
- // from C functions (GNU TLS)
- sok->m_ex = e.clone();
- return -1;
- }
-}
-
-
-shared_ptr <security::cert::certificateChain> TLSSocket_GnuTLS::getPeerCertificates() const
-{
- unsigned int certCount = 0;
- const gnutls_datum* rawData = gnutls_certificate_get_peers
- (*m_session->m_gnutlsSession, &certCount);
-
- if (rawData == NULL)
- return null;
-
- // Try X.509
- gnutls_x509_crt* x509Certs = new gnutls_x509_crt[certCount];
-
- for (unsigned int i = 0; i < certCount; ++i)
- {
- gnutls_x509_crt_init(x509Certs + i);
-
- int res = gnutls_x509_crt_import(x509Certs[i], rawData + i,
- GNUTLS_X509_FMT_DER);
-
- if (res < 0)
- {
- // XXX more fine-grained error reporting?
- delete [] x509Certs;
- return null;
- }
- }
-
- {
- std::vector <shared_ptr <security::cert::certificate> > certs;
- bool error = false;
-
- for (unsigned int i = 0 ; i < certCount ; ++i)
- {
- size_t dataSize = 0;
-
- gnutls_x509_crt_export(x509Certs[i],
- GNUTLS_X509_FMT_DER, NULL, &dataSize);
-
- std::vector <byte_t> data(dataSize);
-
- gnutls_x509_crt_export(x509Certs[i],
- GNUTLS_X509_FMT_DER, &data[0], &dataSize);
-
- shared_ptr <security::cert::X509Certificate> cert =
- security::cert::X509Certificate::import(&data[0], dataSize);
-
- if (cert != NULL)
- certs.push_back(cert);
- else
- error = true;
-
- gnutls_x509_crt_deinit(x509Certs[i]);
- }
-
- delete [] x509Certs;
-
- if (error)
- return null;
-
- return make_shared <security::cert::certificateChain>(certs);
- }
-
- delete [] x509Certs;
-
- return null;
-}
-
-
-// Following is a workaround for C++ exceptions to pass correctly between
-// C and C++ calls.
-//
-// gnutls_record_recv() calls TLSSocket::gnutlsPullFunc, and exceptions
-// thrown by the socket can not be caught.
-
-#ifndef VMIME_BUILDING_DOC
-
-class TLSSocket_DeleteExWrapper : public object
-{
-public:
-
- TLSSocket_DeleteExWrapper(exception* ex) : m_ex(ex) { }
- ~TLSSocket_DeleteExWrapper() { delete m_ex; }
-
-private:
-
- exception* m_ex;
-};
-
-#endif // VMIME_BUILDING_DOC
-
-
-void TLSSocket_GnuTLS::internalThrow()
-{
- static std::vector <shared_ptr <TLSSocket_DeleteExWrapper> > exToDelete;
-
- if (m_ex)
- {
- // Reset the current exception pointer to prevent the same
- // exception from being thrown again later
- exception* ex = m_ex;
- m_ex = NULL;
-
- // To avoid memory leaks
- exToDelete.push_back(make_shared <TLSSocket_DeleteExWrapper>(ex));
-
- throw *ex;
- }
-}
-
-
-} // tls
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS
diff --git a/src/net/tls/openssl/OpenSSLInitializer.cpp b/src/net/tls/openssl/OpenSSLInitializer.cpp
deleted file mode 100644
index 1bbb9ee5..00000000
--- a/src/net/tls/openssl/OpenSSLInitializer.cpp
+++ /dev/null
@@ -1,142 +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_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL
-
-
-#include "vmime/net/tls/openssl/OpenSSLInitializer.hpp"
-
-#include "vmime/utility/sync/autoLock.hpp"
-#include "vmime/utility/sync/criticalSection.hpp"
-
-#include "vmime/platform.hpp"
-
-#include <openssl/ssl.h>
-#include <openssl/rand.h>
-#include <openssl/crypto.h>
-#include <openssl/err.h>
-
-#if OPENSSL_VERSION_NUMBER >= 0x0907000L
-# include <openssl/conf.h>
-#endif
-
-
-namespace vmime {
-namespace net {
-namespace tls {
-
-
-shared_ptr <vmime::utility::sync::criticalSection >* OpenSSLInitializer::sm_mutexes;
-
-
-OpenSSLInitializer::autoInitializer::autoInitializer()
-{
- // The construction of this unique 'oneTimeInitializer' object will be triggered
- // by the 'autoInitializer' objects from the other translation units
- static OpenSSLInitializer::oneTimeInitializer oneTimeInitializer;
-}
-
-
-OpenSSLInitializer::autoInitializer::~autoInitializer()
-{
-}
-
-
-OpenSSLInitializer::oneTimeInitializer::oneTimeInitializer()
-{
- initialize();
-}
-
-
-OpenSSLInitializer::oneTimeInitializer::~oneTimeInitializer()
-{
- uninitialize();
-}
-
-
-// static
-void OpenSSLInitializer::initialize()
-{
-#if OPENSSL_VERSION_NUMBER >= 0x0907000L
- OPENSSL_config(NULL);
-#endif
-
- SSL_load_error_strings();
- SSL_library_init();
- OpenSSL_add_all_algorithms();
-
- unsigned char seed[SEEDSIZE];
- vmime::platform::getHandler()->generateRandomBytes(seed, SEEDSIZE);
- RAND_seed(seed, SEEDSIZE);
-
- int numMutexes = CRYPTO_num_locks();
- sm_mutexes = new shared_ptr <vmime::utility::sync::criticalSection>[numMutexes];
-
- for (int i = 0 ; i < numMutexes ; ++i)
- sm_mutexes[i] = vmime::platform::getHandler()->createCriticalSection();
-
- CRYPTO_set_locking_callback(&OpenSSLInitializer::lock);
- CRYPTO_set_id_callback(&OpenSSLInitializer::id);
-}
-
-
-// static
-void OpenSSLInitializer::uninitialize()
-{
- EVP_cleanup();
- ERR_free_strings();
-
- CRYPTO_set_locking_callback(NULL);
- CRYPTO_set_id_callback(NULL);
-
- delete [] sm_mutexes;
-}
-
-
-// static
-void OpenSSLInitializer::lock(int mode, int n, const char* /* file */, int /* line */)
-{
- if (mode & CRYPTO_LOCK)
- sm_mutexes[n]->lock();
- else
- sm_mutexes[n]->unlock();
-}
-
-
-// static
-unsigned long OpenSSLInitializer::id()
-{
- return vmime::platform::getHandler()->getThreadId();
-}
-
-
-} // tls
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL
-
diff --git a/src/net/tls/openssl/TLSProperties_OpenSSL.cpp b/src/net/tls/openssl/TLSProperties_OpenSSL.cpp
deleted file mode 100644
index 932477df..00000000
--- a/src/net/tls/openssl/TLSProperties_OpenSSL.cpp
+++ /dev/null
@@ -1,112 +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_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL
-
-
-#include "vmime/base.hpp"
-#include "vmime/net/tls/openssl/TLSProperties_OpenSSL.hpp"
-
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-
-
-namespace vmime {
-namespace net {
-namespace tls {
-
-
-TLSProperties::TLSProperties()
- : m_data(make_shared <TLSProperties_OpenSSL>())
-{
- setCipherSuite(CIPHERSUITE_DEFAULT);
-}
-
-
-TLSProperties::TLSProperties(const TLSProperties& props)
- : object(),
- m_data(make_shared <TLSProperties_OpenSSL>())
-{
- *dynamicCast <TLSProperties_OpenSSL>(m_data) = *dynamicCast <TLSProperties_OpenSSL>(props.m_data);
-}
-
-
-void TLSProperties::setCipherSuite(const GenericCipherSuite cipherSuite)
-{
- switch (cipherSuite)
- {
- case CIPHERSUITE_HIGH:
-
- setCipherSuite("HIGH:!ADH:@STRENGTH");
- break;
-
- case CIPHERSUITE_MEDIUM:
-
- setCipherSuite("MEDIUM:!ADH:@STRENGTH");
- break;
-
- case CIPHERSUITE_LOW:
-
- setCipherSuite("LOW:!ADH:@STRENGTH");
- break;
-
- default:
- case CIPHERSUITE_DEFAULT:
-
- setCipherSuite("DEFAULT:!ADH:@STRENGTH");
- break;
- }
-}
-
-
-void TLSProperties::setCipherSuite(const string& cipherSuite)
-{
- dynamicCast <TLSProperties_OpenSSL>(m_data)->cipherSuite = cipherSuite;
-}
-
-
-const string TLSProperties::getCipherSuite() const
-{
- return dynamicCast <TLSProperties_OpenSSL>(m_data)->cipherSuite;
-}
-
-
-
-TLSProperties_OpenSSL& TLSProperties_OpenSSL::operator=(const TLSProperties_OpenSSL& other)
-{
- cipherSuite = other.cipherSuite;
-
- return *this;
-}
-
-
-} // tls
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL
-
diff --git a/src/net/tls/openssl/TLSSession_OpenSSL.cpp b/src/net/tls/openssl/TLSSession_OpenSSL.cpp
deleted file mode 100644
index cf600a63..00000000
--- a/src/net/tls/openssl/TLSSession_OpenSSL.cpp
+++ /dev/null
@@ -1,135 +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_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL
-
-
-#include "vmime/net/tls/openssl/TLSSession_OpenSSL.hpp"
-#include "vmime/net/tls/openssl/TLSProperties_OpenSSL.hpp"
-#include "vmime/net/tls/openssl/OpenSSLInitializer.hpp"
-
-#include "vmime/exception.hpp"
-
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-
-
-namespace vmime {
-namespace net {
-namespace tls {
-
-
-static OpenSSLInitializer::autoInitializer openSSLInitializer;
-
-
-// static
-shared_ptr <TLSSession> TLSSession::create(shared_ptr <security::cert::certificateVerifier> cv, shared_ptr <TLSProperties> props)
-{
- return make_shared <TLSSession_OpenSSL>(cv, props);
-}
-
-
-TLSSession_OpenSSL::TLSSession_OpenSSL(shared_ptr <vmime::security::cert::certificateVerifier> cv, shared_ptr <TLSProperties> props)
- : m_sslctx(0), m_certVerifier(cv), m_props(props)
-{
- m_sslctx = SSL_CTX_new(SSLv23_client_method());
- SSL_CTX_set_options(m_sslctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
- SSL_CTX_set_mode(m_sslctx, SSL_MODE_AUTO_RETRY);
- SSL_CTX_set_cipher_list(m_sslctx, m_props->getCipherSuite().c_str());
- SSL_CTX_set_session_cache_mode(m_sslctx, SSL_SESS_CACHE_OFF);
-}
-
-
-TLSSession_OpenSSL::TLSSession_OpenSSL(const TLSSession_OpenSSL&)
- : TLSSession()
-{
- // Not used
-}
-
-
-TLSSession_OpenSSL::~TLSSession_OpenSSL()
-{
- SSL_CTX_free(m_sslctx);
-}
-
-
-shared_ptr <TLSSocket> TLSSession_OpenSSL::getSocket(shared_ptr <socket> sok)
-{
- return TLSSocket::wrap(dynamicCast <TLSSession>(shared_from_this()), sok);
-}
-
-
-shared_ptr <security::cert::certificateVerifier> TLSSession_OpenSSL::getCertificateVerifier()
-{
- return m_certVerifier;
-}
-
-
-void TLSSession_OpenSSL::usePrivateKeyFile(const vmime::string& keyfile)
-{
- if (SSL_CTX_use_PrivateKey_file(m_sslctx, keyfile.c_str(), SSL_FILETYPE_PEM) != 1)
- {
- unsigned long errCode = ERR_get_error();
- char buffer[256];
- ERR_error_string_n(errCode, buffer, sizeof(buffer));
- vmime::string sslErr(buffer);
- std::ostringstream oss;
- oss << "Error loading private key from file " << keyfile;
- oss << " - msg: " << sslErr;
- throw exceptions::certificate_exception(oss.str());
- }
-}
-
-
-void TLSSession_OpenSSL::useCertificateChainFile(const vmime::string& chainFile)
-{
- if (SSL_CTX_use_certificate_chain_file(m_sslctx, chainFile.c_str()) != 1)
- {
- unsigned long errCode = ERR_get_error();
- char buffer[256];
- ERR_error_string_n(errCode, buffer, sizeof(buffer));
- vmime::string sslErr(buffer);
- std::ostringstream oss;
- oss << "Error loading certificate from file " << chainFile;
- oss << " - msg: " << sslErr;
- throw exceptions::certificate_exception(oss.str());
- }
-}
-
-
-SSL_CTX* TLSSession_OpenSSL::getContext() const
-{
- return m_sslctx;
-}
-
-
-} // tls
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL
-
diff --git a/src/net/tls/openssl/TLSSocket_OpenSSL.cpp b/src/net/tls/openssl/TLSSocket_OpenSSL.cpp
deleted file mode 100644
index ef6647d6..00000000
--- a/src/net/tls/openssl/TLSSocket_OpenSSL.cpp
+++ /dev/null
@@ -1,601 +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_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL
-
-
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-
-#include "vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp"
-#include "vmime/net/tls/openssl/TLSSession_OpenSSL.hpp"
-#include "vmime/net/tls/openssl/OpenSSLInitializer.hpp"
-
-#include "vmime/platform.hpp"
-
-#include "vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp"
-
-#include "vmime/utility/stringUtils.hpp"
-
-#include <vector>
-#include <cstring>
-
-
-namespace vmime {
-namespace net {
-namespace tls {
-
-
-static OpenSSLInitializer::autoInitializer openSSLInitializer;
-
-
-// static
-BIO_METHOD TLSSocket_OpenSSL::sm_customBIOMethod =
-{
- 100 | BIO_TYPE_SOURCE_SINK,
- "vmime::socket glue",
- TLSSocket_OpenSSL::bio_write,
- TLSSocket_OpenSSL::bio_read,
- TLSSocket_OpenSSL::bio_puts,
- NULL, // gets
- TLSSocket_OpenSSL::bio_ctrl,
- TLSSocket_OpenSSL::bio_create,
- TLSSocket_OpenSSL::bio_destroy,
- 0
-};
-
-
-// static
-shared_ptr <TLSSocket> TLSSocket::wrap(shared_ptr <TLSSession> session, shared_ptr <socket> sok)
-{
- return make_shared <TLSSocket_OpenSSL>
- (dynamicCast <TLSSession_OpenSSL>(session), sok);
-}
-
-
-TLSSocket_OpenSSL::TLSSocket_OpenSSL(shared_ptr <TLSSession_OpenSSL> session, shared_ptr <socket> sok)
- : m_session(session), m_wrapped(sok), m_connected(false), m_ssl(0), m_status(0), m_ex(NULL)
-{
-}
-
-
-TLSSocket_OpenSSL::~TLSSocket_OpenSSL()
-{
- try
- {
- disconnect();
-
- if (m_ssl)
- {
- SSL_free(m_ssl);
- m_ssl = 0;
- }
- }
- catch (...)
- {
- // Don't throw in destructor
- }
-}
-
-
-void TLSSocket_OpenSSL::createSSLHandle()
-{
- if (m_wrapped->isConnected())
- {
- BIO* sockBio = BIO_new(&sm_customBIOMethod);
- sockBio->ptr = this;
- sockBio->init = 1;
-
- m_ssl = SSL_new(m_session->getContext());
-
- if (!m_ssl)
- {
- BIO_free(sockBio);
- throw exceptions::tls_exception("Cannot create SSL object");
- }
-
- SSL_set_bio(m_ssl, sockBio, sockBio);
- SSL_set_connect_state(m_ssl);
- }
- else
- {
- throw exceptions::tls_exception("Unconnected socket error");
- }
-}
-
-
-void TLSSocket_OpenSSL::connect(const string& address, const port_t port)
-{
- m_wrapped->connect(address, port);
-
- createSSLHandle();
-
- handshake(null);
-
- m_connected = true;
-}
-
-
-void TLSSocket_OpenSSL::disconnect()
-{
- if (m_connected)
- {
- if (m_ssl)
- {
- // Don't shut down the socket more than once.
- int shutdownState = SSL_get_shutdown(m_ssl);
- bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN;
-
- if (!shutdownSent)
- SSL_shutdown(m_ssl);
- }
-
- m_wrapped->disconnect();
- m_connected = false;
- }
-}
-
-
-bool TLSSocket_OpenSSL::isConnected() const
-{
- return m_wrapped->isConnected() && m_connected;
-}
-
-
-size_t TLSSocket_OpenSSL::getBlockSize() const
-{
- return 16384; // 16 KB
-}
-
-
-const string TLSSocket_OpenSSL::getPeerName() const
-{
- return m_wrapped->getPeerName();
-}
-
-
-const string TLSSocket_OpenSSL::getPeerAddress() const
-{
- return m_wrapped->getPeerAddress();
-}
-
-
-void TLSSocket_OpenSSL::receive(string& buffer)
-{
- const size_t size = receiveRaw(m_buffer, sizeof(m_buffer));
-
- if (size != 0)
- buffer = utility::stringUtils::makeStringFromBytes(m_buffer, size);
- else
- buffer.clear();
-}
-
-
-void TLSSocket_OpenSSL::send(const string& buffer)
-{
- sendRaw(reinterpret_cast <const byte_t*>(buffer.data()), buffer.length());
-}
-
-
-void TLSSocket_OpenSSL::send(const char* str)
-{
- sendRaw(reinterpret_cast <const byte_t*>(str), ::strlen(str));
-}
-
-
-size_t TLSSocket_OpenSSL::receiveRaw(byte_t* buffer, const size_t count)
-{
- m_status &= ~STATUS_WOULDBLOCK;
-
- int rc = SSL_read(m_ssl, buffer, static_cast <int>(count));
-
- if (m_ex.get())
- internalThrow();
-
- if (rc <= 0)
- {
- int error = SSL_get_error(m_ssl, rc);
-
- if (error == SSL_ERROR_WANT_WRITE || error == SSL_ERROR_WANT_READ)
- {
- m_status |= STATUS_WOULDBLOCK;
- return 0;
- }
-
- handleError(rc);
- }
-
- return rc;
-}
-
-
-void TLSSocket_OpenSSL::sendRaw(const byte_t* buffer, const size_t count)
-{
- sendRawNonBlocking(buffer, count);
-}
-
-
-size_t TLSSocket_OpenSSL::sendRawNonBlocking(const byte_t* buffer, const size_t count)
-{
- m_status &= ~STATUS_WOULDBLOCK;
-
- int rc = SSL_write(m_ssl, buffer, static_cast <int>(count));
-
- if (m_ex.get())
- internalThrow();
-
- if (rc <= 0)
- {
- int error = SSL_get_error(m_ssl, rc);
-
- if (error == SSL_ERROR_WANT_WRITE || error == SSL_ERROR_WANT_READ)
- {
- m_status |= STATUS_WOULDBLOCK;
- return 0;
- }
-
- handleError(rc);
- }
-
- return rc;
-}
-
-
-void TLSSocket_OpenSSL::handshake(shared_ptr <timeoutHandler> toHandler)
-{
- if (toHandler)
- toHandler->resetTimeOut();
-
- // Start handshaking process
- m_toHandler = toHandler;
-
- if (!m_ssl)
- createSSLHandle();
-
- try
- {
- int rc;
-
- while ((rc = SSL_do_handshake(m_ssl)) <= 0)
- {
- const int err = SSL_get_error(m_ssl, rc);
-
- if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
- {
- // No data available yet
- platform::getHandler()->wait();
- }
- else
- {
- handleError(rc);
- }
-
- // Check whether the time-out delay is elapsed
- if (m_toHandler && m_toHandler->isTimeOut())
- {
- if (!m_toHandler->handleTimeOut())
- throw exceptions::operation_timed_out();
-
- m_toHandler->resetTimeOut();
- }
- }
- }
- catch (...)
- {
- SSL_free(m_ssl);
- m_ssl = 0;
- m_toHandler = null;
- throw;
- }
-
- m_toHandler = null;
-
- // Verify server's certificate(s)
- shared_ptr <security::cert::certificateChain> certs = getPeerCertificates();
-
- if (certs == NULL)
- throw exceptions::tls_exception("No peer certificate.");
-
- m_session->getCertificateVerifier()->verify(certs, getPeerName());
-
- m_connected = true;
-}
-
-
-shared_ptr <security::cert::certificateChain> TLSSocket_OpenSSL::getPeerCertificates() const
-{
- STACK_OF(X509)* chain = SSL_get_peer_cert_chain(m_ssl);
-
- if (chain == NULL)
- return null;
-
- int certCount = sk_X509_num(chain);
-
- if (certCount == 0)
- return null;
-
- bool error = false;
- std::vector <shared_ptr <security::cert::certificate> > certs;
-
- for (int i = 0; i < certCount && !error; i++)
- {
- shared_ptr <vmime::security::cert::X509Certificate> cert =
- vmime::security::cert::X509Certificate_OpenSSL::importInternal(sk_X509_value(chain, i));
-
- if (cert)
- certs.push_back(cert);
- else
- error = true;
- }
-
- if (error)
- return null;
-
- return make_shared <security::cert::certificateChain>(certs);
-}
-
-
-void TLSSocket_OpenSSL::internalThrow()
-{
- if (m_ex.get())
- throw *m_ex;
-}
-
-
-void TLSSocket_OpenSSL::handleError(int rc)
-{
- if (rc > 0) return;
-
- internalThrow();
-
- int sslError = SSL_get_error(m_ssl, rc);
- long lastError = ERR_get_error();
-
- switch (sslError)
- {
- case SSL_ERROR_ZERO_RETURN:
- return;
-
- case SSL_ERROR_SYSCALL:
- {
- if (lastError == 0)
- {
- if (rc == 0)
- {
- throw exceptions::tls_exception("SSL connection unexpectedly closed");
- }
- else
- {
- vmime::string msg;
- std::ostringstream oss(msg);
- oss << "The BIO reported an error: " << rc;
- oss.flush();
- throw exceptions::tls_exception(oss.str());
- }
- }
- break;
- }
-
- case SSL_ERROR_WANT_READ:
-
- BIO_set_retry_read(SSL_get_rbio(m_ssl));
- break;
-
- case SSL_ERROR_WANT_WRITE:
-
- BIO_set_retry_write(SSL_get_wbio(m_ssl));
- break;
-
- // This happens only for BIOs of type BIO_s_connect() or BIO_s_accept()
- case SSL_ERROR_WANT_CONNECT:
- case SSL_ERROR_WANT_ACCEPT:
- // SSL_CTX_set_client_cert_cb related, not used
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- default:
-
- if (lastError == 0)
- {
- throw exceptions::tls_exception("Unexpected SSL IO error");
- }
- else
- {
- char buffer[256];
- ERR_error_string_n(lastError, buffer, sizeof(buffer));
- vmime::string msg(buffer);
- throw exceptions::tls_exception(msg);
- }
-
- break;
- }
-}
-
-
-unsigned int TLSSocket_OpenSSL::getStatus() const
-{
- return m_status;
-}
-
-
-// Implementation of custom BIO methods
-
-
-// static
-int TLSSocket_OpenSSL::bio_write(BIO* bio, const char* buf, int len)
-{
- BIO_clear_retry_flags(bio);
-
- if (buf == NULL || len <= 0)
- return -1;
-
- TLSSocket_OpenSSL *sok = reinterpret_cast <TLSSocket_OpenSSL*>(bio->ptr);
-
- if (!bio->init || !sok)
- return -1;
-
- try
- {
- const size_t n = sok->m_wrapped->sendRawNonBlocking
- (reinterpret_cast <const byte_t*>(buf), len);
-
- if (n == 0 && sok->m_wrapped->getStatus() & socket::STATUS_WOULDBLOCK)
- {
- BIO_set_retry_write(bio);
- return -1;
- }
-
- return static_cast <int>(len);
- }
- catch (exception& e)
- {
- // Workaround for passing C++ exceptions from C BIO functions
- sok->m_ex.reset(e.clone());
- return -1;
- }
-}
-
-
-// static
-int TLSSocket_OpenSSL::bio_read(BIO* bio, char* buf, int len)
-{
- BIO_clear_retry_flags(bio);
-
- if (buf == NULL || len <= 0)
- return -1;
-
- TLSSocket_OpenSSL *sok = reinterpret_cast <TLSSocket_OpenSSL*>(bio->ptr);
-
- if (!bio->init || !sok)
- return -1;
-
- try
- {
- const size_t n = sok->m_wrapped->receiveRaw
- (reinterpret_cast <byte_t*>(buf), len);
-
- if (n == 0 || sok->m_wrapped->getStatus() & socket::STATUS_WOULDBLOCK)
- {
- BIO_set_retry_read(bio);
- return -1;
- }
-
- return static_cast <int>(n);
- }
- catch (exception& e)
- {
- // Workaround for passing C++ exceptions from C BIO functions
- sok->m_ex.reset(e.clone());
- return -1;
- }
-}
-
-
-// static
-int TLSSocket_OpenSSL::bio_puts(BIO* bio, const char* str)
-{
- return bio_write(bio, str, static_cast <int>(strlen(str)));
-}
-
-
-// static
-long TLSSocket_OpenSSL::bio_ctrl(BIO* bio, int cmd, long num, void* ptr)
-{
- long ret = 1;
-
- switch (cmd)
- {
- case BIO_CTRL_INFO:
-
- ret = 0;
- break;
-
- case BIO_CTRL_GET_CLOSE:
-
- ret = bio->shutdown;
- break;
-
- case BIO_CTRL_SET_CLOSE:
-
- bio->shutdown = static_cast <int>(num);
- break;
-
- case BIO_CTRL_PENDING:
- case BIO_CTRL_WPENDING:
-
- ret = 0;
- break;
-
- case BIO_CTRL_DUP:
- case BIO_CTRL_FLUSH:
-
- ret = 1;
- break;
-
- default:
-
- ret = 0;
- break;
- }
-
- return ret;
-}
-
-
-// static
-int TLSSocket_OpenSSL::bio_create(BIO* bio)
-{
- bio->init = 0;
- bio->num = 0;
- bio->ptr = NULL;
- bio->flags = 0;
-
- return 1;
-}
-
-
-// static
-int TLSSocket_OpenSSL::bio_destroy(BIO* bio)
-{
- if (bio == NULL)
- return 0;
-
- if (bio->shutdown)
- {
- bio->ptr = NULL;
- bio->init = 0;
- bio->flags = 0;
- }
-
- return 1;
-}
-
-
-} // tls
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL
diff --git a/src/net/transport.cpp b/src/net/transport.cpp
deleted file mode 100644
index dd7281d0..00000000
--- a/src/net/transport.cpp
+++ /dev/null
@@ -1,236 +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
-
-
-#include "vmime/net/transport.hpp"
-
-#include "vmime/utility/stream.hpp"
-#include "vmime/mailboxList.hpp"
-#include "vmime/message.hpp"
-#include "vmime/dateTime.hpp"
-#include "vmime/messageId.hpp"
-
-#include "vmime/utility/outputStreamAdapter.hpp"
-#include "vmime/utility/inputStreamStringAdapter.hpp"
-
-
-namespace vmime {
-namespace net {
-
-
-transport::transport(shared_ptr <session> sess, const serviceInfos& infos, shared_ptr <security::authenticator> auth)
- : service(sess, infos, auth)
-{
-}
-
-
-shared_ptr <headerField> transport::processHeaderField(shared_ptr <headerField> field)
-{
- if (utility::stringUtils::isStringEqualNoCase(field->getName(), fields::BCC))
- {
- // Remove Bcc headers from the message, as required by the RFC.
- // Some SMTP server automatically strip this header (Postfix, qmail),
- // and others have an option for this (Exim).
- return null;
- }
- else if (utility::stringUtils::isStringEqualNoCase(field->getName(), fields::RETURN_PATH))
- {
- // RFC-2821: Return-Path header is added by the final transport system
- // that delivers the message to its recipient. Then, it should not be
- // transmitted to MSA.
- return null;
- }
- else if (utility::stringUtils::isStringEqualNoCase(field->getName(), fields::ORIGINAL_RECIPIENT))
- {
- // RFC-2298: Delivering MTA may add the Original-Recipient header and
- // discard existing one; so, no need to send it.
- return null;
- }
-
- // Leave the header field as is
- return field;
-}
-
-
-void transport::processHeader(shared_ptr <header> header)
-{
- if (header->getFieldCount() == 0)
- return;
-
- // Remove/replace fields
- for (size_t idx = header->getFieldCount() ; idx != 0 ; --idx)
- {
- shared_ptr <headerField> field = header->getFieldAt(idx - 1);
- shared_ptr <headerField> newField = processHeaderField(field);
-
- if (newField == NULL)
- header->removeField(field);
- else if (newField != field)
- header->replaceField(field, newField);
- }
-
- // Add missing header fields
- // -- Date
- if (!header->hasField(fields::DATE))
- header->Date()->setValue(datetime::now());
-
- // -- Mime-Version
- if (!header->hasField(fields::MIME_VERSION))
- header->MimeVersion()->setValue(string(SUPPORTED_MIME_VERSION));
-
- // -- Message-Id
- if (!header->hasField(fields::MESSAGE_ID))
- header->MessageId()->setValue(messageId::generateId());
-}
-
-
-static void extractMailboxes
- (mailboxList& recipients, const addressList& list)
-{
- for (size_t i = 0 ; i < list.getAddressCount() ; ++i)
- {
- shared_ptr <mailbox> mbox = dynamicCast <mailbox>(list.getAddressAt(i)->clone());
-
- if (mbox != NULL)
- recipients.appendMailbox(mbox);
- }
-}
-
-
-void transport::send(shared_ptr <vmime::message> msg, utility::progressListener* progress)
-{
- // Extract expeditor
- shared_ptr <mailbox> fromMbox =
- msg->getHeader()->findFieldValue <mailbox>(fields::FROM);
-
- if (!fromMbox)
- throw exceptions::no_expeditor();
-
- mailbox expeditor = *fromMbox;
-
- // Extract sender
- shared_ptr <mailbox> senderMbox =
- msg->getHeader()->findFieldValue <mailbox>(fields::SENDER);
-
- mailbox sender;
-
- if (!senderMbox)
- sender = expeditor;
- else
- sender = *senderMbox;
-
- // Extract recipients
- mailboxList recipients;
-
- // -- "To" field
- shared_ptr <addressList> addresses =
- msg->getHeader()->findFieldValue <addressList>(fields::TO);
-
- if (addresses)
- extractMailboxes(recipients, *addresses);
-
- // -- "Cc" field
- addresses =
- msg->getHeader()->findFieldValue <addressList>(fields::CC);
-
- if (addresses)
- extractMailboxes(recipients, *addresses);
-
- // -- "Bcc" field
- addresses =
- msg->getHeader()->findFieldValue <addressList>(fields::BCC);
-
- if (addresses)
- extractMailboxes(recipients, *addresses);
-
- // Process message header by removing fields that should be removed
- // before transmitting the message to MSA, and adding missing fields
- // which are required/recommended by the RFCs.
- shared_ptr <header> hdr = vmime::clone(msg->getHeader());
- processHeader(hdr);
-
- // To avoid cloning message body (too much overhead), use processed
- // header during the time we are generating the message to a stream.
- // Revert it back to original header after.
- struct XChangeMsgHeader
- {
- XChangeMsgHeader(shared_ptr <vmime::message> _msg,
- shared_ptr <vmime::header> _hdr)
- : msg(_msg), hdr(msg->getHeader())
- {
- // Set new header
- msg->setHeader(_hdr);
- }
-
- ~XChangeMsgHeader()
- {
- // Revert original header
- msg->setHeader(hdr);
- }
-
- private:
-
- shared_ptr <vmime::message> msg;
- shared_ptr <vmime::header> hdr;
- } headerExchanger(msg, hdr);
-
- send(msg, expeditor, recipients, progress, sender);
-}
-
-
-void transport::send
- (shared_ptr <vmime::message> msg, const mailbox& expeditor, const mailboxList& recipients,
- utility::progressListener* progress, const mailbox& sender)
-{
- // Generate the message, "stream" it and delegate the sending
- // to the generic send() function.
- std::ostringstream oss;
- utility::outputStreamAdapter ossAdapter(oss);
-
- msg->generate(ossAdapter);
-
- const string& str(oss.str());
-
- utility::inputStreamStringAdapter isAdapter(str);
-
- send(expeditor, recipients, isAdapter, str.length(), progress, sender);
-}
-
-
-transport::Type transport::getType() const
-{
- return (TYPE_TRANSPORT);
-}
-
-
-} // net
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES
-