diff options
author | 2013-08-18 22:53:03 -0700 | |
---|---|---|
committer | 2013-08-18 22:53:03 -0700 | |
commit | 775ad7c56e930887967fb4d3fa6462c5ba826102 (patch) | |
tree | c860f0b48caa31394b5c61368eeb8aabd1d1be91 /src | |
parent | c378363b5afc43b98d62acb1a3d8186a907da915 (diff) | |
parent | d86e4a126eb37d62557f35ca7bd13d5e16ece648 (diff) |
Merge branch 'autoconfiguration'
Diffstat (limited to 'src')
-rwxr-xr-x | src/async/imap/MCIMAPAsyncConnection.cc | 24 | ||||
-rwxr-xr-x | src/async/imap/MCIMAPAsyncConnection.h | 7 | ||||
-rwxr-xr-x | src/async/imap/MCIMAPAsyncSession.cc | 28 | ||||
-rwxr-xr-x | src/async/imap/MCIMAPAsyncSession.h | 9 | ||||
-rw-r--r-- | src/async/imap/MCIMAPCapabilityOperation.cc | 5 | ||||
-rw-r--r-- | src/async/imap/MCIMAPFetchFoldersOperation.cc | 11 | ||||
-rw-r--r-- | src/async/imap/MCIMAPFetchFoldersOperation.h | 1 | ||||
-rw-r--r-- | src/async/imap/MCIMAPOperation.cc | 13 | ||||
-rw-r--r-- | src/async/imap/MCIMAPOperation.h | 3 | ||||
-rw-r--r-- | src/core/abstract/MCMessageConstants.h | 1 | ||||
-rw-r--r-- | src/core/basetypes/MCOperation.cc | 8 | ||||
-rw-r--r-- | src/core/basetypes/MCOperation.h | 8 | ||||
-rw-r--r-- | src/core/basetypes/MCOperationQueue.cc | 13 | ||||
-rw-r--r-- | src/core/basetypes/MCOperationQueue.h | 1 | ||||
-rwxr-xr-x | src/core/imap/MCIMAPSession.cc | 311 | ||||
-rwxr-xr-x | src/core/imap/MCIMAPSession.h | 24 | ||||
-rw-r--r-- | src/objc/abstract/MCOConstants.h | 2 | ||||
-rwxr-xr-x | src/objc/imap/MCOIMAPSession.h | 3 | ||||
-rwxr-xr-x | src/objc/imap/MCOIMAPSession.mm | 1 |
19 files changed, 370 insertions, 103 deletions
diff --git a/src/async/imap/MCIMAPAsyncConnection.cc b/src/async/imap/MCIMAPAsyncConnection.cc index 1472d974..a5e46a58 100755 --- a/src/async/imap/MCIMAPAsyncConnection.cc +++ b/src/async/imap/MCIMAPAsyncConnection.cc @@ -86,7 +86,6 @@ IMAPAsyncConnection::IMAPAsyncConnection() mSession = new IMAPSession(); mQueue = new OperationQueue(); mDefaultNamespace = NULL; - mDelimiter = 0; mLastFolder = NULL; mQueueCallback = new IMAPOperationQueueCallback(this); mQueue->setCallback(mQueueCallback); @@ -94,6 +93,7 @@ IMAPAsyncConnection::IMAPAsyncConnection() mConnectionLogger = NULL; pthread_mutex_init(&mConnectionLoggerLock, NULL); mInternalLogger = new IMAPConnectionLogger(this); + mAutomaticConfigurationEnabled = true; } IMAPAsyncConnection::~IMAPAsyncConnection() @@ -208,17 +208,6 @@ bool IMAPAsyncConnection::isVoIPEnabled() return mSession->isVoIPEnabled(); } -void IMAPAsyncConnection::setDelimiter(char delimiter) -{ - mSession->setDelimiter(delimiter); - mDelimiter = delimiter; -} - -char IMAPAsyncConnection::delimiter() -{ - return mDelimiter; -} - void IMAPAsyncConnection::setDefaultNamespace(IMAPNamespace * ns) { mSession->setDefaultNamespace(ns); @@ -639,3 +628,14 @@ IMAPMessageRenderingOperation * IMAPAsyncConnection::plainTextBodyRenderingOpera { return renderingOperation(message, folder, IMAPMessageRenderingTypePlainTextBody); } + +void IMAPAsyncConnection::setAutomaticConfigurationEnabled(bool enabled) +{ + mAutomaticConfigurationEnabled = enabled; + mSession->setAutomaticConfigurationEnabled(enabled); +} + +bool IMAPAsyncConnection::isAutomaticConfigurationEnabled() +{ + return mAutomaticConfigurationEnabled; +} diff --git a/src/async/imap/MCIMAPAsyncConnection.h b/src/async/imap/MCIMAPAsyncConnection.h index 13f9ff7b..e7ceb283 100755 --- a/src/async/imap/MCIMAPAsyncConnection.h +++ b/src/async/imap/MCIMAPAsyncConnection.h @@ -67,9 +67,10 @@ namespace mailcore { virtual void setVoIPEnabled(bool enabled); virtual bool isVoIPEnabled(); - virtual void setDelimiter(char delimiter); - virtual char delimiter(); + virtual void setAutomaticConfigurationEnabled(bool enabled); + virtual bool isAutomaticConfigurationEnabled(); + // Needs to be run before starting a connection. virtual void setDefaultNamespace(IMAPNamespace * ns); virtual IMAPNamespace * defaultNamespace(); @@ -132,7 +133,6 @@ namespace mailcore { private: IMAPSession * mSession; OperationQueue * mQueue; - char mDelimiter; IMAPNamespace * mDefaultNamespace; String * mLastFolder; IMAPOperationQueueCallback * mQueueCallback; @@ -140,6 +140,7 @@ namespace mailcore { ConnectionLogger * mConnectionLogger; IMAPConnectionLogger * mInternalLogger; pthread_mutex_t mConnectionLoggerLock; + bool mAutomaticConfigurationEnabled; virtual void tryAutomaticDisconnectAfterDelay(void * context); virtual IMAPMessageRenderingOperation * renderingOperation(IMAPMessage * message, diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index 26c0feca..50c7dcde 100755 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -12,6 +12,7 @@ #include "MCIMAPNamespace.h" #include "MCOperationQueueCallback.h" #include "MCConnectionLogger.h" +#include "MCIMAPSession.h" #define DEFAULT_MAX_CONNECTIONS 3 @@ -32,10 +33,10 @@ IMAPAsyncSession::IMAPAsyncSession() mConnectionType = ConnectionTypeClear; mCheckCertificateEnabled = true; mVoIPEnabled = true; - mDelimiter = 0; mDefaultNamespace = NULL; mTimeout = 30.; mConnectionLogger = NULL; + mAutomaticConfigurationDone = false; } IMAPAsyncSession::~IMAPAsyncSession() @@ -148,17 +149,6 @@ bool IMAPAsyncSession::isVoIPEnabled() return mVoIPEnabled; } - -void IMAPAsyncSession::setDelimiter(char delimiter) -{ - mDelimiter = delimiter; -} - -char IMAPAsyncSession::delimiter() -{ - return mDelimiter; -} - IMAPNamespace * IMAPAsyncSession::defaultNamespace() { return mDefaultNamespace; @@ -206,8 +196,12 @@ IMAPAsyncConnection * IMAPAsyncSession::session() session->setTimeout(mTimeout); session->setCheckCertificateEnabled(mCheckCertificateEnabled); session->setVoIPEnabled(mVoIPEnabled); - session->setDelimiter(mDelimiter); session->setDefaultNamespace(mDefaultNamespace); +#if 0 // should be implemented properly + if (mAutomaticConfigurationDone) { + session->setAutomaticConfigurationEnabled(false); + } +#endif return session; } @@ -495,4 +489,10 @@ IMAPMessageRenderingOperation * IMAPAsyncSession::plainTextBodyRenderingOperatio { IMAPAsyncConnection * session = sessionForFolder(folder); return session->plainTextBodyRenderingOperation(message, folder); -}
\ No newline at end of file +} + +void IMAPAsyncSession::automaticConfigurationDone(IMAPSession * session) +{ + setDefaultNamespace(session->defaultNamespace()); + mAutomaticConfigurationDone = true; +} diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index e5c17078..4360cdef 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -36,6 +36,7 @@ namespace mailcore { class IMAPQuotaOperation; class IMAPMessageRenderingOperation; class IMAPMessage; + class IMAPSession; class IMAPAsyncSession : public Object { public: @@ -74,9 +75,6 @@ namespace mailcore { virtual void setVoIPEnabled(bool enabled); virtual bool isVoIPEnabled(); - virtual void setDelimiter(char delimiter); - virtual char delimiter(); - virtual void setDefaultNamespace(IMAPNamespace * ns); virtual IMAPNamespace * defaultNamespace(); @@ -140,6 +138,9 @@ namespace mailcore { virtual IMAPMessageRenderingOperation * htmlBodyRenderingOperation(IMAPMessage * message, String * folder); virtual IMAPMessageRenderingOperation * plainTextRenderingOperation(IMAPMessage * message, String * folder); virtual IMAPMessageRenderingOperation * plainTextBodyRenderingOperation(IMAPMessage * message, String * folder); + + public: // private + virtual void automaticConfigurationDone(IMAPSession * session); private: Array * mSessions; @@ -153,12 +154,12 @@ namespace mailcore { ConnectionType mConnectionType; bool mCheckCertificateEnabled; bool mVoIPEnabled; - char mDelimiter; IMAPNamespace * mDefaultNamespace; time_t mTimeout; bool mAllowsFolderConcurrentAccessEnabled; unsigned int mMaximumConnections; ConnectionLogger * mConnectionLogger; + bool mAutomaticConfigurationDone; virtual IMAPAsyncConnection * sessionForFolder(String * folder, bool urgent = false); virtual IMAPAsyncConnection * session(); diff --git a/src/async/imap/MCIMAPCapabilityOperation.cc b/src/async/imap/MCIMAPCapabilityOperation.cc index 30bf1e3c..9edb9b1c 100644 --- a/src/async/imap/MCIMAPCapabilityOperation.cc +++ b/src/async/imap/MCIMAPCapabilityOperation.cc @@ -31,6 +31,11 @@ IndexSet * IMAPCapabilityOperation::capabilities() void IMAPCapabilityOperation::main() { ErrorCode error; + session()->session()->loginIfNeeded(&error); + if (error != ErrorNone) { + setError(error); + return; + } mCapabilities = session()->session()->capability(&error); MC_SAFE_RETAIN(mCapabilities); setError(error); diff --git a/src/async/imap/MCIMAPFetchFoldersOperation.cc b/src/async/imap/MCIMAPFetchFoldersOperation.cc index 41a95572..e1f121e8 100644 --- a/src/async/imap/MCIMAPFetchFoldersOperation.cc +++ b/src/async/imap/MCIMAPFetchFoldersOperation.cc @@ -52,15 +52,4 @@ void IMAPFetchFoldersOperation::main() } MC_SAFE_RETAIN(mFolders); setError(error); - - char * delimiterData = (char *) malloc(1); - * delimiterData = session()->session()->delimiter(); - performMethodOnMainThread((Object::Method) &IMAPFetchFoldersOperation::setDelimiterDataOnMainThread, - delimiterData, true); -} - -void IMAPFetchFoldersOperation::setDelimiterDataOnMainThread(char * delimiterData) -{ - session()->setDelimiter(* delimiterData); - free(delimiterData); } diff --git a/src/async/imap/MCIMAPFetchFoldersOperation.h b/src/async/imap/MCIMAPFetchFoldersOperation.h index c59bf85a..057df493 100644 --- a/src/async/imap/MCIMAPFetchFoldersOperation.h +++ b/src/async/imap/MCIMAPFetchFoldersOperation.h @@ -35,7 +35,6 @@ namespace mailcore { String * /* IMAPFolder */ mFolder; bool mFetchSubscribedEnabled; Array * mFolders; - void setDelimiterDataOnMainThread(char * delimiterData); }; } diff --git a/src/async/imap/MCIMAPOperation.cc b/src/async/imap/MCIMAPOperation.cc index 35eedd6c..1211a73b 100644 --- a/src/async/imap/MCIMAPOperation.cc +++ b/src/async/imap/MCIMAPOperation.cc @@ -10,6 +10,7 @@ #include <stdlib.h> +#include "MCIMAPAsyncSession.h" #include "MCIMAPSession.h" #include "MCIMAPAsyncConnection.h" #include "MCIMAPOperationCallback.h" @@ -133,3 +134,15 @@ void IMAPOperation::itemsProgressOnMainThread(void * ctx) free(context); release(); } + +void IMAPOperation::beforeMain() +{ +} + +void IMAPOperation::afterMain() +{ + if (mSession->session()->isAutomaticConfigurationDone()) { + mSession->owner()->automaticConfigurationDone(mSession->session()); + mSession->session()->resetAutomaticConfigurationDone(); + } +} diff --git a/src/async/imap/MCIMAPOperation.h b/src/async/imap/MCIMAPOperation.h index f7e937db..e7dcb9a5 100644 --- a/src/async/imap/MCIMAPOperation.h +++ b/src/async/imap/MCIMAPOperation.h @@ -34,6 +34,9 @@ namespace mailcore { virtual void setImapCallback(IMAPOperationCallback * callback); virtual IMAPOperationCallback * imapCallback(); + virtual void beforeMain(); + virtual void afterMain(); + virtual void start(); // Result. diff --git a/src/core/abstract/MCMessageConstants.h b/src/core/abstract/MCMessageConstants.h index 097ced04..30ce0efc 100644 --- a/src/core/abstract/MCMessageConstants.h +++ b/src/core/abstract/MCMessageConstants.h @@ -208,6 +208,7 @@ namespace mailcore { ErrorDeleteMessage, ErrorInvalidAccount, ErrorFile, + ErrorCompression, }; enum PartType { diff --git a/src/core/basetypes/MCOperation.cc b/src/core/basetypes/MCOperation.cc index d42a0598..73a8d7cd 100644 --- a/src/core/basetypes/MCOperation.cc +++ b/src/core/basetypes/MCOperation.cc @@ -40,10 +40,18 @@ bool Operation::isCancelled() return value; } +void Operation::beforeMain() +{ +} + void Operation::main() { } +void Operation::afterMain() +{ +} + void Operation::start() { } diff --git a/src/core/basetypes/MCOperation.h b/src/core/basetypes/MCOperation.h index 71d0b465..bb77dbb1 100644 --- a/src/core/basetypes/MCOperation.h +++ b/src/core/basetypes/MCOperation.h @@ -18,11 +18,17 @@ namespace mailcore { virtual void setCallback(OperationCallback * callback); virtual OperationCallback * callback(); - + virtual void cancel(); virtual bool isCancelled(); + // Will be called on main thread. + virtual void beforeMain(); + virtual void main(); + + // Will be called on main thread. + virtual void afterMain(); virtual void start(); diff --git a/src/core/basetypes/MCOperationQueue.cc b/src/core/basetypes/MCOperationQueue.cc index 9c30ad22..c20cb907 100644 --- a/src/core/basetypes/MCOperationQueue.cc +++ b/src/core/basetypes/MCOperationQueue.cc @@ -84,6 +84,8 @@ void OperationQueue::runOperations() break; } + performMethodOnMainThread((Object::Method) &OperationQueue::beforeMain, op, true); + op->main(); op->retain()->autorelease(); @@ -99,9 +101,7 @@ void OperationQueue::runOperations() pthread_mutex_unlock(&mLock); if (!op->isCancelled()) { - if (op->callback() != NULL) { - performMethodOnMainThread((Object::Method) &OperationQueue::callbackOnMainThread, op, true); - } + performMethodOnMainThread((Object::Method) &OperationQueue::callbackOnMainThread, op, true); } if (needsCheckRunning) { @@ -115,8 +115,15 @@ void OperationQueue::runOperations() MCLog("cleanup thread %p", this); } +void OperationQueue::beforeMain(Operation * op) +{ + op->beforeMain(); +} + void OperationQueue::callbackOnMainThread(Operation * op) { + op->afterMain(); + if (op->isCancelled()) return; diff --git a/src/core/basetypes/MCOperationQueue.h b/src/core/basetypes/MCOperationQueue.h index ddfe9de2..0518d62f 100644 --- a/src/core/basetypes/MCOperationQueue.h +++ b/src/core/basetypes/MCOperationQueue.h @@ -43,6 +43,7 @@ namespace mailcore { void startThread(); static void runOperationsOnThread(OperationQueue * queue); void runOperations(); + void beforeMain(Operation * op); void callbackOnMainThread(Operation * op); void checkRunningOnMainThread(void * context); void checkRunningAfterDelay(void * context); diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index 5dbe62a6..3c64909f 100755 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -36,6 +36,8 @@ String * mailcore::IMAPNamespacePersonal = NULL; String * mailcore::IMAPNamespaceOther = NULL; String * mailcore::IMAPNamespaceShared = NULL; +static Array * resultsWithError(int r, clist * list, ErrorCode * pError); + __attribute__((constructor)) static void initialize() { @@ -333,6 +335,8 @@ void IMAPSession::init() mQResyncEnabled = false; mCondstoreEnabled = false; mIdentityEnabled = false; + mNamespaceEnabled = false; + mCompressionEnabled = false; mWelcomeString = NULL; mNeedsMboxMailWorkaround = false; mDefaultNamespace = NULL; @@ -352,6 +356,8 @@ void IMAPSession::init() mProgressCallback = NULL; mProgressItemsCount = 0; mConnectionLogger = NULL; + mAutomaticConfigurationEnabled = true; + mAutomaticConfigurationDone = false; } IMAPSession::IMAPSession() @@ -471,16 +477,6 @@ bool IMAPSession::isVoIPEnabled() return mVoIPEnabled; } -void IMAPSession::setDelimiter(char delimiter) -{ - mDelimiter = delimiter; -} - -char IMAPSession::delimiter() -{ - return mDelimiter; -} - static bool hasError(int errorCode) { return ((errorCode != MAILIMAP_NO_ERROR) && (errorCode != MAILIMAP_NO_ERROR_AUTHENTICATED) && @@ -636,8 +632,24 @@ void IMAPSession::connect(ErrorCode * pError) mYahooServer = (mWelcomeString->locationOfString(MCSTR("yahoo.com")) != -1); } - * pError = ErrorNone; mState = STATE_CONNECTED; + + if (isAutomaticConfigurationEnabled()) { + if ((mImap->imap_connection_info != NULL) && (mImap->imap_connection_info->imap_capability != NULL)) { + // Don't keep result. It will be kept in session state. + capabilitySetWithSessionState(IndexSet::indexSet()); + } + else { + IndexSet * capabilities = capability(pError); + if (* pError != ErrorNone) { + MCLog("capabilities failed"); + unsetup(); + return; + } + } + } + + * pError = ErrorNone; MCLog("connect ok"); LOCK(); mCanIdle = true; @@ -676,6 +688,13 @@ void IMAPSession::login(ErrorCode * pError) MCAssert(mState == STATE_CONNECTED); + if (mImap->imap_connection_info != NULL) { + if (mImap->imap_connection_info->imap_capability != NULL) { + mailimap_capability_data_free(mImap->imap_connection_info->imap_capability); + mImap->imap_connection_info->imap_capability = NULL; + } + } + const char * utf8username; const char * utf8password; utf8username = MCUTF8(mUsername); @@ -809,8 +828,70 @@ void IMAPSession::login(ErrorCode * pError) return; } - * pError = ErrorNone; mState = STATE_LOGGEDIN; + + if (isAutomaticConfigurationEnabled()) { + if ((mImap->imap_connection_info != NULL) && (mImap->imap_connection_info->imap_capability != NULL)) { + // Don't keep result. It will be kept in session state. + capabilitySetWithSessionState(IndexSet::indexSet()); + } + else { + IndexSet * capabilities = capability(pError); + if (* pError != ErrorNone) { + MCLog("capabilities failed"); + return; + } + } + } + else { + // TODO: capabilities should be shared with other sessions for non automatic capabilities sessions. + } + enableFeatures(); + + if (isAutomaticConfigurationEnabled()) { + if (isNamespaceEnabled()) { + HashMap * result = fetchNamespace(pError); + if (* pError != ErrorNone) { + MCLog("fetch namespace failed"); + return; + } + IMAPNamespace * personalNamespace = (IMAPNamespace *) result->objectForKey(IMAPNamespacePersonal); + setDefaultNamespace(personalNamespace); + mDelimiter = defaultNamespace()->mainDelimiter(); + } + else { + clist * imap_folders; + IMAPFolder * folder; + Array * folders; + + r = mailimap_list(mImap, "", "", &imap_folders); + folders = resultsWithError(r, imap_folders, pError); + if (* pError != ErrorNone) + return; + + if (folders->count() > 0) { + folder = (IMAPFolder *) folders->objectAtIndex(0); + } + else { + folder = NULL; + } + if (folder == NULL) { + * pError = ErrorNonExistantFolder; + return; + } + + mDelimiter = folder->delimiter(); + IMAPNamespace * defaultNamespace = IMAPNamespace::namespaceWithPrefix(folder->path(), folder->delimiter()); + setDefaultNamespace(defaultNamespace); + } + } + else { + // TODO: namespace should be shared with other sessions for non automatic namespace. + } + + mAutomaticConfigurationDone = true; + + * pError = ErrorNone; MCLog("login ok"); } @@ -1127,6 +1208,7 @@ static Array * resultsWithError(int r, clist * list, ErrorCode * pError) return result; } +// Deprecated char IMAPSession::fetchDelimiterIfNeeded(char defaultDelimiter, ErrorCode * pError) { int r; @@ -1159,18 +1241,22 @@ Array * /* IMAPFolder */ IMAPSession::fetchSubscribedFolders(ErrorCode * pError) { int r; clist * imap_folders; - char delimiter; MCLog("fetch subscribed"); loginIfNeeded(pError); if (* pError != ErrorNone) return NULL; - delimiter = fetchDelimiterIfNeeded(mDelimiter, pError); - if (* pError != ErrorNone) - return NULL; - - setDelimiter(delimiter); + if (mDelimiter == 0) { + char delimiter; + + delimiter = fetchDelimiterIfNeeded(mDelimiter, pError); + if (* pError != ErrorNone) + return NULL; + + //setDelimiter(delimiter); + mDelimiter = delimiter; + } String * prefix; prefix = defaultNamespace()->mainPrefix(); @@ -1178,8 +1264,8 @@ Array * /* IMAPFolder */ IMAPSession::fetchSubscribedFolders(ErrorCode * pError) prefix = MCSTR(""); } if (prefix->length() > 0) { - if (!prefix->hasSuffix(String::stringWithUTF8Format("%c", delimiter))) { - prefix = prefix->stringByAppendingUTF8Format("%c", delimiter); + if (!prefix->hasSuffix(String::stringWithUTF8Format("%c", mDelimiter))) { + prefix = prefix->stringByAppendingUTF8Format("%c", mDelimiter); } } @@ -1192,17 +1278,21 @@ Array * /* IMAPFolder */ IMAPSession::fetchAllFolders(ErrorCode * pError) { int r; clist * imap_folders; - char delimiter; loginIfNeeded(pError); if (* pError != ErrorNone) return NULL; - delimiter = fetchDelimiterIfNeeded(mDelimiter, pError); - if (* pError != ErrorNone) - return NULL; - - setDelimiter(delimiter); + if (mDelimiter == 0) { + char delimiter; + + delimiter = fetchDelimiterIfNeeded(mDelimiter, pError); + if (* pError != ErrorNone) + return NULL; + + //setDelimiter(delimiter); + mDelimiter = delimiter; + } String * prefix = NULL; if (defaultNamespace()) { @@ -1212,8 +1302,8 @@ Array * /* IMAPFolder */ IMAPSession::fetchAllFolders(ErrorCode * pError) prefix = MCSTR(""); } if (prefix->length() > 0) { - if (!prefix->hasSuffix(String::stringWithUTF8Format("%c", delimiter))) { - prefix = prefix->stringByAppendingUTF8Format("%c", delimiter); + if (!prefix->hasSuffix(String::stringWithUTF8Format("%c", mDelimiter))) { + prefix = prefix->stringByAppendingUTF8Format("%c", mDelimiter); } } @@ -3018,7 +3108,7 @@ IndexSet * IMAPSession::capability(ErrorCode * pError) int r; struct mailimap_capability_data * cap; - loginIfNeeded(pError); + connectIfNeeded(pError); if (* pError != ErrorNone) return NULL; @@ -3039,39 +3129,76 @@ IndexSet * IMAPSession::capability(ErrorCode * pError) mailimap_capability_data_free(cap); IndexSet * result = new IndexSet(); + capabilitySetWithSessionState(result); + + * pError = ErrorNone; + result->autorelease(); + return result; +} + +void IMAPSession::capabilitySetWithSessionState(IndexSet * capabilities) +{ if (mailimap_has_id(mImap)) { - result->addIndex(IMAPCapabilityId); - mIdentityEnabled = true; + capabilities->addIndex(IMAPCapabilityId); } if (mailimap_has_xlist(mImap)) { - result->addIndex(IMAPCapabilityXList); - mXListEnabled = true; + capabilities->addIndex(IMAPCapabilityXList); } if (mailimap_has_extension(mImap, (char *) "X-GM-EXT-1")) { // Disable use of XLIST if this is the Gmail IMAP server because it implements // RFC 6154. - mXListEnabled = false; + capabilities->addIndex(IMAPCapabilityGmail); } if (mailimap_has_idle(mImap)) { - result->addIndex(IMAPCapabilityIdle); - mIdleEnabled = true; + capabilities->addIndex(IMAPCapabilityIdle); } if (mailimap_has_condstore(mImap)) { - result->addIndex(IMAPCapabilityCondstore); - mCondstoreEnabled = true; + capabilities->addIndex(IMAPCapabilityCondstore); } if (mailimap_has_qresync(mImap)) { - result->addIndex(IMAPCapabilityQResync); - mQResyncEnabled = true; + capabilities->addIndex(IMAPCapabilityQResync); } if (mailimap_has_xoauth2(mImap)) { - result->addIndex(IMAPCapabilityXOAuth2); + capabilities->addIndex(IMAPCapabilityXOAuth2); + } + if (mailimap_has_namespace(mImap)) { + capabilities->addIndex(IMAPCapabilityNamespace); + } + if (mailimap_has_compress_deflate(mImap)) { + capabilities->addIndex(IMAPCapabilityCompressDeflate); + } + applyCapabilities(capabilities); +} + +void IMAPSession::applyCapabilities(IndexSet * capabilities) +{ + if (capabilities->containsIndex(IMAPCapabilityId)) { + mIdentityEnabled = true; + } + if (capabilities->containsIndex(IMAPCapabilityXList)) { + mXListEnabled = true; + } + if (capabilities->containsIndex(IMAPCapabilityGmail)) { + mXListEnabled = false; + } + if (capabilities->containsIndex(IMAPCapabilityIdle)) { + mIdleEnabled = true; + } + if (capabilities->containsIndex(IMAPCapabilityCondstore)) { + mCondstoreEnabled = true; + } + if (capabilities->containsIndex(IMAPCapabilityQResync)) { + mQResyncEnabled = true; + } + if (capabilities->containsIndex(IMAPCapabilityXOAuth2)) { mXOauth2Enabled = true; } - - * pError = ErrorNone; - result->autorelease(); - return result; + if (capabilities->containsIndex(IMAPCapabilityNamespace)) { + mNamespaceEnabled = true; + } + if (capabilities->containsIndex(IMAPCapabilityCompressDeflate)) { + mCompressionEnabled = true; + } } bool IMAPSession::isIdleEnabled() @@ -3099,10 +3226,21 @@ bool IMAPSession::isIdentityEnabled() return mIdentityEnabled; } -bool IMAPSession::isXOAuthEnabled() { +bool IMAPSession::isXOAuthEnabled() +{ return mXOauth2Enabled; } +bool IMAPSession::isNamespaceEnabled() +{ + return mNamespaceEnabled; +} + +bool IMAPSession::isCompressionEnabled() +{ + return mCompressionEnabled; +} + bool IMAPSession::isDisconnected() { return mState == STATE_DISCONNECTED; @@ -3190,3 +3328,84 @@ String * IMAPSession::plainTextBodyRendering(IMAPMessage * message, String * fol return plainTextBodyString; } + +void IMAPSession::setAutomaticConfigurationEnabled(bool enabled) +{ + mAutomaticConfigurationEnabled = enabled; +} + +bool IMAPSession::isAutomaticConfigurationEnabled() +{ + return mAutomaticConfigurationEnabled; +} + +bool IMAPSession::enableFeature(String * feature) +{ + struct mailimap_capability_data * caps; + clist * cap_list; + struct mailimap_capability * cap; + int r; + + cap_list = clist_new(); + cap = mailimap_capability_new(MAILIMAP_CAPABILITY_NAME, NULL, strdup(MCUTF8(feature))); + clist_append(cap_list, cap); + caps = mailimap_capability_data_new(cap_list); + + struct mailimap_capability_data * result; + r = mailimap_enable(mImap, caps, &result); + if (r != MAILIMAP_NO_ERROR) + return false; + + mailimap_capability_data_free(result); + + return true; +} + +void IMAPSession::enableFeatures() +{ + if (isCompressionEnabled()) { + ErrorCode error; + enableCompression(&error); + if (error != ErrorNone) { + MCLog("could not enable compression"); + } + } + + if (isQResyncEnabled()) { + enableFeature(MCSTR("QRESYNC")); + } + else if (isCondstoreEnabled()) { + enableFeature(MCSTR("CONDSTORE")); + } +} + +void IMAPSession::enableCompression(ErrorCode * pError) +{ + int r; + r = mailimap_compress(mImap); + if (r == MAILIMAP_ERROR_STREAM) { + * pError = ErrorConnection; + return; + } + else if (r == MAILIMAP_ERROR_PARSE) { + * pError = ErrorParse; + return; + } + else if (hasError(r)) { + * pError = ErrorCompression; + return; + } + + this->mCompressionEnabled = true; + * pError = ErrorNone; +} + +bool IMAPSession::isAutomaticConfigurationDone() +{ + return mAutomaticConfigurationDone; +} + +void IMAPSession::resetAutomaticConfigurationDone() +{ + mAutomaticConfigurationDone = false; +} diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h index 0a5506ab..b2c7e25d 100755 --- a/src/core/imap/MCIMAPSession.h +++ b/src/core/imap/MCIMAPSession.h @@ -59,10 +59,6 @@ namespace mailcore { virtual bool isVoIPEnabled(); // Needed for fetchSubscribedFolders() and fetchAllFolders(). - virtual void setDelimiter(char delimiter); - virtual char delimiter(); - - // Needed for fetchSubscribedFolders() and fetchAllFolders(). virtual void setDefaultNamespace(IMAPNamespace * ns); virtual IMAPNamespace * defaultNamespace(); @@ -144,6 +140,8 @@ namespace mailcore { virtual IndexSet * capability(ErrorCode * pError); + virtual void enableCompression(ErrorCode * pError); + virtual uint32_t uidValidity(); virtual uint32_t uidNext(); virtual uint64_t modSequenceValue(); @@ -156,6 +154,8 @@ namespace mailcore { virtual bool isQResyncEnabled(); virtual bool isIdentityEnabled(); virtual bool isXOAuthEnabled(); + virtual bool isNamespaceEnabled(); + virtual bool isCompressionEnabled(); virtual void setConnectionLogger(ConnectionLogger * logger); virtual ConnectionLogger * connectionLogger(); @@ -173,10 +173,19 @@ namespace mailcore { This method can be used to generate the summary of the message.*/ virtual String * plainTextBodyRendering(IMAPMessage * message, String * folder, ErrorCode * pError); + /** Enable automatic query of the capabilities of the IMAP server when set to true. */ + virtual void setAutomaticConfigurationEnabled(bool enabled); + + /** Check if the automatic query of the capabilities of the IMAP server is enabled. */ + virtual bool isAutomaticConfigurationEnabled(); + public: // private virtual void loginIfNeeded(ErrorCode * pError); virtual void connectIfNeeded(ErrorCode * pError); virtual bool isDisconnected(); + virtual bool isAutomaticConfigurationDone(); + virtual void resetAutomaticConfigurationDone(); + virtual void applyCapabilities(IndexSet * capabilities); private: String * mHostname; @@ -199,6 +208,8 @@ namespace mailcore { bool mQResyncEnabled; bool mIdentityEnabled; bool mXOauth2Enabled; + bool mNamespaceEnabled; + bool mCompressionEnabled; String * mWelcomeString; bool mNeedsMboxMailWorkaround; uint32_t mUIDValidity; @@ -217,6 +228,8 @@ namespace mailcore { IMAPProgressCallback * mProgressCallback; unsigned int mProgressItemsCount; ConnectionLogger * mConnectionLogger; + bool mAutomaticConfigurationEnabled; + bool mAutomaticConfigurationDone; void init(); void bodyProgress(unsigned int current, unsigned int maximum); @@ -232,6 +245,9 @@ namespace mailcore { bool fetchByUID, struct mailimap_set * imapset, uint64_t modseq, HashMap * mapping, uint32_t startUid, IMAPProgressCallback * progressCallback, Array * extraHeaders, ErrorCode * pError); + void capabilitySetWithSessionState(IndexSet * capabilities); + bool enableFeature(String * feature); + void enableFeatures(); }; } diff --git a/src/objc/abstract/MCOConstants.h b/src/objc/abstract/MCOConstants.h index 427e787a..0bdf9af6 100644 --- a/src/objc/abstract/MCOConstants.h +++ b/src/objc/abstract/MCOConstants.h @@ -328,6 +328,8 @@ typedef enum { MCOErrorDeleteMessage, /** SMTP: Error while checking account.*/ MCOErrorInvalidAccount, + /** IMAP: Error when trying to enable compression.*/ + MCOErrorCompression, /** The count of all errors */ MCOErrorCodeCount, } MCOErrorCode; diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index ea920114..e92a0636 100755 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -79,9 +79,6 @@ /** When set to YES, VoIP capability will be enabled on the IMAP connection on iOS */ @property (nonatomic, assign, getter=isVoIPEnabled) BOOL voIPEnabled; -/** The default delimiter for the folder paths */ -@property (nonatomic, assign) char delimiter; - /** The default namespace. */ @property (nonatomic, strong) MCOIMAPNamespace * defaultNamespace; diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm index a9bbeb5c..b3584f4d 100755 --- a/src/objc/imap/MCOIMAPSession.mm +++ b/src/objc/imap/MCOIMAPSession.mm @@ -86,7 +86,6 @@ MCO_OBJC_SYNTHESIZE_SCALAR(MCOConnectionType, mailcore::ConnectionType, setConne MCO_OBJC_SYNTHESIZE_SCALAR(NSTimeInterval, time_t, setTimeout, timeout) MCO_OBJC_SYNTHESIZE_BOOL(setCheckCertificateEnabled, isCheckCertificateEnabled) MCO_OBJC_SYNTHESIZE_BOOL(setVoIPEnabled, isVoIPEnabled) -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) |