From 0b1cb3fa30da3766127bb8fd65263351c008bdaa Mon Sep 17 00:00:00 2001 From: alcexhim Date: Fri, 8 Aug 2014 20:57:12 -0400 Subject: [PATCH] Fixed bug in TAR data format where the first four bytes of filename of first file got eaten --- .../TapeArchive/TapeArchiveDataFormat.cs | 375 +++++++++--------- 1 file changed, 187 insertions(+), 188 deletions(-) diff --git a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/TapeArchive/TapeArchiveDataFormat.cs b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/TapeArchive/TapeArchiveDataFormat.cs index 70f879eb..31fa6f37 100644 --- a/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/TapeArchive/TapeArchiveDataFormat.cs +++ b/CSharp/Plugins/UniversalEditor.Plugins.FileSystem/DataFormats/FileSystem/TapeArchive/TapeArchiveDataFormat.cs @@ -18,228 +18,227 @@ namespace UniversalEditor.DataFormats.FileSystem.TapeArchive _dfr = base.MakeReference(); _dfr.Capabilities.Add(typeof(FileSystemObjectModel), DataFormatCapabilities.All); _dfr.Filters.Add("Tape archive", new string[] { "*.tar", "*.tar.gz", "*.tgz", "*.tar.bz2", "*.tbz2", "*.tb2", "*.taz", "*.tar.z", "*.tlz", "*.tar.lz", "*.txz", "*.tar.xz" }); - _dfr.ExportOptions.Add(new CustomOptionBoolean("IsUnixStandardTAR", "Create a UNIX standard tape archive (ustar)", true)); + _dfr.ExportOptions.Add(new CustomOptionBoolean("IsUnixStandardTAR", "Create a UNIX standard tape archive (ustar)", true)); } return _dfr; } - private bool mvarIsUnixStandardTAR = true; - public bool IsUnixStandardTAR { get { return mvarIsUnixStandardTAR; } set { mvarIsUnixStandardTAR = value; } } + private bool mvarIsUnixStandardTAR = true; + public bool IsUnixStandardTAR { get { return mvarIsUnixStandardTAR; } set { mvarIsUnixStandardTAR = value; } } protected override void LoadInternal(ref ObjectModel objectModel) { - FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel); - if (fsom == null) throw new ObjectModelNotSupportedException(); + FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel); + if (fsom == null) throw new ObjectModelNotSupportedException(); - IO.Reader br = base.Accessor.Reader; - byte[] gzhead = br.ReadBytes(4); - if (gzhead.Match(new byte[] { 31, 139, 8, 0 })) - { - br.Accessor.Position -= 4; - byte[] data = br.ReadToEnd(); - data = CompressionModules.Gzip.Decompress(data); - br = new IO.Reader(new MemoryAccessor(data)); - } + IO.Reader br = base.Accessor.Reader; + byte[] gzhead = br.PeekBytes(4); + if (gzhead.Match(new byte[] { 31, 139, 8, 0 })) + { + byte[] data = br.ReadToEnd(); + data = CompressionModules.Gzip.Decompress(data); + br = new IO.Reader(new MemoryAccessor(data)); + } - bool ustar_set = false; - while (!br.EndOfStream) - { - if (br.Remaining < 263) break; + bool ustar_set = false; + while (!br.EndOfStream) + { + if (br.Remaining < 263) break; - string fileName = br.ReadFixedLengthString(100).TrimNull(); - if (fileName == String.Empty) break; + string fileName = br.ReadFixedLengthString(100).TrimNull(); + if (fileName == String.Empty) break; - string fileMode = br.ReadFixedLengthString(8).TrimNull(); - string owner = br.ReadFixedLengthString(8).TrimNull(); - string group = br.ReadFixedLengthString(8).TrimNull(); - string fileSizeInBytesOctal = br.ReadFixedLengthString(12).TrimNull(); - string lastModificationTimeUnixOctal = br.ReadFixedLengthString(12).TrimNull(); - string headerChecksum = br.ReadFixedLengthString(8).TrimNull(); - - char c = br.ReadChar(); - TapeArchiveRecordType type = (TapeArchiveRecordType)((int)c); + string fileMode = br.ReadFixedLengthString(8).TrimNull(); + string owner = br.ReadFixedLengthString(8).TrimNull(); + string group = br.ReadFixedLengthString(8).TrimNull(); + string fileSizeInBytesOctal = br.ReadFixedLengthString(12).TrimNull(); + string lastModificationTimeUnixOctal = br.ReadFixedLengthString(12).TrimNull(); + string headerChecksum = br.ReadFixedLengthString(8).TrimNull(); + + char c = br.ReadChar(); + TapeArchiveRecordType type = (TapeArchiveRecordType)((int)c); - string linkedFileName = br.ReadFixedLengthString(100).TrimNull(); + string linkedFileName = br.ReadFixedLengthString(100).TrimNull(); - string ustar = br.ReadFixedLengthString(6); - if (ustar == "ustar ") - { - if (!ustar_set) - { - mvarIsUnixStandardTAR = true; - ustar_set = true; - } - string ustarVersion = br.ReadFixedLengthString(2).TrimNull(); - string ownerName = br.ReadFixedLengthString(32).TrimNull(); - string groupName = br.ReadFixedLengthString(32).TrimNull(); - string deviceMajor = br.ReadFixedLengthString(8).TrimNull(); - string deviceMinor = br.ReadFixedLengthString(8).TrimNull(); - string filenamePrefix = br.ReadFixedLengthString(155).TrimNull(); - } - else - { - if (!ustar_set) - { - mvarIsUnixStandardTAR = false; - ustar_set = true; - } - br.Accessor.Position -= 6; - } - br.Align(512); + string ustar = br.ReadFixedLengthString(6); + if (ustar == "ustar ") + { + if (!ustar_set) + { + mvarIsUnixStandardTAR = true; + ustar_set = true; + } + string ustarVersion = br.ReadFixedLengthString(2).TrimNull(); + string ownerName = br.ReadFixedLengthString(32).TrimNull(); + string groupName = br.ReadFixedLengthString(32).TrimNull(); + string deviceMajor = br.ReadFixedLengthString(8).TrimNull(); + string deviceMinor = br.ReadFixedLengthString(8).TrimNull(); + string filenamePrefix = br.ReadFixedLengthString(155).TrimNull(); + } + else + { + if (!ustar_set) + { + mvarIsUnixStandardTAR = false; + ustar_set = true; + } + br.Accessor.Position -= 6; + } + br.Align(512); - if (fileName.EndsWith("/")) - { - fileName = fileName.Substring(0, fileName.Length - 1); - Folder folder = fsom.AddFolder(fileName); - } - else - { - File file = fsom.AddFile(fileName); + if (fileName.EndsWith("/")) + { + fileName = fileName.Substring(0, fileName.Length - 1); + Folder folder = fsom.AddFolder(fileName); + } + else + { + File file = fsom.AddFile(fileName); - long fileSize = Convert.ToInt64(fileSizeInBytesOctal, 8); - long fileOffset = (long)br.Accessor.Position; - file.Properties.Add("reader", br); - file.Properties.Add("offset", fileOffset); - file.Properties.Add("length", fileSize); - file.Size = fileSize; - file.DataRequest += file_DataRequest; + long fileSize = Convert.ToInt64(fileSizeInBytesOctal, 8); + long fileOffset = (long)br.Accessor.Position; + file.Properties.Add("reader", br); + file.Properties.Add("offset", fileOffset); + file.Properties.Add("length", fileSize); + file.Size = fileSize; + file.DataRequest += file_DataRequest; - br.Accessor.Position += fileSize; - br.Align(512); - } - } + br.Accessor.Position += fileSize; + br.Align(512); + } + } } - private void file_DataRequest(object sender, DataRequestEventArgs e) - { - File file = (sender as File); - IO.Reader br = (IO.Reader)file.Properties["reader"]; - long offset = (long)file.Properties["offset"]; - long length = (long)file.Properties["length"]; - br.Accessor.Position = offset; - e.Data = br.ReadBytes(length); - } + private void file_DataRequest(object sender, DataRequestEventArgs e) + { + File file = (sender as File); + IO.Reader br = (IO.Reader)file.Properties["reader"]; + long offset = (long)file.Properties["offset"]; + long length = (long)file.Properties["length"]; + br.Accessor.Position = offset; + e.Data = br.ReadBytes(length); + } - private long OctalToBase10(long octal) - { - long value = 0; - while (octal > 0) - { - value += (octal % 8); - octal /= 8; - } - return value; - } + private long OctalToBase10(long octal) + { + long value = 0; + while (octal > 0) + { + value += (octal % 8); + octal /= 8; + } + return value; + } protected override void SaveInternal(ObjectModel objectModel) - { - FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel); - if (fsom == null) throw new ObjectModelNotSupportedException(); + { + FileSystemObjectModel fsom = (objectModel as FileSystemObjectModel); + if (fsom == null) throw new ObjectModelNotSupportedException(); - IO.Writer bw = base.Accessor.Writer; - foreach (Folder folder in fsom.Folders) - { - RecursiveWriteFolder(bw, folder); - } - foreach (File file in fsom.Files) - { - RecursiveWriteFile(bw, file, String.Empty); - } - } + IO.Writer bw = base.Accessor.Writer; + foreach (Folder folder in fsom.Folders) + { + RecursiveWriteFolder(bw, folder); + } + foreach (File file in fsom.Files) + { + RecursiveWriteFile(bw, file, String.Empty); + } + } - private void RecursiveWriteFolder(IO.Writer bw, Folder folder) - { - bw.WriteFixedLengthString(folder.Name + "/", 100); + private void RecursiveWriteFolder(IO.Writer bw, Folder folder) + { + bw.WriteFixedLengthString(folder.Name + "/", 100); - string fileMode = " \0"; - bw.WriteFixedLengthString(fileMode, 8); - string owner = " \0"; - bw.WriteFixedLengthString(owner, 8); - string group = " \0"; - bw.WriteFixedLengthString(group, 8); - string fileSizeInBytesOctal = " \0"; - bw.WriteFixedLengthString(fileSizeInBytesOctal, 12); - string lastModificationTimeUnixOctal = " \0"; - bw.WriteFixedLengthString(lastModificationTimeUnixOctal, 12); - string headerChecksum = " \0"; - bw.WriteFixedLengthString(headerChecksum, 12); + string fileMode = " \0"; + bw.WriteFixedLengthString(fileMode, 8); + string owner = " \0"; + bw.WriteFixedLengthString(owner, 8); + string group = " \0"; + bw.WriteFixedLengthString(group, 8); + string fileSizeInBytesOctal = " \0"; + bw.WriteFixedLengthString(fileSizeInBytesOctal, 12); + string lastModificationTimeUnixOctal = " \0"; + bw.WriteFixedLengthString(lastModificationTimeUnixOctal, 12); + string headerChecksum = " \0"; + bw.WriteFixedLengthString(headerChecksum, 12); - char c = (char)(int)TapeArchiveRecordType.Directory; + char c = (char)(int)TapeArchiveRecordType.Directory; - string linkedFileName = String.Empty; - bw.WriteFixedLengthString(linkedFileName, 100); + string linkedFileName = String.Empty; + bw.WriteFixedLengthString(linkedFileName, 100); - if (mvarIsUnixStandardTAR) - { - bw.WriteFixedLengthString("ustar ", 6); + if (mvarIsUnixStandardTAR) + { + bw.WriteFixedLengthString("ustar ", 6); - string ustarVersion = String.Empty; - bw.WriteFixedLengthString(ustarVersion, 2); - string ownerName = String.Empty; - bw.WriteFixedLengthString(ownerName, 32); - string groupName = String.Empty; - bw.WriteFixedLengthString(groupName, 32); - string deviceMajor = String.Empty; - bw.WriteFixedLengthString(deviceMajor, 8); - string deviceMinor = String.Empty; - bw.WriteFixedLengthString(deviceMinor, 8); - string filenamePrefix = String.Empty; - bw.WriteFixedLengthString(filenamePrefix, 155); - } - bw.Align(512); + string ustarVersion = String.Empty; + bw.WriteFixedLengthString(ustarVersion, 2); + string ownerName = String.Empty; + bw.WriteFixedLengthString(ownerName, 32); + string groupName = String.Empty; + bw.WriteFixedLengthString(groupName, 32); + string deviceMajor = String.Empty; + bw.WriteFixedLengthString(deviceMajor, 8); + string deviceMinor = String.Empty; + bw.WriteFixedLengthString(deviceMinor, 8); + string filenamePrefix = String.Empty; + bw.WriteFixedLengthString(filenamePrefix, 155); + } + bw.Align(512); - foreach (Folder folder1 in folder.Folders) - { - RecursiveWriteFolder(bw, folder1); - } - foreach (File file1 in folder.Files) - { - RecursiveWriteFile(bw, file1, folder.Name + "/"); - } - } - private void RecursiveWriteFile(IO.Writer bw, File file, string parentPath) - { - if (!String.IsNullOrEmpty(parentPath)) parentPath = parentPath + "/"; - parentPath = parentPath + file.Name; + foreach (Folder folder1 in folder.Folders) + { + RecursiveWriteFolder(bw, folder1); + } + foreach (File file1 in folder.Files) + { + RecursiveWriteFile(bw, file1, folder.Name + "/"); + } + } + private void RecursiveWriteFile(IO.Writer bw, File file, string parentPath) + { + if (!String.IsNullOrEmpty(parentPath)) parentPath = parentPath + "/"; + parentPath = parentPath + file.Name; - bw.WriteFixedLengthString(parentPath, 100); + bw.WriteFixedLengthString(parentPath, 100); - string fileMode = " \0"; - bw.WriteFixedLengthString(fileMode, 8); - string owner = " \0"; - bw.WriteFixedLengthString(owner, 8); - string group = " \0"; - bw.WriteFixedLengthString(group, 8); - string fileSizeInBytesOctal = Convert.ToString(file.Size, 8).PadLeft(11, ' ') + "\0"; - bw.WriteFixedLengthString(fileSizeInBytesOctal, 12); - string lastModificationTimeUnixOctal = " \0"; - bw.WriteFixedLengthString(lastModificationTimeUnixOctal, 12); - string headerChecksum = " \0"; - bw.WriteFixedLengthString(headerChecksum, 12); + string fileMode = " \0"; + bw.WriteFixedLengthString(fileMode, 8); + string owner = " \0"; + bw.WriteFixedLengthString(owner, 8); + string group = " \0"; + bw.WriteFixedLengthString(group, 8); + string fileSizeInBytesOctal = Convert.ToString(file.Size, 8).PadLeft(11, ' ') + "\0"; + bw.WriteFixedLengthString(fileSizeInBytesOctal, 12); + string lastModificationTimeUnixOctal = " \0"; + bw.WriteFixedLengthString(lastModificationTimeUnixOctal, 12); + string headerChecksum = " \0"; + bw.WriteFixedLengthString(headerChecksum, 12); - char c = (char)(int)TapeArchiveRecordType.Directory; + char c = (char)(int)TapeArchiveRecordType.Directory; - string linkedFileName = String.Empty; - bw.WriteFixedLengthString(linkedFileName, 100); + string linkedFileName = String.Empty; + bw.WriteFixedLengthString(linkedFileName, 100); - if (mvarIsUnixStandardTAR) - { - bw.WriteFixedLengthString("ustar ", 6); + if (mvarIsUnixStandardTAR) + { + bw.WriteFixedLengthString("ustar ", 6); - string ustarVersion = String.Empty; - bw.WriteFixedLengthString(ustarVersion, 2); - string ownerName = String.Empty; - bw.WriteFixedLengthString(ownerName, 32); - string groupName = String.Empty; - bw.WriteFixedLengthString(groupName, 32); - string deviceMajor = String.Empty; - bw.WriteFixedLengthString(deviceMajor, 8); - string deviceMinor = String.Empty; - bw.WriteFixedLengthString(deviceMinor, 8); - string filenamePrefix = String.Empty; - bw.WriteFixedLengthString(filenamePrefix, 155); - } - bw.Align(512); - } + string ustarVersion = String.Empty; + bw.WriteFixedLengthString(ustarVersion, 2); + string ownerName = String.Empty; + bw.WriteFixedLengthString(ownerName, 32); + string groupName = String.Empty; + bw.WriteFixedLengthString(groupName, 32); + string deviceMajor = String.Empty; + bw.WriteFixedLengthString(deviceMajor, 8); + string deviceMinor = String.Empty; + bw.WriteFixedLengthString(deviceMinor, 8); + string filenamePrefix = String.Empty; + bw.WriteFixedLengthString(filenamePrefix, 155); + } + bw.Align(512); + } } }