Пример #1
0
        private 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;
        }
Пример #2
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;
        }
Пример #3
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>
        private 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":
                case "cdir":
                case "pdir":
                    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;
        }
Пример #4
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+" +
                @"(?<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;
            }

            ////
            // 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 (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;
        }
Пример #5
0
        private static void PostParse(string path, string buf, Parser parser, FtpListItem item)
        {
            // if this is a vax/openvms file listing
            // there are no slashes in the path name
            if (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("/"))
                    item.LinkTarget =
                        path.GetFtpPath(item.LinkTarget.StartsWith("./")
                                            ? item.LinkTarget.Remove(0, 2)
                                            : item.LinkTarget);
            }

            item.Input = buf;
        }