aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs120
1 files changed, 116 insertions, 4 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
index a822d10..247cee4 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
@@ -27,6 +27,9 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
30using OpenMetaverse; 33using OpenMetaverse;
31using OpenSim.Framework; 34using OpenSim.Framework;
32using OpenSim.Services.Interfaces; 35using OpenSim.Services.Interfaces;
@@ -38,7 +41,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
38 /// </summary> 41 /// </summary>
39 public static class InventoryArchiveUtils 42 public static class InventoryArchiveUtils
40 { 43 {
41 public static readonly string PATH_DELIMITER = "/"; 44// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 // Character used for escaping the path delimter ("\/") and itself ("\\") in human escaped strings
47 public static readonly char ESCAPE_CHARACTER = '\\';
48
49 // The character used to separate inventory path components (different folders and items)
50 public static readonly char PATH_DELIMITER = '/';
42 51
43 /// <summary> 52 /// <summary>
44 /// Find a folder given a PATH_DELIMITER delimited path starting from a user's root folder 53 /// Find a folder given a PATH_DELIMITER delimited path starting from a user's root folder
@@ -103,10 +112,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
103 112
104 path = path.Trim(); 113 path = path.Trim();
105 114
106 if (path == PATH_DELIMITER) 115 if (path == PATH_DELIMITER.ToString())
107 return startFolder; 116 return startFolder;
108 117
109 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); 118 string[] components = SplitEscapedPath(path);
119 components[0] = UnescapePath(components[0]);
120
121 //string[] components = path.Split(new string[] { PATH_DELIMITER.ToString() }, 2, StringSplitOptions.None);
122
110 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); 123 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
111 124
112 foreach (InventoryFolderBase folder in contents.Folders) 125 foreach (InventoryFolderBase folder in contents.Folders)
@@ -181,10 +194,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
181 public static InventoryItemBase FindItemByPath( 194 public static InventoryItemBase FindItemByPath(
182 IInventoryService inventoryService, InventoryFolderBase startFolder, string path) 195 IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
183 { 196 {
184 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); 197 string[] components = SplitEscapedPath(path);
198 components[0] = UnescapePath(components[0]);
199
200 //string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None);
185 201
186 if (components.Length == 1) 202 if (components.Length == 1)
187 { 203 {
204// m_log.DebugFormat("FOUND SINGLE COMPONENT [{0}]", components[0]);
205
188 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); 206 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
189 foreach (InventoryItemBase item in items) 207 foreach (InventoryItemBase item in items)
190 { 208 {
@@ -194,6 +212,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
194 } 212 }
195 else 213 else
196 { 214 {
215// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
216
197 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); 217 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
198 218
199 foreach (InventoryFolderBase folder in contents.Folders) 219 foreach (InventoryFolderBase folder in contents.Folders)
@@ -206,5 +226,97 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
206 // We didn't find an item or intermediate folder with the given name 226 // We didn't find an item or intermediate folder with the given name
207 return null; 227 return null;
208 } 228 }
229
230 /// <summary>
231 /// Split a human escaped path into two components if it contains an unescaped path delimiter, or one component
232 /// if no delimiter is present
233 /// </summary>
234 /// <param name="path"></param>
235 /// <returns>
236 /// The split path. We leave the components in their originally unescaped state (though we remove the delimiter
237 /// which originally split them if applicable).
238 /// </returns>
239 public static string[] SplitEscapedPath(string path)
240 {
241// m_log.DebugFormat("SPLITTING PATH {0}", path);
242
243 bool singleEscapeChar = false;
244
245 for (int i = 0; i < path.Length; i++)
246 {
247 if (path[i] == ESCAPE_CHARACTER && !singleEscapeChar)
248 {
249 singleEscapeChar = true;
250 }
251 else
252 {
253 if (PATH_DELIMITER == path[i] && !singleEscapeChar)
254 return new string[2] { path.Remove(i), path.Substring(i + 1) };
255 else
256 singleEscapeChar = false;
257 }
258 }
259
260 // We didn't find a delimiter
261 return new string[1] { path };
262 }
263
264 /// <summary>
265 /// Unescapes a human escaped path. This means that "\\" goes to "\", and "\/" goes to "/"
266 /// </summary>
267 /// <param name="path"></param>
268 /// <returns></returns>
269 public static string UnescapePath(string path)
270 {
271// m_log.DebugFormat("ESCAPING PATH {0}", path);
272
273 StringBuilder sb = new StringBuilder();
274
275 bool singleEscapeChar = false;
276 for (int i = 0; i < path.Length; i++)
277 {
278 if (path[i] == ESCAPE_CHARACTER && !singleEscapeChar)
279 singleEscapeChar = true;
280 else
281 singleEscapeChar = false;
282
283 if (singleEscapeChar)
284 {
285 if (PATH_DELIMITER == path[i])
286 sb.Append(PATH_DELIMITER);
287 }
288 else
289 {
290 sb.Append(path[i]);
291 }
292 }
293
294// m_log.DebugFormat("ESCAPED PATH TO {0}", sb);
295
296 return sb.ToString();
297 }
298
299 /// <summary>
300 /// Escape an archive path.
301 /// </summary>
302 /// This has to be done differently from human paths because we can't leave in any "/" characters (due to
303 /// problems if the archive is built from or extracted to a filesystem
304 /// <param name="path"></param>
305 /// <returns></returns>
306 public static string EscapeArchivePath(string path)
307 {
308 // Only encode ampersands (for escaping anything) and / (since this is used as general dir separator).
309 return path.Replace("&", "&amp;").Replace("/", "&#47;");
310 }
311
312 /// <summary>
313 /// Unescape an archive path.
314 /// </summary>
315 /// <param name="path"></param>
316 /// <returns></returns>
317 public static string UnescapeArchivePath(string path)
318 {
319 return path.Replace("&#47;", "/").Replace("&amp;", "&");
320 }
209 } 321 }
210} \ No newline at end of file 322} \ No newline at end of file