Renamed 'vmime::messaging' to 'vmime::net'.
This commit is contained in:
parent
8cdddcdf03
commit
28bafee944
@ -2,6 +2,12 @@
|
||||
VERSION 0.7.2cvs
|
||||
================
|
||||
|
||||
2005-08-23 Vincent Richard <vincent@vincent-richard.net>
|
||||
|
||||
* All sources: renamed 'vmime::messaging' to 'vmime::net'. An alias has been
|
||||
kept for compatibility with previous versions (its use should be considered
|
||||
as deprecated).
|
||||
|
||||
2005-08-19 Vincent Richard <vincent@vincent-richard.net>
|
||||
|
||||
* exception.hpp: vmime::exception now inherits from std::exception.
|
||||
|
68
SConstruct
68
SConstruct
@ -58,7 +58,7 @@ packageAPIAge = packageVersionMinor
|
||||
packageName = 'libvmime'
|
||||
packageGenericName = 'vmime'
|
||||
packageRealName = 'VMime Library'
|
||||
packageDescription = 'VMime C++ Mail Library (http://vmime.sourceforge.net)'
|
||||
packageDescription = 'VMime C++ Mail Library (http://www.vmime.org)'
|
||||
packageMaintainer = 'vincent@vincent-richard.net'
|
||||
|
||||
packageVersion = '%d.%d.%d' % (packageVersionMajor, packageVersionMinor, packageVersionMicro)
|
||||
@ -182,65 +182,65 @@ libvmime_examples_sources = [
|
||||
]
|
||||
|
||||
libvmime_messaging_sources = [
|
||||
'messaging/authenticator.cpp', 'messaging/authenticator.hpp',
|
||||
'messaging/authenticationInfos.cpp', 'messaging/authenticationInfos.hpp',
|
||||
'messaging/authHelper.cpp', 'messaging/authHelper.hpp',
|
||||
'messaging/builtinServices.inl',
|
||||
'messaging/defaultAuthenticator.cpp', 'messaging/defaultAuthenticator.hpp',
|
||||
'messaging/events.cpp', 'messaging/events.hpp',
|
||||
'messaging/folder.cpp', 'messaging/folder.hpp',
|
||||
'messaging/message.cpp', 'messaging/message.hpp',
|
||||
'messaging/service.cpp', 'messaging/service.hpp',
|
||||
'messaging/serviceFactory.cpp', 'messaging/serviceFactory.hpp',
|
||||
'messaging/serviceInfos.cpp', 'messaging/serviceInfos.hpp',
|
||||
'messaging/session.cpp', 'messaging/session.hpp',
|
||||
'messaging/simpleAuthenticator.cpp', 'messaging/simpleAuthenticator.hpp',
|
||||
'messaging/socket.hpp',
|
||||
'messaging/store.hpp',
|
||||
'messaging/timeoutHandler.hpp',
|
||||
'messaging/transport.cpp', 'messaging/transport.hpp'
|
||||
'net/authenticator.cpp', 'net/authenticator.hpp',
|
||||
'net/authenticationInfos.cpp', 'net/authenticationInfos.hpp',
|
||||
'net/authHelper.cpp', 'net/authHelper.hpp',
|
||||
'net/builtinServices.inl',
|
||||
'net/defaultAuthenticator.cpp', 'net/defaultAuthenticator.hpp',
|
||||
'net/events.cpp', 'net/events.hpp',
|
||||
'net/folder.cpp', 'net/folder.hpp',
|
||||
'net/message.cpp', 'net/message.hpp',
|
||||
'net/service.cpp', 'net/service.hpp',
|
||||
'net/serviceFactory.cpp', 'net/serviceFactory.hpp',
|
||||
'net/serviceInfos.cpp', 'net/serviceInfos.hpp',
|
||||
'net/session.cpp', 'net/session.hpp',
|
||||
'net/simpleAuthenticator.cpp', 'net/simpleAuthenticator.hpp',
|
||||
'net/socket.hpp',
|
||||
'net/store.hpp',
|
||||
'net/timeoutHandler.hpp',
|
||||
'net/transport.cpp', 'net/transport.hpp'
|
||||
]
|
||||
|
||||
libvmime_messaging_proto_sources = [
|
||||
[
|
||||
'pop3',
|
||||
[
|
||||
'messaging/pop3/POP3Store.cpp', 'messaging/pop3/POP3Store.hpp',
|
||||
'messaging/pop3/POP3Folder.cpp', 'messaging/pop3/POP3Folder.hpp',
|
||||
'messaging/pop3/POP3Message.cpp', 'messaging/pop3/POP3Message.hpp'
|
||||
'net/pop3/POP3Store.cpp', 'net/pop3/POP3Store.hpp',
|
||||
'net/pop3/POP3Folder.cpp', 'net/pop3/POP3Folder.hpp',
|
||||
'net/pop3/POP3Message.cpp', 'net/pop3/POP3Message.hpp'
|
||||
]
|
||||
],
|
||||
[
|
||||
'smtp',
|
||||
[
|
||||
'messaging/smtp/SMTPTransport.cpp', 'messaging/smtp/SMTPTransport.hpp'
|
||||
'net/smtp/SMTPTransport.cpp', 'net/smtp/SMTPTransport.hpp'
|
||||
]
|
||||
],
|
||||
[
|
||||
'imap',
|
||||
[
|
||||
'messaging/imap/IMAPConnection.cpp', 'messaging/imap/IMAPConnection.hpp',
|
||||
'messaging/imap/IMAPStore.cpp', 'messaging/imap/IMAPStore.hpp',
|
||||
'messaging/imap/IMAPFolder.cpp', 'messaging/imap/IMAPFolder.hpp',
|
||||
'messaging/imap/IMAPMessage.cpp', 'messaging/imap/IMAPMessage.hpp',
|
||||
'messaging/imap/IMAPTag.cpp', 'messaging/imap/IMAPTag.hpp',
|
||||
'messaging/imap/IMAPUtils.cpp', 'messaging/imap/IMAPUtils.hpp',
|
||||
'messaging/imap/IMAPParser.hpp'
|
||||
'net/imap/IMAPConnection.cpp', 'net/imap/IMAPConnection.hpp',
|
||||
'net/imap/IMAPStore.cpp', 'net/imap/IMAPStore.hpp',
|
||||
'net/imap/IMAPFolder.cpp', 'net/imap/IMAPFolder.hpp',
|
||||
'net/imap/IMAPMessage.cpp', 'net/imap/IMAPMessage.hpp',
|
||||
'net/imap/IMAPTag.cpp', 'net/imap/IMAPTag.hpp',
|
||||
'net/imap/IMAPUtils.cpp', 'net/imap/IMAPUtils.hpp',
|
||||
'net/imap/IMAPParser.hpp'
|
||||
]
|
||||
],
|
||||
[
|
||||
'maildir',
|
||||
[
|
||||
'messaging/maildir/maildirStore.cpp', 'messaging/maildir/maildirStore.hpp',
|
||||
'messaging/maildir/maildirFolder.cpp', 'messaging/maildir/maildirFolder.hpp',
|
||||
'messaging/maildir/maildirMessage.cpp', 'messaging/maildir/maildirMessage.hpp',
|
||||
'messaging/maildir/maildirUtils.cpp', 'messaging/maildir/maildirUtils.hpp'
|
||||
'net/maildir/maildirStore.cpp', 'net/maildir/maildirStore.hpp',
|
||||
'net/maildir/maildirFolder.cpp', 'net/maildir/maildirFolder.hpp',
|
||||
'net/maildir/maildirMessage.cpp', 'net/maildir/maildirMessage.hpp',
|
||||
'net/maildir/maildirUtils.cpp', 'net/maildir/maildirUtils.hpp'
|
||||
]
|
||||
],
|
||||
[
|
||||
'sendmail',
|
||||
[
|
||||
'messaging/sendmail/sendmailTransport.cpp', 'messaging/sendmail/sendmailTransport.hpp'
|
||||
'net/sendmail/sendmailTransport.cpp', 'net/sendmail/sendmailTransport.hpp'
|
||||
]
|
||||
]
|
||||
]
|
||||
|
@ -26,14 +26,14 @@
|
||||
|
||||
|
||||
// Global session object
|
||||
static vmime::ref <vmime::messaging::session> g_session
|
||||
= vmime::create <vmime::messaging::session>();
|
||||
static vmime::ref <vmime::net::session> g_session
|
||||
= vmime::create <vmime::net::session>();
|
||||
|
||||
|
||||
// Authentification handler
|
||||
class interactiveAuthenticator : public vmime::messaging::authenticator
|
||||
class interactiveAuthenticator : public vmime::net::authenticator
|
||||
{
|
||||
const vmime::messaging::authenticationInfos requestAuthInfos() const
|
||||
const vmime::net::authenticationInfos requestAuthInfos() const
|
||||
{
|
||||
vmime::string username, password;
|
||||
|
||||
@ -50,7 +50,7 @@ class interactiveAuthenticator : public vmime::messaging::authenticator
|
||||
|
||||
std::getline(std::cin, password);
|
||||
|
||||
return (vmime::messaging::authenticationInfos(username, password));
|
||||
return (vmime::net::authenticationInfos(username, password));
|
||||
}
|
||||
};
|
||||
|
||||
@ -108,11 +108,11 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
|
||||
* @param s structure object
|
||||
* @param level current depth
|
||||
*/
|
||||
static void printStructure(const vmime::messaging::structure& s, const int level = 0)
|
||||
static void printStructure(const vmime::net::structure& s, const int level = 0)
|
||||
{
|
||||
for (int i = 1 ; i <= s.getCount() ; ++i)
|
||||
{
|
||||
const vmime::messaging::part& part = s[i];
|
||||
const vmime::net::part& part = s[i];
|
||||
|
||||
for (int j = 0 ; j < level * 2 ; ++j)
|
||||
std::cout << " ";
|
||||
@ -127,7 +127,7 @@ static void printStructure(const vmime::messaging::structure& s, const int level
|
||||
}
|
||||
|
||||
|
||||
static const vmime::string getFolderPathString(vmime::ref <vmime::messaging::folder> f)
|
||||
static const vmime::string getFolderPathString(vmime::ref <vmime::net::folder> f)
|
||||
{
|
||||
const vmime::string n = f->getName().getBuffer();
|
||||
|
||||
@ -137,7 +137,7 @@ static const vmime::string getFolderPathString(vmime::ref <vmime::messaging::fol
|
||||
}
|
||||
else
|
||||
{
|
||||
vmime::ref <vmime::messaging::folder> p = f->getParent();
|
||||
vmime::ref <vmime::net::folder> p = f->getParent();
|
||||
return getFolderPathString(p) + n + "/";
|
||||
}
|
||||
}
|
||||
@ -147,14 +147,14 @@ static const vmime::string getFolderPathString(vmime::ref <vmime::messaging::fol
|
||||
*
|
||||
* @param folder current folder
|
||||
*/
|
||||
static void printFolders(vmime::ref <vmime::messaging::folder> folder, const int level = 0)
|
||||
static void printFolders(vmime::ref <vmime::net::folder> folder, const int level = 0)
|
||||
{
|
||||
for (int j = 0 ; j < level * 2 ; ++j)
|
||||
std::cout << " ";
|
||||
|
||||
std::cout << getFolderPathString(folder) << std::endl;
|
||||
|
||||
std::vector <vmime::ref <vmime::messaging::folder> > subFolders = folder->getFolders(false);
|
||||
std::vector <vmime::ref <vmime::net::folder> > subFolders = folder->getFolders(false);
|
||||
|
||||
for (unsigned int i = 0 ; i < subFolders.size() ; ++i)
|
||||
printFolders(subFolders[i], level + 1);
|
||||
@ -210,7 +210,7 @@ static void sendMessage()
|
||||
|
||||
vmime::utility::url url(urlString);
|
||||
|
||||
vmime::ref <vmime::messaging::transport> tr =
|
||||
vmime::ref <vmime::net::transport> tr =
|
||||
g_session->getTransport(url, vmime::create <interactiveAuthenticator>());
|
||||
|
||||
// You can also set some properties (see example7 to know the properties
|
||||
@ -307,7 +307,7 @@ static void connectStore()
|
||||
// If no authenticator is given in argument to getStore(), a default one
|
||||
// is used. Its behaviour is to get the user credentials from the
|
||||
// session properties "auth.username" and "auth.password".
|
||||
vmime::ref <vmime::messaging::store> st;
|
||||
vmime::ref <vmime::net::store> st;
|
||||
|
||||
if (url.getUsername().empty() || url.getPassword().empty())
|
||||
st = g_session->getStore(url, vmime::create <interactiveAuthenticator>());
|
||||
@ -318,10 +318,10 @@ static void connectStore()
|
||||
st->connect();
|
||||
|
||||
// Open the default folder in this store
|
||||
vmime::ref <vmime::messaging::folder> f = st->getDefaultFolder();
|
||||
// vmime::ref <vmime::messaging::folder> f = st->getFolder(vmime::utility::path("a"));
|
||||
vmime::ref <vmime::net::folder> f = st->getDefaultFolder();
|
||||
// vmime::ref <vmime::net::folder> f = st->getFolder(vmime::utility::path("a"));
|
||||
|
||||
f->open(vmime::messaging::folder::MODE_READ_WRITE);
|
||||
f->open(vmime::net::folder::MODE_READ_WRITE);
|
||||
|
||||
int count = f->getMessageCount();
|
||||
|
||||
@ -330,7 +330,7 @@ static void connectStore()
|
||||
|
||||
for (bool cont = true ; cont ; )
|
||||
{
|
||||
typedef std::map <int, vmime::ref <vmime::messaging::message> > MessageList;
|
||||
typedef std::map <int, vmime::ref <vmime::net::message> > MessageList;
|
||||
MessageList msgList;
|
||||
|
||||
try
|
||||
@ -348,7 +348,7 @@ static void connectStore()
|
||||
const int choice = printMenu(choices);
|
||||
|
||||
// Request message number
|
||||
vmime::ref <vmime::messaging::message> msg;
|
||||
vmime::ref <vmime::net::message> msg;
|
||||
|
||||
if (choice != 6 && choice != 7)
|
||||
{
|
||||
@ -389,19 +389,19 @@ static void connectStore()
|
||||
// Show message flags
|
||||
case 1:
|
||||
|
||||
f->fetchMessage(msg, vmime::messaging::folder::FETCH_FLAGS);
|
||||
f->fetchMessage(msg, vmime::net::folder::FETCH_FLAGS);
|
||||
|
||||
if (msg->getFlags() & vmime::messaging::message::FLAG_SEEN)
|
||||
if (msg->getFlags() & vmime::net::message::FLAG_SEEN)
|
||||
std::cout << "FLAG_SEEN" << std::endl;
|
||||
if (msg->getFlags() & vmime::messaging::message::FLAG_RECENT)
|
||||
if (msg->getFlags() & vmime::net::message::FLAG_RECENT)
|
||||
std::cout << "FLAG_RECENT" << std::endl;
|
||||
if (msg->getFlags() & vmime::messaging::message::FLAG_REPLIED)
|
||||
if (msg->getFlags() & vmime::net::message::FLAG_REPLIED)
|
||||
std::cout << "FLAG_REPLIED" << std::endl;
|
||||
if (msg->getFlags() & vmime::messaging::message::FLAG_DELETED)
|
||||
if (msg->getFlags() & vmime::net::message::FLAG_DELETED)
|
||||
std::cout << "FLAG_DELETED" << std::endl;
|
||||
if (msg->getFlags() & vmime::messaging::message::FLAG_MARKED)
|
||||
if (msg->getFlags() & vmime::net::message::FLAG_MARKED)
|
||||
std::cout << "FLAG_MARKED" << std::endl;
|
||||
if (msg->getFlags() & vmime::messaging::message::FLAG_PASSED)
|
||||
if (msg->getFlags() & vmime::net::message::FLAG_PASSED)
|
||||
std::cout << "FLAG_PASSED" << std::endl;
|
||||
|
||||
break;
|
||||
@ -409,21 +409,21 @@ static void connectStore()
|
||||
// Show message structure
|
||||
case 2:
|
||||
|
||||
f->fetchMessage(msg, vmime::messaging::folder::FETCH_STRUCTURE);
|
||||
f->fetchMessage(msg, vmime::net::folder::FETCH_STRUCTURE);
|
||||
printStructure(msg->getStructure());
|
||||
break;
|
||||
|
||||
// Show message header
|
||||
case 3:
|
||||
|
||||
f->fetchMessage(msg, vmime::messaging::folder::FETCH_FULL_HEADER);
|
||||
f->fetchMessage(msg, vmime::net::folder::FETCH_FULL_HEADER);
|
||||
std::cout << msg->getHeader()->generate() << std::endl;
|
||||
break;
|
||||
|
||||
// Show message envelope
|
||||
case 4:
|
||||
|
||||
f->fetchMessage(msg, vmime::messaging::folder::FETCH_ENVELOPE);
|
||||
f->fetchMessage(msg, vmime::net::folder::FETCH_ENVELOPE);
|
||||
|
||||
#define ENV_HELPER(x) \
|
||||
try { std::cout << msg->getHeader()->x()->generate() << std::endl; } \
|
||||
@ -449,7 +449,7 @@ static void connectStore()
|
||||
// List folders
|
||||
case 6:
|
||||
{
|
||||
vmime::ref <vmime::messaging::folder>
|
||||
vmime::ref <vmime::net::folder>
|
||||
root = st->getRootFolder();
|
||||
|
||||
printFolders(root);
|
||||
@ -477,19 +477,19 @@ static void connectStore()
|
||||
|
||||
// Folder renaming
|
||||
{
|
||||
vmime::ref <vmime::messaging::folder> f = st->getFolder(vmime::messaging::folder::path("c"));
|
||||
f->rename(vmime::messaging::folder::path("c2"));
|
||||
vmime::ref <vmime::net::folder> f = st->getFolder(vmime::net::folder::path("c"));
|
||||
f->rename(vmime::net::folder::path("c2"));
|
||||
|
||||
vmime::ref <vmime::messaging::folder> g = st->getFolder(vmime::messaging::folder::path("c2"));
|
||||
g->rename(vmime::messaging::folder::path("c"));
|
||||
vmime::ref <vmime::net::folder> g = st->getFolder(vmime::net::folder::path("c2"));
|
||||
g->rename(vmime::net::folder::path("c"));
|
||||
}
|
||||
|
||||
// Message copy: copy all messages from 'f' to 'g'
|
||||
{
|
||||
vmime::ref <vmime::messaging::folder> g = st->getFolder(vmime::messaging::folder::path("TEMP"));
|
||||
vmime::ref <vmime::net::folder> g = st->getFolder(vmime::net::folder::path("TEMP"));
|
||||
|
||||
if (!g->exists())
|
||||
g->create(vmime::messaging::folder::TYPE_CONTAINS_MESSAGES);
|
||||
g->create(vmime::net::folder::TYPE_CONTAINS_MESSAGES);
|
||||
|
||||
f->copyMessages(g->getFullPath());
|
||||
}
|
||||
|
@ -60,23 +60,23 @@ int main()
|
||||
std::cout << std::endl;
|
||||
|
||||
// Enumerate messaging services and their properties
|
||||
vmime::messaging::serviceFactory* sf = vmime::messaging::serviceFactory::getInstance();
|
||||
vmime::net::serviceFactory* sf = vmime::net::serviceFactory::getInstance();
|
||||
|
||||
std::cout << "Available messaging services:" << std::endl;
|
||||
|
||||
for (int i = 0 ; i < sf->getServiceCount() ; ++i)
|
||||
{
|
||||
const vmime::messaging::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
|
||||
const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
|
||||
|
||||
std::cout << " * " << serv.getName() << std::endl;
|
||||
|
||||
std::vector <vmime::messaging::serviceInfos::property> props =
|
||||
std::vector <vmime::net::serviceInfos::property> props =
|
||||
serv.getInfos().getAvailableProperties();
|
||||
|
||||
for (std::vector <vmime::messaging::serviceInfos::property>::const_iterator it = props.begin() ;
|
||||
for (std::vector <vmime::net::serviceInfos::property>::const_iterator it = props.begin() ;
|
||||
it != props.end() ; ++it)
|
||||
{
|
||||
const vmime::messaging::serviceInfos::property& p = *it;
|
||||
const vmime::net::serviceInfos::property& p = *it;
|
||||
|
||||
const vmime::string name = serv.getInfos().getPropertyPrefix() + p.getName();
|
||||
|
||||
@ -84,17 +84,17 @@ int main()
|
||||
|
||||
switch (p.getType())
|
||||
{
|
||||
case vmime::messaging::serviceInfos::property::TYPE_INTEGER: type = "TYPE_INTEGER"; break;
|
||||
case vmime::messaging::serviceInfos::property::TYPE_STRING: type = "TYPE_STRING"; break;
|
||||
case vmime::messaging::serviceInfos::property::TYPE_BOOL: type = "TYPE_BOOL"; break;
|
||||
case vmime::net::serviceInfos::property::TYPE_INTEGER: type = "TYPE_INTEGER"; break;
|
||||
case vmime::net::serviceInfos::property::TYPE_STRING: type = "TYPE_STRING"; break;
|
||||
case vmime::net::serviceInfos::property::TYPE_BOOL: type = "TYPE_BOOL"; break;
|
||||
default: type = "(unknown)"; break;
|
||||
}
|
||||
|
||||
vmime::string flags;
|
||||
|
||||
if (p.getFlags() & vmime::messaging::serviceInfos::property::FLAG_REQUIRED)
|
||||
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_REQUIRED)
|
||||
flags += " FLAG_REQUIRED";
|
||||
if (p.getFlags() & vmime::messaging::serviceInfos::property::FLAG_HIDDEN)
|
||||
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_HIDDEN)
|
||||
flags += " FLAG_HIDDEN";
|
||||
|
||||
std::cout << " - " << serv.getInfos().getPropertyPrefix() + p.getName();
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include "vmime/options.hpp"
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
#include "vmime/messaging/serviceFactory.hpp"
|
||||
#include "vmime/net/serviceFactory.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
@ -143,7 +143,7 @@ public:
|
||||
textPartFactory::getInstance();
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
messaging::serviceFactory::getInstance();
|
||||
net::serviceFactory::getInstance();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
@ -317,15 +317,15 @@ const char* system_error::name() const throw() { return "system_error"; }
|
||||
|
||||
|
||||
//
|
||||
// messaging_exception
|
||||
// net_exception
|
||||
//
|
||||
|
||||
messaging_exception::~messaging_exception() throw() {}
|
||||
messaging_exception::messaging_exception(const string& what, const exception& other)
|
||||
net_exception::~net_exception() throw() {}
|
||||
net_exception::net_exception(const string& what, const exception& other)
|
||||
: exception(what, other) {}
|
||||
|
||||
exception* messaging_exception::clone() const { return new messaging_exception(*this); }
|
||||
const char* messaging_exception::name() const throw() { return "messaging_exception"; }
|
||||
exception* net_exception::clone() const { return new net_exception(*this); }
|
||||
const char* net_exception::name() const throw() { return "net_exception"; }
|
||||
|
||||
|
||||
//
|
||||
@ -334,7 +334,7 @@ const char* messaging_exception::name() const throw() { return "messaging_except
|
||||
|
||||
connection_error::~connection_error() throw() {}
|
||||
connection_error::connection_error(const string& what, const exception& other)
|
||||
: messaging_exception(what.empty()
|
||||
: net_exception(what.empty()
|
||||
? "Connection error."
|
||||
: "Connection error: '" + what + "'.", other) {}
|
||||
|
||||
@ -348,7 +348,7 @@ const char* connection_error::name() const throw() { return "connection_error";
|
||||
|
||||
connection_greeting_error::~connection_greeting_error() throw() {}
|
||||
connection_greeting_error::connection_greeting_error(const string& response, const exception& other)
|
||||
: messaging_exception("Greeting error.", other), m_response(response) {}
|
||||
: net_exception("Greeting error.", other), m_response(response) {}
|
||||
|
||||
const string& connection_greeting_error::response() const { return (m_response); }
|
||||
|
||||
@ -362,7 +362,7 @@ const char* connection_greeting_error::name() const throw() { return "connection
|
||||
|
||||
authentication_error::~authentication_error() throw() {}
|
||||
authentication_error::authentication_error(const string& response, const exception& other)
|
||||
: messaging_exception("Authentication error.", other), m_response(response) {}
|
||||
: net_exception("Authentication error.", other), m_response(response) {}
|
||||
|
||||
const string& authentication_error::response() const { return (m_response); }
|
||||
|
||||
@ -376,7 +376,7 @@ const char* authentication_error::name() const throw() { return "authentication_
|
||||
|
||||
unsupported_option::~unsupported_option() throw() {}
|
||||
unsupported_option::unsupported_option(const exception& other)
|
||||
: messaging_exception("Unsupported option.", other) {}
|
||||
: net_exception("Unsupported option.", other) {}
|
||||
|
||||
exception* unsupported_option::clone() const { return new unsupported_option(*this); }
|
||||
const char* unsupported_option::name() const throw() { return "unsupported_option"; }
|
||||
@ -388,7 +388,7 @@ const char* unsupported_option::name() const throw() { return "unsupported_optio
|
||||
|
||||
no_service_available::~no_service_available() throw() {}
|
||||
no_service_available::no_service_available(const string& proto, const exception& other)
|
||||
: messaging_exception(proto.empty()
|
||||
: net_exception(proto.empty()
|
||||
? "No service available for this protocol."
|
||||
: "No service available for this protocol: '" + proto + "'.", other) {}
|
||||
|
||||
@ -402,7 +402,7 @@ const char* no_service_available::name() const throw() { return "no_service_avai
|
||||
|
||||
illegal_state::~illegal_state() throw() {}
|
||||
illegal_state::illegal_state(const string& state, const exception& other)
|
||||
: messaging_exception("Illegal state to accomplish the operation: '" + state + "'.", other) {}
|
||||
: net_exception("Illegal state to accomplish the operation: '" + state + "'.", other) {}
|
||||
|
||||
exception* illegal_state::clone() const { return new illegal_state(*this); }
|
||||
const char* illegal_state::name() const throw() { return "illegal_state"; }
|
||||
@ -414,7 +414,7 @@ const char* illegal_state::name() const throw() { return "illegal_state"; }
|
||||
|
||||
folder_not_found::~folder_not_found() throw() {}
|
||||
folder_not_found::folder_not_found(const exception& other)
|
||||
: messaging_exception("Folder not found.", other) {}
|
||||
: net_exception("Folder not found.", other) {}
|
||||
|
||||
exception* folder_not_found::clone() const { return new folder_not_found(*this); }
|
||||
const char* folder_not_found::name() const throw() { return "folder_not_found"; }
|
||||
@ -426,7 +426,7 @@ const char* folder_not_found::name() const throw() { return "folder_not_found";
|
||||
|
||||
message_not_found::~message_not_found() throw() {}
|
||||
message_not_found::message_not_found(const exception& other)
|
||||
: messaging_exception("Message not found.", other) {}
|
||||
: net_exception("Message not found.", other) {}
|
||||
|
||||
exception* message_not_found::clone() const { return new message_not_found(*this); }
|
||||
const char* message_not_found::name() const throw() { return "message_not_found"; }
|
||||
@ -438,7 +438,7 @@ const char* message_not_found::name() const throw() { return "message_not_found"
|
||||
|
||||
operation_not_supported::~operation_not_supported() throw() {}
|
||||
operation_not_supported::operation_not_supported(const exception& other)
|
||||
: messaging_exception("Operation not supported.", other) {}
|
||||
: net_exception("Operation not supported.", other) {}
|
||||
|
||||
exception* operation_not_supported::clone() const { return new operation_not_supported(*this); }
|
||||
const char* operation_not_supported::name() const throw() { return "operation_not_supported"; }
|
||||
@ -450,7 +450,7 @@ const char* operation_not_supported::name() const throw() { return "operation_no
|
||||
|
||||
operation_timed_out::~operation_timed_out() throw() {}
|
||||
operation_timed_out::operation_timed_out(const exception& other)
|
||||
: messaging_exception("Operation timed out.", other) {}
|
||||
: net_exception("Operation timed out.", other) {}
|
||||
|
||||
exception* operation_timed_out::clone() const { return new operation_timed_out(*this); }
|
||||
const char* operation_timed_out::name() const throw() { return "operation_timed_out"; }
|
||||
@ -462,7 +462,7 @@ const char* operation_timed_out::name() const throw() { return "operation_timed_
|
||||
|
||||
operation_cancelled::~operation_cancelled() throw() {}
|
||||
operation_cancelled::operation_cancelled(const exception& other)
|
||||
: messaging_exception("Operation cancelled by the user.", other) {}
|
||||
: net_exception("Operation cancelled by the user.", other) {}
|
||||
|
||||
exception* operation_cancelled::clone() const { return new operation_cancelled(*this); }
|
||||
const char* operation_cancelled::name() const throw() { return "operation_cancelled"; }
|
||||
@ -474,7 +474,7 @@ const char* operation_cancelled::name() const throw() { return "operation_cancel
|
||||
|
||||
unfetched_object::~unfetched_object() throw() {}
|
||||
unfetched_object::unfetched_object(const exception& other)
|
||||
: messaging_exception("Object not fetched.", other) {}
|
||||
: net_exception("Object not fetched.", other) {}
|
||||
|
||||
exception* unfetched_object::clone() const { return new unfetched_object(*this); }
|
||||
const char* unfetched_object::name() const throw() { return "unfetched_object"; }
|
||||
@ -486,7 +486,7 @@ const char* unfetched_object::name() const throw() { return "unfetched_object";
|
||||
|
||||
not_connected::~not_connected() throw() {}
|
||||
not_connected::not_connected(const exception& other)
|
||||
: messaging_exception("Not connected to a service.", other) {}
|
||||
: net_exception("Not connected to a service.", other) {}
|
||||
|
||||
exception* not_connected::clone() const { return new not_connected(*this); }
|
||||
const char* not_connected::name() const throw() { return "not_connected"; }
|
||||
@ -498,7 +498,7 @@ const char* not_connected::name() const throw() { return "not_connected"; }
|
||||
|
||||
already_connected::~already_connected() throw() {}
|
||||
already_connected::already_connected(const exception& other)
|
||||
: messaging_exception("Already connected to a service. Disconnect and retry.", other) {}
|
||||
: net_exception("Already connected to a service. Disconnect and retry.", other) {}
|
||||
|
||||
exception* already_connected::clone() const { return new already_connected(*this); }
|
||||
const char* already_connected::name() const throw() { return "already_connected"; }
|
||||
@ -510,7 +510,7 @@ const char* already_connected::name() const throw() { return "already_connected"
|
||||
|
||||
illegal_operation::~illegal_operation() throw() {}
|
||||
illegal_operation::illegal_operation(const string& msg, const exception& other)
|
||||
: messaging_exception(msg.empty()
|
||||
: net_exception(msg.empty()
|
||||
? "Illegal operation."
|
||||
: "Illegal operation: " + msg + ".",
|
||||
other
|
||||
@ -527,7 +527,7 @@ const char* illegal_operation::name() const throw() { return "illegal_operation"
|
||||
command_error::~command_error() throw() {}
|
||||
command_error::command_error(const string& command, const string& response,
|
||||
const string& desc, const exception& other)
|
||||
: messaging_exception(desc.empty()
|
||||
: net_exception(desc.empty()
|
||||
? "Error while executing command '" + command + "'."
|
||||
: "Error while executing command '" + command + "': " + desc + ".",
|
||||
other
|
||||
@ -548,7 +548,7 @@ const char* command_error::name() const throw() { return "command_error"; }
|
||||
|
||||
invalid_response::~invalid_response() throw() {}
|
||||
invalid_response::invalid_response(const string& command, const string& response, const exception& other)
|
||||
: messaging_exception(command.empty()
|
||||
: net_exception(command.empty()
|
||||
? "Received invalid response."
|
||||
: "Received invalid response for command '" + command + "'.",
|
||||
other
|
||||
@ -569,7 +569,7 @@ const char* invalid_response::name() const throw() { return "invalid_response";
|
||||
|
||||
partial_fetch_not_supported::~partial_fetch_not_supported() throw() {}
|
||||
partial_fetch_not_supported::partial_fetch_not_supported(const exception& other)
|
||||
: messaging_exception("Partial fetch not supported.", other) {}
|
||||
: net_exception("Partial fetch not supported.", other) {}
|
||||
|
||||
exception* partial_fetch_not_supported::clone() const { return new partial_fetch_not_supported(*this); }
|
||||
const char* partial_fetch_not_supported::name() const throw() { return "partial_fetch_not_supported"; }
|
||||
@ -581,7 +581,7 @@ const char* partial_fetch_not_supported::name() const throw() { return "partial_
|
||||
|
||||
malformed_url::~malformed_url() throw() {}
|
||||
malformed_url::malformed_url(const string& error, const exception& other)
|
||||
: messaging_exception("Malformed URL: " + error + ".", other) {}
|
||||
: net_exception("Malformed URL: " + error + ".", other) {}
|
||||
|
||||
exception* malformed_url::clone() const { return new malformed_url(*this); }
|
||||
const char* malformed_url::name() const throw() { return "malformed_url"; }
|
||||
@ -593,7 +593,7 @@ const char* malformed_url::name() const throw() { return "malformed_url"; }
|
||||
|
||||
invalid_folder_name::~invalid_folder_name() throw() {}
|
||||
invalid_folder_name::invalid_folder_name(const string& error, const exception& other)
|
||||
: messaging_exception(error.empty()
|
||||
: net_exception(error.empty()
|
||||
? "Invalid folder name: " + error + "."
|
||||
: "Invalid folder name.",
|
||||
other) {}
|
||||
|
105
src/net/authHelper.cpp
Normal file
105
src/net/authHelper.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/authHelper.hpp"
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
#include "vmime/utility/md5.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
//
|
||||
// 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 <const vmime_uint8*>(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();
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
52
src/net/authenticationInfos.cpp
Normal file
52
src/net/authenticationInfos.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/authenticationInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
33
src/net/authenticator.cpp
Normal file
33
src/net/authenticator.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/authenticator.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
authenticator::~authenticator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
56
src/net/builtinServices.inl
Normal file
56
src/net/builtinServices.inl
Normal file
@ -0,0 +1,56 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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::net::service::initializer <vmime::net::p_class> p_name(#p_name)
|
||||
|
||||
|
||||
#if VMIME_BUILTIN_MESSAGING_PROTO_POP3
|
||||
#include "vmime/net/pop3/POP3Store.hpp"
|
||||
REGISTER_SERVICE(pop3::POP3Store, pop3);
|
||||
#endif
|
||||
|
||||
|
||||
#if VMIME_BUILTIN_MESSAGING_PROTO_SMTP
|
||||
#include "vmime/net/smtp/SMTPTransport.hpp"
|
||||
REGISTER_SERVICE(smtp::SMTPTransport, smtp);
|
||||
#endif
|
||||
|
||||
|
||||
#if VMIME_BUILTIN_MESSAGING_PROTO_IMAP
|
||||
#include "vmime/net/imap/IMAPStore.hpp"
|
||||
REGISTER_SERVICE(imap::IMAPStore, imap);
|
||||
#endif
|
||||
|
||||
|
||||
#if VMIME_BUILTIN_MESSAGING_PROTO_MAILDIR
|
||||
#include "vmime/net/maildir/maildirStore.hpp"
|
||||
REGISTER_SERVICE(maildir::maildirStore, maildir);
|
||||
#endif
|
||||
|
||||
#if VMIME_BUILTIN_MESSAGING_PROTO_SENDMAIL
|
||||
#include "vmime/net/sendmail/sendmailTransport.hpp"
|
||||
REGISTER_SERVICE(sendmail::sendmailTransport, sendmail);
|
||||
#endif
|
||||
|
||||
|
||||
#endif // VMIME_BUILDING_DOC
|
43
src/net/defaultAuthenticator.cpp
Normal file
43
src/net/defaultAuthenticator.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/defaultAuthenticator.hpp"
|
||||
#include "vmime/net/session.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
defaultAuthenticator::defaultAuthenticator(weak_ref <session> 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"]));
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
111
src/net/events.cpp
Normal file
111
src/net/events.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/events.hpp"
|
||||
#include "vmime/net/folder.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace events {
|
||||
|
||||
|
||||
//
|
||||
// messageCountEvent
|
||||
//
|
||||
|
||||
messageCountEvent::messageCountEvent
|
||||
(ref <folder> folder, const Types type, const std::vector <int>& nums)
|
||||
: m_folder(folder), m_type(type)
|
||||
{
|
||||
m_nums.resize(nums.size());
|
||||
std::copy(nums.begin(), nums.end(), m_nums.begin());
|
||||
}
|
||||
|
||||
|
||||
ref <const folder> messageCountEvent::getFolder() const { return (m_folder); }
|
||||
const messageCountEvent::Types messageCountEvent::getType() const { return (m_type); }
|
||||
const std::vector <int>& 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> folder, const Types type, const std::vector <int>& nums)
|
||||
: m_folder(folder), m_type(type)
|
||||
{
|
||||
m_nums.resize(nums.size());
|
||||
std::copy(nums.begin(), nums.end(), m_nums.begin());
|
||||
}
|
||||
|
||||
|
||||
ref <const folder> messageChangedEvent::getFolder() const { return (m_folder); }
|
||||
const messageChangedEvent::Types messageChangedEvent::getType() const { return (m_type); }
|
||||
const std::vector <int>& messageChangedEvent::getNumbers() const { return (m_nums); }
|
||||
|
||||
|
||||
void messageChangedEvent::dispatch(messageChangedListener* listener) const
|
||||
{
|
||||
listener->messageChanged(*this);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// folderEvent
|
||||
//
|
||||
|
||||
folderEvent::folderEvent
|
||||
(ref <folder> folder, const Types type,
|
||||
const utility::path& oldPath, const utility::path& newPath)
|
||||
: m_folder(folder), m_type(type), m_oldPath(oldPath), m_newPath(newPath)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ref <const folder> 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
|
||||
} // net
|
||||
} // vmime
|
96
src/net/folder.cpp
Normal file
96
src/net/folder.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/folder.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
void folder::addMessageChangedListener(events::messageChangedListener* l)
|
||||
{
|
||||
m_messageChangedListeners.push_back(l);
|
||||
}
|
||||
|
||||
|
||||
void folder::removeMessageChangedListener(events::messageChangedListener* l)
|
||||
{
|
||||
std::remove(m_messageChangedListeners.begin(), m_messageChangedListeners.end(), l);
|
||||
}
|
||||
|
||||
|
||||
void folder::notifyMessageChanged(const events::messageChangedEvent& event)
|
||||
{
|
||||
for (std::list <events::messageChangedListener*>::iterator
|
||||
it = m_messageChangedListeners.begin() ; it != m_messageChangedListeners.end() ; ++it)
|
||||
{
|
||||
event.dispatch(*it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void folder::addMessageCountListener(events::messageCountListener* l)
|
||||
{
|
||||
m_messageCountListeners.push_back(l);
|
||||
}
|
||||
|
||||
|
||||
void folder::removeMessageCountListener(events::messageCountListener* l)
|
||||
{
|
||||
std::remove(m_messageCountListeners.begin(), m_messageCountListeners.end(), l);
|
||||
}
|
||||
|
||||
|
||||
void folder::notifyMessageCount(const events::messageCountEvent& event)
|
||||
{
|
||||
for (std::list <events::messageCountListener*>::iterator
|
||||
it = m_messageCountListeners.begin() ; it != m_messageCountListeners.end() ; ++it)
|
||||
{
|
||||
event.dispatch(*it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void folder::addFolderListener(events::folderListener* l)
|
||||
{
|
||||
m_folderListeners.push_back(l);
|
||||
}
|
||||
|
||||
|
||||
void folder::removeFolderListener(events::folderListener* l)
|
||||
{
|
||||
std::remove(m_folderListeners.begin(), m_folderListeners.end(), l);
|
||||
}
|
||||
|
||||
|
||||
void folder::notifyFolder(const events::folderEvent& event)
|
||||
{
|
||||
for (std::list <events::folderListener*>::iterator
|
||||
it = m_folderListeners.begin() ; it != m_folderListeners.end() ; ++it)
|
||||
{
|
||||
event.dispatch(*it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
313
src/net/imap/IMAPConnection.cpp
Normal file
313
src/net/imap/IMAPConnection.cpp
Normal file
@ -0,0 +1,313 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/imap/IMAPTag.hpp"
|
||||
#include "vmime/net/imap/IMAPConnection.hpp"
|
||||
#include "vmime/net/imap/IMAPUtils.hpp"
|
||||
#include "vmime/net/imap/IMAPStore.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
#include "vmime/platformDependant.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
// Helpers for service properties
|
||||
#define GET_PROPERTY(type, prop) \
|
||||
(m_store->getInfos().getPropertyValue <type>(getSession(), \
|
||||
dynamic_cast <const IMAPStore::_infos&>(m_store->getInfos()).getProperties().prop))
|
||||
#define HAS_PROPERTY(prop) \
|
||||
(m_store->getInfos().hasProperty(getSession(), \
|
||||
dynamic_cast <const IMAPStore::_infos&>(m_store->getInfos()).getProperties().prop))
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
IMAPConnection::IMAPConnection(weak_ref <IMAPStore> store, ref <authenticator> auth)
|
||||
: m_store(store), m_auth(auth), m_socket(NULL), m_parser(NULL), m_tag(NULL),
|
||||
m_hierarchySeparator('\0'), m_state(STATE_NONE), m_timeoutHandler(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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 <IMAPTag>();
|
||||
m_parser = vmime::create <IMAPParser>(m_tag, m_socket, m_timeoutHandler);
|
||||
|
||||
|
||||
setState(STATE_NON_AUTHENTICATED);
|
||||
|
||||
|
||||
// Connection greeting
|
||||
//
|
||||
// eg: C: <connection to server>
|
||||
// --- S: * OK mydomain.org IMAP4rev1 v12.256 server ready
|
||||
|
||||
utility::auto_ptr <IMAPParser::greeting> 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 <IMAPParser::response> 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 <IMAPParser::response> resp(m_parser->readResponse());
|
||||
|
||||
if (resp->isBad() || resp->response_done()->response_tagged()->
|
||||
resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
|
||||
{
|
||||
internalDisconnect();
|
||||
throw exceptions::command_error("LIST", m_parser->lastLine(), "bad response");
|
||||
}
|
||||
|
||||
const std::vector <IMAPParser::continue_req_or_response_data*>& 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 <const IMAPParser::response_data*>(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 <const IMAPTag> IMAPConnection::getTag() const
|
||||
{
|
||||
return (m_tag);
|
||||
}
|
||||
|
||||
|
||||
ref <const IMAPParser> IMAPConnection::getParser() const
|
||||
{
|
||||
return (m_parser);
|
||||
}
|
||||
|
||||
|
||||
weak_ref <const IMAPStore> IMAPConnection::getStore() const
|
||||
{
|
||||
return (m_store);
|
||||
}
|
||||
|
||||
|
||||
weak_ref <IMAPStore> IMAPConnection::getStore()
|
||||
{
|
||||
return (m_store);
|
||||
}
|
||||
|
||||
|
||||
ref <session> IMAPConnection::getSession()
|
||||
{
|
||||
return (m_store->getSession());
|
||||
}
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
1608
src/net/imap/IMAPFolder.cpp
Normal file
1608
src/net/imap/IMAPFolder.cpp
Normal file
File diff suppressed because it is too large
Load Diff
859
src/net/imap/IMAPMessage.cpp
Normal file
859
src/net/imap/IMAPMessage.cpp
Normal file
@ -0,0 +1,859 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/imap/IMAPParser.hpp"
|
||||
#include "vmime/net/imap/IMAPMessage.hpp"
|
||||
#include "vmime/net/imap/IMAPFolder.hpp"
|
||||
#include "vmime/net/imap/IMAPStore.hpp"
|
||||
#include "vmime/net/imap/IMAPConnection.hpp"
|
||||
#include "vmime/net/imap/IMAPUtils.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
//
|
||||
// IMAPpart
|
||||
//
|
||||
|
||||
class IMAPstructure;
|
||||
|
||||
class IMAPpart : public part
|
||||
{
|
||||
private:
|
||||
|
||||
friend class vmime::creator;
|
||||
|
||||
IMAPpart(weak_ref <IMAPpart> parent, const int number, const IMAPParser::body_type_mpart* mpart);
|
||||
IMAPpart(weak_ref <IMAPpart> parent, const int number, const IMAPParser::body_type_1part* part);
|
||||
|
||||
public:
|
||||
|
||||
const structure& getStructure() const;
|
||||
structure& getStructure();
|
||||
|
||||
weak_ref <const IMAPpart> 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 <IMAPpart> create
|
||||
(weak_ref <IMAPpart> parent, const int number, const IMAPParser::body* body)
|
||||
{
|
||||
if (body->body_type_mpart())
|
||||
return vmime::create <IMAPpart>(parent, number, body->body_type_mpart());
|
||||
else
|
||||
return vmime::create <IMAPpart>(parent, number, body->body_type_1part());
|
||||
}
|
||||
|
||||
|
||||
header& getOrCreateHeader()
|
||||
{
|
||||
if (m_header != NULL)
|
||||
return (*m_header);
|
||||
else
|
||||
return (*(m_header = vmime::create <header>()));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
ref <IMAPstructure> m_structure;
|
||||
weak_ref <IMAPpart> m_parent;
|
||||
ref <header> 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 <IMAPpart> parent, const std::vector <IMAPParser::body*>& list)
|
||||
{
|
||||
int number = 1;
|
||||
|
||||
for (std::vector <IMAPParser::body*>::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 <ref <IMAPpart> > m_parts;
|
||||
};
|
||||
|
||||
|
||||
IMAPstructure IMAPstructure::m_emptyStructure;
|
||||
|
||||
|
||||
|
||||
IMAPpart::IMAPpart(weak_ref <IMAPpart> 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 <IMAPstructure>
|
||||
(thisWeakRef().dynamicCast <IMAPpart>(), mpart->list());
|
||||
}
|
||||
|
||||
|
||||
IMAPpart::IMAPpart(weak_ref <IMAPpart> 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
|
||||
<const IMAPParser::msg_att_item&>(comp).type();
|
||||
|
||||
if (type == IMAPParser::msg_att_item::BODY_SECTION ||
|
||||
type == IMAPParser::msg_att_item::RFC822_TEXT)
|
||||
{
|
||||
return new targetStream(m_progress, m_os);
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
utility::outputStream& m_os;
|
||||
utility::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 <const header> 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 <IMAPpart&>(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 <const IMAPpart> currentPart = static_cast <const IMAPpart*>(p);
|
||||
std::vector <int> numbers;
|
||||
|
||||
numbers.push_back(currentPart->getNumber());
|
||||
currentPart = currentPart->getParent();
|
||||
|
||||
while (currentPart != NULL)
|
||||
{
|
||||
numbers.push_back(currentPart->getNumber());
|
||||
currentPart = currentPart->getParent();
|
||||
}
|
||||
|
||||
numbers.erase(numbers.end() - 1);
|
||||
|
||||
for (std::vector <int>::reverse_iterator it = numbers.rbegin() ; it != numbers.rend() ; ++it)
|
||||
{
|
||||
if (it != numbers.rbegin()) section << ".";
|
||||
section << *it;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 <IMAPParser::response> 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 <string> 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 <string> 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 <string>::iterator it = headerFields.begin() ;
|
||||
it != headerFields.end() ; ++it)
|
||||
{
|
||||
if (it != headerFields.begin())
|
||||
list += " ";
|
||||
|
||||
list += *it;
|
||||
}
|
||||
|
||||
items.push_back("BODY[HEADER.FIELDS (" + list + ")]");
|
||||
}
|
||||
}
|
||||
|
||||
// Build the request text
|
||||
std::ostringstream command;
|
||||
command << "FETCH " << m_num << " (";
|
||||
|
||||
for (std::vector <string>::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 <IMAPParser::response> 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 <IMAPParser::continue_req_or_response_data*>& respDataList =
|
||||
resp->continue_req_or_response_data();
|
||||
|
||||
for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator
|
||||
it = respDataList.begin() ; it != respDataList.end() ; ++it)
|
||||
{
|
||||
if ((*it)->response_data() == NULL)
|
||||
{
|
||||
throw exceptions::command_error("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 <int>(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 <IMAPParser::msg_att_item*> atts =
|
||||
msgAtt->items();
|
||||
|
||||
int flags = 0;
|
||||
|
||||
for (std::vector <IMAPParser::msg_att_item*>::const_iterator
|
||||
it = atts.begin() ; it != atts.end() ; ++it)
|
||||
{
|
||||
switch ((*it)->type())
|
||||
{
|
||||
case IMAPParser::msg_att_item::FLAGS:
|
||||
{
|
||||
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 <vmime::header> hdr = getOrCreateHeader();
|
||||
|
||||
// Date
|
||||
hdr->Date()->setValue(env->env_date()->value());
|
||||
|
||||
// Subject
|
||||
text subject;
|
||||
text::decodeAndUnfold(env->env_subject()->value(), &subject);
|
||||
|
||||
hdr->Subject()->setValue(subject);
|
||||
|
||||
// From
|
||||
mailboxList from;
|
||||
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 <IMAPstructure>((*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 <ref <headerField> > fields = tempHeader.getFieldList();
|
||||
|
||||
for (std::vector <ref <headerField> >::const_iterator jt = fields.begin() ;
|
||||
jt != fields.end() ; ++jt)
|
||||
{
|
||||
hdr.appendField((*jt)->clone().dynamicCast <headerField>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 <header> IMAPMessage::getOrCreateHeader()
|
||||
{
|
||||
if (m_header != NULL)
|
||||
return (m_header);
|
||||
else
|
||||
return (m_header = vmime::create <header>());
|
||||
}
|
||||
|
||||
|
||||
void IMAPMessage::convertAddressList
|
||||
(const IMAPParser::address_list& src, mailboxList& dest)
|
||||
{
|
||||
for (std::vector <IMAPParser::address*>::const_iterator
|
||||
it = src.addresses().begin() ; it != src.addresses().end() ; ++it)
|
||||
{
|
||||
const IMAPParser::address& addr = **it;
|
||||
|
||||
text name;
|
||||
text::decodeAndUnfold(addr.addr_name()->value(), &name);
|
||||
|
||||
string email = addr.addr_mailbox()->value()
|
||||
+ "@" + addr.addr_host()->value();
|
||||
|
||||
dest.appendMailbox(vmime::create <mailbox>(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 <string> 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 <string>(command, " "));
|
||||
}
|
||||
|
||||
command << *(flagList.end() - 1) << ")";
|
||||
|
||||
// Send the request
|
||||
m_folder->m_connection->send(true, command.str(), true);
|
||||
|
||||
// Get the response
|
||||
utility::auto_ptr <IMAPParser::response> 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 <IMAPParser::continue_req_or_response_data*>& respDataList =
|
||||
resp->continue_req_or_response_data();
|
||||
|
||||
int newFlags = 0;
|
||||
|
||||
for (std::vector <IMAPParser::continue_req_or_response_data*>::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 <IMAPParser::msg_att_item*> atts =
|
||||
messageData->msg_att()->items();
|
||||
|
||||
for (std::vector <IMAPParser::msg_att_item*>::const_iterator
|
||||
it = atts.begin() ; it != atts.end() ; ++it)
|
||||
{
|
||||
if ((*it)->type() == IMAPParser::msg_att_item::FLAGS)
|
||||
newFlags |= IMAPUtils::messageFlagsFromFlags((*it)->flag_list());
|
||||
}
|
||||
}
|
||||
|
||||
m_flags = newFlags;
|
||||
}
|
||||
|
||||
// Notify message flags changed
|
||||
std::vector <int> nums;
|
||||
nums.push_back(m_num);
|
||||
|
||||
events::messageChangedEvent event
|
||||
(m_folder->thisRef().dynamicCast <folder>(),
|
||||
events::messageChangedEvent::TYPE_FLAGS, nums);
|
||||
|
||||
for (std::list <IMAPFolder*>::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
|
||||
} // net
|
||||
} // vmime
|
308
src/net/imap/IMAPStore.cpp
Normal file
308
src/net/imap/IMAPStore.cpp
Normal file
@ -0,0 +1,308 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/imap/IMAPStore.hpp"
|
||||
#include "vmime/net/imap/IMAPFolder.hpp"
|
||||
#include "vmime/net/imap/IMAPConnection.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
#include "vmime/platformDependant.hpp"
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
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 <authenticator> auth)
|
||||
: m_auth(auth), m_infos(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
~IMAPauthenticator()
|
||||
{
|
||||
}
|
||||
|
||||
const authenticationInfos requestAuthInfos() const
|
||||
{
|
||||
if (m_infos == NULL)
|
||||
m_infos = vmime::create <authenticationInfos>(m_auth->requestAuthInfos());
|
||||
|
||||
return (*m_infos);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
ref <authenticator> m_auth;
|
||||
mutable ref <authenticationInfos> m_infos;
|
||||
};
|
||||
|
||||
#endif // VMIME_BUILDING_DOC
|
||||
|
||||
|
||||
|
||||
//
|
||||
// IMAPStore
|
||||
//
|
||||
|
||||
IMAPStore::IMAPStore(ref <session> sess, ref <authenticator> auth)
|
||||
: store(sess, getInfosInstance(), auth),
|
||||
m_connection(NULL), m_oneTimeAuth(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
IMAPStore::~IMAPStore()
|
||||
{
|
||||
if (isConnected())
|
||||
disconnect();
|
||||
}
|
||||
|
||||
|
||||
ref <authenticator> IMAPStore::oneTimeAuthenticator()
|
||||
{
|
||||
return (m_oneTimeAuth);
|
||||
}
|
||||
|
||||
|
||||
const string IMAPStore::getProtocolName() const
|
||||
{
|
||||
return "imap";
|
||||
}
|
||||
|
||||
|
||||
ref <folder> IMAPStore::getRootFolder()
|
||||
{
|
||||
if (!isConnected())
|
||||
throw exceptions::illegal_state("Not connected");
|
||||
|
||||
return vmime::create <IMAPFolder>(folder::path(), this);
|
||||
}
|
||||
|
||||
|
||||
ref <folder> IMAPStore::getDefaultFolder()
|
||||
{
|
||||
if (!isConnected())
|
||||
throw exceptions::illegal_state("Not connected");
|
||||
|
||||
return vmime::create <IMAPFolder>(folder::path::component("INBOX"), this);
|
||||
}
|
||||
|
||||
|
||||
ref <folder> IMAPStore::getFolder(const folder::path& path)
|
||||
{
|
||||
if (!isConnected())
|
||||
throw exceptions::illegal_state("Not connected");
|
||||
|
||||
return vmime::create <IMAPFolder>(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 <IMAPauthenticator>(getAuthenticator());
|
||||
|
||||
m_connection = vmime::create <IMAPConnection>
|
||||
(thisWeakRef().dynamicCast <IMAPStore>(), 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 <IMAPFolder*>::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 <IMAPParser::response> resp(m_connection->readResponse());
|
||||
|
||||
if (resp->isBad() || resp->response_done()->response_tagged()->
|
||||
resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)
|
||||
{
|
||||
throw exceptions::command_error("NOOP", m_connection->getParser()->lastLine());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ref <IMAPConnection> IMAPStore::connection()
|
||||
{
|
||||
return (m_connection);
|
||||
}
|
||||
|
||||
|
||||
void IMAPStore::registerFolder(IMAPFolder* folder)
|
||||
{
|
||||
m_folders.push_back(folder);
|
||||
}
|
||||
|
||||
|
||||
void IMAPStore::unregisterFolder(IMAPFolder* folder)
|
||||
{
|
||||
std::list <IMAPFolder*>::iterator it = std::find(m_folders.begin(), m_folders.end(), folder);
|
||||
if (it != m_folders.end()) m_folders.erase(it);
|
||||
}
|
||||
|
||||
|
||||
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 <serviceInfos::property> IMAPStore::_infos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> 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
|
||||
} // net
|
||||
} // vmime
|
99
src/net/imap/IMAPTag.cpp
Normal file
99
src/net/imap/IMAPTag.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/imap/IMAPTag.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
const int IMAPTag::sm_maxNumber = 52 * 10 * 10 * 10;
|
||||
|
||||
|
||||
IMAPTag::IMAPTag(const int number)
|
||||
: m_number(number)
|
||||
{
|
||||
m_tag.resize(4);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
} // net
|
||||
} // vmime
|
555
src/net/imap/IMAPUtils.cpp
Normal file
555
src/net/imap/IMAPUtils.cpp
Normal file
@ -0,0 +1,555 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/imap/IMAPUtils.hpp"
|
||||
#include "vmime/net/message.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
const string IMAPUtils::quoteString(const string& text)
|
||||
{
|
||||
//
|
||||
// ATOM_CHAR ::= <any CHAR except atom_specials>
|
||||
//
|
||||
// atom_specials ::= "(" / ")" / "{" / SPACE / CTL /
|
||||
// list_wildcards / quoted_specials
|
||||
//
|
||||
// list_wildcards ::= "%" / "*"
|
||||
//
|
||||
// quoted_specials ::= <"> / "\"
|
||||
//
|
||||
// CHAR ::= <any 7-bit US-ASCII character except NUL,
|
||||
// 0x01 - 0x7f>
|
||||
//
|
||||
// CTL ::= <any ASCII control character and DEL,
|
||||
// 0x00 - 0x1f, 0x7f>
|
||||
//
|
||||
|
||||
bool needQuoting = text.empty();
|
||||
|
||||
for (string::const_iterator it = text.begin() ;
|
||||
!needQuoting && it != text.end() ; ++it)
|
||||
{
|
||||
const unsigned char c = *it;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '(':
|
||||
case ')':
|
||||
case '{':
|
||||
case 0x20: // SPACE
|
||||
case '%':
|
||||
case '*':
|
||||
case '"':
|
||||
case '\\':
|
||||
|
||||
needQuoting = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if (c <= 0x1f || c >= 0x7f)
|
||||
needQuoting = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needQuoting)
|
||||
{
|
||||
string quoted;
|
||||
quoted.reserve((text.length() * 3) / 2 + 2);
|
||||
|
||||
quoted += '"';
|
||||
|
||||
for (string::const_iterator it = text.begin() ;
|
||||
!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 <unsigned int>(static_cast <unsigned char>(hierarchySeparator));
|
||||
|
||||
string hsUTF7;
|
||||
hsUTF7.resize(3);
|
||||
|
||||
hsUTF7[0] = base64alphabet[0];
|
||||
hsUTF7[1] = base64alphabet[(hs & 0xF0) >> 4];
|
||||
hsUTF7[2] = base64alphabet[(hs & 0x0F) << 2];
|
||||
|
||||
// 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 <IMAPParser::mailbox_flag*>& flags = list->flags();
|
||||
|
||||
for (std::vector <IMAPParser::mailbox_flag*>::const_iterator it = flags.begin() ;
|
||||
it != flags.end() ; ++it)
|
||||
{
|
||||
if ((*it)->type() == IMAPParser::mailbox_flag::NOSELECT)
|
||||
type &= ~folder::TYPE_CONTAINS_MESSAGES;
|
||||
}
|
||||
|
||||
if (type & folder::TYPE_CONTAINS_MESSAGES)
|
||||
type &= ~folder::TYPE_CONTAINS_FOLDERS;
|
||||
|
||||
return (type);
|
||||
}
|
||||
|
||||
|
||||
const int IMAPUtils::folderFlagsFromFlags(const IMAPParser::mailbox_flag_list* list)
|
||||
{
|
||||
// Get folder flags
|
||||
int folderFlags = folder::FLAG_CHILDREN;
|
||||
const std::vector <IMAPParser::mailbox_flag*>& flags = list->flags();
|
||||
|
||||
for (std::vector <IMAPParser::mailbox_flag*>::const_iterator it = flags.begin() ;
|
||||
it != flags.end() ; ++it)
|
||||
{
|
||||
if ((*it)->type() == IMAPParser::mailbox_flag::NOSELECT)
|
||||
folderFlags |= folder::FLAG_NO_OPEN;
|
||||
else if ((*it)->type() == IMAPParser::mailbox_flag::NOINFERIORS)
|
||||
folderFlags &= ~folder::FLAG_CHILDREN;
|
||||
}
|
||||
|
||||
return (folderFlags);
|
||||
}
|
||||
|
||||
|
||||
const int IMAPUtils::messageFlagsFromFlags(const IMAPParser::flag_list* list)
|
||||
{
|
||||
const std::vector <IMAPParser::flag*>& flagList = list->flags();
|
||||
int flags = 0;
|
||||
|
||||
for (std::vector <IMAPParser::flag*>::const_iterator
|
||||
it = flagList.begin() ; it != flagList.end() ; ++it)
|
||||
{
|
||||
switch ((*it)->type())
|
||||
{
|
||||
case IMAPParser::flag::ANSWERED:
|
||||
flags |= message::FLAG_REPLIED;
|
||||
break;
|
||||
case IMAPParser::flag::FLAGGED:
|
||||
flags |= message::FLAG_MARKED;
|
||||
break;
|
||||
case IMAPParser::flag::DELETED:
|
||||
flags |= message::FLAG_DELETED;
|
||||
break;
|
||||
case IMAPParser::flag::SEEN:
|
||||
flags |= message::FLAG_SEEN;
|
||||
break;
|
||||
|
||||
default:
|
||||
//case IMAPParser::flag::UNKNOWN:
|
||||
//case IMAPParser::flag::DRAFT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (flags);
|
||||
}
|
||||
|
||||
|
||||
const string IMAPUtils::messageFlagList(const int flags)
|
||||
{
|
||||
std::vector <string> flagList;
|
||||
|
||||
if (flags & message::FLAG_REPLIED) flagList.push_back("\\Answered");
|
||||
if (flags & message::FLAG_MARKED) flagList.push_back("\\Flagged");
|
||||
if (flags & message::FLAG_DELETED) flagList.push_back("\\Deleted");
|
||||
if (flags & message::FLAG_SEEN) flagList.push_back("\\Seen");
|
||||
|
||||
if (!flagList.empty())
|
||||
{
|
||||
std::ostringstream res;
|
||||
res << "(";
|
||||
|
||||
if (flagList.size() >= 2)
|
||||
{
|
||||
std::copy(flagList.begin(), flagList.end() - 1,
|
||||
std::ostream_iterator <string>(res, " "));
|
||||
}
|
||||
|
||||
res << *(flagList.end() - 1) << ")";
|
||||
|
||||
return (res.str());
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
// 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 <int>& list, const int max,
|
||||
const bool alreadySorted)
|
||||
{
|
||||
// Sort a copy of the list (if not already sorted)
|
||||
std::vector <int> temp;
|
||||
|
||||
if (!alreadySorted)
|
||||
{
|
||||
temp.resize(list.size());
|
||||
std::copy(list.begin(), list.end(), temp.begin());
|
||||
|
||||
std::sort(temp.begin(), temp.end());
|
||||
}
|
||||
|
||||
const std::vector <int>& theList = (alreadySorted ? list : temp);
|
||||
|
||||
// Build the set
|
||||
std::ostringstream res;
|
||||
int previous = -1, setBegin = -1;
|
||||
|
||||
for (std::vector <int>::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
|
||||
} // net
|
||||
} // vmime
|
1387
src/net/maildir/maildirFolder.cpp
Normal file
1387
src/net/maildir/maildirFolder.cpp
Normal file
File diff suppressed because it is too large
Load Diff
505
src/net/maildir/maildirMessage.cpp
Normal file
505
src/net/maildir/maildirMessage.cpp
Normal file
@ -0,0 +1,505 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/maildir/maildirMessage.hpp"
|
||||
#include "vmime/net/maildir/maildirFolder.hpp"
|
||||
#include "vmime/net/maildir/maildirUtils.hpp"
|
||||
#include "vmime/net/maildir/maildirStore.hpp"
|
||||
|
||||
#include "vmime/message.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
#include "vmime/platformDependant.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace maildir {
|
||||
|
||||
|
||||
//
|
||||
// maildirPart
|
||||
//
|
||||
|
||||
class maildirStructure;
|
||||
|
||||
class maildirPart : public part
|
||||
{
|
||||
public:
|
||||
|
||||
maildirPart(weak_ref <maildirPart> parent, const int number, const bodyPart& part);
|
||||
~maildirPart();
|
||||
|
||||
|
||||
const structure& getStructure() const;
|
||||
structure& getStructure();
|
||||
|
||||
weak_ref <const maildirPart> 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 <header>()));
|
||||
}
|
||||
|
||||
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 <maildirStructure> m_structure;
|
||||
weak_ref <maildirPart> m_parent;
|
||||
ref <header> 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 <maildirPart> parent, const bodyPart& part)
|
||||
{
|
||||
m_parts.push_back(vmime::create <maildirPart>(parent, 1, part));
|
||||
}
|
||||
|
||||
maildirStructure(weak_ref <maildirPart> parent, const std::vector <ref <const vmime::bodyPart> >& list)
|
||||
{
|
||||
int number = 1;
|
||||
|
||||
for (unsigned int i = 0 ; i < list.size() ; ++i)
|
||||
m_parts.push_back(vmime::create <maildirPart>(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 <ref <maildirPart> > m_parts;
|
||||
};
|
||||
|
||||
|
||||
maildirStructure maildirStructure::m_emptyStructure;
|
||||
|
||||
|
||||
|
||||
maildirPart::maildirPart(weak_ref <maildirPart> 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 <maildirStructure>
|
||||
(thisWeakRef().dynamicCast <maildirPart>(),
|
||||
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 <maildirFolder> 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 <const header> 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 <const maildirPart&>(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 <utility::file> file = fsf->create(path);
|
||||
|
||||
ref <utility::fileReader> reader = file->getFileReader();
|
||||
ref <utility::inputStream> 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 <maildirPart&>(p);
|
||||
|
||||
utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory();
|
||||
|
||||
const utility::file::path path = m_folder->getMessageFSPath(m_num);
|
||||
ref <utility::file> file = fsf->create(path);
|
||||
|
||||
ref <utility::fileReader> reader = file->getFileReader();
|
||||
ref <utility::inputStream> 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 <maildirFolder> 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 <utility::file> 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 <utility::fileReader> reader = file->getFileReader();
|
||||
ref <utility::inputStream> 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 <maildirStructure>(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 <header> maildirMessage::getOrCreateHeader()
|
||||
{
|
||||
if (m_header != NULL)
|
||||
return (m_header);
|
||||
else
|
||||
return (m_header = vmime::create <header>());
|
||||
}
|
||||
|
||||
|
||||
} // maildir
|
||||
} // net
|
||||
} // vmime
|
250
src/net/maildir/maildirStore.cpp
Normal file
250
src/net/maildir/maildirStore.cpp
Normal file
@ -0,0 +1,250 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/maildir/maildirStore.hpp"
|
||||
|
||||
#include "vmime/net/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 <type>(getSession(), sm_infos.getProperties().prop))
|
||||
#define HAS_PROPERTY(prop) \
|
||||
(sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop))
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace maildir {
|
||||
|
||||
|
||||
maildirStore::maildirStore(ref <session> sess, ref <authenticator> auth)
|
||||
: store(sess, getInfosInstance(), auth), m_connected(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
maildirStore::~maildirStore()
|
||||
{
|
||||
if (isConnected())
|
||||
disconnect();
|
||||
}
|
||||
|
||||
|
||||
const string maildirStore::getProtocolName() const
|
||||
{
|
||||
return "maildir";
|
||||
}
|
||||
|
||||
|
||||
ref <folder> maildirStore::getRootFolder()
|
||||
{
|
||||
if (!isConnected())
|
||||
throw exceptions::illegal_state("Not connected");
|
||||
|
||||
return vmime::create <maildirFolder>(folder::path(),
|
||||
thisWeakRef().dynamicCast <maildirStore>());
|
||||
}
|
||||
|
||||
|
||||
ref <folder> maildirStore::getDefaultFolder()
|
||||
{
|
||||
if (!isConnected())
|
||||
throw exceptions::illegal_state("Not connected");
|
||||
|
||||
return vmime::create <maildirFolder>(folder::path::component("inbox"),
|
||||
thisWeakRef().dynamicCast <maildirStore>());
|
||||
}
|
||||
|
||||
|
||||
ref <folder> maildirStore::getFolder(const folder::path& path)
|
||||
{
|
||||
if (!isConnected())
|
||||
throw exceptions::illegal_state("Not connected");
|
||||
|
||||
return vmime::create <maildirFolder>(path,
|
||||
thisWeakRef().dynamicCast <maildirStore>());
|
||||
}
|
||||
|
||||
|
||||
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 <utility::file> rootDir = fsf->create(m_fsPath);
|
||||
|
||||
// Try to create the root directory if it does not exist
|
||||
if (!(rootDir->exists() && rootDir->isDirectory()))
|
||||
{
|
||||
try
|
||||
{
|
||||
rootDir->createDirectory();
|
||||
}
|
||||
catch (exceptions::filesystem_exception& e)
|
||||
{
|
||||
throw exceptions::connection_error("Cannot create root directory.", e);
|
||||
}
|
||||
}
|
||||
|
||||
m_connected = true;
|
||||
}
|
||||
|
||||
|
||||
const bool maildirStore::isConnected() const
|
||||
{
|
||||
return (m_connected);
|
||||
}
|
||||
|
||||
|
||||
void maildirStore::disconnect()
|
||||
{
|
||||
for (std::list <maildirFolder*>::iterator it = m_folders.begin() ;
|
||||
it != m_folders.end() ; ++it)
|
||||
{
|
||||
(*it)->onStoreDisconnected();
|
||||
}
|
||||
|
||||
m_folders.clear();
|
||||
|
||||
m_connected = false;
|
||||
}
|
||||
|
||||
|
||||
void maildirStore::noop()
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
|
||||
void maildirStore::registerFolder(maildirFolder* folder)
|
||||
{
|
||||
m_folders.push_back(folder);
|
||||
}
|
||||
|
||||
|
||||
void maildirStore::unregisterFolder(maildirFolder* folder)
|
||||
{
|
||||
std::list <maildirFolder*>::iterator it = std::find(m_folders.begin(), m_folders.end(), folder);
|
||||
if (it != m_folders.end()) m_folders.erase(it);
|
||||
}
|
||||
|
||||
|
||||
const utility::path& maildirStore::getFileSystemPath() const
|
||||
{
|
||||
return (m_fsPath);
|
||||
}
|
||||
|
||||
|
||||
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 <serviceInfos::property> maildirStore::_infos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
// Maildir-specific properties
|
||||
list.push_back(p.PROPERTY_SERVER_ROOTPATH);
|
||||
|
||||
return (list);
|
||||
}
|
||||
|
||||
|
||||
} // maildir
|
||||
} // net
|
||||
} // vmime
|
208
src/net/maildir/maildirUtils.cpp
Normal file
208
src/net/maildir/maildirUtils.cpp
Normal file
@ -0,0 +1,208 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/maildir/maildirUtils.hpp"
|
||||
#include "vmime/net/maildir/maildirStore.hpp"
|
||||
|
||||
#include "vmime/utility/random.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
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 <maildirStore> 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
|
||||
} // net
|
||||
} // vmime
|
46
src/net/message.cpp
Normal file
46
src/net/message.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/message.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
826
src/net/pop3/POP3Folder.cpp
Normal file
826
src/net/pop3/POP3Folder.cpp
Normal file
@ -0,0 +1,826 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/pop3/POP3Folder.hpp"
|
||||
|
||||
#include "vmime/net/pop3/POP3Store.hpp"
|
||||
#include "vmime/net/pop3/POP3Message.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
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 <message> 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 <POP3Message>(this, num);
|
||||
}
|
||||
|
||||
|
||||
std::vector <ref <message> > 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 <ref <message> > v;
|
||||
|
||||
for (int i = from ; i <= to2 ; ++i)
|
||||
v.push_back(vmime::create <POP3Message>(this, i));
|
||||
|
||||
return (v);
|
||||
}
|
||||
|
||||
|
||||
std::vector <ref <message> > POP3Folder::getMessages(const std::vector <int>& nums)
|
||||
{
|
||||
if (!m_store)
|
||||
throw exceptions::illegal_state("Store disconnected");
|
||||
else if (!isOpen())
|
||||
throw exceptions::illegal_state("Folder not open");
|
||||
|
||||
std::vector <ref <message> > v;
|
||||
|
||||
for (std::vector <int>::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 <POP3Message>(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 <folder> POP3Folder::getFolder(const folder::path::component& name)
|
||||
{
|
||||
if (!m_store)
|
||||
throw exceptions::illegal_state("Store disconnected");
|
||||
|
||||
return vmime::create <POP3Folder>(m_path / name, m_store);
|
||||
}
|
||||
|
||||
|
||||
std::vector <ref <folder> > POP3Folder::getFolders(const bool /* recursive */)
|
||||
{
|
||||
if (!m_store)
|
||||
throw exceptions::illegal_state("Store disconnected");
|
||||
|
||||
if (m_path.isEmpty())
|
||||
{
|
||||
std::vector <ref <folder> > v;
|
||||
v.push_back(vmime::create <POP3Folder>(folder::path::component("INBOX"), m_store));
|
||||
return (v);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector <ref <folder> > v;
|
||||
return (v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void POP3Folder::fetchMessages(std::vector <ref <message> >& 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 <ref <message> >::iterator it = msg.begin() ;
|
||||
it != msg.end() ; ++it)
|
||||
{
|
||||
(*it).dynamicCast <POP3Message>()->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 <int, string> result;
|
||||
parseMultiListOrUidlResponse(response, result);
|
||||
|
||||
for (std::vector <ref <message> >::iterator it = msg.begin() ;
|
||||
it != msg.end() ; ++it)
|
||||
{
|
||||
ref <POP3Message> m = (*it).dynamicCast <POP3Message>();
|
||||
|
||||
std::map <int, string>::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 <int, string> result;
|
||||
parseMultiListOrUidlResponse(response, result);
|
||||
|
||||
for (std::vector <ref <message> >::iterator it = msg.begin() ;
|
||||
it != msg.end() ; ++it)
|
||||
{
|
||||
ref <POP3Message> m = (*it).dynamicCast <POP3Message>();
|
||||
|
||||
std::map <int, string>::const_iterator x = result.find(m->m_num);
|
||||
|
||||
if (x != result.end())
|
||||
m->m_uid = (*x).second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (progress)
|
||||
progress->stop(total);
|
||||
}
|
||||
|
||||
|
||||
void POP3Folder::fetchMessage(ref <message> 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 <POP3Message>()->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 <POP3Message>()->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 <POP3Message>()->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 <folder> POP3Folder::getParent()
|
||||
{
|
||||
if (m_path.isEmpty())
|
||||
return NULL;
|
||||
else
|
||||
return vmime::create <POP3Folder>(m_path.getParent(), m_store);
|
||||
}
|
||||
|
||||
|
||||
weak_ref <const store> POP3Folder::getStore() const
|
||||
{
|
||||
return (m_store);
|
||||
}
|
||||
|
||||
|
||||
weak_ref <store> 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 <POP3Message*, int>::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 <int> nums;
|
||||
nums.push_back(num);
|
||||
|
||||
events::messageChangedEvent event
|
||||
(thisRef().dynamicCast <folder>(),
|
||||
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 <POP3Message*, int>::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 <int> nums;
|
||||
|
||||
for (int i = from ; i <= to2 ; ++i)
|
||||
nums.push_back(i);
|
||||
|
||||
events::messageChangedEvent event
|
||||
(thisRef().dynamicCast <folder>(),
|
||||
events::messageChangedEvent::TYPE_FLAGS, nums);
|
||||
|
||||
notifyMessageChanged(event);
|
||||
}
|
||||
|
||||
|
||||
void POP3Folder::deleteMessages(const std::vector <int>& 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 <int>::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 <int> list;
|
||||
|
||||
list.resize(nums.size());
|
||||
std::copy(nums.begin(), nums.end(), list.begin());
|
||||
|
||||
std::sort(list.begin(), list.end());
|
||||
|
||||
// Update local flags
|
||||
for (std::map <POP3Message*, int>::iterator it =
|
||||
m_messages.begin() ; it != m_messages.end() ; ++it)
|
||||
{
|
||||
POP3Message* msg = (*it).first;
|
||||
|
||||
if (std::binary_search(list.begin(), list.end(), msg->getNumber()))
|
||||
msg->m_deleted = true;
|
||||
}
|
||||
|
||||
// Notify message flags changed
|
||||
events::messageChangedEvent event
|
||||
(thisRef().dynamicCast <folder>(),
|
||||
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 <int>& /* 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 <vmime::message> /* 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 <int>& /* 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 <int> 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 <folder>(),
|
||||
events::messageCountEvent::TYPE_ADDED, nums);
|
||||
|
||||
notifyMessageCount(event);
|
||||
|
||||
// Notify folders with the same path
|
||||
for (std::list <POP3Folder*>::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 <folder>(),
|
||||
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 <int, string>& result)
|
||||
{
|
||||
std::istringstream iss(response);
|
||||
std::map <int, string> 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 <int, string>::value_type(number, string(it, line.end())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // pop3
|
||||
} // net
|
||||
} // vmime
|
213
src/net/pop3/POP3Message.cpp
Normal file
213
src/net/pop3/POP3Message.cpp
Normal file
@ -0,0 +1,213 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/pop3/POP3Message.hpp"
|
||||
#include "vmime/net/pop3/POP3Folder.hpp"
|
||||
#include "vmime/net/pop3/POP3Store.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
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 <const header> 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 <POP3Folder*>(m_folder)->m_store->sendRequest(oss.str());
|
||||
|
||||
try
|
||||
{
|
||||
POP3Folder::MessageMap::const_iterator it =
|
||||
m_folder->m_messages.find(const_cast <POP3Message*>(this));
|
||||
|
||||
const int totalSize = (it != m_folder->m_messages.end())
|
||||
? (*it).second : 0;
|
||||
|
||||
const_cast <POP3Folder*>(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 <header>();
|
||||
m_header->parse(buffer);
|
||||
}
|
||||
catch (exceptions::command_error& e)
|
||||
{
|
||||
throw exceptions::command_error("TOP", e.response());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void POP3Message::setFlags(const int /* flags */, const int /* mode */)
|
||||
{
|
||||
throw exceptions::operation_not_supported();
|
||||
}
|
||||
|
||||
|
||||
} // pop3
|
||||
} // net
|
||||
} // vmime
|
630
src/net/pop3/POP3Store.cpp
Normal file
630
src/net/pop3/POP3Store.cpp
Normal file
@ -0,0 +1,630 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/pop3/POP3Store.hpp"
|
||||
#include "vmime/net/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 <algorithm>
|
||||
|
||||
|
||||
// Helpers for service properties
|
||||
#define GET_PROPERTY(type, prop) \
|
||||
(sm_infos.getPropertyValue <type>(getSession(), sm_infos.getProperties().prop))
|
||||
#define HAS_PROPERTY(prop) \
|
||||
(sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop))
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace pop3 {
|
||||
|
||||
|
||||
POP3Store::POP3Store(ref <session> sess, ref <authenticator> 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 <folder> POP3Store::getDefaultFolder()
|
||||
{
|
||||
if (!isConnected())
|
||||
throw exceptions::illegal_state("Not connected");
|
||||
|
||||
return vmime::create <POP3Folder>(folder::path(folder::path::component("INBOX")), this);
|
||||
}
|
||||
|
||||
|
||||
ref <folder> POP3Store::getRootFolder()
|
||||
{
|
||||
if (!isConnected())
|
||||
throw exceptions::illegal_state("Not connected");
|
||||
|
||||
return vmime::create <POP3Folder>(folder::path(), this);
|
||||
}
|
||||
|
||||
|
||||
ref <folder> POP3Store::getFolder(const folder::path& path)
|
||||
{
|
||||
if (!isConnected())
|
||||
throw exceptions::illegal_state("Not connected");
|
||||
|
||||
return vmime::create <POP3Folder>(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: <connection to server>
|
||||
// --- 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 <digest>
|
||||
// --- S: +OK vincent is a valid mailbox
|
||||
messageId mid(response);
|
||||
|
||||
if (GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP))
|
||||
{
|
||||
if (mid.getLeft().length() && mid.getRight().length())
|
||||
{
|
||||
// <digest> is the result of MD5 applied to "<message-id>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 <POP3Folder*>::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 <POP3Folder*>::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 <serviceInfos::property> POP3Store::_infos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
// POP3-specific options
|
||||
list.push_back(p.PROPERTY_OPTIONS_APOP);
|
||||
list.push_back(p.PROPERTY_OPTIONS_APOP_FALLBACK);
|
||||
|
||||
// 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
|
||||
} // net
|
||||
} // vmime
|
||||
|
222
src/net/sendmail/sendmailTransport.cpp
Normal file
222
src/net/sendmail/sendmailTransport.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/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 <type>(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 net {
|
||||
namespace sendmail {
|
||||
|
||||
|
||||
sendmailTransport::sendmailTransport(ref <session> sess, ref <authenticator> 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 <string> 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 <string> 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 <utility::childProcess> 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 <serviceInfos::property> sendmailTransport::_infos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> list;
|
||||
const props& p = getProperties();
|
||||
|
||||
list.push_back(p.PROPERTY_BINPATH);
|
||||
|
||||
return (list);
|
||||
}
|
||||
|
||||
|
||||
} // sendmail
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_BUILTIN_PLATFORM_POSIX
|
70
src/net/service.cpp
Normal file
70
src/net/service.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/service.hpp"
|
||||
|
||||
#include "vmime/net/defaultAuthenticator.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
service::service(ref <session> sess, const serviceInfos& infos, ref <authenticator> auth)
|
||||
: m_session(sess), m_auth(auth)
|
||||
{
|
||||
if (!auth)
|
||||
{
|
||||
m_auth = vmime::create <defaultAuthenticator>
|
||||
(sess, infos.getPropertyPrefix());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
service::~service()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ref <const session> service::getSession() const
|
||||
{
|
||||
return (m_session);
|
||||
}
|
||||
|
||||
|
||||
ref <session> service::getSession()
|
||||
{
|
||||
return (m_session);
|
||||
}
|
||||
|
||||
|
||||
ref <const authenticator> service::getAuthenticator() const
|
||||
{
|
||||
return (m_auth);
|
||||
}
|
||||
|
||||
|
||||
ref <authenticator> service::getAuthenticator()
|
||||
{
|
||||
return (m_auth);
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
124
src/net/serviceFactory.cpp
Normal file
124
src/net/serviceFactory.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/serviceFactory.hpp"
|
||||
#include "vmime/net/service.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
#include "src/net/builtinServices.inl"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
serviceFactory::serviceFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
serviceFactory::~serviceFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
serviceFactory* serviceFactory::getInstance()
|
||||
{
|
||||
static serviceFactory instance;
|
||||
return (&instance);
|
||||
}
|
||||
|
||||
|
||||
ref <service> serviceFactory::create
|
||||
(ref <session> sess, const string& protocol, ref <authenticator> auth)
|
||||
{
|
||||
return (getServiceByProtocol(protocol)->create(sess, auth));
|
||||
}
|
||||
|
||||
|
||||
ref <service> serviceFactory::create
|
||||
(ref <session> sess, const utility::url& u, ref <authenticator> auth)
|
||||
{
|
||||
ref <service> serv = create(sess, u.getProtocol(), auth);
|
||||
|
||||
sess->getProperties()[serv->getInfos().getPropertyPrefix() + "server.address"] = u.getHost();
|
||||
|
||||
if (u.getPort() != utility::url::UNSPECIFIED_PORT)
|
||||
sess->getProperties()[serv->getInfos().getPropertyPrefix() + "server.port"] = u.getPort();
|
||||
|
||||
// Path portion of the URL is used to point a specific folder (empty = root).
|
||||
// In maildir, this is used to point to the root of the message repository.
|
||||
if (!u.getPath().empty())
|
||||
sess->getProperties()[serv->getInfos().getPropertyPrefix() + "server.rootpath"] = u.getPath();
|
||||
|
||||
if (!u.getUsername().empty())
|
||||
{
|
||||
sess->getProperties()[serv->getInfos().getPropertyPrefix() + "auth.username"] = u.getUsername();
|
||||
sess->getProperties()[serv->getInfos().getPropertyPrefix() + "auth.password"] = u.getPassword();
|
||||
}
|
||||
|
||||
return (serv);
|
||||
}
|
||||
|
||||
|
||||
ref <const serviceFactory::registeredService> serviceFactory::getServiceByProtocol(const string& protocol) const
|
||||
{
|
||||
const string name(utility::stringUtils::toLower(protocol));
|
||||
|
||||
for (std::vector <ref <registeredService> >::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 <const serviceFactory::registeredService> serviceFactory::getServiceAt(const int pos) const
|
||||
{
|
||||
return (m_services[pos]);
|
||||
}
|
||||
|
||||
|
||||
const std::vector <ref <const serviceFactory::registeredService> > serviceFactory::getServiceList() const
|
||||
{
|
||||
std::vector <ref <const registeredService> > res;
|
||||
|
||||
for (std::vector <ref <registeredService> >::const_iterator it = m_services.begin() ;
|
||||
it != m_services.end() ; ++it)
|
||||
{
|
||||
res.push_back(*it);
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
150
src/net/serviceInfos.cpp
Normal file
150
src/net/serviceInfos.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/serviceInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
// Common properties
|
||||
const serviceInfos::property serviceInfos::property::SERVER_ADDRESS
|
||||
("server.address", serviceInfos::property::TYPE_STRING);
|
||||
|
||||
const serviceInfos::property serviceInfos::property::SERVER_PORT
|
||||
("server.port", serviceInfos::property::TYPE_INTEGER);
|
||||
|
||||
const serviceInfos::property serviceInfos::property::SERVER_ROOTPATH
|
||||
("server.rootpath", serviceInfos::property::TYPE_STRING);
|
||||
|
||||
const serviceInfos::property serviceInfos::property::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 <session> s, const property& p) const
|
||||
{
|
||||
return s->getProperties().hasProperty(getPropertyPrefix() + p.getName());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// serviceInfos::property
|
||||
|
||||
serviceInfos::property::property
|
||||
(const string& name, const Types type,
|
||||
const string& defaultValue, const int flags)
|
||||
: m_name(name), m_defaultValue(defaultValue),
|
||||
m_type(type), m_flags(flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
serviceInfos::property::property
|
||||
(const property& p, const int addFlags, const int removeFlags)
|
||||
{
|
||||
m_name = p.m_name;
|
||||
m_type = p.m_type;
|
||||
m_defaultValue = p.m_defaultValue;
|
||||
m_flags = (p.m_flags | addFlags) & ~removeFlags;
|
||||
}
|
||||
|
||||
|
||||
serviceInfos::property::property
|
||||
(const property& p, const string& newDefaultValue,
|
||||
const int addFlags, const int removeFlags)
|
||||
{
|
||||
m_name = p.m_name;
|
||||
m_type = p.m_type;
|
||||
m_defaultValue = newDefaultValue;
|
||||
m_flags = (p.m_flags | addFlags) & ~removeFlags;
|
||||
}
|
||||
|
||||
|
||||
serviceInfos::property& serviceInfos::property::operator=(const property& p)
|
||||
{
|
||||
m_name = p.m_name;
|
||||
m_type = p.m_type;
|
||||
m_defaultValue = p.m_defaultValue;
|
||||
m_flags = p.m_flags;
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
const string& serviceInfos::property::getName() const
|
||||
{
|
||||
return (m_name);
|
||||
}
|
||||
|
||||
|
||||
const string& serviceInfos::property::getDefaultValue() const
|
||||
{
|
||||
return (m_defaultValue);
|
||||
}
|
||||
|
||||
|
||||
const serviceInfos::property::Types serviceInfos::property::getType() const
|
||||
{
|
||||
return (m_type);
|
||||
}
|
||||
|
||||
|
||||
const int serviceInfos::property::getFlags() const
|
||||
{
|
||||
return (m_flags);
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
126
src/net/session.cpp
Normal file
126
src/net/session.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/session.hpp"
|
||||
#include "vmime/net/serviceFactory.hpp"
|
||||
|
||||
#include "vmime/net/store.hpp"
|
||||
#include "vmime/net/transport.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
session::session()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
session::session(const session& sess)
|
||||
: object(), m_props(sess.m_props)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
session::session(const propertySet& props)
|
||||
: m_props(props)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
session::~session()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ref <transport> session::getTransport(ref <authenticator> auth)
|
||||
{
|
||||
return (getTransport(m_props["transport.protocol"], auth));
|
||||
}
|
||||
|
||||
|
||||
ref <transport> session::getTransport(const string& protocol, ref <authenticator> auth)
|
||||
{
|
||||
ref <session> sess = thisRef().dynamicCast <session>();
|
||||
ref <service> sv = serviceFactory::getInstance()->create(sess, protocol, auth);
|
||||
|
||||
if (sv->getType() != service::TYPE_TRANSPORT)
|
||||
throw exceptions::no_service_available();
|
||||
|
||||
return sv.staticCast <transport>();
|
||||
}
|
||||
|
||||
|
||||
ref <transport> session::getTransport(const utility::url& url, ref <authenticator> auth)
|
||||
{
|
||||
ref <session> sess = thisRef().dynamicCast <session>();
|
||||
ref <service> sv = serviceFactory::getInstance()->create(sess, url, auth);
|
||||
|
||||
if (sv->getType() != service::TYPE_TRANSPORT)
|
||||
throw exceptions::no_service_available();
|
||||
|
||||
return sv.staticCast <transport>();
|
||||
}
|
||||
|
||||
|
||||
ref <store> session::getStore(ref <authenticator> auth)
|
||||
{
|
||||
return (getStore(m_props["store.protocol"], auth));
|
||||
}
|
||||
|
||||
|
||||
ref <store> session::getStore(const string& protocol, ref <authenticator> auth)
|
||||
{
|
||||
ref <session> sess = thisRef().dynamicCast <session>();
|
||||
ref <service> sv = serviceFactory::getInstance()->create(sess, protocol, auth);
|
||||
|
||||
if (sv->getType() != service::TYPE_STORE)
|
||||
throw exceptions::no_service_available();
|
||||
|
||||
return sv.staticCast <store>();
|
||||
}
|
||||
|
||||
|
||||
ref <store> session::getStore(const utility::url& url, ref <authenticator> auth)
|
||||
{
|
||||
ref <session> sess = thisRef().dynamicCast <session>();
|
||||
ref <service> sv = serviceFactory::getInstance()->create(sess, url, auth);
|
||||
|
||||
if (sv->getType() != service::TYPE_STORE)
|
||||
throw exceptions::no_service_available();
|
||||
|
||||
return sv.staticCast <store>();
|
||||
}
|
||||
|
||||
|
||||
const propertySet& session::getProperties() const
|
||||
{
|
||||
return (m_props);
|
||||
}
|
||||
|
||||
|
||||
propertySet& session::getProperties()
|
||||
{
|
||||
return (m_props);
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
69
src/net/simpleAuthenticator.cpp
Normal file
69
src/net/simpleAuthenticator.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/simpleAuthenticator.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
503
src/net/smtp/SMTPTransport.cpp
Normal file
503
src/net/smtp/SMTPTransport.cpp
Normal file
@ -0,0 +1,503 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/smtp/SMTPTransport.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
#include "vmime/platformDependant.hpp"
|
||||
#include "vmime/encoderB64.hpp"
|
||||
#include "vmime/mailboxList.hpp"
|
||||
|
||||
#include "vmime/net/authHelper.hpp"
|
||||
|
||||
#include "vmime/utility/filteredStream.hpp"
|
||||
|
||||
|
||||
// Helpers for service properties
|
||||
#define GET_PROPERTY(type, prop) \
|
||||
(sm_infos.getPropertyValue <type>(getSession(), sm_infos.getProperties().prop))
|
||||
#define HAS_PROPERTY(prop) \
|
||||
(sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop))
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace smtp {
|
||||
|
||||
|
||||
SMTPTransport::SMTPTransport(ref <session> sess, ref <authenticator> 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: <connection to server>
|
||||
// --- 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 <serviceInfos::property> SMTPTransport::_infos::getAvailableProperties() const
|
||||
{
|
||||
std::vector <property> 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
|
||||
} // net
|
||||
} // vmime
|
116
src/net/transport.cpp
Normal file
116
src/net/transport.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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/net/transport.hpp"
|
||||
|
||||
#include "vmime/utility/stream.hpp"
|
||||
#include "vmime/mailboxList.hpp"
|
||||
#include "vmime/message.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
transport::transport(ref <session> sess, const serviceInfos& infos, ref <authenticator> auth)
|
||||
: service(sess, infos, auth)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void extractMailboxes
|
||||
(mailboxList& recipients, const addressList& list)
|
||||
{
|
||||
for (int i = 0 ; i < list.getAddressCount() ; ++i)
|
||||
{
|
||||
ref <mailbox> mbox = list.getAddressAt(i)->clone().dynamicCast <mailbox>();
|
||||
|
||||
if (mbox != NULL)
|
||||
recipients.appendMailbox(mbox);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void transport::send(ref <vmime::message> msg, utility::progressionListener* progress)
|
||||
{
|
||||
// Extract expeditor
|
||||
mailbox expeditor;
|
||||
|
||||
try
|
||||
{
|
||||
const mailboxField& from = dynamic_cast <const mailboxField&>
|
||||
(*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 <const addressListField&>
|
||||
(*msg->getHeader()->findField(fields::TO));
|
||||
extractMailboxes(recipients, to.getValue());
|
||||
}
|
||||
catch (exceptions::no_such_field&) { }
|
||||
|
||||
try
|
||||
{
|
||||
const addressListField& cc = dynamic_cast <const addressListField&>
|
||||
(*msg->getHeader()->findField(fields::CC));
|
||||
extractMailboxes(recipients, cc.getValue());
|
||||
}
|
||||
catch (exceptions::no_such_field&) { }
|
||||
|
||||
try
|
||||
{
|
||||
const addressListField& bcc = dynamic_cast <const addressListField&>
|
||||
(*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);
|
||||
}
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
@ -166,14 +166,14 @@ const unsigned int posixHandler::getProcessId() const
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
|
||||
vmime::messaging::socketFactory* posixHandler::getSocketFactory
|
||||
vmime::net::socketFactory* posixHandler::getSocketFactory
|
||||
(const vmime::string& /* name */) const
|
||||
{
|
||||
return (m_socketFactory);
|
||||
}
|
||||
|
||||
|
||||
vmime::messaging::timeoutHandlerFactory* posixHandler::getTimeoutHandlerFactory
|
||||
vmime::net::timeoutHandlerFactory* posixHandler::getTimeoutHandlerFactory
|
||||
(const vmime::string& /* name */) const
|
||||
{
|
||||
// Not used by default
|
||||
|
@ -172,7 +172,7 @@ void posixSocket::sendRaw(const char* buffer, const int count)
|
||||
// posixSocketFactory
|
||||
//
|
||||
|
||||
ref <vmime::messaging::socket> posixSocketFactory::create()
|
||||
ref <vmime::net::socket> posixSocketFactory::create()
|
||||
{
|
||||
return vmime::create <posixSocket>();
|
||||
}
|
||||
|
@ -233,14 +233,14 @@ const unsigned int windowsHandler::getProcessId() const
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
|
||||
vmime::messaging::socketFactory* windowsHandler::getSocketFactory
|
||||
vmime::net::socketFactory* windowsHandler::getSocketFactory
|
||||
(const vmime::string& /* name */) const
|
||||
{
|
||||
return (m_socketFactory);
|
||||
}
|
||||
|
||||
|
||||
vmime::messaging::timeoutHandlerFactory* windowsHandler::getTimeoutHandlerFactory
|
||||
vmime::net::timeoutHandlerFactory* windowsHandler::getTimeoutHandlerFactory
|
||||
(const vmime::string& /* name */) const
|
||||
{
|
||||
// Not used by default
|
||||
|
@ -167,7 +167,7 @@ void windowsSocket::sendRaw(const char* buffer, const int count)
|
||||
// posixSocketFactory
|
||||
//
|
||||
|
||||
ref <vmime::messaging::socket> windowsSocketFactory::create()
|
||||
ref <vmime::net::socket> windowsSocketFactory::create()
|
||||
{
|
||||
return vmime::create <windowsSocket>();
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <iterator> // for std::back_inserter
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
#include "vmime/messaging/socket.hpp"
|
||||
#include "vmime/net/socket.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
@ -331,7 +331,7 @@ const stream::size_type inputStreamPointerAdapter::skip(const size_type count)
|
||||
|
||||
// outputStreamSocketAdapter
|
||||
|
||||
outputStreamSocketAdapter::outputStreamSocketAdapter(messaging::socket& sok)
|
||||
outputStreamSocketAdapter::outputStreamSocketAdapter(net::socket& sok)
|
||||
: m_socket(sok)
|
||||
{
|
||||
}
|
||||
@ -346,7 +346,7 @@ void outputStreamSocketAdapter::write
|
||||
|
||||
// inputStreamSocketAdapter
|
||||
|
||||
inputStreamSocketAdapter::inputStreamSocketAdapter(messaging::socket& sok)
|
||||
inputStreamSocketAdapter::inputStreamSocketAdapter(net::socket& sok)
|
||||
: m_socket(sok)
|
||||
{
|
||||
}
|
||||
|
@ -338,26 +338,32 @@ public:
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
|
||||
|
||||
/** Base class for exceptions thrown by the messaging module.
|
||||
/** Base class for exceptions thrown by the networking module.
|
||||
*/
|
||||
|
||||
class messaging_exception : public vmime::exception
|
||||
class net_exception : public vmime::exception
|
||||
{
|
||||
public:
|
||||
|
||||
messaging_exception(const string& what, const exception& other = NO_EXCEPTION);
|
||||
~messaging_exception() throw();
|
||||
net_exception(const string& what, const exception& other = NO_EXCEPTION);
|
||||
~net_exception() throw();
|
||||
|
||||
exception* clone() const;
|
||||
const char* name() const throw();
|
||||
};
|
||||
|
||||
|
||||
/** Alias for 'net_exception' (compatibility with version <= 0.7.1);
|
||||
* this is deprecated.
|
||||
*/
|
||||
typedef net_exception messaging_exception;
|
||||
|
||||
|
||||
/** Error while connecting to the server: this may be a DNS resolution error
|
||||
* or a connection error (for example, time-out while connecting).
|
||||
*/
|
||||
|
||||
class connection_error : public messaging_exception
|
||||
class connection_error : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -372,7 +378,7 @@ public:
|
||||
/** Server did not initiated the connection correctly.
|
||||
*/
|
||||
|
||||
class connection_greeting_error : public messaging_exception
|
||||
class connection_greeting_error : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -394,7 +400,7 @@ private:
|
||||
* or password, or wrong authentication method).
|
||||
*/
|
||||
|
||||
class authentication_error : public messaging_exception
|
||||
class authentication_error : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -415,7 +421,7 @@ private:
|
||||
/** Option not supported.
|
||||
*/
|
||||
|
||||
class unsupported_option : public messaging_exception
|
||||
class unsupported_option : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -430,7 +436,7 @@ public:
|
||||
/** No service available for this protocol.
|
||||
*/
|
||||
|
||||
class no_service_available : public messaging_exception
|
||||
class no_service_available : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -446,7 +452,7 @@ public:
|
||||
* operation (for example, you try to close a folder which is not open).
|
||||
*/
|
||||
|
||||
class illegal_state : public messaging_exception
|
||||
class illegal_state : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -461,7 +467,7 @@ public:
|
||||
/** Folder not found (does not exist).
|
||||
*/
|
||||
|
||||
class folder_not_found : public messaging_exception
|
||||
class folder_not_found : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -476,7 +482,7 @@ public:
|
||||
/** Message not found (does not exist).
|
||||
*/
|
||||
|
||||
class message_not_found : public messaging_exception
|
||||
class message_not_found : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -491,7 +497,7 @@ public:
|
||||
/** Operation not supported by the underlying protocol.
|
||||
*/
|
||||
|
||||
class operation_not_supported : public messaging_exception
|
||||
class operation_not_supported : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -506,7 +512,7 @@ public:
|
||||
/** The operation timed out (time-out delay is elapsed).
|
||||
*/
|
||||
|
||||
class operation_timed_out : public messaging_exception
|
||||
class operation_timed_out : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -521,7 +527,7 @@ public:
|
||||
/** The operation has been cancelled.
|
||||
*/
|
||||
|
||||
class operation_cancelled : public messaging_exception
|
||||
class operation_cancelled : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -537,7 +543,7 @@ public:
|
||||
* the requested object.
|
||||
*/
|
||||
|
||||
class unfetched_object : public messaging_exception
|
||||
class unfetched_object : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -552,7 +558,7 @@ public:
|
||||
/** The service is not currently connected.
|
||||
*/
|
||||
|
||||
class not_connected : public messaging_exception
|
||||
class not_connected : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -567,7 +573,7 @@ public:
|
||||
/** The service is already connected (must disconnect before).
|
||||
*/
|
||||
|
||||
class already_connected : public messaging_exception
|
||||
class already_connected : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -582,7 +588,7 @@ public:
|
||||
/** Illegal operation: cannot run this operation on the object.
|
||||
*/
|
||||
|
||||
class illegal_operation : public messaging_exception
|
||||
class illegal_operation : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -597,7 +603,7 @@ public:
|
||||
/** Command error: operation failed (this is specific to the underlying protocol).
|
||||
*/
|
||||
|
||||
class command_error : public messaging_exception
|
||||
class command_error : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -631,7 +637,7 @@ private:
|
||||
/** The server returned an invalid response.
|
||||
*/
|
||||
|
||||
class invalid_response : public messaging_exception
|
||||
class invalid_response : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -665,7 +671,7 @@ private:
|
||||
/** Partial fetch is not supported by the underlying protocol.
|
||||
*/
|
||||
|
||||
class partial_fetch_not_supported : public messaging_exception
|
||||
class partial_fetch_not_supported : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -680,7 +686,7 @@ public:
|
||||
/** The URL is malformed.
|
||||
*/
|
||||
|
||||
class malformed_url : public messaging_exception
|
||||
class malformed_url : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
@ -695,7 +701,7 @@ public:
|
||||
/** Folder name is invalid.
|
||||
*/
|
||||
|
||||
class invalid_folder_name : public messaging_exception
|
||||
class invalid_folder_name : public net_exception
|
||||
{
|
||||
public:
|
||||
|
||||
|
38
vmime/net/authHelper.hpp
Normal file
38
vmime/net/authHelper.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_AUTHHELPER_HPP_INCLUDED
|
||||
#define VMIME_NET_AUTHHELPER_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
void hmac_md5(const string& text, const string& key, string& hexDigest);
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_AUTHHELPER_HPP_INCLUDED
|
64
vmime/net/authenticationInfos.hpp
Normal file
64
vmime/net/authenticationInfos.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_AUTHENTICATIONINFOS_HPP_INCLUDED
|
||||
#define VMIME_NET_AUTHENTICATIONINFOS_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
/** 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;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_AUTHENTICATIONINFOS_HPP_INCLUDED
|
54
vmime/net/authenticator.hpp
Normal file
54
vmime/net/authenticator.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_AUTHENTICATOR_HPP_INCLUDED
|
||||
#define VMIME_NET_AUTHENTICATOR_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
#include "vmime/net/authenticationInfos.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
/** 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;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_AUTHENTICATOR_HPP_INCLUDED
|
60
vmime/net/defaultAuthenticator.hpp
Normal file
60
vmime/net/defaultAuthenticator.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_DEFAULTAUTHENTICATOR_HPP_INCLUDED
|
||||
#define VMIME_NET_DEFAULTAUTHENTICATOR_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/net/authenticator.hpp"
|
||||
#include "vmime/propertySet.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
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> session, const string& prefix);
|
||||
|
||||
private:
|
||||
|
||||
weak_ref <session> m_session;
|
||||
const string m_prefix;
|
||||
|
||||
const authenticationInfos requestAuthInfos() const;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_DEFAULTAUTHENTICATOR_HPP_INCLUDED
|
229
vmime/net/events.hpp
Normal file
229
vmime/net/events.hpp
Normal file
@ -0,0 +1,229 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_EVENTS_HPP_INCLUDED
|
||||
#define VMIME_NET_EVENTS_HPP_INCLUDED
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "vmime/utility/path.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
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> folder, const Types type, const std::vector <int>& nums);
|
||||
|
||||
/** Return the folder in which messages have been added/removed.
|
||||
*
|
||||
* @return folder in which message count changed
|
||||
*/
|
||||
ref <const folder> 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 <int>& getNumbers() const;
|
||||
|
||||
/** Dispatch the event to the specified listener.
|
||||
*
|
||||
* @param listener listener to notify
|
||||
*/
|
||||
void dispatch(class messageCountListener* listener) const;
|
||||
|
||||
private:
|
||||
|
||||
ref <folder> m_folder;
|
||||
const Types m_type;
|
||||
std::vector <int> 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> folder, const Types type, const std::vector <int>& nums);
|
||||
|
||||
/** Return the folder in which messages have changed.
|
||||
*
|
||||
* @return folder in which message count changed
|
||||
*/
|
||||
ref <const folder> 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 <int>& getNumbers() const;
|
||||
|
||||
/** Dispatch the event to the specified listener.
|
||||
*
|
||||
* @param listener listener to notify
|
||||
*/
|
||||
void dispatch(class messageChangedListener* listener) const;
|
||||
|
||||
private:
|
||||
|
||||
ref <folder> m_folder;
|
||||
const Types m_type;
|
||||
std::vector <int> 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> 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 <const folder> 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 <folder> 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
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_EVENTS_HPP_INCLUDED
|
379
vmime/net/folder.hpp
Normal file
379
vmime/net/folder.hpp
Normal file
@ -0,0 +1,379 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_FOLDER_HPP_INCLUDED
|
||||
#define VMIME_NET_FOLDER_HPP_INCLUDED
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
#include "vmime/dateTime.hpp"
|
||||
|
||||
#include "vmime/message.hpp"
|
||||
#include "vmime/net/message.hpp"
|
||||
#include "vmime/net/events.hpp"
|
||||
|
||||
#include "vmime/utility/path.hpp"
|
||||
#include "vmime/utility/stream.hpp"
|
||||
#include "vmime/utility/progressionListener.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
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 <message> 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 <ref <message> > 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 <ref <message> > getMessages(const std::vector <int>& 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 <folder> 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 <ref <folder> > 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 <int>& 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 <int>& 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 <vmime::message> 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 <int>& 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 <folder> 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 <const store> 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 <store> 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 <ref <message> >& 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 <message> 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 <events::messageChangedListener*> m_messageChangedListeners;
|
||||
std::list <events::messageCountListener*> m_messageCountListeners;
|
||||
std::list <events::folderListener*> m_folderListeners;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_FOLDER_HPP_INCLUDED
|
116
vmime/net/imap/IMAPConnection.hpp
Normal file
116
vmime/net/imap/IMAPConnection.hpp
Normal file
@ -0,0 +1,116 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_IMAP_IMAPCONNECTION_HPP_INCLUDED
|
||||
#define VMIME_NET_IMAP_IMAPCONNECTION_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
#include "vmime/net/authenticator.hpp"
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/timeoutHandler.hpp"
|
||||
#include "vmime/net/session.hpp"
|
||||
|
||||
#include "vmime/net/imap/IMAPParser.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
class IMAPTag;
|
||||
class IMAPStore;
|
||||
|
||||
|
||||
class IMAPConnection : public object
|
||||
{
|
||||
public:
|
||||
|
||||
IMAPConnection(weak_ref <IMAPStore> store, ref <authenticator> 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 <const IMAPTag> getTag() const;
|
||||
ref <const IMAPParser> getParser() const;
|
||||
|
||||
weak_ref <const IMAPStore> getStore() const;
|
||||
weak_ref <IMAPStore> getStore();
|
||||
|
||||
ref <session> getSession();
|
||||
|
||||
private:
|
||||
|
||||
weak_ref <IMAPStore> m_store;
|
||||
|
||||
ref <authenticator> m_auth;
|
||||
|
||||
ref <socket> m_socket;
|
||||
|
||||
ref <IMAPParser> m_parser;
|
||||
|
||||
ref <IMAPTag> m_tag;
|
||||
|
||||
char m_hierarchySeparator;
|
||||
|
||||
ProtocolStates m_state;
|
||||
|
||||
ref <timeoutHandler> m_timeoutHandler;
|
||||
|
||||
|
||||
void internalDisconnect();
|
||||
|
||||
void initHierarchySeparator();
|
||||
};
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_IMAP_IMAPCONNECTION_HPP_INCLUDED
|
158
vmime/net/imap/IMAPFolder.hpp
Normal file
158
vmime/net/imap/IMAPFolder.hpp
Normal file
@ -0,0 +1,158 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_IMAP_IMAPFOLDER_HPP_INCLUDED
|
||||
#define VMIME_NET_IMAP_IMAPFOLDER_HPP_INCLUDED
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
#include "vmime/net/folder.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
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>
|
||||
|
||||
|
||||
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 <message> getMessage(const int num);
|
||||
std::vector <ref <message> > getMessages(const int from = 1, const int to = -1);
|
||||
std::vector <ref <message> > getMessages(const std::vector <int>& nums);
|
||||
const int getMessageCount();
|
||||
|
||||
ref <folder> getFolder(const folder::path::component& name);
|
||||
std::vector <ref <folder> > 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 <int>& nums);
|
||||
|
||||
void setMessageFlags(const int from, const int to, const int flags, const int mode = message::FLAG_MODE_SET);
|
||||
void setMessageFlags(const std::vector <int>& nums, const int flags, const int mode = message::FLAG_MODE_SET);
|
||||
|
||||
void addMessage(ref <vmime::message> 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 <int>& nums);
|
||||
|
||||
void status(int& count, int& unseen);
|
||||
|
||||
void expunge();
|
||||
|
||||
ref <folder> getParent();
|
||||
|
||||
weak_ref <const store> getStore() const;
|
||||
weak_ref <store> getStore();
|
||||
|
||||
|
||||
void fetchMessages(std::vector <ref <message> >& msg, const int options, utility::progressionListener* progress = NULL);
|
||||
void fetchMessage(ref <message> 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 <IMAPConnection> 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 <IMAPMessage*> m_messages;
|
||||
};
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_IMAP_IMAPFOLDER_HPP_INCLUDED
|
111
vmime/net/imap/IMAPMessage.hpp
Normal file
111
vmime/net/imap/IMAPMessage.hpp
Normal file
@ -0,0 +1,111 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_IMAP_IMAPMESSAGE_HPP_INCLUDED
|
||||
#define VMIME_NET_IMAP_IMAPMESSAGE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/net/message.hpp"
|
||||
#include "vmime/net/folder.hpp"
|
||||
|
||||
#include "vmime/mailboxList.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace imap {
|
||||
|
||||
|
||||
class IMAPFolder;
|
||||
|
||||
|
||||
/** IMAP message implementation.
|
||||
*/
|
||||
|
||||
class IMAPMessage : public message
|
||||
{
|
||||
private:
|
||||
|
||||
friend class IMAPFolder;
|
||||
friend class vmime::creator; // vmime::create <IMAPMessage>
|
||||
|
||||
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 <const header> 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 <header> getOrCreateHeader();
|
||||
|
||||
|
||||
void onFolderClosed();
|
||||
|
||||
IMAPFolder* m_folder;
|
||||
|
||||
int m_num;
|
||||
int m_size;
|
||||
int m_flags;
|
||||
bool m_expunged;
|
||||
uid m_uid;
|
||||
|
||||
ref <header> m_header;
|
||||
ref <structure> m_structure;
|
||||
};
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_IMAP_IMAPMESSAGE_HPP_INCLUDED
|
5082
vmime/net/imap/IMAPParser.hpp
Normal file
5082
vmime/net/imap/IMAPParser.hpp
Normal file
File diff suppressed because it is too large
Load Diff
137
vmime/net/imap/IMAPStore.hpp
Normal file
137
vmime/net/imap/IMAPStore.hpp
Normal file
@ -0,0 +1,137 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_IMAP_IMAPSTORE_HPP_INCLUDED
|
||||
#define VMIME_NET_IMAP_IMAPSTORE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
#include "vmime/net/store.hpp"
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/folder.hpp"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
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 <session> sess, ref <authenticator> auth);
|
||||
~IMAPStore();
|
||||
|
||||
const string getProtocolName() const;
|
||||
|
||||
ref <folder> getDefaultFolder();
|
||||
ref <folder> getRootFolder();
|
||||
ref <folder> 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 <IMAPConnection> m_connection;
|
||||
|
||||
// Used to request the authentication informations only the
|
||||
// first time, and reuse these informations the next time.
|
||||
ref <class authenticator> m_oneTimeAuth;
|
||||
|
||||
|
||||
|
||||
ref <class authenticator> oneTimeAuthenticator();
|
||||
|
||||
|
||||
ref <IMAPConnection> connection();
|
||||
|
||||
|
||||
void registerFolder(IMAPFolder* folder);
|
||||
void unregisterFolder(IMAPFolder* folder);
|
||||
|
||||
std::list <IMAPFolder*> 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 <serviceInfos::property> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
static _infos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_IMAP_IMAPSTORE_HPP_INCLUDED
|
66
vmime/net/imap/IMAPTag.hpp
Normal file
66
vmime/net/imap/IMAPTag.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_IMAP_IMAPTAG_HPP_INCLUDED
|
||||
#define VMIME_NET_IMAP_IMAPTAG_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
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
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_IMAP_IMAPTAG_HPP_INCLUDED
|
68
vmime/net/imap/IMAPUtils.hpp
Normal file
68
vmime/net/imap/IMAPUtils.hpp
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_IMAP_IMAPUTILS_HPP_INCLUDED
|
||||
#define VMIME_NET_IMAP_IMAPUTILS_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
#include "vmime/dateTime.hpp"
|
||||
|
||||
#include "vmime/net/folder.hpp"
|
||||
#include "vmime/net/imap/IMAPParser.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
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 <int>& list, const int max = -1, const bool alreadySorted = false);
|
||||
|
||||
static const string dateTime(const vmime::datetime& date);
|
||||
};
|
||||
|
||||
|
||||
} // imap
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_IMAP_IMAPUTILS_HPP_INCLUDED
|
178
vmime/net/maildir/maildirFolder.hpp
Normal file
178
vmime/net/maildir/maildirFolder.hpp
Normal file
@ -0,0 +1,178 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_MAILDIR_MAILDIRFOLDER_HPP_INCLUDED
|
||||
#define VMIME_NET_MAILDIR_MAILDIRFOLDER_HPP_INCLUDED
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
#include "vmime/net/folder.hpp"
|
||||
|
||||
#include "vmime/utility/file.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
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>
|
||||
|
||||
|
||||
maildirFolder(const folder::path& path, weak_ref <maildirStore> 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 <message> getMessage(const int num);
|
||||
std::vector <ref <message> > getMessages(const int from = 1, const int to = -1);
|
||||
std::vector <ref <message> > getMessages(const std::vector <int>& nums);
|
||||
const int getMessageCount();
|
||||
|
||||
ref <folder> getFolder(const folder::path::component& name);
|
||||
std::vector <ref <folder> > 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 <int>& nums);
|
||||
|
||||
void setMessageFlags(const int from, const int to, const int flags, const int mode = message::FLAG_MODE_SET);
|
||||
void setMessageFlags(const std::vector <int>& nums, const int flags, const int mode = message::FLAG_MODE_SET);
|
||||
|
||||
void addMessage(ref <vmime::message> 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 <int>& nums);
|
||||
|
||||
void status(int& count, int& unseen);
|
||||
|
||||
void expunge();
|
||||
|
||||
ref <folder> getParent();
|
||||
|
||||
weak_ref <const store> getStore() const;
|
||||
weak_ref <store> getStore();
|
||||
|
||||
|
||||
void fetchMessages(std::vector <ref <message> >& msg, const int options, utility::progressionListener* progress = NULL);
|
||||
void fetchMessage(ref <message> msg, const int options);
|
||||
|
||||
const int getFetchCapabilities() const;
|
||||
|
||||
private:
|
||||
|
||||
void scanFolder();
|
||||
|
||||
void listFolders(std::vector <ref <folder> >& 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 <int>& nums);
|
||||
void setMessageFlagsImpl(const std::vector <int>& nums, const int flags, const int mode);
|
||||
|
||||
void copyMessagesImpl(const folder::path& dest, const std::vector <int>& 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 <maildirStore> 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 <messageInfos> m_messageInfos;
|
||||
|
||||
// Instanciated message objects
|
||||
std::vector <maildirMessage*> m_messages;
|
||||
};
|
||||
|
||||
|
||||
} // maildir
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_MAILDIR_MAILDIRFOLDER_HPP_INCLUDED
|
103
vmime/net/maildir/maildirMessage.hpp
Normal file
103
vmime/net/maildir/maildirMessage.hpp
Normal file
@ -0,0 +1,103 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_MAILDIR_MAILDIRMESSAGE_HPP_INCLUDED
|
||||
#define VMIME_NET_MAILDIR_MAILDIRMESSAGE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/net/message.hpp"
|
||||
#include "vmime/net/folder.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace maildir {
|
||||
|
||||
|
||||
class maildirFolder;
|
||||
|
||||
|
||||
/** maildir message implementation.
|
||||
*/
|
||||
|
||||
class maildirMessage : public message
|
||||
{
|
||||
friend class maildirFolder;
|
||||
friend class vmime::creator; // vmime::create <maildirMessage>
|
||||
|
||||
private:
|
||||
|
||||
maildirMessage(weak_ref <maildirFolder> 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 <const header> 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 <maildirFolder> folder, const int options);
|
||||
|
||||
void onFolderClosed();
|
||||
|
||||
ref <header> 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 <maildirFolder> m_folder;
|
||||
|
||||
int m_num;
|
||||
int m_size;
|
||||
int m_flags;
|
||||
bool m_expunged;
|
||||
uid m_uid;
|
||||
|
||||
ref <header> m_header;
|
||||
ref <structure> m_structure;
|
||||
};
|
||||
|
||||
|
||||
} // maildir
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_MAILDIR_MAILDIRMESSAGE_HPP_INCLUDED
|
114
vmime/net/maildir/maildirStore.hpp
Normal file
114
vmime/net/maildir/maildirStore.hpp
Normal file
@ -0,0 +1,114 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_MAILDIR_MAILDIRSTORE_HPP_INCLUDED
|
||||
#define VMIME_NET_MAILDIR_MAILDIRSTORE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
#include "vmime/net/store.hpp"
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/folder.hpp"
|
||||
|
||||
#include "vmime/utility/file.hpp"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace maildir {
|
||||
|
||||
|
||||
class maildirFolder;
|
||||
|
||||
|
||||
/** maildir store service.
|
||||
*/
|
||||
|
||||
class maildirStore : public store
|
||||
{
|
||||
friend class maildirFolder;
|
||||
|
||||
public:
|
||||
|
||||
maildirStore(ref <session> sess, ref <authenticator> auth);
|
||||
~maildirStore();
|
||||
|
||||
const string getProtocolName() const;
|
||||
|
||||
ref <folder> getDefaultFolder();
|
||||
ref <folder> getRootFolder();
|
||||
ref <folder> 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 <maildirFolder*> 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 <serviceInfos::property> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
static _infos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
} // maildir
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_MAILDIR_MAILDIRSTORE_HPP_INCLUDED
|
160
vmime/net/maildir/maildirUtils.hpp
Normal file
160
vmime/net/maildir/maildirUtils.hpp
Normal file
@ -0,0 +1,160 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_MAILDIR_MAILDIRUTILS_HPP_INCLUDED
|
||||
#define VMIME_NET_MAILDIR_MAILDIRUTILS_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/utility/file.hpp"
|
||||
#include "vmime/utility/path.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
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 <maildirStore> 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
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_MAILDIR_MAILDIRUTILS_HPP_INCLUDED
|
292
vmime/net/message.hpp
Normal file
292
vmime/net/message.hpp
Normal file
@ -0,0 +1,292 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_MESSAGE_HPP_INCLUDED
|
||||
#define VMIME_NET_MESSAGE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/header.hpp"
|
||||
|
||||
#include "vmime/utility/progressionListener.hpp"
|
||||
#include "vmime/utility/stream.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
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 <const header> 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;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_MESSAGE_HPP_INCLUDED
|
148
vmime/net/pop3/POP3Folder.hpp
Normal file
148
vmime/net/pop3/POP3Folder.hpp
Normal file
@ -0,0 +1,148 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_POP3_POP3FOLDER_HPP_INCLUDED
|
||||
#define VMIME_NET_POP3_POP3FOLDER_HPP_INCLUDED
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
#include "vmime/net/folder.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
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>
|
||||
|
||||
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 <message> getMessage(const int num);
|
||||
std::vector <ref <message> > getMessages(const int from = 1, const int to = -1);
|
||||
std::vector <ref <message> > getMessages(const std::vector <int>& nums);
|
||||
const int getMessageCount();
|
||||
|
||||
ref <folder> getFolder(const folder::path::component& name);
|
||||
std::vector <ref <folder> > 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 <int>& nums);
|
||||
|
||||
void setMessageFlags(const int from, const int to, const int flags, const int mode = message::FLAG_MODE_SET);
|
||||
void setMessageFlags(const std::vector <int>& nums, const int flags, const int mode = message::FLAG_MODE_SET);
|
||||
|
||||
void addMessage(ref <vmime::message> 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 <int>& nums);
|
||||
|
||||
void status(int& count, int& unseen);
|
||||
|
||||
void expunge();
|
||||
|
||||
ref <folder> getParent();
|
||||
|
||||
weak_ref <const store> getStore() const;
|
||||
weak_ref <store> getStore();
|
||||
|
||||
|
||||
void fetchMessages(std::vector <ref <message> >& msg, const int options, utility::progressionListener* progress = NULL);
|
||||
void fetchMessage(ref <message> 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 <int, string>& 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 <POP3Message*, int> MessageMap;
|
||||
MessageMap m_messages;
|
||||
};
|
||||
|
||||
|
||||
} // pop3
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_POP3_POP3FOLDER_HPP_INCLUDED
|
98
vmime/net/pop3/POP3Message.hpp
Normal file
98
vmime/net/pop3/POP3Message.hpp
Normal file
@ -0,0 +1,98 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_POP3_POP3MESSAGE_HPP_INCLUDED
|
||||
#define VMIME_NET_POP3_POP3MESSAGE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
#include "vmime/net/message.hpp"
|
||||
#include "vmime/net/folder.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace pop3 {
|
||||
|
||||
|
||||
class POP3Folder;
|
||||
|
||||
|
||||
/** POP3 message implementation.
|
||||
*/
|
||||
|
||||
class POP3Message : public message
|
||||
{
|
||||
private:
|
||||
|
||||
friend class POP3Folder;
|
||||
friend class vmime::creator; // vmime::create <POP3Message>
|
||||
|
||||
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 <const header> 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 <header> m_header;
|
||||
};
|
||||
|
||||
|
||||
} // pop3
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_POP3_POP3MESSAGE_HPP_INCLUDED
|
138
vmime/net/pop3/POP3Store.hpp
Normal file
138
vmime/net/pop3/POP3Store.hpp
Normal file
@ -0,0 +1,138 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_POP3_POP3STORE_HPP_INCLUDED
|
||||
#define VMIME_NET_POP3_POP3STORE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
#include "vmime/net/store.hpp"
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/timeoutHandler.hpp"
|
||||
|
||||
#include "vmime/utility/stream.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace pop3 {
|
||||
|
||||
|
||||
class POP3Folder;
|
||||
|
||||
|
||||
/** POP3 store service.
|
||||
*/
|
||||
|
||||
class POP3Store : public store
|
||||
{
|
||||
friend class POP3Folder;
|
||||
friend class POP3Message;
|
||||
|
||||
public:
|
||||
|
||||
POP3Store(ref <session> sess, ref <authenticator> auth);
|
||||
~POP3Store();
|
||||
|
||||
const string getProtocolName() const;
|
||||
|
||||
ref <folder> getDefaultFolder();
|
||||
ref <folder> getRootFolder();
|
||||
ref <folder> 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 <POP3Folder*> m_folders;
|
||||
|
||||
|
||||
ref <socket> m_socket;
|
||||
bool m_authentified;
|
||||
|
||||
ref <timeoutHandler> 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 <serviceInfos::property> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
static _infos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
} // pop3
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_POP3_POP3STORE_HPP_INCLUDED
|
103
vmime/net/sendmail/sendmailTransport.hpp
Normal file
103
vmime/net/sendmail/sendmailTransport.hpp
Normal file
@ -0,0 +1,103 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_SENDMAIL_SENDMAILTRANSPORT_HPP_INCLUDED
|
||||
#define VMIME_NET_SENDMAIL_SENDMAILTRANSPORT_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
#include "vmime/net/transport.hpp"
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/timeoutHandler.hpp"
|
||||
|
||||
|
||||
#if VMIME_BUILTIN_PLATFORM_POSIX
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace sendmail {
|
||||
|
||||
|
||||
/** Sendmail local transport service.
|
||||
*/
|
||||
|
||||
class sendmailTransport : public transport
|
||||
{
|
||||
public:
|
||||
|
||||
sendmailTransport(ref <session> sess, ref <authenticator> 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 <string> 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 <serviceInfos::property> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
static _infos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
} // sendmail
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_BUILTIN_PLATFORM_POSIX
|
||||
|
||||
|
||||
#endif // VMIME_NET_SENDMAIL_SENDMAILTRANSPORT_HPP_INCLUDED
|
161
vmime/net/service.hpp
Normal file
161
vmime/net/service.hpp
Normal file
@ -0,0 +1,161 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_SERVICE_HPP_INCLUDED
|
||||
#define VMIME_NET_SERVICE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
#include "vmime/net/session.hpp"
|
||||
#include "vmime/net/authenticator.hpp"
|
||||
|
||||
#include "vmime/net/serviceFactory.hpp"
|
||||
#include "vmime/net/serviceInfos.hpp"
|
||||
|
||||
#include "vmime/utility/progressionListener.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
/** Base class for messaging services.
|
||||
*/
|
||||
|
||||
class service : public object
|
||||
{
|
||||
protected:
|
||||
|
||||
service(ref <session> sess, const serviceInfos& infos, ref <authenticator> 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 <const session> getSession() const;
|
||||
|
||||
/** Return the session object associated with this service instance.
|
||||
*
|
||||
* @return session object
|
||||
*/
|
||||
ref <session> 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 <const authenticator> getAuthenticator() const;
|
||||
|
||||
/** Return the authenticator object used with this service instance.
|
||||
*
|
||||
* @return authenticator object
|
||||
*/
|
||||
ref <authenticator> 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 <typename TYPE>
|
||||
void setProperty(const string& name, const TYPE& value)
|
||||
{
|
||||
m_session->getProperties()[getInfos().getPropertyPrefix() + name] = value;
|
||||
}
|
||||
|
||||
#ifndef VMIME_BUILDING_DOC
|
||||
// Basic service registerer
|
||||
template <class S>
|
||||
class initializer
|
||||
{
|
||||
public:
|
||||
|
||||
initializer(const string& protocol)
|
||||
{
|
||||
serviceFactory::getInstance()->
|
||||
template registerServiceByProtocol <S>(protocol);
|
||||
}
|
||||
};
|
||||
#endif // VMIME_BUILDING_DOC
|
||||
|
||||
private:
|
||||
|
||||
ref <session> m_session;
|
||||
ref <authenticator> m_auth;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_SERVICE_HPP_INCLUDED
|
188
vmime/net/serviceFactory.hpp
Normal file
188
vmime/net/serviceFactory.hpp
Normal file
@ -0,0 +1,188 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_SERVICEFACTORY_HPP_INCLUDED
|
||||
#define VMIME_NET_SERVICEFACTORY_HPP_INCLUDED
|
||||
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
#include "vmime/base.hpp"
|
||||
|
||||
#include "vmime/utility/stringUtils.hpp"
|
||||
#include "vmime/utility/url.hpp"
|
||||
|
||||
#include "vmime/net/serviceInfos.hpp"
|
||||
#include "vmime/net/authenticator.hpp"
|
||||
#include "vmime/net/timeoutHandler.hpp"
|
||||
|
||||
#include "vmime/utility/progressionListener.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
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 <service> create(ref <session> sess, ref <authenticator> auth) const = 0;
|
||||
|
||||
virtual const string& getName() const = 0;
|
||||
virtual const serviceInfos& getInfos() const = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
template <class S>
|
||||
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 <service> create(ref <session> sess, ref <authenticator> auth) const
|
||||
{
|
||||
return vmime::create <S>(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 <ref <registeredService> > m_services;
|
||||
|
||||
public:
|
||||
|
||||
/** Register a new service by its protocol name.
|
||||
*
|
||||
* @param protocol protocol name
|
||||
*/
|
||||
template <class S>
|
||||
void registerServiceByProtocol(const string& protocol)
|
||||
{
|
||||
const string name = utility::stringUtils::toLower(protocol);
|
||||
m_services.push_back(vmime::create <registeredServiceImpl <S> >(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 <service> create(ref <session> sess, const string& protocol, ref <authenticator> 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 <service> create(ref <session> sess, const utility::url& u, ref <authenticator> 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 <const registeredService> 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 <const registeredService> getServiceAt(const int pos) const;
|
||||
|
||||
/** Return a list of all registered services.
|
||||
*
|
||||
* @return list of registered services
|
||||
*/
|
||||
const std::vector <ref <const registeredService> > getServiceList() const;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_SERVICEFACTORY_HPP_INCLUDED
|
228
vmime/net/serviceInfos.hpp
Normal file
228
vmime/net/serviceInfos.hpp
Normal file
@ -0,0 +1,228 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_SERVICEINFOS_HPP_INCLUDED
|
||||
#define VMIME_NET_SERVICEINFOS_HPP_INCLUDED
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
#include "vmime/net/session.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
/** 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 <property> 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 <typename TYPE>
|
||||
const TYPE getPropertyValue(ref <session> s, const property& p) const
|
||||
{
|
||||
if (p.getFlags() & property::FLAG_REQUIRED)
|
||||
return s->getProperties()[getPropertyPrefix() + p.getName()].template getValue <TYPE>();
|
||||
|
||||
return s->getProperties().template getProperty <TYPE>(getPropertyPrefix() + p.getName(),
|
||||
propertySet::valueFromString <TYPE>(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 <session> s, const property& p) const;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_SERVICEINFOS_HPP_INCLUDED
|
135
vmime/net/session.hpp
Normal file
135
vmime/net/session.hpp
Normal file
@ -0,0 +1,135 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_SESSION_HPP_INCLUDED
|
||||
#define VMIME_NET_SESSION_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/net/authenticator.hpp"
|
||||
|
||||
#include "vmime/utility/url.hpp"
|
||||
|
||||
#include "vmime/propertySet.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
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 <transport> getTransport(ref <authenticator> 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 <transport> getTransport(const string& protocol, ref <authenticator> 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 <transport> getTransport(const utility::url& url, ref <authenticator> 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 <store> getStore(ref <authenticator> 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 <store> getStore(const string& protocol, ref <authenticator> 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 <store> getStore(const utility::url& url, ref <authenticator> 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;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_SESSION_HPP_INCLUDED
|
62
vmime/net/simpleAuthenticator.hpp
Normal file
62
vmime/net/simpleAuthenticator.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_SIMPLEAUTHENTICATOR_HPP_INCLUDED
|
||||
#define VMIME_NET_SIMPLEAUTHENTICATOR_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/net/authenticator.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
/** 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;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_SIMPLEAUTHENTICATOR_HPP_INCLUDED
|
113
vmime/net/smtp/SMTPTransport.hpp
Normal file
113
vmime/net/smtp/SMTPTransport.hpp
Normal file
@ -0,0 +1,113 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_SMTP_SMTPTRANSPORT_HPP_INCLUDED
|
||||
#define VMIME_NET_SMTP_SMTPTRANSPORT_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
#include "vmime/net/transport.hpp"
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/timeoutHandler.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
namespace smtp {
|
||||
|
||||
|
||||
/** SMTP transport service.
|
||||
*/
|
||||
|
||||
class SMTPTransport : public transport
|
||||
{
|
||||
public:
|
||||
|
||||
SMTPTransport(ref <session> sess, ref <authenticator> 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 <socket> m_socket;
|
||||
bool m_authentified;
|
||||
bool m_extendedSMTP;
|
||||
|
||||
ref <timeoutHandler> 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 <serviceInfos::property> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
static _infos sm_infos;
|
||||
};
|
||||
|
||||
|
||||
} // smtp
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_SMTP_SMTPTRANSPORT_HPP_INCLUDED
|
112
vmime/net/socket.hpp
Normal file
112
vmime/net/socket.hpp
Normal file
@ -0,0 +1,112 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_SOCKET_HPP_INCLUDED
|
||||
#define VMIME_NET_SOCKET_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/base.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
/** 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 <socket> create() = 0;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_SOCKET_HPP_INCLUDED
|
102
vmime/net/store.hpp
Normal file
102
vmime/net/store.hpp
Normal file
@ -0,0 +1,102 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_STORE_HPP_INCLUDED
|
||||
#define VMIME_NET_STORE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/net/service.hpp"
|
||||
#include "vmime/net/folder.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
/** A store service.
|
||||
* Encapsulate protocols that provide access to user's mail drop.
|
||||
*/
|
||||
|
||||
class store : public service
|
||||
{
|
||||
protected:
|
||||
|
||||
store(ref <session> sess, const serviceInfos& infos, ref <authenticator> 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 <folder> 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 <folder> getRootFolder() = 0;
|
||||
|
||||
/** Return the folder specified by the path.
|
||||
*
|
||||
* @param path absolute folder path
|
||||
* @return folder at the specified path
|
||||
*/
|
||||
virtual ref <folder> 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); }
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_STORE_HPP_INCLUDED
|
77
vmime/net/timeoutHandler.hpp
Normal file
77
vmime/net/timeoutHandler.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_TIMEOUTHANDLER_HPP_INCLUDED
|
||||
#define VMIME_NET_TIMEOUTHANDLER_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/types.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace net {
|
||||
|
||||
|
||||
/** 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 <timeoutHandler> create() = 0;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_TIMEOUTHANDLER_HPP_INCLUDED
|
75
vmime/net/transport.hpp
Normal file
75
vmime/net/transport.hpp
Normal file
@ -0,0 +1,75 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
|
||||
//
|
||||
// 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_NET_TRANSPORT_HPP_INCLUDED
|
||||
#define VMIME_NET_TRANSPORT_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/net/service.hpp"
|
||||
#include "vmime/utility/stream.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
|
||||
class message;
|
||||
class mailbox;
|
||||
class mailboxList;
|
||||
|
||||
namespace net {
|
||||
|
||||
|
||||
/** A transport service.
|
||||
* Encapsulate protocols that can send messages.
|
||||
*/
|
||||
|
||||
class transport : public service
|
||||
{
|
||||
protected:
|
||||
|
||||
transport(ref <session> sess, const serviceInfos& infos, ref <authenticator> 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 <vmime::message> 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;
|
||||
};
|
||||
|
||||
|
||||
} // net
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_NET_TRANSPORT_HPP_INCLUDED
|
@ -27,8 +27,8 @@
|
||||
#include "vmime/charset.hpp"
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
#include "vmime/messaging/socket.hpp"
|
||||
#include "vmime/messaging/timeoutHandler.hpp"
|
||||
#include "vmime/net/socket.hpp"
|
||||
#include "vmime/net/timeoutHandler.hpp"
|
||||
#endif
|
||||
|
||||
#if VMIME_HAVE_FILESYSTEM_FEATURES
|
||||
@ -110,7 +110,7 @@ public:
|
||||
* session object
|
||||
* @return socket factory
|
||||
*/
|
||||
virtual messaging::socketFactory* getSocketFactory(const string& name = "default") const = 0;
|
||||
virtual net::socketFactory* getSocketFactory(const string& name = "default") const = 0;
|
||||
|
||||
/** Return a pointer to a timeout-handler factory for the specified name.
|
||||
* The returned object will not be deleted by VMime, so it can be a
|
||||
@ -124,7 +124,7 @@ public:
|
||||
* @param name time-out type name
|
||||
* @return time-out factory
|
||||
*/
|
||||
virtual messaging::timeoutHandlerFactory* getTimeoutHandlerFactory(const string& name = "default") const = 0;
|
||||
virtual net::timeoutHandlerFactory* getTimeoutHandlerFactory(const string& name = "default") const = 0;
|
||||
#endif
|
||||
#if VMIME_HAVE_FILESYSTEM_FEATURES
|
||||
/** Return a pointer to a factory that creates file-system objects.
|
||||
|
@ -57,9 +57,9 @@ public:
|
||||
const unsigned int getProcessId() const;
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
vmime::messaging::socketFactory* getSocketFactory(const vmime::string& name) const;
|
||||
vmime::net::socketFactory* getSocketFactory(const vmime::string& name) const;
|
||||
|
||||
vmime::messaging::timeoutHandlerFactory* getTimeoutHandlerFactory(const vmime::string& name) const;
|
||||
vmime::net::timeoutHandlerFactory* getTimeoutHandlerFactory(const vmime::string& name) const;
|
||||
#endif
|
||||
|
||||
#if VMIME_HAVE_FILESYSTEM_FEATURES
|
||||
|
@ -21,7 +21,7 @@
|
||||
#define VMIME_PLATFORMS_POSIX_SOCKET_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/messaging/socket.hpp"
|
||||
#include "vmime/net/socket.hpp"
|
||||
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
@ -32,7 +32,7 @@ namespace platforms {
|
||||
namespace posix {
|
||||
|
||||
|
||||
class posixSocket : public vmime::messaging::socket
|
||||
class posixSocket : public vmime::net::socket
|
||||
{
|
||||
public:
|
||||
|
||||
@ -57,11 +57,11 @@ private:
|
||||
|
||||
|
||||
|
||||
class posixSocketFactory : public vmime::messaging::socketFactory
|
||||
class posixSocketFactory : public vmime::net::socketFactory
|
||||
{
|
||||
public:
|
||||
|
||||
ref <vmime::messaging::socket> create();
|
||||
ref <vmime::net::socket> create();
|
||||
};
|
||||
|
||||
|
||||
|
@ -56,9 +56,9 @@ public:
|
||||
const unsigned int getProcessId() const;
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
vmime::messaging::socketFactory* getSocketFactory(const vmime::string& name) const;
|
||||
vmime::net::socketFactory* getSocketFactory(const vmime::string& name) const;
|
||||
|
||||
vmime::messaging::timeoutHandlerFactory* getTimeoutHandlerFactory(const vmime::string& name) const;
|
||||
vmime::net::timeoutHandlerFactory* getTimeoutHandlerFactory(const vmime::string& name) const;
|
||||
#endif
|
||||
|
||||
#if VMIME_HAVE_FILESYSTEM_FEATURES
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
|
||||
#include <winsock2.h>
|
||||
#include "vmime/messaging/socket.hpp"
|
||||
#include "vmime/net/socket.hpp"
|
||||
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
@ -33,7 +33,7 @@ namespace platforms {
|
||||
namespace windows {
|
||||
|
||||
|
||||
class windowsSocket : public vmime::messaging::socket
|
||||
class windowsSocket : public vmime::net::socket
|
||||
{
|
||||
public:
|
||||
windowsSocket();
|
||||
@ -59,11 +59,11 @@ private:
|
||||
|
||||
|
||||
|
||||
class windowsSocketFactory : public vmime::messaging::socketFactory
|
||||
class windowsSocketFactory : public vmime::net::socketFactory
|
||||
{
|
||||
public:
|
||||
|
||||
ref <vmime::messaging::socket> create();
|
||||
ref <vmime::net::socket> create();
|
||||
};
|
||||
|
||||
|
||||
|
@ -47,6 +47,10 @@ namespace vmime
|
||||
using vmime::utility::null_ref;
|
||||
|
||||
extern const null_ref null;
|
||||
|
||||
// For compatibility with versions <= 0.7.1 (deprecated)
|
||||
namespace net { }
|
||||
namespace messaging = net;
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,9 +33,9 @@
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
namespace vmime {
|
||||
namespace messaging {
|
||||
namespace net {
|
||||
class socket; // forward reference
|
||||
} // messaging
|
||||
} // net
|
||||
} // vmime
|
||||
#endif
|
||||
|
||||
@ -336,7 +336,7 @@ class outputStreamSocketAdapter : public outputStream
|
||||
{
|
||||
public:
|
||||
|
||||
outputStreamSocketAdapter(messaging::socket& sok);
|
||||
outputStreamSocketAdapter(net::socket& sok);
|
||||
|
||||
void write(const value_type* const data, const size_type count);
|
||||
|
||||
@ -344,7 +344,7 @@ private:
|
||||
|
||||
outputStreamSocketAdapter(const outputStreamSocketAdapter&);
|
||||
|
||||
messaging::socket& m_socket;
|
||||
net::socket& m_socket;
|
||||
};
|
||||
|
||||
|
||||
@ -355,7 +355,7 @@ class inputStreamSocketAdapter : public inputStream
|
||||
{
|
||||
public:
|
||||
|
||||
inputStreamSocketAdapter(messaging::socket& sok);
|
||||
inputStreamSocketAdapter(net::socket& sok);
|
||||
|
||||
const bool eof() const;
|
||||
void reset();
|
||||
@ -366,7 +366,7 @@ private:
|
||||
|
||||
inputStreamSocketAdapter(const inputStreamSocketAdapter&);
|
||||
|
||||
messaging::socket& m_socket;
|
||||
net::socket& m_socket;
|
||||
};
|
||||
|
||||
|
||||
|
@ -88,19 +88,19 @@
|
||||
|
||||
// Messaging features
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
||||
#include "vmime/messaging/socket.hpp"
|
||||
#include "vmime/net/socket.hpp"
|
||||
|
||||
#include "vmime/messaging/service.hpp"
|
||||
#include "vmime/messaging/store.hpp"
|
||||
#include "vmime/messaging/transport.hpp"
|
||||
#include "vmime/net/service.hpp"
|
||||
#include "vmime/net/store.hpp"
|
||||
#include "vmime/net/transport.hpp"
|
||||
|
||||
#include "vmime/messaging/session.hpp"
|
||||
#include "vmime/messaging/authenticator.hpp"
|
||||
#include "vmime/messaging/defaultAuthenticator.hpp"
|
||||
#include "vmime/messaging/simpleAuthenticator.hpp"
|
||||
#include "vmime/net/session.hpp"
|
||||
#include "vmime/net/authenticator.hpp"
|
||||
#include "vmime/net/defaultAuthenticator.hpp"
|
||||
#include "vmime/net/simpleAuthenticator.hpp"
|
||||
|
||||
#include "vmime/messaging/folder.hpp"
|
||||
#include "vmime/messaging/message.hpp"
|
||||
#include "vmime/net/folder.hpp"
|
||||
#include "vmime/net/message.hpp"
|
||||
#endif // VMIME_HAVE_MESSAGING_FEATURES
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user