Ref #248. Ref #132. Tar reader support for symlinks for .NET standard 2 and Posix platforms

Extracts linkname from the tar header, and exposes this on IEntry as the LinkTarget (string) property. If an entry is not a symlink, then that property is null.

Uses Mono.Posix.NETStandard nuget to create a symlink. However, this is only applicable to .NET standard 2.0+. So far, unable to find a nuget that works for older versions.

Also, not sure what to do on Windows.
This commit is contained in:
Mark Final
2018-11-01 21:48:48 +00:00
parent 0941239454
commit 192b9c1e8b
10 changed files with 55 additions and 10 deletions

View File

@@ -15,6 +15,11 @@ namespace SharpCompress.Common
/// </summary>
public abstract string Key { get; }
/// <summary>
/// The target of a symlink entry internal to the Archive. Will be null if not a symlink.
/// </summary>
public abstract string LinkTarget { get; }
/// <summary>
/// The compressed file size
/// </summary>

View File

@@ -68,19 +68,40 @@ namespace SharpCompress.Common
ExtractionOptions options,
Action<string, FileMode> openAndWrite)
{
FileMode fm = FileMode.Create;
options = options ?? new ExtractionOptions()
{
Overwrite = true
};
if (!options.Overwrite)
#if NETSTANDARD2_0
if (entry.LinkTarget != null)
{
fm = FileMode.CreateNew;
/*
var parDir = System.IO.Path.GetDirectoryName(destinationFileName);
if (!System.IO.Directory.Exists(parDir))
{
System.IO.Directory.CreateDirectory(parDir);
}
*/
var link = new Mono.Unix.UnixSymbolicLinkInfo(destinationFileName);
if (System.IO.File.Exists(destinationFileName))
{
link.Delete(); // equivalent to ln -s -f
}
link.CreateSymbolicLinkTo(entry.LinkTarget);
}
else
#endif
{
FileMode fm = FileMode.Create;
options = options ?? new ExtractionOptions()
{
Overwrite = true
};
openAndWrite(destinationFileName, fm);
entry.PreserveExtractionOptions(destinationFileName, options);
if (!options.Overwrite)
{
fm = FileMode.CreateNew;
}
openAndWrite(destinationFileName, fm);
entry.PreserveExtractionOptions(destinationFileName, options);
}
}
#endif
}

View File

@@ -20,6 +20,8 @@ namespace SharpCompress.Common.GZip
public override string Key => _filePart.FilePartName;
public override string LinkTarget => null;
public override long CompressedSize => 0;
public override long Size => 0;

View File

@@ -10,6 +10,7 @@ namespace SharpCompress.Common
long Crc { get; }
DateTime? CreatedTime { get; }
string Key { get; }
string LinkTarget { get; }
bool IsDirectory { get; }
bool IsEncrypted { get; }
bool IsSplitAfter { get; }

View File

@@ -22,6 +22,8 @@ namespace SharpCompress.Common.Rar
/// </summary>
public override string Key => FileHeader.FileName;
public override string LinkTarget => null;
/// <summary>
/// The entry last modified time in the archive, if recorded
/// </summary>

View File

@@ -18,6 +18,8 @@ namespace SharpCompress.Common.SevenZip
public override string Key => FilePart.Header.Name;
public override string LinkTarget => null;
public override long CompressedSize => 0;
public override long Size => FilePart.Header.Size;

View File

@@ -15,6 +15,7 @@ namespace SharpCompress.Common.Tar.Headers
}
internal string Name { get; set; }
internal string LinkName { get; set; }
//internal int Mode { get; set; }
//internal int UserId { get; set; }
@@ -98,6 +99,12 @@ namespace SharpCompress.Common.Tar.Headers
return false;
}
// for symlinks, additionally read the linkname
if (ReadEntryType(buffer) == EntryType.SymLink)
{
LinkName = ArchiveEncoding.Decode(buffer, 157, 100).TrimNulls();
}
if (ReadEntryType(buffer) == EntryType.LongName)
{
Name = ReadLongName(reader, buffer);

View File

@@ -23,6 +23,8 @@ namespace SharpCompress.Common.Tar
public override string Key => _filePart.Header.Name;
public override string LinkTarget => _filePart.Header.LinkName;
public override long CompressedSize => _filePart.Header.Size;
public override long Size => _filePart.Header.Size;

View File

@@ -60,6 +60,8 @@ namespace SharpCompress.Common.Zip
public override string Key => _filePart.Header.Name;
public override string LinkTarget => null;
public override long CompressedSize => _filePart.Header.CompressedSize;
public override long Size => _filePart.Header.UncompressedSize;

View File

@@ -34,6 +34,7 @@
<DefineConstants>$(DefineConstants);NETCORE</DefineConstants>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
</ItemGroup>
</Project>