Guest User

Untitled

a guest
Aug 7th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.70 KB | None | 0 0
  1. using System.Diagnostics;
  2. using System.Data;
  3. using System.Collections;
  4. using Microsoft.VisualBasic;
  5. using System.Collections.Generic;
  6. using System;
  7. using System.Net;
  8. using System.IO;
  9. using System.Text.RegularExpressions;
  10.  
  11. namespace FTP
  12. {
  13.  
  14.  
  15. #region "FTP client class"
  16. /// <summary>
  17. /// A wrapper class for .NET 2.0 FTP
  18. /// </summary>
  19. /// <remarks>
  20. /// This class does not hold open an FTP connection but
  21. /// instead is stateless: for each FTP request it
  22. /// connects, performs the request and disconnects.
  23. /// </remarks>
  24. public class FTPclient
  25. {
  26.  
  27.  
  28. #region "CONSTRUCTORS"
  29. /// <summary>
  30. /// Blank constructor
  31. /// </summary>
  32. /// <remarks>Hostname, username and password must be set manually</remarks>
  33. public FTPclient()
  34. {
  35. }
  36.  
  37. /// <summary>
  38. /// Constructor just taking the hostname
  39. /// </summary>
  40. /// <param name="Hostname">in either ftp://ftp.host.com or ftp.host.com form</param>
  41. /// <remarks></remarks>
  42. public FTPclient(string Hostname)
  43. {
  44. _hostname = Hostname;
  45. }
  46.  
  47. /// <summary>
  48. /// Constructor taking hostname, username and password
  49. /// </summary>
  50. /// <param name="Hostname">in either ftp://ftp.host.com or ftp.host.com form</param>
  51. /// <param name="Username">Leave blank to use 'anonymous' but set password to your email</param>
  52. /// <param name="Password"></param>
  53. /// <remarks></remarks>
  54. public FTPclient(string Hostname, string Username, string Password)
  55. {
  56. _hostname = Hostname;
  57. _username = Username;
  58. _password = Password;
  59. }
  60. #endregion
  61.  
  62. #region "Directory functions"
  63. /// <summary>
  64. /// Return a simple directory listing
  65. /// </summary>
  66. /// <param name="directory">Directory to list, e.g. /pub</param>
  67. /// <returns>A list of filenames and directories as a List(of String)</returns>
  68. /// <remarks>For a detailed directory listing, use ListDirectoryDetail</remarks>
  69. public List<string> ListDirectory(string directory)
  70. {
  71. //return a simple list of filenames in directory
  72. System.Net.FtpWebRequest ftp = GetRequest(GetDirectory(directory));
  73. //Set request to do simple list
  74. ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectory;
  75.  
  76. string str = GetStringResponse(ftp);
  77. //replace CRLF to CR, remove last instance
  78. str = str.Replace("\r\n", "\r").TrimEnd('\r');
  79. //split the string into a list
  80. List<string> result = new List<string>();
  81. result.AddRange(str.Split('\r'));
  82. return result;
  83. }
  84.  
  85. /// <summary>
  86. /// Return a detailed directory listing
  87. /// </summary>
  88. /// <param name="directory">Directory to list, e.g. /pub/etc</param>
  89. /// <returns>An FTPDirectory object</returns>
  90. public FTPdirectory ListDirectoryDetail(string directory)
  91. {
  92. System.Net.FtpWebRequest ftp = GetRequest(GetDirectory(directory));
  93. //Set request to do simple list
  94. ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectoryDetails;
  95.  
  96. string str = GetStringResponse(ftp);
  97. //replace CRLF to CR, remove last instance
  98. str = str.Replace("\r\n", "\r").TrimEnd('\r');
  99. //split the string into a list
  100. return new FTPdirectory(str, _lastDirectory);
  101. }
  102.  
  103. #endregion
  104.  
  105. #region "Upload: File transfer TO ftp server"
  106. /// <summary>
  107. /// Copy a local file to the FTP server
  108. /// </summary>
  109. /// <param name="localFilename">Full path of the local file</param>
  110. /// <param name="targetFilename">Target filename, if required</param>
  111. /// <returns></returns>
  112. /// <remarks>If the target filename is blank, the source filename is used
  113. /// (assumes current directory). Otherwise use a filename to specify a name
  114. /// or a full path and filename if required.</remarks>
  115. public bool Upload(string localFilename, string targetFilename)
  116. {
  117. //1. check source
  118. if (!File.Exists(localFilename))
  119. {
  120. throw (new ApplicationException("File " + localFilename + " not found"));
  121. }
  122. //copy to FI
  123. FileInfo fi = new FileInfo(localFilename);
  124. return Upload(fi, targetFilename);
  125. }
  126.  
  127. /// <summary>
  128. /// Upload a local file to the FTP server
  129. /// </summary>
  130. /// <param name="fi">Source file</param>
  131. /// <param name="targetFilename">Target filename (optional)</param>
  132. /// <returns></returns>
  133. public bool Upload(FileInfo fi, string targetFilename)
  134. {
  135. //copy the file specified to target file: target file can be full path or just filename (uses current dir)
  136.  
  137. //1. check target
  138. string target;
  139. if (targetFilename.Trim() == "")
  140. {
  141. //Blank target: use source filename & current dir
  142. target = this.CurrentDirectory + fi.Name;
  143. }
  144. else if (targetFilename.Contains("/"))
  145. {
  146. //If contains / treat as a full path
  147. target = AdjustDir(targetFilename);
  148. }
  149. else
  150. {
  151. //otherwise treat as filename only, use current directory
  152. target = CurrentDirectory + targetFilename;
  153. }
  154.  
  155. string URI = Hostname + target;
  156. //perform copy
  157. System.Net.FtpWebRequest ftp = GetRequest(URI);
  158.  
  159. //Set request to upload a file in binary
  160. ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
  161. ftp.UseBinary = true;
  162.  
  163. //Notify FTP of the expected size
  164. ftp.ContentLength = fi.Length;
  165.  
  166. //create byte array to store: ensure at least 1 byte!
  167. const int BufferSize = 2048;
  168. byte[] content = new byte[BufferSize - 1 + 1];
  169. int dataRead;
  170.  
  171. //open file for reading
  172. using (FileStream fs = fi.OpenRead())
  173. {
  174. try
  175. {
  176. //open request to send
  177. using (Stream rs = ftp.GetRequestStream())
  178. {
  179. do
  180. {
  181. dataRead = fs.Read(content, 0, BufferSize);
  182. rs.Write(content, 0, dataRead);
  183. } while (!(dataRead < BufferSize));
  184. rs.Close();
  185. }
  186.  
  187. }
  188. catch (Exception)
  189. {
  190.  
  191. }
  192. finally
  193. {
  194. //ensure file closed
  195. fs.Close();
  196. }
  197.  
  198. }
  199.  
  200.  
  201. ftp = null;
  202. return true;
  203.  
  204. }
  205. #endregion
  206.  
  207. #region "Download: File transfer FROM ftp server"
  208. /// <summary>
  209. /// Copy a file from FTP server to local
  210. /// </summary>
  211. /// <param name="sourceFilename">Target filename, if required</param>
  212. /// <param name="localFilename">Full path of the local file</param>
  213. /// <returns></returns>
  214. /// <remarks>Target can be blank (use same filename), or just a filename
  215. /// (assumes current directory) or a full path and filename</remarks>
  216. public bool Download(string sourceFilename, string localFilename, bool PermitOverwrite)
  217. {
  218. //2. determine target file
  219. FileInfo fi = new FileInfo(localFilename);
  220. return this.Download(sourceFilename, fi, PermitOverwrite);
  221. }
  222.  
  223. //Version taking an FtpFileInfo
  224. public bool Download(FTPfileInfo file, string localFilename, bool PermitOverwrite)
  225. {
  226. return this.Download(file.FullName, localFilename, PermitOverwrite);
  227. }
  228.  
  229. //Another version taking FtpFileInfo and FileInfo
  230. public bool Download(FTPfileInfo file, FileInfo localFI, bool PermitOverwrite)
  231. {
  232. return this.Download(file.FullName, localFI, PermitOverwrite);
  233. }
  234.  
  235. //Version taking string/FileInfo
  236. public bool Download(string sourceFilename, FileInfo targetFI, bool PermitOverwrite)
  237. {
  238. //1. check target
  239. if (targetFI.Exists && !(PermitOverwrite))
  240. {
  241. throw (new ApplicationException("Target file already exists"));
  242. }
  243.  
  244. //2. check source
  245. string target;
  246. if (sourceFilename.Trim() == "")
  247. {
  248. throw (new ApplicationException("File not specified"));
  249. }
  250. else if (sourceFilename.Contains("/"))
  251. {
  252. //treat as a full path
  253. target = AdjustDir(sourceFilename);
  254. }
  255. else
  256. {
  257. //treat as filename only, use current directory
  258. target = CurrentDirectory + sourceFilename;
  259. }
  260.  
  261. string URI = Hostname + target;
  262.  
  263. //3. perform copy
  264. System.Net.FtpWebRequest ftp = GetRequest(URI);
  265.  
  266. //Set request to download a file in binary mode
  267. ftp.Method = System.Net.WebRequestMethods.Ftp.DownloadFile;
  268. ftp.UseBinary = true;
  269.  
  270. //open request and get response stream
  271. using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
  272. {
  273. using (Stream responseStream = response.GetResponseStream())
  274. {
  275. //loop to read & write to file
  276. using (FileStream fs = targetFI.OpenWrite())
  277. {
  278. try
  279. {
  280. byte[] buffer = new byte[2048];
  281. int read = 0;
  282. do
  283. {
  284. read = responseStream.Read(buffer, 0, buffer.Length);
  285. fs.Write(buffer, 0, read);
  286. } while (!(read == 0));
  287. responseStream.Close();
  288. fs.Flush();
  289. fs.Close();
  290. }
  291. catch (Exception)
  292. {
  293. //catch error and delete file only partially downloaded
  294. fs.Close();
  295. //delete target file as it's incomplete
  296. targetFI.Delete();
  297. throw;
  298. }
  299. }
  300.  
  301. responseStream.Close();
  302. }
  303.  
  304. response.Close();
  305. }
  306.  
  307.  
  308. return true;
  309. }
  310. #endregion
  311.  
  312. #region "Other functions: Delete rename etc."
  313. /// <summary>
  314. /// Delete remote file
  315. /// </summary>
  316. /// <param name="filename">filename or full path</param>
  317. /// <returns></returns>
  318. /// <remarks></remarks>
  319. public bool FtpDelete(string filename)
  320. {
  321. //Determine if file or full path
  322. string URI = this.Hostname + GetFullPath(filename);
  323.  
  324. System.Net.FtpWebRequest ftp = GetRequest(URI);
  325. //Set request to delete
  326. ftp.Method = System.Net.WebRequestMethods.Ftp.DeleteFile;
  327. try
  328. {
  329. //get response but ignore it
  330. string str = GetStringResponse(ftp);
  331. }
  332. catch (Exception)
  333. {
  334. return false;
  335. }
  336. return true;
  337. }
  338.  
  339. /// <summary>
  340. /// Determine if file exists on remote FTP site
  341. /// </summary>
  342. /// <param name="filename">Filename (for current dir) or full path</param>
  343. /// <returns></returns>
  344. /// <remarks>Note this only works for files</remarks>
  345. public bool FtpFileExists(string filename)
  346. {
  347. //Try to obtain filesize: if we get error msg containing "550"
  348. //the file does not exist
  349. try
  350. {
  351. long size = GetFileSize(filename);
  352. return true;
  353.  
  354. }
  355. catch (Exception ex)
  356. {
  357. //only handle expected not-found exception
  358. if (ex is System.Net.WebException)
  359. {
  360. //file does not exist/no rights error = 550
  361. if (ex.Message.Contains("550"))
  362. {
  363. //clear
  364. return false;
  365. }
  366. else
  367. {
  368. throw;
  369. }
  370. }
  371. else
  372. {
  373. throw;
  374. }
  375. }
  376. }
  377.  
  378. /// <summary>
  379. /// Determine size of remote file
  380. /// </summary>
  381. /// <param name="filename"></param>
  382. /// <returns></returns>
  383. /// <remarks>Throws an exception if file does not exist</remarks>
  384. public long GetFileSize(string filename)
  385. {
  386. string path;
  387. if (filename.Contains("/"))
  388. {
  389. path = AdjustDir(filename);
  390. }
  391. else
  392. {
  393. path = this.CurrentDirectory + filename;
  394. }
  395. string URI = this.Hostname + path;
  396. System.Net.FtpWebRequest ftp = GetRequest(URI);
  397. //Try to get info on file/dir?
  398. ftp.Method = System.Net.WebRequestMethods.Ftp.GetFileSize;
  399. string tmp = this.GetStringResponse(ftp);
  400. return GetSize(ftp);
  401. }
  402.  
  403. public bool FtpRename(string sourceFilename, string newName)
  404. {
  405. //Does file exist?
  406. string source = GetFullPath(sourceFilename);
  407. if (!FtpFileExists(source))
  408. {
  409. throw (new FileNotFoundException("File " + source + " not found"));
  410. }
  411.  
  412. //build target name, ensure it does not exist
  413. string target = GetFullPath(newName);
  414. if (target == source)
  415. {
  416. throw (new ApplicationException("Source and target are the same"));
  417. }
  418. else if (FtpFileExists(target))
  419. {
  420. throw (new ApplicationException("Target file " + target + " already exists"));
  421. }
  422.  
  423. //perform rename
  424. string URI = this.Hostname + source;
  425.  
  426. System.Net.FtpWebRequest ftp = GetRequest(URI);
  427. //Set request to delete
  428. ftp.Method = System.Net.WebRequestMethods.Ftp.Rename;
  429. ftp.RenameTo = target;
  430. try
  431. {
  432. //get response but ignore it
  433. string str = GetStringResponse(ftp);
  434. }
  435. catch (Exception)
  436. {
  437. return false;
  438. }
  439. return true;
  440. }
  441.  
  442. public bool FtpCreateDirectory(string dirpath)
  443. {
  444. //perform create
  445. string URI = this.Hostname + AdjustDir(dirpath);
  446. System.Net.FtpWebRequest ftp = GetRequest(URI);
  447. //Set request to MkDir
  448. ftp.Method = System.Net.WebRequestMethods.Ftp.MakeDirectory;
  449. try
  450. {
  451. //get response but ignore it
  452. string str = GetStringResponse(ftp);
  453. }
  454. catch (Exception)
  455. {
  456. return false;
  457. }
  458. return true;
  459. }
  460.  
  461. public bool FtpDeleteDirectory(string dirpath)
  462. {
  463. //perform remove
  464. string URI = this.Hostname + AdjustDir(dirpath);
  465. System.Net.FtpWebRequest ftp = GetRequest(URI);
  466. //Set request to RmDir
  467. ftp.Method = System.Net.WebRequestMethods.Ftp.RemoveDirectory;
  468. try
  469. {
  470. //get response but ignore it
  471. string str = GetStringResponse(ftp);
  472. }
  473. catch (Exception)
  474. {
  475. return false;
  476. }
  477. return true;
  478. }
  479. #endregion
  480.  
  481. #region "private supporting fns"
  482. //Get the basic FtpWebRequest object with the
  483. //common settings and security
  484. private FtpWebRequest GetRequest(string URI)
  485. {
  486. //create request
  487. FtpWebRequest result = (FtpWebRequest)FtpWebRequest.Create(URI);
  488. //Set the login details
  489. result.Credentials = GetCredentials();
  490. //Do not keep alive (stateless mode)
  491. result.KeepAlive = false;
  492. return result;
  493. }
  494.  
  495.  
  496. /// <summary>
  497. /// Get the credentials from username/password
  498. /// </summary>
  499. private System.Net.ICredentials GetCredentials()
  500. {
  501. return new System.Net.NetworkCredential(Username, Password);
  502. }
  503.  
  504. /// <summary>
  505. /// returns a full path using CurrentDirectory for a relative file reference
  506. /// </summary>
  507. private string GetFullPath(string file)
  508. {
  509. if (file.Contains("/"))
  510. {
  511. return AdjustDir(file);
  512. }
  513. else
  514. {
  515. return this.CurrentDirectory + file;
  516. }
  517. }
  518.  
  519. /// <summary>
  520. /// Amend an FTP path so that it always starts with /
  521. /// </summary>
  522. /// <param name="path">Path to adjust</param>
  523. /// <returns></returns>
  524. /// <remarks></remarks>
  525. private string AdjustDir(string path)
  526. {
  527. return ((path.StartsWith("/")) ? "" : "/").ToString() + path;
  528. }
  529.  
  530. private string GetDirectory(string directory)
  531. {
  532. string URI;
  533. if (directory == "")
  534. {
  535. //build from current
  536. URI = Hostname + this.CurrentDirectory;
  537. _lastDirectory = this.CurrentDirectory;
  538. }
  539. else
  540. {
  541. if (!directory.StartsWith("/"))
  542. {
  543. throw (new ApplicationException("Directory should start with /"));
  544. }
  545. URI = this.Hostname + directory;
  546. _lastDirectory = directory;
  547. }
  548. return URI;
  549. }
  550.  
  551. //stores last retrieved/set directory
  552. private string _lastDirectory = "";
  553.  
  554. /// <summary>
  555. /// Obtains a response stream as a string
  556. /// </summary>
  557. /// <param name="ftp">current FTP request</param>
  558. /// <returns>String containing response</returns>
  559. /// <remarks>FTP servers typically return strings with CR and
  560. /// not CRLF. Use respons.Replace(vbCR, vbCRLF) to convert
  561. /// to an MSDOS string</remarks>
  562. private string GetStringResponse(FtpWebRequest ftp)
  563. {
  564. //Get the result, streaming to a string
  565. string result = "";
  566. using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
  567. {
  568. long size = response.ContentLength;
  569. using (Stream datastream = response.GetResponseStream())
  570. {
  571. using (StreamReader sr = new StreamReader(datastream))
  572. {
  573. result = sr.ReadToEnd();
  574. sr.Close();
  575. }
  576.  
  577. datastream.Close();
  578. }
  579.  
  580. response.Close();
  581. }
  582.  
  583. return result;
  584. }
  585.  
  586. /// <summary>
  587. /// Gets the size of an FTP request
  588. /// </summary>
  589. /// <param name="ftp"></param>
  590. /// <returns></returns>
  591. /// <remarks></remarks>
  592. private long GetSize(FtpWebRequest ftp)
  593. {
  594. long size;
  595. using (FtpWebResponse response = (FtpWebResponse)ftp.GetResponse())
  596. {
  597. size = response.ContentLength;
  598. response.Close();
  599. }
  600.  
  601. return size;
  602. }
  603. #endregion
  604.  
  605. #region "Properties"
  606. private string _hostname;
  607. /// <summary>
  608. /// Hostname
  609. /// </summary>
  610. /// <value></value>
  611. /// <remarks>Hostname can be in either the full URL format
  612. /// ftp://ftp.myhost.com or just ftp.myhost.com
  613. /// </remarks>
  614. public string Hostname
  615. {
  616. get
  617. {
  618. if (_hostname.StartsWith("ftp://"))
  619. {
  620. return _hostname;
  621. }
  622. else
  623. {
  624. return "ftp://" + _hostname;
  625. }
  626. }
  627. set
  628. {
  629. _hostname = value;
  630. }
  631. }
  632. private string _username;
  633. /// <summary>
  634. /// Username property
  635. /// </summary>
  636. /// <value></value>
  637. /// <remarks>Can be left blank, in which case 'anonymous' is returned</remarks>
  638. public string Username
  639. {
  640. get
  641. {
  642. return (_username == "" ? "anonymous" : _username);
  643. }
  644. set
  645. {
  646. _username = value;
  647. }
  648. }
  649. private string _password;
  650. public string Password
  651. {
  652. get
  653. {
  654. return _password;
  655. }
  656. set
  657. {
  658. _password = value;
  659. }
  660. }
  661.  
  662. /// <summary>
  663. /// The CurrentDirectory value
  664. /// </summary>
  665. /// <remarks>Defaults to the root '/'</remarks>
  666. private string _currentDirectory = "/";
  667. public string CurrentDirectory
  668. {
  669. get
  670. {
  671. //return directory, ensure it ends with /
  672. return _currentDirectory + ((_currentDirectory.EndsWith("/")) ? "" : "/").ToString();
  673. }
  674. set
  675. {
  676. if (!value.StartsWith("/"))
  677. {
  678. throw (new ApplicationException("Directory should start with /"));
  679. }
  680. _currentDirectory = value;
  681. }
  682. }
  683.  
  684.  
  685. #endregion
  686.  
  687. }
  688. #endregion
  689.  
  690.  
  691. #region "FTP file info class"
  692. /// <summary>
  693. /// Represents a file or directory entry from an FTP listing
  694. /// </summary>
  695. /// <remarks>
  696. /// This class is used to parse the results from a detailed
  697. /// directory list from FTP. It supports most formats of
  698. /// </remarks>
  699. public class FTPfileInfo
  700. {
  701.  
  702. //Stores extended info about FTP file
  703.  
  704. #region "Properties"
  705. public string FullName
  706. {
  707. get
  708. {
  709. return Path + Filename;
  710. }
  711. }
  712. public string Filename
  713. {
  714. get
  715. {
  716. return _filename;
  717. }
  718. }
  719. public string Path
  720. {
  721. get
  722. {
  723. return _path;
  724. }
  725. }
  726. public DirectoryEntryTypes FileType
  727. {
  728. get
  729. {
  730. return _fileType;
  731. }
  732. }
  733. public long Size
  734. {
  735. get
  736. {
  737. return _size;
  738. }
  739. }
  740. public DateTime FileDateTime
  741. {
  742. get
  743. {
  744. return _fileDateTime;
  745. }
  746. }
  747. public string Permission
  748. {
  749. get
  750. {
  751. return _permission;
  752. }
  753. }
  754. public string Extension
  755. {
  756. get
  757. {
  758. int i = this.Filename.LastIndexOf(".");
  759. if (i >= 0 && i <(this.Filename.Length - 1))
  760. {
  761. return this.Filename.Substring(i + 1);
  762. }
  763. else
  764. {
  765. return "";
  766. }
  767. }
  768. }
  769. public string NameOnly
  770. {
  771. get
  772. {
  773. int i = this.Filename.LastIndexOf(".");
  774. if (i > 0)
  775. {
  776. return this.Filename.Substring(0, i);
  777. }
  778. else
  779. {
  780. return this.Filename;
  781. }
  782. }
  783. }
  784. private string _filename;
  785. private string _path;
  786. private DirectoryEntryTypes _fileType;
  787. private long _size;
  788. private DateTime _fileDateTime;
  789. private string _permission;
  790.  
  791. #endregion
  792.  
  793. /// <summary>
  794. /// Identifies entry as either File or Directory
  795. /// </summary>
  796. public enum DirectoryEntryTypes
  797. {
  798. File,
  799. Directory
  800. }
  801.  
  802. /// <summary>
  803. /// Constructor taking a directory listing line and path
  804. /// </summary>
  805. /// <param name="line">The line returned from the detailed directory list</param>
  806. /// <param name="path">Path of the directory</param>
  807. /// <remarks></remarks>
  808. public FTPfileInfo(string line, string path)
  809. {
  810. //parse line
  811. Match m = GetMatchingRegex(line);
  812. if (m == null)
  813. {
  814. //failed
  815. throw (new ApplicationException("Unable to parse line: " + line));
  816. }
  817. else
  818. {
  819. _filename = m.Groups["name"].Value;
  820. _path = path;
  821.  
  822. Int64.TryParse(m.Groups["size"].Value, out _size);
  823. //_size = System.Convert.ToInt32(m.Groups["size"].Value);
  824.  
  825. _permission = m.Groups["permission"].Value;
  826. string _dir = m.Groups["dir"].Value;
  827. if (_dir != "" && _dir != "-")
  828. {
  829. _fileType = DirectoryEntryTypes.Directory;
  830. }
  831. else
  832. {
  833. _fileType = DirectoryEntryTypes.File;
  834. }
  835.  
  836. try
  837. {
  838. _fileDateTime = DateTime.Parse(m.Groups["timestamp"].Value);
  839. }
  840. catch (Exception)
  841. {
  842. _fileDateTime = Convert.ToDateTime(null);
  843. }
  844.  
  845. }
  846. }
  847.  
  848. private Match GetMatchingRegex(string line)
  849. {
  850. Regex rx;
  851. Match m;
  852. for (int i = 0; i <= _ParseFormats.Length - 1; i++)
  853. {
  854. rx = new Regex(_ParseFormats[i]);
  855. m = rx.Match(line);
  856. if (m.Success)
  857. {
  858. return m;
  859. }
  860. }
  861. return null;
  862. }
  863.  
  864. #region "Regular expressions for parsing LIST results"
  865. /// <summary>
  866. /// List of REGEX formats for different FTP server listing formats
  867. /// </summary>
  868. /// <remarks>
  869. /// The first three are various UNIX/LINUX formats, fourth is for MS FTP
  870. /// in detailed mode and the last for MS FTP in 'DOS' mode.
  871. /// I wish VB.NET had support for Const arrays like C# but there you go
  872. /// </remarks>
  873. private static string[] _ParseFormats = new string[] {
  874. "(?<dir>[\\-d])(?<permission>([\\-r][\\-w][\\-xs]){3})\\s+\\d+\\s+\\w+\\s+\\w+\\s+(?<size>\\d+)\\s+(?<timestamp>\\w+\\s+\\d+\\s+\\d{4})\\s+(?<name>.+)",
  875. "(?<dir>[\\-d])(?<permission>([\\-r][\\-w][\\-xs]){3})\\s+\\d+\\s+\\d+\\s+(?<size>\\d+)\\s+(?<timestamp>\\w+\\s+\\d+\\s+\\d{4})\\s+(?<name>.+)",
  876. "(?<dir>[\\-d])(?<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>.+)",
  877. "(?<dir>[\\-d])(?<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>.+)",
  878. "(?<dir>[\\-d])(?<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>.+)",
  879. "(?<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>.+)" };
  880. #endregion
  881. }
  882. #endregion
  883.  
  884. #region "FTP Directory class"
  885. /// <summary>
  886. /// Stores a list of files and directories from an FTP result
  887. /// </summary>
  888. /// <remarks></remarks>
  889. public class FTPdirectory : List<FTPfileInfo>
  890. {
  891.  
  892.  
  893. public FTPdirectory()
  894. {
  895. //creates a blank directory listing
  896. }
  897.  
  898. /// <summary>
  899. /// Constructor: create list from a (detailed) directory string
  900. /// </summary>
  901. /// <param name="dir">directory listing string</param>
  902. /// <param name="path"></param>
  903. /// <remarks></remarks>
  904. public FTPdirectory(string dir, string path)
  905. {
  906. foreach (string line in dir.Replace("\n", "").Split(System.Convert.ToChar('\r')))
  907. {
  908. //parse
  909. if (line != "")
  910. {
  911. this.Add(new FTPfileInfo(line, path));
  912. }
  913. }
  914. }
  915.  
  916. /// <summary>
  917. /// Filter out only files from directory listing
  918. /// </summary>
  919. /// <param name="ext">optional file extension filter</param>
  920. /// <returns>FTPdirectory listing</returns>
  921. public FTPdirectory GetFiles(string ext)
  922. {
  923. return this.GetFileOrDir(FTPfileInfo.DirectoryEntryTypes.File, ext);
  924. }
  925.  
  926. /// <summary>
  927. /// Returns a list of only subdirectories
  928. /// </summary>
  929. /// <returns>FTPDirectory list</returns>
  930. /// <remarks></remarks>
  931. public FTPdirectory GetDirectories()
  932. {
  933. return this.GetFileOrDir(FTPfileInfo.DirectoryEntryTypes.Directory, "");
  934. }
  935.  
  936. //internal: share use function for GetDirectories/Files
  937. private FTPdirectory GetFileOrDir(FTPfileInfo.DirectoryEntryTypes type, string ext)
  938. {
  939. FTPdirectory result = new FTPdirectory();
  940. foreach (FTPfileInfo fi in this)
  941. {
  942. if (fi.FileType == type)
  943. {
  944. if (ext == "")
  945. {
  946. result.Add(fi);
  947. }
  948. else if (ext == fi.Extension)
  949. {
  950. result.Add(fi);
  951. }
  952. }
  953. }
  954. return result;
  955.  
  956. }
  957.  
  958. public bool FileExists(string filename)
  959. {
  960. foreach (FTPfileInfo ftpfile in this)
  961. {
  962. if (ftpfile.Filename == filename)
  963. {
  964. return true;
  965. }
  966. }
  967. return false;
  968. }
  969.  
  970. private const char slash = '/';
  971.  
  972. public static string GetParentDirectory(string dir)
  973. {
  974. string tmp = dir.TrimEnd(slash);
  975. int i = tmp.LastIndexOf(slash);
  976. if (i > 0)
  977. {
  978. return tmp.Substring(0, i - 1);
  979. }
  980. else
  981. {
  982. throw (new ApplicationException("No parent for root"));
  983. }
  984. }
  985. }
  986. #endregion
  987.  
  988. }
Add Comment
Please, Sign In to add comment