From a09011630d2e881e84e28b35d239e72fab0d5d2a Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Sat, 29 Oct 2011 19:40:50 +0200 Subject: [PATCH] FileLister (linux): Handle cyclic symbolic links Keep a list of already seen directories. The "udev" project f.e. has a directory with a subdirectory that contains a symbolic link back to the parent directory. --- cli/filelister.cpp | 20 +++++++++++++++----- cli/filelister.h | 2 ++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/cli/filelister.cpp b/cli/filelister.cpp index 0c063721b..b83b6c520 100644 --- a/cli/filelister.cpp +++ b/cli/filelister.cpp @@ -277,6 +277,7 @@ std::string FileLister::getAbsolutePath(const std::string& path) void FileLister::recursiveAddFiles2(std::vector &relative, std::vector &absolute, + std::set &seen_dirs, std::map &filesizes, const std::string &path) { @@ -292,11 +293,13 @@ void FileLister::recursiveAddFiles2(std::vector &relative, if (filename == "." || filename == ".." || filename.length() == 0) continue; + // Determine absolute path. Empty filename if path does not exist + const std::string absolute_path = getAbsolutePath(filename); + if (absolute_path.empty()) + continue; + if (filename[filename.length()-1] != '/') { // File - std::string absolute_path = getAbsolutePath(filename); - if (absolute_path.empty()) - continue; // Did we already see this file? Then bail out if (std::find(absolute.begin(), absolute.end(), absolute_path) != absolute.end()) @@ -313,7 +316,13 @@ void FileLister::recursiveAddFiles2(std::vector &relative, } } else { // Directory - recursiveAddFiles2(relative, absolute, filesizes, filename); + + // Check if we already seen this part of the directory tree (cyclic symbolic links) + if (seen_dirs.find(absolute_path) != seen_dirs.end()) + continue; + + seen_dirs.insert(absolute_path); + recursiveAddFiles2(relative, absolute, seen_dirs, filesizes, filename); } } globfree(&glob_results); @@ -323,7 +332,8 @@ void FileLister::recursiveAddFiles2(std::vector &relative, void FileLister::recursiveAddFiles(std::vector &filenames, std::map &filesizes, const std::string &path) { std::vector abs; - recursiveAddFiles2(filenames, abs, filesizes, path); + std::set seen_dirs; + recursiveAddFiles2(filenames, abs, seen_dirs, filesizes, path); } bool FileLister::isDirectory(const std::string &path) diff --git a/cli/filelister.h b/cli/filelister.h index 9ee319b18..2b12d694f 100644 --- a/cli/filelister.h +++ b/cli/filelister.h @@ -21,6 +21,7 @@ #include #include +#include #include /// @addtogroup CLI @@ -67,6 +68,7 @@ public: static void recursiveAddFiles2(std::vector &relative, std::vector &absolute, + std::set &seen_dirs, std::map &filesizes, const std::string &path); #endif