email/pop3andsmtpmtm/smtpservermtm/src/IMSMSEND.CPP
changeset 0 72b543305e3a
child 76 60a8a215b0ec
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implementation file for class CImStmpSession -- representing
       
    15 // a connection to a remote SMTP server.
       
    16 // 
       
    17 //
       
    18 
       
    19 #include <miutpars.h>           // TImMessageField
       
    20 #include <imcvsend.h>			// CImSendConvert
       
    21 #include <logwrap.h>
       
    22 #include <logwraplimits.h>
       
    23 
       
    24 #include "SMTS.H"
       
    25 #include "IMSM.H"				// CImSmtpSession
       
    26 #include "IMSMSEND.H"			// CImSmtpFile
       
    27 #include "SMTSUTIL.H"			// forward declarations for utility fns
       
    28 #include <imutcon.h>
       
    29 #include "mobilitytestmtmapi.h"
       
    30 
       
    31 const TInt KSmtpAuthCodeSuccessful=235;
       
    32 const TInt KSmtpAuthCodeFailed=535;
       
    33 const TInt KSmtpUnableToAuthAtPresent=435;
       
    34 const TInt KSmtpAuthCodeReadyResponse=334;
       
    35 const TInt KSmtpBadParameter=501;
       
    36 
       
    37 /**
       
    38 Factory constructor
       
    39 
       
    40 @param aServerEntry Server entry
       
    41 @param aSettings SMTP settings
       
    42 @param aServ Socket server
       
    43 @param aConnect Network connection
       
    44 @return Constructed class
       
    45 */
       
    46 CImSmtpSession* CImSmtpSession::NewL(CMsvServerEntry& aServerEntry, CSmtpSettings& aSettings, RSocketServ& aServ, CImConnect& aConnect, TMsvId aServiceId)
       
    47 	{
       
    48 	CImSmtpSession* self = new (ELeave) CImSmtpSession(aServerEntry, aSettings, aServiceId);
       
    49 	CleanupStack::PushL(self);
       
    50 	self->ConstructL(aServ, aConnect);
       
    51 	CleanupStack::Pop(self);
       
    52 	return self;
       
    53 	}
       
    54 
       
    55 /**
       
    56 Connect the session to the server
       
    57 
       
    58 @param aClientStatus Client status to be completed
       
    59 */
       
    60 void CImSmtpSession::ConnectL(TRequestStatus& aClientStatus)
       
    61 	{
       
    62 	__ASSERT_DEBUG(!iSocketIsConnected, gPanic(EImsmSocketAlreadyConnected));
       
    63 
       
    64 	if (!iSocketIsConnected)
       
    65 		{
       
    66 		if(iSettings.SecureSockets())
       
    67 			iThisSession = ESecureSession;		 // if the user has chosen to use TLS then we have to use ESMTP+TLS
       
    68 		else if(iSettings.SMTPAuth())
       
    69 			iThisSession = EEnhancedSmtpSession; // if the user has chosen to use AUTH, when we have to use ESMTP
       
    70 		else
       
    71 			iThisSession = ESmtpSession;		 // use SMTP session for now
       
    72 
       
    73 		iCompleted = KErrNone;
       
    74 		iState = EConnectingToSmtp;		// Initialise to 1st state of state machine
       
    75 		DoStateL();						// Here we go...
       
    76 		Queue(aClientStatus);		
       
    77 		}
       
    78 	else
       
    79 		{
       
    80 		// Nothing to do so just complete the caller
       
    81 		RequestComplete(aClientStatus, KErrNone);
       
    82 		}
       
    83 	}
       
    84 
       
    85 /**
       
    86 Send all the emails to the server
       
    87 
       
    88 @param aSendFiles Files to send
       
    89 @param aClientStatus Client status to be completed
       
    90 */
       
    91 void CImSmtpSession::SendFilesL(CMsgImOutboxSend& aSendFiles, TRequestStatus& aClientStatus)
       
    92 	{
       
    93 	__ASSERT_DEBUG(iSocketIsConnected, gPanic(EImsmSocketNotConnected1));
       
    94 	
       
    95 	TInt error = aSendFiles.NextFile();
       
    96 	if (iSocketIsConnected &&  error == KErrNone)
       
    97 		{
       
    98 		iSendFiles = &aSendFiles;
       
    99 		iState = ESendingImail;
       
   100 		DoStateL();
       
   101 		Queue(aClientStatus);
       
   102 		}
       
   103 	else if(error == KErrNotFound)
       
   104 		{
       
   105 		// Nothing to do so just complete the caller
       
   106 		RequestComplete(aClientStatus, KErrNotFound);
       
   107 		}
       
   108 	else
       
   109 		{
       
   110 		// Nothing to do so just complete the caller
       
   111 		RequestComplete(aClientStatus, KErrNone);
       
   112 		}
       
   113 	}
       
   114 
       
   115 /**
       
   116 Quit from the server
       
   117 
       
   118 @param aClientStatus Client status to be completed
       
   119 */
       
   120 void CImSmtpSession::QuitL(TRequestStatus& aClientStatus)
       
   121 	{
       
   122 	__ASSERT_DEBUG(iSocketIsConnected, gPanic(EImsmSocketNotConnected2));
       
   123 	
       
   124 	if (iSocketIsConnected)
       
   125 		{
       
   126 		iState = EClosingSmtp;
       
   127 		DoStateL();
       
   128 		Queue(aClientStatus);
       
   129 		}
       
   130 	else
       
   131 		{
       
   132 		// Nothing to do so just complete the caller
       
   133 		RequestComplete(aClientStatus, KErrNone);
       
   134 		}
       
   135 	}
       
   136 
       
   137 /**
       
   138 Constructor
       
   139 
       
   140 @param aServerEntry Server entry
       
   141 @param aSettings SMTP settings
       
   142 */
       
   143 CImSmtpSession::CImSmtpSession(CMsvServerEntry& aServerEntry, CSmtpSettings& aSettings, TMsvId aServiceId)
       
   144 			  :	CMsgActive(KImSmtpSessionPriority),
       
   145 			    iServerEntry(aServerEntry),
       
   146 				iSettings(aSettings),
       
   147 				iServiceId(aServiceId),
       
   148 				iCurrentAuthProfile(CSmtpAuthMechanismHelper::EUndefined) // always start with undefined
       
   149 	{
       
   150 	__DECLARE_NAME(_S("CImSmtpSession"));
       
   151 	}
       
   152 
       
   153 /**
       
   154 Second phase constructor
       
   155 
       
   156 @param aServ Socket server
       
   157 @param aConnect Network connection
       
   158 */
       
   159 void CImSmtpSession::ConstructL(RSocketServ& aServ, CImConnect& aConnect)
       
   160 	{
       
   161 	iSocket = CImTextServerSession::NewL(aServ, aConnect);
       
   162 	//if log fails, ignore the error and continue.
       
   163 	TRAP_IGNORE(iLogMessage = CImLogMessage::NewL(iServerEntry.FileSession()));
       
   164 	CActiveScheduler::Add(this);					// Add SmtpSession to scheduler's queue
       
   165 	}
       
   166 
       
   167 /**
       
   168 Destructor
       
   169 */
       
   170 CImSmtpSession::~CImSmtpSession()
       
   171 	{
       
   172 	Cancel();
       
   173 	if (iSocketIsConnected)
       
   174 		{
       
   175 		iSocket->Disconnect();
       
   176 		}
       
   177 	delete iSmtpFile;			// should be dead already
       
   178 	delete iSocket;
       
   179 	delete iSmtpAuthHelper;
       
   180 	delete iLogMessage;
       
   181 	}
       
   182 
       
   183 //
       
   184 //  CreateFormattedAddressL()
       
   185 //
       
   186 //  Creates a new HDesC* containing the concateneatd alias and address strings
       
   187 //
       
   188 HBufC* CImSmtpSession::CreateFormattedAddressLC(const TDesC& aString, const TDesC& aAlias)
       
   189     {
       
   190     TImMessageField msgField;
       
   191 
       
   192     //  Make a buffer..
       
   193     TInt strLen     = aString.Length();
       
   194     TInt aliasLen   = aAlias.Length();
       
   195 
       
   196     HBufC* outString = HBufC::NewLC(strLen+aliasLen+5);
       
   197     HBufC* buffer = HBufC::NewL(strLen);
       
   198 
       
   199     *buffer = msgField.GetValidInternetEmailAddressFromString(aString);
       
   200 
       
   201 	if (aliasLen)
       
   202         {
       
   203 		outString->Des().Format(KSmtpEmailAddressAndAliasFmtStr,&aAlias,buffer);
       
   204         }
       
   205     else
       
   206         {
       
   207         *outString = *buffer;	        // just copy email address; as there's no alias to be added
       
   208         }
       
   209 
       
   210 	delete buffer;
       
   211     return outString;
       
   212     }
       
   213 
       
   214 
       
   215 TImImailFileProgress CImSmtpSession::FileProgress()
       
   216 	{
       
   217 	// Return info about how much of message has been sent so far
       
   218 	TImImailFileProgress progress;
       
   219 
       
   220 	if (iSmtpFile && (iState==ESendingImail))
       
   221 		{
       
   222 		// get progress from CImSmtpFile object as it is doing the work at the moment
       
   223         iSmtpFile->GetProgress(progress);
       
   224 
       
   225 		// If there is more than 1 message being sent(ie when sending to BCC's), then
       
   226 		// update the Progress to take account of the Total Num of Messages sent
       
   227 		if (iNumMsgsToSend > 1)
       
   228 			{
       
   229 			// Calc the Total number of Bytes to send
       
   230 			TInt fileByteSize = iSmtpFile->BytesToSend();
       
   231 			TInt bytesSentBefore = (iNumMsgsSent-1)*fileByteSize;  // iNumMsgsSent-1, as this msg is not yet complete
       
   232 			TInt totalBytesSent = bytesSentBefore + progress.iBytesSent;
       
   233 
       
   234 			// Update the Progress
       
   235 			progress.iBytesToSend = iTotalBytesToSend;
       
   236 			progress.iBytesSent = totalBytesSent;
       
   237 			}
       
   238 		}
       
   239 	else
       
   240 		{
       
   241 		progress.iSessionState = EClosingSmtp;
       
   242 		progress.iBytesSent = 0;
       
   243 		progress.iBytesToSend = 0;
       
   244 		}
       
   245 	return progress;
       
   246 	}
       
   247 
       
   248 
       
   249 void CImSmtpSession::SendFileL()
       
   250 	{
       
   251 	// Start the 'file mailer' object
       
   252 	__ASSERT_DEBUG(!iSmtpFile,gPanic(EImsmSmtpFileObjectAlreadyExists));
       
   253 	// log the info of the message to be sent
       
   254 	if (iLogMessage)
       
   255 		iLogMessage->Reset();
       
   256 	//  Update the header info for this message..
       
   257 	CImHeader* header = CImHeader::NewLC();
       
   258 	CMsvStore* store = iServerEntry.EditStoreL();
       
   259 	CleanupStack::PushL(store);
       
   260 	header->RestoreL(*store);
       
   261 
       
   262 	TBool isBccRcpt = EFalse;
       
   263 	CDesCArray* rcptArray = NULL;
       
   264 	TBool sendBccNow = iToRcptHeaderUpdated;
       
   265 
       
   266 	if(!iToRcptHeaderUpdated)
       
   267 		{
       
   268 		//  Set the new info...
       
   269 		//set from address
       
   270 		HBufC* formatedAddress = CreateFormattedAddressLC(iSettings.EmailAddress(), iSettings.EmailAlias());//Format the address fields
       
   271 		header->SetFromL(*formatedAddress);
       
   272 		CleanupStack::PopAndDestroy(formatedAddress);
       
   273 		formatedAddress = NULL;
       
   274 
       
   275 		// set ReceiptAddress if one exists in the settings
       
   276 		if( header->ReceiptAddress().Length() == 0 && iSettings.ReceiptAddress().Length() > 0 )
       
   277 			{
       
   278 			formatedAddress=CreateFormattedAddressLC(iSettings.ReceiptAddress(),iSettings.EmailAlias());//Format the address fields
       
   279 			header->SetReceiptAddressL(*formatedAddress);
       
   280 			CleanupStack::PopAndDestroy(formatedAddress);
       
   281 			formatedAddress = NULL;
       
   282 			}
       
   283 
       
   284 		if(header->ToRecipients().Count()==0 && header->CcRecipients().Count()==0)
       
   285 			{
       
   286 			sendBccNow=ETrue;
       
   287 			}
       
   288 
       
   289 		// ReplyToAddress
       
   290 		if ((header->ReplyTo().Length() == 0 || header->ReplyTo() == iSettings.ReplyToAddress()) &&
       
   291 		    (iSettings.ReplyToAddress().Length() > 0))
       
   292 			{
       
   293 			formatedAddress= CreateFormattedAddressLC(iSettings.ReplyToAddress(),iSettings.EmailAlias());//Format the address fields
       
   294 			header->SetReplyToL(*formatedAddress);
       
   295 			CleanupStack::PopAndDestroy(formatedAddress);
       
   296 			formatedAddress = NULL;
       
   297 			}
       
   298 		
       
   299 		//make a copy of 'Bcc' recipients then remove from Msg header
       
   300 		rcptArray= &(header->BccRecipients());
       
   301 		if (iSettings.SendCopyToSelf()==ESendCopyAsBccRecipient)
       
   302 			{
       
   303 			if ( header->ReceiptAddress().Length() )
       
   304 				rcptArray->AppendL(header->ReceiptAddress());
       
   305 			else if ( header->ReplyTo().Length() )
       
   306 				rcptArray->AppendL(header->ReplyTo());
       
   307 			}
       
   308 
       
   309 		if(rcptArray->Count() > 0)
       
   310 			{
       
   311 			iBccRcptFound=ETrue; // 'Bcc' recipients exists
       
   312 			iBccRcptIndex=0;	  //reset the counter
       
   313 			iFinishedWithBccRcpts=EFalse;
       
   314 
       
   315 			iSendFiles->ResetBccRcptArrayL();
       
   316 
       
   317 			TInt numberRcpts = rcptArray->Count();
       
   318 			if(numberRcpts)
       
   319 			{
       
   320 			iSendFiles->BccRcptArray().AppendL((*rcptArray)[0]);
       
   321 			CDesCArray& tempArr = iSendFiles->BccRcptArray();
       
   322 			for(TInt counter=1; counter<numberRcpts; counter++)
       
   323 				{
       
   324 				TInt aPos = 0;
       
   325 				tempArr.Find((*rcptArray)[counter],aPos,ECmpFolded16);			
       
   326 				if(aPos > 0)	
       
   327 				iSendFiles->BccRcptArray().AppendL((*rcptArray)[counter]);
       
   328 				}
       
   329 				}
       
   330 			rcptArray->Reset();
       
   331 			}
       
   332 
       
   333 		iToRcptHeaderUpdated=ETrue;
       
   334 		isBccRcpt=EFalse;
       
   335 		}
       
   336 
       
   337 	// Reset the number of Sent Messages, if all previous messages have been sent
       
   338 	if (iNumMsgsSent >= iNumMsgsToSend)
       
   339 		{
       
   340 		iNumMsgsSent = 0;
       
   341 		}
       
   342 
       
   343 	// Calc the num of messages we're sending. If there is a To or CC,
       
   344 	// recipient then there will be a message sent
       
   345 	if(header->ToRecipients().Count()>0 || header->CcRecipients().Count()>0)
       
   346 		iNumMsgsToSend = 1;
       
   347 	else
       
   348 		iNumMsgsToSend = 0;
       
   349 
       
   350 	// If there are BCC recipients, then we will be sending a message to each
       
   351 	if (iBccRcptFound)
       
   352 		iNumMsgsToSend += iSendFiles->BccRcptArray().Count();
       
   353 
       
   354 	// Make sure there are recipients to send to.
       
   355 	__ASSERT_ALWAYS(iNumMsgsToSend,gPanic(EImsmZeroRecipientsInMessage));
       
   356 
       
   357 	// sending Msg to 'Bcc' recipients so update header
       
   358 	if (sendBccNow && iBccRcptFound)
       
   359 		{
       
   360 		rcptArray= &(header->BccRecipients());
       
   361 		rcptArray->Reset();
       
   362 		header->BccRecipients().AppendL(iSendFiles->BccRcptArray()[iBccRcptIndex]);
       
   363 
       
   364 		++iBccRcptIndex;//for the next recipient
       
   365 		if(iBccRcptIndex < iSendFiles->BccRcptArray().Count())
       
   366 			iFinishedWithBccRcpts=EFalse;
       
   367 		else
       
   368 			iFinishedWithBccRcpts=ETrue;
       
   369 
       
   370 		isBccRcpt=ETrue;
       
   371 		}
       
   372 
       
   373 	header->StoreL(*store);
       
   374 	store->CommitL();
       
   375 	if (iLogMessage)
       
   376 		{
       
   377 		iLogMessage->LogEvent().SetEventType(KLogMailEventTypeUid);
       
   378 		if ((header->ToRecipients().Count()
       
   379  			+ header->CcRecipients().Count()
       
   380  			+ header->BccRecipients().Count()) > 1)
       
   381  		// If there are multiple recipients then set the recipient to 'multiple'
       
   382  			{
       
   383  			TBuf<KLogMaxSharedStringLength> multipleRecipientsString;
       
   384  			iLogMessage->GetString(multipleRecipientsString, R_LOG_REMOTE_MULTIPLE);
       
   385  			iLogMessage->LogEvent().SetRemoteParty(multipleRecipientsString);
       
   386  			}
       
   387  		else
       
   388  		// If there is only one recipient then set the recipient name
       
   389  			{
       
   390 			if (header->ToRecipients().Count())
       
   391 				iLogMessage->LogEvent().SetRemoteParty(header->ToRecipients()[0]);
       
   392 
       
   393 			else if (header->CcRecipients().Count())
       
   394 				iLogMessage->LogEvent().SetRemoteParty(header->CcRecipients()[0]);
       
   395 
       
   396 			else if (header->BccRecipients().Count())
       
   397 				iLogMessage->LogEvent().SetRemoteParty(header->BccRecipients()[0]);
       
   398 			}
       
   399 
       
   400 		iLogMessage->LogEvent().SetSubject(header->Subject());
       
   401 
       
   402 		TBuf<KLogMaxSharedStringLength> outString;
       
   403 		iLogMessage->GetString(outString, R_LOG_DIR_OUT);
       
   404 		iLogMessage->LogEvent().SetDirection(outString);
       
   405 
       
   406 		iLogMessage->LogEvent().SetLink(iServerEntry.Entry().Id());
       
   407 		}
       
   408 
       
   409 	CleanupStack::PopAndDestroy(2, header);
       
   410 
       
   411 	iTimeNow.UniversalTime();	// Set time/date of sending this message file
       
   412 	if (iLogMessage)
       
   413 		iLogMessage->LogEvent().SetTime(iTimeNow);
       
   414 	TRAPD(error,iSmtpFile = CImSmtpFile::NewL(	*iSocket,
       
   415                                                 iServerEntry,
       
   416 												iTimeNow,
       
   417 												iSmtpBuffer,
       
   418 												iSettings,
       
   419 												isBccRcpt)); // Create the file mailing object
       
   420 
       
   421 	if(error == KErrNone)
       
   422 		{
       
   423 		// If this is the first message to send, then calc the total bytes to send
       
   424 		if (iNumMsgsSent == 0)
       
   425 			{
       
   426 			iTotalBytesToSend =  iSmtpFile->TotalMsgSizeL() * iNumMsgsToSend;
       
   427 			}
       
   428 
       
   429 		// Tell the file how many bytes it will be sending.  This is just a
       
   430 		// rough estimate for progress
       
   431 		iSmtpFile->SetBytesToSend(iTotalBytesToSend/iNumMsgsToSend);
       
   432 
       
   433 		// Increment the number of messages sent
       
   434 		++iNumMsgsSent;
       
   435 
       
   436 		iSmtpFile->StartL(iStatus);		// start sending the message
       
   437 		MOBILITY_TEST_MTM_STATE(iServiceId, KMobilityTestMtmStateSmtpSendFile);
       
   438 		}
       
   439 	else
       
   440 		{
       
   441 		iCompleted=error;
       
   442 		RequestComplete(iStatus,0-error);	// Failed to create File object, but don't want to stop session prematurely, so negate error code
       
   443 		}
       
   444 	}
       
   445 
       
   446 void CImSmtpSession::DoCancel()
       
   447 	{
       
   448 	if (iSmtpFile)
       
   449 		{
       
   450 		iSmtpFile->Cancel();	//which calls iSocket->Cancel()
       
   451 		delete iSmtpFile;		// this is expected to be deleted
       
   452 		iSmtpFile=NULL;
       
   453 		}
       
   454 	else if (iSocket)
       
   455 		{
       
   456 		iSocket->Cancel();
       
   457 		}
       
   458 
       
   459 	if (iLogMessage)
       
   460 		{
       
   461 		iLogMessage->Cancel();
       
   462 		}
       
   463 	CMsgActive::DoCancel();		// this MUST be the last statement in this function
       
   464 	}
       
   465 
       
   466 
       
   467 void CImSmtpSession::DoRunL()
       
   468 	{
       
   469 	// Received a KErrNone signal completing last pending asynchronous operation.
       
   470 	// So now decide what to do next...
       
   471 
       
   472 	delete iSmtpFile;			// delete mailing object; (new one created later if need to mail another message)
       
   473 	iSmtpFile=NULL;
       
   474 
       
   475 	if (iStatus.Int() != KErrNone && iState!=ELogDataEvent)
       
   476 		{
       
   477 		iCompleted=iStatus.Int();	// retain any non-zero completion code for future reference when DoComplete() is called
       
   478 		}
       
   479 
       
   480 	iState = NextStateL();
       
   481 		
       
   482 	if (!iOperationComplete)
       
   483 		{
       
   484 		if (iSmtpMultiLineResponse)
       
   485 			{
       
   486 			// Don't change state, just read next line of multi-line
       
   487 			// response from remote SMTP server...
       
   488 			iSmtpLastMultiLineResponse=EFalse;
       
   489 			iSocket->QueueReceiveNextTextLine(iStatus);
       
   490 			SetActive();
       
   491 			}
       
   492 		else
       
   493 			{
       
   494 			DoStateL();		// move to state that was chosen by this function
       
   495 			}
       
   496 		}
       
   497 	else
       
   498 		{
       
   499 		iOperationComplete = EFalse;
       
   500 		}
       
   501 	}
       
   502 
       
   503 
       
   504 
       
   505 void CImSmtpSession::DoComplete(TInt& aStatus)
       
   506 	{
       
   507 	if (aStatus==KErrDisconnected && iState==EClosingSmtp)
       
   508 		{
       
   509 		// ignore sudden disconnect if in closing state
       
   510 		aStatus = KErrNone;
       
   511 		}
       
   512 
       
   513 	if (iCompleted && aStatus==KErrNone)		// last non-zero error in aStatus takes preference over older error stored in iCompleted
       
   514 		{
       
   515 		aStatus = iCompleted;
       
   516 		}
       
   517 
       
   518 	if (aStatus>KErrNone)
       
   519 		{
       
   520 		switch (aStatus)
       
   521 			{
       
   522 			case ESmtpMailboxNoAccess:
       
   523 			case ESmtpMailboxName:
       
   524 			case ESmtpTransactionFailed:
       
   525 				aStatus=KSmtpLoginRefused;
       
   526 				break;
       
   527 			case -KSmtpBadMailFromAddress:
       
   528 			case -KSmtpBadRcptToAddress:
       
   529 			case -KSmtpNoMailFromErr:
       
   530 			case -KSmtpLoginRefused:
       
   531 				// Negate the status because it was negated earlier so that it wouldn't be fatal
       
   532 				aStatus = -aStatus;
       
   533 				break;
       
   534 			default:
       
   535 				aStatus=KSmtpUnknownErr;
       
   536 			}
       
   537 		}
       
   538 	}
       
   539 
       
   540 
       
   541 TInt CImSmtpSession::NextStateL()
       
   542 // this returns the next state according to the current state and the response text received from the server
       
   543 // if the text has not been accepted by the server, then we close our session with it, i.e. return EClosingSmtp.
       
   544 	{
       
   545 	switch(iState)
       
   546 		{
       
   547 		case EConnectingToSmtp:
       
   548 			return EWaitingForReply;
       
   549 
       
   550 		case EWaitingForReply:
       
   551 			return NextStateFromWaitingForReply();
       
   552 
       
   553 		case EAuthorisingSmtp:
       
   554 			return NextStateFromAuthorisingSmtpL();
       
   555 
       
   556 		case ESendingStarttls:
       
   557 			return NextStateFromSendStarttls();
       
   558 
       
   559 		case ESettingSecurity:
       
   560 			return NextStateFromSettingSecurityL();
       
   561 
       
   562 		case ESendingImail:
       
   563 			if (iBccRcptFound && !iFinishedWithBccRcpts)
       
   564 				{
       
   565 				return ESendingImail;
       
   566 				}
       
   567 			else
       
   568 				{
       
   569 				// 'Bcc' recipients are dealt with at this point
       
   570 				iSendFiles->SetLastMessageStatusL(iTimeNow,(TSmtpSessionError)iStatus.Int());
       
   571 				// ... which unlocks the server entry (except the first time)
       
   572 
       
   573 				// now move on to the next Email message
       
   574 				iToRcptHeaderUpdated=EFalse; // for the new msg
       
   575 				iBccRcptFound=EFalse;
       
   576 				iFinishedWithBccRcpts=ETrue;
       
   577 				return ELogDataEvent;
       
   578 				}
       
   579 
       
   580 		case ELogDataEvent:
       
   581 			return NextStateFromNextFile();
       
   582 
       
   583 		case EClosingSmtp:
       
   584 			{
       
   585 			iOperationComplete = ETrue;
       
   586 			return iState;
       
   587 			}
       
   588 
       
   589 		case EAuthInProgress:
       
   590 			// for SMTP auth, call specific function, to stop cluttering up this one
       
   591 			return NextStateFromAuthInProgressL();
       
   592 
       
   593 		case EResetSmtp:
       
   594 			return NextStateFromResetSmtp();
       
   595 
       
   596 		default:
       
   597 			return iState;
       
   598 		}
       
   599 	}
       
   600 
       
   601 TInt CImSmtpSession::NextStateFromWaitingForReply()
       
   602 	{
       
   603 	if (CommandAccepted())
       
   604 		{
       
   605 		if (!iEsmtpSpokenHere)
       
   606 			{
       
   607 			iEsmtpSpokenHere = (iSmtpBuffer.Match(KEsmtpMatchString) != KErrNotFound);
       
   608 			if (iEsmtpSpokenHere && iThisSession == ESmtpSession)
       
   609 				iThisSession = EEnhancedSmtpSession;
       
   610 			}
       
   611 
       
   612 		if (iSmtpMultiLineResponse)
       
   613 			{
       
   614 			// If this is not last reply of a mullti-line response... request next
       
   615 			// line and don't change state
       
   616 			return EWaitingForReply;
       
   617 			}
       
   618 		return EAuthorisingSmtp;
       
   619 		}
       
   620 	else
       
   621 		{
       
   622 		// SMTP server didn't return "220" to "HELO" command, so quit session
       
   623 		// without sending any Emails.
       
   624 		return  EClosingSmtp;
       
   625 		}
       
   626 	}
       
   627 
       
   628 TInt CImSmtpSession::NextStateFromAuthorisingSmtpL()
       
   629 	{
       
   630 	if (CommandAccepted())
       
   631 		{
       
   632 		UpdateAuthorisingInfo();
       
   633 
       
   634 		if (iSmtpMultiLineResponse)
       
   635 			{
       
   636 			// If this is not last reply of a mullti-line response... request next
       
   637 			// line and don't change state.
       
   638 			return EAuthorisingSmtp;
       
   639 			}
       
   640 
       
   641 		if (iThisSession==ESecureSession)
       
   642 			{
       
   643 			if(iStartTlsAcceptedHere)
       
   644 				{
       
   645 				return ESendingStarttls;
       
   646 				}
       
   647 			else
       
   648 				{
       
   649 				// The SMTP server doesn't support TLS.
       
   650 				// Save the error and close down the session.
       
   651 				iCompleted = KErrSmtpTLSNegotiateFailed;
       
   652 				return EClosingSmtp;
       
   653 				}
       
   654 			}
       
   655 		else if (iThisSession==EEnhancedSmtpSession)
       
   656 			{
       
   657 			if (iSettings.SMTPAuth() && SelectNextSMTPAuthProfileL())
       
   658 				{
       
   659 				// if possible, perform SMTP AUTH
       
   660 				return EAuthInProgress;
       
   661 				}
       
   662 			
       
   663 			iOperationComplete = ETrue;
       
   664 			return iState;
       
   665 			}
       
   666 		else
       
   667 			{
       
   668 			__ASSERT_DEBUG(iThisSession==ESmtpSession, gPanic(EImsmBadSessionState));
       
   669 			iOperationComplete = ETrue;
       
   670 			return iState;
       
   671 			}
       
   672 		}
       
   673 	else
       
   674 		{
       
   675 		// EHLO or HELO rejected by server
       
   676 		if( iSettings.SecureSockets() )
       
   677 			{
       
   678 			// Cannot continue if we're trying for secure?
       
   679 			iCompleted = KErrSmtpTLSNegotiateFailed;
       
   680 			return EClosingSmtp;
       
   681 			}
       
   682 		else if((iLastSmtpCode == KSmtpBadParameter) && (iRetryAuthWithHostname==EFalse))
       
   683 			{
       
   684 			// The server did not like the supplied IP parameter, reset and retry with a named
       
   685 			// string as paramter using the same EHLO or HELO command if it hasn't already been
       
   686 			// attempted
       
   687 			iRetryAuthWithHostname = ETrue;
       
   688 			iCompleted = KErrNone;
       
   689 			return EResetSmtp;
       
   690 			}
       
   691 		else if(iThisSession==EEnhancedSmtpSession)
       
   692 			{
       
   693 			// EHLO has failed, reset and retry with HELO
       
   694 			iCompleted = KErrNone;
       
   695 			iRetryAuthWithHostname = EFalse;
       
   696 			iThisSession = ESmtpSession;
       
   697 			return EResetSmtp;
       
   698 			}
       
   699 		else
       
   700 			{
       
   701 			// Every attempt has failed, iCompleted has been set with an appropriate
       
   702 			// error code in the CommandAccepted() call, so simply close the smtp session
       
   703 			return EClosingSmtp;
       
   704 			}
       
   705 		}
       
   706 	}
       
   707 
       
   708 TInt CImSmtpSession::NextStateFromSendStarttls()
       
   709 	{
       
   710 	if (CommandAccepted() && iSmtpMultiLineResponse)
       
   711 		{
       
   712 		// If this is not last reply of a mullti-line response... request next
       
   713 		// line and don't change state
       
   714 		return ESendingStarttls;
       
   715 		}
       
   716 
       
   717 	if(iCompleted)
       
   718 		return EClosingSmtp;
       
   719 	else
       
   720 		return ESettingSecurity;
       
   721 	}
       
   722 
       
   723 TInt CImSmtpSession::NextStateFromSettingSecurityL()
       
   724 	{
       
   725 	if ( CommandAccepted() )
       
   726 		{
       
   727 		UpdateAuthorisingInfo();
       
   728 
       
   729 		if (iSmtpMultiLineResponse)
       
   730 			{
       
   731 			// If this is not last reply of a mullti-line response... request next
       
   732 			// line and don't change state
       
   733 			return ESettingSecurity;
       
   734 			}
       
   735 		}
       
   736 
       
   737 	if(iCompleted)
       
   738 		return EClosingSmtp;
       
   739 
       
   740 	if (iSettings.SMTPAuth() && SelectNextSMTPAuthProfileL())
       
   741 		return EAuthInProgress;
       
   742 	else
       
   743 		{
       
   744 		iOperationComplete = ETrue;
       
   745 		return iState;
       
   746 		}
       
   747 	}
       
   748 
       
   749 TInt CImSmtpSession::NextStateFromAuthInProgressL()
       
   750 	{
       
   751 	TInt smtpCode=ESmtpNoReturnCode;
       
   752 	TBool commandAccepted=GetCurrentTextLine();
       
   753 	if (commandAccepted)
       
   754 		{
       
   755 		// parse out SMTP code from text response
       
   756 		smtpCode=SmtpResponseCode(iSmtpBuffer,iSmtpMultiLineResponse,iSmtpLastMultiLineResponse);
       
   757 		if (iSmtpMultiLineResponse)
       
   758 			{
       
   759 			// Check for response code 535
       
   760 			if (smtpCode == KSmtpAuthCodeFailed)
       
   761 				{
       
   762 				User::Leave(KSmtpLoginRefused);
       
   763 				}
       
   764 			iSmtpAuthHelper->SetLastServerMessageL(iSmtpBuffer,iSmtpMultiLineResponse);
       
   765 			return iState;
       
   766 			}
       
   767 		if(smtpCode==KSmtpAuthCodeSuccessful || smtpCode==KSmtpAuthCodeFailed || smtpCode==KSmtpUnableToAuthAtPresent)
       
   768 			{
       
   769 			//if KSmtpAuthCodeSuccessful then SmtpAuth concluded - move onto next state.
       
   770 			//if KSmtpAuthCodeFailed then SmtpAuth failed, but try to send anyway
       
   771 			iOperationComplete = ETrue;
       
   772 			return iState;
       
   773 			}
       
   774 		else if(smtpCode==ESmtpParamNotImplemented)
       
   775 			{
       
   776 			// this mechanism not recognised by the server.
       
   777 			delete iSmtpAuthHelper;
       
   778 			iSmtpAuthHelper=NULL;
       
   779 			if (SelectNextSMTPAuthProfileL())
       
   780 				{
       
   781 				return EAuthInProgress;
       
   782 				}
       
   783 			else
       
   784 				{
       
   785 				// all AUTH attempts fail, try to send anyway
       
   786 				iOperationComplete = ETrue;
       
   787 				return iState;
       
   788 				}
       
   789 			}
       
   790 		else if(smtpCode==KSmtpAuthCodeReadyResponse)
       
   791 			{
       
   792 			iSmtpAuthHelper->SetLastServerMessageL(iSmtpBuffer,iSmtpMultiLineResponse);
       
   793 			return EAuthInProgress;
       
   794 			}
       
   795 			// if here, we will execute default error case, unless someone adds
       
   796 			// a clause not resulting in a "return" statement
       
   797 		}
       
   798 	// default error case
       
   799 	iCompleted=SmtpSessionError(smtpCode);
       
   800 	return EClosingSmtp;
       
   801 
       
   802 	}
       
   803 
       
   804 TInt CImSmtpSession::NextStateFromResetSmtp()
       
   805 	{
       
   806 	if( CommandAccepted() )
       
   807 		{
       
   808 		if (iSmtpMultiLineResponse)
       
   809 			{
       
   810 			// If this is not last reply of a mullti-line response... request next
       
   811 			// line and don't change state
       
   812 			return EResetSmtp;
       
   813 			}
       
   814 		// The reset was accepted - send the HELO command.
       
   815 		return EAuthorisingSmtp;
       
   816 		}
       
   817 
       
   818 	// The reset was not accepted - didn't get a 2xx response. Might as
       
   819 	// well end the SMTP session.
       
   820 	return EClosingSmtp;
       
   821 	}
       
   822 
       
   823 void CImSmtpSession::DoStateL()
       
   824 // performs the operation required by iState
       
   825     {
       
   826     switch (iState)
       
   827         {
       
   828 		case EConnectingToSmtp:
       
   829 			iEsmtpSpokenHere = EFalse;
       
   830 			i8BitMimeAcceptedHere = EFalse;
       
   831 			iSizeAcceptedHere = EFalse;
       
   832 			iStartTlsAcceptedHere = EFalse;
       
   833 			if(iSettings.SSLWrapper())
       
   834 				{
       
   835 				// Open secure socket on port 465 for SMTP session
       
   836 				iSocket->SSLQueueConnectL(iStatus, iSettings.ServerAddress(), iSettings.Port(), iSettings.IapPrefs(), iSettings.TlsSslDomain());
       
   837 				}
       
   838 			else
       
   839 				{
       
   840 				// Open socket on port 25 for SMTP session
       
   841 				iSocket->QueueConnectL(iStatus, iSettings.ServerAddress(), iSettings.Port(), iSettings.IapPrefs(), iSettings.TlsSslDomain());
       
   842 				}
       
   843 
       
   844 			MOBILITY_TEST_MTM_STATE(iServiceId, KMobilityTestMtmStateSmtpConnectingToSmtp);
       
   845 			break;
       
   846 
       
   847 		case EWaitingForReply:
       
   848 			iSocketIsConnected=ETrue;
       
   849 			iSocket->QueueReceiveNextTextLine(iStatus);
       
   850 			MOBILITY_TEST_MTM_STATE(iServiceId, KMobilityTestMtmStateSmtpWaitingForReply);
       
   851 			break;
       
   852 
       
   853 		case EAuthorisingSmtp:
       
   854 			{
       
   855 			TBuf8<KImskIPAddressLen> address;
       
   856 			GetIpAddress(address);
       
   857 			
       
   858 			if(iRetryAuthWithHostname)
       
   859 				{
       
   860 				// Try sending a text string hostname instead of IP address
       
   861 				_LIT(KDefaultNameString, "localhost");
       
   862 				address.Copy(KDefaultNameString);
       
   863 				}
       
   864 
       
   865 			if (iThisSession!=ESmtpSession)
       
   866 				iSmtpBuffer.Format(KSmtpEhloCommand,&address);
       
   867 			else
       
   868 				iSmtpBuffer.Format(KSmtpHeloCommand,&address);
       
   869 
       
   870 			iSocket->SendQueueReceive(iStatus, iSmtpBuffer);
       
   871 			MOBILITY_TEST_MTM_STATE(iServiceId, KMobilityTestMtmStateSmtpAuthorisingSmtp);
       
   872 			break;
       
   873 			}
       
   874 		case EAuthInProgress:
       
   875 			{
       
   876 			iSmtpAuthHelper->GetNextClientMessageL(iSmtpBuffer);
       
   877 			iSocket->SendQueueReceive(iStatus, iSmtpBuffer);
       
   878 			MOBILITY_TEST_MTM_STATE(iServiceId, KMobilityTestMtmStateSmtpAuthInProgress);
       
   879 			break;
       
   880 			}
       
   881 		case ESendingStarttls:
       
   882 			{
       
   883 			// User has chosen to use Tls - send the STARTTLS cmd.
       
   884 			iSocket->SetSSLTLSResponseL(KSmtpTlsResponse);
       
   885 			iSocket->SendQueueReceive(iStatus, KSmtpStartTlsCommand());
       
   886 			MOBILITY_TEST_MTM_STATE(iServiceId, KMobilityTestMtmStateSmtpSendingStartTls);
       
   887 			break;
       
   888 			}
       
   889 		case ESettingSecurity:
       
   890 			{
       
   891 			// Reset the Auth profiles and flags.
       
   892 			i8BitMimeAcceptedHere	= EFalse;
       
   893 			iSizeAcceptedHere		= EFalse;
       
   894 			iStartTlsAcceptedHere	= EFalse;
       
   895 			iSupportedAuthProfiles	= ENone;
       
   896 			
       
   897 			//  Set Security, send a NOOP
       
   898 			//	and then queues asynch read request for a response
       
   899 			//	from the remote SMTP server.
       
   900 			TBuf8<KImskIPAddressLen> address;
       
   901 			GetIpAddress(address);
       
   902 
       
   903 			iSmtpBuffer.Format(KSmtpEhloCommand, &address);
       
   904 			iSocket->SendQueueReceive(iStatus,iSmtpBuffer);
       
   905 			MOBILITY_TEST_MTM_STATE(iServiceId, KMobilityTestMtmStateSmtpSettingSecurity);
       
   906 			break;
       
   907 			}
       
   908 		case ESendingImail:	// send one Imail message
       
   909  			SendFileL();
       
   910 			break;
       
   911 
       
   912 		case ELogDataEvent:
       
   913 			{
       
   914 			if (iLogMessage)
       
   915 				{
       
   916 				const TInt logError = iServerEntry.Entry().iError;
       
   917 				if (logError == KErrNone)
       
   918 					{
       
   919 					TBuf<KLogMaxStatusLength> status;
       
   920 					if (iLogMessage->GetString(status, R_LOG_DEL_SENT) == KErrNone)
       
   921 						iLogMessage->LogEvent().SetStatus(status);
       
   922 					}
       
   923 				iLogMessage->Start(logError, iStatus);
       
   924 				}
       
   925 			else
       
   926 				{
       
   927 				TRequestStatus* status = &iStatus;
       
   928 				User::RequestComplete(status, KErrNone);
       
   929 				}
       
   930 			break;
       
   931 			}
       
   932 		case EResetSmtp:
       
   933 			iSocket->SendQueueReceive(iStatus, KSmtpResetCommand());
       
   934 			MOBILITY_TEST_MTM_STATE(iServiceId, KMobilityTestMtmStateSmtpResetSmtp);
       
   935 			break;
       
   936 
       
   937 		case EClosingSmtp:	//finished running - end SMTP session
       
   938 			iSocket->SendQueueReceive(iStatus, KSmtpQuitCommand());
       
   939 			MOBILITY_TEST_MTM_STATE(iServiceId, KMobilityTestMtmStateSmtpClosingSmtp);
       
   940 			break;
       
   941 
       
   942 		default:     // Unknown state
       
   943 			gPanic(EImsmBadSessionState);
       
   944 			break;
       
   945         }
       
   946  	SetActive();
       
   947     }
       
   948 
       
   949 
       
   950 TInt CImSmtpSession::SmtpSessionError(const TInt aSmtpErrorCode)
       
   951 	{
       
   952 	// This function is called when no socket/memory error occurred whilst completing
       
   953 	// last state, but the remote SMTP server did not return the expected 3 digit
       
   954 	// completion code.
       
   955 	// Select an appropriate error code determined from the current state of CImSmtpSession.
       
   956 	switch (iState)
       
   957 		{
       
   958 		case EAuthorisingSmtp:
       
   959 			if (aSmtpErrorCode==ESmtpSyntaxError)
       
   960 				return (KSmtpLoginRefused);
       
   961 			break;
       
   962 
       
   963 		case EWaitingForReply:
       
   964 			// assume that ANY failure in this state means I have been refused connection to SMTP server
       
   965 			return (KSmtpLoginRefused);
       
   966 
       
   967 		case ESendingStarttls:
       
   968 		case ESettingSecurity:
       
   969 		case EConnectingToSmtp:
       
   970 		case ESendingImail:
       
   971 		case EResetSmtp:
       
   972 		case EClosingSmtp:
       
   973 			break;
       
   974 
       
   975 		case EAuthInProgress:
       
   976 			if (aSmtpErrorCode==KSmtpAuthCodeFailed || aSmtpErrorCode==KSmtpUnableToAuthAtPresent)
       
   977 				return (KSmtpLoginRefused);
       
   978 			break;
       
   979 
       
   980 		default:     // Unknown state
       
   981 			gPanic(EImsmBadSessionState);
       
   982 			break;
       
   983         }
       
   984 
       
   985 	return IdentifySmtpError(aSmtpErrorCode);
       
   986 	}
       
   987 
       
   988 TBool CImSmtpSession::GetCurrentTextLine()
       
   989 	{
       
   990 	TInt result=iSocket->GetCurrentTextLine(iSmtpBuffer);
       
   991 	__ASSERT_DEBUG(result==ECRLFTerminated,gPanic(EImsmBadSmtpBuffer));
       
   992 
       
   993 	if(result==ECRLFTerminated)
       
   994 		return ETrue;
       
   995 	else
       
   996 		return EFalse;
       
   997 	}
       
   998 
       
   999 void CImSmtpSession::GetIpAddress(TDes8& aAddress)
       
  1000 /** Gets the local IP address from the socket without any trailing scope identifiers
       
  1001 @param aAddress Buffer in which the IP address of the socket will be returned */
       
  1002 	{
       
  1003     aAddress.Copy(iSocket->LocalName());
       
  1004 
       
  1005     // Remove the %nn scope identifier if present Eg. x.x.x.x.x.x%1 becomes x.x.x.x.x.x
       
  1006 	//  This only occurs with IPv6 and was a requirement of multi-homing.
       
  1007 	TInt pos = aAddress.Locate(TChar('%'));
       
  1008 	if (pos>0)
       
  1009 		{
       
  1010 		aAddress.SetLength(pos);
       
  1011 		}
       
  1012 	}
       
  1013 
       
  1014 /*
       
  1015 From knowledge of the last profile used, and the profiles available, select a next profile
       
  1016 to try, create the helper class
       
  1017 otherwise return false
       
  1018 */
       
  1019 TBool CImSmtpSession::SelectNextSMTPAuthProfileL()
       
  1020 	{
       
  1021 	CSmtpAuthMechanismHelper::TSmtpAuthProfileFlag nextProfile=NextSMTPAuthProfile(iCurrentAuthProfile);
       
  1022 	while (!(nextProfile&iSupportedAuthProfiles) && nextProfile!=CSmtpAuthMechanismHelper::ENoProfile)	// while "nextProfile" is not supported
       
  1023 																				// and there are profiles to try
       
  1024 		nextProfile=NextSMTPAuthProfile(nextProfile); // try the next one
       
  1025 	iCurrentAuthProfile=nextProfile;
       
  1026 	if (iCurrentAuthProfile==CSmtpAuthMechanismHelper::ENoProfile)  // run out of profiles to try
       
  1027 		return EFalse;
       
  1028 	else
       
  1029 		{
       
  1030 		__ASSERT_DEBUG(!iSmtpAuthHelper, gPanic(EImsmSmtpAuthHelperAlreadyExists));
       
  1031 		iSmtpAuthHelper=CreateSMTPAuthHelperL(iCurrentAuthProfile,iSettings);
       
  1032 		return ETrue;
       
  1033 		}
       
  1034 	}
       
  1035 
       
  1036 // Get the value of the connecting IAP from CImTextServerSession
       
  1037 //  Returns the value of the currently connecting IAP or a system-wide error code.
       
  1038 TInt CImSmtpSession::GetConnectionIAP()
       
  1039 	{
       
  1040 	TUint32 iap;
       
  1041 	TInt err = iSocket->GetIAPValue(iap);
       
  1042 	if (err == KErrNone)
       
  1043 		{
       
  1044 		return iap;
       
  1045 		}
       
  1046 	else
       
  1047 		{
       
  1048 		return err;
       
  1049 		}
       
  1050 	}
       
  1051 
       
  1052 CSmtpAuthMechanismHelper::TSmtpAuthProfileFlag  CImSmtpSession::NextSMTPAuthProfile(CSmtpAuthMechanismHelper::TSmtpAuthProfileFlag aPreviousProfile)
       
  1053 	{
       
  1054 	// we try the following profiles in this order, CRAM-MD5, LOGIN, PLAIN
       
  1055 	switch(aPreviousProfile)
       
  1056 		{
       
  1057 		case CSmtpAuthMechanismHelper::EUndefined:
       
  1058 			return CSmtpAuthMechanismHelper::ECramMD5;
       
  1059 
       
  1060 		case CSmtpAuthMechanismHelper::ECramMD5:
       
  1061 			return CSmtpAuthMechanismHelper::ELogin;
       
  1062 
       
  1063 		case CSmtpAuthMechanismHelper::ELogin:
       
  1064 			return CSmtpAuthMechanismHelper::EPlain;
       
  1065 
       
  1066 		case CSmtpAuthMechanismHelper::EPlain:
       
  1067 			return CSmtpAuthMechanismHelper::ENoProfile;
       
  1068 
       
  1069 		default:
       
  1070 			gPanic(EImsmBadSmtpAuthProfile1);
       
  1071 		}
       
  1072 	return CSmtpAuthMechanismHelper::ENoProfile;
       
  1073 	}
       
  1074 
       
  1075 TInt CImSmtpSession::NextStateFromNextFile()
       
  1076 	{
       
  1077 	if (iSendFiles->NextFile() == KErrNone)
       
  1078 		{
       
  1079 		return ESendingImail;
       
  1080 		}
       
  1081 	else
       
  1082 		{
       
  1083 		iOperationComplete = ETrue;
       
  1084 		return iState;
       
  1085 		}
       
  1086 	}
       
  1087 
       
  1088 TBool CImSmtpSession::CommandAccepted()
       
  1089 	{
       
  1090 	iLastSmtpCode = ESmtpNoReturnCode;
       
  1091 	TBool commandAccepted = GetCurrentTextLine();
       
  1092 	if (commandAccepted)
       
  1093 		{
       
  1094 		iLastSmtpCode = SmtpResponseCode(iSmtpBuffer, iSmtpMultiLineResponse, iSmtpLastMultiLineResponse);   // parse out SMTP code from text response
       
  1095 
       
  1096 		commandAccepted = LastSmtpCommandAccepted(iLastSmtpCode, 2);      // was response accepted by remote server?
       
  1097 		}
       
  1098 
       
  1099 	if (!commandAccepted)
       
  1100 		{
       
  1101 		// overrride completion code with suitable error number
       
  1102 		iCompleted = SmtpSessionError(iLastSmtpCode);
       
  1103 		}
       
  1104 	return commandAccepted;
       
  1105 	}
       
  1106 
       
  1107 void CImSmtpSession::UpdateAuthorisingInfo()
       
  1108 	{
       
  1109 	if (!i8BitMimeAcceptedHere)
       
  1110 		{
       
  1111 		// i.e. don't do test again if flag is already set
       
  1112 		i8BitMimeAcceptedHere = (iSmtpBuffer.Match(K8BitMimeMatchString) != KErrNotFound);
       
  1113 		}
       
  1114 	if (!iSizeAcceptedHere)
       
  1115 		{
       
  1116 		iSizeAcceptedHere = (iSmtpBuffer.Match(KSizeMatchString) != KErrNotFound);
       
  1117 		// ESMTP: V1.1 parse string to extract max message size from string here...
       
  1118 		}
       
  1119 	if (!iStartTlsAcceptedHere)
       
  1120 		{
       
  1121 		iStartTlsAcceptedHere = (iSmtpBuffer.Match(KStartTlsMatchString) != KErrNotFound);
       
  1122 		}
       
  1123 	//Support added for Domino server.
       
  1124 	if (iSmtpBuffer.Match(KAuthMatchString) != KErrNotFound || 
       
  1125     				iSmtpBuffer.Match(KAuthDominoMatchString) != KErrNotFound) 
       
  1126 		{
       
  1127 		// check for each supported profile
       
  1128 		if (iSmtpBuffer.Match(KAuthPlainMatchString) != KErrNotFound)
       
  1129 			iSupportedAuthProfiles|=CSmtpAuthMechanismHelper::EPlain;
       
  1130 		if (iSmtpBuffer.Match(KAuthLoginMatchString) != KErrNotFound)
       
  1131 			iSupportedAuthProfiles|=CSmtpAuthMechanismHelper::ELogin;
       
  1132 		if (iSmtpBuffer.Match(KAuthCramMD5MatchString) != KErrNotFound)
       
  1133 			iSupportedAuthProfiles|=CSmtpAuthMechanismHelper::ECramMD5;
       
  1134    		// Special case for Domino servers tagging "=" after "AUTH" 
       
  1135    		if (iSmtpBuffer.Match(KAuthDominoPlainMatchString) != KErrNotFound) 
       
  1136        		iSupportedAuthProfiles|=CSmtpAuthMechanismHelper::EPlain; 
       
  1137    		if (iSmtpBuffer.Match(KAuthDominoLoginMatchString) != KErrNotFound) 
       
  1138        		iSupportedAuthProfiles|=CSmtpAuthMechanismHelper::ELogin; 
       
  1139    		if (iSmtpBuffer.Match(KAuthDominoCramMD5MatchString) != KErrNotFound) 
       
  1140    			iSupportedAuthProfiles|=CSmtpAuthMechanismHelper::ECramMD5;
       
  1141 
       
  1142  		}
       
  1143 	}