aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Robert Widmann <devteam.codafi@gmail.com>2014-10-21 15:46:19 -0600
committerGravatar Robert Widmann <devteam.codafi@gmail.com>2014-10-21 15:46:19 -0600
commit53a1610d35f00301d933ea051b37b96fd30b0e93 (patch)
treebb2b4a0cdcac791365efc306feede072d347a9ba /src
parentf60b89b388389ee877e907819442b2e366238040 (diff)
parentdf800fed1079fb0b9f49681d7b1688c1d3b97539 (diff)
Merge remote-tracking branch 'upstream/master' into NNTP-Cleanup
Diffstat (limited to 'src')
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncSession.cc54
-rwxr-xr-xsrc/async/imap/MCIMAPAsyncSession.h10
-rw-r--r--src/async/imap/MCIMAPFetchContentOperation.cc27
-rw-r--r--src/async/imap/MCIMAPFetchContentOperation.h4
-rw-r--r--src/async/imap/MCIMAPFolderInfoOperation.cc9
-rw-r--r--src/async/imap/MCIMAPFolderInfoOperation.h4
-rw-r--r--src/async/imap/MCIMAPStoreFlagsOperation.cc19
-rw-r--r--src/async/imap/MCIMAPStoreFlagsOperation.h4
-rw-r--r--src/async/imap/MCIMAPStoreLabelsOperation.cc19
-rw-r--r--src/async/imap/MCIMAPStoreLabelsOperation.h4
-rw-r--r--src/core/abstract/MCAbstractPart.cc51
-rw-r--r--src/core/abstract/MCAbstractPart.h7
-rw-r--r--src/core/abstract/MCMessageConstants.h2
-rw-r--r--src/core/abstract/MCMessageHeader.cc35
-rw-r--r--src/core/abstract/MCMessageHeader.h1
-rw-r--r--src/core/basetypes/MCIterator.h4
-rw-r--r--src/core/basetypes/MCObject.cc7
-rw-r--r--src/core/basetypes/MCOperationQueue.cc15
-rw-r--r--src/core/basetypes/MCString.cc23
-rw-r--r--src/core/imap/MCIMAPMessage.cc16
-rw-r--r--src/core/imap/MCIMAPMessage.h4
-rw-r--r--src/core/imap/MCIMAPSearchExpression.cc8
-rw-r--r--src/core/imap/MCIMAPSearchExpression.h1
-rwxr-xr-xsrc/core/imap/MCIMAPSession.cc255
-rwxr-xr-xsrc/core/imap/MCIMAPSession.h26
-rw-r--r--src/core/pop/MCPOPSession.cc2
-rw-r--r--src/core/renderer/MCDateFormatter.cc6
-rw-r--r--src/core/rfc822/MCAttachment.cc63
-rw-r--r--src/core/rfc822/MCAttachment.h7
-rw-r--r--src/core/rfc822/MCMessageBuilder.cc312
-rw-r--r--src/core/rfc822/MCMessageBuilder.h13
-rw-r--r--src/core/rfc822/MCMessageParser.cc9
-rw-r--r--src/core/smtp/MCSMTPSession.cc2
-rw-r--r--src/objc/abstract/MCOAbstractPart.h12
-rw-r--r--src/objc/abstract/MCOAbstractPart.mm20
-rw-r--r--src/objc/abstract/MCOConstants.h7
-rw-r--r--src/objc/imap/MCOIMAPFetchMessagesOperation.mm3
-rw-r--r--src/objc/imap/MCOIMAPFolderInfo.h3
-rw-r--r--src/objc/imap/MCOIMAPFolderInfo.m2
-rw-r--r--src/objc/imap/MCOIMAPFolderInfoOperation.mm1
-rw-r--r--src/objc/imap/MCOIMAPFolderStatus.h2
-rw-r--r--src/objc/imap/MCOIMAPMessage.h4
-rw-r--r--src/objc/imap/MCOIMAPMessage.mm1
-rw-r--r--src/objc/imap/MCOIMAPSearchExpression.h11
-rw-r--r--src/objc/imap/MCOIMAPSearchExpression.mm5
-rwxr-xr-xsrc/objc/imap/MCOIMAPSession.h263
-rwxr-xr-xsrc/objc/imap/MCOIMAPSession.mm156
-rw-r--r--src/objc/nntp/MCONNTPSession.mm1
-rw-r--r--src/objc/pop/MCOPOPSession.mm1
-rw-r--r--src/objc/rfc822/MCOAttachment.h12
-rw-r--r--src/objc/rfc822/MCOAttachment.mm19
-rw-r--r--src/objc/rfc822/MCOMessageBuilder.h18
-rw-r--r--src/objc/rfc822/MCOMessageBuilder.mm15
-rw-r--r--src/objc/smtp/MCOSMTPSession.h10
-rw-r--r--src/objc/smtp/MCOSMTPSession.mm1
-rw-r--r--src/objc/utils/NSError+MCO.mm3
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];
}