using System; using System.IO; namespace Packaging.Targets.IO { /// /// Represents a Tar archive. /// public class TarFile : ArchiveFile { private TarHeader entryHeader; /// /// Initializes a new instance of the class. /// /// /// A which represents the tar file. /// /// /// to leave the underlying open when this /// is disposed of; otherwise, . /// public TarFile(Stream stream, bool leaveOpen) : base(stream, leaveOpen) { } /// /// Gets the link target of this file. /// public string LinkName { get; private set; } /// public override bool Read() { this.Align(512); this.EntryStream?.Dispose(); this.EntryStream = null; this.entryHeader = this.Stream.ReadStruct(); this.FileHeader = this.entryHeader; this.FileName = this.entryHeader.FileName; this.LinkName = this.entryHeader.LinkName; // There are two empty blocks at the end of the file. if (string.IsNullOrEmpty(this.entryHeader.Magic)) { return false; } if (this.entryHeader.Magic != "ustar") { throw new InvalidDataException("The magic for the file entry is invalid"); } this.Align(512); // TODO: Validate Checksum this.EntryStream = new SubStream(this.Stream, this.Stream.Position, this.entryHeader.FileSize, leaveParentOpen: true); if (this.entryHeader.TypeFlag == TarTypeFlag.LongName) { var longFileName = this.ReadAsUtf8String(); var read = this.Read(); this.FileName = longFileName; return read; } else if (this.entryHeader.TypeFlag == TarTypeFlag.LongLink) { var longLinkName = this.ReadAsUtf8String(); var read = this.Read(); this.LinkName = longLinkName; return read; } else { return true; } } } }