bool SendCommand(Socket client, CQFtpResponse resp) { bool result = true; int send_len = client.Send(Encoding.UTF8.GetBytes(string.Format("{0}\r\n", resp.ToString()))); return(result); }
List <CQFtpResponse> Process(CQFtpRequest req) { List <CQFtpResponse> resps = new List <CQFtpResponse>(); CQFtpResponse resp = new CQFtpResponse(); this.Dispatcher.Invoke(new Action(() => { this.m_MainUI.HandSharks.Add(req.OriginCommand); System.Diagnostics.Trace.WriteLine(req.OriginCommand); })); switch (req.Command.ToUpperInvariant()) { case "USER": { resp.Status = 331; resp.Content = "Guest login ok, send your complete e-mail address as password"; resps.Add(resp); } break; case "PASS": { resp.Status = 230; resp.Content = "Guest login ok, access restrictions apply."; resps.Add(resp); } break; case "SYST": { resp.Status = 215; resp.Content = "Windows."; resps.Add(resp); } break; case "PWD": { resp.Status = 257; resp.Content = string.Format("\"{0}\" is the current directory." , this.m_CurrentPath); resps.Add(resp); } break; case "TYPE": { resp.Status = 200; resp.Content = "Type set."; resps.Add(resp); } break; case "SIZE": { string path = string.Format("{0}{1}" , this.m_Root , req.Content); if (File.Exists(path) == true) { resp.Status = 213; resp.Content = new FileInfo(path).Length.ToString(); resps.Add(resp); } else { resp.Status = 550; resp.Content = "File not found"; resps.Add(resp); } } break; case "CWD": { string path = string.Format("{0}{1}" , this.m_Root , req.Content); if (Directory.Exists(path) == false) { //550 CWD failed. "/WMICodeCreator.cs": directory not found. resp.Status = 550; resp.Content = string.Format("CWD failed \"{0}\": directory not found." , req.Content); resps.Add(resp); } else { this.m_CurrentPath = req.Content; resp.Status = 250; resp.Content = "CWD command successful."; resps.Add(resp); } } break; case "PASV": { resp.Status = 227; string ip = "127,0,0,1"; int port = 3335 + DateTime.Now.Millisecond / 10; if (this.m_SocketData != null) { this.m_SocketData.Close(); this.m_SocketData = null; } this.m_SocketData = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); this.m_SocketData.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); this.m_SocketData.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), port)); this.m_SocketData.Listen(10); Task.Factory.StartNew(() => { this.m_Socket_PASV = this.m_SocketData.Accept(); }); string address = string.Format("{0},{1},{2}" , ip , port / 256 , port % 256); resp.Content = string.Format("Entering Passive Mode ({0})" , address); resps.Add(resp); } break; case "LIST": case "LS": { string path = string.Format("{0}{1}" , this.m_Root , this.m_CurrentPath); resp.Status = 150; resp.Content = "Opening data channel for directory listing of \"/\""; resps.Add(resp); resp = new CQFtpResponse(); StringBuilder strb = new StringBuilder(); DirectoryInfo ddr = new DirectoryInfo(path); DirectoryInfo[] dirs = ddr.GetDirectories(); foreach (var oo in dirs) { strb.Append(string.Format("drwxr-xr-x 1 ftp ftp 0 {0} {1} {2}:{3} {4}\r\n" , System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat.GetAbbreviatedMonthName(oo.CreationTimeUtc.Month) , oo.CreationTimeUtc.Day , oo.CreationTimeUtc.Hour , oo.CreationTimeUtc.Minute , oo.Name)); } FileInfo[] files = ddr.GetFiles(); foreach (var oo in files) { strb.Append(string.Format("-r--r--r-- 1 ftp ftp {0} {1} {2} {3}:{4} {5}\r\n" , oo.Length , System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat.GetAbbreviatedMonthName(oo.CreationTimeUtc.Month) , oo.CreationTimeUtc.Day , oo.CreationTimeUtc.Hour , oo.CreationTimeUtc.Minute , oo.Name)); } resp.Content = strb.ToString(); resps.Add(resp); resp = new CQFtpResponse(); resp.Status = 226; resp.Content = "Successfully transferred \"/\""; resps.Add(resp); } break; case "QUIT": { resp.Status = 221; resp.Content = "Goodbye"; resps.Add(resp); } break; case "OPTS": { resp.Status = 202; resp.Content = "UTF8 mode is always enabled. No need to send this command."; resps.Add(resp); } break; case "RETR": { string path = string.Format("{0}{1}" , this.m_Root , req.Content); resp.Status = 150; resp.Content = "Opening data channel for directory listing of \"/\""; resps.Add(resp); resp = new CQFtpResponse(); resp.Download = new FileStream(path, FileMode.Open); resps.Add(resp); resp = new CQFtpResponse(); resp.Status = 226; resp.Content = "Successfully transferred \"/\""; resps.Add(resp); } break; default: { resp.Status = 502; resp.Content = "No support."; resps.Add(resp); } break; } this.Dispatcher.Invoke(new Action(() => { foreach (var oo in resps) { this.m_MainUI.HandSharks.Add(oo.ToString()); System.Diagnostics.Trace.WriteLine(oo.ToString()); } })); return(resps); }