|
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 |