[banshee] Follow symlinks when scanning (bgo#545768)
- From: Alexander Kojevnikov <alexk src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [banshee] Follow symlinks when scanning (bgo#545768)
- Date: Thu, 4 Feb 2010 11:24:24 +0000 (UTC)
commit d346266f47a3f030b05ed7f778d24113d2c76649
Author: Alexander Kojevnikov <alexander kojevnikov com>
Date: Thu Feb 4 22:24:16 2010 +1100
Follow symlinks when scanning (bgo#545768)
.../Banshee.Unix/Banshee.IO.Unix/Directory.cs | 39 ++++++++++++++++----
.../Banshee.IO/DirectoryScannerPipelineElement.cs | 14 ++++++-
2 files changed, 44 insertions(+), 9 deletions(-)
---
diff --git a/src/Backends/Banshee.Unix/Banshee.IO.Unix/Directory.cs b/src/Backends/Banshee.Unix/Banshee.IO.Unix/Directory.cs
index fcfefc0..8749775 100644
--- a/src/Backends/Banshee.Unix/Banshee.IO.Unix/Directory.cs
+++ b/src/Backends/Banshee.Unix/Banshee.IO.Unix/Directory.cs
@@ -88,9 +88,12 @@ namespace Banshee.IO.Unix
public IEnumerable<string> GetFiles (string directory)
{
- UnixDirectoryInfo unix_dir = new UnixDirectoryInfo (directory);
- foreach (UnixFileSystemInfo entry in unix_dir.GetFileSystemEntries ()) {
- if (!entry.IsDirectory && entry.IsRegularFile && !entry.IsSocket && entry.Exists) {
+ var unix_dir = TraverseSymlink(new UnixDirectoryInfo (directory)) as UnixDirectoryInfo;
+ if (unix_dir == null) {
+ yield break;
+ }
+ foreach (var entry in unix_dir.GetFileSystemEntries ()) {
+ if (entry != null && !entry.IsDirectory && entry.IsRegularFile && !entry.IsSocket && entry.Exists) {
yield return entry.FullName;
}
}
@@ -98,11 +101,33 @@ namespace Banshee.IO.Unix
public IEnumerable<string> GetDirectories (string directory)
{
- UnixDirectoryInfo unix_dir = new UnixDirectoryInfo (directory);
- foreach (UnixFileSystemInfo entry in unix_dir.GetFileSystemEntries ()) {
- if (entry.IsDirectory && entry.Exists && !entry.IsSocket) {
- yield return entry.FullName;
+ var unix_dir = new UnixDirectoryInfo (directory);
+ foreach (var entry in unix_dir.GetFileSystemEntries ()) {
+ var info = TraverseSymlink (entry);
+ if (info != null && info.IsDirectory && info.Exists && !info.IsSocket) {
+ yield return info.FullName;
+ }
+ }
+ }
+
+ private readonly HashSet<string> visited_symlinks = new HashSet<string> ();
+ private UnixFileSystemInfo TraverseSymlink (UnixFileSystemInfo info)
+ {
+ lock (visited_symlinks) {
+ visited_symlinks.Clear ();
+ while (info.IsSymbolicLink) {
+ if (visited_symlinks.Contains (info.FullName)) {
+ return null;
+ }
+ visited_symlinks.Add (info.FullName);
+ var target = new UnixSymbolicLinkInfo (info.FullName).GetContents ();
+ if (info.FullName.StartsWith (target.FullName)) {
+ return null;
+ }
+ info = target;
}
+
+ return info;
}
}
diff --git a/src/Core/Banshee.Core/Banshee.IO/DirectoryScannerPipelineElement.cs b/src/Core/Banshee.Core/Banshee.IO/DirectoryScannerPipelineElement.cs
index 5c71f4f..9147b46 100644
--- a/src/Core/Banshee.Core/Banshee.IO/DirectoryScannerPipelineElement.cs
+++ b/src/Core/Banshee.Core/Banshee.IO/DirectoryScannerPipelineElement.cs
@@ -27,6 +27,7 @@
//
using System;
+using System.Collections.Generic;
using System.IO;
using Hyena.Collections;
@@ -39,10 +40,16 @@ namespace Banshee.IO
{
protected override string ProcessItem (string item)
{
- ScanForFiles (item, false);
+ try {
+ ScanForFiles (item, false);
+ }
+ finally {
+ visited_dirs.Clear ();
+ }
return null;
}
+ private readonly HashSet<string> visited_dirs = new HashSet<string> ();
private void ScanForFiles (string source, bool skip_hidden)
{
CheckForCanceled ();
@@ -72,13 +79,16 @@ namespace Banshee.IO
// Normalise the path (remove the trailing directory separator)
source = Path.Combine (Path.GetDirectoryName (source), Path.GetFileName (source));
if (!skip_hidden || !Path.GetFileName (source).StartsWith (".")) {
+ visited_dirs.Add (source);
try {
foreach (string file in Banshee.IO.Directory.GetFiles (source)) {
ScanForFiles (file, true);
}
foreach (string directory in Banshee.IO.Directory.GetDirectories (source)) {
- ScanForFiles (directory, true);
+ if (!visited_dirs.Contains (directory)) {
+ ScanForFiles (directory, true);
+ }
}
} catch {
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]