aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2013-08-18 22:53:03 -0700
committerGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2013-08-18 22:53:03 -0700
commit775ad7c56e930887967fb4d3fa6462c5ba826102 (patch)
treec860f0b48caa31394b5c61368eeb8aabd1d1be91 /src
parentc378363b5afc43b98d62acb1a3d8186a907da915 (diff)
parentd86e4a126eb37d62557f35ca7bd13d5e16ece648 (diff)
Merge branch 'autoconfiguration'
Diffstat (limited to 'src')
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncConnection.cc24
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncConnection.h7
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncSession.cc28
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncSession.h9
-rw-r--r--src/async/imap/MCIMAPCapabilityOperation.cc5
-rw-r--r--src/async/imap/MCIMAPFetchFoldersOperation.cc11
-rw-r--r--src/async/imap/MCIMAPFetchFoldersOperation.h1
-rw-r--r--src/async/imap/MCIMAPOperation.cc13
-rw-r--r--src/async/imap/MCIMAPOperation.h3
-rw-r--r--src/core/abstract/MCMessageConstants.h1
-rw-r--r--src/core/basetypes/MCOperation.cc8
-rw-r--r--src/core/basetypes/MCOperation.h8
-rw-r--r--src/core/basetypes/MCOperationQueue.cc13
-rw-r--r--src/core/basetypes/MCOperationQueue.h1
-rwxr-xr-xsrc/core/imap/MCIMAPSession.cc311
-rwxr-xr-xsrc/core/imap/MCIMAPSession.h24
-rw-r--r--src/objc/abstract/MCOConstants.h2
-rwxr-xr-xsrc/objc/imap/MCOIMAPSession.h3
-rwxr-xr-xsrc/objc/imap/MCOIMAPSession.mm1
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)