217 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			217 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Linq;
 | |
| using System.Text;
 | |
| using System.Text.RegularExpressions;
 | |
| 
 | |
| namespace AR.FTPClient
 | |
| {
 | |
|     /// <summary>
 | |
|     ///     ''' Represents a file or directory entry from an FTP listing
 | |
|     ///     ''' </summary>
 | |
|     ///     ''' <remarks>
 | |
|     ///     ''' This class is used to parse the results from a detailed
 | |
|     ///     ''' directory list from FTP. It supports most formats of
 | |
|     ///     ''' </remarks>
 | |
|     public class FTPfileInfo
 | |
|     {
 | |
|         // Stores extended info about FTP file
 | |
| 
 | |
|         public string FullName
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 var retval = Path + "/" + Filename;
 | |
|                 return retval.Replace("//", "/");
 | |
|             }
 | |
|         }
 | |
|         public string Filename
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _filename;
 | |
|             }
 | |
|         }
 | |
|         public string Path
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _path;
 | |
|             }
 | |
|         }
 | |
|         public DirectoryEntryTypes FileType
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _fileType;
 | |
|             }
 | |
|         }
 | |
|         public long Size
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _size;
 | |
|             }
 | |
|         }
 | |
|         public DateTime FileDateTime
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _fileDateTime;
 | |
|             }
 | |
|         }
 | |
|         public string Permission
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _permission;
 | |
|             }
 | |
|         }
 | |
|         public string Extension
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 int i = this.Filename.LastIndexOf(".");
 | |
|                 if (i >= 0 & i < (this.Filename.Length - 1))
 | |
|                     return this.Filename.Substring(i + 1);
 | |
|                 else
 | |
|                     return "";
 | |
|             }
 | |
|         }
 | |
|         public string NameOnly
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 int i = this.Filename.LastIndexOf(".");
 | |
|                 if (i > 0)
 | |
|                     return this.Filename.Substring(0, i);
 | |
|                 else
 | |
|                     return this.Filename;
 | |
|             }
 | |
|         }
 | |
|         private string _filename;
 | |
|         private string _path;
 | |
|         private DirectoryEntryTypes _fileType;
 | |
|         private long _size;
 | |
|         private DateTime _fileDateTime;
 | |
|         private string _permission;
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         ///         ''' Identifies entry as either File or Directory
 | |
|         ///         ''' </summary>
 | |
|         public enum DirectoryEntryTypes
 | |
|         {
 | |
|             File,
 | |
|             Directory,
 | |
|             Link
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         ///         ''' Constructor taking a directory listing line and path
 | |
|         ///         ''' </summary>
 | |
|         ///         ''' <param name="line">The line returned from the detailed directory list</param>
 | |
|         ///         ''' <param name="path">Path of the directory</param>
 | |
|         ///         ''' <remarks></remarks>
 | |
|         public FTPfileInfo(string line, string path)
 | |
|         {
 | |
|             // parse line
 | |
| 
 | |
| 
 | |
| 
 | |
|             Match m = GetMatchingRegex(line);
 | |
|             if (m == null)
 | |
|                 // failed
 | |
|                 throw new ApplicationException("Unable to parse line: " + line);
 | |
|             else
 | |
|             {
 | |
|                 _filename = m.Groups["name"].Value;
 | |
|                 _path = path;
 | |
| 
 | |
| 
 | |
|                 _permission = m.Groups["permission"].Value;
 | |
|                 string _dir = m.Groups["dir"].Value;
 | |
|                 if ((_dir != "" & (_dir == "d" || _dir == "D")))
 | |
|                 {
 | |
|                     _fileType = DirectoryEntryTypes.Directory;
 | |
|                     _size = 0; // CLng(m.Groups("size").Value)
 | |
|                 }
 | |
|                 else if ((_dir != "" & (_dir == "l" || _dir == "L")))
 | |
|                 {
 | |
|                     _fileType = DirectoryEntryTypes.Link;
 | |
|                     _size = 0; // CLng(m.Groups("size").Value)
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     _fileType = DirectoryEntryTypes.File;
 | |
|                     _size = System.Convert.ToInt64(m.Groups["size"].Value);
 | |
|                 }
 | |
| 
 | |
| 
 | |
|                 try
 | |
|                 {
 | |
|                     var timestamp = m.Groups["timestamp"].Value;
 | |
|                     if (timestamp.IndexOf(':') == -1)
 | |
|                     {
 | |
|                         _fileDateTime = DateTime.Parse(timestamp);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         _fileDateTime = DateTime.Parse(DateTime.Now.Year + " " + timestamp);
 | |
|                     }
 | |
| 
 | |
|                 }
 | |
|                 catch
 | |
|                 {
 | |
|                     // MsgBox("datetime err=" & Now.Year & Space(1) & "value=" & m.Groups("timestamp").Value & vbCrLf & ex.Message.ToString)
 | |
|                     _fileDateTime = DateTime.Parse("1982-11-23");
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public FTPfileInfo(string filename, string permission, string dir, int size, DateTime filetime, Boolean isdir, string path)
 | |
|         {
 | |
|             _filename = filename;// m.Groups["name"].Value;
 | |
|             _path = path;
 | |
|             _permission = permission; // m.Groups["permission"].Value;
 | |
|             string _dir = dir;// m.Groups["dir"].Value;
 | |
|             if (isdir == true)
 | |
|             {
 | |
|                 _fileType = DirectoryEntryTypes.Directory;
 | |
|                 _size = 0; // CLng(m.Groups("size").Value)
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 _fileType = DirectoryEntryTypes.File;
 | |
|                 _size = size;//
 | |
|             }
 | |
| 
 | |
|             _fileDateTime = filetime;
 | |
|         }
 | |
| 
 | |
|         private Match GetMatchingRegex(string line)
 | |
|         {
 | |
|             Regex rx;
 | |
|             Match m;
 | |
|             for (int i = 0; i <= _ParseFormats.Length - 1; i++)
 | |
|             {
 | |
|                 rx = new Regex(_ParseFormats[i]);
 | |
|                 m = rx.Match(line);
 | |
|                 if (m.Success)
 | |
|                     return m;
 | |
|             }
 | |
|             return null;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         ///         ''' List of REGEX formats for different FTP server listing formats
 | |
|         ///         ''' </summary>
 | |
|         ///         ''' <remarks>
 | |
|         ///         ''' The first three are various UNIX/LINUX formats, fourth is for MS FTP
 | |
|         ///         ''' in detailed mode and the last for MS FTP in 'DOS' mode.
 | |
|         ///         ''' I wish VB.NET had support for Const arrays like C# but there you go
 | |
|         ///         ''' </remarks>
 | |
|         private static string[] _ParseFormats = new[] { @"(?<dir>[\-dl])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\w+\s+\w+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)", @"(?<dir>[\-dl])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\d+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)", @"(?<dir>[\-dl])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\d+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{1,2}:\d{2})\s+(?<name>.+)", @"(?<dir>[\-dl])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\w+\s+\w+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{1,2}:\d{2})\s+(?<name>.+)", @"(?<dir>[\-dl])(?<permission>([\-r][\-w][\-xs]){3})(\s+)(?<size>(\d+))(\s+)(?<ctbit>(\w+\s\w+))(\s+)(?<size2>(\d+))\s+(?<timestamp>\w+\s+\d+\s+\d{2}:\d{2})\s+(?<name>.+)", @"(?<timestamp>\d{2}\-\d{2}\-\d{2}\s+\d{2}:\d{2}[Aa|Pp][mM])\s+(?<dir>\<\w+\>){0,1}(?<size>\d+){0,1}\s+(?<name>.+)" };
 | |
|     }
 | |
| }
 | 
