private static void ApplyCentral(ZipFile zipFile, string?subDir, IBuilder builder)
    {
        for (int i = 0; i < zipFile.Count; i++)
        {
            var entry = zipFile[i];

            string?relativePath = NormalizePath(entry.Name, subDir);
            if (string.IsNullOrEmpty(relativePath))
            {
                continue;
            }

            if (entry.IsDirectory)
            {
                builder.AddDirectory(relativePath);
            }
            else if (entry.IsFile)
            {
                if (IsSymlink(entry))
                {
                    builder.TurnIntoSymlink(relativePath);
                }
                else if (IsExecutable(entry))
                {
                    builder.MarkAsExecutable(relativePath);
                }
            }
        }
    }
Beispiel #2
0
 /// <summary>
 /// Adds a subdirectory to the implementation and returns a wrapped <see cref="IBuilder"/> to elements inside this subdirectory.
 /// </summary>
 /// <param name="builder">The builder.</param>
 /// <param name="path">The path  of the directory to create relative to the implementation root.</param>
 /// <exception cref="UnauthorizedAccessException">Access to a resource was denied.</exception>
 /// <exception cref="IOException">An IO operation failed.</exception>
 /// <returns>An <see cref="IBuilder"/> wrapped around <paramref name="builder"/> that prepends <paramref name="path"/> to paths.</returns>
 public static IBuilder BuildDirectory(this IBuilder builder, string?path)
 {
     if (string.IsNullOrEmpty(path))
     {
         return(builder);
     }
     builder.AddDirectory(path);
     return(new PrefixBuilder(builder, path));
 }
    private void ExtractFiles(ZipInputStream zipStream, string?subDir, IBuilder builder)
    {
        while (zipStream.GetNextEntry() is {} entry)
        {
            Handler.CancellationToken.ThrowIfCancellationRequested();

            string?relativePath = NormalizePath(entry.Name, subDir);
            if (string.IsNullOrEmpty(relativePath))
            {
                continue;
            }

            if (entry.IsDirectory)
            {
                builder.AddDirectory(relativePath);
            }
            else if (entry.IsFile)
            {
                builder.AddFile(relativePath, zipStream.WithLength(entry.Size), GetTimestamp(entry));
            }
        }
    }
    /// <inheritdoc/>
    public override void Extract(IBuilder builder, Stream stream, string?subDir = null)
    {
        EnsureSeekable(stream, seekableStream =>
        {
            try
            {
                var reader = SevenZipArchive.Open(seekableStream).ExtractAllEntries();
                while (reader.MoveToNextEntry())
                {
                    Handler.CancellationToken.ThrowIfCancellationRequested();

                    var entry = reader.Entry;

                    string?relativePath = NormalizePath(entry.Key, subDir);
                    if (relativePath == null)
                    {
                        continue;
                    }

                    if (entry.IsDirectory)
                    {
                        builder.AddDirectory(relativePath);
                    }
                    else
                    {
                        using var elementStream = reader.OpenEntryStream().WithLength(entry.Size);
                        builder.AddFile(relativePath, elementStream, entry.LastModifiedTime ?? new UnixTime());
                    }
                }
            }
            #region Error handling
            catch (Exception ex) when(ex is InvalidOperationException or ExtractionException or IndexOutOfRangeException)
            {
                // Wrap exception since only certain exception types are allowed
                throw new IOException(Resources.ArchiveInvalid, ex);
            }
            #endregion
        });
Beispiel #5
0
    /// <inheritdoc/>
    public override void Extract(IBuilder builder, Stream stream, string?subDir = null)
    {
        try
        {
            using var reader = RarReader.Open(stream, new() { LeaveStreamOpen = true });
            while (reader.MoveToNextEntry())
            {
                Handler.CancellationToken.ThrowIfCancellationRequested();

                var entry = reader.Entry;

                string?relativePath = NormalizePath(entry.Key, subDir);
                if (relativePath == null)
                {
                    continue;
                }

                if (entry.IsDirectory)
                {
                    builder.AddDirectory(relativePath);
                }
                else
                {
                    using var elementStream = reader.OpenEntryStream();
                    builder.AddFile(relativePath, elementStream, entry.LastModifiedTime ?? default);
                }
            }
        }
        #region Error handling
        catch (ExtractionException ex)
        {
            // Wrap exception since only certain exception types are allowed
            throw new IOException(Resources.ArchiveInvalid + "\n" + ex.Message, ex);
        }
        #endregion
    }
    /// <inheritdoc/>
    public override void Extract(IBuilder builder, Stream stream, string?subDir = null)
    {
        var symlinks  = new List <(string path, string target)>();
        var hardlinks = new List <(string path, string existingPath, bool executable)>();

        try
        {
            using var tarStream = new TarInputStream(stream, Encoding.UTF8)
                  {
                      IsStreamOwner = false
                  };

            while (tarStream.GetNextEntry() is {} entry)
            {
                Handler.CancellationToken.ThrowIfCancellationRequested();

                string?relativePath = NormalizePath(entry.Name, subDir);
                if (string.IsNullOrEmpty(relativePath))
                {
                    continue;
                }

                switch (entry.TarHeader.TypeFlag)
                {
                case TarHeader.LF_SYMLINK:
                    symlinks.Add((relativePath, entry.TarHeader.LinkName));
                    break;

                case TarHeader.LF_LINK:
                    string?targetPath = NormalizePath(entry.TarHeader.LinkName, subDir);
                    if (string.IsNullOrEmpty(targetPath))
                    {
                        throw new IOException($"The hardlink '{relativePath}' in the archive points to a non-existent file '{entry.TarHeader.LinkName}'.");
                    }
                    hardlinks.Add((relativePath, targetPath, IsExecutable(entry)));
                    break;

                case TarHeader.LF_DIR:
                    builder.AddDirectory(relativePath);
                    break;

                case TarHeader.LF_NORMAL or TarHeader.LF_OLDNORM:
                    builder.AddFile(relativePath, tarStream.WithLength(entry.Size), entry.TarHeader.ModTime, IsExecutable(entry));
                    break;

                default:
                    throw new NotSupportedException($"Archive entry '{entry.Name}' has unsupported type: {entry.TarHeader.TypeFlag}");
                }
            }

            foreach ((string path, string target) in symlinks)
            {
                builder.AddSymlink(path, target);
            }

            foreach ((string path, string existingPath, bool executable) in hardlinks)
                builder.AddHardlink(path, existingPath, executable);
        }
        #region Error handling
        catch (Exception ex) when(ex is SharpZipBaseException or InvalidDataException or ArgumentOutOfRangeException or IndexOutOfRangeException or {
            Message: "Data Error"
        })
 /// <inheritdoc/>
 public void AddDirectory(string path)
 => _underlyingBuilder.AddDirectory(Path.Combine(_prefix, path));