From: Gunnar Beutner Date: Wed, 19 Aug 2015 05:54:06 +0000 (+0200) Subject: Fix: Utility::Glob on Windows doesn't support wildcards in all but the last path... X-Git-Tag: v2.4.0~393 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b43a3135cc1e388d6a61435e8c3bc89a1d6bdffc;p=icinga2 Fix: Utility::Glob on Windows doesn't support wildcards in all but the last path component fixes #9962 --- diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index b1da99df4..a080b20aa 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -321,18 +321,9 @@ String Utility::NewUniqueID(void) return id; } -/** - * Calls the specified callback for each file matching the path specification. - * - * @param pathSpec The path specification. - * @param callback The callback which is invoked for each matching file. - * @param type The file type (a combination of GlobFile and GlobDirectory) - */ -bool Utility::Glob(const String& pathSpec, const boost::function& callback, int type) -{ - std::vector files, dirs; - #ifdef _WIN32 +static bool GlobHelper(const String& pathSpec, int type, std::vector& files, std::vector& dirs) +{ HANDLE handle; WIN32_FIND_DATA wfd; @@ -345,16 +336,16 @@ bool Utility::Glob(const String& pathSpec, const boost::function& callback, int type) +{ + std::vector files, dirs; + +#ifdef _WIN32 + std::vector tokens; + boost::algorithm::split(tokens, pathSpec, boost::is_any_of("\\/")); + + String part1; + + for (std::vector::size_type i = 0; i < tokens.size() - 1; i++) { + const String& token = tokens[i]; + + if (!part1.IsEmpty()) + part1 += "/"; + + part1 += token; + + if (token.FindFirstOf("?*") != String::NPos) { + String part2; + + for (std::vector::size_type k = i + 1; k < tokens.size(); k++) { + if (!part2.IsEmpty()) + part2 += "/"; + + part2 += tokens[k]; + } + + std::vector files2, dirs2; + + if (!GlobHelper(part1, GlobDirectory, files2, dirs2)) + return false; + + BOOST_FOREACH(const String& dir, dirs2) { + if (!Utility::Glob(dir + "/" + part2, callback, type)) + return false; + } + + return true; + } + } + + if (!GlobHelper(part1 + "/" + tokens[tokens.size() - 1], type, files, dirs)) + return false; #else /* _WIN32 */ glob_t gr;