Beispiel #1
0
        /// <summary>Connect to the FTP server using configuration parameters</summary>
        /// <returns>An FTPClient instance</returns>
        /// <exception cref="System.IO.IOException"/>
        private FTPClient Connect()
        {
            FTPClient     client   = null;
            Configuration conf     = GetConf();
            string        host     = conf.Get(FsFtpHost);
            int           port     = conf.GetInt(FsFtpHostPort, FTP.DefaultPort);
            string        user     = conf.Get(FsFtpUserPrefix + host);
            string        password = conf.Get(FsFtpPasswordPrefix + host);

            client = new FTPClient();
            client.Connect(host, port);
            int reply = client.GetReplyCode();

            if (!FTPReply.IsPositiveCompletion(reply))
            {
                throw NetUtils.WrapException(host, port, NetUtils.UnknownHost, 0, new ConnectException
                                                 ("Server response " + reply));
            }
            else
            {
                if (client.Login(user, password))
                {
                    client.SetFileTransferMode(FTP.BlockTransferMode);
                    client.SetFileType(FTP.BinaryFileType);
                    client.SetBufferSize(DefaultBufferSize);
                }
                else
                {
                    throw new IOException("Login failed on server - " + host + ", port - " + port + " as user '"
                                          + user + "'");
                }
            }
            return(client);
        }
Beispiel #2
0
        FTPReply?ReadNextReply()
        {
            if (CachedReply.Count > 0)
            {
                return(CachedReply.Dequeue());
            }
            string streamstring = null;

            try
            {
                streamstring = MyFTPHelper.ReadFromNetStream(controlStream);
            }
            catch (Exception exc)
            {
                throw exc;
            }
            string[] messages = streamstring.Split(new string[] { MyFTPHelper.FTPNewLine }, StringSplitOptions.RemoveEmptyEntries);
            Array.ForEach(messages, (m) => CachedReply.Enqueue(FTPReply.String2Reply(m)));
            if (CachedReply.Count > 0)
            {
                return(CachedReply.Dequeue());
            }
            else
            {
                return(null);
            }
        }
Beispiel #3
0
        /// <summary>
        /// A stream obtained via this call must be closed before using other APIs of
        /// this class or else the invocation will block.
        /// </summary>
        /// <exception cref="System.IO.IOException"/>
        public override FSDataOutputStream Create(Path file, FsPermission permission, bool
                                                  overwrite, int bufferSize, short replication, long blockSize, Progressable progress
                                                  )
        {
            FTPClient  client   = Connect();
            Path       workDir  = new Path(client.PrintWorkingDirectory());
            Path       absolute = MakeAbsolute(workDir, file);
            FileStatus status;

            try
            {
                status = GetFileStatus(client, file);
            }
            catch (FileNotFoundException)
            {
                status = null;
            }
            if (status != null)
            {
                if (overwrite && !status.IsDirectory())
                {
                    Delete(client, file, false);
                }
                else
                {
                    Disconnect(client);
                    throw new FileAlreadyExistsException("File already exists: " + file);
                }
            }
            Path parent = absolute.GetParent();

            if (parent == null || !Mkdirs(client, parent, FsPermission.GetDirDefault()))
            {
                parent = (parent == null) ? new Path("/") : parent;
                Disconnect(client);
                throw new IOException("create(): Mkdirs failed to create: " + parent);
            }
            client.Allocate(bufferSize);
            // Change to parent directory on the server. Only then can we write to the
            // file on the server by opening up an OutputStream. As a side effect the
            // working directory on the server is changed to the parent directory of the
            // file. The FTP client connection is closed when close() is called on the
            // FSDataOutputStream.
            client.ChangeWorkingDirectory(parent.ToUri().GetPath());
            FSDataOutputStream fos = new _FSDataOutputStream_263(this, client, client.StoreFileStream
                                                                     (file.GetName()), statistics);

            if (!FTPReply.IsPositivePreliminary(client.GetReplyCode()))
            {
                // The ftpClient is an inconsistent state. Must close the stream
                // which in turn will logout and disconnect from FTP server
                fos.Close();
                throw new IOException("Unable to create file: " + file + ", Aborting");
            }
            return(fos);
        }
Beispiel #4
0
        /// <exception cref="System.IO.IOException"/>
        public override FSDataInputStream Open(Path file, int bufferSize)
        {
            FTPClient  client   = Connect();
            Path       workDir  = new Path(client.PrintWorkingDirectory());
            Path       absolute = MakeAbsolute(workDir, file);
            FileStatus fileStat = GetFileStatus(client, absolute);

            if (fileStat.IsDirectory())
            {
                Disconnect(client);
                throw new FileNotFoundException("Path " + file + " is a directory.");
            }
            client.Allocate(bufferSize);
            Path parent = absolute.GetParent();

            // Change to parent directory on the
            // server. Only then can we read the
            // file
            // on the server by opening up an InputStream. As a side effect the working
            // directory on the server is changed to the parent directory of the file.
            // The FTP client connection is closed when close() is called on the
            // FSDataInputStream.
            client.ChangeWorkingDirectory(parent.ToUri().GetPath());
            InputStream       @is = client.RetrieveFileStream(file.GetName());
            FSDataInputStream fis = new FSDataInputStream(new FTPInputStream(@is, client, statistics
                                                                             ));

            if (!FTPReply.IsPositivePreliminary(client.GetReplyCode()))
            {
                // The ftpClient is an inconsistent state. Must close the stream
                // which in turn will logout and disconnect from FTP server
                fis.Close();
                throw new IOException("Unable to open file: " + file + ", Aborting");
            }
            return(fis);
        }
Beispiel #5
0
        public void ReadServerReply()
        {
            while (true)
            {
                try
                {
                    FTPReply?nreply = ReadNextReply();
                    if (nreply == null)
                    {
                        continue;
                    }
                    else
                    {
                        FTPReply reply = nreply.Value;
                        PostMessageToConsoleWithLock("服务器返回值:" + reply.replyCode);
                        switch (reply.replyCode)
                        {
                        case FTPReply.Code_FileList:
                            List <string> fileList = MyFTPHelper.DecodeFileList(reply.post);
                            this.fileList = fileList;
                            PostMessageToConsoleWithLock("更新服务器文件目录");
                            break;

                        case FTPReply.Code_UserNotLogIn:
                            PostMessageToConsoleWithLock("由于账号未登录,命令无效");
                            break;
                        }
                        break;
                    }
                }
                catch (Exception exc)
                {
                    throw exc;
                }
            }
        }
        /// <summary>  
        /// Run a site-specific command on the
        /// server. Support for commands is dependent
        /// on the server
        /// </summary>
        /// <param name="command">  
        /// the site command to run
        /// </param>
        /// <returns> true if command ok, false if
        /// command not implemented
        /// </returns>
        public bool Site(string command)
        {
            // send the retrieve command
            string reply = control.SendCommand("SITE " + command);

            // Can get a 200 (ok) or 202 (not impl). Some
            // FTP servers return 502 (not impl)
            string[] validCodes = new string[]{"200", "202", "502"};
            lastValidReply = control.ValidateReply(reply, validCodes);

            // return true or false? 200 is ok, 202/502 not
            // implemented
            if (reply.Substring(0, (3) - (0)).Equals("200"))
                return true;
            else
                return false;
        }
        /// <summary>  
        /// Delete the specified remote working directory
        /// </summary>
        /// <param name="dir"> 
        /// name of remote directory to delete
        /// </param>
        public void Rmdir(string dir)
        {
            string reply = control.SendCommand("RMD " + dir);

            // some servers return 257, technically incorrect but
            // we cater for it ...
            string[] validCodes = new string[]{"250", "257"};
            lastValidReply = control.ValidateReply(reply, validCodes);
        }
        /// <summary>  
        /// Rename a file or directory
        /// </summary>
        /// <param name="from"> name of file or directory to rename
        /// </param>
        /// <param name="to">   intended name
        /// 
        /// </param>
        public void Rename(string from, string to)
        {
            string reply = control.SendCommand("RNFR " + from);
            lastValidReply = control.ValidateReply(reply, "350");

            reply = control.SendCommand("RNTO " + to);
            lastValidReply = control.ValidateReply(reply, "250");
        }
        /// <summary>  
        /// Issue arbitrary ftp commands to the FTP server.
        /// </summary>
        /// <param name="command">    
        /// ftp command to be sent to server
        /// </param>
        /// <param name="validCodes"> 
        /// valid return codes for this command		
        /// </param>
        public void Quote(string command, string[] validCodes)
        {
            string reply = control.SendCommand(command);

            // allow for no validation to be supplied
            if (validCodes != null && validCodes.Length > 0)
                lastValidReply = control.ValidateReply(reply, validCodes);
        }
        /// <summary>  
        /// Request to the server that the get is set up
        /// </summary>
        /// <param name="remoteFile"> 
        /// name of remote file
        /// </param>
        private void InitGet(string remoteFile)
        {
            // set up data channel
            data = control.CreateDataSocket(connectMode);

            // send the retrieve command
            string reply = control.SendCommand("RETR " + remoteFile);

            // Can get a 125 or a 150
            string[] validCodes1 = new string[]{"125", "150"};
            lastValidReply = control.ValidateReply(reply, validCodes1);
        }
 /// <summary>  
 /// Delete the specified remote file
 /// </summary>
 /// <param name="remoteFile"> name of remote file to
 /// delete
 /// 
 /// </param>
 public void Delete(string remoteFile)
 {
     string reply = control.SendCommand("DELE " + remoteFile);
     lastValidReply = control.ValidateReply(reply, "250");
 }
        /// <summary>  
        /// Request the server to set up the put
        /// </summary>
        /// <param name="remoteFile"> name of remote file in
        /// current directory
        /// </param>
        /// <param name="append">     true if appending, false otherwise
        /// 
        /// </param>
        private void InitPut(string remoteFile, bool append)
        {
            // set up data channel
            data = control.CreateDataSocket(connectMode);

            // send the command to store
            string cmd = append ? "APPE ":"STOR ";
            string reply = control.SendCommand(cmd + remoteFile);

            // Can get a 125 or a 150
            string[] validCodes = new string[]{"125", "150"};
            lastValidReply = control.ValidateReply(reply, validCodes);
        }
 /// <summary>  
 /// Validate that the put() or get() was successful
 /// </summary>
 private void ValidateTransfer()
 {
     // check the control response
     string[] validCodes = new string[]{"226", "250"};
     string reply = control.ReadReply();
     lastValidReply = control.ValidateReply(reply, validCodes);
 }
        /// <summary>  
        /// Get modification time for a remote file
        /// </summary>
        /// <param name="remoteFile">  
        /// name of remote file
        /// </param>
        /// <returns>   
        /// modification time of file as a date
        /// </returns>
        public DateTime ModTime(string remoteFile)
        {
            string reply = control.SendCommand("MDTM " + remoteFile);
            lastValidReply = control.ValidateReply(reply, "213");

            // parse the reply string ...
            DateTime ts = DateTime.ParseExact(lastValidReply.ReplyText, dtFormat, null);
            return ts;
        }
 /// <summary>  
 /// Create the specified remote working directory
 /// </summary>
 /// <param name="dir"> 
 /// name of remote directory to create		
 /// </param>
 public void Mkdir(string dir)
 {
     string reply = control.SendCommand("MKD " + dir);
     lastValidReply = control.ValidateReply(reply, "257");
 }
 /// <summary>  
 /// Login into an account on the FTP server. This
 /// call completes the entire login process
 /// </summary>
 /// <param name="user">      
 /// user name
 /// </param>
 /// <param name="password">  
 /// user's password
 /// </param>
 public void Login(string user, string password)
 {
     string response = control.SendCommand("USER " + user);
     lastValidReply = control.ValidateReply(response, new string[] { "230", "331" });
     if (lastValidReply.ReplyCode == "331")
     {
         response = control.SendCommand("PASS " + password);
         lastValidReply = control.ValidateReply(response, "230");
     }
 }
 /// <summary>  
 /// Get the help text for the specified command
 /// </summary>
 /// <param name="command"> name of the command to get help on
 /// </param>
 /// <returns> help text from the server for the supplied command
 /// 
 /// </returns>
 public string Help(string command)
 {
     string reply = control.SendCommand("HELP " + command);
     string[] validCodes = new string[]{"211", "214"};
     lastValidReply = control.ValidateReply(reply, validCodes);
     return lastValidReply.ReplyText;
 }
        /// <summary>  
        /// List a directory's contents as an array of strings. A detailed
        /// listing is available, otherwise just filenames are provided.
        /// The detailed listing varies in details depending on OS and
        /// FTP server. Note that a full listing can be used on a file
        /// name to obtain information about a file
        /// </summary>
        /// <param name="dirname"> 
        /// name of directory (<b>not</b> a file mask)
        /// </param>
        /// <param name="full">    
        /// true if detailed listing required false otherwise
        /// </param>
        /// <returns>  
        /// an array of directory listing strings
        /// </returns>
        public string[] Dir(string dirname, bool full)
        {
            // set up data channel
            data = control.CreateDataSocket(connectMode);

            // send the retrieve command
            string command = full?"LIST ":"NLST ";
            if (dirname != null)
                command += dirname;

            // some FTP servers bomb out if NLST has whitespace appended
            command = command.Trim();
            string reply = control.SendCommand(command);

            // check the control response. wu-ftp returns 550 if the
            // directory is empty, so we handle 550 appropriately
            string[] validCodes1 = new string[]{"125", "150", "550"};
            lastValidReply = control.ValidateReply(reply, validCodes1);

            // an empty array of files for 550
            string[] result = new string[0];

            // a normal reply ... extract the file list
            if (!lastValidReply.ReplyCode.Equals("550"))
            {
                // get an character input stream to read data from .
                StreamReader reader = new StreamReader(GetDataStream());

                // read a line at a time
                ArrayList lines = new ArrayList();
                string line = null;
                while ((line = reader.ReadLine()) != null)
                {
                    lines.Add(line);
                }
                try
                {
                    reader.Close();
                }
                catch (IOException ignore)
                {
                }

                // check the control response
                string[] validCodes2 = new string[]{"226", "250"};
                reply = control.ReadReply();
                lastValidReply = control.ValidateReply(reply, validCodes2);

                // empty array is default
                if (lines.Count > 0)
                    result = (string[]) lines.ToArray(typeof(string));
            }
            return result;
        }
 /// <summary>  
 /// Get the type of the OS at the server
 /// </summary>
 /// <returns>   
 /// the type of server OS		
 /// </returns>
 public string System()
 {
     string reply = control.SendCommand("SYST");
     lastValidReply = control.ValidateReply(reply, "215");
     return lastValidReply.ReplyText;
 }
        /// <summary>  
        /// Supply the user name to log into an account
        /// on the FTP server. Must be followed by the
        /// password() method - but we allow for
        /// </summary>
        /// <param name="user">      
        /// user name
        /// </param>
        public void User(string user)
        {
            string reply = control.SendCommand("USER " + user);

            // we allow for a site with no password - 230 response
            string[] validCodes = new string[]{"230", "331"};
            lastValidReply = control.ValidateReply(reply, validCodes);
        }
Beispiel #21
0
 public static string Reply2String(FTPReply reply)
 {
     return(((int)reply.firstCode).ToString() + ((int)reply.secondCode).ToString() + reply.finerGradation.ToString() + " " + reply.post);
 }
        /// <summary>  
        /// Supplies the password for a previously supplied
        /// username to log into the FTP server. Must be
        /// preceeded by the user() method
        /// </summary>
        /// <param name="password">  
        /// user's password
        /// </param>
        public void Password(string password)
        {
            string reply = control.SendCommand("PASS " + password);

            // we allow for a site with no passwords (202)
            string[] validCodes = new string[]{"230", "202"};
            lastValidReply = control.ValidateReply(reply, validCodes);
        }
 /// <summary>  
 /// Change the remote working directory to
 /// that supplied
 /// </summary>
 /// <param name="dir"> name of remote directory to
 /// change to
 /// 
 /// </param>
 public void Chdir(string dir)
 {
     string reply = control.SendCommand("CWD " + dir);
     lastValidReply = control.ValidateReply(reply, "250");
 }
Beispiel #24
0
        private static void DoCustomCommand(FTPSClient client)
        {
            FTPReply reply = client.SendCustomCommand(commandArguments[0]);

            Console.WriteLine("Server reply: " + reply.ToString());
        }
        /// <summary>  
        /// Get the current remote working directory
        /// </summary>
        /// <returns>   
        /// the current working directory
        /// </returns>
        public string Pwd()
        {
            string reply = control.SendCommand("PWD");
            lastValidReply = control.ValidateReply(reply, "257");

            // get the reply text and extract the dir
            // listed in quotes, if we can find it. Otherwise
            // just return the whole reply string
            string text = lastValidReply.ReplyText;
            int start = text.IndexOf((System.Char) '"');
            int end = text.LastIndexOf((System.Char) '"');
            if (start >= 0 && end > start)
                return text.Substring(start + 1, (end) - (start + 1));
            else
                return text;
        }
Beispiel #26
0
 public override string ToString()
 {
     return(FTPReply.Reply2String(this));
 }
        public void Query(string searchString, Int32 offsetItems, Int32 isCaseSensitive, Int32 matchWholeWord, Int32 matchPath, Int32 maxItemsReturn)
        {
            string command = String.Format("QUERY {0} {1} {2} {3} {4} {5}", offsetItems, maxItemsReturn, isCaseSensitive, matchWholeWord, matchPath, searchString);
            string reply = control.SendCommand(command);

            // allow for no validation to be supplied
            string[] validCodes = new string[] { "200" };
            lastValidReply = control.ValidateReply(reply, validCodes);
        }
 /// <summary>  
 /// Quit the FTP session
 /// </summary>
 public void Quit()
 {
     try
     {
         string reply = control.SendCommand("QUIT");
         string[] validCodes = new string[]{"221", "226"};
         lastValidReply = control.ValidateReply(reply, validCodes);
     }
     finally
     {
         // ensure we clean up the connection
         control.Logout();
         control = null;
     }
 }
Beispiel #29
0
        public void Start()
        {
            while (true)
            {
                try
                {
                    FTPCommand?ncommand = ReadNextCommand();
                    if (ncommand == null)
                    {
                        continue;
                    }
                    else
                    {
                        FTPCommand command = ncommand.Value;
                        FTPReply   reply   = new FTPReply()
                        {
                            replyCode = FTPReply.Code_SyntaxError
                        };
                        switch (command.controlCommand)
                        {
                        case "USER":     //USER 指定账号
                            if (command.parameters.Length != 1)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_SyntaxErrorPara,
                                };
                                break;
                            }
                            user.username = command.parameters[0];
                            break;

                        case "PASS":     //PASS 指定密码
                            if (command.parameters.Length != 1)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_SyntaxErrorPara,
                                };
                                break;
                            }
                            user.password = command.parameters[0];
                            if (serverDispatcher.CheckUserWithLock(user))
                            {
                                Logined = true;
                                serverDispatcher.PostMessageFromClient("已成功登录", this);
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_UserLoggedIn,
                                    post      = "login success"
                                };
                            }
                            else
                            {
                                serverDispatcher.PostMessageFromClient("密码或用户名有误", this);
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_UserNotLogIn,
                                    post      = "login fail"
                                };
                            }
                            break;

                        case "LIST":     //LIST 返回服务器的文件目录(标准中不指定返回格式,格式为我们自定义)
                            reply = new FTPReply()
                            {
                                replyCode = FTPReply.Code_FileList,
                                post      = serverDispatcher.GetEncodedFileList()
                            };
                            break;

                        case "STOR":     //STOR 客户端上传文件
                            if (command.parameters.Length != 1)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_SyntaxErrorPara
                                };
                                break;
                            }
                            string        filename           = command.parameters[0];
                            FileStream    downloadFileStream = File.OpenWrite(serverDispatcher.GetCurrentDirectory() + filename);
                            NetworkStream downloadDataStream = dataClient.GetStream();
                            if (downloadFileStream == null)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_CantOopenDataConnection
                                };
                                break;
                            }
                            if (dataClient == null)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_ConnectionClosed
                                };
                                break;
                            }
                            currentTransfer = new FileTransfer()
                            {
                                networkStream = downloadDataStream,
                                filestream    = downloadFileStream,
                            };
                            currentTransfer.DownloadAsync(() =>
                            {
                                downloadDataStream.Close();
                                downloadFileStream.Close();
                                serverDispatcher.PostMessageFromClient("文件上传完成", this);
                            }
                                                          );

                            reply = new FTPReply()
                            {
                                replyCode = FTPReply.Code_ConnectionClosed
                            };
                            break;

                        case "RETR":     //RETR 客户端下载文件
                            if (command.parameters.Length != 1)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_SyntaxErrorPara
                                };
                                break;
                            }
                            FileStream    uploadFileStream = serverDispatcher.OpenFileStreamInfileList(command.parameters[0]);
                            NetworkStream uploadDataStream = dataClient.GetStream();
                            if (uploadFileStream == null)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_CantOopenDataConnection
                                };
                                break;
                            }
                            if (dataClient == null)
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_ConnectionClosed
                                };
                                break;
                            }
                            currentTransfer = new FileTransfer()
                            {
                                networkStream = uploadDataStream,
                                filestream    = uploadFileStream,
                            };
                            currentTransfer.UploadAsync(() =>
                            {
                                uploadDataStream.Close();
                                uploadFileStream.Close();
                                serverDispatcher.PostMessageFromClient("文件上传完成", this);
                            }
                                                        );

                            reply = new FTPReply()
                            {
                                replyCode = FTPReply.Code_ConnectionClosed
                            };
                            break;

                        case "ABOR":     //QUIT 关闭与服务器的连接
                            throw new NotImplementedException();

                        case "QUIT":     //ABOR 放弃之前的文件传输
                            throw new NotImplementedException();

                        case "PASV":     //PASV 数据线程让服务器监听特定端口
                            throw new NotImplementedException();

                        case "PORT":     //PORT 客户端的控制端口为N,数据端口为N+1,服务器的控制端口为21,数据端口为20
                            if (command.parameters.Length != 1 || !int.TryParse(command.parameters[0], out controlPort))
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_SyntaxErrorPara
                                };
                                break;
                            }
                            if (!serverDispatcher.CheckDataPortLegal(controlPort, this))
                            {
                                reply = new FTPReply()
                                {
                                    replyCode = FTPReply.Code_CantOopenDataConnection
                                };
                                break;
                            }
                            var remoteDataEnd = (IPEndPoint)controlClient.Client.RemoteEndPoint;
                            remoteDataEnd.Port = controlPort + 1;
                            dataClient         = new TcpClient();
                            reply = new FTPReply()
                            {
                                replyCode = FTPReply.Code_DataConnectionOpen
                            };
                            dataClient.ConnectAsync(remoteDataEnd.Address.MapToIPv4(), remoteDataEnd.Port);
                            serverDispatcher.PostMessageFromClient("与" + user.username + "建立数据连接", this);
                            break;

                        default:
                            break;
                        }
                        MyFTPHelper.WriteToNetStream(reply.ToString(), controlStream);
                    }
                }
                catch (System.IO.IOException exc)
                {
                    serverDispatcher.PostMessageFromClient(exc.Message, this);
                    controlClient.Close();
                    controlStream.Close();
                    return;
                }
            }
        }