Ejemplo n.º 1
0
        public IEnumerable <FtpListItem> GetListing(string path)
        {
            IEnumerable <string> rawListing;
            FtpListType          ftpListType;

            lock (this._lockControlComplexSocket)
            {
                {
                    var success = this.EnsureConnection();
                    if (!success)
                    {
                        return(Enumerable.Empty <FtpListItem>());
                    }
                }

                string command;
                if (this.FtpFeatures.HasFlag(FtpFeatures.MLSD))
                {
                    ftpListType = FtpListType.MLSD;
                    command     = "MLSD";
                }
                else if (this.FtpFeatures.HasFlag(FtpFeatures.MLST))
                {
                    ftpListType = FtpListType.MLST;
                    command     = "MLST";
                }
                else
                {
                    // TODO check if really *always* available
                    ftpListType = FtpListType.LIST;
                    command     = "LIST";
                }


                var concreteCommand = string.Format("{0} {1}",
                                                    command,
                                                    path);

                var controlComplexSocket = this._controlComplexSocket;
                if (this.FtpFeatures.HasFlag(FtpFeatures.PRET))
                {
                    // On servers that advertise PRET (DrFTPD), the PRET command must be executed before a passive connection is opened.
                    {
                        var success = controlComplexSocket.Send(string.Format("PRET {0}",
                                                                              concreteCommand),
                                                                this.Encoding,
                                                                this.SendTimeout);
                        if (!success)
                        {
                            return(Enumerable.Empty <FtpListItem>());
                        }
                    }
                    {
                        var complexResult = controlComplexSocket.Receive(this.Encoding,
                                                                         this.ReceiveTimeout);
                        var success = complexResult.Success;
                        if (!success)
                        {
                            return(Enumerable.Empty <FtpListItem>());
                        }
                    }
                }
                {
                    var transferComplexSocket = this.GetPassiveComplexSocket();
                    if (transferComplexSocket == null)
                    {
                        return(Enumerable.Empty <FtpListItem>());
                    }

                    using (transferComplexSocket)
                    {
                        {
                            // send LIST/MLSD/MLST-command via control socket
                            {
                                var success = controlComplexSocket.Send(concreteCommand,
                                                                        this.Encoding,
                                                                        this.SendTimeout);
                                if (!success)
                                {
                                    return(Enumerable.Empty <FtpListItem>());
                                }
                            }
                            {
                                var complexResult = controlComplexSocket.Receive(this.Encoding,
                                                                                 this.ReceiveTimeout);
                                var success = complexResult.Success;
                                if (!success)
                                {
                                    return(Enumerable.Empty <FtpListItem>());
                                }
                            }
                        }
                        {
                            // receive listing via transfer socket
                            var connected = transferComplexSocket.Connect(this.ConnectTimeout);
                            if (!connected)
                            {
                                return(Enumerable.Empty <FtpListItem>());
                            }

                            var complexResult = transferComplexSocket.Receive(this.Encoding,
                                                                              this.ReceiveTimeout);
                            // TODO check if there's a need to check against FtpReply.Success or anything alike!
                            rawListing = complexResult.Messages;
                        }
                    }
                }
            }

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

            return(ftpListItems);
        }