--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ipsservices/ipssosplugin/src/ipsplgsmtpoperation.cpp Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,374 @@
+/*
+* Copyright (c) 2007 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: This file implements class CIpsPlgSmtpOperation.
+*
+*/
+
+
+#include "emailtrace.h"
+#include "ipsplgheaders.h"
+
+
+const TInt KIpsSmtpOperationCharLessThan = '<';
+const TInt KIpsSmtpOperationCharMoreThan = '>';
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CIpsPlgSmtpOperation* CIpsPlgSmtpOperation::NewL(
+ CMsvSession& aMsvSession,
+ TInt aPriority, TRequestStatus&
+ aObserverRequestStatus,
+ TBool /*aUsePublishSubscribe*/ )
+ {
+ FUNC_LOG;
+ CIpsPlgSmtpOperation* self = CIpsPlgSmtpOperation::NewLC(
+ aMsvSession, aPriority, aObserverRequestStatus, ETrue );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CIpsPlgSmtpOperation* CIpsPlgSmtpOperation::NewLC(
+ CMsvSession& aMsvSession,
+ TInt aPriority,
+ TRequestStatus& aObserverRequestStatus,
+ TBool /*aUsePublishSubscribe*/ )
+ {
+ FUNC_LOG;
+ CIpsPlgSmtpOperation* self = new( ELeave ) CIpsPlgSmtpOperation(
+ aMsvSession, aPriority, aObserverRequestStatus );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+CIpsPlgSmtpOperation::CIpsPlgSmtpOperation(
+ CMsvSession& aMsvSession,
+ TInt aPriority,
+ TRequestStatus& aObserverRequestStatus ) :
+ CMsvOperation( aMsvSession, aPriority, aObserverRequestStatus ),
+ iSmtpMtm( NULL ),
+ iOperation( NULL ),
+ iSelection( NULL ),
+ iMtmRegistry( NULL )
+ {
+ FUNC_LOG;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+CIpsPlgSmtpOperation::~CIpsPlgSmtpOperation()
+ {
+ FUNC_LOG;
+ Cancel();
+ delete iSmtpMtm;
+ delete iMtmRegistry;
+ delete iSelection;
+ delete iOperation;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CIpsPlgSmtpOperation::ConstructL()
+ {
+ FUNC_LOG;
+ iSelection = new (ELeave) CMsvEntrySelection();
+ CActiveScheduler::Add( this );
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CIpsPlgSmtpOperation::RunL()
+ {
+ FUNC_LOG;
+
+
+ if ( iState == EMovingOutbox )
+ {
+ delete iOperation;
+ iOperation = NULL;
+ iSelection->InsertL(0, iSmtpService );
+ CallSendL( );
+ }
+ else if ( iState == ESending )
+ {
+ TImSmtpProgress prog;
+ TPckg<TImSmtpProgress> param(prog);
+ param.Copy( iOperation->FinalProgress() );
+
+ TRequestStatus* status = &iObserverRequestStatus;
+ User::RequestComplete( status, prog.Error() );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CIpsPlgSmtpOperation::DoCancel()
+ {
+ FUNC_LOG;
+
+ if ( iOperation )
+ {
+ iOperation->Cancel();
+ }
+ TRequestStatus* status = &iObserverRequestStatus;
+ User::RequestComplete(status, KErrCancel);
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+const TDesC8& CIpsPlgSmtpOperation::ProgressL()
+ {
+ FUNC_LOG;
+
+ if( iOperation && iState == ESending )
+ {
+ return iOperation->ProgressL();
+ }
+ return KNullDesC8;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CIpsPlgSmtpOperation::StartSendL( TMsvId aMessageId )
+ {
+ FUNC_LOG;
+
+ TMsvId service;
+ TMsvEntry entry;
+ User::LeaveIfError(
+ iMsvSession.GetEntry( aMessageId, service, entry ) );
+ if ( entry.Id() == KMsvNullIndexEntryIdValue )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ iSmtpService = entry.iServiceId;
+ ConstructSmtpMtmL();
+ iSmtpMtm->SwitchCurrentEntryL( entry.Id() );
+
+ if ( entry.Parent() == KMsvGlobalOutBoxIndexEntryIdValue )
+ {
+ iSelection->Reset();
+ // smtp service id have to be first in array
+ // here must be iSmtpService
+ iSelection->AppendL( iSmtpService );
+ // then message id
+ iSelection->AppendL( entry.Id() );
+ CallSendL( );
+ }
+ else
+ {
+ // 1. perform validity checks for recipient addresses
+ // 2. move message to outbox
+ // Perform validity checks for recipient addresses
+ // before moving
+ CMsvEntry* msgCEntry = CMsvEntry::NewL(
+ iMsvSession, aMessageId, TMsvSelectionOrdering() );
+ CleanupStack::PushL( msgCEntry );
+ ValidateRecipientsL( *msgCEntry );
+ CleanupStack::PopAndDestroy( msgCEntry );
+ msgCEntry = NULL;
+
+ iSelection->Reset();
+ // get message entry
+ msgCEntry = CMsvEntry::NewL(
+ iMsvSession, entry.Parent(), TMsvSelectionOrdering() );
+ CleanupStack::PushL( msgCEntry );
+
+ // do the move
+ iSelection->AppendL( entry.Id());
+ iStatus = KRequestPending;
+ delete iOperation;
+ iOperation = NULL;
+ iOperation = msgCEntry->MoveL(
+ *iSelection, KMsvGlobalOutBoxIndexEntryIdValue, iStatus );
+ SetActive();
+ CleanupStack::PopAndDestroy( msgCEntry );
+ iState = EMovingOutbox;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CIpsPlgSmtpOperation::EmptyOutboxFromPendingMessagesL(
+ TMsvId aMailboxId )
+ {
+ FUNC_LOG;
+ TMsvId service;
+ TMsvEntry entry;
+ User::LeaveIfError(
+ iMsvSession.GetEntry( aMailboxId, service, entry ) );
+
+ iSmtpService = entry.iRelatedId;
+
+ TInt retValue = KErrNone;
+
+ iSelection->Reset();
+ ConstructSmtpMtmL();
+ iSmtpMtm->SwitchCurrentEntryL( KMsvGlobalOutBoxIndexEntryIdValue );
+
+ // in sending first entry in selection array have to be service id
+ iSelection->AppendL(iSmtpService);
+ //index to first message entry of selection array
+
+ CMsvEntrySelection* childs = GetOutboxChildrensL( );
+ CleanupStack::PushL( childs );
+ for ( TInt i = 0; i < childs->Count(); i++ )
+ {
+ iMsvSession.GetEntry( childs->At(i), service, entry );
+ TUint sendState = entry.SendingState();
+
+ if ( iSmtpService == entry.iServiceId &&
+ ( sendState != KMsvSendStateUnknown
+ || sendState != KMsvSendStateUponRequest
+ || sendState != KMsvSendStateSent ) )
+ {
+ // chage suspended flag to waiting
+ // is it safe to change flag from suspended to waiting?
+ if ( sendState == KMsvSendStateSuspended )
+ {
+ CMsvEntry* cEntry = CMsvEntry::NewL(
+ iMsvSession, entry.Id(), TMsvSelectionOrdering() );
+ CleanupStack::PushL( cEntry );
+ CIpsPlgOperationWait* wait = CIpsPlgOperationWait::NewLC( );
+ entry.SetSendingState( KMsvSendStateWaiting );
+ cEntry->ChangeL( entry, wait->iStatus );
+ wait->Start();
+ CleanupStack::PopAndDestroy(2, cEntry ); // wait, cEntry
+ }
+ // add to send list
+ iSelection->AppendL( entry.Id() );
+ ++retValue;
+ }
+ }
+ CleanupStack::PopAndDestroy( childs );
+ if (retValue > 0)
+ {
+ CallSendL();
+ }
+ return retValue;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CMsvEntrySelection* CIpsPlgSmtpOperation::GetOutboxChildrensL( )
+ {
+ FUNC_LOG;
+ ConstructSmtpMtmL();
+ iSmtpMtm->SwitchCurrentEntryL( KMsvGlobalOutBoxIndexEntryIdValue );
+ return iSmtpMtm->Entry().ChildrenL();
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CIpsPlgSmtpOperation::CallSendL( )
+ {
+ FUNC_LOG;
+ TBuf8<1> params;
+
+ iOperation = iSmtpMtm->InvokeAsyncFunctionL(
+ KSMTPMTMSendOnNextConnection, *iSelection, params, iStatus);
+ SetActive();
+ iState = ESending;
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CIpsPlgSmtpOperation::ConstructSmtpMtmL()
+ {
+ FUNC_LOG;
+ if ( !iMtmRegistry )
+ {
+ iMtmRegistry = CClientMtmRegistry::NewL( iMsvSession );
+ }
+ if ( !iSmtpMtm )
+ {
+ iSmtpMtm = static_cast<CSmtpClientMtm*>(
+ iMtmRegistry->NewMtmL( KSenduiMtmSmtpUid ) );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CIpsPlgSmtpOperation::ValidateRecipientsL( CMsvEntry& aEntry )
+ {
+ FUNC_LOG;
+
+ // get store object
+ CMsvStore* store = aEntry.ReadStoreL();
+ CleanupStack::PushL( store ); // << store
+
+ // create symbian email header object
+ CImHeader* header = CImHeader::NewLC(); // << header
+ header->RestoreL( *store );
+
+ // checking separate recipient fields
+ ValidateAddressArrayL( header->ToRecipients() );
+ ValidateAddressArrayL( header->CcRecipients() );
+ ValidateAddressArrayL( header->BccRecipients() );
+
+ // Cleanup
+ CleanupStack::PopAndDestroy( header );
+ CleanupStack::PopAndDestroy( store );
+ }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CIpsPlgSmtpOperation::ValidateAddressArrayL( const CDesCArray& aRecipients )
+ {
+ FUNC_LOG;
+
+ TInt count( aRecipients.Count() );
+ for ( TInt i(0); i < count; i++ )
+ {
+ TPtrC fullName( aRecipients[i] );
+
+ // Need to locate angle brackets from end of the data, if there
+ // is display name with special characters
+ TInt start( fullName.LocateReverse( KIpsSmtpOperationCharLessThan ) );
+ TInt end( fullName.LocateReverse( KIpsSmtpOperationCharMoreThan ) );
+ if ( KErrNotFound != start && KErrNotFound != end )
+ {
+ start += 1;
+ fullName.Set( aRecipients[i].Mid( start, ( end - start ) ) );
+ }
+ // make basic sanity checks for email address
+ if( !IpsSetUtils::IsValidEmailAddressL( fullName ) )
+ {
+ User::Leave( KErrBadName );
+ }
+ }
+ }
+
+// End of File
+