aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment')
-rw-r--r--OpenSim/Region/Environment/Modules/World/Archiver/ArchiveRequest.cs13
-rw-r--r--OpenSim/Region/Environment/Modules/World/Archiver/TarArchive.cs174
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
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Text;
33using System.Reflection;
34using log4net;
35
36namespace 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