aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Paul Young <paulyoungonline@gmail.com>2013-07-03 17:06:20 -0400
committerGravatar Paul Young <paulyoungonline@gmail.com>2013-07-03 17:06:20 -0400
commita2f9f56ec6dc3fccb5a3b237ca62d3156cfa1883 (patch)
tree1a3c0ebae239e6571bb1c5d02e5921d299f9a399 /src
parentcc9b898f07b3f750b910cfea73c0e223984f7cad (diff)
parent9fe6ce12c4880a6c2f2a4180752987dd30d65c89 (diff)
Merge branch 'master' into message-rendering-with-session
Conflicts: build-mac/mailcore2.xcodeproj/project.pbxproj
Diffstat (limited to 'src')
-rw-r--r--src/async/imap/MCIMAPAsyncConnection.cc69
-rw-r--r--src/async/imap/MCIMAPAsyncConnection.h194
-rw-r--r--src/async/imap/MCIMAPAsyncSession.cc33
-rw-r--r--src/async/imap/MCIMAPAsyncSession.h12
-rw-r--r--src/async/pop/MCPOPAsyncSession.cc62
-rw-r--r--src/async/pop/MCPOPAsyncSession.h9
-rw-r--r--src/async/smtp/MCSMTPAsyncSession.cc61
-rw-r--r--src/async/smtp/MCSMTPAsyncSession.h10
-rw-r--r--src/core/abstract/MCMessageConstants.h387
-rw-r--r--src/core/basetypes/MCConnectionLogger.h15
-rw-r--r--src/core/basetypes/MCConnectionLoggerUtils.cc19
-rw-r--r--src/core/basetypes/MCHTMLCleaner.cc1
-rw-r--r--src/core/basetypes/MCLibetpan.cpp16
-rw-r--r--src/core/basetypes/MCLibetpan.h14
-rw-r--r--src/core/basetypes/MCObject.cc4
-rw-r--r--src/core/basetypes/MCOperationQueue.cc4
-rw-r--r--src/core/basetypes/MCOperationQueueCallback.h4
-rw-r--r--src/core/basetypes/MCString.cc54
-rw-r--r--src/core/imap/MCIMAPSession.cc24
-rw-r--r--src/core/imap/MCIMAPSession.h6
-rw-r--r--src/core/pop/MCPOPSession.cc5
-rw-r--r--src/core/provider/MCMailProvider.cc108
-rw-r--r--src/core/provider/MCMailProvider.h4
-rw-r--r--src/core/provider/MCNetService.cc62
-rw-r--r--src/core/provider/MCNetService.h53
-rw-r--r--src/core/smtp/MCSMTPSession.cc7
-rw-r--r--src/objc/abstract/MCOAbstractMessage.mm8
-rw-r--r--src/objc/abstract/MCOAbstractPart.mm8
-rw-r--r--src/objc/abstract/MCOConstants.h26
-rw-r--r--src/objc/abstract/MCOMessageHeader.mm6
-rw-r--r--src/objc/imap/MCOIMAPAppendMessageOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPCapabilityOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPCopyMessagesOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPFetchContentOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPFetchFoldersOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPFetchMessagesOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPFetchNamespaceOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPFolderInfoOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPFolderStatusOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPIdentityOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPIdleOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPSearchOperation.mm2
-rw-r--r--src/objc/imap/MCOIMAPSession.h9
-rw-r--r--src/objc/imap/MCOIMAPSession.mm56
-rw-r--r--src/objc/pop/MCOPOPFetchHeaderOperation.mm2
-rw-r--r--src/objc/pop/MCOPOPFetchMessageOperation.mm2
-rw-r--r--src/objc/pop/MCOPOPFetchMessagesOperation.mm2
-rw-r--r--src/objc/pop/MCOPOPOperation.mm2
-rw-r--r--src/objc/pop/MCOPOPSession.h9
-rw-r--r--src/objc/pop/MCOPOPSession.mm58
-rw-r--r--src/objc/smtp/MCOSMTPOperation.mm2
-rw-r--r--src/objc/smtp/MCOSMTPSendOperation.mm12
-rw-r--r--src/objc/smtp/MCOSMTPSession.h9
-rw-r--r--src/objc/smtp/MCOSMTPSession.mm58
55 files changed, 1089 insertions, 443 deletions
diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc
index 2891d439..fc1935b7 100644
--- a/src/async/imap/MCIMAPAsyncConnection.cc
+++ b/src/async/imap/MCIMAPAsyncConnection.cc
@@ -33,6 +33,7 @@
#include "MCOperationQueueCallback.h"
#include "MCIMAPDisconnectOperation.h"
#include "MCIMAPAsyncSession.h"
+#include "MCConnectionLogger.h"
using namespace mailcore;
@@ -46,11 +47,11 @@ namespace mailcore {
virtual ~IMAPOperationQueueCallback() {
}
- virtual void queueStartRunning() {
+ virtual void queueStartRunning(OperationQueue * queue) {
mConnection->queueStartRunning();
}
- virtual void queueStoppedRunning() {
+ virtual void queueStoppedRunning(OperationQueue * queue) {
mConnection->tryAutomaticDisconnect();
mConnection->queueStoppedRunning();
}
@@ -58,6 +59,24 @@ namespace mailcore {
private:
IMAPAsyncConnection * mConnection;
};
+
+ class IMAPConnectionLogger : public Object, public ConnectionLogger {
+ public:
+ IMAPConnectionLogger(IMAPAsyncConnection * connection) {
+ mConnection = connection;
+ }
+
+ virtual ~IMAPConnectionLogger() {
+ }
+
+ virtual void log(void * context, void * sender, ConnectionLogType logType, Data * buffer)
+ {
+ mConnection->logConnection(logType, buffer);
+ }
+
+ private:
+ IMAPAsyncConnection * mConnection;
+ };
}
IMAPAsyncConnection::IMAPAsyncConnection()
@@ -70,11 +89,16 @@ IMAPAsyncConnection::IMAPAsyncConnection()
mQueueCallback = new IMAPOperationQueueCallback(this);
mQueue->setCallback(mQueueCallback);
mOwner = NULL;
+ mConnectionLogger = NULL;
+ pthread_mutex_init(&mConnectionLoggerLock, NULL);
+ mInternalLogger = new IMAPConnectionLogger(this);
}
IMAPAsyncConnection::~IMAPAsyncConnection()
{
cancelDelayedPerformMethod((Object::Method) &IMAPAsyncConnection::tryAutomaticDisconnectAfterDelay, NULL);
+ pthread_mutex_destroy(&mConnectionLoggerLock);
+ MC_SAFE_RELEASE(mInternalLogger);
MC_SAFE_RELEASE(mQueueCallback);
MC_SAFE_RELEASE(mLastFolder);
MC_SAFE_RELEASE(mDefaultNamespace);
@@ -122,6 +146,16 @@ String * IMAPAsyncConnection::password()
return mSession->password();
}
+void IMAPAsyncConnection::setOAuth2Token(String * token)
+{
+ mSession->setOAuth2Token(token);
+}
+
+String * IMAPAsyncConnection::OAuth2Token()
+{
+ return mSession->OAuth2Token();
+}
+
void IMAPAsyncConnection::setAuthType(AuthType authType)
{
mSession->setAuthType(authType);
@@ -526,4 +560,35 @@ IMAPAsyncSession * IMAPAsyncConnection::owner()
return mOwner;
}
+void IMAPAsyncConnection::setConnectionLogger(ConnectionLogger * logger)
+{
+ pthread_mutex_lock(&mConnectionLoggerLock);
+ mConnectionLogger = logger;
+ if (mConnectionLogger != NULL) {
+ mSession->setConnectionLogger(mInternalLogger);
+ }
+ else {
+ mSession->setConnectionLogger(NULL);
+ }
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+}
+ConnectionLogger * IMAPAsyncConnection::connectionLogger()
+{
+ ConnectionLogger * result;
+
+ pthread_mutex_lock(&mConnectionLoggerLock);
+ result = mConnectionLogger;
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+
+ return result;
+}
+
+void IMAPAsyncConnection::logConnection(ConnectionLogType logType, Data * buffer)
+{
+ pthread_mutex_lock(&mConnectionLoggerLock);
+ if (mConnectionLogger != NULL) {
+ mConnectionLogger->log(this, logType, buffer);
+ }
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+}
diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h
index d6ef6a91..319cc224 100644
--- a/src/async/imap/MCIMAPAsyncConnection.h
+++ b/src/async/imap/MCIMAPAsyncConnection.h
@@ -8,129 +8,139 @@
#ifdef __cplusplus
namespace mailcore {
-
- class IMAPOperation;
- class IMAPFetchFoldersOperation;
- class IMAPAppendMessageOperation;
- class IMAPCopyMessagesOperation;
- class IMAPFetchMessagesOperation;
- class IMAPFetchContentOperation;
- class IMAPIdleOperation;
- class IMAPFolderInfoOperation;
- class IMAPFolderStatusOperation;
- class IMAPSession;
- class IMAPNamespace;
- class IMAPSearchOperation;
- class IMAPSearchExpression;
- class IMAPFetchNamespaceOperation;
- class IMAPIdentityOperation;
- class IMAPCapabilityOperation;
+
+ class IMAPOperation;
+ class IMAPFetchFoldersOperation;
+ class IMAPAppendMessageOperation;
+ class IMAPCopyMessagesOperation;
+ class IMAPFetchMessagesOperation;
+ class IMAPFetchContentOperation;
+ class IMAPIdleOperation;
+ class IMAPFolderInfoOperation;
+ class IMAPFolderStatusOperation;
+ class IMAPSession;
+ class IMAPNamespace;
+ class IMAPSearchOperation;
+ class IMAPSearchExpression;
+ class IMAPFetchNamespaceOperation;
+ class IMAPIdentityOperation;
+ class IMAPCapabilityOperation;
class IMAPOperationQueueCallback;
class IMAPAsyncSession;
+ class IMAPConnectionLogger;
- class IMAPAsyncConnection : public Object {
- public:
- IMAPAsyncConnection();
- virtual ~IMAPAsyncConnection();
-
- virtual void setHostname(String * hostname);
- virtual String * hostname();
+ class IMAPAsyncConnection : public Object {
+ public:
+ IMAPAsyncConnection();
+ virtual ~IMAPAsyncConnection();
+
+ virtual void setHostname(String * hostname);
+ virtual String * hostname();
+
+ virtual void setPort(unsigned int port);
+ virtual unsigned int port();
+
+ virtual void setUsername(String * username);
+ virtual String * username();
+
+ virtual void setPassword(String * password);
+ virtual String * password();
- virtual void setPort(unsigned int port);
- virtual unsigned int port();
+ virtual void setOAuth2Token(String * token);
+ virtual String * OAuth2Token();
- virtual void setUsername(String * username);
- virtual String * username();
+ virtual void setAuthType(AuthType authType);
+ virtual AuthType authType();
- virtual void setPassword(String * password);
- virtual String * password();
+ virtual void setConnectionType(ConnectionType connectionType);
+ virtual ConnectionType connectionType();
- virtual void setAuthType(AuthType authType);
- virtual AuthType authType();
+ virtual void setTimeout(time_t timeout);
+ virtual time_t timeout();
- virtual void setConnectionType(ConnectionType connectionType);
- virtual ConnectionType connectionType();
+ virtual void setCheckCertificateEnabled(bool enabled);
+ virtual bool isCheckCertificateEnabled();
- virtual void setTimeout(time_t timeout);
- virtual time_t timeout();
-
- virtual void setCheckCertificateEnabled(bool enabled);
- virtual bool isCheckCertificateEnabled();
+ virtual void setVoIPEnabled(bool enabled);
+ virtual bool isVoIPEnabled();
- virtual void setVoIPEnabled(bool enabled);
- virtual bool isVoIPEnabled();
+ virtual void setDelimiter(char delimiter);
+ virtual char delimiter();
- virtual void setDelimiter(char delimiter);
- virtual char delimiter();
+ virtual void setDefaultNamespace(IMAPNamespace * ns);
+ virtual IMAPNamespace * defaultNamespace();
- virtual void setDefaultNamespace(IMAPNamespace * ns);
- virtual IMAPNamespace * defaultNamespace();
+ virtual void setConnectionLogger(ConnectionLogger * logger);
+ virtual ConnectionLogger * connectionLogger();
- virtual IMAPFolderInfoOperation * folderInfoOperation(String * folder);
+ virtual IMAPFolderInfoOperation * folderInfoOperation(String * folder);
virtual IMAPFolderStatusOperation * folderStatusOperation(String * folder);
-
- virtual IMAPFetchFoldersOperation * fetchSubscribedFoldersOperation();
- virtual IMAPFetchFoldersOperation * fetchAllFoldersOperation();
-
- virtual IMAPOperation * renameFolderOperation(String * folder, String * otherName);
- virtual IMAPOperation * deleteFolderOperation(String * folder);
- virtual IMAPOperation * createFolderOperation(String * folder);
-
- virtual IMAPOperation * subscribeFolderOperation(String * folder);
- virtual IMAPOperation * unsubscribeFolderOperation(String * folder);
-
- virtual IMAPAppendMessageOperation * appendMessageOperation(String * folder, Data * messageData, MessageFlag flags);
-
- virtual IMAPCopyMessagesOperation * copyMessagesOperation(String * folder, IndexSet * uids, String * destFolder);
-
- virtual IMAPOperation * expungeOperation(String * folder);
-
- virtual IMAPFetchMessagesOperation * fetchMessagesByUIDOperation(String * folder, IMAPMessagesRequestKind requestKind,
+
+ virtual IMAPFetchFoldersOperation * fetchSubscribedFoldersOperation();
+ virtual IMAPFetchFoldersOperation * fetchAllFoldersOperation();
+
+ virtual IMAPOperation * renameFolderOperation(String * folder, String * otherName);
+ virtual IMAPOperation * deleteFolderOperation(String * folder);
+ virtual IMAPOperation * createFolderOperation(String * folder);
+
+ virtual IMAPOperation * subscribeFolderOperation(String * folder);
+ virtual IMAPOperation * unsubscribeFolderOperation(String * folder);
+
+ virtual IMAPAppendMessageOperation * appendMessageOperation(String * folder, Data * messageData, MessageFlag flags);
+
+ virtual IMAPCopyMessagesOperation * copyMessagesOperation(String * folder, IndexSet * uids, String * destFolder);
+
+ virtual IMAPOperation * expungeOperation(String * folder);
+
+ virtual IMAPFetchMessagesOperation * fetchMessagesByUIDOperation(String * folder, IMAPMessagesRequestKind requestKind,
IndexSet * uids);
- virtual IMAPFetchMessagesOperation * fetchMessagesByNumberOperation(String * folder, IMAPMessagesRequestKind requestKind,
+ virtual IMAPFetchMessagesOperation * fetchMessagesByNumberOperation(String * folder, IMAPMessagesRequestKind requestKind,
IndexSet * numbers);
virtual IMAPFetchMessagesOperation * syncMessagesByUID(String * folder, IMAPMessagesRequestKind requestKind,
IndexSet * uids, uint64_t modSeq);
- virtual IMAPFetchContentOperation * fetchMessageByUIDOperation(String * folder, uint32_t uid);
- virtual IMAPFetchContentOperation * fetchMessageAttachmentByUIDOperation(String * folder, uint32_t uid, String * partID,
+ virtual IMAPFetchContentOperation * fetchMessageByUIDOperation(String * folder, uint32_t uid);
+ virtual IMAPFetchContentOperation * fetchMessageAttachmentByUIDOperation(String * folder, uint32_t uid, String * partID,
Encoding encoding);
-
- virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags);
- virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels);
-
- virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString);
- virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchExpression * expression);
-
- virtual IMAPIdleOperation * idleOperation(String * folder, uint32_t lastKnownUID);
-
- virtual IMAPFetchNamespaceOperation * fetchNamespaceOperation();
-
- virtual IMAPIdentityOperation * identityOperation(String * vendor, String * name, String * version);
+
+ virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags);
+ virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels);
+
+ virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString);
+ virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchExpression * expression);
+
+ virtual IMAPIdleOperation * idleOperation(String * folder, uint32_t lastKnownUID);
+
+ virtual IMAPFetchNamespaceOperation * fetchNamespaceOperation();
+
+ virtual IMAPIdentityOperation * identityOperation(String * vendor, String * name, String * version);
virtual IMAPOperation * checkAccountOperation();
virtual IMAPCapabilityOperation * capabilityOperation();
private:
- IMAPSession * mSession;
- OperationQueue * mQueue;
- char mDelimiter;
- IMAPNamespace * mDefaultNamespace;
- String * mLastFolder;
+ IMAPSession * mSession;
+ OperationQueue * mQueue;
+ char mDelimiter;
+ IMAPNamespace * mDefaultNamespace;
+ String * mLastFolder;
IMAPOperationQueueCallback * mQueueCallback;
- IMAPAsyncSession * mOwner;
+ IMAPAsyncSession * mOwner;
+ ConnectionLogger * mConnectionLogger;
+ IMAPConnectionLogger * mInternalLogger;
+ pthread_mutex_t mConnectionLoggerLock;
virtual void tryAutomaticDisconnectAfterDelay(void * context);
-
+
public: // private
- virtual void runOperation(IMAPOperation * operation);
- virtual IMAPSession * session();
+ virtual void runOperation(IMAPOperation * operation);
+ virtual IMAPSession * session();
- virtual unsigned int operationsCount();
+ virtual unsigned int operationsCount();
- virtual void setLastFolder(String * folder);
- virtual String * lastFolder();
+ virtual void setLastFolder(String * folder);
+ virtual String * lastFolder();
virtual void tryAutomaticDisconnect();
virtual void queueStartRunning();
@@ -138,6 +148,8 @@ namespace mailcore {
virtual void setOwner(IMAPAsyncSession * owner);
virtual IMAPAsyncSession * owner();
+
+ virtual void logConnection(ConnectionLogType logType, Data * buffer);
};
}
diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc
index 7c085e4a..6981322e 100644
--- a/src/async/imap/MCIMAPAsyncSession.cc
+++ b/src/async/imap/MCIMAPAsyncSession.cc
@@ -11,6 +11,7 @@
#include "MCIMAPAsyncConnection.h"
#include "MCIMAPNamespace.h"
#include "MCOperationQueueCallback.h"
+#include "MCConnectionLogger.h"
#define DEFAULT_MAX_CONNECTIONS 3
@@ -26,6 +27,7 @@ IMAPAsyncSession::IMAPAsyncSession()
mPort = 0;
mUsername = NULL;
mPassword = NULL;
+ mOAuth2Token = NULL;
mAuthType = AuthTypeSASLNone;
mConnectionType = ConnectionTypeClear;
mCheckCertificateEnabled = true;
@@ -33,11 +35,17 @@ IMAPAsyncSession::IMAPAsyncSession()
mDelimiter = 0;
mDefaultNamespace = NULL;
mTimeout = 30.;
+ mConnectionLogger = NULL;
}
IMAPAsyncSession::~IMAPAsyncSession()
{
MC_SAFE_RELEASE(mSessions);
+ MC_SAFE_RELEASE(mHostname);
+ MC_SAFE_RELEASE(mUsername);
+ MC_SAFE_RELEASE(mPassword);
+ MC_SAFE_RELEASE(mOAuth2Token);
+ MC_SAFE_RELEASE(mDefaultNamespace);
}
void IMAPAsyncSession::setHostname(String * hostname)
@@ -80,6 +88,16 @@ String * IMAPAsyncSession::password()
return mPassword;
}
+void IMAPAsyncSession::setOAuth2Token(String * token)
+{
+ MC_SAFE_REPLACE_COPY(String, mOAuth2Token, token);
+}
+
+String * IMAPAsyncSession::OAuth2Token()
+{
+ return mOAuth2Token;
+}
+
void IMAPAsyncSession::setAuthType(AuthType authType)
{
mAuthType = authType;
@@ -174,6 +192,7 @@ unsigned int IMAPAsyncSession::maximumConnections()
IMAPAsyncConnection * IMAPAsyncSession::session()
{
IMAPAsyncConnection * session = new IMAPAsyncConnection();
+ session->setConnectionLogger(mConnectionLogger);
session->setOwner(this);
session->autorelease();
@@ -181,6 +200,7 @@ IMAPAsyncConnection * IMAPAsyncSession::session()
session->setPort(mPort);
session->setUsername(mUsername);
session->setPassword(mPassword);
+ session->setOAuth2Token(mOAuth2Token);
session->setAuthType(mAuthType);
session->setConnectionType(mConnectionType);
session->setTimeout(mTimeout);
@@ -429,3 +449,16 @@ IMAPCapabilityOperation * IMAPAsyncSession::capabilityOperation()
return session->capabilityOperation();
}
+void IMAPAsyncSession::setConnectionLogger(ConnectionLogger * logger)
+{
+ mConnectionLogger = logger;
+ for(unsigned int i = 0 ; i < mSessions->count() ; i ++) {
+ IMAPAsyncConnection * currentSession = (IMAPAsyncConnection *) mSessions->objectAtIndex(i);
+ currentSession->setConnectionLogger(logger);
+ }
+}
+
+ConnectionLogger * IMAPAsyncSession::connectionLogger()
+{
+ return mConnectionLogger;
+}
diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h
index 390fdab8..ae1bbb90 100644
--- a/src/async/imap/MCIMAPAsyncSession.h
+++ b/src/async/imap/MCIMAPAsyncSession.h
@@ -51,6 +51,11 @@ namespace mailcore {
virtual void setPassword(String * password);
virtual String * password();
+ // To authenticate using OAuth2, username and oauth2token should be set.
+ // auth type to use is AuthTypeOAuth2.
+ virtual void setOAuth2Token(String * token);
+ virtual String * OAuth2Token();
+
virtual void setAuthType(AuthType authType);
virtual AuthType authType();
@@ -78,6 +83,9 @@ namespace mailcore {
virtual void setMaximumConnections(unsigned int maxConnections);
virtual unsigned int maximumConnections();
+ virtual void setConnectionLogger(ConnectionLogger * logger);
+ virtual ConnectionLogger * connectionLogger();
+
virtual IMAPFolderInfoOperation * folderInfoOperation(String * folder);
virtual IMAPFolderStatusOperation * folderStatusOperation(String * folder);
@@ -124,7 +132,7 @@ namespace mailcore {
virtual IMAPOperation * checkAccountOperation();
virtual IMAPCapabilityOperation * capabilityOperation();
-
+
private:
Array * mSessions;
@@ -132,6 +140,7 @@ namespace mailcore {
unsigned int mPort;
String * mUsername;
String * mPassword;
+ String * mOAuth2Token;
AuthType mAuthType;
ConnectionType mConnectionType;
bool mCheckCertificateEnabled;
@@ -141,6 +150,7 @@ namespace mailcore {
time_t mTimeout;
bool mAllowsFolderConcurrentAccessEnabled;
unsigned int mMaximumConnections;
+ ConnectionLogger * mConnectionLogger;
virtual IMAPAsyncConnection * sessionForFolder(String * folder, bool urgent = false);
virtual IMAPAsyncConnection * session();
diff --git a/src/async/pop/MCPOPAsyncSession.cc b/src/async/pop/MCPOPAsyncSession.cc
index 1269a34b..342b0f5e 100644
--- a/src/async/pop/MCPOPAsyncSession.cc
+++ b/src/async/pop/MCPOPAsyncSession.cc
@@ -15,6 +15,7 @@
#include "MCPOPFetchMessagesOperation.h"
#include "MCPOPCheckAccountOperation.h"
#include "MCOperationQueueCallback.h"
+#include "MCConnectionLogger.h"
using namespace mailcore;
@@ -28,17 +29,35 @@ namespace mailcore {
virtual ~POPOperationQueueCallback() {
}
- virtual void queueStartRunning() {
+ virtual void queueStartRunning(OperationQueue * queue) {
mSession->retain();
}
- virtual void queueStoppedRunning() {
+ virtual void queueStoppedRunning(OperationQueue * queue) {
mSession->release();
}
private:
POPAsyncSession * mSession;
};
+
+ class POPConnectionLogger : public Object, public ConnectionLogger {
+ public:
+ POPConnectionLogger(POPAsyncSession * session) {
+ mSession = session;
+ }
+
+ virtual ~POPConnectionLogger() {
+ }
+
+ virtual void log(void * context, void * sender, ConnectionLogType logType, Data * buffer)
+ {
+ mSession->logConnection(logType, buffer);
+ }
+
+ private:
+ POPAsyncSession * mSession;
+ };
}
POPAsyncSession::POPAsyncSession()
@@ -47,10 +66,16 @@ POPAsyncSession::POPAsyncSession()
mQueue = new OperationQueue();
mQueueCallback = new POPOperationQueueCallback(this);
mQueue->setCallback(mQueueCallback);
+ mConnectionLogger = NULL;
+ pthread_mutex_init(&mConnectionLoggerLock, NULL);
+ mInternalLogger = new POPConnectionLogger(this);
+ mSession->setConnectionLogger(mInternalLogger);
}
POPAsyncSession::~POPAsyncSession()
{
+ MC_SAFE_RELEASE(mInternalLogger);
+ pthread_mutex_destroy(&mConnectionLoggerLock);
MC_SAFE_RELEASE(mQueueCallback);
MC_SAFE_RELEASE(mSession);
MC_SAFE_RELEASE(mQueue);
@@ -193,3 +218,36 @@ void POPAsyncSession::runOperation(POPOperation * operation)
{
mQueue->addOperation(operation);
}
+
+void POPAsyncSession::setConnectionLogger(ConnectionLogger * logger)
+{
+ pthread_mutex_lock(&mConnectionLoggerLock);
+ mConnectionLogger = logger;
+ if (mConnectionLogger != NULL) {
+ mSession->setConnectionLogger(mInternalLogger);
+ }
+ else {
+ mSession->setConnectionLogger(NULL);
+ }
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+}
+
+ConnectionLogger * POPAsyncSession::connectionLogger()
+{
+ ConnectionLogger * result;
+
+ pthread_mutex_lock(&mConnectionLoggerLock);
+ result = mConnectionLogger;
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+
+ return result;
+}
+
+void POPAsyncSession::logConnection(ConnectionLogType logType, Data * buffer)
+{
+ pthread_mutex_lock(&mConnectionLoggerLock);
+ if (mConnectionLogger != NULL) {
+ mConnectionLogger->log(this, logType, buffer);
+ }
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+}
diff --git a/src/async/pop/MCPOPAsyncSession.h b/src/async/pop/MCPOPAsyncSession.h
index 452d4d75..0345ecd6 100644
--- a/src/async/pop/MCPOPAsyncSession.h
+++ b/src/async/pop/MCPOPAsyncSession.h
@@ -23,6 +23,7 @@ namespace mailcore {
class POPDeleteMessagesOperation;
class POPFetchMessagesOperation;
class POPOperationQueueCallback;
+ class POPConnectionLogger;
class POPAsyncSession : public Object {
public:
@@ -53,6 +54,9 @@ namespace mailcore {
virtual void setCheckCertificateEnabled(bool enabled);
virtual bool isCheckCertificateEnabled();
+ virtual void setConnectionLogger(ConnectionLogger * logger);
+ virtual ConnectionLogger * connectionLogger();
+
virtual POPFetchMessagesOperation * fetchMessagesOperation();
virtual POPFetchHeaderOperation * fetchHeaderOperation(unsigned int index);
@@ -70,11 +74,14 @@ namespace mailcore {
POPSession * mSession;
OperationQueue * mQueue;
POPOperationQueueCallback * mQueueCallback;
+ ConnectionLogger * mConnectionLogger;
+ pthread_mutex_t mConnectionLoggerLock;
+ POPConnectionLogger * mInternalLogger;
public: // private
virtual void runOperation(POPOperation * operation);
virtual POPSession * session();
-
+ virtual void logConnection(ConnectionLogType logType, Data * buffer);
};
}
diff --git a/src/async/smtp/MCSMTPAsyncSession.cc b/src/async/smtp/MCSMTPAsyncSession.cc
index 723c0330..fafc2e82 100644
--- a/src/async/smtp/MCSMTPAsyncSession.cc
+++ b/src/async/smtp/MCSMTPAsyncSession.cc
@@ -19,11 +19,11 @@ namespace mailcore {
virtual ~SMTPOperationQueueCallback() {
}
- virtual void queueStartRunning() {
+ virtual void queueStartRunning(OperationQueue * queue) {
mSession->retain();
}
- virtual void queueStoppedRunning() {
+ virtual void queueStoppedRunning(OperationQueue * queue) {
mSession->tryAutomaticDisconnect();
mSession->release();
}
@@ -31,6 +31,24 @@ namespace mailcore {
private:
SMTPAsyncSession * mSession;
};
+
+ class SMTPConnectionLogger : public Object, public ConnectionLogger {
+ public:
+ SMTPConnectionLogger(SMTPAsyncSession * session) {
+ mSession = session;
+ }
+
+ virtual ~SMTPConnectionLogger() {
+ }
+
+ virtual void log(void * context, void * sender, ConnectionLogType logType, Data * buffer)
+ {
+ mSession->logConnection(logType, buffer);
+ }
+
+ private:
+ SMTPAsyncSession * mSession;
+ };
}
SMTPAsyncSession::SMTPAsyncSession()
@@ -39,10 +57,16 @@ SMTPAsyncSession::SMTPAsyncSession()
mQueue = new OperationQueue();
mQueueCallback = new SMTPOperationQueueCallback(this);
mQueue->setCallback(mQueueCallback);
+ mConnectionLogger = NULL;
+ pthread_mutex_init(&mConnectionLoggerLock, NULL);
+ mInternalLogger = new SMTPConnectionLogger(this);
+ mSession->setConnectionLogger(mInternalLogger);
}
SMTPAsyncSession::~SMTPAsyncSession()
{
+ MC_SAFE_RELEASE(mInternalLogger);
+ pthread_mutex_destroy(&mConnectionLoggerLock);
cancelDelayedPerformMethod((Object::Method) &SMTPAsyncSession::tryAutomaticDisconnectAfterDelay, NULL);
MC_SAFE_RELEASE(mQueueCallback);
MC_SAFE_RELEASE(mQueue);
@@ -184,3 +208,36 @@ SMTPOperation * SMTPAsyncSession::checkAccountOperation(Address * from)
op->setSession(this);
return (SMTPOperation *) op->autorelease();
}
+
+void SMTPAsyncSession::setConnectionLogger(ConnectionLogger * logger)
+{
+ pthread_mutex_lock(&mConnectionLoggerLock);
+ mConnectionLogger = logger;
+ if (mConnectionLogger != NULL) {
+ mSession->setConnectionLogger(mInternalLogger);
+ }
+ else {
+ mSession->setConnectionLogger(NULL);
+ }
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+}
+
+ConnectionLogger * SMTPAsyncSession::connectionLogger()
+{
+ ConnectionLogger * result;
+
+ pthread_mutex_lock(&mConnectionLoggerLock);
+ result = mConnectionLogger;
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+
+ return result;
+}
+
+void SMTPAsyncSession::logConnection(ConnectionLogType logType, Data * buffer)
+{
+ pthread_mutex_lock(&mConnectionLoggerLock);
+ if (mConnectionLogger != NULL) {
+ mConnectionLogger->log(this, logType, buffer);
+ }
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+}
diff --git a/src/async/smtp/MCSMTPAsyncSession.h b/src/async/smtp/MCSMTPAsyncSession.h
index 9cd7a8f0..9fa6dbdf 100644
--- a/src/async/smtp/MCSMTPAsyncSession.h
+++ b/src/async/smtp/MCSMTPAsyncSession.h
@@ -14,6 +14,7 @@ namespace mailcore {
class SMTPSession;
class Address;
class SMTPOperationQueueCallback;
+ class SMTPConnectionLogger;
class SMTPAsyncSession : public Object {
public:
@@ -47,6 +48,9 @@ namespace mailcore {
virtual void setUseHeloIPEnabled(bool enabled);
virtual bool useHeloIPEnabled();
+ virtual void setConnectionLogger(ConnectionLogger * logger);
+ virtual ConnectionLogger * connectionLogger();
+
virtual SMTPOperation * sendMessageOperation(Data * messageData);
virtual SMTPOperation * checkAccountOperation(Address * from);
@@ -54,11 +58,15 @@ namespace mailcore {
virtual void runOperation(SMTPOperation * operation);
virtual SMTPSession * session();
virtual void tryAutomaticDisconnect();
-
+ virtual void logConnection(ConnectionLogType logType, Data * buffer);
+
private:
SMTPSession * mSession;
OperationQueue * mQueue;
SMTPOperationQueueCallback * mQueueCallback;
+ ConnectionLogger * mConnectionLogger;
+ pthread_mutex_t mConnectionLoggerLock;
+ SMTPConnectionLogger * mInternalLogger;
virtual void tryAutomaticDisconnectAfterDelay(void * context);
};
diff --git a/src/core/abstract/MCMessageConstants.h b/src/core/abstract/MCMessageConstants.h
index 417bdb6c..9e1b46b7 100644
--- a/src/core/abstract/MCMessageConstants.h
+++ b/src/core/abstract/MCMessageConstants.h
@@ -4,214 +4,215 @@
#ifdef __cplusplus
namespace mailcore {
-
- enum ConnectionType {
- ConnectionTypeClear = 1 << 0,
- ConnectionTypeStartTLS = 1 << 1,
- ConnectionTypeTLS = 1 << 2,
- };
+
+ enum ConnectionType {
+ ConnectionTypeClear = 1 << 0,
+ ConnectionTypeStartTLS = 1 << 1,
+ ConnectionTypeTLS = 1 << 2,
+ };
- enum AuthType {
- AuthTypeSASLNone = 0,
- AuthTypeSASLCRAMMD5 = 1 << 0,
- AuthTypeSASLPlain = 1 << 1,
- AuthTypeSASLGSSAPI = 1 << 2,
- AuthTypeSASLDIGESTMD5 = 1 << 3,
- AuthTypeSASLLogin = 1 << 4,
- AuthTypeSASLSRP = 1 << 5,
- AuthTypeSASLNTLM = 1 << 6,
- AuthTypeSASLKerberosV4 = 1 << 7,
- };
+ enum AuthType {
+ AuthTypeSASLNone = 0,
+ AuthTypeSASLCRAMMD5 = 1 << 0,
+ AuthTypeSASLPlain = 1 << 1,
+ AuthTypeSASLGSSAPI = 1 << 2,
+ AuthTypeSASLDIGESTMD5 = 1 << 3,
+ AuthTypeSASLLogin = 1 << 4,
+ AuthTypeSASLSRP = 1 << 5,
+ AuthTypeSASLNTLM = 1 << 6,
+ AuthTypeSASLKerberosV4 = 1 << 7,
+ AuthTypeXOAuth2 = 1 << 8,
+ };
- enum IMAPFolderFlag {
- IMAPFolderFlagNone = 0,
- IMAPFolderFlagMarked = 1 << 0,
- IMAPFolderFlagUnmarked = 1 << 1,
- IMAPFolderFlagNoSelect = 1 << 2,
- IMAPFolderFlagNoInferiors = 1 << 3,
- IMAPFolderFlagInbox = 1 << 4,
- IMAPFolderFlagSentMail = 1 << 5,
- IMAPFolderFlagStarred = 1 << 6,
- IMAPFolderFlagAllMail = 1 << 7,
- IMAPFolderFlagTrash = 1 << 8,
- IMAPFolderFlagDrafts = 1 << 9,
- IMAPFolderFlagSpam = 1 << 10,
- IMAPFolderFlagImportant = 1 << 11,
- IMAPFolderFlagArchive = 1 << 12,
+ enum IMAPFolderFlag {
+ IMAPFolderFlagNone = 0,
+ IMAPFolderFlagMarked = 1 << 0,
+ IMAPFolderFlagUnmarked = 1 << 1,
+ IMAPFolderFlagNoSelect = 1 << 2,
+ IMAPFolderFlagNoInferiors = 1 << 3,
+ IMAPFolderFlagInbox = 1 << 4,
+ IMAPFolderFlagSentMail = 1 << 5,
+ IMAPFolderFlagStarred = 1 << 6,
+ IMAPFolderFlagAllMail = 1 << 7,
+ IMAPFolderFlagTrash = 1 << 8,
+ IMAPFolderFlagDrafts = 1 << 9,
+ IMAPFolderFlagSpam = 1 << 10,
+ IMAPFolderFlagImportant = 1 << 11,
+ IMAPFolderFlagArchive = 1 << 12,
IMAPFolderFlagAll = IMAPFolderFlagAllMail,
IMAPFolderFlagJunk = IMAPFolderFlagSpam,
IMAPFolderFlagFlagged = IMAPFolderFlagStarred,
- };
+ };
- enum MessageFlag {
- MessageFlagNone = 0,
- MessageFlagSeen = 1 << 0,
- MessageFlagAnswered = 1 << 1,
- MessageFlagFlagged = 1 << 2,
- MessageFlagDeleted = 1 << 3,
- MessageFlagDraft = 1 << 4,
- MessageFlagMDNSent = 1 << 5,
- MessageFlagForwarded = 1 << 6,
- MessageFlagSubmitPending = 1 << 7,
- MessageFlagSubmitted = 1 << 8,
- } ;
+ enum MessageFlag {
+ MessageFlagNone = 0,
+ MessageFlagSeen = 1 << 0,
+ MessageFlagAnswered = 1 << 1,
+ MessageFlagFlagged = 1 << 2,
+ MessageFlagDeleted = 1 << 3,
+ MessageFlagDraft = 1 << 4,
+ MessageFlagMDNSent = 1 << 5,
+ MessageFlagForwarded = 1 << 6,
+ MessageFlagSubmitPending = 1 << 7,
+ MessageFlagSubmitted = 1 << 8,
+ } ;
- enum IMAPMessagesRequestKind {
- IMAPMessagesRequestKindUid = 0, // This is the default and it's always fetched
- IMAPMessagesRequestKindFlags = 1 << 0,
- IMAPMessagesRequestKindHeaders = 1 << 1,
- IMAPMessagesRequestKindStructure = 1 << 2,
- IMAPMessagesRequestKindInternalDate = 1 << 3,
- IMAPMessagesRequestKindFullHeaders = 1 << 4,
- IMAPMessagesRequestKindHeaderSubject = 1 << 5,
- IMAPMessagesRequestKindGmailLabels = 1 << 6,
- IMAPMessagesRequestKindGmailMessageID = 1 << 7,
- IMAPMessagesRequestKindGmailThreadID = 1 << 8,
- };
+ enum IMAPMessagesRequestKind {
+ IMAPMessagesRequestKindUid = 0, // This is the default and it's always fetched
+ IMAPMessagesRequestKindFlags = 1 << 0,
+ IMAPMessagesRequestKindHeaders = 1 << 1,
+ IMAPMessagesRequestKindStructure = 1 << 2,
+ IMAPMessagesRequestKindInternalDate = 1 << 3,
+ IMAPMessagesRequestKindFullHeaders = 1 << 4,
+ IMAPMessagesRequestKindHeaderSubject = 1 << 5,
+ IMAPMessagesRequestKindGmailLabels = 1 << 6,
+ IMAPMessagesRequestKindGmailMessageID = 1 << 7,
+ IMAPMessagesRequestKindGmailThreadID = 1 << 8,
+ };
- enum IMAPFetchRequestType {
- IMAPFetchRequestTypeUID = 0,
- IMAPFetchRequestTypeSequence = 1
- };
+ enum IMAPFetchRequestType {
+ IMAPFetchRequestTypeUID = 0,
+ IMAPFetchRequestTypeSequence = 1
+ };
- enum IMAPStoreFlagsRequestKind {
- IMAPStoreFlagsRequestKindAdd,
- IMAPStoreFlagsRequestKindRemove,
- IMAPStoreFlagsRequestKindSet,
- };
+ enum IMAPStoreFlagsRequestKind {
+ IMAPStoreFlagsRequestKindAdd,
+ IMAPStoreFlagsRequestKindRemove,
+ IMAPStoreFlagsRequestKindSet,
+ };
- enum IMAPWorkaround {
- IMAPWorkaroundGmail = 1 << 0,
- IMAPWorkaroundYahoo = 1 << 1,
- IMAPWorkaroundExchange2003 = 1 << 2,
- };
+ enum IMAPWorkaround {
+ IMAPWorkaroundGmail = 1 << 0,
+ IMAPWorkaroundYahoo = 1 << 1,
+ IMAPWorkaroundExchange2003 = 1 << 2,
+ };
- enum IMAPCapability {
- IMAPCapabilityACL,
- IMAPCapabilityBinary,
- IMAPCapabilityCatenate,
- IMAPCapabilityChildren,
- IMAPCapabilityCompressDeflate,
- IMAPCapabilityCondstore,
- IMAPCapabilityEnable,
- IMAPCapabilityIdle,
- IMAPCapabilityId,
- IMAPCapabilityLiteralPlus,
- IMAPCapabilityMultiAppend,
- IMAPCapabilityNamespace,
- IMAPCapabilityQResync,
- IMAPCapabilityQuota,
- IMAPCapabilitySort,
- IMAPCapabilityStartTLS,
- IMAPCapabilityThreadOrderedSubject,
- IMAPCapabilityThreadReferences,
- IMAPCapabilityUIDPlus,
- IMAPCapabilityUnselect,
- IMAPCapabilityXList,
- IMAPCapabilityAuthAnonymous,
- IMAPCapabilityAuthCRAMMD5,
- IMAPCapabilityAuthDigestMD5,
- IMAPCapabilityAuthExternal,
- IMAPCapabilityAuthGSSAPI,
- IMAPCapabilityAuthKerberosV4,
- IMAPCapabilityAuthLogin,
- IMAPCapabilityAuthNTLM,
- IMAPCapabilityAuthOTP,
- IMAPCapabilityAuthPlain,
- IMAPCapabilityAuthSKey,
- IMAPCapabilityAuthSRP,
- };
+ enum IMAPCapability {
+ IMAPCapabilityACL,
+ IMAPCapabilityBinary,
+ IMAPCapabilityCatenate,
+ IMAPCapabilityChildren,
+ IMAPCapabilityCompressDeflate,
+ IMAPCapabilityCondstore,
+ IMAPCapabilityEnable,
+ IMAPCapabilityIdle,
+ IMAPCapabilityId,
+ IMAPCapabilityLiteralPlus,
+ IMAPCapabilityMultiAppend,
+ IMAPCapabilityNamespace,
+ IMAPCapabilityQResync,
+ IMAPCapabilityQuota,
+ IMAPCapabilitySort,
+ IMAPCapabilityStartTLS,
+ IMAPCapabilityThreadOrderedSubject,
+ IMAPCapabilityThreadReferences,
+ IMAPCapabilityUIDPlus,
+ IMAPCapabilityUnselect,
+ IMAPCapabilityXList,
+ IMAPCapabilityAuthAnonymous,
+ IMAPCapabilityAuthCRAMMD5,
+ IMAPCapabilityAuthDigestMD5,
+ IMAPCapabilityAuthExternal,
+ IMAPCapabilityAuthGSSAPI,
+ IMAPCapabilityAuthKerberosV4,
+ IMAPCapabilityAuthLogin,
+ IMAPCapabilityAuthNTLM,
+ IMAPCapabilityAuthOTP,
+ IMAPCapabilityAuthPlain,
+ IMAPCapabilityAuthSKey,
+ IMAPCapabilityAuthSRP,
+ };
- enum POPCapability {
- POPCapabilityNone,
- POPCapabilityStartTLS,
- POPCapabilityTop,
- POPCapabilityUser,
- POPCapabilityRespCodes,
- POPCapabilityPipelining,
- POPCapabilityUIDL,
- POPCapabilitySASL,
- POPCapabilityAuthAnonymous,
- POPCapabilityAuthCRAMMD5,
- POPCapabilityAuthDigestMD5,
- POPCapabilityAuthExternal,
- POPCapabilityAuthGSSAPI,
- POPCapabilityAuthKerberosV4,
- POPCapabilityAuthLogin,
- POPCapabilityAuthNTLM,
- POPCapabilityAuthOTP,
- POPCapabilityAuthPlain,
- POPCapabilityAuthSKey,
- POPCapabilityAuthSRP,
- };
+ enum POPCapability {
+ POPCapabilityNone,
+ POPCapabilityStartTLS,
+ POPCapabilityTop,
+ POPCapabilityUser,
+ POPCapabilityRespCodes,
+ POPCapabilityPipelining,
+ POPCapabilityUIDL,
+ POPCapabilitySASL,
+ POPCapabilityAuthAnonymous,
+ POPCapabilityAuthCRAMMD5,
+ POPCapabilityAuthDigestMD5,
+ POPCapabilityAuthExternal,
+ POPCapabilityAuthGSSAPI,
+ POPCapabilityAuthKerberosV4,
+ POPCapabilityAuthLogin,
+ POPCapabilityAuthNTLM,
+ POPCapabilityAuthOTP,
+ POPCapabilityAuthPlain,
+ POPCapabilityAuthSKey,
+ POPCapabilityAuthSRP,
+ };
- enum Encoding {
- Encoding7Bit = 0, // should match MAILIMAP_BODY_FLD_ENC_7BIT
- Encoding8Bit = 1, // should match MAILIMAP_BODY_FLD_ENC_8BIT
- EncodingBinary = 2, // should match MAILIMAP_BODY_FLD_ENC_BINARY
- EncodingBase64 = 3, // should match MAILIMAP_BODY_FLD_ENC_BASE64
- EncodingQuotedPrintable = 4, // should match MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE
- EncodingOther = 5, // should match MAILIMAP_BODY_FLD_ENC_OTHER
- // negative values should be used for other encoding
- EncodingUUEncode = -1
- };
-
- enum IMAPSearchKind {
- IMAPSearchKindNone,
- IMAPSearchKindFrom,
- IMAPSearchKindRecipient,
- IMAPSearchKindSubject,
- IMAPSearchKindContent,
- IMAPSearchKindHeader,
- IMAPSearchKindOr,
- IMAPSearchKindAnd,
- };
-
- enum ErrorCode {
- ErrorNone,
- ErrorConnection,
- ErrorTLSNotAvailable,
- ErrorParse,
- ErrorCertificate,
- ErrorAuthentication,
- ErrorGmailIMAPNotEnabled,
- ErrorGmailExceededBandwidthLimit,
- ErrorGmailTooManySimultaneousConnections,
- ErrorMobileMeMoved,
- ErrorYahooUnavailable,
- ErrorNonExistantFolder,
- ErrorRename,
- ErrorDelete,
- ErrorCreate,
- ErrorSubscribe,
- ErrorAppend,
- ErrorCopy,
- ErrorExpunge,
- ErrorFetch,
- ErrorIdle,
- ErrorIdentity,
- ErrorNamespace,
- ErrorStore,
+ enum Encoding {
+ Encoding7Bit = 0, // should match MAILIMAP_BODY_FLD_ENC_7BIT
+ Encoding8Bit = 1, // should match MAILIMAP_BODY_FLD_ENC_8BIT
+ EncodingBinary = 2, // should match MAILIMAP_BODY_FLD_ENC_BINARY
+ EncodingBase64 = 3, // should match MAILIMAP_BODY_FLD_ENC_BASE64
+ EncodingQuotedPrintable = 4, // should match MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE
+ EncodingOther = 5, // should match MAILIMAP_BODY_FLD_ENC_OTHER
+ // negative values should be used for other encoding
+ EncodingUUEncode = -1
+ };
+
+ enum IMAPSearchKind {
+ IMAPSearchKindNone,
+ IMAPSearchKindFrom,
+ IMAPSearchKindRecipient,
+ IMAPSearchKindSubject,
+ IMAPSearchKindContent,
+ IMAPSearchKindHeader,
+ IMAPSearchKindOr,
+ IMAPSearchKindAnd,
+ };
+
+ enum ErrorCode {
+ ErrorNone,
+ ErrorConnection,
+ ErrorTLSNotAvailable,
+ ErrorParse,
+ ErrorCertificate,
+ ErrorAuthentication,
+ ErrorGmailIMAPNotEnabled,
+ ErrorGmailExceededBandwidthLimit,
+ ErrorGmailTooManySimultaneousConnections,
+ ErrorMobileMeMoved,
+ ErrorYahooUnavailable,
+ ErrorNonExistantFolder,
+ ErrorRename,
+ ErrorDelete,
+ ErrorCreate,
+ ErrorSubscribe,
+ ErrorAppend,
+ ErrorCopy,
+ ErrorExpunge,
+ ErrorFetch,
+ ErrorIdle,
+ ErrorIdentity,
+ ErrorNamespace,
+ ErrorStore,
ErrorCapability,
- ErrorStartTLSNotAvailable,
- ErrorSendMessageIllegalAttachment,
- ErrorStorageLimit,
- ErrorSendMessageNotAllowed,
- ErrorNeedsConnectToWebmail,
- ErrorSendMessage,
- ErrorAuthenticationRequired,
- ErrorFetchMessageList,
- ErrorDeleteMessage,
+ ErrorStartTLSNotAvailable,
+ ErrorSendMessageIllegalAttachment,
+ ErrorStorageLimit,
+ ErrorSendMessageNotAllowed,
+ ErrorNeedsConnectToWebmail,
+ ErrorSendMessage,
+ ErrorAuthenticationRequired,
+ ErrorFetchMessageList,
+ ErrorDeleteMessage,
ErrorInvalidAccount,
- };
-
- enum PartType {
- PartTypeSingle,
- PartTypeMessage,
- PartTypeMultipartMixed,
- PartTypeMultipartRelated,
- PartTypeMultipartAlternative,
- };
+ };
+
+ enum PartType {
+ PartTypeSingle,
+ PartTypeMessage,
+ PartTypeMultipartMixed,
+ PartTypeMultipartRelated,
+ PartTypeMultipartAlternative,
+ };
}
#endif
diff --git a/src/core/basetypes/MCConnectionLogger.h b/src/core/basetypes/MCConnectionLogger.h
index 8083d12d..dd596857 100644
--- a/src/core/basetypes/MCConnectionLogger.h
+++ b/src/core/basetypes/MCConnectionLogger.h
@@ -9,6 +9,8 @@
#ifndef __MAILCORE_CONNECTION_LOGGER_H_
#define __MAILCORE_CONNECTION_LOGGER_H_
+#include <stdlib.h>
+
#ifdef __cplusplus
namespace mailcore {
@@ -17,20 +19,23 @@ namespace mailcore {
class String;
enum ConnectionLogType {
- ConnectionLogTypeGeneric,
+ // Received data
ConnectionLogTypeReceived,
+ // Sent data
ConnectionLogTypeSent,
+ // Sent private data
ConnectionLogTypeSentPrivate,
- ConnectionLogTypeErrorGeneric,
+ // Parse error
+ ConnectionLogTypeErrorParse,
+ // Error while receiving data - log() is called with a NULL buffer.
ConnectionLogTypeErrorReceived,
+ // Error while sending data - log() is called with a NULL buffer.
ConnectionLogTypeErrorSent,
- ConnectionLogTypeErrorSentPrivate,
};
class ConnectionLogger {
public:
- virtual void logBuffer(ConnectionLogType logType, Data * buffer) {}
- virtual void logString(ConnectionLogType logType, String * log) {}
+ virtual void log(void * sender, ConnectionLogType logType, Data * buffer) {}
};
}
diff --git a/src/core/basetypes/MCConnectionLoggerUtils.cc b/src/core/basetypes/MCConnectionLoggerUtils.cc
index 669c8449..234713e7 100644
--- a/src/core/basetypes/MCConnectionLoggerUtils.cc
+++ b/src/core/basetypes/MCConnectionLoggerUtils.cc
@@ -14,21 +14,12 @@
mailcore::ConnectionLogType mailcore::getConnectionType(int log_type)
{
- ConnectionLogType type = ConnectionLogTypeGeneric;
+ ConnectionLogType type = (ConnectionLogType) -1;
bool isBuffer = false;
switch (log_type) {
- case MAILSTREAM_LOG_TYPE_INFO_GENERIC:
- type = ConnectionLogTypeGeneric;
- break;
- case MAILSTREAM_LOG_TYPE_INFO_RECEIVED:
- type = ConnectionLogTypeReceived;
- break;
- case MAILSTREAM_LOG_TYPE_INFO_SENT:
- type = ConnectionLogTypeSent;
- break;
- case MAILSTREAM_LOG_TYPE_ERROR_GENERIC:
- type = ConnectionLogTypeErrorGeneric;
+ case MAILSTREAM_LOG_TYPE_ERROR_PARSE:
+ type = ConnectionLogTypeErrorParse;
isBuffer = true;
break;
case MAILSTREAM_LOG_TYPE_ERROR_RECEIVED:
@@ -60,9 +51,7 @@ bool mailcore::isBufferFromLogType(int log_type)
bool isBuffer = false;
switch (log_type) {
- case MAILSTREAM_LOG_TYPE_ERROR_GENERIC:
- case MAILSTREAM_LOG_TYPE_ERROR_RECEIVED:
- case MAILSTREAM_LOG_TYPE_ERROR_SENT:
+ case MAILSTREAM_LOG_TYPE_ERROR_PARSE:
case MAILSTREAM_LOG_TYPE_DATA_RECEIVED:
case MAILSTREAM_LOG_TYPE_DATA_SENT:
case MAILSTREAM_LOG_TYPE_DATA_SENT_PRIVATE:
diff --git a/src/core/basetypes/MCHTMLCleaner.cc b/src/core/basetypes/MCHTMLCleaner.cc
index 12f1371e..7d45d3f2 100644
--- a/src/core/basetypes/MCHTMLCleaner.cc
+++ b/src/core/basetypes/MCHTMLCleaner.cc
@@ -68,6 +68,7 @@ String * HTMLCleaner::cleanHTML(String * input)
String * result = String::stringWithUTF8Characters((const char *) output.bp);
+ tidyBufFree(&docbuf);
tidyBufFree(&output);
tidyBufFree(&errbuf);
tidyRelease(tdoc);
diff --git a/src/core/basetypes/MCLibetpan.cpp b/src/core/basetypes/MCLibetpan.cpp
new file mode 100644
index 00000000..c8258cc2
--- /dev/null
+++ b/src/core/basetypes/MCLibetpan.cpp
@@ -0,0 +1,16 @@
+//
+// MCLibetpan.cpp
+// mailcore2
+//
+// Created by Hoa Dinh on 6/28/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#include "MCLibetpan.h"
+
+#include <libetpan/libetpan.h>
+
+__attribute__((constructor))
+static void initialize() {
+ mailstream_cfstream_enabled = 1;
+}
diff --git a/src/core/basetypes/MCLibetpan.h b/src/core/basetypes/MCLibetpan.h
new file mode 100644
index 00000000..ef7db1f8
--- /dev/null
+++ b/src/core/basetypes/MCLibetpan.h
@@ -0,0 +1,14 @@
+//
+// MCLibetpan.h
+// mailcore2
+//
+// Created by Hoa Dinh on 6/28/13.
+// Copyright (c) 2013 MailCore. All rights reserved.
+//
+
+#ifndef __MAILCORE_MCLIBETPAN_H_
+#define __MAILCORE_MCLIBETPAN_H_
+
+// No API in this file.
+
+#endif
diff --git a/src/core/basetypes/MCObject.cc b/src/core/basetypes/MCObject.cc
index 879c194f..235738cd 100644
--- a/src/core/basetypes/MCObject.cc
+++ b/src/core/basetypes/MCObject.cc
@@ -83,7 +83,9 @@ String * Object::className()
{
int status;
char * unmangled = abi::__cxa_demangle(typeid(* this).name(), NULL, NULL, &status);
- return mailcore::String::uniquedStringWithUTF8Characters(unmangled);
+ String * result = String::uniquedStringWithUTF8Characters(unmangled);
+ free(unmangled);
+ return result;
}
String * Object::description()
diff --git a/src/core/basetypes/MCOperationQueue.cc b/src/core/basetypes/MCOperationQueue.cc
index d4529fab..9c30ad22 100644
--- a/src/core/basetypes/MCOperationQueue.cc
+++ b/src/core/basetypes/MCOperationQueue.cc
@@ -159,7 +159,7 @@ void OperationQueue::stoppedOnMainThread(void * context)
mStarted = false;
if (mCallback) {
- mCallback->queueStoppedRunning();
+ mCallback->queueStoppedRunning(this);
}
release(); // (2)
@@ -173,7 +173,7 @@ void OperationQueue::startThread()
return;
if (mCallback) {
- mCallback->queueStartRunning();
+ mCallback->queueStartRunning(this);
}
retain(); // (3)
diff --git a/src/core/basetypes/MCOperationQueueCallback.h b/src/core/basetypes/MCOperationQueueCallback.h
index 367888bb..605de030 100644
--- a/src/core/basetypes/MCOperationQueueCallback.h
+++ b/src/core/basetypes/MCOperationQueueCallback.h
@@ -15,8 +15,8 @@ namespace mailcore {
class OperationQueueCallback {
public:
- virtual void queueStartRunning() {}
- virtual void queueStoppedRunning() {}
+ virtual void queueStartRunning(OperationQueue * queue) {}
+ virtual void queueStoppedRunning(OperationQueue * queue) {}
};
}
diff --git a/src/core/basetypes/MCString.cc b/src/core/basetypes/MCString.cc
index 832ffac2..034e3299 100644
--- a/src/core/basetypes/MCString.cc
+++ b/src/core/basetypes/MCString.cc
@@ -10,6 +10,9 @@
#include <libetpan/libetpan.h>
#include <libxml/xmlmemory.h>
#include <libxml/HTMLparser.h>
+#if __APPLE__
+#include <CoreFoundation/CoreFoundation.h>
+#endif
#include "MCData.h"
#include "MCHash.h"
@@ -781,7 +784,9 @@ String * String::stringWithVUTF8Format(const char * format, va_list ap)
{
char * result;
vasprintf(&result, format, ap);
- return stringWithUTF8Characters(result);
+ String * str = stringWithUTF8Characters(result);
+ free(result);
+ return str;
}
String * String::stringWithUTF8Characters(const char * UTF8Characters)
@@ -1121,6 +1126,20 @@ String * String::uppercaseString()
void String::appendBytes(const char * bytes, unsigned int length, const char * charset)
{
+#if __APPLE__
+ CFStringRef encodingName = CFStringCreateWithCString(NULL, charset, kCFStringEncodingUTF8);
+ CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding(encodingName);
+ CFStringRef cfStr = CFStringCreateWithBytes(NULL, (const UInt8 *) bytes, (CFIndex) length, encoding, false);
+ if (cfStr != NULL) {
+ CFDataRef data = CFStringCreateExternalRepresentation(NULL, cfStr, kCFStringEncodingUTF16LE, '_');
+ if (data != NULL) {
+ appendCharactersLength((const UChar *) CFDataGetBytePtr(data), (unsigned int) CFDataGetLength(data) / 2);
+ CFRelease(data);
+ }
+ CFRelease(cfStr);
+ }
+ CFRelease(encodingName);
+#else
UErrorCode err;
err = U_ZERO_ERROR;
@@ -1150,6 +1169,7 @@ void String::appendBytes(const char * bytes, unsigned int length, const char * c
free(dest);
ucnv_close(converter);
+#endif
}
String * String::extractedSubject()
@@ -1773,7 +1793,7 @@ String * String::flattenHTML()
bool String::hasSuffix(String * suffix)
{
- if (mLength > suffix->mLength) {
+ if (mLength >= suffix->mLength) {
if (u_memcmp(suffix->mUnicodeChars + (mLength - suffix->mLength),
mUnicodeChars, suffix->mLength) == 0) {
return true;
@@ -1784,7 +1804,7 @@ bool String::hasSuffix(String * suffix)
bool String::hasPrefix(String * prefix)
{
- if (mLength > prefix->mLength) {
+ if (mLength >= prefix->mLength) {
if (u_memcmp(prefix->mUnicodeChars, mUnicodeChars, prefix->mLength) == 0) {
return true;
}
@@ -1810,13 +1830,34 @@ String * String::pathExtension()
Data * String::dataUsingEncoding(const char * charset)
{
- UErrorCode err;
- Data * data;
-
if (charset == NULL) {
charset = "utf-8";
}
+#if __APPLE__
+ Data * data;
+
+ data = NULL;
+ CFStringRef encodingName = CFStringCreateWithCString(NULL, charset, kCFStringEncodingUTF8);
+ CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding(encodingName);
+ CFStringRef cfStr = CFStringCreateWithBytes(NULL, (const UInt8 *) mUnicodeChars,
+ (CFIndex) mLength * sizeof(* mUnicodeChars), kCFStringEncodingUTF16LE, false);
+ if (cfStr != NULL) {
+ CFDataRef cfData = CFStringCreateExternalRepresentation(NULL, cfStr, encoding, '_');
+ if (cfData != NULL) {
+ data = Data::dataWithBytes((const char *) CFDataGetBytePtr(cfData),
+ (unsigned int) CFDataGetLength(cfData));
+ CFRelease(cfData);
+ }
+ CFRelease(cfStr);
+ }
+ CFRelease(encodingName);
+
+ return data;
+#else
+ UErrorCode err;
+ Data * data;
+
err = U_ZERO_ERROR;
UConverter * converter = ucnv_open(charset, &err);
if (converter == NULL) {
@@ -1846,6 +1887,7 @@ Data * String::dataUsingEncoding(const char * charset)
ucnv_close(converter);
return data;
+#endif
}
const char * String::fileSystemRepresentation()
diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc
index c3327872..125cae2f 100644
--- a/src/core/imap/MCIMAPSession.cc
+++ b/src/core/imap/MCIMAPSession.cc
@@ -317,6 +317,7 @@ void IMAPSession::init()
mPort = 0;
mUsername = NULL;
mPassword = NULL;
+ mOAuth2Token = NULL;
mAuthType = AuthTypeSASLNone;
mConnectionType = ConnectionTypeClear;
mCheckCertificateEnabled = true;
@@ -359,6 +360,7 @@ IMAPSession::~IMAPSession()
MC_SAFE_RELEASE(mHostname);
MC_SAFE_RELEASE(mUsername);
MC_SAFE_RELEASE(mPassword);
+ MC_SAFE_RELEASE(mOAuth2Token);
MC_SAFE_RELEASE(mWelcomeString);
MC_SAFE_RELEASE(mDefaultNamespace);
MC_SAFE_RELEASE(mCurrentFolder);
@@ -405,6 +407,16 @@ String * IMAPSession::password()
return mPassword;
}
+void IMAPSession::setOAuth2Token(String * token)
+{
+ MC_SAFE_REPLACE_COPY(String, mOAuth2Token, token);
+}
+
+String * IMAPSession::OAuth2Token()
+{
+ return mOAuth2Token;
+}
+
void IMAPSession::setAuthType(AuthType authType)
{
mAuthType = authType;
@@ -502,15 +514,17 @@ static void logger(mailimap * imap, int log_type, const char * buffer, size_t si
return;
ConnectionLogType type = getConnectionType(log_type);
+ if ((int) type == -1)
+ return;
+
bool isBuffer = isBufferFromLogType(log_type);
if (isBuffer) {
Data * data = Data::dataWithBytes(buffer, (unsigned int) size);
- session->connectionLogger()->logBuffer(type, data);
+ session->connectionLogger()->log(session, type, data);
}
else {
- Data * data = Data::dataWithBytes(buffer, (unsigned int) size);
- session->connectionLogger()->logString(type, String::stringWithData(data));
+ session->connectionLogger()->log(session, type, NULL);
}
}
@@ -748,6 +762,10 @@ void IMAPSession::login(ErrorCode * pError)
utf8username, utf8username,
utf8password, NULL/* realm */);
break;
+
+ case AuthTypeXOAuth2:
+ r = mailimap_oauth2_authenticate(mImap, MCUTF8(mUsername), MCUTF8(mOAuth2Token));
+ break;
}
if (r == MAILIMAP_ERROR_STREAM) {
* pError = ErrorConnection;
diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h
index 757613e8..53510b0b 100644
--- a/src/core/imap/MCIMAPSession.h
+++ b/src/core/imap/MCIMAPSession.h
@@ -38,6 +38,11 @@ namespace mailcore {
virtual void setPassword(String * password);
virtual String * password();
+ // To authenticate using OAuth2, username and oauth2token should be set.
+ // auth type to use is AuthTypeOAuth2.
+ virtual void setOAuth2Token(String * token);
+ virtual String * OAuth2Token();
+
virtual void setAuthType(AuthType authType);
virtual AuthType authType();
@@ -154,6 +159,7 @@ namespace mailcore {
unsigned int mPort;
String * mUsername;
String * mPassword;
+ String * mOAuth2Token;
AuthType mAuthType;
ConnectionType mConnectionType;
bool mCheckCertificateEnabled;
diff --git a/src/core/pop/MCPOPSession.cc b/src/core/pop/MCPOPSession.cc
index fe15c500..fea4e5e0 100644
--- a/src/core/pop/MCPOPSession.cc
+++ b/src/core/pop/MCPOPSession.cc
@@ -160,11 +160,10 @@ static void logger(mailpop3 * pop3, int log_type, const char * buffer, size_t si
if (isBuffer) {
Data * data = Data::dataWithBytes(buffer, (unsigned int) size);
- session->connectionLogger()->logBuffer(type, data);
+ session->connectionLogger()->log(session, type, data);
}
else {
- Data * data = Data::dataWithBytes(buffer, (unsigned int) size);
- session->connectionLogger()->logString(type, String::stringWithData(data));
+ session->connectionLogger()->log(session, type, NULL);
}
}
diff --git a/src/core/provider/MCMailProvider.cc b/src/core/provider/MCMailProvider.cc
index b814e2ea..43fd94f9 100644
--- a/src/core/provider/MCMailProvider.cc
+++ b/src/core/provider/MCMailProvider.cc
@@ -18,7 +18,7 @@ using namespace mailcore;
void MailProvider::init()
{
mIdentifier = NULL;
- mImapServices = new Array();
+ mImapServices = new Array();
mSmtpServices = new Array();
mPopServices = new Array();
mDomainMatch = new Array();
@@ -31,15 +31,27 @@ MailProvider::MailProvider()
init();
}
+MailProvider::MailProvider(MailProvider * other)
+{
+ init();
+ MC_SAFE_REPLACE_COPY(String, mIdentifier, other->mIdentifier);
+ MC_SAFE_REPLACE_COPY(Array, mImapServices, other->mImapServices);
+ MC_SAFE_REPLACE_COPY(Array, mSmtpServices, other->mSmtpServices);
+ MC_SAFE_REPLACE_COPY(Array, mPopServices, other->mPopServices);
+ MC_SAFE_REPLACE_COPY(Array, mDomainMatch, other->mDomainMatch);
+ MC_SAFE_REPLACE_COPY(Set, mMxSet, other->mMxSet);
+ MC_SAFE_REPLACE_COPY(HashMap, mMailboxPaths, other->mMailboxPaths);
+}
+
MailProvider::~MailProvider()
{
- MC_SAFE_RELEASE(mImapServices);
- MC_SAFE_RELEASE(mSmtpServices);
- MC_SAFE_RELEASE(mPopServices);
- MC_SAFE_RELEASE(mMxSet);
- MC_SAFE_RELEASE(mDomainMatch);
- MC_SAFE_RELEASE(mMailboxPaths);
- MC_SAFE_RELEASE(mIdentifier);
+ MC_SAFE_RELEASE(mImapServices);
+ MC_SAFE_RELEASE(mSmtpServices);
+ MC_SAFE_RELEASE(mPopServices);
+ MC_SAFE_RELEASE(mMxSet);
+ MC_SAFE_RELEASE(mDomainMatch);
+ MC_SAFE_RELEASE(mMailboxPaths);
+ MC_SAFE_RELEASE(mIdentifier);
}
MailProvider * MailProvider::providerWithInfo(HashMap * info)
@@ -52,7 +64,7 @@ MailProvider * MailProvider::providerWithInfo(HashMap * info)
void MailProvider::fillWithInfo(HashMap * info)
{
- Array * imapInfos;
+ Array * imapInfos;
Array * smtpInfos;
Array * popInfos;
HashMap * serverInfo;
@@ -68,9 +80,9 @@ void MailProvider::fillWithInfo(HashMap * info)
}
mxs = (Array *) info->objectForKey(MCSTR("mx"));
mMxSet->removeAllObjects();
- mc_foreacharray(String, mx, mxs) {
- mMxSet->addObject(mx->lowercaseString());
- }
+ mc_foreacharray(String, mx, mxs) {
+ mMxSet->addObject(mx->lowercaseString());
+ }
serverInfo = (HashMap *) info->objectForKey(MCSTR("servers"));
imapInfos = (Array *) serverInfo->objectForKey(MCSTR("imap"));
@@ -78,52 +90,52 @@ void MailProvider::fillWithInfo(HashMap * info)
popInfos = (Array *) serverInfo->objectForKey(MCSTR("pop"));
mImapServices->removeAllObjects();
- mc_foreacharray(HashMap, imapInfo, imapInfos) {
- NetService * service = NetService::serviceWithInfo(imapInfo);
+ mc_foreacharray(HashMap, imapInfo, imapInfos) {
+ NetService * service = NetService::serviceWithInfo(imapInfo);
mImapServices->addObject(service);
- }
-
+ }
+
mSmtpServices->removeAllObjects();
- mc_foreacharray(HashMap, smtpInfo, smtpInfos) {
- NetService * service = NetService::serviceWithInfo(smtpInfo);
- mSmtpServices->addObject(service);
- }
-
+ mc_foreacharray(HashMap, smtpInfo, smtpInfos) {
+ NetService * service = NetService::serviceWithInfo(smtpInfo);
+ mSmtpServices->addObject(service);
+ }
+
mPopServices->removeAllObjects();
- mc_foreacharray(HashMap, popInfo, popInfos) {
- NetService * service = NetService::serviceWithInfo(popInfo);
- mPopServices->addObject(service);
- }
+ mc_foreacharray(HashMap, popInfo, popInfos) {
+ NetService * service = NetService::serviceWithInfo(popInfo);
+ mPopServices->addObject(service);
+ }
}
void MailProvider::setIdentifier(String * identifier)
{
- MC_SAFE_REPLACE_COPY(String, mIdentifier, identifier);
+ MC_SAFE_REPLACE_COPY(String, mIdentifier, identifier);
}
String * MailProvider::identifier()
{
- return mIdentifier;
+ return mIdentifier;
}
Array * MailProvider::imapServices()
{
- return mImapServices;
+ return mImapServices;
}
Array * MailProvider::smtpServices()
{
- return mSmtpServices;
+ return mSmtpServices;
}
Array * MailProvider::popServices()
{
- return mPopServices;
+ return mPopServices;
}
bool MailProvider::matchEmail(String * email)
{
- Array * components;
+ Array * components;
String * domain;
const char * cDomain;
@@ -133,9 +145,9 @@ bool MailProvider::matchEmail(String * email)
domain = (String *) components->lastObject();
cDomain = domain->UTF8Characters();
-
- mc_foreacharray(String, match, mDomainMatch) {
- regex_t r;
+
+ mc_foreacharray(String, match, mDomainMatch) {
+ regex_t r;
bool matched;
match = String::stringWithUTF8Format("^%s$", match->UTF8Characters());
@@ -151,14 +163,14 @@ bool MailProvider::matchEmail(String * email)
if (matched)
return true;
- }
+ }
return false;
}
bool MailProvider::matchMX(String * hostname)
{
- return mMxSet->containsObject(hostname->lowercaseString());
+ return mMxSet->containsObject(hostname->lowercaseString());
}
String * MailProvider::sentMailFolderPath()
@@ -168,38 +180,38 @@ String * MailProvider::sentMailFolderPath()
String * MailProvider::starredFolderPath()
{
- return (String *) mMailboxPaths->objectForKey(MCSTR("starred"));
+ return (String *) mMailboxPaths->objectForKey(MCSTR("starred"));
}
String * MailProvider::allMailFolderPath()
{
- return (String *) mMailboxPaths->objectForKey(MCSTR("allmail"));
+ return (String *) mMailboxPaths->objectForKey(MCSTR("allmail"));
}
String * MailProvider::trashFolderPath()
{
- return (String *) mMailboxPaths->objectForKey(MCSTR("trash"));
+ return (String *) mMailboxPaths->objectForKey(MCSTR("trash"));
}
String * MailProvider::draftsFolderPath()
{
- return (String *) mMailboxPaths->objectForKey(MCSTR("drafts"));
+ return (String *) mMailboxPaths->objectForKey(MCSTR("drafts"));
}
String * MailProvider::spamFolderPath()
{
- return (String *) mMailboxPaths->objectForKey(MCSTR("spam"));
+ return (String *) mMailboxPaths->objectForKey(MCSTR("spam"));
}
String * MailProvider::importantFolderPath()
{
- return (String *) mMailboxPaths->objectForKey(MCSTR("important"));
+ return (String *) mMailboxPaths->objectForKey(MCSTR("important"));
}
bool MailProvider::isMainFolder(String * folderPath, String * prefix)
{
- mc_foreachdictionaryValue(String, path, mMailboxPaths) {
- String * fullPath;
+ mc_foreachdictionaryValue(String, path, mMailboxPaths) {
+ String * fullPath;
if (prefix != NULL) {
fullPath = prefix->stringByAppendingString((String *) path);
@@ -210,7 +222,7 @@ bool MailProvider::isMainFolder(String * folderPath, String * prefix)
if (fullPath->isEqual(folderPath))
return true;
- }
+ }
return false;
}
@@ -219,3 +231,9 @@ String * MailProvider::description()
{
return String::stringWithUTF8Format("<%s:%p, %s>", className()->UTF8Characters(), this, MCUTF8(mIdentifier));
}
+
+Object * MailProvider::copy()
+{
+ return new MailProvider(this);
+}
+
diff --git a/src/core/provider/MCMailProvider.h b/src/core/provider/MCMailProvider.h
index 306b180d..81b816e9 100644
--- a/src/core/provider/MCMailProvider.h
+++ b/src/core/provider/MCMailProvider.h
@@ -45,8 +45,10 @@ namespace mailcore {
virtual bool isMainFolder(String * folderPath, String * prefix);
public: // subclass behavior
+ MailProvider(MailProvider * other);
virtual String * description();
-
+ virtual Object * copy();
+
public: // private
virtual void setIdentifier(String * identifier);
virtual void fillWithInfo(HashMap * info);
diff --git a/src/core/provider/MCNetService.cc b/src/core/provider/MCNetService.cc
index 53ae7475..f760dc61 100644
--- a/src/core/provider/MCNetService.cc
+++ b/src/core/provider/MCNetService.cc
@@ -19,12 +19,20 @@ void NetService::init()
NetService::NetService()
{
- init();
+ init();
+}
+
+NetService::NetService(NetService * other)
+{
+ init();
+ MC_SAFE_REPLACE_COPY(String, mHostname, other->mHostname);
+ mPort = other->mPort;
+ mConnectionType = other->mConnectionType;
}
NetService::~NetService()
{
- MC_SAFE_RELEASE(mHostname);
+ MC_SAFE_RELEASE(mHostname);
}
NetService * NetService::serviceWithInfo(HashMap * info)
@@ -37,10 +45,10 @@ NetService * NetService::serviceWithInfo(HashMap * info)
void NetService::fillWithInfo(HashMap * info)
{
- bool ssl = false;
+ bool ssl = false;
bool starttls = false;
-
- setHostname((String *) info->objectForKey(MCSTR("hostname")));
+
+ setHostname((String *) info->objectForKey(MCSTR("hostname")));
if (info->objectForKey(MCSTR("port")) != NULL) {
setPort(((Value *) info->objectForKey(MCSTR("port")))->intValue());
}
@@ -68,57 +76,57 @@ void NetService::setHostname(String *hostname)
String * NetService::hostname()
{
- return mHostname;
+ return mHostname;
}
void NetService::setPort(unsigned int port)
{
- mPort = port;
+ mPort = port;
}
unsigned int NetService::port()
{
- return mPort;
+ return mPort;
}
void NetService::setConnectionType(ConnectionType connectionType)
{
- mConnectionType = connectionType;
+ mConnectionType = connectionType;
}
ConnectionType NetService::connectionType()
{
- return mConnectionType;
+ return mConnectionType;
}
String * NetService::normalizedHostnameWithEmail(String * email)
{
- Array *components = email->componentsSeparatedByString(MCSTR("@"));
- String *hostname = (String *) mHostname->copy();
- if (components->count() != 0) {
- hostname->replaceOccurrencesOfString(MCSTR("{domain}"), (String *) components->lastObject());
- return hostname;
- }
- return mHostname;
+ Array *components = email->componentsSeparatedByString(MCSTR("@"));
+ String *hostname = (String *) mHostname->copy();
+ if (components->count() != 0) {
+ hostname->replaceOccurrencesOfString(MCSTR("{domain}"), (String *) components->lastObject());
+ return hostname;
+ }
+ return mHostname;
}
HashMap * NetService::info()
{
- HashMap * result;
+ HashMap * result;
result = new HashMap();
if (mHostname != NULL) {
- result->setObjectForKey(MCSTR("hostname"), mHostname);
+ result->setObjectForKey(MCSTR("hostname"), mHostname);
}
if (mPort != 0) {
- result->setObjectForKey(MCSTR("port"), Value::valueWithIntValue(mPort));
+ result->setObjectForKey(MCSTR("port"), Value::valueWithIntValue(mPort));
}
switch (mConnectionType) {
case ConnectionTypeTLS:
- result->setObjectForKey(MCSTR("ssl"), Value::valueWithBoolValue(true));
+ result->setObjectForKey(MCSTR("ssl"), Value::valueWithBoolValue(true));
break;
case ConnectionTypeStartTLS:
- result->setObjectForKey(MCSTR("starttls"), Value::valueWithBoolValue(true));
+ result->setObjectForKey(MCSTR("starttls"), Value::valueWithBoolValue(true));
break;
default:
break;
@@ -126,3 +134,13 @@ HashMap * NetService::info()
return result;
}
+
+String * NetService::description()
+{
+ return String::stringWithUTF8Format("<%s:%p, hostname: %s, port: %u>", className()->UTF8Characters(), this, MCUTF8(mHostname), mPort);
+}
+
+Object * NetService::copy()
+{
+ return new NetService(this);
+}
diff --git a/src/core/provider/MCNetService.h b/src/core/provider/MCNetService.h
index 7b0b9e14..d3aa5dd7 100644
--- a/src/core/provider/MCNetService.h
+++ b/src/core/provider/MCNetService.h
@@ -15,35 +15,40 @@
#ifdef __cplusplus
namespace mailcore {
- class NetService : public Object {
-
- public:
- NetService();
- virtual ~NetService();
-
- virtual void setHostname(String * hostname);
- virtual String * hostname();
-
- virtual void setPort(unsigned int port);
- virtual unsigned int port();
-
- virtual void setConnectionType(ConnectionType connectionType);
- virtual ConnectionType connectionType();
-
- virtual String * normalizedHostnameWithEmail(String * email);
+ class NetService : public Object {
+
+ public:
+ NetService();
+ virtual ~NetService();
+
+ virtual void setHostname(String * hostname);
+ virtual String * hostname();
+
+ virtual void setPort(unsigned int port);
+ virtual unsigned int port();
+
+ virtual void setConnectionType(ConnectionType connectionType);
+ virtual ConnectionType connectionType();
+
+ virtual String * normalizedHostnameWithEmail(String * email);
public: // serialization
static NetService * serviceWithInfo(HashMap * info);
- virtual HashMap * info();
+ virtual HashMap * info();
+
+ public: //subclass behavior
+ NetService(NetService * other);
+ virtual String * description();
+ virtual Object * copy();
+
+ private:
+ String * mHostname;
+ unsigned int mPort;
+ ConnectionType mConnectionType;
- private:
- String * mHostname;
- unsigned int mPort;
- ConnectionType mConnectionType;
-
- void init();
+ void init();
void fillWithInfo(HashMap * info);
- };
+ };
}
#endif
diff --git a/src/core/smtp/MCSMTPSession.cc b/src/core/smtp/MCSMTPSession.cc
index e74a540a..dcbad71e 100644
--- a/src/core/smtp/MCSMTPSession.cc
+++ b/src/core/smtp/MCSMTPSession.cc
@@ -164,7 +164,7 @@ void SMTPSession::bodyProgress(unsigned int current, unsigned int maximum)
}
-static void logger(mailsmtp * pop3, int log_type, const char * buffer, size_t size, void * context)
+static void logger(mailsmtp * smtp, int log_type, const char * buffer, size_t size, void * context)
{
SMTPSession * session = (SMTPSession *) context;
@@ -176,11 +176,10 @@ static void logger(mailsmtp * pop3, int log_type, const char * buffer, size_t si
if (isBuffer) {
Data * data = Data::dataWithBytes(buffer, (unsigned int) size);
- session->connectionLogger()->logBuffer(type, data);
+ session->connectionLogger()->log(session, type, data);
}
else {
- Data * data = Data::dataWithBytes(buffer, (unsigned int) size);
- session->connectionLogger()->logString(type, String::stringWithData(data));
+ session->connectionLogger()->log(session, type, NULL);
}
}
diff --git a/src/objc/abstract/MCOAbstractMessage.mm b/src/objc/abstract/MCOAbstractMessage.mm
index 6fedcc8a..05530845 100644
--- a/src/objc/abstract/MCOAbstractMessage.mm
+++ b/src/objc/abstract/MCOAbstractMessage.mm
@@ -28,6 +28,12 @@
return _message;
}
+- (id) init
+{
+ MCAssert(0);
+ return nil;
+}
+
- (id) initWithMCMessage:(mailcore::AbstractMessage *)message
{
self = [super init];
@@ -40,7 +46,7 @@
- (void) dealloc
{
- _message->release();
+ MC_SAFE_RELEASE(_message);
[super dealloc];
}
diff --git a/src/objc/abstract/MCOAbstractPart.mm b/src/objc/abstract/MCOAbstractPart.mm
index 8b2b008d..7a37dcaf 100644
--- a/src/objc/abstract/MCOAbstractPart.mm
+++ b/src/objc/abstract/MCOAbstractPart.mm
@@ -27,6 +27,12 @@
return _part;
}
+- (id) init
+{
+ MCAssert(0);
+ return nil;
+}
+
- (id) initWithMCPart:(mailcore::AbstractPart *)part
{
self = [super init];
@@ -39,7 +45,7 @@
- (void) dealloc
{
- _part->release();
+ MC_SAFE_RELEASE(_part);
[super dealloc];
}
diff --git a/src/objc/abstract/MCOConstants.h b/src/objc/abstract/MCOConstants.h
index 8fafabf3..5ec21422 100644
--- a/src/objc/abstract/MCOConstants.h
+++ b/src/objc/abstract/MCOConstants.h
@@ -33,6 +33,8 @@ typedef enum {
MCOAuthTypeSASLNTLM = 1 << 6,
/** Kerberos 4 authentication.*/
MCOAuthTypeSASLKerberosV4 = 1 << 7,
+ /** OAuth2 authentication.*/
+ MCOAuthTypeXOAuth2 = 1 << 8,
} MCOAuthType;
/** It's the IMAP flags of the folder.*/
@@ -324,4 +326,28 @@ typedef enum {
MCOErrorInvalidAccount,
} MCOErrorCode;
+/** Here's the list of connection log types.*/
+typedef enum {
+ /** Received data.*/
+ MCOConnectionLogTypeReceived,
+ /** Sent data.*/
+ MCOConnectionLogTypeSent,
+ /** Sent private data. It can be a password.*/
+ MCOConnectionLogTypeSentPrivate,
+ /** Parse error.*/
+ MCOConnectionLogTypeErrorParse,
+ /** Error while receiving data. The data passed to the log will be nil.*/
+ MCOConnectionLogTypeErrorReceived,
+ /** Error while sending dataThe data passed to the log will be nil.*/
+ MCOConnectionLogTypeErrorSent,
+} MCOConnectionLogType;
+
+/**
+ It's a network traffic logger.
+ @param connectionID is the identifier of the underlaying network socket.
+ @param type is the type of the log.
+ @param data is the data related to the log.
+ */
+typedef void (^MCOConnectionLogger)(void * connectionID, MCOConnectionLogType type, NSData * data);
+
#endif
diff --git a/src/objc/abstract/MCOMessageHeader.mm b/src/objc/abstract/MCOMessageHeader.mm
index 6729894d..427131b0 100644
--- a/src/objc/abstract/MCOMessageHeader.mm
+++ b/src/objc/abstract/MCOMessageHeader.mm
@@ -67,6 +67,12 @@
return self;
}
+- (void) dealloc
+{
+ _nativeHeader->release();
+ [super dealloc];
+}
+
+ (MCOMessageHeader *) messageHeaderWithMCMessageHeader:(mailcore::MessageHeader *)header
{
if (header == NULL)
diff --git a/src/objc/imap/MCOIMAPAppendMessageOperation.mm b/src/objc/imap/MCOIMAPAppendMessageOperation.mm
index 16463016..c281b925 100644
--- a/src/objc/imap/MCOIMAPAppendMessageOperation.mm
+++ b/src/objc/imap/MCOIMAPAppendMessageOperation.mm
@@ -57,6 +57,8 @@ typedef void (^CompletionType)(NSError *error, uint32_t createdUID);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], 0);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
- (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum
diff --git a/src/objc/imap/MCOIMAPCapabilityOperation.mm b/src/objc/imap/MCOIMAPCapabilityOperation.mm
index 048475c9..42952378 100644
--- a/src/objc/imap/MCOIMAPCapabilityOperation.mm
+++ b/src/objc/imap/MCOIMAPCapabilityOperation.mm
@@ -53,6 +53,8 @@ typedef void (^CompletionType)(NSError *error, MCOIndexSet * capabilities);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], nil);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
@end
diff --git a/src/objc/imap/MCOIMAPCopyMessagesOperation.mm b/src/objc/imap/MCOIMAPCopyMessagesOperation.mm
index 8f7bf501..d14bcc84 100644
--- a/src/objc/imap/MCOIMAPCopyMessagesOperation.mm
+++ b/src/objc/imap/MCOIMAPCopyMessagesOperation.mm
@@ -54,6 +54,8 @@ typedef void (^CompletionType)(NSError *error, MCOIndexSet * destUids);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], 0);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
@end
diff --git a/src/objc/imap/MCOIMAPFetchContentOperation.mm b/src/objc/imap/MCOIMAPFetchContentOperation.mm
index 984751c0..d5d4757d 100644
--- a/src/objc/imap/MCOIMAPFetchContentOperation.mm
+++ b/src/objc/imap/MCOIMAPFetchContentOperation.mm
@@ -57,6 +57,8 @@ typedef void (^CompletionType)(NSError *error, NSData * data);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], nil);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
- (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum
diff --git a/src/objc/imap/MCOIMAPFetchFoldersOperation.mm b/src/objc/imap/MCOIMAPFetchFoldersOperation.mm
index 53017c90..02b7d880 100644
--- a/src/objc/imap/MCOIMAPFetchFoldersOperation.mm
+++ b/src/objc/imap/MCOIMAPFetchFoldersOperation.mm
@@ -58,6 +58,8 @@ typedef void (^CompletionType)(NSError *error, NSArray *folder);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], nil);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
@end
diff --git a/src/objc/imap/MCOIMAPFetchMessagesOperation.mm b/src/objc/imap/MCOIMAPFetchMessagesOperation.mm
index e43a46e5..6892ab1b 100644
--- a/src/objc/imap/MCOIMAPFetchMessagesOperation.mm
+++ b/src/objc/imap/MCOIMAPFetchMessagesOperation.mm
@@ -53,6 +53,8 @@ typedef void (^CompletionType)(NSError *error, NSArray * messages, MCOIndexSet *
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], nil, nil);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
- (void) itemProgress:(unsigned int)current maximum:(unsigned int)maximum
diff --git a/src/objc/imap/MCOIMAPFetchNamespaceOperation.mm b/src/objc/imap/MCOIMAPFetchNamespaceOperation.mm
index aaa02c96..861298bf 100644
--- a/src/objc/imap/MCOIMAPFetchNamespaceOperation.mm
+++ b/src/objc/imap/MCOIMAPFetchNamespaceOperation.mm
@@ -53,6 +53,8 @@ typedef void (^CompletionType)(NSError *error, NSDictionary * namespaces);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], nil);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
@end
diff --git a/src/objc/imap/MCOIMAPFolderInfoOperation.mm b/src/objc/imap/MCOIMAPFolderInfoOperation.mm
index 37b1a649..61766073 100644
--- a/src/objc/imap/MCOIMAPFolderInfoOperation.mm
+++ b/src/objc/imap/MCOIMAPFolderInfoOperation.mm
@@ -61,6 +61,8 @@ typedef void (^CompletionType)(NSError *error, MCOIMAPFolderInfo *info);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], nil);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
@end
diff --git a/src/objc/imap/MCOIMAPFolderStatusOperation.mm b/src/objc/imap/MCOIMAPFolderStatusOperation.mm
index c7f5370c..2420e0b9 100644
--- a/src/objc/imap/MCOIMAPFolderStatusOperation.mm
+++ b/src/objc/imap/MCOIMAPFolderStatusOperation.mm
@@ -55,6 +55,8 @@ typedef void (^CompletionType)(NSError *error, MCOIMAPFolderStatus *status);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], nil);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
@end
diff --git a/src/objc/imap/MCOIMAPIdentityOperation.mm b/src/objc/imap/MCOIMAPIdentityOperation.mm
index acc5ea10..f02fbba5 100644
--- a/src/objc/imap/MCOIMAPIdentityOperation.mm
+++ b/src/objc/imap/MCOIMAPIdentityOperation.mm
@@ -53,6 +53,8 @@ typedef void (^CompletionType)(NSError *error, NSDictionary * serverIdentity);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], nil);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
@end
diff --git a/src/objc/imap/MCOIMAPIdleOperation.mm b/src/objc/imap/MCOIMAPIdleOperation.mm
index 86419b75..d43bf818 100644
--- a/src/objc/imap/MCOIMAPIdleOperation.mm
+++ b/src/objc/imap/MCOIMAPIdleOperation.mm
@@ -53,6 +53,8 @@ typedef void (^CompletionType)(NSError *error);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()]);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
- (void) interruptIdle
diff --git a/src/objc/imap/MCOIMAPOperation.mm b/src/objc/imap/MCOIMAPOperation.mm
index 7b98c6bd..0b6d48e0 100644
--- a/src/objc/imap/MCOIMAPOperation.mm
+++ b/src/objc/imap/MCOIMAPOperation.mm
@@ -38,6 +38,8 @@ typedef void (^CompletionType)(NSError *error);
NSError * error = [NSError mco_errorWithErrorCode:MCO_NATIVE_INSTANCE->error()];
_completionBlock(error);
+ [_completionBlock release];
+ _completionBlock = nil;
}
@end
diff --git a/src/objc/imap/MCOIMAPSearchOperation.mm b/src/objc/imap/MCOIMAPSearchOperation.mm
index 92f57b62..730c73a0 100644
--- a/src/objc/imap/MCOIMAPSearchOperation.mm
+++ b/src/objc/imap/MCOIMAPSearchOperation.mm
@@ -54,6 +54,8 @@ typedef void (^CompletionType)(NSError *error, MCOIndexSet * searchResult);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], nil);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
@end
diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h
index 1b394eff..0358f7ad 100644
--- a/src/objc/imap/MCOIMAPSession.h
+++ b/src/objc/imap/MCOIMAPSession.h
@@ -90,6 +90,15 @@
*/
@property (nonatomic, assign) unsigned int maximumConnections;
+/**
+ Sets logger callback. The network traffic will be sent to this block.
+
+ [session setConnectionLogger:^(void * connectionID, MCOConnectionLogType type, NSData * data) {
+ ...
+ }];
+*/
+@property (nonatomic, copy) MCOConnectionLogger connectionLogger;
+
/** @name Folder Operations */
/**
diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm
index a8df8aed..43f366e6 100644
--- a/src/objc/imap/MCOIMAPSession.mm
+++ b/src/objc/imap/MCOIMAPSession.mm
@@ -22,8 +22,32 @@
using namespace mailcore;
+@interface MCOIMAPSession ()
+
+- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data;
+
+@end
+
+class MCOIMAPConnectionLoggerBridge : public Object, public ConnectionLogger {
+public:
+ MCOIMAPConnectionLoggerBridge(MCOIMAPSession * session)
+ {
+ mSession = session;
+ }
+
+ virtual void log(void * context, void * sender, ConnectionLogType logType, Data * data)
+ {
+ [mSession _logWithSender:sender connectionType:(MCOConnectionLogType)logType data:MCO_TO_OBJC(data)];
+ }
+
+private:
+ MCOIMAPSession * mSession;
+};
+
@implementation MCOIMAPSession {
IMAPAsyncSession * _session;
+ MCOConnectionLogger _connectionLogger;
+ MCOIMAPConnectionLoggerBridge * _loggerBridge;
}
#define nativeType mailcore::IMAPAsyncSession
@@ -35,13 +59,16 @@ using namespace mailcore;
- (id)init {
self = [super init];
- if (self) {
- _session = new IMAPAsyncSession();
- }
+
+ _session = new IMAPAsyncSession();
+ _loggerBridge = new MCOIMAPConnectionLoggerBridge(self);
+
return self;
}
- (void)dealloc {
+ MC_SAFE_RELEASE(_loggerBridge);
+ [_connectionLogger release];
_session->release();
[super dealloc];
}
@@ -59,6 +86,24 @@ MCO_OBJC_SYNTHESIZE_SCALAR(char, char, setDelimiter, delimiter)
MCO_OBJC_SYNTHESIZE_SCALAR(BOOL, BOOL, setAllowsFolderConcurrentAccessEnabled, allowsFolderConcurrentAccessEnabled)
MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, maximumConnections)
+- (void) setConnectionLogger:(MCOConnectionLogger)connectionLogger
+{
+ [_connectionLogger release];
+ _connectionLogger = [connectionLogger copy];
+
+ if (_connectionLogger != nil) {
+ _session->setConnectionLogger(_loggerBridge);
+ }
+ else {
+ _session->setConnectionLogger(NULL);
+ }
+}
+
+- (MCOConnectionLogger) connectionLogger
+{
+ return _connectionLogger;
+}
+
#pragma mark - Operations
#define MCO_TO_OBJC_OP(op) [self _objcOperationFromNativeOp:op];
@@ -303,4 +348,9 @@ MCO_OBJC_SYNTHESIZE_SCALAR(unsigned int, unsigned int, setMaximumConnections, ma
return MCO_TO_OBJC_OP(coreOp);
}
+- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data
+{
+ _connectionLogger(sender, logType, data);
+}
+
@end
diff --git a/src/objc/pop/MCOPOPFetchHeaderOperation.mm b/src/objc/pop/MCOPOPFetchHeaderOperation.mm
index 1d2c35c6..ab467a76 100644
--- a/src/objc/pop/MCOPOPFetchHeaderOperation.mm
+++ b/src/objc/pop/MCOPOPFetchHeaderOperation.mm
@@ -54,6 +54,8 @@ typedef void (^CompletionType)(NSError *error, MCOMessageHeader * header);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], nil);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
@end
diff --git a/src/objc/pop/MCOPOPFetchMessageOperation.mm b/src/objc/pop/MCOPOPFetchMessageOperation.mm
index 40740961..02bad3ad 100644
--- a/src/objc/pop/MCOPOPFetchMessageOperation.mm
+++ b/src/objc/pop/MCOPOPFetchMessageOperation.mm
@@ -90,6 +90,8 @@ private:
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], nil);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
- (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum
diff --git a/src/objc/pop/MCOPOPFetchMessagesOperation.mm b/src/objc/pop/MCOPOPFetchMessagesOperation.mm
index dcb35845..2fe9b31f 100644
--- a/src/objc/pop/MCOPOPFetchMessagesOperation.mm
+++ b/src/objc/pop/MCOPOPFetchMessagesOperation.mm
@@ -54,6 +54,8 @@ typedef void (^CompletionType)(NSError *error, NSArray * messages);
} else {
_completionBlock([NSError mco_errorWithErrorCode:op->error()], nil);
}
+ [_completionBlock release];
+ _completionBlock = nil;
}
diff --git a/src/objc/pop/MCOPOPOperation.mm b/src/objc/pop/MCOPOPOperation.mm
index 9b58f84d..5f4d1f59 100644
--- a/src/objc/pop/MCOPOPOperation.mm
+++ b/src/objc/pop/MCOPOPOperation.mm
@@ -41,6 +41,8 @@ typedef void (^CompletionType)(NSError *error);
NSError * error = [NSError mco_errorWithErrorCode:MCO_NATIVE_INSTANCE->error()];
_completionBlock(error);
+ [_completionBlock release];
+ _completionBlock = nil;
}
- (void) setSession:(MCOPOPSession *)session
diff --git a/src/objc/pop/MCOPOPSession.h b/src/objc/pop/MCOPOPSession.h
index 6ecca042..4f98421c 100644
--- a/src/objc/pop/MCOPOPSession.h
+++ b/src/objc/pop/MCOPOPSession.h
@@ -53,6 +53,15 @@ See MCOConnectionType for more information.*/
/** When set to YES, the connection will fail if the certificate is incorrect.*/
@property (nonatomic, assign, getter=isCheckCertificateEnabled) BOOL checkCertificateEnabled;
+/**
+ Sets logger callback. The network traffic will be sent to this block.
+
+ [session setConnectionLogger:^(void * connectionID, MCOConnectionLogType type, NSData * data) {
+ ...
+ }];
+ */
+@property (nonatomic, copy) MCOConnectionLogger connectionLogger;
+
/** @name Operations */
/**
diff --git a/src/objc/pop/MCOPOPSession.mm b/src/objc/pop/MCOPOPSession.mm
index 11f7cad6..42c76646 100644
--- a/src/objc/pop/MCOPOPSession.mm
+++ b/src/objc/pop/MCOPOPSession.mm
@@ -16,8 +16,34 @@
#import "MCOPOPFetchMessagesOperation.h"
#import "MCOPOPOperation+Private.h"
+using namespace mailcore;
+
+@interface MCOPOPSession ()
+
+- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data;
+
+@end
+
+class MCOPOPConnectionLoggerBridge : public Object, public ConnectionLogger {
+public:
+ MCOPOPConnectionLoggerBridge(MCOPOPSession * session)
+ {
+ mSession = session;
+ }
+
+ virtual void log(void * context, void * sender, ConnectionLogType logType, Data * data)
+ {
+ [mSession _logWithSender:sender connectionType:(MCOConnectionLogType)logType data:MCO_TO_OBJC(data)];
+ }
+
+private:
+ MCOPOPSession * mSession;
+};
+
@implementation MCOPOPSession {
mailcore::POPAsyncSession * _session;
+ MCOConnectionLogger _connectionLogger;
+ MCOPOPConnectionLoggerBridge * _loggerBridge;
}
#define nativeType mailcore::POPAsyncSession
@@ -34,13 +60,16 @@
- (id)init {
self = [super init];
- if (self) {
- _session = new mailcore::POPAsyncSession();
- }
+
+ _session = new mailcore::POPAsyncSession();
+ _loggerBridge = new MCOPOPConnectionLoggerBridge(self);
+
return self;
}
- (void)dealloc {
+ MC_SAFE_RELEASE(_loggerBridge);
+ [_connectionLogger release];
_session->release();
[super dealloc];
}
@@ -54,6 +83,24 @@ MCO_OBJC_SYNTHESIZE_SCALAR(MCOConnectionType, mailcore::ConnectionType, setConne
MCO_OBJC_SYNTHESIZE_SCALAR(NSTimeInterval, time_t, setTimeout, timeout)
MCO_OBJC_SYNTHESIZE_BOOL(setCheckCertificateEnabled, isCheckCertificateEnabled)
+- (void) setConnectionLogger:(MCOConnectionLogger)connectionLogger
+{
+ [_connectionLogger release];
+ _connectionLogger = [connectionLogger copy];
+
+ if (_connectionLogger != nil) {
+ _session->setConnectionLogger(_loggerBridge);
+ }
+ else {
+ _session->setConnectionLogger(NULL);
+ }
+}
+
+- (MCOConnectionLogger) connectionLogger
+{
+ return _connectionLogger;
+}
+
#pragma mark - Operations
@@ -111,4 +158,9 @@ MCO_OBJC_SYNTHESIZE_BOOL(setCheckCertificateEnabled, isCheckCertificateEnabled)
return OPAQUE_OPERATION(coreOp);
}
+- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data
+{
+ _connectionLogger(sender, logType, data);
+}
+
@end
diff --git a/src/objc/smtp/MCOSMTPOperation.mm b/src/objc/smtp/MCOSMTPOperation.mm
index cd52ad13..9d96613f 100644
--- a/src/objc/smtp/MCOSMTPOperation.mm
+++ b/src/objc/smtp/MCOSMTPOperation.mm
@@ -41,6 +41,8 @@ typedef void (^CompletionType)(NSError *error);
NSError * error = [NSError mco_errorWithErrorCode:MCO_NATIVE_INSTANCE->error()];
_completionBlock(error);
+ [_completionBlock release];
+ _completionBlock = NULL;
}
- (void) setSession:(MCOSMTPSession *)session
diff --git a/src/objc/smtp/MCOSMTPSendOperation.mm b/src/objc/smtp/MCOSMTPSendOperation.mm
index e41a9f5a..8a7d5b04 100644
--- a/src/objc/smtp/MCOSMTPSendOperation.mm
+++ b/src/objc/smtp/MCOSMTPSendOperation.mm
@@ -80,16 +80,16 @@ private:
[self start];
}
+// This method needs to be duplicated from MCOSMTPOperation since _completionBlock
+// references the instance of this subclass and not the one from MCOSMTPOperation.
- (void)operationCompleted {
if (_completionBlock == NULL)
return;
- nativeType *op = MCO_NATIVE_INSTANCE;
- if (op->error() == mailcore::ErrorNone) {
- _completionBlock(nil);
- } else {
- _completionBlock([NSError mco_errorWithErrorCode:op->error()]);
- }
+ NSError * error = [NSError mco_errorWithErrorCode:MCO_NATIVE_INSTANCE->error()];
+ _completionBlock(error);
+ [_completionBlock release];
+ _completionBlock = NULL;
}
- (void) bodyProgress:(unsigned int)current maximum:(unsigned int)maximum
diff --git a/src/objc/smtp/MCOSMTPSession.h b/src/objc/smtp/MCOSMTPSession.h
index 08189bed..44d37942 100644
--- a/src/objc/smtp/MCOSMTPSession.h
+++ b/src/objc/smtp/MCOSMTPSession.h
@@ -64,6 +64,15 @@
*/
@property (nonatomic, assign, getter=isUseHeloIPEnabled) BOOL useHeloIPEnabled;
+/**
+ Sets logger callback. The network traffic will be sent to this block.
+
+ [session setConnectionLogger:^(void * connectionID, MCOConnectionLogType type, NSData * data) {
+ ...
+ }];
+ */
+@property (nonatomic, copy) MCOConnectionLogger connectionLogger;
+
/** @name Operations */
/**
diff --git a/src/objc/smtp/MCOSMTPSession.mm b/src/objc/smtp/MCOSMTPSession.mm
index de6b54cd..1538d53a 100644
--- a/src/objc/smtp/MCOSMTPSession.mm
+++ b/src/objc/smtp/MCOSMTPSession.mm
@@ -17,8 +17,34 @@
#import "MCOAddress.h"
#import "MCOSMTPOperation+Private.h"
+using namespace mailcore;
+
+@interface MCOSMTPSession ()
+
+- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data;
+
+@end
+
+class MCOSMTPConnectionLoggerBridge : public Object, public ConnectionLogger {
+public:
+ MCOSMTPConnectionLoggerBridge(MCOSMTPSession * session)
+ {
+ mSession = session;
+ }
+
+ virtual void log(void * context, void * sender, ConnectionLogType logType, Data * data)
+ {
+ [mSession _logWithSender:sender connectionType:(MCOConnectionLogType)logType data:MCO_TO_OBJC(data)];
+ }
+
+private:
+ MCOSMTPSession * mSession;
+};
+
@implementation MCOSMTPSession {
mailcore::SMTPAsyncSession * _session;
+ MCOConnectionLogger _connectionLogger;
+ MCOSMTPConnectionLoggerBridge * _loggerBridge;
}
#define nativeType mailcore::SMTPAsyncSession
@@ -30,13 +56,16 @@
- (id)init {
self = [super init];
- if (self) {
- _session = new mailcore::SMTPAsyncSession();
- }
+
+ _session = new mailcore::SMTPAsyncSession();
+ _loggerBridge = new MCOSMTPConnectionLoggerBridge(self);
+
return self;
}
- (void)dealloc {
+ MC_SAFE_RELEASE(_loggerBridge);
+ [_connectionLogger release];
_session->release();
[super dealloc];
}
@@ -51,6 +80,24 @@ MCO_OBJC_SYNTHESIZE_SCALAR(NSTimeInterval, time_t, setTimeout, timeout)
MCO_OBJC_SYNTHESIZE_BOOL(setCheckCertificateEnabled, isCheckCertificateEnabled)
MCO_OBJC_SYNTHESIZE_BOOL(setUseHeloIPEnabled, useHeloIPEnabled)
+- (void) setConnectionLogger:(MCOConnectionLogger)connectionLogger
+{
+ [_connectionLogger release];
+ _connectionLogger = [connectionLogger copy];
+
+ if (_connectionLogger != nil) {
+ _session->setConnectionLogger(_loggerBridge);
+ }
+ else {
+ _session->setConnectionLogger(NULL);
+ }
+}
+
+- (MCOConnectionLogger) connectionLogger
+{
+ return _connectionLogger;
+}
+
#pragma mark - Operations
- (MCOSMTPSendOperation *) sendOperationWithData:(NSData *)messageData
@@ -69,4 +116,9 @@ MCO_OBJC_SYNTHESIZE_BOOL(setUseHeloIPEnabled, useHeloIPEnabled)
return result;
}
+- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data
+{
+ _connectionLogger(sender, logType, data);
+}
+
@end