Ejemplo n.º 1
0
        private void DoNLST(Command command, Replyer replyer)
        {
            string path = this.currentAccount_.LocalizePath(command.GetParam());

            if (String.IsNullOrEmpty(path))
            {
                this.OnLogger(replyer.Send(ReplyCode._451));

                return;
            }

            StringBuilder nlst = new StringBuilder();

            foreach (var entry in Directory.GetFileSystemEntries(path))
            {
                nlst.AppendLine(Path.GetFileName(entry));
            }

            this.NotifyType(replyer);

            if (this.currentDTP_.Send(nlst.ToString()))
            {
                this.OnLogger(replyer.Send(ReplyCode._250));
            }
            else
            {
                this.OnLogger(replyer.Send(ReplyCode._451));
            }
        }
Ejemplo n.º 2
0
        private void DoSTOU(Command command, Replyer replyer)
        {
            string file_path = this.currentAccount_.LocalizePath(command.Param);
            string extension = Path.GetExtension(file_path);

            Path.ChangeExtension(file_path,
                                 DateTime.Now.ToString(".yyyy-MM-dd_HH-mm-ss_ffff") + extension);

            if (String.IsNullOrEmpty(file_path))
            {
                this.OnLogger(replyer.Send(ReplyCode._553));
            }
            else
            {
                this.NotifyType(replyer);

                if (this.currentDTP_.Store(file_path))
                {
                    this.OnLogger(replyer.Send(ReplyCode._250));
                }
                else
                {
                    this.OnLogger(replyer.Send(ReplyCode._553));
                }
            }
        }
Ejemplo n.º 3
0
        private void DoTYPE(Command command, Replyer replyer)
        {
            string[] tokens = command.Param.Split(' ');

            switch (tokens[0])
            {
            case "A":
                this.currentDTP_.IsBinary = false;
                this.OnLogger(replyer.Send(ReplyCode._200));
                break;

            case "I":
                this.currentDTP_.IsBinary = false;
                this.OnLogger(replyer.Send(ReplyCode._200));
                break;

            case "E":
            case "L":
                this.OnLogger(replyer.Send(ReplyCode._202));
                break;

            default:
                this.OnLogger(replyer.Send(ReplyCode._501));
                break;
            }
        }
Ejemplo n.º 4
0
 private void DoUSER(Command command, Replyer replyer)
 {
     if (this.currentAccount_.CertaineUser(command.Param))
     {
         replyer.Send(ReplyCode._331);
     }
     else
     {
         this.OnLogger(replyer.Send(ReplyCode._501));
     }
 }
Ejemplo n.º 5
0
 private void DoCWD(Command command, Replyer replyer)
 {
     if (this.currentAccount_.ChangeDirectory(command.Param))
     {
         this.OnLogger(replyer.Send(ReplyCode._250));
     }
     else
     {
         this.OnLogger(replyer.Send(ReplyCode._550));
     }
 }
Ejemplo n.º 6
0
 private void DoCDUP(Command command, Replyer replyer)
 {
     if (this.currentAccount_.ChangeDirectory(".."))
     {
         this.OnLogger(replyer.Send(ReplyCode._200));
     }
     else
     {
         this.OnLogger(replyer.Send(ReplyCode._550));
     }
 }
Ejemplo n.º 7
0
 private void NotifyType(Replyer replyer)
 {
     if (!this.currentDTP_.IsPassive)
     {
         if (this.currentDTP_.IsBinary)
         {
             this.OnLogger(replyer.Send(ReplyCode._150, "Open BINARY mode."));
         }
         else
         {
             this.OnLogger(replyer.Send(ReplyCode._150, "Open ASCII mode."));
         }
     }
 }
Ejemplo n.º 8
0
        private void DoPORT(Command command, Replyer replyer)
        {
            this.currentDTP_.IsPassive = false;
            this.currentDTP_.StopPassive();

            if (this.currentDTP_.SetPort(command.Param))
            {
                this.OnLogger(replyer.Send(ReplyCode._200));
            }
            else
            {
                this.OnLogger(replyer.Send(ReplyCode._501));
            }
        }
Ejemplo n.º 9
0
 private void DoPASS(Command command, Replyer replyer)
 {
     if (this.currentAccount_.CertainePassword(command.Param))
     {
         this.OnLogger(replyer.Send(ReplyCode._230));
     }
     else
     {
         if (String.IsNullOrEmpty(command.Param))
         {
             this.OnLogger(replyer.Send(ReplyCode._501));
         }
         else
         {
             this.OnLogger(replyer.Send(ReplyCode._530));
         }
     }
 }
Ejemplo n.º 10
0
        private void DoPWD(Command command, Replyer replyer)
        {
            string remotePath = this.currentAccount_.RemoteCurrentPath;

            if (String.IsNullOrEmpty(remotePath))
            {
                remotePath = "/";
            }

            this.OnLogger(replyer.Send(ReplyCode._257, String.Format("\"{0}\" is your directory.", remotePath)));
        }
Ejemplo n.º 11
0
        private void DoDELE(Command command, Replyer replyer)
        {
            string file_path = this.currentAccount_.LocalizePath(command.Param);

            if (String.IsNullOrEmpty(file_path))
            {
                this.OnLogger(replyer.Send(ReplyCode._550));
            }
            else
            {
                if (this.currentDTP_.Delete(file_path, false))
                {
                    this.OnLogger(replyer.Send(ReplyCode._250));
                }
                else
                {
                    this.OnLogger(replyer.Send(ReplyCode._550));
                }
            }
        }
Ejemplo n.º 12
0
        private void DoPASV(Command command, Replyer replyer)
        {
            string host_port = MakeHostPortPart(
                this.connection_.Client.LocalEndPoint, FindUnusedPort());

            this.currentDTP_.SetPort(host_port);
            this.currentDTP_.IsPassive = true;
            this.currentDTP_.StartPassive();

            this.OnLogger(replyer.Send(
                              ReplyCode._227, String.Format("Entering Passive Mode. ({0})", host_port)));
        }
Ejemplo n.º 13
0
        private void DoMKD(Command command, Replyer replyer)
        {
            try
            {
                string path = this.currentAccount_.LocalizePath(command.Param);

                if (String.IsNullOrEmpty(path))
                {
                    this.OnLogger(replyer.Send(ReplyCode._550));
                }
                else
                {
                    Directory.CreateDirectory(path);

                    this.OnLogger(replyer.Send(ReplyCode._250));
                }
            }
            catch (Exception e)
            {
                this.OnLogger(replyer.Send(ReplyCode._550));
            }
        }
Ejemplo n.º 14
0
        private void DoAPPE(Command command, Replyer replyer)
        {
            string file_path = this.currentAccount_.LocalizePath(command.Param);

            if (String.IsNullOrEmpty(file_path))
            {
                this.OnLogger(replyer.Send(ReplyCode._553));
            }
            else
            {
                this.NotifyType(replyer);

                if (this.currentDTP_.Append(file_path))
                {
                    this.OnLogger(replyer.Send(ReplyCode._250));
                }
                else
                {
                    this.OnLogger(replyer.Send(ReplyCode._553));
                }
            }
        }
Ejemplo n.º 15
0
        private void DoLIST(Command command, Replyer replyer)
        {
            // Ignore LIST option `-al`
            string path = this.currentAccount_.LocalizePath(command.GetParam());

            if (String.IsNullOrEmpty(path))
            {
                this.OnLogger(replyer.Send(ReplyCode._451));

                return;
            }

            StringBuilder      nlst           = new StringBuilder();
            string             host_name      = Dns.GetHostName();
            DateTimeFormatInfo dateTimeFormat = new CultureInfo("en-US", true).DateTimeFormat;

            // [permission]<SP>[?]<SP>[user]<SP>[datetime]<SP>[name]
            foreach (var entry in Directory.GetFileSystemEntries(path))
            {
                if (Directory.Exists(entry))
                {
                    DirectoryInfo info = new DirectoryInfo(entry);

                    nlst.AppendLine(
                        String.Format("drwxrw-rw-     0 owner {0,15} {1} {2,8} {3}",
                                      0,
                                      dateTimeFormat.GetAbbreviatedMonthName(info.LastWriteTime.Month),
                                      info.LastWriteTime.ToString("d HH:MM"),
                                      info.Name));
                }
                else
                {
                    FileInfo info = new FileInfo(entry);

                    nlst.AppendLine(
                        String.Format("-rwxrw-rw-     0 owner {0,15} {1} {2,8} {3}",
                                      info.Length,
                                      dateTimeFormat.GetAbbreviatedMonthName(info.LastWriteTime.Month),
                                      info.LastWriteTime.ToString("d HH:MM"),
                                      info.Name));
                }
            }
#if MLST
            // MLST format
            // [name];[type];[size];[datetime];[user];[permission]
            foreach (var entry in Directory.GetFileSystemEntries(path))
            {
                if (Directory.Exists(entry))
                {
                    DirectoryInfo info = new DirectoryInfo(entry);

                    nlst.AppendLine(
                        String.Format("{0};D;{1};{2};1;\"owner\" [0];\"\" [0];rwxrw-rw-;1",
                                      info.Name, 0,
                                      info.LastWriteTime.ToString("yyyy-MM-ddTHH:MM:ss.fffZ")
                                      ));
                }
                else
                {
                    FileInfo info = new FileInfo(entry);

                    nlst.AppendLine(
                        String.Format("{0};-;{1};{2};1;\"owner\" [0];\"\" [0];rwxrw-rw-;1",
                                      info.Name, info.Length,
                                      info.LastWriteTime.ToString("yyyy-MM-ddTHH:MM:ss.fffZ")
                                      ));
                }
            }
#endif
            this.NotifyType(replyer);

            if (this.currentDTP_.Send(nlst.ToString()))
            {
                this.OnLogger(replyer.Send(ReplyCode._226));
            }
            else
            {
                this.OnLogger(replyer.Send(ReplyCode._451));
            }
        }
Ejemplo n.º 16
0
        private void Run()
        {
            DataTransferProcess dtp = new DataTransferProcess();

            StreamWriter writer = new StreamWriter(this.connection_.GetStream());
            StreamReader reader = new StreamReader(this.connection_.GetStream(), Encoding.GetEncoding(932));

            writer.AutoFlush = true;

            var replyer = new Replyer(writer);

            this.OnLogger(replyer.Send(ReplyCode._220));

            while (true)
            {
                string commandline;

                try
                {
                    commandline = reader.ReadLine();
                }
                catch (Exception e)
                {
                    this.OnLogger(e.Message);
                    break;
                }

                if (String.IsNullOrEmpty(commandline))
                {
                    break;
                }

                this.OnLogger(commandline);

                // RFC959
                var isQuit  = false;
                var command = new Command(commandline);

                switch (this.currentAccount_.State)
                {
                case LoginAccount.LoginState.NoLogin:
                    switch (command.Name)
                    {
                    case "USER":            // 認証するユーザー名
                        this.DoUSER(command, replyer);
                        break;

                    default:
                        this.OnLogger(replyer.Send(ReplyCode._502));
                        break;
                    }
                    break;

                case LoginAccount.LoginState.Queried:
                    switch (command.Name)
                    {
                    case "PASS":            // 認証パスワード。
                        this.DoPASS(command, replyer);
                        break;

                    default:
                        this.OnLogger(replyer.Send(ReplyCode._502));
                        break;
                    }
                    break;

                case LoginAccount.LoginState.Passed:
                    switch (command.Name)
                    {
                    case "APPE":            // 引数に示したファイルに対して追記する。
                        this.DoAPPE(command, replyer);
                        break;

                    case "CDUP":            // 親ディレクトリに移動する。
                        this.DoCDUP(command, replyer);
                        break;

                    case "CWD":             // 作業ディレクトリの変更。引数は移動するディレクトリ。
                        this.DoCWD(command, replyer);
                        break;

                    case "DELE":            // ファイルを削除する。引数は削除するファイル。
                        this.DoDELE(command, replyer);
                        break;

                    case "HELP":            // コマンドの一覧。引数を指定するとより詳しいコマンド情報を返す。
                        replyer.Send(ReplyCode._202);
                        break;

                    case "LIST":            // 引数に指定したファイルの情報やディレクトリの一覧。指定しない場合、現在のディレクトリの情報を一覧。
                        this.DoLIST(command, replyer);
                        break;

                    case "XMKD":
                    case "MKD":             // 引数に指定した名前のディレクトリを作成する。
                        this.DoMKD(command, replyer);
                        break;

                    case "NLST":            // 引数に指定したディレクトリのファイル一覧を返す。
                        this.DoNLST(command, replyer);
                        break;

                    case "NOOP":            // 何もしない。接続維持のためダミーパケットとして使われることがほとんど。
                        replyer.Send(ReplyCode._200);
                        break;

                    case "MODE":            // 転送モードの設定(ストリーム、ブロック、圧縮)。
                        replyer.Send(ReplyCode._202);
                        break;

                    case "PASS":            // 認証パスワード。
                        this.DoPASS(command, replyer);
                        break;

                    case "PASV":            // パッシブモードに移行する。
                        this.DoPASV(command, replyer);
                        break;

                    case "PORT":            // サーバが接続すべきポートとアドレスを指定する。
                        this.DoPORT(command, replyer);
                        break;

                    case "XPWD":
                    case "PWD":             // 作業ディレクトリを取得する。
                        this.DoPWD(command, replyer);
                        break;

                    case "QUIT":            // 接続を終了する。
                        replyer.Send(ReplyCode._221);

                        isQuit = true;
                        break;

                    case "RETR":            // リモートファイルをダウンロード(Retrieve)する。
                        this.DoRETR(command, replyer);
                        break;

                    case "XRMD":
                    case "RMD":             // 引数に指定したディレクトリを削除する。
                        this.DoRMD(command, replyer);
                        break;

                    case "STOR":            // ファイルをアップロード(Stor)する。
                        this.DoSTOR(command, replyer);
                        break;

                    case "STOU":            // ファイル名が重複しないようにファイルをアップロードする。
                        this.DoSTOU(command, replyer);
                        break;

                    case "TYPE":            // 転送モードを設定する(アスキーモード、バイナリモード)。
                        this.DoTYPE(command, replyer);
                        break;

                    case "USER":            // 認証するユーザー名
                        this.DoUSER(command, replyer);
                        break;

                    case "ABOR":            // ファイルの転送を中止する。
                    case "ACCT":            // アカウント情報。引数はユーザアカウントを示す文字列。
                    case "ALLO":            // ファイルを受け取るために十分なディスクスペースを割り当てる。引数は予約するサイズ。
                    case "REIN":            // 接続を再初期化する。
                    case "RNFR":            // 引数に指定した名前のファイル(ディレクトリ)をリネームする。
                    case "RNTO":            // 引数に指定した名前のファイル(ディレクトリ)にリネームする。
                    case "SITE":            // RFCで定義されていないようなリモートサーバ特有のコマンドを送信する。
                    case "SMNT":            // ファイル構造をマウントする
                    case "STRU":            // 転送するファイルの構造を設定する。
                    case "STAT":            // 現在の状態を取得する。
                    case "SYST":            // システムの種別を返す。
                        this.OnLogger(replyer.Send(ReplyCode._502));
                        break;

                    default:
                        this.OnLogger(replyer.Send(ReplyCode._502));
                        break;
                    }
                    break;

                default:
                    this.OnLogger(replyer.Send(ReplyCode._502));
                    break;
                }

                if (isQuit)
                {
                    break;
                }
            }

            this.currentDTP_.StopPassive();
        }