diff options
Diffstat (limited to 'OpenSim/Region/Environment')
-rw-r--r-- | OpenSim/Region/Environment/Modules/World/Archiver/ArchiveRequest.cs | 13 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Modules/World/Archiver/TarArchive.cs | 174 |
2 files changed, 186 insertions, 1 deletions
diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveRequest.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveRequest.cs index 867aa3a..6824ce9 100644 --- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveRequest.cs +++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveRequest.cs | |||
@@ -97,7 +97,18 @@ namespace OpenSim.Region.Environment | |||
97 | 97 | ||
98 | protected internal void ReceivedAllAssets(IDictionary<LLUUID, AssetBase> assets) | 98 | protected internal void ReceivedAllAssets(IDictionary<LLUUID, AssetBase> assets) |
99 | { | 99 | { |
100 | m_log.DebugFormat("[ARCHIVER]: Received all {0} textures required", assets.Count); | 100 | m_log.DebugFormat("[ARCHIVER]: Received all {0} textures required", assets.Count); |
101 | |||
102 | // XXX: Shouldn't hijack the asset async callback thread like this - this is only temporary | ||
103 | |||
104 | TarArchive archive = new TarArchive(); | ||
105 | |||
106 | foreach (LLUUID uuid in assets.Keys) | ||
107 | { | ||
108 | archive.AddFile(uuid.ToString(), assets[uuid].Data); | ||
109 | } | ||
110 | |||
111 | archive.WriteTar(m_savePath); | ||
101 | } | 112 | } |
102 | 113 | ||
103 | /// <summary> | 114 | /// <summary> |
diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/TarArchive.cs b/OpenSim/Region/Environment/Modules/World/Archiver/TarArchive.cs new file mode 100644 index 0000000..0a6b1c1 --- /dev/null +++ b/OpenSim/Region/Environment/Modules/World/Archiver/TarArchive.cs | |||
@@ -0,0 +1,174 @@ | |||
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 | |||
28 | |||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.IO; | ||
32 | using System.Text; | ||
33 | using System.Reflection; | ||
34 | using log4net; | ||
35 | |||
36 | namespace OpenSim.Region.Environment | ||
37 | { | ||
38 | /// <summary> | ||
39 | /// Temporary code to produce a tar archive in tar v7 format | ||
40 | /// </summary> | ||
41 | public class TarArchive | ||
42 | { | ||
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
44 | |||
45 | protected Dictionary<string, byte[]> m_files = new Dictionary<string, byte[]>(); | ||
46 | |||
47 | protected static System.Text.ASCIIEncoding m_asciiEncoding = new System.Text.ASCIIEncoding(); | ||
48 | |||
49 | /// <summary> | ||
50 | /// Add a file to the tar archive | ||
51 | /// </summary> | ||
52 | /// <param name="filePath"></param> | ||
53 | /// <param name="data"></param> | ||
54 | public void AddFile(string filePath, byte[] data) | ||
55 | { | ||
56 | m_files[filePath] = data; | ||
57 | } | ||
58 | |||
59 | /// <summary> | ||
60 | /// Write the raw tar archive data to a file | ||
61 | /// </summary> | ||
62 | /// <returns></returns> | ||
63 | public void WriteTar(string archivePath) | ||
64 | { | ||
65 | BinaryWriter bw = new BinaryWriter(new FileStream(archivePath, FileMode.Create)); | ||
66 | |||
67 | foreach (string filePath in m_files.Keys) | ||
68 | { | ||
69 | byte[] header = new byte[512]; | ||
70 | byte[] data = m_files[filePath]; | ||
71 | |||
72 | //string filePath = "test.txt"; | ||
73 | //byte[] data = m_asciiEncoding.GetBytes("hello\n"); | ||
74 | |||
75 | // file path field (100) | ||
76 | byte[] nameBytes = m_asciiEncoding.GetBytes(filePath); | ||
77 | int nameSize = (nameBytes.Length >= 100) ? 100 : nameBytes.Length; | ||
78 | Array.Copy(nameBytes, header, nameSize); | ||
79 | |||
80 | // file mode (8) | ||
81 | byte[] modeBytes = m_asciiEncoding.GetBytes("0000644"); | ||
82 | Array.Copy(modeBytes, 0, header, 100, 7); | ||
83 | |||
84 | // owner user id (8) | ||
85 | byte[] ownerIdBytes = m_asciiEncoding.GetBytes("0000764"); | ||
86 | Array.Copy(ownerIdBytes, 0, header, 108, 7); | ||
87 | |||
88 | // group user id (8) | ||
89 | byte[] groupIdBytes = m_asciiEncoding.GetBytes("0000764"); | ||
90 | Array.Copy(groupIdBytes, 0, header, 116, 7); | ||
91 | |||
92 | // file size in bytes (12) | ||
93 | int fileSize = data.Length; | ||
94 | m_log.DebugFormat("[TAR ARCHIVE]: File size of {0} is {1}", filePath, fileSize); | ||
95 | |||
96 | byte[] fileSizeBytes = ConvertDecimalToPaddedOctalBytes(fileSize, 11); | ||
97 | |||
98 | Array.Copy(fileSizeBytes, 0, header, 124, 11); | ||
99 | |||
100 | // last modification time (12) | ||
101 | byte[] lastModTimeBytes = m_asciiEncoding.GetBytes("11017037332"); | ||
102 | Array.Copy(lastModTimeBytes, 0, header, 136, 11); | ||
103 | |||
104 | // link indicator (1) | ||
105 | //header[156] = m_asciiEncoding.GetBytes("0")[0]; | ||
106 | header[156] = 0; | ||
107 | |||
108 | Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 329, 7); | ||
109 | Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 337, 7); | ||
110 | |||
111 | // check sum for header block (8) [calculated last] | ||
112 | Array.Copy(m_asciiEncoding.GetBytes(" "), 0, header, 148, 8); | ||
113 | |||
114 | int checksum = 0; | ||
115 | foreach (byte b in header) | ||
116 | { | ||
117 | checksum += b; | ||
118 | } | ||
119 | |||
120 | m_log.DebugFormat("[TAR ARCHIVE]: Decimal header checksum is {0}", checksum); | ||
121 | |||
122 | byte[] checkSumBytes = ConvertDecimalToPaddedOctalBytes(checksum, 6); | ||
123 | //byte[] checkSumBytes = m_asciiEncoding.GetBytes("007520"); | ||
124 | |||
125 | Array.Copy(checkSumBytes, 0, header, 148, 6); | ||
126 | |||
127 | header[154] = 0; | ||
128 | |||
129 | // Write out header | ||
130 | bw.Write(header); | ||
131 | |||
132 | // Write out data | ||
133 | bw.Write(data); | ||
134 | |||
135 | int paddingRequired = 512 - (data.Length % 512); | ||
136 | if (paddingRequired > 0) | ||
137 | { | ||
138 | m_log.DebugFormat("Padding data with {0} bytes", paddingRequired); | ||
139 | |||
140 | byte[] padding = new byte[paddingRequired]; | ||
141 | bw.Write(padding); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | // Write two consecutive 0 blocks to end the archive | ||
146 | byte[] finalZeroPadding = new byte[1024]; | ||
147 | bw.Write(finalZeroPadding); | ||
148 | |||
149 | bw.Close(); | ||
150 | } | ||
151 | |||
152 | public static byte[] ConvertDecimalToPaddedOctalBytes(int d, int padding) | ||
153 | { | ||
154 | string oString = ""; | ||
155 | |||
156 | while (d > 0) | ||
157 | { | ||
158 | oString = Convert.ToString((byte)'0' + d & 7) + oString; | ||
159 | d >>= 3; | ||
160 | } | ||
161 | |||
162 | while (oString.Length < padding) | ||
163 | { | ||
164 | oString = "0" + oString; | ||
165 | } | ||
166 | |||
167 | m_log.DebugFormat("[TAR ARCHIVE]: oString is {0}", oString); | ||
168 | |||
169 | byte[] oBytes = m_asciiEncoding.GetBytes(oString); | ||
170 | |||
171 | return oBytes; | ||
172 | } | ||
173 | } | ||
174 | } \ No newline at end of file | ||