PageRenderTime 51ms CodeModel.GetById 14ms app.highlight 29ms RepoModel.GetById 2ms app.codeStats 0ms

/Platters/classes/ftp.cs

http://skimpt.googlecode.com/
C# | 1134 lines | 840 code | 164 blank | 130 comment | 134 complexity | 8edb33b502b034f6306723bd775ac42f MD5 | raw file
   1#region "License Agreement"
   2/* Skimpt, an open source screenshot utility.
   3      Copyright (C) <year>  <name of author>
   4
   5      This program is free software: you can redistribute it and/or modify
   6      it under the terms of the GNU General Public License as published by
   7      the Free Software Foundation, either version 3 of the License, or
   8      (at your option) any later version.
   9
  10      this program is distributed in the hope that it will be useful,
  11      but WITHOUT ANY WARRANTY; without even the implied warranty of
  12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13      GNU General Public License for more details.
  14
  15      You should have received a copy of the GNU General Public License
  16      along with this program.  If not, see <http://www.gnu.org/licenses/>. */
  17#endregion
  18using System;
  19using System.Net;
  20using System.IO;
  21using System.Text;
  22using System.Net.Sockets;
  23using System.Text.RegularExpressions;
  24using System.Collections;
  25
  26
  27/// <summary>
  28/// converted to C# and Modified by Andy Bonner - andybonner@lycos.com
  29/// Modified on October 24th 2008 by Affan Shoukat to improve performance.
  30/// </summary>
  31/// 
  32public class FTP
  33{
  34    #region "Class Variable Declarations"
  35    private string m_sRemoteHost;
  36    private string m_sRemotePath;
  37    private string m_sRemoteUser;
  38    private string m_sRemotePassword;
  39    // private string m_sMess;
  40    private int m_iRemotePort;
  41    private int m_iBytes;
  42    private Socket m_objClientSocket;
  43
  44    private int m_iRetValue;
  45    private bool m_bLoggedIn;
  46    private string m_sMes;
  47    private string m_sReply;
  48
  49    //Set the size of the packet that is used to read and to write data to the FTP server
  50    //to the following specified size.
  51    public const int BLOCK_SIZE = 512;
  52    private byte[] m_aBuffer = new byte[BLOCK_SIZE + 1];
  53    private Encoding ASCII = Encoding.ASCII;
  54    public bool flag_bool;
  55    //General variable declaration
  56    private string m_sMessageString;
  57    #endregion
  58
  59    #region " Constructors "
  60
  61    public FTP()
  62    {
  63        m_sRemoteHost = "microsoft";
  64        m_sRemotePath = ".";
  65        m_sRemoteUser = "anonymous";
  66        m_sRemotePassword = "";
  67        m_sMessageString = "";
  68        m_iRemotePort = 21;
  69        m_bLoggedIn = false;
  70    }
  71
  72    public FTP(string sRemoteHost, string sRemotePath,
  73        string sRemoteUser, string sRemotePassword, int iRemotePort)
  74    {
  75        m_sRemoteHost = sRemoteHost;
  76        m_sRemotePath = sRemotePath;
  77        m_sRemoteUser = sRemoteUser;
  78        m_sRemotePassword = sRemotePassword;
  79        m_sMessageString = "";
  80        m_iRemotePort = iRemotePort;
  81        m_bLoggedIn = false;
  82    }
  83
  84    public FTP(string sRemoteHost, string sRemotePath,
  85    string sRemoteUser, string sRemotePassword)
  86    {
  87        m_sRemoteHost = sRemoteHost;
  88        m_sRemotePath = sRemotePath;
  89        m_sRemoteUser = sRemoteUser;
  90        m_sRemotePassword = sRemotePassword;
  91        m_sMessageString = "";
  92        m_iRemotePort = 21;
  93        m_bLoggedIn = false;
  94    }
  95
  96    #endregion
  97
  98    #region " Public Properties "
  99
 100    /// Set or Get the name of the FTP server that you want to connect to.
 101    public string RemoteHostFTPServer
 102    {
 103        get { return m_sRemoteHost; }
 104        set { m_sRemoteHost = value; }
 105    }
 106
 107    /// Set or Get the FTP port number of the FTP server that you want to connect to.
 108    public int RemotePort
 109    {
 110        get { return m_iRemotePort; }
 111        set { m_iRemotePort = value; }
 112    }
 113
 114    /// Set or Get the remote path of the FTP server that you want to connect to.
 115    public string RemotePath
 116    {
 117        get { return m_sRemotePath; }
 118        set { m_sRemotePath = value; }
 119    }
 120
 121    /// Set the remote password of the FTP server that you want to connect to.
 122    public string RemotePassword
 123    {
 124        get { return m_sRemotePassword; }
 125        set { m_sRemotePassword = value; }
 126    }
 127
 128    /// Set or Get the remote user of the FTP server that you want to connect to.
 129    public string RemoteUser
 130    {
 131        get { return m_sRemoteUser; }
 132        set { m_sRemoteUser = value; }
 133    }
 134
 135    /// Set or Get the class messagestring.
 136    public string MessageString
 137    {
 138        get { return m_sMessageString; }
 139        set { m_sMessageString = value; }
 140    }
 141
 142    #endregion
 143
 144    #region " Public Subs and Functions "
 145
 146    /// Return a list of files from the file system. Return these files in a string() array.
 147    public string[] GetFileList(string sMask)
 148    {
 149        Socket cSocket;
 150        int bytes;
 151        char seperator = Convert.ToChar("\n");
 152        string[] mess;
 153        m_sMes = "";
 154        /// Check to see if you are logged on to the FTP server.
 155
 156        if (!m_bLoggedIn)
 157        {
 158            Login();
 159        }
 160
 161        cSocket = CreateDataSocket();
 162
 163        /// Send an FTP command. 
 164        SendCommand("NLST " + sMask);
 165
 166        if (!(m_iRetValue == 150 || m_iRetValue == 125))
 167        {
 168            MessageString = m_sReply;
 169            throw new IOException(m_sReply.Substring(4));
 170        }
 171
 172        m_sMes = "";
 173
 174        while (true)
 175        {
 176            Array.Clear(m_aBuffer, 0, m_aBuffer.Length);
 177            bytes = cSocket.Receive(m_aBuffer, m_aBuffer.Length, 0);
 178            m_sMes += ASCII.GetString(m_aBuffer, 0, bytes);
 179
 180            if (bytes < m_aBuffer.Length)
 181            {
 182                break;
 183            }
 184            System.Threading.Thread.Sleep(10);
 185        }
 186
 187        mess = m_sMes.Split(seperator);
 188
 189        cSocket.Close();
 190        ReadReply();
 191
 192        if (m_iRetValue != 226)
 193        {
 194            MessageString = m_sReply;
 195            throw new IOException(m_sReply.Substring(4));
 196        }
 197
 198        return mess;
 199    }
 200
 201
 202    private struct SplitLine
 203    {
 204        public bool Valid;
 205        public bool Dir;
 206        public string FileName;
 207        public int FileSize;
 208        public string FileDate;
 209        public string FileTime;
 210    }
 211
 212    /// Return a list of files & Directories from the file system.
 213    public void GetDirList(DirList dl)
 214    {
 215        Socket cSocket;
 216        int bytes;
 217        char seperator = Convert.ToChar("\n");
 218        string[] mess;
 219
 220        m_sMes = "";
 221
 222        /// Check to see if you are logged on to the FTP server.
 223
 224        if (!m_bLoggedIn)
 225        {
 226            Login();
 227        }
 228
 229        cSocket = CreateDataSocket();
 230        /// Send an FTP command. 
 231        SendCommand("LIST -AL");
 232
 233        if (!(m_iRetValue == 150 || m_iRetValue == 125))
 234        {
 235            MessageString = m_sReply;
 236            throw new IOException(m_sReply.Substring(4));
 237        }
 238
 239        m_sMes = "";
 240
 241        while (true)
 242        {
 243            Array.Clear(m_aBuffer, 0, m_aBuffer.Length);
 244            bytes = cSocket.Receive(m_aBuffer, m_aBuffer.Length, 0);
 245            m_sMes += ASCII.GetString(m_aBuffer, 0, bytes);
 246
 247            if (bytes < m_aBuffer.Length)
 248            {
 249                break;
 250            }
 251            System.Threading.Thread.Sleep(10);
 252        }
 253
 254        mess = m_sMes.Split(seperator);
 255        cSocket.Close();
 256        ReadReply();
 257
 258        if (m_iRetValue != 226)
 259        {
 260            MessageString = m_sReply;
 261            throw new IOException(m_sReply.Substring(4));
 262        }
 263
 264        if (mess.Length > 0)
 265        {
 266            foreach (string tmpstr in mess)
 267            {
 268                if (tmpstr != "")
 269                {
 270                    DirFile lf;
 271
 272                    SplitLine sl = ParseLine(tmpstr);
 273
 274                    if (sl.Valid)
 275                    {
 276                        if (sl.Dir)
 277                        {
 278                            lf = new DirFile(sl.FileName, sl.FileDate, sl.FileTime, true, 0);
 279                        }
 280                        else
 281                        {
 282                            lf = new DirFile(sl.FileName, sl.FileDate, sl.FileTime, false, sl.FileSize);
 283                        }
 284                        dl.Add(lf);
 285                    }
 286                }
 287            }
 288        }
 289    }
 290    private SplitLine ParseLine(string Line)
 291    {
 292        SplitLine sl = new SplitLine();
 293        sl.Valid = false;
 294        Regex rx;
 295        Match m;
 296
 297        // is it dos format?
 298        rx = new Regex(@"(?<Date>[0-9|-]{8})\s*(?<Time>[0-9|:|AM|PM]*)\s*(?<Size>[0-9"
 299            + @"|\<|\>|DIR]*)\s*(?<Name>.*)\r", RegexOptions.IgnoreCase);
 300
 301        m = rx.Match(Line);
 302        if (m.Success)
 303        {
 304            sl.Valid = true;
 305            if (m.Groups["Size"].Value == "<DIR>")
 306            {
 307                sl.Dir = true;
 308                sl.FileSize = 0;
 309            }
 310            else
 311            {
 312                sl.Dir = false;
 313                sl.FileSize = Convert.ToInt32(m.Groups["Size"].Value);
 314            }
 315            sl.FileName = m.Groups["Name"].Value;
 316            sl.FileDate = m.Groups["Date"].Value;
 317            sl.FileTime = m.Groups["Time"].Value;
 318        }
 319        else
 320        {
 321            // is it unix format?
 322            rx = new Regex(@"(?<Dir>.{1}).{9}\s*[0-9]*\s*\w*\s*\w*\s*(?<Size>[0-9]*)\s*(?"
 323                + @"<Month>[a-z|A-Z]{3})\s*(?<Day>[0-9]*)\s*(?<Time>[0-9|:]*)\s*("
 324                + @"?<Name>.*)\r", RegexOptions.None);
 325
 326            m = rx.Match(Line);
 327            if (m.Success)
 328            {
 329                sl.Valid = true;
 330                if (m.Groups["Dir"].Value == "d")
 331                {
 332                    sl.Dir = true;
 333                }
 334                else
 335                {
 336                    sl.Dir = false;
 337                }
 338                sl.FileSize = Convert.ToInt32(m.Groups["Size"].Value);
 339                sl.FileName = m.Groups["Name"].Value;
 340
 341                if (m.Groups["Time"].Value.IndexOf(':') == -1)
 342                {
 343                    sl.FileDate = m.Groups["Day"].Value + " " + m.Groups["Month"].Value + " " + m.Groups["Time"].Value;
 344                    sl.FileTime = "";
 345                }
 346                else
 347                {
 348                    sl.FileDate = m.Groups["Day"].Value + " " + m.Groups["Month"].Value + " " + DateTime.Now.Year.ToString();
 349                    sl.FileTime = m.Groups["Time"].Value;
 350                }
 351            }
 352        }
 353
 354        return sl;
 355    }
 356
 357
 358    /// Get the size of the file on the FTP server.
 359    public long GetFileSize(string sFileName)
 360    {
 361        long size;
 362
 363        if (!m_bLoggedIn)
 364        {
 365            Login();
 366        }
 367        /// Send an FTP command. 
 368        SendCommand("SIZE " + sFileName);
 369        size = 0;
 370
 371        if (m_iRetValue == 213)
 372        {
 373            size = long.Parse(m_sReply.Substring(4));
 374        }
 375        else
 376        {
 377            MessageString = m_sReply;
 378            throw new IOException(m_sReply.Substring(4));
 379        }
 380
 381        return size;
 382    }
 383
 384    /// Log on to the FTP server.
 385    public bool Login()
 386    {
 387        m_objClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 388
 389        IPEndPoint ep = new IPEndPoint(Dns.Resolve(m_sRemoteHost).AddressList[0], m_iRemotePort);
 390
 391        try
 392        {
 393            m_objClientSocket.Connect(ep);
 394        }
 395        catch (Exception)
 396        {
 397            MessageString = m_sReply;
 398            throw new IOException("Cannot connect to the remote server");
 399        }
 400
 401        ReadReply();
 402        if (m_iRetValue != 220)
 403        {
 404            CloseConnection();
 405            MessageString = m_sReply;
 406            throw new IOException(m_sReply.Substring(4));
 407        }
 408
 409        /// Send an FTP command to send a user logon ID to the server.
 410        SendCommand("USER " + m_sRemoteUser);
 411        if (!(m_iRetValue == 331 || m_iRetValue == 230))
 412        {
 413            Cleanup();
 414            MessageString = m_sReply;
 415            throw new IOException(m_sReply.Substring(4));
 416        }
 417
 418        if (m_iRetValue != 230)
 419        {
 420            ///Send an FTP command to send a user logon password to the server.
 421            SendCommand("PASS " + m_sRemotePassword);
 422            if (!(m_iRetValue == 230 || m_iRetValue == 202))
 423            {
 424                Cleanup();
 425                MessageString = m_sReply;
 426                throw new IOException(m_sReply.Substring(4));
 427            }
 428        }
 429
 430        m_bLoggedIn = true;
 431        /// Call the ChangeDirectory user-defined function to change the directory to the 
 432        /// remote FTP folder that is mapped.
 433        ChangeDirectory(m_sRemotePath);
 434
 435        /// Return the final result.
 436        return m_bLoggedIn;
 437    }
 438
 439    /// If the value of mode is true, set binary mode for downloads. Otherwise, set ASCII mode.
 440    public void SetBinaryMode(bool bMode)
 441    {
 442        if (bMode)
 443        {
 444            /// Send the FTP command to set the binary mode.
 445            /// (TYPE is an FTP command that is used to specify representation type.)
 446            SendCommand("TYPE I");
 447        }
 448        else
 449        {
 450            /// Send the FTP command to set ASCII mode. 
 451            /// (TYPE is an FTP command that is used to specify representation type.)
 452            SendCommand("TYPE A");
 453        }
 454
 455        if (m_iRetValue != 200)
 456        {
 457            MessageString = m_sReply;
 458            throw new IOException(m_sReply.Substring(4));
 459        }
 460    }
 461
 462    ///  Download a file to the local directory of the assembly. Keep the same file name.
 463    public void DownloadFile(string sFileName)
 464    {
 465        DownloadFile(sFileName, "", false);
 466    }
 467
 468    /// Download a remote file to the local directory of the Assembly. Keep the same file name.
 469    public void DownloadFile(string sFileName, bool bResume)
 470    {
 471        DownloadFile(sFileName, "", bResume);
 472    }
 473
 474    /// Download a remote file to a local file name. You must include a path.
 475    /// The local file name will be created or will be overwritten, but the path must exist.
 476    public void DownloadFile(string sFileName, string sLocalFileName)
 477    {
 478        DownloadFile(sFileName, sLocalFileName, false);
 479    }
 480
 481
 482    /// Download a remote file to a local file name. You must include a path. Set the 
 483    /// resume flag. The local file name will be created or will be overwritten, but the path must exist.
 484    public void DownloadFile(string sFileName, string sLocalFileName, bool bResume)
 485    {
 486        Stream st;
 487        FileStream output;
 488        Socket cSocket;
 489        long offset;
 490        //long npos;
 491
 492        if (!m_bLoggedIn)
 493        {
 494            Login();
 495        }
 496
 497        SetBinaryMode(true);
 498
 499        if (sLocalFileName.Equals(""))
 500        {
 501            sLocalFileName = sFileName;
 502        }
 503
 504        if (!File.Exists(sLocalFileName))
 505        {
 506            st = File.Create(sLocalFileName);
 507            st.Close();
 508        }
 509
 510        output = new FileStream(sLocalFileName, FileMode.Open);
 511        cSocket = CreateDataSocket();
 512        offset = 0;
 513
 514        if (bResume)
 515        {
 516            offset = output.Length;
 517
 518            if (offset > 0)
 519            {
 520                /// Send an FTP command to restart.
 521                SendCommand("REST " + offset);
 522                if (m_iRetValue != 350)
 523                {
 524                    offset = 0;
 525                }
 526            }
 527
 528            if (offset > 0)
 529            {
 530                //npos = output.Seek(offset, SeekOrigin.Begin);
 531            }
 532        }
 533
 534        /// Send an FTP command to retrieve a file.
 535        SendCommand("RETR " + sFileName);
 536
 537        if (!(m_iRetValue == 150 || m_iRetValue == 125))
 538        {
 539            MessageString = m_sReply;
 540            throw new IOException(m_sReply.Substring(4));
 541        }
 542
 543        while (true)
 544        {
 545            Array.Clear(m_aBuffer, 0, m_aBuffer.Length);
 546            m_iBytes = cSocket.Receive(m_aBuffer, m_aBuffer.Length, 0);
 547            output.Write(m_aBuffer, 0, m_iBytes);
 548
 549            if (m_iBytes <= 0)
 550            {
 551                break;
 552            }
 553        }
 554
 555        output.Close();
 556
 557        if (cSocket.Connected)
 558        {
 559            cSocket.Close();
 560        }
 561
 562        ReadReply();
 563        if (!(m_iRetValue == 226 || m_iRetValue == 250))
 564        {
 565            MessageString = m_sReply;
 566            throw new IOException(m_sReply.Substring(4));
 567        }
 568
 569    }
 570
 571    /// This is a function that is used to upload a file from your local hard disk
 572    /// to your FTP site.
 573    public void UploadFile(string sFileName)
 574    {
 575        UploadFile(sFileName, false);
 576    }
 577
 578    /// This is a function that is used to upload a file from your local hard disk
 579    ///  to your FTP site and then set the resume flag.
 580    public void UploadFile(string sFileName, bool bResume)
 581    {
 582        Socket cSocket;
 583        long offset;
 584        FileStream input;
 585        bool bFileNotFound;
 586
 587        if (!m_bLoggedIn)
 588        {
 589            Login();
 590        }
 591
 592        cSocket = CreateDataSocket();
 593        offset = 0;
 594
 595        if (bResume)
 596        {
 597            try
 598            {
 599                SetBinaryMode(true);
 600                offset = GetFileSize(sFileName);
 601            }
 602            catch (Exception)
 603            {
 604                offset = 0;
 605            }
 606        }
 607
 608        if (offset > 0)
 609        {
 610            SendCommand("REST " + offset);
 611            if (m_iRetValue != 350)
 612            {
 613                /// The remote server may not support resuming.
 614                offset = 0;
 615            }
 616        }
 617
 618        /// Send an FTP command to store a file.
 619        SendCommand("STOR " + Path.GetFileName(sFileName));
 620        if (!(m_iRetValue == 125 || m_iRetValue == 150))
 621        {
 622            MessageString = m_sReply;
 623            throw new IOException(m_sReply.Substring(4));
 624        }
 625
 626        /// Check to see if the file exists before the upload.
 627        bFileNotFound = false;
 628        if (File.Exists(sFileName))
 629        {
 630            /// Open the input stream to read the source file.
 631            input = new FileStream(sFileName, FileMode.Open);
 632            if (offset != 0)
 633            {
 634                input.Seek(offset, SeekOrigin.Begin);
 635            }
 636
 637            /// Upload the file. 
 638            m_iBytes = input.Read(m_aBuffer, 0, m_aBuffer.Length);
 639            while (m_iBytes > 0)
 640            {
 641                cSocket.Send(m_aBuffer, m_iBytes, 0);
 642                m_iBytes = input.Read(m_aBuffer, 0, m_aBuffer.Length);
 643            }
 644            input.Close();
 645        }
 646        else
 647        {
 648            bFileNotFound = true;
 649        }
 650
 651        if (cSocket.Connected)
 652        {
 653            cSocket.Close();
 654        }
 655
 656        /// Check the return value if the file was not found.
 657        if (bFileNotFound)
 658        {
 659            MessageString = m_sReply;
 660            throw new IOException("The file: " + sFileName + " was not found. Cannot upload the file to the FTP site");
 661        }
 662
 663        ReadReply();
 664        if (!(m_iRetValue == 226 || m_iRetValue == 250))
 665        {
 666            MessageString = m_sReply;
 667            throw new IOException(m_sReply.Substring(4));
 668        }
 669    }
 670
 671    /// Delete a file from the remote FTP server.
 672    public bool DeleteFile(string sFileName)
 673    {
 674        bool bResult;
 675
 676        bResult = true;
 677        if (!m_bLoggedIn)
 678        {
 679            Login();
 680        }
 681        /// Send an FTP command to delete a file.
 682        SendCommand("DELE " + sFileName);
 683        if (m_iRetValue != 250)
 684        {
 685            bResult = false;
 686            MessageString = m_sReply;
 687        }
 688
 689        /// Return the final result.
 690        return bResult;
 691    }
 692
 693    /// Rename a file on the remote FTP server.
 694    public bool RenameFile(string sOldFileName, string sNewFileName)
 695    {
 696        bool bResult = true;
 697
 698        if (!m_bLoggedIn)
 699        {
 700            Login();
 701        }
 702        /// Send an FTP command to rename from a file.
 703        SendCommand("RNFR " + sOldFileName);
 704        if (m_iRetValue != 350)
 705        {
 706            MessageString = m_sReply;
 707            throw new IOException(m_sReply.Substring(4));
 708        }
 709
 710        /// Send an FTP command to rename a file to a new file name.
 711        /// It will overwrite if newFileName exists. 
 712        SendCommand("RNTO " + sNewFileName);
 713        if (m_iRetValue != 250)
 714        {
 715            MessageString = m_sReply;
 716            throw new IOException(m_sReply.Substring(4));
 717        }
 718        /// Return the final result.
 719        return bResult;
 720    }
 721
 722    /// This is a function that is used to create a directory on 
 723    /// the remote FTP server.
 724    public bool CreateDirectory(string sDirName)
 725    {
 726        bool bResult = true;
 727
 728        if (!m_bLoggedIn)
 729        {
 730            Login();
 731        }
 732        /// Send an FTP command to make directory on the FTP server.
 733        SendCommand("MKD " + sDirName);
 734        if (m_iRetValue != 257)
 735        {
 736            bResult = false;
 737            MessageString = m_sReply;
 738        }
 739
 740        /// Return the final result.
 741        return bResult;
 742    }
 743
 744    /// This is a function that is used to delete a directory on 
 745    /// the remote FTP server.
 746    public bool RemoveDirectory(string sDirName)
 747    {
 748        bool bResult = true;
 749
 750        /// Check if logged on to the FTP server
 751        if (!m_bLoggedIn)
 752        {
 753            Login();
 754        }
 755        /// Send an FTP command to remove directory on the FTP server.
 756        SendCommand("RMD " + sDirName);
 757        if (m_iRetValue != 250)
 758        {
 759            bResult = false;
 760            MessageString = m_sReply;
 761        }
 762
 763        /// Return the final result.
 764        return bResult;
 765    }
 766
 767    /// This is a function that is used to change the current working
 768    /// directory on the remote FTP server.
 769    public bool ChangeDirectory(string sDirName)
 770    {
 771        bool bResult = true;
 772
 773        /// Check if you are in the root directory.
 774        if (sDirName.Equals("."))
 775        {
 776            return false;
 777        }
 778        /// Check if logged on to the FTP server
 779        if (!m_bLoggedIn)
 780        {
 781            Login();
 782        }
 783        /// Send an FTP command to change directory on the FTP server.
 784        SendCommand("CWD " + sDirName);
 785        if (m_iRetValue != 250)
 786        {
 787            bResult = false;
 788            MessageString = m_sReply;
 789            throw new DirectoryNotFoundException("Cannot find directory : " + sDirName);
 790        }
 791
 792        m_sRemotePath = sDirName;
 793
 794        /// Return the final result.
 795        return bResult;
 796    }
 797
 798    ///  Close the FTP connection of the remote server.
 799    public void CloseConnection()
 800    {
 801        if (m_objClientSocket != null)
 802        {
 803            /// Send an FTP command to end an FTP server system.
 804            SendCommand("QUIT");
 805        }
 806
 807        Cleanup();
 808    }
 809
 810    #endregion
 811
 812    #region " Private Subs and Functions "
 813
 814    /// Read the reply from the FTP server.
 815    private void ReadReply()
 816    {
 817        m_sMes = "";
 818        m_sReply = ReadLine(false);
 819        m_iRetValue = int.Parse(m_sReply.Substring(0, 3));
 820    }
 821
 822    /// Clean up some variables.
 823    private void Cleanup()
 824    {
 825        if (m_objClientSocket != null)
 826        {
 827            m_objClientSocket.Close();
 828            m_objClientSocket = null;
 829        }
 830
 831        m_bLoggedIn = false;
 832    }
 833
 834    /// Read a line from the FTP server.
 835    private string ReadLine(bool bClearMes)
 836    {
 837        char seperator = Convert.ToChar("\n");
 838        string[] mess;
 839
 840        if (bClearMes)
 841        {
 842            m_sMes = "";
 843        }
 844
 845        while (true)
 846        {
 847            Array.Clear(m_aBuffer, 0, BLOCK_SIZE);
 848            m_iBytes = m_objClientSocket.Receive(m_aBuffer, m_aBuffer.Length, 0);
 849            m_sMes += ASCII.GetString(m_aBuffer, 0, m_iBytes);
 850            if (m_iBytes < m_aBuffer.Length)
 851            {
 852                break;
 853            }
 854        }
 855
 856        mess = m_sMes.Split(seperator);
 857        if (m_sMes.Length > 2)
 858        {
 859            m_sMes = mess[mess.Length - 2];
 860        }
 861        else
 862        {
 863            m_sMes = mess[0];
 864        }
 865
 866        if (!m_sMes.Substring(3, 1).Equals(" "))
 867        {
 868            return ReadLine(true);
 869        }
 870
 871        return m_sMes;
 872    }
 873
 874    ///  This is a function that is used to send a command to the FTP server that you are connected to.
 875    private void SendCommand(string sCommand)
 876    {
 877        sCommand = sCommand + "\r\n";
 878        byte[] cmdbytes = ASCII.GetBytes(sCommand);
 879        m_objClientSocket.Send(cmdbytes, cmdbytes.Length, 0);
 880        ReadReply();
 881    }
 882
 883    /// Create a data socket.
 884    private Socket CreateDataSocket()
 885    {
 886        int index1;
 887        int index2;
 888        int len;
 889        int partCount;
 890        int i;
 891        int port;
 892        string ipData;
 893        string buf;
 894        string ipAddress;
 895        int[] parts = new int[7];
 896        char ch;
 897        Socket s;
 898        IPEndPoint ep;
 899
 900        /// Send an FTP command to use passive data connection. 
 901        SendCommand("PASV");
 902        if (m_iRetValue != 227)
 903        {
 904            MessageString = m_sReply;
 905            throw new IOException(m_sReply.Substring(4));
 906        }
 907
 908        index1 = m_sReply.IndexOf("(");
 909        index2 = m_sReply.IndexOf(")");
 910        ipData = m_sReply.Substring(index1 + 1, index2 - index1 - 1);
 911
 912        len = ipData.Length;
 913        partCount = 0;
 914        buf = "";
 915
 916        for (i = 0; i <= (len - 1); i++)
 917        {
 918            if (partCount > 6)
 919            {
 920                break;
 921            }
 922
 923            ch = char.Parse(ipData.Substring(i, 1));
 924            if (char.IsDigit(ch))
 925            {
 926                buf += ch;
 927            }
 928            else if (ch != Convert.ToChar(","))
 929            {
 930                MessageString = m_sReply;
 931
 932                throw new IOException("Malformed PASV reply: " + m_sReply);
 933            }
 934
 935            if ((ch == Convert.ToChar(",")) | (i + 1 == len))
 936            {
 937                try
 938                {
 939                    parts[partCount] = int.Parse(buf);
 940                    partCount += 1;
 941                    buf = "";
 942                }
 943                catch (Exception)
 944                {
 945                    MessageString = m_sReply;
 946                    throw new IOException("Malformed PASV reply: " + m_sReply);
 947                }
 948            }
 949        }
 950
 951        ipAddress = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[3];
 952
 953        /// Make this call in Visual Basic .NET 2002. You want to 
 954        /// bitshift the number by 8 bits. In Visual Basic .NET 2002 you must
 955        /// multiply the number by 2 to the power of 8.
 956        /// port = parts(4) * (2 ^ 8)
 957
 958        /// Make this call and then comment out the previous line for
 959        /// Visual Basic .NET 2003.
 960        port = parts[4] << 8;
 961
 962        /// Determine the data port number.
 963        port = port + parts[5];
 964
 965        s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 966        ep = new IPEndPoint(Dns.Resolve(ipAddress).AddressList[0], port);
 967
 968        try
 969        {
 970            s.Connect(ep);
 971        }
 972        catch (Exception)
 973        {
 974            MessageString = m_sReply;
 975            flag_bool = false;
 976            throw new IOException("Cannot connect to remote server.");
 977            /// If you cannot connect to the FTP server that is 
 978            /// specified, make the boolean variable false.
 979        }
 980
 981        /// If you can connect to the FTP server that is specified,
 982        /// make the boolean variable true.
 983        flag_bool = true;
 984        return s;
 985    }
 986
 987    #endregion
 988}
 989
 990public class DirFile : IComparable
 991{
 992    private string _Name;
 993    private bool _IsDir;
 994    private string _Date;
 995    private string _Time;
 996    private int _Size;
 997
 998    public string Name { get { return _Name; } }
 999    public bool IsDir { get { return _IsDir; } }
1000    public string FileDate { get { return _Date; } }
1001    public string FileTime { get { return _Time; } }
1002    public int FileSize { get { return _Size; } }
1003
1004    public DirFile(string Name, string FDate, string FTime, bool Dir, int FSize)
1005    {
1006        _Name = Name;
1007        _Date = FDate;
1008        _Time = FTime;
1009        _IsDir = Dir;
1010        _Size = FSize;
1011    }
1012
1013    public int CompareTo(object obj)
1014    {
1015        DirFile df;
1016
1017        // Any non-Nothing object is greater than nothing.
1018        if (obj == null)
1019        {
1020            return 1;
1021        }
1022
1023        // Avoid late-binding and cast to a specific Person Object.
1024        df = ((DirFile)(obj));
1025
1026        // Use the String's CompareTo Method to perform the check.
1027        return this.IsDir.CompareTo(df.IsDir);
1028    }
1029}
1030
1031public class DirList : CollectionBase
1032{
1033    // Create the Default Property Item for this collection.
1034    // Allow the retrieval by index.
1035    public DirFile this[int index]
1036    {
1037        get
1038        {
1039            // Avoid Late-binding and return this as a DirFile Object
1040            return ((DirFile)(this.InnerList[index]));
1041        }
1042    }
1043
1044    // Create another default property for this collection.
1045    // Allow retrieval by name.
1046    public DirFile this[string Instance]
1047    {
1048        get
1049        {
1050            DirFile df;
1051            foreach (DirFile tempLoopVar_df in this.InnerList)
1052            {
1053                df = tempLoopVar_df;
1054                if (df.Name == Instance)
1055                {
1056                    // We found our DirFile object, return it.
1057                    return df;
1058                }
1059            }
1060            return null;
1061        }
1062    }
1063
1064    // Create another property for this collection.
1065    // Allows checking for existance by name.
1066    bool Exists(string Instance)
1067    {
1068        DirFile df;
1069        foreach (DirFile tempLoopVar_df in this.InnerList)
1070        {
1071            df = tempLoopVar_df;
1072            if (df.Name == Instance)
1073            {
1074                // We found our DirFile object, return it.
1075                return true;
1076            }
1077        }
1078        return false;
1079    }
1080
1081    // Create a new instance of our Collection, by calling MyBase.New
1082    public DirList()
1083    {
1084    }
1085
1086    protected override void OnSet(int index, object oldValue, object newValue)
1087    {
1088        if (!(newValue is DirFile))
1089        {
1090            throw (new ArgumentException(string.Format("Cannot add a {0} type to this collection", newValue.GetType().ToString()), "Value"));
1091        }
1092    }
1093
1094    protected override void OnInsert(int index, object value)
1095    {
1096        if (!(value is DirFile))
1097        {
1098            throw (new ArgumentException(string.Format("Cannot add a {0} type to this collection", value.GetType().ToString()), "Value"));
1099        }
1100    }
1101
1102    protected override void OnRemove(int index, object value)
1103    {
1104        if (!(value is DirFile))
1105        {
1106            throw (new ArgumentException(string.Format("Cannot add a {0} type to this collection", value.GetType().ToString()), "Value"));
1107        }
1108    }
1109
1110    // Method to add a single DirFile object to our collection.
1111    public int Add(DirFile value)
1112    {
1113        return this.InnerList.Add(value);
1114    }
1115
1116    // Method to Remove a specific DirFile object from our collection.
1117    public void Remove(DirFile value)
1118    {
1119        this.InnerList.Remove(value);
1120    }
1121
1122    // Method to check if a DirFile object already exists in the collection.
1123    public bool Contains(DirFile value)
1124    {
1125        return this.Contains(value);
1126    }
1127
1128    // Create the Sort method for the collection.
1129    public void Sort()
1130    {
1131        this.InnerList.Sort();
1132    }
1133}
1134