예제 #1
0
        public async void Write_To_UnseekableStream_Async()
        {
            await using (MemoryStream inner = new MemoryStream())
            {
                await using (WrappedStream wrapped = new WrappedStream(inner, canRead: true, canWrite: true, canSeek: false))
                {
                    await using (TarWriter writer = new TarWriter(wrapped, TarEntryFormat.Pax, leaveOpen: true))
                    {
                        PaxTarEntry paxEntry = new PaxTarEntry(TarEntryType.RegularFile, "file.txt");
                        await writer.WriteEntryAsync(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)

                    await using (TarReader reader = new TarReader(wrapped))
                    {
                        TarEntry entry = await reader.GetNextEntryAsync();

                        Assert.Equal(TarEntryFormat.Pax, entry.Format);
                        Assert.Equal(TarEntryType.RegularFile, entry.EntryType);
                        Assert.Null(await reader.GetNextEntryAsync());
                    }
                }
            }
        }
예제 #2
0
        public async Task WritePaxAttributes_Timestamps_UserProvided_Async()
        {
            Dictionary <string, string> extendedAttributes = new();

            extendedAttributes.Add(PaxEaATime, GetTimestampStringFromDateTimeOffset(TestAccessTime));
            extendedAttributes.Add(PaxEaCTime, GetTimestampStringFromDateTimeOffset(TestChangeTime));

            await using (MemoryStream archiveStream = new MemoryStream())
            {
                await using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true))
                {
                    PaxTarEntry regularFile = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName, extendedAttributes);
                    regularFile.ModificationTime = TestModificationTime;
                    await writer.WriteEntryAsync(regularFile);
                }

                archiveStream.Position = 0;
                await using (TarReader reader = new TarReader(archiveStream))
                {
                    PaxTarEntry regularFile = await reader.GetNextEntryAsync() as PaxTarEntry;

                    AssertExtensions.GreaterThanOrEqualTo(regularFile.ExtendedAttributes.Count, 4);
                    VerifyExtendedAttributeTimestamp(regularFile, PaxEaMTime, TestModificationTime);
                    VerifyExtendedAttributeTimestamp(regularFile, PaxEaATime, TestAccessTime);
                    VerifyExtendedAttributeTimestamp(regularFile, PaxEaCTime, TestChangeTime);
                }
            }
        }
        public async Task UnixFileModes_RestrictiveParentDir_Async()
        {
            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);
            }

            await TarFile.ExtractToDirectoryAsync(archivePath, destination.Path, overwriteFiles : false);

            string dirPath = Path.Join(destination.Path, "dir");

            Assert.True(Directory.Exists(dirPath), $"{dirPath}' does not exist.");
            AssertFileModeEquals(dirPath, UnixFileMode.None);

            // Set dir permissions so we can access file.
            SetUnixFileMode(dirPath, UserAll);

            string filePath = Path.Join(dirPath, "file");

            Assert.True(File.Exists(filePath), $"{filePath}' does not exist.");
            AssertFileModeEquals(filePath, TestPermission1);
        }
예제 #4
0
        public void WritePaxAttributes_Timestamps()
        {
            Dictionary <string, string> extendedAttributes = new();

            extendedAttributes.Add("atime", ConvertDateTimeOffsetToDouble(TestAccessTime).ToString("F6", CultureInfo.InvariantCulture));
            extendedAttributes.Add("ctime", ConvertDateTimeOffsetToDouble(TestChangeTime).ToString("F6", CultureInfo.InvariantCulture));

            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);
                Assert.True(regularFile.ExtendedAttributes.Count >= 4);

                Assert.Contains("path", regularFile.ExtendedAttributes);
                VerifyExtendedAttributeTimestamp(regularFile, "mtime", TestModificationTime);
                VerifyExtendedAttributeTimestamp(regularFile, "atime", TestAccessTime);
                VerifyExtendedAttributeTimestamp(regularFile, "ctime", TestChangeTime);
            }
        }
예제 #5
0
        public void SupportedEntryType_CharacterDevice()
        {
            PaxTarEntry characterDevice = new PaxTarEntry(TarEntryType.CharacterDevice, InitialEntryName);

            SetCharacterDevice(characterDevice);
            VerifyCharacterDevice(characterDevice);
        }
예제 #6
0
        public void SupportedEntryType_Directory()
        {
            PaxTarEntry directory = new PaxTarEntry(TarEntryType.Directory, InitialEntryName);

            SetDirectory(directory);
            VerifyDirectory(directory);
        }
예제 #7
0
        public void SupportedEntryType_SymbolicLink()
        {
            PaxTarEntry symbolicLink = new PaxTarEntry(TarEntryType.SymbolicLink, InitialEntryName);

            SetSymbolicLink(symbolicLink);
            VerifySymbolicLink(symbolicLink);
        }
예제 #8
0
        public void SupportedEntryType_HardLink()
        {
            PaxTarEntry hardLink = new PaxTarEntry(TarEntryType.HardLink, InitialEntryName);

            SetHardLink(hardLink);
            VerifyHardLink(hardLink);
        }
예제 #9
0
        public void SupportedEntryType_Fifo()
        {
            PaxTarEntry fifo = new PaxTarEntry(TarEntryType.Fifo, InitialEntryName);

            SetFifo(fifo);
            VerifyFifo(fifo);
        }
        public void Constructor_ConversionFromPax_From_UnseekableTarReader(TarEntryFormat writerFormat)
        {
            using MemoryStream source         = GetTarMemoryStream(CompressionMethod.Uncompressed, TestTarFormat.pax, "file");
            using WrappedStream wrappedSource = new WrappedStream(source, canRead: true, canWrite: false, canSeek: false);

            using TarReader sourceReader = new TarReader(wrappedSource, leaveOpen: true);
            PaxTarEntry paxEntry = sourceReader.GetNextEntry(copyData: false) as PaxTarEntry;
            V7TarEntry  v7Entry  = new V7TarEntry(other: paxEntry); // Convert, and avoid advancing wrappedSource position

            using MemoryStream destination = new MemoryStream();
            using (TarWriter writer = new TarWriter(destination, writerFormat, leaveOpen: true))
            {
                writer.WriteEntry(v7Entry); // Write DataStream exactly where the wrappedSource position was left
            }

            destination.Position = 0; // Rewind
            using (TarReader destinationReader = new TarReader(destination, leaveOpen: false))
            {
                V7TarEntry resultEntry = destinationReader.GetNextEntry() as V7TarEntry;
                Assert.NotNull(resultEntry);
                using (StreamReader streamReader = new StreamReader(resultEntry.DataStream))
                {
                    Assert.Equal("Hello file", streamReader.ReadToEnd());
                }
            }
        }
예제 #11
0
        public void SupportedEntryType_BlockDevice()
        {
            PaxTarEntry blockDevice = new PaxTarEntry(TarEntryType.BlockDevice, InitialEntryName);

            SetBlockDevice(blockDevice);
            VerifyBlockDevice(blockDevice);
        }
        public async Task Extract_UnseekableStream_BlockAlignmentPadding_DoesNotAffectNextEntries_Async(int contentSize)
        {
            byte[] fileContents = new byte[contentSize];
            Array.Fill <byte>(fileContents, 0x1);

            using var archive = new MemoryStream();
            using (var compressor = new GZipStream(archive, CompressionMode.Compress, leaveOpen: true))
            {
                using var writer = new TarWriter(compressor);
                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 decompressor = new GZipStream(archive, CompressionMode.Decompress);
            using var reader       = new TarReader(decompressor);

            using TempDirectory destination = new TempDirectory();
            await TarFile.ExtractToDirectoryAsync(decompressor, destination.Path, overwriteFiles : true);

            Assert.Equal(2, Directory.GetFileSystemEntries(destination.Path, "*", SearchOption.AllDirectories).Count());
        }
예제 #13
0
        public void SupportedEntryType_RegularFile()
        {
            PaxTarEntry regularFile = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName);

            SetRegularFile(regularFile);
            VerifyRegularFile(regularFile, isWritable: true);
        }
예제 #14
0
        public void Extract_AllSegmentsOfPath()
        {
            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 segment1 = new PaxTarEntry(TarEntryType.Directory, "segment1");
                writer.WriteEntry(segment1);

                PaxTarEntry segment2 = new PaxTarEntry(TarEntryType.Directory, "segment1/segment2");
                writer.WriteEntry(segment2);

                PaxTarEntry file = new PaxTarEntry(TarEntryType.RegularFile, "segment1/segment2/file.txt");
                writer.WriteEntry(file);
            }

            TarFile.ExtractToDirectory(archivePath, destination.Path, overwriteFiles: false);

            string segment1Path = Path.Join(destination.Path, "segment1");

            Assert.True(Directory.Exists(segment1Path), $"{segment1Path}' does not exist.");

            string segment2Path = Path.Join(segment1Path, "segment2");

            Assert.True(Directory.Exists(segment2Path), $"{segment2Path}' does not exist.");

            string filePath = Path.Join(segment2Path, "file.txt");

            Assert.True(File.Exists(filePath), $"{filePath}' does not exist.");
        }
예제 #15
0
        protected void VerifyExtendedAttributeTimestamps(PaxTarEntry pax)
        {
            Assert.NotNull(pax.ExtendedAttributes);
            AssertExtensions.GreaterThanOrEqualTo(pax.ExtendedAttributes.Count, 3); // Expect to at least collect mtime, ctime and atime

            VerifyExtendedAttributeTimestamp(pax, PaxEaMTime, MinimumTime);
            VerifyExtendedAttributeTimestamp(pax, PaxEaATime, MinimumTime);
            VerifyExtendedAttributeTimestamp(pax, PaxEaCTime, MinimumTime);
        }
예제 #16
0
        public async Task WriteEntry_AfterDispose_Throws_Async()
        {
            using MemoryStream archiveStream = new MemoryStream();
            TarWriter writer = new TarWriter(archiveStream);
            await writer.DisposeAsync();

            PaxTarEntry entry = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName);
            await Assert.ThrowsAsync <ObjectDisposedException>(() => writer.WriteEntryAsync(entry));
        }
예제 #17
0
        // The fixed size fields for mtime, atime and ctime can fit 12 ASCII characters, but the last character is reserved for an ASCII space.
        // We internally use long to represent the seconds since Unix epoch, not int.
        // If the max allowed value is 77,777,777,777 in octal, then the max allowed seconds since the Unix epoch are 8,589,934,591,
        // which represents the date "2242/03/16 12:56:32 +00:00".
        // Pax should survive after this date because it stores the timestamps in the extended attributes dictionary
        // without size restrictions.
        public async Task WriteTimestampsBeyondOctalLimitInPax_Async()
        {
            DateTimeOffset overLimitTimestamp = new DateTimeOffset(2242, 3, 16, 12, 56, 33, TimeSpan.Zero); // One second past the octal limit

            string strOverLimitTimestamp = GetTimestampStringFromDateTimeOffset(overLimitTimestamp);

            Dictionary <string, string> ea = new Dictionary <string, string>()
            {
                { PaxEaATime, strOverLimitTimestamp },
                { PaxEaCTime, strOverLimitTimestamp }
            };

            PaxTarEntry entry = new PaxTarEntry(TarEntryType.Directory, "dir", ea);

            entry.ModificationTime = overLimitTimestamp;
            Assert.Equal(overLimitTimestamp, entry.ModificationTime);

            Assert.Contains(PaxEaATime, entry.ExtendedAttributes);
            DateTimeOffset atime = GetDateTimeOffsetFromTimestampString(entry.ExtendedAttributes, PaxEaATime);

            Assert.Equal(overLimitTimestamp, atime);

            Assert.Contains(PaxEaCTime, entry.ExtendedAttributes);
            DateTimeOffset ctime = GetDateTimeOffsetFromTimestampString(entry.ExtendedAttributes, PaxEaCTime);

            Assert.Equal(overLimitTimestamp, ctime);

            using MemoryStream archiveStream = new MemoryStream();
            TarWriter writer = new TarWriter(archiveStream, leaveOpen: true);

            await using (writer)
            {
                await writer.WriteEntryAsync(entry);
            }

            archiveStream.Position = 0;
            TarReader reader = new TarReader(archiveStream);

            await using (reader)
            {
                PaxTarEntry readEntry = await reader.GetNextEntryAsync() as PaxTarEntry;

                Assert.NotNull(readEntry);

                Assert.Equal(overLimitTimestamp, readEntry.ModificationTime);

                Assert.Contains(PaxEaATime, readEntry.ExtendedAttributes);
                DateTimeOffset actualATime = GetDateTimeOffsetFromTimestampString(readEntry.ExtendedAttributes, PaxEaATime);
                Assert.Equal(overLimitTimestamp, actualATime);

                Assert.Contains(PaxEaCTime, readEntry.ExtendedAttributes);
                DateTimeOffset actualCTime = GetDateTimeOffsetFromTimestampString(readEntry.ExtendedAttributes, PaxEaCTime);
                Assert.Equal(overLimitTimestamp, actualCTime);
            }
        }
예제 #18
0
        // Y2K38 will happen one second after "2038/19/01 03:14:07 +00:00". This timestamp represents the seconds since the Unix epoch with a
        // value of int.MaxValue: 2,147,483,647.
        // The fixed size fields for mtime, atime and ctime can fit 12 ASCII characters, but the last character is reserved for an ASCII space.
        // All our entry types should survive the Epochalypse because we internally use long to represent the seconds since Unix epoch, not int.
        // So if the max allowed value is 77,777,777,777 in octal, then the max allowed seconds since the Unix epoch are 8,589,934,591, which
        // is way past int MaxValue, but still within the long limits. That number represents the date "2242/16/03 12:56:32 +00:00".
        public async Task WriteTimestampsBeyondEpochalypseInPax_Async()
        {
            DateTimeOffset epochalypse    = new DateTimeOffset(2038, 1, 19, 3, 14, 8, TimeSpan.Zero);
            string         strEpochalypse = GetTimestampStringFromDateTimeOffset(epochalypse);

            Dictionary <string, string> ea = new Dictionary <string, string>()
            {
                { PaxEaATime, strEpochalypse },
                { PaxEaCTime, strEpochalypse }
            };

            PaxTarEntry entry = new PaxTarEntry(TarEntryType.Directory, "dir", ea);

            entry.ModificationTime = epochalypse;
            Assert.Equal(epochalypse, entry.ModificationTime);

            Assert.Contains(PaxEaATime, entry.ExtendedAttributes);
            DateTimeOffset atime = GetDateTimeOffsetFromTimestampString(entry.ExtendedAttributes, PaxEaATime);

            Assert.Equal(epochalypse, atime);

            Assert.Contains(PaxEaCTime, entry.ExtendedAttributes);
            DateTimeOffset ctime = GetDateTimeOffsetFromTimestampString(entry.ExtendedAttributes, PaxEaCTime);

            Assert.Equal(epochalypse, ctime);

            using MemoryStream archiveStream = new MemoryStream();
            TarWriter writer = new TarWriter(archiveStream, leaveOpen: true);

            await using (writer)
            {
                await writer.WriteEntryAsync(entry);
            }

            archiveStream.Position = 0;
            TarReader reader = new TarReader(archiveStream);

            await using (reader)
            {
                PaxTarEntry readEntry = await reader.GetNextEntryAsync() as PaxTarEntry;

                Assert.NotNull(readEntry);

                Assert.Equal(epochalypse, readEntry.ModificationTime);

                Assert.Contains(PaxEaATime, readEntry.ExtendedAttributes);
                DateTimeOffset actualATime = GetDateTimeOffsetFromTimestampString(readEntry.ExtendedAttributes, PaxEaATime);
                Assert.Equal(epochalypse, actualATime);

                Assert.Contains(PaxEaCTime, readEntry.ExtendedAttributes);
                DateTimeOffset actualCTime = GetDateTimeOffsetFromTimestampString(readEntry.ExtendedAttributes, PaxEaCTime);
                Assert.Equal(epochalypse, actualCTime);
            }
        }
예제 #19
0
        public void WriteEntry_AfterDispose_Throws()
        {
            using MemoryStream archiveStream = new MemoryStream();
            TarWriter writer = new TarWriter(archiveStream);

            writer.Dispose();

            PaxTarEntry entry = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName);

            Assert.Throws <ObjectDisposedException>(() => writer.WriteEntry(entry));
        }
예제 #20
0
        public async Task WritePaxAttributes_LongGroupName_LongUserName_Async()
        {
            string userName  = "******";
            string groupName = "IAmAGroupNameWhoseLengthIsWayBeyondTheThirtyTwoByteLimit";

            using MemoryStream archiveStream = new MemoryStream();
            TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true);

            await using (writer)
            {
                PaxTarEntry regularFile = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName);
                SetRegularFile(regularFile);
                VerifyRegularFile(regularFile, isWritable: true);
                regularFile.UserName  = userName;
                regularFile.GroupName = groupName;
                await writer.WriteEntryAsync(regularFile);
            }

            archiveStream.Position = 0;
            TarReader reader = new TarReader(archiveStream);

            await using (reader)
            {
                PaxTarEntry regularFile = await reader.GetNextEntryAsync() as PaxTarEntry;

                VerifyRegularFile(regularFile, isWritable: false);

                Assert.NotNull(regularFile.ExtendedAttributes);

                // path, mtime, atime and ctime are always collected by default
                AssertExtensions.GreaterThanOrEqualTo(regularFile.ExtendedAttributes.Count, 6);

                Assert.Contains(PaxEaName, regularFile.ExtendedAttributes);
                Assert.Contains(PaxEaMTime, regularFile.ExtendedAttributes);
                Assert.Contains(PaxEaATime, regularFile.ExtendedAttributes);
                Assert.Contains(PaxEaCTime, regularFile.ExtendedAttributes);

                Assert.Contains(PaxEaUName, regularFile.ExtendedAttributes);
                Assert.Equal(userName, regularFile.ExtendedAttributes[PaxEaUName]);

                Assert.Contains(PaxEaGName, regularFile.ExtendedAttributes);
                Assert.Equal(groupName, regularFile.ExtendedAttributes[PaxEaGName]);

                // They should also get exposed via the regular properties
                Assert.Equal(groupName, regularFile.GroupName);
                Assert.Equal(userName, regularFile.UserName);
            }
        }
예제 #21
0
        public void Constructor_Name_FullPath_DestinationDirectory_Mismatch_Throws()
        {
            using TempDirectory root = new TempDirectory();

            string fullPath = Path.Join(Path.GetPathRoot(root.Path), "dir", "file.txt");

            PaxTarEntry entry = new PaxTarEntry(TarEntryType.RegularFile, fullPath);

            entry.DataStream = new MemoryStream();
            entry.DataStream.Write(new byte[] { 0x1 });
            entry.DataStream.Seek(0, SeekOrigin.Begin);

            Assert.Throws <IOException>(() => entry.ExtractToFile(root.Path, overwrite: false));

            Assert.False(File.Exists(fullPath));
        }
예제 #22
0
        public void Constructor_Name_FullPath_DestinationDirectory_Match()
        {
            using TempDirectory root = new TempDirectory();

            string fullPath = Path.Join(root.Path, "file.txt");

            PaxTarEntry entry = new PaxTarEntry(TarEntryType.RegularFile, fullPath);

            entry.DataStream = new MemoryStream();
            entry.DataStream.Write(new byte[] { 0x1 });
            entry.DataStream.Seek(0, SeekOrigin.Begin);

            entry.ExtractToFile(fullPath, overwrite: false);

            Assert.True(File.Exists(fullPath));
        }
예제 #23
0
        public void ExtractToFile_Link_Throws(TarEntryType entryType)
        {
            using TempDirectory root = new TempDirectory();
            string fileName = "mylink";
            string fullPath = Path.Join(root.Path, fileName);

            string linkTarget = PlatformDetection.IsWindows ? @"C:\Windows\system32\notepad.exe" : "/usr/bin/nano";

            PaxTarEntry entry = new PaxTarEntry(entryType, fileName);

            entry.LinkName = linkTarget;

            Assert.Throws <InvalidOperationException>(() => entry.ExtractToFile(fileName, overwrite: false));

            Assert.Equal(0, Directory.GetFileSystemEntries(root.Path).Count());
        }
예제 #24
0
        public void WriteSymbolicLink()
        {
            using MemoryStream archiveStream = new MemoryStream();
            using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true))
            {
                PaxTarEntry symbolicLink = new PaxTarEntry(TarEntryType.SymbolicLink, InitialEntryName);
                SetSymbolicLink(symbolicLink);
                VerifySymbolicLink(symbolicLink);
                writer.WriteEntry(symbolicLink);
            }

            archiveStream.Position = 0;
            using (TarReader reader = new TarReader(archiveStream))
            {
                PaxTarEntry symbolicLink = reader.GetNextEntry() as PaxTarEntry;
                VerifySymbolicLink(symbolicLink);
            }
        }
예제 #25
0
        public void WriteBlockDevice()
        {
            using MemoryStream archiveStream = new MemoryStream();
            using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true))
            {
                PaxTarEntry blockDevice = new PaxTarEntry(TarEntryType.BlockDevice, InitialEntryName);
                SetBlockDevice(blockDevice);
                VerifyBlockDevice(blockDevice);
                writer.WriteEntry(blockDevice);
            }

            archiveStream.Position = 0;
            using (TarReader reader = new TarReader(archiveStream))
            {
                PaxTarEntry blockDevice = reader.GetNextEntry() as PaxTarEntry;
                VerifyBlockDevice(blockDevice);
            }
        }
예제 #26
0
        public void WriteFifo()
        {
            using MemoryStream archiveStream = new MemoryStream();
            using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true))
            {
                PaxTarEntry fifo = new PaxTarEntry(TarEntryType.Fifo, InitialEntryName);
                SetFifo(fifo);
                VerifyFifo(fifo);
                writer.WriteEntry(fifo);
            }

            archiveStream.Position = 0;
            using (TarReader reader = new TarReader(archiveStream))
            {
                PaxTarEntry fifo = reader.GetNextEntry() as PaxTarEntry;
                VerifyFifo(fifo);
            }
        }
예제 #27
0
        public void WriteDirectory()
        {
            using MemoryStream archiveStream = new MemoryStream();
            using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true))
            {
                PaxTarEntry directory = new PaxTarEntry(TarEntryType.Directory, InitialEntryName);
                SetDirectory(directory);
                VerifyDirectory(directory);
                writer.WriteEntry(directory);
            }

            archiveStream.Position = 0;
            using (TarReader reader = new TarReader(archiveStream))
            {
                PaxTarEntry directory = reader.GetNextEntry() as PaxTarEntry;
                VerifyDirectory(directory);
            }
        }
예제 #28
0
        public void WriteRegularFile()
        {
            using MemoryStream archiveStream = new MemoryStream();
            using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true))
            {
                PaxTarEntry regularFile = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName);
                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);
            }
        }
예제 #29
0
        public async Task WritePaxAttributes_Name_AutomaticallyAdded_Async()
        {
            using MemoryStream archiveStream = new MemoryStream();
            await using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true))
            {
                PaxTarEntry regularFile = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName);
                await writer.WriteEntryAsync(regularFile);
            }

            archiveStream.Position = 0;
            await using (TarReader reader = new TarReader(archiveStream))
            {
                PaxTarEntry regularFile = await reader.GetNextEntryAsync() as PaxTarEntry;

                AssertExtensions.GreaterThanOrEqualTo(regularFile.ExtendedAttributes.Count, 4);
                Assert.Contains(PaxEaName, regularFile.ExtendedAttributes);
            }
        }
예제 #30
0
        public void WritePaxAttributes_LongGroupName_LongUserName()
        {
            string userName  = "******";
            string groupName = "IAmAGroupNameWhoseLengthIsWayBeyondTheThirtyTwoByteLimit";

            using MemoryStream archiveStream = new MemoryStream();
            using (TarWriter writer = new TarWriter(archiveStream, TarEntryFormat.Pax, leaveOpen: true))
            {
                PaxTarEntry regularFile = new PaxTarEntry(TarEntryType.RegularFile, InitialEntryName);
                SetRegularFile(regularFile);
                VerifyRegularFile(regularFile, isWritable: true);
                regularFile.UserName  = userName;
                regularFile.GroupName = groupName;
                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 >= 6);

                Assert.Contains("path", regularFile.ExtendedAttributes);
                Assert.Contains("mtime", regularFile.ExtendedAttributes);
                Assert.Contains("atime", regularFile.ExtendedAttributes);
                Assert.Contains("ctime", regularFile.ExtendedAttributes);

                Assert.Contains("uname", regularFile.ExtendedAttributes);
                Assert.Equal(userName, regularFile.ExtendedAttributes["uname"]);

                Assert.Contains("gname", regularFile.ExtendedAttributes);
                Assert.Equal(groupName, regularFile.ExtendedAttributes["gname"]);

                // They should also get exposed via the regular properties
                Assert.Equal(groupName, regularFile.GroupName);
                Assert.Equal(userName, regularFile.UserName);
            }
        }