Example #1
0
        private static FtpListItem ParseVaxList(string buf, FtpCapability capabilities)
        {
            Match  match;
            string pattern = @"(?<name>.+)\.(?<extension>.+);(?<version>\d+)\s+(?<size>\d+)\s+(?<modify>\d+-\w+-\d+\s+\d+:\d+)";

            if (!(match = Regex.Match(buf, pattern)).Success)
            {
                return(null);
            }
            FtpListItem item = new FtpListItem {
                m_name = string.Format("{0}.{1};{2}", match.Groups["name"].Value, match.Groups["extension"].Value, match.Groups["version"].Value)
            };

            if (match.Groups["extension"].Value.ToUpper() == "DIR")
            {
                item.m_type = FtpFileSystemObjectType.Directory;
            }
            else
            {
                item.m_type = FtpFileSystemObjectType.File;
            }
            if (!long.TryParse(match.Groups["size"].Value, out item.m_size))
            {
                item.m_size = -1L;
            }
            if (!DateTime.TryParse(match.Groups["modify"].Value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out item.m_modified))
            {
                item.m_modified = DateTime.MinValue;
            }
            return(item);
        }
Example #2
0
		/// <summary>
		/// Performs a bitwise and to check if the specified
		/// flag is set on the <see cref="Capabilities"/>  property.
		/// </summary>
		/// <param name="cap">The <see cref="FtpCapability"/> to check for</param>
		/// <returns>True if the feature was found, false otherwise</returns>
		public bool HasFeature(FtpCapability cap) {
			if (cap == FtpCapability.NONE && Capabilities.Count == 0) {
				return true;
			}

			return Capabilities.Contains(cap);
		}
Example #3
0
        /// <summary>
        /// Parses IIS DOS format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        private static FtpListItem ParseDosList(string buf, FtpCapability capabilities)
        {
            FtpListItem item = new FtpListItem();

            string[] datefmt = new string[]
            {
                "MM-dd-yy  hh:mmtt",
                "MM-dd-yyyy  hh:mmtt"
            };
            Match m;

            // directory
            if (
                (m =
                     Regex.Match(buf, @"(?<modify>\d+-\d+-\d+\s+\d+:\d+\w+)\s+<DIR>\s+(?<name>.*)$", RegexOptions.IgnoreCase))
                .Success)
            {
                DateTime modify;

                item.Type = FtpFileSystemObjectType.Directory;
                item.Name = m.Groups["name"].Value;

                //if (DateTime.TryParse(m.Groups["modify"].Value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out modify))
                if (DateTime.TryParseExact(m.Groups["modify"].Value, datefmt, CultureInfo.InvariantCulture,
                                           DateTimeStyles.AssumeUniversal, out modify))
                {
                    item.Modified = modify;
                }
            }
            // file
            else if (
                (m =
                     Regex.Match(buf, @"(?<modify>\d+-\d+-\d+\s+\d+:\d+\w+)\s+(?<size>\d+)\s+(?<name>.*)$",
                                 RegexOptions.IgnoreCase)).Success)
            {
                DateTime modify;
                long     size;

                item.Type = FtpFileSystemObjectType.File;
                item.Name = m.Groups["name"].Value;

                if (long.TryParse(m.Groups["size"].Value, out size))
                {
                    item.Size = size;
                }

                //if (DateTime.TryParse(m.Groups["modify"].Value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out modify))
                if (DateTime.TryParseExact(m.Groups["modify"].Value, datefmt, CultureInfo.InvariantCulture,
                                           DateTimeStyles.AssumeUniversal, out modify))
                {
                    item.Modified = modify;
                }
            }
            else
            {
                return(null);
            }

            return(item);
        }
Example #4
0
        private static FtpListItem ParseDosList(string buf, FtpCapability capabilities)
        {
            Match       match;
            DateTime    time2;
            long        num;
            FtpListItem item = new FtpListItem();

            string[] formats = new string[] { "MM-dd-yy  hh:mmtt", "MM-dd-yyyy  hh:mmtt" };
            if ((match = Regex.Match(buf, @"(?<modify>\d+-\d+-\d+\s+\d+:\d+\w+)\s+<DIR>\s+(?<name>.*)$", RegexOptions.IgnoreCase)).Success)
            {
                DateTime time;
                item.Type = FtpFileSystemObjectType.Directory;
                item.Name = match.Groups["name"].Value;
                if (DateTime.TryParseExact(match.Groups["modify"].Value, formats, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out time))
                {
                    item.Modified = time;
                }
                return(item);
            }
            if (!(match = Regex.Match(buf, @"(?<modify>\d+-\d+-\d+\s+\d+:\d+\w+)\s+(?<size>\d+)\s+(?<name>.*)$", RegexOptions.IgnoreCase)).Success)
            {
                return(null);
            }
            item.Type = FtpFileSystemObjectType.File;
            item.Name = match.Groups["name"].Value;
            if (long.TryParse(match.Groups["size"].Value, out num))
            {
                item.Size = num;
            }
            if (DateTime.TryParseExact(match.Groups["modify"].Value, formats, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out time2))
            {
                item.Modified = time2;
            }
            return(item);
        }
Example #5
0
        public static FtpListItem ParseWith(string path, string buf, FtpCapability capabilities, Parser parser)
        {
            var item = parser(buf, capabilities);

            if (item != null)
            {
                PostParse(path, buf, parser, item);
            }
            return(item);
        }
Example #6
0
 public static FtpListItem Parse(string path, string buf, FtpCapability capabilities)
 {
     if ((buf != null) && (buf.Length > 0))
     {
         foreach (Parser parser in Parsers)
         {
             FtpListItem item = parser(buf, capabilities);
             if (item != null)
             {
                 if (parser == new Parser(FtpListItem.ParseVaxList))
                 {
                     item.FullName = path + item.Name;
                 }
                 else
                 {
                     FtpTrace.WriteLine(item.Name);
                     if (path.GetFtpFileName().Contains("*"))
                     {
                         path = path.GetFtpDirectoryName();
                     }
                     if (item.Name != null)
                     {
                         if ((item.Name.StartsWith("/") || item.Name.StartsWith("./")) || item.Name.StartsWith("../"))
                         {
                             item.FullName = item.Name;
                             item.Name     = item.Name.GetFtpFileName();
                         }
                         else if (path != null)
                         {
                             item.FullName = path.GetFtpPath(new string[] { item.Name });
                         }
                         else
                         {
                             FtpTrace.WriteLine("Couldn't determine the full path of this object:{0}{1}", new object[] { Environment.NewLine, item.ToString() });
                         }
                     }
                     if ((item.LinkTarget != null) && !item.LinkTarget.StartsWith("/"))
                     {
                         if (item.LinkTarget.StartsWith("./"))
                         {
                             item.LinkTarget = path.GetFtpPath(new string[] { item.LinkTarget.Remove(0, 2) });
                         }
                         else
                         {
                             item.LinkTarget = path.GetFtpPath(new string[] { item.LinkTarget });
                         }
                     }
                 }
                 item.Input = buf;
                 return(item);
             }
         }
     }
     return(null);
 }
Example #7
0
        /// <summary>
        /// Parses a line from a file listing using the first successful match in the Parsers collection.
        /// </summary>
        /// <param name="path">The source path of the file listing</param>
        /// <param name="buf">A line from the file listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>A FtpListItem object representing the parsed line, null if the line was
        /// unable to be parsed. If you have encountered an unsupported list type add a parser
        /// to the public static Parsers collection of FtpListItem.</returns>
        public static FtpListItem Parse(string path, string buf, FtpCapability capabilities)
        {
            if (buf != null && buf.Length > 0)
            {
                FtpListItem item;

                foreach (Parser parser in Parsers)
                {
                    if ((item = parser(buf, capabilities)) != null)
                    {
                        // if this is a vax/openvms file listing
                        // there are no slashes in the path name
                        if (parser == (new Parser(ParseVaxList)))
                        {
                            item.FullName = path + item.Name;
                        }
                        else
                        {
                            FtpTrace.WriteLine(item.Name);

                            // remove globbing/wildcard from path
                            if (path.GetFtpFileName().Contains("*"))
                            {
                                path = path.GetFtpDirectoryName();
                            }

                            item.FullName = path.GetFtpPath(item.Name); //.GetFtpPathWithoutGlob();


                            // if a link target is set and it doesn't include an absolute path
                            // then try to resolve it.
                            if (item.LinkTarget != null && !item.LinkTarget.StartsWith("/"))
                            {
                                if (item.LinkTarget.StartsWith("./"))
                                {
                                    item.LinkTarget = path.GetFtpPath(item.LinkTarget.Remove(0, 2));
                                }
                                else
                                {
                                    item.LinkTarget = path.GetFtpPath(item.LinkTarget);
                                }
                            }
                        }

                        item.Input = buf;
                        return(item);
                    }
                }
            }

            return(null);
        }
Example #8
0
        /// <summary>
        /// Parses GrassValley K2 videoserver format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        static FtpListItem ParseK2List(string buf, FtpCapability capabilities)
        {
            Match  m;
            string regex =
                @"(?<permissions>.+)\s+" +
                @"(?<objectcount>\d+)\s+" +
                @"(?<user>\w+)\s+" +
                @"(?<group>\w+)\s+" +
                @"(?<size>\d*)\s+" +
                @"(?<modify>\w+\s+\d+\s+\d+:\d+:\d+|\w+\s+\d+\s+\d+)\s" +
                @"(?<name>.*)$";

            if ((m = Regex.Match(buf, regex)).Success)
            {
                FtpListItem item = new FtpListItem();
                item.Name     = m.Groups["name"].Value;
                item.Modified = m.Groups["modify"].Value.GetK2Date();
                long size;
                if (long.TryParse(m.Groups["size"].Value, out size))
                {
                    item.Size = size;
                }
                switch (m.Groups["permissions"].Value[0])
                {
                case 'd':
                    item.Type = FtpFileSystemObjectType.Directory;
                    break;

                case '-':
                case 's':
                    item.Type = FtpFileSystemObjectType.Movie;
                    break;

                case 'l':
                    item.Type = FtpFileSystemObjectType.Link;
                    break;

                default:
                    return(null);
                }
                return(item);
            }
            else
            {
                return(null);
            }
        }
        /// <summary>
        /// Parses MLSD/MLST format listings
        /// </summary>
        /// <param name="record">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        public static FtpListItem Parse(string record, FtpCapability capabilities, FtpClient client)
        {
            FtpListItem item = new FtpListItem();
            Match       m;

            if (!(m = Regex.Match(record, "type=(?<type>.+?);", RegexOptions.IgnoreCase)).Success)
            {
                return(null);
            }

            switch (m.Groups["type"].Value.ToLower())
            {
            case "dir":
            case "pdir":
            case "cdir":
                item.Type = FtpFileSystemObjectType.Directory;
                break;

            case "file":
                item.Type = FtpFileSystemObjectType.File;
                break;

            // These are not supported for now.
            case "link":
            case "device":
            default:
                return(null);
            }

            if ((m = Regex.Match(record, "; (?<name>.*)$", RegexOptions.IgnoreCase)).Success)
            {
                item.Name = m.Groups["name"].Value;
            }
            else                 // if we can't parse the file name there is a problem.
            {
                return(null);
            }

            ParseDateTime(record, item);

            ParseFileSize(record, item);

            ParsePermissions(record, item);

            return(item);
        }
        private FtpCapability ParseFeatures()
        {
            FtpCapability features = FtpCapability.NONE;

            foreach (string feat in base.InfoMessages.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
            {
                if (feat.ToUpper().Trim().StartsWith("MLST") || feat.ToUpper().Trim().StartsWith("MLSD"))
                {
                    features |= FtpCapability.MLSD;
                }
                else if (feat.ToUpper().Trim().StartsWith("MDTM"))
                {
                    features |= FtpCapability.MDTM;
                }
                else if (feat.ToUpper().Trim().StartsWith("REST STREAM"))
                {
                    features |= FtpCapability.REST;
                }
                else if (feat.ToUpper().Trim().StartsWith("SIZE"))
                {
                    features |= FtpCapability.SIZE;
                }
                else if (feat.ToUpper().Trim().StartsWith("UTF8"))
                {
                    features |= FtpCapability.UTF8;
                }
                else if (feat.ToUpper().Trim().StartsWith("PRET"))
                {
                    features |= FtpCapability.PRET;
                }
                else if (feat.ToUpper().Trim().StartsWith("MFMT"))
                {
                    features |= FtpCapability.MFMT;
                }
                else if (feat.ToUpper().Trim().StartsWith("MFCT"))
                {
                    features |= FtpCapability.MFCT;
                }
                else if (feat.ToUpper().Trim().StartsWith("MFF"))
                {
                    features |= FtpCapability.MFF;
                }
            }

            return(features);
        }
Example #11
0
        /// <summary>
        /// Parses a line from a file listing using the first successful match in the Parsers collection.
        /// </summary>
        /// <param name="path">The source path of the file listing</param>
        /// <param name="buf">A line from the file listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>A FtpListItem object representing the parsed line, null if the line was
        /// unable to be parsed. If you have encountered an unsupported list type add a parser
        /// to the public static Parsers collection of FtpListItem.</returns>
        public static FtpListItem ParseLegacy(string path, string buf, FtpCapability capabilities, FtpClient client)
        {
            if (!string.IsNullOrEmpty(buf))
            {
                FtpListItem item;

                foreach (Parser parser in Parsers)
                {
                    if ((item = parser(buf, capabilities, client)) != null)
                    {
                        item.Input = buf;
                        return(item);
                    }
                }
            }

            return(null);
        }
Example #12
0
        /// <summary>
        /// Parses Vax/VMS format listings
        /// </summary>
        public static FtpListItem ParseLegacy(string record, FtpCapability capabilities, FtpClient client)
        {
            string regex =
                @"(?<name>.+)\.(?<extension>.+);(?<version>\d+)\s+" +
                @"(?<size>\d+)\s+" +
                @"(?<modify>\d+-\w+-\d+\s+\d+:\d+)";
            Match m;

            if ((m = Regex.Match(record, regex)).Success)
            {
                FtpListItem item = new FtpListItem();

                item.Name = (m.Groups["name"].Value + "." + m.Groups["extension"].Value + ";" + m.Groups["version"].Value);

                if (m.Groups["extension"].Value.ToUpper() == "DIR")
                {
                    item.Type = FtpFileSystemObjectType.Directory;
                }
                else
                {
                    item.Type = FtpFileSystemObjectType.File;
                }
                long itemSize = 0;
                if (!long.TryParse(m.Groups["size"].Value, out itemSize))
                {
                    itemSize = -1;
                }

                item.Size = itemSize;

                DateTime itemModified = DateTime.MinValue;

                if (!DateTime.TryParse(m.Groups["modify"].Value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out itemModified))
                {
                    itemModified = DateTime.MinValue;
                }

                item.Modified = itemModified;

                return(item);
            }

            return(null);
        }
Example #13
0
        /// <summary>
        /// Parses IIS DOS format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        static FtpListItem ParseDosList(string buf, FtpCapability capabilities)
        {
            FtpListItem item = new FtpListItem();
            Match       m;

            // directory
            if ((m = Regex.Match(buf, @"(?<modify>\d+-\d+-\d+\s+\d+:\d+\w+)\s+<DIR>\s+(?<name>.*)$", RegexOptions.IgnoreCase)).Success)
            {
                DateTime modify;

                item.Type = FtpFileSystemObjectType.Directory;
                item.Name = m.Groups["name"].Value;

                if (DateTime.TryParse(m.Groups["modify"].Value, out modify))
                {
                    item.Modified = modify;
                }
            }
            // file
            else if ((m = Regex.Match(buf, @"(?<modify>\d+-\d+-\d+\s+\d+:\d+\w+)\s+(?<size>\d+)\s+(?<name>.*)$", RegexOptions.IgnoreCase)).Success)
            {
                DateTime modify;
                long     size;

                item.Type = FtpFileSystemObjectType.File;
                item.Name = m.Groups["name"].Value;

                if (long.TryParse(m.Groups["size"].Value, out size))
                {
                    item.Size = size;
                }

                if (DateTime.TryParse(m.Groups["modify"].Value, out modify))
                {
                    item.Modified = modify;
                }
            }
            else
            {
                return(null);
            }

            return(item);
        }
Example #14
0
        /// <summary>
        /// Parses a line from a file listing using the first successful match in the Parsers collection.
        /// </summary>
        /// <param name="path">The source path of the file listing</param>
        /// <param name="buf">A line from the file listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>A FtpListItem object representing the parsed line, null if the line was
        /// unable to be parsed. If you have encountered an unsupported list type add a parser
        /// to the public static Parsers collection of FtpListItem.</returns>
        public static FtpListItem Parse(string path, string buf, FtpCapability capabilities)
        {
            if (buf != null && buf.Length > 0)
            {
                FtpListItem item;

                foreach (Parser parser in Parsers)
                {
                    if ((item = parser(buf, capabilities)) != null)
                    {
                        item.FullName = path.GetFtpPath(item.Name);
                        item.Input    = buf;
                        return(item);
                    }
                }
            }

            return(null);
        }
 /// <summary>
 /// Populates the capabilities flags based on capabilities
 /// supported by this server. This method is overridable
 /// so that new features can be supported
 /// </summary>
 /// <param name="reply">The reply object from the FEAT command. The InfoMessages property will
 /// contain a list of the features the server supported delimited by a new line '\n' character.</param>
 internal void ParseFeatures(FtpResponse reply)
 {
     foreach (string feat in reply.InfoMessages.Split(new [] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
     {
         if (feat.ToUpper().Trim().StartsWith("MLST") || feat.ToUpper().Trim().StartsWith("MLSD"))
         {
             m_Caps |= FtpCapability.MLSD;
         }
         else if (feat.ToUpper().Trim().StartsWith("MDTM"))
         {
             m_Caps |= FtpCapability.MDTM;
         }
         else if (feat.ToUpper().Trim().StartsWith("REST STREAM"))
         {
             m_Caps |= FtpCapability.REST;
         }
         else if (feat.ToUpper().Trim().StartsWith("SIZE"))
         {
             m_Caps |= FtpCapability.SIZE;
         }
         else if (feat.ToUpper().Trim().StartsWith("UTF8"))
         {
             m_Caps |= FtpCapability.UTF8;
         }
         else if (feat.ToUpper().Trim().StartsWith("PRET"))
         {
             m_Caps |= FtpCapability.PRET;
         }
         else if (feat.ToUpper().Trim().StartsWith("MFMT"))
         {
             m_Caps |= FtpCapability.MFMT;
         }
         else if (feat.ToUpper().Trim().StartsWith("MFCT"))
         {
             m_Caps |= FtpCapability.MFCT;
         }
         else if (feat.ToUpper().Trim().StartsWith("MFF"))
         {
             m_Caps |= FtpCapability.MFF;
         }
     }
 }
Example #16
0
        /// <summary>
        /// Parses a line from a file listing using the first successful match in the Parsers collection.
        /// </summary>
        /// <param name="path">The source path of the file listing</param>
        /// <param name="buf">A line from the file listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <param name="matchingParser"></param>
        /// <returns>A FtpListItem object representing the parsed line, null if the line was
        /// unable to be parsed. If you have encountered an unsupported list type add a parser
        /// to the public static Parsers collection of FtpListItem.</returns>
        public static FtpListItem Parse(string path, string buf, FtpCapability capabilities, out FtpListItem.Parser matchingParser)
        {
            matchingParser = null;
            if (string.IsNullOrEmpty(buf))
            {
                return(null);
            }

            foreach (var parser in Parsers)
            {
                FtpListItem item;
                if ((item = parser(buf, capabilities)) == null)
                {
                    continue;
                }
                matchingParser = parser;
                PostParse(path, buf, parser, item);
                return(item);
            }
            return(null);
        }
Example #17
0
        static FtpListItem ParseVaxList(string buf, FtpCapability capabilities) {
            string regex =
                @"(?<name>.+)\.(?<extension>.+);(?<version>\d+)\s+" +
                @"(?<size>\d+)\s+" +
                @"(?<modify>\d+-\w+-\d+\s+\d+:\d+)";
            Match m;

            if ((m = Regex.Match(buf, regex)).Success) {
                FtpListItem item = new FtpListItem();

                item.m_name = string.Format("{0}.{1};{2}",
                    m.Groups["name"].Value,
                    m.Groups["extension"].Value,
                    m.Groups["version"].Value);

                if (m.Groups["extension"].Value.ToUpper() == "DIR")
                    item.m_type = FtpFileSystemObjectType.Directory;
                else
                    item.m_type = FtpFileSystemObjectType.File;

                if (!long.TryParse(m.Groups["size"].Value, out item.m_size))
                    item.m_size = -1;

                if (!DateTime.TryParse(m.Groups["modify"].Value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out item.m_modified))
                    item.m_modified = DateTime.MinValue;

                return item;
            }

            return null;
        }
Example #18
0
        /// <summary>
        /// Connect to the server
        /// </summary>
        public async Task ConnectAsync()
        {
            if (m_Stream == null)
            {
                m_Stream = new StreamChannel();
            }
            else
            {
                if (IsConnected) await DisconnectAsync();
            }

            if (HostName == null)
                throw new FtpException("No host has been specified");

            if (Credentials == null)
                throw new FtpException("No credentials have been specified");

            FtpResponse reply;

            if (await m_Stream.ConnectAsync(HostName, ServiceName))
            {
                if (!(reply = await GetReplyAsync()).Success)
                {
                    if (reply.Code == null)
                    {
                        throw new IOException("The connection was terminated before a greeting could be read.");
                    }

                    throw new FtpCommandException(reply);
                }
            }

            // TODO: If the encryption mode is set to explicit, raise to SSL

            if (Credentials != null)
            {
                await AuthenticateAsync(Credentials);
            }

            if ((reply = await m_Stream.GetFeaturesAsync()).Success)
                m_Caps = ((FtpFeaturesResponse) reply).Features;

            // Enable UTF8 if it's available
            if (m_Caps.HasFlag(FtpCapability.UTF8))
            {
                // If the server supports UTF8 it should already be enabled and this
                // command should not matter however there are conflicting drafts
                // about this so we'll just execute it to be safe. 
                await m_Stream.SetOptionsAsync("UTF8 ON");
                m_Stream.Encoding = Encoding.UTF8;
            }
        }
Example #19
0
        /// <summary>
        /// Parse raw file from server into a file object, using the currently active parser.
        /// </summary>
        public FtpListItem ParseSingleLine(string path, string file, FtpCapability caps, bool isMachineList)
        {
            FtpListItem result = null;

            // force machine listing if it is
            if (isMachineList)
            {
                result = FtpMachineListParser.Parse(file, caps, client);
            }
            else
            {
                // use custom parser if given
                if (m_customParser != null)
                {
                    result = m_customParser(file, caps, client);
                }
                else
                {
                    if (IsWrongParser())
                    {
                        ValidateParser(new string[] { file });
                    }

                    // use one of the in-built parsers
                    switch (CurrentParser)
                    {
                    case FtpParser.Legacy:
                        result = ParseLegacy(path, file, caps, client);
                        break;

                    case FtpParser.Machine:
                        result = FtpMachineListParser.Parse(file, caps, client);
                        break;

                    case FtpParser.Windows:
                        result = FtpWindowsParser.Parse(client, file);
                        break;

                    case FtpParser.Unix:
                        result = FtpUnixParser.Parse(client, file);
                        break;

                    case FtpParser.UnixAlt:
                        result = FtpUnixParser.ParseUnixAlt(client, file);
                        break;

                    case FtpParser.VMS:
                        result = FtpVMSParser.Parse(client, file);
                        break;

                    case FtpParser.IBM:
                        result = FtpIBMParser.Parse(client, file);
                        break;

                    case FtpParser.NonStop:
                        result = FtpNonStopParser.Parse(client, file);
                        break;
                    }
                }
            }

            // if parsed file successfully
            if (result != null)
            {
                // apply time difference between server/client
                if (HasTimeOffset)
                {
                    result.Modified = result.Modified - TimeOffset;
                }

                // calc absolute file paths
                result.CalculateFullFtpPath(this.client, path, false);
            }

            return(result);
        }
Example #20
0
        /// <summary>
        /// Parses MLS* format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        static FtpListItem ParseMachineList(string buf, FtpCapability capabilities)
        {
            Match m;

            if (!(m = Regex.Match(buf, "type=(?<type>.+?);", RegexOptions.IgnoreCase)).Success)
            {
                return(null);
            }
            FtpListItem item = new FtpListItem();

            switch (m.Groups["type"].Value.ToLower())
            {
            case "dir":
            case "pdir":
            case "cdir":
                item.Type = FtpFileSystemObjectType.Directory;
                break;

            case "file":
                item.Type = FtpFileSystemObjectType.File;
                break;

            // These are not supported for now.
            case "link":
            case "device":
            default:
                return(null);
            }

            if ((m = Regex.Match(buf, "; (?<name>.*)$", RegexOptions.IgnoreCase)).Success)
            {
                item.Name = m.Groups["name"].Value;
            }
            else // if we can't parse the file name there is a problem.
            {
                return(null);
            }

            if ((m = Regex.Match(buf, "modify=(?<modify>.+?);", RegexOptions.IgnoreCase)).Success)
            {
                item.Modified = m.Groups["modify"].Value.GetFtpDate(DateTimeStyles.AssumeUniversal);
            }

            if ((m = Regex.Match(buf, "created?=(?<create>.+?);", RegexOptions.IgnoreCase)).Success)
            {
                item.Created = m.Groups["create"].Value.GetFtpDate(DateTimeStyles.AssumeUniversal);
            }

            if ((m = Regex.Match(buf, @"size=(?<size>\d+);", RegexOptions.IgnoreCase)).Success)
            {
                long size;

                if (long.TryParse(m.Groups["size"].Value, out size))
                {
                    item.Size = size;
                }
            }

            if ((m = Regex.Match(buf, @"unix.mode=(?<mode>\d+);", RegexOptions.IgnoreCase)).Success)
            {
                if (m.Groups["mode"].Value.Length == 4)
                {
                    item.SpecialPermissions = (FtpSpecialPermissions)int.Parse(m.Groups["mode"].Value[0].ToString());
                    item.OwnerPermissions   = (FtpPermission)int.Parse(m.Groups["mode"].Value[1].ToString());
                    item.GroupPermissions   = (FtpPermission)int.Parse(m.Groups["mode"].Value[2].ToString());
                    item.OthersPermissions  = (FtpPermission)int.Parse(m.Groups["mode"].Value[3].ToString());
                }
                else if (m.Groups["mode"].Value.Length == 3)
                {
                    item.OwnerPermissions  = (FtpPermission)int.Parse(m.Groups["mode"].Value[0].ToString());
                    item.GroupPermissions  = (FtpPermission)int.Parse(m.Groups["mode"].Value[1].ToString());
                    item.OthersPermissions = (FtpPermission)int.Parse(m.Groups["mode"].Value[2].ToString());
                }
            }

            return(item);
        }
Example #21
0
        /// <summary>
        /// Parses MLS* format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        static FtpListItem ParseMachineList(string buf, FtpCapability capabilities)
        {
            FtpListItem item = new FtpListItem();
            Match m;

            if (!(m = Regex.Match(buf, "^type=(?<type>.+?);", RegexOptions.IgnoreCase)).Success)
                return null;

            switch (m.Groups["type"].Value.ToLower()) {
                case "dir":
                    item.Type = FtpFileSystemObjectType.Directory;
                    break;
                case "file":
                    item.Type = FtpFileSystemObjectType.File;
                    break;
                // These are not supported for now.
                case "link":
                case "device":
                default:
                    return null;
            }

            if ((m = Regex.Match(buf, "; (?<name>.*)$", RegexOptions.IgnoreCase)).Success)
                item.Name = m.Groups["name"].Value;
            else // if we can't parse the file name there is a problem.
                return null;

            if ((m = Regex.Match(buf, "modify=(?<modify>.+?);", RegexOptions.IgnoreCase)).Success)
                item.Modified = m.Groups["modify"].Value.GetFtpDate();

            if ((m = Regex.Match(buf, "created?=(?<create>.+?);", RegexOptions.IgnoreCase)).Success)
                item.Created = m.Groups["create"].Value.GetFtpDate();

            if ((m = Regex.Match(buf, @"size=(?<size>\d+);", RegexOptions.IgnoreCase)).Success) {
                long size;

                if (long.TryParse(m.Groups["size"].Value, out size))
                    item.Size = size;
            }

            if((m = Regex.Match(buf, @"unix.mode=(?<mode>\d+);", RegexOptions.IgnoreCase)).Success) {
                if (m.Groups["mode"].Value.Length == 4) {
                    item.SpecialPermissions = (FtpSpecialPermissions)int.Parse(m.Groups["mode"].Value[0].ToString());
                    item.OwnerPermissions = (FtpPermission)int.Parse(m.Groups["mode"].Value[1].ToString());
                    item.GroupPermissions = (FtpPermission)int.Parse(m.Groups["mode"].Value[2].ToString());
                    item.OthersPermissions = (FtpPermission)int.Parse(m.Groups["mode"].Value[3].ToString());
                }
                else if(m.Groups["mode"].Value.Length == 3) {
                    item.OwnerPermissions = (FtpPermission)int.Parse(m.Groups["mode"].Value[0].ToString());
                    item.GroupPermissions = (FtpPermission)int.Parse(m.Groups["mode"].Value[1].ToString());
                    item.OthersPermissions = (FtpPermission)int.Parse(m.Groups["mode"].Value[2].ToString());
                }
            }

            return item;
        }
Example #22
0
        /// <summary>
        /// Parses a line from a file listing using the first successful match in the Parsers collection.
        /// </summary>
        /// <param name="path">The source path of the file listing</param>
        /// <param name="buf">A line from the file listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>A FtpListItem object representing the parsed line, null if the line was
        /// unable to be parsed. If you have encountered an unsupported list type add a parser
        /// to the public static Parsers collection of FtpListItem.</returns>
        public static FtpListItem Parse(string path, string buf, FtpCapability capabilities)
        {
            if (buf != null && buf.Length > 0) {
                FtpListItem item;

                foreach (Parser parser in Parsers) {
                    if ((item = parser(buf, capabilities)) != null) {
                        item.FullName = path.GetFtpPath(item.Name);
                        item.Input = buf;
                        return item;
                    }
                }
            }

            return null;
        }
Example #23
0
        /// <summary>
        /// Parses LIST format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        private static FtpListItem ParseUnixList(string buf, FtpCapability capabilities)
        {
            string regex =
                @"(?<permissions>[dslrwx-]+)\s+" +
                @"(?<objectcount>\d+)\s+" +
                @"(?<user>.+?)\s+" +
                @"(?<group>.+?)\s+" +
                @"(?<size>\d+)\s+" +
                //@"(?<modify>\w+\s+\d+\s+\d+:\d+|\w+\s+\d+\s+\d+|\d+\-\d+\-\d+\-\d+:\d+)\s+" +
                @"(?<modify>\w+\s+\d+\s+\d+:\d+|\w+\s+\d+\s+\d+|\d+\-\d+\-\d+\-\d+:\d+)?\s+" +
                @"(?<name>.*)$";
            FtpListItem item = new FtpListItem();
            Match       m;

            if (!(m = Regex.Match(buf, regex, RegexOptions.IgnoreCase)).Success)
            {
                return(null);
            }

            // if this field is missing we can't determine
            // what the object is.
            if (m.Groups["permissions"].Value.Length == 0)
            {
                return(null);
            }

            switch (m.Groups["permissions"].Value[0])
            {
            case 'd':
                item.Type = FtpFileSystemObjectType.Directory;
                break;

            case '-':
            case 's':
                item.Type = FtpFileSystemObjectType.File;
                break;

            case 'l':
                item.Type = FtpFileSystemObjectType.Link;
                break;

            default:
                return(null);
            }

            // if we can't determine a file name then
            // we are not considering this a successful parsing operation.
            if (m.Groups["name"].Value.Length < 1)
            {
                return(null);
            }
            item.Name = m.Groups["name"].Value;

            switch (item.Type)
            {
            case FtpFileSystemObjectType.Directory:
                // ignore these...
                if (item.Name == "." || item.Name == "..")
                {
                    return(null);
                }
                break;

            case FtpFileSystemObjectType.Link:
                if (!item.Name.Contains(" -> "))
                {
                    return(null);
                }
                item.LinkTarget = item.Name.Remove(0, item.Name.IndexOf("-> ") + 3);
                item.Name       = item.Name.Remove(item.Name.IndexOf(" -> "));
                break;
            }

            ////
            // Modify times for files in LIST format isn't as accurate as what can be had by using the MDTM command.
            // MDTM does not work on directories
            ////

            //if (((capabilities & FtpCapability.MDTM) != FtpCapability.MDTM ||
            //     item.Type == FtpFileSystemObjectType.Directory) && m.Groups["modify"].Value.Length > 0)
            item.Modified = m.Groups["modify"].Value.GetFtpDate(DateTimeStyles.AssumeLocal);

            if (m.Groups["size"].Value.Length > 0)
            {
                long size;

                if (long.TryParse(m.Groups["size"].Value, out size))
                {
                    item.Size = size;
                }
            }

            if (m.Groups["permissions"].Value.Length > 0)
            {
                Match perms = Regex.Match(m.Groups["permissions"].Value,
                                          @"[\w-]{1}(?<owner>[\w-]{3})(?<group>[\w-]{3})(?<others>[\w-]{3})",
                                          RegexOptions.IgnoreCase);

                if (perms.Success)
                {
                    if (perms.Groups["owner"].Value.Length == 3)
                    {
                        if (perms.Groups["owner"].Value[0] == 'r')
                        {
                            item.OwnerPermissions |= FtpPermission.Read;
                        }
                        if (perms.Groups["owner"].Value[1] == 'w')
                        {
                            item.OwnerPermissions |= FtpPermission.Write;
                        }
                        if (perms.Groups["owner"].Value[2] == 'x' || perms.Groups["owner"].Value[2] == 's')
                        {
                            item.OwnerPermissions |= FtpPermission.Execute;
                        }
                        if (perms.Groups["owner"].Value[2] == 's' || perms.Groups["owner"].Value[2] == 'S')
                        {
                            item.SpecialPermissions |= FtpSpecialPermissions.SetUserID;
                        }
                    }

                    if (perms.Groups["group"].Value.Length == 3)
                    {
                        if (perms.Groups["group"].Value[0] == 'r')
                        {
                            item.GroupPermissions |= FtpPermission.Read;
                        }
                        if (perms.Groups["group"].Value[1] == 'w')
                        {
                            item.GroupPermissions |= FtpPermission.Write;
                        }
                        if (perms.Groups["group"].Value[2] == 'x' || perms.Groups["group"].Value[2] == 's')
                        {
                            item.GroupPermissions |= FtpPermission.Execute;
                        }
                        if (perms.Groups["group"].Value[2] == 's' || perms.Groups["group"].Value[2] == 'S')
                        {
                            item.SpecialPermissions |= FtpSpecialPermissions.SetGroupID;
                        }
                    }

                    if (perms.Groups["others"].Value.Length == 3)
                    {
                        if (perms.Groups["others"].Value[0] == 'r')
                        {
                            item.OthersPermissions |= FtpPermission.Read;
                        }
                        if (perms.Groups["others"].Value[1] == 'w')
                        {
                            item.OthersPermissions |= FtpPermission.Write;
                        }
                        if (perms.Groups["others"].Value[2] == 'x' || perms.Groups["others"].Value[2] == 't')
                        {
                            item.OthersPermissions |= FtpPermission.Execute;
                        }
                        if (perms.Groups["others"].Value[2] == 't' || perms.Groups["others"].Value[2] == 'T')
                        {
                            item.SpecialPermissions |= FtpSpecialPermissions.Sticky;
                        }
                    }
                }
            }

            return(item);
        }
        /// <summary>
        /// Connect to the server
        /// </summary>
        public async Task ConnectAsync()
        {
            if (m_Stream == null)
            {
                m_Stream = new FtpStreamChannel();
            }
            else
            {
                if (IsConnected)
                {
                    await DisconnectAsync();
                }
            }

            if (HostName == null)
            {
                throw new FtpException("No host has been specified");
            }

            if (Credentials == null)
            {
                throw new FtpException("No credentials have been specified");
            }

            FtpResponse reply;

            if (await m_Stream.ConnectAsync(HostName, ServiceName))
            {
                if (!(reply = await GetReplyAsync()).Success)
                {
                    if (reply.Code == null)
                    {
                        throw new IOException("The connection was terminated before a greeting could be read.");
                    }

                    throw new FtpCommandException(reply);
                }
            }

            // TODO: If the encryption mode is set to explicit, raise to SSL

            if (Credentials != null)
            {
                await AuthenticateAsync(Credentials);
            }

            if ((reply = await m_Stream.GetFeaturesAsync()).Success)
            {
                m_Caps = ((FtpFeaturesResponse)reply).Features;
            }

            // Enable UTF8 if it's available
            if (m_Caps.HasFlag(FtpCapability.UTF8))
            {
                // If the server supports UTF8 it should already be enabled and this
                // command should not matter however there are conflicting drafts
                // about this so we'll just execute it to be safe.
                await m_Stream.SetOptionsAsync("UTF8 ON");

                m_Stream.Encoding = Encoding.UTF8;
            }
        }
 /// <summary>
 /// Removes the specified capability from the list
 /// </summary>
 /// <param name="cap"></param>
 public void RemoveCapability(FtpCapability cap)
 {
     this.Capabilities &= ~(cap);
 }
Example #26
0
        /// <summary>
        /// Parses LIST format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        static FtpListItem ParseUnixList(string buf, FtpCapability capabilities, FtpClient client)
        {
            FtpListItem item  = new FtpListItem();
            Match       m     = null;
            string      regex =
                @"(?<permissions>[\w-]{10})\s+" +
                @"(?<objectcount>\d+)\s+" +
                @"(?<user>[\w\d]+)\s+" +
                @"(?<group>[\w\d]+)\s+" +
                @"(?<size>\d+)\s+" +
                @"(?<modify>\w+\s+\d+\s+\d+:\d+|\w+\s+\d+\s+\d+)\s+" +
                @"(?<name>.*)$";

            if (!(m = Regex.Match(buf, regex, RegexOptions.IgnoreCase)).Success)
            {
                return(null);
            }

            if (m.Groups["permissions"].Value.StartsWith("d"))
            {
                item.Type = FtpFileSystemObjectType.Directory;
            }
            else if (m.Groups["permissions"].Value.StartsWith("-"))
            {
                item.Type = FtpFileSystemObjectType.File;
            }
            else
            {
                return(null);
            }

            // if we can't determine a file name then
            // we are not considering this a successful parsing operation.
            if (m.Groups["name"].Value.Length < 1)
            {
                return(null);
            }
            item.Name = m.Groups["name"].Value;

            if (item.Type == FtpFileSystemObjectType.Directory && (item.Name == "." || item.Name == ".."))
            {
                return(null);
            }

            ////
            // Ignore the Modify times sent in LIST format for files
            // when the server has support for the MDTM command
            // because they will never be as accurate as what can be had
            // by using the MDTM command. MDTM does not work on directories
            // so if a modify time was parsed from the listing we will try
            // to convert it to a DateTime object and use it for directories.
            ////
            if ((!capabilities.HasFlag(FtpCapability.MDTM) || item.Type == FtpFileSystemObjectType.Directory) && m.Groups["modify"].Value.Length > 0)
            {
                item.Modified = m.Groups["modify"].Value.GetFtpDate(DateTimeStyles.AssumeUniversal);
            }

            if (m.Groups["size"].Value.Length > 0)
            {
                long size;

                if (long.TryParse(m.Groups["size"].Value, out size))
                {
                    item.Size = size;
                }
            }

            if (m.Groups["permissions"].Value.Length > 0)
            {
                Match perms = Regex.Match(m.Groups["permissions"].Value,
                                          @"[\w-]{1}(?<owner>[\w-]{3})(?<group>[\w-]{3})(?<others>[\w-]{3})",
                                          RegexOptions.IgnoreCase);

                if (perms.Success)
                {
                    if (perms.Groups["owner"].Value.Length == 3)
                    {
                        if (perms.Groups["owner"].Value[0] == 'r')
                        {
                            item.OwnerPermissions |= FtpPermission.Read;
                        }
                        if (perms.Groups["owner"].Value[1] == 'w')
                        {
                            item.OwnerPermissions |= FtpPermission.Write;
                        }
                        if (perms.Groups["owner"].Value[2] == 'x' || perms.Groups["owner"].Value[2] == 's')
                        {
                            item.OwnerPermissions |= FtpPermission.Execute;
                        }
                        if (perms.Groups["owner"].Value[2] == 's' || perms.Groups["owner"].Value[2] == 'S')
                        {
                            item.SpecialPermissions |= FtpSpecialPermissions.SetUserID;
                        }
                    }

                    if (perms.Groups["group"].Value.Length == 3)
                    {
                        if (perms.Groups["group"].Value[0] == 'r')
                        {
                            item.GroupPermissions |= FtpPermission.Read;
                        }
                        if (perms.Groups["group"].Value[1] == 'w')
                        {
                            item.GroupPermissions |= FtpPermission.Write;
                        }
                        if (perms.Groups["group"].Value[2] == 'x' || perms.Groups["group"].Value[2] == 's')
                        {
                            item.GroupPermissions |= FtpPermission.Execute;
                        }
                        if (perms.Groups["group"].Value[2] == 's' || perms.Groups["group"].Value[2] == 'S')
                        {
                            item.SpecialPermissions |= FtpSpecialPermissions.SetGroupID;
                        }
                    }

                    if (perms.Groups["others"].Value.Length == 3)
                    {
                        if (perms.Groups["others"].Value[0] == 'r')
                        {
                            item.OthersPermissions |= FtpPermission.Read;
                        }
                        if (perms.Groups["others"].Value[1] == 'w')
                        {
                            item.OthersPermissions |= FtpPermission.Write;
                        }
                        if (perms.Groups["others"].Value[2] == 'x' || perms.Groups["others"].Value[2] == 't')
                        {
                            item.OthersPermissions |= FtpPermission.Execute;
                        }
                        if (perms.Groups["others"].Value[2] == 't' || perms.Groups["others"].Value[2] == 'T')
                        {
                            item.SpecialPermissions |= FtpSpecialPermissions.Sticky;
                        }
                    }
                }
            }

            return(item);
        }
 /// <summary>
 /// Checks if the server supports the specified capability
 /// </summary>
 /// <param name="cap"></param>
 public bool HasCapability(FtpCapability cap)
 {
     return((this.Capabilities & cap) == cap);
 }
Example #28
0
        /// <summary>
        /// Parses a line from a file listing using the first successful match in the Parsers collection.
        /// </summary>
        /// <param name="path">The source path of the file listing</param>
        /// <param name="buf">A line from the file listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <param name="matchingParser"></param>
        /// <returns>A FtpListItem object representing the parsed line, null if the line was
        /// unable to be parsed. If you have encountered an unsupported list type add a parser
        /// to the public static Parsers collection of FtpListItem.</returns>
        public static FtpListItem Parse(string path, string buf, FtpCapability capabilities, out Parser matchingParser)
        {
            matchingParser = null;
            if (string.IsNullOrEmpty(buf)) return null;

            foreach (var parser in Parsers)
            {
                FtpListItem item;
                if ((item = parser(buf, capabilities)) == null) continue;
                matchingParser = parser;
                PostParse(path, buf, parser, item); 
                return item;
            }
            return null;
        }
Example #29
0
        /// <summary>
        /// Parses IIS DOS format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        static FtpListItem ParseDosList(string buf, FtpCapability capabilities)
        {
            FtpListItem item = new FtpListItem();
            Match m;

            // directory
            if ((m = Regex.Match(buf, @"(?<modify>\d+-\d+-\d+\s+\d+:\d+\w+)\s+<DIR>\s+(?<name>.*)$", RegexOptions.IgnoreCase)).Success) {
                DateTime modify;

                item.Type = FtpFileSystemObjectType.Directory;
                item.Name = m.Groups["name"].Value;

                if (DateTime.TryParse(m.Groups["modify"].Value, out modify))
                    item.Modified = modify;
            }
            // file
            else if ((m = Regex.Match(buf, @"(?<modify>\d+-\d+-\d+\s+\d+:\d+\w+)\s+(?<size>\d+)\s+(?<name>.*)$", RegexOptions.IgnoreCase)).Success) {
                DateTime modify;
                long size;

                item.Type = FtpFileSystemObjectType.File;
                item.Name = m.Groups["name"].Value;

                if (long.TryParse(m.Groups["size"].Value, out size))
                    item.Size = size;

                if (DateTime.TryParse(m.Groups["modify"].Value, out modify))
                    item.Modified = modify;
            }
            else
                return null;

            return item;
        }
Example #30
0
 public static FtpListItem ParseWith(string path, string buf, FtpCapability capabilities, Parser parser)
 {
     var item = parser(buf, capabilities);
     if (item != null) PostParse(path, buf, parser, item);
     return item;
 }
Example #31
0
        /// <summary>
        /// Parses LIST format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        static FtpListItem ParseUnixList(string buf, FtpCapability capabilities)
        {
            string regex =
                @"(?<permissions>[\w-]{10})\s+" +
                @"(?<objectcount>\d+)\s+" +
                @"(?<user>[\w\d]+)\s+" +
                @"(?<group>[\w\d]+)\s+" +
                @"(?<size>\d+)\s+" +
                @"(?<modify>\w+\s+\d+\s+\d+:\d+|\w+\s+\d+\s+\d+)\s+" +
                @"(?<name>.*)$";
            FtpListItem item = new FtpListItem();
            Match m;

            if (!(m = Regex.Match(buf, regex, RegexOptions.IgnoreCase)).Success)
                return null;

            if (m.Groups["permissions"].Value.StartsWith("d"))
                item.Type = FtpFileSystemObjectType.Directory;
            else if (m.Groups["permissions"].Value.StartsWith("-"))
                item.Type = FtpFileSystemObjectType.File;
            else
                return null;

            // if we can't determine a file name then
            // we are not considering this a successful parsing operation.
            if (m.Groups["name"].Value.Length < 1)
                return null;
            item.Name = m.Groups["name"].Value;

            if (item.Type == FtpFileSystemObjectType.Directory && (item.Name == "." || item.Name == ".."))
                return null;

            ////
            // Ignore the Modify times sent in LIST format for files
            // when the server has support for the MDTM command
            // because they will never be as accurate as what can be had
            // by using the MDTM command. MDTM does not work on directories
            // so if a modify time was parsed from the listing we will try
            // to convert it to a DateTime object and use it for directories.
            ////
            if ((!capabilities.HasFlag(FtpCapability.MDTM) || item.Type == FtpFileSystemObjectType.Directory) && m.Groups["modify"].Value.Length > 0)
                item.Modified = m.Groups["modify"].Value.GetFtpDate();

            if (m.Groups["size"].Value.Length > 0) {
                long size;

                if (long.TryParse(m.Groups["size"].Value, out size))
                    item.Size = size;
            }

            if (m.Groups["permissions"].Value.Length > 0) {
                Match perms = Regex.Match(m.Groups["permissions"].Value,
                    @"[\w-]{1}(?<owner>[\w-]{3})(?<group>[\w-]{3})(?<others>[\w-]{3})",
                    RegexOptions.IgnoreCase);

                if (perms.Success) {
                    if (perms.Groups["owner"].Value.Length == 3) {
                        if (perms.Groups["owner"].Value[0] == 'r')
                            item.OwnerPermissions |= FtpPermission.Read;
                        if (perms.Groups["owner"].Value[1] == 'w')
                            item.OwnerPermissions |= FtpPermission.Write;
                        if (perms.Groups["owner"].Value[2] == 'x' || perms.Groups["owner"].Value[2] == 's')
                            item.OwnerPermissions |= FtpPermission.Execute;
                        if (perms.Groups["owner"].Value[2] == 's' || perms.Groups["owner"].Value[2] == 'S')
                            item.SpecialPermissions |= FtpSpecialPermissions.SetUserID;
                    }

                    if (perms.Groups["group"].Value.Length == 3) {
                        if (perms.Groups["group"].Value[0] == 'r')
                            item.GroupPermissions |= FtpPermission.Read;
                        if (perms.Groups["group"].Value[1] == 'w')
                            item.GroupPermissions |= FtpPermission.Write;
                        if (perms.Groups["group"].Value[2] == 'x' || perms.Groups["group"].Value[2] == 's')
                            item.GroupPermissions |= FtpPermission.Execute;
                        if (perms.Groups["group"].Value[2] == 's' || perms.Groups["group"].Value[2] == 'S')
                            item.SpecialPermissions |= FtpSpecialPermissions.SetGroupID;
                    }

                    if (perms.Groups["others"].Value.Length == 3) {
                        if (perms.Groups["others"].Value[0] == 'r')
                            item.OthersPermissions |= FtpPermission.Read;
                        if (perms.Groups["others"].Value[1] == 'w')
                            item.OthersPermissions |= FtpPermission.Write;
                        if (perms.Groups["others"].Value[2] == 'x' || perms.Groups["others"].Value[2] == 't')
                            item.OthersPermissions |= FtpPermission.Execute;
                        if (perms.Groups["others"].Value[2] == 't' || perms.Groups["others"].Value[2] == 'T')
                            item.SpecialPermissions |= FtpSpecialPermissions.Sticky;
                    }
                }
            }

            return item;
        }
Example #32
0
        private static FtpListItem ParseMachineList(string buf, FtpCapability capabilities)
        {
            Match       match;
            long        num;
            FtpListItem item = new FtpListItem();

            if ((match = Regex.Match(buf, "type=(?<type>.+?);", RegexOptions.IgnoreCase)).Success)
            {
                switch (match.Groups["type"].Value.ToLower())
                {
                case "dir":
                case "pdir":
                case "cdir":
                    item.Type = FtpFileSystemObjectType.Directory;
                    goto Label_00E2;

                case "file":
                    item.Type = FtpFileSystemObjectType.File;
                    goto Label_00E2;
                }
            }
            return(null);

Label_00E2:
            if ((match = Regex.Match(buf, "; (?<name>.*)$", RegexOptions.IgnoreCase)).Success)
            {
                item.Name = match.Groups["name"].Value;
            }
            else
            {
                return(null);
            }
            if ((match = Regex.Match(buf, "modify=(?<modify>.+?);", RegexOptions.IgnoreCase)).Success)
            {
                item.Modified = match.Groups["modify"].Value.GetFtpDate(DateTimeStyles.AssumeUniversal);
            }
            if ((match = Regex.Match(buf, "created?=(?<create>.+?);", RegexOptions.IgnoreCase)).Success)
            {
                item.Created = match.Groups["create"].Value.GetFtpDate(DateTimeStyles.AssumeUniversal);
            }
            if ((match = Regex.Match(buf, @"size=(?<size>\d+);", RegexOptions.IgnoreCase)).Success && long.TryParse(match.Groups["size"].Value, out num))
            {
                item.Size = num;
            }
            if ((match = Regex.Match(buf, @"unix.mode=(?<mode>\d+);", RegexOptions.IgnoreCase)).Success)
            {
                if (match.Groups["mode"].Value.Length == 4)
                {
                    char ch = match.Groups["mode"].Value[0];
                    item.SpecialPermissions = (FtpSpecialPermissions)int.Parse(ch.ToString());
                    char ch2 = match.Groups["mode"].Value[1];
                    item.OwnerPermissions = (FtpPermission)int.Parse(ch2.ToString());
                    char ch3 = match.Groups["mode"].Value[2];
                    item.GroupPermissions = (FtpPermission)int.Parse(ch3.ToString());
                    char ch4 = match.Groups["mode"].Value[3];
                    item.OthersPermissions = (FtpPermission)int.Parse(ch4.ToString());
                    return(item);
                }
                if (match.Groups["mode"].Value.Length == 3)
                {
                    char ch5 = match.Groups["mode"].Value[0];
                    item.OwnerPermissions = (FtpPermission)int.Parse(ch5.ToString());
                    char ch6 = match.Groups["mode"].Value[1];
                    item.GroupPermissions = (FtpPermission)int.Parse(ch6.ToString());
                    char ch7 = match.Groups["mode"].Value[2];
                    item.OthersPermissions = (FtpPermission)int.Parse(ch7.ToString());
                }
            }
            return(item);
        }
Example #33
0
 public static bool HasFlag(this FtpCapability flags, FtpCapability flag)
 {
     return((flags & flag) == flag);
 }
 /// <summary>
 /// Removes the specified capability from the list
 /// </summary>
 /// <param name="cap"></param>
 public void RemoveCapability(FtpCapability cap) {
     this.Capabilities &= ~(cap);
 }
Example #35
0
        /// <summary>
        /// Parses LIST format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        internal static FtpListItem ParseUnixList(string buf, FtpCapability capabilities)
        {
            string regex =
                @"(?<permissions>.+)\s+" +
                @"(?<objectcount>\d+)\s+" +
                @"(?<user>.+)\s+" +
                @"(?<group>.+)\s+" +
                @"(?<size>\d+)\s+" +
                @"(?<modify>\w+\s+\d+\s+\d+:\d+|\w+\s+\d+\s+\d+)\s" +
                @"(?<name>.*)$";
            Match m;

            if (!(m = Regex.Match(buf, regex, RegexOptions.IgnoreCase)).Success)
            {
                return(null);
            }

            // if this field is missing we can't determine
            // what the object is.
            if (m.Groups["permissions"].Value.Length == 0)
            {
                return(null);
            }

            FtpListItem item = new FtpListItem();

            switch (m.Groups["permissions"].Value[0])
            {
            case 'd':
                item.Type = FtpFileSystemObjectType.Directory;
                break;

            case '-':
            case 's':
                item.Type = FtpFileSystemObjectType.File;
                break;

            case 'l':
                item.Type = FtpFileSystemObjectType.Link;
                break;

            default:
                return(null);
            }

            // if we can't determine a file name then
            // we are not considering this a successful parsing operation.
            if (m.Groups["name"].Value.Length < 1)
            {
                return(null);
            }
            item.Name = m.Groups["name"].Value;

            switch (item.Type)
            {
            case FtpFileSystemObjectType.Directory:
                // ignore these...
                if (item.Name == "." || item.Name == "..")
                {
                    return(null);
                }
                break;

            case FtpFileSystemObjectType.Link:
                if (!item.Name.Contains(" -> "))
                {
                    return(null);
                }
                item.LinkTarget = item.Name.Remove(0, item.Name.IndexOf("-> ") + 3);
                item.Name       = item.Name.Remove(item.Name.IndexOf(" -> "));
                break;
            }

            // for date parser testing only
            //capabilities = ~(capabilities & FtpCapability.MDTM);

            ////
            // Ignore the Modify times sent in LIST format for files
            // when the server has support for the MDTM command
            // because they will never be as accurate as what can be had
            // by using the MDTM command. MDTM does not work on directories
            // so if a modify time was parsed from the listing we will try
            // to convert it to a DateTime object and use it for directories.
            ////
            if (((capabilities & FtpCapability.MDTM) != FtpCapability.MDTM || item.Type == FtpFileSystemObjectType.Directory) && m.Groups["modify"].Value.Length > 0)
            {
                item.Modified = m.Groups["modify"].Value.GetFtpDate(DateTimeStyles.AssumeLocal);
                if (item.Modified == DateTime.MinValue)
                {
                    FtpTrace.WriteLine("GetFtpDate() failed on {0}", m.Groups["modify"].Value);
                }
            }
            else
            {
                if (m.Groups["modify"].Value.Length == 0)
                {
                    FtpTrace.WriteLine("RegEx failed to parse modified date from {0}.", buf);
                }
                else if (item.Type == FtpFileSystemObjectType.Directory)
                {
                    FtpTrace.WriteLine("Modified times of directories are ignored in UNIX long listings.");
                }
                else if ((capabilities & FtpCapability.MDTM) == FtpCapability.MDTM)
                {
                    FtpTrace.WriteLine("Ignoring modified date because MDTM feature is present. If you aren't already, pass FtpListOption.Modify or FtpListOption.SizeModify to GetListing() to retrieve the modification time.");
                }
            }

            if (m.Groups["size"].Value.Length > 0)
            {
                long size;

                if (long.TryParse(m.Groups["size"].Value, out size))
                {
                    item.Size = size;
                }
            }

            if (m.Groups["permissions"].Value.Length > 0)
            {
                Match perms = Regex.Match(m.Groups["permissions"].Value,
                                          @"[\w-]{1}(?<owner>[\w-]{3})(?<group>[\w-]{3})(?<others>[\w-]{3})",
                                          RegexOptions.IgnoreCase);

                if (perms.Success)
                {
                    if (perms.Groups["owner"].Value.Length == 3)
                    {
                        if (perms.Groups["owner"].Value[0] == 'r')
                        {
                            item.OwnerPermissions |= FtpPermission.Read;
                        }
                        if (perms.Groups["owner"].Value[1] == 'w')
                        {
                            item.OwnerPermissions |= FtpPermission.Write;
                        }
                        if (perms.Groups["owner"].Value[2] == 'x' || perms.Groups["owner"].Value[2] == 's')
                        {
                            item.OwnerPermissions |= FtpPermission.Execute;
                        }
                        if (perms.Groups["owner"].Value[2] == 's' || perms.Groups["owner"].Value[2] == 'S')
                        {
                            item.SpecialPermissions |= FtpSpecialPermissions.SetUserID;
                        }
                    }

                    if (perms.Groups["group"].Value.Length == 3)
                    {
                        if (perms.Groups["group"].Value[0] == 'r')
                        {
                            item.GroupPermissions |= FtpPermission.Read;
                        }
                        if (perms.Groups["group"].Value[1] == 'w')
                        {
                            item.GroupPermissions |= FtpPermission.Write;
                        }
                        if (perms.Groups["group"].Value[2] == 'x' || perms.Groups["group"].Value[2] == 's')
                        {
                            item.GroupPermissions |= FtpPermission.Execute;
                        }
                        if (perms.Groups["group"].Value[2] == 's' || perms.Groups["group"].Value[2] == 'S')
                        {
                            item.SpecialPermissions |= FtpSpecialPermissions.SetGroupID;
                        }
                    }

                    if (perms.Groups["others"].Value.Length == 3)
                    {
                        if (perms.Groups["others"].Value[0] == 'r')
                        {
                            item.OthersPermissions |= FtpPermission.Read;
                        }
                        if (perms.Groups["others"].Value[1] == 'w')
                        {
                            item.OthersPermissions |= FtpPermission.Write;
                        }
                        if (perms.Groups["others"].Value[2] == 'x' || perms.Groups["others"].Value[2] == 't')
                        {
                            item.OthersPermissions |= FtpPermission.Execute;
                        }
                        if (perms.Groups["others"].Value[2] == 't' || perms.Groups["others"].Value[2] == 'T')
                        {
                            item.SpecialPermissions |= FtpSpecialPermissions.Sticky;
                        }
                    }
                }
            }

            return(item);
        }
Example #36
0
        /// <summary>
        /// Parses IIS DOS format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        static FtpListItem ParseDosList(string buf, FtpCapability capabilities) {
            FtpListItem item = new FtpListItem();
            string[] datefmt = new string[] {
                "MM-dd-yy  hh:mmtt",
                "MM-dd-yyyy  hh:mmtt"
            };
            Match m;

            // directory
            if ((m = Regex.Match(buf, @"(?<modify>\d+-\d+-\d+\s+\d+:\d+\w+)\s+<DIR>\s+(?<name>.*)$", RegexOptions.IgnoreCase)).Success) {
                DateTime modify;

                item.Type = FtpFileSystemObjectType.Directory;
                item.Name = m.Groups["name"].Value;

                //if (DateTime.TryParse(m.Groups["modify"].Value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out modify))
                if (DateTime.TryParseExact(m.Groups["modify"].Value, datefmt, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out modify))
                    item.Modified = modify;
            }
            // file
            else if ((m = Regex.Match(buf, @"(?<modify>\d+-\d+-\d+\s+\d+:\d+\w+)\s+(?<size>\d+)\s+(?<name>.*)$", RegexOptions.IgnoreCase)).Success) {
                DateTime modify;
                long size;

                item.Type = FtpFileSystemObjectType.File;
                item.Name = m.Groups["name"].Value;

                if (long.TryParse(m.Groups["size"].Value, out size))
                    item.Size = size;

                //if (DateTime.TryParse(m.Groups["modify"].Value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out modify))
                if (DateTime.TryParseExact(m.Groups["modify"].Value, datefmt, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out modify))
                    item.Modified = modify;
            }
            else
                return null;

            return item;
        }
Example #37
0
        /// <summary>
        /// Parses LIST format listings
        /// </summary>
        /// <param name="record">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        public static FtpListItem ParseLegacy(string record, FtpCapability capabilities, FtpClient client)
        {
            string regex =
                @"(?<permissions>.+)\s+" +
                @"(?<objectcount>\d+)\s+" +
                @"(?<user>.+)\s+" +
                @"(?<group>.+)\s+" +
                @"(?<size>\d+)\s+" +
                @"(?<modify>\w+\s+\d+\s+\d+:\d+|\w+\s+\d+\s+\d+)\s" +
                @"(?<name>.*)$";
            FtpListItem item = new FtpListItem();
            Match       m;

            if (!(m = Regex.Match(record, regex, RegexOptions.IgnoreCase)).Success)
            {
                return(null);
            }

            // if this field is missing we can't determine
            // what the object is.
            if (m.Groups["permissions"].Value.Length == 0)
            {
                return(null);
            }
            switch (m.Groups["permissions"].Value[0])
            {
            case 'd':
                item.Type = FtpFileSystemObjectType.Directory;
                break;

            case '-':
            case 's':
                item.Type = FtpFileSystemObjectType.File;
                break;

            case 'l':
                item.Type = FtpFileSystemObjectType.Link;
                break;

            default:
                return(null);
            }

            // if we can't determine a file name then
            // we are not considering this a successful parsing operation.
            if (m.Groups["name"].Value.Length < 1)
            {
                return(null);
            }
            item.Name = m.Groups["name"].Value;

            switch (item.Type)
            {
            case FtpFileSystemObjectType.Directory:
                // ignore these...
                if (item.Name == "." || item.Name == "..")
                {
                    return(null);
                }
                break;

            case FtpFileSystemObjectType.Link:
                if (!item.Name.Contains(" -> "))
                {
                    return(null);
                }
                item.LinkTarget = item.Name.Remove(0, item.Name.IndexOf("-> ") + 3).Trim();
                item.Name       = item.Name.Remove(item.Name.IndexOf(" -> "));
                break;
            }


            // Ignore the Modify times sent in LIST format for files
            // when the server has support for the MDTM command
            // because they will never be as accurate as what can be had
            // by using the MDTM command. MDTM does not work on directories
            // so if a modify time was parsed from the listing we will try
            // to convert it to a DateTime object and use it for directories.
            ////
            if (((capabilities & FtpCapability.MDTM) != FtpCapability.MDTM || item.Type == FtpFileSystemObjectType.Directory) && m.Groups["modify"].Value.Length > 0)
            {
                item.Modified = m.Groups["modify"].Value.GetFtpDate(DateTimeStyles.AssumeLocal);
                if (item.Modified == DateTime.MinValue)
                {
                    client.LogStatus(FtpTraceLevel.Warn, "GetFtpDate() failed on " + m.Groups["modify"].Value);
                }
            }
            else
            {
                if (m.Groups["modify"].Value.Length == 0)
                {
                    client.LogStatus(FtpTraceLevel.Warn, "RegEx failed to parse modified date from " + record);
                }
                else if (item.Type == FtpFileSystemObjectType.Directory)
                {
                    client.LogStatus(FtpTraceLevel.Warn, "Modified times of directories are ignored in UNIX long listings.");
                }
                else if ((capabilities & FtpCapability.MDTM) == FtpCapability.MDTM)
                {
                    client.LogStatus(FtpTraceLevel.Warn, "Ignoring modified date because MDTM feature is present. If you aren't already, pass FtpListOption.Modify or FtpListOption.SizeModify to GetListing() to retrieve the modification time.");
                }
            }

            if (m.Groups["size"].Value.Length > 0)
            {
                long size;

                if (long.TryParse(m.Groups["size"].Value, out size))
                {
                    item.Size = size;
                }
            }

            if (m.Groups["permissions"].Value.Length > 0)
            {
                item.CalculateUnixPermissions(m.Groups["permissions"].Value);
            }

            return(item);
        }
Example #38
0
 /// <summary>
 /// Populates the capabilities flags based on capabilities
 /// supported by this server. This method is overridable
 /// so that new features can be supported
 /// </summary>
 /// <param name="reply">The reply object from the FEAT command. The InfoMessages property will
 /// contain a list of the features the server supported delimited by a new line '\n' character.</param>
 internal void ParseFeatures(FtpResponse reply)
 {
     foreach (string feat in reply.InfoMessages.Split(new[] {"\r\n"}, StringSplitOptions.RemoveEmptyEntries))
     {
         if (feat.ToUpper().Trim().StartsWith("MLST") || feat.ToUpper().Trim().StartsWith("MLSD"))
             m_Caps |= FtpCapability.MLSD;
         else if (feat.ToUpper().Trim().StartsWith("MDTM"))
             m_Caps |= FtpCapability.MDTM;
         else if (feat.ToUpper().Trim().StartsWith("REST STREAM"))
             m_Caps |= FtpCapability.REST;
         else if (feat.ToUpper().Trim().StartsWith("SIZE"))
             m_Caps |= FtpCapability.SIZE;
         else if (feat.ToUpper().Trim().StartsWith("UTF8"))
             m_Caps |= FtpCapability.UTF8;
         else if (feat.ToUpper().Trim().StartsWith("PRET"))
             m_Caps |= FtpCapability.PRET;
         else if (feat.ToUpper().Trim().StartsWith("MFMT"))
             m_Caps |= FtpCapability.MFMT;
         else if (feat.ToUpper().Trim().StartsWith("MFCT"))
             m_Caps |= FtpCapability.MFCT;
         else if (feat.ToUpper().Trim().StartsWith("MFF"))
             m_Caps |= FtpCapability.MFF;
     }
 }
Example #39
0
        private static FtpListItem ParseUnixList(string buf, FtpCapability capabilities)
        {
            Match       match;
            long        num;
            string      pattern = @"(?<permissions>.+)\s+(?<objectcount>\d+)\s+(?<user>.+)\s+(?<group>.+)\s+(?<size>\d+)\s+(?<modify>\w+\s+\d+\s+\d+:\d+|\w+\s+\d+\s+\d+)\s(?<name>.*)$";
            FtpListItem item    = new FtpListItem();

            if ((match = Regex.Match(buf, pattern, RegexOptions.IgnoreCase)).Success)
            {
                if (match.Groups["permissions"].Value.Length == 0)
                {
                    return(null);
                }
                switch (match.Groups["permissions"].Value[0])
                {
                case 'l':
                    item.Type = FtpFileSystemObjectType.Link;
                    goto Label_0099;

                case 's':
                case '-':
                    item.Type = FtpFileSystemObjectType.File;
                    goto Label_0099;

                case 'd':
                    item.Type = FtpFileSystemObjectType.Directory;
                    goto Label_0099;
                }
            }
            return(null);

Label_0099:
            if (match.Groups["name"].Value.Length < 1)
            {
                return(null);
            }
            item.Name = match.Groups["name"].Value;
            switch (item.Type)
            {
            case FtpFileSystemObjectType.Directory:
                if (!(item.Name == ".") && !(item.Name == ".."))
                {
                    break;
                }
                return(null);

            case FtpFileSystemObjectType.Link:
                if (item.Name.Contains(" -> "))
                {
                    item.LinkTarget = item.Name.Remove(0, item.Name.IndexOf("-> ") + 3);
                    item.Name       = item.Name.Remove(item.Name.IndexOf(" -> "));
                    break;
                }
                return(null);
            }
            if ((((capabilities & FtpCapability.MDTM) != FtpCapability.MDTM) || (item.Type == FtpFileSystemObjectType.Directory)) && (match.Groups["modify"].Value.Length > 0))
            {
                item.Modified = match.Groups["modify"].Value.GetFtpDate(DateTimeStyles.AssumeLocal);
                if (item.Modified == DateTime.MinValue)
                {
                    FtpTrace.WriteLine("GetFtpDate() failed on {0}", new object[] { match.Groups["modify"].Value });
                }
            }
            else if (match.Groups["modify"].Value.Length == 0)
            {
                FtpTrace.WriteLine("RegEx failed to parse modified date from {0}.", new object[] { buf });
            }
            else if (item.Type == FtpFileSystemObjectType.Directory)
            {
                FtpTrace.WriteLine("Modified times of directories are ignored in UNIX long listings.");
            }
            else if ((capabilities & FtpCapability.MDTM) == FtpCapability.MDTM)
            {
                FtpTrace.WriteLine("Ignoring modified date because MDTM feature is present. If you aren't already, pass FtpListOption.Modify or FtpListOption.SizeModify to GetListing() to retrieve the modification time.");
            }
            if ((match.Groups["size"].Value.Length > 0) && long.TryParse(match.Groups["size"].Value, out num))
            {
                item.Size = num;
            }
            if (match.Groups["permissions"].Value.Length > 0)
            {
                Match match2 = Regex.Match(match.Groups["permissions"].Value, @"[\w-]{1}(?<owner>[\w-]{3})(?<group>[\w-]{3})(?<others>[\w-]{3})", RegexOptions.IgnoreCase);
                if (!match2.Success)
                {
                    return(item);
                }
                if (match2.Groups["owner"].Value.Length == 3)
                {
                    if (match2.Groups["owner"].Value[0] == 'r')
                    {
                        item.OwnerPermissions |= FtpPermission.None | FtpPermission.Read;
                    }
                    if (match2.Groups["owner"].Value[1] == 'w')
                    {
                        item.OwnerPermissions |= FtpPermission.None | FtpPermission.Write;
                    }
                    if ((match2.Groups["owner"].Value[2] == 'x') || (match2.Groups["owner"].Value[2] == 's'))
                    {
                        item.OwnerPermissions |= FtpPermission.Execute;
                    }
                    if ((match2.Groups["owner"].Value[2] == 's') || (match2.Groups["owner"].Value[2] == 'S'))
                    {
                        item.SpecialPermissions |= FtpSpecialPermissions.SetUserID;
                    }
                }
                if (match2.Groups["group"].Value.Length == 3)
                {
                    if (match2.Groups["group"].Value[0] == 'r')
                    {
                        item.GroupPermissions |= FtpPermission.None | FtpPermission.Read;
                    }
                    if (match2.Groups["group"].Value[1] == 'w')
                    {
                        item.GroupPermissions |= FtpPermission.None | FtpPermission.Write;
                    }
                    if ((match2.Groups["group"].Value[2] == 'x') || (match2.Groups["group"].Value[2] == 's'))
                    {
                        item.GroupPermissions |= FtpPermission.Execute;
                    }
                    if ((match2.Groups["group"].Value[2] == 's') || (match2.Groups["group"].Value[2] == 'S'))
                    {
                        item.SpecialPermissions |= FtpSpecialPermissions.SetGroupID;
                    }
                }
                if (match2.Groups["others"].Value.Length == 3)
                {
                    if (match2.Groups["others"].Value[0] == 'r')
                    {
                        item.OthersPermissions |= FtpPermission.None | FtpPermission.Read;
                    }
                    if (match2.Groups["others"].Value[1] == 'w')
                    {
                        item.OthersPermissions |= FtpPermission.None | FtpPermission.Write;
                    }
                    if ((match2.Groups["others"].Value[2] == 'x') || (match2.Groups["others"].Value[2] == 't'))
                    {
                        item.OthersPermissions |= FtpPermission.Execute;
                    }
                    if ((match2.Groups["others"].Value[2] != 't') && (match2.Groups["others"].Value[2] != 'T'))
                    {
                        return(item);
                    }
                    item.SpecialPermissions |= FtpSpecialPermissions.Sticky;
                }
            }
            return(item);
        }
Example #40
0
        /// <summary>
        /// Parses a line from a file listing using the first successful match in the Parsers collection.
        /// </summary>
        /// <param name="path">The source path of the file listing</param>
        /// <param name="buf">A line from the file listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>A FtpListItem object representing the parsed line, null if the line was
        /// unable to be parsed. If you have encountered an unsupported list type add a parser
        /// to the public static Parsers collection of FtpListItem.</returns>
        public static FtpListItem Parse(string path, string buf, FtpCapability capabilities) {
            if (buf != null && buf.Length > 0) {
                FtpListItem item;

                foreach (Parser parser in Parsers) {
                    if ((item = parser(buf, capabilities)) != null) {
                        // if this is a vax/openvms file listing
                        // there are no slashes in the path name
                        if (parser == (new Parser(ParseVaxList)))
                            item.FullName = path + item.Name;
                        else {
                            FtpTrace.WriteLine(item.Name);

                            // remove globbing/wildcard from path
                            if (path.GetFtpFileName().Contains("*")) {
                                path = path.GetFtpDirectoryName();
                            }

                            if (item.Name != null) {
                                // absolute path? then ignore the path input to this method.
                                if (item.Name.StartsWith("/") || item.Name.StartsWith("./") || item.Name.StartsWith("../")) {
                                    item.FullName = item.Name;
                                    item.Name = item.Name.GetFtpFileName();
                                }
                                else if(path != null) {
                                    item.FullName = path.GetFtpPath(item.Name); //.GetFtpPathWithoutGlob();
                                }
                                else {
                                    FtpTrace.WriteLine("Couldn't determine the full path of this object:{0}{1}",
                                        Environment.NewLine, item.ToString());
                                }
                            }
                            

                            // if a link target is set and it doesn't include an absolute path
                            // then try to resolve it.
                            if (item.LinkTarget != null && !item.LinkTarget.StartsWith("/")) {
                                if (item.LinkTarget.StartsWith("./"))
                                    item.LinkTarget = path.GetFtpPath(item.LinkTarget.Remove(0, 2));
                                else
                                    item.LinkTarget = path.GetFtpPath(item.LinkTarget);
                            }
                        }

                        item.Input = buf;
                        return item;
                    }
                }
            }

            return null;
        }
Example #41
0
        /// <summary>
        /// Parses LIST format listings
        /// </summary>
        /// <param name="buf">A line from the listing</param>
        /// <param name="capabilities">Server capabilities</param>
        /// <returns>FtpListItem if the item is able to be parsed</returns>
        static FtpListItem ParseUnixList(string buf, FtpCapability capabilities) {
            string regex =
                @"(?<permissions>.+)\s+" +
                @"(?<objectcount>\d+)\s+" +
                @"(?<user>.+)\s+" +
                @"(?<group>.+)\s+" +
                @"(?<size>\d+)\s+" +
                @"(?<modify>\w+\s+\d+\s+\d+:\d+|\w+\s+\d+\s+\d+)\s" +
                @"(?<name>.*)$";
            FtpListItem item = new FtpListItem();
            Match m;

            if (!(m = Regex.Match(buf, regex, RegexOptions.IgnoreCase)).Success)
                return null;

            // if this field is missing we can't determine
            // what the object is.
            if (m.Groups["permissions"].Value.Length == 0)
                return null;

            switch (m.Groups["permissions"].Value[0]) {
                case 'd':
                    item.Type = FtpFileSystemObjectType.Directory;
                    break;
                case '-':
                case 's':
                    item.Type = FtpFileSystemObjectType.File;
                    break;
                case 'l':
                    item.Type = FtpFileSystemObjectType.Link;
                    break;
                default:
                    return null;
            }

            // if we can't determine a file name then
            // we are not considering this a successful parsing operation.
            if (m.Groups["name"].Value.Length < 1)
                return null;
            item.Name = m.Groups["name"].Value;

            switch (item.Type) {
                case FtpFileSystemObjectType.Directory:
                    // ignore these...
                    if (item.Name == "." || item.Name == "..")
                        return null;
                    break;
                case FtpFileSystemObjectType.Link:
                    if (!item.Name.Contains(" -> "))
                        return null;
                    item.LinkTarget = item.Name.Remove(0, item.Name.IndexOf("-> ") + 3);
                    item.Name = item.Name.Remove(item.Name.IndexOf(" -> "));
                    break;
            }

            // for date parser testing only
            //capabilities = ~(capabilities & FtpCapability.MDTM);

            ////
            // Ignore the Modify times sent in LIST format for files
            // when the server has support for the MDTM command
            // because they will never be as accurate as what can be had 
            // by using the MDTM command. MDTM does not work on directories
            // so if a modify time was parsed from the listing we will try
            // to convert it to a DateTime object and use it for directories.
            ////
            if (((capabilities & FtpCapability.MDTM) != FtpCapability.MDTM || item.Type == FtpFileSystemObjectType.Directory) && m.Groups["modify"].Value.Length > 0) {
                item.Modified = m.Groups["modify"].Value.GetFtpDate(DateTimeStyles.AssumeLocal);
                if (item.Modified == DateTime.MinValue) {
                    FtpTrace.WriteLine("GetFtpDate() failed on {0}", m.Groups["modify"].Value);
                }
            }
            else {
                if (m.Groups["modify"].Value.Length == 0)
                    FtpTrace.WriteLine("RegEx failed to parse modified date from {0}.", buf);
                else if (item.Type == FtpFileSystemObjectType.Directory)
                    FtpTrace.WriteLine("Modified times of directories are ignored in UNIX long listings.");
                else if ((capabilities & FtpCapability.MDTM) == FtpCapability.MDTM)
                    FtpTrace.WriteLine("Ignoring modified date because MDTM feature is present. If you aren't already, pass FtpListOption.Modify or FtpListOption.SizeModify to GetListing() to retrieve the modification time.");
            }

            if (m.Groups["size"].Value.Length > 0) {
                long size;

                if (long.TryParse(m.Groups["size"].Value, out size))
                    item.Size = size;
            }

            if (m.Groups["permissions"].Value.Length > 0) {
                Match perms = Regex.Match(m.Groups["permissions"].Value,
                    @"[\w-]{1}(?<owner>[\w-]{3})(?<group>[\w-]{3})(?<others>[\w-]{3})",
                    RegexOptions.IgnoreCase);

                if (perms.Success) {
                    if (perms.Groups["owner"].Value.Length == 3) {
                        if (perms.Groups["owner"].Value[0] == 'r')
                            item.OwnerPermissions |= FtpPermission.Read;
                        if (perms.Groups["owner"].Value[1] == 'w')
                            item.OwnerPermissions |= FtpPermission.Write;
                        if (perms.Groups["owner"].Value[2] == 'x' || perms.Groups["owner"].Value[2] == 's')
                            item.OwnerPermissions |= FtpPermission.Execute;
                        if (perms.Groups["owner"].Value[2] == 's' || perms.Groups["owner"].Value[2] == 'S')
                            item.SpecialPermissions |= FtpSpecialPermissions.SetUserID;
                    }

                    if (perms.Groups["group"].Value.Length == 3) {
                        if (perms.Groups["group"].Value[0] == 'r')
                            item.GroupPermissions |= FtpPermission.Read;
                        if (perms.Groups["group"].Value[1] == 'w')
                            item.GroupPermissions |= FtpPermission.Write;
                        if (perms.Groups["group"].Value[2] == 'x' || perms.Groups["group"].Value[2] == 's')
                            item.GroupPermissions |= FtpPermission.Execute;
                        if (perms.Groups["group"].Value[2] == 's' || perms.Groups["group"].Value[2] == 'S')
                            item.SpecialPermissions |= FtpSpecialPermissions.SetGroupID;
                    }

                    if (perms.Groups["others"].Value.Length == 3) {
                        if (perms.Groups["others"].Value[0] == 'r')
                            item.OthersPermissions |= FtpPermission.Read;
                        if (perms.Groups["others"].Value[1] == 'w')
                            item.OthersPermissions |= FtpPermission.Write;
                        if (perms.Groups["others"].Value[2] == 'x' || perms.Groups["others"].Value[2] == 't')
                            item.OthersPermissions |= FtpPermission.Execute;
                        if (perms.Groups["others"].Value[2] == 't' || perms.Groups["others"].Value[2] == 'T')
                            item.SpecialPermissions |= FtpSpecialPermissions.Sticky;
                    }
                }
            }

            return item;
        }
 /// <summary>
 /// Checks if the server supports the specified capability
 /// </summary>
 /// <param name="cap"></param>
 public bool HasCapability(FtpCapability cap) {
     return (this.Capabilities & cap) == cap;
 }