aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/Archiver/TarArchiveReader.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Archiver/TarArchiveReader.cs')
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/TarArchiveReader.cs195
1 files changed, 195 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/TarArchiveReader.cs b/OpenSim/Region/CoreModules/World/Archiver/TarArchiveReader.cs
new file mode 100644
index 0000000..506d770
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Archiver/TarArchiveReader.cs
@@ -0,0 +1,195 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Reflection;
31using System.Text;
32using log4net;
33
34namespace OpenSim.Region.CoreModules.World.Archiver
35{
36 /// <summary>
37 /// Temporary code to do the bare minimum required to read a tar archive for our purposes
38 /// </summary>
39 public class TarArchiveReader
40 {
41 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42
43 public enum TarEntryType
44 {
45 TYPE_UNKNOWN = 0,
46 TYPE_NORMAL_FILE = 1,
47 TYPE_HARD_LINK = 2,
48 TYPE_SYMBOLIC_LINK = 3,
49 TYPE_CHAR_SPECIAL = 4,
50 TYPE_BLOCK_SPECIAL = 5,
51 TYPE_DIRECTORY = 6,
52 TYPE_FIFO = 7,
53 TYPE_CONTIGUOUS_FILE = 8,
54 }
55
56 protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
57
58 /// <summary>
59 /// Binary reader for the underlying stream
60 /// </summary>
61 protected BinaryReader m_br;
62
63 /// <summary>
64 /// Used to trim off null chars
65 /// </summary>
66 protected char[] m_nullCharArray = new char[] { '\0' };
67
68 /// <summary>
69 /// Generate a tar reader which reads from the given stream.
70 /// </summary>
71 /// <param name="s"></param>
72 public TarArchiveReader(Stream s)
73 {
74 m_br = new BinaryReader(s);
75 }
76
77 /// <summary>
78 /// Read the next entry in the tar file.
79 /// </summary>
80 /// <param name="filePath"></param>
81 /// <returns>the data for the entry. Returns null if there are no more entries</returns>
82 public byte[] ReadEntry(out string filePath, out TarEntryType entryType)
83 {
84 filePath = String.Empty;
85 entryType = TarEntryType.TYPE_UNKNOWN;
86 TarHeader header = ReadHeader();
87
88 if (null == header)
89 return null;
90
91 entryType = header.EntryType;
92 filePath = header.FilePath;
93 byte[] data = m_br.ReadBytes(header.FileSize);
94
95 //m_log.DebugFormat("[TAR ARCHIVE READER]: filePath {0}, fileSize {1}", filePath, header.FileSize);
96
97 // Read the rest of the empty padding in the 512 byte block
98 if (header.FileSize % 512 != 0)
99 {
100 int paddingLeft = 512 - (header.FileSize % 512);
101
102 //m_log.DebugFormat("[TAR ARCHIVE READER]: Reading {0} padding bytes", paddingLeft);
103
104 m_br.ReadBytes(paddingLeft);
105 }
106
107 return data;
108 }
109
110 /// <summary>
111 /// Read the next 512 byte chunk of data as a tar header.
112 /// </summary>
113 /// <returns>A tar header struct. null if we have reached the end of the archive.</returns>
114 protected TarHeader ReadHeader()
115 {
116 byte[] header = m_br.ReadBytes(512);
117
118 // If we've reached the end of the archive we'll be in null block territory, which means
119 // the next byte will be 0
120 if (header[0] == 0)
121 return null;
122
123 TarHeader tarHeader = new TarHeader();
124
125 tarHeader.FilePath = m_asciiEncoding.GetString(header, 0, 100);
126 tarHeader.FilePath = tarHeader.FilePath.Trim(m_nullCharArray);
127 tarHeader.FileSize = ConvertOctalBytesToDecimal(header, 124, 11);
128
129 switch (header[156])
130 {
131 case 0:
132 tarHeader.EntryType = TarEntryType.TYPE_NORMAL_FILE;
133 break;
134 case (byte)'0':
135 tarHeader.EntryType = TarEntryType.TYPE_NORMAL_FILE;
136 break;
137 case (byte)'1':
138 tarHeader.EntryType = TarEntryType.TYPE_HARD_LINK;
139 break;
140 case (byte)'2':
141 tarHeader.EntryType = TarEntryType.TYPE_SYMBOLIC_LINK;
142 break;
143 case (byte)'3':
144 tarHeader.EntryType = TarEntryType.TYPE_CHAR_SPECIAL;
145 break;
146 case (byte)'4':
147 tarHeader.EntryType = TarEntryType.TYPE_BLOCK_SPECIAL;
148 break;
149 case (byte)'5':
150 tarHeader.EntryType = TarEntryType.TYPE_DIRECTORY;
151 break;
152 case (byte)'6':
153 tarHeader.EntryType = TarEntryType.TYPE_FIFO;
154 break;
155 case (byte)'7':
156 tarHeader.EntryType = TarEntryType.TYPE_CONTIGUOUS_FILE;
157 break;
158 }
159
160 return tarHeader;
161 }
162
163 public void Close()
164 {
165 m_br.Close();
166 }
167
168 /// <summary>
169 /// Convert octal bytes to a decimal representation
170 /// </summary>
171 /// <param name="bytes"></param>
172 /// <returns></returns>
173 public static int ConvertOctalBytesToDecimal(byte[] bytes, int startIndex, int count)
174 {
175 string oString = m_asciiEncoding.GetString(bytes, startIndex, count);
176
177 int d = 0;
178
179 foreach (char c in oString)
180 {
181 d <<= 3;
182 d |= c - '0';
183 }
184
185 return d;
186 }
187 }
188
189 public class TarHeader
190 {
191 public string FilePath;
192 public int FileSize;
193 public TarArchiveReader.TarEntryType EntryType;
194 }
195}