Beispiel #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FactsListFormatter"/> class.
 /// </summary>
 /// <param name="user">The user to create this formatter for</param>
 /// <param name="fileSystem">The file system where the file system entries are from</param>
 /// <param name="pathEntries">The current path</param>
 /// <param name="activeFacts">The active facts to return for the entries</param>
 public FactsListFormatter(FtpUser user, IUnixFileSystem fileSystem, Stack<IUnixDirectoryEntry> pathEntries, ISet<string> activeFacts)
 {
     _user = user;
     _fileSystem = fileSystem;
     _pathEntries = pathEntries;
     _activeFacts = activeFacts;
 }
        public PermissionsFact(IFtpUser user, IUnixFileSystem fileSystem, IUnixDirectoryEntry dir, IUnixFileEntry entry)
        {
            var values    = new StringBuilder();
            var entryPerm = entry.Permissions.GetAccessModeFor(entry, user);
            var dirPerm   = dir.Permissions.GetAccessModeFor(dir, user);

            if (dirPerm.Write)
            {
                values.Append('c');
                if (entryPerm.Write)
                {
                    if (fileSystem.SupportsAppend)
                    {
                        values.Append('a');
                    }

                    values.Append('d');
                    values.Append('f');
                }
            }
            if (entryPerm.Read)
            {
                values.Append('r');
            }

            if (entryPerm.Write)
            {
                values.Append('w');
            }

            Value = values.ToString();
        }
 /// <summary>
 /// Tries to select the given <paramref name="path"/>.
 /// </summary>
 /// <param name="fileSystem">The file system.</param>
 /// <param name="path">The path to select.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>The result of the selection.</returns>
 public static Task <PathSelectionResult> SelectAsync(
     this IUnixFileSystem fileSystem,
     string?path,
     CancellationToken cancellationToken)
 {
     return(SelectAsync(fileSystem, Enumerable.Empty <IUnixDirectoryEntry>(), path, cancellationToken));
 }
Beispiel #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="InMemoryDirectoryEntry"/> class.
 /// </summary>
 /// <param name="fileSystem">The file system this entry belongs to.</param>
 /// <param name="parent">The parent entry.</param>
 /// <param name="name">The name of this entry.</param>
 /// <param name="children">The children of this directory entry.</param>
 public InMemoryDirectoryEntry(
     IUnixFileSystem fileSystem,
     InMemoryDirectoryEntry parent,
     string name,
     IDictionary <string, IUnixFileSystemEntry> children)
     : base(fileSystem, parent, name, _defaultPermissions)
 {
     Children = children;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="InMemoryFileEntry"/> class.
 /// </summary>
 /// <param name="fileSystem">The file system this entry belongs to.</param>
 /// <param name="parent">The parent entry.</param>
 /// <param name="name">The name of this entry.</param>
 /// <param name="data">The file data.</param>
 public InMemoryFileEntry(
     IUnixFileSystem fileSystem,
     InMemoryDirectoryEntry parent,
     string name,
     byte[] data)
     : base(fileSystem, parent, name, _defaultPermissions)
 {
     Data = data;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="GoogleDriveDirectoryEntry"/> class.
 /// </summary>
 /// <param name="fileSystem">The file system this instance belongs to.</param>
 /// <param name="file">The directory this entry belongs to.</param>
 /// <param name="fullPath">The full path.</param>
 /// <param name="isRoot">Determines whether this a root directory.</param>
 public GoogleDriveDirectoryEntry([NotNull] IUnixFileSystem fileSystem, [NotNull] File file, [NotNull] string fullPath, bool isRoot = false)
 {
     FileSystem  = fileSystem;
     File        = file;
     Permissions = new GenericUnixPermissions(
         new GenericAccessMode(true, true, true),
         new GenericAccessMode(true, true, true),
         new GenericAccessMode(true, true, true));
     FullName      = fullPath;
     IsRoot        = isRoot;
     Name          = File.Name;
     NumberOfLinks = File.Parents?.Count ?? 1;
 }
Beispiel #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="InMemoryFileSystemEntry"/> class.
 /// </summary>
 /// <param name="fileSystem">The file system this entry belongs to.</param>
 /// <param name="parent">The parent entry.</param>
 /// <param name="name">The name of this entry.</param>
 /// <param name="permissions">The permissions of this entry.</param>
 protected InMemoryFileSystemEntry(
     IUnixFileSystem fileSystem,
     InMemoryDirectoryEntry parent,
     string name,
     IUnixPermissions permissions)
 {
     FileSystem  = fileSystem;
     Name        = name;
     Permissions = permissions;
     Parent      = parent;
     Owner       = "owner";
     Group       = "group";
     CreatedTime = DateTimeOffset.Now;
 }
 public MlstFtpResponse(
     ISet <string> activeMlstFacts,
     ClaimsPrincipal user,
     IUnixFileSystem fileSystem,
     IUnixFileSystemEntry targetEntry,
     Stack <IUnixDirectoryEntry> path)
     : base(250, $" {targetEntry.Name}", "End")
 {
     _activeMlstFacts = activeMlstFacts;
     _user            = user;
     _fileSystem      = fileSystem;
     _targetEntry     = targetEntry;
     _path            = path;
 }
Beispiel #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DirectoryListingEnumerator"/> class.
        /// </summary>
        /// <param name="entries">The file system entries to enumerate.</param>
        /// <param name="fileSystem">The file system of the file system entries.</param>
        /// <param name="pathEntries">The path entries of the current directory.</param>
        /// <param name="returnDotEntries"><code>true</code> when this enumerator should return the dot entries.</param>
        public DirectoryListingEnumerator(IEnumerable <IUnixFileSystemEntry> entries, IUnixFileSystem fileSystem, Stack <IUnixDirectoryEntry> pathEntries, bool returnDotEntries)
        {
            FileSystem   = fileSystem;
            _pathEntries = pathEntries;

            var topPathEntries = pathEntries.Take(3).ToList();

            switch (topPathEntries.Count)
            {
            case 0:
                CurrentDirectory     = fileSystem.Root;
                ParentDirectory      = null;
                GrandParentDirectory = null;
                break;

            case 1:
                CurrentDirectory     = topPathEntries[0];
                ParentDirectory      = fileSystem.Root;
                GrandParentDirectory = null;
                break;

            case 2:
                CurrentDirectory     = topPathEntries[0];
                ParentDirectory      = topPathEntries[1];
                GrandParentDirectory = fileSystem.Root;
                break;

            default:
                CurrentDirectory     = topPathEntries[0];
                ParentDirectory      = topPathEntries[1];
                GrandParentDirectory = topPathEntries[2];
                break;
            }

            var dotEntries = new List <Tuple <IUnixDirectoryEntry, string> >();

            if (returnDotEntries)
            {
                dotEntries.Add(Tuple.Create(CurrentDirectory, "."));
                if (ParentDirectory != null)
                {
                    dotEntries.Add(Tuple.Create(ParentDirectory, ".."));
                }
            }

            _dotEntriesEnumerator = dotEntries.GetEnumerator();
            _entriesEnumerator    = entries.GetEnumerator();
        }
Beispiel #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GoogleDriveFileEntry"/> class.
 /// </summary>
 /// <param name="fileSystem">The file system this entry belongs to.</param>
 /// <param name="file">The underlying model.</param>
 /// <param name="fullName">The full path and file name of this entry.</param>
 /// <param name="fileSize">The file size (if it differs from the one in the model).</param>
 public GoogleDriveFileEntry(
     [NotNull] IUnixFileSystem fileSystem,
     [NotNull] File file,
     [NotNull] string fullName,
     long?fileSize = null)
 {
     FileSystem  = fileSystem;
     File        = file;
     Permissions = new GenericUnixPermissions(
         new GenericAccessMode(true, true, false),
         new GenericAccessMode(true, true, false),
         new GenericAccessMode(true, true, false));
     FullName      = fullName;
     Size          = fileSize ?? file.Size ?? 0;
     NumberOfLinks = File.Parents?.Count ?? 1;
 }
Beispiel #11
0
        public static async Task <SearchResult <IUnixFileEntry> > SearchFileAsync(this IUnixFileSystem fileSystem, [NotNull, ItemNotNull] Stack <IUnixDirectoryEntry> currentPath, [NotNull, ItemNotNull] IReadOnlyList <string> pathElements, CancellationToken cancellationToken)
        {
            var sourceDir = await GetDirectoryAsync(fileSystem, currentPath, new ListSegment <string>(pathElements, 0, pathElements.Count - 1), cancellationToken);

            if (sourceDir == null)
            {
                return(null);
            }
            var fileName   = pathElements[pathElements.Count - 1];
            var foundEntry = await fileSystem.GetEntryByNameAsync(sourceDir, fileName, cancellationToken);

            var foundFileEntry = foundEntry as IUnixFileEntry;

            if (foundEntry != null && foundFileEntry == null)
            {
                return(null);
            }
            return(new SearchResult <IUnixFileEntry>(sourceDir, foundFileEntry, fileName));
        }
Beispiel #12
0
        public static async Task <IUnixDirectoryEntry> GetDirectoryAsync([NotNull] this IUnixFileSystem fileSystem, [NotNull, ItemNotNull] Stack <IUnixDirectoryEntry> currentPath, [NotNull, ItemNotNull] IReadOnlyList <string> pathElements, CancellationToken cancellationToken)
        {
            IUnixDirectoryEntry currentDir = currentPath.Count == 0 ? fileSystem.Root : currentPath.Peek();

            foreach (var pathElement in pathElements)
            {
                if (pathElement == string.Empty)
                {
                    currentDir = fileSystem.Root;
                    currentPath.Clear();
                    continue;
                }

                if (pathElement == ".")
                {
                    continue;
                }

                if (pathElement == "..")
                {
                    if (currentPath.Count != 0)
                    {
                        currentPath.Pop();
                        currentDir = currentPath.Count == 0 ? fileSystem.Root : currentPath.Peek();
                    }
                    continue;
                }

                var foundEntry = await fileSystem.GetEntryByNameAsync(currentDir, pathElement, cancellationToken).ConfigureAwait(false);

                if (!(foundEntry is IUnixDirectoryEntry foundDirEntry))
                {
                    return(null);
                }

                currentPath.Push(foundDirEntry);
                currentDir = foundDirEntry;
            }

            return(currentDir);
        }
Beispiel #13
0
        private IReadOnlyList <IFact> BuildFacts([NotNull] IUnixFileSystem fileSystem, [NotNull] IUnixDirectoryEntry directoryEntry, [NotNull] IUnixFileEntry entry)
        {
            var result = new List <IFact>()
            {
                new PermissionsFact(_user, fileSystem, directoryEntry, entry),
                new SizeFact(entry.Size),
                new TypeFact(entry),
            };

            if (entry.LastWriteTime.HasValue)
            {
                result.Add(new ModifyFact(entry.LastWriteTime.Value));
            }

            if (entry.CreatedTime.HasValue)
            {
                result.Add(new CreateFact(entry.CreatedTime.Value));
            }

            return(result);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DirectoryListingEnumerator"/> class.
        /// </summary>
        /// <param name="entries">The file system entries to enumerate</param>
        /// <param name="fileSystem">The file system of the file system entries</param>
        /// <param name="pathEntries">The path entries of the current directory</param>
        /// <param name="returnDotEntries"><code>true</code> when this enumerator should return the dot entries</param>
        public DirectoryListingEnumerator(IEnumerable<IUnixFileSystemEntry> entries, IUnixFileSystem fileSystem, Stack<IUnixDirectoryEntry> pathEntries, bool returnDotEntries)
        {
            _pathEntries = pathEntries;

            var topPathEntries = pathEntries.Take(3).ToList();

            switch (topPathEntries.Count)
            {
                case 0:
                    CurrentDirectory = fileSystem.Root;
                    ParentDirectory = GrandParentDirectory = null;
                    break;
                case 1:
                    CurrentDirectory = topPathEntries[0];
                    ParentDirectory = fileSystem.Root;
                    GrandParentDirectory = null;
                    break;
                case 2:
                    CurrentDirectory = topPathEntries[0];
                    ParentDirectory = topPathEntries[1];
                    GrandParentDirectory = fileSystem.Root;
                    break;
                default:
                    CurrentDirectory = topPathEntries[0];
                    ParentDirectory = topPathEntries[1];
                    GrandParentDirectory = topPathEntries[2];
                    break;
            }

            var dotEntries = new List<Tuple<IUnixDirectoryEntry, string>>();
            if (returnDotEntries)
            {
                dotEntries.Add(Tuple.Create(CurrentDirectory, "."));
                if (ParentDirectory != null)
                    dotEntries.Add(Tuple.Create(ParentDirectory, ".."));
            }

            _dotEntriesEnumerator = dotEntries.GetEnumerator();
            _entriesEnumerator = entries.GetEnumerator();
        }
        private async Task <IFtpResponse?> ExecuteSendAsync(
            IFtpDataConnection dataConnection,
            ClaimsPrincipal user,
            IUnixFileSystem fileSystem,
            Stack <IUnixDirectoryEntry> path,
            IUnixDirectoryEntry dirEntry,
            IMlstFactsFeature factsFeature,
            CancellationToken cancellationToken)
        {
            var encoding = Connection.Features.Get <IEncodingFeature>().Encoding;
            var stream   = dataConnection.Stream;

            using (var writer = new StreamWriter(stream, encoding, 4096, true)
            {
                NewLine = "\r\n",
            })
            {
                var entries = await fileSystem.GetEntriesAsync(dirEntry, cancellationToken).ConfigureAwait(false);

                var enumerator = new DirectoryListingEnumerator(entries, fileSystem, path, true);
                var formatter  = new FactsListFormatter(user, enumerator, factsFeature.ActiveMlstFacts, false);
                while (enumerator.MoveNext())
                {
                    var name  = enumerator.Name;
                    var entry = enumerator.Entry;
                    var line  = formatter.Format(entry, name);
                    _logger?.LogTrace(line);
                    await writer.WriteLineAsync(line).ConfigureAwait(false);
                }

                await writer.FlushAsync().ConfigureAwait(false);
            }

            // Use 250 when the connection stays open.
            return(new FtpResponse(226, T("Closing data connection.")));
        }
Beispiel #16
0
 public FtpDirectory(IUnixFileSystem sys, IDirectory dir) : base(sys, dir)
 {
     this.dir = dir;
 }
Beispiel #17
0
        public static Task <IUnixDirectoryEntry> GetDirectoryAsync([NotNull] this IUnixFileSystem fileSystem, [NotNull, ItemNotNull] Stack <IUnixDirectoryEntry> currentPath, [CanBeNull] string path, CancellationToken cancellationToken)
        {
            var pathElements = GetPathElements(path);

            return(GetDirectoryAsync(fileSystem, currentPath, pathElements, cancellationToken));
        }
Beispiel #18
0
        /// <summary>
        /// Determines whether the <paramref name="pathToTestAsChild"/> is a child or the same path as <paramref name="pathToTestAsParent"/>.
        /// </summary>
        /// <param name="pathToTestAsChild">The path to test as child.</param>
        /// <param name="pathToTestAsParent">The path to test as parent.</param>
        /// <param name="fileSystem">The file system to use to compare the file names.</param>
        /// <returns><code>true</code> if the <paramref name="pathToTestAsChild"/> is a child or the same path as <paramref name="pathToTestAsParent"/>.</returns>
        public static bool IsChildOfOrSameAs([NotNull, ItemNotNull] this Stack <IUnixDirectoryEntry> pathToTestAsChild, [NotNull, ItemNotNull] Stack <IUnixDirectoryEntry> pathToTestAsParent, [NotNull] IUnixFileSystem fileSystem)
        {
            var fullPathOfParent = pathToTestAsParent.GetFullPath();
            var fullPathOfChild  = pathToTestAsChild.GetFullPath();
            var testPathOfChild  = fullPathOfChild.Substring(0, Math.Min(fullPathOfParent.Length, fullPathOfChild.Length));

            return(fileSystem.FileSystemEntryComparer.Equals(testPathOfChild, fullPathOfParent) && fullPathOfParent.Length <= fullPathOfChild.Length);
        }
Beispiel #19
0
        public static async Task <SearchResult <IUnixFileSystemEntry> > SearchEntryAsync(this IUnixFileSystem fileSystem, [NotNull, ItemNotNull] Stack <IUnixDirectoryEntry> currentPath, [NotNull, ItemNotNull] IReadOnlyList <string> pathElements, CancellationToken cancellationToken)
        {
            var sourceDir = await GetDirectoryAsync(fileSystem, currentPath, new ListSegment <string>(pathElements, 0, pathElements.Count - 1), cancellationToken).ConfigureAwait(false);

            if (sourceDir == null)
            {
                return(null);
            }

            IUnixFileSystemEntry foundEntry;
            var fileName = pathElements[pathElements.Count - 1];

            switch (fileName)
            {
            case "":
                currentPath.Clear();
                fileName   = null;
                foundEntry = fileSystem.Root;
                break;

            case ".":
                if (currentPath.Count != 0)
                {
                    foundEntry = currentPath.Pop();
                    fileName   = foundEntry.Name;
                }
                else
                {
                    foundEntry = fileSystem.Root;
                    fileName   = null;
                }

                break;

            case "..":
                if (currentPath.Count != 0)
                {
                    currentPath.Pop();
                }

                if (currentPath.Count != 0)
                {
                    foundEntry = currentPath.Pop();
                    fileName   = foundEntry.Name;
                }
                else
                {
                    foundEntry = fileSystem.Root;
                    fileName   = null;
                }

                break;

            default:
                foundEntry = await fileSystem.GetEntryByNameAsync(sourceDir, fileName, cancellationToken).ConfigureAwait(false);

                break;
            }

            return(new SearchResult <IUnixFileSystemEntry>(sourceDir, foundEntry, fileName));
        }
Beispiel #20
0
 public FtpFile(IUnixFileSystem sys, IFile file) : base(sys, file)
 {
     this.file = file;
 }
        /// <summary>
        /// Get the directory for the given <paramref name="path"/>.
        /// </summary>
        /// <param name="fileSystem">The file system to get the directory for.</param>
        /// <param name="currentPath">The current path.</param>
        /// <param name="path">The (absolute or relative) path to get the directory for.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The found <see cref="IUnixDirectoryEntry"/> or <c>null</c>.</returns>
        public static Task <IUnixDirectoryEntry?> GetDirectoryAsync(this IUnixFileSystem fileSystem, Stack <IUnixDirectoryEntry> currentPath, string?path, CancellationToken cancellationToken)
        {
            var pathElements = GetPathElements(path);

            return(GetDirectoryAsync(fileSystem, currentPath, pathElements, cancellationToken));
        }
        /// <summary>
        /// Tries to select the given <paramref name="path"/>.
        /// </summary>
        /// <param name="fileSystem">The file system.</param>
        /// <param name="pathEntries">The current path (entries).</param>
        /// <param name="path">The path to select.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The result of the selection.</returns>
        public static async Task <PathSelectionResult> SelectAsync(
            this IUnixFileSystem fileSystem,
            IEnumerable <IUnixDirectoryEntry> pathEntries,
            string?path,
            CancellationToken cancellationToken)
        {
            var currentDirectoryEntries = new Stack <IUnixDirectoryEntry>(pathEntries);
            IUnixDirectoryEntry currentDirectoryEntry;

            if (currentDirectoryEntries.Count == 0)
            {
                currentDirectoryEntry = fileSystem.Root;
                currentDirectoryEntries.Push(currentDirectoryEntry);
            }
            else
            {
                currentDirectoryEntry = currentDirectoryEntries.Peek();
            }

            var pathSegments = new PathEnumerator(path)
                               .NormalizePath(GetPathEntryNames(currentDirectoryEntries))
                               .ToArray();

            for (var pathSegmentIndex = 0; pathSegmentIndex != pathSegments.Length; ++pathSegmentIndex)
            {
                var pathSegment = pathSegments[pathSegmentIndex];

                if (pathSegment == "/")
                {
                    currentDirectoryEntries.Clear();
                    currentDirectoryEntry = fileSystem.Root;
                    currentDirectoryEntries.Push(currentDirectoryEntry);
                    continue;
                }

                var isDirectoryExpected = pathSegment.EndsWith("/");
                var childName           = isDirectoryExpected ? pathSegment.Substring(0, pathSegment.Length - 1) : pathSegment;
                var nextEntry           = await fileSystem.GetEntryByNameAsync(
                    currentDirectoryEntry,
                    childName,
                    cancellationToken)
                                          .ConfigureAwait(false);

                if (nextEntry == null)
                {
                    // Entry not found
                    var missingPathSegments = pathSegments.Skip(pathSegmentIndex).ToArray();
                    var lastIsDirectory     = missingPathSegments[missingPathSegments.Length - 1].EndsWith("/");
                    if (lastIsDirectory)
                    {
                        return(PathSelectionResult.CreateMissingDirectory(
                                   currentDirectoryEntries,
                                   missingPathSegments));
                    }

                    return(PathSelectionResult.CreateMissingFileOrDirectory(
                               currentDirectoryEntries,
                               missingPathSegments));
                }

                var isDirectory = nextEntry is IUnixDirectoryEntry;
                if (isDirectoryExpected && !isDirectory)
                {
                    // File instead of directory found
                    var missingPathSegments = pathSegments.Skip(pathSegmentIndex).ToArray();
                    return(PathSelectionResult.CreateMissingDirectory(
                               currentDirectoryEntries,
                               missingPathSegments));
                }

                if (!isDirectory)
                {
                    return(PathSelectionResult.Create(
                               currentDirectoryEntries,
                               (IUnixFileEntry)nextEntry));
                }

                currentDirectoryEntry = (IUnixDirectoryEntry)nextEntry;
                currentDirectoryEntries.Push(currentDirectoryEntry);
            }

            // Found directory
            return(PathSelectionResult.Create(
                       currentDirectoryEntries));
        }
Beispiel #23
0
 protected FtpEntry(IUnixFileSystem sys, IEntry entry)
 {
     this.sys   = sys;
     this.entry = entry;
 }