From a530f25c79c2da9483caa6b7c0f3c17e12e379c6 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Tue, 23 Aug 2005 20:26:20 +0000 Subject: [PATCH] Renamed 'vmime::messaging' to 'vmime::net'. --- src/messaging/authHelper.cpp | 105 - src/messaging/authenticationInfos.cpp | 52 - src/messaging/authenticator.cpp | 33 - src/messaging/builtinServices.inl | 56 - src/messaging/defaultAuthenticator.cpp | 43 - src/messaging/events.cpp | 111 - src/messaging/folder.cpp | 96 - src/messaging/imap/IMAPConnection.cpp | 313 - src/messaging/imap/IMAPFolder.cpp | 1608 ------ src/messaging/imap/IMAPMessage.cpp | 859 --- src/messaging/imap/IMAPStore.cpp | 308 - src/messaging/imap/IMAPTag.cpp | 99 - src/messaging/imap/IMAPUtils.cpp | 555 -- src/messaging/maildir/maildirFolder.cpp | 1387 ----- src/messaging/maildir/maildirMessage.cpp | 505 -- src/messaging/maildir/maildirStore.cpp | 250 - src/messaging/maildir/maildirUtils.cpp | 208 - src/messaging/message.cpp | 46 - src/messaging/pop3/POP3Folder.cpp | 826 --- src/messaging/pop3/POP3Message.cpp | 213 - src/messaging/pop3/POP3Store.cpp | 630 -- src/messaging/sendmail/sendmailTransport.cpp | 222 - src/messaging/service.cpp | 70 - src/messaging/serviceFactory.cpp | 124 - src/messaging/serviceInfos.cpp | 150 - src/messaging/session.cpp | 126 - src/messaging/simpleAuthenticator.cpp | 69 - src/messaging/smtp/SMTPTransport.cpp | 503 -- src/messaging/transport.cpp | 116 - vmime/messaging/authHelper.hpp | 38 - vmime/messaging/authenticationInfos.hpp | 64 - vmime/messaging/authenticator.hpp | 54 - vmime/messaging/defaultAuthenticator.hpp | 60 - vmime/messaging/events.hpp | 229 - vmime/messaging/folder.hpp | 379 -- vmime/messaging/imap/IMAPConnection.hpp | 116 - vmime/messaging/imap/IMAPFolder.hpp | 158 - vmime/messaging/imap/IMAPMessage.hpp | 111 - vmime/messaging/imap/IMAPParser.hpp | 5082 ----------------- vmime/messaging/imap/IMAPStore.hpp | 137 - vmime/messaging/imap/IMAPTag.hpp | 66 - vmime/messaging/imap/IMAPUtils.hpp | 68 - vmime/messaging/maildir/maildirFolder.hpp | 178 - vmime/messaging/maildir/maildirMessage.hpp | 103 - vmime/messaging/maildir/maildirStore.hpp | 114 - vmime/messaging/maildir/maildirUtils.hpp | 160 - vmime/messaging/message.hpp | 292 - vmime/messaging/pop3/POP3Folder.hpp | 148 - vmime/messaging/pop3/POP3Message.hpp | 98 - vmime/messaging/pop3/POP3Store.hpp | 138 - .../messaging/sendmail/sendmailTransport.hpp | 103 - vmime/messaging/service.hpp | 161 - vmime/messaging/serviceFactory.hpp | 188 - vmime/messaging/serviceInfos.hpp | 228 - vmime/messaging/session.hpp | 135 - vmime/messaging/simpleAuthenticator.hpp | 62 - vmime/messaging/smtp/SMTPTransport.hpp | 113 - vmime/messaging/socket.hpp | 112 - vmime/messaging/store.hpp | 102 - vmime/messaging/timeoutHandler.hpp | 77 - vmime/messaging/transport.hpp | 75 - 61 files changed, 18832 deletions(-) delete mode 100644 src/messaging/authHelper.cpp delete mode 100644 src/messaging/authenticationInfos.cpp delete mode 100644 src/messaging/authenticator.cpp delete mode 100644 src/messaging/builtinServices.inl delete mode 100644 src/messaging/defaultAuthenticator.cpp delete mode 100644 src/messaging/events.cpp delete mode 100644 src/messaging/folder.cpp delete mode 100644 src/messaging/imap/IMAPConnection.cpp delete mode 100644 src/messaging/imap/IMAPFolder.cpp delete mode 100644 src/messaging/imap/IMAPMessage.cpp delete mode 100644 src/messaging/imap/IMAPStore.cpp delete mode 100644 src/messaging/imap/IMAPTag.cpp delete mode 100644 src/messaging/imap/IMAPUtils.cpp delete mode 100644 src/messaging/maildir/maildirFolder.cpp delete mode 100644 src/messaging/maildir/maildirMessage.cpp delete mode 100644 src/messaging/maildir/maildirStore.cpp delete mode 100644 src/messaging/maildir/maildirUtils.cpp delete mode 100644 src/messaging/message.cpp delete mode 100644 src/messaging/pop3/POP3Folder.cpp delete mode 100644 src/messaging/pop3/POP3Message.cpp delete mode 100644 src/messaging/pop3/POP3Store.cpp delete mode 100644 src/messaging/sendmail/sendmailTransport.cpp delete mode 100644 src/messaging/service.cpp delete mode 100644 src/messaging/serviceFactory.cpp delete mode 100644 src/messaging/serviceInfos.cpp delete mode 100644 src/messaging/session.cpp delete mode 100644 src/messaging/simpleAuthenticator.cpp delete mode 100644 src/messaging/smtp/SMTPTransport.cpp delete mode 100644 src/messaging/transport.cpp delete mode 100644 vmime/messaging/authHelper.hpp delete mode 100644 vmime/messaging/authenticationInfos.hpp delete mode 100644 vmime/messaging/authenticator.hpp delete mode 100644 vmime/messaging/defaultAuthenticator.hpp delete mode 100644 vmime/messaging/events.hpp delete mode 100644 vmime/messaging/folder.hpp delete mode 100644 vmime/messaging/imap/IMAPConnection.hpp delete mode 100644 vmime/messaging/imap/IMAPFolder.hpp delete mode 100644 vmime/messaging/imap/IMAPMessage.hpp delete mode 100644 vmime/messaging/imap/IMAPParser.hpp delete mode 100644 vmime/messaging/imap/IMAPStore.hpp delete mode 100644 vmime/messaging/imap/IMAPTag.hpp delete mode 100644 vmime/messaging/imap/IMAPUtils.hpp delete mode 100644 vmime/messaging/maildir/maildirFolder.hpp delete mode 100644 vmime/messaging/maildir/maildirMessage.hpp delete mode 100644 vmime/messaging/maildir/maildirStore.hpp delete mode 100644 vmime/messaging/maildir/maildirUtils.hpp delete mode 100644 vmime/messaging/message.hpp delete mode 100644 vmime/messaging/pop3/POP3Folder.hpp delete mode 100644 vmime/messaging/pop3/POP3Message.hpp delete mode 100644 vmime/messaging/pop3/POP3Store.hpp delete mode 100644 vmime/messaging/sendmail/sendmailTransport.hpp delete mode 100644 vmime/messaging/service.hpp delete mode 100644 vmime/messaging/serviceFactory.hpp delete mode 100644 vmime/messaging/serviceInfos.hpp delete mode 100644 vmime/messaging/session.hpp delete mode 100644 vmime/messaging/simpleAuthenticator.hpp delete mode 100644 vmime/messaging/smtp/SMTPTransport.hpp delete mode 100644 vmime/messaging/socket.hpp delete mode 100644 vmime/messaging/store.hpp delete mode 100644 vmime/messaging/timeoutHandler.hpp delete mode 100644 vmime/messaging/transport.hpp diff --git a/src/messaging/authHelper.cpp b/src/messaging/authHelper.cpp deleted file mode 100644 index 9da19043..00000000 --- a/src/messaging/authHelper.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/authHelper.hpp" - -#include "vmime/config.hpp" -#include "vmime/utility/md5.hpp" - - -namespace vmime { -namespace messaging { - - -// -// This code is based on the Sample Code published in the Appendix of -// the RFC-2104: "HMAC: Keyed-Hashing for Message Authentication". -// - -void hmac_md5(const string& text, const string& key, string& hexDigest) -{ - vmime_uint8 digest[16]; - - unsigned char ipad[65]; // inner padding - key XORd with ipad - unsigned char opad[65]; // outer padding - key XORd with opad - - unsigned char tkey[16]; - int tkeyLen; - - // If key is longer than 64 bytes reset it to key = MD5(key) - if (key.length() > 64) - { - utility::md5 keyMD5; - keyMD5.update(reinterpret_cast (key.data()), key.length()); - - std::copy(keyMD5.hash(), keyMD5.hash() + 16, tkey); - tkeyLen = 16; - } - else - { - std::copy(key.begin(), key.end(), tkey); - tkeyLen = key.length(); - } - - // - // the HMAC_MD5 transform looks like: - // - // MD5(K XOR opad, MD5(K XOR ipad, text)) - // - // where K is an n byte key - // ipad is the byte 0x36 repeated 64 times - // - // opad is the byte 0x5c repeated 64 times - // and text is the data being protected - // - - // Start out by storing key in pads - std::fill(ipad, ipad + sizeof(ipad), 0); - std::fill(opad, opad + sizeof(opad), 0); - - std::copy(tkey, tkey + tkeyLen, ipad); - std::copy(tkey, tkey + tkeyLen, opad); - - // XOR key with ipad and opad values - for (int i = 0 ; i < 64 ; ++i) - { - ipad[i] ^= 0x36; - opad[i] ^= 0x5c; - } - - // Perform inner MD5 - utility::md5 innerMD5; - innerMD5.update(ipad, 64); - innerMD5.update(text); - - std::copy(innerMD5.hash(), innerMD5.hash() + 16, digest); - - // Perform outer MD5 - utility::md5 outerMD5; - outerMD5.update(opad, 64); - outerMD5.update(digest, 16); - - //std::copy(outerMD5.hash(), outerMD5.hash() + 16, digest); - - hexDigest = outerMD5.hex(); -} - - -} // messaging -} // vmime diff --git a/src/messaging/authenticationInfos.cpp b/src/messaging/authenticationInfos.cpp deleted file mode 100644 index 0a7c3433..00000000 --- a/src/messaging/authenticationInfos.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/authenticationInfos.hpp" - - -namespace vmime { -namespace messaging { - - -authenticationInfos::authenticationInfos(const string& username, const string& password) - : m_username(username), m_password(password) -{ -} - - -authenticationInfos::authenticationInfos(const authenticationInfos& infos) - : object(), m_username(infos.m_username), m_password(infos.m_password) -{ -} - - -const string& authenticationInfos::getUsername() const -{ - return (m_username); -} - - -const string& authenticationInfos::getPassword() const -{ - return (m_password); -} - - -} // messaging -} // vmime diff --git a/src/messaging/authenticator.cpp b/src/messaging/authenticator.cpp deleted file mode 100644 index d7d9e372..00000000 --- a/src/messaging/authenticator.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/authenticator.hpp" - - -namespace vmime { -namespace messaging { - - -authenticator::~authenticator() -{ -} - - -} // messaging -} // vmime diff --git a/src/messaging/builtinServices.inl b/src/messaging/builtinServices.inl deleted file mode 100644 index d1b63a30..00000000 --- a/src/messaging/builtinServices.inl +++ /dev/null @@ -1,56 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_BUILDING_DOC - - -#define REGISTER_SERVICE(p_class, p_name) \ - vmime::messaging::service::initializer p_name(#p_name) - - -#if VMIME_BUILTIN_MESSAGING_PROTO_POP3 - #include "vmime/messaging/pop3/POP3Store.hpp" - REGISTER_SERVICE(pop3::POP3Store, pop3); -#endif - - -#if VMIME_BUILTIN_MESSAGING_PROTO_SMTP - #include "vmime/messaging/smtp/SMTPTransport.hpp" - REGISTER_SERVICE(smtp::SMTPTransport, smtp); -#endif - - -#if VMIME_BUILTIN_MESSAGING_PROTO_IMAP - #include "vmime/messaging/imap/IMAPStore.hpp" - REGISTER_SERVICE(imap::IMAPStore, imap); -#endif - - -#if VMIME_BUILTIN_MESSAGING_PROTO_MAILDIR - #include "vmime/messaging/maildir/maildirStore.hpp" - REGISTER_SERVICE(maildir::maildirStore, maildir); -#endif - -#if VMIME_BUILTIN_MESSAGING_PROTO_SENDMAIL - #include "vmime/messaging/sendmail/sendmailTransport.hpp" - REGISTER_SERVICE(sendmail::sendmailTransport, sendmail); -#endif - - -#endif // VMIME_BUILDING_DOC diff --git a/src/messaging/defaultAuthenticator.cpp b/src/messaging/defaultAuthenticator.cpp deleted file mode 100644 index 373d3c1d..00000000 --- a/src/messaging/defaultAuthenticator.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/defaultAuthenticator.hpp" -#include "vmime/messaging/session.hpp" - - -namespace vmime { -namespace messaging { - - -defaultAuthenticator::defaultAuthenticator(weak_ref sess, const string& prefix) - : m_session(sess), m_prefix(prefix) -{ -} - - -const authenticationInfos defaultAuthenticator::requestAuthInfos() const -{ - return (authenticationInfos - (m_session->getProperties()[m_prefix + "auth.username"], - m_session->getProperties()[m_prefix + "auth.password"])); -} - - -} // messaging -} // vmime diff --git a/src/messaging/events.cpp b/src/messaging/events.cpp deleted file mode 100644 index 13171832..00000000 --- a/src/messaging/events.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/events.hpp" -#include "vmime/messaging/folder.hpp" - -#include - - -namespace vmime { -namespace messaging { -namespace events { - - -// -// messageCountEvent -// - -messageCountEvent::messageCountEvent - (ref folder, const Types type, const std::vector & nums) - : m_folder(folder), m_type(type) -{ - m_nums.resize(nums.size()); - std::copy(nums.begin(), nums.end(), m_nums.begin()); -} - - -ref messageCountEvent::getFolder() const { return (m_folder); } -const messageCountEvent::Types messageCountEvent::getType() const { return (m_type); } -const std::vector & messageCountEvent::getNumbers() const { return (m_nums); } - - -void messageCountEvent::dispatch(messageCountListener* listener) const -{ - if (m_type == TYPE_ADDED) - listener->messagesAdded(*this); - else - listener->messagesRemoved(*this); -} - - -// -// messageChangedEvent -// - -messageChangedEvent::messageChangedEvent - (ref folder, const Types type, const std::vector & nums) - : m_folder(folder), m_type(type) -{ - m_nums.resize(nums.size()); - std::copy(nums.begin(), nums.end(), m_nums.begin()); -} - - -ref messageChangedEvent::getFolder() const { return (m_folder); } -const messageChangedEvent::Types messageChangedEvent::getType() const { return (m_type); } -const std::vector & messageChangedEvent::getNumbers() const { return (m_nums); } - - -void messageChangedEvent::dispatch(messageChangedListener* listener) const -{ - listener->messageChanged(*this); -} - - -// -// folderEvent -// - -folderEvent::folderEvent - (ref folder, const Types type, - const utility::path& oldPath, const utility::path& newPath) - : m_folder(folder), m_type(type), m_oldPath(oldPath), m_newPath(newPath) -{ -} - - -ref folderEvent::getFolder() const { return (m_folder); } -const folderEvent::Types folderEvent::getType() const { return (m_type); } - - -void folderEvent::dispatch(folderListener* listener) const -{ - switch (m_type) - { - case TYPE_CREATED: listener->folderCreated(*this); break; - case TYPE_RENAMED: listener->folderRenamed(*this); break; - case TYPE_DELETED: listener->folderDeleted(*this); break; - } -} - - -} // events -} // messaging -} // vmime diff --git a/src/messaging/folder.cpp b/src/messaging/folder.cpp deleted file mode 100644 index 8b47e639..00000000 --- a/src/messaging/folder.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/folder.hpp" - -#include - - -namespace vmime { -namespace messaging { - - -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(const events::messageChangedEvent& event) -{ - for (std::list ::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(const events::messageCountEvent& event) -{ - for (std::list ::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(const events::folderEvent& event) -{ - for (std::list ::iterator - it = m_folderListeners.begin() ; it != m_folderListeners.end() ; ++it) - { - event.dispatch(*it); - } -} - - -} // messaging -} // vmime diff --git a/src/messaging/imap/IMAPConnection.cpp b/src/messaging/imap/IMAPConnection.cpp deleted file mode 100644 index 5b82c113..00000000 --- a/src/messaging/imap/IMAPConnection.cpp +++ /dev/null @@ -1,313 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/imap/IMAPTag.hpp" -#include "vmime/messaging/imap/IMAPConnection.hpp" -#include "vmime/messaging/imap/IMAPUtils.hpp" -#include "vmime/messaging/imap/IMAPStore.hpp" - -#include "vmime/exception.hpp" -#include "vmime/platformDependant.hpp" - -#include - - -// Helpers for service properties -#define GET_PROPERTY(type, prop) \ - (m_store->getInfos().getPropertyValue (getSession(), \ - dynamic_cast (m_store->getInfos()).getProperties().prop)) -#define HAS_PROPERTY(prop) \ - (m_store->getInfos().hasProperty(getSession(), \ - dynamic_cast (m_store->getInfos()).getProperties().prop)) - - -namespace vmime { -namespace messaging { -namespace imap { - - -IMAPConnection::IMAPConnection(weak_ref store, ref 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) -{ -} - - -IMAPConnection::~IMAPConnection() -{ - if (isConnected()) - disconnect(); - else if (m_socket) - internalDisconnect(); -} - - -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); - - // Create the time-out handler - if (HAS_PROPERTY(PROPERTY_TIMEOUT_FACTORY)) - { - timeoutHandlerFactory* tof = platformDependant::getHandler()-> - getTimeoutHandlerFactory(GET_PROPERTY(string, PROPERTY_TIMEOUT_FACTORY)); - - m_timeoutHandler = tof->create(); - } - - // Create and connect the socket - socketFactory* sf = platformDependant::getHandler()-> - getSocketFactory(GET_PROPERTY(string, PROPERTY_SERVER_SOCKETFACTORY)); - - m_socket = sf->create(); - m_socket->connect(address, port); - - - m_tag = vmime::create (); - m_parser = vmime::create (m_tag, m_socket, m_timeoutHandler); - - - setState(STATE_NON_AUTHENTICATED); - - - // Connection greeting - // - // eg: C: - // --- S: * OK mydomain.org IMAP4rev1 v12.256 server ready - - utility::auto_ptr greet(m_parser->readGreeting()); - - if (greet->resp_cond_bye()) - { - internalDisconnect(); - throw exceptions::connection_greeting_error(m_parser->lastLine()); - } - else if (greet->resp_cond_auth()->condition() != IMAPParser::resp_cond_auth::PREAUTH) - { - const authenticationInfos auth = m_auth->requestAuthInfos(); - - // TODO: other authentication methods - - send(true, "LOGIN " + IMAPUtils::quoteString(auth.getUsername()) - + " " + IMAPUtils::quoteString(auth.getPassword()), true); - - utility::auto_ptr resp(m_parser->readResponse()); - - if (resp->isBad()) - { - internalDisconnect(); - throw exceptions::command_error("LOGIN", m_parser->lastLine()); - } - else if (resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - internalDisconnect(); - throw exceptions::authentication_error(m_parser->lastLine()); - } - } - - // Get the hierarchy separator character - initHierarchySeparator(); - - // Switch to state "Authenticated" - setState(STATE_AUTHENTICATED); -} - - -const bool IMAPConnection::isConnected() const -{ - return (m_socket && m_socket->isConnected() && - (m_state == STATE_AUTHENTICATED || m_state == STATE_SELECTED)); -} - - -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; -} - - -void IMAPConnection::initHierarchySeparator() -{ - send(true, "LIST \"\" \"\"", true); - - vmime::utility::auto_ptr 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", m_parser->lastLine(), "bad response"); - } - - const std::vector & respDataList = - resp->continue_req_or_response_data(); - - if (respDataList.size() < 1 || respDataList[0]->response_data() == NULL) - { - internalDisconnect(); - throw exceptions::command_error("LIST", m_parser->lastLine(), "unexpected response"); - } - - const IMAPParser::mailbox_data* mailboxData = - static_cast (respDataList[0]->response_data())-> - mailbox_data(); - - if (mailboxData == NULL || mailboxData->type() != IMAPParser::mailbox_data::LIST) - { - internalDisconnect(); - throw exceptions::command_error("LIST", m_parser->lastLine(), "invalid type"); - } - - if (mailboxData->mailbox_list()->quoted_char() == '\0') - { - internalDisconnect(); - throw exceptions::command_error("LIST", m_parser->lastLine(), "no hierarchy separator"); - } - - m_hierarchySeparator = mailboxData->mailbox_list()->quoted_char(); -} - - -void IMAPConnection::send(bool tag, const string& what, bool end) -{ -#if VMIME_DEBUG - std::ostringstream oss; - - if (tag) - { - ++(*m_tag); - - oss << string(*m_tag); - oss << " "; - } - - oss << what; - - if (end) - oss << "\r\n"; - - m_socket->send(oss.str()); -#else - if (tag) - { - ++(*m_tag); - - m_socket->send(*m_tag); - m_socket->send(" "); - } - - m_socket->send(what); - - if (end) - { - m_socket->send("\r\n"); - } -#endif -} - - -void IMAPConnection::sendRaw(const char* buffer, const int count) -{ - m_socket->sendRaw(buffer, count); -} - - -IMAPParser::response* IMAPConnection::readResponse(IMAPParser::literalHandler* lh) -{ - return (m_parser->readResponse(lh)); -} - - -const IMAPConnection::ProtocolStates IMAPConnection::state() const -{ - return (m_state); -} - - -void IMAPConnection::setState(const ProtocolStates state) -{ - m_state = state; -} - -const char IMAPConnection::hierarchySeparator() const -{ - return (m_hierarchySeparator); -} - - -ref IMAPConnection::getTag() const -{ - return (m_tag); -} - - -ref IMAPConnection::getParser() const -{ - return (m_parser); -} - - -weak_ref IMAPConnection::getStore() const -{ - return (m_store); -} - - -weak_ref IMAPConnection::getStore() -{ - return (m_store); -} - - -ref IMAPConnection::getSession() -{ - return (m_store->getSession()); -} - - -} // imap -} // messaging -} // vmime diff --git a/src/messaging/imap/IMAPFolder.cpp b/src/messaging/imap/IMAPFolder.cpp deleted file mode 100644 index ca09fa47..00000000 --- a/src/messaging/imap/IMAPFolder.cpp +++ /dev/null @@ -1,1608 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/imap/IMAPFolder.hpp" - -#include "vmime/messaging/imap/IMAPStore.hpp" -#include "vmime/messaging/imap/IMAPParser.hpp" -#include "vmime/messaging/imap/IMAPMessage.hpp" -#include "vmime/messaging/imap/IMAPUtils.hpp" -#include "vmime/messaging/imap/IMAPConnection.hpp" - -#include "vmime/message.hpp" - -#include "vmime/exception.hpp" -#include "vmime/utility/smartPtr.hpp" - -#include -#include - - -namespace vmime { -namespace messaging { -namespace imap { - - -IMAPFolder::IMAPFolder(const folder::path& path, IMAPStore* store, const int type, const int flags) - : m_store(store), m_connection(m_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), m_messageCount(0), m_uidValidity(0) -{ - m_store->registerFolder(this); -} - - -IMAPFolder::~IMAPFolder() -{ - if (m_store) - { - if (m_open) - close(false); - - m_store->unregisterFolder(this); - } - else if (m_open) - { - m_connection = NULL; - onClose(); - } -} - - -const int IMAPFolder::getMode() const -{ - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - return (m_mode); -} - - -const 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); - } -} - - -const 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) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - - // Open a connection for this folder - ref connection = - vmime::create (m_store, m_store->oneTimeAuthenticator()); - - 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())); - - connection->send(true, oss.str(), true); - - // Read the response - utility::auto_ptr 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", - connection->getParser()->lastLine(), "bad response"); - } - - const std::vector & respDataList = - resp->continue_req_or_response_data(); - - for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("SELECT", - connection->getParser()->lastLine(), "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::UIDVALIDITY: - - m_uidValidity = code->nz_number()->value(); - 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; - } - case IMAPParser::mailbox_data::EXISTS: - { - m_messageCount = responseData->mailbox_data()->number()->value(); - break; - } - case IMAPParser::mailbox_data::RECENT: - { - // TODO - break; - } - - } - } - } - - // 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) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - ref 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->connection(); - - m_open = false; - m_mode = -1; - - m_uidValidity = 0; - - onClose(); -} - - -void IMAPFolder::onClose() -{ - for (std::vector ::iterator it = m_messages.begin() ; - it != m_messages.end() ; ++it) - { - (*it)->onFolderClosed(); - } - - m_messages.clear(); -} - - -void IMAPFolder::create(const int type) -{ - if (!m_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 (!m_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); - - - utility::auto_ptr 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", - m_connection->getParser()->lastLine(), "bad response"); - } - - // Notify folder created - events::folderEvent event - (thisRef().dynamicCast (), - events::folderEvent::TYPE_CREATED, m_path, m_path); - - notifyFolder(event); -} - - -const bool IMAPFolder::exists() -{ - if (!isOpen() && !m_store) - throw exceptions::illegal_state("Store disconnected"); - - return (testExistAndGetType() != TYPE_UNDEFINED); -} - - -const 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); - - - utility::auto_ptr 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", - m_connection->getParser()->lastLine(), "bad response"); - } - - // Check whether the result mailbox list contains this folder - const std::vector & respDataList = - resp->continue_req_or_response_data(); - - for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("LIST", - m_connection->getParser()->lastLine(), "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); -} - - -const bool IMAPFolder::isOpen() const -{ - return (m_open); -} - - -ref IMAPFolder::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 vmime::create (this, num); -} - - -std::vector > IMAPFolder::getMessages(const int from, const int to) -{ - const int messageCount = getMessageCount(); - const int to2 = (to == -1 ? messageCount : to); - - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - else if (to2 < from || from < 1 || to2 < 1 || from > messageCount || to2 > messageCount) - throw exceptions::message_not_found(); - - std::vector > v; - - for (int i = from ; i <= to2 ; ++i) - v.push_back(vmime::create (this, i)); - - return (v); -} - - -std::vector > IMAPFolder::getMessages(const std::vector & nums) -{ - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - std::vector > v; - - for (std::vector ::const_iterator it = nums.begin() ; it != nums.end() ; ++it) - v.push_back(vmime::create (this, *it)); - - return (v); -} - - -const int IMAPFolder::getMessageCount() -{ - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - return (m_messageCount); -} - - -ref IMAPFolder::getFolder(const folder::path::component& name) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - - return vmime::create (m_path / name, m_store); -} - - -std::vector > IMAPFolder::getFolders(const bool recursive) -{ - if (!isOpen() && !m_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); - - - utility::auto_ptr 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", m_connection->getParser()->lastLine(), "bad response"); - } - - const std::vector & respDataList = - resp->continue_req_or_response_data(); - - - std::vector > v; - - for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("LIST", - m_connection->getParser()->lastLine(), "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(vmime::create (path, m_store, - IMAPUtils::folderTypeFromFlags(mailbox_flag_list), - IMAPUtils::folderFlagsFromFlags(mailbox_flag_list))); - } - } - - return (v); -} - - -void IMAPFolder::fetchMessages(std::vector >& msg, const int options, - utility::progressionListener* progress) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - const int total = msg.size(); - int current = 0; - - if (progress) - progress->start(total); - - for (std::vector >::iterator it = msg.begin() ; - it != msg.end() ; ++it) - { - (*it).dynamicCast ()->fetch(this, options); - - if (progress) - progress->progress(++current, total); - } - - if (progress) - progress->stop(total); -} - - -void IMAPFolder::fetchMessage(ref msg, const int options) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - msg.dynamicCast ()->fetch(this, options); -} - - -const int IMAPFolder::getFetchCapabilities() const -{ - return (FETCH_ENVELOPE | FETCH_CONTENT_INFO | FETCH_STRUCTURE | - FETCH_FLAGS | FETCH_SIZE | FETCH_FULL_HEADER | FETCH_UID | - FETCH_IMPORTANCE); -} - - -ref IMAPFolder::getParent() -{ - if (m_path.isEmpty()) - return NULL; - else - return vmime::create (m_path.getParent(), m_store); -} - - -weak_ref IMAPFolder::getStore() const -{ - return (m_store); -} - - -weak_ref IMAPFolder::getStore() -{ - return (m_store); -} - - -void IMAPFolder::registerMessage(IMAPMessage* msg) -{ - m_messages.push_back(msg); -} - - -void IMAPFolder::unregisterMessage(IMAPMessage* msg) -{ - std::vector ::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 = NULL; -} - - -void IMAPFolder::deleteMessage(const int num) -{ - if (!m_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 << "STORE " << num << " +FLAGS.SILENT (\\Deleted)"; - - // Send the request - m_connection->send(true, command.str(), true); - - // Get the response - utility::auto_ptr 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", - m_connection->getParser()->lastLine(), "bad response"); - } - - // Update local flags - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if ((*it)->getNumber() == num && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags |= message::FLAG_DELETED; - } - } - - // Notify message flags changed - std::vector nums; - nums.push_back(num); - - events::messageChangedEvent event - (thisRef().dynamicCast (), - events::messageChangedEvent::TYPE_FLAGS, nums); - - notifyMessageChanged(event); -} - - -void IMAPFolder::deleteMessages(const int from, const int to) -{ - if (from < 1 || (to < from && to != -1)) - throw exceptions::invalid_argument(); - - if (!m_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 << "STORE " << from << ":"; - - if (to == -1) command << m_messageCount; - else command << to; - - command << " +FLAGS.SILENT (\\Deleted)"; - - // Send the request - m_connection->send(true, command.str(), true); - - // Get the response - utility::auto_ptr 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", - m_connection->getParser()->lastLine(), "bad response"); - } - - // Update local flags - const int to2 = (to == -1) ? m_messageCount : to; - const int count = to - from + 1; - - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags |= message::FLAG_DELETED; - } - } - - // Notify message flags changed - std::vector nums; - nums.resize(count); - - for (int i = from, j = 0 ; i <= to2 ; ++i, ++j) - nums[j] = i; - - events::messageChangedEvent event - (thisRef().dynamicCast (), - events::messageChangedEvent::TYPE_FLAGS, nums); - - notifyMessageChanged(event); -} - - -void IMAPFolder::deleteMessages(const std::vector & nums) -{ - if (nums.empty()) - throw exceptions::invalid_argument(); - - if (!m_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"); - - // Sort the list of message numbers - std::vector list; - - list.resize(nums.size()); - std::copy(nums.begin(), nums.end(), list.begin()); - - std::sort(list.begin(), list.end()); - - // Build the request text - std::ostringstream command; - command << "STORE "; - command << IMAPUtils::listToSet(list, m_messageCount, true); - command << " +FLAGS.SILENT (\\Deleted)"; - - // Send the request - m_connection->send(true, command.str(), true); - - // Get the response - utility::auto_ptr 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", - m_connection->getParser()->lastLine(), "bad response"); - } - - // Update local flags - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if (std::binary_search(list.begin(), list.end(), (*it)->getNumber())) - { - if ((*it)->m_flags != message::FLAG_UNDEFINED) - (*it)->m_flags |= message::FLAG_DELETED; - } - } - - // Notify message flags changed - events::messageChangedEvent event - (thisRef().dynamicCast (), - events::messageChangedEvent::TYPE_FLAGS, list); - - notifyMessageChanged(event); -} - - -void IMAPFolder::setMessageFlags(const int from, const int to, const int flags, const int mode) -{ - if (from < 1 || (to < from && to != -1)) - throw exceptions::invalid_argument(); - - if (!m_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"); - - std::ostringstream oss; - - if (to == -1) - oss << from << ":*"; - else - oss << from << ":" << to; - - setMessageFlags(oss.str(), flags, mode); - - // Update local flags - const int to2 = (to == -1) ? m_messageCount : to; - const int count = to - from + 1; - - switch (mode) - { - case message::FLAG_MODE_ADD: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags |= flags; - } - } - - break; - } - case message::FLAG_MODE_REMOVE: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags &= ~flags; - } - } - - break; - } - default: - case message::FLAG_MODE_SET: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags = flags; - } - } - - break; - } - - } - - // Notify message flags changed - std::vector nums; - nums.resize(count); - - for (int i = from, j = 0 ; i <= to2 ; ++i, ++j) - nums[j] = i; - - events::messageChangedEvent event - (thisRef().dynamicCast (), - events::messageChangedEvent::TYPE_FLAGS, nums); - - notifyMessageChanged(event); -} - - -void IMAPFolder::setMessageFlags(const std::vector & nums, const int flags, const int mode) -{ - if (!m_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"); - - // Sort the list of message numbers - std::vector list; - - list.resize(nums.size()); - std::copy(nums.begin(), nums.end(), list.begin()); - - std::sort(list.begin(), list.end()); - - // Delegates call - setMessageFlags(IMAPUtils::listToSet(list, m_messageCount, true), flags, mode); - - // Update local flags - switch (mode) - { - case message::FLAG_MODE_ADD: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags |= flags; - } - } - - break; - } - case message::FLAG_MODE_REMOVE: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags &= ~flags; - } - } - - break; - } - default: - case message::FLAG_MODE_SET: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags = flags; - } - } - - break; - } - - } - - // Notify message flags changed - events::messageChangedEvent event - (thisRef().dynamicCast (), - events::messageChangedEvent::TYPE_FLAGS, nums); - - notifyMessageChanged(event); -} - - -void IMAPFolder::setMessageFlags(const string& set, const int flags, const int mode) -{ - // Build the request text - std::ostringstream command; - command << "STORE " << set; - - switch (mode) - { - case message::FLAG_MODE_ADD: command << " +FLAGS.SILENT "; break; - case message::FLAG_MODE_REMOVE: command << " -FLAGS.SILENT "; break; - default: - case message::FLAG_MODE_SET: command << " FLAGS.SILENT "; 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 - utility::auto_ptr 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", - m_connection->getParser()->lastLine(), "bad response"); - } - } -} - - -void IMAPFolder::addMessage(ref msg, const int flags, - vmime::datetime* date, utility::progressionListener* progress) -{ - std::ostringstream oss; - utility::outputStreamAdapter ossAdapter(oss); - - msg->generate(ossAdapter); - - const std::string& str = oss.str(); - utility::inputStreamStringAdapter strAdapter(str); - - addMessage(strAdapter, str.length(), flags, date, progress); -} - - -void IMAPFolder::addMessage(utility::inputStream& is, const int size, const int flags, - vmime::datetime* date, utility::progressionListener* progress) -{ - if (!m_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 << "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 - utility::auto_ptr resp(m_connection->readResponse()); - - bool ok = false; - const std::vector & respList - = resp->continue_req_or_response_data(); - - for (std::vector ::const_iterator - it = respList.begin() ; !ok && (it != respList.end()) ; ++it) - { - if ((*it)->continue_req()) - ok = true; - } - - if (!ok) - { - throw exceptions::command_error("APPEND", - m_connection->getParser()->lastLine(), "bad response"); - } - - // Send message data - const int total = size; - int current = 0; - - if (progress) - progress->start(total); - - char buffer[65536]; - - while (!is.eof()) - { - // Read some data from the input stream - const int read = is.read(buffer, sizeof(buffer)); - current += read; - - // Put read data into socket output stream - m_connection->sendRaw(buffer, read); - - // Notify progression - if (progress) - progress->progress(current, total); - } - - m_connection->send(false, "", true); - - if (progress) - progress->stop(total); - - // Get the response - utility::auto_ptr 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", - m_connection->getParser()->lastLine(), "bad response"); - } - - // Notify message added - std::vector nums; - nums.push_back(m_messageCount + 1); - - events::messageCountEvent event - (thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - m_messageCount++; - notifyMessageCount(event); - - // Notify folders with the same path - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == m_path) - { - events::messageCountEvent event - ((*it)->thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - (*it)->m_messageCount++; - (*it)->notifyMessageCount(event); - } - } -} - - -void IMAPFolder::expunge() -{ - if (!m_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 - utility::auto_ptr 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", - m_connection->getParser()->lastLine(), "bad response"); - } - - // Update the numbering of the messages - const std::vector & respDataList = - resp->continue_req_or_response_data(); - - std::vector nums; - - for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("EXPUNGE", - m_connection->getParser()->lastLine(), "invalid response"); - } - - const IMAPParser::message_data* messageData = - (*it)->response_data()->message_data(); - - // We are only interested in responses of type "EXPUNGE" - if (messageData == NULL || - messageData->type() != IMAPParser::message_data::EXPUNGE) - { - continue; - } - - const int number = messageData->number(); - - nums.push_back(number); - - for (std::vector ::iterator jt = - m_messages.begin() ; jt != m_messages.end() ; ++jt) - { - if ((*jt)->m_num == number) - (*jt)->m_expunged = true; - else if ((*jt)->m_num > number) - (*jt)->m_num--; - } - } - - m_messageCount -= nums.size(); - - // Notify message expunged - events::messageCountEvent event - (thisRef().dynamicCast (), - events::messageCountEvent::TYPE_REMOVED, nums); - - notifyMessageCount(event); - - // Notify folders with the same path - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == m_path) - { - (*it)->m_messageCount = m_messageCount; - - events::messageCountEvent event - ((*it)->thisRef().dynamicCast (), - events::messageCountEvent::TYPE_REMOVED, nums); - - (*it)->notifyMessageCount(event); - } - } -} - - -void IMAPFolder::rename(const folder::path& newPath) -{ - if (!m_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 (!m_store->isValidFolderName(newPath.getLastComponent())) - throw exceptions::invalid_folder_name(); - - // Build the request text - std::ostringstream command; - 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 - utility::auto_ptr 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", - m_connection->getParser()->lastLine(), "bad response"); - } - - // Notify folder renamed - folder::path oldPath(m_path); - - m_path = newPath; - m_name = newPath.getLastComponent(); - - events::folderEvent event - (thisRef().dynamicCast (), - events::folderEvent::TYPE_RENAMED, oldPath, newPath); - - notifyFolder(event); - - // Notify folders with the same path and sub-folders - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == oldPath) - { - (*it)->m_path = newPath; - (*it)->m_name = newPath.getLastComponent(); - - events::folderEvent event - ((*it)->thisRef().dynamicCast (), - 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); - - events::folderEvent event - ((*it)->thisRef().dynamicCast (), - events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path); - - (*it)->notifyFolder(event); - } - } -} - - -void IMAPFolder::copyMessage(const folder::path& dest, const int num) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - // Construct set - std::ostringstream set; - set << num; - - // Delegate message copy - copyMessages(set.str(), dest); - - // Notify message count changed - std::vector nums; - nums.push_back(num); - - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) - { - if ((*it)->getFullPath() == dest) - { - events::messageCountEvent event - ((*it)->thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - (*it)->m_messageCount++; - (*it)->notifyMessageCount(event); - } - } -} - - -void IMAPFolder::copyMessages(const folder::path& dest, const int from, const int to) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - else if (from < 1 || (to < from && to != -1)) - throw exceptions::invalid_argument(); - - // Construct set - std::ostringstream set; - - if (to == -1) - set << from << ":*"; - else - set << from << ":" << to; - - // Delegate message copy - copyMessages(set.str(), dest); - - // Notify message count changed - const int to2 = (to == -1) ? m_messageCount : to; - const int count = to - from + 1; - - std::vector nums; - nums.resize(count); - - for (int i = from, j = 0 ; i <= to2 ; ++i, ++j) - nums[j] = i; - - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) - { - if ((*it)->getFullPath() == dest) - { - events::messageCountEvent event - ((*it)->thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - (*it)->m_messageCount += count; - (*it)->notifyMessageCount(event); - } - } -} - - -void IMAPFolder::copyMessages(const folder::path& dest, const std::vector & nums) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - // Delegate message copy - copyMessages(IMAPUtils::listToSet(nums, m_messageCount), dest); - - // Notify message count changed - const int count = nums.size(); - - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) - { - if ((*it)->getFullPath() == dest) - { - events::messageCountEvent event - ((*it)->thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - (*it)->m_messageCount += count; - (*it)->notifyMessageCount(event); - } - } -} - - -void IMAPFolder::copyMessages(const string& set, const folder::path& dest) -{ - // Build the request text - std::ostringstream command; - command << "COPY " << set << " "; - command << IMAPUtils::quoteString(IMAPUtils::pathToString - (m_connection->hierarchySeparator(), dest)); - - // Send the request - m_connection->send(true, command.str(), true); - - // Get the response - utility::auto_ptr 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", - m_connection->getParser()->lastLine(), "bad response"); - } -} - - -void IMAPFolder::status(int& count, int& unseen) -{ - count = 0; - unseen = 0; - - // Build the request text - std::ostringstream command; - command << "STATUS "; - command << IMAPUtils::quoteString(IMAPUtils::pathToString - (m_connection->hierarchySeparator(), getFullPath())); - command << " (MESSAGES UNSEEN)"; - - // Send the request - m_store->m_connection->send(true, command.str(), true); - - // Get the response - utility::auto_ptr resp(m_store->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", - m_store->m_connection->getParser()->lastLine(), "bad response"); - } - - const std::vector & respDataList = - resp->continue_req_or_response_data(); - - for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("STATUS", - m_store->m_connection->getParser()->lastLine(), "invalid response"); - } - - const IMAPParser::response_data* responseData = (*it)->response_data(); - - if (responseData->mailbox_data() && - responseData->mailbox_data()->type() == IMAPParser::mailbox_data::STATUS) - { - const std::vector & statusList = - responseData->mailbox_data()->status_info_list(); - - for (std::vector ::const_iterator - jt = statusList.begin() ; jt != statusList.end() ; ++jt) - { - switch ((*jt)->status_att()->type()) - { - case IMAPParser::status_att::MESSAGES: - - count = (*jt)->number()->value(); - break; - - case IMAPParser::status_att::UNSEEN: - - unseen = (*jt)->number()->value(); - break; - - default: - - break; - } - } - } - } - - // Notify message count changed (new messages) - if (m_messageCount != count) - { - const int oldCount = m_messageCount; - - m_messageCount = count; - - if (count > oldCount) - { - std::vector nums; - nums.reserve(count - oldCount); - - for (int i = oldCount + 1, j = 0 ; i <= count ; ++i, ++j) - nums[j] = i; - - events::messageCountEvent event - (thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - notifyMessageCount(event); - - // Notify folders with the same path - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == m_path) - { - (*it)->m_messageCount = count; - - events::messageCountEvent event - ((*it)->thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - (*it)->notifyMessageCount(event); - } - } - } - } -} - - -} // imap -} // messaging -} // vmime diff --git a/src/messaging/imap/IMAPMessage.cpp b/src/messaging/imap/IMAPMessage.cpp deleted file mode 100644 index ba77251b..00000000 --- a/src/messaging/imap/IMAPMessage.cpp +++ /dev/null @@ -1,859 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/imap/IMAPParser.hpp" -#include "vmime/messaging/imap/IMAPMessage.hpp" -#include "vmime/messaging/imap/IMAPFolder.hpp" -#include "vmime/messaging/imap/IMAPStore.hpp" -#include "vmime/messaging/imap/IMAPConnection.hpp" -#include "vmime/messaging/imap/IMAPUtils.hpp" - -#include -#include - - -namespace vmime { -namespace messaging { -namespace imap { - - -// -// IMAPpart -// - -class IMAPstructure; - -class IMAPpart : public part -{ -private: - - friend class vmime::creator; - - IMAPpart(weak_ref parent, const int number, const IMAPParser::body_type_mpart* mpart); - IMAPpart(weak_ref parent, const int number, const IMAPParser::body_type_1part* part); - -public: - - const structure& getStructure() const; - structure& getStructure(); - - weak_ref getParent() const { return (m_parent); } - - const mediaType& getType() const { return (m_mediaType); } - const int getSize() const { return (m_size); } - const int getNumber() const { return (m_number); } - - const header& getHeader() const - { - if (m_header == NULL) - throw exceptions::unfetched_object(); - else - return (*m_header); - } - - - static ref create - (weak_ref parent, const int number, const IMAPParser::body* body) - { - if (body->body_type_mpart()) - return vmime::create (parent, number, body->body_type_mpart()); - else - return vmime::create (parent, number, body->body_type_1part()); - } - - - header& getOrCreateHeader() - { - if (m_header != NULL) - return (*m_header); - else - return (*(m_header = vmime::create
())); - } - -private: - - ref m_structure; - weak_ref m_parent; - ref
m_header; - - int m_number; - int m_size; - mediaType m_mediaType; -}; - - - -// -// IMAPstructure -// - -class IMAPstructure : public structure -{ -private: - - IMAPstructure() - { - } - -public: - - IMAPstructure(const IMAPParser::body* body) - { - m_parts.push_back(IMAPpart::create(NULL, 1, body)); - } - - IMAPstructure(weak_ref parent, const std::vector & list) - { - int number = 1; - - for (std::vector ::const_iterator - it = list.begin() ; it != list.end() ; ++it, ++number) - { - m_parts.push_back(IMAPpart::create(parent, number, *it)); - } - } - - - const part& operator[](const int x) const - { - return (*m_parts[x - 1]); - } - - part& operator[](const int x) - { - return (*m_parts[x - 1]); - } - - const int getCount() const - { - return (m_parts.size()); - } - - - static IMAPstructure* emptyStructure() - { - return (&m_emptyStructure); - } - -private: - - static IMAPstructure m_emptyStructure; - - std::vector > m_parts; -}; - - -IMAPstructure IMAPstructure::m_emptyStructure; - - - -IMAPpart::IMAPpart(weak_ref 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()); - - m_structure = vmime::create - (thisWeakRef().dynamicCast (), mpart->list()); -} - - -IMAPpart::IMAPpart(weak_ref 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; -} - - -const class structure& IMAPpart::getStructure() const -{ - if (m_structure != NULL) - return (*m_structure); - else - return (*IMAPstructure::emptyStructure()); -} - - -class structure& IMAPpart::getStructure() -{ - if (m_structure != NULL) - return (*m_structure); - else - return (*IMAPstructure::emptyStructure()); -} - - - -#ifndef VMIME_BUILDING_DOC - -// -// IMAPMessage_literalHandler -// - -class IMAPMessage_literalHandler : public IMAPParser::literalHandler -{ -public: - - IMAPMessage_literalHandler(utility::outputStream& os, utility::progressionListener* 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 - (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::progressionListener* m_progress; -}; - -#endif // VMIME_BUILDING_DOC - - - -// -// IMAPMessage -// - - -IMAPMessage::IMAPMessage(IMAPFolder* folder, const int num) - : m_folder(folder), m_num(num), m_size(-1), m_flags(FLAG_UNDEFINED), - m_expunged(false), m_structure(NULL) -{ - m_folder->registerMessage(this); -} - - -IMAPMessage::~IMAPMessage() -{ - if (m_folder) - m_folder->unregisterMessage(this); -} - - -void IMAPMessage::onFolderClosed() -{ - m_folder = NULL; -} - - -const int IMAPMessage::getNumber() const -{ - return (m_num); -} - - -const message::uid IMAPMessage::getUniqueId() const -{ - return (m_uid); -} - - -const int IMAPMessage::getSize() const -{ - if (m_size == -1) - throw exceptions::unfetched_object(); - - return (m_size); -} - - -const bool IMAPMessage::isExpunged() const -{ - return (m_expunged); -} - - -const int IMAPMessage::getFlags() const -{ - if (m_flags == FLAG_UNDEFINED) - throw exceptions::unfetched_object(); - - return (m_flags); -} - - -const structure& IMAPMessage::getStructure() const -{ - if (m_structure == NULL) - throw exceptions::unfetched_object(); - - return (*m_structure); -} - - -structure& IMAPMessage::getStructure() -{ - if (m_structure == NULL) - throw exceptions::unfetched_object(); - - return (*m_structure); -} - - -ref IMAPMessage::getHeader() const -{ - if (m_header == NULL) - throw exceptions::unfetched_object(); - - return (m_header); -} - - -void IMAPMessage::extract(utility::outputStream& os, utility::progressionListener* progress, - const int start, const int length, const bool peek) const -{ - if (!m_folder) - throw exceptions::folder_not_found(); - - extract(NULL, os, progress, start, length, false, peek); -} - - -void IMAPMessage::extractPart - (const part& p, utility::outputStream& os, utility::progressionListener* progress, - const int start, const int length, const bool peek) const -{ - if (!m_folder) - throw exceptions::folder_not_found(); - - extract(&p, os, progress, start, length, false, peek); -} - - -void IMAPMessage::fetchPartHeader(part& p) -{ - if (!m_folder) - throw exceptions::folder_not_found(); - - std::ostringstream oss; - utility::outputStreamAdapter ossAdapter(oss); - - extract(&p, ossAdapter, NULL, 0, -1, true, true); - - static_cast (p).getOrCreateHeader().parse(oss.str()); -} - - -void IMAPMessage::extract(const part* p, utility::outputStream& os, - utility::progressionListener* progress, const int start, - const int length, const bool headerOnly, const bool peek) const -{ - IMAPMessage_literalHandler literalHandler(os, progress); - - // Construct section identifier - std::ostringstream section; - - if (p != NULL) - { - weak_ref currentPart = static_cast (p); - std::vector 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 ::reverse_iterator it = numbers.rbegin() ; it != numbers.rend() ; ++it) - { - if (it != numbers.rbegin()) section << "."; - section << *it; - } - } - - // Build the request text - std::ostringstream command; - - command << "FETCH " << m_num << " BODY"; - if (peek) command << ".PEEK"; - command << "["; - command << section.str(); - if (headerOnly) command << ".MIME"; // "MIME" not "HEADER" for parts - command << "]"; - - if (start != 0 || length != -1) - command << "<" << start << "." << length << ">"; - - // Send the request - m_folder->m_connection->send(true, command.str(), true); - - // Get the response - utility::auto_ptr resp - (m_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", - m_folder->m_connection->getParser()->lastLine(), "bad response"); - } - - - if (!headerOnly) - { - // TODO: update the flags (eg. flag "\Seen" may have been set) - } -} - - -void IMAPMessage::fetch(IMAPFolder* folder, const int options) -{ - if (m_folder != folder) - throw exceptions::folder_not_found(); - - // TODO: optimization: send the request for multiple - // messages at the same time (FETCH x:y) - - // 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 items; - - if (options & folder::FETCH_SIZE) - items.push_back("RFC822.SIZE"); - - if (options & folder::FETCH_FLAGS) - items.push_back("FLAGS"); - - if (options & folder::FETCH_STRUCTURE) - items.push_back("BODYSTRUCTURE"); - - if (options & folder::FETCH_UID) - items.push_back("UID"); - - if (options & folder::FETCH_FULL_HEADER) - items.push_back("RFC822.HEADER"); - else - { - if (options & folder::FETCH_ENVELOPE) - items.push_back("ENVELOPE"); - - std::vector headerFields; - - if (options & folder::FETCH_CONTENT_INFO) - headerFields.push_back("CONTENT_TYPE"); - - if (options & folder::FETCH_IMPORTANCE) - { - headerFields.push_back("IMPORTANCE"); - headerFields.push_back("X-PRIORITY"); - } - - if (!headerFields.empty()) - { - string list; - - for (std::vector ::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 << "FETCH " << m_num << " ("; - - for (std::vector ::const_iterator it = items.begin() ; - it != items.end() ; ++it) - { - if (it != items.begin()) command << " "; - command << *it; - } - - command << ")"; - - // Send the request - m_folder->m_connection->send(true, command.str(), true); - - // Get the response - utility::auto_ptr resp(m_folder->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", - m_folder->m_connection->getParser()->lastLine(), "bad response"); - } - - const std::vector & respDataList = - resp->continue_req_or_response_data(); - - for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("FETCH", - m_folder->m_connection->getParser()->lastLine(), "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; - - if (static_cast (messageData->number()) != m_num) - continue; - - // Process fetch response for this message - processFetchResponse(options, messageData->msg_att()); - } -} - - -void IMAPMessage::processFetchResponse - (const int options, const IMAPParser::msg_att* msgAtt) -{ - // Get message attributes - const std::vector atts = - msgAtt->items(); - - int flags = 0; - - for (std::vector ::const_iterator - it = atts.begin() ; it != atts.end() ; ++it) - { - switch ((*it)->type()) - { - case IMAPParser::msg_att_item::FLAGS: - { - flags |= IMAPUtils::messageFlagsFromFlags((*it)->flag_list()); - break; - } - case IMAPParser::msg_att_item::UID: - { - std::ostringstream oss; - oss << m_folder->m_uidValidity << ":" << (*it)->unique_id()->value(); - - m_uid = oss.str(); - break; - } - case IMAPParser::msg_att_item::ENVELOPE: - { - if (!(options & folder::FETCH_FULL_HEADER)) - { - const IMAPParser::envelope* env = (*it)->envelope(); - ref 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; - convertAddressList(*(env->env_from()), from); - - if (!from.isEmpty()) - hdr->From()->setValue(*(from.getMailboxAt(0))); - - // To - mailboxList to; - convertAddressList(*(env->env_to()), to); - - hdr->To()->setValue(to); - - // Sender - mailboxList sender; - convertAddressList(*(env->env_sender()), sender); - - if (!sender.isEmpty()) - hdr->Sender()->setValue(*(sender.getMailboxAt(0))); - - // Reply-to - mailboxList replyTo; - convertAddressList(*(env->env_reply_to()), replyTo); - - if (!replyTo.isEmpty()) - hdr->ReplyTo()->setValue(*(replyTo.getMailboxAt(0))); - - // Cc - mailboxList cc; - convertAddressList(*(env->env_cc()), cc); - - if (!cc.isEmpty()) - hdr->Cc()->setValue(cc); - - // Bcc - mailboxList bcc; - convertAddressList(*(env->env_bcc()), bcc); - - if (!bcc.isEmpty()) - hdr->Bcc()->setValue(bcc); - } - - break; - } - case IMAPParser::msg_att_item::BODY_STRUCTURE: - { - m_structure = vmime::create ((*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 = (*it)->number()->value(); - break; - } - case IMAPParser::msg_att_item::BODY_SECTION: - { - if (!(options & folder::FETCH_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 > fields = tempHeader.getFieldList(); - - for (std::vector >::const_iterator jt = fields.begin() ; - jt != fields.end() ; ++jt) - { - hdr.appendField((*jt)->clone().dynamicCast ()); - } - } - } - - 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; - } - - } - } - - if (options & folder::FETCH_FLAGS) - m_flags = flags; -} - - -ref
IMAPMessage::getOrCreateHeader() -{ - if (m_header != NULL) - return (m_header); - else - return (m_header = vmime::create
()); -} - - -void IMAPMessage::convertAddressList - (const IMAPParser::address_list& src, mailboxList& dest) -{ - for (std::vector ::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(vmime::create (name, email)); - } -} - - -void IMAPMessage::setFlags(const int flags, const int mode) -{ - if (!m_folder) - throw exceptions::folder_not_found(); - else if (m_folder->m_mode == folder::MODE_READ_ONLY) - throw exceptions::illegal_state("Folder is read-only"); - - // Build the request text - std::ostringstream command; - command << "STORE " << m_num; - - switch (mode) - { - case FLAG_MODE_ADD: command << " +FLAGS"; break; - case FLAG_MODE_REMOVE: command << " -FLAGS"; break; - default: - case FLAG_MODE_SET: command << " FLAGS"; break; - } - - if (m_flags == FLAG_UNDEFINED) // Update local flags only if they - command << ".SILENT "; // have been fetched previously - else - command << " "; - - std::vector flagList; - - if (flags & FLAG_REPLIED) flagList.push_back("\\Answered"); - if (flags & FLAG_MARKED) flagList.push_back("\\Flagged"); - if (flags & FLAG_DELETED) flagList.push_back("\\Deleted"); - if (flags & FLAG_SEEN) flagList.push_back("\\Seen"); - - if (!flagList.empty()) - { - command << "("; - - if (flagList.size() >= 2) - { - std::copy(flagList.begin(), flagList.end() - 1, - std::ostream_iterator (command, " ")); - } - - command << *(flagList.end() - 1) << ")"; - - // Send the request - m_folder->m_connection->send(true, command.str(), true); - - // Get the response - utility::auto_ptr resp(m_folder->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", - m_folder->m_connection->getParser()->lastLine(), "bad response"); - } - - // Update the local flags for this message - if (m_flags != FLAG_UNDEFINED) - { - const std::vector & respDataList = - resp->continue_req_or_response_data(); - - int newFlags = 0; - - for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - continue; - - 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 message attributes - const std::vector atts = - messageData->msg_att()->items(); - - for (std::vector ::const_iterator - it = atts.begin() ; it != atts.end() ; ++it) - { - if ((*it)->type() == IMAPParser::msg_att_item::FLAGS) - newFlags |= IMAPUtils::messageFlagsFromFlags((*it)->flag_list()); - } - } - - m_flags = newFlags; - } - - // Notify message flags changed - std::vector nums; - nums.push_back(m_num); - - events::messageChangedEvent event - (m_folder->thisRef().dynamicCast (), - events::messageChangedEvent::TYPE_FLAGS, nums); - - for (std::list ::iterator it = m_folder->m_store->m_folders.begin() ; - it != m_folder->m_store->m_folders.end() ; ++it) - { - if ((*it)->getFullPath() == m_folder->m_path) - (*it)->notifyMessageChanged(event); - } - } -} - - -} // imap -} // messaging -} // vmime diff --git a/src/messaging/imap/IMAPStore.cpp b/src/messaging/imap/IMAPStore.cpp deleted file mode 100644 index 00ef98f2..00000000 --- a/src/messaging/imap/IMAPStore.cpp +++ /dev/null @@ -1,308 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/imap/IMAPStore.hpp" -#include "vmime/messaging/imap/IMAPFolder.hpp" -#include "vmime/messaging/imap/IMAPConnection.hpp" - -#include "vmime/exception.hpp" -#include "vmime/platformDependant.hpp" - -#include - - -namespace vmime { -namespace messaging { -namespace imap { - - -#ifndef VMIME_BUILDING_DOC - -// -// IMAPauthenticator: private class used internally -// -// Used to request user credentials only in the first authentication -// and reuse this information the next times -// - -class IMAPauthenticator : public authenticator -{ -public: - - IMAPauthenticator(ref auth) - : m_auth(auth), m_infos(NULL) - { - } - - ~IMAPauthenticator() - { - } - - const authenticationInfos requestAuthInfos() const - { - if (m_infos == NULL) - m_infos = vmime::create (m_auth->requestAuthInfos()); - - return (*m_infos); - } - -private: - - ref m_auth; - mutable ref m_infos; -}; - -#endif // VMIME_BUILDING_DOC - - - -// -// IMAPStore -// - -IMAPStore::IMAPStore(ref sess, ref auth) - : store(sess, getInfosInstance(), auth), - m_connection(NULL), m_oneTimeAuth(NULL) -{ -} - - -IMAPStore::~IMAPStore() -{ - if (isConnected()) - disconnect(); -} - - -ref IMAPStore::oneTimeAuthenticator() -{ - return (m_oneTimeAuth); -} - - -const string IMAPStore::getProtocolName() const -{ - return "imap"; -} - - -ref IMAPStore::getRootFolder() -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); - - return vmime::create (folder::path(), this); -} - - -ref IMAPStore::getDefaultFolder() -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); - - return vmime::create (folder::path::component("INBOX"), this); -} - - -ref IMAPStore::getFolder(const folder::path& path) -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); - - return vmime::create (path, this); -} - - -const bool IMAPStore::isValidFolderName(const folder::path::component& /* name */) const -{ - return true; -} - - -void IMAPStore::connect() -{ - if (isConnected()) - throw exceptions::already_connected(); - - m_oneTimeAuth = vmime::create (getAuthenticator()); - - m_connection = vmime::create - (thisWeakRef().dynamicCast (), m_oneTimeAuth); - - try - { - m_connection->connect(); - } - catch (std::exception&) - { - m_connection = NULL; - throw; - } -} - - -const bool IMAPStore::isConnected() const -{ - return (m_connection && m_connection->isConnected()); -} - - -void IMAPStore::disconnect() -{ - if (!isConnected()) - throw exceptions::not_connected(); - - for (std::list ::iterator it = m_folders.begin() ; - it != m_folders.end() ; ++it) - { - (*it)->onStoreDisconnected(); - } - - m_folders.clear(); - - - m_connection->disconnect(); - - m_oneTimeAuth = NULL; - - m_connection = NULL; -} - - -void IMAPStore::noop() -{ - if (!isConnected()) - throw exceptions::not_connected(); - - m_connection->send(true, "NOOP", true); - - utility::auto_ptr 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", m_connection->getParser()->lastLine()); - } -} - - -ref IMAPStore::connection() -{ - return (m_connection); -} - - -void IMAPStore::registerFolder(IMAPFolder* folder) -{ - m_folders.push_back(folder); -} - - -void IMAPStore::unregisterFolder(IMAPFolder* folder) -{ - std::list ::iterator it = std::find(m_folders.begin(), m_folders.end(), folder); - if (it != m_folders.end()) m_folders.erase(it); -} - - -const 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 - -IMAPStore::_infos IMAPStore::sm_infos; - - -const serviceInfos& IMAPStore::getInfosInstance() -{ - return (sm_infos); -} - - -const serviceInfos& IMAPStore::getInfos() const -{ - return (sm_infos); -} - - -const string IMAPStore::_infos::getPropertyPrefix() const -{ - return "store.imap."; -} - - -const IMAPStore::_infos::props& IMAPStore::_infos::getProperties() const -{ - static props p = - { - // IMAP-specific options - // (none) - - // Common properties - property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED), - property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED), - - property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED), - property(serviceInfos::property::SERVER_PORT, "143"), - property(serviceInfos::property::SERVER_SOCKETFACTORY), - - property(serviceInfos::property::TIMEOUT_FACTORY) - }; - - return p; -} - - -const std::vector IMAPStore::_infos::getAvailableProperties() const -{ - std::vector list; - const props& p = getProperties(); - - // IMAP-specific options - // (none) - - // Common properties - list.push_back(p.PROPERTY_AUTH_USERNAME); - list.push_back(p.PROPERTY_AUTH_PASSWORD); - - list.push_back(p.PROPERTY_SERVER_ADDRESS); - list.push_back(p.PROPERTY_SERVER_PORT); - list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY); - - list.push_back(p.PROPERTY_TIMEOUT_FACTORY); - - return (list); -} - - - -} // imap -} // messaging -} // vmime diff --git a/src/messaging/imap/IMAPTag.cpp b/src/messaging/imap/IMAPTag.cpp deleted file mode 100644 index c1cf659d..00000000 --- a/src/messaging/imap/IMAPTag.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/imap/IMAPTag.hpp" - - -namespace vmime { -namespace messaging { -namespace imap { - - -const int IMAPTag::sm_maxNumber = 52 * 10 * 10 * 10; - - -IMAPTag::IMAPTag(const int number) - : m_number(number) -{ - m_tag.resize(4); -} - - -IMAPTag::IMAPTag(const IMAPTag& tag) - : object(), m_number(tag.m_number) -{ - m_tag.resize(4); -} - - -IMAPTag::IMAPTag() - : m_number(0) -{ - m_tag.resize(4); -} - - -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); -} - - -const 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] = '0' + (m_number % 1000) / 100; - m_tag[2] = '0' + (m_number % 100) / 10; - m_tag[3] = '0' + (m_number % 10); -} - - -} // imap -} // messaging -} // vmime diff --git a/src/messaging/imap/IMAPUtils.cpp b/src/messaging/imap/IMAPUtils.cpp deleted file mode 100644 index 3a41598d..00000000 --- a/src/messaging/imap/IMAPUtils.cpp +++ /dev/null @@ -1,555 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/imap/IMAPUtils.hpp" -#include "vmime/messaging/message.hpp" - -#include -#include -#include - - -namespace vmime { -namespace messaging { -namespace imap { - - -const string IMAPUtils::quoteString(const string& text) -{ - // - // ATOM_CHAR ::= - // - // atom_specials ::= "(" / ")" / "{" / SPACE / CTL / - // list_wildcards / quoted_specials - // - // list_wildcards ::= "%" / "*" - // - // quoted_specials ::= <"> / "\" - // - // CHAR ::= - // - // CTL ::= - // - - 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() ; - !needQuoting && 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 (int 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 (static_cast (hierarchySeparator)); - - string hsUTF7; - hsUTF7.resize(3); - - hsUTF7[0] = base64alphabet[0]; - hsUTF7[1] = base64alphabet[(hs & 0xF0) >> 4]; - hsUTF7[2] = base64alphabet[(hs & 0x0F) << 2]; - - // 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; - - // Replace hierarchy separator with an equivalent UTF-7 Base64 sequence - if (!inB64sequence && c == hierarchySeparator) - { - out += "&" + hsUTF7 + "-"; - continue; - } - - 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 - case '/': - { - out += inB64sequence ? ',' : '/'; - break; - } - // '&' (0x26) is represented by the two-octet sequence "&-" - case '&': - { - if (!inB64sequence) - out += "&-"; - else - out += '&'; - - break; - } - default: - { - out += c; - break; - } - - } - } - - 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))); -} - - -const 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 & flags = list->flags(); - - for (std::vector ::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); -} - - -const int IMAPUtils::folderFlagsFromFlags(const IMAPParser::mailbox_flag_list* list) -{ - // Get folder flags - int folderFlags = folder::FLAG_CHILDREN; - const std::vector & flags = list->flags(); - - for (std::vector ::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); -} - - -const int IMAPUtils::messageFlagsFromFlags(const IMAPParser::flag_list* list) -{ - const std::vector & flagList = list->flags(); - int flags = 0; - - for (std::vector ::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; - - default: - //case IMAPParser::flag::UNKNOWN: - //case IMAPParser::flag::DRAFT: - break; - } - } - - return (flags); -} - - -const string IMAPUtils::messageFlagList(const int flags) -{ - std::vector 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 (!flagList.empty()) - { - std::ostringstream res; - res << "("; - - if (flagList.size() >= 2) - { - std::copy(flagList.begin(), flagList.end() - 1, - std::ostream_iterator (res, " ")); - } - - res << *(flagList.end() - 1) << ")"; - - return (res.str()); - } - - return ""; -} - - -// This function builds a "IMAP set" given a list. Try to group consecutive -// message numbers to reduce the list. -// -// Example: -// IN = "1,2,3,4,5,7,8,13,15,16,17" -// OUT = "1:5,7:8,13,15:*" for a mailbox with a total of 17 messages (max = 17) - -const string IMAPUtils::listToSet(const std::vector & list, const int max, - const bool alreadySorted) -{ - // Sort a copy of the list (if not already sorted) - std::vector temp; - - if (!alreadySorted) - { - temp.resize(list.size()); - std::copy(list.begin(), list.end(), temp.begin()); - - std::sort(temp.begin(), temp.end()); - } - - const std::vector & theList = (alreadySorted ? list : temp); - - // Build the set - std::ostringstream res; - int previous = -1, setBegin = -1; - - for (std::vector ::const_iterator it = theList.begin() ; - it != theList.end() ; ++it) - { - const int current = *it; - - if (previous == -1) - { - res << current; - - previous = current; - setBegin = current; - } - else - { - if (current == previous + 1) - { - previous = current; - } - else - { - if (setBegin != previous) - { - res << ":" << previous << "," << current; - - previous = current; - setBegin = current; - } - else - { - if (setBegin != current) // skip duplicates - res << "," << current; - - previous = current; - setBegin = current; - } - } - } - } - - if (previous != setBegin) - { - if (previous == max) - res << ":*"; - else - res << ":" << previous; - } - - return (res.str()); -} - - -const string IMAPUtils::dateTime(const vmime::datetime& date) -{ - std::ostringstream res; - - // 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()); -} - - -} // imap -} // messaging -} // vmime diff --git a/src/messaging/maildir/maildirFolder.cpp b/src/messaging/maildir/maildirFolder.cpp deleted file mode 100644 index e7a4e2f8..00000000 --- a/src/messaging/maildir/maildirFolder.cpp +++ /dev/null @@ -1,1387 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/maildir/maildirFolder.hpp" - -#include "vmime/messaging/maildir/maildirStore.hpp" -#include "vmime/messaging/maildir/maildirMessage.hpp" -#include "vmime/messaging/maildir/maildirUtils.hpp" - -#include "vmime/utility/smartPtr.hpp" - -#include "vmime/message.hpp" - -#include "vmime/exception.hpp" -#include "vmime/platformDependant.hpp" - - -namespace vmime { -namespace messaging { -namespace maildir { - - -maildirFolder::maildirFolder(const folder::path& path, weak_ref 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) -{ - m_store->registerFolder(this); -} - - -maildirFolder::~maildirFolder() -{ - if (m_store) - { - if (m_open) - close(false); - - m_store->unregisterFolder(this); - } - else if (m_open) - { - close(false); - } -} - - -void maildirFolder::onStoreDisconnected() -{ - m_store = NULL; -} - - -const int maildirFolder::getMode() const -{ - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - return (m_mode); -} - - -const int maildirFolder::getType() -{ - if (m_path.isEmpty()) - return (TYPE_CONTAINS_FOLDERS); - else - return (TYPE_CONTAINS_FOLDERS | TYPE_CONTAINS_MESSAGES); -} - - -const int maildirFolder::getFlags() -{ - int flags = 0; - - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - ref rootDir = fsf->create - (maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_CONTAINER)); - - ref it = rootDir->getFiles(); - - while (it->hasMoreElements()) - { - ref file = it->nextElement(); - - if (maildirUtils::isSubfolderDirectory(*file)) - { - flags |= FLAG_CHILDREN; // Contains at least one sub-folder - break; - } - } - - 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 */) -{ - if (!m_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) -{ - if (!m_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 ::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 ::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 */) -{ - if (!m_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 (!m_store->isValidFolderName(m_name)) - throw exceptions::invalid_folder_name(); - - // Create directory on file system - try - { - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - if (!fsf->isValidPath(maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_ROOT))) - throw exceptions::invalid_folder_name(); - - ref rootDir = fsf->create - (maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_ROOT)); - - ref newDir = fsf->create - (maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_NEW)); - ref tmpDir = fsf->create - (maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_TMP)); - ref curDir = fsf->create - (maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_CUR)); - - rootDir->createDirectory(true); - - newDir->createDirectory(false); - tmpDir->createDirectory(false); - curDir->createDirectory(false); - } - catch (exceptions::filesystem_exception& e) - { - throw exceptions::command_error("CREATE", "", "File system exception", e); - } - - // Notify folder created - events::folderEvent event - (thisRef().dynamicCast (), - events::folderEvent::TYPE_CREATED, m_path, m_path); - - notifyFolder(event); -} - - -const bool maildirFolder::exists() -{ - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - ref rootDir = fsf->create - (maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_ROOT)); - - ref newDir = fsf->create - (maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_NEW)); - ref tmpDir = fsf->create - (maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_TMP)); - ref curDir = fsf->create - (maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_CUR)); - - return (rootDir->exists() && rootDir->isDirectory() && - newDir->exists() && newDir->isDirectory() && - tmpDir->exists() && tmpDir->isDirectory() && - curDir->exists() && curDir->isDirectory()); -} - - -const bool maildirFolder::isOpen() const -{ - return (m_open); -} - - -void maildirFolder::scanFolder() -{ - try - { - m_messageCount = 0; - m_unreadMessageCount = 0; - - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - utility::file::path newDirPath = maildirUtils::getFolderFSPath - (m_store, m_path, maildirUtils::FOLDER_PATH_NEW); - ref newDir = fsf->create(newDirPath); - - utility::file::path curDirPath = maildirUtils::getFolderFSPath - (m_store, m_path, maildirUtils::FOLDER_PATH_CUR); - ref curDir = fsf->create(curDirPath); - - // New received messages (new/) - ref nit = newDir->getFiles(); - std::vector newMessageFilenames; - - while (nit->hasMoreElements()) - { - ref file = nit->nextElement(); - - if (maildirUtils::isMessageFile(*file)) - newMessageFilenames.push_back(file->getFullPath().getLastComponent()); - } - - // Current messages (cur/) - ref cit = curDir->getFiles(); - std::vector curMessageFilenames; - - while (cit->hasMoreElements()) - { - ref 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 ::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 ::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' - ref file = fsf->create(newDirPath / *it); - file->rename(curDirPath / newFilename); - - // Append to message list - messageInfos msgInfos; - msgInfos.path = newFilename; - 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 ::const_iterator - it = curMessageFilenames.begin() ; it != curMessageFilenames.end() ; ++it) - { - // Append to message list - messageInfos msgInfos; - msgInfos.path = *it; - msgInfos.type = messageInfos::TYPE_CUR; - - m_messageInfos.push_back(msgInfos); - } - - // Update message count - int unreadMessageCount = 0; - - for (std::vector ::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... - } -} - - -ref 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 vmime::create - (thisWeakRef().dynamicCast (), num); -} - - -std::vector > maildirFolder::getMessages(const int from, const int to) -{ - const int to2 = (to == -1 ? m_messageCount : to); - - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - else if (to2 < from || from < 1 || to2 < 1 || from > m_messageCount || to2 > m_messageCount) - throw exceptions::message_not_found(); - - std::vector > v; - - for (int i = from ; i <= to2 ; ++i) - { - v.push_back(vmime::create - (thisWeakRef().dynamicCast (), i)); - } - - return (v); -} - - -std::vector > maildirFolder::getMessages(const std::vector & nums) -{ - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - std::vector > v; - - for (std::vector ::const_iterator it = nums.begin() ; it != nums.end() ; ++it) - { - v.push_back(vmime::create - (thisWeakRef().dynamicCast (), *it)); - } - - return (v); -} - - -const int maildirFolder::getMessageCount() -{ - return (m_messageCount); -} - - -ref maildirFolder::getFolder(const folder::path::component& name) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - - return vmime::create (m_path / name, m_store); -} - - -std::vector > maildirFolder::getFolders(const bool recursive) -{ - if (!isOpen() && !m_store) - throw exceptions::illegal_state("Store disconnected"); - - std::vector > list; - - listFolders(list, recursive); - - return (list); -} - - -void maildirFolder::listFolders(std::vector >& list, const bool recursive) -{ - try - { - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - ref rootDir = fsf->create - (maildirUtils::getFolderFSPath(m_store, m_path, - m_path.isEmpty() ? maildirUtils::FOLDER_PATH_ROOT - : maildirUtils::FOLDER_PATH_CONTAINER)); - - if (rootDir->exists()) - { - ref it = rootDir->getFiles(); - - while (it->hasMoreElements()) - { - ref file = it->nextElement(); - - if (maildirUtils::isSubfolderDirectory(*file)) - { - const utility::path subPath = - m_path / file->getFullPath().getLastComponent(); - - ref subFolder = - vmime::create (subPath, m_store); - - list.push_back(subFolder); - - if (recursive) - subFolder->listFolders(list, true); - } - } - } - else - { - // No sub-folder - } - } - catch (exceptions::filesystem_exception& e) - { - throw exceptions::command_error("LIST", "", "", e); - } -} - - -void maildirFolder::rename(const folder::path& newPath) -{ - if (!m_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_store->isValidFolderName(newPath.getLastComponent())) - throw exceptions::invalid_folder_name(); - - // Rename the directory on the file system - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - ref rootDir = fsf->create - (maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_ROOT)); - ref contDir = fsf->create - (maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_CONTAINER)); - - try - { - const utility::file::path newRootPath = - maildirUtils::getFolderFSPath(m_store, newPath, maildirUtils::FOLDER_PATH_ROOT); - const utility::file::path newContPath = - maildirUtils::getFolderFSPath(m_store, newPath, maildirUtils::FOLDER_PATH_CONTAINER); - - 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 = - maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_ROOT); - const utility::file::path contPath = - maildirUtils::getFolderFSPath(m_store, m_path, maildirUtils::FOLDER_PATH_CONTAINER); - - try - { - rootDir->rename(rootPath); - contDir->rename(contPath); - } - catch (exceptions::filesystem_exception& e) - { - // Ignore - } - - throw exceptions::command_error("RENAME", "", "", e); - } - - // Notify folder renamed - folder::path oldPath(m_path); - - m_path = newPath; - m_name = newPath.getLastComponent(); - - events::folderEvent event - (thisRef().dynamicCast (), - events::folderEvent::TYPE_RENAMED, oldPath, newPath); - - notifyFolder(event); - - // Notify folders with the same path - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == oldPath) - { - (*it)->m_path = newPath; - (*it)->m_name = newPath.getLastComponent(); - - events::folderEvent event - ((*it)->thisRef().dynamicCast (), - 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); - - events::folderEvent event - ((*it)->thisRef().dynamicCast (), - events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path); - - (*it)->notifyFolder(event); - } - } -} - - -void maildirFolder::deleteMessage(const int num) -{ - // Mark messages as deleted - setMessageFlags(num, num, message::FLAG_MODE_ADD, message::FLAG_DELETED); -} - - -void maildirFolder::deleteMessages(const int from, const int to) -{ - // Mark messages as deleted - setMessageFlags(from, to, message::FLAG_MODE_ADD, message::FLAG_DELETED); -} - - -void maildirFolder::deleteMessages(const std::vector & nums) -{ - // Mark messages as deleted - setMessageFlags(nums, message::FLAG_MODE_ADD, message::FLAG_DELETED); -} - - -void maildirFolder::setMessageFlags - (const int from, const int to, const int flags, const int mode) -{ - if (from < 1 || (to < from && to != -1)) - throw exceptions::invalid_argument(); - - if (!m_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"); - - // Construct the list of message numbers - const int to2 = (to == -1) ? m_messageCount : to; - const int count = to - from + 1; - - std::vector nums; - nums.resize(count); - - for (int i = from, j = 0 ; i <= to2 ; ++i, ++j) - nums[j] = i; - - // Change message flags - setMessageFlagsImpl(nums, flags, mode); - - // Update local flags - switch (mode) - { - case message::FLAG_MODE_ADD: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags |= flags; - } - } - - break; - } - case message::FLAG_MODE_REMOVE: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags &= ~flags; - } - } - - break; - } - default: - case message::FLAG_MODE_SET: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags = flags; - } - } - - break; - } - - } - - // Notify message flags changed - events::messageChangedEvent event - (thisRef().dynamicCast (), - events::messageChangedEvent::TYPE_FLAGS, nums); - - notifyMessageChanged(event); - - // TODO: notify other folders with the same path -} - - -void maildirFolder::setMessageFlags - (const std::vector & nums, const int flags, const int mode) -{ - if (!m_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"); - - // Sort the list of message numbers - std::vector list; - - list.resize(nums.size()); - std::copy(nums.begin(), nums.end(), list.begin()); - - std::sort(list.begin(), list.end()); - - // Change message flags - setMessageFlagsImpl(list, flags, mode); - - // Update local flags - switch (mode) - { - case message::FLAG_MODE_ADD: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags |= flags; - } - } - - break; - } - case message::FLAG_MODE_REMOVE: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags &= ~flags; - } - } - - break; - } - default: - case message::FLAG_MODE_SET: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && - (*it)->m_flags != message::FLAG_UNDEFINED) - { - (*it)->m_flags = flags; - } - } - - break; - } - - } - - // Notify message flags changed - events::messageChangedEvent event - (thisRef().dynamicCast (), - events::messageChangedEvent::TYPE_FLAGS, nums); - - notifyMessageChanged(event); - - // TODO: notify other folders with the same path -} - - -void maildirFolder::setMessageFlagsImpl - (const std::vector & nums, const int flags, const int mode) -{ - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - utility::file::path curDirPath = maildirUtils::getFolderFSPath - (m_store, m_path, maildirUtils::FOLDER_PATH_CUR); - - for (std::vector ::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; - ref 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) - } - } -} - - -void maildirFolder::addMessage(ref msg, const int flags, - vmime::datetime* date, utility::progressionListener* progress) -{ - std::ostringstream oss; - utility::outputStreamAdapter ossAdapter(oss); - - msg->generate(ossAdapter); - - const std::string& str = oss.str(); - utility::inputStreamStringAdapter strAdapter(str); - - addMessage(strAdapter, str.length(), flags, date, progress); -} - - -void maildirFolder::addMessage(utility::inputStream& is, const int size, - const int flags, vmime::datetime* /* date */, utility::progressionListener* progress) -{ - if (!m_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"); - - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - utility::file::path tmpDirPath = maildirUtils::getFolderFSPath - (m_store, m_path, maildirUtils::FOLDER_PATH_TMP); - utility::file::path curDirPath = maildirUtils::getFolderFSPath - (m_store, m_path, maildirUtils::FOLDER_PATH_CUR); - - const utility::file::path::component filename = - maildirUtils::buildFilename(maildirUtils::generateId(), - ((flags == message::FLAG_UNDEFINED) ? 0 : flags)); - - try - { - ref tmpDir = fsf->create(tmpDirPath); - tmpDir->createDirectory(true); - } - catch (exceptions::filesystem_exception&) - { - // Don't throw now, it will fail later... - } - - try - { - ref curDir = fsf->create(curDirPath); - curDir->createDirectory(true); - } - catch (exceptions::filesystem_exception&) - { - // Don't throw now, it will fail later... - } - - // Actually add the message - copyMessageImpl(tmpDirPath, curDirPath, 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 nums; - nums.push_back(m_messageCount); - - events::messageCountEvent event - (thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - notifyMessageCount(event); - - // Notify folders with the same path - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_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()); - - events::messageCountEvent event - ((*it)->thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - (*it)->notifyMessageCount(event); - } - } -} - - -void maildirFolder::copyMessageImpl(const utility::file::path& tmpDirPath, - const utility::file::path& curDirPath, const utility::file::path::component& filename, - utility::inputStream& is, const utility::stream::size_type size, - utility::progressionListener* progress) -{ - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - ref file = fsf->create(tmpDirPath / filename); - - if (progress) - progress->start(size); - - // First, write the message into 'tmp'... - try - { - file->createFile(); - - ref fw = file->getFileWriter(); - ref os = fw->getOutputStream(); - - utility::stream::value_type buffer[65536]; - utility::stream::size_type total = 0; - - while (!is.eof()) - { - const utility::stream::size_type read = is.read(buffer, sizeof(buffer)); - - if (read != 0) - { - os->write(buffer, read); - total += read; - } - - if (progress) - progress->progress(total, size); - } - } - catch (exception& e) - { - if (progress) - progress->stop(size); - - // Delete temporary file - try - { - ref 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(curDirPath / filename); - } - catch (exception& e) - { - if (progress) - progress->stop(size); - - // Delete temporary file - try - { - ref file = fsf->create(tmpDirPath / filename); - file->remove(); - } - catch (exceptions::filesystem_exception&) - { - // Ignore - } - - throw exceptions::command_error("ADD", "", "", e); - } - - if (progress) - progress->stop(size); -} - - -void maildirFolder::copyMessage(const folder::path& dest, const int num) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - copyMessages(dest, num, num); -} - - -void maildirFolder::copyMessages(const folder::path& dest, const int from, const int to) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - else if (from < 1 || (to < from && to != -1)) - throw exceptions::invalid_argument(); - - // Construct the list of message numbers - const int to2 = (to == -1) ? m_messageCount : to; - const int count = to - from + 1; - - std::vector nums; - nums.resize(count); - - for (int i = from, j = 0 ; i <= to2 ; ++i, ++j) - nums[j] = i; - - // Copy messages - copyMessagesImpl(dest, nums); -} - - -void maildirFolder::copyMessages(const folder::path& dest, const std::vector & nums) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - // Copy messages - copyMessagesImpl(dest, nums); -} - - -void maildirFolder::copyMessagesImpl(const folder::path& dest, const std::vector & nums) -{ - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - utility::file::path curDirPath = maildirUtils::getFolderFSPath - (m_store, m_path, maildirUtils::FOLDER_PATH_CUR); - - utility::file::path destCurDirPath = maildirUtils::getFolderFSPath - (m_store, dest, maildirUtils::FOLDER_PATH_CUR); - utility::file::path destTmpDirPath = maildirUtils::getFolderFSPath - (m_store, dest, maildirUtils::FOLDER_PATH_TMP); - - // Create destination directories - try - { - ref destTmpDir = fsf->create(destTmpDirPath); - destTmpDir->createDirectory(true); - } - catch (exceptions::filesystem_exception&) - { - // Don't throw now, it will fail later... - } - - try - { - ref destCurDir = fsf->create(destCurDirPath); - destCurDir->createDirectory(true); - } - catch (exceptions::filesystem_exception&) - { - // Don't throw now, it will fail later... - } - - // Copy messages - try - { - for (std::vector ::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); - - ref file = fsf->create(curDirPath / msg.path); - ref fr = file->getFileReader(); - ref 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) -{ - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_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) -{ - const int oldCount = m_messageCount; - - scanFolder(); - - count = m_messageCount; - unseen = m_unreadMessageCount; - - // Notify message count changed (new messages) - if (count > oldCount) - { - std::vector nums; - nums.reserve(count - oldCount); - - for (int i = oldCount + 1, j = 0 ; i <= count ; ++i, ++j) - nums[j] = i; - - events::messageCountEvent event - (thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - notifyMessageCount(event); - - // Notify folders with the same path - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_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()); - - events::messageCountEvent event - ((*it)->thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - (*it)->notifyMessageCount(event); - } - } - } -} - - -void maildirFolder::expunge() -{ - if (!m_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"); - - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - utility::file::path curDirPath = maildirUtils::getFolderFSPath - (m_store, m_path, maildirUtils::FOLDER_PATH_CUR); - - std::vector 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 ::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 - { - ref file = fsf->create(curDirPath / infos.path); - file->remove(); - } - catch (exceptions::filesystem_exception& e) - { - // Ignore (not important) - } - } - } - - if (!nums.empty()) - { - for (int i = nums.size() - 1 ; i >= 0 ; --i) - m_messageInfos.erase(m_messageInfos.begin() + i); - } - - m_messageCount -= nums.size(); - m_unreadMessageCount -= unreadCount; - - // Notify message expunged - events::messageCountEvent event - (thisRef().dynamicCast (), - events::messageCountEvent::TYPE_REMOVED, nums); - - notifyMessageCount(event); - - // Notify folders with the same path - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_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()); - - events::messageCountEvent event - ((*it)->thisRef().dynamicCast (), - events::messageCountEvent::TYPE_REMOVED, nums); - - (*it)->notifyMessageCount(event); - } - } -} - - -ref maildirFolder::getParent() -{ - if (m_path.isEmpty()) - return NULL; - else - return vmime::create (m_path.getParent(), m_store); -} - - -weak_ref maildirFolder::getStore() const -{ - return (m_store); -} - - -weak_ref maildirFolder::getStore() -{ - return (m_store); -} - - -void maildirFolder::fetchMessages(std::vector >& msg, - const int options, utility::progressionListener* progress) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - const int total = msg.size(); - int current = 0; - - if (progress) - progress->start(total); - - weak_ref _this = thisWeakRef().dynamicCast (); - - for (std::vector >::iterator it = msg.begin() ; - it != msg.end() ; ++it) - { - (*it).dynamicCast ()->fetch(_this, options); - - if (progress) - progress->progress(++current, total); - } - - if (progress) - progress->stop(total); -} - - -void maildirFolder::fetchMessage(ref msg, const int options) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - msg.dynamicCast ()->fetch - (thisWeakRef().dynamicCast (), options); -} - - -const int maildirFolder::getFetchCapabilities() const -{ - return (FETCH_ENVELOPE | FETCH_STRUCTURE | FETCH_CONTENT_INFO | - FETCH_FLAGS | FETCH_SIZE | FETCH_FULL_HEADER | FETCH_UID | - FETCH_IMPORTANCE); -} - - -const utility::file::path maildirFolder::getMessageFSPath(const int number) const -{ - utility::file::path curDirPath = maildirUtils::getFolderFSPath - (m_store, m_path, maildirUtils::FOLDER_PATH_CUR); - - return (curDirPath / m_messageInfos[number - 1].path); -} - - -} // maildir -} // messaging -} // vmime diff --git a/src/messaging/maildir/maildirMessage.cpp b/src/messaging/maildir/maildirMessage.cpp deleted file mode 100644 index e2393774..00000000 --- a/src/messaging/maildir/maildirMessage.cpp +++ /dev/null @@ -1,505 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/maildir/maildirMessage.hpp" -#include "vmime/messaging/maildir/maildirFolder.hpp" -#include "vmime/messaging/maildir/maildirUtils.hpp" -#include "vmime/messaging/maildir/maildirStore.hpp" - -#include "vmime/message.hpp" - -#include "vmime/exception.hpp" -#include "vmime/platformDependant.hpp" - - -namespace vmime { -namespace messaging { -namespace maildir { - - -// -// maildirPart -// - -class maildirStructure; - -class maildirPart : public part -{ -public: - - maildirPart(weak_ref parent, const int number, const bodyPart& part); - ~maildirPart(); - - - const structure& getStructure() const; - structure& getStructure(); - - weak_ref getParent() const { return (m_parent); } - - const mediaType& getType() const { return (m_mediaType); } - const int getSize() const { return (m_size); } - const int getNumber() const { return (m_number); } - - const header& getHeader() const - { - if (m_header == NULL) - throw exceptions::unfetched_object(); - else - return (*m_header); - } - - header& getOrCreateHeader() - { - if (m_header != NULL) - return (*m_header); - else - return (*(m_header = vmime::create
())); - } - - const int getHeaderParsedOffset() const { return (m_headerParsedOffset); } - const int getHeaderParsedLength() const { return (m_headerParsedLength); } - - const int getBodyParsedOffset() const { return (m_bodyParsedOffset); } - const int getBodyParsedLength() const { return (m_bodyParsedLength); } - -private: - - ref m_structure; - weak_ref m_parent; - ref
m_header; - - int m_number; - int m_size; - mediaType m_mediaType; - - int m_headerParsedOffset; - int m_headerParsedLength; - - int m_bodyParsedOffset; - int m_bodyParsedLength; -}; - - - -// -// maildirStructure -// - -class maildirStructure : public structure -{ -private: - - maildirStructure() - { - } - -public: - - maildirStructure(weak_ref parent, const bodyPart& part) - { - m_parts.push_back(vmime::create (parent, 1, part)); - } - - maildirStructure(weak_ref parent, const std::vector >& list) - { - int number = 1; - - for (unsigned int i = 0 ; i < list.size() ; ++i) - m_parts.push_back(vmime::create (parent, number, *list[i])); - } - - - const part& operator[](const int x) const - { - return (*m_parts[x - 1]); - } - - part& operator[](const int x) - { - return (*m_parts[x - 1]); - } - - const int getCount() const - { - return (m_parts.size()); - } - - - static maildirStructure* emptyStructure() - { - return (&m_emptyStructure); - } - -private: - - static maildirStructure m_emptyStructure; - - std::vector > m_parts; -}; - - -maildirStructure maildirStructure::m_emptyStructure; - - - -maildirPart::maildirPart(weak_ref parent, const int number, const bodyPart& part) - : m_parent(parent), m_header(NULL), m_number(number) -{ - if (part.getBody()->getPartList().size() == 0) - m_structure = NULL; - else - { - m_structure = vmime::create - (thisWeakRef().dynamicCast (), - part.getBody()->getPartList()); - } - - 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(); -} - - -maildirPart::~maildirPart() -{ -} - - -const structure& maildirPart::getStructure() const -{ - if (m_structure != NULL) - return (*m_structure); - else - return (*maildirStructure::emptyStructure()); -} - - -structure& maildirPart::getStructure() -{ - if (m_structure != NULL) - return (*m_structure); - else - return (*maildirStructure::emptyStructure()); -} - - - -// -// maildirMessage -// - -maildirMessage::maildirMessage(weak_ref folder, const int num) - : m_folder(folder), m_num(num), m_size(-1), m_flags(FLAG_UNDEFINED), - m_expunged(false), m_structure(NULL) -{ - m_folder->registerMessage(this); -} - - -maildirMessage::~maildirMessage() -{ - if (m_folder) - m_folder->unregisterMessage(this); -} - - -void maildirMessage::onFolderClosed() -{ - m_folder = NULL; -} - - -const int maildirMessage::getNumber() const -{ - return (m_num); -} - - -const message::uid maildirMessage::getUniqueId() const -{ - return (m_uid); -} - - -const int maildirMessage::getSize() const -{ - if (m_size == -1) - throw exceptions::unfetched_object(); - - return (m_size); -} - - -const bool maildirMessage::isExpunged() const -{ - return (m_expunged); -} - - -const structure& maildirMessage::getStructure() const -{ - if (m_structure == NULL) - throw exceptions::unfetched_object(); - - return (*m_structure); -} - - -structure& maildirMessage::getStructure() -{ - if (m_structure == NULL) - throw exceptions::unfetched_object(); - - return (*m_structure); -} - - -ref maildirMessage::getHeader() const -{ - if (m_header == NULL) - throw exceptions::unfetched_object(); - - return (m_header); -} - - -const 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) -{ - if (!m_folder) - throw exceptions::folder_not_found(); - - m_folder->setMessageFlags(m_num, m_num, flags, mode); -} - - -void maildirMessage::extract(utility::outputStream& os, - utility::progressionListener* progress, const int start, - const int length, const bool peek) const -{ - extractImpl(os, progress, 0, m_size, start, length, peek); -} - - -void maildirMessage::extractPart(const part& p, utility::outputStream& os, - utility::progressionListener* progress, const int start, - const int length, const bool peek) const -{ - const maildirPart& mp = dynamic_cast (p); - - extractImpl(os, progress, mp.getBodyParsedOffset(), mp.getBodyParsedLength(), - start, length, peek); -} - - -void maildirMessage::extractImpl(utility::outputStream& os, utility::progressionListener* progress, - const int start, const int length, const int partialStart, const int partialLength, - const bool /* peek */) const -{ - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - const utility::file::path path = m_folder->getMessageFSPath(m_num); - ref file = fsf->create(path); - - ref reader = file->getFileReader(); - ref is = reader->getInputStream(); - - is->skip(start + partialStart); - - utility::stream::value_type buffer[8192]; - utility::stream::size_type remaining = (partialLength == -1 ? length - : std::min(partialLength, length)); - - const int total = remaining; - int current = 0; - - if (progress) - progress->start(total); - - while (!is->eof() && remaining > 0) - { - const utility::stream::size_type 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(part& p) -{ - maildirPart& mp = dynamic_cast (p); - - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - const utility::file::path path = m_folder->getMessageFSPath(m_num); - ref file = fsf->create(path); - - ref reader = file->getFileReader(); - ref is = reader->getInputStream(); - - is->skip(mp.getHeaderParsedOffset()); - - utility::stream::value_type buffer[1024]; - utility::stream::size_type remaining = mp.getHeaderParsedLength(); - - string contents; - contents.reserve(remaining); - - while (!is->eof() && remaining > 0) - { - const utility::stream::size_type read = - is->read(buffer, std::min(remaining, sizeof(buffer))); - - remaining -= read; - - contents.append(buffer, read); - } - - mp.getOrCreateHeader().parse(contents); -} - - -void maildirMessage::fetch(weak_ref folder, const int options) -{ - if (m_folder != folder) - throw exceptions::folder_not_found(); - - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - const utility::file::path path = folder->getMessageFSPath(m_num); - ref file = fsf->create(path); - - if (options & folder::FETCH_FLAGS) - m_flags = maildirUtils::extractFlags(path.getLastComponent()); - - if (options & folder::FETCH_SIZE) - m_size = file->getLength(); - - if (options & folder::FETCH_UID) - m_uid = maildirUtils::extractId(path.getLastComponent()).getBuffer(); - - if (options & (folder::FETCH_ENVELOPE | folder::FETCH_CONTENT_INFO | - folder::FETCH_FULL_HEADER | folder::FETCH_STRUCTURE | - folder::FETCH_IMPORTANCE)) - { - string contents; - - ref reader = file->getFileReader(); - ref is = reader->getInputStream(); - - // Need whole message contents for structure - if (options & folder::FETCH_STRUCTURE) - { - utility::stream::value_type buffer[16384]; - - contents.reserve(file->getLength()); - - while (!is->eof()) - { - const utility::stream::size_type read = is->read(buffer, sizeof(buffer)); - contents.append(buffer, read); - } - } - // Need only header - else - { - utility::stream::value_type buffer[1024]; - - contents.reserve(4096); - - while (!is->eof()) - { - const utility::stream::size_type read = is->read(buffer, sizeof(buffer)); - contents.append(buffer, read); - - const string::size_type sep1 = contents.rfind("\r\n\r\n"); - const string::size_type 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 & folder::FETCH_STRUCTURE) - { - m_structure = vmime::create (null, msg); - } - - // Extract some header fields or whole header - if (options & (folder::FETCH_ENVELOPE | - folder::FETCH_CONTENT_INFO | - folder::FETCH_FULL_HEADER | - folder::FETCH_IMPORTANCE)) - { - getOrCreateHeader()->copyFrom(*(msg.getHeader())); - } - } -} - - -ref
maildirMessage::getOrCreateHeader() -{ - if (m_header != NULL) - return (m_header); - else - return (m_header = vmime::create
()); -} - - -} // maildir -} // messaging -} // vmime diff --git a/src/messaging/maildir/maildirStore.cpp b/src/messaging/maildir/maildirStore.cpp deleted file mode 100644 index ccbd35a4..00000000 --- a/src/messaging/maildir/maildirStore.cpp +++ /dev/null @@ -1,250 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/maildir/maildirStore.hpp" - -#include "vmime/messaging/maildir/maildirFolder.hpp" - -#include "vmime/utility/smartPtr.hpp" - -#include "vmime/exception.hpp" -#include "vmime/platformDependant.hpp" - - -// Helpers for service properties -#define GET_PROPERTY(type, prop) \ - (sm_infos.getPropertyValue (getSession(), sm_infos.getProperties().prop)) -#define HAS_PROPERTY(prop) \ - (sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop)) - - -namespace vmime { -namespace messaging { -namespace maildir { - - -maildirStore::maildirStore(ref sess, ref auth) - : store(sess, getInfosInstance(), auth), m_connected(false) -{ -} - - -maildirStore::~maildirStore() -{ - if (isConnected()) - disconnect(); -} - - -const string maildirStore::getProtocolName() const -{ - return "maildir"; -} - - -ref maildirStore::getRootFolder() -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); - - return vmime::create (folder::path(), - thisWeakRef().dynamicCast ()); -} - - -ref maildirStore::getDefaultFolder() -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); - - return vmime::create (folder::path::component("inbox"), - thisWeakRef().dynamicCast ()); -} - - -ref maildirStore::getFolder(const folder::path& path) -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); - - return vmime::create (path, - thisWeakRef().dynamicCast ()); -} - - -const bool maildirStore::isValidFolderName(const folder::path::component& name) const -{ - if (!platformDependant::getHandler()->getFileSystemFactory()->isValidPathComponent(name)) - return false; - - const string& buf = name.getBuffer(); - - // Name cannot start/end with spaces - if (utility::stringUtils::trim(buf) != name.getBuffer()) - return false; - - // Name cannot start with '.' - const int 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 - utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory(); - - m_fsPath = fsf->stringToPath(GET_PROPERTY(string, PROPERTY_SERVER_ROOTPATH)); - - ref 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_connected = true; -} - - -const bool maildirStore::isConnected() const -{ - return (m_connected); -} - - -void maildirStore::disconnect() -{ - for (std::list ::iterator it = m_folders.begin() ; - it != m_folders.end() ; ++it) - { - (*it)->onStoreDisconnected(); - } - - m_folders.clear(); - - m_connected = false; -} - - -void maildirStore::noop() -{ - // Nothing to do. -} - - -void maildirStore::registerFolder(maildirFolder* folder) -{ - m_folders.push_back(folder); -} - - -void maildirStore::unregisterFolder(maildirFolder* folder) -{ - std::list ::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); -} - - -const 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 - -maildirStore::_infos maildirStore::sm_infos; - - -const serviceInfos& maildirStore::getInfosInstance() -{ - return (sm_infos); -} - - -const serviceInfos& maildirStore::getInfos() const -{ - return (sm_infos); -} - - -const string maildirStore::_infos::getPropertyPrefix() const -{ - return "store.maildir."; -} - - -const maildirStore::_infos::props& maildirStore::_infos::getProperties() const -{ - static props p = - { - property(serviceInfos::property::SERVER_ROOTPATH, serviceInfos::property::FLAG_REQUIRED) - }; - - return p; -} - - -const std::vector maildirStore::_infos::getAvailableProperties() const -{ - std::vector list; - const props& p = getProperties(); - - // Maildir-specific properties - list.push_back(p.PROPERTY_SERVER_ROOTPATH); - - return (list); -} - - -} // maildir -} // messaging -} // vmime diff --git a/src/messaging/maildir/maildirUtils.cpp b/src/messaging/maildir/maildirUtils.cpp deleted file mode 100644 index 9e411cd6..00000000 --- a/src/messaging/maildir/maildirUtils.cpp +++ /dev/null @@ -1,208 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/maildir/maildirUtils.hpp" -#include "vmime/messaging/maildir/maildirStore.hpp" - -#include "vmime/utility/random.hpp" - - -namespace vmime { -namespace messaging { -namespace maildir { - - -const vmime::word maildirUtils::TMP_DIR("tmp", vmime::charset(vmime::charsets::US_ASCII)); // ensure reliable delivery (not to be listed) -const vmime::word maildirUtils::CUR_DIR("cur", vmime::charset(vmime::charsets::US_ASCII)); // no longer new messages -const vmime::word maildirUtils::NEW_DIR("new", vmime::charset(vmime::charsets::US_ASCII)); // unread messages - - -const utility::file::path maildirUtils::getFolderFSPath - (weak_ref store, const utility::path& folderPath, const FolderFSPathMode mode) -{ - // Root path - utility::file::path path(store->getFileSystemPath()); - - const int count = (mode == FOLDER_PATH_CONTAINER - ? folderPath.getSize() : folderPath.getSize() - 1); - - // Parent folders - for (int i = 0 ; i < count ; ++i) - { - utility::file::path::component comp(folderPath[i]); - - // TODO: may not work with all encodings... - comp.setBuffer("." + comp.getBuffer() + ".directory"); - - path /= comp; - } - - // Last component - if (folderPath.getSize() != 0 && - mode != FOLDER_PATH_CONTAINER) - { - path /= folderPath.getLastComponent(); - - switch (mode) - { - case FOLDER_PATH_ROOT: break; // Nothing to do - case FOLDER_PATH_NEW: path /= NEW_DIR; break; - case FOLDER_PATH_CUR: path /= CUR_DIR; break; - case FOLDER_PATH_TMP: path /= TMP_DIR; break; - case FOLDER_PATH_CONTAINER: break; // Can't happen... - } - } - - return (path); -} - - -const bool maildirUtils::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); -} - - -const 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); -} - - -const utility::file::path::component maildirUtils::extractId - (const utility::file::path::component& filename) -{ - string::size_type sep = filename.getBuffer().rfind(':'); - if (sep == string::npos) return (filename); - - return (utility::path::component - (string(filename.getBuffer().begin(), filename.getBuffer().begin() + sep))); -} - - -const int maildirUtils::extractFlags(const utility::file::path::component& comp) -{ - string::size_type sep = comp.getBuffer().rfind(':'); - if (sep == string::npos) return (0); - - const string flagsString(comp.getBuffer().begin() + sep + 1, comp.getBuffer().end()); - const string::size_type count = flagsString.length(); - - int flags = 0; - - for (string::size_type 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; - } - } - - 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"; - - return (utility::file::path::component(str)); -} - - -const utility::file::path::component maildirUtils::buildFilename - (const utility::file::path::component& id, const int flags) -{ - return (buildFilename(id, buildFlags(flags))); -} - - -const utility::file::path::component maildirUtils::buildFilename - (const utility::file::path::component& id, const utility::file::path::component& flags) -{ - return (utility::path::component(id.getBuffer() + ":" + flags.getBuffer())); -} - - -const utility::file::path::component maildirUtils::generateId() -{ - std::ostringstream oss; - - oss << utility::random::getTime(); - oss << "."; - oss << utility::random::getProcess(); - oss << "."; - oss << utility::random::getString(6); - - return (utility::file::path::component(oss.str())); -} - - - -// -// messageIdComparator -// - -maildirUtils::messageIdComparator::messageIdComparator - (const utility::file::path::component& comp) - : m_comp(maildirUtils::extractId(comp)) -{ -} - - -const bool maildirUtils::messageIdComparator::operator() - (const utility::file::path::component& other) const -{ - return (m_comp == maildirUtils::extractId(other)); -} - - -} // maildir -} // messaging -} // vmime diff --git a/src/messaging/message.cpp b/src/messaging/message.cpp deleted file mode 100644 index 994adcdb..00000000 --- a/src/messaging/message.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/message.hpp" - - -namespace vmime { -namespace messaging { - - -const part& part::operator[](const int x) const -{ - return (getStructure()[x]); -} - - -part& part::operator[](const int x) -{ - return (getStructure()[x]); -} - - -const int part::getCount() const -{ - return (getStructure().getCount()); -} - - -} // messaging -} // vmime diff --git a/src/messaging/pop3/POP3Folder.cpp b/src/messaging/pop3/POP3Folder.cpp deleted file mode 100644 index ec2c9d52..00000000 --- a/src/messaging/pop3/POP3Folder.cpp +++ /dev/null @@ -1,826 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/pop3/POP3Folder.hpp" - -#include "vmime/messaging/pop3/POP3Store.hpp" -#include "vmime/messaging/pop3/POP3Message.hpp" - -#include "vmime/exception.hpp" - - -namespace vmime { -namespace messaging { -namespace pop3 { - - -POP3Folder::POP3Folder(const folder::path& path, POP3Store* store) - : m_store(store), m_path(path), - m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()), - m_mode(-1), m_open(false) -{ - m_store->registerFolder(this); -} - - -POP3Folder::~POP3Folder() -{ - if (m_store) - { - if (m_open) - close(false); - - m_store->unregisterFolder(this); - } - else if (m_open) - { - onClose(); - } -} - - -const int POP3Folder::getMode() const -{ - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - return (m_mode); -} - - -const 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(); -} - - -const 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) -{ - if (!m_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") - { - m_store->sendRequest("STAT"); - - string response; - m_store->readResponse(response, false); - - if (!m_store->isSuccessResponse(response)) - throw exceptions::command_error("STAT", response); - - m_store->stripResponseCode(response, response); - - std::istringstream iss(response); - iss >> m_messageCount; - - if (iss.fail()) - throw exceptions::invalid_response("STAT", response); - - m_open = true; - m_mode = mode; - } - else - { - throw exceptions::folder_not_found(); - } -} - -void POP3Folder::close(const bool expunge) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - if (!expunge) - { - m_store->sendRequest("RSET"); - - string response; - m_store->readResponse(response, false); - } - - 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(); -} - - -const bool POP3Folder::exists() -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - - return (m_path.isEmpty() || (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX")); -} - - -const bool POP3Folder::isOpen() const -{ - return (m_open); -} - - -ref POP3Folder::getMessage(const int num) -{ - if (!m_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 vmime::create (this, num); -} - - -std::vector > POP3Folder::getMessages(const int from, const int to) -{ - const int to2 = (to == -1 ? m_messageCount : to); - - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - else if (to2 < from || from < 1 || to2 < 1 || from > m_messageCount || to2 > m_messageCount) - throw exceptions::message_not_found(); - - std::vector > v; - - for (int i = from ; i <= to2 ; ++i) - v.push_back(vmime::create (this, i)); - - return (v); -} - - -std::vector > POP3Folder::getMessages(const std::vector & nums) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - std::vector > v; - - for (std::vector ::const_iterator it = nums.begin() ; it != nums.end() ; ++it) - { - if (*it < 1|| *it > m_messageCount) - throw exceptions::message_not_found(); - - v.push_back(vmime::create (this, *it)); - } - - return (v); -} - - -const int POP3Folder::getMessageCount() -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - return (m_messageCount); -} - - -ref POP3Folder::getFolder(const folder::path::component& name) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - - return vmime::create (m_path / name, m_store); -} - - -std::vector > POP3Folder::getFolders(const bool /* recursive */) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - - if (m_path.isEmpty()) - { - std::vector > v; - v.push_back(vmime::create (folder::path::component("INBOX"), m_store)); - return (v); - } - else - { - std::vector > v; - return (v); - } -} - - -void POP3Folder::fetchMessages(std::vector >& msg, const int options, - utility::progressionListener* progress) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - const int total = msg.size(); - int current = 0; - - if (progress) - progress->start(total); - - for (std::vector >::iterator it = msg.begin() ; - it != msg.end() ; ++it) - { - (*it).dynamicCast ()->fetch(this, options); - - if (progress) - progress->progress(++current, total); - } - - if (options & FETCH_SIZE) - { - // Send the "LIST" command - std::ostringstream command; - command << "LIST"; - - m_store->sendRequest(command.str()); - - // Get the response - string response; - m_store->readResponse(response, true, NULL); - - if (m_store->isSuccessResponse(response)) - { - m_store->stripFirstLine(response, response, NULL); - - // C: LIST - // S: +OK - // S: 1 47548 - // S: 2 12653 - // S: . - std::map result; - parseMultiListOrUidlResponse(response, result); - - for (std::vector >::iterator it = msg.begin() ; - it != msg.end() ; ++it) - { - ref m = (*it).dynamicCast (); - - std::map ::const_iterator x = result.find(m->m_num); - - if (x != result.end()) - { - int size = 0; - - std::istringstream iss((*x).second); - iss >> size; - - m->m_size = size; - } - } - } - - } - - if (options & FETCH_UID) - { - // Send the "UIDL" command - std::ostringstream command; - command << "UIDL"; - - m_store->sendRequest(command.str()); - - // Get the response - string response; - m_store->readResponse(response, true, NULL); - - if (m_store->isSuccessResponse(response)) - { - m_store->stripFirstLine(response, response, NULL); - - // C: UIDL - // S: +OK - // S: 1 whqtswO00WBw418f9t5JxYwZ - // S: 2 QhdPYR:00WBw1Ph7x7 - // S: . - std::map result; - parseMultiListOrUidlResponse(response, result); - - for (std::vector >::iterator it = msg.begin() ; - it != msg.end() ; ++it) - { - ref m = (*it).dynamicCast (); - - std::map ::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(ref msg, const int options) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - msg.dynamicCast ()->fetch(this, options); - - if (options & FETCH_SIZE) - { - // Send the "LIST" command - std::ostringstream command; - command << "LIST " << msg->getNumber(); - - m_store->sendRequest(command.str()); - - // Get the response - string response; - m_store->readResponse(response, false, NULL); - - if (m_store->isSuccessResponse(response)) - { - m_store->stripResponseCode(response, response); - - // C: LIST 2 - // S: +OK 2 4242 - string::iterator it = response.begin(); - - while (it != response.end() && (*it == ' ' || *it == '\t')) ++it; - while (it != response.end() && !(*it == ' ' || *it == '\t')) ++it; - while (it != response.end() && (*it == ' ' || *it == '\t')) ++it; - - if (it != response.end()) - { - int size = 0; - - std::istringstream iss(string(it, response.end())); - iss >> size; - - msg.dynamicCast ()->m_size = size; - } - } - } - - if (options & FETCH_UID) - { - // Send the "UIDL" command - std::ostringstream command; - command << "UIDL " << msg->getNumber(); - - m_store->sendRequest(command.str()); - - // Get the response - string response; - m_store->readResponse(response, false, NULL); - - if (m_store->isSuccessResponse(response)) - { - m_store->stripResponseCode(response, response); - - // C: UIDL 2 - // S: +OK 2 QhdPYR:00WBw1Ph7x7 - string::iterator it = response.begin(); - - while (it != response.end() && (*it == ' ' || *it == '\t')) ++it; - while (it != response.end() && !(*it == ' ' || *it == '\t')) ++it; - while (it != response.end() && (*it == ' ' || *it == '\t')) ++it; - - if (it != response.end()) - { - msg.dynamicCast ()->m_uid = - string(it, response.end()); - } - } - } -} - - -const int POP3Folder::getFetchCapabilities() const -{ - return (FETCH_ENVELOPE | FETCH_CONTENT_INFO | - FETCH_SIZE | FETCH_FULL_HEADER | FETCH_UID | - FETCH_IMPORTANCE); -} - - -ref POP3Folder::getParent() -{ - if (m_path.isEmpty()) - return NULL; - else - return vmime::create (m_path.getParent(), m_store); -} - - -weak_ref POP3Folder::getStore() const -{ - return (m_store); -} - - -weak_ref POP3Folder::getStore() -{ - return (m_store); -} - - -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 = NULL; -} - - -void POP3Folder::deleteMessage(const int num) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - std::ostringstream command; - command << "DELE " << num; - - m_store->sendRequest(command.str()); - - string response; - m_store->readResponse(response, false); - - if (!m_store->isSuccessResponse(response)) - throw exceptions::command_error("DELE", response); - - // Update local flags - for (std::map ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - POP3Message* msg = (*it).first; - - if (msg->getNumber() == num) - msg->m_deleted = true; - } - - // Notify message flags changed - std::vector nums; - nums.push_back(num); - - events::messageChangedEvent event - (thisRef().dynamicCast (), - events::messageChangedEvent::TYPE_FLAGS, nums); - - notifyMessageChanged(event); -} - - -void POP3Folder::deleteMessages(const int from, const int to) -{ - if (from < 1 || (to < from && to != -1)) - throw exceptions::invalid_argument(); - - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - const int to2 = (to == -1 ? m_messageCount : to); - - for (int i = from ; i <= to2 ; ++i) - { - std::ostringstream command; - command << "DELE " << i; - - m_store->sendRequest(command.str()); - - string response; - m_store->readResponse(response, false); - - if (!m_store->isSuccessResponse(response)) - throw exceptions::command_error("DELE", response); - } - - // Update local flags - for (std::map ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - POP3Message* msg = (*it).first; - - if (msg->getNumber() >= from && msg->getNumber() <= to2) - msg->m_deleted = true; - } - - // Notify message flags changed - std::vector nums; - - for (int i = from ; i <= to2 ; ++i) - nums.push_back(i); - - events::messageChangedEvent event - (thisRef().dynamicCast (), - events::messageChangedEvent::TYPE_FLAGS, nums); - - notifyMessageChanged(event); -} - - -void POP3Folder::deleteMessages(const std::vector & nums) -{ - if (nums.empty()) - throw exceptions::invalid_argument(); - - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - for (std::vector ::const_iterator - it = nums.begin() ; it != nums.end() ; ++it) - { - std::ostringstream command; - command << "DELE " << (*it); - - m_store->sendRequest(command.str()); - - string response; - m_store->readResponse(response, false); - - if (!m_store->isSuccessResponse(response)) - throw exceptions::command_error("DELE", response); - } - - // Sort message list - std::vector 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 ::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 - events::messageChangedEvent event - (thisRef().dynamicCast (), - events::messageChangedEvent::TYPE_FLAGS, list); - - notifyMessageChanged(event); -} - - -void POP3Folder::setMessageFlags(const int /* from */, const int /* to */, - const int /* flags */, const int /* mode */) -{ - throw exceptions::operation_not_supported(); -} - - -void POP3Folder::setMessageFlags(const std::vector & /* nums */, - 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(ref /* msg */, const int /* flags */, - vmime::datetime* /* date */, utility::progressionListener* /* progress */) -{ - throw exceptions::operation_not_supported(); -} - - -void POP3Folder::addMessage(utility::inputStream& /* is */, const int /* size */, const int /* flags */, - vmime::datetime* /* date */, utility::progressionListener* /* progress */) -{ - throw exceptions::operation_not_supported(); -} - - -void POP3Folder::copyMessage(const folder::path& /* dest */, const int /* num */) -{ - throw exceptions::operation_not_supported(); -} - - -void POP3Folder::copyMessages(const folder::path& /* dest */, const int /* from */, const int /* to */) -{ - throw exceptions::operation_not_supported(); -} - - -void POP3Folder::copyMessages(const folder::path& /* dest */, const std::vector & /* nums */) -{ - throw exceptions::operation_not_supported(); -} - - -void POP3Folder::status(int& count, int& unseen) -{ - if (!m_store) - throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); - - m_store->sendRequest("STAT"); - - string response; - m_store->readResponse(response, false); - - if (!m_store->isSuccessResponse(response)) - throw exceptions::command_error("STAT", response); - - m_store->stripResponseCode(response, response); - - std::istringstream iss(response); - iss >> count; - - unseen = count; - - // Update local message count - if (m_messageCount != count) - { - const int oldCount = m_messageCount; - - m_messageCount = count; - - if (count > oldCount) - { - std::vector nums; - nums.reserve(count - oldCount); - - for (int i = oldCount + 1, j = 0 ; i <= count ; ++i, ++j) - nums[j] = i; - - // Notify message count changed - events::messageCountEvent event - (thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - notifyMessageCount(event); - - // Notify folders with the same path - for (std::list ::iterator it = m_store->m_folders.begin() ; - it != m_store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == m_path) - { - (*it)->m_messageCount = count; - - events::messageCountEvent event - ((*it)->thisRef().dynamicCast (), - events::messageCountEvent::TYPE_ADDED, nums); - - (*it)->notifyMessageCount(event); - } - } - } - } -} - - -void POP3Folder::expunge() -{ - // Not supported by POP3 protocol (deleted messages are automatically - // expunged at the end of the session...). -} - - -void POP3Folder::parseMultiListOrUidlResponse(const string& response, std::map & result) -{ - std::istringstream iss(response); - std::map ids; - - string line; - - while (std::getline(iss, line)) - { - 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 ::value_type(number, string(it, line.end()))); - } - } - } -} - - -} // pop3 -} // messaging -} // vmime diff --git a/src/messaging/pop3/POP3Message.cpp b/src/messaging/pop3/POP3Message.cpp deleted file mode 100644 index ed8999e3..00000000 --- a/src/messaging/pop3/POP3Message.cpp +++ /dev/null @@ -1,213 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/pop3/POP3Message.hpp" -#include "vmime/messaging/pop3/POP3Folder.hpp" -#include "vmime/messaging/pop3/POP3Store.hpp" - -#include - - -namespace vmime { -namespace messaging { -namespace pop3 { - - -POP3Message::POP3Message(POP3Folder* folder, const int num) - : m_folder(folder), m_num(num), m_size(-1), m_deleted(false) -{ - m_folder->registerMessage(this); -} - - -POP3Message::~POP3Message() -{ - if (m_folder) - m_folder->unregisterMessage(this); -} - - -void POP3Message::onFolderClosed() -{ - m_folder = NULL; -} - - -const int POP3Message::getNumber() const -{ - return (m_num); -} - - -const message::uid POP3Message::getUniqueId() const -{ - return (m_uid); -} - - -const int POP3Message::getSize() const -{ - if (m_size == -1) - throw exceptions::unfetched_object(); - - return (m_size); -} - - -const bool POP3Message::isExpunged() const -{ - return (false); -} - - -const int POP3Message::getFlags() const -{ - int flags = FLAG_RECENT; - - if (m_deleted) - flags |= FLAG_DELETED; - - return (flags); -} - - -const structure& POP3Message::getStructure() const -{ - throw exceptions::operation_not_supported(); -} - - -structure& POP3Message::getStructure() -{ - throw exceptions::operation_not_supported(); -} - - -ref POP3Message::getHeader() const -{ - if (m_header == NULL) - throw exceptions::unfetched_object(); - - return (m_header); -} - - -void POP3Message::extract(utility::outputStream& os, - utility::progressionListener* progress, const int start, - const int length, const bool /* peek */) const -{ - if (!m_folder) - throw exceptions::illegal_state("Folder closed"); - else if (!m_folder->m_store) - throw exceptions::illegal_state("Store disconnected"); - - if (start != 0 && length != -1) - throw exceptions::partial_fetch_not_supported(); - - // Emit the "RETR" command - std::ostringstream oss; - oss << "RETR " << m_num; - - const_cast (m_folder)->m_store->sendRequest(oss.str()); - - try - { - POP3Folder::MessageMap::const_iterator it = - m_folder->m_messages.find(const_cast (this)); - - const int totalSize = (it != m_folder->m_messages.end()) - ? (*it).second : 0; - - const_cast (m_folder)->m_store-> - readResponse(os, progress, totalSize); - } - catch (exceptions::command_error& e) - { - throw exceptions::command_error("RETR", e.response()); - } -} - - -void POP3Message::extractPart - (const part& /* p */, utility::outputStream& /* os */, - utility::progressionListener* /* progress */, - const int /* start */, const int /* length */, - const bool /* peek */) const -{ - throw exceptions::operation_not_supported(); -} - - -void POP3Message::fetchPartHeader(part& /* p */) -{ - throw exceptions::operation_not_supported(); -} - - -void POP3Message::fetch(POP3Folder* folder, const int options) -{ - if (m_folder != folder) - throw exceptions::folder_not_found(); - - // FETCH_STRUCTURE and FETCH_FLAGS are not supported by POP3. - if (options & (folder::FETCH_STRUCTURE | folder::FETCH_FLAGS)) - throw exceptions::operation_not_supported(); - - // Check for the real need to fetch the full header - static const int optionsRequiringHeader = - folder::FETCH_ENVELOPE | folder::FETCH_CONTENT_INFO | - folder::FETCH_FULL_HEADER | folder::FETCH_IMPORTANCE; - - if (!(options & optionsRequiringHeader)) - return; - - // No need to differenciate between FETCH_ENVELOPE, - // FETCH_CONTENT_INFO, ... since POP3 only permits to - // retrieve the whole header and not fields in particular. - - // Emit the "TOP" command - std::ostringstream oss; - oss << "TOP " << m_num << " 0"; - - m_folder->m_store->sendRequest(oss.str()); - - try - { - string buffer; - m_folder->m_store->readResponse(buffer, true); - - m_header = vmime::create
(); - 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(); -} - - -} // pop3 -} // messaging -} // vmime diff --git a/src/messaging/pop3/POP3Store.cpp b/src/messaging/pop3/POP3Store.cpp deleted file mode 100644 index 1407df35..00000000 --- a/src/messaging/pop3/POP3Store.cpp +++ /dev/null @@ -1,630 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/pop3/POP3Store.hpp" -#include "vmime/messaging/pop3/POP3Folder.hpp" - -#include "vmime/exception.hpp" -#include "vmime/platformDependant.hpp" -#include "vmime/messageId.hpp" -#include "vmime/utility/md5.hpp" -#include "vmime/utility/filteredStream.hpp" - -#include - - -// Helpers for service properties -#define GET_PROPERTY(type, prop) \ - (sm_infos.getPropertyValue (getSession(), sm_infos.getProperties().prop)) -#define HAS_PROPERTY(prop) \ - (sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop)) - - -namespace vmime { -namespace messaging { -namespace pop3 { - - -POP3Store::POP3Store(ref sess, ref auth) - : store(sess, getInfosInstance(), auth), m_socket(NULL), - m_authentified(false), m_timeoutHandler(NULL) -{ -} - - -POP3Store::~POP3Store() -{ - if (isConnected()) - disconnect(); - else if (m_socket) - internalDisconnect(); -} - - -const string POP3Store::getProtocolName() const -{ - return "pop3"; -} - - -ref POP3Store::getDefaultFolder() -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); - - return vmime::create (folder::path(folder::path::component("INBOX")), this); -} - - -ref POP3Store::getRootFolder() -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); - - return vmime::create (folder::path(), this); -} - - -ref POP3Store::getFolder(const folder::path& path) -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); - - return vmime::create (path, this); -} - - -const bool POP3Store::isValidFolderName(const folder::path::component& /* name */) const -{ - return true; -} - - -void POP3Store::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); - - // Create the time-out handler - if (HAS_PROPERTY(PROPERTY_TIMEOUT_FACTORY)) - { - timeoutHandlerFactory* tof = platformDependant::getHandler()-> - getTimeoutHandlerFactory(GET_PROPERTY(string, PROPERTY_TIMEOUT_FACTORY)); - - m_timeoutHandler = tof->create(); - } - - // Create and connect the socket - socketFactory* sf = platformDependant::getHandler()-> - getSocketFactory(GET_PROPERTY(string, PROPERTY_SERVER_SOCKETFACTORY)); - - m_socket = sf->create(); - m_socket->connect(address, port); - - // Connection - // - // eg: C: - // --- S: +OK MailSite POP3 Server 5.3.4.0 Ready <36938848.1056800841.634@somewhere.com> - - string response; - readResponse(response, false); - - if (isSuccessResponse(response)) - { - bool authentified = false; - - const authenticationInfos auth = getAuthenticator()->requestAuthInfos(); - - // Secured authentication with APOP (if requested and if available) - // - // eg: C: APOP vincent - // --- S: +OK vincent is a valid mailbox - messageId mid(response); - - if (GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP)) - { - if (mid.getLeft().length() && mid.getRight().length()) - { - // is the result of MD5 applied to "password" - sendRequest("APOP " + auth.getUsername() + " " - + utility::md5(mid.generate() + auth.getPassword()).hex()); - readResponse(response, false); - - if (isSuccessResponse(response)) - { - authentified = true; - } - else - { - if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP_FALLBACK)) - { - internalDisconnect(); - throw exceptions::authentication_error(response); - } - } - } - else - { - // APOP not supported - if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP_FALLBACK)) - { - // Can't fallback on basic authentification - internalDisconnect(); - throw exceptions::unsupported_option(); - } - } - } - - if (!authentified) - { - // 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) - - sendRequest("USER " + auth.getUsername()); - readResponse(response, false); - - if (isSuccessResponse(response)) - { - sendRequest("PASS " + auth.getPassword()); - readResponse(response, false); - - if (!isSuccessResponse(response)) - { - internalDisconnect(); - throw exceptions::authentication_error(response); - } - } - else - { - internalDisconnect(); - throw exceptions::authentication_error(response); - } - } - } - else - { - internalDisconnect(); - throw exceptions::connection_greeting_error(response); - } - - m_authentified = true; -} - - -const bool POP3Store::isConnected() const -{ - return (m_socket && m_socket->isConnected() && m_authentified); -} - - -void POP3Store::disconnect() -{ - if (!isConnected()) - throw exceptions::not_connected(); - - internalDisconnect(); -} - - -void POP3Store::internalDisconnect() -{ - for (std::list ::iterator it = m_folders.begin() ; - it != m_folders.end() ; ++it) - { - (*it)->onStoreDisconnected(); - } - - m_folders.clear(); - - - sendRequest("QUIT"); - - m_socket->disconnect(); - m_socket = NULL; - - m_timeoutHandler = NULL; - - m_authentified = false; -} - - -void POP3Store::noop() -{ - m_socket->send("NOOP"); - - string response; - readResponse(response, false); - - if (!isSuccessResponse(response)) - throw exceptions::command_error("NOOP", response); -} - - -const bool POP3Store::isSuccessResponse(const string& buffer) -{ - static const string OK("+OK"); - - return (buffer.length() >= 3 && - std::equal(buffer.begin(), buffer.begin() + 3, OK.begin())); -} - - -const bool POP3Store::stripFirstLine(const string& buffer, string& result, string* firstLine) -{ - const string::size_type end = buffer.find('\n'); - - if (end != string::npos) - { - if (firstLine) *firstLine = buffer.substr(0, end); - result = buffer.substr(end + 1); - return (true); - } - else - { - result = buffer; - return (false); - } -} - - -void POP3Store::stripResponseCode(const string& buffer, string& result) -{ - const string::size_type pos = buffer.find_first_of(" \t"); - - if (pos != string::npos) - result = buffer.substr(pos + 1); - else - result = buffer; -} - - -void POP3Store::sendRequest(const string& buffer, const bool end) -{ - if (end) - m_socket->send(buffer + "\r\n"); - else - m_socket->send(buffer); -} - - -void POP3Store::readResponse(string& buffer, const bool multiLine, - utility::progressionListener* progress) -{ - bool foundTerminator = false; - int current = 0, total = 0; - - if (progress) - progress->start(total); - - if (m_timeoutHandler) - m_timeoutHandler->resetTimeOut(); - - buffer.clear(); - - string::value_type last1 = '\0', last2 = '\0'; - - for ( ; !foundTerminator ; ) - { -#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 - string receiveBuffer; - m_socket->receive(receiveBuffer); - - if (receiveBuffer.empty()) // buffer is empty - { - platformDependant::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 string::value_type 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 (string::size_type trans ; - string::npos != (trans = receiveBuffer.find("\n..")) ; ) - { - receiveBuffer.replace(trans, 3, "\n."); - } - - last1 = receiveBuffer[receiveBuffer.length() - 1]; - last2 = (receiveBuffer.length() >= 2) ? receiveBuffer[receiveBuffer.length() - 2] : 0; - - // Append the data to the response buffer - buffer += receiveBuffer; - current += receiveBuffer.length(); - - // Check for terminator string (and strip it if present) - foundTerminator = checkTerminator(buffer, multiLine); - - // Notify progression - if (progress) - { - total = std::max(total, current); - progress->progress(current, total); - } - - // 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); - } - } - - if (progress) - progress->stop(total); -} - - -void POP3Store::readResponse(utility::outputStream& os, - utility::progressionListener* progress, const int predictedSize) -{ - int 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 - utility::stream::value_type buffer[65536]; - const utility::stream::size_type read = is.read(buffer, sizeof(buffer)); - - if (read == 0) // buffer is empty - { - platformDependant::getHandler()->wait(); - continue; - } - - // We have received data: reset the time-out counter - if (m_timeoutHandler) - m_timeoutHandler->resetTimeOut(); - - // If we don't have extracted the response code yet - if (!codeDone) - { - temp += string(buffer, read); - - string firstLine; - - if (stripFirstLine(temp, temp, &firstLine) == true) - { - if (!isSuccessResponse(firstLine)) - throw exceptions::command_error("?", firstLine); - - codeDone = true; - - os.write(temp.data(), temp.length()); - temp.clear(); - - continue; - } - } - else - { - // Inject the data into the output stream - os.write(buffer, read); - current += read; - - // Notify progression - if (progress) - { - total = std::max(total, current); - progress->progress(current, total); - } - } - } - - if (progress) - progress->stop(total); -} - - -const bool POP3Store::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); -} - - -const bool POP3Store::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); -} - - -void POP3Store::registerFolder(POP3Folder* folder) -{ - m_folders.push_back(folder); -} - - -void POP3Store::unregisterFolder(POP3Folder* folder) -{ - std::list ::iterator it = std::find(m_folders.begin(), m_folders.end(), folder); - if (it != m_folders.end()) m_folders.erase(it); -} - - -const int POP3Store::getCapabilities() const -{ - return (CAPABILITY_DELETE_MESSAGE); -} - - - -// Service infos - -POP3Store::_infos POP3Store::sm_infos; - - -const serviceInfos& POP3Store::getInfosInstance() -{ - return (sm_infos); -} - - -const serviceInfos& POP3Store::getInfos() const -{ - return (sm_infos); -} - - -const string POP3Store::_infos::getPropertyPrefix() const -{ - return "store.pop3."; -} - - -const POP3Store::_infos::props& POP3Store::_infos::getProperties() const -{ - static props p = - { - // POP3-specific options - property("options.apop", serviceInfos::property::TYPE_BOOL, "false"), - property("options.apop.fallback", serviceInfos::property::TYPE_BOOL, "false"), - - // Common properties - property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED), - property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED), - - property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED), - property(serviceInfos::property::SERVER_PORT, "110"), - property(serviceInfos::property::SERVER_SOCKETFACTORY), - - property(serviceInfos::property::TIMEOUT_FACTORY) - }; - - return p; -} - - -const std::vector POP3Store::_infos::getAvailableProperties() const -{ - std::vector list; - const props& p = getProperties(); - - // POP3-specific options - list.push_back(p.PROPERTY_OPTIONS_APOP); - list.push_back(p.PROPERTY_OPTIONS_APOP_FALLBACK); - - // Common properties - list.push_back(p.PROPERTY_AUTH_USERNAME); - list.push_back(p.PROPERTY_AUTH_PASSWORD); - - list.push_back(p.PROPERTY_SERVER_ADDRESS); - list.push_back(p.PROPERTY_SERVER_PORT); - list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY); - - list.push_back(p.PROPERTY_TIMEOUT_FACTORY); - - return (list); -} - - -} // pop3 -} // messaging -} // vmime - diff --git a/src/messaging/sendmail/sendmailTransport.cpp b/src/messaging/sendmail/sendmailTransport.cpp deleted file mode 100644 index e9b8256b..00000000 --- a/src/messaging/sendmail/sendmailTransport.cpp +++ /dev/null @@ -1,222 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/sendmail/sendmailTransport.hpp" - -#include "vmime/exception.hpp" -#include "vmime/platformDependant.hpp" -#include "vmime/message.hpp" -#include "vmime/mailboxList.hpp" - -#include "vmime/utility/filteredStream.hpp" -#include "vmime/utility/childProcess.hpp" -#include "vmime/utility/smartPtr.hpp" - -#include "vmime/config.hpp" - - -// Helpers for service properties -#define GET_PROPERTY(type, prop) \ - (sm_infos.getPropertyValue (getSession(), sm_infos.getProperties().prop)) -#define HAS_PROPERTY(prop) \ - (sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop)) - - -#if VMIME_BUILTIN_PLATFORM_POSIX - - -namespace vmime { -namespace messaging { -namespace sendmail { - - -sendmailTransport::sendmailTransport(ref sess, ref auth) - : transport(sess, getInfosInstance(), auth), m_connected(false) -{ -} - - -sendmailTransport::~sendmailTransport() -{ - if (isConnected()) - disconnect(); -} - - -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; -} - - -const bool sendmailTransport::isConnected() const -{ - return (m_connected); -} - - -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 utility::stream::size_type size, - utility::progressionListener* progress) -{ - // 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 args; - - args.push_back("-i"); - args.push_back("-f"); - args.push_back(expeditor.getEmail()); - args.push_back("--"); - - for (int i = 0 ; i < recipients.getMailboxCount() ; ++i) - args.push_back(recipients.getMailboxAt(i)->getEmail()); - - // 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 args, utility::inputStream& is, - const utility::stream::size_type size, utility::progressionListener* progress) -{ - const utility::file::path path = vmime::platformDependant::getHandler()-> - getFileSystemFactory()->stringToPath(m_sendmailPath); - - ref proc = - vmime::platformDependant::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 - -sendmailTransport::_infos sendmailTransport::sm_infos; - - -const serviceInfos& sendmailTransport::getInfosInstance() -{ - return (sm_infos); -} - - -const serviceInfos& sendmailTransport::getInfos() const -{ - return (sm_infos); -} - - -const string sendmailTransport::_infos::getPropertyPrefix() const -{ - return "transport.sendmail."; -} - - -const sendmailTransport::_infos::props& sendmailTransport::_infos::getProperties() const -{ - static props p = - { - // Path to sendmail (override default) - property("binpath", serviceInfos::property::TYPE_STRING, string(VMIME_SENDMAIL_PATH)) - }; - - return p; -} - - -const std::vector sendmailTransport::_infos::getAvailableProperties() const -{ - std::vector list; - const props& p = getProperties(); - - list.push_back(p.PROPERTY_BINPATH); - - return (list); -} - - -} // sendmail -} // messaging -} // vmime - - -#endif // VMIME_BUILTIN_PLATFORM_POSIX diff --git a/src/messaging/service.cpp b/src/messaging/service.cpp deleted file mode 100644 index eab4db8a..00000000 --- a/src/messaging/service.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/service.hpp" - -#include "vmime/messaging/defaultAuthenticator.hpp" - - -namespace vmime { -namespace messaging { - - -service::service(ref sess, const serviceInfos& infos, ref auth) - : m_session(sess), m_auth(auth) -{ - if (!auth) - { - m_auth = vmime::create - (sess, infos.getPropertyPrefix()); - } -} - - -service::~service() -{ -} - - -ref service::getSession() const -{ - return (m_session); -} - - -ref service::getSession() -{ - return (m_session); -} - - -ref service::getAuthenticator() const -{ - return (m_auth); -} - - -ref service::getAuthenticator() -{ - return (m_auth); -} - - -} // messaging -} // vmime diff --git a/src/messaging/serviceFactory.cpp b/src/messaging/serviceFactory.cpp deleted file mode 100644 index a706b0ba..00000000 --- a/src/messaging/serviceFactory.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/serviceFactory.hpp" -#include "vmime/messaging/service.hpp" - -#include "vmime/exception.hpp" -#include "vmime/config.hpp" - -#include "src/messaging/builtinServices.inl" - - -namespace vmime { -namespace messaging { - - -serviceFactory::serviceFactory() -{ -} - - -serviceFactory::~serviceFactory() -{ -} - - -serviceFactory* serviceFactory::getInstance() -{ - static serviceFactory instance; - return (&instance); -} - - -ref serviceFactory::create - (ref sess, const string& protocol, ref auth) -{ - return (getServiceByProtocol(protocol)->create(sess, auth)); -} - - -ref serviceFactory::create - (ref sess, const utility::url& u, ref auth) -{ - ref 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); -} - - -ref serviceFactory::getServiceByProtocol(const string& protocol) const -{ - const string name(utility::stringUtils::toLower(protocol)); - - for (std::vector >::const_iterator it = m_services.begin() ; - it != m_services.end() ; ++it) - { - if ((*it)->getName() == name) - return (*it); - } - - throw exceptions::no_service_available(name); -} - - -const int serviceFactory::getServiceCount() const -{ - return (m_services.size()); -} - - -ref serviceFactory::getServiceAt(const int pos) const -{ - return (m_services[pos]); -} - - -const std::vector > serviceFactory::getServiceList() const -{ - std::vector > res; - - for (std::vector >::const_iterator it = m_services.begin() ; - it != m_services.end() ; ++it) - { - res.push_back(*it); - } - - return (res); -} - - -} // messaging -} // vmime diff --git a/src/messaging/serviceInfos.cpp b/src/messaging/serviceInfos.cpp deleted file mode 100644 index a8359fd0..00000000 --- a/src/messaging/serviceInfos.cpp +++ /dev/null @@ -1,150 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/serviceInfos.hpp" - - -namespace vmime { -namespace messaging { - - -// 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::SERVER_SOCKETFACTORY - ("server.socket-factory", serviceInfos::property::TYPE_STRING, "default"); - -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); - -const serviceInfos::property serviceInfos::property::TIMEOUT_FACTORY - ("timeout.factory", serviceInfos::property::TYPE_STRING); - - - -// serviceInfos - -serviceInfos::serviceInfos() -{ -} - - -serviceInfos::serviceInfos(const serviceInfos&) -{ -} - - -serviceInfos& serviceInfos::operator=(const serviceInfos&) -{ - return (*this); -} - - -serviceInfos::~serviceInfos() -{ -} - - -const bool serviceInfos::hasProperty(ref 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); -} - - -const serviceInfos::property::Types serviceInfos::property::getType() const -{ - return (m_type); -} - - -const int serviceInfos::property::getFlags() const -{ - return (m_flags); -} - - -} // messaging -} // vmime - diff --git a/src/messaging/session.cpp b/src/messaging/session.cpp deleted file mode 100644 index 12aca36d..00000000 --- a/src/messaging/session.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/session.hpp" -#include "vmime/messaging/serviceFactory.hpp" - -#include "vmime/messaging/store.hpp" -#include "vmime/messaging/transport.hpp" - - -namespace vmime { -namespace messaging { - - -session::session() -{ -} - - -session::session(const session& sess) - : object(), m_props(sess.m_props) -{ -} - - -session::session(const propertySet& props) - : m_props(props) -{ -} - - -session::~session() -{ -} - - -ref session::getTransport(ref auth) -{ - return (getTransport(m_props["transport.protocol"], auth)); -} - - -ref session::getTransport(const string& protocol, ref auth) -{ - ref sess = thisRef().dynamicCast (); - ref sv = serviceFactory::getInstance()->create(sess, protocol, auth); - - if (sv->getType() != service::TYPE_TRANSPORT) - throw exceptions::no_service_available(); - - return sv.staticCast (); -} - - -ref session::getTransport(const utility::url& url, ref auth) -{ - ref sess = thisRef().dynamicCast (); - ref sv = serviceFactory::getInstance()->create(sess, url, auth); - - if (sv->getType() != service::TYPE_TRANSPORT) - throw exceptions::no_service_available(); - - return sv.staticCast (); -} - - -ref session::getStore(ref auth) -{ - return (getStore(m_props["store.protocol"], auth)); -} - - -ref session::getStore(const string& protocol, ref auth) -{ - ref sess = thisRef().dynamicCast (); - ref sv = serviceFactory::getInstance()->create(sess, protocol, auth); - - if (sv->getType() != service::TYPE_STORE) - throw exceptions::no_service_available(); - - return sv.staticCast (); -} - - -ref session::getStore(const utility::url& url, ref auth) -{ - ref sess = thisRef().dynamicCast (); - ref sv = serviceFactory::getInstance()->create(sess, url, auth); - - if (sv->getType() != service::TYPE_STORE) - throw exceptions::no_service_available(); - - return sv.staticCast (); -} - - -const propertySet& session::getProperties() const -{ - return (m_props); -} - - -propertySet& session::getProperties() -{ - return (m_props); -} - - -} // messaging -} // vmime diff --git a/src/messaging/simpleAuthenticator.cpp b/src/messaging/simpleAuthenticator.cpp deleted file mode 100644 index 1dee6cae..00000000 --- a/src/messaging/simpleAuthenticator.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/simpleAuthenticator.hpp" - - -namespace vmime { -namespace messaging { - - -simpleAuthenticator::simpleAuthenticator() -{ -} - - -simpleAuthenticator::simpleAuthenticator(const string& username, const string& password) - : m_username(username), m_password(password) -{ -} - - -const authenticationInfos simpleAuthenticator::getAuthInfos() const -{ - return (authenticationInfos(m_username, m_password)); -} - - -const string& simpleAuthenticator::getUsername() const -{ - return (m_username); -} - - -void simpleAuthenticator::setUsername(const string& username) -{ - m_username = username; -} - - -const string& simpleAuthenticator::getPassword() const -{ - return (m_password); -} - - -void simpleAuthenticator::setPassword(const string& password) -{ - m_password = password; -} - - -} // messaging -} // vmime diff --git a/src/messaging/smtp/SMTPTransport.cpp b/src/messaging/smtp/SMTPTransport.cpp deleted file mode 100644 index 5613a47d..00000000 --- a/src/messaging/smtp/SMTPTransport.cpp +++ /dev/null @@ -1,503 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/smtp/SMTPTransport.hpp" - -#include "vmime/exception.hpp" -#include "vmime/platformDependant.hpp" -#include "vmime/encoderB64.hpp" -#include "vmime/mailboxList.hpp" - -#include "vmime/messaging/authHelper.hpp" - -#include "vmime/utility/filteredStream.hpp" - - -// Helpers for service properties -#define GET_PROPERTY(type, prop) \ - (sm_infos.getPropertyValue (getSession(), sm_infos.getProperties().prop)) -#define HAS_PROPERTY(prop) \ - (sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop)) - - -namespace vmime { -namespace messaging { -namespace smtp { - - -SMTPTransport::SMTPTransport(ref sess, ref auth) - : transport(sess, getInfosInstance(), auth), m_socket(NULL), - m_authentified(false), m_extendedSMTP(false), m_timeoutHandler(NULL) -{ -} - - -SMTPTransport::~SMTPTransport() -{ - if (isConnected()) - disconnect(); - else if (m_socket) - internalDisconnect(); -} - - -const string SMTPTransport::getProtocolName() const -{ - return "smtp"; -} - - -void SMTPTransport::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); - - // Create the time-out handler - if (HAS_PROPERTY(PROPERTY_TIMEOUT_FACTORY)) - { - timeoutHandlerFactory* tof = platformDependant::getHandler()-> - getTimeoutHandlerFactory(GET_PROPERTY(string, PROPERTY_TIMEOUT_FACTORY)); - - m_timeoutHandler = tof->create(); - } - - // Create and connect the socket - socketFactory* sf = platformDependant::getHandler()-> - getSocketFactory(GET_PROPERTY(string, PROPERTY_SERVER_SOCKETFACTORY)); - - m_socket = sf->create(); - m_socket->connect(address, port); - - // Connection - // - // eg: C: - // --- S: 220 smtp.domain.com Service ready - - string response; - readResponse(response); - - if (responseCode(response) != 220) - { - internalDisconnect(); - throw exceptions::connection_greeting_error(response); - } - - // Identification - // First, try Extended SMTP (ESMTP) - // - // eg: C: EHLO thismachine.ourdomain.com - // S: 250 OK - - sendRequest("EHLO " + platformDependant::getHandler()->getHostName()); - readResponse(response); - - if (responseCode(response) != 250) - { - // Next, try "Basic" SMTP - // - // eg: C: HELO thismachine.ourdomain.com - // S: 250 OK - - sendRequest("HELO " + platformDependant::getHandler()->getHostName()); - readResponse(response); - - if (responseCode(response) != 250) - { - internalDisconnect(); - throw exceptions::connection_greeting_error(response); - } - - m_extendedSMTP = false; - } - else - { - m_extendedSMTP = true; - } - - // Authentication - if (GET_PROPERTY(bool, PROPERTY_OPTIONS_NEEDAUTH)) - { - if (!m_extendedSMTP) - { - internalDisconnect(); - throw exceptions::command_error("AUTH", "ESMTP not supported."); - } - - const authenticationInfos auth = getAuthenticator()->requestAuthInfos(); - bool authentified = false; - - enum AuthMethods - { - First = 0, - CRAM_MD5 = First, - // TODO: more authentication methods... - End - }; - - for (int currentMethod = First ; !authentified ; ++currentMethod) - { - switch (currentMethod) - { - case CRAM_MD5: - { - sendRequest("AUTH CRAM-MD5"); - readResponse(response); - - if (responseCode(response) == 334) - { - encoderB64 base64; - - string challengeB64 = responseText(response); - string challenge, challengeHex; - - { - utility::inputStreamStringAdapter in(challengeB64); - utility::outputStreamStringAdapter out(challenge); - - base64.decode(in, out); - } - - hmac_md5(challenge, auth.getPassword(), challengeHex); - - string decoded = auth.getUsername() + " " + challengeHex; - string encoded; - - { - utility::inputStreamStringAdapter in(decoded); - utility::outputStreamStringAdapter out(encoded); - - base64.encode(in, out); - } - - sendRequest(encoded); - readResponse(response); - - if (responseCode(response) == 235) - { - authentified = true; - } - else - { - internalDisconnect(); - throw exceptions::authentication_error(response); - } - } - - break; - } - case End: - { - // All authentication methods have been tried and - // the server does not understand any. - throw exceptions::authentication_error(response); - } - - } - } - } - - m_authentified = true; -} - - -const bool SMTPTransport::isConnected() const -{ - return (m_socket && m_socket->isConnected() && m_authentified); -} - - -void SMTPTransport::disconnect() -{ - if (!isConnected()) - throw exceptions::not_connected(); - - internalDisconnect(); -} - - -void SMTPTransport::internalDisconnect() -{ - sendRequest("QUIT"); - - m_socket->disconnect(); - m_socket = NULL; - - m_timeoutHandler = NULL; - - m_authentified = false; - m_extendedSMTP = false; -} - - -void SMTPTransport::noop() -{ - m_socket->send("NOOP"); - - string response; - readResponse(response); - - if (responseCode(response) != 250) - throw exceptions::command_error("NOOP", response); -} - - -void SMTPTransport::send(const mailbox& expeditor, const mailboxList& recipients, - utility::inputStream& is, const utility::stream::size_type size, - utility::progressionListener* progress) -{ - // If no recipient/expeditor was found, throw an exception - if (recipients.isEmpty()) - throw exceptions::no_recipient(); - else if (expeditor.isEmpty()) - throw exceptions::no_expeditor(); - - // Emit the "MAIL" command - string response; - - sendRequest("MAIL FROM: <" + expeditor.getEmail() + ">"); - readResponse(response); - - if (responseCode(response) != 250) - { - internalDisconnect(); - throw exceptions::command_error("MAIL", response); - } - - // Emit a "RCPT TO" command for each recipient - for (int i = 0 ; i < recipients.getMailboxCount() ; ++i) - { - const mailbox& mbox = *recipients.getMailboxAt(i); - - sendRequest("RCPT TO: <" + mbox.getEmail() + ">"); - readResponse(response); - - if (responseCode(response) != 250) - { - internalDisconnect(); - throw exceptions::command_error("RCPT TO", response); - } - } - - // Send the message data - sendRequest("DATA"); - readResponse(response); - - if (responseCode(response) != 354) - { - internalDisconnect(); - throw exceptions::command_error("DATA", response); - } - - // Stream copy with "\n." to "\n.." transformation - utility::outputStreamSocketAdapter sos(*m_socket); - utility::dotFilteredOutputStream fos(sos); - - utility::bufferedStreamCopy(is, fos, size, progress); - - // Send end-of-data delimiter - m_socket->sendRaw("\r\n.\r\n", 5); - readResponse(response); - - if (responseCode(response) != 250) - { - internalDisconnect(); - throw exceptions::command_error("DATA", response); - } -} - - -void SMTPTransport::sendRequest(const string& buffer, const bool end) -{ - m_socket->send(buffer); - if (end) m_socket->send("\r\n"); -} - - -const int SMTPTransport::responseCode(const string& response) -{ - int code = 0; - - if (response.length() >= 3) - { - code = (response[0] - '0') * 100 - + (response[1] - '0') * 10 - + (response[2] - '0'); - } - - return (code); -} - - -const string SMTPTransport::responseText(const string& response) -{ - string text; - - std::istringstream iss(response); - std::string line; - - while (std::getline(iss, line)) - { - if (line.length() >= 4) - text += line.substr(4); - else - text += line; - - text += "\n"; - } - - return (text); -} - - -void SMTPTransport::readResponse(string& buffer) -{ - bool foundTerminator = false; - - buffer.clear(); - - 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(); - } - - // Receive data from the socket - string receiveBuffer; - m_socket->receive(receiveBuffer); - - if (receiveBuffer.empty()) // buffer is empty - { - platformDependant::getHandler()->wait(); - continue; - } - - // We have received data: reset the time-out counter - if (m_timeoutHandler) - m_timeoutHandler->resetTimeOut(); - - // Append the data to the response buffer - buffer += receiveBuffer; - - // Check for terminator string (and strip it if present) - if (buffer.length() >= 2 && buffer[buffer.length() - 1] == '\n') - { - string::size_type p = buffer.length() - 2; - bool end = false; - - for ( ; !end ; --p) - { - if (p == 0 || buffer[p] == '\n') - { - end = true; - - if (p + 4 < buffer.length()) - foundTerminator = true; - } - } - } - } - - // Remove [CR]LF at the end of the response - if (buffer.length() >= 2 && buffer[buffer.length() - 1] == '\n') - { - if (buffer[buffer.length() - 2] == '\r') - buffer.resize(buffer.length() - 2); - else - buffer.resize(buffer.length() - 1); - } -} - - - -// Service infos - -SMTPTransport::_infos SMTPTransport::sm_infos; - - -const serviceInfos& SMTPTransport::getInfosInstance() -{ - return (sm_infos); -} - - -const serviceInfos& SMTPTransport::getInfos() const -{ - return (sm_infos); -} - - -const string SMTPTransport::_infos::getPropertyPrefix() const -{ - return "transport.smtp."; -} - - -const SMTPTransport::_infos::props& SMTPTransport::_infos::getProperties() const -{ - static props p = - { - // SMTP-specific options - property("options.need-authentication", serviceInfos::property::TYPE_BOOL, "false"), - - // Common properties - property(serviceInfos::property::AUTH_USERNAME), - property(serviceInfos::property::AUTH_PASSWORD), - - property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED), - property(serviceInfos::property::SERVER_PORT, "25"), - property(serviceInfos::property::SERVER_SOCKETFACTORY), - - property(serviceInfos::property::TIMEOUT_FACTORY) - }; - - return p; -} - - -const std::vector SMTPTransport::_infos::getAvailableProperties() const -{ - std::vector list; - const props& p = getProperties(); - - // SMTP-specific options - list.push_back(p.PROPERTY_OPTIONS_NEEDAUTH); - - // Common properties - list.push_back(p.PROPERTY_AUTH_USERNAME); - list.push_back(p.PROPERTY_AUTH_PASSWORD); - - list.push_back(p.PROPERTY_SERVER_ADDRESS); - list.push_back(p.PROPERTY_SERVER_PORT); - list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY); - - list.push_back(p.PROPERTY_TIMEOUT_FACTORY); - - return (list); -} - - -} // smtp -} // messaging -} // vmime diff --git a/src/messaging/transport.cpp b/src/messaging/transport.cpp deleted file mode 100644 index 59a2871c..00000000 --- a/src/messaging/transport.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#include "vmime/messaging/transport.hpp" - -#include "vmime/utility/stream.hpp" -#include "vmime/mailboxList.hpp" -#include "vmime/message.hpp" - - -namespace vmime { -namespace messaging { - - -transport::transport(ref sess, const serviceInfos& infos, ref auth) - : service(sess, infos, auth) -{ -} - - -static void extractMailboxes - (mailboxList& recipients, const addressList& list) -{ - for (int i = 0 ; i < list.getAddressCount() ; ++i) - { - ref mbox = list.getAddressAt(i)->clone().dynamicCast (); - - if (mbox != NULL) - recipients.appendMailbox(mbox); - } -} - - -void transport::send(ref msg, utility::progressionListener* progress) -{ - // Extract expeditor - mailbox expeditor; - - try - { - const mailboxField& from = dynamic_cast - (*msg->getHeader()->findField(fields::FROM)); - expeditor = from.getValue(); - } - catch (exceptions::no_such_field&) - { - throw exceptions::no_expeditor(); - } - - // Extract recipients - mailboxList recipients; - - try - { - const addressListField& to = dynamic_cast - (*msg->getHeader()->findField(fields::TO)); - extractMailboxes(recipients, to.getValue()); - } - catch (exceptions::no_such_field&) { } - - try - { - const addressListField& cc = dynamic_cast - (*msg->getHeader()->findField(fields::CC)); - extractMailboxes(recipients, cc.getValue()); - } - catch (exceptions::no_such_field&) { } - - try - { - const addressListField& bcc = dynamic_cast - (*msg->getHeader()->findField(fields::BCC)); - extractMailboxes(recipients, bcc.getValue()); - } - catch (exceptions::no_such_field&) { } - - // 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); -} - - -const transport::Type transport::getType() const -{ - return (TYPE_TRANSPORT); -} - - -} // messaging -} // vmime - diff --git a/vmime/messaging/authHelper.hpp b/vmime/messaging/authHelper.hpp deleted file mode 100644 index 1227b283..00000000 --- a/vmime/messaging/authHelper.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_AUTHHELPER_HPP_INCLUDED -#define VMIME_MESSAGING_AUTHHELPER_HPP_INCLUDED - - -#include "vmime/types.hpp" - - -namespace vmime { -namespace messaging { - - -void hmac_md5(const string& text, const string& key, string& hexDigest); - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_AUTHHELPER_HPP_INCLUDED diff --git a/vmime/messaging/authenticationInfos.hpp b/vmime/messaging/authenticationInfos.hpp deleted file mode 100644 index 3682056b..00000000 --- a/vmime/messaging/authenticationInfos.hpp +++ /dev/null @@ -1,64 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_AUTHENTICATIONINFOS_HPP_INCLUDED -#define VMIME_MESSAGING_AUTHENTICATIONINFOS_HPP_INCLUDED - - -#include "vmime/types.hpp" - - -namespace vmime { -namespace messaging { - - -/** This class encapsulates user credentials. - */ - -class authenticationInfos : public object -{ -public: - - authenticationInfos(const string& username, const string& password); - authenticationInfos(const authenticationInfos& infos); - - /** Return the user account name. - * - * @return account name - */ - const string& getUsername() const; - - /** Return the user account password. - * - * @return account password - */ - const string& getPassword() const; - -private: - - string m_username; - string m_password; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_AUTHENTICATIONINFOS_HPP_INCLUDED diff --git a/vmime/messaging/authenticator.hpp b/vmime/messaging/authenticator.hpp deleted file mode 100644 index 3aa4b9ad..00000000 --- a/vmime/messaging/authenticator.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_AUTHENTICATOR_HPP_INCLUDED -#define VMIME_MESSAGING_AUTHENTICATOR_HPP_INCLUDED - - -#include "vmime/types.hpp" -#include "vmime/messaging/authenticationInfos.hpp" - - -namespace vmime { -namespace messaging { - - -/** This class is used to obtain user credentials. - */ - -class authenticator : public object -{ -public: - - virtual ~authenticator(); - - /** Called when the service needs to retrieve user credentials. - * It should return the user account name and password. - * - * @return user credentials (user name and password) - */ - virtual const authenticationInfos requestAuthInfos() const = 0; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_AUTHENTICATOR_HPP_INCLUDED diff --git a/vmime/messaging/defaultAuthenticator.hpp b/vmime/messaging/defaultAuthenticator.hpp deleted file mode 100644 index 55d1af42..00000000 --- a/vmime/messaging/defaultAuthenticator.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_DEFAULTAUTHENTICATOR_HPP_INCLUDED -#define VMIME_MESSAGING_DEFAULTAUTHENTICATOR_HPP_INCLUDED - - -#include "vmime/messaging/authenticator.hpp" -#include "vmime/propertySet.hpp" - - -namespace vmime { -namespace messaging { - - -class session; - - -/** Default implementation for authenticator. It simply returns - * the credentials set in the session properties (named 'username' - * and 'password'). This is the default implementation used if - * you do not write your own authenticator object. - */ - -class defaultAuthenticator : public authenticator -{ -public: - - defaultAuthenticator(weak_ref session, const string& prefix); - -private: - - weak_ref m_session; - const string m_prefix; - - const authenticationInfos requestAuthInfos() const; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_DEFAULTAUTHENTICATOR_HPP_INCLUDED diff --git a/vmime/messaging/events.hpp b/vmime/messaging/events.hpp deleted file mode 100644 index a74d6459..00000000 --- a/vmime/messaging/events.hpp +++ /dev/null @@ -1,229 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_EVENTS_HPP_INCLUDED -#define VMIME_MESSAGING_EVENTS_HPP_INCLUDED - - -#include - -#include "vmime/utility/path.hpp" - - -namespace vmime { -namespace messaging { - -class folder; - -namespace events { - - -/** Event about the message count in a folder. - */ - -class messageCountEvent -{ -public: - - enum Types - { - TYPE_ADDED, /**< New messages have been added. */ - TYPE_REMOVED /**< Messages have been expunged (renumbering). */ - }; - - - messageCountEvent(ref folder, const Types type, const std::vector & nums); - - /** Return the folder in which messages have been added/removed. - * - * @return folder in which message count changed - */ - ref getFolder() const; - - /** Return the event type. - * - * @return event type (see messageCountEvent::Types) - */ - const Types getType() const; - - /** Return the numbers of the messages that have been added/removed. - * - * @return a list of message numbers - */ - const std::vector & getNumbers() const; - - /** Dispatch the event to the specified listener. - * - * @param listener listener to notify - */ - void dispatch(class messageCountListener* listener) const; - -private: - - ref m_folder; - const Types m_type; - std::vector m_nums; -}; - - -/** Listener for events about the message count in a folder. - */ - -class messageCountListener -{ -protected: - - virtual ~messageCountListener() { } - -public: - - virtual void messagesAdded(const messageCountEvent& event) = 0; - virtual void messagesRemoved(const messageCountEvent& event) = 0; -}; - - -/** Event occuring on a message. - */ - -class messageChangedEvent -{ -public: - - enum Types - { - TYPE_FLAGS // flags changed - }; - - - messageChangedEvent(ref folder, const Types type, const std::vector & nums); - - /** Return the folder in which messages have changed. - * - * @return folder in which message count changed - */ - ref getFolder() const; - - /** Return the event type. - * - * @return event type (see messageChangedEvent::Types) - */ - const Types getType() const; - - /** Return the numbers of the messages that have changed. - * - * @return a list of message numbers - */ - const std::vector & getNumbers() const; - - /** Dispatch the event to the specified listener. - * - * @param listener listener to notify - */ - void dispatch(class messageChangedListener* listener) const; - -private: - - ref m_folder; - const Types m_type; - std::vector m_nums; -}; - - -/** Listener for events occuring on a message. - */ - -class messageChangedListener -{ -protected: - - virtual ~messageChangedListener() { } - -public: - - virtual void messageChanged(const messageChangedEvent& event) = 0; -}; - - -/** Event occuring on a folder. - */ - -class folderEvent -{ -public: - - enum Types - { - TYPE_CREATED, /**< A folder was created. */ - TYPE_DELETED, /**< A folder was deleted. */ - TYPE_RENAMED /**< A folder was renamed. */ - }; - - - folderEvent(ref folder, const Types type, const utility::path& oldPath, const utility::path& newPath); - - /** Return the folder on which the event occured. - * - * @return folder on which the event occured - */ - ref getFolder() const; - - /** Return the event type. - * - * @return event type (see folderEvent::Types) - */ - const Types getType() const; - - /** Dispatch the event to the specified listener. - * - * @param listener listener to notify - */ - void dispatch(class folderListener* listener) const; - -private: - - ref m_folder; - const Types m_type; - const utility::path m_oldPath; - const utility::path m_newPath; -}; - - -/** Listener for events occuring on a folder. - */ - -class folderListener -{ -protected: - - virtual ~folderListener() { } - -public: - - virtual void folderCreated(const folderEvent& event) = 0; - virtual void folderRenamed(const folderEvent& event) = 0; - virtual void folderDeleted(const folderEvent& event) = 0; -}; - - -} // events -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_EVENTS_HPP_INCLUDED diff --git a/vmime/messaging/folder.hpp b/vmime/messaging/folder.hpp deleted file mode 100644 index ac6e4250..00000000 --- a/vmime/messaging/folder.hpp +++ /dev/null @@ -1,379 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_FOLDER_HPP_INCLUDED -#define VMIME_MESSAGING_FOLDER_HPP_INCLUDED - - -#include - -#include "vmime/types.hpp" -#include "vmime/dateTime.hpp" - -#include "vmime/message.hpp" -#include "vmime/messaging/message.hpp" -#include "vmime/messaging/events.hpp" - -#include "vmime/utility/path.hpp" -#include "vmime/utility/stream.hpp" -#include "vmime/utility/progressionListener.hpp" - - -namespace vmime { -namespace messaging { - - -class store; - - -/** Abstract representation of a folder in a message store. - */ - -class folder : public object -{ -protected: - - folder(const folder&) : object() { } - folder() { } - -public: - - virtual ~folder() { } - - /** Type used for fully qualified path name of a folder. - */ - typedef vmime::utility::path path; - - - /** Open mode. - */ - enum Modes - { - MODE_READ_ONLY, /**< Read-only mode (no modification to folder or messages is possible). */ - MODE_READ_WRITE /**< Full access mode (read and write). */ - }; - - /** Folder types. - */ - enum Types - { - TYPE_CONTAINS_FOLDERS = (1 << 0), /**< Folder can contain folders. */ - TYPE_CONTAINS_MESSAGES = (1 << 1), /**< Folder can contain messages. */ - - TYPE_UNDEFINED = 9999 /**< Used internally (this should not be returned - by the type() function). */ - }; - - /** Folder flags. - */ - enum Flags - { - FLAG_CHILDREN = (1 << 0), /**< Folder contains subfolders. */ - FLAG_NO_OPEN = (1 << 1), /**< Folder cannot be open. */ - - FLAG_UNDEFINED = 9999 /**< Used internally (this should not be returned - by the type() function). */ - }; - - /** Return the type of this folder. - * - * @return folder type (see folder::Types) - */ - virtual const int getType() = 0; - - /** Return the flags of this folder. - * - * @return folder flags (see folder::Flags) - */ - virtual const int getFlags() = 0; - - /** Return the mode in which the folder has been open. - * - * @return folder opening mode (see folder::Modes) - */ - virtual const int getMode() const = 0; - - /** Return the name of this folder. - * - * @return folder name - */ - virtual const folder::path::component getName() const = 0; - - /** Return the fully qualified path name of this folder. - * - * @return absolute path of the folder - */ - virtual const folder::path getFullPath() const = 0; - - /** Open this folder. - * - * @param mode open mode (see folder::Modes) - * @param failIfModeIsNotAvailable if set to false and if the requested mode - * is not available, a more restricted mode will be selected automatically. - * If set to true and if the requested mode is not available, the opening - * will fail. - */ - virtual void open(const int mode, bool failIfModeIsNotAvailable = false) = 0; - - /** Close this folder. - * - * @param expunge if set to true, deleted messages are expunged - */ - virtual void close(const bool expunge) = 0; - - /** Create this folder. - * - * @param type folder type (see folder::Types) - */ - virtual void create(const int type) = 0; - - /** Test whether this folder exists. - * - * @return true if the folder exists, false otherwise - */ - virtual const bool exists() = 0; - - /** Test whether this folder is open. - * - * @return true if the folder is open, false otherwise - */ - virtual const bool isOpen() const = 0; - - /** Get a new reference to a message in this folder. - * - * @param num message sequence number - * @return a new object referencing the specified message - */ - virtual ref getMessage(const int num) = 0; - - /** Get new references to messages in this folder. - * - * @param from sequence number of the first message to get - * @param to sequence number of the last message to get - * @return new objects referencing the specified messages - */ - virtual std::vector > getMessages(const int from = 1, const int to = -1) = 0; - - /** Get new references to messages in this folder. - * - * @param nums sequence numbers of the messages to delete - * @return new objects referencing the specified messages - */ - virtual std::vector > getMessages(const std::vector & nums) = 0; - - /** Return the number of messages in this folder. - * - * @return number of messages in the folder - */ - virtual const int getMessageCount() = 0; - - /** Get a new reference to a sub-folder in this folder. - * - * @param name sub-folder name - * @return a new object referencing the specified folder - */ - virtual ref getFolder(const folder::path::component& name) = 0; - - /** Get the list of all sub-folders in this folder. - * - * @param recursive if set to true, all the descendant are returned. - * If set to false, only the direct children are returned. - * @return list of sub-folders - */ - virtual std::vector > getFolders(const bool recursive = false) = 0; - - /** Rename (move) this folder to another location. - * - * @param newPath new path of the folder - */ - virtual void rename(const folder::path& newPath) = 0; - - /** Remove a message in this folder. - * - * @param num sequence number of the message to delete - */ - virtual void deleteMessage(const int num) = 0; - - /** Remove one or more messages from this folder. - * - * @param from sequence number of the first message to delete - * @param to sequence number of the last message to delete - */ - virtual void deleteMessages(const int from = 1, const int to = -1) = 0; - - /** Remove one or more messages from this folder. - * - * @param nums sequence numbers of the messages to delete - */ - virtual void deleteMessages(const std::vector & nums) = 0; - - /** Change the flags for one or more messages in this folder. - * - * @param from sequence number of the first message to modify - * @param to sequence number of the last message to modify - * @param flags set of flags (see message::Flags) - * @param mode indicate how to treat old and new flags (see message::FlagsModes) - */ - virtual void setMessageFlags(const int from, const int to, const int flags, const int mode = message::FLAG_MODE_SET) = 0; - - /** Change the flags for one or more messages in this folder. - * - * @param nums sequence numbers of the messages to modify - * @param flags set of flags (see message::Flags) - * @param mode indicate how to treat old and new flags (see message::FlagsModes) - */ - virtual void setMessageFlags(const std::vector & nums, const int flags, const int mode = message::FLAG_MODE_SET) = 0; - - /** Add a message to this folder. - * - * @param msg message to add (data: header + body) - * @param flags flags for the new message - * @param date date/time for the new message (if NULL, the current time is used) - * @param progress progression listener, or NULL if not used - */ - virtual void addMessage(ref msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressionListener* progress = NULL) = 0; - - /** Add a message to this folder. - * - * @param is message to add (data: header + body) - * @param size size of the message to add (in bytes) - * @param flags flags for the new message - * @param date date/time for the new message (if NULL, the current time is used) - * @param progress progression listener, or NULL if not used - */ - virtual void addMessage(utility::inputStream& is, const int size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressionListener* progress = NULL) = 0; - - /** Copy a message from this folder to another folder. - * - * @param dest destination folder path - * @param num sequence number of the message to copy - */ - virtual void copyMessage(const folder::path& dest, const int num) = 0; - - /** Copy messages from this folder to another folder. - * - * @param dest destination folder path - * @param from sequence number of the first message to copy - * @param to sequence number of the last message to copy - */ - virtual void copyMessages(const folder::path& dest, const int from = 1, const int to = -1) = 0; - - /** Copy messages from this folder to another folder. - * - * @param dest destination folder path - * @param nums sequence numbers of the messages to copy - */ - virtual void copyMessages(const folder::path& dest, const std::vector & nums) = 0; - - /** Request folder status without opening it. - * - * @param count will receive the number of messages in the folder - * @param unseen will receive the number of unseen messages in the folder - */ - virtual void status(int& count, int& unseen) = 0; - - /** Expunge deleted messages. - */ - virtual void expunge() = 0; - - /** Return a new folder object referencing the parent folder of this folder. - * - * @return parent folder object - */ - virtual ref getParent() = 0; - - /** Return a reference to the store to which this folder belongs. - * - * @return the store object to which this folder is attached - */ - virtual weak_ref getStore() const = 0; - - /** Return a reference to the store to which this folder belongs. - * - * @return the store object to which this folder is attached - */ - virtual weak_ref getStore() = 0; - - /** Fetchable objects. - */ - enum FetchOptions - { - FETCH_ENVELOPE = (1 << 0), /**< Fetch sender, recipients, date, subject. */ - FETCH_STRUCTURE = (1 << 1), /**< Fetch structure (body parts). */ - FETCH_CONTENT_INFO = (1 << 2), /**< Fetch top-level content type. */ - FETCH_FLAGS = (1 << 3), /**< Fetch message flags. */ - FETCH_SIZE = (1 << 4), /**< Fetch message size (exact or estimated). */ - FETCH_FULL_HEADER = (1 << 5), /**< Fetch full RFC-[2]822 header. */ - FETCH_UID = (1 << 6), /**< Fetch unique identifier (protocol specific). */ - FETCH_IMPORTANCE = (1 << 7), /**< Fetch header fields suitable for use with misc::importanceHelper. */ - - FETCH_CUSTOM = (1 << 16) /**< Reserved for future use. */ - }; - - /** Fetch objects for the specified messages. - * - * @param msg list of message sequence numbers - * @param options objects to fetch (combination of folder::FetchOptions flags) - * @param progress progression listener, or NULL if not used - */ - virtual void fetchMessages(std::vector >& msg, const int options, utility::progressionListener* progress = NULL) = 0; - - /** Fetch objects for the specified message. - * - * @param msg the message - * @param options objects to fetch (combination of folder::FetchOptions flags) - */ - virtual void fetchMessage(ref msg, const int options) = 0; - - /** Return the list of fetchable objects supported by - * the underlying protocol (see folder::FetchOptions). - * - * @return list of supported fetchable objects - */ - virtual const int getFetchCapabilities() const = 0; - - // Event listeners - void addMessageChangedListener(events::messageChangedListener* l); - void removeMessageChangedListener(events::messageChangedListener* l); - - void addMessageCountListener(events::messageCountListener* l); - void removeMessageCountListener(events::messageCountListener* l); - - void addFolderListener(events::folderListener* l); - void removeFolderListener(events::folderListener* l); - -protected: - - void notifyMessageChanged(const events::messageChangedEvent& event); - void notifyMessageCount(const events::messageCountEvent& event); - void notifyFolder(const events::folderEvent& event); - -private: - - std::list m_messageChangedListeners; - std::list m_messageCountListeners; - std::list m_folderListeners; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_FOLDER_HPP_INCLUDED diff --git a/vmime/messaging/imap/IMAPConnection.hpp b/vmime/messaging/imap/IMAPConnection.hpp deleted file mode 100644 index 5ceca567..00000000 --- a/vmime/messaging/imap/IMAPConnection.hpp +++ /dev/null @@ -1,116 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_IMAP_IMAPCONNECTION_HPP_INCLUDED -#define VMIME_MESSAGING_IMAP_IMAPCONNECTION_HPP_INCLUDED - - -#include "vmime/config.hpp" - -#include "vmime/messaging/authenticator.hpp" -#include "vmime/messaging/socket.hpp" -#include "vmime/messaging/timeoutHandler.hpp" -#include "vmime/messaging/session.hpp" - -#include "vmime/messaging/imap/IMAPParser.hpp" - - -namespace vmime { -namespace messaging { -namespace imap { - - -class IMAPTag; -class IMAPStore; - - -class IMAPConnection : public object -{ -public: - - IMAPConnection(weak_ref store, ref auth); - ~IMAPConnection(); - - - void connect(); - const bool isConnected() const; - void disconnect(); - - - enum ProtocolStates - { - STATE_NONE, - STATE_NON_AUTHENTICATED, - STATE_AUTHENTICATED, - STATE_SELECTED, - STATE_LOGOUT - }; - - const ProtocolStates state() const; - void setState(const ProtocolStates state); - - - const char hierarchySeparator() const; - - - void send(bool tag, const string& what, bool end); - void sendRaw(const char* buffer, const int count); - - IMAPParser::response* readResponse(IMAPParser::literalHandler* lh = NULL); - - - ref getTag() const; - ref getParser() const; - - weak_ref getStore() const; - weak_ref getStore(); - - ref getSession(); - -private: - - weak_ref m_store; - - ref m_auth; - - ref m_socket; - - ref m_parser; - - ref m_tag; - - char m_hierarchySeparator; - - ProtocolStates m_state; - - ref m_timeoutHandler; - - - void internalDisconnect(); - - void initHierarchySeparator(); -}; - - -} // imap -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_IMAP_IMAPCONNECTION_HPP_INCLUDED diff --git a/vmime/messaging/imap/IMAPFolder.hpp b/vmime/messaging/imap/IMAPFolder.hpp deleted file mode 100644 index 0d803a7f..00000000 --- a/vmime/messaging/imap/IMAPFolder.hpp +++ /dev/null @@ -1,158 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_IMAP_IMAPFOLDER_HPP_INCLUDED -#define VMIME_MESSAGING_IMAP_IMAPFOLDER_HPP_INCLUDED - - -#include -#include - -#include "vmime/types.hpp" - -#include "vmime/messaging/folder.hpp" - - -namespace vmime { -namespace messaging { -namespace imap { - - -class IMAPStore; -class IMAPMessage; -class IMAPConnection; - - -/** IMAP folder implementation. - */ - -class IMAPFolder : public folder -{ -private: - - friend class IMAPStore; - friend class IMAPMessage; - friend class vmime::creator; // vmime::create - - - IMAPFolder(const folder::path& path, IMAPStore* store, const int type = TYPE_UNDEFINED, const int flags = FLAG_UNDEFINED); - IMAPFolder(const IMAPFolder&) : folder() { } - - ~IMAPFolder(); - -public: - - const int getMode() const; - - const int getType(); - - const int getFlags(); - - const folder::path::component getName() const; - const folder::path getFullPath() const; - - void open(const int mode, bool failIfModeIsNotAvailable = false); - void close(const bool expunge); - void create(const int type); - - const bool exists(); - - const bool isOpen() const; - - ref getMessage(const int num); - std::vector > getMessages(const int from = 1, const int to = -1); - std::vector > getMessages(const std::vector & nums); - const int getMessageCount(); - - ref getFolder(const folder::path::component& name); - std::vector > getFolders(const bool recursive = false); - - void rename(const folder::path& newPath); - - void deleteMessage(const int num); - void deleteMessages(const int from = 1, const int to = -1); - void deleteMessages(const std::vector & nums); - - void setMessageFlags(const int from, const int to, const int flags, const int mode = message::FLAG_MODE_SET); - void setMessageFlags(const std::vector & nums, const int flags, const int mode = message::FLAG_MODE_SET); - - void addMessage(ref msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressionListener* progress = NULL); - void addMessage(utility::inputStream& is, const int size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressionListener* progress = NULL); - - void copyMessage(const folder::path& dest, const int num); - void copyMessages(const folder::path& dest, const int from = 1, const int to = -1); - void copyMessages(const folder::path& dest, const std::vector & nums); - - void status(int& count, int& unseen); - - void expunge(); - - ref getParent(); - - weak_ref getStore() const; - weak_ref getStore(); - - - void fetchMessages(std::vector >& msg, const int options, utility::progressionListener* progress = NULL); - void fetchMessage(ref msg, const int options); - - const int getFetchCapabilities() const; - -private: - - void registerMessage(IMAPMessage* msg); - void unregisterMessage(IMAPMessage* msg); - - void onStoreDisconnected(); - - void onClose(); - - const int testExistAndGetType(); - - void setMessageFlags(const string& set, const int flags, const int mode); - - void copyMessages(const string& set, const folder::path& dest); - - - IMAPStore* m_store; - ref m_connection; - - folder::path m_path; - folder::path::component m_name; - - int m_mode; - bool m_open; - - int m_type; - int m_flags; - - int m_messageCount; - - int m_uidValidity; - - std::vector m_messages; -}; - - -} // imap -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_IMAP_IMAPFOLDER_HPP_INCLUDED diff --git a/vmime/messaging/imap/IMAPMessage.hpp b/vmime/messaging/imap/IMAPMessage.hpp deleted file mode 100644 index 04032b42..00000000 --- a/vmime/messaging/imap/IMAPMessage.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_IMAP_IMAPMESSAGE_HPP_INCLUDED -#define VMIME_MESSAGING_IMAP_IMAPMESSAGE_HPP_INCLUDED - - -#include "vmime/messaging/message.hpp" -#include "vmime/messaging/folder.hpp" - -#include "vmime/mailboxList.hpp" - - -namespace vmime { -namespace messaging { -namespace imap { - - -class IMAPFolder; - - -/** IMAP message implementation. - */ - -class IMAPMessage : public message -{ -private: - - friend class IMAPFolder; - friend class vmime::creator; // vmime::create - - IMAPMessage(IMAPFolder* folder, const int num); - IMAPMessage(const IMAPMessage&) : message() { } - - ~IMAPMessage(); - -public: - - const int getNumber() const; - - const uid getUniqueId() const; - - const int getSize() const; - - const bool isExpunged() const; - - const structure& getStructure() const; - structure& getStructure(); - - ref getHeader() const; - - const int getFlags() const; - void setFlags(const int flags, const int mode = FLAG_MODE_SET); - - void extract(utility::outputStream& os, utility::progressionListener* progress = NULL, const int start = 0, const int length = -1, const bool peek = false) const; - void extractPart(const part& p, utility::outputStream& os, utility::progressionListener* progress = NULL, const int start = 0, const int length = -1, const bool peek = false) const; - - void fetchPartHeader(part& p); - -private: - - void fetch(IMAPFolder* folder, const int options); - - void processFetchResponse(const int options, const IMAPParser::msg_att* msgAtt); - - void extract(const part* p, utility::outputStream& os, utility::progressionListener* progress, const int start, const int length, const bool headerOnly, const bool peek) const; - - - void convertAddressList(const IMAPParser::address_list& src, mailboxList& dest); - - - ref
getOrCreateHeader(); - - - void onFolderClosed(); - - IMAPFolder* m_folder; - - int m_num; - int m_size; - int m_flags; - bool m_expunged; - uid m_uid; - - ref
m_header; - ref m_structure; -}; - - -} // imap -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_IMAP_IMAPMESSAGE_HPP_INCLUDED diff --git a/vmime/messaging/imap/IMAPParser.hpp b/vmime/messaging/imap/IMAPParser.hpp deleted file mode 100644 index 205644de..00000000 --- a/vmime/messaging/imap/IMAPParser.hpp +++ /dev/null @@ -1,5082 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_IMAP_IMAPPARSER_HPP_INCLUDED -#define VMIME_MESSAGING_IMAP_IMAPPARSER_HPP_INCLUDED - - -#include "vmime/base.hpp" -#include "vmime/dateTime.hpp" -#include "vmime/charset.hpp" -#include "vmime/exception.hpp" - -#include "vmime/utility/smartPtr.hpp" -#include "vmime/utility/stringUtils.hpp" -#include "vmime/utility/progressionListener.hpp" - -#include "vmime/encoderB64.hpp" -#include "vmime/encoderQP.hpp" - -#include "vmime/platformDependant.hpp" - -#include "vmime/messaging/timeoutHandler.hpp" -#include "vmime/messaging/socket.hpp" - -#include "vmime/messaging/imap/IMAPTag.hpp" - -#include -#include - - -//#define DEBUG_RESPONSE 1 - - -#if DEBUG_RESPONSE -# include -#endif - - -namespace vmime { -namespace messaging { -namespace imap { - - -#if DEBUG_RESPONSE - static string DEBUG_RESPONSE_level; - static std::vector DEBUG_RESPONSE_components; - -# define DEBUG_ENTER_COMPONENT(x) \ - DEBUG_RESPONSE_components.push_back(x); \ - std::cout << DEBUG_RESPONSE_level \ - << "(" << DEBUG_RESPONSE_level.length() << ") " \ - << (x) << std::endl; -# define DEBUG_FOUND(x, y) \ - std::cout << "FOUND: " << x << ": " << y << std::endl; -#else -# define DEBUG_ENTER_COMPONENT(x) -# define DEBUG_FOUND(x, y) -#endif - - -class IMAPParser : public object -{ -public: - - IMAPParser(weak_ref tag, weak_ref sok, weak_ref _timeoutHandler) - : m_tag(tag), m_socket(sok), m_progress(NULL), - m_literalHandler(NULL), m_timeoutHandler(_timeoutHandler) - { - } - - - weak_ref tag() const - { - return (m_tag); - } - - - const string lastLine() const - { - // Remove blanks and new lines at the end of the line. - string line(m_lastLine); - - string::const_iterator it = line.end(); - int count = 0; - - while (it != line.begin()) - { - const unsigned char c = *(it - 1); - - if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) - break; - - ++count; - --it; - } - - line.resize(line.length() - count); - - return (line); - } - - - - // - // literalHandler : literal content handler - // - - class component; - - class literalHandler - { - public: - - virtual ~literalHandler() { } - - - // Abstract target class - class target - { - protected: - - target(utility::progressionListener* progress) : m_progress(progress) {} - target(const target&) {} - - public: - - virtual ~target() { } - - - utility::progressionListener* progressionListener() { return (m_progress); } - - virtual void putData(const string& chunk) = 0; - - private: - - utility::progressionListener* m_progress; - }; - - - // Target: put in a string - class targetString : public target - { - public: - - targetString(utility::progressionListener* progress, vmime::string& str) - : target(progress), m_string(str) { } - - const vmime::string& string() const { return (m_string); } - vmime::string& string() { return (m_string); } - - - void putData(const vmime::string& chunk) - { - m_string += chunk; - } - - private: - - vmime::string& m_string; - }; - - - // Target: redirect to an output stream - class targetStream : public target - { - public: - - targetStream(utility::progressionListener* progress, utility::outputStream& stream) - : target(progress), m_stream(stream) { } - - const utility::outputStream& stream() const { return (m_stream); } - utility::outputStream& stream() { return (m_stream); } - - - void putData(const string& chunk) - { - m_stream.write(chunk.data(), chunk.length()); - } - - private: - - utility::outputStream& m_stream; - }; - - - // Called when the parser needs to know what to do with a literal - // . comp: the component in which we are at this moment - // . data: data specific to the component (may not be used) - // - // Returns : - // . == NULL to put the literal into the response - // . != NULL to redirect the literal to the specified target - - virtual target* targetFor(const component& comp, const int data) = 0; - }; - - - // - // Base class for a terminal or a non-terminal - // - - class component - { - public: - - component() { } - virtual ~component() { } - - virtual void go(IMAPParser& parser, string& line, string::size_type* currentPos) = 0; - - - const string makeResponseLine(const string& comp, const string& line, - const string::size_type pos) - { -#if DEBUG_RESPONSE - if (pos > line.length()) - std::cout << "WARNING: component::makeResponseLine(): pos > line.length()" << std::endl; -#endif - - string result(line.substr(0, pos)); - result += "[^]"; // indicates current parser position - result += line.substr(pos, line.length()); - if (!comp.empty()) result += " [" + comp + "]"; - - return (result); - } - }; - - - - // - // Parse one character - // - - template - class one_char : public component - { - public: - - void go(IMAPParser& /* parser */, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT(string("one_char <") + C + ">: current='" + ((*currentPos < line.length() ? line[*currentPos] : '?')) + "'"); - - const string::size_type pos = *currentPos; - - if (pos < line.length() && line[pos] == C) - *currentPos = pos + 1; - else - throw exceptions::invalid_response("", makeResponseLine("", line, pos)); - } - }; - - - // - // SPACE ::= - // - - class SPACE : public component - { - public: - - void go(IMAPParser& /* parser */, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("SPACE"); - - string::size_type pos = *currentPos; - - while (pos < line.length() && (line[pos] == ' ' || line[pos] == '\t')) - ++pos; - - if (pos > *currentPos) - *currentPos = pos; - else - throw exceptions::invalid_response("", makeResponseLine("SPACE", line, pos)); - } - }; - - - // - // CR ::= - // LF ::= - // CRLF ::= CR LF - // - - class CRLF : public component - { - public: - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("CRLF"); - - string::size_type pos = *currentPos; - - parser.check (line, &pos, true); - - if (pos + 1 < line.length() && - line[pos] == 0x0d && line[pos + 1] == 0x0a) - { - *currentPos = pos + 2; - } - else - { - throw exceptions::invalid_response("", makeResponseLine("CRLF", line, pos)); - } - } - }; - - - // - // SPACE ::= - // CTL ::= - // CHAR ::= - // ATOM_CHAR ::= - // atom_specials ::= "(" / ")" / "{" / SPACE / CTL / list_wildcards / quoted_specials - // list_wildcards ::= "%" / "*" - // quoted_specials ::= <"> / "\" - // - // tag ::= 1* (named "xtag") - // - - class xtag : public component - { - public: - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("tag"); - - string::size_type pos = *currentPos; - - bool end = false; - - string tagString; - tagString.reserve(10); - - while (!end && pos < line.length()) - { - const unsigned char c = line[pos]; - - switch (c) - { - case '+': - case '(': - case ')': - case '{': - case 0x20: // SPACE - case '%': // list_wildcards - case '*': // list_wildcards - case '"': // quoted_specials - case '\\': // quoted_specials - - end = true; - break; - - default: - - if (c <= 0x1f || c >= 0x7f) - end = true; - else - { - tagString += c; - ++pos; - } - - break; - } - } - - if (tagString == string(*(parser.tag()))) - { - *currentPos = pos; - } - else - { - // Invalid tag - throw exceptions::invalid_response("", makeResponseLine("tag", line, pos)); - } - } - }; - - - // - // digit ::= "0" / digit_nz - // digit_nz ::= "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" - // - // number ::= 1*digit - // ;; Unsigned 32-bit integer - // ;; (0 <= n < 4,294,967,296) - // - - class number : public component - { - public: - - number(const bool nonZero = false) - : m_nonZero(nonZero), m_value(0) - { - } - - void go(IMAPParser& /* parser */, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("number"); - - string::size_type pos = *currentPos; - - bool valid = true; - unsigned int val = 0; - - while (valid && pos < line.length()) - { - const char c = line[pos]; - - if (c >= '0' && c <= '9') - { - val = (val * 10) + (c - '0'); - ++pos; - } - else - { - valid = false; - } - } - - // Check for non-null length (and for non-zero number) - if (!(m_nonZero && val == 0) && pos != *currentPos) - { - m_value = val; - *currentPos = pos; - } - else - { - throw exceptions::invalid_response("", makeResponseLine("number", line, pos)); - } - } - - private: - - const bool m_nonZero; - unsigned int m_value; - - public: - - const unsigned int value() const { return (m_value); } - }; - - - // nz_number ::= digit_nz *digit - // ;; Non-zero unsigned 32-bit integer - // ;; (0 < n < 4,294,967,296) - // - - class nz_number : public number - { - public: - - nz_number() : number(true) - { - } - }; - - - // - // text ::= 1*TEXT_CHAR - // - // CHAR ::= - // TEXT_CHAR ::= - // - - class text : public component - { - public: - - text(bool allow8bits = false, const char except = 0) - : m_allow8bits(allow8bits), m_except(except) - { - } - - void go(IMAPParser& /* parser */, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("text"); - - string::size_type pos = *currentPos; - string::size_type len = 0; - - if (m_allow8bits) - { - const unsigned char except = m_except; - - for (bool end = false ; !end && pos < line.length() ; ) - { - const unsigned char c = line[pos]; - - if (c == 0x00 || c == 0x0d || c == 0x0a || c == except) - { - end = true; - } - else - { - ++pos; - ++len; - } - } - } - else - { - const unsigned char except = m_except; - - for (bool end = false ; !end && pos < line.length() ; ) - { - const unsigned char c = line[pos]; - - if (c < 0x01 || c > 0x7f || c == 0x0d || c == 0x0a || c == except) - { - end = true; - } - else - { - ++pos; - ++len; - } - } - } - - if (len != 0) - { - m_value.resize(len); - std::copy(line.begin() + *currentPos, line.begin() + pos, m_value.begin()); - - *currentPos = pos; - } - else - { - throw exceptions::invalid_response("", makeResponseLine("text", line, pos)); - } - } - - private: - - string m_value; - const bool m_allow8bits; - const char m_except; - - public: - - const string& value() const { return (m_value); } - }; - - - class text8 : public text - { - public: - - text8() : text(true) - { - } - }; - - - template - class text_except : public text - { - public: - - text_except() : text(false, C) - { - } - }; - - - template - class text8_except : public text - { - public: - - text8_except() : text(true, C) - { - } - }; - - - // - // QUOTED_CHAR ::= / "\" quoted_specials - // quoted_specials ::= <"> / "\" - // TEXT_CHAR ::= - // CHAR ::= - // - - class QUOTED_CHAR : public component - { - public: - - void go(IMAPParser& /* parser */, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("quoted_char"); - - string::size_type pos = *currentPos; - - const unsigned char c = (pos < line.length() ? line[pos] : 0); - - if (c >= 0x01 && c <= 0x7f && // 0x01 - 0x7f - c != '"' && c != '\\' && // quoted_specials - c != '\r' && c != '\n') // CR and LF - { - m_value = c; - *currentPos = pos + 1; - } - else if (c == '\\' && pos + 1 < line.length() && - (line[pos + 1] == '"' || line[pos + 1] == '\\')) - { - m_value = line[pos + 1]; - *currentPos = pos + 2; - } - else - { - throw exceptions::invalid_response("", makeResponseLine("QUOTED_CHAR", line, pos)); - } - } - - private: - - char m_value; - - public: - - const char value() const { return (m_value); } - }; - - - // - // quoted ::= <"> *QUOTED_CHAR <"> - // QUOTED_CHAR ::= / "\" quoted_specials - // quoted_specials ::= <"> / "\" - // TEXT_CHAR ::= - // CHAR ::= - // - - class quoted_text : public component - { - public: - - void go(IMAPParser& /* parser */, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("quoted_text"); - - string::size_type pos = *currentPos; - string::size_type len = 0; - bool valid = false; - - m_value.reserve(line.length() - pos); - - for (bool end = false, quoted = false ; !end && pos < line.length() ; ) - { - const unsigned char c = line[pos]; - - if (quoted) - { - if (c == '"' || c == '\\') - m_value += c; - else - { - m_value += '\\'; - m_value += c; - } - - quoted = false; - - ++pos; - ++len; - } - else - { - if (c == '\\') - { - quoted = true; - - ++pos; - ++len; - } - else if (c == '"') - { - valid = true; - end = true; - } - else if (c >= 0x01 && c <= 0x7f && // CHAR - c != 0x0a && c != 0x0d) // CR and LF - { - m_value += c; - - ++pos; - ++len; - } - else - { - valid = false; - end = true; - } - } - } - - if (valid) - { - *currentPos = pos; - } - else - { - throw exceptions::invalid_response("", makeResponseLine("quoted_text", line, pos)); - } - } - - private: - - string m_value; - - public: - - const string& value() const { return (m_value); } - }; - - - // - // nil ::= "NIL" - // - - class NIL : public component - { - public: - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("NIL"); - - string::size_type pos = *currentPos; - - parser.checkWithArg (line, &pos, "nil"); - - *currentPos = pos; - } - }; - - - // - // string ::= quoted / literal ----> named 'xstring' - // - // nil ::= "NIL" - // quoted ::= <"> *QUOTED_CHAR <"> - // QUOTED_CHAR ::= / "\" quoted_specials - // quoted_specials ::= <"> / "\" - // TEXT_CHAR ::= - // CHAR ::= - // literal ::= "{" number "}" CRLF *CHAR8 - // ;; Number represents the number of CHAR8 octets - // CHAR8 ::= - // - - class xstring : public component - { - public: - - xstring(const bool canBeNIL = false, component* comp = NULL, const int data = 0) - : m_canBeNIL(canBeNIL), m_component(comp), m_data(data) - { - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("string"); - - string::size_type pos = *currentPos; - - if (m_canBeNIL && - parser.checkWithArg (line, &pos, "nil", true)) - { - // NIL - } - else - { - pos = *currentPos; - - // quoted ::= <"> *QUOTED_CHAR <"> - if (parser.check >(line, &pos, true)) - { - utility::auto_ptr text(parser.get (line, &pos)); - parser.check >(line, &pos); - - if (parser.m_literalHandler != NULL) - { - literalHandler::target* target = - parser.m_literalHandler->targetFor(*m_component, m_data); - - if (target != NULL) - { - m_value = "[literal-handler]"; - - const string::size_type length = text->value().length(); - utility::progressionListener* progress = target->progressionListener(); - - if (progress) - { - progress->start(length); - } - - target->putData(text->value()); - - if (progress) - { - progress->progress(length, length); - progress->stop(length); - } - - delete (target); - } - else - { - m_value = text->value(); - } - } - else - { - m_value = text->value(); - } - - DEBUG_FOUND("string[quoted]", ""); - } - // literal ::= "{" number "}" CRLF *CHAR8 - else - { - parser.check >(line, &pos); - - number* num = parser.get (line, &pos); - - const string::size_type length = num->value(); - delete (num); - - parser.check >(line, &pos); - - parser.check (line, &pos); - - - if (parser.m_literalHandler != NULL) - { - literalHandler::target* target = - parser.m_literalHandler->targetFor(*m_component, m_data); - - if (target != NULL) - { - m_value = "[literal-handler]"; - - parser.m_progress = target->progressionListener(); - parser.readLiteral(*target, length); - parser.m_progress = NULL; - - delete (target); - } - else - { - literalHandler::targetString target(NULL, m_value); - parser.readLiteral(target, length); - } - } - else - { - literalHandler::targetString target(NULL, m_value); - parser.readLiteral(target, length); - } - - line += parser.readLine(); - - DEBUG_FOUND("string[literal]", ""); - } - } - - *currentPos = pos; - } - - private: - - bool m_canBeNIL; - string m_value; - - component* m_component; - const int m_data; - - public: - - const string& value() const { return (m_value); } - }; - - - // - // nstring ::= string / nil - // - - class nstring : public xstring - { - public: - - nstring(component* comp = NULL, const int data = 0) - : xstring(true, comp, data) - { - } - }; - - - // - // astring ::= atom / string - // - - class astring : public component - { - public: - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("astring"); - - string::size_type pos = *currentPos; - - xstring* str = NULL; - - if ((str = parser.get (line, &pos, true))) - { - m_value = str->value(); - delete (str); - } - else - { - atom* at = parser.get (line, &pos); - m_value = at->value(); - delete (at); - } - - *currentPos = pos; - } - - private: - - string m_value; - - public: - - const string& value() const { return (m_value); } - }; - - - // - // atom ::= 1*ATOM_CHAR - // - // ATOM_CHAR ::= - // atom_specials ::= "(" / ")" / "{" / SPACE / CTL / list_wildcards / quoted_specials - // CHAR ::= - // CTL ::= - // list_wildcards ::= "%" / "*" - // quoted_specials ::= <"> / "\" - // SPACE ::= - // - - class atom : public component - { - public: - - void go(IMAPParser& /* parser */, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("atom"); - - string::size_type pos = *currentPos; - string::size_type len = 0; - - for (bool end = false ; !end && pos < line.length() ; ) - { - const unsigned char c = line[pos]; - - switch (c) - { - case '(': - case ')': - case '{': - case 0x20: // SPACE - case '%': // list_wildcards - case '*': // list_wildcards - case '"': // quoted_specials - case '\\': // quoted_specials - - case '[': - case ']': // for "special_atom" - - end = true; - break; - - default: - - if (c <= 0x1f || c >= 0x7f) - end = true; - else - { - ++pos; - ++len; - } - } - } - - if (len != 0) - { - m_value.resize(len); - std::copy(line.begin() + *currentPos, line.begin() + pos, m_value.begin()); - - *currentPos = pos; - } - else - { - throw exceptions::invalid_response("", makeResponseLine("atom", line, pos)); - } - } - - private: - - string m_value; - - public: - - const string& value() const { return (m_value); } - }; - - - // - // special atom (eg. "CAPABILITY", "FLAGS", "STATUS"...) - // - // " Except as noted otherwise, all alphabetic characters are case- - // insensitive. The use of upper or lower case characters to define - // token strings is for editorial clarity only. Implementations MUST - // accept these strings in a case-insensitive fashion. " - // - - class special_atom : public atom - { - public: - - special_atom(const char* str) - : m_string(str) // 'string' must be in lower-case - { - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT(string("special_atom(") + m_string + ")"); - - string::size_type pos = *currentPos; - - atom::go(parser, line, &pos); - - const char* cmp = value().c_str(); - const char* with = m_string; - - bool ok = true; - - while (ok && *cmp && *with) - { - ok = (std::tolower(*cmp, std::locale()) == *with); - - ++cmp; - ++with; - } - - if (!ok || *cmp || *with) - { - throw exceptions::invalid_response("", makeResponseLine(string("special_atom <") + m_string + ">", line, pos)); - } - else - { - *currentPos = pos; - } - } - - private: - - const char* m_string; - }; - - - // - // text_mime2 ::= "=?" "?" "?" "?=" - // ;; Syntax defined in [MIME-HDRS] - // - - class text_mime2 : public component - { - public: - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("text_mime2"); - - string::size_type pos = *currentPos; - - atom* theCharset = NULL, *theEncoding = NULL; - text* theText = NULL; - - try - { - parser.check >(line, &pos); - - theCharset = parser.get (line, &pos); - - parser.check >(line, &pos); - - theEncoding = parser.get (line, &pos); - - parser.check >(line, &pos); - - theText = parser.get >(line, &pos); - - parser.check >(line, &pos); - parser.check value()[0] == 'Q') - { - // Quoted-printable - theEncoder = new encoderQP; - theEncoder->getProperties()["rfc2047"] = true; - } - else if (theEncoding->value()[0] == 'b' || theEncoding->value()[0] == 'B') - { - // Base64 - theEncoder = new encoderB64; - } - - if (theEncoder) - { - utility::inputStreamStringAdapter in(theText->value()); - utility::outputStreamStringAdapter out(m_value); - - theEncoder->decode(in, out); - delete (theEncoder); - } - // No decoder available - else - { - m_value = theText->value(); - } - - delete (theEncoding); - delete (theText); - - *currentPos = pos; - } - - private: - - vmime::charset m_charset; - string m_value; - - public: - - const vmime::charset& charset() const { return (m_charset); } - const string& value() const { return (m_value); } - }; - - - // - // flag ::= "\Answered" / "\Flagged" / "\Deleted" / - // "\Seen" / "\Draft" / flag_keyword / flag_extension - // - // flag_extension ::= "\" atom - // ;; Future expansion. Client implementations - // ;; MUST accept flag_extension flags. Server - // ;; implementations MUST NOT generate - // ;; flag_extension flags except as defined by - // ;; future standard or standards-track - // ;; revisions of this specification. - // - // flag_keyword ::= atom - // - - class flag : public component - { - public: - - flag() - : m_flag_keyword(NULL) - { - } - - ~flag() - { - delete (m_flag_keyword); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("flag_keyword"); - - string::size_type pos = *currentPos; - - if (parser.check >(line, &pos, true)) - { - if (parser.check >(line, &pos, true)) - { - m_type = STAR; - } - else - { - atom* at = parser.get (line, &pos); - const string name = utility::stringUtils::toLower(at->value()); - delete (at); - - if (name == "answered") - m_type = ANSWERED; - else if (name == "flagged") - m_type = FLAGGED; - else if (name == "deleted") - m_type = DELETED; - else if (name == "seen") - m_type = SEEN; - else if (name == "draft") - m_type = DRAFT; - else - { - m_type = UNKNOWN; - m_name = name; - } - } - } - else - { - m_flag_keyword = parser.get (line, &pos); - } - - *currentPos = pos; - } - - - enum Type - { - UNKNOWN, - ANSWERED, - FLAGGED, - DELETED, - SEEN, - DRAFT, - STAR // * = custom flags allowed - }; - - private: - - Type m_type; - string m_name; - - IMAPParser::atom* m_flag_keyword; - - public: - - const Type type() const { return (m_type); } - const string& name() const { return (m_name); } - - const IMAPParser::atom* flag_keyword() const { return (m_flag_keyword); } - }; - - - // - // flag_list ::= "(" #flag ")" - // - - class flag_list : public component - { - public: - - ~flag_list() - { - for (std::vector ::iterator it = m_flags.begin() ; - it != m_flags.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("flag_list"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - - while (!parser.check >(line, &pos, true)) - { - m_flags.push_back(parser.get (line, &pos)); - parser.check (line, &pos, true); - } - - *currentPos = pos; - } - - private: - - std::vector m_flags; - - public: - - const std::vector & flags() const { return (m_flags); } - }; - - - // - // mailbox ::= "INBOX" / astring - // ;; INBOX is case-insensitive. All case variants of - // ;; INBOX (e.g. "iNbOx") MUST be interpreted as INBOX - // ;; not as an astring. Refer to section 5.1 for - // ;; further semantic details of mailbox names. - // - - class mailbox : public component - { - public: - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("mailbox"); - - string::size_type pos = *currentPos; - - if (parser.checkWithArg (line, &pos, "inbox", true)) - { - m_type = INBOX; - m_name = "INBOX"; - } - else - { - m_type = OTHER; - - astring* astr = parser.get (line, &pos); - m_name = astr->value(); - delete (astr); - } - - *currentPos = pos; - } - - - enum Type - { - INBOX, - OTHER - }; - - private: - - Type m_type; - string m_name; - - public: - - const Type type() const { return (m_type); } - const string& name() const { return (m_name); } - }; - - - // - // mailbox_flag := "\Marked" / "\Noinferiors" / - // "\Noselect" / "\Unmarked" / flag_extension - // - - class mailbox_flag : public component - { - public: - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("mailbox_flag"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - - atom* at = parser.get (line, &pos); - const string name = utility::stringUtils::toLower(at->value()); - delete (at); - - if (name == "marked") - m_type = MARKED; - else if (name == "noinferiors") - m_type = NOINFERIORS; - else if (name == "noselect") - m_type = NOSELECT; - else if (name == "unmarked") - m_type = UNMARKED; - else - { - m_type = UNKNOWN; - m_name = name; - } - - *currentPos = pos; - } - - - enum Type - { - UNKNOWN, - MARKED, - NOINFERIORS, - NOSELECT, - UNMARKED - }; - - private: - - Type m_type; - string m_name; - - public: - - const Type type() const { return (m_type); } - const string& name() const { return (m_name); } - }; - - - // - // mailbox_flag_list ::= "(" #(mailbox_flag) ")" - // - - class mailbox_flag_list : public component - { - public: - - ~mailbox_flag_list() - { - for (std::vector ::iterator it = m_flags.begin() ; - it != m_flags.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("mailbox_flag_list"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - - while (!parser.check >(line, &pos, true)) - { - m_flags.push_back(parser.get (line, &pos)); - parser.check (line, &pos, true); - } - - *currentPos = pos; - } - - private: - - std::vector m_flags; - - public: - - const std::vector & flags() const { return (m_flags); } - }; - - - // - // mailbox_list ::= mailbox_flag_list SPACE - // (<"> QUOTED_CHAR <"> / nil) SPACE mailbox - // - - class mailbox_list : public component - { - public: - - mailbox_list() - : m_mailbox_flag_list(NULL), - m_mailbox(NULL), m_quoted_char('\0') - { - } - - ~mailbox_list() - { - delete (m_mailbox_flag_list); - delete (m_mailbox); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("mailbox_list"); - - string::size_type pos = *currentPos; - - m_mailbox_flag_list = parser.get (line, &pos); - - parser.check (line, &pos); - - if (!parser.check (line, &pos, true)) - { - parser.check >(line, &pos); - - QUOTED_CHAR* qc = parser.get (line, &pos); - m_quoted_char = qc->value(); - delete (qc); - - parser.check >(line, &pos); - } - - parser.check (line, &pos); - - m_mailbox = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::mailbox_flag_list* m_mailbox_flag_list; - IMAPParser::mailbox* m_mailbox; - char m_quoted_char; - - public: - - const IMAPParser::mailbox_flag_list* mailbox_flag_list() const { return (m_mailbox_flag_list); } - const IMAPParser::mailbox* mailbox() const { return (m_mailbox); } - const char quoted_char() const { return (m_quoted_char); } - }; - - - // - // resp_text_code ::= "ALERT" / "PARSE" / - // "PERMANENTFLAGS" SPACE "(" #(flag / "\*") ")" / - // "READ-ONLY" / "READ-WRITE" / "TRYCREATE" / - // "UIDVALIDITY" SPACE nz_number / - // "UNSEEN" SPACE nz_number / - // atom [SPACE 1*] - - class resp_text_code : public component - { - public: - - resp_text_code() - : m_nz_number(NULL), m_atom(NULL), m_flag_list(NULL), m_text(NULL) - { - } - - ~resp_text_code() - { - delete (m_nz_number); - delete (m_atom); - delete (m_flag_list); - delete (m_text); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("resp_text_code"); - - string::size_type pos = *currentPos; - - // "ALERT" - if (parser.checkWithArg (line, &pos, "alert", true)) - { - m_type = ALERT; - } - // "PARSE" - else if (parser.checkWithArg (line, &pos, "parse", true)) - { - m_type = PARSE; - } - // "PERMANENTFLAGS" SPACE flag_list - else if (parser.checkWithArg (line, &pos, "permanentflags", true)) - { - m_type = PERMANENTFLAGS; - - parser.check (line, &pos); - - m_flag_list = parser.get (line, &pos); - } - // "READ-ONLY" - else if (parser.checkWithArg (line, &pos, "read-only", true)) - { - m_type = READ_ONLY; - } - // "READ-WRITE" - else if (parser.checkWithArg (line, &pos, "read-write", true)) - { - m_type = READ_WRITE; - } - // "TRYCREATE" - else if (parser.checkWithArg (line, &pos, "trycreate", true)) - { - m_type = TRYCREATE; - } - // "UIDVALIDITY" SPACE nz_number - else if (parser.checkWithArg (line, &pos, "uidvalidity", true)) - { - m_type = UIDVALIDITY; - - parser.check (line, &pos); - m_nz_number = parser.get (line, &pos); - } - // "UNSEEN" SPACE nz_number - else if (parser.checkWithArg (line, &pos, "unseen", true)) - { - m_type = UNSEEN; - - parser.check (line, &pos); - m_nz_number = parser.get (line, &pos); - } - // atom [SPACE 1*] - else - { - m_type = OTHER; - - m_atom = parser.get (line, &pos); - - if (parser.check (line, &pos, true)) - m_text = parser.get >(line, &pos); - } - - *currentPos = pos; - } - - - enum Type - { - ALERT, - PARSE, - PERMANENTFLAGS, - READ_ONLY, - READ_WRITE, - TRYCREATE, - UIDVALIDITY, - UNSEEN, - OTHER - }; - - private: - - Type m_type; - - IMAPParser::nz_number* m_nz_number; - IMAPParser::atom* m_atom; - IMAPParser::flag_list* m_flag_list; - IMAPParser::text* m_text; - - public: - - const Type type() const { return (m_type); } - - const IMAPParser::nz_number* nz_number() const { return (m_nz_number); } - const IMAPParser::atom* atom() const { return (m_atom); } - const IMAPParser::flag_list* flag_list() const { return (m_flag_list); } - const IMAPParser::text* text() const { return (m_text); } - }; - - - // - // resp_text ::= ["[" resp_text_code "]" SPACE] (text_mime2 / text) - // ;; text SHOULD NOT begin with "[" or "=" - - class resp_text : public component - { - public: - - resp_text() - : m_resp_text_code(NULL) - { - } - - ~resp_text() - { - delete (m_resp_text_code); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("resp_text"); - - string::size_type pos = *currentPos; - - if (parser.check >(line, &pos, true)) - { - m_resp_text_code = parser.get (line, &pos); - - parser.check >(line, &pos); - parser.check (line, &pos); - } - - text_mime2* text1 = parser.get (line, &pos, true); - - if (text1 != NULL) - { - m_text = text1->value(); - delete (text1); - } - else - { - IMAPParser::text* text2 = - parser.get (line, &pos); - - m_text = text2->value(); - delete (text2); - } - - *currentPos = pos; - } - - private: - - IMAPParser::resp_text_code* m_resp_text_code; - string m_text; - - public: - - const IMAPParser::resp_text_code* resp_text_code() const { return (m_resp_text_code); } - const string& text() const { return (m_text); } - }; - - - // - // continue_req ::= "+" SPACE (resp_text / base64) - // - - class continue_req : public component - { - public: - - continue_req() - : m_resp_text(NULL) - { - } - - ~continue_req() - { - delete (m_resp_text); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("continue_req"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - parser.check (line, &pos); - - m_resp_text = parser.get (line, &pos); - - parser.check (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::resp_text* m_resp_text; - - public: - - const IMAPParser::resp_text* resp_text() const { return (m_resp_text); } - }; - - - // - // auth_type ::= atom - // ;; Defined by [IMAP-AUTH] - // - - class auth_type : public component - { - public: - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("auth_type"); - - atom* at = parser.get (line, currentPos); - m_name = utility::stringUtils::toLower(at->value()); - delete (at); - - if (m_name == "kerberos_v4") - m_type = KERBEROS_V4; - else if (m_name == "gssapi") - m_type = GSSAPI; - else if (m_name == "skey") - m_type = SKEY; - else - m_type = UNKNOWN; - } - - - enum Type - { - UNKNOWN, - - // RFC 1731 - IMAP4 Authentication Mechanisms - KERBEROS_V4, - GSSAPI, - SKEY - }; - - private: - - Type m_type; - string m_name; - - public: - - const Type type() const { return (m_type); } - const string name() const { return (m_name); } - }; - - - // - // status_att ::= "MESSAGES" / "RECENT" / "UIDNEXT" / - // "UIDVALIDITY" / "UNSEEN" - // - - class status_att : public component - { - public: - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("status_att"); - - string::size_type pos = *currentPos; - - if (parser.checkWithArg (line, &pos, "messages", true)) - { - m_type = MESSAGES; - } - else if (parser.checkWithArg (line, &pos, "recent", true)) - { - m_type = RECENT; - } - else if (parser.checkWithArg (line, &pos, "uidnext", true)) - { - m_type = UIDNEXT; - } - else if (parser.checkWithArg (line, &pos, "uidvalidity", true)) - { - m_type = UIDVALIDITY; - } - else - { - parser.checkWithArg (line, &pos, "unseen"); - m_type = UNSEEN; - } - - *currentPos = pos; - } - - - enum Type - { - MESSAGES, - RECENT, - UIDNEXT, - UIDVALIDITY, - UNSEEN - }; - - private: - - Type m_type; - - public: - - const Type type() const { return (m_type); } - }; - - - // - // capability ::= "AUTH=" auth_type / atom - // ;; New capabilities MUST begin with "X" or be - // ;; registered with IANA as standard or standards-track - // - - class capability : public component - { - public: - - capability() - : m_auth_type(NULL), m_atom(NULL) - { - } - - ~capability() - { - delete (m_auth_type); - delete (m_atom); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("capability"); - - string::size_type pos = *currentPos; - - class atom* at = parser.get (line, &pos); - - string value = at->value(); - const char* str = value.c_str(); - - if ((str[0] == 'a' || str[0] == 'A') && - (str[1] == 'u' || str[1] == 'U') && - (str[2] == 't' || str[2] == 'T') && - (str[3] == 'h' || str[3] == 'H') && - (str[4] == '=')) - { - string::size_type pos = 5; - m_auth_type = parser.get (value, &pos); - delete (at); - } - else - { - m_atom = at; - } - - *currentPos = pos; - } - - private: - - IMAPParser::auth_type* m_auth_type; - IMAPParser::atom* m_atom; - - public: - - const IMAPParser::auth_type* auth_type() const { return (m_auth_type); } - const IMAPParser::atom* atom() const { return (m_atom); } - }; - - - // - // capability_data ::= "CAPABILITY" SPACE [1#capability SPACE] "IMAP4rev1" - // [SPACE 1#capability] - // ;; IMAP4rev1 servers which offer RFC 1730 - // ;; compatibility MUST list "IMAP4" as the first - // ;; capability. - // - - class capability_data : public component - { - public: - - ~capability_data() - { - for (std::vector ::iterator it = m_capabilities.begin() ; - it != m_capabilities.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("capability_data"); - - string::size_type pos = *currentPos; - - parser.checkWithArg (line, &pos, "capability"); - parser.check (line, &pos); - - bool IMAP4rev1 = false; - - for (bool end = false ; !end && !IMAP4rev1 ; ) - { - if (parser.checkWithArg (line, &pos, "imap4rev1", true)) - { - IMAP4rev1 = true; - } - else - { - capability* cap = parser.get (line, &pos); - end = (cap == NULL); - - if (cap) - { - m_capabilities.push_back(cap); - } - } - - parser.check (line, &pos); - } - - - if (parser.check (line, &pos, true)) - { - for (capability* cap = NULL ; - (cap = parser.get (line, &pos)) != NULL ; ) - { - m_capabilities.push_back(cap); - - parser.check (line, &pos); - } - } - - *currentPos = pos; - } - - private: - - std::vector m_capabilities; - - public: - - const std::vector & capabilities() const { return (m_capabilities); } - }; - - - // - // date_day_fixed ::= (SPACE digit) / 2digit - // ;; Fixed-format version of date_day - // - // date_month ::= "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / - // "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec" - // - // date_year ::= 4digit - // - // time ::= 2digit ":" 2digit ":" 2digit - // ;; Hours minutes seconds - // - // zone ::= ("+" / "-") 4digit - // ;; Signed four-digit value of hhmm representing - // ;; hours and minutes west of Greenwich (that is, - // ;; (the amount that the given time differs from - // ;; Universal Time). Subtracting the timezone - // ;; from the given time will give the UT form. - // ;; The Universal Time zone is "+0000". - // - // date_time ::= <"> date_day_fixed "-" date_month "-" date_year - // SPACE time SPACE zone <"> - // - - class date_time : public component - { - public: - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("date_time"); - - string::size_type pos = *currentPos; - - // <"> date_day_fixed "-" date_month "-" date_year - parser.check >(line, &pos); - parser.check (line, &pos, true); - - utility::auto_ptr nd(parser.get (line, &pos)); - - parser.check >(line, &pos); - - utility::auto_ptr amo(parser.get (line, &pos)); - - parser.check >(line, &pos); - - utility::auto_ptr ny(parser.get (line, &pos)); - - parser.check (line, &pos, true); - - // 2digit ":" 2digit ":" 2digit - utility::auto_ptr nh(parser.get (line, &pos)); - - parser.check >(line, &pos); - - utility::auto_ptr nmi(parser.get (line, &pos)); - - parser.check >(line, &pos); - - utility::auto_ptr ns(parser.get (line, &pos)); - - parser.check (line, &pos, true); - - // ("+" / "-") 4digit - int sign = 1; - - if (!(parser.check >(line, &pos, true))) - parser.check >(line, &pos); - - utility::auto_ptr nz(parser.get (line, &pos)); - - parser.check >(line, &pos); - - - m_datetime.setHour(std::min(std::max(nh->value(), 0u), 23u)); - m_datetime.setMinute(std::min(std::max(nmi->value(), 0u), 59u)); - m_datetime.setSecond(std::min(std::max(ns->value(), 0u), 59u)); - - const int zone = static_cast (nz->value()); - const int zh = zone / 100; // hour offset - const int zm = zone % 100; // minute offset - - m_datetime.setZone(((zh * 60) + zm) * sign); - - m_datetime.setDay(std::min(std::max(nd->value(), 1u), 31u)); - m_datetime.setYear(ny->value()); - - const string month(utility::stringUtils::toLower(amo->value())); - int mon = vmime::datetime::JANUARY; - - if (month.length() >= 3) - { - switch (month[0]) - { - case 'j': - { - switch (month[1]) - { - case 'a': mon = vmime::datetime::JANUARY; break; - case 'u': - { - switch (month[2]) - { - case 'n': mon = vmime::datetime::JUNE; break; - default: mon = vmime::datetime::JULY; break; - } - - break; - } - - } - - break; - } - case 'f': mon = vmime::datetime::FEBRUARY; break; - case 'm': - { - switch (month[2]) - { - case 'r': mon = vmime::datetime::MARCH; break; - default: mon = vmime::datetime::MAY; break; - } - - break; - } - case 'a': - { - switch (month[1]) - { - case 'p': mon = vmime::datetime::APRIL; break; - default: mon = vmime::datetime::AUGUST; break; - } - - break; - } - case 's': mon = vmime::datetime::SEPTEMBER; break; - case 'o': mon = vmime::datetime::OCTOBER; break; - case 'n': mon = vmime::datetime::NOVEMBER; break; - case 'd': mon = vmime::datetime::DECEMBER; break; - } - } - - m_datetime.setMonth(mon); - - *currentPos = pos; - } - - private: - - vmime::datetime m_datetime; - }; - - - // - // header_fld_name ::= astring - // - - typedef astring header_fld_name; - - - // - // header_list ::= "(" 1#header_fld_name ")" - // - - class header_list : public component - { - public: - - ~header_list() - { - for (std::vector ::iterator it = m_fld_names.begin() ; - it != m_fld_names.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("header_list"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - - while (!parser.check >(line, &pos, true)) - { - m_fld_names.push_back(parser.get (line, &pos)); - parser.check (line, &pos, true); - } - - *currentPos = pos; - } - - private: - - std::vector m_fld_names; - - public: - - const std::vector & fld_names() const { return (m_fld_names); } - }; - - - // - // body_extension ::= nstring / number / "(" 1#body_extension ")" - // ;; Future expansion. Client implementations - // ;; MUST accept body_extension fields. Server - // ;; implementations MUST NOT generate - // ;; body_extension fields except as defined by - // ;; future standard or standards-track - // ;; revisions of this specification. - // - - class body_extension : public component - { - public: - - body_extension() - : m_nstring(NULL), m_number(NULL) - { - } - - ~body_extension() - { - delete (m_nstring); - delete (m_number); - - for (std::vector ::iterator it = m_body_extensions.begin() ; - it != m_body_extensions.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - string::size_type pos = *currentPos; - - if (parser.check >(line, &pos, true)) - { - m_body_extensions.push_back - (parser.get (line, &pos)); - - while (!parser.check >(line, &pos, true)) - m_body_extensions.push_back(parser.get (line, &pos, true)); - } - else - { - if (!(m_nstring = parser.get (line, &pos, true))) - m_number = parser.get (line, &pos); - } - - *currentPos = pos; - } - - private: - - IMAPParser::nstring* m_nstring; - IMAPParser::number* m_number; - - std::vector m_body_extensions; - - public: - - IMAPParser::nstring* nstring() const { return (m_nstring); } - IMAPParser::number* number() const { return (m_number); } - - const std::vector & body_extensions() const { return (m_body_extensions); } - }; - - - // - // section_text ::= "HEADER" / "HEADER.FIELDS" [".NOT"] - // SPACE header_list / "TEXT" / "MIME" - // - - class section_text : public component - { - public: - - section_text() - : m_header_list(NULL) - { - } - - ~section_text() - { - delete (m_header_list); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("section_text"); - - string::size_type pos = *currentPos; - - // "HEADER.FIELDS" [".NOT"] SPACE header_list - const bool b1 = parser.checkWithArg (line, &pos, "header.fields.not", true); - const bool b2 = (b1 ? false : parser.checkWithArg (line, &pos, "header.fields", true)); - - if (b1 || b2) - { - m_type = b1 ? HEADER_FIELDS_NOT : HEADER_FIELDS; - - parser.check (line, &pos); - m_header_list = parser.get (line, &pos); - } - // "HEADER" - else if (parser.checkWithArg (line, &pos, "header", true)) - { - m_type = HEADER; - } - // "MIME" - else if (parser.checkWithArg (line, &pos, "mime", true)) - { - m_type = MIME; - } - // "TEXT" - else - { - m_type = TEXT; - - parser.checkWithArg (line, &pos, "text"); - } - - *currentPos = pos; - } - - - enum Type - { - HEADER, - HEADER_FIELDS, - HEADER_FIELDS_NOT, - MIME, - TEXT - }; - - private: - - Type m_type; - IMAPParser::header_list* m_header_list; - - public: - - const Type type() const { return (m_type); } - const IMAPParser::header_list* header_list() const { return (m_header_list); } - }; - - - // - // section ::= "[" [section_text / (nz_number *["." nz_number] - // ["." (section_text / "MIME")])] "]" - // - - class section : public component - { - public: - - section() - : m_section_text1(NULL), m_section_text2(NULL) - { - } - - ~section() - { - delete (m_section_text1); - delete (m_section_text2); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("section"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - - if (!parser.check >(line, &pos, true)) - { - if (!(m_section_text1 = parser.get (line, &pos, true))) - { - nz_number* num = parser.get (line, &pos); - m_nz_numbers.push_back(num->value()); - delete (num); - - while (parser.check >(line, &pos, true)) - { - if ((num = parser.get (line, &pos, true))) - { - m_nz_numbers.push_back(num->value()); - delete (num); - } - else - { - m_section_text2 = parser.get (line, &pos); - break; - } - } - } - - parser.check >(line, &pos); - } - - *currentPos = pos; - } - - private: - - section_text* m_section_text1; - section_text* m_section_text2; - std::vector m_nz_numbers; - - public: - - const section_text* section_text1() const { return (m_section_text1); } - const section_text* section_text2() const { return (m_section_text2); } - const std::vector & nz_numbers() const { return (m_nz_numbers); } - }; - - - // - // addr_adl ::= nstring - // ;; Holds route from [RFC-822] route-addr if - // ;; non-NIL - // - // addr_host ::= nstring - // ;; NIL indicates [RFC-822] group syntax. - // ;; Otherwise, holds [RFC-822] domain name - // - // addr_mailbox ::= nstring - // ;; NIL indicates end of [RFC-822] group; if - // ;; non-NIL and addr_host is NIL, holds - // ;; [RFC-822] group name. - // ;; Otherwise, holds [RFC-822] local-part - // - // addr_name ::= nstring - // ;; Holds phrase from [RFC-822] mailbox if - // ;; non-NIL - // - // address ::= "(" addr_name SPACE addr_adl SPACE addr_mailbox - // SPACE addr_host ")" - // - - class address : public component - { - public: - - address() - : m_addr_name(NULL), m_addr_adl(NULL), - m_addr_mailbox(NULL), m_addr_host(NULL) - { - } - - ~address() - { - delete (m_addr_name); - delete (m_addr_adl); - delete (m_addr_mailbox); - delete (m_addr_host); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("address"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - m_addr_name = parser.get (line, &pos); - parser.check (line, &pos); - m_addr_adl = parser.get (line, &pos); - parser.check (line, &pos); - m_addr_mailbox = parser.get (line, &pos); - parser.check (line, &pos); - m_addr_host = parser.get (line, &pos); - parser.check >(line, &pos); - - *currentPos = pos; - } - - private: - - nstring* m_addr_name; - nstring* m_addr_adl; - nstring* m_addr_mailbox; - nstring* m_addr_host; - - public: - - nstring* addr_name() const { return (m_addr_name); } - nstring* addr_adl() const { return (m_addr_adl); } - nstring* addr_mailbox() const { return (m_addr_mailbox); } - nstring* addr_host() const { return (m_addr_host); } - }; - - - // - // address_list ::= "(" 1*address ")" / nil - // - - class address_list : public component - { - public: - - ~address_list() - { - for (std::vector ::iterator it = m_addresses.begin() ; - it != m_addresses.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("address_list"); - - string::size_type pos = *currentPos; - - if (!parser.check (line, &pos, true)) - { - parser.check >(line, &pos); - - while (!parser.check >(line, &pos, true)) - { - m_addresses.push_back(parser.get
(line, &pos)); - parser.check (line, &pos, true); - } - } - - *currentPos = pos; - } - - private: - - std::vector m_addresses; - - public: - - const std::vector & addresses() const { return (m_addresses); } - }; - - - // - // env_bcc ::= "(" 1*address ")" / nil - // - - typedef address_list env_bcc; - - - // - // env_cc ::= "(" 1*address ")" / nil - // - - typedef address_list env_cc; - - - // - // env_date ::= nstring - // - - typedef nstring env_date; - - - // - // env_from ::= "(" 1*address ")" / nil - // - - typedef address_list env_from; - - - // - // env_in_reply_to ::= nstring - // - - typedef nstring env_in_reply_to; - - - // - // env_message_id ::= nstring - // - - typedef nstring env_message_id; - - - // - // env_reply_to ::= "(" 1*address ")" / nil - // - - typedef address_list env_reply_to; - - - // - // env_sender ::= "(" 1*address ")" / nil - // - - typedef address_list env_sender; - - - // - // env_subject ::= nstring - // - - typedef nstring env_subject; - - - // - // env_to ::= "(" 1*address ")" / nil - // - - typedef address_list env_to; - - - // - // envelope ::= "(" env_date SPACE env_subject SPACE env_from - // SPACE env_sender SPACE env_reply_to SPACE env_to - // SPACE env_cc SPACE env_bcc SPACE env_in_reply_to - // SPACE env_message_id ")" - // - - class envelope : public component - { - public: - - envelope() - : m_env_date(NULL), m_env_subject(NULL), - m_env_from(NULL), m_env_sender(NULL), m_env_reply_to(NULL), - m_env_to(NULL), m_env_cc(NULL), m_env_bcc(NULL), - m_env_in_reply_to(NULL), m_env_message_id(NULL) - { - } - - ~envelope() - { - delete (m_env_date); - delete (m_env_subject); - delete (m_env_from); - delete (m_env_sender); - delete (m_env_reply_to); - delete (m_env_to); - delete (m_env_cc); - delete (m_env_bcc); - delete (m_env_in_reply_to); - delete (m_env_message_id); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("envelope"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - - m_env_date = parser.get (line, &pos); - parser.check (line, &pos); - - m_env_subject = parser.get (line, &pos); - parser.check (line, &pos); - - m_env_from = parser.get (line, &pos); - parser.check (line, &pos); - - m_env_sender = parser.get (line, &pos); - parser.check (line, &pos); - - m_env_reply_to = parser.get (line, &pos); - parser.check (line, &pos); - - m_env_to = parser.get (line, &pos); - parser.check (line, &pos); - - m_env_cc = parser.get (line, &pos); - parser.check (line, &pos); - - m_env_bcc = parser.get (line, &pos); - parser.check (line, &pos); - - m_env_in_reply_to = parser.get (line, &pos); - parser.check (line, &pos); - - m_env_message_id = parser.get (line, &pos); - - parser.check >(line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::env_date* m_env_date; - IMAPParser::env_subject* m_env_subject; - IMAPParser::env_from* m_env_from; - IMAPParser::env_sender* m_env_sender; - IMAPParser::env_reply_to* m_env_reply_to; - IMAPParser::env_to* m_env_to; - IMAPParser::env_cc* m_env_cc; - IMAPParser::env_bcc* m_env_bcc; - IMAPParser::env_in_reply_to* m_env_in_reply_to; - IMAPParser::env_message_id* m_env_message_id; - - public: - - const IMAPParser::env_date* env_date() const { return (m_env_date); } - const IMAPParser::env_subject* env_subject() const { return (m_env_subject); } - const IMAPParser::env_from* env_from() const { return (m_env_from); } - const IMAPParser::env_sender* env_sender() const { return (m_env_sender); } - const IMAPParser::env_reply_to* env_reply_to() const { return (m_env_reply_to); } - const IMAPParser::env_to* env_to() const { return (m_env_to); } - const IMAPParser::env_cc* env_cc() const { return (m_env_cc); } - const IMAPParser::env_bcc* env_bcc() const { return (m_env_bcc); } - const IMAPParser::env_in_reply_to* env_in_reply_to() const { return (m_env_in_reply_to); } - const IMAPParser::env_message_id* env_message_id() const { return (m_env_message_id); } - }; - - - // - // body_fld_desc ::= nstring - // - - typedef nstring body_fld_desc; - - - // - // body_fld_id ::= nstring - // - - typedef nstring body_fld_id; - - - // - // body_fld_md5 ::= nstring - // - - typedef nstring body_fld_md5; - - - // - // body_fld_octets ::= number - // - - typedef number body_fld_octets; - - - // - // body_fld_lines ::= number - // - - typedef number body_fld_lines; - - - // - // body_fld_enc ::= (<"> ("7BIT" / "8BIT" / "BINARY" / "BASE64"/ - // "QUOTED-PRINTABLE") <">) / string - // - - typedef xstring body_fld_enc; - - - // - // body_fld_param_item ::= string SPACE string - // - - class body_fld_param_item : public component - { - public: - - body_fld_param_item() - : m_string1(NULL), m_string2(NULL) - { - } - - ~body_fld_param_item() - { - delete (m_string1); - delete (m_string2); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body_fld_param_item"); - - string::size_type pos = *currentPos; - - m_string1 = parser.get (line, &pos); - parser.check (line, &pos); - m_string2 = parser.get (line, &pos); - - DEBUG_FOUND("body_fld_param_item", "<" << m_string1->value() << ", " << m_string2->value() << ">"); - - *currentPos = pos; - } - - private: - - xstring* m_string1; - xstring* m_string2; - - public: - - const xstring* string1() const { return (m_string1); } - const xstring* string2() const { return (m_string2); } - }; - - - // - // body_fld_param ::= "(" 1#(body_fld_param_item) ")" / nil - // - - class body_fld_param : public component - { - public: - - ~body_fld_param() - { - for (std::vector ::iterator it = m_items.begin() ; - it != m_items.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body_fld_param"); - - string::size_type pos = *currentPos; - - if (!parser.check (line, &pos, true)) - { - parser.check >(line, &pos); - - m_items.push_back(parser.get (line, &pos)); - - while (!parser.check >(line, &pos, true)) - { - parser.check (line, &pos); - m_items.push_back(parser.get (line, &pos)); - } - } - - *currentPos = pos; - } - - private: - - std::vector m_items; - - public: - - const std::vector & items() const { return (m_items); } - }; - - - // - // body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil - // - - class body_fld_dsp : public component - { - public: - - body_fld_dsp() - : m_string(NULL), m_body_fld_param(NULL) - { - } - - ~body_fld_dsp() - { - delete (m_string); - delete (m_body_fld_param); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body_fld_dsp"); - - string::size_type pos = *currentPos; - - if (!parser.check (line, &pos, true)) - { - parser.check >(line, &pos); - m_string = parser.get (line, &pos); - parser.check (line, &pos); - m_body_fld_param = parser.get (line, &pos); - parser.check >(line, &pos); - } - - *currentPos = pos; - } - - private: - - class xstring* m_string; - class body_fld_param* m_body_fld_param; - - public: - - const class xstring* str() const { return (m_string); } - const class body_fld_param* body_fld_param() const { return (m_body_fld_param); } - }; - - - // - // body_fld_lang ::= nstring / "(" 1#string ")" - // - - class body_fld_lang : public component - { - public: - - ~body_fld_lang() - { - for (std::vector ::iterator it = m_strings.begin() ; - it != m_strings.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body_fld_lang"); - - string::size_type pos = *currentPos; - - if (parser.check >(line, &pos, true)) - { - m_strings.push_back(parser.get (line, &pos)); - - while (!parser.check >(line, &pos, true)) - m_strings.push_back(parser.get (line, &pos)); - } - else - { - m_strings.push_back(parser.get (line, &pos)); - } - - *currentPos = pos; - } - - private: - - std::vector m_strings; - - public: - - const std::vector & strings() const { return (m_strings); } - }; - - - // - // body_fields ::= body_fld_param SPACE body_fld_id SPACE - // body_fld_desc SPACE body_fld_enc SPACE - // body_fld_octets - // - - class body_fields : public component - { - public: - - body_fields() - : m_body_fld_param(NULL), m_body_fld_id(NULL), - m_body_fld_desc(NULL), m_body_fld_enc(NULL), m_body_fld_octets(NULL) - { - } - - ~body_fields() - { - delete (m_body_fld_param); - delete (m_body_fld_id); - delete (m_body_fld_desc); - delete (m_body_fld_enc); - delete (m_body_fld_octets); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body_fields"); - - string::size_type pos = *currentPos; - - m_body_fld_param = parser.get (line, &pos); - parser.check (line, &pos); - m_body_fld_id = parser.get (line, &pos); - parser.check (line, &pos); - m_body_fld_desc = parser.get (line, &pos); - parser.check (line, &pos); - m_body_fld_enc = parser.get (line, &pos); - parser.check (line, &pos); - m_body_fld_octets = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::body_fld_param* m_body_fld_param; - IMAPParser::body_fld_id* m_body_fld_id; - IMAPParser::body_fld_desc* m_body_fld_desc; - IMAPParser::body_fld_enc* m_body_fld_enc; - IMAPParser::body_fld_octets* m_body_fld_octets; - - public: - - const IMAPParser::body_fld_param* body_fld_param() const { return (m_body_fld_param); } - const IMAPParser::body_fld_id* body_fld_id() const { return (m_body_fld_id); } - const IMAPParser::body_fld_desc* body_fld_desc() const { return (m_body_fld_desc); } - const IMAPParser::body_fld_enc* body_fld_enc() const { return (m_body_fld_enc); } - const IMAPParser::body_fld_octets* body_fld_octets() const { return (m_body_fld_octets); } - }; - - - // - // media_subtype ::= string - // ;; Defined in [MIME-IMT] - // - - typedef xstring media_subtype; - - - // - // media_text ::= <"> "TEXT" <"> SPACE media_subtype - // ;; Defined in [MIME-IMT] - // - - class media_text : public component - { - public: - - media_text() - : m_media_subtype(NULL) - { - } - - ~media_text() - { - delete (m_media_subtype); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("media_text"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - parser.checkWithArg (line, &pos, "text"); - parser.check >(line, &pos); - parser.check (line, &pos); - - m_media_subtype = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::media_subtype* m_media_subtype; - - public: - - const IMAPParser::media_subtype* media_subtype() const { return (m_media_subtype); } - }; - - - // - // media_message ::= <"> "MESSAGE" <"> SPACE <"> "RFC822" <"> - // ;; Defined in [MIME-IMT] - // - - class media_message : public component - { - public: - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("media_message"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - parser.checkWithArg (line, &pos, "message"); - parser.check >(line, &pos); - parser.check (line, &pos); - - //parser.check >(line, &pos); - //parser.checkWithArg (line, &pos, "rfc822"); - //parser.check >(line, &pos); - - m_media_subtype = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::media_subtype* m_media_subtype; - - public: - - const IMAPParser::media_subtype* media_subtype() const { return (m_media_subtype); } - }; - - - // - // media_basic ::= (<"> ("APPLICATION" / "AUDIO" / "IMAGE" / - // "MESSAGE" / "VIDEO") <">) / string) - // SPACE media_subtype - // ;; Defined in [MIME-IMT] - - class media_basic : public component - { - public: - - media_basic() - : m_media_type(NULL), m_media_subtype(NULL) - { - } - - ~media_basic() - { - delete (m_media_type); - delete (m_media_subtype); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("media_basic"); - - string::size_type pos = *currentPos; - - m_media_type = parser.get (line, &pos); - - parser.check (line, &pos); - - m_media_subtype = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::xstring* m_media_type; - IMAPParser::media_subtype* m_media_subtype; - - public: - - const IMAPParser::xstring* media_type() const { return (m_media_type); } - const IMAPParser::media_subtype* media_subtype() const { return (m_media_subtype); } - }; - - - // - // body_ext_1part ::= body_fld_md5 [SPACE body_fld_dsp - // [SPACE body_fld_lang - // [SPACE 1#body_extension]]] - // ;; MUST NOT be returned on non-extensible - // ;; "BODY" fetch - // - - class body_ext_1part : public component - { - public: - - body_ext_1part() - : m_body_fld_md5(NULL), m_body_fld_dsp(NULL), m_body_fld_lang(NULL) - { - } - - ~body_ext_1part() - { - delete (m_body_fld_md5); - delete (m_body_fld_dsp); - delete (m_body_fld_lang); - - for (std::vector ::iterator it = m_body_extensions.begin() ; - it != m_body_extensions.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body_ext_1part"); - - string::size_type pos = *currentPos; - - m_body_fld_md5 = parser.get (line, &pos); - - // [SPACE body_fld_dsp - if (parser.check (line, &pos, true)) - { - m_body_fld_dsp = parser.get (line, &pos); - - // [SPACE body_fld_lang - if (parser.check (line, &pos, true)) - { - m_body_fld_lang = parser.get (line, &pos); - - // [SPACE 1#body_extension] - if (parser.check (line, &pos, true)) - { - m_body_extensions.push_back - (parser.get (line, &pos)); - - body_extension* ext = NULL; - - while ((ext = parser.get (line, &pos, true)) != NULL) - m_body_extensions.push_back(ext); - } - } - } - - *currentPos = pos; - } - - private: - - IMAPParser::body_fld_md5* m_body_fld_md5; - IMAPParser::body_fld_dsp* m_body_fld_dsp; - IMAPParser::body_fld_lang* m_body_fld_lang; - - std::vector m_body_extensions; - - public: - - const IMAPParser::body_fld_md5* body_fld_md5() const { return (m_body_fld_md5); } - const IMAPParser::body_fld_dsp* body_fld_dsp() const { return (m_body_fld_dsp); } - const IMAPParser::body_fld_lang* body_fld_lang() const { return (m_body_fld_lang); } - - const std::vector body_extensions() const { return (m_body_extensions); } - }; - - - // - // body_ext_mpart ::= body_fld_param - // [SPACE body_fld_dsp SPACE body_fld_lang - // [SPACE 1#body_extension]] - // ;; MUST NOT be returned on non-extensible - // ;; "BODY" fetch - - class body_ext_mpart : public component - { - public: - - body_ext_mpart() - : m_body_fld_param(NULL), m_body_fld_dsp(NULL), m_body_fld_lang(NULL) - { - } - - ~body_ext_mpart() - { - delete (m_body_fld_param); - delete (m_body_fld_dsp); - delete (m_body_fld_lang); - - for (std::vector ::iterator it = m_body_extensions.begin() ; - it != m_body_extensions.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body_ext_mpart"); - - string::size_type pos = *currentPos; - - m_body_fld_param = parser.get (line, &pos); - - // [SPACE body_fld_dsp SPACE body_fld_lang [SPACE 1#body_extension]] - if (parser.check (line, &pos, true)) - { - m_body_fld_dsp = parser.get (line, &pos); - parser.check (line, &pos); - m_body_fld_lang = parser.get (line, &pos); - - // [SPACE 1#body_extension] - if (parser.check (line, &pos, true)) - { - m_body_extensions.push_back - (parser.get (line, &pos)); - - body_extension* ext = NULL; - - while ((ext = parser.get (line, &pos, true)) != NULL) - m_body_extensions.push_back(ext); - } - } - - *currentPos = pos; - } - - private: - - IMAPParser::body_fld_param* m_body_fld_param; - IMAPParser::body_fld_dsp* m_body_fld_dsp; - IMAPParser::body_fld_lang* m_body_fld_lang; - - std::vector m_body_extensions; - - public: - - const IMAPParser::body_fld_param* body_fld_param() const { return (m_body_fld_param); } - const IMAPParser::body_fld_dsp* body_fld_dsp() const { return (m_body_fld_dsp); } - const IMAPParser::body_fld_lang* body_fld_lang() const { return (m_body_fld_lang); } - - const std::vector body_extensions() const { return (m_body_extensions); } - }; - - - // - // body_type_basic ::= media_basic SPACE body_fields - // ;; MESSAGE subtype MUST NOT be "RFC822" - // - - class body_type_basic : public component - { - public: - - body_type_basic() - : m_media_basic(NULL), m_body_fields(NULL) - { - } - - ~body_type_basic() - { - delete (m_media_basic); - delete (m_body_fields); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body_type_basic"); - - string::size_type pos = *currentPos; - - m_media_basic = parser.get (line, &pos); - parser.check (line, &pos); - m_body_fields = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::media_basic* m_media_basic; - IMAPParser::body_fields* m_body_fields; - - public: - - const IMAPParser::media_basic* media_basic() const { return (m_media_basic); } - const IMAPParser::body_fields* body_fields() const { return (m_body_fields); } - }; - - - // - // body_type_msg ::= media_message SPACE body_fields SPACE envelope - // SPACE body SPACE body_fld_lines - // - - class xbody; - typedef xbody body; - - class body_type_msg : public component - { - public: - - body_type_msg() - : m_media_message(NULL), m_body_fields(NULL), - m_envelope(NULL), m_body(NULL), m_body_fld_lines(NULL) - { - } - - ~body_type_msg() - { - delete (m_media_message); - delete (m_body_fields); - delete (m_envelope); - delete (m_body); - delete (m_body_fld_lines); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body_type_msg"); - - string::size_type pos = *currentPos; - - m_media_message = parser.get (line, &pos); - parser.check (line, &pos); - m_body_fields = parser.get (line, &pos); - parser.check (line, &pos); - m_envelope = parser.get (line, &pos); - parser.check (line, &pos); - m_body = parser.get (line, &pos); - parser.check (line, &pos); - m_body_fld_lines = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::media_message* m_media_message; - IMAPParser::body_fields* m_body_fields; - IMAPParser::envelope* m_envelope; - IMAPParser::xbody* m_body; - IMAPParser::body_fld_lines* m_body_fld_lines; - - public: - - const IMAPParser::media_message* media_message() const { return (m_media_message); } - const IMAPParser::body_fields* body_fields() const { return (m_body_fields); } - const IMAPParser::envelope* envelope() const { return (m_envelope); } - const IMAPParser::xbody* body() const { return (m_body); } - const IMAPParser::body_fld_lines* body_fld_lines() const { return (m_body_fld_lines); } - }; - - - // - // body_type_text ::= media_text SPACE body_fields SPACE body_fld_lines - // - - class body_type_text : public component - { - public: - - body_type_text() - : m_media_text(NULL), - m_body_fields(NULL), m_body_fld_lines(NULL) - { - } - - ~body_type_text() - { - delete (m_media_text); - delete (m_body_fields); - delete (m_body_fld_lines); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body_type_text"); - - string::size_type pos = *currentPos; - - m_media_text = parser.get (line, &pos); - parser.check (line, &pos); - m_body_fields = parser.get (line, &pos); - parser.check (line, &pos); - m_body_fld_lines = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::media_text* m_media_text; - IMAPParser::body_fields* m_body_fields; - IMAPParser::body_fld_lines* m_body_fld_lines; - - public: - - const IMAPParser::media_text* media_text() const { return (m_media_text); } - const IMAPParser::body_fields* body_fields() const { return (m_body_fields); } - const IMAPParser::body_fld_lines* body_fld_lines() const { return (m_body_fld_lines); } - }; - - - // - // body_type_1part ::= (body_type_basic / body_type_msg / body_type_text) - // [SPACE body_ext_1part] - // - - class body_type_1part : public component - { - public: - - body_type_1part() - : m_body_type_basic(NULL), m_body_type_msg(NULL), - m_body_type_text(NULL), m_body_ext_1part(NULL) - { - } - - ~body_type_1part() - { - delete (m_body_type_basic); - delete (m_body_type_msg); - delete (m_body_type_text); - - delete (m_body_ext_1part); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body_type_1part"); - - string::size_type pos = *currentPos; - - if (!(m_body_type_text = parser.get (line, &pos, true))) - if (!(m_body_type_msg = parser.get (line, &pos, true))) - m_body_type_basic = parser.get (line, &pos); - - if (parser.check (line, &pos, true)) - m_body_ext_1part = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::body_type_basic* m_body_type_basic; - IMAPParser::body_type_msg* m_body_type_msg; - IMAPParser::body_type_text* m_body_type_text; - - IMAPParser::body_ext_1part* m_body_ext_1part; - - public: - - const IMAPParser::body_type_basic* body_type_basic() const { return (m_body_type_basic); } - const IMAPParser::body_type_msg* body_type_msg() const { return (m_body_type_msg); } - const IMAPParser::body_type_text* body_type_text() const { return (m_body_type_text); } - - const IMAPParser::body_ext_1part* body_ext_1part() const { return (m_body_ext_1part); } - }; - - - // - // body_type_mpart ::= 1*body SPACE media_subtype - // [SPACE body_ext_mpart] - // - - class body_type_mpart : public component - { - public: - - body_type_mpart() - : m_media_subtype(NULL), m_body_ext_mpart(NULL) - { - } - - ~body_type_mpart() - { - delete (m_media_subtype); - delete (m_body_ext_mpart); - - for (std::vector ::iterator it = m_list.begin() ; - it != m_list.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body_type_mpart"); - - string::size_type pos = *currentPos; - - m_list.push_back(parser.get (line, &pos)); - - for (xbody* b ; (b = parser.get (line, &pos, true)) ; ) - m_list.push_back(b); - - parser.check (line, &pos); - - m_media_subtype = parser.get (line, &pos); - - if (parser.check (line, &pos, true)) - m_body_ext_mpart = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::media_subtype* m_media_subtype; - IMAPParser::body_ext_mpart* m_body_ext_mpart; - - std::vector m_list; - - public: - - const std::vector & list() const { return (m_list); } - - const IMAPParser::media_subtype* media_subtype() const { return (m_media_subtype); } - const IMAPParser::body_ext_mpart* body_ext_mpart() const { return (m_body_ext_mpart); } - }; - - - // - // xbody ::= "(" body_type_1part / body_type_mpart ")" - // - - class xbody : public component - { - public: - - xbody() - : m_body_type_1part(NULL), m_body_type_mpart(NULL) - { - } - - ~xbody() - { - delete (m_body_type_1part); - delete (m_body_type_mpart); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("body"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - - if (!(m_body_type_1part = parser.get (line, &pos, true))) - m_body_type_mpart = parser.get (line, &pos); - - parser.check >(line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::body_type_1part* m_body_type_1part; - IMAPParser::body_type_mpart* m_body_type_mpart; - - public: - - const IMAPParser::body_type_1part* body_type_1part() const { return (m_body_type_1part); } - const IMAPParser::body_type_mpart* body_type_mpart() const { return (m_body_type_mpart); } - }; - - - // - // uniqueid ::= nz_number - // ;; Strictly ascending - // - // msg_att_item ::= "ENVELOPE" SPACE envelope / - // "FLAGS" SPACE "(" #(flag / "\Recent") ")" / - // "INTERNALDATE" SPACE date_time / - // "RFC822" [".HEADER" / ".TEXT"] SPACE nstring / - // "RFC822.SIZE" SPACE number / - // "BODY" ["STRUCTURE"] SPACE body / - // "BODY" section ["<" number ">"] SPACE nstring / - // "UID" SPACE uniqueid - // - - class msg_att_item : public component - { - public: - - msg_att_item() - : m_date_time(NULL), m_number(NULL), m_envelope(NULL), - m_uniqueid(NULL), m_nstring(NULL), m_body(NULL), m_flag_list(NULL) - { - } - - ~msg_att_item() - { - delete (m_date_time); - delete (m_number); - delete (m_envelope); - delete (m_uniqueid); - delete (m_nstring); - delete (m_body); - delete (m_flag_list); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("msg_att_item"); - - string::size_type pos = *currentPos; - - // "ENVELOPE" SPACE envelope - if (parser.checkWithArg (line, &pos, "envelope", true)) - { - m_type = ENVELOPE; - - parser.check (line, &pos); - m_envelope = parser.get (line, &pos); - } - // "FLAGS" SPACE "(" #(flag / "\Recent") ")" - else if (parser.checkWithArg (line, &pos, "flags", true)) - { - m_type = FLAGS; - - parser.check (line, &pos); - - m_flag_list = parser.get (line, &pos); - } - // "INTERNALDATE" SPACE date_time - else if (parser.checkWithArg (line, &pos, "internaldate", true)) - { - m_type = INTERNALDATE; - - parser.check (line, &pos); - m_date_time = parser.get (line, &pos); - } - // "RFC822" ".HEADER" SPACE nstring - else if (parser.checkWithArg (line, &pos, "rfc822.header", true)) - { - m_type = RFC822_HEADER; - - parser.check (line, &pos); - - m_nstring = parser.get (line, &pos); - } - // "RFC822" ".TEXT" SPACE nstring - else if (parser.checkWithArg (line, &pos, "rfc822.text", true)) - { - m_type = RFC822_TEXT; - - parser.check (line, &pos); - - m_nstring = parser.getWithArgs - (line, &pos, this, RFC822_TEXT); - } - // "RFC822.SIZE" SPACE number - else if (parser.checkWithArg (line, &pos, "rfc822.size", true)) - { - m_type = RFC822_SIZE; - - parser.check (line, &pos); - m_number = parser.get (line, &pos); - } - // "RFC822" SPACE nstring - else if (parser.checkWithArg (line, &pos, "rfc822", true)) - { - m_type = RFC822; - - parser.check (line, &pos); - - m_nstring = parser.get (line, &pos); - } - // "BODY" "STRUCTURE" SPACE body - else if (parser.checkWithArg (line, &pos, "bodystructure", true)) - { - m_type = BODY_STRUCTURE; - - parser.check (line, &pos); - - m_body = parser.get (line, &pos); - } - // "BODY" section ["<" number ">"] SPACE nstring - // "BODY" SPACE body - else if (parser.checkWithArg (line, &pos, "body", true)) - { - m_section = parser.get (line, &pos, true); - - // "BODY" section ["<" number ">"] SPACE nstring - if (m_section != NULL) - { - m_type = BODY_SECTION; - - if (parser.check >(line, &pos, true)) - { - m_number = parser.get (line, &pos); - parser.check '> >(line, &pos); - } - - parser.check (line, &pos); - - m_nstring = parser.getWithArgs - (line, &pos, this, BODY_SECTION); - } - // "BODY" SPACE body - else - { - m_type = BODY; - - parser.check (line, &pos); - - m_body = parser.get (line, &pos); - } - } - // "UID" SPACE uniqueid - else - { - m_type = UID; - - parser.checkWithArg (line, &pos, "uid"); - parser.check (line, &pos); - - m_uniqueid = parser.get (line, &pos); - } - - *currentPos = pos; - } - - - enum Type - { - ENVELOPE, - FLAGS, - INTERNALDATE, - RFC822, - RFC822_SIZE, - RFC822_HEADER, - RFC822_TEXT, - BODY, - BODY_SECTION, - BODY_STRUCTURE, - UID - }; - - private: - - Type m_type; - - IMAPParser::date_time* m_date_time; - IMAPParser::number* m_number; - IMAPParser::envelope* m_envelope; - IMAPParser::nz_number* m_uniqueid; - IMAPParser::nstring* m_nstring; - IMAPParser::xbody* m_body; - IMAPParser::flag_list* m_flag_list; - IMAPParser::section* m_section; - - public: - - const Type type() const { return (m_type); } - - const IMAPParser::date_time* date_time() const { return (m_date_time); } - const IMAPParser::number* number() const { return (m_number); } - const IMAPParser::envelope* envelope() const { return (m_envelope); } - const IMAPParser::nz_number* unique_id() const { return (m_uniqueid); } - const IMAPParser::nstring* nstring() const { return (m_nstring); } - const IMAPParser::xbody* body() const { return (m_body); } - const IMAPParser::flag_list* flag_list() const { return (m_flag_list); } - const IMAPParser::section* section() const { return (m_section); } - }; - - - // - // msg_att ::= "(" 1#(msg_att_item) ")" - // - - class msg_att : public component - { - public: - - ~msg_att() - { - for (std::vector ::iterator it = m_items.begin() ; - it != m_items.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("msg_att"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - - m_items.push_back(parser.get (line, &pos)); - - while (!parser.check >(line, &pos, true)) - { - parser.check (line, &pos); - m_items.push_back(parser.get (line, &pos)); - } - - *currentPos = pos; - } - - private: - - std::vector m_items; - - public: - - const std::vector & items() const { return (m_items); } - }; - - - // - // message_data ::= nz_number SPACE ("EXPUNGE" / - // ("FETCH" SPACE msg_att)) - // - - class message_data : public component - { - public: - - message_data() - : m_number(0), m_msg_att(NULL) - { - } - - ~message_data() - { - delete (m_msg_att); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("message_data"); - - string::size_type pos = *currentPos; - - nz_number* num = parser.get (line, &pos); - m_number = num->value(); - delete (num); - - parser.check (line, &pos); - - if (parser.checkWithArg (line, &pos, "expunge", true)) - { - m_type = EXPUNGE; - } - else - { - parser.checkWithArg (line, &pos, "fetch"); - - parser.check (line, &pos); - - m_type = FETCH; - m_msg_att = parser.get (line, &pos); - } - - *currentPos = pos; - } - - - enum Type - { - EXPUNGE, - FETCH - }; - - private: - - Type m_type; - unsigned int m_number; - IMAPParser::msg_att* m_msg_att; - - public: - - const Type type() const { return (m_type); } - const unsigned int number() const { return (m_number); } - const IMAPParser::msg_att* msg_att() const { return (m_msg_att); } - }; - - - // - // resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text - // ;; Status condition - // - - class resp_cond_state : public component - { - public: - - resp_cond_state() - : m_resp_text(NULL), m_status(BAD) - { - } - - ~resp_cond_state() - { - delete (m_resp_text); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("resp_cond_state"); - - string::size_type pos = *currentPos; - - if (parser.checkWithArg (line, &pos, "ok", true)) - { - m_status = OK; - } - else if (parser.checkWithArg (line, &pos, "no", true)) - { - m_status = NO; - } - else - { - parser.checkWithArg (line, &pos, "bad"); - m_status = BAD; - } - - parser.check (line, &pos); - - m_resp_text = parser.get (line, &pos); - - *currentPos = pos; - } - - - enum Status - { - OK, - NO, - BAD - }; - - private: - - IMAPParser::resp_text* m_resp_text; - Status m_status; - - public: - - const IMAPParser::resp_text* resp_text() const { return (m_resp_text); } - const Status status() const { return (m_status); } - }; - - - // - // resp_cond_bye ::= "BYE" SPACE resp_text - // - - class resp_cond_bye : public component - { - public: - - resp_cond_bye() - : m_resp_text(NULL) - { - } - - ~resp_cond_bye() - { - delete (m_resp_text); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("resp_cond_bye"); - - string::size_type pos = *currentPos; - - parser.checkWithArg (line, &pos, "bye"); - - parser.check (line, &pos); - - m_resp_text = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::resp_text* m_resp_text; - - public: - - const IMAPParser::resp_text* resp_text() const { return (m_resp_text); } - }; - - - // - // resp_cond_auth ::= ("OK" / "PREAUTH") SPACE resp_text - // ;; Authentication condition - // - - class resp_cond_auth : public component - { - public: - - resp_cond_auth() - : m_resp_text(NULL) - { - } - - ~resp_cond_auth() - { - delete (m_resp_text); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("resp_cond_auth"); - - string::size_type pos = *currentPos; - - if (parser.checkWithArg (line, &pos, "ok", true)) - { - m_cond = OK; - } - else - { - parser.checkWithArg (line, &pos, "preauth"); - - m_cond = PREAUTH; - } - - parser.check (line, &pos); - - m_resp_text = parser.get (line, &pos); - - *currentPos = pos; - } - - - enum Condition - { - OK, - PREAUTH - }; - - private: - - Condition m_cond; - IMAPParser::resp_text* m_resp_text; - - public: - - const Condition condition() const { return (m_cond); } - const IMAPParser::resp_text* resp_text() const { return (m_resp_text); } - }; - - - // - // status_info ::= status_att SPACE number - // - - class status_info : public component - { - public: - - status_info() - : m_status_att(NULL), m_number(NULL) - { - } - - ~status_info() - { - delete (m_status_att); - delete (m_number); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("status_info"); - - string::size_type pos = *currentPos; - - m_status_att = parser.get (line, &pos); - parser.check (line, &pos); - m_number = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::status_att* m_status_att; - IMAPParser::number* m_number; - - public: - - const IMAPParser::status_att* status_att() const { return (m_status_att); } - const IMAPParser::number* number() const { return (m_number); } - }; - - - // - // mailbox_data ::= "FLAGS" SPACE mailbox_flag_list / - // "LIST" SPACE mailbox_list / - // "LSUB" SPACE mailbox_list / - // "MAILBOX" SPACE text / - // "SEARCH" [SPACE 1#nz_number] / - // "STATUS" SPACE mailbox SPACE - // "(" #::iterator it = m_search_nz_number_list.begin() ; - it != m_search_nz_number_list.end() ; ++it) - { - delete (*it); - } - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("mailbox_data"); - - string::size_type pos = *currentPos; - - m_number = parser.get (line, &pos, true); - - if (m_number) - { - parser.check (line, &pos); - - if (parser.checkWithArg (line, &pos, "exists", true)) - { - m_type = EXISTS; - } - else - { - parser.checkWithArg (line, &pos, "recent"); - - m_type = RECENT; - } - } - else - { - // "FLAGS" SPACE mailbox_flag_list - if (parser.checkWithArg (line, &pos, "flags", true)) - { - parser.check (line, &pos); - - m_mailbox_flag_list = parser.get (line, &pos); - - m_type = FLAGS; - } - // "LIST" SPACE mailbox_list - else if (parser.checkWithArg (line, &pos, "list", true)) - { - parser.check (line, &pos); - - m_mailbox_list = parser.get (line, &pos); - - m_type = LIST; - } - // "LSUB" SPACE mailbox_list - else if (parser.checkWithArg (line, &pos, "lsub", true)) - { - parser.check (line, &pos); - - m_mailbox_list = parser.get (line, &pos); - - m_type = LSUB; - } - // "MAILBOX" SPACE text - else if (parser.checkWithArg (line, &pos, "mailbox", true)) - { - parser.check (line, &pos); - - m_text = parser.get (line, &pos); - - m_type = MAILBOX; - } - // "SEARCH" [SPACE 1#nz_number] - else if (parser.checkWithArg (line, &pos, "search", true)) - { - if (parser.check (line, &pos, true)) - { - m_search_nz_number_list.push_back - (parser.get (line, &pos)); - - while (parser.check (line, &pos, true)) - { - m_search_nz_number_list.push_back - (parser.get (line, &pos)); - } - } - - m_type = SEARCH; - } - // "STATUS" SPACE mailbox SPACE - // "(" #(line, &pos, "status"); - parser.check (line, &pos); - - m_mailbox = parser.get (line, &pos); - - parser.check (line, &pos); - parser.check >(line, &pos); - - m_status_info_list.push_back(parser.get (line, &pos)); - - while (!parser.check >(line, &pos, true)) - { - parser.check (line, &pos); - m_status_info_list.push_back(parser.get (line, &pos)); - } - - m_type = STATUS; - } - } - - *currentPos = pos; - } - - - enum Type - { - FLAGS, - LIST, - LSUB, - MAILBOX, - SEARCH, - STATUS, - EXISTS, - RECENT - }; - - private: - - Type m_type; - - IMAPParser::number* m_number; - IMAPParser::mailbox_flag_list* m_mailbox_flag_list; - IMAPParser::mailbox_list* m_mailbox_list; - IMAPParser::mailbox* m_mailbox; - IMAPParser::text* m_text; - std::vector m_search_nz_number_list; - std::vector m_status_info_list; - - public: - - const Type type() const { return (m_type); } - - const IMAPParser::number* number() const { return (m_number); } - const IMAPParser::mailbox_flag_list* mailbox_flag_list() const { return (m_mailbox_flag_list); } - const IMAPParser::mailbox_list* mailbox_list() const { return (m_mailbox_list); } - const IMAPParser::mailbox* mailbox() const { return (m_mailbox); } - const IMAPParser::text* text() const { return (m_text); } - const std::vector & search_nz_number_list() const { return (m_search_nz_number_list); } - const std::vector & status_info_list() const { return (m_status_info_list); } - }; - - - // - // response_data ::= "*" SPACE (resp_cond_state / resp_cond_bye / - // mailbox_data / message_data / capability_data) CRLF - // - - class response_data : public component - { - public: - - response_data() - : m_resp_cond_state(NULL), m_resp_cond_bye(NULL), - m_mailbox_data(NULL), m_message_data(NULL), m_capability_data(NULL) - { - } - - ~response_data() - { - delete (m_resp_cond_state); - delete (m_resp_cond_bye); - delete (m_mailbox_data); - delete (m_message_data); - delete (m_capability_data); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("response_data"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - parser.check (line, &pos); - - if (!(m_resp_cond_state = parser.get (line, &pos, true))) - if (!(m_resp_cond_bye = parser.get (line, &pos, true))) - if (!(m_mailbox_data = parser.get (line, &pos, true))) - if (!(m_message_data = parser.get (line, &pos, true))) - m_capability_data = parser.get (line, &pos); - - parser.check (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::resp_cond_state* m_resp_cond_state; - IMAPParser::resp_cond_bye* m_resp_cond_bye; - IMAPParser::mailbox_data* m_mailbox_data; - IMAPParser::message_data* m_message_data; - IMAPParser::capability_data* m_capability_data; - - public: - - const IMAPParser::resp_cond_state* resp_cond_state() const { return (m_resp_cond_state); } - const IMAPParser::resp_cond_bye* resp_cond_bye() const { return (m_resp_cond_bye); } - const IMAPParser::mailbox_data* mailbox_data() const { return (m_mailbox_data); } - const IMAPParser::message_data* message_data() const { return (m_message_data); } - const IMAPParser::capability_data* capability_data() const { return (m_capability_data); } - }; - - - class continue_req_or_response_data : public component - { - public: - - continue_req_or_response_data() - : m_continue_req(NULL), m_response_data(NULL) - { - } - - ~continue_req_or_response_data() - { - delete (m_continue_req); - delete (m_response_data); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("continue_req_or_response_data"); - - string::size_type pos = *currentPos; - - if (!(m_continue_req = parser.get (line, &pos, true))) - m_response_data = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::continue_req* m_continue_req; - IMAPParser::response_data* m_response_data; - - public: - - const IMAPParser::continue_req* continue_req() const { return (m_continue_req); } - const IMAPParser::response_data* response_data() const { return (m_response_data); } - }; - - - // - // response_fatal ::= "*" SPACE resp_cond_bye CRLF - // ;; Server closes connection immediately - // - - class response_fatal : public component - { - public: - - response_fatal() - : m_resp_cond_bye(NULL) - { - } - - ~response_fatal() - { - delete (m_resp_cond_bye); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("response_fatal"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - parser.check (line, &pos); - - m_resp_cond_bye = parser.get (line, &pos); - - parser.check (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::resp_cond_bye* m_resp_cond_bye; - - public: - - const IMAPParser::resp_cond_bye* resp_cond_bye() const { return (m_resp_cond_bye); } - }; - - - // - // response_tagged ::= tag SPACE resp_cond_state CRLF - // - - class response_tagged : public component - { - public: - - response_tagged() - : m_resp_cond_state(NULL) - { - } - - ~response_tagged() - { - delete (m_resp_cond_state); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("response_tagged"); - - string::size_type pos = *currentPos; - - parser.check (line, &pos); - parser.check (line, &pos); - m_resp_cond_state = parser.get (line, &pos); - parser.check (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::resp_cond_state* m_resp_cond_state; - - public: - - const IMAPParser::resp_cond_state* resp_cond_state() const { return (m_resp_cond_state); } - }; - - - // - // response_done ::= response_tagged / response_fatal - // - - class response_done : public component - { - public: - - response_done() - : m_response_tagged(NULL), m_response_fatal(NULL) - { - } - - ~response_done() - { - delete (m_response_tagged); - delete (m_response_fatal); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("response_done"); - - string::size_type pos = *currentPos; - - if (!(m_response_tagged = parser.get (line, &pos, true))) - m_response_fatal = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::response_tagged* m_response_tagged; - IMAPParser::response_fatal* m_response_fatal; - - public: - - const IMAPParser::response_tagged* response_tagged() const { return (m_response_tagged); } - const IMAPParser::response_fatal* response_fatal() const { return (m_response_fatal); } - }; - - - // - // response ::= *(continue_req / response_data) response_done - // - - class response : public component - { - public: - - response() - : m_response_done(NULL) - { - } - - ~response() - { - for (std::vector ::iterator - it = m_continue_req_or_response_data.begin() ; - it != m_continue_req_or_response_data.end() ; ++it) - { - delete (*it); - } - - delete (m_response_done); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("response"); - - string::size_type pos = *currentPos; - string curLine = line; - bool partial = false; // partial response - - IMAPParser::continue_req_or_response_data* resp = NULL; - - while ((resp = parser.get (curLine, &pos, true)) != NULL) - { - m_continue_req_or_response_data.push_back(resp); - - // Partial response (continue_req) - if (resp->continue_req()) - { - partial = true; - break; - } - - // We have read a CRLF, read another line - curLine = parser.readLine(); - pos = 0; - } - - if (!partial) - m_response_done = parser.get (curLine, &pos); - - *currentPos = pos; - } - - - const bool isBad() const - { - if (!response_done()) // incomplete (partial) response - return (true); - - if (response_done()->response_fatal()) - return (true); - - if (response_done()->response_tagged()->resp_cond_state()-> - status() == IMAPParser::resp_cond_state::BAD) - { - return (true); - } - - return (false); - } - - private: - - std::vector m_continue_req_or_response_data; - IMAPParser::response_done* m_response_done; - - public: - - const std::vector & continue_req_or_response_data() const { return (m_continue_req_or_response_data); } - const IMAPParser::response_done* response_done() const { return (m_response_done); } - }; - - - // - // greeting ::= "*" SPACE (resp_cond_auth / resp_cond_bye) CRLF - // - - class greeting : public component - { - public: - - greeting() - : m_resp_cond_auth(NULL), m_resp_cond_bye(NULL) - { - } - - ~greeting() - { - delete (m_resp_cond_auth); - delete (m_resp_cond_bye); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("greeting"); - - string::size_type pos = *currentPos; - - parser.check >(line, &pos); - parser.check (line, &pos); - - if (!(m_resp_cond_auth = parser.get (line, &pos, true))) - m_resp_cond_bye = parser.get (line, &pos); - - parser.check (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::resp_cond_auth* m_resp_cond_auth; - IMAPParser::resp_cond_bye* m_resp_cond_bye; - - public: - - const IMAPParser::resp_cond_auth* resp_cond_auth() const { return (m_resp_cond_auth); } - const IMAPParser::resp_cond_bye* resp_cond_bye() const { return (m_resp_cond_bye); } - }; - - - - // - // The main functions used to parse a response - // - - response* readResponse(literalHandler* lh = NULL) - { - string::size_type pos = 0; - string line = readLine(); - - m_literalHandler = lh; - response* resp = get (line, &pos); - m_literalHandler = NULL; - - return (resp); - } - - - greeting* readGreeting() - { - string::size_type pos = 0; - string line = readLine(); - - return get (line, &pos); - } - - - // - // Get a token and advance - // - - template - TYPE* get(string& line, string::size_type* currentPos, - const bool noThrow = false) - { - component* resp = new TYPE; - return internalGet (resp, line, currentPos, noThrow); - } - - - template - TYPE* getWithArgs(string& line, string::size_type* currentPos, - ARG1_TYPE arg1, ARG2_TYPE arg2, const bool noThrow = false) - { - component* resp = new TYPE(arg1, arg2); - return internalGet (resp, line, currentPos, noThrow); - } - - -private: - - template - TYPE* internalGet(component* resp, string& line, string::size_type* currentPos, - const bool noThrow = false) - { -#if DEBUG_RESPONSE - DEBUG_RESPONSE_level += " "; -#endif - - try - { - resp->go(*this, line, currentPos); - -#if DEBUG_RESPONSE - std::cout << DEBUG_RESPONSE_level << "SUCCESS! (" << DEBUG_RESPONSE_components.back() << ")" << std::endl; - - DEBUG_RESPONSE_level.erase(DEBUG_RESPONSE_level.begin() + DEBUG_RESPONSE_level.length() - 1); - DEBUG_RESPONSE_components.pop_back(); -#endif - } - catch (...) - { -#if DEBUG_RESPONSE - std::cout << DEBUG_RESPONSE_level << "FAILED! (" << DEBUG_RESPONSE_components.back() << ")" << std::endl; - - DEBUG_RESPONSE_level.erase(DEBUG_RESPONSE_level.begin() + DEBUG_RESPONSE_level.length() - 1); - DEBUG_RESPONSE_components.pop_back(); -#endif - - delete (resp); - if (!noThrow) throw; - return (NULL); - } - - return static_cast (resp); - } - - -public: - - // - // Check a token and advance - // - - template - const bool check(string& line, string::size_type* currentPos, - const bool noThrow = false) - { - try - { - TYPE term; - term.go(*this, line, currentPos); - -#if DEBUG_RESPONSE - std::cout << DEBUG_RESPONSE_level << "SUCCESS! (" << DEBUG_RESPONSE_components.back() << ")" << std::endl; - DEBUG_RESPONSE_components.pop_back(); -#endif - } - catch (...) - { -#if DEBUG_RESPONSE - std::cout << DEBUG_RESPONSE_level << "FAILED! (" << DEBUG_RESPONSE_components.back() << ")" << std::endl; - DEBUG_RESPONSE_components.pop_back(); -#endif - - if (!noThrow) throw; - return false; - } - - return true; - } - - template - const bool checkWithArg(string& line, string::size_type* currentPos, - const ARG_TYPE arg, const bool noThrow = false) - { - try - { - TYPE term(arg); - term.go(*this, line, currentPos); - -#if DEBUG_RESPONSE - std::cout << DEBUG_RESPONSE_level << "SUCCESS! (" << DEBUG_RESPONSE_components.back() << ")" << std::endl; - DEBUG_RESPONSE_components.pop_back(); -#endif - } - catch (...) - { -#if DEBUG_RESPONSE - std::cout << DEBUG_RESPONSE_level << "FAILED! (" << DEBUG_RESPONSE_components.back() << ")" << std::endl; - DEBUG_RESPONSE_components.pop_back(); -#endif - - if (!noThrow) throw; - return false; - } - - return true; - } - - -private: - - weak_ref m_tag; - weak_ref m_socket; - - utility::progressionListener* m_progress; - - literalHandler* m_literalHandler; - - weak_ref m_timeoutHandler; - - - string m_buffer; - int m_pos; - - string m_lastLine; - -public: - - // - // Read one line - // - - const string readLine() - { - string::size_type pos; - - while ((pos = m_buffer.find('\n')) == string::npos) - { - read(); - } - - string line; - line.resize(pos + 1); - std::copy(m_buffer.begin(), m_buffer.begin() + pos + 1, line.begin()); - - m_buffer.erase(m_buffer.begin(), m_buffer.begin() + pos + 1); - - m_lastLine = line; - -#if DEBUG_RESPONSE - std::cout << std::endl << "Read line:" << std::endl << line << std::endl; -#endif - - return (line); - } - - - // - // Read available data from socket stream - // - - void read() - { - string receiveBuffer; - - while (receiveBuffer.empty()) - { - // Check whether the time-out delay is elapsed - if (m_timeoutHandler && m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) - throw exceptions::operation_timed_out(); - } - - // We have received data: reset the time-out counter - m_socket->receive(receiveBuffer); - - if (receiveBuffer.empty()) // buffer is empty - { - platformDependant::getHandler()->wait(); - continue; - } - - // We have received data ... - if (m_timeoutHandler) - m_timeoutHandler->resetTimeOut(); - } - - m_buffer += receiveBuffer; - } - - - void readLiteral(literalHandler::target& buffer, string::size_type count) - { - string::size_type len = 0; - string receiveBuffer; - - if (m_progress) - m_progress->start(count); - - if (m_timeoutHandler) - m_timeoutHandler->resetTimeOut(); - - if (!m_buffer.empty()) - { - if (m_buffer.length() > count) - { - buffer.putData(string(m_buffer.begin(), m_buffer.begin() + count)); - m_buffer.erase(m_buffer.begin(), m_buffer.begin() + count); - len = count; - } - else - { - len += m_buffer.length(); - buffer.putData(m_buffer); - m_buffer.clear(); - } - } - - while (len < count) - { - // 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 - m_socket->receive(receiveBuffer); - - if (receiveBuffer.empty()) // buffer is empty - { - platformDependant::getHandler()->wait(); - continue; - } - - // We have received data: reset the time-out counter - if (m_timeoutHandler) - m_timeoutHandler->resetTimeOut(); - - if (len + receiveBuffer.length() > count) - { - const string::size_type remaining = count - len; - - // Get the needed amount of data - buffer.putData(string(receiveBuffer.begin(), receiveBuffer.begin() + remaining)); - - // Put the remaining data into the internal response buffer - receiveBuffer.erase(receiveBuffer.begin(), receiveBuffer.begin() + remaining); - m_buffer += receiveBuffer; - - len = count; - } - else - { - buffer.putData(receiveBuffer); - len += receiveBuffer.length(); - } - - // Notify progression - if (m_progress) - m_progress->progress(len, count); - } - - if (m_progress) - m_progress->stop(count); - } -}; - - -} // imap -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_IMAP_IMAPPARSER_HPP_INCLUDED diff --git a/vmime/messaging/imap/IMAPStore.hpp b/vmime/messaging/imap/IMAPStore.hpp deleted file mode 100644 index 227a0f27..00000000 --- a/vmime/messaging/imap/IMAPStore.hpp +++ /dev/null @@ -1,137 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_IMAP_IMAPSTORE_HPP_INCLUDED -#define VMIME_MESSAGING_IMAP_IMAPSTORE_HPP_INCLUDED - - -#include "vmime/config.hpp" - -#include "vmime/messaging/store.hpp" -#include "vmime/messaging/socket.hpp" -#include "vmime/messaging/folder.hpp" - -#include - - -namespace vmime { -namespace messaging { -namespace imap { - - -class IMAPParser; -class IMAPTag; -class IMAPConnection; -class IMAPFolder; - - -/** IMAP store service. - */ - -class IMAPStore : public store -{ - friend class IMAPFolder; - friend class IMAPMessage; - friend class IMAPConnection; - -public: - - IMAPStore(ref sess, ref auth); - ~IMAPStore(); - - const string getProtocolName() const; - - ref getDefaultFolder(); - ref getRootFolder(); - ref getFolder(const folder::path& path); - - const bool isValidFolderName(const folder::path::component& name) const; - - static const serviceInfos& getInfosInstance(); - const serviceInfos& getInfos() const; - - void connect(); - const bool isConnected() const; - void disconnect(); - - void noop(); - - const int getCapabilities() const; - -private: - - // Connection - ref m_connection; - - // Used to request the authentication informations only the - // first time, and reuse these informations the next time. - ref m_oneTimeAuth; - - - - ref oneTimeAuthenticator(); - - - ref connection(); - - - void registerFolder(IMAPFolder* folder); - void unregisterFolder(IMAPFolder* folder); - - std::list m_folders; - - - - // Service infos - class _infos : public serviceInfos - { - public: - - struct props - { - // IMAP-specific options - // (none) - - // Common properties - serviceInfos::property PROPERTY_AUTH_USERNAME; - serviceInfos::property PROPERTY_AUTH_PASSWORD; - - serviceInfos::property PROPERTY_SERVER_ADDRESS; - serviceInfos::property PROPERTY_SERVER_PORT; - serviceInfos::property PROPERTY_SERVER_SOCKETFACTORY; - - serviceInfos::property PROPERTY_TIMEOUT_FACTORY; - }; - - const props& getProperties() const; - - const string getPropertyPrefix() const; - const std::vector getAvailableProperties() const; - }; - - static _infos sm_infos; -}; - - -} // imap -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_IMAP_IMAPSTORE_HPP_INCLUDED diff --git a/vmime/messaging/imap/IMAPTag.hpp b/vmime/messaging/imap/IMAPTag.hpp deleted file mode 100644 index 526efb74..00000000 --- a/vmime/messaging/imap/IMAPTag.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_IMAP_IMAPTAG_HPP_INCLUDED -#define VMIME_MESSAGING_IMAP_IMAPTAG_HPP_INCLUDED - - -#include "vmime/types.hpp" - - -namespace vmime { -namespace messaging { -namespace imap { - - -class IMAPTag : public object -{ -private: - - IMAPTag(const int number); - IMAPTag(const IMAPTag& tag); - -public: - - IMAPTag(); - - IMAPTag& operator++(); // ++IMAPTag - const IMAPTag operator++(int); // IMAPTag++ - - const int number() const; - - operator string() const; - -private: - - void generate(); - - static const int sm_maxNumber; - - int m_number; - string m_tag; -}; - - -} // imap -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_IMAP_IMAPTAG_HPP_INCLUDED diff --git a/vmime/messaging/imap/IMAPUtils.hpp b/vmime/messaging/imap/IMAPUtils.hpp deleted file mode 100644 index 5060c780..00000000 --- a/vmime/messaging/imap/IMAPUtils.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_IMAP_IMAPUTILS_HPP_INCLUDED -#define VMIME_MESSAGING_IMAP_IMAPUTILS_HPP_INCLUDED - - -#include "vmime/types.hpp" -#include "vmime/dateTime.hpp" - -#include "vmime/messaging/folder.hpp" -#include "vmime/messaging/imap/IMAPParser.hpp" - -#include - - -namespace vmime { -namespace messaging { -namespace imap { - - -class IMAPUtils -{ -public: - - static const string pathToString(const char hierarchySeparator, const folder::path& path); - static const folder::path stringToPath(const char hierarchySeparator, const string& str); - - static const string toModifiedUTF7(const char hierarchySeparator, const folder::path::component& text); - static const folder::path::component fromModifiedUTF7(const string& text); - - static const string quoteString(const string& text); - - static const int folderTypeFromFlags(const IMAPParser::mailbox_flag_list* list); - static const int folderFlagsFromFlags(const IMAPParser::mailbox_flag_list* list); - - static const int messageFlagsFromFlags(const IMAPParser::flag_list* list); - - static const string messageFlagList(const int flags); - - static const string listToSet(const std::vector & list, const int max = -1, const bool alreadySorted = false); - - static const string dateTime(const vmime::datetime& date); -}; - - -} // imap -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_IMAP_IMAPUTILS_HPP_INCLUDED diff --git a/vmime/messaging/maildir/maildirFolder.hpp b/vmime/messaging/maildir/maildirFolder.hpp deleted file mode 100644 index e7702673..00000000 --- a/vmime/messaging/maildir/maildirFolder.hpp +++ /dev/null @@ -1,178 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_MAILDIR_MAILDIRFOLDER_HPP_INCLUDED -#define VMIME_MESSAGING_MAILDIR_MAILDIRFOLDER_HPP_INCLUDED - - -#include -#include - -#include "vmime/types.hpp" - -#include "vmime/messaging/folder.hpp" - -#include "vmime/utility/file.hpp" - - -namespace vmime { -namespace messaging { -namespace maildir { - - -class maildirStore; -class maildirMessage; - - -/** maildir folder implementation. - */ - -class maildirFolder : public folder -{ -private: - - friend class maildirStore; - friend class maildirMessage; - friend class vmime::creator; // vmime::create - - - maildirFolder(const folder::path& path, weak_ref store); - maildirFolder(const maildirFolder&) : folder() { } - - ~maildirFolder(); - -public: - - const int getMode() const; - - const int getType(); - - const int getFlags(); - - const folder::path::component getName() const; - const folder::path getFullPath() const; - - void open(const int mode, bool failIfModeIsNotAvailable = false); - void close(const bool expunge); - void create(const int type); - - const bool exists(); - - const bool isOpen() const; - - ref getMessage(const int num); - std::vector > getMessages(const int from = 1, const int to = -1); - std::vector > getMessages(const std::vector & nums); - const int getMessageCount(); - - ref getFolder(const folder::path::component& name); - std::vector > getFolders(const bool recursive = false); - - void rename(const folder::path& newPath); - - void deleteMessage(const int num); - void deleteMessages(const int from = 1, const int to = -1); - void deleteMessages(const std::vector & nums); - - void setMessageFlags(const int from, const int to, const int flags, const int mode = message::FLAG_MODE_SET); - void setMessageFlags(const std::vector & nums, const int flags, const int mode = message::FLAG_MODE_SET); - - void addMessage(ref msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressionListener* progress = NULL); - void addMessage(utility::inputStream& is, const int size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressionListener* progress = NULL); - - void copyMessage(const folder::path& dest, const int num); - void copyMessages(const folder::path& dest, const int from = 1, const int to = -1); - void copyMessages(const folder::path& dest, const std::vector & nums); - - void status(int& count, int& unseen); - - void expunge(); - - ref getParent(); - - weak_ref getStore() const; - weak_ref getStore(); - - - void fetchMessages(std::vector >& msg, const int options, utility::progressionListener* progress = NULL); - void fetchMessage(ref msg, const int options); - - const int getFetchCapabilities() const; - -private: - - void scanFolder(); - - void listFolders(std::vector >& list, const bool recursive); - - void registerMessage(maildirMessage* msg); - void unregisterMessage(maildirMessage* msg); - - const utility::file::path getMessageFSPath(const int number) const; - - void onStoreDisconnected(); - - void onClose(); - - void deleteMessagesImpl(const std::vector & nums); - void setMessageFlagsImpl(const std::vector & nums, const int flags, const int mode); - - void copyMessagesImpl(const folder::path& dest, const std::vector & nums); - void copyMessageImpl(const utility::file::path& tmpDirPath, const utility::file::path& curDirPath, const utility::file::path::component& filename, utility::inputStream& is, const utility::stream::size_type size, utility::progressionListener* progress); - - void notifyMessagesCopied(const folder::path& dest); - - - weak_ref m_store; - - folder::path m_path; - folder::path::component m_name; - - int m_mode; - bool m_open; - - int m_unreadMessageCount; - int m_messageCount; - - // Store information about scanned messages - struct messageInfos - { - enum Type - { - TYPE_CUR, - TYPE_DELETED - }; - - utility::file::path::component path; // filename - Type type; // current location - }; - - std::vector m_messageInfos; - - // Instanciated message objects - std::vector m_messages; -}; - - -} // maildir -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_MAILDIR_MAILDIRFOLDER_HPP_INCLUDED diff --git a/vmime/messaging/maildir/maildirMessage.hpp b/vmime/messaging/maildir/maildirMessage.hpp deleted file mode 100644 index 36c91cd4..00000000 --- a/vmime/messaging/maildir/maildirMessage.hpp +++ /dev/null @@ -1,103 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_MAILDIR_MAILDIRMESSAGE_HPP_INCLUDED -#define VMIME_MESSAGING_MAILDIR_MAILDIRMESSAGE_HPP_INCLUDED - - -#include "vmime/messaging/message.hpp" -#include "vmime/messaging/folder.hpp" - - -namespace vmime { -namespace messaging { -namespace maildir { - - -class maildirFolder; - - -/** maildir message implementation. - */ - -class maildirMessage : public message -{ - friend class maildirFolder; - friend class vmime::creator; // vmime::create - -private: - - maildirMessage(weak_ref folder, const int num); - maildirMessage(const maildirMessage&) : message() { } - - ~maildirMessage(); - -public: - - const int getNumber() const; - - const uid getUniqueId() const; - - const int getSize() const; - - const bool isExpunged() const; - - const structure& getStructure() const; - structure& getStructure(); - - ref getHeader() const; - - const int getFlags() const; - void setFlags(const int flags, const int mode = FLAG_MODE_SET); - - void extract(utility::outputStream& os, utility::progressionListener* progress = NULL, const int start = 0, const int length = -1, const bool peek = false) const; - void extractPart(const part& p, utility::outputStream& os, utility::progressionListener* progress = NULL, const int start = 0, const int length = -1, const bool peek = false) const; - - void fetchPartHeader(part& p); - -private: - - void fetch(weak_ref folder, const int options); - - void onFolderClosed(); - - ref
getOrCreateHeader(); - - void extractImpl(utility::outputStream& os, utility::progressionListener* progress, const int start, const int length, const int partialStart, const int partialLength, const bool peek) const; - - - weak_ref m_folder; - - int m_num; - int m_size; - int m_flags; - bool m_expunged; - uid m_uid; - - ref
m_header; - ref m_structure; -}; - - -} // maildir -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_MAILDIR_MAILDIRMESSAGE_HPP_INCLUDED diff --git a/vmime/messaging/maildir/maildirStore.hpp b/vmime/messaging/maildir/maildirStore.hpp deleted file mode 100644 index 23c667a4..00000000 --- a/vmime/messaging/maildir/maildirStore.hpp +++ /dev/null @@ -1,114 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_MAILDIR_MAILDIRSTORE_HPP_INCLUDED -#define VMIME_MESSAGING_MAILDIR_MAILDIRSTORE_HPP_INCLUDED - - -#include "vmime/config.hpp" - -#include "vmime/messaging/store.hpp" -#include "vmime/messaging/socket.hpp" -#include "vmime/messaging/folder.hpp" - -#include "vmime/utility/file.hpp" - -#include - - -namespace vmime { -namespace messaging { -namespace maildir { - - -class maildirFolder; - - -/** maildir store service. - */ - -class maildirStore : public store -{ - friend class maildirFolder; - -public: - - maildirStore(ref sess, ref auth); - ~maildirStore(); - - const string getProtocolName() const; - - ref getDefaultFolder(); - ref getRootFolder(); - ref getFolder(const folder::path& path); - - const bool isValidFolderName(const folder::path::component& name) const; - - static const serviceInfos& getInfosInstance(); - const serviceInfos& getInfos() const; - - void connect(); - const bool isConnected() const; - void disconnect(); - - void noop(); - - const utility::path& getFileSystemPath() const; - - const int getCapabilities() const; - -private: - - void registerFolder(maildirFolder* folder); - void unregisterFolder(maildirFolder* folder); - - - std::list m_folders; - - bool m_connected; - - utility::path m_fsPath; - - - // Service infos - class _infos : public serviceInfos - { - public: - - struct props - { - serviceInfos::property PROPERTY_SERVER_ROOTPATH; - }; - - const props& getProperties() const; - - const string getPropertyPrefix() const; - const std::vector getAvailableProperties() const; - }; - - static _infos sm_infos; -}; - - -} // maildir -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_MAILDIR_MAILDIRSTORE_HPP_INCLUDED diff --git a/vmime/messaging/maildir/maildirUtils.hpp b/vmime/messaging/maildir/maildirUtils.hpp deleted file mode 100644 index 8f322d92..00000000 --- a/vmime/messaging/maildir/maildirUtils.hpp +++ /dev/null @@ -1,160 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_MAILDIR_MAILDIRUTILS_HPP_INCLUDED -#define VMIME_MESSAGING_MAILDIR_MAILDIRUTILS_HPP_INCLUDED - - -#include "vmime/utility/file.hpp" -#include "vmime/utility/path.hpp" - - -namespace vmime { -namespace messaging { -namespace maildir { - - -class maildirStore; - - -/** Miscellaneous helpers functions for maildir messaging system. - */ - -class maildirUtils -{ -public: - - /** Comparator for message filenames, based only on the - * unique identifier part of the filename. - */ - class messageIdComparator - { - public: - - messageIdComparator(const utility::file::path::component& comp); - - const bool operator()(const utility::file::path::component& other) const; - - private: - - const utility::file::path::component m_comp; - }; - - /** Mode for return value of getFolderFSPath(). */ - enum FolderFSPathMode - { - FOLDER_PATH_ROOT, /**< Root folder. Eg: ~/Mail/MyFolder */ - FOLDER_PATH_NEW, /**< Folder containing unread messages. Eg: ~/Mail/MyFolder/new */ - FOLDER_PATH_CUR, /**< Folder containing messages that have been seen. Eg: ~/Mail/MyFolder/cur */ - FOLDER_PATH_TMP, /**< Temporary folder used for reliable delivery. Eg: ~/Mail/MyFolder/tmp */ - FOLDER_PATH_CONTAINER /**< Container for sub-folders. Eg: ~/Mail/.MyFolder.directory */ - }; - - /** Return the path on the filesystem for the folder in specified store. - * - * @param store parent store - * @param folderPath path of the folder - * @param mode type of path to return (see FolderFSPathMode) - * @return filesystem path for the specified folder - */ - static const utility::file::path getFolderFSPath(weak_ref store, - const utility::path& folderPath, const FolderFSPathMode mode); - - /** Test whether the specified file-system directory corresponds to - * a maildir sub-folder. The name of the directory should not start - * with '.' to be listed as a sub-folder. - * - * @param file reference to a file-system directory - * @return true if the specified directory is a maildir sub-folder, - * false otherwise - */ - static const bool isSubfolderDirectory(const utility::file& file); - - /** Test whether the specified file-system object is a message. - * - * @param file reference to a file-system object - * @return true if the specified object is a message file, - * false otherwise - */ - static const bool isMessageFile(const utility::file& file); - - /** Extract the unique identifier part of the message filename. - * Eg: for the filename "1071577232.28549.m03s:2,RS", it will - * return "1071577232.28549.m03s". - * - * @param filename filename part - * @return part of the filename that corresponds to the unique - * identifier of the message - */ - static const utility::file::path::component extractId(const utility::file::path::component& filename); - - /** Extract message flags from the specified message filename. - * Eg: for the filename "1071577232.28549.m03s:2,RS", it will - * return (message::FLAG_SEEN | message::FLAG_REPLIED). - * - * @param comp filename part - * @return message flags extracted from the specified filename - */ - static const int extractFlags(const utility::file::path::component& comp); - - /** Return a string representing the specified message flags. - * Eg: for (message::FLAG_SEEN | message::FLAG_REPLIED), it will - * return "RS". - * - * @param flags set of flags - * @return message flags in a string representation - */ - static const utility::file::path::component buildFlags(const int flags); - - /** Build a filename with the specified id and flags. - * - * @param id id part of the filename - * @param flags flags part of the filename - * @return message filename - */ - static const utility::file::path::component buildFilename(const utility::file::path::component& id, const utility::file::path::component& flags); - - /** Build a filename with the specified id and flags. - * - * @param id id part of the filename - * @param flags set of flags - * @return message filename - */ - static const utility::file::path::component buildFilename(const utility::file::path::component& id, const int flags); - - /** Generate a new unique message identifier. - * - * @return unique message id - */ - static const utility::file::path::component generateId(); - -private: - - static const vmime::word TMP_DIR; - static const vmime::word CUR_DIR; - static const vmime::word NEW_DIR; -}; - - -} // maildir -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_MAILDIR_MAILDIRUTILS_HPP_INCLUDED diff --git a/vmime/messaging/message.hpp b/vmime/messaging/message.hpp deleted file mode 100644 index 0784d1b3..00000000 --- a/vmime/messaging/message.hpp +++ /dev/null @@ -1,292 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_MESSAGE_HPP_INCLUDED -#define VMIME_MESSAGING_MESSAGE_HPP_INCLUDED - - -#include "vmime/header.hpp" - -#include "vmime/utility/progressionListener.hpp" -#include "vmime/utility/stream.hpp" - - -namespace vmime { -namespace messaging { - - -class structure; - - -/** A MIME part in a message. - */ - -class part : public object -{ -protected: - - part() { } - part(const part&) : object() { } - - virtual ~part() { } - -public: - - /** Return the structure of this part. - * - * @return structure of the part - */ - virtual const structure& getStructure() const = 0; - - /** Return the structure of this part. - * - * @return structure of the part - */ - virtual structure& getStructure() = 0; - - /** Return the header section for this part (you must fetch header - * before using this function: see message::fetchPartHeader). - * - * @return header section - */ - virtual const header& getHeader() const = 0; - - /** Return the media-type of the content in this part. - * - * @return content media type - */ - virtual const mediaType& getType() const = 0; - - /** Return the size of this part. - * - * @return size of the part (in bytes) - */ - virtual const int getSize() const = 0; - - /** Return the part sequence number (index) - * - * @return part number - */ - virtual const int getNumber() const = 0; // begin at 1 - - /** Return the sub-part at the specified position. - * This provide easy access to parts: - * Eg: "message->extractPart(message->getStructure()[3][1][2])". - * - * @param x index of the sub-part - * @return sub-part at position 'x' - */ - const part& operator[](const int x) const; - - /** Return the sub-part at the specified position. - * This provide easy access to parts: - * Eg: "message->extractPart(message->getStructure()[3][1][2])". - * - * @param x index of the sub-part - * @return sub-part at position 'x' - */ - part& operator[](const int x); - - /** Return the number of sub-parts in this part. - * - * @return number of sub-parts - */ - const int getCount() const; -}; - - -/** Structure of a MIME part/message. - */ - -class structure : public object -{ -protected: - - structure() { } - structure(const structure&) : object() { } - -public: - - virtual ~structure() { } - - /** Return the part at the specified position (first - * part is at position 1). - * - * @param x position - * @return part at position 'x' - */ - virtual const part& operator[](const int x) const = 0; - - /** Return the part at the specified position (first - * part is at position 1). - * - * @param x position - * @return part at position 'x' - */ - virtual part& operator[](const int x) = 0; - - /** Return the number of parts in this part. - * - * @return number of parts - */ - virtual const int getCount() const = 0; -}; - - -/** Abstract representation of a message in a store/transport service. - */ - -class message : public object -{ -protected: - - message() { } - message(const message&) : object() { } - -public: - - virtual ~message() { } - - /** The type for an unique message identifier. - */ - typedef string uid; - - /** Return the MIME structure of the message (must fetch before). - * - * @return MIME structure of the message - */ - virtual const structure& getStructure() const = 0; - - /** Return the MIME structure of the message (must fetch before). - * - * @return MIME structure of the message - */ - virtual structure& getStructure() = 0; - - /** Return a reference to the header fields of the message (must fetch before). - * - * @return header section of the message - */ - virtual ref getHeader() const = 0; - - /** Return the sequence number of this message. This number is - * used to reference the message in the folder. - * - * @return sequence number of the message - */ - virtual const int getNumber() const = 0; - - /** Return the unique identified of this message (must fetch before). - * - * @return UID of the message - */ - virtual const uid getUniqueId() const = 0; - - /** Return the size of the message (must fetch before). - * - * @return size of the message (in bytes) - */ - virtual const int getSize() const = 0; - - /** Check whether this message has been expunged - * (ie: definitively deleted). - * - * @return true if the message is expunged, false otherwise - */ - virtual const bool isExpunged() const = 0; - - /** Possible flags for a message. - */ - enum Flags - { - FLAG_SEEN = (1 << 0), /**< Message has been seen. */ - FLAG_RECENT = (1 << 1), /**< Message has been recently received. */ - FLAG_DELETED = (1 << 2), /**< Message is marked for deletion. */ - FLAG_REPLIED = (1 << 3), /**< User replied to this message. */ - FLAG_MARKED = (1 << 4), /**< Used-defined flag. */ - FLAG_PASSED = (1 << 5), /**< Message has been resent/forwarded/bounced. */ - - FLAG_UNDEFINED = 9999 /**< Used internally (this should not be returned - by the flags() function). */ - }; - - /** Methods for setting the flags. - */ - enum FlagsModes - { - FLAG_MODE_SET, /**< Set (replace) the flags. */ - FLAG_MODE_ADD, /**< Add the flags. */ - FLAG_MODE_REMOVE /**< Remove the flags. */ - }; - - /** Return the flags of this message. - * - * @return flags of the message - */ - virtual const int getFlags() const = 0; - - /** Set the flags of this message. - * - * @param flags set of flags (see Flags) - * @param mode indicate how to treat old and new flags (see FlagsModes) - */ - virtual void setFlags(const int flags, const int mode = FLAG_MODE_SET) = 0; - - /** Extract the whole message data (header + contents). - * - * \warning Partial fetch might not be supported by the underlying protocol. - * - * @param os output stream in which to write message data - * @param progress progression listener, or NULL if not used - * @param start index of the first byte to retrieve (used for partial fetch) - * @param length number of bytes to retrieve (used for partial fetch) - * @param peek if true, try not to mark the message as read. This may not - * be supported by the protocol (IMAP supports this), but it will NOT throw - * an exception if not supported. - */ - virtual void extract(utility::outputStream& os, utility::progressionListener* progress = NULL, const int start = 0, const int length = -1, const bool peek = false) const = 0; - - /** Extract the specified MIME part of the message (header + contents). - * - * \warning Partial fetch might not be supported by the underlying protocol. - * - * @param p part to extract - * @param os output stream in which to write part data - * @param progress progression listener, or NULL if not used - * @param start index of the first byte to retrieve (used for partial fetch) - * @param length number of bytes to retrieve (used for partial fetch) - * @param peek if true, try not to mark the message as read. This may not - * be supported by the protocol (IMAP supports this), but it will NOT throw - * an exception if not supported. - */ - virtual void extractPart(const part& p, utility::outputStream& os, utility::progressionListener* progress = NULL, const int start = 0, const int length = -1, const bool peek = false) const = 0; - - /** Fetch the MIME header for the specified part. - * - * @param p the part for which to fetch the header - */ - virtual void fetchPartHeader(part& p) = 0; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_MESSAGE_HPP_INCLUDED diff --git a/vmime/messaging/pop3/POP3Folder.hpp b/vmime/messaging/pop3/POP3Folder.hpp deleted file mode 100644 index bb29f858..00000000 --- a/vmime/messaging/pop3/POP3Folder.hpp +++ /dev/null @@ -1,148 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_POP3_POP3FOLDER_HPP_INCLUDED -#define VMIME_MESSAGING_POP3_POP3FOLDER_HPP_INCLUDED - - -#include -#include - -#include "vmime/config.hpp" -#include "vmime/types.hpp" - -#include "vmime/messaging/folder.hpp" - - -namespace vmime { -namespace messaging { -namespace pop3 { - - -class POP3Store; -class POP3Message; - - -/** POP3 folder implementation. - */ - -class POP3Folder : public folder -{ -private: - - friend class POP3Store; - friend class POP3Message; - friend class vmime::creator; // vmime::create - - POP3Folder(const folder::path& path, POP3Store* store); - POP3Folder(const POP3Folder&) : folder() { } - - ~POP3Folder(); - -public: - - const int getMode() const; - - const int getType(); - - const int getFlags(); - - const folder::path::component getName() const; - const folder::path getFullPath() const; - - void open(const int mode, bool failIfModeIsNotAvailable = false); - void close(const bool expunge); - void create(const int type); - - const bool exists(); - - const bool isOpen() const; - - ref getMessage(const int num); - std::vector > getMessages(const int from = 1, const int to = -1); - std::vector > getMessages(const std::vector & nums); - const int getMessageCount(); - - ref getFolder(const folder::path::component& name); - std::vector > getFolders(const bool recursive = false); - - void rename(const folder::path& newPath); - - void deleteMessage(const int num); - void deleteMessages(const int from = 1, const int to = -1); - void deleteMessages(const std::vector & nums); - - void setMessageFlags(const int from, const int to, const int flags, const int mode = message::FLAG_MODE_SET); - void setMessageFlags(const std::vector & nums, const int flags, const int mode = message::FLAG_MODE_SET); - - void addMessage(ref msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressionListener* progress = NULL); - void addMessage(utility::inputStream& is, const int size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressionListener* progress = NULL); - - void copyMessage(const folder::path& dest, const int num); - void copyMessages(const folder::path& dest, const int from = 1, const int to = -1); - void copyMessages(const folder::path& dest, const std::vector & nums); - - void status(int& count, int& unseen); - - void expunge(); - - ref getParent(); - - weak_ref getStore() const; - weak_ref getStore(); - - - void fetchMessages(std::vector >& msg, const int options, utility::progressionListener* progress = NULL); - void fetchMessage(ref msg, const int options); - - const int getFetchCapabilities() const; - -private: - - void registerMessage(POP3Message* msg); - void unregisterMessage(POP3Message* msg); - - void onStoreDisconnected(); - - void onClose(); - - void parseMultiListOrUidlResponse(const string& response, std::map & result); - - - POP3Store* m_store; - - folder::path m_path; - folder::path::component m_name; - - int m_mode; - bool m_open; - - int m_messageCount; - - typedef std::map MessageMap; - MessageMap m_messages; -}; - - -} // pop3 -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_POP3_POP3FOLDER_HPP_INCLUDED diff --git a/vmime/messaging/pop3/POP3Message.hpp b/vmime/messaging/pop3/POP3Message.hpp deleted file mode 100644 index 5aa22d90..00000000 --- a/vmime/messaging/pop3/POP3Message.hpp +++ /dev/null @@ -1,98 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_POP3_POP3MESSAGE_HPP_INCLUDED -#define VMIME_MESSAGING_POP3_POP3MESSAGE_HPP_INCLUDED - - -#include "vmime/config.hpp" - -#include "vmime/messaging/message.hpp" -#include "vmime/messaging/folder.hpp" - - -namespace vmime { -namespace messaging { -namespace pop3 { - - -class POP3Folder; - - -/** POP3 message implementation. - */ - -class POP3Message : public message -{ -private: - - friend class POP3Folder; - friend class vmime::creator; // vmime::create - - POP3Message(POP3Folder* folder, const int num); - POP3Message(const POP3Message&) : message() { } - - ~POP3Message(); - -public: - - const int getNumber() const; - - const uid getUniqueId() const; - - const int getSize() const; - - const bool isExpunged() const; - - const structure& getStructure() const; - structure& getStructure(); - - ref getHeader() const; - - const int getFlags() const; - void setFlags(const int flags, const int mode = FLAG_MODE_SET); - - void extract(utility::outputStream& os, utility::progressionListener* progress = NULL, const int start = 0, const int length = -1, const bool peek = false) const; - void extractPart(const part& p, utility::outputStream& os, utility::progressionListener* progress = NULL, const int start = 0, const int length = -1, const bool peek = false) const; - - void fetchPartHeader(part& p); - -private: - - void fetch(POP3Folder* folder, const int options); - - void onFolderClosed(); - - POP3Folder* m_folder; - int m_num; - uid m_uid; - int m_size; - - bool m_deleted; - - ref
m_header; -}; - - -} // pop3 -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_POP3_POP3MESSAGE_HPP_INCLUDED diff --git a/vmime/messaging/pop3/POP3Store.hpp b/vmime/messaging/pop3/POP3Store.hpp deleted file mode 100644 index 3ff291ea..00000000 --- a/vmime/messaging/pop3/POP3Store.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_POP3_POP3STORE_HPP_INCLUDED -#define VMIME_MESSAGING_POP3_POP3STORE_HPP_INCLUDED - - -#include "vmime/config.hpp" - -#include "vmime/messaging/store.hpp" -#include "vmime/messaging/socket.hpp" -#include "vmime/messaging/timeoutHandler.hpp" - -#include "vmime/utility/stream.hpp" - - -namespace vmime { -namespace messaging { -namespace pop3 { - - -class POP3Folder; - - -/** POP3 store service. - */ - -class POP3Store : public store -{ - friend class POP3Folder; - friend class POP3Message; - -public: - - POP3Store(ref sess, ref auth); - ~POP3Store(); - - const string getProtocolName() const; - - ref getDefaultFolder(); - ref getRootFolder(); - ref getFolder(const folder::path& path); - - const bool isValidFolderName(const folder::path::component& name) const; - - static const serviceInfos& getInfosInstance(); - const serviceInfos& getInfos() const; - - void connect(); - const bool isConnected() const; - void disconnect(); - - void noop(); - - const int getCapabilities() const; - -private: - - static const bool isSuccessResponse(const string& buffer); - static const bool stripFirstLine(const string& buffer, string& result, string* firstLine = NULL); - static void stripResponseCode(const string& buffer, string& result); - - void sendRequest(const string& buffer, const bool end = true); - void readResponse(string& buffer, const bool multiLine, utility::progressionListener* progress = NULL); - void readResponse(utility::outputStream& os, utility::progressionListener* progress = NULL, const int predictedSize = 0); - - static const bool checkTerminator(string& buffer, const bool multiLine); - static const bool checkOneTerminator(string& buffer, const string& term); - - void internalDisconnect(); - - - void registerFolder(POP3Folder* folder); - void unregisterFolder(POP3Folder* folder); - - std::list m_folders; - - - ref m_socket; - bool m_authentified; - - ref m_timeoutHandler; - - - // Service infos - class _infos : public serviceInfos - { - public: - - struct props - { - // POP3-specific options - serviceInfos::property PROPERTY_OPTIONS_APOP; - serviceInfos::property PROPERTY_OPTIONS_APOP_FALLBACK; - - // Common properties - serviceInfos::property PROPERTY_AUTH_USERNAME; - serviceInfos::property PROPERTY_AUTH_PASSWORD; - - serviceInfos::property PROPERTY_SERVER_ADDRESS; - serviceInfos::property PROPERTY_SERVER_PORT; - serviceInfos::property PROPERTY_SERVER_SOCKETFACTORY; - - serviceInfos::property PROPERTY_TIMEOUT_FACTORY; - }; - - const props& getProperties() const; - - const string getPropertyPrefix() const; - const std::vector getAvailableProperties() const; - }; - - static _infos sm_infos; -}; - - -} // pop3 -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_POP3_POP3STORE_HPP_INCLUDED diff --git a/vmime/messaging/sendmail/sendmailTransport.hpp b/vmime/messaging/sendmail/sendmailTransport.hpp deleted file mode 100644 index c63a6fac..00000000 --- a/vmime/messaging/sendmail/sendmailTransport.hpp +++ /dev/null @@ -1,103 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_SENDMAIL_SENDMAILTRANSPORT_HPP_INCLUDED -#define VMIME_MESSAGING_SENDMAIL_SENDMAILTRANSPORT_HPP_INCLUDED - - -#include "vmime/config.hpp" - -#include "vmime/messaging/transport.hpp" -#include "vmime/messaging/socket.hpp" -#include "vmime/messaging/timeoutHandler.hpp" - - -#if VMIME_BUILTIN_PLATFORM_POSIX - - -namespace vmime { -namespace messaging { -namespace sendmail { - - -/** Sendmail local transport service. - */ - -class sendmailTransport : public transport -{ -public: - - sendmailTransport(ref sess, ref auth); - ~sendmailTransport(); - - const string getProtocolName() const; - - static const serviceInfos& getInfosInstance(); - const serviceInfos& getInfos() const; - - void connect(); - const bool isConnected() const; - void disconnect(); - - void noop(); - - void send(const mailbox& expeditor, const mailboxList& recipients, utility::inputStream& is, const utility::stream::size_type size, utility::progressionListener* progress = NULL); - -private: - - void internalDisconnect(); - - void internalSend(const std::vector args, utility::inputStream& is, - const utility::stream::size_type size, utility::progressionListener* progress); - - - string m_sendmailPath; - - bool m_connected; - - - // Service infos - class _infos : public serviceInfos - { - public: - - struct props - { - serviceInfos::property PROPERTY_BINPATH; - }; - - const props& getProperties() const; - - const string getPropertyPrefix() const; - const std::vector getAvailableProperties() const; - }; - - static _infos sm_infos; -}; - - -} // sendmail -} // messaging -} // vmime - - -#endif // VMIME_BUILTIN_PLATFORM_POSIX - - -#endif // VMIME_MESSAGING_SENDMAIL_SENDMAILTRANSPORT_HPP_INCLUDED diff --git a/vmime/messaging/service.hpp b/vmime/messaging/service.hpp deleted file mode 100644 index 9d2e76d9..00000000 --- a/vmime/messaging/service.hpp +++ /dev/null @@ -1,161 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_SERVICE_HPP_INCLUDED -#define VMIME_MESSAGING_SERVICE_HPP_INCLUDED - - -#include "vmime/types.hpp" - -#include "vmime/messaging/session.hpp" -#include "vmime/messaging/authenticator.hpp" - -#include "vmime/messaging/serviceFactory.hpp" -#include "vmime/messaging/serviceInfos.hpp" - -#include "vmime/utility/progressionListener.hpp" - - -namespace vmime { -namespace messaging { - - -/** Base class for messaging services. - */ - -class service : public object -{ -protected: - - service(ref sess, const serviceInfos& infos, ref auth); - -public: - - virtual ~service(); - - // Possible service types - enum Type - { - TYPE_STORE = 0, /**< The service is a message store. */ - TYPE_TRANSPORT /**< The service sends messages. */ - }; - - /** Return the type of service. - * - * @return type of service - */ - virtual const Type getType() const = 0; - - /** Return the protocol name of this service. - * - * @return protocol name - */ - virtual const string getProtocolName() const = 0; - - /** Return the session object associated with this service instance. - * - * @return session object - */ - ref getSession() const; - - /** Return the session object associated with this service instance. - * - * @return session object - */ - ref getSession(); - - /** Return information about this service. - * - * @return information about the service - */ - virtual const serviceInfos& getInfos() const = 0; - - /** Connect to service. - */ - virtual void connect() = 0; - - /** Disconnect from service. - */ - virtual void disconnect() = 0; - - /** Test whether this service is connected. - * - * @return true if the service is connected, false otherwise - */ - virtual const bool isConnected() const = 0; - - /** Do nothing but ensure the server do not disconnect (for - * example, this can reset the auto-logout timer on the - * server, if one exists). - */ - virtual void noop() = 0; - - /** Return the authenticator object used with this service instance. - * - * @return authenticator object - */ - ref getAuthenticator() const; - - /** Return the authenticator object used with this service instance. - * - * @return authenticator object - */ - ref getAuthenticator(); - - /** Set a property for this service (service prefix is added automatically). - * - * WARNING: this sets the property on the session object, so all service - * instances created with the session object will inherit the property. - * - * @param name property name - * @param value property value - */ - template - void setProperty(const string& name, const TYPE& value) - { - m_session->getProperties()[getInfos().getPropertyPrefix() + name] = value; - } - -#ifndef VMIME_BUILDING_DOC - // Basic service registerer - template - class initializer - { - public: - - initializer(const string& protocol) - { - serviceFactory::getInstance()-> - template registerServiceByProtocol (protocol); - } - }; -#endif // VMIME_BUILDING_DOC - -private: - - ref m_session; - ref m_auth; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_SERVICE_HPP_INCLUDED diff --git a/vmime/messaging/serviceFactory.hpp b/vmime/messaging/serviceFactory.hpp deleted file mode 100644 index c7eff565..00000000 --- a/vmime/messaging/serviceFactory.hpp +++ /dev/null @@ -1,188 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_SERVICEFACTORY_HPP_INCLUDED -#define VMIME_MESSAGING_SERVICEFACTORY_HPP_INCLUDED - - -#include - -#include "vmime/types.hpp" -#include "vmime/base.hpp" - -#include "vmime/utility/stringUtils.hpp" -#include "vmime/utility/url.hpp" - -#include "vmime/messaging/serviceInfos.hpp" -#include "vmime/messaging/authenticator.hpp" -#include "vmime/messaging/timeoutHandler.hpp" - -#include "vmime/utility/progressionListener.hpp" - - -namespace vmime { -namespace messaging { - - -class service; -class session; - - -/** A factory to create 'service' objects for a specified protocol. - */ - -class serviceFactory -{ -private: - - serviceFactory(); - ~serviceFactory(); - -public: - - static serviceFactory* getInstance(); - - /** Information about a registered service. */ - class registeredService : public object - { - friend class serviceFactory; - - protected: - - virtual ~registeredService() { } - - public: - - virtual ref create(ref sess, ref auth) const = 0; - - virtual const string& getName() const = 0; - virtual const serviceInfos& getInfos() const = 0; - }; - -private: - - template - class registeredServiceImpl : public registeredService - { - friend class serviceFactory; - friend class vmime::creator; - - protected: - - registeredServiceImpl(const string& name) - : m_name(name), m_servInfos(S::getInfosInstance()) - { - } - - public: - - ref create(ref sess, ref auth) const - { - return vmime::create (sess, auth); - } - - const serviceInfos& getInfos() const - { - return (m_servInfos); - } - - const string& getName() const - { - return (m_name); - } - - private: - - const string m_name; - const serviceInfos& m_servInfos; - }; - - std::vector > m_services; - -public: - - /** Register a new service by its protocol name. - * - * @param protocol protocol name - */ - template - void registerServiceByProtocol(const string& protocol) - { - const string name = utility::stringUtils::toLower(protocol); - m_services.push_back(vmime::create >(name)); - } - - /** Create a new service instance from a protocol name. - * - * @param sess session - * @param protocol protocol name (eg. "pop3") - * @param auth authenticator used to provide credentials (can be NULL if not used) - * @return a new service instance for the specified protocol - * @throw exceptions::no_service_available if no service is registered - * for this protocol - */ - ref create(ref sess, const string& protocol, ref auth = NULL); - - /** Create a new service instance from a URL. - * - * @param sess session - * @param u full URL with at least protocol and server (you can also specify - * port, username and password) - * @param auth authenticator used to provide credentials (can be NULL if not used) - * @return a new service instance for the specified protocol - * @throw exceptions::no_service_available if no service is registered - * for this protocol - */ - ref create(ref sess, const utility::url& u, ref auth = NULL); - - /** Return information about a registered protocol. - * - * @param protocol protocol name - * @return information about this protocol - * @throw exceptions::no_service_available if no service is registered - * for this protocol - */ - ref getServiceByProtocol(const string& protocol) const; - - /** Return the number of registered services. - * - * @return number of registered services - */ - const int getServiceCount() const; - - /** Return the registered service at the specified position. - * - * @param pos position of the registered service to return - * @return registered service at the specified position - */ - ref getServiceAt(const int pos) const; - - /** Return a list of all registered services. - * - * @return list of registered services - */ - const std::vector > getServiceList() const; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_SERVICEFACTORY_HPP_INCLUDED diff --git a/vmime/messaging/serviceInfos.hpp b/vmime/messaging/serviceInfos.hpp deleted file mode 100644 index bdfcd887..00000000 --- a/vmime/messaging/serviceInfos.hpp +++ /dev/null @@ -1,228 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_SERVICEINFOS_HPP_INCLUDED -#define VMIME_MESSAGING_SERVICEINFOS_HPP_INCLUDED - - -#include - -#include "vmime/types.hpp" - -#include "vmime/messaging/session.hpp" - - -namespace vmime { -namespace messaging { - - -/** Stores information about a messaging service. - */ - -class serviceInfos -{ - friend class serviceFactory; - -protected: - - serviceInfos(); - serviceInfos(const serviceInfos&); - -private: - - serviceInfos& operator=(const serviceInfos&); - -public: - - virtual ~serviceInfos(); - - - /** A service property. - */ - class property - { - public: - - /** The common property 'server.address' which is - * the host name or the IP address of the server. */ - static const property SERVER_ADDRESS; - - /** The common property 'server.port' which is - * the port used to connect to the server. */ - static const property SERVER_PORT; - - /** The common property 'server.rootpath' which is - * the full path of the folder on the server (for - * maildir, this is the local filesystem directory). */ - static const property SERVER_ROOTPATH; - - /** The common property 'server.socket-factory' used - * to indicate which factory to use to instanciate - * new socket objects. */ - static const property SERVER_SOCKETFACTORY; - - /** The common property 'auth.username' which is the - * username used to authenticate with the server. */ - static const property AUTH_USERNAME; - - /** The common property 'auth.password' which is the - * password used to authenticate with the server. */ - static const property AUTH_PASSWORD; - - /** The common property 'timeout.factory' used to - * specify which factory to use to instanciate - * time-out handler objects. If none is specified, - * no time-out handler is used. */ - static const property TIMEOUT_FACTORY; - - - /** Value types. - */ - enum Types - { - TYPE_INTEGER, /*< Integer number. */ - TYPE_STRING, /*< Character string. */ - TYPE_BOOL, /*< Boolean (true or false). */ - - TYPE_DEFAULT = TYPE_STRING - }; - - /** Property flags. - */ - enum Flags - { - FLAG_NONE = 0, /*< No flags. */ - FLAG_REQUIRED = (1 << 0), /*< The property must be valued. */ - FLAG_HIDDEN = (1 << 1), /*< The property should not be shown - to the user but can be modified. */ - - FLAG_DEFAULT = FLAG_NONE /*< Default flags. */ - }; - - - /** Construct a new property. - * - * @param name property name - * @param type value type - * @param defaultValue default value - * @param flags property attributes - */ - property(const string& name, const Types type, const string& defaultValue = "", const int flags = FLAG_DEFAULT); - - /** Construct a new property from an existing property. - * - * @param p source property - * @param addFlags flags to add - * @param removeFlags flags to remove - */ - property(const property& p, const int addFlags = FLAG_NONE, const int removeFlags = FLAG_NONE); - - /** Construct a new property from an existing property. - * - * @param p source property - * @param newDefaultValue new default value - * @param addFlags flags to add - * @param removeFlags flags to remove - */ - property(const property& p, const string& newDefaultValue, const int addFlags = FLAG_NONE, const int removeFlags = FLAG_NONE); - - property& operator=(const property& p); - - /** Return the name of the property. - * - * @return property name - */ - const string& getName() const; - - /** Return the default value of the property or - * an empty string if there is no default value. - * - * @return default value for the property - */ - const string& getDefaultValue() const; - - /** Return the value type of the property. - * - * @return property value type - */ - const Types getType() const; - - /** Return the attributes of the property (see - * serviceInfos::property::Types constants). - * - * @return property attributes - */ - const int getFlags() const; - - private: - - string m_name; - string m_defaultValue; - Types m_type; - int m_flags; - }; - - - /** Return the property prefix used by this service. - * Use this to set/get properties in the session object. - * - * @return property prefix - */ - virtual const string getPropertyPrefix() const = 0; - - /** Return a list of available properties for this service. - * - * @return list of properties - */ - virtual const std::vector getAvailableProperties() const = 0; - - /** Helper function to retrieve the value of a property. - * - * @param s session object - * @param p property to retrieve - * @throw exceptions::no_such_property if the property does not exist - * and has the flag property::FLAG_REQUIRED - * @return value of the property - */ - template - const TYPE getPropertyValue(ref s, const property& p) const - { - if (p.getFlags() & property::FLAG_REQUIRED) - return s->getProperties()[getPropertyPrefix() + p.getName()].template getValue (); - - return s->getProperties().template getProperty (getPropertyPrefix() + p.getName(), - propertySet::valueFromString (p.getDefaultValue())); - } - - /** Helper function to test if the specified property is set in - * the session object. - * - * @param s session object - * @param p property to test - * @return true if the property is set, false otherwise - */ - const bool hasProperty(ref s, const property& p) const; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_SERVICEINFOS_HPP_INCLUDED diff --git a/vmime/messaging/session.hpp b/vmime/messaging/session.hpp deleted file mode 100644 index e2b92634..00000000 --- a/vmime/messaging/session.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_SESSION_HPP_INCLUDED -#define VMIME_MESSAGING_SESSION_HPP_INCLUDED - - -#include "vmime/messaging/authenticator.hpp" - -#include "vmime/utility/url.hpp" - -#include "vmime/propertySet.hpp" - - -namespace vmime { -namespace messaging { - - -class store; -class transport; - - -/** An object that contains all the information needed - * for connection to a service. - */ - -class session : public object -{ -public: - - session(); - session(const session& sess); - session(const propertySet& props); - - virtual ~session(); - - /** Return a transport service instance for the protocol specified - * in the session properties. - * - * The property "transport.protocol" specify the protocol to use. - * - * @param auth authenticator object to use for the new transport service. If - * NULL, a default one is used. The default authenticator simply return user - * credentials by reading the session properties "auth.username" and "auth.password". - * @return a new transport service - */ - ref getTransport(ref auth = NULL); - - /** Return a transport service instance for the specified protocol. - * - * @param protocol transport protocol to use (eg. "smtp") - * @param auth authenticator object to use for the new transport service. If - * NULL, a default one is used. The default authenticator simply return user - * credentials by reading the session properties "auth.username" and "auth.password". - * @return a new transport service - */ - ref getTransport(const string& protocol, ref auth = NULL); - - /** Return a transport service instance for the specified URL. - * - * @param url full URL with at least the protocol to use (eg: "smtp://myserver.com/") - * @param auth authenticator object to use for the new transport service. If - * NULL, a default one is used. The default authenticator simply return user - * credentials by reading the session properties "auth.username" and "auth.password". - * @return a new transport service - */ - ref getTransport(const utility::url& url, ref auth = NULL); - - /** Return a transport service instance for the protocol specified - * in the session properties. - * - * The property "store.protocol" specify the protocol to use. - * - * @param auth authenticator object to use for the new store service. If - * NULL, a default one is used. The default authenticator simply return user - * credentials by reading the session properties "auth.username" and "auth.password". - * @return a new store service - */ - ref getStore(ref auth = NULL); - - /** Return a store service instance for the specified protocol. - * - * @param protocol store protocol to use (eg. "imap") - * @param auth authenticator object to use for the new store service. If - * NULL, a default one is used. The default authenticator simply return user - * credentials by reading the session properties "auth.username" and "auth.password". - * @return a new store service - */ - ref getStore(const string& protocol, ref auth = NULL); - - /** Return a store service instance for the specified URL. - * - * @param url full URL with at least the protocol to use (eg: "imap://username:password@myserver.com/") - * @param auth authenticator object to use for the new store service. If - * NULL, a default one is used. The default authenticator simply return user - * credentials by reading the session properties "auth.username" and "auth.password". - * @return a new store service - */ - ref getStore(const utility::url& url, ref auth = NULL); - - /** Properties for the session and for the services. - */ - const propertySet& getProperties() const; - - /** Properties for the session and for the services. - */ - propertySet& getProperties(); - -private: - - propertySet m_props; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_SESSION_HPP_INCLUDED diff --git a/vmime/messaging/simpleAuthenticator.hpp b/vmime/messaging/simpleAuthenticator.hpp deleted file mode 100644 index bf09f43b..00000000 --- a/vmime/messaging/simpleAuthenticator.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_SIMPLEAUTHENTICATOR_HPP_INCLUDED -#define VMIME_MESSAGING_SIMPLEAUTHENTICATOR_HPP_INCLUDED - - -#include "vmime/messaging/authenticator.hpp" - - -namespace vmime { -namespace messaging { - - -/** Basic implementation for an authenticator. - */ - -class simpleAuthenticator : public authenticator -{ -public: - - simpleAuthenticator(); - simpleAuthenticator(const string& username, const string& password); - -public: - - const string& getUsername() const; - void setUsername(const string& username); - - const string& getPassword() const; - void setPassword(const string& password); - -private: - - string m_username; - string m_password; - - const authenticationInfos getAuthInfos() const; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_SIMPLEAUTHENTICATOR_HPP_INCLUDED diff --git a/vmime/messaging/smtp/SMTPTransport.hpp b/vmime/messaging/smtp/SMTPTransport.hpp deleted file mode 100644 index 191d134c..00000000 --- a/vmime/messaging/smtp/SMTPTransport.hpp +++ /dev/null @@ -1,113 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_SMTP_SMTPTRANSPORT_HPP_INCLUDED -#define VMIME_MESSAGING_SMTP_SMTPTRANSPORT_HPP_INCLUDED - - -#include "vmime/config.hpp" - -#include "vmime/messaging/transport.hpp" -#include "vmime/messaging/socket.hpp" -#include "vmime/messaging/timeoutHandler.hpp" - - -namespace vmime { -namespace messaging { -namespace smtp { - - -/** SMTP transport service. - */ - -class SMTPTransport : public transport -{ -public: - - SMTPTransport(ref sess, ref auth); - ~SMTPTransport(); - - const string getProtocolName() const; - - static const serviceInfos& getInfosInstance(); - const serviceInfos& getInfos() const; - - void connect(); - const bool isConnected() const; - void disconnect(); - - void noop(); - - void send(const mailbox& expeditor, const mailboxList& recipients, utility::inputStream& is, const utility::stream::size_type size, utility::progressionListener* progress = NULL); - -private: - - static const int responseCode(const string& response); - static const string responseText(const string& response); - - void sendRequest(const string& buffer, const bool end = true); - - void readResponse(string& buffer); - - void internalDisconnect(); - - ref m_socket; - bool m_authentified; - bool m_extendedSMTP; - - ref m_timeoutHandler; - - - // Service infos - class _infos : public serviceInfos - { - public: - - struct props - { - // SMTP-specific options - serviceInfos::property PROPERTY_OPTIONS_NEEDAUTH; - - // Common properties - serviceInfos::property PROPERTY_AUTH_USERNAME; - serviceInfos::property PROPERTY_AUTH_PASSWORD; - - serviceInfos::property PROPERTY_SERVER_ADDRESS; - serviceInfos::property PROPERTY_SERVER_PORT; - serviceInfos::property PROPERTY_SERVER_SOCKETFACTORY; - - serviceInfos::property PROPERTY_TIMEOUT_FACTORY; - }; - - const props& getProperties() const; - - const string getPropertyPrefix() const; - const std::vector getAvailableProperties() const; - }; - - static _infos sm_infos; -}; - - -} // smtp -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_SMTP_SMTPTRANSPORT_HPP_INCLUDED diff --git a/vmime/messaging/socket.hpp b/vmime/messaging/socket.hpp deleted file mode 100644 index dc5cdad9..00000000 --- a/vmime/messaging/socket.hpp +++ /dev/null @@ -1,112 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_SOCKET_HPP_INCLUDED -#define VMIME_MESSAGING_SOCKET_HPP_INCLUDED - - -#include "vmime/base.hpp" - - -namespace vmime { -namespace messaging { - - -/** Interface for connecting to servers. - */ - -class socket : public object -{ -public: - - virtual ~socket() { } - - /** Connect to the specified address and port. - * - * @param address server address (this can be a full qualified domain name - * or an IP address, doesn't matter) - * @param port server port - */ - virtual void connect(const string& address, const port_t port) = 0; - - /** Disconnect from the server. - */ - virtual void disconnect() = 0; - - /** Test whether this socket is connected. - * - * @return true if the socket is connected, false otherwise - */ - virtual const bool isConnected() const = 0; - - /** Receive (text) data from the socket. - * - * @param buffer buffer in which to write received data - */ - virtual void receive(string& buffer) = 0; - - /** Receive (raw) data from the socket. - * - * @param buffer buffer in which to write received data - * @param count maximum number of bytes to receive (size of buffer) - * @return number of bytes received/written into output buffer - */ - virtual const int receiveRaw(char* buffer, const int count) = 0; - - /** Send (text) data to the socket. - * - * @param buffer data to send - */ - virtual void send(const string& buffer) = 0; - - /** Send (raw) data to the socket. - * - * @param buffer data to send - * @param count number of bytes to send (size of buffer) - */ - virtual void sendRaw(const char* buffer, const int count) = 0; - -protected: - - socket() { } - -private: - - socket(const socket&) : object() { } -}; - - -/** A class to create 'socket' objects. - */ - -class socketFactory -{ -public: - - virtual ~socketFactory() { } - - virtual ref create() = 0; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_SOCKET_HPP_INCLUDED diff --git a/vmime/messaging/store.hpp b/vmime/messaging/store.hpp deleted file mode 100644 index 68dfaf98..00000000 --- a/vmime/messaging/store.hpp +++ /dev/null @@ -1,102 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_STORE_HPP_INCLUDED -#define VMIME_MESSAGING_STORE_HPP_INCLUDED - - -#include "vmime/messaging/service.hpp" -#include "vmime/messaging/folder.hpp" - - -namespace vmime { -namespace messaging { - - -/** A store service. - * Encapsulate protocols that provide access to user's mail drop. - */ - -class store : public service -{ -protected: - - store(ref sess, const serviceInfos& infos, ref auth) - : service(sess, infos, auth) { } - -public: - - /** Return the default folder. This is protocol dependant - * and usually is the INBOX folder. - * - * @return default folder - */ - virtual ref getDefaultFolder() = 0; - - /** Return the root folder. This is protocol dependant - * and usually is the user's mail drop root folder. - * - * @return root folder - */ - virtual ref getRootFolder() = 0; - - /** Return the folder specified by the path. - * - * @param path absolute folder path - * @return folder at the specified path - */ - virtual ref getFolder(const folder::path& path) = 0; - - /** Test whether the specified folder name is a syntactically - * a valid name. - * - * @return true if the specified folder name is valid, false otherwise - */ - virtual const bool isValidFolderName(const folder::path::component& name) const = 0; - - /** Store capabilities. */ - enum Capabilities - { - CAPABILITY_CREATE_FOLDER = (1 << 0), /**< Can create folders. */ - CAPABILITY_RENAME_FOLDER = (1 << 1), /**< Can rename folders. */ - CAPABILITY_ADD_MESSAGE = (1 << 2), /**< Can append message to folders. */ - CAPABILITY_COPY_MESSAGE = (1 << 3), /**< Can copy messages from a folder to another one. */ - CAPABILITY_DELETE_MESSAGE = (1 << 4), /**< Can delete messages. */ - CAPABILITY_PARTIAL_FETCH = (1 << 5), /**< Is partial fetch supported? */ - CAPABILITY_MESSAGE_FLAGS = (1 << 6), /**< Can set flags on messages. */ - CAPABILITY_EXTRACT_PART = (1 << 7) /**< Can extract a specific part of the message. */ - }; - - /** Return the features supported by this service. This is - * a combination of store::CAPABILITY_xxx flags. - * - * @return features supported by this service - */ - virtual const int getCapabilities() const = 0; - - - const Type getType() const { return (TYPE_STORE); } -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_STORE_HPP_INCLUDED diff --git a/vmime/messaging/timeoutHandler.hpp b/vmime/messaging/timeoutHandler.hpp deleted file mode 100644 index 75d333e0..00000000 --- a/vmime/messaging/timeoutHandler.hpp +++ /dev/null @@ -1,77 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_TIMEOUTHANDLER_HPP_INCLUDED -#define VMIME_MESSAGING_TIMEOUTHANDLER_HPP_INCLUDED - - -#include "vmime/types.hpp" - - -namespace vmime { -namespace messaging { - - -/** A class to manage time-out in messaging services. - */ - -class timeoutHandler : public object -{ -public: - - virtual ~timeoutHandler() { } - - /** Called to test if the time limit has been reached. - * - * @return true if the time-out delay is elapsed - */ - virtual const bool isTimeOut() = 0; - - /** Called to reset the time-out counter. - */ - virtual void resetTimeOut() = 0; - - /** Called when the time limit has been reached (when - * isTimeOut() returned true). - * - * @return true to continue (and reset the time-out) - * or false to cancel the current operation - */ - virtual const bool handleTimeOut() = 0; -}; - - -/** A class to create 'timeoutHandler' objects. - */ - -class timeoutHandlerFactory -{ -public: - - virtual ~timeoutHandlerFactory() { } - - virtual ref create() = 0; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_TIMEOUTHANDLER_HPP_INCLUDED diff --git a/vmime/messaging/transport.hpp b/vmime/messaging/transport.hpp deleted file mode 100644 index 8f499154..00000000 --- a/vmime/messaging/transport.hpp +++ /dev/null @@ -1,75 +0,0 @@ -// -// VMime library (http://www.vmime.org) -// Copyright (C) 2002-2005 Vincent Richard -// -// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. -// - -#ifndef VMIME_MESSAGING_TRANSPORT_HPP_INCLUDED -#define VMIME_MESSAGING_TRANSPORT_HPP_INCLUDED - - -#include "vmime/messaging/service.hpp" -#include "vmime/utility/stream.hpp" - - -namespace vmime { - -class message; -class mailbox; -class mailboxList; - -namespace messaging { - - -/** A transport service. - * Encapsulate protocols that can send messages. - */ - -class transport : public service -{ -protected: - - transport(ref sess, const serviceInfos& infos, ref auth); - -public: - - /** Send a message over this transport service. - * - * @param msg message to send - * @param progress progression listener, or NULL if not used - */ - virtual void send(ref msg, utility::progressionListener* progress = NULL); - - /** Send a message over this transport service. - * - * @param expeditor expeditor mailbox - * @param recipients list of recipient mailboxes - * @param is input stream provding message data (header + body) - * @param size size of the message data - * @param progress progression listener, or NULL if not used - */ - virtual void send(const mailbox& expeditor, const mailboxList& recipients, utility::inputStream& is, const utility::stream::size_type size, utility::progressionListener* progress = NULL) = 0; - - - const Type getType() const; -}; - - -} // messaging -} // vmime - - -#endif // VMIME_MESSAGING_TRANSPORT_HPP_INCLUDED