public Format ( IUnixFileSystemEntry entry, string name ) : string | ||
entry | IUnixFileSystemEntry | |
name | string | |
return | string |
private async Task<FtpResponse> ProcessMlstAsync(FtpCommand command, CancellationToken cancellationToken) { var argument = command.Argument; var path = Data.Path.Clone(); IUnixFileSystemEntry targetEntry; if (string.IsNullOrEmpty(argument)) { targetEntry = path.Count == 0 ? Data.FileSystem.Root : path.Peek(); } else { var foundEntry = await Data.FileSystem.SearchEntryAsync(path, argument, cancellationToken); if (foundEntry?.Entry == null) return new FtpResponse(550, "File system entry not found."); targetEntry = foundEntry.Entry; } await Connection.WriteAsync($"250- {targetEntry.Name}", cancellationToken); var entries = new List<IUnixFileSystemEntry>() { targetEntry, }; var enumerator = new DirectoryListingEnumerator(entries, Data.FileSystem, path, false); var formatter = new FactsListFormatter(Data.User, enumerator, Data.ActiveMlstFacts, true); while (enumerator.MoveNext()) { var name = enumerator.Name; var entry = enumerator.Entry; var line = formatter.Format(entry, name); await Connection.WriteAsync($" {line}", cancellationToken); } return new FtpResponse(250, "End"); }
/// <inheritdoc/> public override async Task<FtpResponse> Process(FtpCommand command, CancellationToken cancellationToken) { var argument = command.Argument; var path = Data.Path.Clone(); IUnixFileSystemEntry targetEntry; if (string.IsNullOrEmpty(argument)) { targetEntry = path.Count == 0 ? Data.FileSystem.Root : path.Peek(); } else { var foundEntry = await Data.FileSystem.SearchEntryAsync(path, argument, cancellationToken); if (foundEntry?.Entry == null) return new FtpResponse(550, "File system entry not found."); targetEntry = foundEntry.Entry; } var dirEntry = targetEntry as IUnixDirectoryEntry; var isDirEntry = dirEntry != null; var listDir = string.Equals(command.Name, "MLSD", StringComparison.OrdinalIgnoreCase); if (listDir && !isDirEntry) return new FtpResponse(501, "Not a directory."); await Connection.WriteAsync(new FtpResponse(150, "Opening data connection."), cancellationToken); ITcpSocketClient responseSocket; try { responseSocket = await Connection.CreateResponseSocket(); } catch (Exception) { return new FtpResponse(425, "Can't open data connection."); } try { var formatter = new FactsListFormatter(Data.User, Data.FileSystem, path, Data.ActiveMlstFacts); var encoding = Data.NlstEncoding ?? Connection.Encoding; using (var stream = await Connection.CreateEncryptedStream(responseSocket.WriteStream)) { using (var writer = new StreamWriter(stream, encoding, 4096, true) { NewLine = "\r\n", }) { if (listDir) { foreach (var line in formatter.GetPrefix(dirEntry)) { Connection.Log?.Debug(line); await writer.WriteLineAsync(line); } foreach (var entry in await Data.FileSystem.GetEntriesAsync(dirEntry, cancellationToken)) { var line = formatter.Format(entry); Connection.Log?.Debug(line); await writer.WriteLineAsync(line); } foreach (var line in formatter.GetSuffix(dirEntry)) { Connection.Log?.Debug(line); await writer.WriteLineAsync(line); } } else { var line = formatter.Format(targetEntry); Connection.Log?.Debug(line); await writer.WriteLineAsync(line); } await writer.FlushAsync(); } await stream.FlushAsync(cancellationToken); } } finally { responseSocket.Dispose(); } // Use 250 when the connection stays open. return new FtpResponse(226, "Closing data connection."); }
private async Task<FtpResponse> ProcessMlsdAsync(FtpCommand command, CancellationToken cancellationToken) { var argument = command.Argument; var path = Data.Path.Clone(); IUnixDirectoryEntry dirEntry; if (string.IsNullOrEmpty(argument)) { dirEntry = path.Count == 0 ? Data.FileSystem.Root : path.Peek(); } else { var foundEntry = await Data.FileSystem.SearchEntryAsync(path, argument, cancellationToken); if (foundEntry?.Entry == null) return new FtpResponse(550, "File system entry not found."); dirEntry = foundEntry.Entry as IUnixDirectoryEntry; if (dirEntry == null) return new FtpResponse(501, "Not a directory."); if (!dirEntry.IsRoot) path.Push(dirEntry); } await Connection.WriteAsync(new FtpResponse(150, "Opening data connection."), cancellationToken); ITcpSocketClient responseSocket; try { responseSocket = await Connection.CreateResponseSocket(); } catch (Exception) { return new FtpResponse(425, "Can't open data connection."); } try { var encoding = Data.NlstEncoding ?? Connection.Encoding; using (var stream = await Connection.CreateEncryptedStream(responseSocket.WriteStream)) { using (var writer = new StreamWriter(stream, encoding, 4096, true) { NewLine = "\r\n", }) { var entries = await Data.FileSystem.GetEntriesAsync(dirEntry, cancellationToken); var enumerator = new DirectoryListingEnumerator(entries, Data.FileSystem, path, true); var formatter = new FactsListFormatter(Data.User, enumerator, Data.ActiveMlstFacts, false); while (enumerator.MoveNext()) { var name = enumerator.Name; var entry = enumerator.Entry; var line = formatter.Format(entry, name); Connection.Log?.Debug(line); await writer.WriteLineAsync(line); } await writer.FlushAsync(); } await stream.FlushAsync(cancellationToken); } } finally { responseSocket.Dispose(); } // Use 250 when the connection stays open. return new FtpResponse(226, "Closing data connection."); }