From b57497fd41ad4cc56af40139ba940b5a4bbd47a6 Mon Sep 17 00:00:00 2001
From: Justin Clarke Casey
Date: Wed, 4 Mar 2009 18:33:05 +0000
Subject: * Add gnu tar format long file name support to tar reading and
writing. * Not actually tested yet though existing code which doesn't require
long file names looks fine
---
.../CoreModules/World/Archiver/TarArchiveWriter.cs | 185 ++++++++++++---------
1 file changed, 106 insertions(+), 79 deletions(-)
(limited to 'OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs')
diff --git a/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs b/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs
index f8e649e..09ea7ec 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs
@@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
{
m_files[filePath] = data;
}
-
+
///
/// Write the raw tar archive data to a stream. The stream will be closed on completion.
///
@@ -87,84 +87,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
foreach (string filePath in m_files.Keys)
{
- byte[] header = new byte[512];
- byte[] data = m_files[filePath];
-
- // file path field (100)
- byte[] nameBytes = m_asciiEncoding.GetBytes(filePath);
- int nameSize = (nameBytes.Length >= 100) ? 100 : nameBytes.Length;
- Array.Copy(nameBytes, header, nameSize);
-
- // file mode (8)
- byte[] modeBytes = m_asciiEncoding.GetBytes("0000777");
- Array.Copy(modeBytes, 0, header, 100, 7);
-
- // owner user id (8)
- byte[] ownerIdBytes = m_asciiEncoding.GetBytes("0000764");
- Array.Copy(ownerIdBytes, 0, header, 108, 7);
-
- // group user id (8)
- byte[] groupIdBytes = m_asciiEncoding.GetBytes("0000764");
- Array.Copy(groupIdBytes, 0, header, 116, 7);
-
- // file size in bytes (12)
- int fileSize = data.Length;
- //m_log.DebugFormat("[TAR ARCHIVE WRITER]: File size of {0} is {1}", filePath, fileSize);
-
- byte[] fileSizeBytes = ConvertDecimalToPaddedOctalBytes(fileSize, 11);
-
- Array.Copy(fileSizeBytes, 0, header, 124, 11);
-
- // last modification time (12)
- byte[] lastModTimeBytes = m_asciiEncoding.GetBytes("11017037332");
- Array.Copy(lastModTimeBytes, 0, header, 136, 11);
-
- // link indicator (1)
- //header[156] = m_asciiEncoding.GetBytes("0")[0];
- if (filePath.EndsWith("/"))
- {
- header[156] = m_asciiEncoding.GetBytes("5")[0];
- }
- else
- {
- header[156] = 0;
- }
-
- Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 329, 7);
- Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 337, 7);
-
- // check sum for header block (8) [calculated last]
- Array.Copy(m_asciiEncoding.GetBytes(" "), 0, header, 148, 8);
-
- int checksum = 0;
- foreach (byte b in header)
- {
- checksum += b;
- }
-
- //m_log.DebugFormat("[TAR ARCHIVE WRITER]: Decimal header checksum is {0}", checksum);
-
- byte[] checkSumBytes = ConvertDecimalToPaddedOctalBytes(checksum, 6);
-
- Array.Copy(checkSumBytes, 0, header, 148, 6);
-
- header[154] = 0;
-
- // Write out header
- bw.Write(header);
-
- // Write out data
- bw.Write(data);
-
- if (data.Length % 512 != 0)
- {
- int paddingRequired = 512 - (data.Length % 512);
-
- //m_log.DebugFormat("[TAR ARCHIVE WRITER]: Padding data with {0} bytes", paddingRequired);
-
- byte[] padding = new byte[paddingRequired];
- bw.Write(padding);
- }
+ WriteFile(bw, filePath, m_files[filePath]);
}
//m_log.Debug("[TAR ARCHIVE WRITER]: Writing final consecutive 0 blocks");
@@ -195,6 +118,110 @@ namespace OpenSim.Region.CoreModules.World.Archiver
byte[] oBytes = m_asciiEncoding.GetBytes(oString);
return oBytes;
+ }
+
+ ///
+ /// Write a particular file of data
+ ///
+ ///
+ ///
+ protected void WriteFile(BinaryWriter bw, string filePath, byte[] data)
+ {
+ if (filePath.Length > 100)
+ WriteEntry(bw, "././@LongLink", m_asciiEncoding.GetBytes(filePath), 'L');
+
+ char fileType;
+
+ if (filePath.EndsWith("/"))
+ {
+ fileType = '5';
+ }
+ else
+ {
+ fileType = '0';
+ }
+
+ WriteEntry(bw, filePath, data, fileType);
}
+
+ ///
+ /// Write a particular file of data
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected void WriteEntry(BinaryWriter bw, string filePath, byte[] data, char fileType)
+ {
+ byte[] header = new byte[512];
+
+ // file path field (100)
+ byte[] nameBytes = m_asciiEncoding.GetBytes(filePath);
+ int nameSize = (nameBytes.Length >= 100) ? 100 : nameBytes.Length;
+ Array.Copy(nameBytes, header, nameSize);
+
+ // file mode (8)
+ byte[] modeBytes = m_asciiEncoding.GetBytes("0000777");
+ Array.Copy(modeBytes, 0, header, 100, 7);
+
+ // owner user id (8)
+ byte[] ownerIdBytes = m_asciiEncoding.GetBytes("0000764");
+ Array.Copy(ownerIdBytes, 0, header, 108, 7);
+
+ // group user id (8)
+ byte[] groupIdBytes = m_asciiEncoding.GetBytes("0000764");
+ Array.Copy(groupIdBytes, 0, header, 116, 7);
+
+ // file size in bytes (12)
+ int fileSize = data.Length;
+ //m_log.DebugFormat("[TAR ARCHIVE WRITER]: File size of {0} is {1}", filePath, fileSize);
+
+ byte[] fileSizeBytes = ConvertDecimalToPaddedOctalBytes(fileSize, 11);
+
+ Array.Copy(fileSizeBytes, 0, header, 124, 11);
+
+ // last modification time (12)
+ byte[] lastModTimeBytes = m_asciiEncoding.GetBytes("11017037332");
+ Array.Copy(lastModTimeBytes, 0, header, 136, 11);
+
+ // entry type indicator (1)
+ header[156] = m_asciiEncoding.GetBytes(new char[] { fileType })[0];
+
+ Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 329, 7);
+ Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 337, 7);
+
+ // check sum for header block (8) [calculated last]
+ Array.Copy(m_asciiEncoding.GetBytes(" "), 0, header, 148, 8);
+
+ int checksum = 0;
+ foreach (byte b in header)
+ {
+ checksum += b;
+ }
+
+ //m_log.DebugFormat("[TAR ARCHIVE WRITER]: Decimal header checksum is {0}", checksum);
+
+ byte[] checkSumBytes = ConvertDecimalToPaddedOctalBytes(checksum, 6);
+
+ Array.Copy(checkSumBytes, 0, header, 148, 6);
+
+ header[154] = 0;
+
+ // Write out header
+ bw.Write(header);
+
+ // Write out data
+ bw.Write(data);
+
+ if (data.Length % 512 != 0)
+ {
+ int paddingRequired = 512 - (data.Length % 512);
+
+ //m_log.DebugFormat("[TAR ARCHIVE WRITER]: Padding data with {0} bytes", paddingRequired);
+
+ byte[] padding = new byte[paddingRequired];
+ bw.Write(padding);
+ }
+ }
}
}
--
cgit v1.1