mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-22 23:15:20 +00:00
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:
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user