public void CanCreateATarFileWithMultipleFileEntriesWithADeepHierarchy() { using (Stream outStream = BuildOutStream()) { using (var writer = new TarWriter(outStream)) using (var entry1 = GetFileEntryFrom(@"deep\1.txt")) using (var entry2 = GetFileEntryFrom(@"deep\2\fox.txt")) using (var entry3 = GetFileEntryFrom(@"deep\2\3\dog.txt")) { writer.Write(entry1.Path, entry1.Stream, 511, new DateTime(2013, 4, 1, 13, 12, 58, 548).ToUniversalTime()); writer.Write(entry2.Path, entry2.Stream, 511, new DateTime(2013, 4, 1, 13, 12, 58, 548).ToUniversalTime()); writer.Write(entry3.Path, entry3.Stream, 511, new DateTime(2013, 4, 1, 13, 12, 58, 548).ToUniversalTime()); } outStream.Seek(0, SeekOrigin.Begin); using (var reader = new StreamReader(outStream)) using (var expectedContentStream = GetExpectedStream("CanCreateATarFileWithMultipleFileEntriesWithADeepHierarchy")) { string content = reader.ReadToEnd(); string expectedContent = expectedContentStream.ReadToEnd(); Assert.Equal(expectedContent, content); } } }
public static Stream CreateTarStream(IList<string> paths, CancellationToken cancellationToken, IProgress<string> progress = null) { var pipe = new Pipe(); var reader = new PipeReadStream(pipe); try { var tarTask = Task.Run(async () => { using (var writer = new PipeWriteStream(pipe)) { try { var tar = new TarWriter(writer); foreach (var path in paths) { var fi = new FileInfo(path); if (fi.Attributes.HasFlag(FileAttributes.Directory)) { await tar.CreateEntriesFromDirectoryAsync(path, ".", cancellationToken, progress); } else { if (progress != null) { progress.Report(path); } await tar.CreateEntryFromFileAsync(path, Path.GetFileName(path), cancellationToken); } } await tar.CloseAsync(); } catch (Exception e) { writer.Close(e); throw; } writer.Close(); } }, cancellationToken); } catch (Exception e) { reader.Close(e); throw; } return reader; }
public async Task WriteFifo_Async() { await using (MemoryStream archiveStream = new MemoryStream()) { await using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true)) { PaxTarEntry fifo = new PaxTarEntry(TarEntryType.Fifo, InitialEntryName); SetFifo(fifo); VerifyFifo(fifo); await writer.WriteEntryAsync(fifo); } archiveStream.Position = 0; await using (TarReader reader = new TarReader(archiveStream)) { PaxTarEntry fifo = await reader.GetNextEntryAsync() as PaxTarEntry; VerifyFifo(fifo); } } }
public async Task WriteBlockDevice_Async() { await using (MemoryStream archiveStream = new MemoryStream()) { await using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true)) { PaxTarEntry blockDevice = new PaxTarEntry(TarEntryType.BlockDevice, InitialEntryName); SetBlockDevice(blockDevice); VerifyBlockDevice(blockDevice); await writer.WriteEntryAsync(blockDevice); } archiveStream.Position = 0; await using (TarReader reader = new TarReader(archiveStream)) { PaxTarEntry blockDevice = await reader.GetNextEntryAsync() as PaxTarEntry; VerifyBlockDevice(blockDevice); } } }
private void InitializeArchive() { if (archiveFileName1 == null) { archiveFileName1 = Path.GetTempFileName(); SharedData.Instance.ArchiveFileName = archiveFileName1; SharedData.Instance.TempFiles.Add(archiveFileName1); } //gzFile = File.Create(archiveFileName1); //gzFile.SetLength(0); //SharedData.Instance.OpenDisposables.Add(gzFile); //gzStream = new GZipStream(gzFile, CompressionMode.Compress, false); //SharedData.Instance.OpenDisposables.Add(gzStream); //tarWriter = new TarWriter(gzStream); tarFile = File.Create(archiveFileName1); tarFile.SetLength(0); SharedData.Instance.OpenDisposables.Add(tarFile); tarWriter = new TarWriter(tarFile); SharedData.Instance.OpenDisposables.Add(tarWriter); createdDirs.Clear(); }
public async Task WriteRegularFile_Async() { await using (MemoryStream archiveStream = new MemoryStream()) { await using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true)) { PaxTarEntry regularFile = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName); SetRegularFile(regularFile); VerifyRegularFile(regularFile, isWritable: true); await writer.WriteEntryAsync(regularFile); } archiveStream.Position = 0; await using (TarReader reader = new TarReader(archiveStream)) { PaxTarEntry regularFile = await reader.GetNextEntryAsync() as PaxTarEntry; VerifyRegularFile(regularFile, isWritable: false); } } }
public override void Import(Stream input, Stream output, string filename) { using (var importer = new AssimpContext()) { var scene = importer.ImportFileFromStream(input, PostProcessSteps.Triangulate | PostProcessSteps.SortByPrimitiveType | PostProcessSteps.GenerateNormals, Path.GetExtension(filename)); using (var tw = new TarWriter(output)) { var textures = new Dictionary <string, string>(); using (var ms = new MemoryStream()) { using (var bw = new BinaryWriter(ms)) { this.WriteModel(scene, bw, textures); bw.Flush(); //this.PrintNode(scene, scene.RootNode, 0); ms.Position = 0; tw.Write(ms, ms.Length, "model.bin"); } } this.WriteTextures(scene, tw, textures); } } }
public void Write_V7RegularFileEntry_As_RegularFileEntry() { using MemoryStream archive = new MemoryStream(); using (TarWriter writer = new TarWriter(archive, archiveFormat: TarFormat.Pax, leaveOpen: true)) { V7TarEntry entry = new V7TarEntry(TarEntryType.V7RegularFile, InitialEntryName); // Should be written as RegularFile writer.WriteEntry(entry); } archive.Seek(0, SeekOrigin.Begin); using (TarReader reader = new TarReader(archive)) { PaxTarEntry entry = reader.GetNextEntry() as PaxTarEntry; Assert.NotNull(entry); Assert.Equal(TarEntryType.RegularFile, entry.EntryType); Assert.Null(reader.GetNextEntry()); } }
public void Write_To_UnseekableStream() { using MemoryStream inner = new MemoryStream(); using WrappedStream wrapped = new WrappedStream(inner, canRead: true, canWrite: true, canSeek: false); using (TarWriter writer = new TarWriter(wrapped, leaveOpen: true)) { PaxTarEntry paxEntry = new PaxTarEntry(TarEntryType.RegularFile, "file.txt"); writer.WriteEntry(paxEntry); } // The final records should get written, and the length should not be set because position cannot be read inner.Seek(0, SeekOrigin.Begin); // Rewind the base stream (wrapped cannot be rewound) using (TarReader reader = new TarReader(wrapped)) { TarEntry entry = reader.GetNextEntry(); Assert.Equal(TarFormat.Pax, reader.Format); Assert.Equal(TarEntryType.RegularFile, entry.EntryType); Assert.Null(reader.GetNextEntry()); } }
public async Task Extract_LinkEntry_TargetOutsideDirectory_Async(TarEntryType entryType) { await using (MemoryStream archive = new MemoryStream()) { await using (TarWriter writer = new TarWriter(archive, TarEntryFormat.Ustar, leaveOpen: true)) { UstarTarEntry entry = new UstarTarEntry(entryType, "link"); entry.LinkName = PlatformDetection.IsWindows ? @"C:\Windows\System32\notepad.exe" : "/usr/bin/nano"; await writer.WriteEntryAsync(entry); } archive.Seek(0, SeekOrigin.Begin); using (TempDirectory root = new TempDirectory()) { await Assert.ThrowsAsync <IOException>(() => TarFile.ExtractToDirectoryAsync(archive, root.Path, overwriteFiles: false)); Assert.Equal(0, Directory.GetFileSystemEntries(root.Path).Count()); } } }
public async Task WriteSymbolicLink_Async() { await using (MemoryStream archiveStream = new MemoryStream()) { await using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true)) { PaxTarEntry symbolicLink = new PaxTarEntry(TarEntryType.SymbolicLink, InitialEntryName); SetSymbolicLink(symbolicLink); VerifySymbolicLink(symbolicLink); await writer.WriteEntryAsync(symbolicLink); } archiveStream.Position = 0; await using (TarReader reader = new TarReader(archiveStream)) { PaxTarEntry symbolicLink = await reader.GetNextEntryAsync() as PaxTarEntry; VerifySymbolicLink(symbolicLink); } } }
private async Task Verify_Checksum_Internal_Async(TarEntryFormat format, TarEntryType entryType, bool longPath, bool longLink) { using MemoryStream archive = new MemoryStream(); int expectedChecksum; await using (TarWriter writer = new TarWriter(archive, format, leaveOpen: true)) { TarEntry entry = CreateTarEntryAndGetExpectedChecksum(format, entryType, longPath, longLink, out expectedChecksum); await writer.WriteEntryAsync(entry); Assert.Equal(expectedChecksum, entry.Checksum); } archive.Seek(0, SeekOrigin.Begin); await using (TarReader reader = new TarReader(archive)) { TarEntry entry = await reader.GetNextEntryAsync(); Assert.Equal(expectedChecksum, entry.Checksum); } }
public async Task WriteDirectory_Async() { await using (MemoryStream archiveStream = new MemoryStream()) { await using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true)) { PaxTarEntry directory = new PaxTarEntry(TarEntryType.Directory, InitialEntryName); SetDirectory(directory); VerifyDirectory(directory); await writer.WriteEntryAsync(directory); } archiveStream.Position = 0; await using (TarReader reader = new TarReader(archiveStream)) { PaxTarEntry directory = await reader.GetNextEntryAsync() as PaxTarEntry; VerifyDirectory(directory); } } }
/// <summary> /// Adds every file in the directory to the tar, and recurses into subdirectories. /// </summary> private void AddAllToTar(string root, TarWriter tar) { Log("Opening in " + root + "..."); // Add subdirectories... foreach (var directory in Directory.GetDirectories(root)) { AddAllToTar(directory, tar); } foreach (var file in Directory.GetFiles(root)) { var info = new FileInfo(file); Log("Writing " + info.Name + "... (" + Util.FormatFileSize(info.Length) + ")"); using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { tar.Write(fs); } } }
public async Task EntryName_NullOrEmpty_Async() { using (TempDirectory root = new TempDirectory()) { string file1Name = "file1.txt"; string file2Name = "file2.txt"; string file1Path = Path.Join(root.Path, file1Name); string file2Path = Path.Join(root.Path, file2Name); File.Create(file1Path).Dispose(); File.Create(file2Path).Dispose(); await using (MemoryStream archiveStream = new MemoryStream()) { await using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true)) { await writer.WriteEntryAsync(file1Path, null); await writer.WriteEntryAsync(file2Path, string.Empty); } archiveStream.Seek(0, SeekOrigin.Begin); await using (TarReader reader = new TarReader(archiveStream)) { TarEntry first = await reader.GetNextEntryAsync(); Assert.NotNull(first); Assert.Equal(file1Name, first.Name); TarEntry second = await reader.GetNextEntryAsync(); Assert.NotNull(second); Assert.Equal(file2Name, second.Name); Assert.Null(await reader.GetNextEntryAsync()); } } } }
public async Task WritePaxAttributes_LongLinkName_AutomaticallyAdded_Async() { using MemoryStream archiveStream = new MemoryStream(); string longSymbolicLinkName = new string('a', 101); string longHardLinkName = new string('b', 101); await using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true)) { PaxTarEntry symlink = new PaxTarEntry(TarEntryType.SymbolicLink, "symlink"); symlink.LinkName = longSymbolicLinkName; await writer.WriteEntryAsync(symlink); PaxTarEntry hardlink = new PaxTarEntry(TarEntryType.HardLink, "hardlink"); hardlink.LinkName = longHardLinkName; await writer.WriteEntryAsync(hardlink); } archiveStream.Position = 0; await using (TarReader reader = new TarReader(archiveStream)) { PaxTarEntry symlink = await reader.GetNextEntryAsync() as PaxTarEntry; AssertExtensions.GreaterThanOrEqualTo(symlink.ExtendedAttributes.Count, 5); Assert.Contains(PaxEaName, symlink.ExtendedAttributes); Assert.Equal("symlink", symlink.ExtendedAttributes[PaxEaName]); Assert.Contains(PaxEaLinkName, symlink.ExtendedAttributes); Assert.Equal(longSymbolicLinkName, symlink.ExtendedAttributes[PaxEaLinkName]); PaxTarEntry hardlink = await reader.GetNextEntryAsync() as PaxTarEntry; AssertExtensions.GreaterThanOrEqualTo(hardlink.ExtendedAttributes.Count, 5); Assert.Contains(PaxEaName, hardlink.ExtendedAttributes); Assert.Equal("hardlink", hardlink.ExtendedAttributes[PaxEaName]); Assert.Contains(PaxEaLinkName, hardlink.ExtendedAttributes); Assert.Equal(longHardLinkName, hardlink.ExtendedAttributes[PaxEaLinkName]); } }
public void Add_SymbolicLink(TarEntryFormat format, bool createTarget) { using TempDirectory root = new TempDirectory(); string targetName = "file.txt"; string linkName = "link.txt"; string targetPath = Path.Join(root.Path, targetName); string linkPath = Path.Join(root.Path, linkName); if (createTarget) { File.Create(targetPath).Dispose(); } FileInfo linkInfo = new FileInfo(linkPath); linkInfo.CreateAsSymbolicLink(targetName); using MemoryStream archive = new MemoryStream(); using (TarWriter writer = new TarWriter(archive, format, leaveOpen: true)) { writer.WriteEntry(fileName: linkPath, entryName: linkName); } archive.Seek(0, SeekOrigin.Begin); using (TarReader reader = new TarReader(archive)) { TarEntry entry = reader.GetNextEntry(); Assert.Equal(format, entry.Format); Assert.NotNull(entry); Assert.Equal(linkName, entry.Name); Assert.Equal(targetName, entry.LinkName); Assert.Equal(TarEntryType.SymbolicLink, entry.EntryType); Assert.Null(entry.DataStream); VerifyPlatformSpecificMetadata(linkPath, entry); Assert.Null(reader.GetNextEntry()); } }
public void Add_CharacterDevice(TarEntryFormat format) { RemoteExecutor.Invoke((string strFormat) => { TarEntryFormat expectedFormat = Enum.Parse <TarEntryFormat>(strFormat); using TempDirectory root = new TempDirectory(); string characterDevicePath = Path.Join(root.Path, AssetCharacterDeviceFileName); // Creating device files needs elevation Interop.CheckIo(Interop.Sys.CreateCharacterDevice(characterDevicePath, (int)DefaultFileMode, TestCharacterDeviceMajor, TestCharacterDeviceMinor)); using MemoryStream archive = new MemoryStream(); using (TarWriter writer = new TarWriter(archive, expectedFormat, leaveOpen: true)) { writer.WriteEntry(fileName: characterDevicePath, entryName: AssetCharacterDeviceFileName); } archive.Seek(0, SeekOrigin.Begin); using (TarReader reader = new TarReader(archive)) { PosixTarEntry entry = reader.GetNextEntry() as PosixTarEntry; Assert.Equal(expectedFormat, entry.Format); Assert.NotNull(entry); Assert.Equal(AssetCharacterDeviceFileName, entry.Name); Assert.Equal(DefaultLinkName, entry.LinkName); Assert.Equal(TarEntryType.CharacterDevice, entry.EntryType); Assert.Null(entry.DataStream); VerifyPlatformSpecificMetadata(characterDevicePath, entry); Assert.Equal(TestCharacterDeviceMajor, entry.DeviceMajor); Assert.Equal(TestCharacterDeviceMinor, entry.DeviceMinor); Assert.Null(reader.GetNextEntry()); } }, format.ToString(), new RemoteInvokeOptions { RunAsSudo = true }).Dispose(); }
public async Task WritePaxAttributes_Name_AutomaticallyAdded_Async() { using MemoryStream archiveStream = new MemoryStream(); TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true); await using (writer) { PaxTarEntry regularFile = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName); await writer.WriteEntryAsync(regularFile); } archiveStream.Position = 0; TarReader reader = new TarReader(archiveStream); await using (reader) { PaxTarEntry regularFile = await reader.GetNextEntryAsync() as PaxTarEntry; AssertExtensions.GreaterThanOrEqualTo(regularFile.ExtendedAttributes.Count, 4); Assert.Contains(PaxEaName, regularFile.ExtendedAttributes); } }
public async Task WriteTimestampsBeyondEpochalypse_Async(TarEntryFormat format) { DateTimeOffset epochalypse = new DateTimeOffset(2038, 1, 19, 3, 14, 8, TimeSpan.Zero); // One second past Y2K38 TarEntry entry = InvokeTarEntryCreationConstructor(format, TarEntryType.Directory, "dir"); entry.ModificationTime = epochalypse; Assert.Equal(epochalypse, entry.ModificationTime); if (entry is GnuTarEntry gnuEntry) { gnuEntry.AccessTime = epochalypse; Assert.Equal(epochalypse, gnuEntry.AccessTime); gnuEntry.ChangeTime = epochalypse; Assert.Equal(epochalypse, gnuEntry.ChangeTime); } using MemoryStream archiveStream = new MemoryStream(); await using (TarWriter writer = new TarWriter(archiveStream, leaveOpen: true)) { await writer.WriteEntryAsync(entry); } archiveStream.Position = 0; await using (TarReader reader = new TarReader(archiveStream)) { TarEntry readEntry = await reader.GetNextEntryAsync(); Assert.NotNull(readEntry); Assert.Equal(epochalypse, readEntry.ModificationTime); if (readEntry is GnuTarEntry gnuReadEntry) { Assert.Equal(epochalypse, gnuReadEntry.AccessTime); Assert.Equal(epochalypse, gnuReadEntry.ChangeTime); } } }
public async Task ReadAndWriteMultipleGlobalExtendedAttributesEntries_Async(TarEntryFormat format) { Dictionary <string, string> attrs = new Dictionary <string, string>() { { "hello", "world" }, { "dotnet", "runtime" } }; using MemoryStream archiveStream = new MemoryStream(); TarWriter writer = new TarWriter(archiveStream, leaveOpen: true); await using (writer) { PaxGlobalExtendedAttributesTarEntry gea1 = new PaxGlobalExtendedAttributesTarEntry(attrs); await writer.WriteEntryAsync(gea1); TarEntry entry1 = InvokeTarEntryCreationConstructor(format, TarEntryType.Directory, "dir1"); await writer.WriteEntryAsync(entry1); PaxGlobalExtendedAttributesTarEntry gea2 = new PaxGlobalExtendedAttributesTarEntry(attrs); await writer.WriteEntryAsync(gea2); TarEntry entry2 = InvokeTarEntryCreationConstructor(format, TarEntryType.Directory, "dir2"); await writer.WriteEntryAsync(entry2); } archiveStream.Position = 0; TarReader reader = new TarReader(archiveStream, leaveOpen: false); await using (reader) { VerifyGlobalExtendedAttributesEntry(await reader.GetNextEntryAsync(), attrs); VerifyDirectory(await reader.GetNextEntryAsync(), format, "dir1"); VerifyGlobalExtendedAttributesEntry(await reader.GetNextEntryAsync(), attrs); VerifyDirectory(await reader.GetNextEntryAsync(), format, "dir2"); Assert.Null(await reader.GetNextEntryAsync()); } }
public void Add_Fifo(TarEntryFormat format) { RemoteExecutor.Invoke((string strFormat) => { TarEntryFormat expectedFormat = Enum.Parse <TarEntryFormat>(strFormat); using TempDirectory root = new TempDirectory(); string fifoName = "fifofile"; string fifoPath = Path.Join(root.Path, fifoName); Interop.CheckIo(Interop.Sys.MkFifo(fifoPath, (int)DefaultMode)); using MemoryStream archive = new MemoryStream(); using (TarWriter writer = new TarWriter(archive, expectedFormat, leaveOpen: true)) { writer.WriteEntry(fileName: fifoPath, entryName: fifoName); } archive.Seek(0, SeekOrigin.Begin); using (TarReader reader = new TarReader(archive)) { Assert.Equal(TarEntryFormat.Unknown, reader.Format); PosixTarEntry entry = reader.GetNextEntry() as PosixTarEntry; Assert.Equal(expectedFormat, reader.Format); Assert.NotNull(entry); Assert.Equal(fifoName, entry.Name); Assert.Equal(DefaultLinkName, entry.LinkName); Assert.Equal(TarEntryType.Fifo, entry.EntryType); Assert.Null(entry.DataStream); VerifyPlatformSpecificMetadata(fifoPath, entry); Assert.Null(reader.GetNextEntry()); } }, format.ToString(), new RemoteInvokeOptions { RunAsSudo = true }).Dispose(); }
public async Task BlockAlignmentPadding_DoesNotAffectNextEntries_Async(int contentSize, bool copyData) { byte[] fileContents = new byte[contentSize]; Array.Fill <byte>(fileContents, 0x1); using var archive = new MemoryStream(); using (var writer = new TarWriter(archive, leaveOpen: true)) { var entry1 = new PaxTarEntry(TarEntryType.RegularFile, "file"); entry1.DataStream = new MemoryStream(fileContents); await writer.WriteEntryAsync(entry1); var entry2 = new PaxTarEntry(TarEntryType.RegularFile, "next-file"); await writer.WriteEntryAsync(entry2); } archive.Position = 0; using var unseekable = new WrappedStream(archive, archive.CanRead, archive.CanWrite, canSeek: false); using var reader = new TarReader(unseekable); TarEntry e = await reader.GetNextEntryAsync(copyData); Assert.Equal(contentSize, e.Length); byte[] buffer = new byte[contentSize]; while (e.DataStream.Read(buffer) > 0) { ; } AssertExtensions.SequenceEqual(fileContents, buffer); e = await reader.GetNextEntryAsync(copyData); Assert.Equal(0, e.Length); e = await reader.GetNextEntryAsync(copyData); Assert.Null(e); }
public void WritePaxAttributes_Timestamps_AutomaticallyAdded() { DateTimeOffset minimumTime = DateTimeOffset.UtcNow - TimeSpan.FromHours(1); using MemoryStream archiveStream = new MemoryStream(); using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true)) { PaxTarEntry regularFile = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName); writer.WriteEntry(regularFile); } archiveStream.Position = 0; using (TarReader reader = new TarReader(archiveStream)) { PaxTarEntry regularFile = reader.GetNextEntry() as PaxTarEntry; AssertExtensions.GreaterThanOrEqualTo(regularFile.ExtendedAttributes.Count, 4); VerifyExtendedAttributeTimestamp(regularFile, PaxEaMTime, minimumTime); VerifyExtendedAttributeTimestamp(regularFile, PaxEaATime, minimumTime); VerifyExtendedAttributeTimestamp(regularFile, PaxEaCTime, minimumTime); } }
public void Write_V7RegularFileEntry_In_OtherFormatsWriter(TarEntryFormat writerFormat) { using MemoryStream archive = new MemoryStream(); using (TarWriter writer = new TarWriter(archive, format: writerFormat, leaveOpen: true)) { V7TarEntry entry = new V7TarEntry(TarEntryType.V7RegularFile, InitialEntryName); // Should be written in the format of the entry writer.WriteEntry(entry); } archive.Seek(0, SeekOrigin.Begin); using (TarReader reader = new TarReader(archive)) { TarEntry entry = reader.GetNextEntry(); Assert.NotNull(entry); Assert.Equal(TarEntryFormat.V7, entry.Format); Assert.True(entry is V7TarEntry); Assert.Null(reader.GetNextEntry()); } }
public void UnixFileModes_RestrictiveParentDir(bool overwrite) { using TempDirectory source = new TempDirectory(); using TempDirectory destination = new TempDirectory(); string archivePath = Path.Join(source.Path, "archive.tar"); using FileStream archiveStream = File.Create(archivePath); using (TarWriter writer = new TarWriter(archiveStream)) { PaxTarEntry dir = new PaxTarEntry(TarEntryType.Directory, "dir"); dir.Mode = UnixFileMode.None; // Restrict permissions. writer.WriteEntry(dir); PaxTarEntry file = new PaxTarEntry(TarEntryType.RegularFile, "dir/file"); file.Mode = TestPermission1; writer.WriteEntry(file); } string dirPath = Path.Join(destination.Path, "dir"); string filePath = Path.Join(dirPath, "file"); if (overwrite) { Directory.CreateDirectory(dirPath); File.OpenWrite(filePath).Dispose(); } TarFile.ExtractToDirectory(archivePath, destination.Path, overwriteFiles: overwrite); Assert.True(Directory.Exists(dirPath), $"{dirPath}' does not exist."); AssertFileModeEquals(dirPath, UnixFileMode.None); // Set dir permissions so we can access file. SetUnixFileMode(dirPath, UserAll); Assert.True(File.Exists(filePath), $"{filePath}' does not exist."); AssertFileModeEquals(filePath, TestPermission1); }
public void Write_LongLinkName(TarEntryType entryType) { // LinkName field in header only fits 100 bytes string longLinkName = new string('a', 101); using MemoryStream archiveStream = new MemoryStream(); using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Gnu, leaveOpen: true)) { GnuTarEntry entry = new GnuTarEntry(entryType, "file.txt"); entry.LinkName = longLinkName; writer.WriteEntry(entry); } archiveStream.Position = 0; using (TarReader reader = new TarReader(archiveStream)) { GnuTarEntry entry = reader.GetNextEntry() as GnuTarEntry; Assert.Equal(entryType, entry.EntryType); Assert.Equal("file.txt", entry.Name); Assert.Equal(longLinkName, entry.LinkName); } }
public void Add_Directory(TarEntryFormat format, bool withContents) { using TempDirectory root = new TempDirectory(); string dirName = "dir"; string dirPath = Path.Join(root.Path, dirName); Directory.CreateDirectory(dirPath); if (withContents) { // Add a file inside the directory, we need to ensure the contents // of the directory are ignored when using AddFile File.Create(Path.Join(dirPath, "file.txt")).Dispose(); } using MemoryStream archive = new MemoryStream(); using (TarWriter writer = new TarWriter(archive, format, leaveOpen: true)) { writer.WriteEntry(fileName: dirPath, entryName: dirName); } archive.Seek(0, SeekOrigin.Begin); using (TarReader reader = new TarReader(archive)) { Assert.Equal(TarEntryFormat.Unknown, reader.Format); TarEntry entry = reader.GetNextEntry(); Assert.Equal(format, reader.Format); Assert.NotNull(entry); Assert.Equal(dirName, entry.Name); Assert.Equal(TarEntryType.Directory, entry.EntryType); Assert.Null(entry.DataStream); VerifyPlatformSpecificMetadata(dirPath, entry); Assert.Null(reader.GetNextEntry()); // If the dir had contents, they should've been excluded } }
public void TarReaderWriter() { var checks = new Dictionary <string, byte[]>(); var random = new Random(); byte[] data; using (var stream = new MemoryStream()) { using (var writer = new TarWriter(stream, true)) { for (var i = 0; i < 1000; i++) { var buffer = new byte[random.Next(64 * 1024)]; var name = $"{i % 10}/{i} {buffer.GetHashCode().ToString("x")}.txt"; checks.Add(name, buffer); writer.AddFile(name, buffer); } } data = stream.ToArray(); } using (var stream = new MemoryStream(data)) { using (var reader = new TarReader(stream, true)) { var copy = checks.ToDictionary(i => i.Key, i => i.Value); while (reader.ReadNext(out var entry, out var content)) { if (!copy.TryGetValue(entry.Name, out var expectedContent)) { Assert.Fail("Entry name not found at source!"); } copy.Remove(entry.Name); CollectionAssert.AreEqual(expectedContent, content); } } } }
public void WritePaxAttributes_CustomAttribute() { string expectedKey = "MyExtendedAttributeKey"; string expectedValue = "MyExtendedAttributeValue"; Dictionary <string, string> extendedAttributes = new(); extendedAttributes.Add(expectedKey, expectedValue); using MemoryStream archiveStream = new MemoryStream(); using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true)) { PaxTarEntry regularFile = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName, extendedAttributes); SetRegularFile(regularFile); VerifyRegularFile(regularFile, isWritable: true); writer.WriteEntry(regularFile); } archiveStream.Position = 0; using (TarReader reader = new TarReader(archiveStream)) { PaxTarEntry regularFile = reader.GetNextEntry() as PaxTarEntry; VerifyRegularFile(regularFile, isWritable: false); Assert.NotNull(regularFile.ExtendedAttributes); // path, mtime, atime and ctime are always collected by default Assert.True(regularFile.ExtendedAttributes.Count >= 5); Assert.Contains("path", regularFile.ExtendedAttributes); Assert.Contains("mtime", regularFile.ExtendedAttributes); Assert.Contains("atime", regularFile.ExtendedAttributes); Assert.Contains("ctime", regularFile.ExtendedAttributes); Assert.Contains(expectedKey, regularFile.ExtendedAttributes); Assert.Equal(expectedValue, regularFile.ExtendedAttributes[expectedKey]); } }
public async Task Write_Long_Name_Async(TarEntryType entryType) { // Name field in header only fits 100 bytes string longName = new string('a', 101); await using (MemoryStream archiveStream = new MemoryStream()) { await using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Gnu, leaveOpen: true)) { GnuTarEntry entry = new GnuTarEntry(entryType, longName); await writer.WriteEntryAsync(entry); } archiveStream.Position = 0; await using (TarReader reader = new TarReader(archiveStream)) { GnuTarEntry entry = await reader.GetNextEntryAsync() as GnuTarEntry; Assert.Equal(entryType, entry.EntryType); Assert.Equal(longName, entry.Name); } } }
public void LongEndMarkers_DoNotAdvanceStream() { using MemoryStream archive = new MemoryStream(); using (TarWriter writer = new TarWriter(archive, TarEntryFormat.Ustar, leaveOpen: true)) { UstarTarEntry entry = new UstarTarEntry(TarEntryType.Directory, "dir"); writer.WriteEntry(entry); } byte[] buffer = new byte[2048]; // Four additional end markers (512 each) Array.Fill <byte>(buffer, 0x0); archive.Write(buffer); archive.Seek(0, SeekOrigin.Begin); using TarReader reader = new TarReader(archive); Assert.NotNull(reader.GetNextEntry()); Assert.Null(reader.GetNextEntry()); long expectedPosition = archive.Position; // After reading the first null entry, should not advance more Assert.Null(reader.GetNextEntry()); Assert.Equal(expectedPosition, archive.Position); }
public void CanCreateATarFileWithOneFileEntry() { using (Stream outStream = BuildOutStream()) { using (var writer = new TarWriter(outStream)) using (var entry = GetFileEntryFrom(@"single\1.txt")) { writer.Write(entry.Path, entry.Stream, 511, new DateTime(2013, 4, 1, 13, 12, 58, 548).ToUniversalTime()); } outStream.Seek(0, SeekOrigin.Begin); using (var reader = new StreamReader(outStream)) using (var expectedContentStream = GetExpectedStream("CanCreateATarFileWithOneFileEntry")) { string content = reader.ReadToEnd(); string expectedContent = expectedContentStream.ReadToEnd(); Assert.Equal(expectedContent, content); } } }
public TarWriterStream(TarWriter writer) { _writer = writer; }