protected override string OnProcess(string sMessage) { sMessage = sMessage.Trim(); if (sMessage == "") { return(GetMessage(500, string.Format("{0} needs a paramter", Command))); } string dirToMake = GetPath(FileNameHelpers.AppendDirTag(sMessage)); // check directory name if (!FileNameHelpers.IsValid(dirToMake)) { FtpServer.LogWrite(this, sMessage, 553, 0); return(GetMessage(553, string.Format("\"{0}\": Invalid directory name", sMessage))); } // check whether directory already exists if (ConnectionObject.FileSystemObject.DirectoryExists(dirToMake)) { FtpServer.LogWrite(this, sMessage, 553, 0); return(GetMessage(553, string.Format("Directory \"{0}\" already exists", sMessage))); } // create directory if (!ConnectionObject.FileSystemObject.CreateDirectory(dirToMake)) { FtpServer.LogWrite(this, sMessage, 550, 0); return(GetMessage(550, string.Format("Couldn't create directory. ({0})", sMessage))); } FtpServer.LogWrite(this, sMessage, 257, 0); return(GetMessage(257, string.Format("{0} successful \"{1}\".", Command, dirToMake))); }
protected override string OnProcess(string sMessage) { string sDirectory = ConnectionObject.CurrentDirectory; FtpServer.LogWrite(this, sMessage, 257, 0); return(GetMessage(257, string.Format("\"{0}\" {1} Successful.", sDirectory, Command))); }
public IFileSystem Create(string sUser, string sPassword) { if ((sUser == null) || (sPassword == null)) { return(null); } FtpAccount account; if (!m_accountManager.CheckAccount(sUser, sPassword, out account)) { return(null); } if (!account.WriteAccess && !account.ReadAccess) { FtpServer.LogWrite($"user {sUser} has neither read nor write permissions"); return(null); } IFileSystem system = new AzureFileSystem(account.RootFolder ?? sUser); if (!account.WriteAccess) { system = new ReadOnlyFileSystem(system); } return(system); }
protected override string OnProcess(string sMessage) { string[] args = sMessage.Split(' '); if (args.Length > 2 || args.Length < 1) { return(GetMessage(501, string.Format("Invalid TYPE parameter: {0}", sMessage))); } switch (args[0].ToUpper()) { case "A": ConnectionObject.DataType = DataType.Ascii; if (args.Length == 1) { FtpServer.LogWrite(this, sMessage, 200, 0); return(GetMessage(200, string.Format("{0} command succeeded, data type is Ascii", Command))); } else { switch (args[1].ToUpper()) { case "N": ConnectionObject.FormatControl = FormatControl.NonPrint; FtpServer.LogWrite(this, sMessage, 200, 0); return(GetMessage(200, string.Format("{0} command succeeded, data type is Ascii, format is NonPrint", Command))); case "T": case "C": ConnectionObject.FormatControl = FormatControl.NonPrint; FtpServer.LogWrite(this, sMessage, 504, 0); return(GetMessage(504, string.Format("Format {0} is not supported, use NonPrint format", args[1]))); default: FtpServer.LogWrite(this, sMessage, 550, 0); return(GetMessage(550, string.Format("Error - unknown format \"{0}\"", args[1]))); } } case "I": ConnectionObject.DataType = DataType.Image; FtpServer.LogWrite(this, sMessage, 200, 0); return(GetMessage(200, string.Format("{0} command succeeded, data type is Image (Binary)", Command))); case "E": case "L": ConnectionObject.DataType = DataType.Image; FtpServer.LogWrite(this, sMessage, 504, 0); return(GetMessage(504, string.Format("Data type {0} is not supported, use Image (Binary) type", args[0]))); default: FtpServer.LogWrite(this, sMessage, 550, 0); return(GetMessage(550, string.Format("Error - unknown data type \"{0}\"", args[1]))); } }
protected override string OnProcess(string sMessage) { sMessage = sMessage.Trim(); if (sMessage == "") { return(GetMessage(501, string.Format("{0} needs a parameter", Command))); } ConnectionObject.User = sMessage; FtpServer.LogWrite(this, sMessage, 331, 0); return(GetMessage(331, string.Format("User {0} logged in, needs password", sMessage))); }
protected override string OnProcess(string sMessage) { if (sMessage.Trim() != "") { return(GetMessage(501, "REIN needs no parameters")); } // log out current user ConnectionObject.LogOut(); FtpServer.LogWrite(this, sMessage, 220, 0); return(GetMessage(220, "Service ready for new user!")); }
protected override string OnProcess(string sMessage) { sMessage = sMessage.Trim(); if (sMessage.Length == 0) { return(GetMessage(501, string.Format("Syntax error. {0} needs a parameter", Command))); } // append the final '/' char string sMessageFull = FileNameHelpers.AppendDirTag(sMessage); #region change to the parent dir if (sMessageFull == @"../") { // get the parent directory string parentDir = GetParentDir(); if (parentDir == null) { return(GetMessage(550, "Root directory, cannot change to the parent directory")); } ConnectionObject.CurrentDirectory = parentDir; FtpServer.LogWrite(this, sMessage, 200, 0); return(GetMessage(200, string.Format("{0} Successful ({1})", Command, parentDir))); } #endregion if (!FileNameHelpers.IsValid(sMessageFull)) { FtpServer.LogWrite(this, sMessage, 550, 0); return(GetMessage(550, string.Format("\"{0}\" is not a valid directory string.", sMessage))); } // get the new directory path string newDirectory = GetPath(sMessageFull); // checks whether the new directory exists if (!ConnectionObject.FileSystemObject.DirectoryExists(newDirectory)) { FtpServer.LogWrite(this, sMessage, 550, 0); return(GetMessage(550, string.Format("\"{0}\" no such directory.", sMessage))); } ConnectionObject.CurrentDirectory = newDirectory; FtpServer.LogWrite(this, sMessage, 250, 0); return(GetMessage(250, string.Format("{0} Successful ({1})", Command, newDirectory))); }
protected override string OnProcess(string sMessage) { sMessage = sMessage.Trim(); if (sMessage == "") { return(GetMessage(501, $"{Command} needs a parameter")); } string fileToDelete = GetPath(sMessage); Trace.TraceInformation($"DELE {fileToDelete} - BEGIN"); Stopwatch sw = new Stopwatch(); sw.Start(); // 2015-11-24 cljung : Q&D fix. If path contains double slashes, reduce to single since // NTFS/etc treams sub1//sub2 as sub1/sub two but Azure Blob Storage doesn't if (ConnectionObject.FileSystemObject.FileExists(fileToDelete)) { if (!StorageProviderConfiguration.FtpReplaceSlashOnDELE) { fileToDelete = fileToDelete.Replace("//", "/"); } else { FtpServer.LogWrite(this, sMessage, 550, sw.ElapsedMilliseconds); return(GetMessage(550, $"File \"{fileToDelete}\" does not exist.")); } } if (!ConnectionObject.FileSystemObject.FileExists(fileToDelete)) { FtpServer.LogWrite(this, sMessage, 550, sw.ElapsedMilliseconds); return(GetMessage(550, $"File \"{fileToDelete}\" does not exist.")); } if (!ConnectionObject.FileSystemObject.DeleteFile(fileToDelete)) { FtpServer.LogWrite(this, sMessage, 550, sw.ElapsedMilliseconds); return(GetMessage(550, $"Delete file \"{fileToDelete}\" failed.")); } sw.Stop(); Trace.TraceInformation($"DELE {fileToDelete} - END, Time {sw.ElapsedMilliseconds} ms"); FtpServer.LogWrite(this, sMessage, 250, sw.ElapsedMilliseconds); return(GetMessage(250, $"{Command} successful. Time {sw.ElapsedMilliseconds} ms")); }
protected override string OnProcess(string sMessage) { if (sMessage.Length != 0) { return(GetMessage(501, string.Format("Invalid syntax for {0} command", Command))); } // get the parent directory string parentDir = GetParentDir(); if (parentDir == null) { FtpServer.LogWrite(this, sMessage, 550, 0); return(GetMessage(550, "Root directory, cannot change to the parent directory")); } ConnectionObject.CurrentDirectory = parentDir; FtpServer.LogWrite(this, sMessage, 200, 0); return(GetMessage(200, string.Format("{0} Successful ({1})", Command, parentDir))); }
protected override string OnProcess(string sMessage) { string[] asData = sMessage.Split(new[] { ',' }); if (asData.Length != 6) { return(GetMessage(501, string.Format("{0}: Syntax error in parameters", Command))); } ConnectionObject.DataConnectionType = DataConnectionType.Active; int nSocketPort = int.Parse(asData[4]) * 256 + int.Parse(asData[5]); ConnectionObject.PortCommandSocketPort = nSocketPort; ConnectionObject.PortCommandSocketAddress = string.Join(".", asData, 0, 4); FtpServer.LogWrite(this, sMessage, 200, 0); return(GetMessage(200, string.Format("{0} successful.", Command))); }
protected override string OnProcess(string sMessage) { sMessage = sMessage.Trim(); if (sMessage == "") { return(GetMessage(501, string.Format("{0} needs a parameter", Command))); } if (ConnectionObject.Login(sMessage)) { FtpServer.LogWrite(this, "******", 220, 0); return(GetMessage(230, "Password ok, FTP server ready")); } else { FtpServer.LogWrite(this, "******", 530, 0); return(GetMessage(530, "Username or password incorrect")); } }
protected override string OnProcess(string sMessage) { Stopwatch sw = new Stopwatch(); sw.Start(); if (ConnectionObject.FileToRename.Length == 0) { FtpServer.LogWrite(this, sMessage, 503, 0); return(GetMessage(503, "RNTO must be preceded by a RNFR.")); } string sOldFileName = ConnectionObject.FileToRename; ConnectionObject.FileToRename = ""; // note: sMessage = sMessage.Trim(); string sNewFileName = GetPath(sMessage); // check whether the new filename is valid if (!FileNameHelpers.IsValid(sNewFileName) || sNewFileName.EndsWith(@"/")) { FtpServer.LogWrite(this, sMessage, 553, 0); return(GetMessage(553, string.Format("\"{0}\" is not a valid file name", sMessage))); } // check whether the new filename exists // note: azure allows file&virtualdir has the same name if (ConnectionObject.FileSystemObject.FileExists(sNewFileName)) { FtpServer.LogWrite(this, sMessage, 553, sw.ElapsedMilliseconds); return(GetMessage(553, string.Format("File already exists ({0}).", sMessage))); } if (!ConnectionObject.FileSystemObject.Move(sOldFileName, sNewFileName)) { FtpServer.LogWrite(this, sMessage, 553, sw.ElapsedMilliseconds); return(GetMessage(553, "Rename failed")); } FtpServer.LogWrite(this, sMessage, 250, sw.ElapsedMilliseconds); return(GetMessage(250, "Renamed file successfully.")); }
protected override string OnProcess(string sMessage) { sMessage = sMessage.Trim(); if (sMessage == "") { return(GetMessage(501, string.Format("{0} needs a parameter", Command))); } string sFile = GetPath(sMessage); Stopwatch sw = new Stopwatch(); sw.Start(); if (!FileNameHelpers.IsValid(sFile)) { FtpServer.LogWrite(this, sMessage, 553, sw.ElapsedMilliseconds); return(GetMessage(553, string.Format("\"{0}\" is not a valid file name", sMessage))); } var socketData = new FtpDataSocket(ConnectionObject); if (!socketData.Loaded) { return(GetMessage(425, "Unable to establish the data connection")); } SocketHelpers.Send(ConnectionObject.Socket, GetMessage(150, "Opening connection for data transfer."), ConnectionObject.Encoding); if (!ConnectionObject.FileSystemObject.AppendFile(sFile, socketData.Socket.GetStream())) { FtpServer.LogWrite(this, sMessage, 553, sw.ElapsedMilliseconds); return(GetMessage(553, string.Format("{0} error", Command))); } // remove the orginal blob ContentMD5 ConnectionObject.FileSystemObject.SetFileMd5(sFile, string.Empty); sw.Stop(); FtpServer.LogWrite(this, sMessage, 250, sw.ElapsedMilliseconds); return(GetMessage(250, string.Format("{0} successful", Command))); }
protected override string OnProcess(string sMessage) { ConnectionObject.DataConnectionType = DataConnectionType.Passive; Stopwatch sw = new Stopwatch(); sw.Start(); string pasvListenAddress = GetPassiveAddressInfo(); //return GetMessage(227, string.Format("Entering Passive Mode ({0})", pasvListenAddress)); // listen at the port by the "FTP" endpoint setting int port = int.Parse(ConfigurationManager.AppSettings["FTPPASV"]); System.Net.IPAddress ipaddr = SocketHelpers.GetLocalAddress(); System.Net.IPEndPoint ipEndPoint = new System.Net.IPEndPoint(ipaddr.Address, port); TcpListener listener = SocketHelpers.CreateTcpListener(ipEndPoint); if (listener == null) { FtpServer.LogWrite(this, sMessage, 550, 0); return(GetMessage(550, string.Format("Couldn't start listener on port {0}", m_nPort))); } Trace.TraceInformation(string.Format("Entering Passive Mode on {0}", pasvListenAddress)); SocketHelpers.Send(ConnectionObject.Socket, string.Format("227 Entering Passive Mode ({0})\r\n", pasvListenAddress), ConnectionObject.Encoding); listener.Start(); ConnectionObject.PassiveSocket = listener.AcceptTcpClient(); listener.Stop(); sw.Stop(); FtpServer.LogWrite(this, sMessage, 0, sw.ElapsedMilliseconds); return(""); }
public int Write(byte[] abData, int nDataSize) { if (BlobStream == null) { throw new Exception("BlobStream is null!"); } try { BlobStream.Write(abData, 0, nDataSize); return(nDataSize); } catch (IOException io) { FtpServer.LogWrite($"IO failure when writing {name}: {io}"); return(0); } catch (Exception e) { FtpServer.LogWrite($"failed to write to {name}: {e}"); return(0); } }
protected override string OnProcess(string sMessage) { sMessage = sMessage.Trim(); if (sMessage == "") { return(GetMessage(501, string.Format("{0} needs a parameter", Command))); } string dirToRemove = GetPath(FileNameHelpers.AppendDirTag(sMessage)); // check whether directory exists if (!ConnectionObject.FileSystemObject.DirectoryExists(dirToRemove)) { FtpServer.LogWrite(this, sMessage, 550, 0); return(GetMessage(550, string.Format("Directory \"{0}\" does not exist", dirToRemove))); } // can not delete root directory if (dirToRemove == "/") { FtpServer.LogWrite(this, sMessage, 553, 0); return(GetMessage(553, "Can not remove root directory")); } // delete directory if (ConnectionObject.FileSystemObject.DeleteDirectory(dirToRemove)) { FtpServer.LogWrite(this, sMessage, 250, 0); return(GetMessage(250, string.Format("{0} successful.", Command))); } else { FtpServer.LogWrite(this, sMessage, 550, 0); return(GetMessage(550, string.Format("Couldn't remove directory ({0}).", dirToRemove))); } }
public int Read(byte[] abData, int nDataSize) { if (BlobStream == null) { return(0); } try { return(BlobStream.Read(abData, 0, nDataSize)); } catch (IOException io) { FtpServer.LogWrite($"IO failure when reading {name}: {io}"); return(0); } // other exceptions catch (Exception e) { FtpServer.LogWrite($"error while reading file {name}: {e}"); // need logging, fix me return(0); } }
private bool FailOnReadOnlyFs([CallerMemberName] string caller = null) { FtpServer.LogWrite($"attempt to {caller} on read only file"); return(false); }
protected override string OnProcess(string sMessage) { FtpServer.LogWrite(this, sMessage, 220, 0); return(GetMessage(220, "Goodbye")); }
protected override string OnProcess(string sMessage) { sMessage = sMessage.Trim(); if (sMessage == "") { return(GetMessage(501, string.Format("{0} needs a parameter", Command))); } string sFile = GetPath(sMessage); if (!FileNameHelpers.IsValid(sFile) || sFile.EndsWith(@"/")) { return(GetMessage(553, string.Format("\"{0}\" is not a valid file name", sMessage))); } if (ConnectionObject.FileSystemObject.FileExists(sFile)) { // 2015-11-24 cljung : RFC959 says STOR commands overwrite files, so delete if exists if (!StorageProviderConfiguration.FtpOverwriteFileOnSTOR) { return(GetMessage(553, string.Format("File \"{0}\" already exists.", sMessage))); } Trace.TraceInformation(string.Format("STOR {0} - Deleting existing file", sFile)); if (!ConnectionObject.FileSystemObject.DeleteFile(sFile)) { return(GetMessage(550, string.Format("Delete file \"{0}\" failed.", sFile))); } } var socketData = new FtpDataSocket(ConnectionObject); if (!socketData.Loaded) { return(GetMessage(425, "Unable to establish the data connection")); } Trace.TraceInformation(string.Format("STOR {0} - BEGIN", sFile)); IFile file = ConnectionObject.FileSystemObject.OpenFile(sFile, true); if (file == null) { socketData.Close();// close data socket return(GetMessage(550, "Couldn't open file")); } SocketHelpers.Send(ConnectionObject.Socket, GetMessage(150, "Opening connection for data transfer."), ConnectionObject.Encoding); string md5Value = string.Empty; Stopwatch sw = new Stopwatch(); sw.Start(); // TYPE I, default if (ConnectionObject.DataType == DataType.Image) { // md5 hash function MD5 md5Hash = MD5.Create(); var abData = new byte[m_nBufferSize]; int nReceived = socketData.Receive(abData); while (nReceived > 0) { int writeSize = file.Write(abData, nReceived); // maybe error if (writeSize != nReceived) { file.Close(); socketData.Close(); FtpServer.LogWrite(this, sMessage, 451, sw.ElapsedMilliseconds); return(GetMessage(451, "Write data to Azure error!")); } md5Hash.TransformBlock(abData, 0, nReceived, null, 0); nReceived = socketData.Receive(abData); } md5Hash.TransformFinalBlock(new byte[1], 0, 0); md5Value = BytesToStr(md5Hash.Hash); } // TYPE A // won't compute md5, because read characters from client stream else if (ConnectionObject.DataType == DataType.Ascii) { int readSize = SocketHelpers.CopyStreamAscii(socketData.Socket.GetStream(), file.BlobStream, m_nBufferSize); FtpServerMessageHandler.SendMessage(ConnectionObject.Id, string.Format("Use ascii type success, read {0} chars!", readSize)); } else // mustn't reach { file.Close(); socketData.Close(); FtpServer.LogWrite(this, sMessage, 451, sw.ElapsedMilliseconds); return(GetMessage(451, "Error in transfer data: invalid data type.")); } sw.Stop(); Trace.TraceInformation(string.Format("STOR {0} - END, Time {1} ms", sFile, sw.ElapsedMilliseconds)); // upload notification ConnectionObject.FileSystemObject.Log4Upload(sFile); file.Close(); socketData.Close(); // record md5 ConnectionObject.FileSystemObject.SetFileMd5(sFile, md5Value); FtpServer.LogWrite(this, sMessage, 226, sw.ElapsedMilliseconds); return(GetMessage(226, string.Format("{0} successful. Time {1} ms", Command, sw.ElapsedMilliseconds))); }
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { FtpServer.LogWrite($"UNHANDLED ERROR: {e.ExceptionObject}"); }
protected override string OnProcess(string sMessage) { sMessage = sMessage.Trim(); if (sMessage == "") { return(GetMessage(501, string.Format("{0} needs a parameter", Command))); } string sFilePath = GetPath(sMessage); Trace.TraceInformation(string.Format("RETR {0} - BEGIN", sFilePath)); Stopwatch sw = new Stopwatch(); sw.Start(); if (!ConnectionObject.FileSystemObject.FileExists(sFilePath)) { FtpServer.LogWrite(this, sMessage, 550, sw.ElapsedMilliseconds); return(GetMessage(550, string.Format("File \"{0}\" doesn't exist", sMessage))); } var socketData = new FtpDataSocket(ConnectionObject); if (!socketData.Loaded) { FtpServer.LogWrite(this, sMessage, 425, sw.ElapsedMilliseconds); return(GetMessage(425, "Unable to establish the data connection")); } SocketHelpers.Send(ConnectionObject.Socket, "150 Starting data transfer, please wait...\r\n", ConnectionObject.Encoding); IFile file = ConnectionObject.FileSystemObject.OpenFile(sFilePath, false); if (file == null) { return(GetMessage(550, "Couldn't open file")); } // TYPE I, default if (ConnectionObject.DataType == DataType.Image) { var abBuffer = new byte[m_nBufferSize]; int nRead = file.Read(abBuffer, m_nBufferSize); while (nRead > 0 && socketData.Send(abBuffer, nRead)) { nRead = file.Read(abBuffer, m_nBufferSize); } } // TYPE A else if (ConnectionObject.DataType == DataType.Ascii) { int writeSize = SocketHelpers.CopyStreamAscii(file.BlobStream, socketData.Socket.GetStream(), m_nBufferSize); FtpServerMessageHandler.SendMessage(ConnectionObject.Id, string.Format("Use ascii type success, write {0} chars!", writeSize)); } else // mustn't reach { file.Close(); socketData.Close(); FtpServer.LogWrite(this, sMessage, 451, sw.ElapsedMilliseconds); return(GetMessage(451, "Error in transfer data: invalid data type.")); } file.Close(); socketData.Close(); sw.Stop(); Trace.TraceInformation(string.Format("RETR {0} - END, Time {1} ms", sFilePath, sw.ElapsedMilliseconds)); FtpServer.LogWrite(this, sMessage, 226, sw.ElapsedMilliseconds); return(GetMessage(226, string.Format("File download succeeded. Time {0} ms", sw.ElapsedMilliseconds))); }
protected override string OnProcess(string sMessage) { ConnectionObject.DataConnectionType = DataConnectionType.Passive; Stopwatch sw = new Stopwatch(); sw.Start(); //return GetMessage(227, string.Format("Entering Passive Mode ({0})", pasvListenAddress)); // listen at the port by the "FTP" endpoint setting int port = int.Parse(ConfigurationManager.AppSettings["FTPPASV"]); int maxPort = port + int.Parse(ConfigurationManager.AppSettings["MaxClients"]); int selectedPort = port; lock (ListeningPassivePorts) { while (selectedPort < maxPort && !ListeningPassivePorts.Add(selectedPort)) { selectedPort++; } } if (selectedPort == maxPort) { FtpServer.LogWrite("unable to select passive ports, looks like too many clients are connected at once"); return(GetMessage(550, "Too many concurrent PASV requests")); } string pasvListenAddress = GetPassiveAddressInfo(selectedPort); //System.Net.IPAddress ipaddr = SocketHelpers.GetLocalAddress(); //System.Net.IPEndPoint ipEndPoint = new System.Net.IPEndPoint(ipaddr.Address, port); System.Net.IPEndPoint ipEndPoint = new System.Net.IPEndPoint(IPAddress.Any, selectedPort); TcpListener listener = SocketHelpers.CreateTcpListener(ipEndPoint); if (listener == null) { FtpServer.LogWrite(this, sMessage, 550, 0); return(GetMessage(550, $"Couldn't start listener on port {m_nPort}")); } try { Trace.TraceInformation($"Entering Passive Mode on {pasvListenAddress}"); SocketHelpers.Send(ConnectionObject.Socket, $"227 Entering Passive Mode ({pasvListenAddress})\r\n", ConnectionObject.Encoding); listener.Start(); Task <TcpClient> acceptTask = listener.AcceptTcpClientAsync(); int completed = Task.WaitAny(new[] { acceptTask }, TimeSpan.FromSeconds(maxAcceptWaitTimeSeconds)); if (completed != 0) { FtpServer.LogWrite("timeout while waiting on PASV connection"); return(GetMessage(550, "PASV listener timeout")); } ConnectionObject.PassiveSocket = acceptTask.Result; } finally { listener.Stop(); sw.Stop(); lock (ListeningPassivePorts) { ListeningPassivePorts.Remove(selectedPort); } } FtpServer.LogWrite(this, sMessage, 0, sw.ElapsedMilliseconds); return(""); }
protected override string OnProcess(string sMessage) { sMessage = sMessage.Trim(); string[] asFiles = null; string[] asDirectories = null; // Get the file/dir to list string targetToList = GetPath(sMessage); Stopwatch sw = new Stopwatch(); sw.Start(); // checks the file/dir name if (!FileNameHelpers.IsValid(targetToList)) { FtpServer.LogWrite(this, sMessage, 501, 0); return(GetMessage(501, string.Format("\"{0}\" is not a valid file/directory name", sMessage))); } // two vars indicating different list results bool targetIsFile = false; bool targetIsDir = false; // targetToList ends with '/', must be a directory if (targetToList.EndsWith(@"/")) { targetIsFile = false; if (ConnectionObject.FileSystemObject.DirectoryExists(targetToList)) { targetIsDir = true; } } else { // check whether the target to list is a directory if (ConnectionObject.FileSystemObject.DirectoryExists(FileNameHelpers.AppendDirTag(targetToList))) { targetIsDir = true; } // check whether the target to list is a file if (ConnectionObject.FileSystemObject.FileExists(targetToList)) { targetIsFile = true; } } if (targetIsFile) { asFiles = new string[1] { targetToList }; if (targetIsDir) { asDirectories = new string[1] { FileNameHelpers.AppendDirTag(targetToList) } } ; } // list a directory else if (targetIsDir) { targetToList = FileNameHelpers.AppendDirTag(targetToList); asFiles = ConnectionObject.FileSystemObject.GetFiles(targetToList); asDirectories = ConnectionObject.FileSystemObject.GetDirectories(targetToList); } else { FtpServer.LogWrite(this, sMessage, 550, sw.ElapsedMilliseconds); return(GetMessage(550, string.Format("\"{0}\" not exists", sMessage))); } var socketData = new FtpDataSocket(ConnectionObject); if (!socketData.Loaded) { FtpServer.LogWrite(this, sMessage, 425, sw.ElapsedMilliseconds); return(GetMessage(425, "Unable to establish the data connection")); } // prepare to write response to data channel SocketHelpers.Send(ConnectionObject.Socket, string.Format("150 Opening data connection for {0}\r\n", Command), ConnectionObject.Encoding); // generate the response string sFileList = BuildReply(asFiles, asDirectories); // ToDo, send response according to ConnectionObject.DataType, i.e., Ascii or Binary socketData.Send(sFileList, Encoding.UTF8); socketData.Close(); sw.Stop(); FtpServer.LogWrite(this, sMessage, 226, sw.ElapsedMilliseconds); return(GetMessage(226, string.Format("{0} successful.", Command))); }