applayerprotocols/ftpengine/ftpprot/FTPPROT.CPP
changeset 0 b16258d2340f
equal deleted inserted replaced
-1:000000000000 0:b16258d2340f
       
     1 // Copyright (c) 2003-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 // FTP protocol engine
       
    15 // Author:	Philippe Gabriel
       
    16 // Entry point in the DLL
       
    17 // Implements the interface to the FTP protocol
       
    18 // through FTP commands defined as per RFC 959
       
    19 // Drives the DTP and PI channels
       
    20 // 
       
    21 //
       
    22 
       
    23 /**
       
    24  @file FTPPROT.CPP
       
    25  @internalComponent
       
    26 */
       
    27 
       
    28 #include <es_sock.h>
       
    29 #include <c32comm.h>
       
    30 #include "DEBUG.H"
       
    31 #include "PROTOCOL.H"
       
    32 #include "PICHNL.H"
       
    33 #include "ANSPARSE.H"
       
    34 #include "PASVANS.H"
       
    35 #include "DTPCHNL.H"
       
    36 #include "SETERROR.H"
       
    37 
       
    38 //
       
    39 //					Definitions
       
    40 //
       
    41 
       
    42 //
       
    43 //					Minterface Implementation
       
    44 //
       
    45 
       
    46 void CFtpProtocolDerived::PIChannelOperationCompletion(const TPiOperationCompletion aCompletionStatus)
       
    47 /**
       
    48 Define the PIChannel callback notifiers
       
    49 These notifiers are called from PIChannel, but the event source
       
    50 can be quite different:
       
    51 PIChannelOperationCompletion, PIChannelOperationError and PIChannelReset
       
    52 come from an error signaled at the TCP/IP level
       
    53 where PIChannelRcvNotification is called whenever the server sent us a message
       
    54 */
       
    55 	{
       
    56 	switch (aCompletionStatus)
       
    57 		{
       
    58 		case MPIChannelNotifier::EPiConnectComplete:
       
    59 			FTPPROTDEBUG(_DBGFtpprot,_L("PIChannelNotifierClass::PIChannelOperationCompletion(EPiConnectComplete) called\n"));
       
    60 			// Get my IP address for future use
       
    61 			iPiChannel->GetLocalAddress(iLocalAddress);
       
    62 			// Get welcome message from server 
       
    63 			iPiChannel->GetNextAnswer(iServerAnswerBuffer);
       
    64 			UpdateState(EPiChannelConnectComplete);
       
    65 			break;
       
    66 		case MPIChannelNotifier::EPiSendComplete:
       
    67 			FTPPROTDEBUG(_DBGFtpprot,_L("PIChannelNotifierClass::PIChannelOperationCompletion(EPiSendComplete) called\n"));
       
    68 			UpdateState(EPiChannelSendComplete);
       
    69 			break;
       
    70 		default:
       
    71 			FTPPROTDEBUG(_DBGFtpprot,_L("PIChannelNotifierClass::PIChannelOperationCompletion() called\n"));
       
    72 			break;
       
    73 		}
       
    74 	return;
       
    75 	}
       
    76 
       
    77 void CFtpProtocolDerived::PIChannelOperationError(const TPiOperationError aErrorStatus)
       
    78 	{
       
    79 	FTPPROTDEBUG(_DBGFtpprot,_L("PIChannelNotifier::PIChannelOperationError called\n"));
       
    80 		//Close DTP Channel
       
    81 		iDtpChannel->Disconnect();
       
    82 		//Reset state
       
    83 		iState = EIdle;
       
    84 		switch (aErrorStatus)
       
    85 			{
       
    86 			case MPIChannelNotifier::EPiConnectionReset:
       
    87 				//ARGHH this is serious and not recoverable
       
    88 				// Notify upper layer
       
    89 				iNotifier->ErrorNotification(MFtpProtocolNotifier::EOpConnectionReset);
       
    90 				break;
       
    91 			case MPIChannelNotifier::EPiConnectFailed:
       
    92 				// Notify upper layer
       
    93 				iNotifier->ErrorNotification(MFtpProtocolNotifier::EOpConnectionFailed);
       
    94 				break;
       
    95 			default:
       
    96 				break;
       
    97 			}
       
    98 	return;
       
    99 	}
       
   100 
       
   101 void CFtpProtocolDerived::PIChannelRcvNotification(void)
       
   102 	{
       
   103 	// Must call upper level client before issuing another read, otherwise
       
   104 	// I lose my buffer
       
   105 	FTPPROTDEBUG(_DBGFtpprot,_L("PIChannelNotifier::PIChannelRcvNotification called\n"));
       
   106 	// At this point need to parse the incoming buffer to decide if 
       
   107 	// more data is to be fetched
       
   108 	// 2 cases
       
   109 	// - 1 line message
       
   110 	// - multiline message
       
   111 	// Parse the buffer 
       
   112 	// it may contain several answers
       
   113 	for(;;)
       
   114 		{
       
   115 		TBool answer;
       
   116 		// Parse an answer
       
   117 		answer = iFTPServerAnswerParser->Parse(iServerAnswerBuffer);
       
   118 		// If I'm performing a PASV
       
   119 		// Parse an address
       
   120 		if(	iState == EPerformingPasv)		
       
   121 			iFtpPASVAnswerParser->Parse(iServerAnswerBuffer, iRemoteAddress);
       
   122 		//Passes the server text to upper layer
       
   123 		iNotifier->ServerMessage(iServerAnswerBuffer.Left(iFTPServerAnswerParser->NChars()));
       
   124 		// Remove what's already parsed from buffer
       
   125 		iServerAnswerBuffer.Delete(0,iFTPServerAnswerParser->NChars());
       
   126 		if(answer)
       
   127 			{
       
   128 			// if I parsed an answer succesfully, notify upper layer
       
   129 			// of answer code
       
   130 			UpdateState(EFtpCodeReply);
       
   131 			}
       
   132 		//If buffer empty, stop parsing
       
   133 		if(iServerAnswerBuffer.Length()==0)
       
   134 			break;
       
   135 		}
       
   136 	// Fetch next answer, if there's more to come
       
   137 	// PG 2808 Always fetch next, potential hanging on close bug here
       
   138 	//if (iState != EPerformingQuit)
       
   139 		// Get ready to fetch next answer from server 
       
   140 		iPiChannel->GetNextAnswer(iServerAnswerBuffer);
       
   141 	return;
       
   142 	}
       
   143 
       
   144 void CFtpProtocolDerived::DTPChannelOperationCompletion(const TDtpOperationCompletion aCompletionStatus)
       
   145 /**
       
   146 Define the DTPChannel callback notifiers
       
   147 Notify of normal completion of an operation
       
   148 */
       
   149 	{
       
   150 	FTPPROTDEBUG(_DBGFtpprot,_L("CFtpProtocolDerived::DTPChannelOperationCompletion called "));
       
   151 	switch(aCompletionStatus)
       
   152 		{
       
   153 		case MDTPChannelNotifier::EDtpAcceptComplete:
       
   154 		case MDTPChannelNotifier::EDtpConnectComplete:
       
   155 			FTPPROTDEBUG(_DBGFtpprot,_L("Connected \n"));
       
   156 			switch(iState)
       
   157 				{
       
   158 				case EPerformingList:
       
   159 				case EPerformingNlst:
       
   160 				case EPerformingRetr:
       
   161 					iDtpChannel->Recv(*iIOBuffer);
       
   162 					break;
       
   163 				case EPerformingStor:
       
   164 				case EPerformingStou:
       
   165 					iDtpChannel->Send(*iIOBuffer);
       
   166 					break;
       
   167 				}
       
   168 			break;
       
   169 		default:
       
   170 			break;
       
   171 		}
       
   172 	}
       
   173 
       
   174 void CFtpProtocolDerived::DTPChannelOperationError(const TDtpOperationError aErrorStatus)
       
   175 /**
       
   176 Notify of error performing an operation
       
   177 */
       
   178 	{
       
   179 	FTPPROTDEBUG(_DBGFtpprot,_L("CFtpProtocolDerived::DTPChannelOperationError called\n"));
       
   180 		switch (aErrorStatus)
       
   181 			{
       
   182 			case MDTPChannelNotifier::EDtpConnectFailed:
       
   183 				// 
       
   184 				iNotifier->ErrorNotification(MFtpProtocolNotifier::EXferNotInitialised);
       
   185 				break;
       
   186 			case MDTPChannelNotifier::EDtpRecvAborted:
       
   187 			case MDTPChannelNotifier::EDtpSendAborted:
       
   188 				switch(iState)
       
   189 					{
       
   190 					// Some bad behaved ftp server (microsoft)
       
   191 					// reset the DTP connection on abort
       
   192 					case EPerformingAbor:
       
   193 						UpdateState(EDtpChannelClosed);
       
   194 						break;
       
   195 					default:
       
   196 						//Close PI Channel
       
   197 						iPiChannel->Disconnect();
       
   198 						//Reset state
       
   199 						iState = EIdle;
       
   200 						iNotifier->ErrorNotification(MFtpProtocolNotifier::EXferReset);
       
   201 						break;
       
   202 					}
       
   203 				break;
       
   204 			default:
       
   205 				// Cannot come here
       
   206 				__ASSERT_DEBUG(FALSE, User::Panic(_L("CFtpProtocolDerived"), 0));
       
   207 				break;
       
   208 			}
       
   209 	return;
       
   210 	}
       
   211 	
       
   212 void CFtpProtocolDerived::DTPChannelXferNotification(const TDtpOperationCompletion aCompletionStatus)
       
   213 /**
       
   214 Notify of reception 
       
   215 */
       
   216 	{
       
   217 	FTPPROTDEBUG(_DBGFtpprot,_L("CFtpProtocolDerived::DTPChannelRcvNotification called\n"));
       
   218 	// notify upper layer a packet is ready
       
   219 	switch(aCompletionStatus)
       
   220 		{
       
   221 		case MDTPChannelNotifier::EDtpRcvMoreData:
       
   222 			FTPPROTDEBUG(_DBGFtpprot,_L("EDtpRcvMoreData\n"));
       
   223 			iNotifier->ServerXFerNotification(MFtpProtocolNotifier::EPacketReceived);
       
   224 			break;
       
   225 		case MDTPChannelNotifier::EDtpSendEOFComplete:
       
   226 			FTPPROTDEBUG(_DBGFtpprot,_L("EDtpSendEOFComplete\n"));
       
   227 			UpdateState(EDtpChannelClosed);
       
   228 			break;
       
   229 		case MDTPChannelNotifier::EDtpRcvComplete:
       
   230 			FTPPROTDEBUG(_DBGFtpprot,_L("EDtpRecvEOFComplete\n"));
       
   231 			UpdateState(EDtpChannelClosed);
       
   232 			break;
       
   233 		case MDTPChannelNotifier::EDtpSendComplete:
       
   234 			FTPPROTDEBUG(_DBGFtpprot,_L("EDtpSendComplete\n"));
       
   235 			iNotifier->ServerXFerNotification(MFtpProtocolNotifier::EPacketSent);
       
   236 			break;
       
   237 		default:
       
   238 			FTPPROTDEBUG(_DBGFtpprot,_L("WARNING !!!!! Unrecognised event\n"));
       
   239 			break;
       
   240 		}
       
   241 	}
       
   242 
       
   243 void CFtpProtocolDerived::FTPResolverNotifier(const TFTPResolverNotificationCode aCompletionStatus)
       
   244 /**
       
   245 Resolver callback
       
   246 */
       
   247 	{
       
   248 	FTPPROTDEBUG(_DBGFtpprot,_L("CFtpProtocolDerived::DFTPResolverNotifier called"));
       
   249 	__ASSERT_DEBUG(iState == ELookingUp, User::Panic(_L("CFtpProtocolDerived"), EPIPanicMegaOI));
       
   250 	switch(aCompletionStatus)
       
   251 		{
       
   252 		case MFTPResolverNotifier::EDtpLookupComplete:
       
   253 			FTPPROTDEBUG(_DBGFtpprot,_L("EDtpLookupComplete\n"));
       
   254 			iState = EConnecting;
       
   255 			iResolver->SetAddress(iRemoteAddress);
       
   256 			Connect(iRemoteAddress);
       
   257 			break;
       
   258 		case MFTPResolverNotifier::EDtpLookupFailed:
       
   259 			FTPPROTDEBUG(_DBGFtpprot,_L("EDtpLookupFailed\n"));
       
   260 			//
       
   261 			iNotifier->ErrorNotification(MFtpProtocolNotifier::EHostNotFound);
       
   262 			iState = EIdle;
       
   263 
       
   264 			break;
       
   265 		}
       
   266 	}
       
   267 
       
   268 void CFtpProtocolDerived::SetErrorNotifier(const TInt aError)
       
   269 /**
       
   270 Define the CFTPSetError callback notifier
       
   271 */
       
   272 {
       
   273 	switch(aError)
       
   274 		{
       
   275 		case MFtpProtocolNotifier::ESocketError:
       
   276 			iNotifier->ErrorNotification(MFtpProtocolNotifier::ESocketError);
       
   277 			break;
       
   278 		case MFtpProtocolNotifier::EOpCanceled:
       
   279 			iNotifier->ErrorNotification(MFtpProtocolNotifier::EOpCanceled);
       
   280 			break;
       
   281 		default:
       
   282 			__ASSERT_DEBUG(FALSE, User::Panic(_L("CFtpProtocolDerived"), EPIPanicMegaOI));
       
   283 			break;
       
   284 		}
       
   285 }
       
   286 
       
   287 //
       
   288 //					FTP Private methods implementation 
       
   289 //
       
   290 
       
   291 void CFtpProtocolDerived::UpdateState(const TInternalEvents aEvent)
       
   292 	{
       
   293 #if defined(__FTPPROTDEBUG__)
       
   294 	TBuf<4> debugBuffer;	//Placeholder for the answer I got from the FTP server
       
   295 #endif
       
   296 	FTPPROTDEBUG(_DBGFtpprot,_L("CFtpProtocolDerived::UpdateState\n"));
       
   297 	// Do some preprocessing according to the event
       
   298 	switch(aEvent)
       
   299 		{
       
   300 		case EFtpCodeReply:
       
   301 			// Called when an answer has been parsed 
       
   302 			FTPPROTDEBUG(_DBGFtpprot,_L("CFtpProtocolDerived::UpdateState called aEvent==EFtpCodeReply\n"));
       
   303 			// Fetch the answer
       
   304 			iFTPServerAnswerParser->ServerAnswer(iAnswer);
       
   305 			//Display the answer for debug purpose
       
   306 #if defined(__FTPPROTDEBUG__)
       
   307 			debugBuffer.Copy(iAnswer);
       
   308 			debugBuffer.Append(0);
       
   309 			FTPPROTDEBUG(_DBGFtpprot,_L("Parsed server answer: <"));
       
   310 			FTPPROTDEBUG(_DBGFtpprot,debugBuffer);
       
   311 			FTPPROTDEBUG(_DBGFtpprot,_L(">\n"));
       
   312 #endif
       
   313 			// Check the answer to keep it in the allowed bounds
       
   314 			if((iAnswer[0]<'1') || (iAnswer[0]>'5'))
       
   315 				{
       
   316 				// Answer out of bounds
       
   317 				FTPPROTDEBUG(0xffff,_L("!!!!!!SERVER ANSWER OUT OF BOUND\n"));
       
   318 				}
       
   319 			break;
       
   320 		default:
       
   321 			break;
       
   322 		}
       
   323 	// Completion callback can only be sent when 
       
   324 	// - PI Channel has been notified of success for the send operation
       
   325 	// - An answer has been received and parsed
       
   326 	// Accordingly, we bail out if any of these conditions is not
       
   327 	// completed yet
       
   328 	if (iAnswer.Length()<3)
       
   329 		{
       
   330 		FTPPROTDEBUG(_DBGFtpprot,_L("iAnswer.Length()<3\n"));
       
   331 		return;
       
   332 		}
       
   333 	if (iPiChannel->Busy()) 
       
   334 		{
       
   335 		FTPPROTDEBUG(_DBGFtpprot,_L("iPiChannel->Busy()) \n"));
       
   336 		return;
       
   337 		}
       
   338 	// Execute the next sequence of operations depending on our current state
       
   339 	switch(iState)
       
   340 		{
       
   341 		// Simple commands as per FSM page 54 of RFC 959
       
   342 		case EConnecting:
       
   343 		case EPerformingAllo:
       
   344 		case EPerformingDele:
       
   345 		case EPerformingCwd:
       
   346 		case EPerformingCdup:
       
   347 		case EPerformingSmnt:
       
   348 		case EPerformingHelp:
       
   349 		case EPerformingMode:
       
   350 		case EPerformingNoop:
       
   351 		case EPerformingSite:
       
   352 		case EPerformingPort:
       
   353 		case EPerformingSyst:
       
   354 		case EPerformingStat:
       
   355 		case EPerformingRmd:
       
   356 		case EPerformingMkd:
       
   357 		case EPerformingPwd:
       
   358 		case EPerformingStru:
       
   359 		case EPerformingType:
       
   360 			// Only allow a "2" answer
       
   361 				if (iAnswer[0]=='2')
       
   362 					iNotifier->ServerPositiveAnswerNotification(MFtpProtocolNotifier::EOpComplete);
       
   363 				else
       
   364 					iNotifier->ServerNegativeAnswerNotification(MFtpProtocolNotifier::EOpFailed);
       
   365 			break;
       
   366 		case EPerformingQuit:
       
   367 			// In any case close the PI Channel
       
   368 			iPiChannel->Disconnect();
       
   369 			// Only allow a "2" answer
       
   370 				if (iAnswer[0]=='2')
       
   371 					iNotifier->ServerPositiveAnswerNotification(MFtpProtocolNotifier::EOpComplete);
       
   372 				else
       
   373 					iNotifier->ServerNegativeAnswerNotification(MFtpProtocolNotifier::EOpFailed);
       
   374 			break;
       
   375 		case EPerformingAbor:
       
   376 			// rfc says, I might get a 426
       
   377 			// then I'll get a 2xx to ack the ABORT
       
   378 			// Just wait for a "2"
       
   379 			// Note: Not checking for error here
       
   380 			// If the server nack my abort, I'll hang and the user has to reset me
       
   381 				if (iAnswer[0]=='2')
       
   382 					{
       
   383 					// Check the DtpChannel has been closed
       
   384 					if(!iDtpChannel->Closed())
       
   385 						{
       
   386 						FTPPROTDEBUG(_DBGFtpprot,_L("!iDtpChannel->Closed()\n"));
       
   387 						return;
       
   388 						}
       
   389 					// Channel closed and 2 answer - notify completion
       
   390 					iNotifier->ServerPositiveAnswerNotification(MFtpProtocolNotifier::EOpComplete);
       
   391 					}
       
   392 				else if (iAnswer[0]=='4')
       
   393 					// Assume that if the server acknowledged my abort
       
   394 					// request with a 4, it has already issued a FIN
       
   395 					// I just reset the connection, otherwise I might have to 
       
   396 					// wait for a long time to flush the queud packets
       
   397 					iDtpChannel->Disconnect();
       
   398 			break;
       
   399 		case EPerformingPasv:
       
   400 			// Only allow a "2" answer, verify we got a valid address to connect to
       
   401 				if ((iAnswer[0]=='2') && (iFtpPASVAnswerParser->Fetch(iFTPDTPAddress)))
       
   402 					iNotifier->ServerPositiveAnswerNotification(MFtpProtocolNotifier::EOpComplete);
       
   403 				else
       
   404 					iNotifier->ServerNegativeAnswerNotification(MFtpProtocolNotifier::EOpFailed);
       
   405 			break;
       
   406 		// Commands defined as per 1st FSM page 55 of RFC 959
       
   407 		case EPerformingList:
       
   408 		case EPerformingNlst:
       
   409 		case EPerformingRetr:
       
   410 		case EPerformingStor:
       
   411 		case EPerformingStou:
       
   412 		// If We get an error close DTP channel, notify error and bail out
       
   413 			switch(iAnswer[0])
       
   414 				{
       
   415 				case '1':
       
   416 					// Ignore a 1 answer
       
   417 					break;
       
   418 				case '2':
       
   419 					// Check the DtpChannel has been closed
       
   420 					if(!iDtpChannel->Closed())
       
   421 						{
       
   422 						FTPPROTDEBUG(_DBGFtpprot,_L("!iDtpChannel->Closed()\n"));
       
   423 						return;
       
   424 						}
       
   425 					// Channel closed and 2 answer - notify completion
       
   426 					iNotifier->ServerPositiveAnswerNotification(MFtpProtocolNotifier::EOpComplete);
       
   427 					break;
       
   428 				case '3':
       
   429 				case '4':
       
   430 				case '5':
       
   431 				default:
       
   432 					// If something else than 1-5 it really screwed up!!
       
   433 					iDtpChannel->Disconnect();
       
   434 					iNotifier->ServerNegativeAnswerNotification(MFtpProtocolNotifier::EOpFailed);
       
   435 					break;
       
   436 				}
       
   437 			break;
       
   438 		case EPerformingAppe:
       
   439 		case EPerformingRein:
       
   440 		// Not much to do, just ignore any "1" answer
       
   441 			if (iAnswer[0]=='1')
       
   442 				break;
       
   443 			if (iAnswer[0]=='2')
       
   444 					iNotifier->ServerPositiveAnswerNotification(MFtpProtocolNotifier::EOpComplete);
       
   445 				else
       
   446 					iNotifier->ServerNegativeAnswerNotification(MFtpProtocolNotifier::EOpFailed);
       
   447 			break;
       
   448 		// rename sequence defined as per 2nd FSM page 55 of RFC 959
       
   449 		case EPerformingRnfr:
       
   450 				if (iAnswer[0]=='3')
       
   451 					iNotifier->ServerPositiveAnswerNotification(MFtpProtocolNotifier::EOpComplete);
       
   452 				else
       
   453 					iNotifier->ServerNegativeAnswerNotification(MFtpProtocolNotifier::EOpFailed);
       
   454 			break;
       
   455 		case EPerformingRnto:
       
   456 				if (iAnswer[0]=='2')
       
   457 					iNotifier->ServerPositiveAnswerNotification(MFtpProtocolNotifier::EOpComplete);
       
   458 				else
       
   459 					iNotifier->ServerNegativeAnswerNotification(MFtpProtocolNotifier::EOpFailed);
       
   460 			break;
       
   461 		// Rest sequence as defined per FSM page 56 of RFC 959 
       
   462 		case EPerformingRest:
       
   463 				if (iAnswer[0]=='3')
       
   464 					iNotifier->ServerPositiveAnswerNotification(MFtpProtocolNotifier::EOpComplete);
       
   465 				else
       
   466 					iNotifier->ServerNegativeAnswerNotification(MFtpProtocolNotifier::EOpFailed);
       
   467 			break;
       
   468 		// Login sequence as defined by FSM page 57 of RFC 959 
       
   469 		case EPerformingUser:
       
   470 				if ((iAnswer[0]=='3') || 
       
   471 					(iAnswer[0]=='2')) // Slight divergence from the RFC here, but some servers
       
   472 					// allow disabling the passwd check and send back a 2 answer at this stage
       
   473 					iNotifier->ServerPositiveAnswerNotification(MFtpProtocolNotifier::EOpComplete);
       
   474 				else
       
   475 					iNotifier->ServerNegativeAnswerNotification(MFtpProtocolNotifier::EOpFailed);
       
   476 			break;
       
   477 		case EPerformingPass:
       
   478 				if (iAnswer[0]=='2')
       
   479 					iNotifier->ServerPositiveAnswerNotification(MFtpProtocolNotifier::EOpComplete);
       
   480 				else
       
   481 					iNotifier->ServerNegativeAnswerNotification(MFtpProtocolNotifier::EOpFailed);
       
   482 			break;
       
   483 		case EIdle:
       
   484 			// Can't be here in Idle state
       
   485 			__ASSERT_DEBUG(FALSE, User::Panic(_L("CFtpProtocolDerived"), EPIPanicMegaOI));
       
   486 			break;
       
   487 		default:
       
   488 			// OOps, forgot something
       
   489 			__ASSERT_DEBUG(FALSE, User::Panic(_L("CFtpProtocolDerived"), 0));
       
   490 		}
       
   491 
       
   492 
       
   493 	}
       
   494 //
       
   495 //					FTP Command interface implementation 
       
   496 //
       
   497 
       
   498 void CFtpProtocolDerived::SendBuffer(TDes8* aBuffer)
       
   499 /**
       
   500 Set a buffer for reception and initiate reception 
       
   501 if the dtp channel is connected
       
   502 */
       
   503 	{
       
   504 	iIOBuffer = aBuffer;
       
   505 	if(iDtpChannel->Connected())
       
   506 		{
       
   507 		iDtpChannel->Send(*iIOBuffer);
       
   508 		}
       
   509 	}
       
   510 
       
   511 void CFtpProtocolDerived::SendEOF(void)
       
   512 /**
       
   513 Terminates the connection with the peer to mark the end of transfer.
       
   514 */
       
   515 	{
       
   516 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::SendEOF called\n"));
       
   517 	iDtpChannel->SendEOF();
       
   518 	}
       
   519 
       
   520 void CFtpProtocolDerived::RecvBuffer(TDes8* aBuffer)
       
   521 /**
       
   522 Set a buffer for reception and initiate reception if the dtp channel is connected.
       
   523 */
       
   524 	{
       
   525 	iIOBuffer = aBuffer;
       
   526 	if(iDtpChannel->Connected())
       
   527 		{
       
   528 		iDtpChannel->Recv(*iIOBuffer);
       
   529 		}
       
   530 	}
       
   531 
       
   532 void CFtpProtocolDerived::Connect(TSockAddr& aNetAddr)
       
   533 /**
       
   534 Establish a connection:
       
   535 */
       
   536 	{
       
   537 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Connect called\n"));
       
   538 	iState = EConnecting;
       
   539 	iRemoteAddress = aNetAddr;
       
   540 	// Reset the last answer
       
   541 	iAnswer.Zero();
       
   542 	if(!(iPiChannel->Connect(aNetAddr)))
       
   543 		// PiChannel could not open a socket 
       
   544 		// Post an error
       
   545 		iCFTPSetError->SetError(MFtpProtocolNotifier::ESocketError);
       
   546 	}
       
   547 
       
   548 void CFtpProtocolDerived::Connect(const THostName& aServerName)
       
   549 	{
       
   550 	// DNS name
       
   551 	Connect(aServerName,DEFAULT_SERVER_PI_PORT);
       
   552 	}
       
   553 
       
   554 void CFtpProtocolDerived::Connect(const THostName& aServerName, const TUint aPort)
       
   555 	{
       
   556 	// DNS name + port
       
   557 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Connect called\n"));
       
   558 	iState = ELookingUp;
       
   559 	// Reset the last answer
       
   560 	iAnswer.Zero();
       
   561 	iRemoteAddress.SetPort(aPort);
       
   562 	iResolver->Lookup(aServerName);
       
   563 	} 
       
   564 
       
   565 void CFtpProtocolDerived::User(const TDesC8& aParam)
       
   566 /**
       
   567 FTP commands, presented in the same order as RFC959:
       
   568 */
       
   569 	{
       
   570 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::User called\n"));
       
   571 	iFTPCmdBuffer = _L8("USER ");
       
   572 	iFTPCmdBuffer.Append(aParam);
       
   573 	iState = EPerformingUser;
       
   574 	// Reset the last answer
       
   575 	iAnswer.Zero();
       
   576 	// Fire the command
       
   577 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   578 	}
       
   579 
       
   580 void CFtpProtocolDerived::Pass(const TDesC8& aParam)
       
   581 	{
       
   582 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Pass called\n"));
       
   583 	iFTPCmdBuffer = _L8("PASS ");
       
   584 	iFTPCmdBuffer.Append(aParam);
       
   585 	iState = EPerformingPass;
       
   586 	// Reset the last answer
       
   587 	iAnswer.Zero();
       
   588 	// Fire the command
       
   589 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   590 	}
       
   591 
       
   592 void CFtpProtocolDerived::Acct(const TDesC8& /*aParam*/)
       
   593 	{
       
   594 	iState = EPerformingAcct;
       
   595 	}
       
   596 
       
   597 void CFtpProtocolDerived::Cwd(const TDesC8& aParam)
       
   598 	{
       
   599 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Cwd called\n"));
       
   600 	iFTPCmdBuffer = _L8("CWD ");
       
   601 	iFTPCmdBuffer.Append(aParam);
       
   602 	iState = EPerformingCwd;
       
   603 	// Reset the last answer
       
   604 	iAnswer.Zero();
       
   605 	// Fire the command
       
   606 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   607 	}
       
   608 
       
   609 void CFtpProtocolDerived::Cdup(void)
       
   610 	{
       
   611 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Cdup called\n"));
       
   612 	iFTPCmdBuffer = _L8("CDUP");
       
   613 	iState = EPerformingCdup;
       
   614 	// Reset the last answer
       
   615 	iAnswer.Zero();
       
   616 	// Fire the command
       
   617 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   618 	}
       
   619 
       
   620 void CFtpProtocolDerived::Smnt(const TDesC8& /*aParam*/)
       
   621 	{
       
   622 	iState = EPerformingSmnt;
       
   623 	}
       
   624 
       
   625 void CFtpProtocolDerived::Quit(void)
       
   626 	{
       
   627 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Quit called\n"));
       
   628 	iFTPCmdBuffer = _L8("QUIT");
       
   629 	iState = EPerformingQuit;
       
   630 	// Reset the last answer
       
   631 	iAnswer.Zero();
       
   632 	// Fire the command
       
   633 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   634 	}
       
   635 
       
   636 void CFtpProtocolDerived::Rein(void)
       
   637 	{
       
   638 	iState = EPerformingRein;
       
   639 	}
       
   640 
       
   641 void CFtpProtocolDerived::Port(void)
       
   642 	{// Sets the DTP port to one allocated by ESOCK
       
   643 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Port called\n"));
       
   644 	iState = EPerformingPort;
       
   645 	iPort = iDtpChannel->ListeningPort();
       
   646 	if ( iPort ==0)
       
   647 		{
       
   648 		// Some socket operations failed, post an async error
       
   649 		iCFTPSetError->SetError(MFtpProtocolNotifier::ESocketError);
       
   650 		// and bail out
       
   651 		return;
       
   652 		}
       
   653 	if (iLocalAddress.Family() == KAfInet)
       
   654 		{
       
   655 		FTPPROTDEBUG(_DBGFtpprot,_L("***Using PORT\n"));
       
   656 		BuildPORTCommand();
       
   657 		}
       
   658 	else
       
   659 		{
       
   660 		__ASSERT_DEBUG(iLocalAddress.Family() == KAfInet6, User::Panic(_L("CFtpProtocolDerived"), EAddressFamily));
       
   661 		FTPPROTDEBUG(_DBGFtpprot,_L("***Using EPRT\n"));
       
   662 		BuildEPRTCommand();
       
   663 		}
       
   664 	//PG 12/08/1999 following won't build, flogger doesn't take TDes8
       
   665 	//FTPPROTDEBUG(_DBGFtpprot,_L("Sending command -->"));
       
   666 	//FTPPROTDEBUG(_DBGFtpprot,iFTPCmdBuffer);
       
   667 	//FTPPROTDEBUG(_DBGFtpprot,_L("\n"));
       
   668 	// Set the PASV switch
       
   669 	iPASVMode = FALSE;
       
   670 	// Reset the last answer
       
   671 	iAnswer.Zero();
       
   672 	// Fire the command
       
   673 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   674 	}
       
   675 
       
   676 void CFtpProtocolDerived::BuildPORTCommand()
       
   677 	{
       
   678 	iFTPCmdBuffer = _L8("PORT ");
       
   679 	iFTPCmdBuffer.AppendNum(((iLocalAddress.Address())>>24), EDecimal);
       
   680 	iFTPCmdBuffer.Append(_L(","));
       
   681 	iFTPCmdBuffer.AppendNum((((iLocalAddress.Address()) & 0xFF0000) >>16), EDecimal);
       
   682 	iFTPCmdBuffer.Append(_L(","));
       
   683 	iFTPCmdBuffer.AppendNum((((iLocalAddress.Address()) & 0xFF00) >>8), EDecimal);
       
   684 	iFTPCmdBuffer.Append(_L(","));
       
   685 	iFTPCmdBuffer.AppendNum(((iLocalAddress.Address()) & 0xFF), EDecimal);
       
   686 	iFTPCmdBuffer.Append(_L(","));
       
   687 	iFTPCmdBuffer.AppendNum((((iPort) & 0xFF00) >>8), EDecimal);
       
   688 	iFTPCmdBuffer.Append(_L(","));
       
   689 	iFTPCmdBuffer.AppendNum(((iPort) & 0xFF), EDecimal);
       
   690 	}
       
   691 
       
   692 void CFtpProtocolDerived::BuildEPRTCommand()
       
   693 	{
       
   694 	TBuf<39> addrBuf;
       
   695 	iLocalAddress.Output(addrBuf);
       
   696 	
       
   697 	iFTPCmdBuffer = _L8("EPRT ");
       
   698 	iFTPCmdBuffer.Append(_L("|2|"));
       
   699 	iFTPCmdBuffer.Append(addrBuf);
       
   700 	iFTPCmdBuffer.Append(_L("|"));
       
   701 	iFTPCmdBuffer.AppendNum(iPort, EDecimal);
       
   702 	iFTPCmdBuffer.Append(_L("|"));
       
   703 	}
       
   704 
       
   705 void CFtpProtocolDerived::Port(TUint /*aPort*/)
       
   706 	{
       
   707 	// Sets the DTP port to a specific one
       
   708 	}
       
   709 
       
   710 void CFtpProtocolDerived::Pasv(void)
       
   711 	{
       
   712 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Pasv called\n"));
       
   713 	if (iLocalAddress.Family() == KAfInet)
       
   714 		{
       
   715 		FTPPROTDEBUG(_DBGFtpprot,_L("***Using PASV\n"));
       
   716 		iFTPCmdBuffer = _L8("PASV");
       
   717 		}
       
   718 	else
       
   719 		{
       
   720 		FTPPROTDEBUG(_DBGFtpprot,_L("***Using EPSV\n"));
       
   721 		iFTPCmdBuffer = _L8("EPSV");
       
   722 		}
       
   723 
       
   724 	iState = EPerformingPasv;
       
   725 	// Reset the last answer
       
   726 	iAnswer.Zero();
       
   727 	// Reset the Pasv Address Parser
       
   728 	iFtpPASVAnswerParser->Reset();
       
   729 	// Set the bool switch
       
   730 	iPASVMode = TRUE;
       
   731 	// Fire the command
       
   732 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   733 	}
       
   734 
       
   735 void CFtpProtocolDerived::Type(const TDesC8& aParam)
       
   736 	{
       
   737 	iState = EPerformingType;
       
   738 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Type called\n"));
       
   739 	iFTPCmdBuffer = _L8("TYPE ");
       
   740 	iFTPCmdBuffer.Append(aParam);
       
   741 	// Reset the last answer
       
   742 	iAnswer.Zero();
       
   743 	// Fire the command
       
   744 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   745 	}
       
   746 
       
   747 void CFtpProtocolDerived::Type(const TDesC8& /*aParam1*/, const TDesC8& /*aParam2*/)
       
   748 	{
       
   749 	iState = EPerformingType;
       
   750 	}
       
   751 
       
   752 void CFtpProtocolDerived::Stru(const TDesC8& /*aParam*/)
       
   753 	{
       
   754 	iState = EPerformingStru;
       
   755 	}
       
   756 
       
   757 void CFtpProtocolDerived::Mode(const TDesC8& /*aParam*/)
       
   758 	{
       
   759 	iState = EPerformingMode;
       
   760 	}
       
   761 
       
   762 void CFtpProtocolDerived::Retr(const TDesC8& aFileName)
       
   763 	{
       
   764 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Retr called\n"));
       
   765 	iFTPCmdBuffer = _L8("RETR ");
       
   766 	iFTPCmdBuffer.Append(aFileName);
       
   767 	iState = EPerformingRetr;
       
   768 	// Reset the last answer
       
   769 	iAnswer.Zero();
       
   770 	// Fire the command
       
   771 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   772 	if(iPASVMode)
       
   773 		{
       
   774 		if (!(iDtpChannel->Connect(iFTPDTPAddress)))
       
   775 			{
       
   776 			// Some socket operations failed, post an async error
       
   777 			iCFTPSetError->SetError(MFtpProtocolNotifier::ESocketError);
       
   778 			return;
       
   779 			}
       
   780 
       
   781 		}
       
   782 	else
       
   783 		{
       
   784 		// For non passive mode accept server connection
       
   785 		iDtpChannel->Accept();
       
   786 		}
       
   787 	}
       
   788 
       
   789 void CFtpProtocolDerived::Stor(const TDesC8& aFileName)
       
   790 	{
       
   791 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Stor called\n"));
       
   792 	iFTPCmdBuffer = _L8("STOR ");
       
   793 	iFTPCmdBuffer.Append(aFileName);
       
   794 	iState = EPerformingStor;
       
   795 	// Reset the last answer
       
   796 	iAnswer.Zero();
       
   797 	// Fire the command
       
   798 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   799 	if(iPASVMode)
       
   800 		{
       
   801 		if (!(iDtpChannel->Connect(iFTPDTPAddress)))
       
   802 			{
       
   803 			// Some socket operations failed, post an async error
       
   804 			iCFTPSetError->SetError(MFtpProtocolNotifier::ESocketError);
       
   805 			return;
       
   806 			}
       
   807 		}
       
   808 	else
       
   809 		{
       
   810 		// For non passive mode accept server connection
       
   811 		iDtpChannel->Accept();
       
   812 		}
       
   813 	}
       
   814 
       
   815 void CFtpProtocolDerived::List(void)
       
   816 	{
       
   817 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::List called\n"));
       
   818 	iFTPCmdBuffer = _L8("LIST");
       
   819 	iState = EPerformingList;
       
   820 	// Reset the last answer
       
   821 	iAnswer.Zero();
       
   822 	// Fire the command
       
   823 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   824 	if(iPASVMode)
       
   825 		{
       
   826 		if (!(iDtpChannel->Connect(iFTPDTPAddress)))
       
   827 			{
       
   828 			// Some socket operations failed, post an async error
       
   829 			iCFTPSetError->SetError(MFtpProtocolNotifier::ESocketError);
       
   830 			return;
       
   831 			}
       
   832 		}
       
   833 	else
       
   834 		{
       
   835 		// For non passive mode accept server connection
       
   836 		iDtpChannel->Accept();
       
   837 		}
       
   838 	}
       
   839 
       
   840 void CFtpProtocolDerived::List(const TDesC8& aParam)
       
   841 	{
       
   842 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::List called\n"));
       
   843 	iFTPCmdBuffer = _L8("LIST ");
       
   844 	iFTPCmdBuffer.Append(aParam);
       
   845 	iState = EPerformingList;
       
   846 	// Reset the last answer
       
   847 	iAnswer.Zero();
       
   848 	// Fire the command
       
   849 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   850 	if(iPASVMode)
       
   851 		{
       
   852 		if (!(iDtpChannel->Connect(iFTPDTPAddress)))
       
   853 			{
       
   854 			// Some socket operations failed, post an async error
       
   855 			iCFTPSetError->SetError(MFtpProtocolNotifier::ESocketError);
       
   856 			return;
       
   857 			}
       
   858 		}
       
   859 	else
       
   860 		{
       
   861 		// For non passive mode accept server connection
       
   862 		iDtpChannel->Accept();
       
   863 		}
       
   864 	}
       
   865 
       
   866 void CFtpProtocolDerived::Stou(void)
       
   867 	{
       
   868 	iState = EPerformingStou;
       
   869 	}
       
   870 
       
   871 void CFtpProtocolDerived::Appe(const TDesC8& /*aFileName*/)
       
   872 	{
       
   873 	iState = EPerformingAppe;
       
   874 	}
       
   875 
       
   876 void CFtpProtocolDerived::Allo(const TDesC8& /*aParam*/)
       
   877 	{
       
   878 	iState = EPerformingAllo;
       
   879 	}
       
   880 
       
   881 void CFtpProtocolDerived::Allo(const TDesC8& /*aParam1*/, const TDesC8& /*aParam2*/)
       
   882 	{
       
   883 	iState = EPerformingAllo;
       
   884 	}
       
   885 
       
   886 void CFtpProtocolDerived::Rest(const TDesC8& aParam)
       
   887 	{
       
   888 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Rest called\n"));
       
   889 	iFTPCmdBuffer = _L8("REST ");
       
   890 	iFTPCmdBuffer.Append(aParam);
       
   891 	iState = EPerformingRest;
       
   892 	// Reset the last answer
       
   893 	iAnswer.Zero();
       
   894 	// Fire the command
       
   895 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   896 	}
       
   897 
       
   898 void CFtpProtocolDerived::Rnfr(const TDesC8& aFileName)
       
   899 	{
       
   900 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Rnfr called\n"));
       
   901 	iFTPCmdBuffer = _L8("RNFR ");
       
   902 	iFTPCmdBuffer.Append(aFileName);
       
   903 	iState = EPerformingRnfr;
       
   904 	// Reset the last answer
       
   905 	iAnswer.Zero();
       
   906 	// Get ready to receive an answer
       
   907 //	iPiChannel->GetNextAnswer(iServerAnswerBuffer);
       
   908 	// Fire the command
       
   909 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   910 	}
       
   911 
       
   912 void CFtpProtocolDerived::Rnto(const TDesC8& aFileName)
       
   913 	{
       
   914 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Rnto called\n"));
       
   915 	iFTPCmdBuffer = _L8("RNTO ");
       
   916 	iFTPCmdBuffer.Append(aFileName);
       
   917 	iState = EPerformingRnto;
       
   918 	// Reset the last answer
       
   919 	iAnswer.Zero();
       
   920 	// Fire the command
       
   921 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   922 	}
       
   923 
       
   924 void CFtpProtocolDerived::Abor(void)
       
   925 	{
       
   926 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Abor called\n"));
       
   927 	iFTPCmdBuffer.Zero();
       
   928 	iFTPCmdBuffer.Append(IAC);
       
   929 	iFTPCmdBuffer.Append(IP); 
       
   930 	iFTPCmdBuffer.Append(IAC);
       
   931 	iFTPCmdBuffer.Append(SYNCH);
       
   932 	iFTPCmdBuffer.Append(_L8("ABOR"));
       
   933 	iState = EPerformingAbor;
       
   934 	// Fire the command
       
   935 	iPiChannel->SendCommand(iFTPCmdBuffer,KSockWriteUrgent);
       
   936 	}
       
   937 
       
   938 void CFtpProtocolDerived::Dele(const TDesC8& aFileName)
       
   939 	{
       
   940 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Dele called\n"));
       
   941 	iFTPCmdBuffer = _L8("DELE ");
       
   942 	iFTPCmdBuffer.Append(aFileName);
       
   943 	iState = EPerformingDele;
       
   944 	// Reset the last answer
       
   945 	iAnswer.Zero();
       
   946 	// Fire the command
       
   947 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   948 	}
       
   949 
       
   950 void CFtpProtocolDerived::Rmd(const TDesC8& aParam)
       
   951 	{
       
   952 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Rmd called\n"));
       
   953 	iFTPCmdBuffer = _L8("RMD ");
       
   954 	iFTPCmdBuffer.Append(aParam);
       
   955 	iState = EPerformingRmd;
       
   956 	// Reset the last answer
       
   957 	iAnswer.Zero();
       
   958 	// Fire the command
       
   959 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   960 	}
       
   961 
       
   962 void CFtpProtocolDerived::Mkd(const TDesC8& aParam)
       
   963 	{
       
   964 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Mkd called\n"));
       
   965 	iFTPCmdBuffer = _L8("MKD ");
       
   966 	iFTPCmdBuffer.Append(aParam);
       
   967 	iState = EPerformingMkd;
       
   968 	// Reset the last answer
       
   969 	iAnswer.Zero();
       
   970 	// Fire the command
       
   971 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   972 	}
       
   973 
       
   974 void CFtpProtocolDerived::Pwd(void)
       
   975 	{
       
   976 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Pwd called\n"));
       
   977 	iFTPCmdBuffer = _L8("PWD");
       
   978 	iState = EPerformingPwd;
       
   979 	// Reset the last answer
       
   980 	iAnswer.Zero();
       
   981 	// Fire the command
       
   982 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
   983 	}
       
   984 
       
   985 void CFtpProtocolDerived::Nlst(void)
       
   986 	{
       
   987 	iState = EPerformingNlst;
       
   988 	}
       
   989 
       
   990 void CFtpProtocolDerived::Nlst(const TDesC8& /*aParam*/)
       
   991 	{
       
   992 	iState = EPerformingNlst;
       
   993 	}
       
   994 
       
   995 void CFtpProtocolDerived::Site(const TDesC8& /*aParam*/)
       
   996 	{
       
   997 	iState = EPerformingSite;
       
   998 	}
       
   999 
       
  1000 void CFtpProtocolDerived::Syst(void)
       
  1001 	{
       
  1002 	iState = EPerformingSyst;
       
  1003 	}
       
  1004 
       
  1005 void CFtpProtocolDerived::Stat(const TDesC8& /*aParam*/)
       
  1006 	{
       
  1007 	iState = EPerformingStat;
       
  1008 	}
       
  1009 
       
  1010 void CFtpProtocolDerived::Stat(void)
       
  1011 	{
       
  1012 	iState = EPerformingStat;
       
  1013 	}
       
  1014 
       
  1015 void CFtpProtocolDerived::Help(const TDesC8& /*aParam*/)
       
  1016 	{
       
  1017 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Help called\n"));
       
  1018 	iFTPCmdBuffer = _L8("HELP");
       
  1019 	iState = EPerformingHelp;
       
  1020 	// Reset the last answer
       
  1021 	iAnswer.Zero();
       
  1022 	// Fire the command
       
  1023 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
  1024 	}
       
  1025 
       
  1026 void CFtpProtocolDerived::Help(void)
       
  1027 	{
       
  1028 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Help called\n"));
       
  1029 	iFTPCmdBuffer = _L8("HELP");
       
  1030 	iState = EPerformingHelp;
       
  1031 	// Reset the last answer
       
  1032 	iAnswer.Zero();
       
  1033 	// Fire the command
       
  1034 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
  1035 	}
       
  1036 
       
  1037 void CFtpProtocolDerived::Noop(void)
       
  1038 	{
       
  1039 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::Help called\n"));
       
  1040 	iFTPCmdBuffer = _L8("NOOP");
       
  1041 	iState = EPerformingNoop;
       
  1042 	// Reset the last answer
       
  1043 	iAnswer.Zero();
       
  1044 	// Fire the command
       
  1045 	iPiChannel->SendCommand(iFTPCmdBuffer);
       
  1046 	}
       
  1047 
       
  1048 void CFtpProtocolDerived::UserCancel(void)
       
  1049 	{
       
  1050 	FTPPROTDEBUG(_DBGFtpprot,_L("***CFtpProtocolDerived::UserCancel called "));
       
  1051 	switch(iState)
       
  1052 		{
       
  1053 		case ELookingUp:
       
  1054 			FTPPROTDEBUG(_DBGFtpprot,_L("State: ELookingUp\n"));
       
  1055 			iResolver->Cancel();
       
  1056 			break;
       
  1057 		case EConnecting:
       
  1058 			FTPPROTDEBUG(_DBGFtpprot,_L("State: EConnecting\n"));
       
  1059 			iPiChannel->Disconnect();
       
  1060 			break;
       
  1061 		default:
       
  1062 			FTPPROTDEBUG(_DBGFtpprot,_L("Do Nothing\n"));
       
  1063 			break;
       
  1064 		}
       
  1065 	}
       
  1066 
       
  1067 
       
  1068 //Extensions: 
       
  1069 
       
  1070 EXPORT_C TUint32 CFtpProtocol::GetVersion(void)
       
  1071 /** Gets the API version number.
       
  1072 *
       
  1073 * @return	32-bit number: with MAJOR_VERSION in the highest byte, 
       
  1074 * 			MINOR_VERSION in the next byte, and BUILD_NUMBER in the lowest two bytes
       
  1075 * 			i.e. MAJOR 2, MINOR 0x34, BUILD 0x278 would be "ver 2.52, build 632".
       
  1076 */
       
  1077 	{
       
  1078 		return FTPPROTDLL_VERSION_NUMBER;
       
  1079 	}
       
  1080 
       
  1081 EXPORT_C CFtpProtocol *CFtpProtocol::NewL( MFtpProtocolNotifier* aNotifier)
       
  1082 /** Allocates and constructs a new FTP engine object.
       
  1083 *
       
  1084 * @param aNotifier	Client callback interface. 
       
  1085 * 					The FTP engine calls this interface to pass server responses and 
       
  1086 * 					status messages to the client.
       
  1087 * @return			New FTP engine object.
       
  1088 */
       
  1089 	{
       
  1090 	return CFtpProtocolDerived::NewL(aNotifier);
       
  1091 	}
       
  1092 	
       
  1093 CFtpProtocolDerived *CFtpProtocolDerived::NewL( MFtpProtocolNotifier* aNotifier)
       
  1094 	{
       
  1095 	CFtpProtocolDerived* self = new (ELeave) CFtpProtocolDerived(aNotifier);
       
  1096 	CleanupStack::PushL(self);
       
  1097 	self->ConstructL();
       
  1098 	CleanupStack::Pop();
       
  1099 	return self;
       
  1100 	}
       
  1101 
       
  1102 CFtpProtocolDerived::CFtpProtocolDerived(MFtpProtocolNotifier* aNotifier
       
  1103 									):iNotifier(aNotifier)
       
  1104 	{
       
  1105 	}
       
  1106 
       
  1107 void CFtpProtocolDerived::ConstructL(void)
       
  1108 	{
       
  1109 	InitCommL();
       
  1110 	iCFTPSetError = CFTPSetError::NewL(this);
       
  1111 	iPiChannel = CPIChannel::NewL(this,iSockServ);
       
  1112 	iDtpChannel = CDTPChannel::NewL(this,iCFTPSetError,iSockServ);
       
  1113 	iResolver = CFTPResolver::NewL(this,iSockServ);
       
  1114 	iFTPServerAnswerParser = new (ELeave) TFTPServerAnswerParser();
       
  1115 	iFtpPASVAnswerParser = new (ELeave) TFtpPASVAnswerParser();
       
  1116 	// Reset the last answer
       
  1117 	iAnswer.Zero();
       
  1118 	}
       
  1119 
       
  1120 CFtpProtocol::~CFtpProtocol()
       
  1121 /** Destructor. */
       
  1122 	{}
       
  1123 	
       
  1124 CFtpProtocolDerived::~CFtpProtocolDerived()
       
  1125 	{
       
  1126 	FTPPROTDEBUG(_DBGFtpprot,_L("CFtpProtocolDerived::~CFtpProtocolDerived called\n"));
       
  1127 	delete  iPiChannel;
       
  1128 	delete  iDtpChannel;
       
  1129 	delete  iResolver;
       
  1130 	delete	iCFTPSetError;
       
  1131 	delete  iFTPServerAnswerParser;
       
  1132 	delete  iFtpPASVAnswerParser;
       
  1133 	iSockServ.Close();		
       
  1134 	}
       
  1135 
       
  1136 void CFtpProtocolDerived::InitCommL(void)
       
  1137 	{
       
  1138 	// Initialise Comm modules
       
  1139  	// When bootstrapping C32 we have to avoid the PhBkSyncServer being started, since
       
  1140  	// it needs a different CommDB
       
  1141  	_LIT(KPhbkSyncCMI, "phbsync.cmi");
       
  1142     StartC32WithCMISuppressions(KPhbkSyncCMI);
       
  1143 	// Open socket server
       
  1144 	User::LeaveIfError(iSockServ.Connect());
       
  1145 	}
       
  1146