From 0978e46d5a29c0ff4da4bbabe4c32c36eebaadf9 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Fri, 22 Nov 2013 09:03:52 +0100 Subject: [PATCH] Implement file type flags for Utility::Glob. Fixes #5123 --- components/cluster/clusterlistener.cpp | 10 ++++++---- components/livestatus/logtable.cpp | 4 ++-- components/livestatus/statehisttable.cpp | 4 ++-- lib/base/unix.h | 2 ++ lib/base/utility.cpp | 24 +++++++++++++++++++++++- lib/base/utility.h | 8 +++++++- lib/config/configcompiler.cpp | 2 +- 7 files changed, 43 insertions(+), 11 deletions(-) diff --git a/components/cluster/clusterlistener.cpp b/components/cluster/clusterlistener.cpp index 85a2e0003..137dd4458 100644 --- a/components/cluster/clusterlistener.cpp +++ b/components/cluster/clusterlistener.cpp @@ -383,7 +383,7 @@ void ClusterListener::ReplayLog(const Endpoint::Ptr& endpoint, const Stream::Ptr count = 0; std::vector files; - Utility::Glob(GetClusterDir() + "log/*", boost::bind(&ClusterListener::LogGlobHandler, boost::ref(files), _1)); + Utility::Glob(GetClusterDir() + "log/*", boost::bind(&ClusterListener::LogGlobHandler, boost::ref(files), _1), GlobFile); std::sort(files.begin(), files.end()); BOOST_FOREACH(int ts, files) { @@ -479,6 +479,8 @@ void ClusterListener::ReplayLog(const Endpoint::Ptr& endpoint, const Stream::Ptr void ClusterListener::ConfigGlobHandler(const Dictionary::Ptr& config, const String& file, bool basename) { + CONTEXT("Creating config update for file '" + file + "'"); + Dictionary::Ptr elem = make_shared(); std::ifstream fp(file.CStr()); @@ -532,7 +534,7 @@ void ClusterListener::NewClientHandler(const Socket::Ptr& client, TlsRole role) if (configFiles) { ObjectLock olock(configFiles); BOOST_FOREACH(const String& pattern, configFiles) { - Utility::Glob(pattern, boost::bind(&ClusterListener::ConfigGlobHandler, boost::cref(config), _1, false)); + Utility::Glob(pattern, boost::bind(&ClusterListener::ConfigGlobHandler, boost::cref(config), _1, false), GlobFile); } } @@ -591,7 +593,7 @@ void ClusterListener::ClusterTimerHandler(void) } std::vector files; - Utility::Glob(GetClusterDir() + "log/*", boost::bind(&ClusterListener::LogGlobHandler, boost::ref(files), _1)); + Utility::Glob(GetClusterDir() + "log/*", boost::bind(&ClusterListener::LogGlobHandler, boost::ref(files), _1), GlobFile); std::sort(files.begin(), files.end()); BOOST_FOREACH(int ts, files) { @@ -1391,7 +1393,7 @@ void ClusterListener::MessageHandler(const Endpoint::Ptr& sender, const Dictiona } Dictionary::Ptr localConfig = make_shared(); - Utility::Glob(dir + "/*", boost::bind(&ClusterListener::ConfigGlobHandler, boost::cref(localConfig), _1, true)); + Utility::Glob(dir + "/*", boost::bind(&ClusterListener::ConfigGlobHandler, boost::cref(localConfig), _1, true), GlobFile); bool configChange = false; diff --git a/components/livestatus/logtable.cpp b/components/livestatus/logtable.cpp index 30f3e79c6..1493ec3ab 100644 --- a/components/livestatus/logtable.cpp +++ b/components/livestatus/logtable.cpp @@ -291,8 +291,8 @@ Value LogTable::CommandNameAccessor(const Value& row) void LogTable::CreateLogIndex(const String& path) { - Utility::Glob(path + "/icinga.log", boost::bind(&LogTable::CreateLogIndexFileHandler, _1, boost::ref(m_LogFileIndex))); - Utility::Glob(path + "/archives/*.log", boost::bind(&LogTable::CreateLogIndexFileHandler, _1, boost::ref(m_LogFileIndex))); + Utility::Glob(path + "/icinga.log", boost::bind(&LogTable::CreateLogIndexFileHandler, _1, boost::ref(m_LogFileIndex)), GlobFile); + Utility::Glob(path + "/archives/*.log", boost::bind(&LogTable::CreateLogIndexFileHandler, _1, boost::ref(m_LogFileIndex)), GlobFile); } void LogTable::CreateLogIndexFileHandler(const String& path, std::map& index) diff --git a/components/livestatus/statehisttable.cpp b/components/livestatus/statehisttable.cpp index 1d1fa3def..908f810b9 100644 --- a/components/livestatus/statehisttable.cpp +++ b/components/livestatus/statehisttable.cpp @@ -518,8 +518,8 @@ Value StateHistTable::DurationPartUnmonitoredAccessor(const Value& row) void StateHistTable::CreateLogIndex(const String& path) { - Utility::Glob(path + "/icinga.log", boost::bind(&StateHistTable::CreateLogIndexFileHandler, _1, boost::ref(m_LogFileIndex))); - Utility::Glob(path + "/archives/*.log", boost::bind(&StateHistTable::CreateLogIndexFileHandler, _1, boost::ref(m_LogFileIndex))); + Utility::Glob(path + "/icinga.log", boost::bind(&StateHistTable::CreateLogIndexFileHandler, _1, boost::ref(m_LogFileIndex)), GlobFile); + Utility::Glob(path + "/archives/*.log", boost::bind(&StateHistTable::CreateLogIndexFileHandler, _1, boost::ref(m_LogFileIndex)), GlobFile); } void StateHistTable::CreateLogIndexFileHandler(const String& path, std::map& index) diff --git a/lib/base/unix.h b/lib/base/unix.h index 76e8c1d2f..ee6022839 100644 --- a/lib/base/unix.h +++ b/lib/base/unix.h @@ -35,6 +35,8 @@ #include #include #include +#include +#include typedef int SOCKET; #define INVALID_SOCKET (-1) diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index bb32eef41..d43e12b90 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -320,8 +320,10 @@ String Utility::NewUniqueID(void) * 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) +bool Utility::Glob(const String& pathSpec, const boost::function& callback, int type) { #ifdef _WIN32 HANDLE handle; @@ -342,6 +344,12 @@ bool Utility::Glob(const String& pathSpec, const boost::function 0; gp++, left--) { + struct stat statbuf; + + if (lstat(*gp, &statbuf) < 0) + continue; + + if (!S_ISDIR(statbuf.st_mode) && !S_ISREG(statbuf.st_mode)) + continue; + + if (S_ISDIR(statbuf.st_mode) && !(type & GlobDirectory)) + continue; + + if (!S_ISDIR(statbuf.st_mode) && !(type & GlobFile)) + continue; + callback(*gp); } diff --git a/lib/base/utility.h b/lib/base/utility.h index ddffa4b44..269b9af96 100644 --- a/lib/base/utility.h +++ b/lib/base/utility.h @@ -43,6 +43,12 @@ struct THREADNAME_INFO # pragma pack(pop) #endif +enum GlobType +{ + GlobFile = 1, + GlobDirectory = 2 +}; + /** * Helper functions. * @@ -69,7 +75,7 @@ public: static String NewUniqueID(void); - static bool Glob(const String& pathSpec, const boost::function& callback); + static bool Glob(const String& pathSpec, const boost::function& callback, int type = GlobFile | GlobDirectory); static void QueueAsyncCallback(const boost::function& callback); diff --git a/lib/config/configcompiler.cpp b/lib/config/configcompiler.cpp index cf798480e..ea42c78b9 100644 --- a/lib/config/configcompiler.cpp +++ b/lib/config/configcompiler.cpp @@ -203,7 +203,7 @@ void ConfigCompiler::HandleFileInclude(const String& include, bool search, std::vector items; - if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CompileFile, _1)) && includePath.FindFirstOf("*?") == String::NPos) { + if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CompileFile, _1), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) { std::ostringstream msgbuf; msgbuf << "Include file '" + include + "' does not exist: " << debuginfo; BOOST_THROW_EXCEPTION(std::invalid_argument(msgbuf.str()));