diff -r 000000000000 -r 72b543305e3a email/pop3andsmtpmtm/popservermtm/src/POPSOP.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/pop3andsmtpmtm/popservermtm/src/POPSOP.CPP Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,921 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include "POPS.H" //CImPop3Session +#include "POPSOP.H" //CImPop3Operation +#include "POPS.PAN" //IMPP panic codes + +#include //CImRecvConvert +#include //ImCheckDiskSpace utility class +#include //MessageServer utility class + +const TInt KTOPRequestSize = 18; // i.e. 'TOP nnnn 1\r\n' where nnnn can be a 32 bit integer +const TInt KTOPBatchLimit = 100; // Pipelining limit of 100 TOP requests at a time + +// string constants used whilst parsing response from POP3 email server +_LIT8(KAuthMatchString,"*SASL *"); +_LIT8(KAuthPlainMatchString,"* PLAIN*"); +_LIT8(KAuthLoginMatchString,"* LOGIN*"); +_LIT8(KAuthCramMD5MatchString,"* CRAM-MD5*"); + +// Special case for non-compliant Domino servers +_LIT8(KAuthDominoMatchString,"*AUTH=*"); +_LIT8(KAuthDominoPlainMatchString,"*=PLAIN*"); +_LIT8(KAuthDominoLoginMatchString,"*=LOGIN*"); +_LIT8(KAuthDominoCramMD5MatchString,"*=CRAM-MD5*"); + +// Utility functions declared in IMPP.CPP +GLREF_C TBool CommandAccepted(TDesC8& aResponse); + +// IMPP Panic function +GLREF_C void Panic(TPopsPanic aPanic); +// +// CImPop3Operation - an Abstract base for all the specific POP3 operations +// +CImPop3Operation::CImPop3Operation() + : CMsgActive(KImPopSessionPriority),iFullStopTerminator(_S8(".\r\n")) + { + _LIT(KPop3Operation,"CImPop3Operation"); + __DECLARE_NAME(KPop3Operation()); + } + +CImPop3Operation::~CImPop3Operation() + { + Cancel(); + delete iImId; + } + +// +// 2nd stage of construction +// +void CImPop3Operation::Construct(CImPop3Session *aPopSession) + { + iPopSession=aPopSession; + iTextServer=aPopSession->TextServerSession(); + CActiveScheduler::Add(this); + } + +void CImPop3Operation::Construct(CImPop3Session *aPopSession, CImRecvConvert* aRecvConverter) + { + Construct(aPopSession); + iRecvConverter=aRecvConverter; + } + +void CImPop3Operation::DoRunL() + { + iPopSession->SetOpNotPending(); + + __ASSERT_ALWAYS(iTextServer->GetCurrentTextLine(iTextServerResponse)==ECRLFTerminated,User::Leave(EImppBufferNotTerminated)); + if(CommandAccepted(iTextServerResponse)==EFalse) + { + // Message has disapeared already + } + } + +void CImPop3Operation::DoCancel() + { + iTextServer->Cancel(); + if (iRecvConverter != NULL) + { + iRecvConverter->Cancel(); + } + CMsgActive::DoCancel(); + } +// +// Queue a read operation to get next line of text +// +void CImPop3Operation::QueueReadNext() + { + iTextServer->QueueReceiveNextTextLine(iStatus); + SetActive(); + } + +// +// Return the Pop3 mailbox index no of a message with give Babel msg id +// +TInt CImPop3Operation::MessageNo(TMsvId aMsgId) + { + TInt msgNo=iPopSession->MessageNo(aMsgId); + return msgNo; + } + +// +// Check if there's a poperation outstainding if so panic +// +void CImPop3Operation::CheckIfPending() + { + iPopSession->IsPending() ? Panic(EImppOperationAlreadyPending) : iPopSession->SetPending(); + } + +// +// Retrieve a full message or just the specified no of lines +// +void CImPop3Operation::RetrieveMessageL() + { + iPopSession->SetOpNotPending(); + + iTextServer->GetCurrentTextLine(iTextServerResponse); + + if(iFirstLine) + { + iParsedHeader=EFalse; + iCommandAccepted=CommandAccepted(iTextServerResponse); + iFirstLine=EFalse; + if(!iCommandAccepted) + { + return; + } + } + else + { + TBool fakeDot=EFalse; + if(iTextServerResponse.Compare(iFullStopTerminator)!=0) // header + first n lines last line is a full stop + { + RemoveFirstDot(); + if (iRecvConverter->ParseNextField( iTextServerResponse ) == KErrNoMemory) + { + User::Leave(KErrNoMemory); + } + } + else if(iParsedHeader==EFalse) + { + RemoveFirstDot(); + _LIT8(KCrLfStr,"\r\n"); + if (iRecvConverter->ParseNextField( KCrLfStr ) == KErrNoMemory) + { + User::Leave(KErrNoMemory); + } + fakeDot=ETrue; + } + else + return; + + // test for comp header + if(iRecvConverter->ValidCompleteHeader()) + { + iParsedHeader=ETrue; + // test for valid headers + const CImHeader& header = iRecvConverter->Header(); + iEmptyHeaders=( (header.From().Length()==0) + &&(header.ReplyTo().Length()==0) + &&(header.ToRecipients().Count()==0) + &&(header.CcRecipients().Count()==0) + &&(header.BccRecipients().Count()==0)); + + // store id of new entry created by IMCV + iNewEntryId = iRecvConverter->EntryId(); + // store internet msg id + HBufC8* imId = header.ImMsgId().AllocL(); + delete iImId; + iImId = NULL; + iImId = imId; + } + + if(fakeDot!=EFalse) + { + return; + } + } + + QueueReadNext(); + } + +// +// What to do on completion +// +void CImPop3Operation::DoComplete(TInt& /*aCompleteRequest*/) + { + } + +TBool CImPop3Operation::PopCommandAccepted() + { + return iCommandAccepted; + } + +// +// Remove first dot of a pair +// +void CImPop3Operation::RemoveFirstDot() + { + if(iTextServerResponse.Length()>2) + { + if( (iTextServerResponse[0]=='.') && (iTextServerResponse[1]=='.')) + { + iTextServerResponse.Delete(0,1); + } + } + } + +TPtrC8 CImPop3Operation::ImMsgId() + { + return (iImId ? TPtrC8(*iImId) : TPtrC8()); + } + +TBool CImPop3Operation::SetMessage(TMsvId anId) + { + iMessageNo=MessageNo(anId); + return iMessageNo == KErrNotFound ? EFalse: ETrue; + } + + +// +// CImPop3Stat return no of messages and the mailbox size +// +CImPop3Stat* CImPop3Stat::NewL(CImPop3Session *aPopSession) + { + CImPop3Stat* self = new (ELeave) CImPop3Stat(); + self->Construct(aPopSession); + return self; + } + +void CImPop3Stat::Start(TRequestStatus& aStatus, TUint &aNoMsg, TUint &aMboxSize) + { + CheckIfPending(); + + iNoMessages=&aNoMsg; + iMailboxSize=&aMboxSize; + + _LIT8(KStatCrLfStr,"STAT\r\n"); + iTextServer->SendQueueReceive(iStatus, KStatCrLfStr()); + SetActive(); + Queue(aStatus); + } + +// Got a response from the text server + +void CImPop3Stat::DoRunL() + { + iPopSession->SetOpNotPending(); + __ASSERT_ALWAYS(iTextServer->GetCurrentTextLine(iTextServerResponse)==ECRLFTerminated,User::Leave(EImppBufferNotTerminated)); + + if(CommandAccepted(iTextServerResponse)) + { + TLex8 parseResponse(iTextServerResponse); + parseResponse.SkipCharacters(); + parseResponse.SkipSpace(); + + if(parseResponse.Val(*iNoMessages)==KErrNone) + { + parseResponse.SkipSpace(); + parseResponse.Val(*iMailboxSize); + } + else + *iNoMessages=0; + } + } + +// +// CImPop3List list a specific message no and size or all messages and sizes +// +CImPop3List* CImPop3List::NewL(CImPop3Session *aPopSession) + { + CImPop3List* self = new (ELeave) CImPop3List(); + self->Construct(aPopSession); + return self; + } + +void CImPop3List::Start(TRequestStatus& aStatus, TUint* aSize) + { + CheckIfPending(); + iSize=aSize; + iArrayPos=0; + + if(iMessageNo!=0) + { + _LIT8(KListArgCrLfStr,"LIST %d\r\n"); + iTextServer->SendQueueReceive(iStatus, KListArgCrLfStr, iMessageNo); + } + else + { + _LIT8(KListCrLfStr,"LIST\r\n"); + iTextServer->SendQueueReceive(iStatus,KListCrLfStr()); + iFirstLine=ETrue; + } + + SetActive(); + Queue(aStatus); + } + +void CImPop3List::DoRunL() + { + iPopSession->SetOpNotPending(); + + __ASSERT_ALWAYS(iTextServer->GetCurrentTextLine(iTextServerResponse)==ECRLFTerminated,User::Leave(EImppBufferNotTerminated)); + TLex8 parseResponse(iTextServerResponse); + + if(iNoResponses > 0) + { + if(CommandAccepted(iTextServerResponse)) + User::Leave(KErrNotFound); + } + + if(iMessageNo!=0) + { + if(CommandAccepted(iTextServerResponse)) + { + parseResponse.SkipCharacters(); + parseResponse.SkipSpace(); + GetIndexAndSize(&parseResponse); + } + else + Panic(EImppBabelMsgDoesNotExist); + } + else + { + if(iFirstLine) + { + if(CommandAccepted(iTextServerResponse)) + { + iFirstLine=EFalse; + } + else + { + return; + } + } + else + { + if(iTextServerResponse.Compare(iFullStopTerminator)==0) // list of message info last line is a full stop + { + return; + } + else + { + if(GetIndexAndSize(&parseResponse)==KErrNone) + { + iArrayPos++; + iNoResponses++; + } + else + { + iSize[iArrayPos] = 0; + } + } + } + QueueReadNext(); + } + } + +// +// Get size of a specific message (folder view displays message sizes) +// +TInt CImPop3List::GetIndexAndSize(TLex8 *aLex) + { + aLex->SkipCharacters(); + aLex->SkipSpace(); + return(aLex->Val(iSize[iArrayPos])); + } + +// +// CImPop3Retr Retrieve a specific message +// +CImPop3Retr* CImPop3Retr::NewL(CImPop3Session *aPopSession, CImRecvConvert* aRecvConverter, RFs& aFs) + { + CImPop3Retr* self = new (ELeave) CImPop3Retr(aFs); + CleanupStack::PushL(self); + self->ConstructL(aPopSession, aRecvConverter); + CleanupStack::Pop(self); + return self; + } +void CImPop3Retr::ConstructL(CImPop3Session *aPopSession, CImRecvConvert* aRecvConverter) + { + Construct(aPopSession,aRecvConverter); + iCurrentDrive = MessageServer::CurrentDriveL(iFs); + } + +void CImPop3Retr::StartL(TRequestStatus& aStatus) + { + CheckIfPending(); + iFirstLine=ETrue; + iNoBytesRetrieved=0; + iEmptyHeaders = EFalse; + ImCheckDiskSpace::LeaveIfLowDiskL(iFs, iCurrentDrive); + + iRecvConverter->ResetL(); + + _LIT8(KRetrArgCrLfStr,"RETR %d\r\n"); + iTextServer->SendQueueReceive(iStatus, KRetrArgCrLfStr, iMessageNo); + SetActive(); + Queue(aStatus); + } + +void CImPop3Retr::DoRunL() + { + RetrieveMessageL(); + if(iFirstLine==EFalse) + { + iNoBytesRetrieved+=iTextServerResponse.Length(); + } + } + +TUint CImPop3Retr::Progress() + { + return iNoBytesRetrieved; + } + +void CImPop3Retr::SetMessageIndex(TInt anIndex) + { + iMessageNo=anIndex; + } +// +// CImPop3Dele Delete a specified message +// +CImPop3Dele* CImPop3Dele::NewL(CImPop3Session *aPopSession) + { + CImPop3Dele* self = new (ELeave) CImPop3Dele(); + self->Construct(aPopSession); + return self; + } + +void CImPop3Dele::Start(TRequestStatus& aStatus) + { + CheckIfPending(); + + _LIT8(KDeleArgCrLfStr,"DELE %d\r\n"); + iTextServer->SendQueueReceive(iStatus, KDeleArgCrLfStr, iMessageNo); + SetActive(); + Queue(aStatus); + } + + +// +// CImPop3Noop No operation (but I'm still here) +// +CImPop3Noop* CImPop3Noop::NewL(CImPop3Session *aPopSession) + { + CImPop3Noop* self = new (ELeave) CImPop3Noop(); + self->Construct(aPopSession); + return self; + } + +void CImPop3Noop::Start(TRequestStatus& aStatus) + { + CheckIfPending(); + + _LIT8(KNoopCrLfStr,"NOOP\r\n"); + iTextServer->SendQueueReceive(iStatus, KNoopCrLfStr()); + SetActive(); + Queue(aStatus); + } + +// +// CImPop3Rset Reset +// +CImPop3Rset* CImPop3Rset::NewL(CImPop3Session *aPopSession) + { + CImPop3Rset* self = new (ELeave) CImPop3Rset(); + self->Construct(aPopSession); + return self; + } + +void CImPop3Rset::Start(TRequestStatus& aStatus) + { + CheckIfPending(); + _LIT8(KRsetCrLfStr,"RSET\r\n"); + iTextServer->SendQueueReceive(iStatus, KRsetCrLfStr()); + SetActive(); + Queue(aStatus); + } + +// +// Return specified header and top n lines of message. +// If the POP server supports pipelining, TOP requests will be submitted in +// batches. The batch size limit is 100 requests. +// +CImPop3Top* CImPop3Top::NewL(CImPop3Session *aPopSession, CImRecvConvert* aRecvConverter,TBool aHeaderOnly) + { + CImPop3Top* self = new (ELeave) CImPop3Top(); + self->ConstructL(aPopSession,aRecvConverter,aHeaderOnly); + return self; + } + +void CImPop3Top::ConstructL(CImPop3Session *aPopSession, CImRecvConvert* aRecvConverter,TBool aHeaderOnly) + { + CImPop3Operation::Construct(aPopSession,aRecvConverter); + iHeadersOnly = aHeaderOnly; + } + +void CImPop3Top::StartL(TRequestStatus& aStatus) + { + CheckIfPending(); + iFirstLine=ETrue; + iNoBytesRetrieved=0; + iEmptyHeaders = EFalse; + + if (iHeadersOnly) + { + iRecvConverter->ResetForHeadersL(); + } + else + { + iRecvConverter->ResetL(); + } + + if(iPipeliningSupported) + { + if(iMessageNo <= iLastMulti) + { + TInt numberToGet = iLastMulti - iStartMsg; + TInt tempStartPos(iStartMsg); + if (numberToGet > KTOPBatchLimit) + { + tempStartPos = iLastMulti - KTOPBatchLimit; + numberToGet = KTOPBatchLimit; + } + HBufC8* buffer = HBufC8::NewLC(numberToGet * KTOPRequestSize); + TPtr8 bufferPtr = buffer->Des(); + for(; iLastMulti > tempStartPos; --iLastMulti) + { + if(iPopSession->MessageArray()[iLastMulti-1]==0) + { + _LIT8(KTopArgArgCrLfStr,"TOP %d %d\r\n"); + bufferPtr.AppendFormat( KTopArgArgCrLfStr, iLastMulti, iNoLines ); + } + } + iTextServer->SendQueueReceive(iStatus, bufferPtr); + CleanupStack::PopAndDestroy(buffer); + } + else + { + // These headers should be on their way already, queue another read + QueueReadNext(); // This calls SetActive() for us + Queue(aStatus); + return; + } + } + else // pipelining not supported by server + { + _LIT8(KTopArgArgCrLfStr,"TOP %d %d\r\n"); + iTextServer->SendQueueReceive(iStatus, KTopArgArgCrLfStr, iMessageNo, iNoLines); + } + SetActive(); + Queue(aStatus); + } + +void CImPop3Top::DoRunL() + { + RetrieveMessageL(); + if(iFirstLine==EFalse) + { + iNoBytesRetrieved+=iTextServerResponse.Length(); + } + } + +TBool CImPop3Top::SetMessageAndLines(TMsvId aId, TInt aNoLines) + { + iNoLines=aNoLines; + return SetMessage(aId); + } + +void CImPop3Top::SetMessageIndexAndLines(TInt anIndex, TInt aNoLines) + { + iMessageNo=anIndex; + iNoLines=aNoLines; + } + +void CImPop3Top::SetStartAndEndMessageIndex(TInt aStart, TInt aEnd) + { + iPipeliningSupported = ETrue; + iStartMsg = aStart; + iLastMulti = aEnd + 1; // off by one + } + +TUint CImPop3Top::Progress() + { + return iNoBytesRetrieved; + } + +// CImPop3UidlMap +// +CImPop3UidlMap* CImPop3UidlMap::NewL(TInt aMsgCount) + { + return new(ELeave) CImPop3UidlMap(aMsgCount); + } + +CImPop3UidlMap::~CImPop3UidlMap() + {} + +void CImPop3UidlMap::BindL(TInt aMsgIx,const TDesC8& aUidl) + { + // Insert mail Uidls into Uidl array including duplicated uidls. + TInt pos = iUid.InsertIsqAllowDuplicatesL(aUidl,ECmpNormal); + iMsgNo.InsertL(pos,aMsgIx); + } + + +TInt CImPop3UidlMap::MsgNo(const TDesC8& aUidl) const + { + TInt pos; + if (iUid.FindIsq(aUidl,pos,ECmpNormal)==0) + { + return iMsgNo[pos]; + } + return -1; + } + +TPtrC8 CImPop3UidlMap::At(TInt aMsgIx) const + { + if (iMsgNo.Count()) + { + const TInt* p=&iMsgNo[0]; + for (TInt ii=iMsgNo.Count();--ii>=0;) + { + if (p[ii]==aMsgIx) + { + return iUid[ii]; + } + } + } + return TPtrC8(); + } + +CImPop3UidlMap::CImPop3UidlMap(TInt aMsgCount) + :iUid(aMsgCount),iMsgNo(aMsgCount) + { + __DECLARE_NAME(_S("CImPop3UidlMap")); + } + +// +// CImPop3 Uidl return unique id for a specified message or all the messages +// +CImPop3Uidl* CImPop3Uidl::NewL(CImPop3Session *aPopSession) + { + CImPop3Uidl* self = new (ELeave) CImPop3Uidl(); + self->Construct(aPopSession); + return self; + } + +void CImPop3Uidl::Start(TRequestStatus& aStatus, CImPop3UidlMap& anArray) + { + CheckIfPending(); + iMsgUid=&anArray; + if(iMessageNo!=0) + { + _LIT8(KUidlArgCrLfStr,"UIDL %d\r\n"); + iTextServer->SendQueueReceive(iStatus, KUidlArgCrLfStr, iMessageNo); + } + else + { + _LIT8(KUidlCrLfStr,"UIDL\r\n"); + iTextServer->SendQueueReceive(iStatus, KUidlCrLfStr()); + iFirstLine=ETrue; + } + SetActive(); + Queue(aStatus); + } + +void CImPop3Uidl::DoRunL() + { + iPopSession->SetOpNotPending(); + __ASSERT_ALWAYS(iTextServer->GetCurrentTextLine(iTextServerResponse)==ECRLFTerminated,User::Leave(EImppBufferNotTerminated)); + TLex8 parseResponse(iTextServerResponse); + + if(iMessageNo!=0) // one specific Uid + { + iCommandAccepted=CommandAccepted(iTextServerResponse); + if(iCommandAccepted) + { + parseResponse.SkipCharacters(); + parseResponse.SkipSpace(); + GetIndexAndUidL(&parseResponse); + } + else + Panic(EImppBabelMsgDoesNotExist); + } + else // list all Uids + { + if(iFirstLine) + { + iCommandAccepted=CommandAccepted(iTextServerResponse); + if(iCommandAccepted) + { + iFirstLine=EFalse; + } + else + { + return; + } + } + else + { + if(iTextServerResponse.Compare(iFullStopTerminator)==0) // list of message info last line is a full stop + { + return; + } + else + { + GetIndexAndUidL(&parseResponse); + } + } + QueueReadNext(); + } + } + +// +// Get index no and Pop id of a message +// +void CImPop3Uidl::GetIndexAndUidL(TLex8* aLex) + { + TInt msgNo; + TInt lexErr=aLex->Val(msgNo); + TLexMark8 uidMarker; + + if(lexErr==KErrNone) + { + aLex->SkipSpace(); + aLex->Mark(uidMarker); + aLex->SkipCharacters(); + iMsgUid->BindL(msgNo-1,aLex->MarkedToken( uidMarker )); + } + } + +// +// CImPop3Capa returns the list of capabilities supported by the server +// +CImPop3Capa* CImPop3Capa::NewL(CImPop3Session *aPopSession) + { + CImPop3Capa* self = new (ELeave) CImPop3Capa(); + self->Construct(aPopSession); + return self; + } + +void CImPop3Capa::Start(TRequestStatus& aStatus) + { + CheckIfPending(); + _LIT8(KCapaCrLfStr,"CAPA\r\n"); + iTextServer->SendQueueReceive(iStatus, KCapaCrLfStr()); + iFirstLine = ETrue; + SetActive(); + Queue(aStatus); + } + +// Got a response from the text server +void CImPop3Capa::DoRunL() + { + iPopSession->SetOpNotPending(); + + iTextServer->GetCurrentTextLine(iTextServerResponse); + if(iFirstLine) + { + iCommandAccepted = CommandAccepted(iTextServerResponse); + iFirstLine = EFalse; + if(!iCommandAccepted) + { + return; + } + } + else + { + if(iTextServerResponse.Compare(iFullStopTerminator) != 0) + { + TInt crPos = iTextServerResponse.Find(KImcvCRLF); + if(crPos>0) + { + TPtrC8 ptr; + ptr.Set(iTextServerResponse.Left(crPos)); + _LIT8(KPipelining, "PIPELINING"); + + if(ptr.CompareF(KPipelining) == 0) + { + iPipeliningSupported = ETrue; + } + +#if (defined SYMBIAN_EMAIL_CAPABILITY_SUPPORT) + if (iTextServerResponse.Match(KAuthMatchString) != KErrNotFound || + iTextServerResponse.Match(KAuthDominoMatchString) != KErrNotFound) + { + SetSaslAuthExtensionFlag(); + } +#endif + } + else + return; + } + else + return; + } + QueueReadNext(); + } + +TBool CImPop3Capa::PipeliningSupport() + { + return iPipeliningSupported; + } + +#if (defined SYMBIAN_EMAIL_CAPABILITY_SUPPORT) + +/** +To check the Server Response for CAPABILITY command and set iSupportedAuthProfiles accordingly. +*/ +void CImPop3Capa::SetSaslAuthExtensionFlag() + { + // check for each supported profile + if (iTextServerResponse.Match(KAuthMatchString) != KErrNotFound) + { + if (iTextServerResponse.Match(KAuthPlainMatchString) != KErrNotFound) + { + iSupportedAuthProfiles|=CPopAuthMechanismHelper::EPlain; + } + + if (iTextServerResponse.Match(KAuthLoginMatchString) != KErrNotFound) + { + iSupportedAuthProfiles|=CPopAuthMechanismHelper::ELogin; + } + + if (iTextServerResponse.Match(KAuthCramMD5MatchString) != KErrNotFound) + { + iSupportedAuthProfiles|=CPopAuthMechanismHelper::ECramMD5; + } + } + + // Special case for Domino servers tagging "=" after "AUTH" + if (iTextServerResponse.Match(KAuthDominoMatchString) != KErrNotFound) + { + if (iTextServerResponse.Match(KAuthDominoPlainMatchString) != KErrNotFound) + { + iSupportedAuthProfiles|=CPopAuthMechanismHelper::EPlain; + } + + if (iTextServerResponse.Match(KAuthDominoLoginMatchString) != KErrNotFound) + { + iSupportedAuthProfiles|=CPopAuthMechanismHelper::ELogin; + } + + if (iTextServerResponse.Match(KAuthDominoCramMD5MatchString) != KErrNotFound) + { + iSupportedAuthProfiles|=CPopAuthMechanismHelper::ECramMD5; + } + } + } + +/** +To get iSupportedAuthProfiles value. +*/ +TUint CImPop3Capa::SaslAuthExtensionFlag() + { + return iSupportedAuthProfiles; + } +#endif + +// Function will return Index of message(if unique UIDL) Or KErrAlreadyExists(if Duplicate UIdl) +//Or KErrNotFound if UIdl not present.. +TInt CImPop3UidlMap::MsgUidlNo(const TDesC8& aUidl,TInt& aPos) const + { + if (iUid.FindIsq(aUidl,aPos,ECmpNormal) == 0) + { + if(aPos > 0 ) + { + //To Check that the index does not exceed size of the iUid array. + if(aPos == (iMsgNo.Count() - 1)) + { + if ((iUid[aPos-1]) == aUidl) + { + return KErrAlreadyExists; + } + } + else + { + if ((iUid[aPos-1]) == aUidl || (iUid[aPos+1]) == aUidl) + { + return KErrAlreadyExists; + } + + } + } + return iMsgNo[aPos]; + + } + return KErrNotFound; + } + + +// To return the Index of the UIDL corresponding to a UIDL position. +TInt CImPop3UidlMap::MsgIndex(TInt aPos) const + { + return iMsgNo[aPos]; + } + +// To get the no. of UIDLs in the server.. +TInt CImPop3UidlMap::MsgCount() const + { + return iMsgNo.Count(); + } + +//Return the UIDL at aPos. +TPtrC8 CImPop3UidlMap::MsgUidl(TInt aPos) const + { + return iUid[aPos]; + }