예제 #1
0
 public bool Delete(FtpDirectory ftpDirectory,
                    CancellationToken cancellationToken)
 {
     return(this.DeleteAsync(ftpDirectory,
                             cancellationToken)
            .Result);
 }
예제 #2
0
        private async Task <bool> ChangeWorkingDirectoryAsync(ComplexSocket controlComplexSocket,
                                                              string directory,
                                                              CancellationToken cancellationToken,
                                                              bool createDirectoryIfNotExists = false)
        {
            var success = await this.SendAndLogAsync(controlComplexSocket,
                                                     cancellationToken,
                                                     "CWD {0}",
                                                     directory);

            if (!success)
            {
                return(false);
            }
            var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket,
                                                         cancellationToken);

            switch (ftpReply.FtpResponseType)
            {
            case FtpResponseType.PermanentNegativeCompletion:
                // TODO some parsing of the actual FtpReply.ResponseCode should be done in here. i assume 5xx-state means "directory does not exist" all the time, which might be wrong
                if (!createDirectoryIfNotExists)
                {
                    return(false);
                }
                success = await this.SendAndLogAsync(controlComplexSocket,
                                                     cancellationToken,
                                                     "MKD {0}",
                                                     directory);

                if (!success)
                {
                    return(false);
                }
                ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket,
                                                         cancellationToken);

                if (!ftpReply.Success)
                {
                    return(false);
                }
                goto case FtpResponseType.PositiveCompletion;

            case FtpResponseType.PositiveCompletion:
                this._currentFtpDirectory = FtpDirectory.Create(this._currentFtpDirectory,
                                                                directory);
                break;

            default:
                return(false);
            }
            return(true);
        }
예제 #3
0
        private async Task <bool> GotoParentDirectoryAsync(ComplexSocket controlComplexSocket,
                                                           FtpFileSystemObject ftpFileSystemObject,
                                                           CancellationToken cancellationToken,
                                                           bool createDirectoryIfNotExists = false)
        {
            var ftpDirectory     = ftpFileSystemObject.GetParentFtpDirectory();
            var directoryChanges = FtpClientHelper.DirectoryChanges(this._currentFtpDirectory,
                                                                    ftpDirectory);

            foreach (var directoryChange in directoryChanges)
            {
                if (string.Equals(directoryChange,
                                  FtpFileSystemObject.ParentChangeCommand))
                {
                    var success = await this.SendAndLogAsync(controlComplexSocket,
                                                             cancellationToken,
                                                             "CDUP");

                    if (success)
                    {
                        var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket,
                                                                     cancellationToken);

                        if (ftpReply.Success)
                        {
                            this._currentFtpDirectory = this._currentFtpDirectory.GetParentFtpDirectory();
                        }
                    }
                }
                else
                {
                    var success = await this.ChangeWorkingDirectoryAsync(controlComplexSocket,
                                                                         directoryChange,
                                                                         cancellationToken,
                                                                         createDirectoryIfNotExists);

                    if (!success)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
예제 #4
0
        public async Task <bool> DeleteAsync(FtpDirectory ftpDirectory,
                                             CancellationToken cancellationToken)
        {
            using (await this._mutex.LockAsync(cancellationToken))
            {
                var controlComplexSocket = await this.EnsureConnectionAndAuthenticationAsync(cancellationToken);

                if (controlComplexSocket == null)
                {
                    return(false);
                }

                var success = await this.GotoParentDirectoryAsync(controlComplexSocket,
                                                                  ftpDirectory,
                                                                  cancellationToken);

                if (!success)
                {
                    return(false);
                }

                success = await this.SendAndLogAsync(controlComplexSocket,
                                                     cancellationToken,
                                                     "RMD {0}",
                                                     ftpDirectory.DirectoryName);

                if (!success)
                {
                    return(false);
                }

                var ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket,
                                                             cancellationToken);

                if (!ftpReply.Success)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #5
0
        public async Task <bool> CreateDirectoryAsync(string path,
                                                      CancellationToken cancellationToken)
        {
            using (await this._mutex.LockAsync())
            {
                var controlComplexSocket = await this.EnsureConnectionAndAuthenticationAsync(cancellationToken);

                if (controlComplexSocket == null)
                {
                    return(false);
                }

                var ftpDirectory = FtpDirectory.Create(path);
                var success      = await this.GotoParentDirectoryAsync(controlComplexSocket,
                                                                       ftpDirectory,
                                                                       cancellationToken,
                                                                       true);

                return(success);
            }
        }
예제 #6
0
        public static IEnumerable <string> DirectoryChanges(FtpDirectory sourceFtpDirectory,
                                                            FtpDirectory targetFtpDirectory)
        {
            var sourceHierarchy = sourceFtpDirectory.GetHierarchy()
                                  .ToList();
            var targetHierarchy = targetFtpDirectory.GetHierarchy()
                                  .ToList();

            var wereEqualBefore = true;
            var i            = 0;
            var levelOfEqual = 0;

            for (; i < sourceHierarchy.Count; i++)
            {
                var sourceDirectory = sourceHierarchy.ElementAt(i);
                var targetDirectory = targetHierarchy.ElementAtOrDefault(i);

                if (wereEqualBefore)
                {
                    if (!string.Equals(sourceDirectory,
                                       targetDirectory))
                    {
                        levelOfEqual    = i;
                        wereEqualBefore = false;
                    }
                }
                if (!wereEqualBefore)
                {
                    yield return(FtpFileSystemObject.ParentChangeCommand);
                }
            }

            foreach (var directory in targetHierarchy.Skip(levelOfEqual))
            {
                yield return(directory);
            }
        }
예제 #7
0
 public async Task <bool> DeleteAsync(FtpDirectory ftpDirectory)
 {
     return(await this.DeleteAsync(ftpDirectory,
                                   CancellationToken.None));
 }
예제 #8
0
 public bool Delete(FtpDirectory ftpDirectory)
 {
     return(this.Delete(ftpDirectory,
                        CancellationToken.None));
 }
예제 #9
0
        public async Task <IEnumerable <FtpListItem> > GetListingAsync(string path,
                                                                       CancellationToken cancellationToken)
        {
            IEnumerable <string> rawListing;
            FtpListType          ftpListType;

            using (await this._mutex.LockAsync(cancellationToken))
            {
                var controlComplexSocket = await this.EnsureConnectionAndAuthenticationAsync(cancellationToken);

                if (controlComplexSocket == null)
                {
                    return(Enumerable.Empty <FtpListItem>());
                }

                string command;
                var    ftpFeatures = await this.GetFtpFeaturesAsync(controlComplexSocket,
                                                                    cancellationToken);

                if (ftpFeatures.HasFlag(FtpFeatures.MLSD))
                {
                    ftpListType = FtpListType.MLSD;
                    command     = "MLSD";
                }
                else if (ftpFeatures.HasFlag(FtpFeatures.MLST))
                {
                    ftpListType = FtpListType.MLST;
                    command     = "MLST";
                }
                else
                {
                    ftpListType = FtpListType.LIST;
                    command     = "LIST";
                }

                var ftpDirectory = FtpDirectory.Create(path);

                {
                    var success = await this.GotoParentDirectoryAsync(controlComplexSocket,
                                                                      ftpDirectory,
                                                                      cancellationToken);

                    if (!success)
                    {
                        return(Enumerable.Empty <FtpListItem>());
                    }
                }

                if (!string.IsNullOrEmpty(ftpDirectory.DirectoryName))
                {
                    var success = await this.ChangeWorkingDirectoryAsync(controlComplexSocket,
                                                                         ftpDirectory.DirectoryName,
                                                                         cancellationToken);

                    if (!success)
                    {
                        return(Enumerable.Empty <FtpListItem>());
                    }
                }

                {
                    // sending PASV
                    // reading PASV
                    var transferComplexSocket = await this.GetPassiveComplexSocketAsync(controlComplexSocket,
                                                                                        cancellationToken);

                    if (transferComplexSocket == null)
                    {
                        return(Enumerable.Empty <FtpListItem>());
                    }

                    FtpReply ftpReply;

                    using (transferComplexSocket)
                    {
                        // sending LIST/...
                        // open PASV
                        // reading LIST/... (150 Here comes the directory listing)
                        var success = await this.SendAndLogAsync(controlComplexSocket,
                                                                 cancellationToken,
                                                                 command);

                        if (!success)
                        {
                            return(Enumerable.Empty <FtpListItem>());
                        }

                        success = await transferComplexSocket.ConnectAsync(cancellationToken);

                        if (!success)
                        {
                            return(Enumerable.Empty <FtpListItem>());
                        }

                        ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket,
                                                                 cancellationToken);

                        if (!ftpReply.Success)
                        {
                            return(Enumerable.Empty <FtpListItem>());
                        }

                        {
                            this.WaitBeforeReceive();

                            // reading transfer

                            var receiveResult = await transferComplexSocket.Socket.ReceiveAsync(this.ChunkReceiveBufferSize,
                                                                                                transferComplexSocket.GetSocketAsyncEventArgs,
                                                                                                this.Encoding,
                                                                                                cancellationToken);

                            if (!receiveResult.Success)
                            {
                                return(Enumerable.Empty <FtpListItem>());
                            }

                            rawListing = (receiveResult.Data ?? string.Empty).Split(Environment.NewLine.ToCharArray(),
                                                                                    StringSplitOptions.RemoveEmptyEntries);
                        }
                    }
                    if (!ftpReply.Completed)
                    {
                        // reading LIST/... (226 Directory send OK)
                        ftpReply = await this.ReceiveAndLogAsync(controlComplexSocket,
                                                                 cancellationToken);

                        if (!ftpReply.Success)
                        {
                            return(Enumerable.Empty <FtpListItem>());
                        }
                    }
                }
            }

            var ftpListItems = FtpListItem.ParseList(rawListing,
                                                     ftpListType);

            return(ftpListItems);
        }