diff options
author | 2013-08-05 16:41:50 -0700 | |
---|---|---|
committer | 2013-08-05 16:41:50 -0700 | |
commit | f3a2c777ebe69fe2fefbebb31788757d82ce1837 (patch) | |
tree | 5af2cb7c33ef38183ad641dedda0b5758a17c444 /src | |
parent | 4970546ecec70e89e2baece66eccfd350c499050 (diff) |
Automatic fetch of namespace and capabilities in IMAPSession
Diffstat (limited to 'src')
-rw-r--r-- | src/core/imap/MCIMAPSession.cc | 196 | ||||
-rw-r--r-- | src/core/imap/MCIMAPSession.h | 18 |
2 files changed, 200 insertions, 14 deletions
diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index 7ebe4354..13cff58c 100644 --- 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,7 @@ void IMAPSession::init() mQResyncEnabled = false; mCondstoreEnabled = false; mIdentityEnabled = false; + mNamespaceEnabled = false; mWelcomeString = NULL; mNeedsMboxMailWorkaround = false; mDefaultNamespace = NULL; @@ -351,6 +354,9 @@ void IMAPSession::init() mProgressCallback = NULL; mProgressItemsCount = 0; mConnectionLogger = NULL; + mAutomaticCapabilitiesEnabled = true; + mAutomaticNamespaceEnabled = true; + mAutomaticConfigurationDone = false; } IMAPSession::IMAPSession() @@ -634,8 +640,24 @@ void IMAPSession::connect(ErrorCode * pError) MC_SAFE_REPLACE_RETAIN(String, mWelcomeString, String::stringWithUTF8Characters(mImap->imap_response)); } - * pError = ErrorNone; mState = STATE_CONNECTED; + + if (isAutomaticCapabilitiesEnabled()) { + 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; @@ -674,6 +696,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); @@ -807,8 +836,73 @@ void IMAPSession::login(ErrorCode * pError) return; } - * pError = ErrorNone; mState = STATE_LOGGEDIN; + + if (isAutomaticCapabilitiesEnabled()) { + 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; + } + } + + enableFeatures(); + } + else { + // TODO: capabilities should be shared for non automatic capabilities sessions. + enableFeatures(); + } + + if (isAutomaticNamespaceEnabled()) { + 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 for non automatic namespace. + // setDefaultNamespace() + } + + mAutomaticConfigurationDone = true; + + * pError = ErrorNone; MCLog("login ok"); } @@ -1124,6 +1218,7 @@ static Array * resultsWithError(int r, clist * list, ErrorCode * pError) return result; } +// Deprecated char IMAPSession::fetchDelimiterIfNeeded(char defaultDelimiter, ErrorCode * pError) { int r; @@ -2981,7 +3076,7 @@ IndexSet * IMAPSession::capability(ErrorCode * pError) int r; struct mailimap_capability_data * cap; - loginIfNeeded(pError); + connectIfNeeded(pError); if (* pError != ErrorNone) return NULL; @@ -3002,12 +3097,21 @@ 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); + capabilities->addIndex(IMAPCapabilityId); mIdentityEnabled = true; } if (mailimap_has_xlist(mImap)) { - result->addIndex(IMAPCapabilityXList); + capabilities->addIndex(IMAPCapabilityXList); mXListEnabled = true; } if (mailimap_has_extension(mImap, (char *) "X-GM-EXT-1")) { @@ -3016,25 +3120,25 @@ IndexSet * IMAPSession::capability(ErrorCode * pError) mXListEnabled = false; } if (mailimap_has_idle(mImap)) { - result->addIndex(IMAPCapabilityIdle); + capabilities->addIndex(IMAPCapabilityIdle); mIdleEnabled = true; } if (mailimap_has_condstore(mImap)) { - result->addIndex(IMAPCapabilityCondstore); + capabilities->addIndex(IMAPCapabilityCondstore); mCondstoreEnabled = true; } if (mailimap_has_condstore(mImap)) { - result->addIndex(IMAPCapabilityQResync); + capabilities->addIndex(IMAPCapabilityQResync); mQResyncEnabled = true; } if (mailimap_has_xoauth2(mImap)) { - result->addIndex(IMAPCapabilityXOAuth2); + capabilities->addIndex(IMAPCapabilityXOAuth2); mXOauth2Enabled = true; } - - * pError = ErrorNone; - result->autorelease(); - return result; + if (mailimap_has_namespace(mImap)) { + capabilities->addIndex(IMAPCapabilityNamespace); + mNamespaceEnabled = true; + } } bool IMAPSession::isIdleEnabled() @@ -3062,10 +3166,16 @@ bool IMAPSession::isIdentityEnabled() return mIdentityEnabled; } -bool IMAPSession::isXOAuthEnabled() { +bool IMAPSession::isXOAuthEnabled() +{ return mXOauth2Enabled; } +bool IMAPSession::isNamespaceEnabled() +{ + return mNamespaceEnabled; +} + bool IMAPSession::isDisconnected() { return mState == STATE_DISCONNECTED; @@ -3153,3 +3263,61 @@ String * IMAPSession::plainTextBodyRendering(IMAPMessage * message, String * fol return plainTextBodyString; } + +void IMAPSession::setAutomaticCapabilitiesEnabled(bool enabled) +{ + mAutomaticCapabilitiesEnabled = enabled; +} + +bool IMAPSession::isAutomaticCapabilitiesEnabled() +{ + return mAutomaticCapabilitiesEnabled; +} + +void IMAPSession::setAutomaticNamespaceEnabled(bool enabled) +{ + mAutomaticNamespaceEnabled = enabled; +} + +bool IMAPSession::isAutomaticNamespaceEnabled() +{ + return mAutomaticNamespaceEnabled; +} + +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 (isQResyncEnabled()) { + IMAPSession::enableFeature(MCSTR("QRESYNC")); + } + else if (isCondstoreEnabled()) { + IMAPSession::enableFeature(MCSTR("CONDSTORE")); + } +} + +bool IMAPSession::isAutomaticConfigurationDone() +{ + return mAutomaticConfigurationDone; +} + diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h index 4128b516..09b2fa17 100644 --- a/src/core/imap/MCIMAPSession.h +++ b/src/core/imap/MCIMAPSession.h @@ -155,6 +155,7 @@ namespace mailcore { virtual bool isQResyncEnabled(); virtual bool isIdentityEnabled(); virtual bool isXOAuthEnabled(); + virtual bool isNamespaceEnabled(); virtual void setConnectionLogger(ConnectionLogger * logger); virtual ConnectionLogger * connectionLogger(); @@ -172,10 +173,20 @@ 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 setAutomaticCapabilitiesEnabled(bool enabled); + + /** Check if the automatic query of the capabilities of the IMAP server is enabled. */ + virtual bool isAutomaticCapabilitiesEnabled(); + + virtual void setAutomaticNamespaceEnabled(bool enabled); + virtual bool isAutomaticNamespaceEnabled(); + public: // private virtual void loginIfNeeded(ErrorCode * pError); virtual void connectIfNeeded(ErrorCode * pError); virtual bool isDisconnected(); + virtual bool isAutomaticConfigurationDone(); private: String * mHostname; @@ -198,6 +209,7 @@ namespace mailcore { bool mQResyncEnabled; bool mIdentityEnabled; bool mXOauth2Enabled; + bool mNamespaceEnabled; String * mWelcomeString; bool mNeedsMboxMailWorkaround; uint32_t mUIDValidity; @@ -215,6 +227,9 @@ namespace mailcore { IMAPProgressCallback * mProgressCallback; unsigned int mProgressItemsCount; ConnectionLogger * mConnectionLogger; + bool mAutomaticCapabilitiesEnabled; + bool mAutomaticNamespaceEnabled; + bool mAutomaticConfigurationDone; void init(); void bodyProgress(unsigned int current, unsigned int maximum); @@ -230,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(); }; } |