AX_BOOST_THREAD
AX_BOOST_SYSTEM
AX_BOOST_UNIT_TEST_FRAMEWORK
+AX_BOOST_PROGRAM_OPTIONS
AX_CHECK_OPENSSL([], [AC_MSG_ERROR([You need the OpenSSL headers and libraries in order to build this application])])
AC_CHECK_LIB(ssl, SSL_new)
AC_CHECK_LIB(crypto, X509_NAME_oneline)
$(BOOST_SIGNALS_LIB) \
$(BOOST_THREAD_LIB) \
$(BOOST_SYSTEM_LIB) \
+ $(BOOST_PROGRAM_OPTIONS_LIB) \
${top_builddir}/lib/base/libbase.la \
${top_builddir}/lib/config/libconfig.la \
${top_builddir}/lib/remoting/libremoting.la \
#endif /* _WIN32 */
using namespace icinga;
+namespace po = boost::program_options;
/**
* Entry point for the Icinga application.
#endif /* _WIN32 */
);
- if (argc < 3 || strcmp(argv[1], "-c") != 0) {
- stringstream msgbuf;
- msgbuf << "Syntax: " << argv[0] << " -c <config-file> ...";
- Logger::Write(LogInformation, "icinga-app", msgbuf.str());
- return EXIT_FAILURE;
+ po::options_description desc("Supported options");
+ desc.add_options()
+ ("help,h", "show this help message")
+ ("library,l", po::value<vector<String> >(), "load a library")
+ ("include,I", po::value<vector<String> >(), "add include search directory")
+ ("config,c", po::value<vector<String> >(), "parse a configuration file")
+ ("validate,v", "exit after validating the configuration")
+ ("debug", "enable debugging")
+ ("daemonize,d", "daemonize after reading the configuration files")
+ ;
+
+ po::variables_map vm;
+ po::store(po::parse_command_line(argc, argv, desc), vm);
+ po::notify(vm);
+
+ if (vm.count("debug"))
+ Application::SetDebugging(true);
+
+ if (vm.count("help")) {
+ std::cout << desc << "\n";
+
+ return EXIT_SUCCESS;
}
Component::AddSearchDir(Application::GetPkgLibDir());
Utility::LoadIcingaLibrary("icinga", false);
+ if (vm.count("library")) {
+ BOOST_FOREACH(const String& libraryName, vm["library"].as<vector<String> >()) {
+ Utility::LoadIcingaLibrary(libraryName, false);
+ }
+ }
+
ConfigCompiler::AddIncludeSearchDir(Application::GetPkgDataDir());
+ if (vm.count("include")) {
+ BOOST_FOREACH(const String& includePath, vm["include"].as<vector<String> >()) {
+ ConfigCompiler::AddIncludeSearchDir(includePath);
+ }
+ }
+
+ if (vm.count("config") == 0) {
+ Logger::Write(LogCritical, "icinga-app", "You need to specify at least one config file (using the --config option).");
+
+ return EXIT_FAILURE;
+ }
+
try {
DynamicObject::BeginTx();
- /* load config file */
- String configFile = argv[2];
- vector<ConfigItem::Ptr> items;
- vector<ConfigType::Ptr> types;
+ /* load config files */
+ BOOST_FOREACH(const String& configPath, vm["config"].as<vector<String> >()) {
+ String configFile = argv[2];
+ vector<ConfigItem::Ptr> items;
+ vector<ConfigType::Ptr> types;
- ConfigCompiler::CompileFile(configFile, &items, &types);
+ ConfigCompiler::CompileFile(configFile, &items, &types);
- Logger::Write(LogInformation, "icinga-app", "Registering config types...");
-
- BOOST_FOREACH(const ConfigType::Ptr& type, types) {
- type->Commit();
- }
-
- Logger::Write(LogInformation, "icinga-app", "Executing config items...");
-
- BOOST_FOREACH(const ConfigItem::Ptr& item, items) {
- item->Commit();
- }
-
- Logger::Write(LogInformation, "icinga-app", "Validating config items...");
+ Logger::Write(LogInformation, "icinga-app", "Registering config types...");
+ BOOST_FOREACH(const ConfigType::Ptr& type, types) {
+ type->Commit();
+ }
- DynamicType::Ptr type;
- BOOST_FOREACH(tie(tuples::ignore, type), DynamicType::GetTypes()) {
- ConfigType::Ptr ctype = ConfigType::GetByName(type->GetName());
-
- if (!ctype) {
- Logger::Write(LogWarning, "icinga-app", "No config type found for type '" + type->GetName() + "'");
-
- continue;
+ Logger::Write(LogInformation, "icinga-app", "Executing config items...");
+ BOOST_FOREACH(const ConfigItem::Ptr& item, items) {
+ item->Commit();
}
+
+ Logger::Write(LogInformation, "icinga-app", "Validating config items...");
+ DynamicType::Ptr type;
+ BOOST_FOREACH(tie(tuples::ignore, type), DynamicType::GetTypes()) {
+ ConfigType::Ptr ctype = ConfigType::GetByName(type->GetName());
- DynamicObject::Ptr object;
- BOOST_FOREACH(tie(tuples::ignore, object), type->GetObjects()) {
- ctype->ValidateObject(object);
+ if (!ctype) {
+ Logger::Write(LogWarning, "icinga-app", "No config type found for type '" + type->GetName() + "'");
+
+ continue;
+ }
+
+ DynamicObject::Ptr object;
+ BOOST_FOREACH(tie(tuples::ignore, object), type->GetObjects()) {
+ ctype->ValidateObject(object);
+ }
}
}
if (!app)
throw_exception(runtime_error("Configuration must create an Application object."));
- /* The application class doesn't need to know about the "-c configFile"
- * command-line arguments. */
- return app->Run(argc - 2, &(argv[2]));
+ if (vm.count("validate")) {
+ Logger::Write(LogInformation, "icinga-app", "Terminating as requested by --validate.");
+ return EXIT_SUCCESS;
+ }
+
+ if (vm.count("daemonize")) {
+ Logger::Write(LogInformation, "icinga", "Daemonizing.");
+ Utility::Daemonize();
+ }
+
+ return app->Run();
}
#endif /* _WIN32 */
}
+/**
+ * Sets whether debugging is enabled.
+ *
+ * @param debug Whether to enable debugging.
+ */
+void Application::SetDebugging(bool debug)
+{
+ m_Debugging = debug;
+}
+
/**
* Retrieves the debugging mode of the application.
*
/**
* Runs the application.
*
- * @param argc The number of arguments.
- * @param argv The arguments that should be passed to the application.
* @returns The application's exit code.
*/
-int Application::Run(int argc, char **argv)
+int Application::Run(void)
{
int result;
SetConsoleCtrlHandler(&Application::CtrlHandler, TRUE);
#endif /* _WIN32 */
- m_Arguments.clear();
- for (int i = 0; i < argc; i++)
- m_Arguments.push_back(String(argv[i]));
-
DynamicObject::BeginTx();
- result = Main(m_Arguments);
+ result = Main();
DynamicObject::FinishTx();
DynamicObject::DeactivateObjects();
static Application::Ptr GetInstance(void);
- int Run(int argc, char **argv);
+ int Run(void);
/**
* Starts the application.
*
- * @param args Arguments for the application.
* @returns The exit code of the application.
*/
- virtual int Main(const vector<String>& args) = 0;
+ virtual int Main(void) = 0;
static void InstallExceptionHandlers(void);
static void RequestShutdown(void);
static void Terminate(int exitCode);
+ static void SetDebugging(bool debug);
static bool IsDebugging(void);
static bool IsMainThread(void);
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
+#include <boost/program_options.hpp>
using boost::shared_ptr;
using boost::weak_ptr;
processed = true;
}
- if (!processed && entry.Severity >= LogInformation) {
+ LogSeverity defaultLogLevel;
+
+ if (Application::IsDebugging())
+ defaultLogLevel = LogDebug;
+ else
+ defaultLogLevel = LogInformation;
+
+ if (!processed && entry.Severity >= defaultLogLevel) {
static bool tty = StreamLogger::IsTty(std::cout);
StreamLogger::ProcessLogEntry(std::cout, tty, entry);
*/
void ConfigCompiler::AddIncludeSearchDir(const String& dir)
{
+ Logger::Write(LogInformation, "config", "Adding include search dir: " + dir);
+
m_IncludeSearchDirs.push_back(dir);
}
/**
* The entry point for the Icinga application.
*
- * @param args Command-line arguments.
* @returns An exit status.
*/
-int IcingaApplication::Main(const vector<String>& args)
+int IcingaApplication::Main(void)
{
Logger::Write(LogInformation, "icinga", "In IcingaApplication::Main()");
m_StartTime = Utility::GetTime();
- if (args.size() == 1 && args[0] == "--help") {
- stringstream msgbuf;
- msgbuf << "Syntax: " << args[0] << " ... -d";
- Logger::Write(LogInformation, "icinga", msgbuf.str());
- return EXIT_FAILURE;
- }
-
- bool daemonize = false;
- bool parseOpts = true;
- String configFile;
-
- /* TODO: clean up this mess; for now it will just have to do */
- vector<String>::const_iterator it;
- for (it = args.begin() + 1 ; it != args.end(); it++) {
- String arg = *it;
-
- /* ignore empty arguments */
- if (arg.IsEmpty())
- continue;
-
- if (arg == "--") {
- parseOpts = false;
- continue;
- }
-
- if (parseOpts && arg[0] == '-') {
- if (arg == "-d") {
- daemonize = true;
- continue;
- } else {
- throw_exception(invalid_argument("Unknown option: " + arg));
- }
- }
- }
-
UpdatePidFile(GetPidPath());
if (!GetCertificateFile().IsEmpty() && !GetCAFile().IsEmpty()) {
if (!GetService().IsEmpty())
EndpointManager::GetInstance()->AddListener(GetService());
- if (daemonize) {
- Logger::Write(LogInformation, "icinga", "Daemonizing.");
- ClosePidFile();
- Utility::Daemonize();
- UpdatePidFile(GetPidPath());
- }
-
/* restore the previous program state */
DynamicObject::RestoreObjects(GetStatePath());
IcingaApplication(const Dictionary::Ptr& serializedUpdate);
- int Main(const vector<String>& args);
+ int Main(void);
static IcingaApplication::Ptr GetInstance(void);
--- /dev/null
+# ============================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_boost_program_options.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+# AX_BOOST_PROGRAM_OPTIONS
+#
+# DESCRIPTION
+#
+# Test for program options library from the Boost C++ libraries. The macro
+# requires a preceding call to AX_BOOST_BASE. Further documentation is
+# available at <http://randspringer.de/boost/index.html>.
+#
+# This macro calls:
+#
+# AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB)
+#
+# And sets:
+#
+# HAVE_BOOST_PROGRAM_OPTIONS
+#
+# LICENSE
+#
+# Copyright (c) 2009 Thomas Porschberg <thomas@randspringer.de>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 22
+
+AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS],
+[
+ AC_ARG_WITH([boost-program-options],
+ AS_HELP_STRING([--with-boost-program-options@<:@=special-lib@:>@],
+ [use the program options library from boost - it is possible to specify a certain library for the linker
+ e.g. --with-boost-program-options=boost_program_options-gcc-mt-1_33_1 ]),
+ [
+ if test "$withval" = "no"; then
+ want_boost="no"
+ elif test "$withval" = "yes"; then
+ want_boost="yes"
+ ax_boost_user_program_options_lib=""
+ else
+ want_boost="yes"
+ ax_boost_user_program_options_lib="$withval"
+ fi
+ ],
+ [want_boost="yes"]
+ )
+
+ if test "x$want_boost" = "xyes"; then
+ AC_REQUIRE([AC_PROG_CC])
+ export want_boost
+ CPPFLAGS_SAVED="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+ export CPPFLAGS
+ LDFLAGS_SAVED="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+ export LDFLAGS
+ AC_CACHE_CHECK([whether the Boost::Program_Options library is available],
+ ax_cv_boost_program_options,
+ [AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/program_options.hpp>
+ ]],
+ [[boost::program_options::options_description generic("Generic options");
+ return 0;]])],
+ ax_cv_boost_program_options=yes, ax_cv_boost_program_options=no)
+ AC_LANG_POP([C++])
+ ])
+ if test "$ax_cv_boost_program_options" = yes; then
+ AC_DEFINE(HAVE_BOOST_PROGRAM_OPTIONS,,[define if the Boost::PROGRAM_OPTIONS library is available])
+ BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+ if test "x$ax_boost_user_program_options_lib" = "x"; then
+ for libextension in `ls $BOOSTLIBDIR/libboost_program_options*.so* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.so.*$;\1;'` `ls $BOOSTLIBDIR/libboost_program_options*.dylib* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.dylib.*$;\1;'` `ls $BOOSTLIBDIR/libboost_program_options*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_program_options.*\)\.a.*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break],
+ [link_program_options="no"])
+ done
+ if test "x$link_program_options" != "xyes"; then
+ for libextension in `ls $BOOSTLIBDIR/boost_program_options*.dll* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_program_options.*\)\.dll.*$;\1;'` `ls $BOOSTLIBDIR/boost_program_options*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_program_options.*\)\.a.*$;\1;'` ; do
+ ax_lib=${libextension}
+ AC_CHECK_LIB($ax_lib, exit,
+ [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break],
+ [link_program_options="no"])
+ done
+ fi
+ else
+ for ax_lib in $ax_boost_user_program_options_lib boost_program_options-$ax_boost_user_program_options_lib; do
+ AC_CHECK_LIB($ax_lib, main,
+ [BOOST_PROGRAM_OPTIONS_LIB="-l$ax_lib"; AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) link_program_options="yes"; break],
+ [link_program_options="no"])
+ done
+ fi
+ if test "x$ax_lib" = "x"; then
+ AC_MSG_ERROR(Could not find a version of the library!)
+ fi
+ if test "x$link_program_options" != "xyes"; then
+ AC_MSG_ERROR([Could not link against [$ax_lib] !])
+ fi
+ fi
+
+ ax_lib=""
+
+ CPPFLAGS="$CPPFLAGS_SAVED"
+ LDFLAGS="$LDFLAGS_SAVED"
+ fi
+])