diff options
author | Robert Widmann <devteam.codafi@gmail.com> | 2014-10-21 15:46:19 -0600 |
---|---|---|
committer | Robert Widmann <devteam.codafi@gmail.com> | 2014-10-21 15:46:19 -0600 |
commit | 53a1610d35f00301d933ea051b37b96fd30b0e93 (patch) | |
tree | bb2b4a0cdcac791365efc306feede072d347a9ba /src | |
parent | f60b89b388389ee877e907819442b2e366238040 (diff) | |
parent | df800fed1079fb0b9f49681d7b1688c1d3b97539 (diff) |
Merge remote-tracking branch 'upstream/master' into NNTP-Cleanup
Diffstat (limited to 'src')
56 files changed, 1235 insertions, 358 deletions
diff --git a/src/async/imap/MCIMAPAsyncSession.cc b/src/async/imap/MCIMAPAsyncSession.cc index 68625746..ef3bb621 100755 --- a/src/async/imap/MCIMAPAsyncSession.cc +++ b/src/async/imap/MCIMAPAsyncSession.cc @@ -524,7 +524,32 @@ IMAPFetchContentOperation * IMAPAsyncSession::fetchMessageAttachmentByUIDOperati return op; } -IMAPOperation * IMAPAsyncSession::storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) +IMAPFetchContentOperation * IMAPAsyncSession::fetchMessageByNumberOperation(String * folder, uint32_t number, bool urgent) +{ + IMAPFetchContentOperation * op = new IMAPFetchContentOperation(); + op->setMainSession(this); + op->setFolder(folder); + op->setNumber(number); + op->setUrgent(urgent); + op->autorelease(); + return op; +} + +IMAPFetchContentOperation * IMAPAsyncSession::fetchMessageAttachmentByNumberOperation(String * folder, uint32_t number, String * partID, + Encoding encoding, bool urgent) +{ + IMAPFetchContentOperation * op = new IMAPFetchContentOperation(); + op->setMainSession(this); + op->setFolder(folder); + op->setNumber(number); + op->setPartID(partID); + op->setEncoding(encoding); + op->setUrgent(urgent); + op->autorelease(); + return op; +} + +IMAPOperation * IMAPAsyncSession::storeFlagsByUIDOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) { IMAPStoreFlagsOperation * op = new IMAPStoreFlagsOperation(); op->setMainSession(this); @@ -537,7 +562,20 @@ IMAPOperation * IMAPAsyncSession::storeFlagsOperation(String * folder, IndexSet return op; } -IMAPOperation * IMAPAsyncSession::storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels) +IMAPOperation * IMAPAsyncSession::storeFlagsByNumberOperation(String * folder, IndexSet * numbers, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags) +{ + IMAPStoreFlagsOperation * op = new IMAPStoreFlagsOperation(); + op->setMainSession(this); + op->setFolder(folder); + op->setNumbers(numbers); + op->setKind(kind); + op->setFlags(flags); + op->setCustomFlags(customFlags); + op->autorelease(); + return op; +} + +IMAPOperation * IMAPAsyncSession::storeLabelsByUIDOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels) { IMAPStoreLabelsOperation * op = new IMAPStoreLabelsOperation(); op->setMainSession(this); @@ -549,6 +587,18 @@ IMAPOperation * IMAPAsyncSession::storeLabelsOperation(String * folder, IndexSet return op; } +IMAPOperation * IMAPAsyncSession::storeLabelsByNumberOperation(String * folder, IndexSet * numbers, IMAPStoreFlagsRequestKind kind, Array * labels) +{ + IMAPStoreLabelsOperation * op = new IMAPStoreLabelsOperation(); + op->setMainSession(this); + op->setFolder(folder); + op->setNumbers(numbers); + op->setKind(kind); + op->setLabels(labels); + op->autorelease(); + return op; +} + IMAPSearchOperation * IMAPAsyncSession::searchOperation(String * folder, IMAPSearchKind kind, String * searchString) { IMAPSearchOperation * op = new IMAPSearchOperation(); diff --git a/src/async/imap/MCIMAPAsyncSession.h b/src/async/imap/MCIMAPAsyncSession.h index 333783b2..a7ec90a0 100755 --- a/src/async/imap/MCIMAPAsyncSession.h +++ b/src/async/imap/MCIMAPAsyncSession.h @@ -133,8 +133,14 @@ namespace mailcore { virtual IMAPFetchContentOperation * fetchMessageAttachmentByUIDOperation(String * folder, uint32_t uid, String * partID, Encoding encoding, bool urgent = false); - virtual IMAPOperation * storeFlagsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags = NULL); - virtual IMAPOperation * storeLabelsOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels); + virtual IMAPFetchContentOperation * fetchMessageByNumberOperation(String * folder, uint32_t number, bool urgent = false); + virtual IMAPFetchContentOperation * fetchMessageAttachmentByNumberOperation(String * folder, uint32_t number, String * partID, + Encoding encoding, bool urgent = false); + + virtual IMAPOperation * storeFlagsByUIDOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags = NULL); + virtual IMAPOperation * storeFlagsByNumberOperation(String * folder, IndexSet * numbers, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags = NULL); + virtual IMAPOperation * storeLabelsByUIDOperation(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels); + virtual IMAPOperation * storeLabelsByNumberOperation(String * folder, IndexSet * numbers, IMAPStoreFlagsRequestKind kind, Array * labels); virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchKind kind, String * searchString); virtual IMAPSearchOperation * searchOperation(String * folder, IMAPSearchExpression * expression); diff --git a/src/async/imap/MCIMAPFetchContentOperation.cc b/src/async/imap/MCIMAPFetchContentOperation.cc index de3b911e..049ac8a7 100644 --- a/src/async/imap/MCIMAPFetchContentOperation.cc +++ b/src/async/imap/MCIMAPFetchContentOperation.cc @@ -16,6 +16,7 @@ using namespace mailcore; IMAPFetchContentOperation::IMAPFetchContentOperation() { mUid = 0; + mNumber = 0; mPartID = NULL; mEncoding = Encoding7Bit; mData = NULL; @@ -37,6 +38,16 @@ uint32_t IMAPFetchContentOperation::uid() return mUid; } +void IMAPFetchContentOperation::setNumber(uint32_t value) +{ + mNumber = value; +} + +uint32_t IMAPFetchContentOperation::number() +{ + return mNumber; +} + void IMAPFetchContentOperation::setPartID(String * partID) { MC_SAFE_REPLACE_COPY(String, mPartID, partID); @@ -65,11 +76,21 @@ Data * IMAPFetchContentOperation::data() void IMAPFetchContentOperation::main() { ErrorCode error; - if (mPartID != NULL) { - mData = session()->session()->fetchMessageAttachmentByUID(folder(), mUid, mPartID, mEncoding, this, &error); + if (mUid != 0) { + if (mPartID != NULL) { + mData = session()->session()->fetchMessageAttachmentByUID(folder(), mUid, mPartID, mEncoding, this, &error); + } + else { + mData = session()->session()->fetchMessageByUID(folder(), mUid, this, &error); + } } else { - mData = session()->session()->fetchMessageByUID(folder(), mUid, this, &error); + if (mPartID != NULL) { + mData = session()->session()->fetchMessageAttachmentByNumber(folder(), mNumber, mPartID, mEncoding, this, &error); + } + else { + mData = session()->session()->fetchMessageByNumber(folder(), mNumber, this, &error); + } } MC_SAFE_RETAIN(mData); setError(error); diff --git a/src/async/imap/MCIMAPFetchContentOperation.h b/src/async/imap/MCIMAPFetchContentOperation.h index 3d4dd17d..3cae3c5a 100644 --- a/src/async/imap/MCIMAPFetchContentOperation.h +++ b/src/async/imap/MCIMAPFetchContentOperation.h @@ -24,6 +24,9 @@ namespace mailcore { virtual void setUid(uint32_t uid); virtual uint32_t uid(); + virtual void setNumber(uint32_t value); + virtual uint32_t number(); + virtual void setPartID(String * partID); virtual String * partID(); @@ -38,6 +41,7 @@ namespace mailcore { private: uint32_t mUid; + uint32_t mNumber; String * mPartID; Encoding mEncoding; Data * mData; diff --git a/src/async/imap/MCIMAPFolderInfoOperation.cc b/src/async/imap/MCIMAPFolderInfoOperation.cc index 8ca500f3..0ea0d005 100644 --- a/src/async/imap/MCIMAPFolderInfoOperation.cc +++ b/src/async/imap/MCIMAPFolderInfoOperation.cc @@ -20,6 +20,7 @@ IMAPFolderInfoOperation::IMAPFolderInfoOperation() mMessageCount = 0; mModSequenceValue = 0; mFirstUnseenUid = 0; + mAllowsNewPermanentFlags = false; } IMAPFolderInfoOperation::~IMAPFolderInfoOperation() @@ -51,6 +52,11 @@ uint32_t IMAPFolderInfoOperation::firstUnseenUid() return mFirstUnseenUid; } +bool IMAPFolderInfoOperation::allowsNewPermanentFlags() +{ + return mAllowsNewPermanentFlags; +} + void IMAPFolderInfoOperation::main() { ErrorCode error; @@ -73,7 +79,8 @@ void IMAPFolderInfoOperation::main() mModSequenceValue = session()->session()->modSequenceValue(); mMessageCount = session()->session()->lastFolderMessageCount(); mFirstUnseenUid = session()->session()->firstUnseenUid(); - + mAllowsNewPermanentFlags = session()->session()->allowsNewPermanentFlags(); + setError(error); } diff --git a/src/async/imap/MCIMAPFolderInfoOperation.h b/src/async/imap/MCIMAPFolderInfoOperation.h index 9b0027a4..b53be2cb 100644 --- a/src/async/imap/MCIMAPFolderInfoOperation.h +++ b/src/async/imap/MCIMAPFolderInfoOperation.h @@ -26,6 +26,7 @@ namespace mailcore { virtual uint64_t modSequenceValue(); virtual int messageCount(); virtual uint32_t firstUnseenUid(); + virtual bool allowsNewPermanentFlags(); public: // subclass behavior virtual void main(); @@ -37,7 +38,8 @@ namespace mailcore { uint64_t mModSequenceValue; int mMessageCount; uint32_t mFirstUnseenUid; - + bool mAllowsNewPermanentFlags; + }; } diff --git a/src/async/imap/MCIMAPStoreFlagsOperation.cc b/src/async/imap/MCIMAPStoreFlagsOperation.cc index df68529a..a049333e 100644 --- a/src/async/imap/MCIMAPStoreFlagsOperation.cc +++ b/src/async/imap/MCIMAPStoreFlagsOperation.cc @@ -16,6 +16,7 @@ using namespace mailcore; IMAPStoreFlagsOperation::IMAPStoreFlagsOperation() { mUids = NULL; + mNumbers = NULL; mKind = IMAPStoreFlagsRequestKindAdd; mFlags = MessageFlagNone; mCustomFlags = NULL; @@ -23,6 +24,7 @@ IMAPStoreFlagsOperation::IMAPStoreFlagsOperation() IMAPStoreFlagsOperation::~IMAPStoreFlagsOperation() { + MC_SAFE_RELEASE(mNumbers); MC_SAFE_RELEASE(mUids); MC_SAFE_RELEASE(mCustomFlags); } @@ -37,6 +39,16 @@ IndexSet * IMAPStoreFlagsOperation::uids() return mUids; } +void IMAPStoreFlagsOperation::setNumbers(IndexSet * numbers) +{ + MC_SAFE_REPLACE_RETAIN(IndexSet, mNumbers, numbers); +} + +IndexSet * IMAPStoreFlagsOperation::numbers() +{ + return mNumbers; +} + void IMAPStoreFlagsOperation::setKind(IMAPStoreFlagsRequestKind kind) { mKind = kind; @@ -70,6 +82,11 @@ Array * IMAPStoreFlagsOperation::customFlags() void IMAPStoreFlagsOperation::main() { ErrorCode error; - session()->session()->storeFlagsAndCustomFlags(folder(), mUids, mKind, mFlags, mCustomFlags, &error); + if (mUids != NULL) { + session()->session()->storeFlagsAndCustomFlagsByUID(folder(), mUids, mKind, mFlags, mCustomFlags, &error); + } + else { + session()->session()->storeFlagsAndCustomFlagsByNumber(folder(), mNumbers, mKind, mFlags, mCustomFlags, &error); + } setError(error); } diff --git a/src/async/imap/MCIMAPStoreFlagsOperation.h b/src/async/imap/MCIMAPStoreFlagsOperation.h index f6219b30..1687f5cd 100644 --- a/src/async/imap/MCIMAPStoreFlagsOperation.h +++ b/src/async/imap/MCIMAPStoreFlagsOperation.h @@ -24,6 +24,9 @@ namespace mailcore { virtual void setUids(IndexSet * uids); virtual IndexSet * uids(); + virtual void setNumbers(IndexSet * numbers); + virtual IndexSet * numbers(); + virtual void setKind(IMAPStoreFlagsRequestKind kind); virtual IMAPStoreFlagsRequestKind kind(); @@ -38,6 +41,7 @@ namespace mailcore { private: IndexSet * mUids; + IndexSet * mNumbers; IMAPStoreFlagsRequestKind mKind; MessageFlag mFlags; Array * mCustomFlags; diff --git a/src/async/imap/MCIMAPStoreLabelsOperation.cc b/src/async/imap/MCIMAPStoreLabelsOperation.cc index ed738d11..3ad2212a 100644 --- a/src/async/imap/MCIMAPStoreLabelsOperation.cc +++ b/src/async/imap/MCIMAPStoreLabelsOperation.cc @@ -16,12 +16,14 @@ using namespace mailcore; IMAPStoreLabelsOperation::IMAPStoreLabelsOperation() { mUids = NULL; + mNumbers = NULL; mKind = IMAPStoreFlagsRequestKindAdd; mLabels = NULL; } IMAPStoreLabelsOperation::~IMAPStoreLabelsOperation() { + MC_SAFE_RELEASE(mNumbers); MC_SAFE_RELEASE(mUids); MC_SAFE_RELEASE(mLabels); } @@ -36,6 +38,16 @@ IndexSet * IMAPStoreLabelsOperation::uids() return mUids; } +void IMAPStoreLabelsOperation::setNumbers(IndexSet * numbers) +{ + MC_SAFE_REPLACE_RETAIN(IndexSet, mNumbers, numbers); +} + +IndexSet * IMAPStoreLabelsOperation::numbers() +{ + return mNumbers; +} + void IMAPStoreLabelsOperation::setKind(IMAPStoreFlagsRequestKind kind) { mKind = kind; @@ -59,7 +71,12 @@ Array * IMAPStoreLabelsOperation::labels() void IMAPStoreLabelsOperation::main() { ErrorCode error; - session()->session()->storeLabels(folder(), mUids, mKind, mLabels, &error); + if (mUids != NULL) { + session()->session()->storeLabelsByUID(folder(), mUids, mKind, mLabels, &error); + } + else { + session()->session()->storeLabelsByNumber(folder(), mUids, mKind, mLabels, &error); + } setError(error); } diff --git a/src/async/imap/MCIMAPStoreLabelsOperation.h b/src/async/imap/MCIMAPStoreLabelsOperation.h index 822cd83f..53348309 100644 --- a/src/async/imap/MCIMAPStoreLabelsOperation.h +++ b/src/async/imap/MCIMAPStoreLabelsOperation.h @@ -24,6 +24,9 @@ namespace mailcore { virtual void setUids(IndexSet * uids); virtual IndexSet * uids(); + virtual void setNumbers(IndexSet * numbers); + virtual IndexSet * numbers(); + virtual void setKind(IMAPStoreFlagsRequestKind kind); virtual IMAPStoreFlagsRequestKind kind(); @@ -35,6 +38,7 @@ namespace mailcore { private: IndexSet * mUids; + IndexSet * mNumbers; IMAPStoreFlagsRequestKind mKind; Array * /* String */ mLabels; diff --git a/src/core/abstract/MCAbstractPart.cc b/src/core/abstract/MCAbstractPart.cc index 50f12249..5b7a1c9a 100644 --- a/src/core/abstract/MCAbstractPart.cc +++ b/src/core/abstract/MCAbstractPart.cc @@ -27,6 +27,7 @@ AbstractPart::AbstractPart(AbstractPart * other) setContentDescription(other->mContentDescription); setInlineAttachment(other->mInlineAttachment); setPartType(other->mPartType); + setContentTypeParameters(other->mContentTypeParameters); } void AbstractPart::init() @@ -40,6 +41,7 @@ void AbstractPart::init() mContentDescription = NULL; mInlineAttachment = false; mPartType = PartTypeSingle; + mContentTypeParameters = NULL; } AbstractPart::~AbstractPart() @@ -51,6 +53,7 @@ AbstractPart::~AbstractPart() MC_SAFE_RELEASE(mContentID); MC_SAFE_RELEASE(mContentLocation); MC_SAFE_RELEASE(mContentDescription); + MC_SAFE_RELEASE(mContentTypeParameters); } String * AbstractPart::description() @@ -76,6 +79,11 @@ String * AbstractPart::description() result->appendUTF8Format("content-description: %s\n", mContentDescription->UTF8Characters()); } result->appendUTF8Format("inline: %i\n", mInlineAttachment); + if (mContentTypeParameters != NULL) { + mc_foreachhashmapKeyAndValue(String, key, String, value, mContentTypeParameters) { + result->appendUTF8Format("%s: %s\n", key->UTF8Characters(), value->UTF8Characters()); + } + } result->appendUTF8Format(">"); return result; @@ -395,3 +403,46 @@ void AbstractPart::importSerializable(HashMap * serializable) } } } + +void AbstractPart::setContentTypeParameters(HashMap * parameters) +{ + MC_SAFE_REPLACE_COPY(HashMap, mContentTypeParameters, parameters); +} + +Array * AbstractPart::allContentTypeParametersNames() +{ + if (mContentTypeParameters == NULL) + return Array::array(); + return mContentTypeParameters->allKeys(); +} + +void AbstractPart::setContentTypeParameter(String * name, String * object) +{ + if (mContentTypeParameters == NULL) { + mContentTypeParameters = new HashMap(); + } + removeContentTypeParameter(name); + mContentTypeParameters->setObjectForKey(name, object); +} + +void AbstractPart::removeContentTypeParameter(String * name) +{ + if (mContentTypeParameters == NULL) + return; + mc_foreachhashmapKey(String, key, mContentTypeParameters) { + if (key->isEqualCaseInsensitive(name)) { + mContentTypeParameters->removeObjectForKey(key); + break; + } + } +} + +String * AbstractPart::contentTypeParameterValueForName(String * name) +{ + mc_foreachhashmapKey(String, key, mContentTypeParameters) { + if (key->isEqualCaseInsensitive(name)) { + return (String *) mContentTypeParameters->objectForKey(key); + } + } + return NULL; +} diff --git a/src/core/abstract/MCAbstractPart.h b/src/core/abstract/MCAbstractPart.h index 7f641205..0fcbf279 100644 --- a/src/core/abstract/MCAbstractPart.h +++ b/src/core/abstract/MCAbstractPart.h @@ -48,6 +48,12 @@ namespace mailcore { virtual String * decodedStringForData(Data * data); + void setContentTypeParameters(HashMap * parameters); + Array * allContentTypeParametersNames(); + void setContentTypeParameter(String * name, String * object); + void removeContentTypeParameter(String * name); + String * contentTypeParameterValueForName(String * name); + public: // subclass behavior AbstractPart(AbstractPart * other); virtual String * description(); @@ -70,6 +76,7 @@ namespace mailcore { String * mContentDescription; bool mInlineAttachment; PartType mPartType; + HashMap * mContentTypeParameters; void init(); }; diff --git a/src/core/abstract/MCMessageConstants.h b/src/core/abstract/MCMessageConstants.h index 222ca322..c81f8360 100644 --- a/src/core/abstract/MCMessageConstants.h +++ b/src/core/abstract/MCMessageConstants.h @@ -178,6 +178,7 @@ namespace mailcore { IMAPSearchKindRecipient, // Recipient is the combination of To, Cc and Bcc IMAPSearchKindSubject, IMAPSearchKindContent, + IMAPSearchKindBody, IMAPSearchKindUIDs, IMAPSearchKindHeader, IMAPSearchKindRead, @@ -247,6 +248,7 @@ namespace mailcore { ErrorNoSender, ErrorNoRecipient, ErrorNoop, + ErrorGmailApplicationSpecificPasswordRequired, }; enum PartType { diff --git a/src/core/abstract/MCMessageHeader.cc b/src/core/abstract/MCMessageHeader.cc index 6e8d2c09..89dec15c 100644 --- a/src/core/abstract/MCMessageHeader.cc +++ b/src/core/abstract/MCMessageHeader.cc @@ -62,7 +62,6 @@ void MessageHeader::init(bool generateDate, bool generateMessageID) mDate = (time_t) -1; mReceivedDate = (time_t) -1; mExtraHeaders = NULL; - mlcExtraHeaders = NULL; if (generateDate) { time_t date; @@ -116,7 +115,6 @@ MessageHeader::~MessageHeader() MC_SAFE_RELEASE(mReplyTo); MC_SAFE_RELEASE(mSubject); MC_SAFE_RELEASE(mExtraHeaders); - MC_SAFE_RELEASE(mlcExtraHeaders); } String * MessageHeader::description() @@ -307,13 +305,6 @@ String * MessageHeader::userAgent() void MessageHeader::setExtraHeaders(HashMap * headers) { MC_SAFE_REPLACE_COPY(HashMap, mExtraHeaders, headers); - MC_SAFE_RELEASE(mlcExtraHeaders); - if (mExtraHeaders != NULL) { - mlcExtraHeaders = new HashMap(); - mc_foreachhashmapKeyAndValue(String, key, String, value, mExtraHeaders) { - mlcExtraHeaders->setObjectForKey(key->lowercaseString(), value); - } - } } Array * MessageHeader::allExtraHeadersNames() @@ -328,30 +319,30 @@ void MessageHeader::setExtraHeader(String * name, String * object) if (mExtraHeaders == NULL) { mExtraHeaders = new HashMap(); } - if (mlcExtraHeaders == NULL) { - mlcExtraHeaders = new HashMap(); - } - if (object == NULL) { - removeExtraHeader(name); - return; - } + removeExtraHeader(name); mExtraHeaders->setObjectForKey(name, object); - mlcExtraHeaders->setObjectForKey(name->lowercaseString(), object); } void MessageHeader::removeExtraHeader(String * name) { if (mExtraHeaders == NULL) return; - mExtraHeaders->removeObjectForKey(name); - mlcExtraHeaders->removeObjectForKey(name); + mc_foreachhashmapKey(String, key, mExtraHeaders) { + if (key->isEqualCaseInsensitive(name)) { + mExtraHeaders->removeObjectForKey(key); + break; + } + } } String * MessageHeader::extraHeaderValueForName(String * name) { - if (mlcExtraHeaders == NULL) - return NULL; - return (String *) mlcExtraHeaders->objectForKey(name->lowercaseString()); + mc_foreachhashmapKey(String, key, mExtraHeaders) { + if (key->isEqualCaseInsensitive(name)) { + return (String *) mExtraHeaders->objectForKey(key); + } + } + return NULL; } String * MessageHeader::extractedSubject() diff --git a/src/core/abstract/MCMessageHeader.h b/src/core/abstract/MCMessageHeader.h index 51b1e2f7..4018343c 100644 --- a/src/core/abstract/MCMessageHeader.h +++ b/src/core/abstract/MCMessageHeader.h @@ -99,7 +99,6 @@ namespace mailcore { time_t mDate; time_t mReceivedDate; HashMap * mExtraHeaders; - HashMap * mlcExtraHeaders; void init(bool generateDate, bool generateMessageID); void setExtraHeaders(HashMap *headers); Array * recipientWithReplyAll(bool replyAll, bool includeTo, bool includeCc, Array * senderEmails); diff --git a/src/core/basetypes/MCIterator.h b/src/core/basetypes/MCIterator.h index c8b23fab..e1f258d4 100644 --- a/src/core/basetypes/MCIterator.h +++ b/src/core/basetypes/MCIterator.h @@ -32,13 +32,13 @@ for (unsigned int __index = 0; NULL != (__variable = (type *) mailcore::ArrayIte keyType * __key; \ HashMapIterator __key##__iterator = HashMapIteratorInit(__hashmap, true, false); \ while (HashMapIteratorRun(&__key##__iterator)) \ -while (HashMapIteratorNext(&__key##__iterator, &__key, NULL)) +while (HashMapIteratorNext(&__key##__iterator, (Object **) &__key, (Object **) NULL)) #define mc_foreachhashmapValue(valueType, __value, __hashmap) \ valueType * __value; \ HashMapIterator __value##__iterator = HashMapIteratorInit(__hashmap, false, true); \ while (HashMapIteratorRun(&__value##__iterator)) \ -while (HashMapIteratorNext(&__value##__iterator, NULL, (Object **) &__value)) +while (HashMapIteratorNext(&__value##__iterator, (Object **) NULL, (Object **) &__value)) #define mc_foreachhashmapKeyAndValue(keyType, __key, valueType, __value, __hashmap) \ keyType * __key; \ diff --git a/src/core/basetypes/MCObject.cc b/src/core/basetypes/MCObject.cc index 0e8d9639..1d8f0c27 100644 --- a/src/core/basetypes/MCObject.cc +++ b/src/core/basetypes/MCObject.cc @@ -130,6 +130,7 @@ struct mainThreadCallData { static pthread_once_t delayedPerformOnce = PTHREAD_ONCE_INIT; static chash * delayedPerformHash = NULL; +static pthread_mutex_t delayedPerformLock = PTHREAD_MUTEX_INITIALIZER; static void reallyInitDelayedPerform() { @@ -164,7 +165,9 @@ static void removeFromPerformHash(Object * obj, Object::Method method, void * co key.data = &keyData; key.len = sizeof(keyData); + pthread_mutex_lock(&delayedPerformLock); chash_delete(delayedPerformHash, (chashdatum *) &key, NULL); + pthread_mutex_unlock(&delayedPerformLock); } static void queueIdentifierDestructor(void * identifier) @@ -196,7 +199,9 @@ static void addToPerformHash(Object * obj, Object::Method method, void * context key.len = sizeof(keyData); value.data = performValue; value.len = 0; + pthread_mutex_lock(&delayedPerformLock); chash_set(delayedPerformHash, &key, &value, NULL); + pthread_mutex_unlock(&delayedPerformLock); } static void * getFromPerformHash(Object * obj, Object::Method method, void * context, void * targetDispatchQueue) @@ -221,7 +226,9 @@ static void * getFromPerformHash(Object * obj, Object::Method method, void * con key.data = &keyData; key.len = sizeof(keyData); + pthread_mutex_lock(&delayedPerformLock); r = chash_get(delayedPerformHash, &key, &value); + pthread_mutex_unlock(&delayedPerformLock); if (r < 0) return NULL; diff --git a/src/core/basetypes/MCOperationQueue.cc b/src/core/basetypes/MCOperationQueue.cc index e45f04ee..7783a978 100644 --- a/src/core/basetypes/MCOperationQueue.cc +++ b/src/core/basetypes/MCOperationQueue.cc @@ -178,11 +178,21 @@ void OperationQueue::checkRunningOnMainThread(void * context) { retain(); // (4) if (_pendingCheckRunning) { +#if __APPLE__ + cancelDelayedPerformMethodOnDispatchQueue((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL, mDispatchQueue); +#else cancelDelayedPerformMethod((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL); +#endif release(); // (4) } _pendingCheckRunning = true; + +#if __APPLE__ + performMethodOnDispatchQueueAfterDelay((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL, mDispatchQueue, 1); +#else performMethodAfterDelay((Object::Method) &OperationQueue::checkRunningAfterDelay, NULL, 1); +#endif + release(); // (1) } @@ -215,6 +225,11 @@ void OperationQueue::stoppedOnMainThread(void * context) mCallback->queueStoppedRunning(); } + if (mOperations->count() > 0) { + //Operations have been added while thread was quitting, so restart automatically + startThread(); + } + release(); // (2) release(); // (3) diff --git a/src/core/basetypes/MCString.cc b/src/core/basetypes/MCString.cc index 5c2da323..bcc1ec9d 100644 --- a/src/core/basetypes/MCString.cc +++ b/src/core/basetypes/MCString.cc @@ -1355,17 +1355,8 @@ static void charactersParsed(void * context, } String * modifiedString; modifiedString = new String((const char *) ch, len); - modifiedString->replaceOccurrencesOfString(MCSTR("\n"), MCSTR(" ")); - modifiedString->replaceOccurrencesOfString(MCSTR("\r"), MCSTR(" ")); - modifiedString->replaceOccurrencesOfString(MCSTR("\t"), MCSTR(" ")); - - UChar specialCh[2]; - specialCh[0] = 133; - specialCh[1] = 0; - modifiedString->replaceOccurrencesOfString(String::stringWithCharacters(specialCh), MCSTR(" ")); - - while (modifiedString->replaceOccurrencesOfString(MCSTR(" "), MCSTR(" ")) > 0) { - } + modifiedString->autorelease(); + modifiedString = modifiedString->stripWhitespace(); if (modifiedString->length() > 0) { if (state->lastCharIsWhitespace) { @@ -1413,7 +1404,6 @@ static void charactersParsed(void * context, state->hasText = true; } } - modifiedString->release(); } /* GCS: custom error function to ignore errors */ @@ -1830,6 +1820,13 @@ String * String::stripWhitespace() str->replaceOccurrencesOfString(MCSTR("\v"), MCSTR(" ")); str->replaceOccurrencesOfString(MCSTR("\f"), MCSTR(" ")); str->replaceOccurrencesOfString(MCSTR("\r"), MCSTR(" ")); + UChar ch[2]; + ch[0] = 160; + ch[1] = 0; + str->replaceOccurrencesOfString(String::stringWithCharacters(ch), MCSTR(" ")); + ch[0] = 133; + ch[1] = 0; + str->replaceOccurrencesOfString(String::stringWithCharacters(ch), MCSTR(" ")); while (str->replaceOccurrencesOfString(MCSTR(" "), MCSTR(" ")) > 0) { /* do nothing */ @@ -1863,6 +1860,8 @@ bool String::hasPrefix(String * prefix) String * String::lastPathComponent() { // TODO: Improve Windows compatibility. + if (mUnicodeChars == NULL) + return MCSTR(""); UChar * component = u_strrchr(mUnicodeChars, '/'); if (component == NULL) return (String *) this->copy()->autorelease(); diff --git a/src/core/imap/MCIMAPMessage.cc b/src/core/imap/MCIMAPMessage.cc index 6cb1472c..7f393f32 100644 --- a/src/core/imap/MCIMAPMessage.cc +++ b/src/core/imap/MCIMAPMessage.cc @@ -16,6 +16,7 @@ static AbstractPart * partForPartIDInMessagePart(AbstractMessagePart * part, Str void IMAPMessage::init() { mUid = 0; + mSequenceNumber = 0; mFlags = MessageFlagNone; mOriginalFlags = MessageFlagNone; mCustomFlags = NULL; @@ -35,6 +36,7 @@ IMAPMessage::IMAPMessage(IMAPMessage * other) : AbstractMessage(other) { init(); setUid(other->uid()); + setSequenceNumber(other->sequenceNumber()); setFlags(other->flags()); setOriginalFlags(other->originalFlags()); setCustomFlags(other->customFlags()); @@ -59,7 +61,7 @@ Object * IMAPMessage::copy() String * IMAPMessage::description() { String * result = String::string(); - result->appendUTF8Format("<%s:%p %u\n", className()->UTF8Characters(), this, (unsigned int) uid()); + result->appendUTF8Format("<%s:%p %u %u\n", className()->UTF8Characters(), this, (unsigned int) uid(), (unsigned int) sequenceNumber()); result->appendString(header()->description()); if (mainPart() != NULL) { result->appendString(mainPart()->description()); @@ -79,6 +81,16 @@ void IMAPMessage::setUid(uint32_t uid) mUid = uid; } +uint32_t IMAPMessage::sequenceNumber() +{ + return mSequenceNumber; +} + +void IMAPMessage::setSequenceNumber(uint32_t value) +{ + mSequenceNumber = value; +} + uint32_t IMAPMessage::size() { return mSize; @@ -235,6 +247,7 @@ String * IMAPMessage::htmlRendering(String * folder, HashMap * IMAPMessage::serializable() { + // sequenceNumber is not serialized. HashMap * result = AbstractMessage::serializable(); result->setObjectForKey(MCSTR("modSeqValue"), String::stringWithUTF8Format("%llu", (long long unsigned) modSeqValue())); result->setObjectForKey(MCSTR("uid"), String::stringWithUTF8Format("%lu", (long unsigned) uid())); @@ -261,6 +274,7 @@ HashMap * IMAPMessage::serializable() void IMAPMessage::importSerializable(HashMap * serializable) { + // sequenceNumber is not serialized. AbstractMessage::importSerializable(serializable); String * modSeq = (String *) serializable->objectForKey(MCSTR("modSeqValue")); if (modSeq != NULL) { diff --git a/src/core/imap/MCIMAPMessage.h b/src/core/imap/MCIMAPMessage.h index a78a04d6..b5266719 100644 --- a/src/core/imap/MCIMAPMessage.h +++ b/src/core/imap/MCIMAPMessage.h @@ -20,6 +20,9 @@ namespace mailcore { IMAPMessage(); virtual ~IMAPMessage(); + virtual uint32_t sequenceNumber(); + virtual void setSequenceNumber(uint32_t sequenceNumber); + virtual uint32_t uid(); virtual void setUid(uint32_t uid); @@ -70,6 +73,7 @@ namespace mailcore { uint64_t mModSeqValue; uint32_t mUid; uint32_t mSize; + uint32_t mSequenceNumber; // not serialized. MessageFlag mFlags; MessageFlag mOriginalFlags; diff --git a/src/core/imap/MCIMAPSearchExpression.cc b/src/core/imap/MCIMAPSearchExpression.cc index cd3ccc2d..b3467e59 100644 --- a/src/core/imap/MCIMAPSearchExpression.cc +++ b/src/core/imap/MCIMAPSearchExpression.cc @@ -154,6 +154,14 @@ IMAPSearchExpression * IMAPSearchExpression::searchContent(String * value) return (IMAPSearchExpression *) expr->autorelease(); } +IMAPSearchExpression * IMAPSearchExpression::searchBody(String * value) +{ + IMAPSearchExpression * expr = new IMAPSearchExpression(); + expr->mKind = IMAPSearchKindBody; + MC_SAFE_REPLACE_COPY(String, expr->mValue, value); + return (IMAPSearchExpression *) expr->autorelease(); +} + IMAPSearchExpression * IMAPSearchExpression::searchUIDs(IndexSet * uids) { IMAPSearchExpression * expr = new IMAPSearchExpression(); diff --git a/src/core/imap/MCIMAPSearchExpression.h b/src/core/imap/MCIMAPSearchExpression.h index a0647216..a6e4833b 100644 --- a/src/core/imap/MCIMAPSearchExpression.h +++ b/src/core/imap/MCIMAPSearchExpression.h @@ -33,6 +33,7 @@ namespace mailcore { static IMAPSearchExpression * searchRecipient(String * value); static IMAPSearchExpression * searchSubject(String * value); static IMAPSearchExpression * searchContent(String * value); + static IMAPSearchExpression * searchBody(String * value); static IMAPSearchExpression * searchHeader(String * header, String * value); static IMAPSearchExpression * searchUIDs(IndexSet * uids); static IMAPSearchExpression * searchRead(); diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index a2fe5c9e..50602842 100755 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -237,59 +237,6 @@ static Array * arrayFromSet(struct mailimap_set * imap_set) return result; } -#if 0 -static int compareValuesUnsignedLong(void * value1, void * value2, void * context) -{ - Value * concreteValue1 = (Value *) value1; - Value * concreteValue2 = (Value *) value2; - - if (concreteValue2->unsignedLongValue() > concreteValue1->unsignedLongValue()) { - return 1; - } - else if (concreteValue2->unsignedLongValue() < concreteValue1->unsignedLongValue()) { - return -1; - } - else { - return 0; - } -} - -static struct mailimap_set * setFromArray(Array * array) -{ - unsigned int currentIndex = 0; - unsigned int currentFirst = 0; - unsigned int currentValue = 0; - unsigned int lastValue = 0; - struct mailimap_set * imap_set; - - array = array->sortedArray(compareValuesUnsignedLong, NULL); - imap_set = mailimap_set_new_empty(); - - while (currentIndex < array->count()) { - currentValue = (unsigned int) ((Value *) array->objectAtIndex(currentIndex))->unsignedLongValue(); - if (currentFirst == 0) { - currentFirst = currentValue; - } - - if ((lastValue != 0) && (currentValue != lastValue + 1)) { - mailimap_set_add_interval(imap_set, currentFirst, lastValue); - currentFirst = 0; - lastValue = 0; - } - else { - lastValue = currentValue; - currentIndex ++; - } - } - if (currentFirst != 0) { - mailimap_set_add_interval(imap_set, currentFirst, lastValue); - } - - return imap_set; -} - -#endif - static clist * splitSet(struct mailimap_set * set, unsigned int splitCount) { struct mailimap_set * current_set; @@ -378,6 +325,7 @@ void IMAPSession::init() mNamespaceEnabled = false; mCompressionEnabled = false; mIsGmail = false; + mAllowsNewPermanentFlags = false; mWelcomeString = NULL; mNeedsMboxMailWorkaround = false; mDefaultNamespace = NULL; @@ -870,6 +818,9 @@ void IMAPSession::login(ErrorCode * pError) else if (response->locationOfString(MCSTR("Maximum number of connections")) != -1) { * pError = ErrorGmailTooManySimultaneousConnections; } + else if (response->locationOfString(MCSTR("Application-specific password required")) != -1) { + * pError = ErrorGmailApplicationSpecificPasswordRequired; + } else if (response->locationOfString(MCSTR("http://me.com/move")) != -1) { * pError = ErrorMobileMeMoved; } @@ -1077,7 +1028,20 @@ void IMAPSession::select(String * folder, ErrorCode * pError) mFirstUnseenUid = 0; } - + if (mImap->imap_selection_info->sel_perm_flags) { + clistiter * cur; + + struct mailimap_flag_perm * perm_flag; + for(cur = clist_end(mImap->imap_selection_info->sel_perm_flags) ; cur != NULL ; + cur = clist_previous(cur)) { + perm_flag = (struct mailimap_flag_perm *)clist_content(cur); + mAllowsNewPermanentFlags = perm_flag->fl_type == MAILIMAP_FLAG_PERM_ALL; + if (mAllowsNewPermanentFlags) { + break; + } + } + } + mModSequenceValue = get_mod_sequence_value(mImap); } @@ -1761,7 +1725,7 @@ void IMAPSession::expunge(String * folder, ErrorCode * pError) } static int -fetch_imap(mailimap * imap, uint32_t uid, +fetch_imap(mailimap * imap, bool identifier_is_uid, uint32_t identifier, struct mailimap_fetch_type * fetch_type, char ** result, size_t * result_len) { @@ -1774,8 +1738,13 @@ fetch_imap(mailimap * imap, uint32_t uid, size_t text_length; clistiter * cur; - set = mailimap_set_new_single(uid); - r = mailimap_uid_fetch(imap, set, fetch_type, &fetch_result); + set = mailimap_set_new_single(identifier); + if (identifier_is_uid) { + r = mailimap_uid_fetch(imap, set, fetch_type, &fetch_result); + } + else { + r = mailimap_fetch(imap, set, fetch_type, &fetch_result); + } mailimap_set_free(set); @@ -1786,7 +1755,7 @@ fetch_imap(mailimap * imap, uint32_t uid, return r; } - if (clist_begin(fetch_result) == NULL) { + if (clist_isempty(fetch_result)) { mailimap_fetch_list_free(fetch_result); return MAILIMAP_ERROR_FETCH; } @@ -1800,16 +1769,18 @@ fetch_imap(mailimap * imap, uint32_t uid, cur = clist_next(cur)) { msg_att_item = (struct mailimap_msg_att_item *) clist_content(cur); - if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) { - - if (msg_att_item->att_data.att_static->att_type == - MAILIMAP_MSG_ATT_BODY_SECTION) { - text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part; - msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = NULL; - text_length = - msg_att_item->att_data.att_static->att_data.att_body_section->sec_length; - } + if (msg_att_item->att_type != MAILIMAP_MSG_ATT_ITEM_STATIC) { + continue; } + + if (msg_att_item->att_data.att_static->att_type != + MAILIMAP_MSG_ATT_BODY_SECTION) { + continue; + } + + text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part; + msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = NULL; + text_length = msg_att_item->att_data.att_static->att_data.att_body_section->sec_length; } mailimap_fetch_list_free(fetch_result); @@ -1978,6 +1949,7 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context) if (mapping != NULL) { uid = (uint32_t) ((Value *) mapping->objectForKey(Value::valueWithUnsignedLongValue(msg_att->att_number)))->longLongValue(); } + msg->setSequenceNumber(msg_att->att_number); for(item_iter = clist_begin(msg_att->att_list) ; item_iter != NULL ; item_iter = clist_next(item_iter)) { struct mailimap_msg_att_item * att_item; @@ -2469,9 +2441,23 @@ Array * IMAPSession::fetchMessagesByNumberWithExtraHeaders(String * folder, IMAP return result; } -static int fetch_rfc822(mailimap * session, - uint32_t msgid, char ** result) +static int fetch_rfc822(mailimap * session, bool identifier_is_uid, + uint32_t identifier, char ** result, size_t * result_len) { + struct mailimap_section * section; + struct mailimap_fetch_att * fetch_att; + struct mailimap_fetch_type * fetch_type; + + section = mailimap_section_new(NULL); + fetch_att = mailimap_fetch_att_new_body_peek_section(section); + fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att); + int r = fetch_imap(session, identifier_is_uid, identifier, + fetch_type, result, result_len); + mailimap_fetch_type_free(fetch_type); + + return r; + +#if 0 int r; clist * fetch_list; struct mailimap_section * section; @@ -2487,9 +2473,14 @@ static int fetch_rfc822(mailimap * session, fetch_att = mailimap_fetch_att_new_body_peek_section(section); fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att); - set = mailimap_set_new_single(msgid); + set = mailimap_set_new_single(identifier); - r = mailimap_uid_fetch(session, set, fetch_type, &fetch_list); + if (identifier_is_uid) { + r = mailimap_uid_fetch(session, set, fetch_type, &fetch_list); + } + else { + r = mailimap_fetch(session, set, fetch_type, &fetch_list); + } mailimap_set_free(set); mailimap_fetch_type_free(fetch_type); @@ -2529,27 +2520,41 @@ free: mailimap_fetch_list_free(fetch_list); err: return res; +#endif } Data * IMAPSession::fetchMessageByUID(String * folder, uint32_t uid, IMAPProgressCallback * progressCallback, ErrorCode * pError) { + return fetchMessage(folder, true, uid, progressCallback, pError); +} + +Data * IMAPSession::fetchMessageByNumber(String * folder, uint32_t number, + IMAPProgressCallback * progressCallback, ErrorCode * pError) +{ + return fetchMessage(folder, false, number, progressCallback, pError); +} + +Data * IMAPSession::fetchMessage(String * folder, bool identifier_is_uid, uint32_t identifier, + IMAPProgressCallback * progressCallback, ErrorCode * pError) +{ char * rfc822; + size_t rfc822_len; int r; Data * data; - + selectIfNeeded(folder, pError); if (* pError != ErrorNone) return NULL; - + mProgressItemsCount = 0; mProgressCallback = progressCallback; - + rfc822 = NULL; - r = fetch_rfc822(mImap, uid, &rfc822); + r = fetch_rfc822(mImap, identifier_is_uid, identifier, &rfc822, &rfc822_len); if (r == MAILIMAP_NO_ERROR) { size_t len; - + len = 0; if (rfc822 != NULL) { len = strlen(rfc822); @@ -2557,7 +2562,7 @@ Data * IMAPSession::fetchMessageByUID(String * folder, uint32_t uid, bodyProgress((unsigned int) len, (unsigned int) len); } mProgressCallback = NULL; - + if (r == MAILIMAP_ERROR_STREAM) { mShouldDisconnect = true; * pError = ErrorConnection; @@ -2571,22 +2576,23 @@ Data * IMAPSession::fetchMessageByUID(String * folder, uint32_t uid, * pError = ErrorFetch; return NULL; } - + if (rfc822 == NULL) { data = Data::data(); } else { - data = Data::dataWithBytes(rfc822, (unsigned int) strlen(rfc822)); + data = Data::dataWithBytes(rfc822, (unsigned int) rfc822_len); } - + mailimap_nstring_free(rfc822); * pError = ErrorNone; - + return data; } -Data * IMAPSession::fetchMessageAttachmentByUID(String * folder, uint32_t uid, String * partID, - Encoding encoding, IMAPProgressCallback * progressCallback, ErrorCode * pError) +Data * IMAPSession::fetchMessageAttachment(String * folder, bool identifier_is_uid, + uint32_t identifier, String * partID, + Encoding encoding, IMAPProgressCallback * progressCallback, ErrorCode * pError) { struct mailimap_fetch_type * fetch_type; struct mailimap_fetch_att * fetch_att; @@ -2623,7 +2629,7 @@ Data * IMAPSession::fetchMessageAttachmentByUID(String * folder, uint32_t uid, S fetch_att = mailimap_fetch_att_new_body_peek_section(section); fetch_type = mailimap_fetch_type_new_fetch_att(fetch_att); - r = fetch_imap(mImap, uid, fetch_type, &text, &text_length); + r = fetch_imap(mImap, identifier_is_uid, identifier, fetch_type, &text, &text_length); mailimap_fetch_type_free(fetch_type); mProgressCallback = NULL; @@ -2652,6 +2658,18 @@ Data * IMAPSession::fetchMessageAttachmentByUID(String * folder, uint32_t uid, S return data; } +Data * IMAPSession::fetchMessageAttachmentByUID(String * folder, uint32_t uid, String * partID, + Encoding encoding, IMAPProgressCallback * progressCallback, ErrorCode * pError) +{ + return fetchMessageAttachment(folder, true, uid, partID, encoding, progressCallback, pError); +} + +Data * IMAPSession::fetchMessageAttachmentByNumber(String * folder, uint32_t number, String * partID, + Encoding encoding, IMAPProgressCallback * progressCallback, ErrorCode * pError) +{ + return fetchMessageAttachment(folder, false, number, partID, encoding, progressCallback, pError); +} + IndexSet * IMAPSession::search(String * folder, IMAPSearchKind kind, String * searchString, ErrorCode * pError) { IMAPSearchExpression * expr; @@ -2755,6 +2773,10 @@ static struct mailimap_search_key * searchKeyFromSearchExpression(IMAPSearchExpr { return mailimap_search_key_new_text(strdup(expression->value()->UTF8Characters())); } + case IMAPSearchKindBody: + { + return mailimap_search_key_new_body(strdup(expression->value()->UTF8Characters())); + } case IMAPSearchKindUIDs: { return mailimap_search_key_new_uid(setFromIndexSet(expression->uids())); @@ -2947,7 +2969,14 @@ IndexSet * IMAPSession::search(String * folder, IMAPSearchExpression * expressio if (mYahooServer) { charset = NULL; } - int r = mailimap_uid_search(mImap, charset, key, &result_list); + + int r; + if (mIsGmail) { + r = mailimap_uid_search_literalplus(mImap, charset, key, &result_list); + } + else { + r = mailimap_uid_search(mImap, charset, key, &result_list); + } mailimap_search_key_free(key); MCLog("had error : %i", r); if (r == MAILIMAP_ERROR_STREAM) { @@ -3280,12 +3309,18 @@ HashMap * IMAPSession::fetchNamespace(ErrorCode * pError) return result; } -void IMAPSession::storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError) +void IMAPSession::storeFlagsByUID(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError) { - this->storeFlagsAndCustomFlags(folder, uids, kind, flags, NULL, pError); + this->storeFlagsAndCustomFlagsByUID(folder, uids, kind, flags, NULL, pError); } -void IMAPSession::storeFlagsAndCustomFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError) +void IMAPSession::storeFlagsAndCustomFlagsByUID(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError) +{ + storeFlagsAndCustomFlags(folder, true, uids, kind, flags, customFlags, pError); +} + +void IMAPSession::storeFlagsAndCustomFlags(String * folder, bool identifier_is_uid, IndexSet * identifiers, + IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError) { struct mailimap_set * imap_set; struct mailimap_store_att_flags * store_att_flags; @@ -3297,7 +3332,7 @@ void IMAPSession::storeFlagsAndCustomFlags(String * folder, IndexSet * uids, IMA if (* pError != ErrorNone) return; - imap_set = setFromIndexSet(uids); + imap_set = setFromIndexSet(identifiers); if (clist_count(imap_set->set_list) == 0) { mailimap_set_free(imap_set); return; @@ -3388,7 +3423,12 @@ void IMAPSession::storeFlagsAndCustomFlags(String * folder, IndexSet * uids, IMA store_att_flags = mailimap_store_att_flags_new_set_flags_silent(flag_list); break; } - r = mailimap_uid_store(mImap, current_set, store_att_flags); + if (identifier_is_uid) { + r = mailimap_uid_store(mImap, current_set, store_att_flags); + } + else { + r = mailimap_store(mImap, current_set, store_att_flags); + } if (r == MAILIMAP_ERROR_STREAM) { mShouldDisconnect = true; @@ -3418,7 +3458,27 @@ void IMAPSession::storeFlagsAndCustomFlags(String * folder, IndexSet * uids, IMA * pError = ErrorNone; } -void IMAPSession::storeLabels(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels, ErrorCode * pError) +void IMAPSession::storeFlagsByNumber(String * folder, IndexSet * numbers, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError) +{ + this->storeFlagsAndCustomFlagsByNumber(folder, numbers, kind, flags, NULL, pError); +} + +void IMAPSession::storeFlagsAndCustomFlagsByNumber(String * folder, IndexSet * numbers, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError) +{ + storeFlagsAndCustomFlags(folder, false, numbers, kind, flags, customFlags, pError); +} + +void IMAPSession::storeLabelsByUID(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels, ErrorCode * pError) +{ + storeLabels(folder, true, uids, kind, labels, pError); +} + +void IMAPSession::storeLabelsByNumber(String * folder, IndexSet * numbers, IMAPStoreFlagsRequestKind kind, Array * labels, ErrorCode * pError) +{ + storeLabels(folder, false, numbers, kind, labels, pError); +} + +void IMAPSession::storeLabels(String * folder, bool identifier_is_uid, IndexSet * identifiers, IMAPStoreFlagsRequestKind kind, Array * labels, ErrorCode * pError) { struct mailimap_set * imap_set; struct mailimap_msg_att_xgmlabels * xgmlabels; @@ -3429,7 +3489,7 @@ void IMAPSession::storeLabels(String * folder, IndexSet * uids, IMAPStoreFlagsRe if (* pError != ErrorNone) return; - imap_set = setFromIndexSet(uids); + imap_set = setFromIndexSet(identifiers); if (clist_count(imap_set->set_list) == 0) { mailimap_set_free(imap_set); return; @@ -3460,7 +3520,12 @@ void IMAPSession::storeLabels(String * folder, IndexSet * uids, IMAPStoreFlagsRe fl_sign = 0; break; } - r = mailimap_uid_store_xgmlabels(mImap, current_set, fl_sign, 1, xgmlabels); + if (identifier_is_uid) { + r = mailimap_uid_store_xgmlabels(mImap, current_set, fl_sign, 1, xgmlabels); + } + else { + r = mailimap_store_xgmlabels(mImap, current_set, fl_sign, 1, xgmlabels); + } if (r == MAILIMAP_ERROR_STREAM) { mShouldDisconnect = true; * pError = ErrorConnection; @@ -3694,6 +3759,10 @@ bool IMAPSession::isCompressionEnabled() return mCompressionEnabled; } +bool IMAPSession::allowsNewPermanentFlags() { + return mAllowsNewPermanentFlags; +} + bool IMAPSession::isDisconnected() { return mState == STATE_DISCONNECTED; diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h index e52dc74f..591466fc 100755 --- a/src/core/imap/MCIMAPSession.h +++ b/src/core/imap/MCIMAPSession.h @@ -110,8 +110,12 @@ namespace mailcore { virtual Data * fetchMessageByUID(String * folder, uint32_t uid, IMAPProgressCallback * progressCallback, ErrorCode * pError); + virtual Data * fetchMessageByNumber(String * folder, uint32_t number, + IMAPProgressCallback * progressCallback, ErrorCode * pError); virtual Data * fetchMessageAttachmentByUID(String * folder, uint32_t uid, String * partID, Encoding encoding, IMAPProgressCallback * progressCallback, ErrorCode * pError); + virtual Data * fetchMessageAttachmentByNumber(String * folder, uint32_t number, String * partID, + Encoding encoding, IMAPProgressCallback * progressCallback, ErrorCode * pError); virtual HashMap * fetchMessageNumberUIDMapping(String * folder, uint32_t fromUID, uint32_t toUID, ErrorCode * pError); @@ -125,9 +129,13 @@ namespace mailcore { IMAPProgressCallback * progressCallback, Array * extraHeaders, ErrorCode * pError); - virtual void storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError); - virtual void storeFlagsAndCustomFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError); - virtual void storeLabels(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels, ErrorCode * pError); + virtual void storeFlagsByUID(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError); + virtual void storeFlagsAndCustomFlagsByUID(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError); + virtual void storeFlagsByNumber(String * folder, IndexSet * numbers, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError); + virtual void storeFlagsAndCustomFlagsByNumber(String * folder, IndexSet * numbers, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError); + + virtual void storeLabelsByUID(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, Array * labels, ErrorCode * pError); + virtual void storeLabelsByNumber(String * folder, IndexSet * numbers, IMAPStoreFlagsRequestKind kind, Array * labels, ErrorCode * pError); virtual IndexSet * search(String * folder, IMAPSearchKind kind, String * searchString, ErrorCode * pError); virtual IndexSet * search(String * folder, IMAPSearchExpression * expression, ErrorCode * pError); @@ -167,7 +175,8 @@ namespace mailcore { virtual bool isXOAuthEnabled(); virtual bool isNamespaceEnabled(); virtual bool isCompressionEnabled(); - + virtual bool allowsNewPermanentFlags(); + virtual String * gmailUserDisplayName(); virtual void setConnectionLogger(ConnectionLogger * logger); @@ -227,6 +236,7 @@ namespace mailcore { bool mNamespaceEnabled; bool mCompressionEnabled; bool mIsGmail; + bool mAllowsNewPermanentFlags; String * mWelcomeString; bool mNeedsMboxMailWorkaround; uint32_t mUIDValidity; @@ -268,6 +278,14 @@ namespace mailcore { void capabilitySetWithSessionState(IndexSet * capabilities); bool enableFeature(String * feature); void enableFeatures(); + Data * fetchMessage(String * folder, bool identifier_is_uid, uint32_t identifier, + IMAPProgressCallback * progressCallback, ErrorCode * pError); + void storeFlagsAndCustomFlags(String * folder, bool identifier_is_uid, IndexSet * identifiers, + IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError); + Data * fetchMessageAttachment(String * folder, bool identifier_is_uid, + uint32_t identifier, String * partID, + Encoding encoding, IMAPProgressCallback * progressCallback, ErrorCode * pError); + void storeLabels(String * folder, bool identifier_is_uid, IndexSet * identifiers, IMAPStoreFlagsRequestKind kind, Array * labels, ErrorCode * pError); }; } diff --git a/src/core/pop/MCPOPSession.cc b/src/core/pop/MCPOPSession.cc index 0d26682e..b703f16d 100644 --- a/src/core/pop/MCPOPSession.cc +++ b/src/core/pop/MCPOPSession.cc @@ -241,7 +241,7 @@ void POPSession::connect(ErrorCode * pError) default: r = mailpop3_socket_connect(mPop, MCUTF8(hostname()), port()); - if (r != MAILIMAP_NO_ERROR) { + if (r != MAILPOP3_NO_ERROR) { * pError = ErrorConnection; return; } diff --git a/src/core/renderer/MCDateFormatter.cc b/src/core/renderer/MCDateFormatter.cc index 2882977d..96d347d5 100644 --- a/src/core/renderer/MCDateFormatter.cc +++ b/src/core/renderer/MCDateFormatter.cc @@ -216,6 +216,12 @@ void DateFormatter::prepare() localeRef = CFLocaleCopyCurrent(); } mAppleDateFormatter = CFDateFormatterCreate(NULL, localeRef, toAppleStyle(mDateStyle), toAppleStyle(mTimeStyle)); + if (mDateFormat != NULL) { + CFStringRef dateFormatCFString = CFStringCreateWithCharacters(NULL, (const UniChar *) mDateFormat->unicodeCharacters(), + mDateFormat->length()); + CFDateFormatterSetFormat((CFDateFormatterRef) mAppleDateFormatter, dateFormatCFString); + CFRelease(dateFormatCFString); + } if (localeIdentifier != NULL) { CFRelease(localeIdentifier); } diff --git a/src/core/rfc822/MCAttachment.cc b/src/core/rfc822/MCAttachment.cc index 172881cb..63551b6a 100644 --- a/src/core/rfc822/MCAttachment.cc +++ b/src/core/rfc822/MCAttachment.cc @@ -87,6 +87,9 @@ HashMap * Attachment::readMimeTypesFile(String * filename) String * Attachment::mimeTypeForFilename(String * filename) { + if (filename == NULL) { + return NULL; + } static HashMap * mimeTypes = NULL; static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&lock); @@ -211,8 +214,6 @@ Attachment * Attachment::attachmentWithText(String * text) void Attachment::init() { mData = NULL; - mContentTypeParameters = NULL; - mlcContentTypeParameters = NULL; setMimeType(MCSTR("application/octet-stream")); } @@ -225,14 +226,11 @@ Attachment::Attachment(Attachment * other) : AbstractPart(other) { init(); MC_SAFE_REPLACE_RETAIN(Data, mData, other->mData); - setContentTypeParameters(other->mContentTypeParameters); } Attachment::~Attachment() { MC_SAFE_RELEASE(mData); - MC_SAFE_RELEASE(mContentTypeParameters); - MC_SAFE_RELEASE(mlcContentTypeParameters); } String * Attachment::description() @@ -261,11 +259,6 @@ String * Attachment::description() else { result->appendUTF8Format("no data\n"); } - if (mContentTypeParameters != NULL) { - mc_foreachhashmapKeyAndValue(String, key, String, value, mContentTypeParameters) { - result->appendUTF8Format("%s: %s\n", key->UTF8Characters(), value->UTF8Characters()); - } - } result->appendUTF8Format(">"); return result; @@ -296,56 +289,6 @@ String * Attachment::decodedString() } } -void Attachment::setContentTypeParameters(HashMap * parameters) -{ - MC_SAFE_REPLACE_COPY(HashMap, mContentTypeParameters, parameters); - MC_SAFE_RELEASE(mlcContentTypeParameters); - if (mContentTypeParameters != NULL) { - mlcContentTypeParameters = new HashMap(); - mc_foreachhashmapKeyAndValue(String, key, String, value, mContentTypeParameters) { - mlcContentTypeParameters->setObjectForKey(key->lowercaseString(), value); - } - } -} - -Array * Attachment::allContentTypeParametersNames() -{ - if (mContentTypeParameters == NULL) - return Array::array(); - return mContentTypeParameters->allKeys(); -} - -void Attachment::setContentTypeParameter(String * name, String * object) -{ - if (mContentTypeParameters == NULL) { - mContentTypeParameters = new HashMap(); - } - if (mlcContentTypeParameters == NULL) { - mlcContentTypeParameters = new HashMap(); - } - if (object == NULL) { - removeContentTypeParameter(name); - return; - } - mContentTypeParameters->setObjectForKey(name, object); - mlcContentTypeParameters->setObjectForKey(name->lowercaseString(), object); -} - -void Attachment::removeContentTypeParameter(String * name) -{ - if (mContentTypeParameters == NULL) - return; - mContentTypeParameters->removeObjectForKey(name); - mlcContentTypeParameters->removeObjectForKey(name); -} - -String * Attachment::contentTypeParameterValueForName(String * name) -{ - if (mlcContentTypeParameters == NULL) - return NULL; - return (String *) mlcContentTypeParameters->objectForKey(name->lowercaseString()); -} - AbstractPart * Attachment::attachmentsWithMIME(struct mailmime * mime) { return attachmentsWithMIMEWithMain(mime, true); diff --git a/src/core/rfc822/MCAttachment.h b/src/core/rfc822/MCAttachment.h index 069688f2..2217bc4c 100644 --- a/src/core/rfc822/MCAttachment.h +++ b/src/core/rfc822/MCAttachment.h @@ -29,11 +29,6 @@ namespace mailcore { virtual Data * data(); virtual String * decodedString(); - virtual void setContentTypeParameter(String * name, String * value); - virtual void removeContentTypeParameter(String * name); - virtual String * contentTypeParameterValueForName(String *name); - virtual Array * allContentTypeParametersNames(); - public: // subclass behavior Attachment(Attachment * other); virtual String * description(); @@ -44,8 +39,6 @@ namespace mailcore { private: Data * mData; - HashMap * mContentTypeParameters; - HashMap * mlcContentTypeParameters; void init(); static void fillMultipartSubAttachments(AbstractMultipart * multipart, struct mailmime * mime); static AbstractPart * attachmentsWithMIMEWithMain(struct mailmime * mime, bool isMain); diff --git a/src/core/rfc822/MCMessageBuilder.cc b/src/core/rfc822/MCMessageBuilder.cc index 3e63ce4a..0ffe0819 100644 --- a/src/core/rfc822/MCMessageBuilder.cc +++ b/src/core/rfc822/MCMessageBuilder.cc @@ -12,32 +12,54 @@ using namespace mailcore; static char * generate_boundary(const char * boundary_prefix); -struct mailmime * part_multiple_new(const char * type, const char * boundary_prefix); +struct mailmime * part_multiple_new(MessageBuilder * builder, const char * type, const char * boundary_prefix); static struct mailmime * -part_new_empty(struct mailmime_content * content, +part_new_empty(MessageBuilder * builder, struct mailmime_content * content, struct mailmime_fields * mime_fields, const char * boundary_prefix, int force_single); -static struct mailmime * get_multipart_alternative(const char * boundary_prefix) +static struct mailmime * get_multipart_alternative(MessageBuilder * builder, const char * boundary_prefix) { struct mailmime * mime; - mime = part_multiple_new("multipart/alternative", boundary_prefix); + mime = part_multiple_new(builder, "multipart/alternative", boundary_prefix); return mime; } -static struct mailmime * get_multipart_related(const char * boundary_prefix) +static struct mailmime * get_multipart_related(MessageBuilder * builder, const char * boundary_prefix) { struct mailmime * mime; - mime = part_multiple_new("multipart/related", boundary_prefix); + mime = part_multiple_new(builder, "multipart/related", boundary_prefix); return mime; } -static int add_attachment(struct mailmime * mime, +static struct mailmime * get_multipart_signed_pgp(MessageBuilder * builder, const char * boundary_prefix) +{ + struct mailmime * mime; + + mime = part_multiple_new(builder, "multipart/signed", boundary_prefix); + struct mailmime_parameter * param = mailmime_param_new_with_data((char *) "protocol", (char *) "application/pgp-signature"); + clist_append(mime->mm_content_type->ct_parameters, param); + + return mime; +} + +static struct mailmime * get_multipart_encrypted_pgp(MessageBuilder * builder, const char * boundary_prefix) +{ + struct mailmime * mime; + + mime = part_multiple_new(builder, "multipart/encrypted", boundary_prefix); + struct mailmime_parameter * param = mailmime_param_new_with_data((char *) "protocol", (char *) "application/pgp-encrypted"); + clist_append(mime->mm_content_type->ct_parameters, param); + + return mime; +} + +static int add_attachment(MessageBuilder * builder, struct mailmime * mime, struct mailmime * mime_sub, const char * boundary_prefix) { @@ -88,7 +110,7 @@ static int add_attachment(struct mailmime * mime, /* create a multipart */ - mp = part_multiple_new("multipart/mixed", boundary_prefix); + mp = part_multiple_new(builder, "multipart/mixed", boundary_prefix); if (mp == NULL) { res = MAILIMF_ERROR_MEMORY; goto err; @@ -132,7 +154,8 @@ err: return res; } -static struct mailmime * get_text_part(const char * mime_type, const char * charset, const char * content_id, +static struct mailmime * get_text_part(MessageBuilder * builder, + const char * mime_type, const char * charset, const char * content_id, const char * description, const char * text, size_t length, int encoding_type, clist * contentTypeParameters) { @@ -169,23 +192,30 @@ static struct mailmime * get_text_part(const char * mime_type, const char * char clist_concat(content->ct_parameters, contentTypeParameters); } - mime = part_new_empty(content, mime_fields, NULL, 1); + mime = part_new_empty(builder, content, mime_fields, NULL, 1); mailmime_set_body_text(mime, (char *) text, length); return mime; } -static struct mailmime * get_plain_text_part(const char * mime_type, const char * charset, const char * content_id, +static struct mailmime * get_plain_text_part(MessageBuilder * builder, + const char * mime_type, const char * charset, const char * content_id, const char * description, - const char * text, size_t length, clist * contentTypeParameters) + const char * text, size_t length, clist * contentTypeParameters, bool forEncryption) { bool needsQuotedPrintable; int mechanism; needsQuotedPrintable = false; - for(size_t i = 0 ; i < length ; i ++) { - if ((text[i] & (1 << 7)) != 0) { - needsQuotedPrintable = true; + if (forEncryption) { + needsQuotedPrintable = true; + } + if (!needsQuotedPrintable) { + for(size_t i = 0 ; i < length ; i ++) { + if ((text[i] & (1 << 7)) != 0) { + needsQuotedPrintable = true; + break; + } } } @@ -193,17 +223,19 @@ static struct mailmime * get_plain_text_part(const char * mime_type, const char if (needsQuotedPrintable) { mechanism = MAILMIME_MECHANISM_QUOTED_PRINTABLE; } - return get_text_part(mime_type, charset, content_id, description, text, length, mechanism, contentTypeParameters); + return get_text_part(builder, mime_type, charset, content_id, description, text, length, mechanism, contentTypeParameters); } -static struct mailmime * get_other_text_part(const char * mime_type, const char * charset, const char * content_id, +static struct mailmime * get_other_text_part(MessageBuilder * builder, + const char * mime_type, const char * charset, const char * content_id, const char * description, const char * text, size_t length, clist * contentTypeParameters) { - return get_text_part(mime_type, charset, content_id, description, text, length, MAILMIME_MECHANISM_QUOTED_PRINTABLE, contentTypeParameters); + return get_text_part(builder, mime_type, charset, content_id, description, text, length, MAILMIME_MECHANISM_QUOTED_PRINTABLE, contentTypeParameters); } -static struct mailmime * get_file_part(const char * filename, const char * mime_type, int is_inline, +static struct mailmime * get_file_part(MessageBuilder * builder, + const char * filename, const char * mime_type, int is_inline, const char * content_id, const char * content_description, const char * text, size_t length, clist * contentTypeParameters) @@ -247,7 +279,7 @@ static struct mailmime * get_file_part(const char * filename, const char * mime_ clist_concat(content->ct_parameters, contentTypeParameters); } - mime = part_new_empty(content, mime_fields, NULL, 1); + mime = part_new_empty(builder, content, mime_fields, NULL, 1); mailmime_set_body_text(mime, (char *) text, length); return mime; @@ -272,7 +304,7 @@ static clist * content_type_parameters_from_attachment(Attachment * att) return contentTypeParameters; } -static struct mailmime * mime_from_attachment(Attachment * att) +static struct mailmime * mime_from_attachment(MessageBuilder * builder, Attachment * att, bool forEncryption) { struct mailmime * mime; Data * data; @@ -291,21 +323,22 @@ static struct mailmime * mime_from_attachment(Attachment * att) else { clist * contentTypeParameters = content_type_parameters_from_attachment(att); if (att->isInlineAttachment() && att->mimeType()->lowercaseString()->isEqual(MCSTR("text/plain"))) { - mime = get_plain_text_part(MCUTF8(att->mimeType()), MCUTF8(att->charset()), + mime = get_plain_text_part(builder, MCUTF8(att->mimeType()), MCUTF8(att->charset()), MCUTF8(att->contentID()), MIME_ENCODED_STR(att->contentDescription()), data->bytes(), data->length(), - contentTypeParameters); + contentTypeParameters, + forEncryption); } else if (att->isInlineAttachment() && att->mimeType()->lowercaseString()->hasPrefix(MCSTR("text/"))) { - mime = get_other_text_part(MCUTF8(att->mimeType()), MCUTF8(att->charset()), + mime = get_other_text_part(builder, MCUTF8(att->mimeType()), MCUTF8(att->charset()), MCUTF8(att->contentID()), MIME_ENCODED_STR(att->contentDescription()), data->bytes(), data->length(), contentTypeParameters); } else { - mime = get_file_part(MIME_ENCODED_STR(att->filename()), + mime = get_file_part(builder, MIME_ENCODED_STR(att->filename()), MCUTF8(att->mimeType()), att->isInlineAttachment(), MCUTF8(att->contentID()), MIME_ENCODED_STR(att->contentDescription()), @@ -319,24 +352,25 @@ static struct mailmime * mime_from_attachment(Attachment * att) return mime; } -static struct mailmime * multipart_related_from_attachments(Attachment * htmlAttachment, - Array * attachments, const char * boundary_prefix) +static struct mailmime * multipart_related_from_attachments(MessageBuilder * builder, + Attachment * htmlAttachment, + Array * attachments, const char * boundary_prefix, bool forEncryption) { if ((attachments != NULL) && (attachments->count() > 0)) { struct mailmime * submime; struct mailmime * mime; - mime = get_multipart_related(boundary_prefix); + mime = get_multipart_related(builder, boundary_prefix); - submime = mime_from_attachment(htmlAttachment); - add_attachment(mime, submime, boundary_prefix); + submime = mime_from_attachment(builder, htmlAttachment, forEncryption); + add_attachment(builder, mime, submime, boundary_prefix); for(unsigned int i = 0 ; i < attachments->count() ; i ++) { Attachment * attachment; attachment = (Attachment *) attachments->objectAtIndex(i); - submime = mime_from_attachment(attachment); - add_attachment(mime, submime, boundary_prefix); + submime = mime_from_attachment(builder, attachment, forEncryption); + add_attachment(builder, mime, submime, boundary_prefix); } return mime; @@ -344,14 +378,14 @@ static struct mailmime * multipart_related_from_attachments(Attachment * htmlAtt else { struct mailmime * mime; - mime = mime_from_attachment(htmlAttachment); + mime = mime_from_attachment(builder, htmlAttachment, forEncryption); return mime; } } static struct mailmime * -part_new_empty(struct mailmime_content * content, +part_new_empty(MessageBuilder * builder, struct mailmime_content * content, struct mailmime_fields * mime_fields, const char * boundary_prefix, int force_single) @@ -410,7 +444,13 @@ part_new_empty(struct mailmime_content * content, if (attr_name == NULL) goto free_list; - boundary = generate_boundary(boundary_prefix); + if (builder != NULL) { + String * boundaryString = builder->nextBoundary(); + boundary = strdup(boundaryString->UTF8Characters()); + } + else { + boundary = generate_boundary(boundary_prefix); + } attr_value = boundary; if (attr_name == NULL) { free(attr_name); @@ -462,7 +502,7 @@ err: return NULL; } -struct mailmime * part_multiple_new(const char * type, const char * boundary_prefix) +struct mailmime * part_multiple_new(MessageBuilder * builder, const char * type, const char * boundary_prefix) { struct mailmime_fields * mime_fields; struct mailmime_content * content; @@ -476,7 +516,7 @@ struct mailmime * part_multiple_new(const char * type, const char * boundary_pre if (content == NULL) goto free_fields; - mp = part_new_empty(content, mime_fields, boundary_prefix, 0); + mp = part_new_empty(builder, content, mime_fields, boundary_prefix, 0); if (mp == NULL) goto free_content; @@ -519,8 +559,10 @@ void MessageBuilder::init() mAttachments = NULL; mRelatedAttachments = NULL; mBoundaryPrefix = NULL; + mBoundaries = new Array(); + mCurrentBoundaryIndex = 0; } - + MessageBuilder::MessageBuilder() { init(); @@ -543,6 +585,7 @@ MessageBuilder::~MessageBuilder() MC_SAFE_RELEASE(mAttachments); MC_SAFE_RELEASE(mRelatedAttachments); MC_SAFE_RELEASE(mBoundaryPrefix); + MC_SAFE_RELEASE(mBoundaries); } String * MessageBuilder::description() @@ -655,45 +698,42 @@ String * MessageBuilder::boundaryPrefix() return mBoundaryPrefix; } -Data * MessageBuilder::dataAndFilterBcc(bool filterBcc) +struct mailmime * MessageBuilder::mimeAndFilterBccAndForEncryption(bool filterBcc, bool forEncryption) { - Data * data; - MMAPString * str; - int col; - struct mailmime * htmlPart; struct mailmime * textPart; struct mailmime * altPart; struct mailmime * mainPart; - + + mCurrentBoundaryIndex = 0; htmlPart = NULL; textPart = NULL; altPart = NULL; mainPart = NULL; - + if (htmlBody() != NULL) { Attachment * htmlAttachment; - + htmlAttachment = Attachment::attachmentWithHTMLString(htmlBody()); - htmlPart = multipart_related_from_attachments(htmlAttachment, mRelatedAttachments, - MCUTF8(mBoundaryPrefix)); + htmlPart = multipart_related_from_attachments(this, htmlAttachment, mRelatedAttachments, + MCUTF8(mBoundaryPrefix), forEncryption); } - + if (textBody() != NULL) { Attachment * textAttachment; - + textAttachment = Attachment::attachmentWithText(textBody()); - textPart = mime_from_attachment(textAttachment); + textPart = mime_from_attachment(this, textAttachment, forEncryption); } else if (htmlBody() != NULL) { Attachment * textAttachment; - + textAttachment = Attachment::attachmentWithText(htmlBody()->flattenHTML()); - textPart = mime_from_attachment(textAttachment); + textPart = mime_from_attachment(this, textAttachment, forEncryption); } - + if ((textPart != NULL) && (htmlPart != NULL)) { - altPart = get_multipart_alternative(MCUTF8(mBoundaryPrefix)); + altPart = get_multipart_alternative(this, MCUTF8(mBoundaryPrefix)); mailmime_smart_add_part(altPart, textPart); mailmime_smart_add_part(altPart, htmlPart); mainPart = altPart; @@ -704,44 +744,66 @@ Data * MessageBuilder::dataAndFilterBcc(bool filterBcc) else if (htmlPart != NULL) { mainPart = htmlPart; } - + struct mailimf_fields * fields; unsigned int i; struct mailmime * mime; - + fields = header()->createIMFFieldsAndFilterBcc(filterBcc); - + mime = mailmime_new_message_data(NULL); mailmime_set_imf_fields(mime, fields); - + if (mainPart != NULL) { - add_attachment(mime, mainPart, MCUTF8(mBoundaryPrefix)); + add_attachment(this, mime, mainPart, MCUTF8(mBoundaryPrefix)); } - + if (attachments() != NULL) { for(i = 0 ; i < attachments()->count() ; i ++) { Attachment * attachment; struct mailmime * submime; - + attachment = (Attachment *) attachments()->objectAtIndex(i); - submime = mime_from_attachment(attachment); - add_attachment(mime, submime, MCUTF8(mBoundaryPrefix)); + submime = mime_from_attachment(this, attachment, forEncryption); + add_attachment(this, mime, submime, MCUTF8(mBoundaryPrefix)); } } + struct mailmime * result = mime; + if (forEncryption) { + result = mime->mm_data.mm_message.mm_msg_mime; + mime->mm_data.mm_message.mm_msg_mime = NULL; + mailmime_free(mime); + } + + return result; +} + +Data * MessageBuilder::dataAndFilterBccAndForEncryption(bool filterBcc, bool forEncryption) +{ + Data * data; + MMAPString * str; + int col; + str = mmap_string_new(""); col = 0; + struct mailmime * mime = mimeAndFilterBccAndForEncryption(filterBcc, forEncryption); mailmime_write_mem(str, &col, mime); data = Data::dataWithBytes(str->str, (unsigned int) str->len); mmap_string_free(str); mailmime_free(mime); - + return data; } Data * MessageBuilder::data() { - return dataAndFilterBcc(false); + return dataAndFilterBccAndForEncryption(false, false); +} + +Data * MessageBuilder::dataForEncryption() +{ + return dataAndFilterBccAndForEncryption(false, true); } String * MessageBuilder::htmlRendering(HTMLRendererTemplateCallback * htmlCallback) @@ -768,3 +830,121 @@ String * MessageBuilder::plainTextBodyRendering(bool stripWhitespace) return message->plainTextBodyRendering(stripWhitespace); } +struct mailmime * get_signature_part(Data * signature) +{ + struct mailmime * mime; + struct mailmime_content * content; + + content = mailmime_content_new_with_str("application/pgp-signature"); + struct mailmime_fields * mime_fields = mailmime_fields_new_empty(); + mime = part_new_empty(NULL, content, mime_fields, NULL, 1); + mailmime_set_body_text(mime, signature->bytes(), signature->length()); + + return mime; +} + +Data * MessageBuilder::openPGPSignedMessageDataWithSignatureData(Data * signature) +{ + struct mailimf_fields * fields; + struct mailmime * mime; + + fields = header()->createIMFFieldsAndFilterBcc(false); + + mime = mailmime_new_message_data(NULL); + mailmime_set_imf_fields(mime, fields); + + struct mailmime * multipart = get_multipart_signed_pgp(NULL, MCUTF8(boundaryPrefix())); + add_attachment(NULL, mime, multipart, MCUTF8(boundaryPrefix())); + struct mailmime * part_to_sign = mimeAndFilterBccAndForEncryption(false, true); + add_attachment(NULL, multipart, part_to_sign, MCUTF8(boundaryPrefix())); + struct mailmime * signature_part = get_signature_part(signature); + add_attachment(NULL, multipart, signature_part, MCUTF8(boundaryPrefix())); + + MMAPString * str = mmap_string_new(""); + int col = 0; + + mailmime_write_mem(str, &col, mime); + Data * data = Data::dataWithBytes(str->str, (unsigned int) str->len); + mmap_string_free(str); + mailmime_free(mime); + + return data; +} + +static struct mailmime * get_pgp_version_part(void) +{ + struct mailmime * mime; + struct mailmime_content * content; + + content = mailmime_content_new_with_str("application/pgp-encrypted"); + struct mailmime_fields * mime_fields = mailmime_fields_new_empty(); + mime = part_new_empty(NULL, content, mime_fields, NULL, 1); + const char * version = "Version: 1\r\n"; + mailmime_set_body_text(mime, (char *) version, strlen(version)); + + return mime; +} + +static struct mailmime * get_encrypted_part(Data * encryptedData) +{ + struct mailmime * mime; + struct mailmime_content * content; + + content = mailmime_content_new_with_str("application/octet-stream"); + struct mailmime_fields * mime_fields = mailmime_fields_new_empty(); + mime = part_new_empty(NULL, content, mime_fields, NULL, 1); + mailmime_set_body_text(mime, encryptedData->bytes(), encryptedData->length()); + + return mime; +} + +Data * MessageBuilder::openPGPEncryptedMessageDataWithEncryptedData(Data * encryptedData) +{ + struct mailimf_fields * fields; + struct mailmime * mime; + + fields = header()->createIMFFieldsAndFilterBcc(false); + + mime = mailmime_new_message_data(NULL); + mailmime_set_imf_fields(mime, fields); + + struct mailmime * multipart = get_multipart_encrypted_pgp(NULL, MCUTF8(boundaryPrefix())); + add_attachment(NULL, mime, multipart, MCUTF8(boundaryPrefix())); + + struct mailmime * version_part = get_pgp_version_part(); + add_attachment(NULL, multipart, version_part, MCUTF8(boundaryPrefix())); + struct mailmime * encrypted_part = get_encrypted_part(encryptedData); + add_attachment(NULL, multipart, encrypted_part, MCUTF8(boundaryPrefix())); + + MMAPString * str = mmap_string_new(""); + int col = 0; + + mailmime_write_mem(str, &col, mime); + Data * data = Data::dataWithBytes(str->str, (unsigned int) str->len); + mmap_string_free(str); + mailmime_free(mime); + + return data; +} + +String * MessageBuilder::nextBoundary() +{ + unsigned int idx = mCurrentBoundaryIndex; + mCurrentBoundaryIndex ++; + if (idx < mBoundaries->count()) { + return (String *) mBoundaries->objectAtIndex(idx); + } + + char * boundary = generate_boundary(MCUTF8(mBoundaryPrefix)); + String * boundaryString = String::stringWithUTF8Characters(boundary); + mBoundaries->addObject(boundaryString); + free(boundary); + + return boundaryString; +} + +void MessageBuilder::resetBoundaries() +{ + mBoundaries->removeAllObjects(); +} + diff --git a/src/core/rfc822/MCMessageBuilder.h b/src/core/rfc822/MCMessageBuilder.h index 413d1a4d..aef594a1 100644 --- a/src/core/rfc822/MCMessageBuilder.h +++ b/src/core/rfc822/MCMessageBuilder.h @@ -39,6 +39,7 @@ namespace mailcore { virtual String * boundaryPrefix(); virtual Data * data(); + virtual Data * dataForEncryption(); virtual String * htmlRendering(HTMLRendererTemplateCallback * htmlCallback = NULL); virtual String * htmlBodyRendering(); @@ -46,11 +47,18 @@ namespace mailcore { virtual String * plainTextRendering(); virtual String * plainTextBodyRendering(bool stripWhitespace); + virtual Data * openPGPSignedMessageDataWithSignatureData(Data * signature); + virtual Data * openPGPEncryptedMessageDataWithEncryptedData(Data * encryptedData); + public: // subclass behavior MessageBuilder(MessageBuilder * other); virtual String * description(); virtual Object * copy(); + public: // private + virtual String * nextBoundary(); + virtual void resetBoundaries(); + private: String * mHTMLBody; String * mTextBody; @@ -58,7 +66,10 @@ namespace mailcore { Array * /* Attachment */ mRelatedAttachments; String * mBoundaryPrefix; void init(); - Data * dataAndFilterBcc(bool filterBcc); + Data * dataAndFilterBccAndForEncryption(bool filterBcc, bool forEncryption); + struct mailmime * mimeAndFilterBccAndForEncryption(bool filterBcc, bool forEncryption); + Array * mBoundaries; + unsigned int mCurrentBoundaryIndex; }; }; diff --git a/src/core/rfc822/MCMessageParser.cc b/src/core/rfc822/MCMessageParser.cc index d5bf84e7..21e2e985 100644 --- a/src/core/rfc822/MCMessageParser.cc +++ b/src/core/rfc822/MCMessageParser.cc @@ -143,14 +143,7 @@ String * MessageParser::plainTextBodyRendering(bool stripWhitespace) String * plainTextBodyString = html->flattenHTML(); if (stripWhitespace) { - plainTextBodyString->replaceOccurrencesOfString(MCSTR("\t"), MCSTR(" ")); - plainTextBodyString->replaceOccurrencesOfString(MCSTR("\n"), MCSTR(" ")); - plainTextBodyString->replaceOccurrencesOfString(MCSTR("\v"), MCSTR(" ")); - plainTextBodyString->replaceOccurrencesOfString(MCSTR("\f"), MCSTR(" ")); - plainTextBodyString->replaceOccurrencesOfString(MCSTR("\r"), MCSTR(" ")); - while (plainTextBodyString->replaceOccurrencesOfString(MCSTR(" "), MCSTR(" "))) { - // do nothing. - } + plainTextBodyString = plainTextBodyString->stripWhitespace(); } return plainTextBodyString; } diff --git a/src/core/smtp/MCSMTPSession.cc b/src/core/smtp/MCSMTPSession.cc index c6f28ff9..771b6302 100644 --- a/src/core/smtp/MCSMTPSession.cc +++ b/src/core/smtp/MCSMTPSession.cc @@ -323,7 +323,7 @@ void SMTPSession::connect(ErrorCode * pError) default: r = mailsmtp_socket_connect(mSmtp, MCUTF8(hostname()), port()); - if (r != MAILIMAP_NO_ERROR) { + if (r != MAILSMTP_NO_ERROR) { * pError = ErrorConnection; goto close; } diff --git a/src/objc/abstract/MCOAbstractPart.h b/src/objc/abstract/MCOAbstractPart.h index e30f09bf..30dd8f5f 100644 --- a/src/objc/abstract/MCOAbstractPart.h +++ b/src/objc/abstract/MCOAbstractPart.h @@ -82,6 +82,18 @@ typedef NS_ENUM(NSInteger, MCOPartType) { /** Returns a string representation of the data according to charset.*/ - (NSString *) decodedStringForData:(NSData *)data; +/** Adds a content type parameter.*/ +- (void) setContentTypeParameterValue:(NSString *)value forName:(NSString *)name; + +/** Remove a given content type parameter.*/ +- (void) removeContentTypeParameterForName:(NSString *)name; + +/** Returns the value of a given content type parameter.*/ +- (NSString *) contentTypeParameterValueForName:(NSString *)name; + +/** Returns an array with the names of all content type parameters.*/ +- (NSArray * /* NSString */) allContentTypeParametersNames; + @end #endif diff --git a/src/objc/abstract/MCOAbstractPart.mm b/src/objc/abstract/MCOAbstractPart.mm index d55422d5..8608ec61 100644 --- a/src/objc/abstract/MCOAbstractPart.mm +++ b/src/objc/abstract/MCOAbstractPart.mm @@ -87,4 +87,24 @@ MCO_OBJC_SYNTHESIZE_BOOL(setInlineAttachment, isInlineAttachment) { return [NSString mco_stringWithMCString:MCO_NATIVE_INSTANCE->decodedStringForData([data mco_mcData])]; } + +- (void) setContentTypeParameterValue:(NSString *)value forName:(NSString *)name +{ + MCO_NATIVE_INSTANCE->setContentTypeParameter(MCO_FROM_OBJC(mailcore::String, name), MCO_FROM_OBJC(mailcore::String, value)); +} + +- (NSString *) contentTypeParameterValueForName:(NSString *)name +{ + return MCO_TO_OBJC(MCO_NATIVE_INSTANCE->contentTypeParameterValueForName((MCO_FROM_OBJC(mailcore::String, name)))); +} +- (void) removeContentTypeParameterForName:(NSString *)name +{ + MCO_NATIVE_INSTANCE->removeContentTypeParameter(MCO_FROM_OBJC(mailcore::String, name)); +} + +- (NSArray * /* NSString */) allContentTypeParametersNames +{ + return MCO_TO_OBJC(MCO_NATIVE_INSTANCE->allContentTypeParametersNames()); +} + @end diff --git a/src/objc/abstract/MCOConstants.h b/src/objc/abstract/MCOConstants.h index 32a1b1bb..2752c34b 100644 --- a/src/objc/abstract/MCOConstants.h +++ b/src/objc/abstract/MCOConstants.h @@ -180,8 +180,10 @@ typedef NS_ENUM(NSInteger, MCOIMAPSearchKind) { MCOIMAPSearchKindRecipient, /** Match subject.*/ MCOIMAPSearchKindSubject, - /** Match content of the message.*/ + /** Match content of the message, including the headers.*/ MCOIMAPSearchKindContent, + /** Match content of the message, excluding the headers.*/ + MCOIMAPSearchKindBody, /** Match uids */ MCOIMAPSearchKindUids, /** Match headers of the message.*/ @@ -400,6 +402,9 @@ typedef NS_ENUM(NSInteger, MCOErrorCode) { MCOErrorNoRecipient, /** IMAP: Error when a noop operation fails.*/ MCOErrorNoop, + /** IMAP: Error when the password has been entered but second factor + authentication is enabled: an application specific password is required. */ + MCOErrorGmailApplicationSpecificPasswordRequired, /** The count of all errors */ MCOErrorCodeCount, }; diff --git a/src/objc/imap/MCOIMAPFetchMessagesOperation.mm b/src/objc/imap/MCOIMAPFetchMessagesOperation.mm index bd86d99b..83012ca5 100644 --- a/src/objc/imap/MCOIMAPFetchMessagesOperation.mm +++ b/src/objc/imap/MCOIMAPFetchMessagesOperation.mm @@ -17,8 +17,11 @@ typedef void (^CompletionType)(NSError *error, NSArray * messages, MCOIndexSet * @implementation MCOIMAPFetchMessagesOperation { CompletionType _completionBlock; + MCOIMAPBaseOperationItemProgressBlock _progress; } +@synthesize progress = _progress; + #define nativeType mailcore::IMAPFetchMessagesOperation + (void) load diff --git a/src/objc/imap/MCOIMAPFolderInfo.h b/src/objc/imap/MCOIMAPFolderInfo.h index c15c5a37..53ad35b8 100644 --- a/src/objc/imap/MCOIMAPFolderInfo.h +++ b/src/objc/imap/MCOIMAPFolderInfo.h @@ -34,6 +34,9 @@ // first uid of the unseen messages. @property (nonatomic, assign) uint32_t firstUnseenUid; +/** An boolean indicates that this folder or IMAP server allows to add a new permanent flags */ +@property (nonatomic, assign) BOOL allowsNewPermanentFlags; + @end #endif diff --git a/src/objc/imap/MCOIMAPFolderInfo.m b/src/objc/imap/MCOIMAPFolderInfo.m index e39551a4..be1d2c3e 100644 --- a/src/objc/imap/MCOIMAPFolderInfo.m +++ b/src/objc/imap/MCOIMAPFolderInfo.m @@ -14,6 +14,7 @@ uint64_t _modSequenceValue; int _messageCount; uint32_t _firstUnseenUid; + BOOL _allowsNewPermanentFlags; } @synthesize uidNext = _uidNext; @@ -21,6 +22,7 @@ @synthesize modSequenceValue = _modSequenceValue; @synthesize messageCount = _messageCount; @synthesize firstUnseenUid = _firstUnseenUid; +@synthesize allowsNewPermanentFlags = _allowsNewPermanentFlags; + (MCOIMAPFolderInfo *) info { diff --git a/src/objc/imap/MCOIMAPFolderInfoOperation.mm b/src/objc/imap/MCOIMAPFolderInfoOperation.mm index 7ea8e887..f4d322af 100644 --- a/src/objc/imap/MCOIMAPFolderInfoOperation.mm +++ b/src/objc/imap/MCOIMAPFolderInfoOperation.mm @@ -65,6 +65,7 @@ typedef void (^CompletionType)(NSError *error, MCOIMAPFolderInfo *info); [info setModSequenceValue:MCO_NATIVE_INSTANCE->modSequenceValue()]; [info setMessageCount:MCO_NATIVE_INSTANCE->messageCount()]; [info setFirstUnseenUid:MCO_NATIVE_INSTANCE->firstUnseenUid()]; + [info setAllowsNewPermanentFlags:MCO_NATIVE_INSTANCE->allowsNewPermanentFlags()]; _completionBlock(nil, info); } diff --git a/src/objc/imap/MCOIMAPFolderStatus.h b/src/objc/imap/MCOIMAPFolderStatus.h index fedd31a3..bd1ddef3 100644 --- a/src/objc/imap/MCOIMAPFolderStatus.h +++ b/src/objc/imap/MCOIMAPFolderStatus.h @@ -32,7 +32,7 @@ @property (nonatomic, assign) uint32_t messageCount; /** Highest modification sequence value for this folder. See CONDSTORE RFC 4551. */ -@property (nonatomic, assign) uint64_t setHighestModSeqValue; +@property (nonatomic, assign) uint64_t highestModSeqValue; @end diff --git a/src/objc/imap/MCOIMAPMessage.h b/src/objc/imap/MCOIMAPMessage.h index 7ca40b9e..8e2e1c27 100644 --- a/src/objc/imap/MCOIMAPMessage.h +++ b/src/objc/imap/MCOIMAPMessage.h @@ -34,6 +34,10 @@ /** IMAP UID of the message. */ @property (nonatomic, assign) uint32_t uid; +/** IMAP sequence number of the message. + @warning *Important*: This property won't be serialized. */ +@property (nonatomic, assign) uint32_t sequenceNumber; + /* Size of the entire message */ @property (nonatomic, assign) uint32_t size; diff --git a/src/objc/imap/MCOIMAPMessage.mm b/src/objc/imap/MCOIMAPMessage.mm index f663d8bd..d7d499ef 100644 --- a/src/objc/imap/MCOIMAPMessage.mm +++ b/src/objc/imap/MCOIMAPMessage.mm @@ -42,6 +42,7 @@ MCO_SYNTHESIZE_NSCODING MCO_OBJC_SYNTHESIZE_SCALAR(uint32_t, uint32_t, setUid, uid) +MCO_OBJC_SYNTHESIZE_SCALAR(uint32_t, uint32_t, setSequenceNumber, sequenceNumber) MCO_OBJC_SYNTHESIZE_SCALAR(uint32_t, uint32_t, setSize, size) MCO_OBJC_SYNTHESIZE_SCALAR(MCOMessageFlag, mailcore::MessageFlag, setFlags, flags) MCO_OBJC_SYNTHESIZE_SCALAR(MCOMessageFlag, mailcore::MessageFlag, setOriginalFlags, originalFlags) diff --git a/src/objc/imap/MCOIMAPSearchExpression.h b/src/objc/imap/MCOIMAPSearchExpression.h index fbffb8f3..51688dc2 100644 --- a/src/objc/imap/MCOIMAPSearchExpression.h +++ b/src/objc/imap/MCOIMAPSearchExpression.h @@ -82,7 +82,7 @@ + (MCOIMAPSearchExpression *) searchSubject:(NSString *)value; /** - Creates a search expression that matches the content of an email. + Creates a search expression that matches the content of an email, including the headers. Example: @@ -91,6 +91,15 @@ + (MCOIMAPSearchExpression *) searchContent:(NSString *)value; /** + Creates a search expression that matches the content of an email, excluding the headers. + + Example: + + MCOIMAPSearchExpression * expr = [MCOIMAPSearchExpression searchBody:@"building"] + */ ++ (MCOIMAPSearchExpression *) searchBody:(NSString *)value; + +/** Creates a search expression that matches the uids specified. Example: diff --git a/src/objc/imap/MCOIMAPSearchExpression.mm b/src/objc/imap/MCOIMAPSearchExpression.mm index f395596c..57ae8455 100644 --- a/src/objc/imap/MCOIMAPSearchExpression.mm +++ b/src/objc/imap/MCOIMAPSearchExpression.mm @@ -96,6 +96,11 @@ return MCO_TO_OBJC(mailcore::IMAPSearchExpression::searchContent([value mco_mcString])); } ++ (MCOIMAPSearchExpression *) searchBody:(NSString *)value +{ + return MCO_TO_OBJC(mailcore::IMAPSearchExpression::searchBody([value mco_mcString])); +} + + (MCOIMAPSearchExpression *) searchUIDs:(MCOIndexSet *) uids { return MCO_TO_OBJC(mailcore::IMAPSearchExpression::searchUIDs(MCO_FROM_OBJC(mailcore::IndexSet, uids))); diff --git a/src/objc/imap/MCOIMAPSession.h b/src/objc/imap/MCOIMAPSession.h index 7a35b7e3..a6034e9a 100755 --- a/src/objc/imap/MCOIMAPSession.h +++ b/src/objc/imap/MCOIMAPSession.h @@ -326,6 +326,25 @@ uids:(MCOIndexSet *)uids kind:(MCOIMAPStoreFlagsRequestKind)kind flags:(MCOMessageFlag)flags; + +/** + Returns an operation to change flags of messages, using IMAP sequence number. + + For example: Adds the seen flag to the message with the sequence number number 42. + + MCOIMAPOperation * op = [session storeFlagsOperationWithFolder:@"INBOX" + numbers:[MCOIndexSet indexSetWithIndex:42] + kind:MCOIMAPStoreFlagsRequestKindAdd + flags:MCOMessageFlagSeen]; + [op start:^(NSError * error) { + ... + }]; + */ +- (MCOIMAPOperation *) storeFlagsOperationWithFolder:(NSString *)folder + numbers:(MCOIndexSet *)numbers + kind:(MCOIMAPStoreFlagsRequestKind)kind + flags:(MCOMessageFlag)flags; + /** Returns an operation to change flags and custom flags of messages. @@ -345,15 +364,55 @@ kind:(MCOIMAPStoreFlagsRequestKind)kind flags:(MCOMessageFlag)flags customFlags:(NSArray *)customFlags; + + +/** + Returns an operation to change flags and custom flags of messages, using IMAP sequence number. + + For example: Adds the seen flag and $CNS-Greeting-On flag to the message with the sequence number 42. + + MCOIMAPOperation * op = [session storeFlagsOperationWithFolder:@"INBOX" + numbers:[MCOIndexSet indexSetWithIndex:42] + kind:MCOIMAPStoreFlagsRequestKindAdd + flags:MCOMessageFlagSeen + customFlags:@["$CNS-Greeting-On"]]; + [op start:^(NSError * error) { + ... + }]; + */ +- (MCOIMAPOperation *) storeFlagsOperationWithFolder:(NSString *)folder + numbers:(MCOIndexSet *)numbers + kind:(MCOIMAPStoreFlagsRequestKind)kind + flags:(MCOMessageFlag)flags + customFlags:(NSArray *)customFlags; + +/** + Returns an operation to change labels of messages. Intended for Gmail + + For example: Adds the label "Home" flag to the message with UID 42. + + MCOIMAPOperation * op = [session storeLabelsOperationWithFolder:@"INBOX" + numbers:[MCOIndexSet indexSetWithIndex:42] + kind:MCOIMAPStoreFlagsRequestKindAdd + labels:[NSArray arrayWithObject:@"Home"]]; + [op start:^(NSError * error) { + ... + }]; +*/ +- (MCOIMAPOperation *) storeLabelsOperationWithFolder:(NSString *)folder + numbers:(MCOIndexSet *)numbers + kind:(MCOIMAPStoreFlagsRequestKind)kind + labels:(NSArray *)labels; + /** Returns an operation to change labels of messages. Intended for Gmail For example: Adds the label "Home" flag to the message with UID 456. - MCOIMAPOperation * op = [session storeFlagsOperationWithFolder:@"INBOX" - uids:[MCOIndexSet indexSetWithIndex:456] - kind:MCOIMAPStoreFlagsRequestKindAdd - labels:[NSArray arrayWithObject:@"Home"]]; + MCOIMAPOperation * op = [session storeLabelsOperationWithFolder:@"INBOX" + uids:[MCOIndexSet indexSetWithIndex:456] + kind:MCOIMAPStoreFlagsRequestKindAdd + labels:[NSArray arrayWithObject:@"Home"]]; [op start:^(NSError * error) { ... }]; @@ -379,7 +438,23 @@ */ - (MCOIMAPFetchMessagesOperation *) fetchMessagesByUIDOperationWithFolder:(NSString *)folder requestKind:(MCOIMAPMessagesRequestKind)requestKind - uids:(MCOIndexSet *)uids; + uids:(MCOIndexSet *)uids DEPRECATED_ATTRIBUTE; + +/** + Returns an operation to fetch messages by UID. + + MCOIMAPFetchMessagesOperation * op = [session fetchMessagesOperationWithFolder:@"INBOX" + requestKind:MCOIMAPMessagesRequestKindHeaders | MCOIMAPMessagesRequestKindStructure + uids:MCORangeMake(1, UINT64_MAX)]; + [op start:^(NSError * error, NSArray * messages, MCOIndexSet * vanishedMessages) { + for(MCOIMAPMessage * msg in messages) { + NSLog(@"%lu: %@", [msg uid], [msg header]); + } + }]; +*/ +- (MCOIMAPFetchMessagesOperation *) fetchMessagesOperationWithFolder:(NSString *)folder + requestKind:(MCOIMAPMessagesRequestKind)requestKind + uids:(MCOIndexSet *)uids; /** Returns an operation to fetch messages by (sequence) number. @@ -425,7 +500,27 @@ vanishedMessages will be set only for servers that support QRESYNC. See [RFC5162 - (MCOIMAPFetchMessagesOperation *) syncMessagesByUIDWithFolder:(NSString *)folder requestKind:(MCOIMAPMessagesRequestKind)requestKind uids:(MCOIndexSet *)uids - modSeq:(uint64_t)modSeq; + modSeq:(uint64_t)modSeq DEPRECATED_ATTRIBUTE; + +/** + Returns an operation to sync the last changes related to the given message list given a modSeq. + + MCOIMAPFetchMessagesOperation * op = [session syncMessagesWithFolder:@"INBOX" + requestKind:MCOIMAPMessagesRequestKindUID + uids:MCORangeMake(1, UINT64_MAX) + modSeq:lastModSeq]; + [op start:^(NSError * error, NSArray * messages, MCOIndexSet * vanishedMessages) { + NSLog(@"added or modified messages: %@", messages); + NSLog(@"deleted messages: %@", vanishedMessages); + }]; + +@warn *Important*: This is only for servers that support Conditional Store. See [RFC4551](http://tools.ietf.org/html/rfc4551) +vanishedMessages will be set only for servers that support QRESYNC. See [RFC5162](http://tools.ietf.org/html/rfc5162) +*/ +- (MCOIMAPFetchMessagesOperation *) syncMessagesWithFolder:(NSString *)folder + requestKind:(MCOIMAPMessagesRequestKind)requestKind + uids:(MCOIndexSet *)uids + modSeq:(uint64_t)modSeq; /** Returns an operation to fetch the content of a message. @@ -439,7 +534,7 @@ vanishedMessages will be set only for servers that support QRESYNC. See [RFC5162 */ - (MCOIMAPFetchContentOperation *) fetchMessageByUIDOperationWithFolder:(NSString *)folder uid:(uint32_t)uid - urgent:(BOOL)urgent; + urgent:(BOOL)urgent DEPRECATED_ATTRIBUTE; /** Returns an operation to fetch the content of a message. @@ -451,7 +546,59 @@ vanishedMessages will be set only for servers that support QRESYNC. See [RFC5162 }]; */ - (MCOIMAPFetchContentOperation *) fetchMessageByUIDOperationWithFolder:(NSString *)folder - uid:(uint32_t)uid; + uid:(uint32_t)uid DEPRECATED_ATTRIBUTE; + +/** + Returns an operation to fetch the content of a message. + @param urgent is set to YES, an additional connection to the same folder might be opened to fetch the content. + + MCOIMAPFetchContentOperation * op = [session fetchMessageOperationWithFolder:@"INBOX" uid:456 urgent:NO]; + [op start:^(NSError * error, NSData * messageData) { + MCOMessageParser * parser = [MCOMessageParser messageParserWithData:messageData] + ... + }]; + */ +- (MCOIMAPFetchContentOperation *) fetchMessageOperationWithFolder:(NSString *)folder + uid:(uint32_t)uid + urgent:(BOOL)urgent; + +/** + Returns an operation to fetch the content of a message. + + MCOIMAPFetchContentOperation * op = [session fetchMessageOperationWithFolder:@"INBOX" uid:456]; + [op start:^(NSError * error, NSData * messageData) { + MCOMessageParser * parser = [MCOMessageParser messageParserWithData:messageData] + ... + }]; + */ +- (MCOIMAPFetchContentOperation *) fetchMessageOperationWithFolder:(NSString *)folder + uid:(uint32_t)uid; + +/** + Returns an operation to fetch the content of a message, using IMAP sequence number. + @param urgent is set to YES, an additional connection to the same folder might be opened to fetch the content. + + MCOIMAPFetchContentOperation * op = [session fetchMessageOperationWithFolder:@"INBOX" number:42 urgent:NO]; + [op start:^(NSError * error, NSData * messageData) { + MCOMessageParser * parser = [MCOMessageParser messageParserWithData:messageData] + ... + }]; +*/ +- (MCOIMAPFetchContentOperation *) fetchMessageOperationWithFolder:(NSString *)folder + number:(uint32_t)number + urgent:(BOOL)urgent; + +/** + Returns an operation to fetch the content of a message, using IMAP sequence number. + + MCOIMAPFetchContentOperation * op = [session fetchMessageOperationWithFolder:@"INBOX" number:42]; + [op start:^(NSError * error, NSData * messageData) { + MCOMessageParser * parser = [MCOMessageParser messageParserWithData:messageData] + ... + }]; +*/ +- (MCOIMAPFetchContentOperation *) fetchMessageOperationWithFolder:(NSString *)folder + number:(uint32_t)number; /** @name Fetching Attachment Operations */ @@ -472,7 +619,7 @@ vanishedMessages will be set only for servers that support QRESYNC. See [RFC5162 uid:(uint32_t)uid partID:(NSString *)partID encoding:(MCOEncoding)encoding - urgent:(BOOL)urgent; + urgent:(BOOL)urgent DEPRECATED_ATTRIBUTE; /** Returns an operation to fetch an attachment. @@ -500,7 +647,101 @@ vanishedMessages will be set only for servers that support QRESYNC. See [RFC5162 - (MCOIMAPFetchContentOperation *) fetchMessageAttachmentByUIDOperationWithFolder:(NSString *)folder uid:(uint32_t)uid partID:(NSString *)partID - encoding:(MCOEncoding)encoding; + encoding:(MCOEncoding)encoding DEPRECATED_ATTRIBUTE; + +/** + Returns an operation to fetch an attachment. + @param urgent is set to YES, an additional connection to the same folder might be opened to fetch the content. + + MCOIMAPFetchContentOperation * op = [session fetchMessageAttachmentOperationWithFolder:@"INBOX" + uid:456 + partID:@"1.2" + encoding:MCOEncodingBase64 + urgent:YES]; + [op start:^(NSError * error, NSData * partData) { + ... + }]; +*/ +- (MCOIMAPFetchContentOperation *) fetchMessageAttachmentOperationWithFolder:(NSString *)folder + uid:(uint32_t)uid + partID:(NSString *)partID + encoding:(MCOEncoding)encoding + urgent:(BOOL)urgent; + +/** + Returns an operation to fetch an attachment. + + Example 1: + + MCOIMAPFetchContentOperation * op = [session fetchMessageAttachmentOperationWithFolder:@"INBOX" + uid:456 + partID:@"1.2" + encoding:MCOEncodingBase64]; + [op start:^(NSError * error, NSData * partData) { + ... + }]; + + Example 2: + + MCOIMAPFetchContentOperation * op = [session fetchMessageAttachmentOperationWithFolder:@"INBOX" + uid:[message uid] + partID:[part partID] + encoding:[part encoding]]; + [op start:^(NSError * error, NSData * partData) { + ... + }]; +*/ +- (MCOIMAPFetchContentOperation *) fetchMessageAttachmentOperationWithFolder:(NSString *)folder + uid:(uint32_t)uid + partID:(NSString *)partID + encoding:(MCOEncoding)encoding; + +/** + Returns an operation to fetch an attachment. + @param urgent is set to YES, an additional connection to the same folder might be opened to fetch the content. + + MCOIMAPFetchContentOperation * op = [session fetchMessageAttachmentOperationWithFolder:@"INBOX" + uid:456 + partID:@"1.2" + encoding:MCOEncodingBase64 + urgent:YES]; + [op start:^(NSError * error, NSData * partData) { + ... + }]; +*/ +- (MCOIMAPFetchContentOperation *) fetchMessageAttachmentOperationWithFolder:(NSString *)folder + number:(uint32_t)number + partID:(NSString *)partID + encoding:(MCOEncoding)encoding + urgent:(BOOL)urgent; + +/** + Returns an operation to fetch an attachment. + + Example 1: + + MCOIMAPFetchContentOperation * op = [session fetchMessageAttachmentOperationWithFolder:@"INBOX" + number:42 + partID:@"1.2" + encoding:MCOEncodingBase64]; + [op start:^(NSError * error, NSData * partData) { + ... + }]; + + Example 2: + + MCOIMAPFetchContentOperation * op = [session fetchMessageAttachmentOperationWithFolder:@"INBOX" + number:[message sequenceNumber] + partID:[part partID] + encoding:[part encoding]]; + [op start:^(NSError * error, NSData * partData) { + ... + }]; +*/ +- (MCOIMAPFetchContentOperation *) fetchMessageAttachmentOperationWithFolder:(NSString *)folder + number:(uint32_t)number + partID:(NSString *)partID + encoding:(MCOEncoding)encoding; /** @name General IMAP Actions */ @@ -539,7 +780,7 @@ vanishedMessages will be set only for servers that support QRESYNC. See [RFC5162 MCOIMAPIdentity * identity = [MCOIMAPIdentity identityWithVendor:@"Mozilla" name:@"Thunderbird" version:@"17.0.5"]; MCOIMAPIdentityOperation * op = [session identityOperationWithClientIdentity:identity]; - [op start:^(NSError * error, MCOIMAPIdentity * serverIdentity) { + [op start:^(NSError * error, NSDictionary * serverIdentity) { ... }]; */ diff --git a/src/objc/imap/MCOIMAPSession.mm b/src/objc/imap/MCOIMAPSession.mm index dddb27fa..c7c389a4 100755 --- a/src/objc/imap/MCOIMAPSession.mm +++ b/src/objc/imap/MCOIMAPSession.mm @@ -285,6 +285,13 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, requestKind:(MCOIMAPMessagesRequestKind)requestKind uids:(MCOIndexSet *)uids { + return [self fetchMessagesOperationWithFolder:folder requestKind:requestKind uids:uids]; +} + +- (MCOIMAPFetchMessagesOperation *) fetchMessagesOperationWithFolder:(NSString *)folder + requestKind:(MCOIMAPMessagesRequestKind)requestKind + uids:(MCOIndexSet *)uids +{ IMAPFetchMessagesOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessagesByUIDOperation([folder mco_mcString], (IMAPMessagesRequestKind) requestKind, MCO_FROM_OBJC(IndexSet, uids)); @@ -306,6 +313,14 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, uids:(MCOIndexSet *)uids modSeq:(uint64_t)modSeq { + return [self syncMessagesWithFolder:folder requestKind:requestKind uids:uids modSeq:modSeq]; +} + +- (MCOIMAPFetchMessagesOperation *) syncMessagesWithFolder:(NSString *)folder + requestKind:(MCOIMAPMessagesRequestKind)requestKind + uids:(MCOIndexSet *)uids + modSeq:(uint64_t)modSeq +{ IMAPFetchMessagesOperation * coreOp = MCO_NATIVE_INSTANCE->syncMessagesByUID([folder mco_mcString], (IMAPMessagesRequestKind) requestKind, MCO_FROM_OBJC(IndexSet, uids), @@ -317,14 +332,41 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, uid:(uint32_t)uid urgent:(BOOL)urgent { - IMAPFetchContentOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessageByUIDOperation([folder mco_mcString], uid, urgent); - return MCO_TO_OBJC_OP(coreOp); + return [self fetchMessageOperationWithFolder:folder uid:uid urgent:urgent]; } - (MCOIMAPFetchContentOperation *) fetchMessageByUIDOperationWithFolder:(NSString *)folder uid:(uint32_t)uid { - return [self fetchMessageByUIDOperationWithFolder:folder uid:uid urgent:NO]; + return [self fetchMessageOperationWithFolder:folder uid:uid]; +} + +- (MCOIMAPFetchContentOperation *) fetchMessageOperationWithFolder:(NSString *)folder + uid:(uint32_t)uid + urgent:(BOOL)urgent +{ + IMAPFetchContentOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessageByUIDOperation([folder mco_mcString], uid, urgent); + return MCO_TO_OBJC_OP(coreOp); +} + +- (MCOIMAPFetchContentOperation *) fetchMessageOperationWithFolder:(NSString *)folder + uid:(uint32_t)uid +{ + return [self fetchMessageOperationWithFolder:folder uid:uid urgent:NO]; +} + +- (MCOIMAPFetchContentOperation *) fetchMessageOperationWithFolder:(NSString *)folder + number:(uint32_t)number + urgent:(BOOL)urgent +{ + IMAPFetchContentOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessageByNumberOperation([folder mco_mcString], number, urgent); + return MCO_TO_OBJC_OP(coreOp); +} + +- (MCOIMAPFetchContentOperation *) fetchMessageOperationWithFolder:(NSString *)folder + number:(uint32_t)number +{ + return [self fetchMessageOperationWithFolder:folder number:number urgent:NO]; } - (MCOIMAPFetchContentOperation *) fetchMessageAttachmentByUIDOperationWithFolder:(NSString *)folder @@ -333,6 +375,30 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, encoding:(MCOEncoding)encoding urgent:(BOOL)urgent { + return [self fetchMessageAttachmentOperationWithFolder:folder + uid:uid + partID:partID + encoding:encoding + urgent:urgent]; +} + +- (MCOIMAPFetchContentOperation *) fetchMessageAttachmentByUIDOperationWithFolder:(NSString *)folder + uid:(uint32_t)uid + partID:(NSString *)partID + encoding:(MCOEncoding)encoding +{ + return [self fetchMessageAttachmentOperationWithFolder:folder + uid:uid + partID:partID + encoding:encoding]; +} + +- (MCOIMAPFetchContentOperation *) fetchMessageAttachmentOperationWithFolder:(NSString *)folder + uid:(uint32_t)uid + partID:(NSString *)partID + encoding:(MCOEncoding)encoding + urgent:(BOOL)urgent +{ IMAPFetchContentOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessageAttachmentByUIDOperation([folder mco_mcString], uid, [partID mco_mcString], @@ -341,12 +407,34 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, return MCO_TO_OBJC_OP(coreOp); } -- (MCOIMAPFetchContentOperation *) fetchMessageAttachmentByUIDOperationWithFolder:(NSString *)folder - uid:(uint32_t)uid - partID:(NSString *)partID - encoding:(MCOEncoding)encoding +- (MCOIMAPFetchContentOperation *) fetchMessageAttachmentOperationWithFolder:(NSString *)folder + uid:(uint32_t)uid + partID:(NSString *)partID + encoding:(MCOEncoding)encoding +{ + return [self fetchMessageAttachmentOperationWithFolder:folder uid:uid partID:partID encoding:encoding urgent:NO]; +} + +- (MCOIMAPFetchContentOperation *) fetchMessageAttachmentOperationWithFolder:(NSString *)folder + number:(uint32_t)number + partID:(NSString *)partID + encoding:(MCOEncoding)encoding + urgent:(BOOL)urgent +{ + IMAPFetchContentOperation * coreOp = MCO_NATIVE_INSTANCE->fetchMessageAttachmentByNumberOperation([folder mco_mcString], + number, + [partID mco_mcString], + (Encoding) encoding, + urgent); + return MCO_TO_OBJC_OP(coreOp); +} + +- (MCOIMAPFetchContentOperation *) fetchMessageAttachmentOperationWithFolder:(NSString *)folder + number:(uint32_t)number + partID:(NSString *)partID + encoding:(MCOEncoding)encoding { - return [self fetchMessageAttachmentByUIDOperationWithFolder:folder uid:uid partID:partID encoding:encoding urgent:NO]; + return [self fetchMessageAttachmentOperationWithFolder:folder number:number partID:partID encoding:encoding urgent:NO]; } - (MCOIMAPOperation *) storeFlagsOperationWithFolder:(NSString *)folder @@ -363,11 +451,33 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, flags:(MCOMessageFlag)flags customFlags:(NSArray *)customFlags { - IMAPOperation * coreOp = MCO_NATIVE_INSTANCE->storeFlagsOperation([folder mco_mcString], - MCO_FROM_OBJC(IndexSet, uids), - (IMAPStoreFlagsRequestKind) kind, - (MessageFlag) flags, - MCO_FROM_OBJC(Array, customFlags)); + IMAPOperation * coreOp = MCO_NATIVE_INSTANCE->storeFlagsByUIDOperation([folder mco_mcString], + MCO_FROM_OBJC(IndexSet, uids), + (IMAPStoreFlagsRequestKind) kind, + (MessageFlag) flags, + MCO_FROM_OBJC(Array, customFlags)); + return OPAQUE_OPERATION(coreOp); +} + +- (MCOIMAPOperation *) storeFlagsOperationWithFolder:(NSString *)folder + numbers:(MCOIndexSet *)numbers + kind:(MCOIMAPStoreFlagsRequestKind)kind + flags:(MCOMessageFlag)flags +{ + return [self storeFlagsOperationWithFolder:folder numbers:numbers kind:kind flags:flags customFlags:NULL]; +} + +- (MCOIMAPOperation *) storeFlagsOperationWithFolder:(NSString *)folder + numbers:(MCOIndexSet *)numbers + kind:(MCOIMAPStoreFlagsRequestKind)kind + flags:(MCOMessageFlag)flags + customFlags:(NSArray *)customFlags +{ + IMAPOperation * coreOp = MCO_NATIVE_INSTANCE->storeFlagsByNumberOperation([folder mco_mcString], + MCO_FROM_OBJC(IndexSet, numbers), + (IMAPStoreFlagsRequestKind) kind, + (MessageFlag) flags, + MCO_FROM_OBJC(Array, customFlags)); return OPAQUE_OPERATION(coreOp); } @@ -376,10 +486,22 @@ MCO_OBJC_SYNTHESIZE_SCALAR(dispatch_queue_t, dispatch_queue_t, setDispatchQueue, kind:(MCOIMAPStoreFlagsRequestKind)kind labels:(NSArray *)labels { - IMAPOperation * coreOp = MCO_NATIVE_INSTANCE->storeLabelsOperation([folder mco_mcString], - MCO_FROM_OBJC(IndexSet, uids), - (IMAPStoreFlagsRequestKind) kind, - MCO_FROM_OBJC(Array, labels)); + IMAPOperation * coreOp = MCO_NATIVE_INSTANCE->storeLabelsByUIDOperation([folder mco_mcString], + MCO_FROM_OBJC(IndexSet, uids), + (IMAPStoreFlagsRequestKind) kind, + MCO_FROM_OBJC(Array, labels)); + return OPAQUE_OPERATION(coreOp); +} + +- (MCOIMAPOperation *) storeLabelsOperationWithFolder:(NSString *)folder + numbers:(MCOIndexSet *)numbers + kind:(MCOIMAPStoreFlagsRequestKind)kind + labels:(NSArray *)labels +{ + IMAPOperation * coreOp = MCO_NATIVE_INSTANCE->storeLabelsByNumberOperation([folder mco_mcString], + MCO_FROM_OBJC(IndexSet, numbers), + (IMAPStoreFlagsRequestKind) kind, + MCO_FROM_OBJC(Array, labels)); return OPAQUE_OPERATION(coreOp); } diff --git a/src/objc/nntp/MCONNTPSession.mm b/src/objc/nntp/MCONNTPSession.mm index d7db82b2..23e2e786 100644 --- a/src/objc/nntp/MCONNTPSession.mm +++ b/src/objc/nntp/MCONNTPSession.mm @@ -70,6 +70,7 @@ private: - (void)dealloc { MC_SAFE_RELEASE(_loggerBridge); [_connectionLogger release]; + _session->setConnectionLogger(NULL); _session->release(); [super dealloc]; } diff --git a/src/objc/pop/MCOPOPSession.mm b/src/objc/pop/MCOPOPSession.mm index 893995a5..61d9320b 100644 --- a/src/objc/pop/MCOPOPSession.mm +++ b/src/objc/pop/MCOPOPSession.mm @@ -70,6 +70,7 @@ private: - (void)dealloc { MC_SAFE_RELEASE(_loggerBridge); [_connectionLogger release]; + _session->setConnectionLogger(NULL); _session->release(); [super dealloc]; } diff --git a/src/objc/rfc822/MCOAttachment.h b/src/objc/rfc822/MCOAttachment.h index 954a825c..eec1bd19 100644 --- a/src/objc/rfc822/MCOAttachment.h +++ b/src/objc/rfc822/MCOAttachment.h @@ -42,18 +42,6 @@ /** Returns string representation according to charset*/ - (NSString *) decodedString; -/** Adds a content type parameter.*/ -- (void) setContentTypeParameterValue:(NSString *)value forName:(NSString *)name; - -/** Remove a given content type parameter.*/ -- (void) removeContentTypeParameterForName:(NSString *)name; - -/** Returns the value of a given content type parameter.*/ -- (NSString *) contentTypeParameterValueForName:(NSString *)name; - -/** Returns an array with the names of all content type parameters.*/ -- (NSArray * /* NSString */) allContentTypeParametersNames; - @end #endif diff --git a/src/objc/rfc822/MCOAttachment.mm b/src/objc/rfc822/MCOAttachment.mm index 18c13693..afaf96af 100644 --- a/src/objc/rfc822/MCOAttachment.mm +++ b/src/objc/rfc822/MCOAttachment.mm @@ -90,23 +90,4 @@ MCO_OBJC_SYNTHESIZE_DATA(setData, data) return [NSString mco_stringWithMCString:result]; } -- (void) setContentTypeParameterValue:(NSString *)value forName:(NSString *)name -{ - MCO_NATIVE_INSTANCE->setContentTypeParameter(MCO_FROM_OBJC(mailcore::String, name), MCO_FROM_OBJC(mailcore::String, value)); -} - -- (NSString *) contentTypeParameterValueForName:(NSString *)name -{ - return MCO_TO_OBJC(MCO_NATIVE_INSTANCE->contentTypeParameterValueForName((MCO_FROM_OBJC(mailcore::String, name)))); -} -- (void) removeContentTypeParameterForName:(NSString *)name -{ - MCO_NATIVE_INSTANCE->removeContentTypeParameter(MCO_FROM_OBJC(mailcore::String, name)); -} - -- (NSArray * /* NSString */) allContentTypeParametersNames -{ - return MCO_TO_OBJC(MCO_NATIVE_INSTANCE->allContentTypeParametersNames()); -} - @end diff --git a/src/objc/rfc822/MCOMessageBuilder.h b/src/objc/rfc822/MCOMessageBuilder.h index a52afc0f..1663d6f7 100644 --- a/src/objc/rfc822/MCOMessageBuilder.h +++ b/src/objc/rfc822/MCOMessageBuilder.h @@ -58,6 +58,24 @@ /** RFC 822 formatted message.*/ - (NSData *) data; +/** RFC 822 formatted message for encryption.*/ +- (NSData *) dataForEncryption; + +/** + Returns an OpenPGP signed message with a given signature. + The signature needs to be computed on the data returned by -dataForEncryption + before calling this method. + You could use http://www.netpgp.com to generate it. + */ +- (NSData *) openPGPSignedMessageDataWithSignatureData:(NSData *)signature; + +/** + Returns an OpenPGP encrypted message with a given encrypted data. + The encrypted data needs to be computed before calling this method. + You could use http://www.netpgp.com to generate it. + */ +- (NSData *) openPGPEncryptedMessageDataWithEncryptedData:(NSData *)encryptedData; + /** HTML rendering of the message to be displayed in a web view. The delegate can be nil.*/ - (NSString *) htmlRenderingWithDelegate:(id <MCOHTMLRendererDelegate>)delegate; diff --git a/src/objc/rfc822/MCOMessageBuilder.mm b/src/objc/rfc822/MCOMessageBuilder.mm index c884386f..c122ab14 100644 --- a/src/objc/rfc822/MCOMessageBuilder.mm +++ b/src/objc/rfc822/MCOMessageBuilder.mm @@ -66,6 +66,11 @@ MCO_OBJC_SYNTHESIZE_STRING(setBoundaryPrefix, boundaryPrefix) return MCO_OBJC_BRIDGE_GET(data); } +- (NSData *) dataForEncryption +{ + return MCO_OBJC_BRIDGE_GET(dataForEncryption); +} + - (NSString *) htmlRenderingWithDelegate:(id <MCOHTMLRendererDelegate>)delegate { MCOAbstractMessageRendererCallback * htmlRenderCallback = new MCOAbstractMessageRendererCallback(self, delegate, NULL); @@ -95,4 +100,14 @@ MCO_OBJC_SYNTHESIZE_STRING(setBoundaryPrefix, boundaryPrefix) return MCO_TO_OBJC(MCO_NATIVE_INSTANCE->plainTextBodyRendering(stripWhitespace)); } +- (NSData *) openPGPSignedMessageDataWithSignatureData:(NSData *)signature +{ + return MCO_TO_OBJC(MCO_NATIVE_INSTANCE->openPGPSignedMessageDataWithSignatureData(MCO_FROM_OBJC(mailcore::Data, signature))); +} + +- (NSData *) openPGPEncryptedMessageDataWithEncryptedData:(NSData *)encryptedData +{ + return MCO_TO_OBJC(MCO_NATIVE_INSTANCE->openPGPEncryptedMessageDataWithEncryptedData(MCO_FROM_OBJC(mailcore::Data, encryptedData))); +} + @end diff --git a/src/objc/smtp/MCOSMTPSession.h b/src/objc/smtp/MCOSMTPSession.h index 5c616244..286cd7c3 100644 --- a/src/objc/smtp/MCOSMTPSession.h +++ b/src/objc/smtp/MCOSMTPSession.h @@ -30,7 +30,7 @@ /** This is the hostname of the SMTP server to connect to. */ @property (nonatomic, copy) NSString * hostname; -/** This is the port of the POP3 server to connect to. */ +/** This is the port of the SMTP server to connect to. */ @property (nonatomic, assign) unsigned int port; /** This is the username of the account. */ @@ -95,7 +95,7 @@ Generate RFC 822 data using MCOMessageBuilder - MCOPOPOperation * op = [session sendOperationWithData:rfc822Data]; + MCOSMTPOperation * op = [session sendOperationWithData:rfc822Data]; [op start:^(NSError * error) { ... }]; @@ -109,7 +109,7 @@ Generate RFC 822 data using MCOMessageBuilder - MCOPOPOperation * op = [session sendOperationWithData:rfc822Data + MCOSMTPOperation * op = [session sendOperationWithData:rfc822Data from:[MCOAddress addressWithMailbox:@"hoa@etpan.org"] recipients:[NSArray arrayWithObject:[MCOAddress addressWithMailbox:@"laura@etpan.org"]]]; [op start:^(NSError * error) { @@ -123,7 +123,7 @@ /** Returns an operation that will check whether the SMTP account is valid. - MCOPOPOperation * op = [session checkAccountOperationWithFrom:[MCOAddress addressWithMailbox:@"hoa@etpan.org"]]; + MCOSMTPOperation * op = [session checkAccountOperationWithFrom:[MCOAddress addressWithMailbox:@"hoa@etpan.org"]]; [op start:^(NSError * error) { ... }]; @@ -133,7 +133,7 @@ /** Returns an operation that will perform a No-Op. - MCOPOPOperation * op = [session noopOperation]; + MCOSMTPOperation * op = [session noopOperation]; [op start:^(NSError * error) { ... }]; diff --git a/src/objc/smtp/MCOSMTPSession.mm b/src/objc/smtp/MCOSMTPSession.mm index 17dc5057..e0eb2a7d 100644 --- a/src/objc/smtp/MCOSMTPSession.mm +++ b/src/objc/smtp/MCOSMTPSession.mm @@ -67,6 +67,7 @@ private: - (void)dealloc { MC_SAFE_RELEASE(_loggerBridge); [_connectionLogger release]; + _session->setConnectionLogger(NULL); _session->release(); [super dealloc]; } diff --git a/src/objc/utils/NSError+MCO.mm b/src/objc/utils/NSError+MCO.mm index 6d49e4bb..b6b73f6d 100644 --- a/src/objc/utils/NSError+MCO.mm +++ b/src/objc/utils/NSError+MCO.mm @@ -48,6 +48,7 @@ static NSString * MCOLocalizedDescriptionTable[] = { @"A sender is required to send message", /** MCOErrorNoSender */ @"A recipient is required to send message", /** MCOErrorNoRecipient */ @"An error occured while performing a No-Op operation.", /** MCOErrorNoop */ + @"An application specific password is required", /** MCOErrorGmailApplicationSpecificPasswordRequired */ }; @implementation NSError (MCO) @@ -57,7 +58,7 @@ static NSString * MCOLocalizedDescriptionTable[] = { } NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; - if (code < MCOErrorCodeCount) { + if ((NSInteger) code < MCOErrorCodeCount) { NSString * localizedString = NSLocalizedStringFromTable(MCOLocalizedDescriptionTable[code], @"description of errors of mailcore", @"MailCore"); [userInfo setObject:localizedString forKey:NSLocalizedDescriptionKey]; } |