Ejemplo n.º 1
0
        static public List <CQFtpRequest> Parse(string src)
        {
            List <CQFtpRequest> reqs = new List <CQFtpRequest>();

            string[] s1 = src.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < s1.Length; i++)
            {
                int index = s1[i].IndexOf(" ");
                if (index > 0)
                {
                    CQFtpRequest req = new CQFtpRequest()
                    {
                        OriginCommand = s1[i]
                    };
                    req.Command = s1[i].Substring(0, index);
                    req.Content = s1[i].Remove(0, index);
                    reqs.Add(req);
                }
                else
                {
                    CQFtpRequest req = new CQFtpRequest()
                    {
                        Command = src.Replace("\r\n", ""), Content = "", OriginCommand = s1[i]
                    };
                    reqs.Add(req);
                }
                //string[] s2 = s1[i].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                //if(s2.Length == 2)
                //{
                //    CQFtpRequest req = new CQFtpRequest() { Command = s2[0], Content = s2[1], OriginCommand=s1[i] };
                //    reqs.Add(req);
                //}
                //else
                //{
                //    CQFtpRequest req = new CQFtpRequest() { Command = src.Replace("\r\n", ""), Content = "", OriginCommand = src };
                //    reqs.Add(req);
                //}
            }
            return(reqs);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (this.m_MainUI == null)
            {
                //this.FtpClient();


                this.DataContext = this.m_MainUI = new CQMainUI();

                Task.Factory.StartNew(() =>
                {
                    this.m_SocketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    this.m_SocketServer.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3333));
                    this.m_SocketServer.Listen(10);
                    while (true)
                    {
                        Socket client = this.m_SocketServer.Accept();

                        client.Send(Encoding.UTF8.GetBytes("220 QQ FTP reade.\r\n"));
                        byte[] buf = new byte[client.ReceiveBufferSize];

                        while (true)
                        {
                            Array.Clear(buf, 0, buf.Length);
                            int recv_len = client.Receive(buf);
                            if (recv_len == 0)
                            {
                                break;
                            }
                            string str = Encoding.UTF8.GetString(buf, 0, recv_len);
                            List <CQFtpRequest> reqs = CQFtpRequest.Parse(str);
                            foreach (var req in reqs)
                            {
                                List <CQFtpResponse> resps = this.Process(req);
                                for (int i = 0; i < resps.Count; i++)
                                {
                                    if (resps[i].Status > 0)
                                    {
                                        int send_len = client.Send(Encoding.UTF8.GetBytes(string.Format("{0}\r\n", resps[i].ToString())));
                                    }
                                    else
                                    {
                                        if (this.m_Socket_PASV != null)
                                        {
                                            if (string.IsNullOrEmpty(resps[i].Content) == false)
                                            {
                                                int send_len = this.m_Socket_PASV.Send(Encoding.UTF8.GetBytes(string.Format("{0}\r\n", resps[i].ToString())));
                                            }
                                            if (resps[i].Download != null)
                                            {
                                                byte[] send_buf = new byte[client.SendBufferSize];
                                                while (true)
                                                {
                                                    int read_len = resps[i].Download.Read(send_buf, 0, send_buf.Length);
                                                    if (read_len > 0)
                                                    {
                                                        this.m_Socket_PASV.Send(send_buf, read_len, SocketFlags.None);
                                                    }
                                                    if (read_len != send_buf.Length)
                                                    {
                                                        break;
                                                    }
                                                }
                                            }

                                            this.m_Socket_PASV.Close();
                                            this.m_Socket_PASV = null;
                                        }
                                    }
                                }
                            }
                            if (reqs.Any(x => x.Command.ToUpperInvariant() == "QUIT") == true)
                            {
                                client.Shutdown(SocketShutdown.Both);
                                client.Close();
                                break;
                            }
                        }
                    }
                }, TaskCreationOptions.LongRunning);
            }
        }