[icinga-checkins] icinga.org: icinga2/master: Config: implement support for wildcard includes

git at icinga.org git at icinga.org
Sat Feb 2 00:32:23 CET 2013


Module: icinga2
Branch: master
Commit: 11cf07fa9c1c3b5acccf9f42cb48a5865757221b
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=11cf07fa9c1c3b5acccf9f42cb48a5865757221b

Author: Gunnar Beutner <gunnar at beutner.name>
Date:   Sat Feb  2 00:28:00 2013 +0100

Config: implement support for wildcard includes

Fixes #2771

---

 lib/base/unix.h               |    1 +
 lib/base/utility.cpp          |   56 +++++++++++++++++++++++++++++++++++++++++
 lib/base/utility.h            |    2 +
 lib/config/configcompiler.cpp |   20 +++++++++++++-
 lib/config/configcompiler.h   |    2 +
 5 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/lib/base/unix.h b/lib/base/unix.h
index 09453a4..e39af51 100644
--- a/lib/base/unix.h
+++ b/lib/base/unix.h
@@ -35,6 +35,7 @@
 #include <syslog.h>
 #include <sys/file.h>
 #include <sys/wait.h>
+#include <glob.h>
 #include <ltdl.h>
 
 typedef int SOCKET;
diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp
index b6cec47..2595a1d 100644
--- a/lib/base/utility.cpp
+++ b/lib/base/utility.cpp
@@ -283,6 +283,9 @@ String Utility::DirName(const String& path)
 	}
 
 	result = dir;
+
+	if (result.IsEmpty())
+		result = ".";
 #endif /* _WIN32 */
 
 	free(dir);
@@ -438,3 +441,56 @@ String Utility::NewUUID(void)
 	return boost::lexical_cast<String>(uuid);
 }
 
+/**
+ * Calls the specified callback for each file matching the path specification.
+ *
+ * @param pathSpec The path specification.
+ */
+bool Utility::Glob(const String& pathSpec, const function<void (const String&)>& callback)
+{
+#ifdef _WIN32
+	HANDLE handle;
+	WIN32_FIND_DATA wfd;
+
+	handle = FindFirstFile(pathSpec.CStr(), &wfd);
+
+	if (handle == INVALID_HANDLE_VALUE) {
+		DWORD errorCode = GetLastError();
+
+		if (errorCode == ERROR_FILE_NOT_FOUND)
+			return false;
+
+		throw_exception(Win32Exception("FindFirstFile() failed", errorCode));
+	}
+
+	do {
+		callback(wfd.cFileName);
+	} while (FindNextFile(handle, &wfd));
+
+	if (!FindClose(handle))
+		throw_exception(Win32Exception("FindClose() failed", GetLastError()));
+
+	return true;
+#else /* _WIN32 */
+	glob_t gr;
+
+	int rc = glob(pathSpec.CStr(), GLOB_ERR | GLOB_NOSORT, NULL, &gr);
+
+	if (rc < 0) {
+		if (rc == GLOB_NOMATCH)
+			return false;
+
+		throw_exception(PosixException("glob() failed", errno));
+	}
+
+	size_t left;
+	char **gp;
+	for (gp = gr.gl_pathv, left = gr.gl_pathc; left > 0; gp++, left--) {
+		callback(*gp);
+	}
+
+	globfree(&gr);
+
+	return true;
+#endif /* _WIN32 */
+}
diff --git a/lib/base/utility.h b/lib/base/utility.h
index 9dc1d4d..347fd18 100644
--- a/lib/base/utility.h
+++ b/lib/base/utility.h
@@ -56,6 +56,8 @@ public:
 
 	static String NewUUID(void);
 
+	static bool Glob(const String& pathSpec, const function<void (const String&)>& callback);
+
 	static
 #ifdef _WIN32
 	HMODULE
diff --git a/lib/config/configcompiler.cpp b/lib/config/configcompiler.cpp
index 77f614f..fa04277 100644
--- a/lib/config/configcompiler.cpp
+++ b/lib/config/configcompiler.cpp
@@ -166,6 +166,18 @@ vector<ConfigItem::Ptr> ConfigCompiler::CompileText(const String& path,
 }
 
 /**
+ * Compiles the specified file and returns the resulting config items in the passed vector.
+ *
+ * @param path The file that should be compiled.
+ * @param resultItems The vector that should be used to store the config items.
+ */
+void ConfigCompiler::CompileFileIncludeHelper(const String& path, vector<ConfigItem::Ptr>& resultItems)
+{
+	vector<ConfigItem::Ptr> items = CompileFile(path);
+	std::copy(items.begin(), items.end(), std::back_inserter(resultItems));
+}
+
+/**
  * Default include handler. Includes the file and returns a list of
  * configuration items.
  *
@@ -195,8 +207,12 @@ vector<ConfigItem::Ptr> ConfigCompiler::HandleFileInclude(const String& include,
 		}
 	}
 
-	/* TODO: implement wildcard includes */
-	return CompileFile(includePath);
+	vector<ConfigItem::Ptr> items;
+
+	if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CompileFileIncludeHelper, _1, boost::ref(items))))
+		throw_exception(invalid_argument("Include file '" + include + "' does not exist (or no files found for pattern)."));
+
+	return items;
 }
 
 /**
diff --git a/lib/config/configcompiler.h b/lib/config/configcompiler.h
index 2916df7..95e66de 100644
--- a/lib/config/configcompiler.h
+++ b/lib/config/configcompiler.h
@@ -73,6 +73,8 @@ private:
 
 	void InitializeScanner(void);
 	void DestroyScanner(void);
+
+	static void CompileFileIncludeHelper(const String& path, vector<ConfigItem::Ptr>& resultItems);
 };
 
 }





More information about the icinga-checkins mailing list