public void GetFile(string remotePath, Stream outStream, bool restart)
        {
            if (remotePath == null)
            {
                throw new ArgumentNullException("remotePath");
            }

            if (remotePath.Length == 0)
            {
                throw new ArgumentException("must contain a value", "remotePath");
            }

            if (outStream == null)
            {
                throw new ArgumentNullException("outStream");
            }

            if (outStream.CanWrite == false)
            {
                throw new ArgumentException("must be writable.  The CanWrite property must return the value 'true'.", "outStream");
            }

            FtpRequest request = new FtpRequest(base.CharacterEncoding, FtpCmd.Retr, remotePath);

            if (restart)
            {
                long remoteSize = GetFileSize(remotePath);

                if (outStream.Length == remoteSize)
                {
                    return;
                }

                base.TransferData(TransferDirection.ToClient, request, outStream, outStream.Length - 1);
            }
            else
            {
                base.TransferData(TransferDirection.ToClient, request, outStream);
            }
        }
 internal string TransferText(FtpRequest request)
 {
     Stream output = new MemoryStream();
     TransferData(TransferDirection.ToClient, request, output);
     output.Position = 0;
     StreamReader reader = new StreamReader(output, _encoding);
     return reader.ReadToEnd();
 }
        public void GetFile(string remotePath, string localPath, FileAction action)
        {
            if (remotePath == null)
            {
                throw new ArgumentNullException("remotePath");
            }

            if (remotePath.Length == 0)
            {
                throw new ArgumentException("must contain a value", "remotePath");
            }

            if (localPath == null)
            {
                throw new ArgumentNullException("localPath");
            }

            if (localPath.Length == 0)
            {
                throw new ArgumentException("must contain a value", "localPath");
            }

            if (action == FileAction.None)
            {
                throw new ArgumentOutOfRangeException("action", "must contain a value other than 'Unknown'");
            }

            localPath = CorrectLocalPath(localPath);
            WriteToLog(String.Format("Action='GetFile';Status='TransferBegin';LocalPath='{0}';RemotePath='{1}';FileAction='{1}'", localPath, remotePath, action));
            FtpRequest request = new FtpRequest(base.CharacterEncoding, FtpCmd.Retr, remotePath);

            try
            {
                switch (action)
                {
                    case FileAction.CreateNew:
                        using (Stream localFile = File.Open(localPath, FileMode.CreateNew))
                        {
                            base.TransferData(TransferDirection.ToClient, request, localFile);
                        }

                        break;
                    case FileAction.Create:
                        using (Stream localFile = File.Open(localPath, FileMode.Create))
                        {
                            base.TransferData(TransferDirection.ToClient, request, localFile);
                        }

                        break;
                    case FileAction.CreateOrAppend:
                        using (Stream localFile = File.Open(localPath, FileMode.OpenOrCreate))
                        {
                            localFile.Position = localFile.Length;
                            base.TransferData(TransferDirection.ToClient, request, localFile);
                        }

                        break;
                    case FileAction.Resume:
                        using (Stream localFile = File.Open(localPath, FileMode.Open))
                        {
                            long remoteSize = GetFileSize(remotePath);

                            if (localFile.Length == remoteSize)
                            {
                                return;
                            }

                            base.TransferData(TransferDirection.ToClient, request, localFile, localFile.Length - 1);
                        }

                        break;
                    case FileAction.ResumeOrCreate:
                        if (File.Exists(localPath) && (new FileInfo(localPath)).Length > 0)
                        {
                            GetFile(remotePath, localPath, FileAction.Resume);
                        }
                        else
                        {
                            GetFile(remotePath, localPath, FileAction.Create);
                        }

                        break;
                }
            }
            catch (Exception ex)
            {
                WriteToLog(String.Format("Action='GetFile';Status='TransferError';LocalPath='{0}';RemotePath='{1}';FileAction='{1}';ErrorMessage='{2}", localPath, remotePath, action, ex.Message));
                throw new FtpException(String.Format("An unexpected exception occurred while retrieving file '{0}'.", remotePath), base.LastResponse, ex);
            }

            WriteToLog(String.Format("Action='GetFile';Status='TransferSuccess';LocalPath='{0}';RemotePath='{1}';FileAction='{1}'", localPath, remotePath, action));
        }
        internal void TransferData(TransferDirection direction, FtpRequest request, Stream data, long restartPosition)
        {
            if (_commandConn == null || _commandConn.Connected == false)
            {
                throw new FtpConnectionClosedException("Connection is closed.");
            }

            if (request == null)
            {
                throw new ArgumentNullException("request", "value is required");
            }

            if (data == null)
            {
                throw new ArgumentNullException("data", "value is required");
            }

            switch (direction)
            {
                case TransferDirection.ToClient:
                    if (!data.CanWrite)
                        throw new FtpDataTransferException("Data transfer error.  Data conn does not allow write operation.");
                    break;
                case TransferDirection.ToServer:
                    if (!data.CanRead)
                        throw new FtpDataTransferException("Data transfer error.  Data conn does not allow read operation.");
                    break;
            }

            if (restartPosition > 0 && !data.CanSeek)
            {
                throw new FtpDataTransferException("Data transfer restart error.  Data conn does not allow seek operation.");
            }

            try
            {
                OpenDataConn();

                if (restartPosition > 0)
                {
                    SendRequest(new FtpRequest(_encoding, FtpCmd.Rest, restartPosition.ToString(CultureInfo.InvariantCulture)));
                    data.Position = restartPosition;
                }

                SendRequest(request);
                System.Threading.Thread.Sleep(5);
                WaitForDataConn();

                if (_dataConn == null)
                {
                    throw new FtpDataConnectionException("Unable to establish a data connection to the destination.  The destination may have refused the connection.");
                }

                Stream conn = _dataConn.GetStream();

                if (_securityProtocol != FtpSecurityProtocol.None)
                {
                    conn = CreateSslStream(conn);
                }

                if (_isCompressionEnabled)
                {
                    conn = CreateZlibStream(direction, conn);
                }

                switch (direction)
                {
                    case TransferDirection.ToClient:
                        TransferBytes(conn, data, _maxDownloadSpeed * 1024);
                        break;
                    case TransferDirection.ToServer:
                        TransferBytes(data, conn, _maxUploadSpeed * 1024);
                        break;
                }
            }
            finally
            {
                CloseDataConn();
            }

            WaitForHappyCodes(FtpResponseCode.ClosingDataConnection);

            if (_hashAlgorithm != HashingFunction.None && request.IsFileTransfer)
            {
                DoIntegrityCheck(request, data, restartPosition);
            }
        }
 internal void TransferData(TransferDirection direction, FtpRequest request, Stream data)
 {
     TransferData(direction, request, data, 0);
 }
        internal void SendRequest(FtpRequest request)
        {
            if (_commandConn == null || _commandConn.Connected == false)
            {
                throw new FtpConnectionClosedException("Connection is closed.");
            }

            DontWaitForHappyCodes();

            if (ClientRequest != null)
            {
                ClientRequest(this, new FtpRequestEventArgs(request));
            }

            byte[] buffer = request.GetBytes();

            try
            {
                _commandStream.Write(buffer, 0, buffer.Length);
            }
            catch (IOException ex)
            {
                throw new FtpConnectionBrokenException("Connection is broken.  Failed to send command.", ex);
            }

            if (request.HasHappyCodes)
            {
                WaitForHappyCodes(request.GetHappyCodes());
            }
            else
            {
                if (request.Command != FtpCmd.Quit)
                {
                    Thread.Sleep(2000);
                }

                DontWaitForHappyCodes();
            }
        }
        private void DoIntegrityCheck(FtpRequest request, Stream stream, long restartPosition)
        {
            string path = request.Arguments[0];
            long startPos = restartPosition;
            long endPos = stream.Length;
            string streamHash = ComputeChecksum(_hashAlgorithm, stream, startPos);
            string serverHash = GetChecksum(_hashAlgorithm, path, startPos, endPos);

            if (String.Compare(streamHash, serverHash, StringComparison.InvariantCultureIgnoreCase) != 0)
            {
                throw new FtpFileIntegrityException(String.Format("File integrity check failed.  The destination integrity value '{0}' for the file '{1}' did not match the data transfer integrity value '{2}'.", serverHash, path, streamHash));
            }
        }
 public FtpRequestEventArgs(FtpRequest request)
 {
     _request = request;
 }