diff --git a/src/SharpCompress/Common/ExtractionMethods.cs b/src/SharpCompress/Common/ExtractionMethods.cs index bc898cc8..15efd220 100644 --- a/src/SharpCompress/Common/ExtractionMethods.cs +++ b/src/SharpCompress/Common/ExtractionMethods.cs @@ -68,18 +68,15 @@ namespace SharpCompress.Common ExtractionOptions options, Action openAndWrite) { -#if NETSTANDARD2_0 if (entry.LinkTarget != null) { - var link = new Mono.Unix.UnixSymbolicLinkInfo(destinationFileName); - if (System.IO.File.Exists(destinationFileName)) + if (null == options.WriteSymbolicLink) { - link.Delete(); // equivalent to ln -s -f + throw new ExtractionException("Entry is a symbolic link but ExtractionOptions.WriteSymbolicLink delegate is null"); } - link.CreateSymbolicLinkTo(entry.LinkTarget); + options.WriteSymbolicLink(destinationFileName, entry.LinkTarget); } else -#endif { FileMode fm = FileMode.Create; options = options ?? new ExtractionOptions() diff --git a/src/SharpCompress/Common/ExtractionOptions.cs b/src/SharpCompress/Common/ExtractionOptions.cs index 9dba482e..7f6e1efc 100644 --- a/src/SharpCompress/Common/ExtractionOptions.cs +++ b/src/SharpCompress/Common/ExtractionOptions.cs @@ -21,5 +21,14 @@ /// preserve windows file attributes /// public bool PreserveAttributes { get; set; } + + /// + /// Delegate for writing symbolic links to disk. + /// sourcePath is where the symlink is created. + /// targetPath is what the symlink refers to. + /// + public delegate void SymbolicLinkWriterDelegate(string sourcePath, string targetPath); + + public SymbolicLinkWriterDelegate WriteSymbolicLink; } } \ No newline at end of file diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj index 66775ecc..1e009ded 100644 --- a/src/SharpCompress/SharpCompress.csproj +++ b/src/SharpCompress/SharpCompress.csproj @@ -34,7 +34,6 @@ $(DefineConstants);NETCORE - \ No newline at end of file diff --git a/tests/SharpCompress.Test/SharpCompress.Test.csproj b/tests/SharpCompress.Test/SharpCompress.Test.csproj index 6223a62d..4d08ac18 100644 --- a/tests/SharpCompress.Test/SharpCompress.Test.csproj +++ b/tests/SharpCompress.Test/SharpCompress.Test.csproj @@ -16,5 +16,6 @@ + \ No newline at end of file diff --git a/tests/SharpCompress.Test/Tar/TarReaderTests.cs b/tests/SharpCompress.Test/Tar/TarReaderTests.cs index ac58b3e4..a5b75e4a 100644 --- a/tests/SharpCompress.Test/Tar/TarReaderTests.cs +++ b/tests/SharpCompress.Test/Tar/TarReaderTests.cs @@ -190,6 +190,8 @@ namespace SharpCompress.Test.Tar [Fact] public void Tar_GZip_With_Symlink_Entries() { + var isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform( + System.Runtime.InteropServices.OSPlatform.Windows); using (Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "TarWithSymlink.tar.gz"))) using (var reader = TarReader.Open(stream)) { @@ -204,21 +206,42 @@ namespace SharpCompress.Test.Tar new ExtractionOptions() { ExtractFullPath = true, - Overwrite = true + Overwrite = true, + WriteSymbolicLink = (sourcePath, targetPath) => + { + if (!isWindows) + { + var link = new Mono.Unix.UnixSymbolicLinkInfo(sourcePath); + if (System.IO.File.Exists(sourcePath)) + { + link.Delete(); // equivalent to ln -s -f + } + link.CreateSymbolicLinkTo(targetPath); + } + } }); - if (reader.Entry.LinkTarget != null) + if (!isWindows) { -#if NETSTANDARD2_0 - var link = new Mono.Unix.UnixSymbolicLinkInfo(reader.Entry.Key); - if (link.HasContents) + if (reader.Entry.LinkTarget != null) { - Assert.Equal(link.GetContents(), reader.Entry.LinkTarget); + var path = System.IO.Path.Combine(SCRATCH_FILES_PATH, reader.Entry.Key); + var link = new Mono.Unix.UnixSymbolicLinkInfo(path); + if (link.HasContents) + { + // need to convert the link to an absolute path for comparison + var target = reader.Entry.LinkTarget; + var realTarget = System.IO.Path.GetFullPath( + System.IO.Path.Combine($"{System.IO.Path.GetDirectoryName(path)}", + target) + ); + + Assert.Equal(realTarget, link.GetContents().ToString()); + } + else + { + Assert.True(false, "Symlink has no target"); + } } - else - { - Assert.True(false); - } -#endif } } }