email/pop3andsmtpmtm/autosend/src/autosend.cpp
changeset 0 72b543305e3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/email/pop3andsmtpmtm/autosend/src/autosend.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,287 @@
+// Copyright (c) 2001-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 <e32base.h>
+#include <e32std.h>
+#include <msventry.h>
+#include <msvapi.h>
+#include <msvids.h>
+#include <mtclreg.h>
+#include <autosend.h>
+#include <smtcmtm.h>
+#include <bacline.h>
+
+const TInt KProgressPollingRate = 10000000; // 10 seconds
+
+//uncomment the following line if you do not want logging.
+//#define NO_AUTOSEND_LOGGING
+
+#ifdef AUTOSEND_LOGGING
+_LIT(KAutoSendLogDir, "email");
+_LIT(KAutoSendLogFile, "autosend.txt");
+#endif
+
+TInt Execute(const TMsvId aDestinationId)
+	{
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+
+	TRAPD(leaveValue, DoExecuteL(aDestinationId));
+
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return leaveValue;
+	}
+
+#include <u32std.h>
+
+void TDummyMsvSessionObserver::HandleSessionEventL(TMsvSessionEvent /*aEvent*/, TAny */*aArg1*/, TAny */*aArg2*/, TAny */*aArg3*/)
+	{
+	}
+
+void CheckProcessCreatorL(void)
+	{
+	RProcess me;
+	TSecurityInfo inf(me);
+	inf.SetToCreatorInfo();
+	TDummyMsvSessionObserver dummyObserver;
+	
+	CMsvSession *sess = CMsvSession::OpenSyncL(dummyObserver);
+	CleanupStack::PushL(sess);
+	
+	// inf.iCaps should be the TCapabilitySet of the creator process.
+	TCapabilitySet mtmCapSet;
+	sess->GetMtmRequiredCapabilitiesL(KUidMsgTypeSMTP, mtmCapSet);
+
+	if(!inf.iCaps.HasCapabilities(mtmCapSet))
+		{
+		// work out the missing capabilities for the diagnostics
+		mtmCapSet.Remove(inf.iCaps);
+		User::LeaveIfError(PlatSec::CreatorCapabilityCheckFail(mtmCapSet,__PLATSEC_DIAGNOSTIC_STRING("Autorun.exe: Creator Caps do not match those of the SMTP Server MTM")));
+		}
+		
+	CleanupStack::PopAndDestroy(sess);
+	}
+
+void DoExecuteL(const TMsvId aDestinationId)
+	{
+	CActiveScheduler* activeSch = new (ELeave) CActiveScheduler();
+	CleanupStack::PushL(activeSch);
+
+	CActiveScheduler::Install(activeSch);
+
+	CheckProcessCreatorL();
+
+	CImAutoSend::StartLC(aDestinationId);
+
+	CleanupStack::PopAndDestroy(2); //activeSch, CAutoSend
+	}
+
+/*
+//
+	CImAutoSend Implementation
+//
+*/
+
+/*
+	CImAutoSend Constructor
+*/
+CImAutoSend::CImAutoSend(const TMsvId aDestinationId)
+	: CActive(KDefaultPriority), iDestinationId(aDestinationId)
+	{
+	//Add this to the Active Scheduler.
+	//This is a requirement if a class is derived from CActive
+	CActiveScheduler::Add(this);
+	}
+
+/*
+	CImAutoSend Destructor
+*/
+CImAutoSend::~CImAutoSend()
+	{
+	Cancel();
+	delete iTimer;
+	delete iOperation;
+	delete iSession;
+	}
+
+/*
+	StartLC
+
+	1. Constructs CImAutoSend
+	2. Attempts to send the messages
+*/
+CImAutoSend* CImAutoSend::StartLC(const TMsvId aDestinationId)
+	{
+	CImAutoSend* self = new (ELeave) CImAutoSend(aDestinationId);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+void CImAutoSend::ConstructL()
+	{
+#ifdef AUTOSEND_LOGGING
+	FLog(_L("Autosend using service %d"), iDestinationId);
+#endif
+	iSession = CMsvSession::OpenSyncL(*this);
+
+	CallMtmL();
+	iActiveSchedulerWait.Start();
+	}
+
+/*
+	CallMtmL
+
+	Attempts to send the messages in the Outbox.  The selection of messages is determined
+	on the Server side dependant on which IAP the user is connected to.
+*/
+void CImAutoSend::CallMtmL()
+	{
+#ifdef AUTOSEND_LOGGING
+	FLog(_L("\tCallMtmL"));
+#endif
+
+	TBuf8<1> buf;
+	CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection();
+	CleanupStack::PushL(selection);
+	selection->AppendL(iDestinationId);
+	iOperation = iSession->TransferCommandL(*selection, KSMTPMTMSendOnNextConnection, buf, iStatus);
+
+	CleanupStack::PopAndDestroy(selection);
+
+	delete iTimer;
+	iTimer = NULL;
+
+	iTimer = CAutoSendProgressTimer::NewL(*iOperation, KProgressPollingRate);
+	iTimer->Start();
+	iStatus=KRequestPending;
+	SetActive();
+	}
+
+void CImAutoSend::DoCancel()
+	{
+#ifdef AUTOSEND_LOGGING
+	FLog(_L("\tDoCancel"));
+#endif
+	iActiveSchedulerWait.AsyncStop();
+	}
+
+/*
+	RunL
+
+	Called by the Active Scheduler with iStatus is complete,
+	i.e when the selection of messages have been sent to the appropriate Mtm.
+*/
+void CImAutoSend::RunL()
+	{
+#ifdef AUTOSEND_LOGGING
+	FLog(_L("\tRunL iStatus=%d"), iStatus.Int());
+#endif
+	iActiveSchedulerWait.AsyncStop();
+	}
+
+#ifdef AUTOSEND_LOGGING
+void CImAutoSend::FLog(TRefByValue<const TDesC> aFormat, ...)
+	{
+	VA_LIST list;
+	VA_START(list, aFormat);
+	RFileLogger::WriteFormat(KAutoSendLogDir, KAutoSendLogFile, EFileLoggingModeAppend,
+		aFormat, list);
+	}
+
+void CImAutoSend::FLog(const TDesC& buf)
+	{
+	RFileLogger::Write(KAutoSendLogDir, KAutoSendLogFile, EFileLoggingModeAppend,buf);
+	}
+#endif
+
+
+/*
+//
+	CAutoSendProgressTimer Implementation
+//
+*/
+
+CAutoSendProgressTimer* CAutoSendProgressTimer::NewL(CMsvOperation& aOperation, const TTimeIntervalMicroSeconds32& aPollInterval)
+	{
+	CAutoSendProgressTimer* self = new (ELeave) CAutoSendProgressTimer(aOperation, aPollInterval);
+	CleanupStack::PushL(self);
+
+	self->ConstructL();
+
+	CleanupStack::Pop();
+
+	return self;
+	}
+
+CAutoSendProgressTimer::CAutoSendProgressTimer(CMsvOperation& aOperation, const TTimeIntervalMicroSeconds32& aPollInterval)
+: CTimer(EPriorityHigh), iOperation(aOperation), iPollInterval(aPollInterval)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CAutoSendProgressTimer::~CAutoSendProgressTimer()
+	{
+	Cancel();
+	}
+
+void CAutoSendProgressTimer::Start()
+	{
+	if (iPollInterval.Int() > 0)
+		{
+		After(iPollInterval);
+		}
+	}
+
+void CAutoSendProgressTimer::RunL()
+	{
+	if (iPollInterval.Int() > 0)
+		{
+		// Ignore progress errors (we don't care)
+		TRAPD(error, iOperation.ProgressL());
+
+#ifdef AUTOSEND_LOGGING
+		RFileLogger::WriteFormat(KAutoSendLogDir, KAutoSendLogFile, EFileLoggingModeAppend,
+			_L("\tPollProgress error=%d"), error);
+#endif
+
+		After(iPollInterval);
+		}
+	}
+
+
+/*
+//
+	The function that actually does the stuff
+//
+*/
+
+GLDEF_C TInt E32Main()
+	{
+	TMsvId serviceId = KMsvNullIndexEntryId;
+
+	TBuf<0x100> cmd;
+		User::CommandLine(cmd);
+	
+	TLex lex(cmd);
+	lex.Val(serviceId);
+
+	if (serviceId)
+		return Execute(serviceId);
+
+	return KErrArgument;
+	}
+