protected virtual void Dispose(bool disposing) { lock (this) { _disposed = true; if (disposing) { } try { FtpDataConnection dc = _currentDC; if (null != dc) { dc.Dispose(); } } catch (Exception e) { NSTrace.WriteLineError("DTP.Dispose() ex: " + e.ToString()); } catch { NSTrace.WriteLineError("DTP.Dispose() non cls ex: " + Environment.StackTrace); } } }
//---------------------------------------- //simply reset data connection internal void Reset() { FtpDataConnection curDC = _currentDC; if (null != curDC) { curDC.Abort(); } }
void GetDC_End(IAsyncResult ar) { RunDTP_SO stateObj = (RunDTP_SO)ar.AsyncState; try { stateObj.UpdateContext(); lock (this) { if (!_disposed) { _currentDC = stateObj.GetDC_Cmd.EndExecute(ar); } } CheckDisposed(); //send restart position, if needed if (stateObj.Restart > 0) { string restCmd = "REST " + stateObj.Restart.ToString(); _cc.BeginSendCommandEx(stateObj.Timeout, restCmd, new AsyncCallback(this.Restart_End), stateObj); } else { //establish connection now, if it is outbound if (FtpDataConnectionType.Outbound == _currentDC.Type) { _currentDC.BeginEstablish(stateObj.Timeout, new AsyncCallback(this.OutboundEstablish_End), stateObj); } else { _cc.BeginSendCommandEx(stateObj.Timeout, stateObj.Command, new AsyncCallback(this.SendCommandEx_End), stateObj); } } } catch (Exception e) { HandleCatch(e, stateObj); } catch { HandleCatch(null, stateObj); } }
void ClearAtEnd(RunDTP_SO stateObj) { stateObj.SetCompleted(); //---------------------------------------- //Clear context _client.CurrentDTP = null; _currentDC = null; //---------------------------------------- //Unlock control connection, now the command //like abort, stat, quit could be issued UnlockCC(stateObj); }
///<summary>Processes an FTP command, sent from the client.</summary> ///<param name="Command">The command to process.</param> ///<returns>True if the command may be sent to the server, false otherwise.</returns> private bool ProcessCommand(string Command) { try { int Ret = Command.IndexOf(' '); if (Ret < 0) { Ret = Command.Length; } switch (Command.Substring(0, Ret).ToUpper().Trim()) { case "OPEN": ConnectTo(ParseIPPort(Command.Substring(Ret + 1))); break; case "USER": Ret = Command.IndexOf('@'); if (Ret < 0) { return(true); } else { User = Command.Substring(0, Ret).Trim() + "\r\n"; ConnectTo(ParseIPPort(Command.Substring(Ret + 1))); } break; case "PORT": ProcessPortCommand(Command.Substring(5).Trim()); break; case "PASV": DataForward = new FtpDataConnection(); DataForward.ProcessPasv(this); return(true); default: return(true); } return(false); } catch { Dispose(); return(false); } }
///<summary>Processes a PORT command, sent from the client.</summary> ///<param name="Input">The parameters of the PORT command.</param> private void ProcessPortCommand(string Input) { try { string[] Parts = Input.Split(','); if (Parts.Length == 6) { DataForward = new FtpDataConnection(); string Reply = DataForward.ProcessPort(new IPEndPoint(IPAddress.Parse(String.Join(".", Parts, 0, 4)), int.Parse(Parts[4]) * 256 + int.Parse(Parts[5]))); DestinationSocket.BeginSend(Encoding.ASCII.GetBytes(Reply), 0, Reply.Length, SocketFlags.None, new AsyncCallback(OnCommandSent), DestinationSocket); } } catch { Dispose(); } }
internal IAsyncResult BeginExecute(int timeout, string command, FtpDataType dataType, long restart, DTPStream userStream, AsyncCallback cb, object state) { RunDTP_SO stateObj = new RunDTP_SO(timeout, command, dataType, restart, userStream, cb, state); SetProgress(true); _currentDC = null; try { //---------------------------------------- //Lock Control connection to prevent //run the command like abort, quit, stat //during configuring of data connection _cc.BeginLock(Timeout.Infinite, new WaitOrTimerCallback(LockFirst_End), stateObj); } catch (Exception e) { SetProgress(false); CheckDisposed(); NSTrace.WriteLineError(_errMsg + e.ToString()); throw; } catch { SetProgress(false); CheckDisposed(); NSTrace.WriteLineError(_errMsgNonCls + Environment.StackTrace.ToString()); throw; } return(stateObj); }
void RunDTP_End(IAsyncResult ar) { RunDTP_SO stateObj = (RunDTP_SO)ar.AsyncState; try { stateObj.UpdateContext(); _currentDC.DataTransfered -= new FtpDataConnection.DataTransferedEventHandler(OnDataTransfered); _currentDC.Completed -= new FtpDataConnection.CompletedEventHandler(OnCompleted); try { //finish DTP... _currentDC.EndRunDTPStream(ar); stateObj.ManuallyClosed = _currentDC.ManuallyClosed; } catch (FtpAbortedException ex) { stateObj.AbortEx = ex; } finally { _currentDC.Dispose(); _currentDC = null; } //---------------------------------------- //Lock control connection again - reading //responses _cc.BeginLock(Timeout.Infinite, new WaitOrTimerCallback(LockLast_End), stateObj); } catch (Exception e) { HandleCatch(e, stateObj); } catch { HandleCatch(null, stateObj); } }
internal void Abort() { //---------------------------------------- //We need to hold this flag, because its //determine the behaviour at the last stage //(during reading responses after DTP). _aborted = true; //---------------------------------------- //Abort data-connection manually... //We need to do it because not everybody //follow RFC. (RFC: server should close //data-connection in case of ABORT cmd) FtpDataConnection curDC = _currentDC; if (null != curDC) { curDC.Abort(); } }
internal void Execute(int timeout, string cmd, FtpDataType dataType, long restart, DTPStream userStream) { bool ccLocked = false; //protected component against simultaneuous usage SetProgress(true); try { //---------------------------------------- //Lock Control connection to prevent //run the command like abort, quit, stat //during configuring of data connection ccLocked = _cc.Lock(Timeout.Infinite); FtpResponse response = null; //---------------------------------------- //send transfser type command if ((false == _client.IsDataTypeWasCached) || ((true == _client.IsDataTypeWasCached) && (_client.CachedDataType != dataType))) { string typeCmd = GetTypeCommand(dataType); response = _cc.SendCommandEx(timeout, typeCmd); FtpClient.CheckCompletionResponse(response); _client.IsDataTypeWasCached = true; _client.CachedDataType = dataType; } //---------------------------------------- //Initialize data connection _currentDC = null; Cmd_GetDataConnection getDC = new Cmd_GetDataConnection(_client); lock (this) { if (!_disposed) { _currentDC = getDC.Execute(timeout); } } CheckDisposed(); //---------------------------------------- //send restart position, if needed if (0 < restart) { string restCmd = "REST " + restart.ToString(); response = _cc.SendCommandEx(timeout, restCmd); if (false == response.IsIntermediateReply) { throw GetRestartNotSuppException(response); } CheckDisposed(); } //---------------------------------------- //establish connection now, if it is outbound if (FtpDataConnectionType.Outbound == _currentDC.Type) { _currentDC.Establish(timeout); CheckDisposed(); } //---------------------------------------- //send transfer request to the server response = _cc.SendCommandEx(timeout, cmd); CheckDisposed(); //---------------------------------------- //first respone should be one //of the 1** - let's check it if (response.IsCompletionReply) //should not happen { NSTrace.WriteLineError("Executing DTP: receive completion as first reply."); //_currentDC.AbortAsyncEstablish(); } else { FtpClient.CheckPreliminaryResponse(response); //---------------------------------------- //establish connection now, if it is inbound if (FtpDataConnectionType.Inbound == _currentDC.Type) { _currentDC.Establish(timeout); CheckDisposed(); } FtpAbortedException abortEx = null; try { //---------------------------------------- //subscribe to data events _currentDC.DataTransfered += new FtpDataConnection.DataTransferedEventHandler(OnDataTransfered); _currentDC.Completed += new FtpDataConnection.CompletedEventHandler(OnCompleted); //---------------------------------------- //prepare for abortion _aborted = false; _client.CurrentDTP = this; //---------------------------------------- //Unlock control connection, now the command //like abort, stat, quit could be issued ccLocked = false; _cc.Unlock(); //---------------------------------------- //start DTP _currentDC.RunDTPStream(timeout, userStream); } catch (FtpAbortedException ex) { abortEx = ex; } finally { _currentDC.DataTransfered -= new FtpDataConnection.DataTransferedEventHandler(OnDataTransfered); _currentDC.Completed -= new FtpDataConnection.CompletedEventHandler(OnCompleted); } //---------------------------------------- //Lock control connection again - reading //responses ccLocked = _cc.Lock(Timeout.Infinite); //---------------------------------------- //Skip preliminary responses // for (int i = 0; i < 10; i++) { response = _cc.ReadResponse(timeout); CheckDisposed(); if (response.IsPreliminaryReply) { continue; } break; } //---------------------------------------- //If still receiving priliminary responses //then it looks suspecious? // if (response.IsPreliminaryReply) { throw GetTooManyRespException(); } //---------------------------------------- // Dealing with Abort or Reset // if (!_aborted && (null == abortEx)) { if (!_currentDC.ManuallyClosed) { FtpClient.CheckCompletionResponse(response); } else { //---------------------------------------- //we DID close the data connection, //so, in general, the response should be //errorneous - therefore skip checking of it } } else { if (null != abortEx) //&& !response.IsCompletionReply) { abortEx.SetResponse(response); } //---------------------------------------- //If "ABOR" command was sent we need to //one more response... // if (_aborted) { response = _cc.ReadResponse(timeout); } } //------------------------------------------ //If "QUIT" was sent during data transfer //then here we need read one more response if (_quited) { response = _cc.ReadResponse(timeout); } if (null != abortEx) { throw abortEx; } } } catch (Exception e) { CheckDisposed(); NSTrace.WriteLineError(_errMsg + e.ToString()); throw; } catch { CheckDisposed(); NSTrace.WriteLineError(_errMsgNonCls + Environment.StackTrace.ToString()); throw; } finally { SetProgress(false); _client.CurrentDTP = null; if (true == ccLocked) { _cc.Unlock(); } } }