// Decompiled with JetBrains decompiler
// Type: Retro.FTP.FTPClient
// Assembly: parvulus, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 9FA193B5-EDCA-4010-A168-C8A18CE631F5
// Assembly location: C:\Users\Administrateur\Downloads\Virusshare-00000-msil\P2P-Worm.MSIL.Lupar.a-b4e8ccd55ff21847335fb2856ad750c5cf8f2baa869366cdde763f6410ca3f96.exe

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace Retro.FTP
{
  public class FTPClient
  {
    private string Host;
    private string fPath;
    private string User;
    private string Pass;
    private string l;
    private int Port;
    private int bytes;
    private Socket ftpSocket;
    private int value;
    private bool logined;
    private string reply;
    private static int BLOCK_SIZE = 512;
    private byte[] b = new byte[FTPClient.BLOCK_SIZE];
    private Encoding ASCII = Encoding.ASCII;

    public FTPClient()
    {
      this.Host = "localhost";
      this.fPath = ".";
      this.User = "anonymous";
      this.Pass = "test@test.com";
      this.Port = 21;
      this.logined = false;
    }

    public void setHost(string Host) => this.Host = Host;

    public string getHost() => this.Host;

    public void setPort(int Port) => this.Port = Port;

    public int getPort() => this.Port;

    public void setPath(string Path) => this.fPath = Path;

    public string getPath() => this.fPath;

    public void setUser(string User) => this.User = User;

    public void setPass(string Pass) => this.Pass = Pass;

    public string[] getFileList(string mask)
    {
      if (!this.logined)
        this.login();
      Socket dataSocket = this.createDataSocket();
      this.sendCommand("NLST " + mask);
      if (this.value != 150 && this.value != 125)
        throw new IOException(this.reply.Substring(4));
      this.l = "";
      int count;
      do
      {
        count = dataSocket.Receive(this.b, this.b.Length, SocketFlags.None);
        this.l += this.ASCII.GetString(this.b, 0, count);
      }
      while (count >= this.b.Length);
      string[] fileList = this.l.Split('\n');
      dataSocket.Close();
      this.readReply();
      if (this.value != 226)
        throw new IOException(this.reply.Substring(4));
      return fileList;
    }

    public long getFileSize(string fileName)
    {
      if (!this.logined)
        this.login();
      this.sendCommand("SIZE " + fileName);
      if (this.value == 213)
        return long.Parse(this.reply.Substring(4));
      throw new IOException(this.reply.Substring(4));
    }

    public void login()
    {
      this.ftpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
      IPEndPoint remoteEP = new IPEndPoint(Dns.GetHostEntry(this.Host).AddressList[0], this.Port);
      try
      {
        this.ftpSocket.Connect((EndPoint) remoteEP);
      }
      catch (Exception ex)
      {
        throw new IOException("Couldn't connect to remote server");
      }
      this.readReply();
      if (this.value != 220)
      {
        this.close();
        throw new IOException(this.reply.Substring(4));
      }
      this.sendCommand("USER " + this.User);
      if (this.value != 331 && this.value != 230)
      {
        this.cleanup();
        throw new IOException(this.reply.Substring(4));
      }
      if (this.value != 230)
      {
        this.sendCommand("PASS " + this.Pass);
        if (this.value != 230 && this.value != 202)
        {
          this.cleanup();
          throw new IOException(this.reply.Substring(4));
        }
      }
      this.logined = true;
      Console.WriteLine("Connected to " + this.Host);
      this.chdir(this.fPath);
    }

    public void setBinaryMode(bool mode)
    {
      if (mode)
        this.sendCommand("TYPE I");
      else
        this.sendCommand("TYPE A");
      if (this.value != 200)
        throw new IOException(this.reply.Substring(4));
    }

    public void upload(string fileName) => this.upload(fileName, false);

    public void upload(string fileName, bool resume)
    {
      if (!this.logined)
        this.login();
      Socket dataSocket = this.createDataSocket();
      long offset = 0;
      if (resume)
      {
        try
        {
          this.setBinaryMode(true);
          offset = this.getFileSize(fileName);
        }
        catch (Exception ex)
        {
          offset = 0L;
        }
      }
      if (offset > 0L)
      {
        this.sendCommand("REST " + (object) offset);
        if (this.value != 350)
          offset = 0L;
      }
      this.sendCommand("STOR " + Path.GetFileName(fileName));
      if (this.value != 125)
      {
        int num = this.value;
      }
      FileStream fileStream = new FileStream(fileName, FileMode.Open);
      if (offset != 0L)
        fileStream.Seek(offset, SeekOrigin.Begin);
      while ((this.bytes = fileStream.Read(this.b, 0, this.b.Length)) > 0)
        dataSocket.Send(this.b, this.bytes, SocketFlags.None);
      fileStream.Close();
      if (dataSocket.Connected)
        dataSocket.Close();
      this.readReply();
      if (this.value != 226 && this.value != 250)
        throw new IOException(this.reply.Substring(4));
    }

    public void deleteRemoteFile(string fileName)
    {
      if (!this.logined)
        this.login();
      this.sendCommand("DELE " + fileName);
      int num = this.value;
    }

    public void renameRemoteFile(string oldFileName, string newFileName)
    {
      if (!this.logined)
        this.login();
      this.sendCommand("RNFR " + oldFileName);
      if (this.value != 350)
        throw new IOException(this.reply.Substring(4));
      this.sendCommand("RNTO " + newFileName);
      if (this.value != 250)
        throw new IOException(this.reply.Substring(4));
    }

    public void mkdir(string dirName)
    {
      if (!this.logined)
        this.login();
      this.sendCommand("MKD " + dirName);
      int num = this.value;
    }

    public void rmdir(string dirName)
    {
      if (!this.logined)
        this.login();
      this.sendCommand("RMD " + dirName);
      int num = this.value;
    }

    public void chdir(string dirName)
    {
      if (dirName.Equals("."))
        return;
      if (!this.logined)
        this.login();
      this.sendCommand("CWD " + dirName);
      int num = this.value;
      this.fPath = dirName;
    }

    public void close()
    {
      if (this.ftpSocket != null)
        this.sendCommand("QUIT");
      this.cleanup();
    }

    private void readReply()
    {
      this.l = "";
      this.reply = this.readLine();
      this.value = int.Parse(this.reply.Substring(0, 3));
    }

    private void cleanup()
    {
      if (this.ftpSocket != null)
      {
        this.ftpSocket.Close();
        this.ftpSocket = (Socket) null;
      }
      this.logined = false;
    }

    private string readLine()
    {
      do
      {
        this.bytes = this.ftpSocket.Receive(this.b, this.b.Length, SocketFlags.None);
        this.l += this.ASCII.GetString(this.b, 0, this.bytes);
      }
      while (this.bytes >= this.b.Length);
      string[] strArray = this.l.Split('\n');
      this.l = this.l.Length <= 2 ? strArray[0] : strArray[strArray.Length - 2];
      return !this.l.Substring(3, 1).Equals(" ") ? this.readLine() : this.l;
    }

    private void sendCommand(string command)
    {
      byte[] bytes = Encoding.ASCII.GetBytes((command + "\r\n").ToCharArray());
      this.ftpSocket.Send(bytes, bytes.Length, SocketFlags.None);
      this.readReply();
    }

    private Socket createDataSocket()
    {
      this.sendCommand("PASV");
      if (this.value != 227)
        throw new IOException(this.reply.Substring(4));
      int num1 = this.reply.IndexOf('(');
      int num2 = this.reply.IndexOf(')');
      string str = this.reply.Substring(num1 + 1, num2 - num1 - 1);
      int[] numArray = new int[6];
      int length = str.Length;
      int num3 = 0;
      string s = "";
      for (int startIndex = 0; startIndex < length && num3 <= 6; ++startIndex)
      {
        char c = char.Parse(str.Substring(startIndex, 1));
        if (char.IsDigit(c))
          s += (string) (object) c;
        if (c != ',')
        {
          if (startIndex + 1 != length)
            continue;
        }
        try
        {
          numArray[num3++] = int.Parse(s);
          s = "";
        }
        catch (Exception ex)
        {
        }
      }
      string hostNameOrAddress = numArray[0].ToString() + "." + (object) numArray[1] + "." + (object) numArray[2] + "." + (object) numArray[3];
      int port = (numArray[4] << 8) + numArray[5];
      Socket dataSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
      IPEndPoint remoteEP = new IPEndPoint(Dns.GetHostEntry(hostNameOrAddress).AddressList[0], port);
      try
      {
        dataSocket.Connect((EndPoint) remoteEP);
      }
      catch (Exception ex)
      {
      }
      return dataSocket;
    }
  }
}
