aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/imap
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/imap')
-rw-r--r--src/core/imap/MCIMAPMessage.cc20
-rw-r--r--src/core/imap/MCIMAPMessage.h4
-rwxr-xr-xsrc/core/imap/MCIMAPSession.cc126
-rwxr-xr-xsrc/core/imap/MCIMAPSession.h11
4 files changed, 156 insertions, 5 deletions
diff --git a/src/core/imap/MCIMAPMessage.cc b/src/core/imap/MCIMAPMessage.cc
index 59d67654..6845d19a 100644
--- a/src/core/imap/MCIMAPMessage.cc
+++ b/src/core/imap/MCIMAPMessage.cc
@@ -17,6 +17,7 @@ void IMAPMessage::init()
mUid = 0;
mFlags = MessageFlagNone;
mOriginalFlags = MessageFlagNone;
+ mCustomFlags = NULL;
mMainPart = NULL;
mGmailLabels = NULL;
mModSeqValue = 0;
@@ -35,6 +36,7 @@ IMAPMessage::IMAPMessage(IMAPMessage * other) : AbstractMessage(other)
setUid(other->uid());
setFlags(other->flags());
setOriginalFlags(other->originalFlags());
+ setCustomFlags(other->customFlags());
setMainPart((AbstractPart *) other->mainPart()->copy()->autorelease());
setGmailLabels(other->gmailLabels());
setGmailThreadID(other->gmailThreadID());
@@ -45,6 +47,7 @@ IMAPMessage::~IMAPMessage()
{
MC_SAFE_RELEASE(mMainPart);
MC_SAFE_RELEASE(mGmailLabels);
+ MC_SAFE_RELEASE(mCustomFlags);
}
Object * IMAPMessage::copy()
@@ -105,6 +108,16 @@ MessageFlag IMAPMessage::originalFlags()
return mOriginalFlags;
}
+void IMAPMessage::setCustomFlags(Array * customFlags)
+{
+ MC_SAFE_REPLACE_COPY(Array, mCustomFlags, customFlags);
+}
+
+Array * IMAPMessage::customFlags()
+{
+ return mCustomFlags;
+}
+
void IMAPMessage::setModSeqValue(uint64_t uid)
{
mModSeqValue = uid;
@@ -226,6 +239,9 @@ HashMap * IMAPMessage::serializable()
result->setObjectForKey(MCSTR("size"), String::stringWithUTF8Format("%lu", (long unsigned) uid()));
result->setObjectForKey(MCSTR("flags"), String::stringWithUTF8Format("%u", (unsigned) flags()));
result->setObjectForKey(MCSTR("originalFlags"), String::stringWithUTF8Format("%u", (unsigned) originalFlags()));
+ if (customFlags() != NULL) {
+ result->setObjectForKey(MCSTR("customFlags"), customFlags());
+ }
result->setObjectForKey(MCSTR("mainPart"), mMainPart->serializable());
if (gmailLabels() != NULL) {
result->setObjectForKey(MCSTR("gmailLabels"), gmailLabels());
@@ -262,6 +278,10 @@ void IMAPMessage::importSerializable(HashMap * serializable)
if (originalFlags != NULL) {
setFlags((MessageFlag) originalFlags->unsignedIntValue());
}
+ String * customFlags = (String *) serializable->objectForKey(MCSTR("customFlags"));
+ if (customFlags != NULL) {
+ setCustomFlags((Array *) serializable->objectForKey(MCSTR("customFlags")));
+ }
setMainPart((AbstractPart *) Object::objectWithSerializable((HashMap *) serializable->objectForKey(MCSTR("mainPart"))));
setGmailLabels((Array *) serializable->objectForKey(MCSTR("gmailLabels")));
String * gmailMessageID = (String *) serializable->objectForKey(MCSTR("gmailMessageID"));
diff --git a/src/core/imap/MCIMAPMessage.h b/src/core/imap/MCIMAPMessage.h
index ebcad889..e072d131 100644
--- a/src/core/imap/MCIMAPMessage.h
+++ b/src/core/imap/MCIMAPMessage.h
@@ -32,6 +32,9 @@ namespace mailcore {
virtual void setOriginalFlags(MessageFlag flags);
virtual MessageFlag originalFlags();
+ virtual void setCustomFlags(Array * customFlags);
+ virtual Array * customFlags();
+
virtual uint64_t modSeqValue();
virtual void setModSeqValue(uint64_t uid);
@@ -70,6 +73,7 @@ namespace mailcore {
MessageFlag mFlags;
MessageFlag mOriginalFlags;
+ Array * /* String */ mCustomFlags;
AbstractPart * mMainPart;
Array * /* String */ mGmailLabels;
uint64_t mGmailMessageID;
diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc
index 32cd4ebd..02e569dc 100755
--- a/src/core/imap/MCIMAPSession.cc
+++ b/src/core/imap/MCIMAPSession.cc
@@ -133,12 +133,12 @@ static MessageFlag flag_from_lep(struct mailimap_flag * flag)
static MessageFlag flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic * att_dynamic)
{
- MessageFlag flags;
- clistiter * iter;
-
if (att_dynamic->att_list == NULL)
return MessageFlagNone;
+ MessageFlag flags;
+ clistiter * iter;
+
flags = MessageFlagNone;
for(iter = clist_begin(att_dynamic->att_list) ;iter != NULL ; iter = clist_next(iter)) {
struct mailimap_flag_fetch * flag_fetch;
@@ -156,6 +156,62 @@ static MessageFlag flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic *
return flags;
}
+static bool isKnownCustomFlag(const char * keyword)
+{
+ return !(strcmp(keyword, "$MDNSent") != 0 && strcmp(keyword, "$Forwarded") != 0 && strcmp(keyword, "$SubmitPending") != 0 && strcmp(keyword, "$Submitted") != 0);
+}
+
+static Array * custom_flags_from_lep_att_dynamic(struct mailimap_msg_att_dynamic * att_dynamic)
+{
+ if (att_dynamic->att_list == NULL)
+ return NULL;
+
+ clistiter * iter;
+ bool hasCustomFlags = false;
+
+ for (iter = clist_begin(att_dynamic->att_list); iter != NULL; iter = clist_next(iter)) {
+ struct mailimap_flag_fetch * flag_fetch;
+ struct mailimap_flag * flag;
+
+ flag_fetch = (struct mailimap_flag_fetch *) clist_content(iter);
+ if (flag_fetch->fl_type != MAILIMAP_FLAG_FETCH_OTHER) {
+ continue;
+ }
+
+ flag = flag_fetch->fl_flag;
+ if (flag->fl_type == MAILIMAP_FLAG_KEYWORD) {
+ if (!isKnownCustomFlag(flag->fl_data.fl_keyword)) {
+ hasCustomFlags = true;
+ }
+ }
+ }
+
+ if (!hasCustomFlags)
+ return NULL;
+
+ Array * result = Array::array();
+ for (iter = clist_begin(att_dynamic->att_list); iter != NULL; iter = clist_next(iter)) {
+ struct mailimap_flag_fetch * flag_fetch;
+ struct mailimap_flag * flag;
+
+ flag_fetch = (struct mailimap_flag_fetch *) clist_content(iter);
+ if (flag_fetch->fl_type != MAILIMAP_FLAG_FETCH_OTHER) {
+ continue;
+ }
+
+ flag = flag_fetch->fl_flag;
+ if (flag->fl_type == MAILIMAP_FLAG_KEYWORD) {
+ if (!isKnownCustomFlag(flag->fl_data.fl_keyword)) {
+ String * customFlag;
+ customFlag = String::stringWithUTF8Characters(flag->fl_data.fl_keyword);
+ result->addObject(customFlag);
+ }
+ }
+ }
+
+ return result;
+}
+
#pragma mark set conversion
static Array * arrayFromSet(struct mailimap_set * imap_set)
@@ -320,6 +376,7 @@ void IMAPSession::init()
mIdentityEnabled = false;
mNamespaceEnabled = false;
mCompressionEnabled = false;
+ mIsGmail = false;
mWelcomeString = NULL;
mNeedsMboxMailWorkaround = false;
mDefaultNamespace = NULL;
@@ -344,6 +401,8 @@ void IMAPSession::init()
mAutomaticConfigurationEnabled = true;
mAutomaticConfigurationDone = false;
mShouldDisconnect = false;
+ mLoginResponse = NULL;
+ mGmailUserDisplayName = NULL;
}
IMAPSession::IMAPSession()
@@ -353,6 +412,8 @@ IMAPSession::IMAPSession()
IMAPSession::~IMAPSession()
{
+ MC_SAFE_RELEASE(mGmailUserDisplayName);
+ MC_SAFE_RELEASE(mLoginResponse);
MC_SAFE_RELEASE(mClientIdentity);
MC_SAFE_RELEASE(mServerIdentity);
MC_SAFE_RELEASE(mHostname);
@@ -819,6 +880,23 @@ void IMAPSession::login(ErrorCode * pError)
return;
}
+ String * loginResponse = MCSTR("");
+ if (mIsGmail) {
+ if (mImap->imap_response != NULL) {
+ loginResponse = String::stringWithUTF8Characters(mImap->imap_response);
+
+ int location = loginResponse->locationOfString(MCSTR(" authenticated (Success)"));
+ if (location != -1) {
+ String * emailAndName = loginResponse->substringToIndex(location);
+ location = emailAndName->locationOfString(MCSTR(" "));
+ MC_SAFE_RELEASE(mGmailUserDisplayName);
+ mGmailUserDisplayName = emailAndName->substringFromIndex(location + 1);
+ mGmailUserDisplayName->retain();
+ }
+ }
+ }
+ MC_SAFE_REPLACE_COPY(String, mLoginResponse, loginResponse);
+
mState = STATE_LOGGEDIN;
if (isAutomaticConfigurationEnabled()) {
@@ -1500,6 +1578,12 @@ void IMAPSession::unsubscribeFolder(String * folder, ErrorCode * pError)
void IMAPSession::appendMessage(String * folder, Data * messageData, MessageFlag flags,
IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError)
{
+ this->appendMessageWithCustomFlags(folder, messageData, flags, NULL, progressCallback, createdUID, pError);
+}
+
+void IMAPSession::appendMessageWithCustomFlags(String * folder, Data * messageData, MessageFlag flags, Array * customFlags,
+ IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError)
+{
int r;
struct mailimap_flag_list * flag_list;
uint32_t uidvalidity;
@@ -1514,6 +1598,15 @@ void IMAPSession::appendMessage(String * folder, Data * messageData, MessageFlag
flag_list = NULL;
flag_list = flags_to_lep(flags);
+ if (customFlags != NULL) {
+ for (unsigned int i = 0 ; i < customFlags->count() ; i ++) {
+ struct mailimap_flag * f;
+ String * customFlag = (String *) customFlags->objectAtIndex(i);
+
+ f = mailimap_flag_new_flag_keyword(strdup(customFlag->UTF8Characters()));
+ mailimap_flag_list_add(flag_list, f);
+ }
+ }
r = mailimap_uidplus_append(mImap, MCUTF8(folder), flag_list, NULL, messageData->bytes(), messageData->length(),
&uidvalidity, &uidresult);
mailimap_flag_list_free(flag_list);
@@ -1876,6 +1969,10 @@ static void msg_att_handler(struct mailimap_msg_att * msg_att, void * context)
msg->setFlags(flags);
msg->setOriginalFlags(flags);
hasFlags = true;
+
+ Array * customFlags;
+ customFlags = custom_flags_from_lep_att_dynamic(att_item->att_data.att_dyn);
+ msg->setCustomFlags(customFlags);
}
else if (att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) {
struct mailimap_msg_att_static * att_static;
@@ -3165,6 +3262,11 @@ HashMap * IMAPSession::fetchNamespace(ErrorCode * pError)
void IMAPSession::storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, ErrorCode * pError)
{
+ this->storeFlagsAndCustomFlags(folder, uids, kind, flags, NULL, pError);
+}
+
+void IMAPSession::storeFlagsAndCustomFlags(String * folder, IndexSet * uids, IMAPStoreFlagsRequestKind kind, MessageFlag flags, Array * customFlags, ErrorCode * pError)
+{
struct mailimap_set * imap_set;
struct mailimap_store_att_flags * store_att_flags;
struct mailimap_flag_list * flag_list;
@@ -3233,10 +3335,20 @@ void IMAPSession::storeFlags(String * folder, IndexSet * uids, IMAPStoreFlagsReq
}
if ((flags & MessageFlagSubmitted) != 0) {
struct mailimap_flag * f;
-
+
f = mailimap_flag_new_flag_keyword(strdup("$Submitted"));
mailimap_flag_list_add(flag_list, f);
}
+
+ if (customFlags != NULL) {
+ for (unsigned int i = 0 ; i < customFlags->count() ; i ++) {
+ struct mailimap_flag * f;
+ String * customFlag = (String *) customFlags->objectAtIndex(i);
+
+ f = mailimap_flag_new_flag_keyword(strdup(customFlag->UTF8Characters()));
+ mailimap_flag_list_add(flag_list, f);
+ }
+ }
store_att_flags = NULL;
for(clistiter * iter = clist_begin(setList) ; iter != NULL ; iter = clist_next(iter)) {
@@ -3494,6 +3606,7 @@ void IMAPSession::applyCapabilities(IndexSet * capabilities)
}
if (capabilities->containsIndex(IMAPCapabilityGmail)) {
mXListEnabled = false;
+ mIsGmail = true;
}
if (capabilities->containsIndex(IMAPCapabilityIdle)) {
mIdleEnabled = true;
@@ -3726,3 +3839,8 @@ void IMAPSession::resetAutomaticConfigurationDone()
{
mAutomaticConfigurationDone = false;
}
+
+String * IMAPSession::gmailUserDisplayName()
+{
+ return mGmailUserDisplayName;
+}
diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h
index 0cd91fcb..39e1768f 100755
--- a/src/core/imap/MCIMAPSession.h
+++ b/src/core/imap/MCIMAPSession.h
@@ -81,6 +81,8 @@ namespace mailcore {
virtual void appendMessage(String * folder, Data * messageData, MessageFlag flags,
IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError);
+ virtual void appendMessageWithCustomFlags(String * folder, Data * messageData, MessageFlag flags, Array * customFlags,
+ IMAPProgressCallback * progressCallback, uint32_t * createdUID, ErrorCode * pError);
void copyMessages(String * folder, IndexSet * uidSet, String * destFolder,
HashMap ** pUidMapping, ErrorCode * pError);
@@ -120,8 +122,9 @@ namespace mailcore {
IndexSet * uids, uint64_t modseq,
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 IndexSet * search(String * folder, IMAPSearchKind kind, String * searchString, ErrorCode * pError);
@@ -163,6 +166,8 @@ namespace mailcore {
virtual bool isNamespaceEnabled();
virtual bool isCompressionEnabled();
+ virtual String * gmailUserDisplayName();
+
virtual void setConnectionLogger(ConnectionLogger * logger);
virtual ConnectionLogger * connectionLogger();
@@ -219,6 +224,7 @@ namespace mailcore {
bool mXOauth2Enabled;
bool mNamespaceEnabled;
bool mCompressionEnabled;
+ bool mIsGmail;
String * mWelcomeString;
bool mNeedsMboxMailWorkaround;
uint32_t mUIDValidity;
@@ -241,6 +247,9 @@ namespace mailcore {
bool mAutomaticConfigurationDone;
bool mShouldDisconnect;
+ String * mLoginResponse;
+ String * mGmailUserDisplayName;
+
void init();
void bodyProgress(unsigned int current, unsigned int maximum);
void itemsProgress(unsigned int current, unsigned int maximum);