diff options
Diffstat (limited to 'src/core/imap')
-rw-r--r-- | src/core/imap/MCIMAPMessage.cc | 20 | ||||
-rw-r--r-- | src/core/imap/MCIMAPMessage.h | 4 | ||||
-rwxr-xr-x | src/core/imap/MCIMAPSession.cc | 126 | ||||
-rwxr-xr-x | src/core/imap/MCIMAPSession.h | 11 |
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); |